@happyvertical/ai 0.103.1 → 0.103.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +71 -0
- package/dist/chunks/{anthropic-CdbK9Jl-.js → anthropic-DhNGsQpl.js} +3 -3
- package/dist/chunks/{anthropic-CdbK9Jl-.js.map → anthropic-DhNGsQpl.js.map} +1 -1
- package/dist/chunks/{bedrock-DNkxz3ow.js → bedrock-CrtUO8yx.js} +3 -3
- package/dist/chunks/{bedrock-DNkxz3ow.js.map → bedrock-CrtUO8yx.js.map} +1 -1
- package/dist/chunks/{bifrost-DmbaXObX.js → bifrost-DZxTeE1Q.js} +4 -4
- package/dist/chunks/{bifrost-DmbaXObX.js.map → bifrost-DZxTeE1Q.js.map} +1 -1
- package/dist/chunks/{byteplus-modelark-BAi0y9SK.js → byteplus-modelark-gG941oea.js} +3 -3
- package/dist/chunks/{byteplus-modelark-BAi0y9SK.js.map → byteplus-modelark-gG941oea.js.map} +1 -1
- package/dist/chunks/{claude-cli-C40pIzrp.js → claude-cli-CW_gIocm.js} +3 -3
- package/dist/chunks/{claude-cli-C40pIzrp.js.map → claude-cli-CW_gIocm.js.map} +1 -1
- package/dist/chunks/{continuation-L5KnnE9R.js → continuation-KdrnmvzP.js} +2 -2
- package/dist/chunks/{continuation-L5KnnE9R.js.map → continuation-KdrnmvzP.js.map} +1 -1
- package/dist/chunks/{gateway-audio-models-B1tGNv1H.js → gateway-audio-models-DuXbi_2q.js} +2 -2
- package/dist/chunks/{gateway-audio-models-B1tGNv1H.js.map → gateway-audio-models-DuXbi_2q.js.map} +1 -1
- package/dist/chunks/{gemini-C-r6c4N9.js → gemini-DCo6d-n1.js} +3 -3
- package/dist/chunks/{gemini-C-r6c4N9.js.map → gemini-DCo6d-n1.js.map} +1 -1
- package/dist/chunks/{huggingface-DtuYF1vb.js → huggingface-jqjeFPdr.js} +3 -3
- package/dist/chunks/{huggingface-DtuYF1vb.js.map → huggingface-jqjeFPdr.js.map} +1 -1
- package/dist/chunks/{laya-D-P82D0h.js → laya-D8o5TEO7.js} +3 -3
- package/dist/chunks/{laya-D-P82D0h.js.map → laya-D8o5TEO7.js.map} +1 -1
- package/dist/chunks/{litellm-BaGgWzHR.js → litellm-8k7PMuh_.js} +4 -4
- package/dist/chunks/{litellm-BaGgWzHR.js.map → litellm-8k7PMuh_.js.map} +1 -1
- package/dist/chunks/{ollama-C3T3mn68.js → ollama-DHbYj2lH.js} +4 -4
- package/dist/chunks/{ollama-C3T3mn68.js.map → ollama-DHbYj2lH.js.map} +1 -1
- package/dist/chunks/{openai-compat-video-CwFsKAxR.js → openai-compat-video-ByTC2nzb.js} +3 -3
- package/dist/chunks/{openai-compat-video-CwFsKAxR.js.map → openai-compat-video-ByTC2nzb.js.map} +1 -1
- package/dist/chunks/{qwen-tts-DqMxfA54.js → qwen-tts-CWdO07D_.js} +2 -2
- package/dist/chunks/{qwen-tts-DqMxfA54.js.map → qwen-tts-CWdO07D_.js.map} +1 -1
- package/dist/chunks/{rate-limit-BkK4-hXY.js → rate-limit-Dwyde1BY.js} +2 -2
- package/dist/chunks/{rate-limit-BkK4-hXY.js.map → rate-limit-Dwyde1BY.js.map} +1 -1
- package/dist/chunks/{seevio-EzC6eKz-.js → seevio-B9V2nZtr.js} +3 -3
- package/dist/chunks/{seevio-EzC6eKz-.js.map → seevio-B9V2nZtr.js.map} +1 -1
- package/dist/chunks/{src-Cc5yFnnQ.js → src-BnMUshQt.js} +462 -20
- package/dist/chunks/src-BnMUshQt.js.map +1 -0
- package/dist/chunks/{typesafe-D7ZmI9-n.js → typesafe-B1_jGusy.js} +3 -3
- package/dist/chunks/{typesafe-D7ZmI9-n.js.map → typesafe-B1_jGusy.js.map} +1 -1
- package/dist/chunks/{usage-B9gPCWSa.js → usage-DS7uDhi1.js} +2 -1
- package/dist/chunks/usage-DS7uDhi1.js.map +1 -0
- package/dist/chunks/{webllm-DT31sqUY.js → webllm-DVDsgVT7.js} +2 -2
- package/dist/chunks/{webllm-DT31sqUY.js.map → webllm-DVDsgVT7.js.map} +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/local.js +2 -2
- package/dist/node.js +4 -4
- package/dist/shared/factory.d.ts.map +1 -1
- package/dist/shared/providers/chatgpt-plan.d.ts +60 -0
- package/dist/shared/providers/chatgpt-plan.d.ts.map +1 -0
- package/dist/shared/types.d.ts +28 -2
- package/dist/shared/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/chunks/src-Cc5yFnnQ.js.map +0 -1
- package/dist/chunks/usage-B9gPCWSa.js.map +0 -1
package/README.md
CHANGED
|
@@ -45,6 +45,22 @@ for await (const chunk of ai.stream([
|
|
|
45
45
|
// OpenAI (default when type is omitted)
|
|
46
46
|
const openai = await getAI({ apiKey: 'sk-...' });
|
|
47
47
|
|
|
48
|
+
// ChatGPT plan usage for an explicitly authorized local OSS app.
|
|
49
|
+
// LocalChatGPTSessionManager owns refreshable credentials; this provider asks
|
|
50
|
+
// it for a usable access token immediately before each request.
|
|
51
|
+
import { LocalChatGPTSessionManager } from '@happyvertical/auth/local';
|
|
52
|
+
|
|
53
|
+
const sessions = new LocalChatGPTSessionManager({
|
|
54
|
+
appName: 'my-local-app',
|
|
55
|
+
path: '/user/config/my-local-app/chatgpt.json',
|
|
56
|
+
});
|
|
57
|
+
const chatgpt = await getAI({
|
|
58
|
+
type: 'chatgpt-plan',
|
|
59
|
+
clientId: selectedAccount.clientId,
|
|
60
|
+
sessionManager: sessions,
|
|
61
|
+
defaultModel: selectedModel.slug,
|
|
62
|
+
});
|
|
63
|
+
|
|
48
64
|
// LiteLLM (OpenAI-compatible gateway)
|
|
49
65
|
const litellm = await getAI({
|
|
50
66
|
type: 'litellm',
|
|
@@ -149,6 +165,61 @@ const laya = await getAI({
|
|
|
149
165
|
const local = await getAI({ type: 'webllm', model: 'Llama-3.2-1B-Instruct-q4f16_1-MLC' });
|
|
150
166
|
```
|
|
151
167
|
|
|
168
|
+
## ChatGPT plan usage
|
|
169
|
+
|
|
170
|
+
`type: 'chatgpt-plan'` is a separate, explicit provider for local open-source
|
|
171
|
+
apps using [Sign in with ChatGPT plan usage](https://developers.openai.com/siwc/token-sharing-open-source).
|
|
172
|
+
It does not use an OpenAI API key and is never selected automatically or used
|
|
173
|
+
as a fallback. Pass the selected registration's `clientId` and a protected
|
|
174
|
+
`sessionManager` compatible with `LocalChatGPTSessionManager` from
|
|
175
|
+
`@happyvertical/auth/local`.
|
|
176
|
+
|
|
177
|
+
`getModels()` reads the selected account's current model catalog. Use a
|
|
178
|
+
returned model ID as `defaultModel` or the per-call `model`. Chat and stream
|
|
179
|
+
requests follow the preview's
|
|
180
|
+
[models and inference contract](https://developers.openai.com/siwc/token-sharing-open-source/models-and-inference):
|
|
181
|
+
they always call the public Responses API with `store: false`, `stream: true`,
|
|
182
|
+
and complete only after `response.completed`.
|
|
183
|
+
|
|
184
|
+
The provider rejects request options that the
|
|
185
|
+
[preview limitations](https://developers.openai.com/siwc/token-sharing-open-source/preview-limitations)
|
|
186
|
+
do not allow, including `maxTokens`, `temperature`, `topP`, `user`, hosted
|
|
187
|
+
tools, and prior-response state. System messages are sent as developer messages.
|
|
188
|
+
It supports text and image input; embeddings, hosted image generation, file
|
|
189
|
+
search, Code Interpreter, native computer use, hosted MCP/connectors, and audio
|
|
190
|
+
are unavailable on this provider.
|
|
191
|
+
|
|
192
|
+
Handle plan-specific failures without changing providers implicitly:
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
import {
|
|
196
|
+
ChatGPTPlanSessionRevokedError,
|
|
197
|
+
ChatGPTPlanUsageLimitError,
|
|
198
|
+
ChatGPTPlanUsageUnavailableError,
|
|
199
|
+
ChatGPTPlanWorkspaceError,
|
|
200
|
+
} from '@happyvertical/ai';
|
|
201
|
+
|
|
202
|
+
try {
|
|
203
|
+
await chatgpt.message('Draft the implementation plan.');
|
|
204
|
+
} catch (error) {
|
|
205
|
+
if (error instanceof ChatGPTPlanUsageLimitError) {
|
|
206
|
+
// Pause plan-backed requests and link to ChatGPT Settings → Usage.
|
|
207
|
+
} else if (error instanceof ChatGPTPlanWorkspaceError) {
|
|
208
|
+
// Explain the selected account/workspace restriction.
|
|
209
|
+
} else if (error instanceof ChatGPTPlanSessionRevokedError) {
|
|
210
|
+
// Ask the user to sign in again.
|
|
211
|
+
} else if (error instanceof ChatGPTPlanUsageUnavailableError) {
|
|
212
|
+
// Preserve the session and retry later with bounded backoff.
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
The provider preserves structured status, code, parameter, and request-ID
|
|
218
|
+
details where OpenAI supplies them. Bearer credentials are sent only in the
|
|
219
|
+
`Authorization` header and are redacted from provider-generated diagnostics.
|
|
220
|
+
Callers can still offer another configured provider, but must make that billing
|
|
221
|
+
choice explicit.
|
|
222
|
+
|
|
152
223
|
## In-Browser Chat
|
|
153
224
|
|
|
154
225
|
`type: 'webllm'` runs a chat model entirely on the visitor's GPU through
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { b as extractTextContent, f as AuthenticationError, g as ModelNotFoundError, l as prepareRequestControls, m as ContextLengthError, o as normalizeBaseAIOptions, s as normalizeChatOptions, t as emitUsage, u as AIError } from "./usage-
|
|
2
|
-
import { n as rateLimitErrorFrom } from "./rate-limit-
|
|
1
|
+
import { b as extractTextContent, f as AuthenticationError, g as ModelNotFoundError, l as prepareRequestControls, m as ContextLengthError, o as normalizeBaseAIOptions, s as normalizeChatOptions, t as emitUsage, u as AIError } from "./usage-DS7uDhi1.js";
|
|
2
|
+
import { n as rateLimitErrorFrom } from "./rate-limit-Dwyde1BY.js";
|
|
3
3
|
import { r as parseToolArguments } from "./tool-messages-0ND35mYX.js";
|
|
4
4
|
//#region src/shared/providers/anthropic.ts
|
|
5
5
|
/**
|
|
@@ -604,4 +604,4 @@ function extractThinkingBlocks(content) {
|
|
|
604
604
|
//#endregion
|
|
605
605
|
export { AnthropicProvider };
|
|
606
606
|
|
|
607
|
-
//# sourceMappingURL=anthropic-
|
|
607
|
+
//# sourceMappingURL=anthropic-DhNGsQpl.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic-CdbK9Jl-.js","names":[],"sources":["../../src/shared/providers/anthropic.ts"],"sourcesContent":["/**\n * Anthropic Claude provider implementation\n *\n * Provides a standardized interface for interacting with Anthropic's Claude models,\n * including chat completions, streaming responses, and vision capabilities.\n * Note: Claude models do not support embeddings - use OpenAI or another provider for that.\n */\n\nimport { rateLimitErrorFrom } from '../rate-limit';\nimport {\n normalizeBaseAIOptions,\n normalizeChatOptions,\n type PreparedRequestControls,\n prepareRequestControls,\n} from '../safety';\nimport { parseToolArguments } from '../tool-messages';\nimport type {\n AICapabilities,\n AIInterface,\n AIMessage,\n AIModel,\n AIResponse,\n AIThinkingBlock,\n AIToolCall,\n AnthropicOptions,\n ChatOptions,\n CompletionOptions,\n EmbeddingOptions,\n EmbeddingResponse,\n ImageDescriptionOptions,\n ImageEmbeddingOptions,\n ImageGenerationOptions,\n ImageGenerationResponse,\n MessageOptions,\n TokenUsage,\n TTSOptions,\n TTSResponse,\n VideoGenerationJob,\n VideoGenerationOptions,\n VideoGenerationResult,\n VideoGenerationStatusResult,\n Voice,\n VoiceCloneOptions,\n VoiceDesignOptions,\n VoiceListOptions,\n} from '../types';\nimport {\n AIError,\n AuthenticationError,\n ContextLengthError,\n extractTextContent,\n ModelNotFoundError,\n} from '../types';\nimport { emitUsage } from './usage';\n\ntype AnthropicContentBlock =\n | AIThinkingBlock\n | { type: 'text'; text: string }\n | {\n type: 'tool_use';\n id: string;\n name: string;\n input: Record<string, unknown>;\n }\n | { type: 'tool_result'; tool_use_id: string; content: string };\n\ninterface AnthropicMessage {\n role: 'user' | 'assistant';\n content: string | AnthropicContentBlock[];\n}\n\n// Note: This implementation will require @anthropic-ai/sdk package\n// For now, this is a placeholder that defines the interface\n\n/**\n * Anthropic Claude provider implementation that handles all interactions with Anthropic's API.\n * Supports Claude models, streaming, vision capabilities, and function calling.\n * Does not support embeddings (use OpenAI or another provider for embeddings).\n */\nexport class AnthropicProvider implements AIInterface {\n private options: AnthropicOptions;\n private client: any; // Will be Anthropic instance from @anthropic-ai/sdk\n\n /**\n * Creates a new Anthropic provider instance\n * @param options - Configuration options for the Anthropic provider\n */\n constructor(options: AnthropicOptions) {\n this.options = normalizeBaseAIOptions({\n defaultModel: 'claude-3-5-sonnet-20241022',\n anthropicVersion: '2023-06-01',\n ...options,\n });\n\n // Initialize Anthropic client\n this.initializeClientSync();\n }\n\n private initializeClientSync() {\n try {\n // Dynamic import in constructor - this will work if the package is installed\n import('@anthropic-ai/sdk')\n .then(({ Anthropic }) => {\n this.client = new Anthropic({\n apiKey: this.options.apiKey,\n baseURL: this.options.baseUrl,\n timeout: this.options.timeout,\n maxRetries: this.options.maxRetries,\n defaultHeaders: {\n 'anthropic-version': this.options.anthropicVersion,\n ...this.options.headers,\n },\n });\n })\n .catch(() => {\n // Client will be null and we'll handle it in methods\n });\n } catch (_error) {\n // Client will be null and we'll handle it in methods\n }\n }\n\n /**\n * Ensures the Anthropic client is initialized by dynamically importing the SDK\n * @throws {AIError} When the Anthropic SDK cannot be loaded\n * @private\n */\n private async ensureClient() {\n if (!this.client) {\n try {\n const { Anthropic } = await import('@anthropic-ai/sdk');\n this.client = new Anthropic({\n apiKey: this.options.apiKey,\n baseURL: this.options.baseUrl,\n timeout: this.options.timeout,\n maxRetries: this.options.maxRetries,\n defaultHeaders: {\n 'anthropic-version': this.options.anthropicVersion,\n ...this.options.headers,\n },\n });\n } catch (_error) {\n throw new AIError(\n 'Failed to initialize Anthropic client. Make sure @anthropic-ai/sdk is installed.',\n 'INITIALIZATION_ERROR',\n 'anthropic',\n );\n }\n }\n }\n\n /**\n * Generate a chat completion using Claude models\n * @param messages - Array of conversation messages\n * @param options - Optional configuration for the chat completion\n * @returns Promise resolving to the AI response with content and metadata\n * @throws {AIError} When the API request fails or SDK is not available\n *\n * @example\n * ```typescript\n * const response = await provider.chat([\n * { role: 'system', content: 'You are a helpful assistant.' },\n * { role: 'user', content: 'Explain quantum computing' }\n * ], {\n * model: 'claude-3-5-sonnet-20241022',\n * maxTokens: 1000\n * });\n * ```\n */\n async chat(\n messages: AIMessage[],\n options: ChatOptions = {},\n ): Promise<AIResponse> {\n const startTime = Date.now();\n let controls: PreparedRequestControls | undefined;\n try {\n await this.ensureClient();\n\n const { system, anthropicMessages } =\n this.mapMessagesToAnthropic(messages);\n\n const model = options.model || this.options.defaultModel;\n options = normalizeChatOptions(this.options, options, 'anthropic', model);\n controls = prepareRequestControls(this.options, options);\n\n // Build request parameters\n const requestParams: Record<string, any> = {\n model,\n messages: anthropicMessages,\n max_tokens: options.maxTokens,\n temperature: options.temperature,\n top_p: options.topP,\n stop_sequences: Array.isArray(options.stop)\n ? options.stop\n : options.stop\n ? [options.stop]\n : undefined,\n system: system || undefined,\n ...this.mapToolParams(options, anthropicMessages),\n stream: false,\n };\n const thinking = this.mapThinking(options, anthropicMessages);\n if (thinking) {\n requestParams.thinking = thinking;\n }\n\n // Add response format if specified\n if (options.responseFormat?.type === 'json_object') {\n const jsonInstruction =\n '\\n\\nIMPORTANT: You must respond with valid JSON only. Do not include any explanatory text outside the JSON object.';\n requestParams.system = requestParams.system\n ? requestParams.system + jsonInstruction\n : jsonInstruction.trim();\n }\n\n const response = await this.client.messages.create(requestParams, {\n signal: controls.signal,\n timeout: controls.timeout,\n });\n\n // Extract text content and tool calls from response\n const textContent = response.content\n .filter((block: any) => block.type === 'text')\n .map((block: any) => block.text)\n .join('');\n\n const toolCalls: AIToolCall[] = response.content\n .filter((block: any) => block.type === 'tool_use')\n .map((block: any) => ({\n id: block.id,\n type: 'function' as const,\n function: {\n name: block.name,\n arguments: JSON.stringify(block.input),\n },\n }));\n\n // Extended thinking: the replayed tool_use turn must start with these\n // blocks (signatures intact), so they ride on the first tool call.\n const thinkingBlocks = extractThinkingBlocks(response.content);\n if (toolCalls.length > 0 && thinkingBlocks.length > 0) {\n toolCalls[0].thinkingBlocks = thinkingBlocks;\n }\n\n const usage: TokenUsage = {\n promptTokens: response.usage.input_tokens,\n completionTokens: response.usage.output_tokens,\n totalTokens: response.usage.input_tokens + response.usage.output_tokens,\n };\n emitUsage(\n this.options,\n 'anthropic',\n 'chat',\n response.model || model,\n usage,\n startTime,\n options.usageTags,\n );\n\n return {\n content: textContent,\n model: response.model,\n finishReason: this.mapFinishReason(response.stop_reason),\n usage,\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n };\n } catch (error) {\n if (controls?.didTimeout()) {\n throw new AIError(\n `AI request timed out after ${controls.timeout}ms`,\n 'AI_TIMEOUT',\n 'anthropic',\n options.model,\n );\n }\n if (options.signal?.aborted) {\n throw new AIError(\n 'AI request aborted by caller',\n 'AI_ABORTED',\n 'anthropic',\n options.model,\n );\n }\n throw this.mapError(error);\n } finally {\n controls?.cleanup();\n }\n }\n\n async complete(\n prompt: string,\n options: CompletionOptions = {},\n ): Promise<AIResponse> {\n return this.chat([{ role: 'user', content: prompt }], {\n model: options.model,\n maxTokens: options.maxTokens,\n temperature: options.temperature,\n topP: options.topP,\n n: options.n,\n stop: options.stop,\n stream: options.stream,\n onProgress: options.onProgress,\n signal: options.signal,\n timeout: options.timeout,\n reasoning: options.reasoning,\n usageTags: options.usageTags,\n continueOnLength: options.continueOnLength,\n });\n }\n\n /**\n * Simple message interface for single-turn interactions with optional history\n *\n * @param text - The message text to send\n * @param options - Configuration options including history, model, etc.\n * @returns Promise resolving to the response content string\n *\n * @example\n * ```typescript\n * // Simple usage\n * const response = await provider.message('Hello!');\n *\n * // With history\n * const response = await provider.message('What was my question?', {\n * history: [\n * { role: 'user', content: 'What is 2+2?' },\n * { role: 'assistant', content: '4' }\n * ]\n * });\n * ```\n */\n async message(text: string, options: MessageOptions = {}): Promise<string> {\n // Build messages array from history + current message\n const messages: AIMessage[] = [\n ...(options.history || []),\n { role: options.role || 'user', content: text },\n ];\n\n const response = await this.chat(messages, {\n model: options.model,\n maxTokens: options.maxTokens,\n temperature: options.temperature,\n topP: options.topP,\n stop: options.stop,\n stream: options.stream,\n frequencyPenalty: options.frequencyPenalty,\n presencePenalty: options.presencePenalty,\n responseFormat: options.responseFormat,\n seed: options.seed,\n tools: options.tools,\n toolChoice: options.toolChoice,\n onProgress: options.onProgress,\n signal: options.signal,\n timeout: options.timeout,\n reasoning: options.reasoning,\n usageTags: options.usageTags,\n continueOnLength: options.continueOnLength,\n });\n\n return response.content;\n }\n\n async embed(\n _text: string | string[],\n _options: EmbeddingOptions = {},\n ): Promise<EmbeddingResponse> {\n // Anthropic Claude doesn't provide embeddings API\n throw new AIError(\n 'Anthropic Claude does not support embeddings. Use OpenAI or another provider for embeddings.',\n 'NOT_SUPPORTED',\n 'anthropic',\n );\n }\n\n async embedImage(\n _image: string | Buffer,\n _options: ImageEmbeddingOptions = {},\n ): Promise<EmbeddingResponse> {\n throw new AIError(\n 'Anthropic Claude does not support image embeddings. Use OpenAI or Gemini.',\n 'NOT_SUPPORTED',\n 'anthropic',\n );\n }\n\n async describeImage(\n _image: string | Buffer,\n _prompt?: string,\n _options: ImageDescriptionOptions = {},\n ): Promise<string> {\n // Note: Claude does support vision, but we're keeping this as a stub for now\n // A full implementation could use the chat API with image content\n throw new AIError(\n 'Image description is not yet implemented for Anthropic. Use OpenAI or Gemini.',\n 'NOT_IMPLEMENTED',\n 'anthropic',\n );\n }\n\n async generateImage(\n _prompt: string,\n _options: ImageGenerationOptions = {},\n ): Promise<ImageGenerationResponse> {\n throw new AIError(\n 'Anthropic Claude does not support image generation. Use OpenAI or Gemini.',\n 'NOT_SUPPORTED',\n 'anthropic',\n );\n }\n\n /**\n * Streams a chat completion as text chunks.\n *\n * Streams yield text only and never surface tool calls, so `options.tools`\n * and `options.toolChoice` are ignored: tools are declared only when the\n * replayed history contains `tool_use` blocks (Anthropic requires it), with\n * `tool_choice: { type: 'none' }`. Use `chat()` for rounds that may call\n * tools.\n */\n async *stream(\n messages: AIMessage[],\n options: ChatOptions = {},\n ): AsyncIterable<string> {\n const startTime = Date.now();\n let controls: PreparedRequestControls | undefined;\n try {\n await this.ensureClient();\n\n const { system, anthropicMessages } =\n this.mapMessagesToAnthropic(messages);\n\n const model = options.model || this.options.defaultModel;\n options = normalizeChatOptions(this.options, options, 'anthropic', model);\n controls = prepareRequestControls(this.options, options);\n\n const requestParams: Record<string, any> = {\n model,\n messages: anthropicMessages,\n max_tokens: options.maxTokens,\n temperature: options.temperature,\n top_p: options.topP,\n stop_sequences: Array.isArray(options.stop)\n ? options.stop\n : options.stop\n ? [options.stop]\n : undefined,\n system: system || undefined,\n // stream() yields text only, so a tool call would be lost: declare\n // tools only when the replayed history requires it, with\n // tool_choice none.\n ...this.mapHistoryToolParams(anthropicMessages),\n stream: true,\n };\n const thinking = this.mapThinking(options, anthropicMessages);\n if (thinking) {\n requestParams.thinking = thinking;\n }\n const stream = await this.client.messages.create(requestParams, {\n signal: controls.signal,\n timeout: controls.timeout,\n });\n\n let streamStopReason: string | null = null;\n for await (const chunk of stream) {\n if (chunk.type === 'message_delta' && chunk.delta?.stop_reason) {\n streamStopReason = chunk.delta.stop_reason;\n }\n if (\n chunk.type === 'content_block_delta' &&\n chunk.delta.type === 'text_delta'\n ) {\n if (options.onProgress) {\n options.onProgress(chunk.delta.text);\n }\n yield chunk.delta.text;\n }\n }\n options.onFinishReason?.(\n this.mapFinishReason(streamStopReason) ?? 'stop',\n );\n\n emitUsage(\n this.options,\n 'anthropic',\n 'stream',\n model!,\n undefined,\n startTime,\n options.usageTags,\n );\n } catch (error) {\n if (controls?.didTimeout()) {\n throw new AIError(\n `AI request timed out after ${controls.timeout}ms`,\n 'AI_TIMEOUT',\n 'anthropic',\n options.model,\n );\n }\n if (options.signal?.aborted) {\n throw new AIError(\n 'AI request aborted by caller',\n 'AI_ABORTED',\n 'anthropic',\n options.model,\n );\n }\n throw this.mapError(error);\n } finally {\n controls?.cleanup();\n }\n }\n\n async countTokens(text: string): Promise<number> {\n // Anthropic doesn't provide a direct token counting API\n // This is an approximation - Claude uses a different tokenizer than OpenAI\n return Math.ceil(text.length / 3.5); // Slightly different ratio for Claude\n }\n\n async getModels(): Promise<AIModel[]> {\n // Return static list of known Claude models\n return [\n {\n id: 'claude-3-5-sonnet-20241022',\n name: 'Claude 3.5 Sonnet',\n description: 'Most intelligent Claude model with balanced performance',\n contextLength: 200000,\n capabilities: ['text', 'chat', 'vision', 'functions'],\n supportsFunctions: true,\n supportsVision: true,\n },\n {\n id: 'claude-3-5-haiku-20241022',\n name: 'Claude 3.5 Haiku',\n description: 'Fastest Claude model for simple tasks',\n contextLength: 200000,\n capabilities: ['text', 'chat', 'vision'],\n supportsFunctions: true,\n supportsVision: true,\n },\n {\n id: 'claude-3-opus-20240229',\n name: 'Claude 3 Opus',\n description: 'Most powerful Claude model for complex tasks',\n contextLength: 200000,\n capabilities: ['text', 'chat', 'vision', 'functions'],\n supportsFunctions: true,\n supportsVision: true,\n },\n {\n id: 'claude-3-sonnet-20240229',\n name: 'Claude 3 Sonnet',\n description: 'Balanced Claude model for most tasks',\n contextLength: 200000,\n capabilities: ['text', 'chat', 'vision'],\n supportsFunctions: true,\n supportsVision: true,\n },\n {\n id: 'claude-3-haiku-20240307',\n name: 'Claude 3 Haiku',\n description: 'Fast Claude model for simple tasks',\n contextLength: 200000,\n capabilities: ['text', 'chat', 'vision'],\n supportsFunctions: false,\n supportsVision: true,\n },\n ];\n }\n\n async getCapabilities(): Promise<AICapabilities> {\n return {\n chat: true,\n completion: true,\n embeddings: false, // Claude doesn't support embeddings\n streaming: true,\n functions: true,\n vision: true,\n fineTuning: false,\n imageEmbeddings: false,\n imageGeneration: false,\n videoGeneration: false,\n tts: false,\n voiceCloning: false,\n voiceDesign: false,\n maxContextLength: 200000,\n supportedOperations: [\n 'chat',\n 'completion',\n 'streaming',\n 'functions',\n 'vision',\n ],\n };\n }\n\n // ============================================================================\n // Video Generation Methods (Not supported - use gemini, byteplus-modelark,\n // or openai-compat-video provider)\n // ============================================================================\n\n async submitVideoGenerationJob(\n _options: VideoGenerationOptions,\n ): Promise<VideoGenerationJob> {\n throw new AIError(\n 'Video generation is not supported by Anthropic provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'anthropic',\n );\n }\n\n async getVideoGenerationJob(\n _handle: VideoGenerationJob,\n ): Promise<VideoGenerationStatusResult> {\n throw new AIError(\n 'Video generation is not supported by Anthropic provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'anthropic',\n );\n }\n\n async fetchVideoGenerationResult(\n _handle: VideoGenerationJob,\n ): Promise<VideoGenerationResult> {\n throw new AIError(\n 'Video generation is not supported by Anthropic provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'anthropic',\n );\n }\n\n async cancelVideoGenerationJob(_handle: VideoGenerationJob): Promise<void> {\n throw new AIError(\n 'Video generation is not supported by Anthropic provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'anthropic',\n );\n }\n\n async validateVideoGenerationAccess(): Promise<boolean> {\n throw new AIError(\n 'Video generation is not supported by Anthropic provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'anthropic',\n );\n }\n\n // ============================================================================\n // TTS Methods (Not supported - use Qwen3-TTS provider)\n // ============================================================================\n\n async synthesizeSpeech(\n _text: string,\n _options?: TTSOptions,\n ): Promise<TTSResponse> {\n throw new AIError(\n 'TTS is not supported by Anthropic provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'anthropic',\n );\n }\n\n streamSpeech(_text: string, _options?: TTSOptions): AsyncIterable<Buffer> {\n const error = new AIError(\n 'TTS streaming is not supported by Anthropic provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'anthropic',\n );\n return {\n [Symbol.asyncIterator]: () => ({\n next: () => Promise.reject(error),\n }),\n };\n }\n\n async cloneVoice(_options: VoiceCloneOptions): Promise<Voice> {\n throw new AIError(\n 'Voice cloning is not supported by Anthropic provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'anthropic',\n );\n }\n\n async designVoice(_options: VoiceDesignOptions): Promise<Voice> {\n throw new AIError(\n 'Voice design is not supported by Anthropic provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'anthropic',\n );\n }\n\n async getVoices(_options?: VoiceListOptions): Promise<Voice[]> {\n throw new AIError(\n 'Voice listing is not supported by Anthropic provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'anthropic',\n );\n }\n\n /**\n * Maps internal messages to Anthropic Messages API turns.\n *\n * Assistant `tool_calls` become `tool_use` blocks and `role: 'tool'`\n * results become `tool_result` blocks paired by `tool_call_id`\n * (`tool_use_id`). Consecutive tool results are grouped into one user turn,\n * as Anthropic requires every result for a turn to follow it directly.\n * Only answered calls are replayed as `tool_use`, and only results whose\n * `tool_call_id` matches a replayed call become `tool_result`. A result\n * without `tool_call_id`, or one answering no replayed call, falls back to\n * plain text (and a call left unanswered keeps only its text).\n */\n private mapMessagesToAnthropic(messages: AIMessage[]): {\n system?: string;\n anthropicMessages: AnthropicMessage[];\n } {\n // Anthropic handles system messages separately\n let system: string | undefined;\n const anthropicMessages: AnthropicMessage[] = [];\n const answeredToolCallIds = new Set(\n messages\n .filter((message) => message.role === 'tool' && message.tool_call_id)\n .map((message) => message.tool_call_id as string),\n );\n // Calls replayed as tool_use: those with an answer. Only results for\n // these ids become tool_result blocks; any other result is an orphan\n // Anthropic would reject, so it falls back to plain text.\n const replayedToolUseIds = new Set<string>();\n for (const message of messages) {\n if (message.role !== 'assistant') continue;\n for (const toolCall of message.tool_calls || []) {\n if (answeredToolCallIds.has(toolCall.id)) {\n replayedToolUseIds.add(toolCall.id);\n }\n }\n }\n\n for (const message of messages) {\n const textContent = extractTextContent(message.content);\n if (message.role === 'system') {\n // Combine multiple system messages\n system = system ? `${system}\\n\\n${textContent}` : textContent;\n continue;\n }\n\n if (\n message.role === 'tool' &&\n message.tool_call_id &&\n replayedToolUseIds.has(message.tool_call_id)\n ) {\n const block: AnthropicContentBlock = {\n type: 'tool_result',\n tool_use_id: message.tool_call_id,\n content: textContent,\n };\n const previous = anthropicMessages[anthropicMessages.length - 1];\n if (\n previous?.role === 'user' &&\n Array.isArray(previous.content) &&\n previous.content.every((part) => part.type === 'tool_result')\n ) {\n previous.content.push(block);\n } else {\n anthropicMessages.push({ role: 'user', content: [block] });\n }\n continue;\n }\n\n const toolCalls =\n message.role === 'assistant'\n ? (message.tool_calls || []).filter((toolCall) =>\n answeredToolCallIds.has(toolCall.id),\n )\n : [];\n if (toolCalls.length > 0) {\n const content: AnthropicContentBlock[] = [];\n for (const toolCall of toolCalls) {\n for (const block of toolCall.thinkingBlocks || []) {\n content.push({ ...block });\n }\n }\n if (textContent) {\n content.push({ type: 'text', text: textContent });\n }\n for (const toolCall of toolCalls) {\n content.push({\n type: 'tool_use',\n id: toolCall.id,\n name: toolCall.function.name,\n input: parseToolArguments(toolCall.function.arguments),\n });\n }\n anthropicMessages.push({ role: 'assistant', content });\n continue;\n }\n\n anthropicMessages.push({\n role: message.role === 'assistant' ? 'assistant' : 'user',\n content: textContent,\n });\n }\n\n return { system, anthropicMessages };\n }\n\n /**\n * Builds the `tools` / `tool_choice` request fields.\n *\n * Anthropic rejects a request whose history contains `tool_use` or\n * `tool_result` blocks unless `tools` is declared. A tool loop's final,\n * tool-less round (no `tools`, typically `toolChoice: 'none'`) still\n * replays that history, so when the caller declares no tools but the\n * history uses some, this declares a minimal definition for each tool the\n * history references and sets `tool_choice: { type: 'none' }` so the model\n * answers in text instead of calling them.\n */\n private mapToolParams(\n options: ChatOptions,\n anthropicMessages: AnthropicMessage[],\n ): { tools?: Record<string, any>[]; tool_choice?: Record<string, any> } {\n const tools = this.mapTools(options);\n if (tools) {\n return { tools, tool_choice: this.mapToolChoice(options.toolChoice) };\n }\n return this.mapHistoryToolParams(anthropicMessages);\n }\n\n /**\n * Declares a minimal definition for each tool the replayed history\n * references, with `tool_choice: { type: 'none' }`, or nothing when the\n * history has no `tool_use` blocks. Used for tool-less rounds and for\n * every stream (streams never yield tool calls).\n */\n private mapHistoryToolParams(anthropicMessages: AnthropicMessage[]): {\n tools?: Record<string, any>[];\n tool_choice?: Record<string, any>;\n } {\n // mapMessagesToAnthropic emits tool_result only for ids it replayed as\n // tool_use (orphan results become text), so tool_use names cover every\n // tool the history references.\n const historyToolNames = new Set<string>();\n for (const message of anthropicMessages) {\n if (!Array.isArray(message.content)) continue;\n for (const block of message.content) {\n if (block.type === 'tool_use') historyToolNames.add(block.name);\n }\n }\n if (historyToolNames.size === 0) {\n return {};\n }\n\n return {\n tools: [...historyToolNames].map((name) => ({\n name,\n description:\n 'Used earlier in this conversation; not available for this turn.',\n input_schema: { type: 'object' },\n })),\n tool_choice: { type: 'none' },\n };\n }\n\n /**\n * Builds the `thinking` request field for `options.reasoning.maxTokens`.\n *\n * While thinking is enabled, Anthropic requires the assistant turn of an\n * in-progress tool loop (the last assistant turn, when it holds `tool_use`)\n * to start with its thinking blocks. They are replayed from\n * `AIToolCall.thinkingBlocks`; when that turn has none (the history came\n * from another provider, a store that dropped the field, or a call made\n * without thinking), thinking is left off for this request rather than\n * sending a request Anthropic would reject.\n */\n private mapThinking(\n options: ChatOptions,\n anthropicMessages: AnthropicMessage[],\n ): { type: 'enabled'; budget_tokens: number } | undefined {\n const budget = options.reasoning?.maxTokens || 0;\n if (budget <= 0) return undefined;\n\n const lastAssistant = [...anthropicMessages]\n .reverse()\n .find((message) => message.role === 'assistant');\n if (\n lastAssistant &&\n Array.isArray(lastAssistant.content) &&\n lastAssistant.content.some((block) => block.type === 'tool_use')\n ) {\n const firstType = lastAssistant.content[0]?.type;\n if (firstType !== 'thinking' && firstType !== 'redacted_thinking') {\n return undefined;\n }\n }\n\n return { type: 'enabled', budget_tokens: budget };\n }\n\n private mapTools(options: ChatOptions): Record<string, any>[] | undefined {\n return options.tools && options.tools.length > 0\n ? options.tools.map((tool) => ({\n name: tool.function.name,\n description: tool.function.description || '',\n input_schema: tool.function.parameters || { type: 'object' },\n }))\n : undefined;\n }\n\n private mapToolChoice(\n toolChoice?:\n | 'auto'\n | 'none'\n | { type: 'function'; function: { name: string } },\n ): any {\n if (!toolChoice || toolChoice === 'auto') {\n return { type: 'auto' };\n }\n\n if (toolChoice === 'none') {\n return { type: 'none' };\n }\n\n if (typeof toolChoice === 'object' && toolChoice.type === 'function') {\n return {\n type: 'tool',\n name: toolChoice.function.name,\n };\n }\n\n return { type: 'auto' };\n }\n\n private mapFinishReason(reason: string | null): AIResponse['finishReason'] {\n switch (reason) {\n case 'end_turn':\n return 'stop';\n case 'max_tokens':\n return 'length';\n case 'stop_sequence':\n return 'stop';\n case 'tool_use':\n return 'tool_calls';\n default:\n return 'stop';\n }\n }\n\n private mapError(error: unknown): AIError {\n if (error instanceof AIError) {\n return error;\n }\n\n // Map common HTTP status codes from Anthropic API\n if (typeof error === 'object' && error !== null && 'status' in error) {\n const apiError = error as { status: number; message?: string };\n switch (apiError.status) {\n case 401:\n return new AuthenticationError('anthropic');\n case 429:\n return rateLimitErrorFrom('anthropic', error);\n case 404:\n return new ModelNotFoundError(\n apiError.message || 'Model not found',\n 'anthropic',\n );\n case 413:\n return new ContextLengthError('anthropic');\n }\n }\n\n const errorMessage =\n error instanceof Error\n ? error.message\n : 'Unknown Anthropic error occurred';\n return new AIError(errorMessage, 'UNKNOWN_ERROR', 'anthropic');\n }\n}\n\n/**\n * Thinking and redacted-thinking blocks from an Anthropic response, copied\n * with only the fields the API accepts back.\n */\nfunction extractThinkingBlocks(content: any[]): AIThinkingBlock[] {\n const blocks: AIThinkingBlock[] = [];\n for (const block of content || []) {\n if (block?.type === 'thinking') {\n blocks.push({\n type: 'thinking',\n thinking: block.thinking,\n signature: block.signature,\n });\n } else if (block?.type === 'redacted_thinking') {\n blocks.push({ type: 'redacted_thinking', data: block.data });\n }\n }\n return blocks;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"anthropic-DhNGsQpl.js","names":[],"sources":["../../src/shared/providers/anthropic.ts"],"sourcesContent":["/**\n * Anthropic Claude provider implementation\n *\n * Provides a standardized interface for interacting with Anthropic's Claude models,\n * including chat completions, streaming responses, and vision capabilities.\n * Note: Claude models do not support embeddings - use OpenAI or another provider for that.\n */\n\nimport { rateLimitErrorFrom } from '../rate-limit';\nimport {\n normalizeBaseAIOptions,\n normalizeChatOptions,\n type PreparedRequestControls,\n prepareRequestControls,\n} from '../safety';\nimport { parseToolArguments } from '../tool-messages';\nimport type {\n AICapabilities,\n AIInterface,\n AIMessage,\n AIModel,\n AIResponse,\n AIThinkingBlock,\n AIToolCall,\n AnthropicOptions,\n ChatOptions,\n CompletionOptions,\n EmbeddingOptions,\n EmbeddingResponse,\n ImageDescriptionOptions,\n ImageEmbeddingOptions,\n ImageGenerationOptions,\n ImageGenerationResponse,\n MessageOptions,\n TokenUsage,\n TTSOptions,\n TTSResponse,\n VideoGenerationJob,\n VideoGenerationOptions,\n VideoGenerationResult,\n VideoGenerationStatusResult,\n Voice,\n VoiceCloneOptions,\n VoiceDesignOptions,\n VoiceListOptions,\n} from '../types';\nimport {\n AIError,\n AuthenticationError,\n ContextLengthError,\n extractTextContent,\n ModelNotFoundError,\n} from '../types';\nimport { emitUsage } from './usage';\n\ntype AnthropicContentBlock =\n | AIThinkingBlock\n | { type: 'text'; text: string }\n | {\n type: 'tool_use';\n id: string;\n name: string;\n input: Record<string, unknown>;\n }\n | { type: 'tool_result'; tool_use_id: string; content: string };\n\ninterface AnthropicMessage {\n role: 'user' | 'assistant';\n content: string | AnthropicContentBlock[];\n}\n\n// Note: This implementation will require @anthropic-ai/sdk package\n// For now, this is a placeholder that defines the interface\n\n/**\n * Anthropic Claude provider implementation that handles all interactions with Anthropic's API.\n * Supports Claude models, streaming, vision capabilities, and function calling.\n * Does not support embeddings (use OpenAI or another provider for embeddings).\n */\nexport class AnthropicProvider implements AIInterface {\n private options: AnthropicOptions;\n private client: any; // Will be Anthropic instance from @anthropic-ai/sdk\n\n /**\n * Creates a new Anthropic provider instance\n * @param options - Configuration options for the Anthropic provider\n */\n constructor(options: AnthropicOptions) {\n this.options = normalizeBaseAIOptions({\n defaultModel: 'claude-3-5-sonnet-20241022',\n anthropicVersion: '2023-06-01',\n ...options,\n });\n\n // Initialize Anthropic client\n this.initializeClientSync();\n }\n\n private initializeClientSync() {\n try {\n // Dynamic import in constructor - this will work if the package is installed\n import('@anthropic-ai/sdk')\n .then(({ Anthropic }) => {\n this.client = new Anthropic({\n apiKey: this.options.apiKey,\n baseURL: this.options.baseUrl,\n timeout: this.options.timeout,\n maxRetries: this.options.maxRetries,\n defaultHeaders: {\n 'anthropic-version': this.options.anthropicVersion,\n ...this.options.headers,\n },\n });\n })\n .catch(() => {\n // Client will be null and we'll handle it in methods\n });\n } catch (_error) {\n // Client will be null and we'll handle it in methods\n }\n }\n\n /**\n * Ensures the Anthropic client is initialized by dynamically importing the SDK\n * @throws {AIError} When the Anthropic SDK cannot be loaded\n * @private\n */\n private async ensureClient() {\n if (!this.client) {\n try {\n const { Anthropic } = await import('@anthropic-ai/sdk');\n this.client = new Anthropic({\n apiKey: this.options.apiKey,\n baseURL: this.options.baseUrl,\n timeout: this.options.timeout,\n maxRetries: this.options.maxRetries,\n defaultHeaders: {\n 'anthropic-version': this.options.anthropicVersion,\n ...this.options.headers,\n },\n });\n } catch (_error) {\n throw new AIError(\n 'Failed to initialize Anthropic client. Make sure @anthropic-ai/sdk is installed.',\n 'INITIALIZATION_ERROR',\n 'anthropic',\n );\n }\n }\n }\n\n /**\n * Generate a chat completion using Claude models\n * @param messages - Array of conversation messages\n * @param options - Optional configuration for the chat completion\n * @returns Promise resolving to the AI response with content and metadata\n * @throws {AIError} When the API request fails or SDK is not available\n *\n * @example\n * ```typescript\n * const response = await provider.chat([\n * { role: 'system', content: 'You are a helpful assistant.' },\n * { role: 'user', content: 'Explain quantum computing' }\n * ], {\n * model: 'claude-3-5-sonnet-20241022',\n * maxTokens: 1000\n * });\n * ```\n */\n async chat(\n messages: AIMessage[],\n options: ChatOptions = {},\n ): Promise<AIResponse> {\n const startTime = Date.now();\n let controls: PreparedRequestControls | undefined;\n try {\n await this.ensureClient();\n\n const { system, anthropicMessages } =\n this.mapMessagesToAnthropic(messages);\n\n const model = options.model || this.options.defaultModel;\n options = normalizeChatOptions(this.options, options, 'anthropic', model);\n controls = prepareRequestControls(this.options, options);\n\n // Build request parameters\n const requestParams: Record<string, any> = {\n model,\n messages: anthropicMessages,\n max_tokens: options.maxTokens,\n temperature: options.temperature,\n top_p: options.topP,\n stop_sequences: Array.isArray(options.stop)\n ? options.stop\n : options.stop\n ? [options.stop]\n : undefined,\n system: system || undefined,\n ...this.mapToolParams(options, anthropicMessages),\n stream: false,\n };\n const thinking = this.mapThinking(options, anthropicMessages);\n if (thinking) {\n requestParams.thinking = thinking;\n }\n\n // Add response format if specified\n if (options.responseFormat?.type === 'json_object') {\n const jsonInstruction =\n '\\n\\nIMPORTANT: You must respond with valid JSON only. Do not include any explanatory text outside the JSON object.';\n requestParams.system = requestParams.system\n ? requestParams.system + jsonInstruction\n : jsonInstruction.trim();\n }\n\n const response = await this.client.messages.create(requestParams, {\n signal: controls.signal,\n timeout: controls.timeout,\n });\n\n // Extract text content and tool calls from response\n const textContent = response.content\n .filter((block: any) => block.type === 'text')\n .map((block: any) => block.text)\n .join('');\n\n const toolCalls: AIToolCall[] = response.content\n .filter((block: any) => block.type === 'tool_use')\n .map((block: any) => ({\n id: block.id,\n type: 'function' as const,\n function: {\n name: block.name,\n arguments: JSON.stringify(block.input),\n },\n }));\n\n // Extended thinking: the replayed tool_use turn must start with these\n // blocks (signatures intact), so they ride on the first tool call.\n const thinkingBlocks = extractThinkingBlocks(response.content);\n if (toolCalls.length > 0 && thinkingBlocks.length > 0) {\n toolCalls[0].thinkingBlocks = thinkingBlocks;\n }\n\n const usage: TokenUsage = {\n promptTokens: response.usage.input_tokens,\n completionTokens: response.usage.output_tokens,\n totalTokens: response.usage.input_tokens + response.usage.output_tokens,\n };\n emitUsage(\n this.options,\n 'anthropic',\n 'chat',\n response.model || model,\n usage,\n startTime,\n options.usageTags,\n );\n\n return {\n content: textContent,\n model: response.model,\n finishReason: this.mapFinishReason(response.stop_reason),\n usage,\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n };\n } catch (error) {\n if (controls?.didTimeout()) {\n throw new AIError(\n `AI request timed out after ${controls.timeout}ms`,\n 'AI_TIMEOUT',\n 'anthropic',\n options.model,\n );\n }\n if (options.signal?.aborted) {\n throw new AIError(\n 'AI request aborted by caller',\n 'AI_ABORTED',\n 'anthropic',\n options.model,\n );\n }\n throw this.mapError(error);\n } finally {\n controls?.cleanup();\n }\n }\n\n async complete(\n prompt: string,\n options: CompletionOptions = {},\n ): Promise<AIResponse> {\n return this.chat([{ role: 'user', content: prompt }], {\n model: options.model,\n maxTokens: options.maxTokens,\n temperature: options.temperature,\n topP: options.topP,\n n: options.n,\n stop: options.stop,\n stream: options.stream,\n onProgress: options.onProgress,\n signal: options.signal,\n timeout: options.timeout,\n reasoning: options.reasoning,\n usageTags: options.usageTags,\n continueOnLength: options.continueOnLength,\n });\n }\n\n /**\n * Simple message interface for single-turn interactions with optional history\n *\n * @param text - The message text to send\n * @param options - Configuration options including history, model, etc.\n * @returns Promise resolving to the response content string\n *\n * @example\n * ```typescript\n * // Simple usage\n * const response = await provider.message('Hello!');\n *\n * // With history\n * const response = await provider.message('What was my question?', {\n * history: [\n * { role: 'user', content: 'What is 2+2?' },\n * { role: 'assistant', content: '4' }\n * ]\n * });\n * ```\n */\n async message(text: string, options: MessageOptions = {}): Promise<string> {\n // Build messages array from history + current message\n const messages: AIMessage[] = [\n ...(options.history || []),\n { role: options.role || 'user', content: text },\n ];\n\n const response = await this.chat(messages, {\n model: options.model,\n maxTokens: options.maxTokens,\n temperature: options.temperature,\n topP: options.topP,\n stop: options.stop,\n stream: options.stream,\n frequencyPenalty: options.frequencyPenalty,\n presencePenalty: options.presencePenalty,\n responseFormat: options.responseFormat,\n seed: options.seed,\n tools: options.tools,\n toolChoice: options.toolChoice,\n onProgress: options.onProgress,\n signal: options.signal,\n timeout: options.timeout,\n reasoning: options.reasoning,\n usageTags: options.usageTags,\n continueOnLength: options.continueOnLength,\n });\n\n return response.content;\n }\n\n async embed(\n _text: string | string[],\n _options: EmbeddingOptions = {},\n ): Promise<EmbeddingResponse> {\n // Anthropic Claude doesn't provide embeddings API\n throw new AIError(\n 'Anthropic Claude does not support embeddings. Use OpenAI or another provider for embeddings.',\n 'NOT_SUPPORTED',\n 'anthropic',\n );\n }\n\n async embedImage(\n _image: string | Buffer,\n _options: ImageEmbeddingOptions = {},\n ): Promise<EmbeddingResponse> {\n throw new AIError(\n 'Anthropic Claude does not support image embeddings. Use OpenAI or Gemini.',\n 'NOT_SUPPORTED',\n 'anthropic',\n );\n }\n\n async describeImage(\n _image: string | Buffer,\n _prompt?: string,\n _options: ImageDescriptionOptions = {},\n ): Promise<string> {\n // Note: Claude does support vision, but we're keeping this as a stub for now\n // A full implementation could use the chat API with image content\n throw new AIError(\n 'Image description is not yet implemented for Anthropic. Use OpenAI or Gemini.',\n 'NOT_IMPLEMENTED',\n 'anthropic',\n );\n }\n\n async generateImage(\n _prompt: string,\n _options: ImageGenerationOptions = {},\n ): Promise<ImageGenerationResponse> {\n throw new AIError(\n 'Anthropic Claude does not support image generation. Use OpenAI or Gemini.',\n 'NOT_SUPPORTED',\n 'anthropic',\n );\n }\n\n /**\n * Streams a chat completion as text chunks.\n *\n * Streams yield text only and never surface tool calls, so `options.tools`\n * and `options.toolChoice` are ignored: tools are declared only when the\n * replayed history contains `tool_use` blocks (Anthropic requires it), with\n * `tool_choice: { type: 'none' }`. Use `chat()` for rounds that may call\n * tools.\n */\n async *stream(\n messages: AIMessage[],\n options: ChatOptions = {},\n ): AsyncIterable<string> {\n const startTime = Date.now();\n let controls: PreparedRequestControls | undefined;\n try {\n await this.ensureClient();\n\n const { system, anthropicMessages } =\n this.mapMessagesToAnthropic(messages);\n\n const model = options.model || this.options.defaultModel;\n options = normalizeChatOptions(this.options, options, 'anthropic', model);\n controls = prepareRequestControls(this.options, options);\n\n const requestParams: Record<string, any> = {\n model,\n messages: anthropicMessages,\n max_tokens: options.maxTokens,\n temperature: options.temperature,\n top_p: options.topP,\n stop_sequences: Array.isArray(options.stop)\n ? options.stop\n : options.stop\n ? [options.stop]\n : undefined,\n system: system || undefined,\n // stream() yields text only, so a tool call would be lost: declare\n // tools only when the replayed history requires it, with\n // tool_choice none.\n ...this.mapHistoryToolParams(anthropicMessages),\n stream: true,\n };\n const thinking = this.mapThinking(options, anthropicMessages);\n if (thinking) {\n requestParams.thinking = thinking;\n }\n const stream = await this.client.messages.create(requestParams, {\n signal: controls.signal,\n timeout: controls.timeout,\n });\n\n let streamStopReason: string | null = null;\n for await (const chunk of stream) {\n if (chunk.type === 'message_delta' && chunk.delta?.stop_reason) {\n streamStopReason = chunk.delta.stop_reason;\n }\n if (\n chunk.type === 'content_block_delta' &&\n chunk.delta.type === 'text_delta'\n ) {\n if (options.onProgress) {\n options.onProgress(chunk.delta.text);\n }\n yield chunk.delta.text;\n }\n }\n options.onFinishReason?.(\n this.mapFinishReason(streamStopReason) ?? 'stop',\n );\n\n emitUsage(\n this.options,\n 'anthropic',\n 'stream',\n model!,\n undefined,\n startTime,\n options.usageTags,\n );\n } catch (error) {\n if (controls?.didTimeout()) {\n throw new AIError(\n `AI request timed out after ${controls.timeout}ms`,\n 'AI_TIMEOUT',\n 'anthropic',\n options.model,\n );\n }\n if (options.signal?.aborted) {\n throw new AIError(\n 'AI request aborted by caller',\n 'AI_ABORTED',\n 'anthropic',\n options.model,\n );\n }\n throw this.mapError(error);\n } finally {\n controls?.cleanup();\n }\n }\n\n async countTokens(text: string): Promise<number> {\n // Anthropic doesn't provide a direct token counting API\n // This is an approximation - Claude uses a different tokenizer than OpenAI\n return Math.ceil(text.length / 3.5); // Slightly different ratio for Claude\n }\n\n async getModels(): Promise<AIModel[]> {\n // Return static list of known Claude models\n return [\n {\n id: 'claude-3-5-sonnet-20241022',\n name: 'Claude 3.5 Sonnet',\n description: 'Most intelligent Claude model with balanced performance',\n contextLength: 200000,\n capabilities: ['text', 'chat', 'vision', 'functions'],\n supportsFunctions: true,\n supportsVision: true,\n },\n {\n id: 'claude-3-5-haiku-20241022',\n name: 'Claude 3.5 Haiku',\n description: 'Fastest Claude model for simple tasks',\n contextLength: 200000,\n capabilities: ['text', 'chat', 'vision'],\n supportsFunctions: true,\n supportsVision: true,\n },\n {\n id: 'claude-3-opus-20240229',\n name: 'Claude 3 Opus',\n description: 'Most powerful Claude model for complex tasks',\n contextLength: 200000,\n capabilities: ['text', 'chat', 'vision', 'functions'],\n supportsFunctions: true,\n supportsVision: true,\n },\n {\n id: 'claude-3-sonnet-20240229',\n name: 'Claude 3 Sonnet',\n description: 'Balanced Claude model for most tasks',\n contextLength: 200000,\n capabilities: ['text', 'chat', 'vision'],\n supportsFunctions: true,\n supportsVision: true,\n },\n {\n id: 'claude-3-haiku-20240307',\n name: 'Claude 3 Haiku',\n description: 'Fast Claude model for simple tasks',\n contextLength: 200000,\n capabilities: ['text', 'chat', 'vision'],\n supportsFunctions: false,\n supportsVision: true,\n },\n ];\n }\n\n async getCapabilities(): Promise<AICapabilities> {\n return {\n chat: true,\n completion: true,\n embeddings: false, // Claude doesn't support embeddings\n streaming: true,\n functions: true,\n vision: true,\n fineTuning: false,\n imageEmbeddings: false,\n imageGeneration: false,\n videoGeneration: false,\n tts: false,\n voiceCloning: false,\n voiceDesign: false,\n maxContextLength: 200000,\n supportedOperations: [\n 'chat',\n 'completion',\n 'streaming',\n 'functions',\n 'vision',\n ],\n };\n }\n\n // ============================================================================\n // Video Generation Methods (Not supported - use gemini, byteplus-modelark,\n // or openai-compat-video provider)\n // ============================================================================\n\n async submitVideoGenerationJob(\n _options: VideoGenerationOptions,\n ): Promise<VideoGenerationJob> {\n throw new AIError(\n 'Video generation is not supported by Anthropic provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'anthropic',\n );\n }\n\n async getVideoGenerationJob(\n _handle: VideoGenerationJob,\n ): Promise<VideoGenerationStatusResult> {\n throw new AIError(\n 'Video generation is not supported by Anthropic provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'anthropic',\n );\n }\n\n async fetchVideoGenerationResult(\n _handle: VideoGenerationJob,\n ): Promise<VideoGenerationResult> {\n throw new AIError(\n 'Video generation is not supported by Anthropic provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'anthropic',\n );\n }\n\n async cancelVideoGenerationJob(_handle: VideoGenerationJob): Promise<void> {\n throw new AIError(\n 'Video generation is not supported by Anthropic provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'anthropic',\n );\n }\n\n async validateVideoGenerationAccess(): Promise<boolean> {\n throw new AIError(\n 'Video generation is not supported by Anthropic provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'anthropic',\n );\n }\n\n // ============================================================================\n // TTS Methods (Not supported - use Qwen3-TTS provider)\n // ============================================================================\n\n async synthesizeSpeech(\n _text: string,\n _options?: TTSOptions,\n ): Promise<TTSResponse> {\n throw new AIError(\n 'TTS is not supported by Anthropic provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'anthropic',\n );\n }\n\n streamSpeech(_text: string, _options?: TTSOptions): AsyncIterable<Buffer> {\n const error = new AIError(\n 'TTS streaming is not supported by Anthropic provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'anthropic',\n );\n return {\n [Symbol.asyncIterator]: () => ({\n next: () => Promise.reject(error),\n }),\n };\n }\n\n async cloneVoice(_options: VoiceCloneOptions): Promise<Voice> {\n throw new AIError(\n 'Voice cloning is not supported by Anthropic provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'anthropic',\n );\n }\n\n async designVoice(_options: VoiceDesignOptions): Promise<Voice> {\n throw new AIError(\n 'Voice design is not supported by Anthropic provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'anthropic',\n );\n }\n\n async getVoices(_options?: VoiceListOptions): Promise<Voice[]> {\n throw new AIError(\n 'Voice listing is not supported by Anthropic provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'anthropic',\n );\n }\n\n /**\n * Maps internal messages to Anthropic Messages API turns.\n *\n * Assistant `tool_calls` become `tool_use` blocks and `role: 'tool'`\n * results become `tool_result` blocks paired by `tool_call_id`\n * (`tool_use_id`). Consecutive tool results are grouped into one user turn,\n * as Anthropic requires every result for a turn to follow it directly.\n * Only answered calls are replayed as `tool_use`, and only results whose\n * `tool_call_id` matches a replayed call become `tool_result`. A result\n * without `tool_call_id`, or one answering no replayed call, falls back to\n * plain text (and a call left unanswered keeps only its text).\n */\n private mapMessagesToAnthropic(messages: AIMessage[]): {\n system?: string;\n anthropicMessages: AnthropicMessage[];\n } {\n // Anthropic handles system messages separately\n let system: string | undefined;\n const anthropicMessages: AnthropicMessage[] = [];\n const answeredToolCallIds = new Set(\n messages\n .filter((message) => message.role === 'tool' && message.tool_call_id)\n .map((message) => message.tool_call_id as string),\n );\n // Calls replayed as tool_use: those with an answer. Only results for\n // these ids become tool_result blocks; any other result is an orphan\n // Anthropic would reject, so it falls back to plain text.\n const replayedToolUseIds = new Set<string>();\n for (const message of messages) {\n if (message.role !== 'assistant') continue;\n for (const toolCall of message.tool_calls || []) {\n if (answeredToolCallIds.has(toolCall.id)) {\n replayedToolUseIds.add(toolCall.id);\n }\n }\n }\n\n for (const message of messages) {\n const textContent = extractTextContent(message.content);\n if (message.role === 'system') {\n // Combine multiple system messages\n system = system ? `${system}\\n\\n${textContent}` : textContent;\n continue;\n }\n\n if (\n message.role === 'tool' &&\n message.tool_call_id &&\n replayedToolUseIds.has(message.tool_call_id)\n ) {\n const block: AnthropicContentBlock = {\n type: 'tool_result',\n tool_use_id: message.tool_call_id,\n content: textContent,\n };\n const previous = anthropicMessages[anthropicMessages.length - 1];\n if (\n previous?.role === 'user' &&\n Array.isArray(previous.content) &&\n previous.content.every((part) => part.type === 'tool_result')\n ) {\n previous.content.push(block);\n } else {\n anthropicMessages.push({ role: 'user', content: [block] });\n }\n continue;\n }\n\n const toolCalls =\n message.role === 'assistant'\n ? (message.tool_calls || []).filter((toolCall) =>\n answeredToolCallIds.has(toolCall.id),\n )\n : [];\n if (toolCalls.length > 0) {\n const content: AnthropicContentBlock[] = [];\n for (const toolCall of toolCalls) {\n for (const block of toolCall.thinkingBlocks || []) {\n content.push({ ...block });\n }\n }\n if (textContent) {\n content.push({ type: 'text', text: textContent });\n }\n for (const toolCall of toolCalls) {\n content.push({\n type: 'tool_use',\n id: toolCall.id,\n name: toolCall.function.name,\n input: parseToolArguments(toolCall.function.arguments),\n });\n }\n anthropicMessages.push({ role: 'assistant', content });\n continue;\n }\n\n anthropicMessages.push({\n role: message.role === 'assistant' ? 'assistant' : 'user',\n content: textContent,\n });\n }\n\n return { system, anthropicMessages };\n }\n\n /**\n * Builds the `tools` / `tool_choice` request fields.\n *\n * Anthropic rejects a request whose history contains `tool_use` or\n * `tool_result` blocks unless `tools` is declared. A tool loop's final,\n * tool-less round (no `tools`, typically `toolChoice: 'none'`) still\n * replays that history, so when the caller declares no tools but the\n * history uses some, this declares a minimal definition for each tool the\n * history references and sets `tool_choice: { type: 'none' }` so the model\n * answers in text instead of calling them.\n */\n private mapToolParams(\n options: ChatOptions,\n anthropicMessages: AnthropicMessage[],\n ): { tools?: Record<string, any>[]; tool_choice?: Record<string, any> } {\n const tools = this.mapTools(options);\n if (tools) {\n return { tools, tool_choice: this.mapToolChoice(options.toolChoice) };\n }\n return this.mapHistoryToolParams(anthropicMessages);\n }\n\n /**\n * Declares a minimal definition for each tool the replayed history\n * references, with `tool_choice: { type: 'none' }`, or nothing when the\n * history has no `tool_use` blocks. Used for tool-less rounds and for\n * every stream (streams never yield tool calls).\n */\n private mapHistoryToolParams(anthropicMessages: AnthropicMessage[]): {\n tools?: Record<string, any>[];\n tool_choice?: Record<string, any>;\n } {\n // mapMessagesToAnthropic emits tool_result only for ids it replayed as\n // tool_use (orphan results become text), so tool_use names cover every\n // tool the history references.\n const historyToolNames = new Set<string>();\n for (const message of anthropicMessages) {\n if (!Array.isArray(message.content)) continue;\n for (const block of message.content) {\n if (block.type === 'tool_use') historyToolNames.add(block.name);\n }\n }\n if (historyToolNames.size === 0) {\n return {};\n }\n\n return {\n tools: [...historyToolNames].map((name) => ({\n name,\n description:\n 'Used earlier in this conversation; not available for this turn.',\n input_schema: { type: 'object' },\n })),\n tool_choice: { type: 'none' },\n };\n }\n\n /**\n * Builds the `thinking` request field for `options.reasoning.maxTokens`.\n *\n * While thinking is enabled, Anthropic requires the assistant turn of an\n * in-progress tool loop (the last assistant turn, when it holds `tool_use`)\n * to start with its thinking blocks. They are replayed from\n * `AIToolCall.thinkingBlocks`; when that turn has none (the history came\n * from another provider, a store that dropped the field, or a call made\n * without thinking), thinking is left off for this request rather than\n * sending a request Anthropic would reject.\n */\n private mapThinking(\n options: ChatOptions,\n anthropicMessages: AnthropicMessage[],\n ): { type: 'enabled'; budget_tokens: number } | undefined {\n const budget = options.reasoning?.maxTokens || 0;\n if (budget <= 0) return undefined;\n\n const lastAssistant = [...anthropicMessages]\n .reverse()\n .find((message) => message.role === 'assistant');\n if (\n lastAssistant &&\n Array.isArray(lastAssistant.content) &&\n lastAssistant.content.some((block) => block.type === 'tool_use')\n ) {\n const firstType = lastAssistant.content[0]?.type;\n if (firstType !== 'thinking' && firstType !== 'redacted_thinking') {\n return undefined;\n }\n }\n\n return { type: 'enabled', budget_tokens: budget };\n }\n\n private mapTools(options: ChatOptions): Record<string, any>[] | undefined {\n return options.tools && options.tools.length > 0\n ? options.tools.map((tool) => ({\n name: tool.function.name,\n description: tool.function.description || '',\n input_schema: tool.function.parameters || { type: 'object' },\n }))\n : undefined;\n }\n\n private mapToolChoice(\n toolChoice?:\n | 'auto'\n | 'none'\n | { type: 'function'; function: { name: string } },\n ): any {\n if (!toolChoice || toolChoice === 'auto') {\n return { type: 'auto' };\n }\n\n if (toolChoice === 'none') {\n return { type: 'none' };\n }\n\n if (typeof toolChoice === 'object' && toolChoice.type === 'function') {\n return {\n type: 'tool',\n name: toolChoice.function.name,\n };\n }\n\n return { type: 'auto' };\n }\n\n private mapFinishReason(reason: string | null): AIResponse['finishReason'] {\n switch (reason) {\n case 'end_turn':\n return 'stop';\n case 'max_tokens':\n return 'length';\n case 'stop_sequence':\n return 'stop';\n case 'tool_use':\n return 'tool_calls';\n default:\n return 'stop';\n }\n }\n\n private mapError(error: unknown): AIError {\n if (error instanceof AIError) {\n return error;\n }\n\n // Map common HTTP status codes from Anthropic API\n if (typeof error === 'object' && error !== null && 'status' in error) {\n const apiError = error as { status: number; message?: string };\n switch (apiError.status) {\n case 401:\n return new AuthenticationError('anthropic');\n case 429:\n return rateLimitErrorFrom('anthropic', error);\n case 404:\n return new ModelNotFoundError(\n apiError.message || 'Model not found',\n 'anthropic',\n );\n case 413:\n return new ContextLengthError('anthropic');\n }\n }\n\n const errorMessage =\n error instanceof Error\n ? error.message\n : 'Unknown Anthropic error occurred';\n return new AIError(errorMessage, 'UNKNOWN_ERROR', 'anthropic');\n }\n}\n\n/**\n * Thinking and redacted-thinking blocks from an Anthropic response, copied\n * with only the fields the API accepts back.\n */\nfunction extractThinkingBlocks(content: any[]): AIThinkingBlock[] {\n const blocks: AIThinkingBlock[] = [];\n for (const block of content || []) {\n if (block?.type === 'thinking') {\n blocks.push({\n type: 'thinking',\n thinking: block.thinking,\n signature: block.signature,\n });\n } else if (block?.type === 'redacted_thinking') {\n blocks.push({ type: 'redacted_thinking', data: block.data });\n }\n }\n return blocks;\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { b as extractTextContent, c as normalizeImageGenerationOptions, f as AuthenticationError, g as ModelNotFoundError, l as prepareRequestControls, m as ContextLengthError, o as normalizeBaseAIOptions, s as normalizeChatOptions, t as emitUsage, u as AIError } from "./usage-
|
|
2
|
-
import { n as rateLimitErrorFrom } from "./rate-limit-
|
|
1
|
+
import { b as extractTextContent, c as normalizeImageGenerationOptions, f as AuthenticationError, g as ModelNotFoundError, l as prepareRequestControls, m as ContextLengthError, o as normalizeBaseAIOptions, s as normalizeChatOptions, t as emitUsage, u as AIError } from "./usage-DS7uDhi1.js";
|
|
2
|
+
import { n as rateLimitErrorFrom } from "./rate-limit-Dwyde1BY.js";
|
|
3
3
|
//#region src/shared/providers/bedrock.ts
|
|
4
4
|
/**
|
|
5
5
|
* AWS Bedrock provider implementation
|
|
@@ -761,4 +761,4 @@ var BedrockProvider = class {
|
|
|
761
761
|
//#endregion
|
|
762
762
|
export { BedrockProvider };
|
|
763
763
|
|
|
764
|
-
//# sourceMappingURL=bedrock-
|
|
764
|
+
//# sourceMappingURL=bedrock-CrtUO8yx.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bedrock-DNkxz3ow.js","names":[],"sources":["../../src/shared/providers/bedrock.ts"],"sourcesContent":["/**\n * AWS Bedrock provider implementation\n */\n\nimport { rateLimitErrorFrom } from '../rate-limit';\nimport {\n normalizeBaseAIOptions,\n normalizeChatOptions,\n normalizeImageGenerationOptions,\n type PreparedRequestControls,\n prepareRequestControls,\n} from '../safety';\nimport type {\n AICapabilities,\n AIInterface,\n AIMessage,\n AIModel,\n AIResponse,\n BedrockOptions,\n ChatOptions,\n CompletionOptions,\n EmbeddingOptions,\n EmbeddingResponse,\n ImageDescriptionOptions,\n ImageEmbeddingOptions,\n ImageGenerationOptions,\n ImageGenerationResponse,\n MessageOptions,\n TokenUsage,\n TTSOptions,\n TTSResponse,\n VideoGenerationJob,\n VideoGenerationOptions,\n VideoGenerationResult,\n VideoGenerationStatusResult,\n Voice,\n VoiceCloneOptions,\n VoiceDesignOptions,\n VoiceListOptions,\n} from '../types';\nimport {\n AIError,\n AuthenticationError,\n ContextLengthError,\n extractTextContent,\n ModelNotFoundError,\n} from '../types';\nimport { emitUsage } from './usage';\n\nconst BEDROCK_DEFAULT_CHAT_MODEL = 'anthropic.claude-3-5-sonnet-20241022-v2:0';\nconst BEDROCK_TEXT_EMBEDDING_MODEL = 'amazon.titan-embed-text-v2:0';\nconst BEDROCK_IMAGE_EMBEDDING_MODEL = 'amazon.titan-embed-image-v1';\nconst BEDROCK_IMAGE_GENERATION_MODEL = 'amazon.titan-image-generator-v2:0';\n\n/**\n * System instruction standing in for a \"none\" tool choice, which Converse\n * lacks, when tools must still be declared (see `mapToolConfig`).\n */\nconst NO_TOOL_CALLS_INSTRUCTION =\n 'Do not call any tools in this response. Answer in text using the information already in the conversation.';\n\nexport class BedrockProvider implements AIInterface {\n private options: BedrockOptions;\n private client: any; // Will be BedrockRuntimeClient instance from @aws-sdk/client-bedrock-runtime\n\n constructor(options: BedrockOptions) {\n this.options = normalizeBaseAIOptions({\n defaultModel: BEDROCK_DEFAULT_CHAT_MODEL,\n ...options,\n });\n\n // Initialize AWS Bedrock client\n this.initializeClientSync();\n }\n\n private initializeClientSync() {\n try {\n // Dynamic import in constructor - this will work if the package is installed\n import('@aws-sdk/client-bedrock-runtime')\n .then(({ BedrockRuntimeClient }) => {\n this.client = new BedrockRuntimeClient({\n region: this.options.region,\n credentials: this.options.credentials,\n endpoint: this.options.endpoint,\n maxAttempts: (this.options.maxRetries || 0) + 1,\n });\n })\n .catch(() => {\n // Client will be null and we'll handle it in methods\n });\n } catch (_error) {\n // Client will be null and we'll handle it in methods\n }\n }\n\n private async ensureClient() {\n if (!this.client) {\n try {\n const { BedrockRuntimeClient } = await import(\n '@aws-sdk/client-bedrock-runtime'\n );\n this.client = new BedrockRuntimeClient({\n region: this.options.region,\n credentials: this.options.credentials,\n endpoint: this.options.endpoint,\n maxAttempts: (this.options.maxRetries || 0) + 1,\n });\n } catch (_error) {\n throw new AIError(\n 'Failed to initialize Bedrock client. Make sure @aws-sdk/client-bedrock-runtime is installed.',\n 'INITIALIZATION_ERROR',\n 'bedrock',\n );\n }\n }\n }\n\n async chat(\n messages: AIMessage[],\n options: ChatOptions = {},\n ): Promise<AIResponse> {\n const startTime = Date.now();\n let controls: PreparedRequestControls | undefined;\n try {\n await this.ensureClient();\n\n const modelId = options.model || this.options.defaultModel;\n options = normalizeChatOptions(this.options, options, 'bedrock', modelId);\n controls = prepareRequestControls(this.options, options);\n const response = this.mapConverseResponse(\n await this.client.converse(\n await this.buildConverseRequest(\n messages,\n options,\n modelId!,\n controls.signal,\n ),\n { abortSignal: controls.signal },\n ),\n modelId!,\n );\n\n emitUsage(\n this.options,\n 'bedrock',\n 'chat',\n response.model || modelId || 'unknown',\n response.usage,\n startTime,\n options.usageTags,\n );\n return response;\n } catch (error) {\n if (controls?.didTimeout()) {\n throw new AIError(\n `AI request timed out after ${controls.timeout}ms`,\n 'AI_TIMEOUT',\n 'bedrock',\n options.model,\n );\n }\n if (options.signal?.aborted) {\n throw new AIError(\n 'AI request aborted by caller',\n 'AI_ABORTED',\n 'bedrock',\n options.model,\n );\n }\n throw this.mapError(error);\n } finally {\n controls?.cleanup();\n }\n }\n\n async complete(\n prompt: string,\n options: CompletionOptions = {},\n ): Promise<AIResponse> {\n return this.chat([{ role: 'user', content: prompt }], {\n model: options.model,\n maxTokens: options.maxTokens,\n temperature: options.temperature,\n topP: options.topP,\n n: options.n,\n stop: options.stop,\n stream: options.stream,\n onProgress: options.onProgress,\n signal: options.signal,\n timeout: options.timeout,\n reasoning: options.reasoning,\n usageTags: options.usageTags,\n continueOnLength: options.continueOnLength,\n });\n }\n\n /**\n * Simple message interface for single-turn interactions with optional history\n *\n * @param text - The message text to send\n * @param options - Configuration options including history, model, etc.\n * @returns Promise resolving to the response content string\n */\n async message(text: string, options: MessageOptions = {}): Promise<string> {\n // Build messages array from history + current message\n const messages: AIMessage[] = [\n ...(options.history || []),\n { role: options.role || 'user', content: text },\n ];\n\n const response = await this.chat(messages, {\n model: options.model,\n maxTokens: options.maxTokens,\n temperature: options.temperature,\n topP: options.topP,\n stop: options.stop,\n stream: options.stream,\n frequencyPenalty: options.frequencyPenalty,\n presencePenalty: options.presencePenalty,\n responseFormat: options.responseFormat,\n seed: options.seed,\n tools: options.tools,\n toolChoice: options.toolChoice,\n onProgress: options.onProgress,\n signal: options.signal,\n timeout: options.timeout,\n reasoning: options.reasoning,\n usageTags: options.usageTags,\n continueOnLength: options.continueOnLength,\n });\n\n return response.content;\n }\n\n async embed(\n text: string | string[],\n options: EmbeddingOptions = {},\n ): Promise<EmbeddingResponse> {\n const startTime = Date.now();\n try {\n await this.ensureClient();\n\n const model = options.model || BEDROCK_TEXT_EMBEDDING_MODEL;\n const inputs = Array.isArray(text) ? text : [text];\n const embeddings: number[][] = [];\n let totalTokens = 0;\n\n for (const inputText of inputs) {\n const response = await this.client.invokeModel({\n modelId: model,\n contentType: 'application/json',\n accept: 'application/json',\n body: JSON.stringify({\n inputText,\n ...(options.dimensions && { dimensions: options.dimensions }),\n normalize: true,\n }),\n });\n\n const payload = await this.parseInvokeModelBody(response.body);\n const embedding = this.extractEmbeddingVector(payload);\n if (embedding) {\n embeddings.push(embedding);\n }\n\n totalTokens +=\n payload.inputTextTokenCount ||\n payload.inputTokenCount ||\n payload.tokenCount ||\n 0;\n }\n\n const usage: TokenUsage | undefined =\n totalTokens > 0\n ? {\n promptTokens: totalTokens,\n completionTokens: 0,\n totalTokens,\n }\n : undefined;\n\n emitUsage(\n this.options,\n 'bedrock',\n 'embed',\n model,\n usage,\n startTime,\n options.usageTags,\n );\n\n return {\n embeddings,\n model,\n usage,\n };\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async embedImage(\n image: string | Buffer,\n options: ImageEmbeddingOptions = {},\n ): Promise<EmbeddingResponse> {\n const startTime = Date.now();\n try {\n await this.ensureClient();\n\n const model = options.model || BEDROCK_IMAGE_EMBEDDING_MODEL;\n const response = await this.client.invokeModel({\n modelId: model,\n contentType: 'application/json',\n accept: 'application/json',\n body: JSON.stringify({\n inputImage: await this.imageToBase64(image),\n ...(options.dimensions && {\n embeddingConfig: {\n outputEmbeddingLength: options.dimensions,\n },\n }),\n }),\n });\n\n const payload = await this.parseInvokeModelBody(response.body);\n const embedding = this.extractEmbeddingVector(payload);\n\n emitUsage(\n this.options,\n 'bedrock',\n 'embedImage',\n model,\n undefined,\n startTime,\n );\n\n return {\n embeddings: embedding ? [embedding] : [],\n model,\n };\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async describeImage(\n image: string | Buffer,\n prompt?: string,\n options: ImageDescriptionOptions = {},\n ): Promise<string> {\n const imageUrl = await this.imageToDataUrl(image, options.signal);\n const response = await this.chat(\n [\n {\n role: 'user',\n content: [\n {\n type: 'text',\n text:\n prompt ||\n 'Describe this image for a search index. Include objects, mood, lighting, and any visible text.',\n },\n {\n type: 'image_url',\n image_url: { url: imageUrl },\n },\n ],\n },\n ],\n {\n model: options.model || this.options.defaultModel,\n maxTokens: options.maxTokens ?? 500,\n signal: options.signal,\n timeout: options.timeout,\n reasoning: options.reasoning,\n usageTags: options.usageTags,\n },\n );\n\n return response.content;\n }\n\n async generateImage(\n prompt: string,\n options: ImageGenerationOptions = {},\n ): Promise<ImageGenerationResponse> {\n let controls: PreparedRequestControls | undefined;\n try {\n await this.ensureClient();\n\n const model = options.model || BEDROCK_IMAGE_GENERATION_MODEL;\n options = normalizeImageGenerationOptions(\n this.options,\n options,\n 'bedrock',\n model,\n );\n controls = prepareRequestControls(this.options, options);\n const size = this.resolveImageSize(options);\n const response = await this.client.invokeModel(\n {\n modelId: model,\n contentType: 'application/json',\n accept: 'application/json',\n body: JSON.stringify({\n taskType: 'TEXT_IMAGE',\n textToImageParams: {\n text: prompt,\n ...(options.imageInput && {\n conditionImage: await this.imageToBase64(\n options.imageInput,\n controls.signal,\n ),\n }),\n },\n imageGenerationConfig: {\n numberOfImages: options.n,\n quality: this.mapImageQuality(options.quality),\n ...size,\n },\n }),\n },\n { abortSignal: controls.signal },\n );\n\n const payload = await this.parseInvokeModelBody(response.body);\n if (payload.error) {\n throw new AIError(payload.error, 'API_ERROR', 'bedrock');\n }\n\n const images = (payload.images || []).map((encoded: string) => {\n const mimeType = 'image/png';\n if (options.outputFormat === 'base64') {\n return { data: encoded, mimeType };\n }\n if (options.outputFormat === 'url') {\n return { data: `data:${mimeType};base64,${encoded}`, mimeType };\n }\n return {\n data: Buffer.from(encoded, 'base64'),\n mimeType,\n };\n });\n\n return {\n images,\n model,\n };\n } catch (error) {\n if (controls?.didTimeout()) {\n throw new AIError(\n `AI request timed out after ${controls.timeout}ms`,\n 'AI_TIMEOUT',\n 'bedrock',\n options.model,\n );\n }\n if (options.signal?.aborted) {\n throw new AIError(\n 'AI request aborted by caller',\n 'AI_ABORTED',\n 'bedrock',\n options.model,\n );\n }\n throw this.mapError(error);\n } finally {\n controls?.cleanup();\n }\n }\n\n async *stream(\n messages: AIMessage[],\n options: ChatOptions = {},\n ): AsyncIterable<string> {\n const startTime = Date.now();\n let controls: PreparedRequestControls | undefined;\n try {\n await this.ensureClient();\n\n const modelId = options.model || this.options.defaultModel;\n options = normalizeChatOptions(this.options, options, 'bedrock', modelId);\n controls = prepareRequestControls(this.options, options);\n const response = await this.client.converseStream(\n await this.buildConverseRequest(\n messages,\n options,\n modelId!,\n controls.signal,\n ),\n { abortSignal: controls.signal },\n );\n\n let usage: TokenUsage | undefined;\n let streamStopReason: string | null | undefined;\n\n for await (const event of response.stream || []) {\n if (event.messageStop?.stopReason) {\n streamStopReason = event.messageStop.stopReason;\n }\n const text = event.contentBlockDelta?.delta?.text;\n if (text) {\n if (options.onProgress) {\n options.onProgress(text);\n }\n yield text;\n }\n\n if (event.metadata?.usage) {\n usage = {\n promptTokens: event.metadata.usage.inputTokens || 0,\n completionTokens: event.metadata.usage.outputTokens || 0,\n totalTokens: event.metadata.usage.totalTokens || 0,\n };\n }\n }\n\n options.onFinishReason?.(\n this.mapBedrockFinishReason(streamStopReason) ?? 'stop',\n );\n\n emitUsage(\n this.options,\n 'bedrock',\n 'stream',\n modelId || 'unknown',\n usage,\n startTime,\n options.usageTags,\n );\n } catch (error) {\n if (controls?.didTimeout()) {\n throw new AIError(\n `AI request timed out after ${controls.timeout}ms`,\n 'AI_TIMEOUT',\n 'bedrock',\n options.model,\n );\n }\n if (options.signal?.aborted) {\n throw new AIError(\n 'AI request aborted by caller',\n 'AI_ABORTED',\n 'bedrock',\n options.model,\n );\n }\n throw this.mapError(error);\n } finally {\n controls?.cleanup();\n }\n }\n\n async countTokens(text: string): Promise<number> {\n try {\n await this.ensureClient();\n\n const modelId = this.options.defaultModel || BEDROCK_DEFAULT_CHAT_MODEL;\n const response = await this.client.countTokens({\n modelId,\n input: {\n converse: {\n messages: [\n {\n role: 'user',\n content: [{ text }],\n },\n ],\n },\n },\n });\n\n return response.inputTokens || Math.ceil(text.length / 4);\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async getModels(): Promise<AIModel[]> {\n // Return static list of popular Bedrock models\n return [\n // Anthropic Claude models\n {\n id: 'anthropic.claude-3-5-sonnet-20241022-v2:0',\n name: 'Claude 3.5 Sonnet v2',\n description: 'Latest Claude 3.5 Sonnet model on Bedrock',\n contextLength: 200000,\n capabilities: ['text', 'chat', 'vision', 'functions'],\n supportsFunctions: true,\n supportsVision: true,\n },\n {\n id: 'anthropic.claude-3-opus-20240229-v1:0',\n name: 'Claude 3 Opus',\n description: 'Most powerful Claude model on Bedrock',\n contextLength: 200000,\n capabilities: ['text', 'chat', 'vision'],\n supportsFunctions: false,\n supportsVision: true,\n },\n // Amazon Titan models\n {\n id: 'amazon.titan-text-premier-v1:0',\n name: 'Titan Text Premier',\n description: 'Premier Amazon Titan text model',\n contextLength: 32000,\n capabilities: ['text', 'chat'],\n supportsFunctions: false,\n supportsVision: false,\n },\n {\n id: 'amazon.titan-embed-text-v1',\n name: 'Titan Embeddings Text',\n description: 'Amazon Titan text embeddings model',\n contextLength: 8192,\n capabilities: ['embeddings'],\n supportsFunctions: false,\n supportsVision: false,\n },\n {\n id: BEDROCK_TEXT_EMBEDDING_MODEL,\n name: 'Titan Embeddings Text V2',\n description: 'Amazon Titan text embeddings v2 model',\n contextLength: 8192,\n capabilities: ['embeddings'],\n supportsFunctions: false,\n supportsVision: false,\n },\n {\n id: BEDROCK_IMAGE_EMBEDDING_MODEL,\n name: 'Titan Multimodal Embeddings G1',\n description:\n 'Amazon Titan multimodal embeddings model for image similarity',\n contextLength: 256,\n capabilities: ['embeddings', 'image_embedding'],\n supportsFunctions: false,\n supportsVision: false,\n },\n {\n id: BEDROCK_IMAGE_GENERATION_MODEL,\n name: 'Titan Image Generator V2',\n description: 'Amazon Titan image generation model',\n contextLength: 0,\n capabilities: ['image_generation'],\n supportsFunctions: false,\n supportsVision: false,\n },\n // Cohere models\n {\n id: 'cohere.command-r-plus-v1:0',\n name: 'Command R+',\n description: 'Cohere Command R+ model with advanced capabilities',\n contextLength: 128000,\n capabilities: ['text', 'chat', 'functions'],\n supportsFunctions: true,\n supportsVision: false,\n },\n // Meta Llama models\n {\n id: 'meta.llama3-1-405b-instruct-v1:0',\n name: 'Llama 3.1 405B Instruct',\n description: 'Meta Llama 3.1 405B instruction-tuned model',\n contextLength: 128000,\n capabilities: ['text', 'chat'],\n supportsFunctions: false,\n supportsVision: false,\n },\n ];\n }\n\n async getCapabilities(): Promise<AICapabilities> {\n return {\n chat: true,\n completion: true,\n embeddings: true,\n streaming: true,\n functions: true, // Some models support function calling\n vision: true, // Some models support vision\n fineTuning: true, // Via Bedrock fine-tuning\n imageEmbeddings: true,\n imageGeneration: true,\n videoGeneration: false,\n tts: false,\n voiceCloning: false,\n voiceDesign: false,\n maxContextLength: 200000,\n supportedOperations: [\n 'chat',\n 'completion',\n 'embedding',\n 'streaming',\n 'functions',\n 'vision',\n 'image_embedding',\n 'image_generation',\n ],\n };\n }\n\n // ============================================================================\n // Video Generation Methods (Not supported - use gemini, byteplus-modelark,\n // or openai-compat-video provider)\n // ============================================================================\n\n async submitVideoGenerationJob(\n _options: VideoGenerationOptions,\n ): Promise<VideoGenerationJob> {\n throw new AIError(\n 'Video generation is not supported by Bedrock provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n }\n\n async getVideoGenerationJob(\n _handle: VideoGenerationJob,\n ): Promise<VideoGenerationStatusResult> {\n throw new AIError(\n 'Video generation is not supported by Bedrock provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n }\n\n async fetchVideoGenerationResult(\n _handle: VideoGenerationJob,\n ): Promise<VideoGenerationResult> {\n throw new AIError(\n 'Video generation is not supported by Bedrock provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n }\n\n async cancelVideoGenerationJob(_handle: VideoGenerationJob): Promise<void> {\n throw new AIError(\n 'Video generation is not supported by Bedrock provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n }\n\n async validateVideoGenerationAccess(): Promise<boolean> {\n throw new AIError(\n 'Video generation is not supported by Bedrock provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n }\n\n // ============================================================================\n // TTS Methods (Not supported - use Qwen3-TTS provider)\n // ============================================================================\n\n async synthesizeSpeech(\n _text: string,\n _options?: TTSOptions,\n ): Promise<TTSResponse> {\n throw new AIError(\n 'TTS is not supported by Bedrock provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n }\n\n streamSpeech(_text: string, _options?: TTSOptions): AsyncIterable<Buffer> {\n const error = new AIError(\n 'TTS streaming is not supported by Bedrock provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n return {\n [Symbol.asyncIterator]: () => ({\n next: () => Promise.reject(error),\n }),\n };\n }\n\n async cloneVoice(_options: VoiceCloneOptions): Promise<Voice> {\n throw new AIError(\n 'Voice cloning is not supported by Bedrock provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n }\n\n async designVoice(_options: VoiceDesignOptions): Promise<Voice> {\n throw new AIError(\n 'Voice design is not supported by Bedrock provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n }\n\n async getVoices(_options?: VoiceListOptions): Promise<Voice[]> {\n throw new AIError(\n 'Voice listing is not supported by Bedrock provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n }\n\n private async buildConverseRequest(\n messages: AIMessage[],\n options: ChatOptions,\n modelId: string,\n signal?: AbortSignal,\n ): Promise<Record<string, any>> {\n const { system, bedrockMessages } = await this.mapMessagesToBedrock(\n messages,\n signal,\n );\n const toolConfig = this.mapToolConfig(options, bedrockMessages);\n const systemPrompt = [\n system,\n options.responseFormat?.type === 'json_object'\n ? 'Respond with valid JSON only. Do not include explanatory text outside the JSON object.'\n : undefined,\n toolConfig && (options.toolChoice === 'none' || !options.tools?.length)\n ? NO_TOOL_CALLS_INSTRUCTION\n : undefined,\n ]\n .filter(Boolean)\n .join('\\n\\n');\n\n const inferenceConfig = Object.fromEntries(\n Object.entries({\n maxTokens: options.maxTokens,\n temperature: options.temperature,\n topP: options.topP,\n stopSequences: Array.isArray(options.stop)\n ? options.stop\n : options.stop\n ? [options.stop]\n : undefined,\n }).filter(([, value]) => value !== undefined),\n );\n\n const request: Record<string, any> = {\n modelId,\n messages: bedrockMessages,\n ...(Object.keys(inferenceConfig).length > 0 && { inferenceConfig }),\n ...(systemPrompt && { system: [{ text: systemPrompt }] }),\n };\n if ((options.reasoning?.maxTokens || 0) > 0) {\n request.additionalModelRequestFields = {\n thinking: {\n type: 'enabled',\n budget_tokens: options.reasoning?.maxTokens,\n },\n };\n }\n\n if (toolConfig) {\n request.toolConfig = toolConfig;\n }\n\n return request;\n }\n\n private async mapMessagesToBedrock(\n messages: AIMessage[],\n signal?: AbortSignal,\n ): Promise<{\n system?: string;\n bedrockMessages: Array<{ role: 'user' | 'assistant'; content: any[] }>;\n }> {\n let system: string | undefined;\n const bedrockMessages: Array<{\n role: 'user' | 'assistant';\n content: any[];\n }> = [];\n\n for (const message of messages) {\n const textContent = extractTextContent(message.content);\n if (message.role === 'system') {\n system = system ? `${system}\\n\\n${textContent}` : textContent;\n continue;\n }\n\n if (message.role === 'tool' && message.tool_call_id) {\n // Converse pairs results with calls by toolUseId, and all results\n // for one assistant turn must share the following user turn.\n const block = {\n toolResult: {\n toolUseId: message.tool_call_id,\n content: [{ text: textContent }],\n },\n };\n const previous = bedrockMessages[bedrockMessages.length - 1];\n if (\n previous?.role === 'user' &&\n previous.content.every((part) => part.toolResult)\n ) {\n previous.content.push(block);\n } else {\n bedrockMessages.push({ role: 'user', content: [block] });\n }\n continue;\n }\n\n const content: any[] = [];\n if (typeof message.content === 'string') {\n // Converse rejects empty text blocks (e.g. tool-call-only turns).\n if (message.content) content.push({ text: message.content });\n } else {\n for (const part of message.content) {\n if (part.type === 'text') {\n content.push({ text: part.text });\n continue;\n }\n\n const image = await this.imageUrlToBedrockImage(\n part.image_url.url,\n signal,\n );\n content.push({ image });\n }\n }\n\n if (message.role === 'assistant' && message.tool_calls) {\n for (const toolCall of message.tool_calls) {\n content.push({\n toolUse: {\n toolUseId: toolCall.id,\n name: toolCall.function.name,\n input: this.safeJsonParse(toolCall.function.arguments),\n },\n });\n }\n }\n\n if (content.length === 0 && textContent) {\n content.push({ text: textContent });\n }\n\n bedrockMessages.push({\n role: message.role === 'assistant' ? 'assistant' : 'user',\n content,\n });\n }\n\n return { system, bedrockMessages };\n }\n\n private mapConverseResponse(response: any, modelId: string): AIResponse {\n const contentBlocks = response.output?.message?.content || [];\n const textContent = contentBlocks\n .filter((block: any) => typeof block.text === 'string')\n .map((block: any) => block.text)\n .join('');\n\n const toolCalls = contentBlocks\n .filter((block: any) => block.toolUse)\n .map((block: any) => ({\n id: block.toolUse.toolUseId,\n type: 'function' as const,\n function: {\n name: block.toolUse.name,\n arguments: JSON.stringify(block.toolUse.input || {}),\n },\n }));\n\n const usage =\n response.usage &&\n ({\n promptTokens: response.usage.inputTokens || 0,\n completionTokens: response.usage.outputTokens || 0,\n totalTokens: response.usage.totalTokens || 0,\n } satisfies TokenUsage);\n\n return {\n content: textContent,\n model: modelId,\n finishReason: this.mapBedrockFinishReason(response.stopReason),\n usage,\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n };\n }\n\n private mapBedrockFinishReason(\n reason: string | null | undefined,\n ): AIResponse['finishReason'] {\n switch (reason) {\n case 'end_turn':\n return 'stop';\n case 'max_tokens':\n return 'length';\n case 'stop_sequence':\n return 'stop';\n case 'tool_use':\n return 'tool_calls';\n default:\n return 'stop';\n }\n }\n\n /**\n * Builds the Converse `toolConfig`.\n *\n * Converse rejects a request whose history contains `toolUse` or\n * `toolResult` blocks unless `toolConfig` is present, and it has no \"none\"\n * tool choice. So:\n * - declared tools are always sent; `toolChoice: 'none'` omits the\n * `toolChoice` field and the caller adds {@link NO_TOOL_CALLS_INSTRUCTION}\n * to the system prompt (an instruction, not a hard guarantee);\n * - with no declared tools, a history that uses tools (a tool loop's final,\n * tool-less round) gets a minimal spec for each tool it references, so\n * the request is valid, again with the no-tool-calls instruction.\n */\n private mapToolConfig(\n options: ChatOptions,\n bedrockMessages: Array<{ role: 'user' | 'assistant'; content: any[] }>,\n ): Record<string, any> | undefined {\n if (options.tools && options.tools.length > 0) {\n const toolChoice =\n options.toolChoice && options.toolChoice !== 'none'\n ? this.mapToolChoice(options.toolChoice)\n : undefined;\n return {\n tools: options.tools.map((tool) => ({\n toolSpec: {\n name: tool.function.name,\n description: tool.function.description || '',\n inputSchema: {\n json: tool.function.parameters || { type: 'object' },\n },\n },\n })),\n ...(toolChoice && { toolChoice }),\n };\n }\n\n const historyToolNames = new Set<string>();\n for (const message of bedrockMessages) {\n for (const block of message.content) {\n if (block.toolUse?.name) historyToolNames.add(block.toolUse.name);\n }\n }\n if (historyToolNames.size === 0) {\n return undefined;\n }\n\n return {\n tools: [...historyToolNames].map((name) => ({\n toolSpec: {\n name,\n description:\n 'Used earlier in this conversation; not available for this turn.',\n inputSchema: { json: { type: 'object' } },\n },\n })),\n };\n }\n\n private mapToolChoice(\n toolChoice?:\n | 'auto'\n | 'none'\n | { type: 'function'; function: { name: string } },\n ): Record<string, any> | undefined {\n if (!toolChoice || toolChoice === 'auto') {\n return { auto: {} };\n }\n\n if (toolChoice === 'none') {\n return undefined;\n }\n\n return {\n tool: {\n name: toolChoice.function.name,\n },\n };\n }\n\n private async parseInvokeModelBody(body: unknown): Promise<any> {\n const bytes =\n typeof (body as any)?.transformToByteArray === 'function'\n ? await (body as any).transformToByteArray()\n : body instanceof Uint8Array\n ? body\n : Buffer.isBuffer(body)\n ? body\n : new Uint8Array(body as ArrayBuffer);\n return JSON.parse(new TextDecoder().decode(bytes));\n }\n\n private extractEmbeddingVector(payload: any): number[] | undefined {\n if (Array.isArray(payload.embedding)) {\n return payload.embedding;\n }\n\n if (Array.isArray(payload.embeddings?.[0])) {\n return payload.embeddings[0];\n }\n\n if (Array.isArray(payload.embeddingsByType?.float)) {\n return payload.embeddingsByType.float;\n }\n\n if (Array.isArray(payload.vector)) {\n return payload.vector;\n }\n\n return undefined;\n }\n\n private async imageUrlToBedrockImage(\n imageUrl: string,\n signal?: AbortSignal,\n ): Promise<any> {\n const { bytes, mimeType } = await this.imageToBytes(imageUrl, signal);\n return {\n format: this.mimeTypeToBedrockImageFormat(mimeType),\n source: { bytes },\n };\n }\n\n private async imageToDataUrl(\n image: string | Buffer,\n signal?: AbortSignal,\n ): Promise<string> {\n if (Buffer.isBuffer(image)) {\n return `data:image/png;base64,${image.toString('base64')}`;\n }\n if (image.startsWith('data:')) {\n return image;\n }\n\n const { bytes, mimeType } = await this.imageToBytes(image, signal);\n return `data:${mimeType};base64,${Buffer.from(bytes).toString('base64')}`;\n }\n\n private async imageToBase64(\n image: string | Buffer,\n signal?: AbortSignal,\n ): Promise<string> {\n if (Buffer.isBuffer(image)) {\n return image.toString('base64');\n }\n if (image.startsWith('data:')) {\n const match = image.match(/^data:([^;]+);base64,(.+)$/);\n if (!match) {\n throw new AIError(\n 'Invalid base64 data URL format',\n 'INVALID_INPUT',\n 'bedrock',\n );\n }\n return match[2];\n }\n\n const { bytes } = await this.imageToBytes(image, signal);\n return Buffer.from(bytes).toString('base64');\n }\n\n private async imageToBytes(\n image: string,\n signal?: AbortSignal,\n ): Promise<{ bytes: Uint8Array; mimeType: string }> {\n if (image.startsWith('data:')) {\n const match = image.match(/^data:([^;]+);base64,(.+)$/);\n if (!match) {\n throw new AIError(\n 'Invalid base64 data URL format',\n 'INVALID_INPUT',\n 'bedrock',\n );\n }\n\n return {\n bytes: Uint8Array.from(Buffer.from(match[2], 'base64')),\n mimeType: match[1],\n };\n }\n\n const response = await fetch(image, { signal });\n if (!response.ok) {\n throw new AIError(\n `Failed to fetch image: ${response.status} ${response.statusText}`,\n 'IMAGE_FETCH_ERROR',\n 'bedrock',\n );\n }\n\n const arrayBuffer = await response.arrayBuffer();\n return {\n bytes: new Uint8Array(arrayBuffer),\n mimeType: response.headers.get('content-type') || 'image/png',\n };\n }\n\n private mimeTypeToBedrockImageFormat(mimeType: string): string {\n if (mimeType.includes('png')) return 'png';\n if (mimeType.includes('jpeg') || mimeType.includes('jpg')) return 'jpeg';\n if (mimeType.includes('gif')) return 'gif';\n if (mimeType.includes('webp')) return 'webp';\n\n throw new AIError(\n `Unsupported image format for Bedrock: ${mimeType}`,\n 'INVALID_INPUT',\n 'bedrock',\n );\n }\n\n private resolveImageSize(options: ImageGenerationOptions): {\n width: number;\n height: number;\n } {\n if (options.size) {\n const [width, height] = options.size.split('x').map(Number);\n if (Number.isFinite(width) && Number.isFinite(height)) {\n return { width, height };\n }\n }\n\n const aspectRatioSizes: Record<string, { width: number; height: number }> =\n {\n '1:1': { width: 1024, height: 1024 },\n '2:3': { width: 768, height: 1152 },\n '3:2': { width: 1152, height: 768 },\n '3:5': { width: 768, height: 1280 },\n '5:3': { width: 1280, height: 768 },\n '7:9': { width: 896, height: 1152 },\n '9:7': { width: 1152, height: 896 },\n '6:11': { width: 768, height: 1408 },\n '11:6': { width: 1408, height: 768 },\n '5:11': { width: 640, height: 1408 },\n '11:5': { width: 1408, height: 640 },\n '9:5': { width: 1152, height: 640 },\n '16:9': { width: 1173, height: 640 },\n };\n\n return (\n aspectRatioSizes[options.aspectRatio || ''] || {\n width: 1024,\n height: 1024,\n }\n );\n }\n\n private mapImageQuality(quality?: string): string {\n if (!quality || quality === 'standard') {\n return 'standard';\n }\n\n if (quality === 'hd') {\n return 'premium';\n }\n\n return quality;\n }\n\n private safeJsonParse(input: string): any {\n try {\n return JSON.parse(input);\n } catch {\n return { rawArguments: input };\n }\n }\n\n private mapError(error: unknown): AIError {\n if (error instanceof AIError) {\n return error;\n }\n\n // Map common AWS error codes\n if (typeof error === 'object' && error !== null) {\n const awsError = error as { name?: string; message?: string };\n\n if (awsError.name === 'AccessDeniedException') {\n return new AuthenticationError('bedrock');\n }\n\n if (awsError.name === 'ThrottlingException') {\n return rateLimitErrorFrom('bedrock', error);\n }\n\n if (awsError.name === 'ResourceNotFoundException') {\n return new ModelNotFoundError(\n awsError.message || 'Model not found',\n 'bedrock',\n );\n }\n\n if (\n awsError.name === 'ValidationException' &&\n awsError.message?.includes('input is too long')\n ) {\n return new ContextLengthError('bedrock');\n }\n }\n\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown Bedrock error occurred';\n return new AIError(errorMessage, 'UNKNOWN_ERROR', 'bedrock');\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bedrock-CrtUO8yx.js","names":[],"sources":["../../src/shared/providers/bedrock.ts"],"sourcesContent":["/**\n * AWS Bedrock provider implementation\n */\n\nimport { rateLimitErrorFrom } from '../rate-limit';\nimport {\n normalizeBaseAIOptions,\n normalizeChatOptions,\n normalizeImageGenerationOptions,\n type PreparedRequestControls,\n prepareRequestControls,\n} from '../safety';\nimport type {\n AICapabilities,\n AIInterface,\n AIMessage,\n AIModel,\n AIResponse,\n BedrockOptions,\n ChatOptions,\n CompletionOptions,\n EmbeddingOptions,\n EmbeddingResponse,\n ImageDescriptionOptions,\n ImageEmbeddingOptions,\n ImageGenerationOptions,\n ImageGenerationResponse,\n MessageOptions,\n TokenUsage,\n TTSOptions,\n TTSResponse,\n VideoGenerationJob,\n VideoGenerationOptions,\n VideoGenerationResult,\n VideoGenerationStatusResult,\n Voice,\n VoiceCloneOptions,\n VoiceDesignOptions,\n VoiceListOptions,\n} from '../types';\nimport {\n AIError,\n AuthenticationError,\n ContextLengthError,\n extractTextContent,\n ModelNotFoundError,\n} from '../types';\nimport { emitUsage } from './usage';\n\nconst BEDROCK_DEFAULT_CHAT_MODEL = 'anthropic.claude-3-5-sonnet-20241022-v2:0';\nconst BEDROCK_TEXT_EMBEDDING_MODEL = 'amazon.titan-embed-text-v2:0';\nconst BEDROCK_IMAGE_EMBEDDING_MODEL = 'amazon.titan-embed-image-v1';\nconst BEDROCK_IMAGE_GENERATION_MODEL = 'amazon.titan-image-generator-v2:0';\n\n/**\n * System instruction standing in for a \"none\" tool choice, which Converse\n * lacks, when tools must still be declared (see `mapToolConfig`).\n */\nconst NO_TOOL_CALLS_INSTRUCTION =\n 'Do not call any tools in this response. Answer in text using the information already in the conversation.';\n\nexport class BedrockProvider implements AIInterface {\n private options: BedrockOptions;\n private client: any; // Will be BedrockRuntimeClient instance from @aws-sdk/client-bedrock-runtime\n\n constructor(options: BedrockOptions) {\n this.options = normalizeBaseAIOptions({\n defaultModel: BEDROCK_DEFAULT_CHAT_MODEL,\n ...options,\n });\n\n // Initialize AWS Bedrock client\n this.initializeClientSync();\n }\n\n private initializeClientSync() {\n try {\n // Dynamic import in constructor - this will work if the package is installed\n import('@aws-sdk/client-bedrock-runtime')\n .then(({ BedrockRuntimeClient }) => {\n this.client = new BedrockRuntimeClient({\n region: this.options.region,\n credentials: this.options.credentials,\n endpoint: this.options.endpoint,\n maxAttempts: (this.options.maxRetries || 0) + 1,\n });\n })\n .catch(() => {\n // Client will be null and we'll handle it in methods\n });\n } catch (_error) {\n // Client will be null and we'll handle it in methods\n }\n }\n\n private async ensureClient() {\n if (!this.client) {\n try {\n const { BedrockRuntimeClient } = await import(\n '@aws-sdk/client-bedrock-runtime'\n );\n this.client = new BedrockRuntimeClient({\n region: this.options.region,\n credentials: this.options.credentials,\n endpoint: this.options.endpoint,\n maxAttempts: (this.options.maxRetries || 0) + 1,\n });\n } catch (_error) {\n throw new AIError(\n 'Failed to initialize Bedrock client. Make sure @aws-sdk/client-bedrock-runtime is installed.',\n 'INITIALIZATION_ERROR',\n 'bedrock',\n );\n }\n }\n }\n\n async chat(\n messages: AIMessage[],\n options: ChatOptions = {},\n ): Promise<AIResponse> {\n const startTime = Date.now();\n let controls: PreparedRequestControls | undefined;\n try {\n await this.ensureClient();\n\n const modelId = options.model || this.options.defaultModel;\n options = normalizeChatOptions(this.options, options, 'bedrock', modelId);\n controls = prepareRequestControls(this.options, options);\n const response = this.mapConverseResponse(\n await this.client.converse(\n await this.buildConverseRequest(\n messages,\n options,\n modelId!,\n controls.signal,\n ),\n { abortSignal: controls.signal },\n ),\n modelId!,\n );\n\n emitUsage(\n this.options,\n 'bedrock',\n 'chat',\n response.model || modelId || 'unknown',\n response.usage,\n startTime,\n options.usageTags,\n );\n return response;\n } catch (error) {\n if (controls?.didTimeout()) {\n throw new AIError(\n `AI request timed out after ${controls.timeout}ms`,\n 'AI_TIMEOUT',\n 'bedrock',\n options.model,\n );\n }\n if (options.signal?.aborted) {\n throw new AIError(\n 'AI request aborted by caller',\n 'AI_ABORTED',\n 'bedrock',\n options.model,\n );\n }\n throw this.mapError(error);\n } finally {\n controls?.cleanup();\n }\n }\n\n async complete(\n prompt: string,\n options: CompletionOptions = {},\n ): Promise<AIResponse> {\n return this.chat([{ role: 'user', content: prompt }], {\n model: options.model,\n maxTokens: options.maxTokens,\n temperature: options.temperature,\n topP: options.topP,\n n: options.n,\n stop: options.stop,\n stream: options.stream,\n onProgress: options.onProgress,\n signal: options.signal,\n timeout: options.timeout,\n reasoning: options.reasoning,\n usageTags: options.usageTags,\n continueOnLength: options.continueOnLength,\n });\n }\n\n /**\n * Simple message interface for single-turn interactions with optional history\n *\n * @param text - The message text to send\n * @param options - Configuration options including history, model, etc.\n * @returns Promise resolving to the response content string\n */\n async message(text: string, options: MessageOptions = {}): Promise<string> {\n // Build messages array from history + current message\n const messages: AIMessage[] = [\n ...(options.history || []),\n { role: options.role || 'user', content: text },\n ];\n\n const response = await this.chat(messages, {\n model: options.model,\n maxTokens: options.maxTokens,\n temperature: options.temperature,\n topP: options.topP,\n stop: options.stop,\n stream: options.stream,\n frequencyPenalty: options.frequencyPenalty,\n presencePenalty: options.presencePenalty,\n responseFormat: options.responseFormat,\n seed: options.seed,\n tools: options.tools,\n toolChoice: options.toolChoice,\n onProgress: options.onProgress,\n signal: options.signal,\n timeout: options.timeout,\n reasoning: options.reasoning,\n usageTags: options.usageTags,\n continueOnLength: options.continueOnLength,\n });\n\n return response.content;\n }\n\n async embed(\n text: string | string[],\n options: EmbeddingOptions = {},\n ): Promise<EmbeddingResponse> {\n const startTime = Date.now();\n try {\n await this.ensureClient();\n\n const model = options.model || BEDROCK_TEXT_EMBEDDING_MODEL;\n const inputs = Array.isArray(text) ? text : [text];\n const embeddings: number[][] = [];\n let totalTokens = 0;\n\n for (const inputText of inputs) {\n const response = await this.client.invokeModel({\n modelId: model,\n contentType: 'application/json',\n accept: 'application/json',\n body: JSON.stringify({\n inputText,\n ...(options.dimensions && { dimensions: options.dimensions }),\n normalize: true,\n }),\n });\n\n const payload = await this.parseInvokeModelBody(response.body);\n const embedding = this.extractEmbeddingVector(payload);\n if (embedding) {\n embeddings.push(embedding);\n }\n\n totalTokens +=\n payload.inputTextTokenCount ||\n payload.inputTokenCount ||\n payload.tokenCount ||\n 0;\n }\n\n const usage: TokenUsage | undefined =\n totalTokens > 0\n ? {\n promptTokens: totalTokens,\n completionTokens: 0,\n totalTokens,\n }\n : undefined;\n\n emitUsage(\n this.options,\n 'bedrock',\n 'embed',\n model,\n usage,\n startTime,\n options.usageTags,\n );\n\n return {\n embeddings,\n model,\n usage,\n };\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async embedImage(\n image: string | Buffer,\n options: ImageEmbeddingOptions = {},\n ): Promise<EmbeddingResponse> {\n const startTime = Date.now();\n try {\n await this.ensureClient();\n\n const model = options.model || BEDROCK_IMAGE_EMBEDDING_MODEL;\n const response = await this.client.invokeModel({\n modelId: model,\n contentType: 'application/json',\n accept: 'application/json',\n body: JSON.stringify({\n inputImage: await this.imageToBase64(image),\n ...(options.dimensions && {\n embeddingConfig: {\n outputEmbeddingLength: options.dimensions,\n },\n }),\n }),\n });\n\n const payload = await this.parseInvokeModelBody(response.body);\n const embedding = this.extractEmbeddingVector(payload);\n\n emitUsage(\n this.options,\n 'bedrock',\n 'embedImage',\n model,\n undefined,\n startTime,\n );\n\n return {\n embeddings: embedding ? [embedding] : [],\n model,\n };\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async describeImage(\n image: string | Buffer,\n prompt?: string,\n options: ImageDescriptionOptions = {},\n ): Promise<string> {\n const imageUrl = await this.imageToDataUrl(image, options.signal);\n const response = await this.chat(\n [\n {\n role: 'user',\n content: [\n {\n type: 'text',\n text:\n prompt ||\n 'Describe this image for a search index. Include objects, mood, lighting, and any visible text.',\n },\n {\n type: 'image_url',\n image_url: { url: imageUrl },\n },\n ],\n },\n ],\n {\n model: options.model || this.options.defaultModel,\n maxTokens: options.maxTokens ?? 500,\n signal: options.signal,\n timeout: options.timeout,\n reasoning: options.reasoning,\n usageTags: options.usageTags,\n },\n );\n\n return response.content;\n }\n\n async generateImage(\n prompt: string,\n options: ImageGenerationOptions = {},\n ): Promise<ImageGenerationResponse> {\n let controls: PreparedRequestControls | undefined;\n try {\n await this.ensureClient();\n\n const model = options.model || BEDROCK_IMAGE_GENERATION_MODEL;\n options = normalizeImageGenerationOptions(\n this.options,\n options,\n 'bedrock',\n model,\n );\n controls = prepareRequestControls(this.options, options);\n const size = this.resolveImageSize(options);\n const response = await this.client.invokeModel(\n {\n modelId: model,\n contentType: 'application/json',\n accept: 'application/json',\n body: JSON.stringify({\n taskType: 'TEXT_IMAGE',\n textToImageParams: {\n text: prompt,\n ...(options.imageInput && {\n conditionImage: await this.imageToBase64(\n options.imageInput,\n controls.signal,\n ),\n }),\n },\n imageGenerationConfig: {\n numberOfImages: options.n,\n quality: this.mapImageQuality(options.quality),\n ...size,\n },\n }),\n },\n { abortSignal: controls.signal },\n );\n\n const payload = await this.parseInvokeModelBody(response.body);\n if (payload.error) {\n throw new AIError(payload.error, 'API_ERROR', 'bedrock');\n }\n\n const images = (payload.images || []).map((encoded: string) => {\n const mimeType = 'image/png';\n if (options.outputFormat === 'base64') {\n return { data: encoded, mimeType };\n }\n if (options.outputFormat === 'url') {\n return { data: `data:${mimeType};base64,${encoded}`, mimeType };\n }\n return {\n data: Buffer.from(encoded, 'base64'),\n mimeType,\n };\n });\n\n return {\n images,\n model,\n };\n } catch (error) {\n if (controls?.didTimeout()) {\n throw new AIError(\n `AI request timed out after ${controls.timeout}ms`,\n 'AI_TIMEOUT',\n 'bedrock',\n options.model,\n );\n }\n if (options.signal?.aborted) {\n throw new AIError(\n 'AI request aborted by caller',\n 'AI_ABORTED',\n 'bedrock',\n options.model,\n );\n }\n throw this.mapError(error);\n } finally {\n controls?.cleanup();\n }\n }\n\n async *stream(\n messages: AIMessage[],\n options: ChatOptions = {},\n ): AsyncIterable<string> {\n const startTime = Date.now();\n let controls: PreparedRequestControls | undefined;\n try {\n await this.ensureClient();\n\n const modelId = options.model || this.options.defaultModel;\n options = normalizeChatOptions(this.options, options, 'bedrock', modelId);\n controls = prepareRequestControls(this.options, options);\n const response = await this.client.converseStream(\n await this.buildConverseRequest(\n messages,\n options,\n modelId!,\n controls.signal,\n ),\n { abortSignal: controls.signal },\n );\n\n let usage: TokenUsage | undefined;\n let streamStopReason: string | null | undefined;\n\n for await (const event of response.stream || []) {\n if (event.messageStop?.stopReason) {\n streamStopReason = event.messageStop.stopReason;\n }\n const text = event.contentBlockDelta?.delta?.text;\n if (text) {\n if (options.onProgress) {\n options.onProgress(text);\n }\n yield text;\n }\n\n if (event.metadata?.usage) {\n usage = {\n promptTokens: event.metadata.usage.inputTokens || 0,\n completionTokens: event.metadata.usage.outputTokens || 0,\n totalTokens: event.metadata.usage.totalTokens || 0,\n };\n }\n }\n\n options.onFinishReason?.(\n this.mapBedrockFinishReason(streamStopReason) ?? 'stop',\n );\n\n emitUsage(\n this.options,\n 'bedrock',\n 'stream',\n modelId || 'unknown',\n usage,\n startTime,\n options.usageTags,\n );\n } catch (error) {\n if (controls?.didTimeout()) {\n throw new AIError(\n `AI request timed out after ${controls.timeout}ms`,\n 'AI_TIMEOUT',\n 'bedrock',\n options.model,\n );\n }\n if (options.signal?.aborted) {\n throw new AIError(\n 'AI request aborted by caller',\n 'AI_ABORTED',\n 'bedrock',\n options.model,\n );\n }\n throw this.mapError(error);\n } finally {\n controls?.cleanup();\n }\n }\n\n async countTokens(text: string): Promise<number> {\n try {\n await this.ensureClient();\n\n const modelId = this.options.defaultModel || BEDROCK_DEFAULT_CHAT_MODEL;\n const response = await this.client.countTokens({\n modelId,\n input: {\n converse: {\n messages: [\n {\n role: 'user',\n content: [{ text }],\n },\n ],\n },\n },\n });\n\n return response.inputTokens || Math.ceil(text.length / 4);\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async getModels(): Promise<AIModel[]> {\n // Return static list of popular Bedrock models\n return [\n // Anthropic Claude models\n {\n id: 'anthropic.claude-3-5-sonnet-20241022-v2:0',\n name: 'Claude 3.5 Sonnet v2',\n description: 'Latest Claude 3.5 Sonnet model on Bedrock',\n contextLength: 200000,\n capabilities: ['text', 'chat', 'vision', 'functions'],\n supportsFunctions: true,\n supportsVision: true,\n },\n {\n id: 'anthropic.claude-3-opus-20240229-v1:0',\n name: 'Claude 3 Opus',\n description: 'Most powerful Claude model on Bedrock',\n contextLength: 200000,\n capabilities: ['text', 'chat', 'vision'],\n supportsFunctions: false,\n supportsVision: true,\n },\n // Amazon Titan models\n {\n id: 'amazon.titan-text-premier-v1:0',\n name: 'Titan Text Premier',\n description: 'Premier Amazon Titan text model',\n contextLength: 32000,\n capabilities: ['text', 'chat'],\n supportsFunctions: false,\n supportsVision: false,\n },\n {\n id: 'amazon.titan-embed-text-v1',\n name: 'Titan Embeddings Text',\n description: 'Amazon Titan text embeddings model',\n contextLength: 8192,\n capabilities: ['embeddings'],\n supportsFunctions: false,\n supportsVision: false,\n },\n {\n id: BEDROCK_TEXT_EMBEDDING_MODEL,\n name: 'Titan Embeddings Text V2',\n description: 'Amazon Titan text embeddings v2 model',\n contextLength: 8192,\n capabilities: ['embeddings'],\n supportsFunctions: false,\n supportsVision: false,\n },\n {\n id: BEDROCK_IMAGE_EMBEDDING_MODEL,\n name: 'Titan Multimodal Embeddings G1',\n description:\n 'Amazon Titan multimodal embeddings model for image similarity',\n contextLength: 256,\n capabilities: ['embeddings', 'image_embedding'],\n supportsFunctions: false,\n supportsVision: false,\n },\n {\n id: BEDROCK_IMAGE_GENERATION_MODEL,\n name: 'Titan Image Generator V2',\n description: 'Amazon Titan image generation model',\n contextLength: 0,\n capabilities: ['image_generation'],\n supportsFunctions: false,\n supportsVision: false,\n },\n // Cohere models\n {\n id: 'cohere.command-r-plus-v1:0',\n name: 'Command R+',\n description: 'Cohere Command R+ model with advanced capabilities',\n contextLength: 128000,\n capabilities: ['text', 'chat', 'functions'],\n supportsFunctions: true,\n supportsVision: false,\n },\n // Meta Llama models\n {\n id: 'meta.llama3-1-405b-instruct-v1:0',\n name: 'Llama 3.1 405B Instruct',\n description: 'Meta Llama 3.1 405B instruction-tuned model',\n contextLength: 128000,\n capabilities: ['text', 'chat'],\n supportsFunctions: false,\n supportsVision: false,\n },\n ];\n }\n\n async getCapabilities(): Promise<AICapabilities> {\n return {\n chat: true,\n completion: true,\n embeddings: true,\n streaming: true,\n functions: true, // Some models support function calling\n vision: true, // Some models support vision\n fineTuning: true, // Via Bedrock fine-tuning\n imageEmbeddings: true,\n imageGeneration: true,\n videoGeneration: false,\n tts: false,\n voiceCloning: false,\n voiceDesign: false,\n maxContextLength: 200000,\n supportedOperations: [\n 'chat',\n 'completion',\n 'embedding',\n 'streaming',\n 'functions',\n 'vision',\n 'image_embedding',\n 'image_generation',\n ],\n };\n }\n\n // ============================================================================\n // Video Generation Methods (Not supported - use gemini, byteplus-modelark,\n // or openai-compat-video provider)\n // ============================================================================\n\n async submitVideoGenerationJob(\n _options: VideoGenerationOptions,\n ): Promise<VideoGenerationJob> {\n throw new AIError(\n 'Video generation is not supported by Bedrock provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n }\n\n async getVideoGenerationJob(\n _handle: VideoGenerationJob,\n ): Promise<VideoGenerationStatusResult> {\n throw new AIError(\n 'Video generation is not supported by Bedrock provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n }\n\n async fetchVideoGenerationResult(\n _handle: VideoGenerationJob,\n ): Promise<VideoGenerationResult> {\n throw new AIError(\n 'Video generation is not supported by Bedrock provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n }\n\n async cancelVideoGenerationJob(_handle: VideoGenerationJob): Promise<void> {\n throw new AIError(\n 'Video generation is not supported by Bedrock provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n }\n\n async validateVideoGenerationAccess(): Promise<boolean> {\n throw new AIError(\n 'Video generation is not supported by Bedrock provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n }\n\n // ============================================================================\n // TTS Methods (Not supported - use Qwen3-TTS provider)\n // ============================================================================\n\n async synthesizeSpeech(\n _text: string,\n _options?: TTSOptions,\n ): Promise<TTSResponse> {\n throw new AIError(\n 'TTS is not supported by Bedrock provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n }\n\n streamSpeech(_text: string, _options?: TTSOptions): AsyncIterable<Buffer> {\n const error = new AIError(\n 'TTS streaming is not supported by Bedrock provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n return {\n [Symbol.asyncIterator]: () => ({\n next: () => Promise.reject(error),\n }),\n };\n }\n\n async cloneVoice(_options: VoiceCloneOptions): Promise<Voice> {\n throw new AIError(\n 'Voice cloning is not supported by Bedrock provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n }\n\n async designVoice(_options: VoiceDesignOptions): Promise<Voice> {\n throw new AIError(\n 'Voice design is not supported by Bedrock provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n }\n\n async getVoices(_options?: VoiceListOptions): Promise<Voice[]> {\n throw new AIError(\n 'Voice listing is not supported by Bedrock provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n }\n\n private async buildConverseRequest(\n messages: AIMessage[],\n options: ChatOptions,\n modelId: string,\n signal?: AbortSignal,\n ): Promise<Record<string, any>> {\n const { system, bedrockMessages } = await this.mapMessagesToBedrock(\n messages,\n signal,\n );\n const toolConfig = this.mapToolConfig(options, bedrockMessages);\n const systemPrompt = [\n system,\n options.responseFormat?.type === 'json_object'\n ? 'Respond with valid JSON only. Do not include explanatory text outside the JSON object.'\n : undefined,\n toolConfig && (options.toolChoice === 'none' || !options.tools?.length)\n ? NO_TOOL_CALLS_INSTRUCTION\n : undefined,\n ]\n .filter(Boolean)\n .join('\\n\\n');\n\n const inferenceConfig = Object.fromEntries(\n Object.entries({\n maxTokens: options.maxTokens,\n temperature: options.temperature,\n topP: options.topP,\n stopSequences: Array.isArray(options.stop)\n ? options.stop\n : options.stop\n ? [options.stop]\n : undefined,\n }).filter(([, value]) => value !== undefined),\n );\n\n const request: Record<string, any> = {\n modelId,\n messages: bedrockMessages,\n ...(Object.keys(inferenceConfig).length > 0 && { inferenceConfig }),\n ...(systemPrompt && { system: [{ text: systemPrompt }] }),\n };\n if ((options.reasoning?.maxTokens || 0) > 0) {\n request.additionalModelRequestFields = {\n thinking: {\n type: 'enabled',\n budget_tokens: options.reasoning?.maxTokens,\n },\n };\n }\n\n if (toolConfig) {\n request.toolConfig = toolConfig;\n }\n\n return request;\n }\n\n private async mapMessagesToBedrock(\n messages: AIMessage[],\n signal?: AbortSignal,\n ): Promise<{\n system?: string;\n bedrockMessages: Array<{ role: 'user' | 'assistant'; content: any[] }>;\n }> {\n let system: string | undefined;\n const bedrockMessages: Array<{\n role: 'user' | 'assistant';\n content: any[];\n }> = [];\n\n for (const message of messages) {\n const textContent = extractTextContent(message.content);\n if (message.role === 'system') {\n system = system ? `${system}\\n\\n${textContent}` : textContent;\n continue;\n }\n\n if (message.role === 'tool' && message.tool_call_id) {\n // Converse pairs results with calls by toolUseId, and all results\n // for one assistant turn must share the following user turn.\n const block = {\n toolResult: {\n toolUseId: message.tool_call_id,\n content: [{ text: textContent }],\n },\n };\n const previous = bedrockMessages[bedrockMessages.length - 1];\n if (\n previous?.role === 'user' &&\n previous.content.every((part) => part.toolResult)\n ) {\n previous.content.push(block);\n } else {\n bedrockMessages.push({ role: 'user', content: [block] });\n }\n continue;\n }\n\n const content: any[] = [];\n if (typeof message.content === 'string') {\n // Converse rejects empty text blocks (e.g. tool-call-only turns).\n if (message.content) content.push({ text: message.content });\n } else {\n for (const part of message.content) {\n if (part.type === 'text') {\n content.push({ text: part.text });\n continue;\n }\n\n const image = await this.imageUrlToBedrockImage(\n part.image_url.url,\n signal,\n );\n content.push({ image });\n }\n }\n\n if (message.role === 'assistant' && message.tool_calls) {\n for (const toolCall of message.tool_calls) {\n content.push({\n toolUse: {\n toolUseId: toolCall.id,\n name: toolCall.function.name,\n input: this.safeJsonParse(toolCall.function.arguments),\n },\n });\n }\n }\n\n if (content.length === 0 && textContent) {\n content.push({ text: textContent });\n }\n\n bedrockMessages.push({\n role: message.role === 'assistant' ? 'assistant' : 'user',\n content,\n });\n }\n\n return { system, bedrockMessages };\n }\n\n private mapConverseResponse(response: any, modelId: string): AIResponse {\n const contentBlocks = response.output?.message?.content || [];\n const textContent = contentBlocks\n .filter((block: any) => typeof block.text === 'string')\n .map((block: any) => block.text)\n .join('');\n\n const toolCalls = contentBlocks\n .filter((block: any) => block.toolUse)\n .map((block: any) => ({\n id: block.toolUse.toolUseId,\n type: 'function' as const,\n function: {\n name: block.toolUse.name,\n arguments: JSON.stringify(block.toolUse.input || {}),\n },\n }));\n\n const usage =\n response.usage &&\n ({\n promptTokens: response.usage.inputTokens || 0,\n completionTokens: response.usage.outputTokens || 0,\n totalTokens: response.usage.totalTokens || 0,\n } satisfies TokenUsage);\n\n return {\n content: textContent,\n model: modelId,\n finishReason: this.mapBedrockFinishReason(response.stopReason),\n usage,\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n };\n }\n\n private mapBedrockFinishReason(\n reason: string | null | undefined,\n ): AIResponse['finishReason'] {\n switch (reason) {\n case 'end_turn':\n return 'stop';\n case 'max_tokens':\n return 'length';\n case 'stop_sequence':\n return 'stop';\n case 'tool_use':\n return 'tool_calls';\n default:\n return 'stop';\n }\n }\n\n /**\n * Builds the Converse `toolConfig`.\n *\n * Converse rejects a request whose history contains `toolUse` or\n * `toolResult` blocks unless `toolConfig` is present, and it has no \"none\"\n * tool choice. So:\n * - declared tools are always sent; `toolChoice: 'none'` omits the\n * `toolChoice` field and the caller adds {@link NO_TOOL_CALLS_INSTRUCTION}\n * to the system prompt (an instruction, not a hard guarantee);\n * - with no declared tools, a history that uses tools (a tool loop's final,\n * tool-less round) gets a minimal spec for each tool it references, so\n * the request is valid, again with the no-tool-calls instruction.\n */\n private mapToolConfig(\n options: ChatOptions,\n bedrockMessages: Array<{ role: 'user' | 'assistant'; content: any[] }>,\n ): Record<string, any> | undefined {\n if (options.tools && options.tools.length > 0) {\n const toolChoice =\n options.toolChoice && options.toolChoice !== 'none'\n ? this.mapToolChoice(options.toolChoice)\n : undefined;\n return {\n tools: options.tools.map((tool) => ({\n toolSpec: {\n name: tool.function.name,\n description: tool.function.description || '',\n inputSchema: {\n json: tool.function.parameters || { type: 'object' },\n },\n },\n })),\n ...(toolChoice && { toolChoice }),\n };\n }\n\n const historyToolNames = new Set<string>();\n for (const message of bedrockMessages) {\n for (const block of message.content) {\n if (block.toolUse?.name) historyToolNames.add(block.toolUse.name);\n }\n }\n if (historyToolNames.size === 0) {\n return undefined;\n }\n\n return {\n tools: [...historyToolNames].map((name) => ({\n toolSpec: {\n name,\n description:\n 'Used earlier in this conversation; not available for this turn.',\n inputSchema: { json: { type: 'object' } },\n },\n })),\n };\n }\n\n private mapToolChoice(\n toolChoice?:\n | 'auto'\n | 'none'\n | { type: 'function'; function: { name: string } },\n ): Record<string, any> | undefined {\n if (!toolChoice || toolChoice === 'auto') {\n return { auto: {} };\n }\n\n if (toolChoice === 'none') {\n return undefined;\n }\n\n return {\n tool: {\n name: toolChoice.function.name,\n },\n };\n }\n\n private async parseInvokeModelBody(body: unknown): Promise<any> {\n const bytes =\n typeof (body as any)?.transformToByteArray === 'function'\n ? await (body as any).transformToByteArray()\n : body instanceof Uint8Array\n ? body\n : Buffer.isBuffer(body)\n ? body\n : new Uint8Array(body as ArrayBuffer);\n return JSON.parse(new TextDecoder().decode(bytes));\n }\n\n private extractEmbeddingVector(payload: any): number[] | undefined {\n if (Array.isArray(payload.embedding)) {\n return payload.embedding;\n }\n\n if (Array.isArray(payload.embeddings?.[0])) {\n return payload.embeddings[0];\n }\n\n if (Array.isArray(payload.embeddingsByType?.float)) {\n return payload.embeddingsByType.float;\n }\n\n if (Array.isArray(payload.vector)) {\n return payload.vector;\n }\n\n return undefined;\n }\n\n private async imageUrlToBedrockImage(\n imageUrl: string,\n signal?: AbortSignal,\n ): Promise<any> {\n const { bytes, mimeType } = await this.imageToBytes(imageUrl, signal);\n return {\n format: this.mimeTypeToBedrockImageFormat(mimeType),\n source: { bytes },\n };\n }\n\n private async imageToDataUrl(\n image: string | Buffer,\n signal?: AbortSignal,\n ): Promise<string> {\n if (Buffer.isBuffer(image)) {\n return `data:image/png;base64,${image.toString('base64')}`;\n }\n if (image.startsWith('data:')) {\n return image;\n }\n\n const { bytes, mimeType } = await this.imageToBytes(image, signal);\n return `data:${mimeType};base64,${Buffer.from(bytes).toString('base64')}`;\n }\n\n private async imageToBase64(\n image: string | Buffer,\n signal?: AbortSignal,\n ): Promise<string> {\n if (Buffer.isBuffer(image)) {\n return image.toString('base64');\n }\n if (image.startsWith('data:')) {\n const match = image.match(/^data:([^;]+);base64,(.+)$/);\n if (!match) {\n throw new AIError(\n 'Invalid base64 data URL format',\n 'INVALID_INPUT',\n 'bedrock',\n );\n }\n return match[2];\n }\n\n const { bytes } = await this.imageToBytes(image, signal);\n return Buffer.from(bytes).toString('base64');\n }\n\n private async imageToBytes(\n image: string,\n signal?: AbortSignal,\n ): Promise<{ bytes: Uint8Array; mimeType: string }> {\n if (image.startsWith('data:')) {\n const match = image.match(/^data:([^;]+);base64,(.+)$/);\n if (!match) {\n throw new AIError(\n 'Invalid base64 data URL format',\n 'INVALID_INPUT',\n 'bedrock',\n );\n }\n\n return {\n bytes: Uint8Array.from(Buffer.from(match[2], 'base64')),\n mimeType: match[1],\n };\n }\n\n const response = await fetch(image, { signal });\n if (!response.ok) {\n throw new AIError(\n `Failed to fetch image: ${response.status} ${response.statusText}`,\n 'IMAGE_FETCH_ERROR',\n 'bedrock',\n );\n }\n\n const arrayBuffer = await response.arrayBuffer();\n return {\n bytes: new Uint8Array(arrayBuffer),\n mimeType: response.headers.get('content-type') || 'image/png',\n };\n }\n\n private mimeTypeToBedrockImageFormat(mimeType: string): string {\n if (mimeType.includes('png')) return 'png';\n if (mimeType.includes('jpeg') || mimeType.includes('jpg')) return 'jpeg';\n if (mimeType.includes('gif')) return 'gif';\n if (mimeType.includes('webp')) return 'webp';\n\n throw new AIError(\n `Unsupported image format for Bedrock: ${mimeType}`,\n 'INVALID_INPUT',\n 'bedrock',\n );\n }\n\n private resolveImageSize(options: ImageGenerationOptions): {\n width: number;\n height: number;\n } {\n if (options.size) {\n const [width, height] = options.size.split('x').map(Number);\n if (Number.isFinite(width) && Number.isFinite(height)) {\n return { width, height };\n }\n }\n\n const aspectRatioSizes: Record<string, { width: number; height: number }> =\n {\n '1:1': { width: 1024, height: 1024 },\n '2:3': { width: 768, height: 1152 },\n '3:2': { width: 1152, height: 768 },\n '3:5': { width: 768, height: 1280 },\n '5:3': { width: 1280, height: 768 },\n '7:9': { width: 896, height: 1152 },\n '9:7': { width: 1152, height: 896 },\n '6:11': { width: 768, height: 1408 },\n '11:6': { width: 1408, height: 768 },\n '5:11': { width: 640, height: 1408 },\n '11:5': { width: 1408, height: 640 },\n '9:5': { width: 1152, height: 640 },\n '16:9': { width: 1173, height: 640 },\n };\n\n return (\n aspectRatioSizes[options.aspectRatio || ''] || {\n width: 1024,\n height: 1024,\n }\n );\n }\n\n private mapImageQuality(quality?: string): string {\n if (!quality || quality === 'standard') {\n return 'standard';\n }\n\n if (quality === 'hd') {\n return 'premium';\n }\n\n return quality;\n }\n\n private safeJsonParse(input: string): any {\n try {\n return JSON.parse(input);\n } catch {\n return { rawArguments: input };\n }\n }\n\n private mapError(error: unknown): AIError {\n if (error instanceof AIError) {\n return error;\n }\n\n // Map common AWS error codes\n if (typeof error === 'object' && error !== null) {\n const awsError = error as { name?: string; message?: string };\n\n if (awsError.name === 'AccessDeniedException') {\n return new AuthenticationError('bedrock');\n }\n\n if (awsError.name === 'ThrottlingException') {\n return rateLimitErrorFrom('bedrock', error);\n }\n\n if (awsError.name === 'ResourceNotFoundException') {\n return new ModelNotFoundError(\n awsError.message || 'Model not found',\n 'bedrock',\n );\n }\n\n if (\n awsError.name === 'ValidationException' &&\n awsError.message?.includes('input is too long')\n ) {\n return new ContextLengthError('bedrock');\n }\n }\n\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown Bedrock error occurred';\n return new AIError(errorMessage, 'UNKNOWN_ERROR', 'bedrock');\n }\n}\n"],"mappings":"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"}
|