diff --git a/.changeset/olive-colts-sparkle.md b/.changeset/olive-colts-sparkle.md new file mode 100644 index 000000000000..6d7aa2a42ed1 --- /dev/null +++ b/.changeset/olive-colts-sparkle.md @@ -0,0 +1,5 @@ +--- +"@ai-sdk/amazon-bedrock": patch +--- + +feat(bedrock): support native structured output for anthropic models without reasoning diff --git a/packages/amazon-bedrock/src/bedrock-chat-language-model.test.ts b/packages/amazon-bedrock/src/bedrock-chat-language-model.test.ts index 099be70c012c..703c329ec018 100644 --- a/packages/amazon-bedrock/src/bedrock-chat-language-model.test.ts +++ b/packages/amazon-bedrock/src/bedrock-chat-language-model.test.ts @@ -4580,6 +4580,65 @@ describe('doGenerate', () => { expect(result.providerMetadata?.bedrock?.isJsonResponseFromTool).toBe(true); }); + it('should use native output_config.format for models with structured output support even without thinking enabled', async () => { + server.urls[newerAnthropicGenerateUrl].response = { + type: 'json-value', + body: { + output: { + message: { + content: [{ text: '{"name":"Test"}' }], + role: 'assistant', + }, + }, + usage: { inputTokens: 4, outputTokens: 10, totalTokens: 14 }, + stopReason: 'end_turn', + }, + }; + + await newerAnthropicModel.doGenerate({ + prompt: [ + { + role: 'user', + content: [{ type: 'text', text: 'Generate a name' }], + }, + ], + responseFormat: { + type: 'json', + schema: { + type: 'object', + properties: { + name: { type: 'string' }, + }, + required: ['name'], + }, + }, + }); + + const requestBody = await server.calls[0].requestBodyJson; + + expect(requestBody.toolConfig).toBeUndefined(); + + expect(requestBody.additionalModelRequestFields?.output_config) + .toMatchInlineSnapshot(` + { + "format": { + "schema": { + "properties": { + "name": { + "type": "string", + }, + }, + "required": [ + "name", + ], + "type": "object", + }, + "type": "json_schema", + }, + } + `); + }); + it('should extract reasoning text with signature', async () => { server.urls[generateUrl].response = { type: 'json-value', diff --git a/packages/amazon-bedrock/src/bedrock-chat-language-model.ts b/packages/amazon-bedrock/src/bedrock-chat-language-model.ts index 2c752d2645ee..bdadde8dd858 100644 --- a/packages/amazon-bedrock/src/bedrock-chat-language-model.ts +++ b/packages/amazon-bedrock/src/bedrock-chat-language-model.ts @@ -157,9 +157,12 @@ export class BedrockChatLanguageModel implements LanguageModelV4 { bedrockOptions.reasoningConfig?.type === 'enabled' || bedrockOptions.reasoningConfig?.type === 'adaptive'; + const { supportsStructuredOutput: modelSupportsStructuredOutput } = + getModelCapabilities(this.modelId); + const useNativeStructuredOutput = isAnthropicModel && - isThinkingEnabled && + (modelSupportsStructuredOutput || isThinkingEnabled) && responseFormat?.type === 'json' && responseFormat.schema != null;