@tanstack/ai-anthropic 0.4.1 → 0.5.0
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/dist/esm/adapters/text.d.ts +9 -0
- package/dist/esm/adapters/text.js +87 -33
- package/dist/esm/adapters/text.js.map +1 -1
- package/dist/esm/index.d.ts +2 -1
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/model-meta.d.ts +44 -21
- package/dist/esm/model-meta.js +46 -0
- package/dist/esm/model-meta.js.map +1 -0
- package/dist/esm/text/text-provider-options.d.ts +32 -1
- package/dist/esm/text/text-provider-options.js.map +1 -1
- package/dist/esm/utils/client.d.ts +2 -2
- package/dist/esm/utils/client.js +1 -0
- package/dist/esm/utils/client.js.map +1 -1
- package/package.json +4 -4
- package/src/adapters/text.ts +121 -37
- package/src/index.ts +2 -1
- package/src/model-meta.ts +66 -24
- package/src/text/text-provider-options.ts +39 -1
- package/src/utils/client.ts +3 -1
|
@@ -45,6 +45,15 @@ export declare class AnthropicTextAdapter<TModel extends (typeof ANTHROPIC_MODEL
|
|
|
45
45
|
private mapCommonOptionsToAnthropic;
|
|
46
46
|
private convertContentPartToAnthropic;
|
|
47
47
|
private formatMessages;
|
|
48
|
+
/**
|
|
49
|
+
* Merge consecutive messages of the same role into a single message.
|
|
50
|
+
* Anthropic's API requires strictly alternating user/assistant roles.
|
|
51
|
+
* Tool results are wrapped as role:'user' messages, which can collide
|
|
52
|
+
* with actual user messages in multi-turn conversations.
|
|
53
|
+
*
|
|
54
|
+
* Also filters out empty assistant messages (e.g., from a previous failed request).
|
|
55
|
+
*/
|
|
56
|
+
private mergeConsecutiveSameRoleMessages;
|
|
48
57
|
private processAnthropicStream;
|
|
49
58
|
}
|
|
50
59
|
/**
|
|
@@ -112,6 +112,7 @@ class AnthropicTextAdapter extends BaseTextAdapter {
|
|
|
112
112
|
const validKeys = [
|
|
113
113
|
"container",
|
|
114
114
|
"context_management",
|
|
115
|
+
"effort",
|
|
115
116
|
"mcp_servers",
|
|
116
117
|
"service_tier",
|
|
117
118
|
"stop_sequences",
|
|
@@ -270,7 +271,49 @@ class AnthropicTextAdapter extends BaseTextAdapter {
|
|
|
270
271
|
) : ""
|
|
271
272
|
});
|
|
272
273
|
}
|
|
273
|
-
return formattedMessages;
|
|
274
|
+
return this.mergeConsecutiveSameRoleMessages(formattedMessages);
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Merge consecutive messages of the same role into a single message.
|
|
278
|
+
* Anthropic's API requires strictly alternating user/assistant roles.
|
|
279
|
+
* Tool results are wrapped as role:'user' messages, which can collide
|
|
280
|
+
* with actual user messages in multi-turn conversations.
|
|
281
|
+
*
|
|
282
|
+
* Also filters out empty assistant messages (e.g., from a previous failed request).
|
|
283
|
+
*/
|
|
284
|
+
mergeConsecutiveSameRoleMessages(messages) {
|
|
285
|
+
const merged = [];
|
|
286
|
+
for (const msg of messages) {
|
|
287
|
+
if (msg.role === "assistant") {
|
|
288
|
+
const hasContent = Array.isArray(msg.content) ? msg.content.length > 0 : typeof msg.content === "string" && msg.content.length > 0;
|
|
289
|
+
if (!hasContent) {
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
const prev = merged[merged.length - 1];
|
|
294
|
+
if (prev && prev.role === msg.role) {
|
|
295
|
+
const prevBlocks = Array.isArray(prev.content) ? prev.content : typeof prev.content === "string" && prev.content ? [{ type: "text", text: prev.content }] : [];
|
|
296
|
+
const msgBlocks = Array.isArray(msg.content) ? msg.content : typeof msg.content === "string" && msg.content ? [{ type: "text", text: msg.content }] : [];
|
|
297
|
+
prev.content = [...prevBlocks, ...msgBlocks];
|
|
298
|
+
} else {
|
|
299
|
+
merged.push({ ...msg });
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
for (const msg of merged) {
|
|
303
|
+
if (Array.isArray(msg.content)) {
|
|
304
|
+
const seenToolResultIds = /* @__PURE__ */ new Set();
|
|
305
|
+
msg.content = msg.content.filter((block) => {
|
|
306
|
+
if (block.type === "tool_result" && block.tool_use_id) {
|
|
307
|
+
if (seenToolResultIds.has(block.tool_use_id)) {
|
|
308
|
+
return false;
|
|
309
|
+
}
|
|
310
|
+
seenToolResultIds.add(block.tool_use_id);
|
|
311
|
+
}
|
|
312
|
+
return true;
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return merged;
|
|
274
317
|
}
|
|
275
318
|
async *processAnthropicStream(stream, model, genId) {
|
|
276
319
|
let accumulatedContent = "";
|
|
@@ -283,6 +326,8 @@ class AnthropicTextAdapter extends BaseTextAdapter {
|
|
|
283
326
|
let stepId = null;
|
|
284
327
|
let hasEmittedRunStarted = false;
|
|
285
328
|
let hasEmittedTextMessageStart = false;
|
|
329
|
+
let hasEmittedRunFinished = false;
|
|
330
|
+
let currentBlockType = null;
|
|
286
331
|
try {
|
|
287
332
|
for await (const event of stream) {
|
|
288
333
|
if (!hasEmittedRunStarted) {
|
|
@@ -295,6 +340,7 @@ class AnthropicTextAdapter extends BaseTextAdapter {
|
|
|
295
340
|
};
|
|
296
341
|
}
|
|
297
342
|
if (event.type === "content_block_start") {
|
|
343
|
+
currentBlockType = event.content_block.type;
|
|
298
344
|
if (event.content_block.type === "tool_use") {
|
|
299
345
|
currentToolIndex++;
|
|
300
346
|
toolCallsMap.set(currentToolIndex, {
|
|
@@ -373,53 +419,61 @@ class AnthropicTextAdapter extends BaseTextAdapter {
|
|
|
373
419
|
}
|
|
374
420
|
}
|
|
375
421
|
} else if (event.type === "content_block_stop") {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
if (
|
|
379
|
-
existing.started
|
|
422
|
+
if (currentBlockType === "tool_use") {
|
|
423
|
+
const existing = toolCallsMap.get(currentToolIndex);
|
|
424
|
+
if (existing) {
|
|
425
|
+
if (!existing.started) {
|
|
426
|
+
existing.started = true;
|
|
427
|
+
yield {
|
|
428
|
+
type: "TOOL_CALL_START",
|
|
429
|
+
toolCallId: existing.id,
|
|
430
|
+
toolName: existing.name,
|
|
431
|
+
model,
|
|
432
|
+
timestamp,
|
|
433
|
+
index: currentToolIndex
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
let parsedInput = {};
|
|
437
|
+
try {
|
|
438
|
+
const parsed = existing.input ? JSON.parse(existing.input) : {};
|
|
439
|
+
parsedInput = parsed && typeof parsed === "object" ? parsed : {};
|
|
440
|
+
} catch {
|
|
441
|
+
parsedInput = {};
|
|
442
|
+
}
|
|
380
443
|
yield {
|
|
381
|
-
type: "
|
|
444
|
+
type: "TOOL_CALL_END",
|
|
382
445
|
toolCallId: existing.id,
|
|
383
446
|
toolName: existing.name,
|
|
384
447
|
model,
|
|
385
448
|
timestamp,
|
|
386
|
-
|
|
449
|
+
input: parsedInput
|
|
387
450
|
};
|
|
451
|
+
hasEmittedTextMessageStart = false;
|
|
388
452
|
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
453
|
+
} else {
|
|
454
|
+
if (hasEmittedTextMessageStart && accumulatedContent) {
|
|
455
|
+
yield {
|
|
456
|
+
type: "TEXT_MESSAGE_END",
|
|
457
|
+
messageId,
|
|
458
|
+
model,
|
|
459
|
+
timestamp
|
|
460
|
+
};
|
|
395
461
|
}
|
|
396
|
-
yield {
|
|
397
|
-
type: "TOOL_CALL_END",
|
|
398
|
-
toolCallId: existing.id,
|
|
399
|
-
toolName: existing.name,
|
|
400
|
-
model,
|
|
401
|
-
timestamp,
|
|
402
|
-
input: parsedInput
|
|
403
|
-
};
|
|
404
462
|
}
|
|
405
|
-
|
|
463
|
+
currentBlockType = null;
|
|
464
|
+
} else if (event.type === "message_stop") {
|
|
465
|
+
if (!hasEmittedRunFinished) {
|
|
406
466
|
yield {
|
|
407
|
-
type: "
|
|
408
|
-
|
|
467
|
+
type: "RUN_FINISHED",
|
|
468
|
+
runId,
|
|
409
469
|
model,
|
|
410
|
-
timestamp
|
|
470
|
+
timestamp,
|
|
471
|
+
finishReason: "stop"
|
|
411
472
|
};
|
|
412
473
|
}
|
|
413
|
-
} else if (event.type === "message_stop") {
|
|
414
|
-
yield {
|
|
415
|
-
type: "RUN_FINISHED",
|
|
416
|
-
runId,
|
|
417
|
-
model,
|
|
418
|
-
timestamp,
|
|
419
|
-
finishReason: "stop"
|
|
420
|
-
};
|
|
421
474
|
} else if (event.type === "message_delta") {
|
|
422
475
|
if (event.delta.stop_reason) {
|
|
476
|
+
hasEmittedRunFinished = true;
|
|
423
477
|
switch (event.delta.stop_reason) {
|
|
424
478
|
case "tool_use": {
|
|
425
479
|
yield {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.js","sources":["../../../src/adapters/text.ts"],"sourcesContent":["import { BaseTextAdapter } from '@tanstack/ai/adapters'\nimport { convertToolsToProviderFormat } from '../tools/tool-converter'\nimport { validateTextProviderOptions } from '../text/text-provider-options'\nimport {\n createAnthropicClient,\n generateId,\n getAnthropicApiKeyFromEnv,\n} from '../utils'\nimport type {\n ANTHROPIC_MODELS,\n AnthropicChatModelProviderOptionsByName,\n AnthropicModelInputModalitiesByName,\n} from '../model-meta'\nimport type {\n StructuredOutputOptions,\n StructuredOutputResult,\n} from '@tanstack/ai/adapters'\nimport type {\n Base64ImageSource,\n Base64PDFSource,\n DocumentBlockParam,\n ImageBlockParam,\n MessageParam,\n TextBlockParam,\n URLImageSource,\n URLPDFSource,\n} from '@anthropic-ai/sdk/resources/messages'\nimport type Anthropic_SDK from '@anthropic-ai/sdk'\nimport type {\n ContentPart,\n Modality,\n ModelMessage,\n StreamChunk,\n TextOptions,\n} from '@tanstack/ai'\nimport type {\n ExternalTextProviderOptions,\n InternalTextProviderOptions,\n} from '../text/text-provider-options'\nimport type {\n AnthropicDocumentMetadata,\n AnthropicImageMetadata,\n AnthropicMessageMetadataByModality,\n AnthropicTextMetadata,\n} from '../message-types'\nimport type { AnthropicClientConfig } from '../utils'\n\n/**\n * Configuration for Anthropic text adapter\n */\nexport interface AnthropicTextConfig extends AnthropicClientConfig {}\n\n/**\n * Anthropic-specific provider options for text/chat\n */\nexport type AnthropicTextProviderOptions = ExternalTextProviderOptions\n\ntype AnthropicContentBlocks =\n Extract<MessageParam['content'], Array<unknown>> extends Array<infer Block>\n ? Array<Block>\n : never\ntype AnthropicContentBlock =\n AnthropicContentBlocks extends Array<infer Block> ? Block : never\n\n// ===========================\n// Type Resolution Helpers\n// ===========================\n\n/**\n * Resolve provider options for a specific model.\n * If the model has explicit options in the map, use those; otherwise use base options.\n */\ntype ResolveProviderOptions<TModel extends string> =\n TModel extends keyof AnthropicChatModelProviderOptionsByName\n ? AnthropicChatModelProviderOptionsByName[TModel]\n : AnthropicTextProviderOptions\n\n/**\n * Resolve input modalities for a specific model.\n * If the model has explicit modalities in the map, use those; otherwise use default.\n */\ntype ResolveInputModalities<TModel extends string> =\n TModel extends keyof AnthropicModelInputModalitiesByName\n ? AnthropicModelInputModalitiesByName[TModel]\n : readonly ['text', 'image', 'document']\n\n// ===========================\n// Adapter Implementation\n// ===========================\n\n/**\n * Anthropic Text (Chat) Adapter\n *\n * Tree-shakeable adapter for Anthropic chat/text completion functionality.\n * Import only what you need for smaller bundle sizes.\n */\nexport class AnthropicTextAdapter<\n TModel extends (typeof ANTHROPIC_MODELS)[number],\n TProviderOptions extends object = ResolveProviderOptions<TModel>,\n TInputModalities extends ReadonlyArray<Modality> =\n ResolveInputModalities<TModel>,\n> extends BaseTextAdapter<\n TModel,\n TProviderOptions,\n TInputModalities,\n AnthropicMessageMetadataByModality\n> {\n readonly kind = 'text' as const\n readonly name = 'anthropic' as const\n\n private client: Anthropic_SDK\n\n constructor(config: AnthropicTextConfig, model: TModel) {\n super({}, model)\n this.client = createAnthropicClient(config)\n }\n\n async *chatStream(\n options: TextOptions<AnthropicTextProviderOptions>,\n ): AsyncIterable<StreamChunk> {\n try {\n const requestParams = this.mapCommonOptionsToAnthropic(options)\n\n const stream = await this.client.beta.messages.create(\n { ...requestParams, stream: true },\n {\n signal: options.request?.signal,\n headers: options.request?.headers,\n },\n )\n\n yield* this.processAnthropicStream(stream, options.model, () =>\n generateId(this.name),\n )\n } catch (error: unknown) {\n const err = error as Error & { status?: number; code?: string }\n yield {\n type: 'RUN_ERROR',\n model: options.model,\n timestamp: Date.now(),\n error: {\n message: err.message || 'Unknown error occurred',\n code: err.code || String(err.status),\n },\n }\n }\n }\n\n /**\n * Generate structured output using Anthropic's tool-based approach.\n * Anthropic doesn't have native structured output, so we use a tool with the schema\n * and force the model to call it.\n * The outputSchema is already JSON Schema (converted in the ai layer).\n */\n async structuredOutput(\n options: StructuredOutputOptions<AnthropicTextProviderOptions>,\n ): Promise<StructuredOutputResult<unknown>> {\n const { chatOptions, outputSchema } = options\n\n const requestParams = this.mapCommonOptionsToAnthropic(chatOptions)\n\n // Create a tool that will capture the structured output\n // Anthropic's SDK requires input_schema with type: 'object' literal\n const structuredOutputTool = {\n name: 'structured_output',\n description:\n 'Use this tool to provide your response in the required structured format.',\n input_schema: {\n type: 'object' as const,\n properties: outputSchema.properties ?? {},\n required: outputSchema.required ?? [],\n },\n }\n\n try {\n // Make non-streaming request with tool_choice forced to our structured output tool\n const response = await this.client.messages.create(\n {\n ...requestParams,\n stream: false,\n tools: [structuredOutputTool],\n tool_choice: { type: 'tool', name: 'structured_output' },\n },\n {\n signal: chatOptions.request?.signal,\n headers: chatOptions.request?.headers,\n },\n )\n\n // Extract the tool use content from the response\n let parsed: unknown = null\n let rawText = ''\n\n for (const block of response.content) {\n if (block.type === 'tool_use' && block.name === 'structured_output') {\n parsed = block.input\n rawText = JSON.stringify(block.input)\n break\n }\n }\n\n if (parsed === null) {\n // Fallback: try to extract text content and parse as JSON\n rawText = response.content\n .map((b) => {\n if (b.type === 'text') {\n return b.text\n }\n return ''\n })\n .join('')\n try {\n parsed = JSON.parse(rawText)\n } catch {\n throw new Error(\n `Failed to extract structured output from response. Content: ${rawText.slice(0, 200)}${rawText.length > 200 ? '...' : ''}`,\n )\n }\n }\n\n return {\n data: parsed,\n rawText,\n }\n } catch (error: unknown) {\n const err = error as Error\n throw new Error(\n `Structured output generation failed: ${err.message || 'Unknown error occurred'}`,\n )\n }\n }\n\n private mapCommonOptionsToAnthropic(\n options: TextOptions<AnthropicTextProviderOptions>,\n ) {\n const modelOptions = options.modelOptions as\n | InternalTextProviderOptions\n | undefined\n\n const formattedMessages = this.formatMessages(options.messages)\n const tools = options.tools\n ? convertToolsToProviderFormat(options.tools)\n : undefined\n\n const validProviderOptions: Partial<InternalTextProviderOptions> = {}\n if (modelOptions) {\n const validKeys: Array<keyof InternalTextProviderOptions> = [\n 'container',\n 'context_management',\n 'mcp_servers',\n 'service_tier',\n 'stop_sequences',\n 'system',\n 'thinking',\n 'tool_choice',\n 'top_k',\n ]\n for (const key of validKeys) {\n if (key in modelOptions) {\n const value = modelOptions[key]\n if (key === 'tool_choice' && typeof value === 'string') {\n ;(validProviderOptions as Record<string, unknown>)[key] = {\n type: value,\n }\n } else {\n ;(validProviderOptions as Record<string, unknown>)[key] = value\n }\n }\n }\n }\n\n const thinkingBudget =\n validProviderOptions.thinking?.type === 'enabled'\n ? validProviderOptions.thinking.budget_tokens\n : undefined\n const defaultMaxTokens = options.maxTokens || 1024\n const maxTokens =\n thinkingBudget && thinkingBudget >= defaultMaxTokens\n ? thinkingBudget + 1\n : defaultMaxTokens\n\n const requestParams: InternalTextProviderOptions = {\n model: options.model,\n max_tokens: maxTokens,\n temperature: options.temperature,\n top_p: options.topP,\n messages: formattedMessages,\n system: options.systemPrompts?.join('\\n'),\n tools: tools,\n ...validProviderOptions,\n }\n validateTextProviderOptions(requestParams)\n return requestParams\n }\n\n private convertContentPartToAnthropic(\n part: ContentPart,\n ): TextBlockParam | ImageBlockParam | DocumentBlockParam {\n switch (part.type) {\n case 'text': {\n const metadata = part.metadata as AnthropicTextMetadata | undefined\n return {\n type: 'text',\n text: part.content,\n ...metadata,\n }\n }\n\n case 'image': {\n const metadata = part.metadata as AnthropicImageMetadata | undefined\n const imageSource: Base64ImageSource | URLImageSource =\n part.source.type === 'data'\n ? {\n type: 'base64',\n data: part.source.value,\n media_type: part.source.mimeType as\n | 'image/jpeg'\n | 'image/png'\n | 'image/gif'\n | 'image/webp',\n }\n : {\n type: 'url',\n url: part.source.value,\n }\n return {\n type: 'image',\n source: imageSource,\n ...metadata,\n }\n }\n case 'document': {\n const metadata = part.metadata as AnthropicDocumentMetadata | undefined\n const docSource: Base64PDFSource | URLPDFSource =\n part.source.type === 'data'\n ? {\n type: 'base64',\n data: part.source.value,\n media_type: part.source.mimeType as 'application/pdf',\n }\n : {\n type: 'url',\n url: part.source.value,\n }\n return {\n type: 'document',\n source: docSource,\n ...metadata,\n }\n }\n case 'audio':\n case 'video':\n throw new Error(\n `Anthropic does not support ${part.type} content directly`,\n )\n default: {\n const _exhaustiveCheck: never = part\n throw new Error(\n `Unsupported content part type: ${(_exhaustiveCheck as ContentPart).type}`,\n )\n }\n }\n }\n\n private formatMessages(\n messages: Array<ModelMessage>,\n ): InternalTextProviderOptions['messages'] {\n const formattedMessages: InternalTextProviderOptions['messages'] = []\n\n for (const message of messages) {\n const role = message.role\n\n if (role === 'tool' && message.toolCallId) {\n formattedMessages.push({\n role: 'user',\n content: [\n {\n type: 'tool_result',\n tool_use_id: message.toolCallId,\n content:\n typeof message.content === 'string' ? message.content : '',\n },\n ],\n })\n continue\n }\n\n if (role === 'assistant' && message.toolCalls?.length) {\n const contentBlocks: AnthropicContentBlocks = []\n\n if (message.content) {\n const content =\n typeof message.content === 'string' ? message.content : ''\n const textBlock: AnthropicContentBlock = {\n type: 'text',\n text: content,\n }\n contentBlocks.push(textBlock)\n }\n\n for (const toolCall of message.toolCalls) {\n let parsedInput: unknown = {}\n try {\n const parsed = toolCall.function.arguments\n ? JSON.parse(toolCall.function.arguments)\n : {}\n parsedInput = parsed && typeof parsed === 'object' ? parsed : {}\n } catch {\n parsedInput = toolCall.function.arguments\n }\n\n const toolUseBlock: AnthropicContentBlock = {\n type: 'tool_use',\n id: toolCall.id,\n name: toolCall.function.name,\n input: parsedInput,\n }\n contentBlocks.push(toolUseBlock)\n }\n\n formattedMessages.push({\n role: 'assistant',\n content: contentBlocks,\n })\n\n continue\n }\n\n if (role === 'user' && Array.isArray(message.content)) {\n const contentBlocks = message.content.map((part) =>\n this.convertContentPartToAnthropic(part),\n )\n formattedMessages.push({\n role: 'user',\n content: contentBlocks,\n })\n continue\n }\n\n formattedMessages.push({\n role: role === 'assistant' ? 'assistant' : 'user',\n content:\n typeof message.content === 'string'\n ? message.content\n : message.content\n ? message.content.map((c) =>\n this.convertContentPartToAnthropic(c),\n )\n : '',\n })\n }\n\n return formattedMessages\n }\n\n private async *processAnthropicStream(\n stream: AsyncIterable<Anthropic_SDK.Beta.BetaRawMessageStreamEvent>,\n model: string,\n genId: () => string,\n ): AsyncIterable<StreamChunk> {\n let accumulatedContent = ''\n let accumulatedThinking = ''\n const timestamp = Date.now()\n const toolCallsMap = new Map<\n number,\n { id: string; name: string; input: string; started: boolean }\n >()\n let currentToolIndex = -1\n\n // AG-UI lifecycle tracking\n const runId = genId()\n const messageId = genId()\n let stepId: string | null = null\n let hasEmittedRunStarted = false\n let hasEmittedTextMessageStart = false\n\n try {\n for await (const event of stream) {\n // Emit RUN_STARTED on first event\n if (!hasEmittedRunStarted) {\n hasEmittedRunStarted = true\n yield {\n type: 'RUN_STARTED',\n runId,\n model,\n timestamp,\n }\n }\n\n if (event.type === 'content_block_start') {\n if (event.content_block.type === 'tool_use') {\n currentToolIndex++\n toolCallsMap.set(currentToolIndex, {\n id: event.content_block.id,\n name: event.content_block.name,\n input: '',\n started: false,\n })\n } else if (event.content_block.type === 'thinking') {\n accumulatedThinking = ''\n // Emit STEP_STARTED for thinking\n stepId = genId()\n yield {\n type: 'STEP_STARTED',\n stepId,\n model,\n timestamp,\n stepType: 'thinking',\n }\n }\n } else if (event.type === 'content_block_delta') {\n if (event.delta.type === 'text_delta') {\n // Emit TEXT_MESSAGE_START on first text content\n if (!hasEmittedTextMessageStart) {\n hasEmittedTextMessageStart = true\n yield {\n type: 'TEXT_MESSAGE_START',\n messageId,\n model,\n timestamp,\n role: 'assistant',\n }\n }\n\n const delta = event.delta.text\n accumulatedContent += delta\n yield {\n type: 'TEXT_MESSAGE_CONTENT',\n messageId,\n model,\n timestamp,\n delta,\n content: accumulatedContent,\n }\n } else if (event.delta.type === 'thinking_delta') {\n const delta = event.delta.thinking\n accumulatedThinking += delta\n yield {\n type: 'STEP_FINISHED',\n stepId: stepId || genId(),\n model,\n timestamp,\n delta,\n content: accumulatedThinking,\n }\n } else if (event.delta.type === 'input_json_delta') {\n const existing = toolCallsMap.get(currentToolIndex)\n if (existing) {\n // Emit TOOL_CALL_START on first args delta\n if (!existing.started) {\n existing.started = true\n yield {\n type: 'TOOL_CALL_START',\n toolCallId: existing.id,\n toolName: existing.name,\n model,\n timestamp,\n index: currentToolIndex,\n }\n }\n\n existing.input += event.delta.partial_json\n\n yield {\n type: 'TOOL_CALL_ARGS',\n toolCallId: existing.id,\n model,\n timestamp,\n delta: event.delta.partial_json,\n args: existing.input,\n }\n }\n }\n } else if (event.type === 'content_block_stop') {\n const existing = toolCallsMap.get(currentToolIndex)\n if (existing) {\n // If tool call wasn't started yet (no args), start it now\n if (!existing.started) {\n existing.started = true\n yield {\n type: 'TOOL_CALL_START',\n toolCallId: existing.id,\n toolName: existing.name,\n model,\n timestamp,\n index: currentToolIndex,\n }\n }\n\n // Emit TOOL_CALL_END\n let parsedInput: unknown = {}\n try {\n const parsed = existing.input ? JSON.parse(existing.input) : {}\n parsedInput = parsed && typeof parsed === 'object' ? parsed : {}\n } catch {\n parsedInput = {}\n }\n\n yield {\n type: 'TOOL_CALL_END',\n toolCallId: existing.id,\n toolName: existing.name,\n model,\n timestamp,\n input: parsedInput,\n }\n }\n\n // Emit TEXT_MESSAGE_END if we had text content\n if (hasEmittedTextMessageStart && accumulatedContent) {\n yield {\n type: 'TEXT_MESSAGE_END',\n messageId,\n model,\n timestamp,\n }\n }\n } else if (event.type === 'message_stop') {\n yield {\n type: 'RUN_FINISHED',\n runId,\n model,\n timestamp,\n finishReason: 'stop',\n }\n } else if (event.type === 'message_delta') {\n if (event.delta.stop_reason) {\n switch (event.delta.stop_reason) {\n case 'tool_use': {\n yield {\n type: 'RUN_FINISHED',\n runId,\n model,\n timestamp,\n finishReason: 'tool_calls',\n usage: {\n promptTokens: event.usage.input_tokens || 0,\n completionTokens: event.usage.output_tokens || 0,\n totalTokens:\n (event.usage.input_tokens || 0) +\n (event.usage.output_tokens || 0),\n },\n }\n break\n }\n case 'max_tokens': {\n yield {\n type: 'RUN_ERROR',\n runId,\n model,\n timestamp,\n error: {\n message:\n 'The response was cut off because the maximum token limit was reached.',\n code: 'max_tokens',\n },\n }\n break\n }\n default: {\n yield {\n type: 'RUN_FINISHED',\n runId,\n model,\n timestamp,\n finishReason: 'stop',\n usage: {\n promptTokens: event.usage.input_tokens || 0,\n completionTokens: event.usage.output_tokens || 0,\n totalTokens:\n (event.usage.input_tokens || 0) +\n (event.usage.output_tokens || 0),\n },\n }\n }\n }\n }\n }\n }\n } catch (error: unknown) {\n const err = error as Error & { status?: number; code?: string }\n\n yield {\n type: 'RUN_ERROR',\n runId,\n model,\n timestamp,\n error: {\n message: err.message || 'Unknown error occurred',\n code: err.code || String(err.status),\n },\n }\n }\n }\n}\n\n/**\n * Creates an Anthropic chat adapter with explicit API key.\n * Type resolution happens here at the call site.\n */\nexport function createAnthropicChat<\n TModel extends (typeof ANTHROPIC_MODELS)[number],\n>(\n model: TModel,\n apiKey: string,\n config?: Omit<AnthropicTextConfig, 'apiKey'>,\n): AnthropicTextAdapter<\n TModel,\n ResolveProviderOptions<TModel>,\n ResolveInputModalities<TModel>\n> {\n return new AnthropicTextAdapter({ apiKey, ...config }, model)\n}\n\n/**\n * Creates an Anthropic text adapter with automatic API key detection.\n * Type resolution happens here at the call site.\n */\nexport function anthropicText<TModel extends (typeof ANTHROPIC_MODELS)[number]>(\n model: TModel,\n config?: Omit<AnthropicTextConfig, 'apiKey'>,\n): AnthropicTextAdapter<\n TModel,\n ResolveProviderOptions<TModel>,\n ResolveInputModalities<TModel>\n> {\n const apiKey = getAnthropicApiKeyFromEnv()\n return createAnthropicChat(model, apiKey, config)\n}\n"],"names":[],"mappings":";;;;AAgGO,MAAM,6BAKH,gBAKR;AAAA,EAMA,YAAY,QAA6B,OAAe;AACtD,UAAM,CAAA,GAAI,KAAK;AANjB,SAAS,OAAO;AAChB,SAAS,OAAO;AAMd,SAAK,SAAS,sBAAsB,MAAM;AAAA,EAC5C;AAAA,EAEA,OAAO,WACL,SAC4B;AAC5B,QAAI;AACF,YAAM,gBAAgB,KAAK,4BAA4B,OAAO;AAE9D,YAAM,SAAS,MAAM,KAAK,OAAO,KAAK,SAAS;AAAA,QAC7C,EAAE,GAAG,eAAe,QAAQ,KAAA;AAAA,QAC5B;AAAA,UACE,QAAQ,QAAQ,SAAS;AAAA,UACzB,SAAS,QAAQ,SAAS;AAAA,QAAA;AAAA,MAC5B;AAGF,aAAO,KAAK;AAAA,QAAuB;AAAA,QAAQ,QAAQ;AAAA,QAAO,MACxD,WAAW,KAAK,IAAI;AAAA,MAAA;AAAA,IAExB,SAAS,OAAgB;AACvB,YAAM,MAAM;AACZ,YAAM;AAAA,QACJ,MAAM;AAAA,QACN,OAAO,QAAQ;AAAA,QACf,WAAW,KAAK,IAAA;AAAA,QAChB,OAAO;AAAA,UACL,SAAS,IAAI,WAAW;AAAA,UACxB,MAAM,IAAI,QAAQ,OAAO,IAAI,MAAM;AAAA,QAAA;AAAA,MACrC;AAAA,IAEJ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,iBACJ,SAC0C;AAC1C,UAAM,EAAE,aAAa,aAAA,IAAiB;AAEtC,UAAM,gBAAgB,KAAK,4BAA4B,WAAW;AAIlE,UAAM,uBAAuB;AAAA,MAC3B,MAAM;AAAA,MACN,aACE;AAAA,MACF,cAAc;AAAA,QACZ,MAAM;AAAA,QACN,YAAY,aAAa,cAAc,CAAA;AAAA,QACvC,UAAU,aAAa,YAAY,CAAA;AAAA,MAAC;AAAA,IACtC;AAGF,QAAI;AAEF,YAAM,WAAW,MAAM,KAAK,OAAO,SAAS;AAAA,QAC1C;AAAA,UACE,GAAG;AAAA,UACH,QAAQ;AAAA,UACR,OAAO,CAAC,oBAAoB;AAAA,UAC5B,aAAa,EAAE,MAAM,QAAQ,MAAM,oBAAA;AAAA,QAAoB;AAAA,QAEzD;AAAA,UACE,QAAQ,YAAY,SAAS;AAAA,UAC7B,SAAS,YAAY,SAAS;AAAA,QAAA;AAAA,MAChC;AAIF,UAAI,SAAkB;AACtB,UAAI,UAAU;AAEd,iBAAW,SAAS,SAAS,SAAS;AACpC,YAAI,MAAM,SAAS,cAAc,MAAM,SAAS,qBAAqB;AACnE,mBAAS,MAAM;AACf,oBAAU,KAAK,UAAU,MAAM,KAAK;AACpC;AAAA,QACF;AAAA,MACF;AAEA,UAAI,WAAW,MAAM;AAEnB,kBAAU,SAAS,QAChB,IAAI,CAAC,MAAM;AACV,cAAI,EAAE,SAAS,QAAQ;AACrB,mBAAO,EAAE;AAAA,UACX;AACA,iBAAO;AAAA,QACT,CAAC,EACA,KAAK,EAAE;AACV,YAAI;AACF,mBAAS,KAAK,MAAM,OAAO;AAAA,QAC7B,QAAQ;AACN,gBAAM,IAAI;AAAA,YACR,+DAA+D,QAAQ,MAAM,GAAG,GAAG,CAAC,GAAG,QAAQ,SAAS,MAAM,QAAQ,EAAE;AAAA,UAAA;AAAA,QAE5H;AAAA,MACF;AAEA,aAAO;AAAA,QACL,MAAM;AAAA,QACN;AAAA,MAAA;AAAA,IAEJ,SAAS,OAAgB;AACvB,YAAM,MAAM;AACZ,YAAM,IAAI;AAAA,QACR,wCAAwC,IAAI,WAAW,wBAAwB;AAAA,MAAA;AAAA,IAEnF;AAAA,EACF;AAAA,EAEQ,4BACN,SACA;AACA,UAAM,eAAe,QAAQ;AAI7B,UAAM,oBAAoB,KAAK,eAAe,QAAQ,QAAQ;AAC9D,UAAM,QAAQ,QAAQ,QAClB,6BAA6B,QAAQ,KAAK,IAC1C;AAEJ,UAAM,uBAA6D,CAAA;AACnE,QAAI,cAAc;AAChB,YAAM,YAAsD;AAAA,QAC1D;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAEF,iBAAW,OAAO,WAAW;AAC3B,YAAI,OAAO,cAAc;AACvB,gBAAM,QAAQ,aAAa,GAAG;AAC9B,cAAI,QAAQ,iBAAiB,OAAO,UAAU,UAAU;AACpD,iCAAiD,GAAG,IAAI;AAAA,cACxD,MAAM;AAAA,YAAA;AAAA,UAEV,OAAO;AACH,iCAAiD,GAAG,IAAI;AAAA,UAC5D;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,iBACJ,qBAAqB,UAAU,SAAS,YACpC,qBAAqB,SAAS,gBAC9B;AACN,UAAM,mBAAmB,QAAQ,aAAa;AAC9C,UAAM,YACJ,kBAAkB,kBAAkB,mBAChC,iBAAiB,IACjB;AAEN,UAAM,gBAA6C;AAAA,MACjD,OAAO,QAAQ;AAAA,MACf,YAAY;AAAA,MACZ,aAAa,QAAQ;AAAA,MACrB,OAAO,QAAQ;AAAA,MACf,UAAU;AAAA,MACV,QAAQ,QAAQ,eAAe,KAAK,IAAI;AAAA,MACxC;AAAA,MACA,GAAG;AAAA,IAAA;AAEL,gCAA4B,aAAa;AACzC,WAAO;AAAA,EACT;AAAA,EAEQ,8BACN,MACuD;AACvD,YAAQ,KAAK,MAAA;AAAA,MACX,KAAK,QAAQ;AACX,cAAM,WAAW,KAAK;AACtB,eAAO;AAAA,UACL,MAAM;AAAA,UACN,MAAM,KAAK;AAAA,UACX,GAAG;AAAA,QAAA;AAAA,MAEP;AAAA,MAEA,KAAK,SAAS;AACZ,cAAM,WAAW,KAAK;AACtB,cAAM,cACJ,KAAK,OAAO,SAAS,SACjB;AAAA,UACE,MAAM;AAAA,UACN,MAAM,KAAK,OAAO;AAAA,UAClB,YAAY,KAAK,OAAO;AAAA,QAAA,IAM1B;AAAA,UACE,MAAM;AAAA,UACN,KAAK,KAAK,OAAO;AAAA,QAAA;AAEzB,eAAO;AAAA,UACL,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,GAAG;AAAA,QAAA;AAAA,MAEP;AAAA,MACA,KAAK,YAAY;AACf,cAAM,WAAW,KAAK;AACtB,cAAM,YACJ,KAAK,OAAO,SAAS,SACjB;AAAA,UACE,MAAM;AAAA,UACN,MAAM,KAAK,OAAO;AAAA,UAClB,YAAY,KAAK,OAAO;AAAA,QAAA,IAE1B;AAAA,UACE,MAAM;AAAA,UACN,KAAK,KAAK,OAAO;AAAA,QAAA;AAEzB,eAAO;AAAA,UACL,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,GAAG;AAAA,QAAA;AAAA,MAEP;AAAA,MACA,KAAK;AAAA,MACL,KAAK;AACH,cAAM,IAAI;AAAA,UACR,8BAA8B,KAAK,IAAI;AAAA,QAAA;AAAA,MAE3C,SAAS;AACP,cAAM,mBAA0B;AAChC,cAAM,IAAI;AAAA,UACR,kCAAmC,iBAAiC,IAAI;AAAA,QAAA;AAAA,MAE5E;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEQ,eACN,UACyC;AACzC,UAAM,oBAA6D,CAAA;AAEnE,eAAW,WAAW,UAAU;AAC9B,YAAM,OAAO,QAAQ;AAErB,UAAI,SAAS,UAAU,QAAQ,YAAY;AACzC,0BAAkB,KAAK;AAAA,UACrB,MAAM;AAAA,UACN,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,aAAa,QAAQ;AAAA,cACrB,SACE,OAAO,QAAQ,YAAY,WAAW,QAAQ,UAAU;AAAA,YAAA;AAAA,UAC5D;AAAA,QACF,CACD;AACD;AAAA,MACF;AAEA,UAAI,SAAS,eAAe,QAAQ,WAAW,QAAQ;AACrD,cAAM,gBAAwC,CAAA;AAE9C,YAAI,QAAQ,SAAS;AACnB,gBAAM,UACJ,OAAO,QAAQ,YAAY,WAAW,QAAQ,UAAU;AAC1D,gBAAM,YAAmC;AAAA,YACvC,MAAM;AAAA,YACN,MAAM;AAAA,UAAA;AAER,wBAAc,KAAK,SAAS;AAAA,QAC9B;AAEA,mBAAW,YAAY,QAAQ,WAAW;AACxC,cAAI,cAAuB,CAAA;AAC3B,cAAI;AACF,kBAAM,SAAS,SAAS,SAAS,YAC7B,KAAK,MAAM,SAAS,SAAS,SAAS,IACtC,CAAA;AACJ,0BAAc,UAAU,OAAO,WAAW,WAAW,SAAS,CAAA;AAAA,UAChE,QAAQ;AACN,0BAAc,SAAS,SAAS;AAAA,UAClC;AAEA,gBAAM,eAAsC;AAAA,YAC1C,MAAM;AAAA,YACN,IAAI,SAAS;AAAA,YACb,MAAM,SAAS,SAAS;AAAA,YACxB,OAAO;AAAA,UAAA;AAET,wBAAc,KAAK,YAAY;AAAA,QACjC;AAEA,0BAAkB,KAAK;AAAA,UACrB,MAAM;AAAA,UACN,SAAS;AAAA,QAAA,CACV;AAED;AAAA,MACF;AAEA,UAAI,SAAS,UAAU,MAAM,QAAQ,QAAQ,OAAO,GAAG;AACrD,cAAM,gBAAgB,QAAQ,QAAQ;AAAA,UAAI,CAAC,SACzC,KAAK,8BAA8B,IAAI;AAAA,QAAA;AAEzC,0BAAkB,KAAK;AAAA,UACrB,MAAM;AAAA,UACN,SAAS;AAAA,QAAA,CACV;AACD;AAAA,MACF;AAEA,wBAAkB,KAAK;AAAA,QACrB,MAAM,SAAS,cAAc,cAAc;AAAA,QAC3C,SACE,OAAO,QAAQ,YAAY,WACvB,QAAQ,UACR,QAAQ,UACN,QAAQ,QAAQ;AAAA,UAAI,CAAC,MACnB,KAAK,8BAA8B,CAAC;AAAA,QAAA,IAEtC;AAAA,MAAA,CACT;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,OAAe,uBACb,QACA,OACA,OAC4B;AAC5B,QAAI,qBAAqB;AACzB,QAAI,sBAAsB;AAC1B,UAAM,YAAY,KAAK,IAAA;AACvB,UAAM,mCAAmB,IAAA;AAIzB,QAAI,mBAAmB;AAGvB,UAAM,QAAQ,MAAA;AACd,UAAM,YAAY,MAAA;AAClB,QAAI,SAAwB;AAC5B,QAAI,uBAAuB;AAC3B,QAAI,6BAA6B;AAEjC,QAAI;AACF,uBAAiB,SAAS,QAAQ;AAEhC,YAAI,CAAC,sBAAsB;AACzB,iCAAuB;AACvB,gBAAM;AAAA,YACJ,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,UAAA;AAAA,QAEJ;AAEA,YAAI,MAAM,SAAS,uBAAuB;AACxC,cAAI,MAAM,cAAc,SAAS,YAAY;AAC3C;AACA,yBAAa,IAAI,kBAAkB;AAAA,cACjC,IAAI,MAAM,cAAc;AAAA,cACxB,MAAM,MAAM,cAAc;AAAA,cAC1B,OAAO;AAAA,cACP,SAAS;AAAA,YAAA,CACV;AAAA,UACH,WAAW,MAAM,cAAc,SAAS,YAAY;AAClD,kCAAsB;AAEtB,qBAAS,MAAA;AACT,kBAAM;AAAA,cACJ,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA;AAAA,cACA,UAAU;AAAA,YAAA;AAAA,UAEd;AAAA,QACF,WAAW,MAAM,SAAS,uBAAuB;AAC/C,cAAI,MAAM,MAAM,SAAS,cAAc;AAErC,gBAAI,CAAC,4BAA4B;AAC/B,2CAA6B;AAC7B,oBAAM;AAAA,gBACJ,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,MAAM;AAAA,cAAA;AAAA,YAEV;AAEA,kBAAM,QAAQ,MAAM,MAAM;AAC1B,kCAAsB;AACtB,kBAAM;AAAA,cACJ,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA,SAAS;AAAA,YAAA;AAAA,UAEb,WAAW,MAAM,MAAM,SAAS,kBAAkB;AAChD,kBAAM,QAAQ,MAAM,MAAM;AAC1B,mCAAuB;AACvB,kBAAM;AAAA,cACJ,MAAM;AAAA,cACN,QAAQ,UAAU,MAAA;AAAA,cAClB;AAAA,cACA;AAAA,cACA;AAAA,cACA,SAAS;AAAA,YAAA;AAAA,UAEb,WAAW,MAAM,MAAM,SAAS,oBAAoB;AAClD,kBAAM,WAAW,aAAa,IAAI,gBAAgB;AAClD,gBAAI,UAAU;AAEZ,kBAAI,CAAC,SAAS,SAAS;AACrB,yBAAS,UAAU;AACnB,sBAAM;AAAA,kBACJ,MAAM;AAAA,kBACN,YAAY,SAAS;AAAA,kBACrB,UAAU,SAAS;AAAA,kBACnB;AAAA,kBACA;AAAA,kBACA,OAAO;AAAA,gBAAA;AAAA,cAEX;AAEA,uBAAS,SAAS,MAAM,MAAM;AAE9B,oBAAM;AAAA,gBACJ,MAAM;AAAA,gBACN,YAAY,SAAS;AAAA,gBACrB;AAAA,gBACA;AAAA,gBACA,OAAO,MAAM,MAAM;AAAA,gBACnB,MAAM,SAAS;AAAA,cAAA;AAAA,YAEnB;AAAA,UACF;AAAA,QACF,WAAW,MAAM,SAAS,sBAAsB;AAC9C,gBAAM,WAAW,aAAa,IAAI,gBAAgB;AAClD,cAAI,UAAU;AAEZ,gBAAI,CAAC,SAAS,SAAS;AACrB,uBAAS,UAAU;AACnB,oBAAM;AAAA,gBACJ,MAAM;AAAA,gBACN,YAAY,SAAS;AAAA,gBACrB,UAAU,SAAS;AAAA,gBACnB;AAAA,gBACA;AAAA,gBACA,OAAO;AAAA,cAAA;AAAA,YAEX;AAGA,gBAAI,cAAuB,CAAA;AAC3B,gBAAI;AACF,oBAAM,SAAS,SAAS,QAAQ,KAAK,MAAM,SAAS,KAAK,IAAI,CAAA;AAC7D,4BAAc,UAAU,OAAO,WAAW,WAAW,SAAS,CAAA;AAAA,YAChE,QAAQ;AACN,4BAAc,CAAA;AAAA,YAChB;AAEA,kBAAM;AAAA,cACJ,MAAM;AAAA,cACN,YAAY,SAAS;AAAA,cACrB,UAAU,SAAS;AAAA,cACnB;AAAA,cACA;AAAA,cACA,OAAO;AAAA,YAAA;AAAA,UAEX;AAGA,cAAI,8BAA8B,oBAAoB;AACpD,kBAAM;AAAA,cACJ,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA;AAAA,YAAA;AAAA,UAEJ;AAAA,QACF,WAAW,MAAM,SAAS,gBAAgB;AACxC,gBAAM;AAAA,YACJ,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,YACA,cAAc;AAAA,UAAA;AAAA,QAElB,WAAW,MAAM,SAAS,iBAAiB;AACzC,cAAI,MAAM,MAAM,aAAa;AAC3B,oBAAQ,MAAM,MAAM,aAAA;AAAA,cAClB,KAAK,YAAY;AACf,sBAAM;AAAA,kBACJ,MAAM;AAAA,kBACN;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA,cAAc;AAAA,kBACd,OAAO;AAAA,oBACL,cAAc,MAAM,MAAM,gBAAgB;AAAA,oBAC1C,kBAAkB,MAAM,MAAM,iBAAiB;AAAA,oBAC/C,cACG,MAAM,MAAM,gBAAgB,MAC5B,MAAM,MAAM,iBAAiB;AAAA,kBAAA;AAAA,gBAClC;AAEF;AAAA,cACF;AAAA,cACA,KAAK,cAAc;AACjB,sBAAM;AAAA,kBACJ,MAAM;AAAA,kBACN;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA,OAAO;AAAA,oBACL,SACE;AAAA,oBACF,MAAM;AAAA,kBAAA;AAAA,gBACR;AAEF;AAAA,cACF;AAAA,cACA,SAAS;AACP,sBAAM;AAAA,kBACJ,MAAM;AAAA,kBACN;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA,cAAc;AAAA,kBACd,OAAO;AAAA,oBACL,cAAc,MAAM,MAAM,gBAAgB;AAAA,oBAC1C,kBAAkB,MAAM,MAAM,iBAAiB;AAAA,oBAC/C,cACG,MAAM,MAAM,gBAAgB,MAC5B,MAAM,MAAM,iBAAiB;AAAA,kBAAA;AAAA,gBAClC;AAAA,cAEJ;AAAA,YAAA;AAAA,UAEJ;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAgB;AACvB,YAAM,MAAM;AAEZ,YAAM;AAAA,QACJ,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO;AAAA,UACL,SAAS,IAAI,WAAW;AAAA,UACxB,MAAM,IAAI,QAAQ,OAAO,IAAI,MAAM;AAAA,QAAA;AAAA,MACrC;AAAA,IAEJ;AAAA,EACF;AACF;AAMO,SAAS,oBAGd,OACA,QACA,QAKA;AACA,SAAO,IAAI,qBAAqB,EAAE,QAAQ,GAAG,OAAA,GAAU,KAAK;AAC9D;AAMO,SAAS,cACd,OACA,QAKA;AACA,QAAM,SAAS,0BAAA;AACf,SAAO,oBAAoB,OAAO,QAAQ,MAAM;AAClD;"}
|
|
1
|
+
{"version":3,"file":"text.js","sources":["../../../src/adapters/text.ts"],"sourcesContent":["import { BaseTextAdapter } from '@tanstack/ai/adapters'\nimport { convertToolsToProviderFormat } from '../tools/tool-converter'\nimport { validateTextProviderOptions } from '../text/text-provider-options'\nimport {\n createAnthropicClient,\n generateId,\n getAnthropicApiKeyFromEnv,\n} from '../utils'\nimport type {\n ANTHROPIC_MODELS,\n AnthropicChatModelProviderOptionsByName,\n AnthropicModelInputModalitiesByName,\n} from '../model-meta'\nimport type {\n StructuredOutputOptions,\n StructuredOutputResult,\n} from '@tanstack/ai/adapters'\nimport type {\n Base64ImageSource,\n Base64PDFSource,\n DocumentBlockParam,\n ImageBlockParam,\n MessageParam,\n TextBlockParam,\n URLImageSource,\n URLPDFSource,\n} from '@anthropic-ai/sdk/resources/messages'\nimport type Anthropic_SDK from '@anthropic-ai/sdk'\nimport type {\n ContentPart,\n Modality,\n ModelMessage,\n StreamChunk,\n TextOptions,\n} from '@tanstack/ai'\nimport type {\n ExternalTextProviderOptions,\n InternalTextProviderOptions,\n} from '../text/text-provider-options'\nimport type {\n AnthropicDocumentMetadata,\n AnthropicImageMetadata,\n AnthropicMessageMetadataByModality,\n AnthropicTextMetadata,\n} from '../message-types'\nimport type { AnthropicClientConfig } from '../utils'\n\n/**\n * Configuration for Anthropic text adapter\n */\nexport interface AnthropicTextConfig extends AnthropicClientConfig {}\n\n/**\n * Anthropic-specific provider options for text/chat\n */\nexport type AnthropicTextProviderOptions = ExternalTextProviderOptions\n\ntype AnthropicContentBlocks =\n Extract<MessageParam['content'], Array<unknown>> extends Array<infer Block>\n ? Array<Block>\n : never\ntype AnthropicContentBlock =\n AnthropicContentBlocks extends Array<infer Block> ? Block : never\n\n// ===========================\n// Type Resolution Helpers\n// ===========================\n\n/**\n * Resolve provider options for a specific model.\n * If the model has explicit options in the map, use those; otherwise use base options.\n */\ntype ResolveProviderOptions<TModel extends string> =\n TModel extends keyof AnthropicChatModelProviderOptionsByName\n ? AnthropicChatModelProviderOptionsByName[TModel]\n : AnthropicTextProviderOptions\n\n/**\n * Resolve input modalities for a specific model.\n * If the model has explicit modalities in the map, use those; otherwise use default.\n */\ntype ResolveInputModalities<TModel extends string> =\n TModel extends keyof AnthropicModelInputModalitiesByName\n ? AnthropicModelInputModalitiesByName[TModel]\n : readonly ['text', 'image', 'document']\n\n// ===========================\n// Adapter Implementation\n// ===========================\n\n/**\n * Anthropic Text (Chat) Adapter\n *\n * Tree-shakeable adapter for Anthropic chat/text completion functionality.\n * Import only what you need for smaller bundle sizes.\n */\nexport class AnthropicTextAdapter<\n TModel extends (typeof ANTHROPIC_MODELS)[number],\n TProviderOptions extends object = ResolveProviderOptions<TModel>,\n TInputModalities extends ReadonlyArray<Modality> =\n ResolveInputModalities<TModel>,\n> extends BaseTextAdapter<\n TModel,\n TProviderOptions,\n TInputModalities,\n AnthropicMessageMetadataByModality\n> {\n readonly kind = 'text' as const\n readonly name = 'anthropic' as const\n\n private client: Anthropic_SDK\n\n constructor(config: AnthropicTextConfig, model: TModel) {\n super({}, model)\n this.client = createAnthropicClient(config)\n }\n\n async *chatStream(\n options: TextOptions<AnthropicTextProviderOptions>,\n ): AsyncIterable<StreamChunk> {\n try {\n const requestParams = this.mapCommonOptionsToAnthropic(options)\n\n const stream = await this.client.beta.messages.create(\n { ...requestParams, stream: true },\n {\n signal: options.request?.signal,\n headers: options.request?.headers,\n },\n )\n\n yield* this.processAnthropicStream(stream, options.model, () =>\n generateId(this.name),\n )\n } catch (error: unknown) {\n const err = error as Error & { status?: number; code?: string }\n yield {\n type: 'RUN_ERROR',\n model: options.model,\n timestamp: Date.now(),\n error: {\n message: err.message || 'Unknown error occurred',\n code: err.code || String(err.status),\n },\n }\n }\n }\n\n /**\n * Generate structured output using Anthropic's tool-based approach.\n * Anthropic doesn't have native structured output, so we use a tool with the schema\n * and force the model to call it.\n * The outputSchema is already JSON Schema (converted in the ai layer).\n */\n async structuredOutput(\n options: StructuredOutputOptions<AnthropicTextProviderOptions>,\n ): Promise<StructuredOutputResult<unknown>> {\n const { chatOptions, outputSchema } = options\n\n const requestParams = this.mapCommonOptionsToAnthropic(chatOptions)\n\n // Create a tool that will capture the structured output\n // Anthropic's SDK requires input_schema with type: 'object' literal\n const structuredOutputTool = {\n name: 'structured_output',\n description:\n 'Use this tool to provide your response in the required structured format.',\n input_schema: {\n type: 'object' as const,\n properties: outputSchema.properties ?? {},\n required: outputSchema.required ?? [],\n },\n }\n\n try {\n // Make non-streaming request with tool_choice forced to our structured output tool\n const response = await this.client.messages.create(\n {\n ...requestParams,\n stream: false,\n tools: [structuredOutputTool],\n tool_choice: { type: 'tool', name: 'structured_output' },\n },\n {\n signal: chatOptions.request?.signal,\n headers: chatOptions.request?.headers,\n },\n )\n\n // Extract the tool use content from the response\n let parsed: unknown = null\n let rawText = ''\n\n for (const block of response.content) {\n if (block.type === 'tool_use' && block.name === 'structured_output') {\n parsed = block.input\n rawText = JSON.stringify(block.input)\n break\n }\n }\n\n if (parsed === null) {\n // Fallback: try to extract text content and parse as JSON\n rawText = response.content\n .map((b) => {\n if (b.type === 'text') {\n return b.text\n }\n return ''\n })\n .join('')\n try {\n parsed = JSON.parse(rawText)\n } catch {\n throw new Error(\n `Failed to extract structured output from response. Content: ${rawText.slice(0, 200)}${rawText.length > 200 ? '...' : ''}`,\n )\n }\n }\n\n return {\n data: parsed,\n rawText,\n }\n } catch (error: unknown) {\n const err = error as Error\n throw new Error(\n `Structured output generation failed: ${err.message || 'Unknown error occurred'}`,\n )\n }\n }\n\n private mapCommonOptionsToAnthropic(\n options: TextOptions<AnthropicTextProviderOptions>,\n ) {\n const modelOptions = options.modelOptions as\n | InternalTextProviderOptions\n | undefined\n\n const formattedMessages = this.formatMessages(options.messages)\n const tools = options.tools\n ? convertToolsToProviderFormat(options.tools)\n : undefined\n\n const validProviderOptions: Partial<InternalTextProviderOptions> = {}\n if (modelOptions) {\n const validKeys: Array<keyof InternalTextProviderOptions> = [\n 'container',\n 'context_management',\n 'effort',\n 'mcp_servers',\n 'service_tier',\n 'stop_sequences',\n 'system',\n 'thinking',\n 'tool_choice',\n 'top_k',\n ]\n for (const key of validKeys) {\n if (key in modelOptions) {\n const value = modelOptions[key]\n if (key === 'tool_choice' && typeof value === 'string') {\n ;(validProviderOptions as Record<string, unknown>)[key] = {\n type: value,\n }\n } else {\n ;(validProviderOptions as Record<string, unknown>)[key] = value\n }\n }\n }\n }\n\n const thinkingBudget =\n validProviderOptions.thinking?.type === 'enabled'\n ? validProviderOptions.thinking.budget_tokens\n : undefined\n const defaultMaxTokens = options.maxTokens || 1024\n const maxTokens =\n thinkingBudget && thinkingBudget >= defaultMaxTokens\n ? thinkingBudget + 1\n : defaultMaxTokens\n\n const requestParams: InternalTextProviderOptions = {\n model: options.model,\n max_tokens: maxTokens,\n temperature: options.temperature,\n top_p: options.topP,\n messages: formattedMessages,\n system: options.systemPrompts?.join('\\n'),\n tools: tools,\n ...validProviderOptions,\n }\n validateTextProviderOptions(requestParams)\n return requestParams\n }\n\n private convertContentPartToAnthropic(\n part: ContentPart,\n ): TextBlockParam | ImageBlockParam | DocumentBlockParam {\n switch (part.type) {\n case 'text': {\n const metadata = part.metadata as AnthropicTextMetadata | undefined\n return {\n type: 'text',\n text: part.content,\n ...metadata,\n }\n }\n\n case 'image': {\n const metadata = part.metadata as AnthropicImageMetadata | undefined\n const imageSource: Base64ImageSource | URLImageSource =\n part.source.type === 'data'\n ? {\n type: 'base64',\n data: part.source.value,\n media_type: part.source.mimeType as\n | 'image/jpeg'\n | 'image/png'\n | 'image/gif'\n | 'image/webp',\n }\n : {\n type: 'url',\n url: part.source.value,\n }\n return {\n type: 'image',\n source: imageSource,\n ...metadata,\n }\n }\n case 'document': {\n const metadata = part.metadata as AnthropicDocumentMetadata | undefined\n const docSource: Base64PDFSource | URLPDFSource =\n part.source.type === 'data'\n ? {\n type: 'base64',\n data: part.source.value,\n media_type: part.source.mimeType as 'application/pdf',\n }\n : {\n type: 'url',\n url: part.source.value,\n }\n return {\n type: 'document',\n source: docSource,\n ...metadata,\n }\n }\n case 'audio':\n case 'video':\n throw new Error(\n `Anthropic does not support ${part.type} content directly`,\n )\n default: {\n const _exhaustiveCheck: never = part\n throw new Error(\n `Unsupported content part type: ${(_exhaustiveCheck as ContentPart).type}`,\n )\n }\n }\n }\n\n private formatMessages(\n messages: Array<ModelMessage>,\n ): InternalTextProviderOptions['messages'] {\n const formattedMessages: InternalTextProviderOptions['messages'] = []\n\n for (const message of messages) {\n const role = message.role\n\n if (role === 'tool' && message.toolCallId) {\n formattedMessages.push({\n role: 'user',\n content: [\n {\n type: 'tool_result',\n tool_use_id: message.toolCallId,\n content:\n typeof message.content === 'string' ? message.content : '',\n },\n ],\n })\n continue\n }\n\n if (role === 'assistant' && message.toolCalls?.length) {\n const contentBlocks: AnthropicContentBlocks = []\n\n if (message.content) {\n const content =\n typeof message.content === 'string' ? message.content : ''\n const textBlock: AnthropicContentBlock = {\n type: 'text',\n text: content,\n }\n contentBlocks.push(textBlock)\n }\n\n for (const toolCall of message.toolCalls) {\n let parsedInput: unknown = {}\n try {\n const parsed = toolCall.function.arguments\n ? JSON.parse(toolCall.function.arguments)\n : {}\n parsedInput = parsed && typeof parsed === 'object' ? parsed : {}\n } catch {\n parsedInput = toolCall.function.arguments\n }\n\n const toolUseBlock: AnthropicContentBlock = {\n type: 'tool_use',\n id: toolCall.id,\n name: toolCall.function.name,\n input: parsedInput,\n }\n contentBlocks.push(toolUseBlock)\n }\n\n formattedMessages.push({\n role: 'assistant',\n content: contentBlocks,\n })\n\n continue\n }\n\n if (role === 'user' && Array.isArray(message.content)) {\n const contentBlocks = message.content.map((part) =>\n this.convertContentPartToAnthropic(part),\n )\n formattedMessages.push({\n role: 'user',\n content: contentBlocks,\n })\n continue\n }\n\n formattedMessages.push({\n role: role === 'assistant' ? 'assistant' : 'user',\n content:\n typeof message.content === 'string'\n ? message.content\n : message.content\n ? message.content.map((c) =>\n this.convertContentPartToAnthropic(c),\n )\n : '',\n })\n }\n\n // Post-process: Anthropic requires strictly alternating user/assistant roles.\n // Tool results are sent as role:'user' messages, which can create consecutive\n // user messages when followed by a new user message. Merge them.\n return this.mergeConsecutiveSameRoleMessages(formattedMessages)\n }\n\n /**\n * Merge consecutive messages of the same role into a single message.\n * Anthropic's API requires strictly alternating user/assistant roles.\n * Tool results are wrapped as role:'user' messages, which can collide\n * with actual user messages in multi-turn conversations.\n *\n * Also filters out empty assistant messages (e.g., from a previous failed request).\n */\n private mergeConsecutiveSameRoleMessages(\n messages: InternalTextProviderOptions['messages'],\n ): InternalTextProviderOptions['messages'] {\n const merged: InternalTextProviderOptions['messages'] = []\n\n for (const msg of messages) {\n // Skip empty assistant messages (no content or empty string)\n if (msg.role === 'assistant') {\n const hasContent = Array.isArray(msg.content)\n ? msg.content.length > 0\n : typeof msg.content === 'string' && msg.content.length > 0\n if (!hasContent) {\n continue\n }\n }\n\n const prev = merged[merged.length - 1]\n if (prev && prev.role === msg.role) {\n // Normalize both contents to arrays and concatenate\n const prevBlocks = Array.isArray(prev.content)\n ? prev.content\n : typeof prev.content === 'string' && prev.content\n ? [{ type: 'text' as const, text: prev.content }]\n : []\n const msgBlocks = Array.isArray(msg.content)\n ? msg.content\n : typeof msg.content === 'string' && msg.content\n ? [{ type: 'text' as const, text: msg.content }]\n : []\n prev.content = [...prevBlocks, ...msgBlocks]\n } else {\n merged.push({ ...msg })\n }\n }\n\n // De-duplicate tool_result blocks with the same tool_use_id.\n // This can happen when the core layer generates tool results from both\n // the tool-result part and the tool-call part's output field.\n for (const msg of merged) {\n if (Array.isArray(msg.content)) {\n const seenToolResultIds = new Set<string>()\n msg.content = msg.content.filter((block: any) => {\n if (block.type === 'tool_result' && block.tool_use_id) {\n if (seenToolResultIds.has(block.tool_use_id)) {\n return false // Remove duplicate\n }\n seenToolResultIds.add(block.tool_use_id)\n }\n return true\n })\n }\n }\n\n return merged\n }\n\n private async *processAnthropicStream(\n stream: AsyncIterable<Anthropic_SDK.Beta.BetaRawMessageStreamEvent>,\n model: string,\n genId: () => string,\n ): AsyncIterable<StreamChunk> {\n let accumulatedContent = ''\n let accumulatedThinking = ''\n const timestamp = Date.now()\n const toolCallsMap = new Map<\n number,\n { id: string; name: string; input: string; started: boolean }\n >()\n let currentToolIndex = -1\n\n // AG-UI lifecycle tracking\n const runId = genId()\n const messageId = genId()\n let stepId: string | null = null\n let hasEmittedRunStarted = false\n let hasEmittedTextMessageStart = false\n let hasEmittedRunFinished = false\n // Track current content block type for proper content_block_stop handling\n let currentBlockType: string | null = null\n\n try {\n for await (const event of stream) {\n // Emit RUN_STARTED on first event\n if (!hasEmittedRunStarted) {\n hasEmittedRunStarted = true\n yield {\n type: 'RUN_STARTED',\n runId,\n model,\n timestamp,\n }\n }\n\n if (event.type === 'content_block_start') {\n currentBlockType = event.content_block.type\n if (event.content_block.type === 'tool_use') {\n currentToolIndex++\n toolCallsMap.set(currentToolIndex, {\n id: event.content_block.id,\n name: event.content_block.name,\n input: '',\n started: false,\n })\n } else if (event.content_block.type === 'thinking') {\n accumulatedThinking = ''\n // Emit STEP_STARTED for thinking\n stepId = genId()\n yield {\n type: 'STEP_STARTED',\n stepId,\n model,\n timestamp,\n stepType: 'thinking',\n }\n }\n } else if (event.type === 'content_block_delta') {\n if (event.delta.type === 'text_delta') {\n // Emit TEXT_MESSAGE_START on first text content\n if (!hasEmittedTextMessageStart) {\n hasEmittedTextMessageStart = true\n yield {\n type: 'TEXT_MESSAGE_START',\n messageId,\n model,\n timestamp,\n role: 'assistant',\n }\n }\n\n const delta = event.delta.text\n accumulatedContent += delta\n yield {\n type: 'TEXT_MESSAGE_CONTENT',\n messageId,\n model,\n timestamp,\n delta,\n content: accumulatedContent,\n }\n } else if (event.delta.type === 'thinking_delta') {\n const delta = event.delta.thinking\n accumulatedThinking += delta\n yield {\n type: 'STEP_FINISHED',\n stepId: stepId || genId(),\n model,\n timestamp,\n delta,\n content: accumulatedThinking,\n }\n } else if (event.delta.type === 'input_json_delta') {\n const existing = toolCallsMap.get(currentToolIndex)\n if (existing) {\n // Emit TOOL_CALL_START on first args delta\n if (!existing.started) {\n existing.started = true\n yield {\n type: 'TOOL_CALL_START',\n toolCallId: existing.id,\n toolName: existing.name,\n model,\n timestamp,\n index: currentToolIndex,\n }\n }\n\n existing.input += event.delta.partial_json\n\n yield {\n type: 'TOOL_CALL_ARGS',\n toolCallId: existing.id,\n model,\n timestamp,\n delta: event.delta.partial_json,\n args: existing.input,\n }\n }\n }\n } else if (event.type === 'content_block_stop') {\n if (currentBlockType === 'tool_use') {\n const existing = toolCallsMap.get(currentToolIndex)\n if (existing) {\n // If tool call wasn't started yet (no args), start it now\n if (!existing.started) {\n existing.started = true\n yield {\n type: 'TOOL_CALL_START',\n toolCallId: existing.id,\n toolName: existing.name,\n model,\n timestamp,\n index: currentToolIndex,\n }\n }\n\n // Emit TOOL_CALL_END\n let parsedInput: unknown = {}\n try {\n const parsed = existing.input ? JSON.parse(existing.input) : {}\n parsedInput = parsed && typeof parsed === 'object' ? parsed : {}\n } catch {\n parsedInput = {}\n }\n\n yield {\n type: 'TOOL_CALL_END',\n toolCallId: existing.id,\n toolName: existing.name,\n model,\n timestamp,\n input: parsedInput,\n }\n\n // Reset so a new TEXT_MESSAGE_START is emitted if text follows tool calls\n hasEmittedTextMessageStart = false\n }\n } else {\n // Emit TEXT_MESSAGE_END only for text blocks (not tool_use blocks)\n if (hasEmittedTextMessageStart && accumulatedContent) {\n yield {\n type: 'TEXT_MESSAGE_END',\n messageId,\n model,\n timestamp,\n }\n }\n }\n currentBlockType = null\n } else if (event.type === 'message_stop') {\n // Only emit RUN_FINISHED from message_stop if message_delta didn't already emit one.\n // message_delta carries the real stop_reason (tool_use, end_turn, etc.),\n // while message_stop is just a completion signal.\n if (!hasEmittedRunFinished) {\n yield {\n type: 'RUN_FINISHED',\n runId,\n model,\n timestamp,\n finishReason: 'stop',\n }\n }\n } else if (event.type === 'message_delta') {\n if (event.delta.stop_reason) {\n hasEmittedRunFinished = true\n switch (event.delta.stop_reason) {\n case 'tool_use': {\n yield {\n type: 'RUN_FINISHED',\n runId,\n model,\n timestamp,\n finishReason: 'tool_calls',\n usage: {\n promptTokens: event.usage.input_tokens || 0,\n completionTokens: event.usage.output_tokens || 0,\n totalTokens:\n (event.usage.input_tokens || 0) +\n (event.usage.output_tokens || 0),\n },\n }\n break\n }\n case 'max_tokens': {\n yield {\n type: 'RUN_ERROR',\n runId,\n model,\n timestamp,\n error: {\n message:\n 'The response was cut off because the maximum token limit was reached.',\n code: 'max_tokens',\n },\n }\n break\n }\n default: {\n yield {\n type: 'RUN_FINISHED',\n runId,\n model,\n timestamp,\n finishReason: 'stop',\n usage: {\n promptTokens: event.usage.input_tokens || 0,\n completionTokens: event.usage.output_tokens || 0,\n totalTokens:\n (event.usage.input_tokens || 0) +\n (event.usage.output_tokens || 0),\n },\n }\n }\n }\n }\n }\n }\n } catch (error: unknown) {\n const err = error as Error & { status?: number; code?: string }\n\n yield {\n type: 'RUN_ERROR',\n runId,\n model,\n timestamp,\n error: {\n message: err.message || 'Unknown error occurred',\n code: err.code || String(err.status),\n },\n }\n }\n }\n}\n\n/**\n * Creates an Anthropic chat adapter with explicit API key.\n * Type resolution happens here at the call site.\n */\nexport function createAnthropicChat<\n TModel extends (typeof ANTHROPIC_MODELS)[number],\n>(\n model: TModel,\n apiKey: string,\n config?: Omit<AnthropicTextConfig, 'apiKey'>,\n): AnthropicTextAdapter<\n TModel,\n ResolveProviderOptions<TModel>,\n ResolveInputModalities<TModel>\n> {\n return new AnthropicTextAdapter({ apiKey, ...config }, model)\n}\n\n/**\n * Creates an Anthropic text adapter with automatic API key detection.\n * Type resolution happens here at the call site.\n */\nexport function anthropicText<TModel extends (typeof ANTHROPIC_MODELS)[number]>(\n model: TModel,\n config?: Omit<AnthropicTextConfig, 'apiKey'>,\n): AnthropicTextAdapter<\n TModel,\n ResolveProviderOptions<TModel>,\n ResolveInputModalities<TModel>\n> {\n const apiKey = getAnthropicApiKeyFromEnv()\n return createAnthropicChat(model, apiKey, config)\n}\n"],"names":[],"mappings":"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"}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { AnthropicTextAdapter, anthropicText, createAnthropicChat, type AnthropicTextConfig, type AnthropicTextProviderOptions, } from './adapters/text.js';
|
|
2
2
|
export { AnthropicSummarizeAdapter, anthropicSummarize, createAnthropicSummarize, type AnthropicSummarizeConfig, type AnthropicSummarizeProviderOptions, } from './adapters/summarize.js';
|
|
3
|
-
export
|
|
3
|
+
export { ANTHROPIC_MODELS } from './model-meta.js';
|
|
4
|
+
export type { AnthropicChatModelProviderOptionsByName, AnthropicModelInputModalitiesByName, AnthropicChatModel, } from './model-meta.js';
|
|
4
5
|
export type { AnthropicTextMetadata, AnthropicImageMetadata, AnthropicDocumentMetadata, AnthropicAudioMetadata, AnthropicVideoMetadata, AnthropicMessageMetadataByModality, } from './message-types.js';
|
|
5
6
|
export { convertToolsToProviderFormat } from './tools/tool-converter.js';
|
|
6
7
|
export type { AnthropicTool, CustomTool } from './tools.js';
|
package/dist/esm/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { AnthropicTextAdapter, anthropicText, createAnthropicChat } from "./adapters/text.js";
|
|
2
2
|
import { AnthropicSummarizeAdapter, anthropicSummarize, createAnthropicSummarize } from "./adapters/summarize.js";
|
|
3
|
+
import { ANTHROPIC_MODELS } from "./model-meta.js";
|
|
3
4
|
import { convertToolsToProviderFormat } from "./tools/tool-converter.js";
|
|
4
5
|
export {
|
|
6
|
+
ANTHROPIC_MODELS,
|
|
5
7
|
AnthropicSummarizeAdapter,
|
|
6
8
|
AnthropicTextAdapter,
|
|
7
9
|
anthropicSummarize,
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
package/dist/esm/model-meta.d.ts
CHANGED
|
@@ -1,4 +1,44 @@
|
|
|
1
1
|
import { AnthropicContainerOptions, AnthropicContextManagementOptions, AnthropicMCPOptions, AnthropicSamplingOptions, AnthropicServiceTierOptions, AnthropicStopSequencesOptions, AnthropicThinkingOptions, AnthropicToolChoiceOptions } from './text/text-provider-options.js';
|
|
2
|
+
declare const CLAUDE_OPUS_4_6: {
|
|
3
|
+
readonly name: "claude-opus-4-6";
|
|
4
|
+
readonly id: "claude-opus-4-6";
|
|
5
|
+
readonly context_window: 200000;
|
|
6
|
+
readonly max_output_tokens: 128000;
|
|
7
|
+
readonly knowledge_cutoff: "2025-05-01";
|
|
8
|
+
readonly pricing: {
|
|
9
|
+
readonly input: {
|
|
10
|
+
readonly normal: 5;
|
|
11
|
+
};
|
|
12
|
+
readonly output: {
|
|
13
|
+
readonly normal: 25;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
readonly supports: {
|
|
17
|
+
readonly input: ["text", "image", "document"];
|
|
18
|
+
readonly extended_thinking: true;
|
|
19
|
+
readonly priority_tier: true;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
declare const CLAUDE_OPUS_4_5: {
|
|
23
|
+
readonly name: "claude-opus-4-5";
|
|
24
|
+
readonly id: "claude-opus-4-5";
|
|
25
|
+
readonly context_window: 200000;
|
|
26
|
+
readonly max_output_tokens: 32000;
|
|
27
|
+
readonly knowledge_cutoff: "2025-11-01";
|
|
28
|
+
readonly pricing: {
|
|
29
|
+
readonly input: {
|
|
30
|
+
readonly normal: 15;
|
|
31
|
+
};
|
|
32
|
+
readonly output: {
|
|
33
|
+
readonly normal: 75;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
readonly supports: {
|
|
37
|
+
readonly input: ["text", "image", "document"];
|
|
38
|
+
readonly extended_thinking: true;
|
|
39
|
+
readonly priority_tier: true;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
2
42
|
declare const CLAUDE_SONNET_4_5: {
|
|
3
43
|
readonly name: "claude-sonnet-4-5";
|
|
4
44
|
readonly id: "claude-sonnet-4-5";
|
|
@@ -59,26 +99,6 @@ declare const CLAUDE_OPUS_4_1: {
|
|
|
59
99
|
readonly priority_tier: true;
|
|
60
100
|
};
|
|
61
101
|
};
|
|
62
|
-
declare const CLAUDE_OPUS_4_5: {
|
|
63
|
-
readonly name: "claude-opus-4-5";
|
|
64
|
-
readonly id: "claude-opus-4-5";
|
|
65
|
-
readonly context_window: 200000;
|
|
66
|
-
readonly max_output_tokens: 32000;
|
|
67
|
-
readonly knowledge_cutoff: "2025-11-01";
|
|
68
|
-
readonly pricing: {
|
|
69
|
-
readonly input: {
|
|
70
|
-
readonly normal: 15;
|
|
71
|
-
};
|
|
72
|
-
readonly output: {
|
|
73
|
-
readonly normal: 75;
|
|
74
|
-
};
|
|
75
|
-
};
|
|
76
|
-
readonly supports: {
|
|
77
|
-
readonly input: ["text", "image", "document"];
|
|
78
|
-
readonly extended_thinking: true;
|
|
79
|
-
readonly priority_tier: true;
|
|
80
|
-
};
|
|
81
|
-
};
|
|
82
102
|
declare const CLAUDE_SONNET_4: {
|
|
83
103
|
readonly name: "claude-sonnet-4";
|
|
84
104
|
readonly id: "claude-sonnet-4";
|
|
@@ -178,8 +198,10 @@ declare const CLAUDE_HAIKU_3: {
|
|
|
178
198
|
readonly priority_tier: false;
|
|
179
199
|
};
|
|
180
200
|
};
|
|
181
|
-
export declare const ANTHROPIC_MODELS: readonly ["claude-opus-4-5", "claude-sonnet-4-5", "claude-haiku-4-5", "claude-opus-4-1", "claude-sonnet-4", "claude-3-7-sonnet", "claude-opus-4", "claude-3-5-haiku", "claude-3-haiku"];
|
|
201
|
+
export declare const ANTHROPIC_MODELS: readonly ["claude-opus-4-6", "claude-opus-4-5", "claude-sonnet-4-5", "claude-haiku-4-5", "claude-opus-4-1", "claude-sonnet-4", "claude-3-7-sonnet", "claude-opus-4", "claude-3-5-haiku", "claude-3-haiku"];
|
|
202
|
+
export type AnthropicChatModel = (typeof ANTHROPIC_MODELS)[number];
|
|
182
203
|
export type AnthropicChatModelProviderOptionsByName = {
|
|
204
|
+
[CLAUDE_OPUS_4_6.id]: AnthropicContainerOptions & AnthropicContextManagementOptions & AnthropicMCPOptions & AnthropicServiceTierOptions & AnthropicStopSequencesOptions & AnthropicThinkingOptions & AnthropicToolChoiceOptions & AnthropicSamplingOptions;
|
|
183
205
|
[CLAUDE_OPUS_4_5.id]: AnthropicContainerOptions & AnthropicContextManagementOptions & AnthropicMCPOptions & AnthropicServiceTierOptions & AnthropicStopSequencesOptions & AnthropicThinkingOptions & AnthropicToolChoiceOptions & AnthropicSamplingOptions;
|
|
184
206
|
[CLAUDE_SONNET_4_5.id]: AnthropicContainerOptions & AnthropicContextManagementOptions & AnthropicMCPOptions & AnthropicServiceTierOptions & AnthropicStopSequencesOptions & AnthropicThinkingOptions & AnthropicToolChoiceOptions & AnthropicSamplingOptions;
|
|
185
207
|
[CLAUDE_HAIKU_4_5.id]: AnthropicContainerOptions & AnthropicContextManagementOptions & AnthropicMCPOptions & AnthropicServiceTierOptions & AnthropicStopSequencesOptions & AnthropicThinkingOptions & AnthropicToolChoiceOptions & AnthropicSamplingOptions;
|
|
@@ -202,6 +224,7 @@ export type AnthropicChatModelProviderOptionsByName = {
|
|
|
202
224
|
* @see https://docs.anthropic.com/claude/docs/pdf-support
|
|
203
225
|
*/
|
|
204
226
|
export type AnthropicModelInputModalitiesByName = {
|
|
227
|
+
[CLAUDE_OPUS_4_6.id]: typeof CLAUDE_OPUS_4_6.supports.input;
|
|
205
228
|
[CLAUDE_OPUS_4_5.id]: typeof CLAUDE_OPUS_4_5.supports.input;
|
|
206
229
|
[CLAUDE_SONNET_4_5.id]: typeof CLAUDE_SONNET_4_5.supports.input;
|
|
207
230
|
[CLAUDE_HAIKU_4_5.id]: typeof CLAUDE_HAIKU_4_5.supports.input;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const CLAUDE_OPUS_4_6 = {
|
|
2
|
+
id: "claude-opus-4-6"
|
|
3
|
+
};
|
|
4
|
+
const CLAUDE_OPUS_4_5 = {
|
|
5
|
+
id: "claude-opus-4-5"
|
|
6
|
+
};
|
|
7
|
+
const CLAUDE_SONNET_4_5 = {
|
|
8
|
+
id: "claude-sonnet-4-5"
|
|
9
|
+
};
|
|
10
|
+
const CLAUDE_HAIKU_4_5 = {
|
|
11
|
+
id: "claude-haiku-4-5"
|
|
12
|
+
};
|
|
13
|
+
const CLAUDE_OPUS_4_1 = {
|
|
14
|
+
id: "claude-opus-4-1"
|
|
15
|
+
};
|
|
16
|
+
const CLAUDE_SONNET_4 = {
|
|
17
|
+
id: "claude-sonnet-4"
|
|
18
|
+
};
|
|
19
|
+
const CLAUDE_SONNET_3_7 = {
|
|
20
|
+
id: "claude-3-7-sonnet"
|
|
21
|
+
};
|
|
22
|
+
const CLAUDE_OPUS_4 = {
|
|
23
|
+
id: "claude-opus-4"
|
|
24
|
+
};
|
|
25
|
+
const CLAUDE_HAIKU_3_5 = {
|
|
26
|
+
id: "claude-3-5-haiku"
|
|
27
|
+
};
|
|
28
|
+
const CLAUDE_HAIKU_3 = {
|
|
29
|
+
id: "claude-3-haiku"
|
|
30
|
+
};
|
|
31
|
+
const ANTHROPIC_MODELS = [
|
|
32
|
+
CLAUDE_OPUS_4_6.id,
|
|
33
|
+
CLAUDE_OPUS_4_5.id,
|
|
34
|
+
CLAUDE_SONNET_4_5.id,
|
|
35
|
+
CLAUDE_HAIKU_4_5.id,
|
|
36
|
+
CLAUDE_OPUS_4_1.id,
|
|
37
|
+
CLAUDE_SONNET_4.id,
|
|
38
|
+
CLAUDE_SONNET_3_7.id,
|
|
39
|
+
CLAUDE_OPUS_4.id,
|
|
40
|
+
CLAUDE_HAIKU_3_5.id,
|
|
41
|
+
CLAUDE_HAIKU_3.id
|
|
42
|
+
];
|
|
43
|
+
export {
|
|
44
|
+
ANTHROPIC_MODELS
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=model-meta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-meta.js","sources":["../../src/model-meta.ts"],"sourcesContent":["import type {\n AnthropicContainerOptions,\n AnthropicContextManagementOptions,\n AnthropicMCPOptions,\n AnthropicSamplingOptions,\n AnthropicServiceTierOptions,\n AnthropicStopSequencesOptions,\n AnthropicThinkingOptions,\n AnthropicToolChoiceOptions,\n} from './text/text-provider-options'\n\ninterface ModelMeta<\n TProviderOptions = unknown,\n TToolCapabilities = unknown,\n TMessageCapabilities = unknown,\n> {\n name: string\n id: string\n supports: {\n input: Array<'text' | 'image' | 'audio' | 'video' | 'document'>\n extended_thinking?: boolean\n adaptive_thinking?: boolean\n priority_tier?: boolean\n }\n context_window?: number\n max_output_tokens?: number\n knowledge_cutoff?: string\n pricing: {\n input: {\n normal: number\n cached?: number\n }\n output: {\n normal: number\n }\n }\n /**\n * Type-level description of which provider options this model supports.\n */\n providerOptions?: TProviderOptions\n /**\n * Type-level description of which tool capabilities this model supports.\n */\n toolCapabilities?: TToolCapabilities\n /**\n * Type-level description of which message/input capabilities this model supports.\n */\n messageCapabilities?: TMessageCapabilities\n}\n\nconst CLAUDE_OPUS_4_6 = {\n name: 'claude-opus-4-6',\n id: 'claude-opus-4-6',\n context_window: 200_000,\n max_output_tokens: 128_000,\n knowledge_cutoff: '2025-05-01',\n pricing: {\n input: {\n normal: 5,\n },\n output: {\n normal: 25,\n },\n },\n supports: {\n input: ['text', 'image', 'document'],\n extended_thinking: true,\n priority_tier: true,\n },\n} as const satisfies ModelMeta<\n AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicThinkingOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions\n>\n\nconst CLAUDE_OPUS_4_5 = {\n name: 'claude-opus-4-5',\n id: 'claude-opus-4-5',\n context_window: 200_000,\n max_output_tokens: 32_000,\n knowledge_cutoff: '2025-11-01',\n pricing: {\n input: {\n normal: 15,\n },\n output: {\n normal: 75,\n },\n },\n supports: {\n input: ['text', 'image', 'document'],\n extended_thinking: true,\n priority_tier: true,\n },\n} as const satisfies ModelMeta<\n AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicThinkingOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions\n>\n\nconst CLAUDE_SONNET_4_5 = {\n name: 'claude-sonnet-4-5',\n id: 'claude-sonnet-4-5',\n context_window: 200_000,\n max_output_tokens: 64_000,\n knowledge_cutoff: '2025-09-29',\n pricing: {\n input: {\n normal: 3,\n },\n output: {\n normal: 15,\n },\n },\n supports: {\n input: ['text', 'image', 'document'],\n extended_thinking: true,\n priority_tier: true,\n },\n} as const satisfies ModelMeta<\n AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicThinkingOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions\n>\n\nconst CLAUDE_HAIKU_4_5 = {\n name: 'claude-haiku-4-5',\n id: 'claude-haiku-4-5',\n context_window: 200_000,\n max_output_tokens: 64_000,\n knowledge_cutoff: '2025-10-01',\n pricing: {\n input: {\n normal: 1,\n },\n output: {\n normal: 5,\n },\n },\n supports: {\n input: ['text', 'image', 'document'],\n extended_thinking: true,\n priority_tier: true,\n },\n} as const satisfies ModelMeta<\n AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicThinkingOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions\n>\n\nconst CLAUDE_OPUS_4_1 = {\n name: 'claude-opus-4-1',\n id: 'claude-opus-4-1',\n context_window: 200_000,\n max_output_tokens: 64_000,\n knowledge_cutoff: '2025-08-05',\n pricing: {\n input: {\n normal: 15,\n },\n output: {\n normal: 75,\n },\n },\n supports: {\n input: ['text', 'image', 'document'],\n extended_thinking: true,\n priority_tier: true,\n },\n} as const satisfies ModelMeta<\n AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicThinkingOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions\n>\n\nconst CLAUDE_SONNET_4 = {\n name: 'claude-sonnet-4',\n id: 'claude-sonnet-4',\n context_window: 200_000,\n max_output_tokens: 64_000,\n knowledge_cutoff: '2025-05-14',\n pricing: {\n input: {\n normal: 3,\n },\n output: {\n normal: 15,\n },\n },\n supports: {\n input: ['text', 'image', 'document'],\n extended_thinking: true,\n priority_tier: true,\n },\n} as const satisfies ModelMeta<\n AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicThinkingOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions\n>\n\nconst CLAUDE_SONNET_3_7 = {\n name: 'claude-sonnet-3-7',\n id: 'claude-3-7-sonnet',\n max_output_tokens: 64_000,\n knowledge_cutoff: '2025-05-14',\n pricing: {\n input: {\n normal: 3,\n },\n output: {\n normal: 15,\n },\n },\n supports: {\n input: ['text', 'image', 'document'],\n extended_thinking: true,\n priority_tier: true,\n },\n} as const satisfies ModelMeta<\n AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicThinkingOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions\n>\n\nconst CLAUDE_OPUS_4 = {\n name: 'claude-opus-4',\n id: 'claude-opus-4',\n context_window: 200_000,\n max_output_tokens: 32_000,\n knowledge_cutoff: '2025-05-14',\n pricing: {\n input: {\n normal: 15,\n },\n output: {\n normal: 75,\n },\n },\n supports: {\n input: ['text', 'image', 'document'],\n extended_thinking: true,\n priority_tier: true,\n },\n} as const satisfies ModelMeta<\n AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicThinkingOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions\n>\n\nconst CLAUDE_HAIKU_3_5 = {\n name: 'claude-haiku-3-5',\n id: 'claude-3-5-haiku',\n context_window: 200_000,\n max_output_tokens: 8_000,\n knowledge_cutoff: '2025-10-22',\n pricing: {\n input: {\n normal: 0.8,\n },\n output: {\n normal: 4,\n },\n },\n supports: {\n input: ['text', 'image', 'document'],\n extended_thinking: false,\n priority_tier: true,\n },\n} as const satisfies ModelMeta<\n AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicThinkingOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions\n>\n\nconst CLAUDE_HAIKU_3 = {\n name: 'claude-haiku-3',\n id: 'claude-3-haiku',\n context_window: 200_000,\n max_output_tokens: 4_000,\n knowledge_cutoff: '2024-03-07',\n pricing: {\n input: {\n normal: 0.25,\n },\n output: {\n normal: 1.25,\n },\n },\n supports: {\n input: ['text', 'image', 'document'],\n extended_thinking: false,\n priority_tier: false,\n },\n} as const satisfies ModelMeta<\n AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicThinkingOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions\n>\n\n/* const ANTHROPIC_MODEL_META = {\n [CLAUDE_OPUS_4_5.name]: CLAUDE_OPUS_4_5,\n [CLAUDE_SONNET_4_5.name]: CLAUDE_SONNET_4_5,\n [CLAUDE_HAIKU_4_5.name]: CLAUDE_HAIKU_4_5,\n [CLAUDE_OPUS_4_1.name]: CLAUDE_OPUS_4_1,\n [CLAUDE_SONNET_4.name]: CLAUDE_SONNET_4,\n [CLAUDE_SONNET_3_7.name]: CLAUDE_SONNET_3_7,\n [CLAUDE_OPUS_4.name]: CLAUDE_OPUS_4,\n [CLAUDE_HAIKU_3_5.name]: CLAUDE_HAIKU_3_5,\n [CLAUDE_HAIKU_3.name]: CLAUDE_HAIKU_3,\n} as const */\n\n/* export type AnthropicModelProviderOptions<\n TModel extends keyof AnthropicModelMetaMap,\n> =\n AnthropicModelMetaMap[TModel] extends ModelMeta<\n infer TProviderOptions,\n any,\n any\n >\n ? TProviderOptions\n : unknown */\n\n/* export type AnthropicModelToolCapabilities<\n TModel extends keyof AnthropicModelMetaMap,\n> =\n AnthropicModelMetaMap[TModel] extends ModelMeta<\n any,\n infer TToolCapabilities,\n any\n >\n ? TToolCapabilities\n : unknown\n */\n/* export type AnthropicModelMessageCapabilities<\n TModel extends keyof AnthropicModelMetaMap,\n> =\n AnthropicModelMetaMap[TModel] extends ModelMeta<\n any,\n any,\n infer TMessageCapabilities\n >\n ? TMessageCapabilities\n : unknown */\n\nexport const ANTHROPIC_MODELS = [\n CLAUDE_OPUS_4_6.id,\n CLAUDE_OPUS_4_5.id,\n CLAUDE_SONNET_4_5.id,\n CLAUDE_HAIKU_4_5.id,\n CLAUDE_OPUS_4_1.id,\n CLAUDE_SONNET_4.id,\n CLAUDE_SONNET_3_7.id,\n CLAUDE_OPUS_4.id,\n CLAUDE_HAIKU_3_5.id,\n CLAUDE_HAIKU_3.id,\n] as const\n\n// const ANTHROPIC_IMAGE_MODELS = [] as const\n// const ANTHROPIC_EMBEDDING_MODELS = [] as const\n// const ANTHROPIC_AUDIO_MODELS = [] as const\n// const ANTHROPIC_VIDEO_MODELS = [] as const\n\n/* type AnthropicModel = (typeof ANTHROPIC_MODELS)[number] */\nexport type AnthropicChatModel = (typeof ANTHROPIC_MODELS)[number]\n// Manual type map for per-model provider options\n// Models are differentiated by extended_thinking and priority_tier support\nexport type AnthropicChatModelProviderOptionsByName = {\n // Models with both extended_thinking and priority_tier\n [CLAUDE_OPUS_4_6.id]: AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicThinkingOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions\n [CLAUDE_OPUS_4_5.id]: AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicThinkingOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions\n [CLAUDE_SONNET_4_5.id]: AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicThinkingOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions\n [CLAUDE_HAIKU_4_5.id]: AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicThinkingOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions\n [CLAUDE_OPUS_4_1.id]: AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicThinkingOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions\n [CLAUDE_SONNET_4.id]: AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicThinkingOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions\n [CLAUDE_SONNET_3_7.id]: AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicThinkingOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions\n [CLAUDE_OPUS_4.id]: AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicThinkingOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions\n\n // Model with priority_tier but NO extended_thinking\n [CLAUDE_HAIKU_3_5.id]: AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions\n\n // Model with neither extended_thinking nor priority_tier\n [CLAUDE_HAIKU_3.id]: AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicStopSequencesOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions\n}\n\n/**\n * Type-only map from chat model name to its supported input modalities.\n * All Anthropic Claude models support text, image, and document (PDF) input.\n * Used by the core AI types to constrain ContentPart types based on the selected model.\n * Note: These must be inlined as readonly arrays (not typeof) because the model\n * constants are not exported and typeof references don't work in .d.ts files\n * when consumed by external packages.\n *\n * @see https://docs.anthropic.com/claude/docs/vision\n * @see https://docs.anthropic.com/claude/docs/pdf-support\n */\nexport type AnthropicModelInputModalitiesByName = {\n [CLAUDE_OPUS_4_6.id]: typeof CLAUDE_OPUS_4_6.supports.input\n [CLAUDE_OPUS_4_5.id]: typeof CLAUDE_OPUS_4_5.supports.input\n [CLAUDE_SONNET_4_5.id]: typeof CLAUDE_SONNET_4_5.supports.input\n [CLAUDE_HAIKU_4_5.id]: typeof CLAUDE_HAIKU_4_5.supports.input\n [CLAUDE_OPUS_4_1.id]: typeof CLAUDE_OPUS_4_1.supports.input\n [CLAUDE_SONNET_4.id]: typeof CLAUDE_SONNET_4.supports.input\n [CLAUDE_SONNET_3_7.id]: typeof CLAUDE_SONNET_3_7.supports.input\n [CLAUDE_OPUS_4.id]: typeof CLAUDE_OPUS_4.supports.input\n [CLAUDE_HAIKU_3_5.id]: typeof CLAUDE_HAIKU_3_5.supports.input\n [CLAUDE_HAIKU_3.id]: typeof CLAUDE_HAIKU_3.supports.input\n}\n"],"names":[],"mappings":"AAkDA,MAAM,kBAAkB;AAAA,EAEtB,IAAI;AAiBN;AAWA,MAAM,kBAAkB;AAAA,EAEtB,IAAI;AAiBN;AAWA,MAAM,oBAAoB;AAAA,EAExB,IAAI;AAiBN;AAWA,MAAM,mBAAmB;AAAA,EAEvB,IAAI;AAiBN;AAWA,MAAM,kBAAkB;AAAA,EAEtB,IAAI;AAiBN;AAWA,MAAM,kBAAkB;AAAA,EAEtB,IAAI;AAiBN;AAWA,MAAM,oBAAoB;AAAA,EAExB,IAAI;AAgBN;AAWA,MAAM,gBAAgB;AAAA,EAEpB,IAAI;AAiBN;AAWA,MAAM,mBAAmB;AAAA,EAEvB,IAAI;AAiBN;AAWA,MAAM,iBAAiB;AAAA,EAErB,IAAI;AAiBN;AAwDO,MAAM,mBAAmB;AAAA,EAC9B,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,eAAe;AACjB;"}
|
|
@@ -73,6 +73,37 @@ Must be ≥1024 and less than max_tokens
|
|
|
73
73
|
type: 'disabled';
|
|
74
74
|
};
|
|
75
75
|
}
|
|
76
|
+
export interface AnthropicAdaptiveThinkingOptions {
|
|
77
|
+
/**
|
|
78
|
+
* Configuration for Claude's adaptive thinking (Opus 4.6+).
|
|
79
|
+
*
|
|
80
|
+
* In adaptive mode, Claude dynamically decides when and how much to think.
|
|
81
|
+
* Use the effort parameter to control thinking depth.
|
|
82
|
+
* `thinking: {type: "enabled"}` with `budget_tokens` is deprecated on Opus 4.6.
|
|
83
|
+
*/
|
|
84
|
+
thinking?: {
|
|
85
|
+
type: 'adaptive';
|
|
86
|
+
} | {
|
|
87
|
+
/**
|
|
88
|
+
* @deprecated Use `type: 'adaptive'` with the effort parameter on Opus 4.6+.
|
|
89
|
+
*/
|
|
90
|
+
budget_tokens: number;
|
|
91
|
+
type: 'enabled';
|
|
92
|
+
} | {
|
|
93
|
+
type: 'disabled';
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
export interface AnthropicEffortOptions {
|
|
97
|
+
/**
|
|
98
|
+
* Controls the thinking depth for adaptive thinking mode (Opus 4.6+).
|
|
99
|
+
*
|
|
100
|
+
* - `max`: Absolute highest capability
|
|
101
|
+
* - `high`: Default - Claude will almost always think
|
|
102
|
+
* - `medium`: Balanced cost-quality
|
|
103
|
+
* - `low`: May skip thinking for simpler problems
|
|
104
|
+
*/
|
|
105
|
+
effort?: 'max' | 'high' | 'medium' | 'low';
|
|
106
|
+
}
|
|
76
107
|
export interface AnthropicToolChoiceOptions {
|
|
77
108
|
tool_choice?: BetaToolChoiceAny | BetaToolChoiceTool | BetaToolChoiceAuto;
|
|
78
109
|
}
|
|
@@ -87,7 +118,7 @@ export interface AnthropicSamplingOptions {
|
|
|
87
118
|
*/
|
|
88
119
|
top_k?: number;
|
|
89
120
|
}
|
|
90
|
-
export type ExternalTextProviderOptions = AnthropicContainerOptions & AnthropicContextManagementOptions & AnthropicMCPOptions & AnthropicServiceTierOptions & AnthropicStopSequencesOptions & AnthropicThinkingOptions & AnthropicToolChoiceOptions & AnthropicSamplingOptions
|
|
121
|
+
export type ExternalTextProviderOptions = AnthropicContainerOptions & AnthropicContextManagementOptions & AnthropicMCPOptions & AnthropicServiceTierOptions & AnthropicStopSequencesOptions & AnthropicThinkingOptions & AnthropicToolChoiceOptions & AnthropicSamplingOptions & Partial<AnthropicAdaptiveThinkingOptions> & Partial<AnthropicEffortOptions>;
|
|
91
122
|
export interface InternalTextProviderOptions extends ExternalTextProviderOptions {
|
|
92
123
|
model: string;
|
|
93
124
|
messages: Array<MessageParam>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text-provider-options.js","sources":["../../../src/text/text-provider-options.ts"],"sourcesContent":["import type {\n BetaContextManagementConfig,\n BetaToolChoiceAny,\n BetaToolChoiceAuto,\n BetaToolChoiceTool,\n} from '@anthropic-ai/sdk/resources/beta/messages/messages'\nimport type { AnthropicTool } from '../tools'\nimport type {\n MessageParam,\n TextBlockParam,\n} from '@anthropic-ai/sdk/resources/messages'\n\nexport interface AnthropicContainerOptions {\n /**\n * Container identifier for reuse across requests.\n * Container parameters with skills to be loaded.\n */\n container?: {\n id: string | null\n /**\n * List of skills to load into the container\n */\n skills: Array<{\n /**\n * Between 1-64 characters\n */\n skill_id: string\n\n type: 'anthropic' | 'custom'\n /**\n * Skill version or latest by default\n */\n version?: string\n }> | null\n } | null\n}\n\nexport interface AnthropicContextManagementOptions {\n /**\n * Context management configuration.\n\nThis allows you to control how Claude manages context across multiple requests, such as whether to clear function results or not.\n */\n context_management?: BetaContextManagementConfig | null\n}\n\nexport interface AnthropicMCPOptions {\n /**\n * MCP servers to be utilized in this request\n * Maximum of 20 servers\n */\n mcp_servers?: Array<MCPServer>\n}\n\nexport interface AnthropicServiceTierOptions {\n /**\n * Determines whether to use priority capacity (if available) or standard capacity for this request.\n */\n service_tier?: 'auto' | 'standard_only'\n}\n\nexport interface AnthropicStopSequencesOptions {\n /**\n * Custom text sequences that will cause the model to stop generating.\n\nAnthropic models will normally stop when they have naturally completed their turn, which will result in a response stop_reason of \"end_turn\".\n\nIf you want the model to stop generating when it encounters custom strings of text, you can use the stop_sequences parameter. If the model encounters one of the custom sequences, the response stop_reason value will be \"stop_sequence\" and the response stop_sequence value will contain the matched stop sequence.\n */\n stop_sequences?: Array<string>\n}\n\nexport interface AnthropicThinkingOptions {\n /**\n * Configuration for enabling Claude's extended thinking.\n\nWhen enabled, responses include thinking content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your max_tokens limit.\n */\n thinking?:\n | {\n /**\n* Determines how many tokens Claude can use for its internal reasoning process. Larger budgets can enable more thorough analysis for complex problems, improving response quality.\n\nMust be ≥1024 and less than max_tokens\n*/\n budget_tokens: number\n\n type: 'enabled'\n }\n | {\n type: 'disabled'\n }\n}\n\nexport interface AnthropicToolChoiceOptions {\n tool_choice?: BetaToolChoiceAny | BetaToolChoiceTool | BetaToolChoiceAuto\n}\n\nexport interface AnthropicSamplingOptions {\n /**\n * Only sample from the top K options for each subsequent token.\n\nUsed to remove \"long tail\" low probability responses.\nRecommended for advanced use cases only. You usually only need to use temperature.\n\nRequired range: x >= 0\n */\n top_k?: number\n}\n\nexport type ExternalTextProviderOptions = AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicThinkingOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions
|
|
1
|
+
{"version":3,"file":"text-provider-options.js","sources":["../../../src/text/text-provider-options.ts"],"sourcesContent":["import type {\n BetaContextManagementConfig,\n BetaToolChoiceAny,\n BetaToolChoiceAuto,\n BetaToolChoiceTool,\n} from '@anthropic-ai/sdk/resources/beta/messages/messages'\nimport type { AnthropicTool } from '../tools'\nimport type {\n MessageParam,\n TextBlockParam,\n} from '@anthropic-ai/sdk/resources/messages'\n\nexport interface AnthropicContainerOptions {\n /**\n * Container identifier for reuse across requests.\n * Container parameters with skills to be loaded.\n */\n container?: {\n id: string | null\n /**\n * List of skills to load into the container\n */\n skills: Array<{\n /**\n * Between 1-64 characters\n */\n skill_id: string\n\n type: 'anthropic' | 'custom'\n /**\n * Skill version or latest by default\n */\n version?: string\n }> | null\n } | null\n}\n\nexport interface AnthropicContextManagementOptions {\n /**\n * Context management configuration.\n\nThis allows you to control how Claude manages context across multiple requests, such as whether to clear function results or not.\n */\n context_management?: BetaContextManagementConfig | null\n}\n\nexport interface AnthropicMCPOptions {\n /**\n * MCP servers to be utilized in this request\n * Maximum of 20 servers\n */\n mcp_servers?: Array<MCPServer>\n}\n\nexport interface AnthropicServiceTierOptions {\n /**\n * Determines whether to use priority capacity (if available) or standard capacity for this request.\n */\n service_tier?: 'auto' | 'standard_only'\n}\n\nexport interface AnthropicStopSequencesOptions {\n /**\n * Custom text sequences that will cause the model to stop generating.\n\nAnthropic models will normally stop when they have naturally completed their turn, which will result in a response stop_reason of \"end_turn\".\n\nIf you want the model to stop generating when it encounters custom strings of text, you can use the stop_sequences parameter. If the model encounters one of the custom sequences, the response stop_reason value will be \"stop_sequence\" and the response stop_sequence value will contain the matched stop sequence.\n */\n stop_sequences?: Array<string>\n}\n\nexport interface AnthropicThinkingOptions {\n /**\n * Configuration for enabling Claude's extended thinking.\n\nWhen enabled, responses include thinking content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your max_tokens limit.\n */\n thinking?:\n | {\n /**\n* Determines how many tokens Claude can use for its internal reasoning process. Larger budgets can enable more thorough analysis for complex problems, improving response quality.\n\nMust be ≥1024 and less than max_tokens\n*/\n budget_tokens: number\n\n type: 'enabled'\n }\n | {\n type: 'disabled'\n }\n}\n\nexport interface AnthropicAdaptiveThinkingOptions {\n /**\n * Configuration for Claude's adaptive thinking (Opus 4.6+).\n *\n * In adaptive mode, Claude dynamically decides when and how much to think.\n * Use the effort parameter to control thinking depth.\n * `thinking: {type: \"enabled\"}` with `budget_tokens` is deprecated on Opus 4.6.\n */\n thinking?:\n | {\n type: 'adaptive'\n }\n | {\n /**\n * @deprecated Use `type: 'adaptive'` with the effort parameter on Opus 4.6+.\n */\n budget_tokens: number\n type: 'enabled'\n }\n | {\n type: 'disabled'\n }\n}\n\nexport interface AnthropicEffortOptions {\n /**\n * Controls the thinking depth for adaptive thinking mode (Opus 4.6+).\n *\n * - `max`: Absolute highest capability\n * - `high`: Default - Claude will almost always think\n * - `medium`: Balanced cost-quality\n * - `low`: May skip thinking for simpler problems\n */\n effort?: 'max' | 'high' | 'medium' | 'low'\n}\n\nexport interface AnthropicToolChoiceOptions {\n tool_choice?: BetaToolChoiceAny | BetaToolChoiceTool | BetaToolChoiceAuto\n}\n\nexport interface AnthropicSamplingOptions {\n /**\n * Only sample from the top K options for each subsequent token.\n\nUsed to remove \"long tail\" low probability responses.\nRecommended for advanced use cases only. You usually only need to use temperature.\n\nRequired range: x >= 0\n */\n top_k?: number\n}\n\nexport type ExternalTextProviderOptions = AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicThinkingOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions &\n Partial<AnthropicAdaptiveThinkingOptions> &\n Partial<AnthropicEffortOptions>\n\nexport interface InternalTextProviderOptions extends ExternalTextProviderOptions {\n model: string\n\n messages: Array<MessageParam>\n\n /**\n * The maximum number of tokens to generate before stopping. This parameter only specifies the absolute maximum number of tokens to generate.\n * Range x >= 1.\n */\n max_tokens: number\n /**\n * Whether to incrementally stream the response using server-sent events.\n */\n stream?: boolean\n /**\n * stem prompt.\n \n A system prompt is a way of providing context and instructions to Claude, such as specifying a particular goal or role.\n */\n system?: string | Array<TextBlockParam>\n /**\n * Amount of randomness injected into the response.\n * Either use this or top_p, but not both.\n * Defaults to 1.0. Ranges from 0.0 to 1.0. Use temperature closer to 0.0 for analytical / multiple choice, and closer to 1.0 for creative and generative tasks.\n * @default 1.0\n */\n temperature?: number\n\n tools?: Array<AnthropicTool>\n\n /**\n * Use nucleus sampling.\n\nIn nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by top_p. You should either alter temperature or top_p, but not both.\n */\n top_p?: number\n}\n\nconst validateTopPandTemperature = (options: InternalTextProviderOptions) => {\n if (options.top_p !== undefined && options.temperature !== undefined) {\n throw new Error('You should either set top_p or temperature, but not both.')\n }\n}\n\nexport interface CacheControl {\n type: 'ephemeral'\n ttl: '5m' | '1h'\n}\n\nconst validateThinking = (options: InternalTextProviderOptions) => {\n const thinking = options.thinking\n if (thinking && thinking.type === 'enabled') {\n if (thinking.budget_tokens < 1024) {\n throw new Error('thinking.budget_tokens must be at least 1024.')\n }\n if (thinking.budget_tokens >= options.max_tokens) {\n throw new Error('thinking.budget_tokens must be less than max_tokens.')\n }\n }\n}\n\ninterface MCPServer {\n name: string\n url: string\n type: 'url'\n authorization_token?: string | null\n tool_configuration: {\n allowed_tools?: Array<string> | null\n enabled?: boolean | null\n } | null\n}\n\nconst validateMaxTokens = (options: InternalTextProviderOptions) => {\n if (options.max_tokens < 1) {\n throw new Error('max_tokens must be at least 1.')\n }\n}\n\nexport const validateTextProviderOptions = (\n options: InternalTextProviderOptions,\n) => {\n validateTopPandTemperature(options)\n validateThinking(options)\n validateMaxTokens(options)\n}\n"],"names":[],"mappings":"AAmMA,MAAM,6BAA6B,CAAC,YAAyC;AAC3E,MAAI,QAAQ,UAAU,UAAa,QAAQ,gBAAgB,QAAW;AACpE,UAAM,IAAI,MAAM,2DAA2D;AAAA,EAC7E;AACF;AAOA,MAAM,mBAAmB,CAAC,YAAyC;AACjE,QAAM,WAAW,QAAQ;AACzB,MAAI,YAAY,SAAS,SAAS,WAAW;AAC3C,QAAI,SAAS,gBAAgB,MAAM;AACjC,YAAM,IAAI,MAAM,+CAA+C;AAAA,IACjE;AACA,QAAI,SAAS,iBAAiB,QAAQ,YAAY;AAChD,YAAM,IAAI,MAAM,sDAAsD;AAAA,IACxE;AAAA,EACF;AACF;AAaA,MAAM,oBAAoB,CAAC,YAAyC;AAClE,MAAI,QAAQ,aAAa,GAAG;AAC1B,UAAM,IAAI,MAAM,gCAAgC;AAAA,EAClD;AACF;AAEO,MAAM,8BAA8B,CACzC,YACG;AACH,6BAA2B,OAAO;AAClC,mBAAiB,OAAO;AACxB,oBAAkB,OAAO;AAC3B;"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { default as Anthropic_SDK } from '@anthropic-ai/sdk';
|
|
2
|
-
export interface AnthropicClientConfig {
|
|
1
|
+
import { default as Anthropic_SDK, ClientOptions } from '@anthropic-ai/sdk';
|
|
2
|
+
export interface AnthropicClientConfig extends ClientOptions {
|
|
3
3
|
apiKey: string;
|
|
4
4
|
}
|
|
5
5
|
/**
|
package/dist/esm/utils/client.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sources":["../../../src/utils/client.ts"],"sourcesContent":["import Anthropic_SDK from '@anthropic-ai/sdk'\n\nexport interface AnthropicClientConfig {\n apiKey: string\n}\n\n/**\n * Creates an Anthropic SDK client instance\n */\nexport function createAnthropicClient(\n config: AnthropicClientConfig,\n): Anthropic_SDK {\n return new Anthropic_SDK({\n apiKey: config.apiKey,\n })\n}\n\n/**\n * Gets Anthropic API key from environment variables\n * @throws Error if ANTHROPIC_API_KEY is not found\n */\nexport function getAnthropicApiKeyFromEnv(): string {\n const env =\n typeof globalThis !== 'undefined' && (globalThis as any).window?.env\n ? (globalThis as any).window.env\n : typeof process !== 'undefined'\n ? process.env\n : undefined\n const key = env?.ANTHROPIC_API_KEY\n\n if (!key) {\n throw new Error(\n 'ANTHROPIC_API_KEY is required. Please set it in your environment variables or use the factory function with an explicit API key.',\n )\n }\n\n return key\n}\n\n/**\n * Generates a unique ID with a prefix\n */\nexport function generateId(prefix: string): string {\n return `${prefix}-${Date.now()}-${Math.random().toString(36).substring(7)}`\n}\n"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"client.js","sources":["../../../src/utils/client.ts"],"sourcesContent":["import Anthropic_SDK from '@anthropic-ai/sdk'\nimport type { ClientOptions } from '@anthropic-ai/sdk'\n\nexport interface AnthropicClientConfig extends ClientOptions {\n apiKey: string\n}\n\n/**\n * Creates an Anthropic SDK client instance\n */\nexport function createAnthropicClient(\n config: AnthropicClientConfig,\n): Anthropic_SDK {\n return new Anthropic_SDK({\n ...config,\n apiKey: config.apiKey,\n })\n}\n\n/**\n * Gets Anthropic API key from environment variables\n * @throws Error if ANTHROPIC_API_KEY is not found\n */\nexport function getAnthropicApiKeyFromEnv(): string {\n const env =\n typeof globalThis !== 'undefined' && (globalThis as any).window?.env\n ? (globalThis as any).window.env\n : typeof process !== 'undefined'\n ? process.env\n : undefined\n const key = env?.ANTHROPIC_API_KEY\n\n if (!key) {\n throw new Error(\n 'ANTHROPIC_API_KEY is required. Please set it in your environment variables or use the factory function with an explicit API key.',\n )\n }\n\n return key\n}\n\n/**\n * Generates a unique ID with a prefix\n */\nexport function generateId(prefix: string): string {\n return `${prefix}-${Date.now()}-${Math.random().toString(36).substring(7)}`\n}\n"],"names":[],"mappings":";AAUO,SAAS,sBACd,QACe;AACf,SAAO,IAAI,cAAc;AAAA,IACvB,GAAG;AAAA,IACH,QAAQ,OAAO;AAAA,EAAA,CAChB;AACH;AAMO,SAAS,4BAAoC;AAClD,QAAM,MACJ,OAAO,eAAe,eAAgB,WAAmB,QAAQ,MAC5D,WAAmB,OAAO,MAC3B,OAAO,YAAY,cACjB,QAAQ,MACR;AACR,QAAM,MAAM,KAAK;AAEjB,MAAI,CAAC,KAAK;AACR,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AAEA,SAAO;AACT;AAKO,SAAS,WAAW,QAAwB;AACjD,SAAO,GAAG,MAAM,IAAI,KAAK,KAAK,IAAI,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,UAAU,CAAC,CAAC;AAC3E;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/ai-anthropic",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Anthropic Claude adapter for TanStack AI",
|
|
5
5
|
"author": "",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,16 +30,16 @@
|
|
|
30
30
|
"src"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@anthropic-ai/sdk": "^0.71.
|
|
33
|
+
"@anthropic-ai/sdk": "^0.71.2"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"zod": "^4.0.0",
|
|
37
|
-
"@tanstack/ai": "^0.
|
|
37
|
+
"@tanstack/ai": "^0.5.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@vitest/coverage-v8": "4.0.14",
|
|
41
41
|
"zod": "^4.2.0",
|
|
42
|
-
"@tanstack/ai": "0.
|
|
42
|
+
"@tanstack/ai": "0.5.0"
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
45
|
"build": "vite build",
|
package/src/adapters/text.ts
CHANGED
|
@@ -247,6 +247,7 @@ export class AnthropicTextAdapter<
|
|
|
247
247
|
const validKeys: Array<keyof InternalTextProviderOptions> = [
|
|
248
248
|
'container',
|
|
249
249
|
'context_management',
|
|
250
|
+
'effort',
|
|
250
251
|
'mcp_servers',
|
|
251
252
|
'service_tier',
|
|
252
253
|
'stop_sequences',
|
|
@@ -450,7 +451,74 @@ export class AnthropicTextAdapter<
|
|
|
450
451
|
})
|
|
451
452
|
}
|
|
452
453
|
|
|
453
|
-
|
|
454
|
+
// Post-process: Anthropic requires strictly alternating user/assistant roles.
|
|
455
|
+
// Tool results are sent as role:'user' messages, which can create consecutive
|
|
456
|
+
// user messages when followed by a new user message. Merge them.
|
|
457
|
+
return this.mergeConsecutiveSameRoleMessages(formattedMessages)
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Merge consecutive messages of the same role into a single message.
|
|
462
|
+
* Anthropic's API requires strictly alternating user/assistant roles.
|
|
463
|
+
* Tool results are wrapped as role:'user' messages, which can collide
|
|
464
|
+
* with actual user messages in multi-turn conversations.
|
|
465
|
+
*
|
|
466
|
+
* Also filters out empty assistant messages (e.g., from a previous failed request).
|
|
467
|
+
*/
|
|
468
|
+
private mergeConsecutiveSameRoleMessages(
|
|
469
|
+
messages: InternalTextProviderOptions['messages'],
|
|
470
|
+
): InternalTextProviderOptions['messages'] {
|
|
471
|
+
const merged: InternalTextProviderOptions['messages'] = []
|
|
472
|
+
|
|
473
|
+
for (const msg of messages) {
|
|
474
|
+
// Skip empty assistant messages (no content or empty string)
|
|
475
|
+
if (msg.role === 'assistant') {
|
|
476
|
+
const hasContent = Array.isArray(msg.content)
|
|
477
|
+
? msg.content.length > 0
|
|
478
|
+
: typeof msg.content === 'string' && msg.content.length > 0
|
|
479
|
+
if (!hasContent) {
|
|
480
|
+
continue
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
const prev = merged[merged.length - 1]
|
|
485
|
+
if (prev && prev.role === msg.role) {
|
|
486
|
+
// Normalize both contents to arrays and concatenate
|
|
487
|
+
const prevBlocks = Array.isArray(prev.content)
|
|
488
|
+
? prev.content
|
|
489
|
+
: typeof prev.content === 'string' && prev.content
|
|
490
|
+
? [{ type: 'text' as const, text: prev.content }]
|
|
491
|
+
: []
|
|
492
|
+
const msgBlocks = Array.isArray(msg.content)
|
|
493
|
+
? msg.content
|
|
494
|
+
: typeof msg.content === 'string' && msg.content
|
|
495
|
+
? [{ type: 'text' as const, text: msg.content }]
|
|
496
|
+
: []
|
|
497
|
+
prev.content = [...prevBlocks, ...msgBlocks]
|
|
498
|
+
} else {
|
|
499
|
+
merged.push({ ...msg })
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// De-duplicate tool_result blocks with the same tool_use_id.
|
|
504
|
+
// This can happen when the core layer generates tool results from both
|
|
505
|
+
// the tool-result part and the tool-call part's output field.
|
|
506
|
+
for (const msg of merged) {
|
|
507
|
+
if (Array.isArray(msg.content)) {
|
|
508
|
+
const seenToolResultIds = new Set<string>()
|
|
509
|
+
msg.content = msg.content.filter((block: any) => {
|
|
510
|
+
if (block.type === 'tool_result' && block.tool_use_id) {
|
|
511
|
+
if (seenToolResultIds.has(block.tool_use_id)) {
|
|
512
|
+
return false // Remove duplicate
|
|
513
|
+
}
|
|
514
|
+
seenToolResultIds.add(block.tool_use_id)
|
|
515
|
+
}
|
|
516
|
+
return true
|
|
517
|
+
})
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
return merged
|
|
454
522
|
}
|
|
455
523
|
|
|
456
524
|
private async *processAnthropicStream(
|
|
@@ -473,6 +541,9 @@ export class AnthropicTextAdapter<
|
|
|
473
541
|
let stepId: string | null = null
|
|
474
542
|
let hasEmittedRunStarted = false
|
|
475
543
|
let hasEmittedTextMessageStart = false
|
|
544
|
+
let hasEmittedRunFinished = false
|
|
545
|
+
// Track current content block type for proper content_block_stop handling
|
|
546
|
+
let currentBlockType: string | null = null
|
|
476
547
|
|
|
477
548
|
try {
|
|
478
549
|
for await (const event of stream) {
|
|
@@ -488,6 +559,7 @@ export class AnthropicTextAdapter<
|
|
|
488
559
|
}
|
|
489
560
|
|
|
490
561
|
if (event.type === 'content_block_start') {
|
|
562
|
+
currentBlockType = event.content_block.type
|
|
491
563
|
if (event.content_block.type === 'tool_use') {
|
|
492
564
|
currentToolIndex++
|
|
493
565
|
toolCallsMap.set(currentToolIndex, {
|
|
@@ -572,59 +644,71 @@ export class AnthropicTextAdapter<
|
|
|
572
644
|
}
|
|
573
645
|
}
|
|
574
646
|
} else if (event.type === 'content_block_stop') {
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
existing.started
|
|
647
|
+
if (currentBlockType === 'tool_use') {
|
|
648
|
+
const existing = toolCallsMap.get(currentToolIndex)
|
|
649
|
+
if (existing) {
|
|
650
|
+
// If tool call wasn't started yet (no args), start it now
|
|
651
|
+
if (!existing.started) {
|
|
652
|
+
existing.started = true
|
|
653
|
+
yield {
|
|
654
|
+
type: 'TOOL_CALL_START',
|
|
655
|
+
toolCallId: existing.id,
|
|
656
|
+
toolName: existing.name,
|
|
657
|
+
model,
|
|
658
|
+
timestamp,
|
|
659
|
+
index: currentToolIndex,
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
// Emit TOOL_CALL_END
|
|
664
|
+
let parsedInput: unknown = {}
|
|
665
|
+
try {
|
|
666
|
+
const parsed = existing.input ? JSON.parse(existing.input) : {}
|
|
667
|
+
parsedInput = parsed && typeof parsed === 'object' ? parsed : {}
|
|
668
|
+
} catch {
|
|
669
|
+
parsedInput = {}
|
|
670
|
+
}
|
|
671
|
+
|
|
580
672
|
yield {
|
|
581
|
-
type: '
|
|
673
|
+
type: 'TOOL_CALL_END',
|
|
582
674
|
toolCallId: existing.id,
|
|
583
675
|
toolName: existing.name,
|
|
584
676
|
model,
|
|
585
677
|
timestamp,
|
|
586
|
-
|
|
678
|
+
input: parsedInput,
|
|
587
679
|
}
|
|
588
|
-
}
|
|
589
680
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
try {
|
|
593
|
-
const parsed = existing.input ? JSON.parse(existing.input) : {}
|
|
594
|
-
parsedInput = parsed && typeof parsed === 'object' ? parsed : {}
|
|
595
|
-
} catch {
|
|
596
|
-
parsedInput = {}
|
|
681
|
+
// Reset so a new TEXT_MESSAGE_START is emitted if text follows tool calls
|
|
682
|
+
hasEmittedTextMessageStart = false
|
|
597
683
|
}
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
684
|
+
} else {
|
|
685
|
+
// Emit TEXT_MESSAGE_END only for text blocks (not tool_use blocks)
|
|
686
|
+
if (hasEmittedTextMessageStart && accumulatedContent) {
|
|
687
|
+
yield {
|
|
688
|
+
type: 'TEXT_MESSAGE_END',
|
|
689
|
+
messageId,
|
|
690
|
+
model,
|
|
691
|
+
timestamp,
|
|
692
|
+
}
|
|
606
693
|
}
|
|
607
694
|
}
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
if
|
|
695
|
+
currentBlockType = null
|
|
696
|
+
} else if (event.type === 'message_stop') {
|
|
697
|
+
// Only emit RUN_FINISHED from message_stop if message_delta didn't already emit one.
|
|
698
|
+
// message_delta carries the real stop_reason (tool_use, end_turn, etc.),
|
|
699
|
+
// while message_stop is just a completion signal.
|
|
700
|
+
if (!hasEmittedRunFinished) {
|
|
611
701
|
yield {
|
|
612
|
-
type: '
|
|
613
|
-
|
|
702
|
+
type: 'RUN_FINISHED',
|
|
703
|
+
runId,
|
|
614
704
|
model,
|
|
615
705
|
timestamp,
|
|
706
|
+
finishReason: 'stop',
|
|
616
707
|
}
|
|
617
708
|
}
|
|
618
|
-
} else if (event.type === 'message_stop') {
|
|
619
|
-
yield {
|
|
620
|
-
type: 'RUN_FINISHED',
|
|
621
|
-
runId,
|
|
622
|
-
model,
|
|
623
|
-
timestamp,
|
|
624
|
-
finishReason: 'stop',
|
|
625
|
-
}
|
|
626
709
|
} else if (event.type === 'message_delta') {
|
|
627
710
|
if (event.delta.stop_reason) {
|
|
711
|
+
hasEmittedRunFinished = true
|
|
628
712
|
switch (event.delta.stop_reason) {
|
|
629
713
|
case 'tool_use': {
|
|
630
714
|
yield {
|
package/src/index.ts
CHANGED
|
@@ -19,7 +19,7 @@ export {
|
|
|
19
19
|
type AnthropicSummarizeConfig,
|
|
20
20
|
type AnthropicSummarizeProviderOptions,
|
|
21
21
|
} from './adapters/summarize'
|
|
22
|
-
|
|
22
|
+
export { ANTHROPIC_MODELS } from './model-meta'
|
|
23
23
|
// ============================================================================
|
|
24
24
|
// Type Exports
|
|
25
25
|
// ============================================================================
|
|
@@ -27,6 +27,7 @@ export {
|
|
|
27
27
|
export type {
|
|
28
28
|
AnthropicChatModelProviderOptionsByName,
|
|
29
29
|
AnthropicModelInputModalitiesByName,
|
|
30
|
+
AnthropicChatModel,
|
|
30
31
|
} from './model-meta'
|
|
31
32
|
export type {
|
|
32
33
|
AnthropicTextMetadata,
|
package/src/model-meta.ts
CHANGED
|
@@ -19,6 +19,7 @@ interface ModelMeta<
|
|
|
19
19
|
supports: {
|
|
20
20
|
input: Array<'text' | 'image' | 'audio' | 'video' | 'document'>
|
|
21
21
|
extended_thinking?: boolean
|
|
22
|
+
adaptive_thinking?: boolean
|
|
22
23
|
priority_tier?: boolean
|
|
23
24
|
}
|
|
24
25
|
context_window?: number
|
|
@@ -46,19 +47,50 @@ interface ModelMeta<
|
|
|
46
47
|
*/
|
|
47
48
|
messageCapabilities?: TMessageCapabilities
|
|
48
49
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
|
|
51
|
+
const CLAUDE_OPUS_4_6 = {
|
|
52
|
+
name: 'claude-opus-4-6',
|
|
53
|
+
id: 'claude-opus-4-6',
|
|
52
54
|
context_window: 200_000,
|
|
53
|
-
max_output_tokens:
|
|
54
|
-
knowledge_cutoff: '2025-
|
|
55
|
+
max_output_tokens: 128_000,
|
|
56
|
+
knowledge_cutoff: '2025-05-01',
|
|
55
57
|
pricing: {
|
|
56
58
|
input: {
|
|
57
|
-
normal:
|
|
59
|
+
normal: 5,
|
|
58
60
|
},
|
|
59
61
|
output: {
|
|
62
|
+
normal: 25,
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
supports: {
|
|
66
|
+
input: ['text', 'image', 'document'],
|
|
67
|
+
extended_thinking: true,
|
|
68
|
+
priority_tier: true,
|
|
69
|
+
},
|
|
70
|
+
} as const satisfies ModelMeta<
|
|
71
|
+
AnthropicContainerOptions &
|
|
72
|
+
AnthropicContextManagementOptions &
|
|
73
|
+
AnthropicMCPOptions &
|
|
74
|
+
AnthropicServiceTierOptions &
|
|
75
|
+
AnthropicStopSequencesOptions &
|
|
76
|
+
AnthropicThinkingOptions &
|
|
77
|
+
AnthropicToolChoiceOptions &
|
|
78
|
+
AnthropicSamplingOptions
|
|
79
|
+
>
|
|
80
|
+
|
|
81
|
+
const CLAUDE_OPUS_4_5 = {
|
|
82
|
+
name: 'claude-opus-4-5',
|
|
83
|
+
id: 'claude-opus-4-5',
|
|
84
|
+
context_window: 200_000,
|
|
85
|
+
max_output_tokens: 32_000,
|
|
86
|
+
knowledge_cutoff: '2025-11-01',
|
|
87
|
+
pricing: {
|
|
88
|
+
input: {
|
|
60
89
|
normal: 15,
|
|
61
90
|
},
|
|
91
|
+
output: {
|
|
92
|
+
normal: 75,
|
|
93
|
+
},
|
|
62
94
|
},
|
|
63
95
|
supports: {
|
|
64
96
|
input: ['text', 'image', 'document'],
|
|
@@ -76,18 +108,18 @@ const CLAUDE_SONNET_4_5 = {
|
|
|
76
108
|
AnthropicSamplingOptions
|
|
77
109
|
>
|
|
78
110
|
|
|
79
|
-
const
|
|
80
|
-
name: 'claude-
|
|
81
|
-
id: 'claude-
|
|
111
|
+
const CLAUDE_SONNET_4_5 = {
|
|
112
|
+
name: 'claude-sonnet-4-5',
|
|
113
|
+
id: 'claude-sonnet-4-5',
|
|
82
114
|
context_window: 200_000,
|
|
83
115
|
max_output_tokens: 64_000,
|
|
84
|
-
knowledge_cutoff: '2025-
|
|
116
|
+
knowledge_cutoff: '2025-09-29',
|
|
85
117
|
pricing: {
|
|
86
118
|
input: {
|
|
87
|
-
normal:
|
|
119
|
+
normal: 3,
|
|
88
120
|
},
|
|
89
121
|
output: {
|
|
90
|
-
normal:
|
|
122
|
+
normal: 15,
|
|
91
123
|
},
|
|
92
124
|
},
|
|
93
125
|
supports: {
|
|
@@ -106,18 +138,18 @@ const CLAUDE_HAIKU_4_5 = {
|
|
|
106
138
|
AnthropicSamplingOptions
|
|
107
139
|
>
|
|
108
140
|
|
|
109
|
-
const
|
|
110
|
-
name: 'claude-
|
|
111
|
-
id: 'claude-
|
|
141
|
+
const CLAUDE_HAIKU_4_5 = {
|
|
142
|
+
name: 'claude-haiku-4-5',
|
|
143
|
+
id: 'claude-haiku-4-5',
|
|
112
144
|
context_window: 200_000,
|
|
113
145
|
max_output_tokens: 64_000,
|
|
114
|
-
knowledge_cutoff: '2025-
|
|
146
|
+
knowledge_cutoff: '2025-10-01',
|
|
115
147
|
pricing: {
|
|
116
148
|
input: {
|
|
117
|
-
normal:
|
|
149
|
+
normal: 1,
|
|
118
150
|
},
|
|
119
151
|
output: {
|
|
120
|
-
normal:
|
|
152
|
+
normal: 5,
|
|
121
153
|
},
|
|
122
154
|
},
|
|
123
155
|
supports: {
|
|
@@ -136,12 +168,12 @@ const CLAUDE_OPUS_4_1 = {
|
|
|
136
168
|
AnthropicSamplingOptions
|
|
137
169
|
>
|
|
138
170
|
|
|
139
|
-
const
|
|
140
|
-
name: 'claude-opus-4-
|
|
141
|
-
id: 'claude-opus-4-
|
|
171
|
+
const CLAUDE_OPUS_4_1 = {
|
|
172
|
+
name: 'claude-opus-4-1',
|
|
173
|
+
id: 'claude-opus-4-1',
|
|
142
174
|
context_window: 200_000,
|
|
143
|
-
max_output_tokens:
|
|
144
|
-
knowledge_cutoff: '2025-
|
|
175
|
+
max_output_tokens: 64_000,
|
|
176
|
+
knowledge_cutoff: '2025-08-05',
|
|
145
177
|
pricing: {
|
|
146
178
|
input: {
|
|
147
179
|
normal: 15,
|
|
@@ -361,6 +393,7 @@ const CLAUDE_HAIKU_3 = {
|
|
|
361
393
|
: unknown */
|
|
362
394
|
|
|
363
395
|
export const ANTHROPIC_MODELS = [
|
|
396
|
+
CLAUDE_OPUS_4_6.id,
|
|
364
397
|
CLAUDE_OPUS_4_5.id,
|
|
365
398
|
CLAUDE_SONNET_4_5.id,
|
|
366
399
|
CLAUDE_HAIKU_4_5.id,
|
|
@@ -378,11 +411,19 @@ export const ANTHROPIC_MODELS = [
|
|
|
378
411
|
// const ANTHROPIC_VIDEO_MODELS = [] as const
|
|
379
412
|
|
|
380
413
|
/* type AnthropicModel = (typeof ANTHROPIC_MODELS)[number] */
|
|
381
|
-
|
|
414
|
+
export type AnthropicChatModel = (typeof ANTHROPIC_MODELS)[number]
|
|
382
415
|
// Manual type map for per-model provider options
|
|
383
416
|
// Models are differentiated by extended_thinking and priority_tier support
|
|
384
417
|
export type AnthropicChatModelProviderOptionsByName = {
|
|
385
418
|
// Models with both extended_thinking and priority_tier
|
|
419
|
+
[CLAUDE_OPUS_4_6.id]: AnthropicContainerOptions &
|
|
420
|
+
AnthropicContextManagementOptions &
|
|
421
|
+
AnthropicMCPOptions &
|
|
422
|
+
AnthropicServiceTierOptions &
|
|
423
|
+
AnthropicStopSequencesOptions &
|
|
424
|
+
AnthropicThinkingOptions &
|
|
425
|
+
AnthropicToolChoiceOptions &
|
|
426
|
+
AnthropicSamplingOptions
|
|
386
427
|
[CLAUDE_OPUS_4_5.id]: AnthropicContainerOptions &
|
|
387
428
|
AnthropicContextManagementOptions &
|
|
388
429
|
AnthropicMCPOptions &
|
|
@@ -470,6 +511,7 @@ export type AnthropicChatModelProviderOptionsByName = {
|
|
|
470
511
|
* @see https://docs.anthropic.com/claude/docs/pdf-support
|
|
471
512
|
*/
|
|
472
513
|
export type AnthropicModelInputModalitiesByName = {
|
|
514
|
+
[CLAUDE_OPUS_4_6.id]: typeof CLAUDE_OPUS_4_6.supports.input
|
|
473
515
|
[CLAUDE_OPUS_4_5.id]: typeof CLAUDE_OPUS_4_5.supports.input
|
|
474
516
|
[CLAUDE_SONNET_4_5.id]: typeof CLAUDE_SONNET_4_5.supports.input
|
|
475
517
|
[CLAUDE_HAIKU_4_5.id]: typeof CLAUDE_HAIKU_4_5.supports.input
|
|
@@ -92,6 +92,42 @@ Must be ≥1024 and less than max_tokens
|
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
export interface AnthropicAdaptiveThinkingOptions {
|
|
96
|
+
/**
|
|
97
|
+
* Configuration for Claude's adaptive thinking (Opus 4.6+).
|
|
98
|
+
*
|
|
99
|
+
* In adaptive mode, Claude dynamically decides when and how much to think.
|
|
100
|
+
* Use the effort parameter to control thinking depth.
|
|
101
|
+
* `thinking: {type: "enabled"}` with `budget_tokens` is deprecated on Opus 4.6.
|
|
102
|
+
*/
|
|
103
|
+
thinking?:
|
|
104
|
+
| {
|
|
105
|
+
type: 'adaptive'
|
|
106
|
+
}
|
|
107
|
+
| {
|
|
108
|
+
/**
|
|
109
|
+
* @deprecated Use `type: 'adaptive'` with the effort parameter on Opus 4.6+.
|
|
110
|
+
*/
|
|
111
|
+
budget_tokens: number
|
|
112
|
+
type: 'enabled'
|
|
113
|
+
}
|
|
114
|
+
| {
|
|
115
|
+
type: 'disabled'
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export interface AnthropicEffortOptions {
|
|
120
|
+
/**
|
|
121
|
+
* Controls the thinking depth for adaptive thinking mode (Opus 4.6+).
|
|
122
|
+
*
|
|
123
|
+
* - `max`: Absolute highest capability
|
|
124
|
+
* - `high`: Default - Claude will almost always think
|
|
125
|
+
* - `medium`: Balanced cost-quality
|
|
126
|
+
* - `low`: May skip thinking for simpler problems
|
|
127
|
+
*/
|
|
128
|
+
effort?: 'max' | 'high' | 'medium' | 'low'
|
|
129
|
+
}
|
|
130
|
+
|
|
95
131
|
export interface AnthropicToolChoiceOptions {
|
|
96
132
|
tool_choice?: BetaToolChoiceAny | BetaToolChoiceTool | BetaToolChoiceAuto
|
|
97
133
|
}
|
|
@@ -115,7 +151,9 @@ export type ExternalTextProviderOptions = AnthropicContainerOptions &
|
|
|
115
151
|
AnthropicStopSequencesOptions &
|
|
116
152
|
AnthropicThinkingOptions &
|
|
117
153
|
AnthropicToolChoiceOptions &
|
|
118
|
-
AnthropicSamplingOptions
|
|
154
|
+
AnthropicSamplingOptions &
|
|
155
|
+
Partial<AnthropicAdaptiveThinkingOptions> &
|
|
156
|
+
Partial<AnthropicEffortOptions>
|
|
119
157
|
|
|
120
158
|
export interface InternalTextProviderOptions extends ExternalTextProviderOptions {
|
|
121
159
|
model: string
|
package/src/utils/client.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Anthropic_SDK from '@anthropic-ai/sdk'
|
|
2
|
+
import type { ClientOptions } from '@anthropic-ai/sdk'
|
|
2
3
|
|
|
3
|
-
export interface AnthropicClientConfig {
|
|
4
|
+
export interface AnthropicClientConfig extends ClientOptions {
|
|
4
5
|
apiKey: string
|
|
5
6
|
}
|
|
6
7
|
|
|
@@ -11,6 +12,7 @@ export function createAnthropicClient(
|
|
|
11
12
|
config: AnthropicClientConfig,
|
|
12
13
|
): Anthropic_SDK {
|
|
13
14
|
return new Anthropic_SDK({
|
|
15
|
+
...config,
|
|
14
16
|
apiKey: config.apiKey,
|
|
15
17
|
})
|
|
16
18
|
}
|