fix: correct anthropic beta header config for fine-grained tool streaming

- Use bedrock.anthropicBeta for Bedrock provider (not additionalModelRequestFields)
- Use top-level headers for direct Anthropic API
- Update @ai-sdk/amazon-bedrock to 3.0.62
- Add headers support to ModelConfig interface
This commit is contained in:
dayuan.jiang
2025-11-30 16:12:12 +09:00
parent 00af87edbe
commit de910bdf6c
3 changed files with 48 additions and 92 deletions

View File

@@ -120,13 +120,14 @@ ${lastMessageText}
console.log("Enhanced messages:", enhancedMessages); console.log("Enhanced messages:", enhancedMessages);
// Get AI model from environment configuration // Get AI model from environment configuration
const { model, providerOptions } = getAIModel(); const { model, providerOptions, headers } = getAIModel();
const result = streamText({ const result = streamText({
model, model,
system: systemMessage, system: systemMessage,
messages: enhancedMessages, messages: enhancedMessages,
...(providerOptions && { providerOptions }), ...(providerOptions && { providerOptions }),
...(headers && { headers }),
tools: { tools: {
// Client-side tool that will be executed on the client // Client-side tool that will be executed on the client
display_diagram: { display_diagram: {

View File

@@ -18,15 +18,19 @@ export type ProviderName =
interface ModelConfig { interface ModelConfig {
model: any; model: any;
providerOptions?: any; providerOptions?: any;
headers?: Record<string, string>;
} }
// Anthropic beta headers for fine-grained tool streaming // Bedrock provider options for Anthropic beta features
const ANTHROPIC_BETA_OPTIONS = { const BEDROCK_ANTHROPIC_BETA = {
anthropic: { bedrock: {
additionalModelRequestFields: { anthropicBeta: ['fine-grained-tool-streaming-2025-05-14'],
anthropic_beta: ['fine-grained-tool-streaming-2025-05-14'] },
} };
}
// Direct Anthropic API headers for beta features
const ANTHROPIC_BETA_HEADERS = {
'anthropic-beta': 'fine-grained-tool-streaming-2025-05-14',
}; };
/** /**
@@ -87,13 +91,14 @@ export function getAIModel(): ModelConfig {
let model: any; let model: any;
let providerOptions: any = undefined; let providerOptions: any = undefined;
let headers: Record<string, string> | undefined = undefined;
switch (provider) { switch (provider) {
case 'bedrock': case 'bedrock':
model = bedrock(modelId); model = bedrock(modelId);
// Add Anthropic beta headers if using Claude models via Bedrock // Add Anthropic beta options if using Claude models via Bedrock
if (modelId.includes('anthropic.claude')) { if (modelId.includes('anthropic.claude')) {
providerOptions = ANTHROPIC_BETA_OPTIONS; providerOptions = BEDROCK_ANTHROPIC_BETA;
} }
break; break;
@@ -112,7 +117,7 @@ export function getAIModel(): ModelConfig {
case 'anthropic': case 'anthropic':
model = anthropic(modelId); model = anthropic(modelId);
// Add beta headers for fine-grained tool streaming // Add beta headers for fine-grained tool streaming
providerOptions = ANTHROPIC_BETA_OPTIONS; headers = ANTHROPIC_BETA_HEADERS;
break; break;
case 'google': case 'google':
@@ -140,10 +145,10 @@ export function getAIModel(): ModelConfig {
); );
} }
// Log if provider options are being applied // Log if provider options or headers are being applied
if (providerOptions) { if (providerOptions || headers) {
console.log('[AI Provider] Applying provider-specific options'); console.log('[AI Provider] Applying provider-specific options/headers');
} }
return { model, providerOptions }; return { model, providerOptions, headers };
} }

104
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "next-ai-draw-io", "name": "next-ai-draw-io",
"version": "0.1.0", "version": "0.2.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "next-ai-draw-io", "name": "next-ai-draw-io",
"version": "0.1.0", "version": "0.2.0",
"dependencies": { "dependencies": {
"@ai-sdk/amazon-bedrock": "^3.0.52", "@ai-sdk/amazon-bedrock": "^3.0.52",
"@ai-sdk/anthropic": "^2.0.44", "@ai-sdk/anthropic": "^2.0.44",
@@ -50,14 +50,14 @@
} }
}, },
"node_modules/@ai-sdk/amazon-bedrock": { "node_modules/@ai-sdk/amazon-bedrock": {
"version": "3.0.53", "version": "3.0.62",
"resolved": "https://registry.npmjs.org/@ai-sdk/amazon-bedrock/-/amazon-bedrock-3.0.53.tgz", "resolved": "https://registry.npmjs.org/@ai-sdk/amazon-bedrock/-/amazon-bedrock-3.0.62.tgz",
"integrity": "sha512-HyVLZbdGunqJbdCK2v/jofo9Z4lDAbngO2X/T57K+4wPZtCeUnv0f9F941RgU6XVJwdxjxITX1XEhhBP1qqGnw==", "integrity": "sha512-vVtndaj5zfHmgw8NSqN4baFDbFDTBZP6qufhKfqSNLtygEm8+8PL9XQX9urgzSzU3zp+zi3AmNNemvKLkkqblg==",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@ai-sdk/anthropic": "2.0.43", "@ai-sdk/anthropic": "2.0.50",
"@ai-sdk/provider": "2.0.0", "@ai-sdk/provider": "2.0.0",
"@ai-sdk/provider-utils": "3.0.16", "@ai-sdk/provider-utils": "3.0.18",
"@smithy/eventstream-codec": "^4.0.1", "@smithy/eventstream-codec": "^4.0.1",
"@smithy/util-utf8": "^4.0.0", "@smithy/util-utf8": "^4.0.0",
"aws4fetch": "^1.0.20" "aws4fetch": "^1.0.20"
@@ -69,47 +69,14 @@
"zod": "^3.25.76 || ^4.1.8" "zod": "^3.25.76 || ^4.1.8"
} }
}, },
"node_modules/@ai-sdk/amazon-bedrock/node_modules/@ai-sdk/anthropic": {
"version": "2.0.43",
"resolved": "https://registry.npmjs.org/@ai-sdk/anthropic/-/anthropic-2.0.43.tgz",
"integrity": "sha512-YQWYdoU6X1E16BS/KYCkage18q8sqj3FguCZ/RQs/wxS1551DVeD5DrWiYXxm5T293HzeAVJssQFEx67kc4LmA==",
"license": "Apache-2.0",
"dependencies": {
"@ai-sdk/provider": "2.0.0",
"@ai-sdk/provider-utils": "3.0.16"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"zod": "^3.25.76 || ^4.1.8"
}
},
"node_modules/@ai-sdk/anthropic": { "node_modules/@ai-sdk/anthropic": {
"version": "2.0.44", "version": "2.0.50",
"resolved": "https://registry.npmjs.org/@ai-sdk/anthropic/-/anthropic-2.0.44.tgz", "resolved": "https://registry.npmjs.org/@ai-sdk/anthropic/-/anthropic-2.0.50.tgz",
"integrity": "sha512-o8TfNXRzO/KZkBrcx+CL9LQsPhx7PHyqzUGjza3TJaF9WxfH1S5UQLAmEw8F7lQoHNLU0IX03WT8o8R/4JbUxQ==", "integrity": "sha512-21PaHfoLmouOXXNINTsZJsMw+wE5oLR2He/1kq/sKokTVKyq7ObGT1LDk6ahwxaz/GoaNaGankMh+EgVcdv2Cw==",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@ai-sdk/provider": "2.0.0", "@ai-sdk/provider": "2.0.0",
"@ai-sdk/provider-utils": "3.0.17" "@ai-sdk/provider-utils": "3.0.18"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"zod": "^3.25.76 || ^4.1.8"
}
},
"node_modules/@ai-sdk/anthropic/node_modules/@ai-sdk/provider-utils": {
"version": "3.0.17",
"resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-3.0.17.tgz",
"integrity": "sha512-TR3Gs4I3Tym4Ll+EPdzRdvo/rc8Js6c4nVhFLuvGLX/Y4V9ZcQMa/HTiYsHEgmYrf1zVi6Q145UEZUfleOwOjw==",
"license": "Apache-2.0",
"dependencies": {
"@ai-sdk/provider": "2.0.0",
"@standard-schema/spec": "^1.0.0",
"eventsource-parser": "^3.0.6"
}, },
"engines": { "engines": {
"node": ">=18" "node": ">=18"
@@ -153,14 +120,14 @@
} }
}, },
"node_modules/@ai-sdk/gateway": { "node_modules/@ai-sdk/gateway": {
"version": "2.0.7", "version": "2.0.17",
"resolved": "https://registry.npmjs.org/@ai-sdk/gateway/-/gateway-2.0.7.tgz", "resolved": "https://registry.npmjs.org/@ai-sdk/gateway/-/gateway-2.0.17.tgz",
"integrity": "sha512-/AI5AKi4vOK9SEb8Z1dfXkhsJ5NAfWsoJQc96B/mzn2KIrjw5occOjIwD06scuhV9xWlghCoXJT1sQD9QH/tyg==", "integrity": "sha512-oVAG6q72KsjKlrYdLhWjRO7rcqAR8CjokAbYuyVZoCO4Uh2PH/VzZoxZav71w2ipwlXhHCNaInGYWNs889MMDA==",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@ai-sdk/provider": "2.0.0", "@ai-sdk/provider": "2.0.0",
"@ai-sdk/provider-utils": "3.0.16", "@ai-sdk/provider-utils": "3.0.18",
"@vercel/oidc": "3.0.3" "@vercel/oidc": "3.0.5"
}, },
"engines": { "engines": {
"node": ">=18" "node": ">=18"
@@ -258,9 +225,9 @@
} }
}, },
"node_modules/@ai-sdk/provider-utils": { "node_modules/@ai-sdk/provider-utils": {
"version": "3.0.16", "version": "3.0.18",
"resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-3.0.16.tgz", "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-3.0.18.tgz",
"integrity": "sha512-lsWQY9aDXHitw7C1QRYIbVGmgwyT98TF3MfM8alNIXKpdJdi+W782Rzd9f1RyOfgRmZ08gJ2EYNDhWNK7RqpEA==", "integrity": "sha512-ypv1xXMsgGcNKUP+hglKqtdDuMg68nWHucPPAhIENrbFAI+xCHiqPVN8Zllxyv1TNZwGWUghPxJXU+Mqps0YRQ==",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@ai-sdk/provider": "2.0.0", "@ai-sdk/provider": "2.0.0",
@@ -2123,9 +2090,9 @@
} }
}, },
"node_modules/@vercel/oidc": { "node_modules/@vercel/oidc": {
"version": "3.0.3", "version": "3.0.5",
"resolved": "https://registry.npmjs.org/@vercel/oidc/-/oidc-3.0.3.tgz", "resolved": "https://registry.npmjs.org/@vercel/oidc/-/oidc-3.0.5.tgz",
"integrity": "sha512-yNEQvPcVrK9sIe637+I0jD6leluPxzwJKx/Haw6F4H77CdDsszUn5V3o96LPziXkSNE2B83+Z3mjqGKBK/R6Gg==", "integrity": "sha512-fnYhv671l+eTTp48gB4zEsTW/YtRgRPnkI2nT7x6qw5rkI1Lq2hTmQIpHPgyThI0znLK+vX2n9XxKdXZ7BUbbw==",
"license": "Apache-2.0", "license": "Apache-2.0",
"engines": { "engines": {
"node": ">= 20" "node": ">= 20"
@@ -2150,14 +2117,14 @@
} }
}, },
"node_modules/ai": { "node_modules/ai": {
"version": "5.0.90", "version": "5.0.104",
"resolved": "https://registry.npmjs.org/ai/-/ai-5.0.90.tgz", "resolved": "https://registry.npmjs.org/ai/-/ai-5.0.104.tgz",
"integrity": "sha512-bawNN10N2cXzFedbDdNUZo8KkcGp12VX1b+mCL5dfllh6WmLsIYYME7GVxsRJvHvPP7xRhuds5fn0jtLyxGnZw==", "integrity": "sha512-MZOkL9++nY5PfkpWKBR3Rv+Oygxpb9S16ctv8h91GvrSif7UnNEdPMVZe3bUyMd2djxf0AtBk/csBixP0WwWZQ==",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@ai-sdk/gateway": "2.0.7", "@ai-sdk/gateway": "2.0.17",
"@ai-sdk/provider": "2.0.0", "@ai-sdk/provider": "2.0.0",
"@ai-sdk/provider-utils": "3.0.16", "@ai-sdk/provider-utils": "3.0.18",
"@opentelemetry/api": "1.9.0" "@opentelemetry/api": "1.9.0"
}, },
"engines": { "engines": {
@@ -4026,23 +3993,6 @@
"zod": "^4.0.16" "zod": "^4.0.16"
} }
}, },
"node_modules/ollama-ai-provider-v2/node_modules/@ai-sdk/provider-utils": {
"version": "3.0.17",
"resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-3.0.17.tgz",
"integrity": "sha512-TR3Gs4I3Tym4Ll+EPdzRdvo/rc8Js6c4nVhFLuvGLX/Y4V9ZcQMa/HTiYsHEgmYrf1zVi6Q145UEZUfleOwOjw==",
"license": "Apache-2.0",
"dependencies": {
"@ai-sdk/provider": "2.0.0",
"@standard-schema/spec": "^1.0.0",
"eventsource-parser": "^3.0.6"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"zod": "^3.25.76 || ^4.1.8"
}
},
"node_modules/pako": { "node_modules/pako": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",