Skip to content

Commit b0b85cb

Browse files
authored
fix(ai): omit empty Bedrock tool descriptions (#48582)
1 parent 0f26ad8 commit b0b85cb

2 files changed

Lines changed: 48 additions & 2 deletions

File tree

‎packages/ai/src/protocols/bedrock-converse.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ type BedrockSystemBlock = Schema.Schema.Type<typeof BedrockSystemBlock>
106106
const BedrockToolSpec = Schema.Struct({
107107
toolSpec: Schema.Struct({
108108
name: Schema.String,
109-
description: Schema.String,
109+
description: Schema.optional(Schema.String),
110110
inputSchema: Schema.Struct({
111111
json: JsonObject,
112112
}),
@@ -222,7 +222,7 @@ type BedrockEvent = Schema.Schema.Type<typeof BedrockEvent>
222222
const lowerToolSpec = (tool: ToolDefinition, inputSchema: JsonSchema): BedrockToolSpec => ({
223223
toolSpec: {
224224
name: tool.name,
225-
description: tool.description,
225+
...(tool.description.trim().length > 0 ? { description: tool.description } : {}),
226226
inputSchema: { json: inputSchema },
227227
},
228228
})

‎packages/ai/test/provider/bedrock-converse.test.ts‎

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,52 @@ describe("Bedrock Converse route", () => {
279279
})
280280
}),
281281
)
282+
;["", " \t\r\n"].forEach((description) => {
283+
it.effect(`omits blank tool description ${JSON.stringify(description)}`, () =>
284+
Effect.gen(function* () {
285+
const prepared = yield* compileRequest(
286+
LLMRequest.update(baseRequest, {
287+
tools: [
288+
ToolDefinition.make({
289+
name: "lookup",
290+
description,
291+
inputSchema: { type: "object", properties: { query: { type: "string" } } },
292+
}),
293+
],
294+
}),
295+
)
296+
297+
expect(prepared.body.toolConfig.tools).toEqual([
298+
{
299+
toolSpec: {
300+
name: "lookup",
301+
inputSchema: { json: { type: "object", properties: { query: { type: "string" } } } },
302+
},
303+
},
304+
])
305+
expect(prepared.body.toolConfig.tools[0].toolSpec).not.toHaveProperty("description")
306+
}),
307+
)
308+
})
309+
310+
it.effect("preserves meaningful tool descriptions including surrounding whitespace", () =>
311+
Effect.gen(function* () {
312+
const description = " \tLookup data.\n"
313+
const prepared = yield* compileRequest(
314+
LLMRequest.update(baseRequest, {
315+
tools: [
316+
ToolDefinition.make({
317+
name: "lookup",
318+
description,
319+
inputSchema: { type: "object" },
320+
}),
321+
],
322+
}),
323+
)
324+
325+
expect(prepared.body.toolConfig.tools[0].toolSpec.description).toBe(description)
326+
}),
327+
)
282328

283329
it.effect("keeps tools and omits the unsupported choice when tool choice is none", () =>
284330
Effect.gen(function* () {

0 commit comments

Comments
 (0)