This commit is contained in:
2026-07-26 14:02:37 +07:00
parent bc56546b49
commit 367ebc1c7f
171 changed files with 4617 additions and 10402 deletions
@@ -32,6 +32,17 @@ const tool: Tool = {
parameters: Type.Object({ value: Type.String() }),
};
const schemaCompatibilityTool: Tool = {
...tool,
parameters: Type.Object({ value: Type.String() }, { additionalProperties: false, title: "LookupInput" }),
};
const strictTool: Tool = {
...tool,
parameters: Type.Object({ value: Type.String() }, { additionalProperties: false, title: "StrictLookupInput" }),
constrainedSampling: { type: "json_schema", strict: "prefer" },
};
function createContext(tools: Tool[] = [tool]): Context {
return {
messages: [{ role: "user", content: "Use the tool", timestamp: Date.now() }],
@@ -98,6 +109,14 @@ function getFirstTool(body: Record<string, unknown>): Record<string, unknown> {
return tools[0] as Record<string, unknown>;
}
function getFirstToolInputSchema(body: Record<string, unknown>): Record<string, unknown> {
const inputSchema = getFirstTool(body).input_schema;
if (typeof inputSchema !== "object" || inputSchema === null || Array.isArray(inputSchema)) {
throw new Error("Expected first tool input schema in request body");
}
return inputSchema as Record<string, unknown>;
}
describe("Anthropic eager tool input streaming compatibility", () => {
it("sends per-tool eager_input_streaming by default", async () => {
const request = await captureAnthropicRequest(undefined, createContext());
@@ -119,4 +138,24 @@ describe("Anthropic eager tool input streaming compatibility", () => {
expect(request.body.tools).toBeUndefined();
expect(request.headers["anthropic-beta"]).toBeUndefined();
});
it("only sends the full input schema for strict JSON-schema tools", async () => {
const legacyRequest = await captureAnthropicRequest(
{ supportsStrictTools: true },
createContext([schemaCompatibilityTool]),
);
const parameters = schemaCompatibilityTool.parameters as { properties?: unknown; required?: unknown };
expect(getFirstToolInputSchema(legacyRequest.body)).toEqual({
type: "object",
properties: parameters.properties,
required: parameters.required,
});
const strictRequest = await captureAnthropicRequest({ supportsStrictTools: true }, createContext([strictTool]));
expect(getFirstTool(strictRequest.body).strict).toBe(true);
expect(getFirstToolInputSchema(strictRequest.body)).toMatchObject({
additionalProperties: false,
title: "StrictLookupInput",
});
});
});