Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/api-reference/veryfront/agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -815,7 +815,7 @@ Input delivered to a hosted agent-service detached execution callback.
| `getProjectAgentRuntimeAgentIdCandidates` | Return project agent runtime agent ID candidates. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/project/agent-runtime.ts#L223) |
| `getProjectSteeringMutation` | Return project steering mutation. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/project/steering-mutation.ts#L112) |
| `getProviderNativeToolNames` | Return provider native tool names. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/provider-native-tool-inventory.ts#L48) |
| `getProviderToolProfile` | Return provider tool profile. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/provider-tool-compat.ts#L51) |
| `getProviderToolProfile` | Return provider tool profile. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/provider-tool-compat.ts#L59) |
| `getRuntimeAgentMarkdownDefinition` | Definition for get runtime agent markdown. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/agent-markdown-adapter.ts#L45) |
| `getRuntimeProjectFile` | Return runtime project file. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/project-files-client.ts#L404) |
| `getRuntimeProjectFiles` | Return runtime project files. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/project-files-client.ts#L671) |
Expand Down Expand Up @@ -981,11 +981,11 @@ Input delivered to a hosted agent-service detached execution callback.
| `runWithRunEventSink` | Scope an operation to a run event sink. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/runtime/run-event-sink-context.ts#L24) |
| `sanitizeDefaultHostedChildRequestedTools` | Sanitize default hosted child requested tools. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/hosted/child-requested-tools.ts#L276) |
| `sanitizeHostedChildRequestedTools` | Sanitize hosted child requested tools. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/hosted/child-requested-tools.ts#L57) |
| `sanitizeProviderToolSchema` | Zod schema for sanitize provider tool. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/provider-tool-compat.ts#L409) |
| `sanitizeProviderToolSchema` | Zod schema for sanitize provider tool. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/provider-tool-compat.ts#L549) |
| `selectDefaultHostedChildForkRuntimeTools` | Select default hosted child fork runtime tools helper. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/hosted/child-requested-tools.ts#L291) |
| `selectHostedChildForkRuntimeTools` | Select hosted child fork runtime tools helper. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/hosted/child-requested-tools.ts#L208) |
| `selectProviderCompatibleToolNames` | Select provider compatible tool names helper. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/provider-tool-compat.ts#L90) |
| `selectProviderCompatibleTools` | Select provider compatible tools helper. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/provider-tool-compat.ts#L118) |
| `selectProviderCompatibleToolNames` | Select provider compatible tool names helper. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/provider-tool-compat.ts#L98) |
| `selectProviderCompatibleTools` | Select provider compatible tools helper. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/provider-tool-compat.ts#L126) |
| `shouldBlockHostedChildSameTurnRetry` | Should block hosted child same turn retry helper. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/hosted/child-status.ts#L49) |
| `shouldContinueForkRuntimeStep` | Should continue fork runtime step helper. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/streaming/fork-runtime-step-progress.ts#L42) |
| `shouldFailEmptyHostedFinalizedMessage` | Message shape for should fail empty hosted finalized. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/hosted/stream-terminal-error.ts#L132) |
Expand Down
48 changes: 48 additions & 0 deletions src/agent/runtime/model-tool-converter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,54 @@ describe("model-tool-converter", () => {
});
});

it("removes top-level composition from a 198-tool Anthropic child set", () => {
const tools: ToolDefinition[] = [
...Array.from({ length: 197 }, (_, index) => ({
name: `child_tool_${index}`,
description: `Child tool ${index}`,
parameters: { type: "object" as const, properties: {} },
})),
{
name: "load_skill",
description: "Load a skill body or one of its advertised references",
parameters: {
anyOf: [
{
type: "object",
properties: {
skillId: { type: "string", enum: ["unloaded"] },
file: { type: "string" },
},
required: ["skillId"],
},
{
type: "object",
properties: {
skillId: { type: "string", enum: ["loaded"] },
file: { type: "string" },
},
required: ["skillId", "file"],
},
],
} as never,
},
];

const result = convertToolsToRuntimeTools(tools, {
model: "veryfront-cloud/anthropic/claude-opus-4-6",
});
const schema = getRuntimeToolSchema(result?.load_skill) as Record<string, unknown>;
const properties = schema.properties as Record<string, Record<string, unknown>>;

assertEquals(Object.keys(result ?? {}).length, 198);
assertEquals(schema.type, "object");
assertEquals(Object.hasOwn(schema, "anyOf"), false);
assertEquals(Object.hasOwn(schema, "oneOf"), false);
assertEquals(Object.hasOwn(schema, "allOf"), false);
assertEquals(Object.keys(properties), ["skillId", "file"]);
assertEquals(schema.required, ["skillId"]);
});

