fix: strip strict parameter from tools in Bedrock XML-based tool calling

- Fix convertToolsForBedrock to strip the strict parameter which Bedrock does not support
- Add Mistral models (mistral-large-3-675b-instruct and magistral-small-2509) to bedrockModels
- Add test coverage for strict parameter stripping

Fixes #9913
This commit is contained in:
Roo Code 2025-12-11 02:36:09 +00:00
parent 483e70c47b
commit 4b2116c7f9
3 changed files with 129 additions and 11 deletions

View file

@ -485,6 +485,26 @@ export const bedrockModels = {
outputPrice: 1.8,
description: "Qwen3 Coder 480B (MoE model with 35B active parameters)",
},
"mistral.mistral-large-3-675b-instruct": {
maxTokens: 8192,
contextWindow: 128_000,
supportsImages: true,
supportsPromptCache: false,
supportsNativeTools: false,
inputPrice: 0.5,
outputPrice: 1.5,
description: "Mistral Large 3 (675B)",
},
"mistral.magistral-small-2509": {
maxTokens: 8192,
contextWindow: 128_000,
supportsImages: true,
supportsPromptCache: false,
supportsNativeTools: false,
inputPrice: 0.5,
outputPrice: 1.5,
description: "Magistral Small 1.2",
},
} as const satisfies Record<string, ModelInfo>
export const BEDROCK_DEFAULT_TEMPERATURE = 0.3

View file

@ -755,4 +755,101 @@ describe("AwsBedrockHandler", () => {
expect(commandArg.modelId).toBe(`us.${BEDROCK_1M_CONTEXT_MODEL_IDS[0]}`)
})
})
describe("native tools", () => {
it("should strip the strict parameter from tool functions when converting to Bedrock format", () => {
const handler = new AwsBedrockHandler({
apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0",
awsAccessKey: "test",
awsSecretKey: "test",
awsRegion: "us-east-1",
})
// Access private method using type casting
const convertToolsForBedrock = (handler as any).convertToolsForBedrock.bind(handler)
// Create tools with strict parameter (which Bedrock doesn't support)
const tools = [
{
type: "function" as const,
function: {
name: "test_tool",
description: "A test tool",
parameters: {
type: "object",
properties: {
param1: { type: "string" },
},
required: ["param1"],
},
strict: false, // This parameter should be stripped
},
},
]
const convertedTools = convertToolsForBedrock(tools)
// Verify the tool was converted correctly
expect(convertedTools).toHaveLength(1)
expect(convertedTools[0].toolSpec.name).toBe("test_tool")
expect(convertedTools[0].toolSpec.description).toBe("A test tool")
expect(convertedTools[0].toolSpec.inputSchema.json).toEqual({
type: "object",
properties: {
param1: { type: "string" },
},
required: ["param1"],
})
// Verify that the strict parameter was not included in the converted tool
// The toolSpec should not have any 'strict' property
expect(convertedTools[0].toolSpec).not.toHaveProperty("strict")
expect(convertedTools[0]).not.toHaveProperty("strict")
})
it("should handle tools without strict parameter correctly", () => {
const handler = new AwsBedrockHandler({
apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0",
awsAccessKey: "test",
awsSecretKey: "test",
awsRegion: "us-east-1",
})
// Access private method using type casting
const convertToolsForBedrock = (handler as any).convertToolsForBedrock.bind(handler)
// Create tools without strict parameter
const tools = [
{
type: "function" as const,
function: {
name: "test_tool",
description: "A test tool",
parameters: {
type: "object",
properties: {
param1: { type: "string" },
},
required: ["param1"],
},
// No strict parameter here
},
},
]
const convertedTools = convertToolsForBedrock(tools)
// Verify the tool was converted correctly
expect(convertedTools).toHaveLength(1)
expect(convertedTools[0].toolSpec.name).toBe("test_tool")
expect(convertedTools[0].toolSpec.description).toBe("A test tool")
expect(convertedTools[0].toolSpec.inputSchema.json).toEqual({
type: "object",
properties: {
param1: { type: "string" },
},
required: ["param1"],
})
})
})
})

View file

@ -1150,18 +1150,19 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH
private convertToolsForBedrock(tools: OpenAI.Chat.ChatCompletionTool[]): Tool[] {
return tools
.filter((tool) => tool.type === "function")
.map(
(tool) =>
({
toolSpec: {
name: tool.function.name,
description: tool.function.description,
inputSchema: {
json: tool.function.parameters as Record<string, unknown>,
},
.map((tool) => {
// Destructure to exclude 'strict' property which Bedrock doesn't support
const { strict: _strict, ...functionWithoutStrict } = tool.function as any
return {
toolSpec: {
name: functionWithoutStrict.name,
description: functionWithoutStrict.description,
inputSchema: {
json: functionWithoutStrict.parameters as Record<string, unknown>,
},
}) as Tool,
)
},
} as Tool
})
}
/**