it("adds provider-native web_search for anthropic models when explicitly configured", () => {
const result = convertToolsToRuntimeTools([], {
model: "anthropic/claude-sonnet-4-6",
Expand Down
84 changes: 84 additions & 0 deletions src/agent/runtime/provider-tool-compat.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { describe, it } from "#veryfront/testing/bdd.ts";
import type { ToolDefinition } from "#veryfront/tool";
import {
getProviderToolProfile,
normalizeProviderToolInputSchema,
sanitizeProviderToolSchema,
selectProviderCompatibleToolNames,
selectProviderCompatibleTools,
Expand All @@ -26,6 +27,27 @@ function containsKey(value: unknown, key: string): boolean {
}

describe("provider-tool-compat", () => {
it("returns independent permissive fallback schemas", () => {
for (
const createFallback of [
() => normalizeProviderToolInputSchema(null as never),
() =>
sanitizeProviderToolSchema(null as never, {
model: "anthropic/claude-opus-4-6",
}),
]
) {
const first = createFallback();
(first.properties as Record<string, unknown>).injected = { type: "string" };

assertEquals(createFallback(), {
type: "object",
properties: {},
additionalProperties: true,
});
}
});

it("caps OpenAI-compatible tool names while preserving required tools first", () => {
const requiredToolNames = ["form_input", "invoke_agent", "load_skill", "sleep"];
const remoteToolNames = Array.from({ length: 150 }, (_, index) => `remote_${index}`);
Expand Down Expand Up @@ -328,4 +350,66 @@ describe("provider-tool-compat", () => {
["fine"],
);
});

it("removes every unsupported Anthropic root composition keyword", () => {
for (const keyword of ["allOf", "anyOf", "oneOf"] as const) {
const sanitized = sanitizeProviderToolSchema(
{
[keyword]: [
{
type: "object",
properties: { shared: { type: "string" } },
required: ["shared"],
},
{
type: "object",
properties: { extra: { type: "number" } },
required: ["extra"],
},
],
} as never,
{ model: "anthropic/claude-opus-4-6" },
);

assertEquals(sanitized.type, "object");
assertEquals(Object.hasOwn(sanitized, "allOf"), false);
assertEquals(Object.hasOwn(sanitized, "anyOf"), false);
assertEquals(Object.hasOwn(sanitized, "oneOf"), false);
assertEquals(Object.keys(sanitized.properties ?? {}), ["shared", "extra"]);
assertEquals(sanitized.required, keyword === "allOf" ? ["shared", "extra"] : undefined);
}
});

it("preserves local reference constraints when flattening Anthropic compositions", () => {
const sanitized = sanitizeProviderToolSchema(
{
anyOf: [
{
type: "object",
properties: { query: { type: "string" } },
required: ["query"],
},
{ $ref: "#/$defs/defaultQuery" },
],
$defs: {
defaultQuery: {
type: "object",
properties: { fallback: { type: "boolean" } },
required: ["fallback"],
},
},
} as never,
{ model: "anthropic/claude-opus-4-6" },
);

assertEquals(Object.keys(sanitized.properties ?? {}), ["query", "fallback"]);
assertEquals(sanitized.required, undefined);
assertEquals(sanitized.$defs, {
defaultQuery: {
type: "object",
properties: { fallback: { type: "boolean" } },
required: ["fallback"],
},
});
});
});
Loading