@mariozechner/pi-ai 0.5.19 → 0.5.21

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.
@@ -15,7 +15,7 @@ export declare class AnthropicLLM implements LLM<AnthropicLLMOptions> {
15
15
  private isOAuthToken;
16
16
  constructor(model: Model, apiKey?: string);
17
17
  getModel(): Model;
18
- complete(context: Context, options?: AnthropicLLMOptions): Promise<AssistantMessage>;
18
+ generate(context: Context, options?: AnthropicLLMOptions): Promise<AssistantMessage>;
19
19
  private convertMessages;
20
20
  private convertTools;
21
21
  private mapStopReason;
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACX,gBAAgB,EAChB,OAAO,EACP,GAAG,EACH,UAAU,EAEV,KAAK,EAIL,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,mBAAoB,SAAQ,UAAU;IACtD,QAAQ,CAAC,EAAE;QACV,OAAO,EAAE,OAAO,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACtE;AAED,qBAAa,YAAa,YAAW,GAAG,CAAC,mBAAmB,CAAC;IAC5D,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,YAAY,CAAkB;gBAE1B,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,MAAM;IAyBzC,QAAQ,IAAI,KAAK;IAIX,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA0M1F,OAAO,CAAC,eAAe;IAkFvB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,aAAa;CAkBrB"}
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACX,gBAAgB,EAChB,OAAO,EACP,GAAG,EACH,UAAU,EAEV,KAAK,EAKL,MAAM,aAAa,CAAC;AAGrB,MAAM,WAAW,mBAAoB,SAAQ,UAAU;IACtD,QAAQ,CAAC,EAAE;QACV,OAAO,EAAE,OAAO,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACtE;AAED,qBAAa,YAAa,YAAW,GAAG,CAAC,mBAAmB,CAAC;IAC5D,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,YAAY,CAAkB;gBAE1B,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,MAAM;IA4BzC,QAAQ,IAAI,KAAK;IAIX,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAmL1F,OAAO,CAAC,eAAe;IAqFvB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,aAAa;CAkBrB"}
@@ -1,5 +1,6 @@
1
1
  import Anthropic from "@anthropic-ai/sdk";
2
2
  import { calculateCost } from "../models.js";
3
+ import { transformMessages } from "./utils.js";
3
4
  export class AnthropicLLM {
4
5
  client;
5
6
  modelInfo;
@@ -16,7 +17,10 @@ export class AnthropicLLM {
16
17
  accept: "application/json",
17
18
  "anthropic-beta": "oauth-2025-04-20,fine-grained-tool-streaming-2025-05-14",
18
19
  };
19
- process.env.ANTHROPIC_API_KEY = undefined;
20
+ // Clear the env var if we're in Node.js to prevent SDK from using it
21
+ if (typeof process !== "undefined" && process.env) {
22
+ process.env.ANTHROPIC_API_KEY = undefined;
23
+ }
20
24
  this.client = new Anthropic({ apiKey: null, authToken: apiKey, baseURL: model.baseUrl, defaultHeaders });
21
25
  this.isOAuthToken = true;
22
26
  }
@@ -29,7 +33,21 @@ export class AnthropicLLM {
29
33
  getModel() {
30
34
  return this.modelInfo;
31
35
  }
32
- async complete(context, options) {
36
+ async generate(context, options) {
37
+ const output = {
38
+ role: "assistant",
39
+ content: [],
40
+ provider: this.modelInfo.provider,
41
+ model: this.modelInfo.id,
42
+ usage: {
43
+ input: 0,
44
+ output: 0,
45
+ cacheRead: 0,
46
+ cacheWrite: 0,
47
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
48
+ },
49
+ stopReason: "stop",
50
+ };
33
51
  try {
34
52
  const messages = this.convertMessages(context.messages);
35
53
  const params = {
@@ -90,144 +108,113 @@ export class AnthropicLLM {
90
108
  signal: options?.signal,
91
109
  });
92
110
  options?.onEvent?.({ type: "start", model: this.modelInfo.id, provider: this.modelInfo.provider });
93
- let blockType = "other";
94
- let blockContent = "";
95
- let toolCall = null;
111
+ let currentBlock = null;
96
112
  for await (const event of stream) {
97
113
  if (event.type === "content_block_start") {
98
114
  if (event.content_block.type === "text") {
99
- blockType = "text";
100
- blockContent = "";
115
+ currentBlock = {
116
+ type: "text",
117
+ text: "",
118
+ };
119
+ output.content.push(currentBlock);
101
120
  options?.onEvent?.({ type: "text_start" });
102
121
  }
103
122
  else if (event.content_block.type === "thinking") {
104
- blockType = "thinking";
105
- blockContent = "";
123
+ currentBlock = {
124
+ type: "thinking",
125
+ thinking: "",
126
+ thinkingSignature: "",
127
+ };
128
+ output.content.push(currentBlock);
106
129
  options?.onEvent?.({ type: "thinking_start" });
107
130
  }
108
131
  else if (event.content_block.type === "tool_use") {
109
132
  // We wait for the full tool use to be streamed to send the event
110
- toolCall = {
133
+ currentBlock = {
111
134
  type: "toolCall",
112
135
  id: event.content_block.id,
113
136
  name: event.content_block.name,
114
137
  arguments: event.content_block.input,
115
138
  partialJson: "",
116
139
  };
117
- blockType = "toolUse";
118
- blockContent = "";
119
- }
120
- else {
121
- blockType = "other";
122
- blockContent = "";
123
140
  }
124
141
  }
125
- if (event.type === "content_block_delta") {
142
+ else if (event.type === "content_block_delta") {
126
143
  if (event.delta.type === "text_delta") {
127
- options?.onEvent?.({ type: "text_delta", content: blockContent, delta: event.delta.text });
128
- blockContent += event.delta.text;
129
- }
130
- if (event.delta.type === "thinking_delta") {
131
- options?.onEvent?.({ type: "thinking_delta", content: blockContent, delta: event.delta.thinking });
132
- blockContent += event.delta.thinking;
133
- }
134
- if (event.delta.type === "input_json_delta") {
135
- toolCall.partialJson += event.delta.partial_json;
144
+ if (currentBlock && currentBlock.type === "text") {
145
+ currentBlock.text += event.delta.text;
146
+ options?.onEvent?.({ type: "text_delta", content: currentBlock.text, delta: event.delta.text });
147
+ }
136
148
  }
137
- }
138
- if (event.type === "content_block_stop") {
139
- if (blockType === "text") {
140
- options?.onEvent?.({ type: "text_end", content: blockContent });
149
+ else if (event.delta.type === "thinking_delta") {
150
+ if (currentBlock && currentBlock.type === "thinking") {
151
+ currentBlock.thinking += event.delta.thinking;
152
+ options?.onEvent?.({
153
+ type: "thinking_delta",
154
+ content: currentBlock.thinking,
155
+ delta: event.delta.thinking,
156
+ });
157
+ }
141
158
  }
142
- else if (blockType === "thinking") {
143
- options?.onEvent?.({ type: "thinking_end", content: blockContent });
159
+ else if (event.delta.type === "input_json_delta") {
160
+ if (currentBlock && currentBlock.type === "toolCall") {
161
+ currentBlock.partialJson += event.delta.partial_json;
162
+ }
144
163
  }
145
- else if (blockType === "toolUse") {
146
- const finalToolCall = {
147
- type: "toolCall",
148
- id: toolCall.id,
149
- name: toolCall.name,
150
- arguments: toolCall.partialJson ? JSON.parse(toolCall.partialJson) : toolCall.arguments,
151
- };
152
- toolCall = null;
153
- options?.onEvent?.({ type: "toolCall", toolCall: finalToolCall });
164
+ else if (event.delta.type === "signature_delta") {
165
+ if (currentBlock && currentBlock.type === "thinking") {
166
+ currentBlock.thinkingSignature = currentBlock.thinkingSignature || "";
167
+ currentBlock.thinkingSignature += event.delta.signature;
168
+ }
154
169
  }
155
- blockType = "other";
156
170
  }
157
- }
158
- const msg = await stream.finalMessage();
159
- const blocks = [];
160
- for (const block of msg.content) {
161
- if (block.type === "text" && block.text) {
162
- blocks.push({
163
- type: "text",
164
- text: block.text,
165
- });
166
- }
167
- else if (block.type === "thinking" && block.thinking) {
168
- blocks.push({
169
- type: "thinking",
170
- thinking: block.thinking,
171
- thinkingSignature: block.signature,
172
- });
171
+ else if (event.type === "content_block_stop") {
172
+ if (currentBlock) {
173
+ if (currentBlock.type === "text") {
174
+ options?.onEvent?.({ type: "text_end", content: currentBlock.text });
175
+ }
176
+ else if (currentBlock.type === "thinking") {
177
+ options?.onEvent?.({ type: "thinking_end", content: currentBlock.thinking });
178
+ }
179
+ else if (currentBlock.type === "toolCall") {
180
+ const finalToolCall = {
181
+ type: "toolCall",
182
+ id: currentBlock.id,
183
+ name: currentBlock.name,
184
+ arguments: JSON.parse(currentBlock.partialJson),
185
+ };
186
+ output.content.push(finalToolCall);
187
+ options?.onEvent?.({ type: "toolCall", toolCall: finalToolCall });
188
+ }
189
+ currentBlock = null;
190
+ }
173
191
  }
174
- else if (block.type === "tool_use") {
175
- blocks.push({
176
- type: "toolCall",
177
- id: block.id,
178
- name: block.name,
179
- arguments: block.input,
180
- });
192
+ else if (event.type === "message_delta") {
193
+ if (event.delta.stop_reason) {
194
+ output.stopReason = this.mapStopReason(event.delta.stop_reason);
195
+ }
196
+ output.usage.input += event.usage.input_tokens || 0;
197
+ output.usage.output += event.usage.output_tokens || 0;
198
+ output.usage.cacheRead += event.usage.cache_read_input_tokens || 0;
199
+ output.usage.cacheWrite += event.usage.cache_creation_input_tokens || 0;
200
+ calculateCost(this.modelInfo, output.usage);
181
201
  }
182
202
  }
183
- const usage = {
184
- input: msg.usage.input_tokens,
185
- output: msg.usage.output_tokens,
186
- cacheRead: msg.usage.cache_read_input_tokens || 0,
187
- cacheWrite: msg.usage.cache_creation_input_tokens || 0,
188
- cost: {
189
- input: 0,
190
- output: 0,
191
- cacheRead: 0,
192
- cacheWrite: 0,
193
- total: 0,
194
- },
195
- };
196
- calculateCost(this.modelInfo, usage);
197
- const output = {
198
- role: "assistant",
199
- content: blocks,
200
- provider: this.modelInfo.provider,
201
- model: this.modelInfo.id,
202
- usage,
203
- stopReason: this.mapStopReason(msg.stop_reason),
204
- };
205
203
  options?.onEvent?.({ type: "done", reason: output.stopReason, message: output });
206
204
  return output;
207
205
  }
208
206
  catch (error) {
209
- const output = {
210
- role: "assistant",
211
- content: [],
212
- provider: this.modelInfo.provider,
213
- model: this.modelInfo.id,
214
- usage: {
215
- input: 0,
216
- output: 0,
217
- cacheRead: 0,
218
- cacheWrite: 0,
219
- cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
220
- },
221
- stopReason: "error",
222
- error: error instanceof Error ? error.message : JSON.stringify(error),
223
- };
207
+ output.stopReason = "error";
208
+ output.error = error instanceof Error ? error.message : JSON.stringify(error);
224
209
  options?.onEvent?.({ type: "error", error: output.error });
225
210
  return output;
226
211
  }
227
212
  }
228
213
  convertMessages(messages) {
229
214
  const params = [];
230
- for (const msg of messages) {
215
+ // Transform messages for cross-provider compatibility
216
+ const transformedMessages = transformMessages(messages, this.modelInfo);
217
+ for (const msg of transformedMessages) {
231
218
  if (msg.role === "user") {
232
219
  // Handle both string and array content
233
220
  if (typeof msg.content === "string") {
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"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","sourcesContent":["import Anthropic from \"@anthropic-ai/sdk\";\nimport type {\n\tContentBlockParam,\n\tMessageCreateParamsStreaming,\n\tMessageParam,\n\tTool,\n} from \"@anthropic-ai/sdk/resources/messages.js\";\nimport { calculateCost } from \"../models.js\";\nimport type {\n\tAssistantMessage,\n\tContext,\n\tLLM,\n\tLLMOptions,\n\tMessage,\n\tModel,\n\tStopReason,\n\tToolCall,\n\tUsage,\n} from \"../types.js\";\n\nexport interface AnthropicLLMOptions extends LLMOptions {\n\tthinking?: {\n\t\tenabled: boolean;\n\t\tbudgetTokens?: number;\n\t};\n\ttoolChoice?: \"auto\" | \"any\" | \"none\" | { type: \"tool\"; name: string };\n}\n\nexport class AnthropicLLM implements LLM<AnthropicLLMOptions> {\n\tprivate client: Anthropic;\n\tprivate modelInfo: Model;\n\tprivate isOAuthToken: boolean = false;\n\n\tconstructor(model: Model, apiKey?: string) {\n\t\tif (!apiKey) {\n\t\t\tif (!process.env.ANTHROPIC_API_KEY) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Anthropic API key is required. Set ANTHROPIC_API_KEY environment variable or pass it as an argument.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tapiKey = process.env.ANTHROPIC_API_KEY;\n\t\t}\n\t\tif (apiKey.includes(\"sk-ant-oat\")) {\n\t\t\tconst defaultHeaders = {\n\t\t\t\taccept: \"application/json\",\n\t\t\t\t\"anthropic-beta\": \"oauth-2025-04-20,fine-grained-tool-streaming-2025-05-14\",\n\t\t\t};\n\n\t\t\tprocess.env.ANTHROPIC_API_KEY = undefined;\n\t\t\tthis.client = new Anthropic({ apiKey: null, authToken: apiKey, baseURL: model.baseUrl, defaultHeaders });\n\t\t\tthis.isOAuthToken = true;\n\t\t} else {\n\t\t\tthis.client = new Anthropic({ apiKey, baseURL: model.baseUrl });\n\t\t\tthis.isOAuthToken = false;\n\t\t}\n\t\tthis.modelInfo = model;\n\t}\n\n\tgetModel(): Model {\n\t\treturn this.modelInfo;\n\t}\n\n\tasync complete(context: Context, options?: AnthropicLLMOptions): Promise<AssistantMessage> {\n\t\ttry {\n\t\t\tconst messages = this.convertMessages(context.messages);\n\n\t\t\tconst params: MessageCreateParamsStreaming = {\n\t\t\t\tmodel: this.modelInfo.id,\n\t\t\t\tmessages,\n\t\t\t\tmax_tokens: options?.maxTokens || 4096,\n\t\t\t\tstream: true,\n\t\t\t};\n\n\t\t\t// For OAuth tokens, we MUST include Claude Code identity\n\t\t\tif (this.isOAuthToken) {\n\t\t\t\tparams.system = [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: \"You are Claude Code, Anthropic's official CLI for Claude.\",\n\t\t\t\t\t\tcache_control: {\n\t\t\t\t\t\t\ttype: \"ephemeral\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t];\n\t\t\t\tif (context.systemPrompt) {\n\t\t\t\t\tparams.system.push({\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: context.systemPrompt,\n\t\t\t\t\t\tcache_control: {\n\t\t\t\t\t\t\ttype: \"ephemeral\",\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else if (context.systemPrompt) {\n\t\t\t\tparams.system = context.systemPrompt;\n\t\t\t}\n\n\t\t\tif (options?.temperature !== undefined) {\n\t\t\t\tparams.temperature = options?.temperature;\n\t\t\t}\n\n\t\t\tif (context.tools) {\n\t\t\t\tparams.tools = this.convertTools(context.tools);\n\t\t\t}\n\n\t\t\t// Only enable thinking if the model supports it\n\t\t\tif (options?.thinking?.enabled && this.modelInfo.reasoning) {\n\t\t\t\tparams.thinking = {\n\t\t\t\t\ttype: \"enabled\",\n\t\t\t\t\tbudget_tokens: options.thinking.budgetTokens || 1024,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (options?.toolChoice) {\n\t\t\t\tif (typeof options.toolChoice === \"string\") {\n\t\t\t\t\tparams.tool_choice = { type: options.toolChoice };\n\t\t\t\t} else {\n\t\t\t\t\tparams.tool_choice = options.toolChoice;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst stream = this.client.messages.stream(\n\t\t\t\t{\n\t\t\t\t\t...params,\n\t\t\t\t\tstream: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tsignal: options?.signal,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\toptions?.onEvent?.({ type: \"start\", model: this.modelInfo.id, provider: this.modelInfo.provider });\n\n\t\t\tlet blockType: \"text\" | \"thinking\" | \"toolUse\" | \"other\" = \"other\";\n\t\t\tlet blockContent = \"\";\n\t\t\tlet toolCall: (ToolCall & { partialJson: string }) | null = null;\n\t\t\tfor await (const event of stream) {\n\t\t\t\tif (event.type === \"content_block_start\") {\n\t\t\t\t\tif (event.content_block.type === \"text\") {\n\t\t\t\t\t\tblockType = \"text\";\n\t\t\t\t\t\tblockContent = \"\";\n\t\t\t\t\t\toptions?.onEvent?.({ type: \"text_start\" });\n\t\t\t\t\t} else if (event.content_block.type === \"thinking\") {\n\t\t\t\t\t\tblockType = \"thinking\";\n\t\t\t\t\t\tblockContent = \"\";\n\t\t\t\t\t\toptions?.onEvent?.({ type: \"thinking_start\" });\n\t\t\t\t\t} else if (event.content_block.type === \"tool_use\") {\n\t\t\t\t\t\t// We wait for the full tool use to be streamed to send the event\n\t\t\t\t\t\ttoolCall = {\n\t\t\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\t\t\tid: event.content_block.id,\n\t\t\t\t\t\t\tname: event.content_block.name,\n\t\t\t\t\t\t\targuments: event.content_block.input as Record<string, any>,\n\t\t\t\t\t\t\tpartialJson: \"\",\n\t\t\t\t\t\t};\n\t\t\t\t\t\tblockType = \"toolUse\";\n\t\t\t\t\t\tblockContent = \"\";\n\t\t\t\t\t} else {\n\t\t\t\t\t\tblockType = \"other\";\n\t\t\t\t\t\tblockContent = \"\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (event.type === \"content_block_delta\") {\n\t\t\t\t\tif (event.delta.type === \"text_delta\") {\n\t\t\t\t\t\toptions?.onEvent?.({ type: \"text_delta\", content: blockContent, delta: event.delta.text });\n\t\t\t\t\t\tblockContent += event.delta.text;\n\t\t\t\t\t}\n\t\t\t\t\tif (event.delta.type === \"thinking_delta\") {\n\t\t\t\t\t\toptions?.onEvent?.({ type: \"thinking_delta\", content: blockContent, delta: event.delta.thinking });\n\t\t\t\t\t\tblockContent += event.delta.thinking;\n\t\t\t\t\t}\n\t\t\t\t\tif (event.delta.type === \"input_json_delta\") {\n\t\t\t\t\t\ttoolCall!.partialJson += event.delta.partial_json;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (event.type === \"content_block_stop\") {\n\t\t\t\t\tif (blockType === \"text\") {\n\t\t\t\t\t\toptions?.onEvent?.({ type: \"text_end\", content: blockContent });\n\t\t\t\t\t} else if (blockType === \"thinking\") {\n\t\t\t\t\t\toptions?.onEvent?.({ type: \"thinking_end\", content: blockContent });\n\t\t\t\t\t} else if (blockType === \"toolUse\") {\n\t\t\t\t\t\tconst finalToolCall: ToolCall = {\n\t\t\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\t\t\tid: toolCall!.id,\n\t\t\t\t\t\t\tname: toolCall!.name,\n\t\t\t\t\t\t\targuments: toolCall!.partialJson ? JSON.parse(toolCall!.partialJson) : toolCall!.arguments,\n\t\t\t\t\t\t};\n\t\t\t\t\t\ttoolCall = null;\n\t\t\t\t\t\toptions?.onEvent?.({ type: \"toolCall\", toolCall: finalToolCall });\n\t\t\t\t\t}\n\t\t\t\t\tblockType = \"other\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst msg = await stream.finalMessage();\n\t\t\tconst blocks: AssistantMessage[\"content\"] = [];\n\t\t\tfor (const block of msg.content) {\n\t\t\t\tif (block.type === \"text\" && block.text) {\n\t\t\t\t\tblocks.push({\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: block.text,\n\t\t\t\t\t});\n\t\t\t\t} else if (block.type === \"thinking\" && block.thinking) {\n\t\t\t\t\tblocks.push({\n\t\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\t\tthinking: block.thinking,\n\t\t\t\t\t\tthinkingSignature: block.signature,\n\t\t\t\t\t});\n\t\t\t\t} else if (block.type === \"tool_use\") {\n\t\t\t\t\tblocks.push({\n\t\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\t\tid: block.id,\n\t\t\t\t\t\tname: block.name,\n\t\t\t\t\t\targuments: block.input as Record<string, any>,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst usage: Usage = {\n\t\t\t\tinput: msg.usage.input_tokens,\n\t\t\t\toutput: msg.usage.output_tokens,\n\t\t\t\tcacheRead: msg.usage.cache_read_input_tokens || 0,\n\t\t\t\tcacheWrite: msg.usage.cache_creation_input_tokens || 0,\n\t\t\t\tcost: {\n\t\t\t\t\tinput: 0,\n\t\t\t\t\toutput: 0,\n\t\t\t\t\tcacheRead: 0,\n\t\t\t\t\tcacheWrite: 0,\n\t\t\t\t\ttotal: 0,\n\t\t\t\t},\n\t\t\t};\n\t\t\tcalculateCost(this.modelInfo, usage);\n\n\t\t\tconst output = {\n\t\t\t\trole: \"assistant\",\n\t\t\t\tcontent: blocks,\n\t\t\t\tprovider: this.modelInfo.provider,\n\t\t\t\tmodel: this.modelInfo.id,\n\t\t\t\tusage,\n\t\t\t\tstopReason: this.mapStopReason(msg.stop_reason),\n\t\t\t} satisfies AssistantMessage;\n\t\t\toptions?.onEvent?.({ type: \"done\", reason: output.stopReason, message: output });\n\n\t\t\treturn output;\n\t\t} catch (error) {\n\t\t\tconst output = {\n\t\t\t\trole: \"assistant\",\n\t\t\t\tcontent: [],\n\t\t\t\tprovider: this.modelInfo.provider,\n\t\t\t\tmodel: this.modelInfo.id,\n\t\t\t\tusage: {\n\t\t\t\t\tinput: 0,\n\t\t\t\t\toutput: 0,\n\t\t\t\t\tcacheRead: 0,\n\t\t\t\t\tcacheWrite: 0,\n\t\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t\t},\n\t\t\t\tstopReason: \"error\",\n\t\t\t\terror: error instanceof Error ? error.message : JSON.stringify(error),\n\t\t\t} satisfies AssistantMessage;\n\t\t\toptions?.onEvent?.({ type: \"error\", error: output.error });\n\t\t\treturn output;\n\t\t}\n\t}\n\n\tprivate convertMessages(messages: Message[]): MessageParam[] {\n\t\tconst params: MessageParam[] = [];\n\n\t\tfor (const msg of messages) {\n\t\t\tif (msg.role === \"user\") {\n\t\t\t\t// Handle both string and array content\n\t\t\t\tif (typeof msg.content === \"string\") {\n\t\t\t\t\tparams.push({\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: msg.content,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t// Convert array content to Anthropic format\n\t\t\t\t\tconst blocks: ContentBlockParam[] = msg.content.map((item) => {\n\t\t\t\t\t\tif (item.type === \"text\") {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\ttext: item.text,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Image content\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\ttype: \"image\",\n\t\t\t\t\t\t\t\tsource: {\n\t\t\t\t\t\t\t\t\ttype: \"base64\",\n\t\t\t\t\t\t\t\t\tmedia_type: item.mimeType as \"image/jpeg\" | \"image/png\" | \"image/gif\" | \"image/webp\",\n\t\t\t\t\t\t\t\t\tdata: item.data,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tparams.push({\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: blocks,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else if (msg.role === \"assistant\") {\n\t\t\t\tconst blocks: ContentBlockParam[] = [];\n\n\t\t\t\tfor (const block of msg.content) {\n\t\t\t\t\tif (block.type === \"text\") {\n\t\t\t\t\t\tblocks.push({\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: block.text,\n\t\t\t\t\t\t});\n\t\t\t\t\t} else if (block.type === \"thinking\") {\n\t\t\t\t\t\tblocks.push({\n\t\t\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\t\t\tthinking: block.thinking,\n\t\t\t\t\t\t\tsignature: block.thinkingSignature || \"\",\n\t\t\t\t\t\t});\n\t\t\t\t\t} else if (block.type === \"toolCall\") {\n\t\t\t\t\t\tblocks.push({\n\t\t\t\t\t\t\ttype: \"tool_use\",\n\t\t\t\t\t\t\tid: block.id,\n\t\t\t\t\t\t\tname: block.name,\n\t\t\t\t\t\t\tinput: block.arguments,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tparams.push({\n\t\t\t\t\trole: \"assistant\",\n\t\t\t\t\tcontent: blocks,\n\t\t\t\t});\n\t\t\t} else if (msg.role === \"toolResult\") {\n\t\t\t\tparams.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"tool_result\",\n\t\t\t\t\t\t\ttool_use_id: msg.toolCallId,\n\t\t\t\t\t\t\tcontent: msg.content,\n\t\t\t\t\t\t\tis_error: msg.isError,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn params;\n\t}\n\n\tprivate convertTools(tools: Context[\"tools\"]): Tool[] {\n\t\tif (!tools) return [];\n\n\t\treturn tools.map((tool) => ({\n\t\t\tname: tool.name,\n\t\t\tdescription: tool.description,\n\t\t\tinput_schema: {\n\t\t\t\ttype: \"object\" as const,\n\t\t\t\tproperties: tool.parameters.properties || {},\n\t\t\t\trequired: tool.parameters.required || [],\n\t\t\t},\n\t\t}));\n\t}\n\n\tprivate mapStopReason(reason: Anthropic.Messages.StopReason | null): StopReason {\n\t\tswitch (reason) {\n\t\t\tcase \"end_turn\":\n\t\t\t\treturn \"stop\";\n\t\t\tcase \"max_tokens\":\n\t\t\t\treturn \"length\";\n\t\t\tcase \"tool_use\":\n\t\t\t\treturn \"toolUse\";\n\t\t\tcase \"refusal\":\n\t\t\t\treturn \"safety\";\n\t\t\tcase \"pause_turn\": // Stop is good enough -> resubmit\n\t\t\t\treturn \"stop\";\n\t\t\tcase \"stop_sequence\":\n\t\t\t\treturn \"stop\"; // We don't supply stop sequences, so this should never happen\n\t\t\tdefault:\n\t\t\t\treturn \"stop\";\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"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","sourcesContent":["import Anthropic from \"@anthropic-ai/sdk\";\nimport type {\n\tContentBlockParam,\n\tMessageCreateParamsStreaming,\n\tMessageParam,\n\tTool,\n} from \"@anthropic-ai/sdk/resources/messages.js\";\nimport { calculateCost } from \"../models.js\";\nimport type {\n\tAssistantMessage,\n\tContext,\n\tLLM,\n\tLLMOptions,\n\tMessage,\n\tModel,\n\tStopReason,\n\tTextContent,\n\tThinkingContent,\n\tToolCall,\n} from \"../types.js\";\nimport { transformMessages } from \"./utils.js\";\n\nexport interface AnthropicLLMOptions extends LLMOptions {\n\tthinking?: {\n\t\tenabled: boolean;\n\t\tbudgetTokens?: number;\n\t};\n\ttoolChoice?: \"auto\" | \"any\" | \"none\" | { type: \"tool\"; name: string };\n}\n\nexport class AnthropicLLM implements LLM<AnthropicLLMOptions> {\n\tprivate client: Anthropic;\n\tprivate modelInfo: Model;\n\tprivate isOAuthToken: boolean = false;\n\n\tconstructor(model: Model, apiKey?: string) {\n\t\tif (!apiKey) {\n\t\t\tif (!process.env.ANTHROPIC_API_KEY) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Anthropic API key is required. Set ANTHROPIC_API_KEY environment variable or pass it as an argument.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tapiKey = process.env.ANTHROPIC_API_KEY;\n\t\t}\n\t\tif (apiKey.includes(\"sk-ant-oat\")) {\n\t\t\tconst defaultHeaders = {\n\t\t\t\taccept: \"application/json\",\n\t\t\t\t\"anthropic-beta\": \"oauth-2025-04-20,fine-grained-tool-streaming-2025-05-14\",\n\t\t\t};\n\n\t\t\t// Clear the env var if we're in Node.js to prevent SDK from using it\n\t\t\tif (typeof process !== \"undefined\" && process.env) {\n\t\t\t\tprocess.env.ANTHROPIC_API_KEY = undefined;\n\t\t\t}\n\t\t\tthis.client = new Anthropic({ apiKey: null, authToken: apiKey, baseURL: model.baseUrl, defaultHeaders });\n\t\t\tthis.isOAuthToken = true;\n\t\t} else {\n\t\t\tthis.client = new Anthropic({ apiKey, baseURL: model.baseUrl });\n\t\t\tthis.isOAuthToken = false;\n\t\t}\n\t\tthis.modelInfo = model;\n\t}\n\n\tgetModel(): Model {\n\t\treturn this.modelInfo;\n\t}\n\n\tasync generate(context: Context, options?: AnthropicLLMOptions): Promise<AssistantMessage> {\n\t\tconst output: AssistantMessage = {\n\t\t\trole: \"assistant\",\n\t\t\tcontent: [],\n\t\t\tprovider: this.modelInfo.provider,\n\t\t\tmodel: this.modelInfo.id,\n\t\t\tusage: {\n\t\t\t\tinput: 0,\n\t\t\t\toutput: 0,\n\t\t\t\tcacheRead: 0,\n\t\t\t\tcacheWrite: 0,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t},\n\t\t\tstopReason: \"stop\",\n\t\t};\n\n\t\ttry {\n\t\t\tconst messages = this.convertMessages(context.messages);\n\n\t\t\tconst params: MessageCreateParamsStreaming = {\n\t\t\t\tmodel: this.modelInfo.id,\n\t\t\t\tmessages,\n\t\t\t\tmax_tokens: options?.maxTokens || 4096,\n\t\t\t\tstream: true,\n\t\t\t};\n\n\t\t\t// For OAuth tokens, we MUST include Claude Code identity\n\t\t\tif (this.isOAuthToken) {\n\t\t\t\tparams.system = [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: \"You are Claude Code, Anthropic's official CLI for Claude.\",\n\t\t\t\t\t\tcache_control: {\n\t\t\t\t\t\t\ttype: \"ephemeral\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t];\n\t\t\t\tif (context.systemPrompt) {\n\t\t\t\t\tparams.system.push({\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: context.systemPrompt,\n\t\t\t\t\t\tcache_control: {\n\t\t\t\t\t\t\ttype: \"ephemeral\",\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else if (context.systemPrompt) {\n\t\t\t\tparams.system = context.systemPrompt;\n\t\t\t}\n\n\t\t\tif (options?.temperature !== undefined) {\n\t\t\t\tparams.temperature = options?.temperature;\n\t\t\t}\n\n\t\t\tif (context.tools) {\n\t\t\t\tparams.tools = this.convertTools(context.tools);\n\t\t\t}\n\n\t\t\t// Only enable thinking if the model supports it\n\t\t\tif (options?.thinking?.enabled && this.modelInfo.reasoning) {\n\t\t\t\tparams.thinking = {\n\t\t\t\t\ttype: \"enabled\",\n\t\t\t\t\tbudget_tokens: options.thinking.budgetTokens || 1024,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (options?.toolChoice) {\n\t\t\t\tif (typeof options.toolChoice === \"string\") {\n\t\t\t\t\tparams.tool_choice = { type: options.toolChoice };\n\t\t\t\t} else {\n\t\t\t\t\tparams.tool_choice = options.toolChoice;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst stream = this.client.messages.stream(\n\t\t\t\t{\n\t\t\t\t\t...params,\n\t\t\t\t\tstream: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tsignal: options?.signal,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\toptions?.onEvent?.({ type: \"start\", model: this.modelInfo.id, provider: this.modelInfo.provider });\n\n\t\t\tlet currentBlock: ThinkingContent | TextContent | (ToolCall & { partialJson: string }) | null = null;\n\t\t\tfor await (const event of stream) {\n\t\t\t\tif (event.type === \"content_block_start\") {\n\t\t\t\t\tif (event.content_block.type === \"text\") {\n\t\t\t\t\t\tcurrentBlock = {\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: \"\",\n\t\t\t\t\t\t};\n\t\t\t\t\t\toutput.content.push(currentBlock);\n\t\t\t\t\t\toptions?.onEvent?.({ type: \"text_start\" });\n\t\t\t\t\t} else if (event.content_block.type === \"thinking\") {\n\t\t\t\t\t\tcurrentBlock = {\n\t\t\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\t\t\tthinking: \"\",\n\t\t\t\t\t\t\tthinkingSignature: \"\",\n\t\t\t\t\t\t};\n\t\t\t\t\t\toutput.content.push(currentBlock);\n\t\t\t\t\t\toptions?.onEvent?.({ type: \"thinking_start\" });\n\t\t\t\t\t} else if (event.content_block.type === \"tool_use\") {\n\t\t\t\t\t\t// We wait for the full tool use to be streamed to send the event\n\t\t\t\t\t\tcurrentBlock = {\n\t\t\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\t\t\tid: event.content_block.id,\n\t\t\t\t\t\t\tname: event.content_block.name,\n\t\t\t\t\t\t\targuments: event.content_block.input as Record<string, any>,\n\t\t\t\t\t\t\tpartialJson: \"\",\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t} else if (event.type === \"content_block_delta\") {\n\t\t\t\t\tif (event.delta.type === \"text_delta\") {\n\t\t\t\t\t\tif (currentBlock && currentBlock.type === \"text\") {\n\t\t\t\t\t\t\tcurrentBlock.text += event.delta.text;\n\t\t\t\t\t\t\toptions?.onEvent?.({ type: \"text_delta\", content: currentBlock.text, delta: event.delta.text });\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (event.delta.type === \"thinking_delta\") {\n\t\t\t\t\t\tif (currentBlock && currentBlock.type === \"thinking\") {\n\t\t\t\t\t\t\tcurrentBlock.thinking += event.delta.thinking;\n\t\t\t\t\t\t\toptions?.onEvent?.({\n\t\t\t\t\t\t\t\ttype: \"thinking_delta\",\n\t\t\t\t\t\t\t\tcontent: currentBlock.thinking,\n\t\t\t\t\t\t\t\tdelta: event.delta.thinking,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (event.delta.type === \"input_json_delta\") {\n\t\t\t\t\t\tif (currentBlock && currentBlock.type === \"toolCall\") {\n\t\t\t\t\t\t\tcurrentBlock.partialJson += event.delta.partial_json;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (event.delta.type === \"signature_delta\") {\n\t\t\t\t\t\tif (currentBlock && currentBlock.type === \"thinking\") {\n\t\t\t\t\t\t\tcurrentBlock.thinkingSignature = currentBlock.thinkingSignature || \"\";\n\t\t\t\t\t\t\tcurrentBlock.thinkingSignature += event.delta.signature;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (event.type === \"content_block_stop\") {\n\t\t\t\t\tif (currentBlock) {\n\t\t\t\t\t\tif (currentBlock.type === \"text\") {\n\t\t\t\t\t\t\toptions?.onEvent?.({ type: \"text_end\", content: currentBlock.text });\n\t\t\t\t\t\t} else if (currentBlock.type === \"thinking\") {\n\t\t\t\t\t\t\toptions?.onEvent?.({ type: \"thinking_end\", content: currentBlock.thinking });\n\t\t\t\t\t\t} else if (currentBlock.type === \"toolCall\") {\n\t\t\t\t\t\t\tconst finalToolCall: ToolCall = {\n\t\t\t\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\t\t\t\tid: currentBlock.id,\n\t\t\t\t\t\t\t\tname: currentBlock.name,\n\t\t\t\t\t\t\t\targuments: JSON.parse(currentBlock.partialJson),\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\toutput.content.push(finalToolCall);\n\t\t\t\t\t\t\toptions?.onEvent?.({ type: \"toolCall\", toolCall: finalToolCall });\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcurrentBlock = null;\n\t\t\t\t\t}\n\t\t\t\t} else if (event.type === \"message_delta\") {\n\t\t\t\t\tif (event.delta.stop_reason) {\n\t\t\t\t\t\toutput.stopReason = this.mapStopReason(event.delta.stop_reason);\n\t\t\t\t\t}\n\t\t\t\t\toutput.usage.input += event.usage.input_tokens || 0;\n\t\t\t\t\toutput.usage.output += event.usage.output_tokens || 0;\n\t\t\t\t\toutput.usage.cacheRead += event.usage.cache_read_input_tokens || 0;\n\t\t\t\t\toutput.usage.cacheWrite += event.usage.cache_creation_input_tokens || 0;\n\t\t\t\t\tcalculateCost(this.modelInfo, output.usage);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\toptions?.onEvent?.({ type: \"done\", reason: output.stopReason, message: output });\n\t\t\treturn output;\n\t\t} catch (error) {\n\t\t\toutput.stopReason = \"error\";\n\t\t\toutput.error = error instanceof Error ? error.message : JSON.stringify(error);\n\t\t\toptions?.onEvent?.({ type: \"error\", error: output.error });\n\t\t\treturn output;\n\t\t}\n\t}\n\n\tprivate convertMessages(messages: Message[]): MessageParam[] {\n\t\tconst params: MessageParam[] = [];\n\n\t\t// Transform messages for cross-provider compatibility\n\t\tconst transformedMessages = transformMessages(messages, this.modelInfo);\n\n\t\tfor (const msg of transformedMessages) {\n\t\t\tif (msg.role === \"user\") {\n\t\t\t\t// Handle both string and array content\n\t\t\t\tif (typeof msg.content === \"string\") {\n\t\t\t\t\tparams.push({\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: msg.content,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t// Convert array content to Anthropic format\n\t\t\t\t\tconst blocks: ContentBlockParam[] = msg.content.map((item) => {\n\t\t\t\t\t\tif (item.type === \"text\") {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\ttext: item.text,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Image content\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\ttype: \"image\",\n\t\t\t\t\t\t\t\tsource: {\n\t\t\t\t\t\t\t\t\ttype: \"base64\",\n\t\t\t\t\t\t\t\t\tmedia_type: item.mimeType as \"image/jpeg\" | \"image/png\" | \"image/gif\" | \"image/webp\",\n\t\t\t\t\t\t\t\t\tdata: item.data,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tparams.push({\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: blocks,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else if (msg.role === \"assistant\") {\n\t\t\t\tconst blocks: ContentBlockParam[] = [];\n\n\t\t\t\tfor (const block of msg.content) {\n\t\t\t\t\tif (block.type === \"text\") {\n\t\t\t\t\t\tblocks.push({\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: block.text,\n\t\t\t\t\t\t});\n\t\t\t\t\t} else if (block.type === \"thinking\") {\n\t\t\t\t\t\tblocks.push({\n\t\t\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\t\t\tthinking: block.thinking,\n\t\t\t\t\t\t\tsignature: block.thinkingSignature || \"\",\n\t\t\t\t\t\t});\n\t\t\t\t\t} else if (block.type === \"toolCall\") {\n\t\t\t\t\t\tblocks.push({\n\t\t\t\t\t\t\ttype: \"tool_use\",\n\t\t\t\t\t\t\tid: block.id,\n\t\t\t\t\t\t\tname: block.name,\n\t\t\t\t\t\t\tinput: block.arguments,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tparams.push({\n\t\t\t\t\trole: \"assistant\",\n\t\t\t\t\tcontent: blocks,\n\t\t\t\t});\n\t\t\t} else if (msg.role === \"toolResult\") {\n\t\t\t\tparams.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"tool_result\",\n\t\t\t\t\t\t\ttool_use_id: msg.toolCallId,\n\t\t\t\t\t\t\tcontent: msg.content,\n\t\t\t\t\t\t\tis_error: msg.isError,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn params;\n\t}\n\n\tprivate convertTools(tools: Context[\"tools\"]): Tool[] {\n\t\tif (!tools) return [];\n\n\t\treturn tools.map((tool) => ({\n\t\t\tname: tool.name,\n\t\t\tdescription: tool.description,\n\t\t\tinput_schema: {\n\t\t\t\ttype: \"object\" as const,\n\t\t\t\tproperties: tool.parameters.properties || {},\n\t\t\t\trequired: tool.parameters.required || [],\n\t\t\t},\n\t\t}));\n\t}\n\n\tprivate mapStopReason(reason: Anthropic.Messages.StopReason | null): StopReason {\n\t\tswitch (reason) {\n\t\t\tcase \"end_turn\":\n\t\t\t\treturn \"stop\";\n\t\t\tcase \"max_tokens\":\n\t\t\t\treturn \"length\";\n\t\t\tcase \"tool_use\":\n\t\t\t\treturn \"toolUse\";\n\t\t\tcase \"refusal\":\n\t\t\t\treturn \"safety\";\n\t\t\tcase \"pause_turn\": // Stop is good enough -> resubmit\n\t\t\t\treturn \"stop\";\n\t\t\tcase \"stop_sequence\":\n\t\t\t\treturn \"stop\"; // We don't supply stop sequences, so this should never happen\n\t\t\tdefault:\n\t\t\t\treturn \"stop\";\n\t\t}\n\t}\n}\n"]}
@@ -8,10 +8,10 @@ export interface GoogleLLMOptions extends LLMOptions {
8
8
  }
9
9
  export declare class GoogleLLM implements LLM<GoogleLLMOptions> {
10
10
  private client;
11
- private model;
11
+ private modelInfo;
12
12
  constructor(model: Model, apiKey?: string);
13
13
  getModel(): Model;
14
- complete(context: Context, options?: GoogleLLMOptions): Promise<AssistantMessage>;
14
+ generate(context: Context, options?: GoogleLLMOptions): Promise<AssistantMessage>;
15
15
  private convertMessages;
16
16
  private convertTools;
17
17
  private mapToolChoice;
@@ -1 +1 @@
1
- {"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../../src/providers/google.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACX,gBAAgB,EAChB,OAAO,EACP,GAAG,EACH,UAAU,EAEV,KAAK,EAOL,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,gBAAiB,SAAQ,UAAU;IACnD,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;IACrC,QAAQ,CAAC,EAAE;QACV,OAAO,EAAE,OAAO,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACF;AAED,qBAAa,SAAU,YAAW,GAAG,CAAC,gBAAgB,CAAC;IACtD,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,KAAK,CAAQ;gBAET,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,MAAM;IAazC,QAAQ,IAAI,KAAK;IAIX,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAuNvF,OAAO,CAAC,eAAe;IAoFvB,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,aAAa;CAwBrB"}
1
+ {"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../../src/providers/google.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACX,gBAAgB,EAChB,OAAO,EACP,GAAG,EACH,UAAU,EAEV,KAAK,EAML,MAAM,aAAa,CAAC;AAGrB,MAAM,WAAW,gBAAiB,SAAQ,UAAU;IACnD,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;IACrC,QAAQ,CAAC,EAAE;QACV,OAAO,EAAE,OAAO,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACF;AAED,qBAAa,SAAU,YAAW,GAAG,CAAC,gBAAgB,CAAC;IACtD,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,SAAS,CAAQ;gBAEb,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,MAAM;IAazC,QAAQ,IAAI,KAAK;IAIX,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA+LvF,OAAO,CAAC,eAAe;IAuFvB,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,aAAa;CAwBrB"}
@@ -1,8 +1,9 @@
1
1
  import { FunctionCallingConfigMode, GoogleGenAI, } from "@google/genai";
2
2
  import { calculateCost } from "../models.js";
3
+ import { transformMessages } from "./utils.js";
3
4
  export class GoogleLLM {
4
5
  client;
5
- model;
6
+ modelInfo;
6
7
  constructor(model, apiKey) {
7
8
  if (!apiKey) {
8
9
  if (!process.env.GEMINI_API_KEY) {
@@ -11,12 +12,26 @@ export class GoogleLLM {
11
12
  apiKey = process.env.GEMINI_API_KEY;
12
13
  }
13
14
  this.client = new GoogleGenAI({ apiKey });
14
- this.model = model;
15
+ this.modelInfo = model;
15
16
  }
16
17
  getModel() {
17
- return this.model;
18
+ return this.modelInfo;
18
19
  }
19
- async complete(context, options) {
20
+ async generate(context, options) {
21
+ const output = {
22
+ role: "assistant",
23
+ content: [],
24
+ provider: this.modelInfo.provider,
25
+ model: this.modelInfo.id,
26
+ usage: {
27
+ input: 0,
28
+ output: 0,
29
+ cacheRead: 0,
30
+ cacheWrite: 0,
31
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
32
+ },
33
+ stopReason: "stop",
34
+ };
20
35
  try {
21
36
  const contents = this.convertMessages(context.messages);
22
37
  // Build generation config
@@ -42,7 +57,7 @@ export class GoogleLLM {
42
57
  };
43
58
  }
44
59
  // Add thinking config if enabled and model supports it
45
- if (options?.thinking?.enabled && this.model.reasoning) {
60
+ if (options?.thinking?.enabled && this.modelInfo.reasoning) {
46
61
  config.thinkingConfig = {
47
62
  includeThoughts: true,
48
63
  ...(options.thinking.budgetTokens !== undefined && { thinkingBudget: options.thinking.budgetTokens }),
@@ -57,23 +72,13 @@ export class GoogleLLM {
57
72
  }
58
73
  // Build the request parameters
59
74
  const params = {
60
- model: this.model.id,
75
+ model: this.modelInfo.id,
61
76
  contents,
62
77
  config,
63
78
  };
64
79
  const stream = await this.client.models.generateContentStream(params);
65
- options?.onEvent?.({ type: "start", model: this.model.id, provider: this.model.provider });
66
- const blocks = [];
80
+ options?.onEvent?.({ type: "start", model: this.modelInfo.id, provider: this.modelInfo.provider });
67
81
  let currentBlock = null;
68
- let usage = {
69
- input: 0,
70
- output: 0,
71
- cacheRead: 0,
72
- cacheWrite: 0,
73
- cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
74
- };
75
- let stopReason = "stop";
76
- // Process the stream
77
82
  for await (const chunk of stream) {
78
83
  // Extract parts from the chunk
79
84
  const candidate = chunk.candidates?.[0];
@@ -85,7 +90,6 @@ export class GoogleLLM {
85
90
  if (!currentBlock ||
86
91
  (isThinking && currentBlock.type !== "thinking") ||
87
92
  (!isThinking && currentBlock.type !== "text")) {
88
- // Save and finalize current block
89
93
  if (currentBlock) {
90
94
  if (currentBlock.type === "text") {
91
95
  options?.onEvent?.({ type: "text_end", content: currentBlock.text });
@@ -93,7 +97,6 @@ export class GoogleLLM {
93
97
  else {
94
98
  options?.onEvent?.({ type: "thinking_end", content: currentBlock.thinking });
95
99
  }
96
- blocks.push(currentBlock);
97
100
  }
98
101
  // Start new block
99
102
  if (isThinking) {
@@ -104,6 +107,7 @@ export class GoogleLLM {
104
107
  currentBlock = { type: "text", text: "" };
105
108
  options?.onEvent?.({ type: "text_start" });
106
109
  }
110
+ output.content.push(currentBlock);
107
111
  }
108
112
  // Append content to current block
109
113
  if (currentBlock.type === "thinking") {
@@ -122,7 +126,6 @@ export class GoogleLLM {
122
126
  }
123
127
  // Handle function calls
124
128
  if (part.functionCall) {
125
- // Save current block if exists
126
129
  if (currentBlock) {
127
130
  if (currentBlock.type === "text") {
128
131
  options?.onEvent?.({ type: "text_end", content: currentBlock.text });
@@ -130,7 +133,6 @@ export class GoogleLLM {
130
133
  else {
131
134
  options?.onEvent?.({ type: "thinking_end", content: currentBlock.thinking });
132
135
  }
133
- blocks.push(currentBlock);
134
136
  currentBlock = null;
135
137
  }
136
138
  // Add tool call
@@ -141,22 +143,22 @@ export class GoogleLLM {
141
143
  name: part.functionCall.name || "",
142
144
  arguments: part.functionCall.args,
143
145
  };
144
- blocks.push(toolCall);
146
+ output.content.push(toolCall);
145
147
  options?.onEvent?.({ type: "toolCall", toolCall });
146
148
  }
147
149
  }
148
150
  }
149
151
  // Map finish reason
150
152
  if (candidate?.finishReason) {
151
- stopReason = this.mapStopReason(candidate.finishReason);
153
+ output.stopReason = this.mapStopReason(candidate.finishReason);
152
154
  // Check if we have tool calls in blocks
153
- if (blocks.some((b) => b.type === "toolCall")) {
154
- stopReason = "toolUse";
155
+ if (output.content.some((b) => b.type === "toolCall")) {
156
+ output.stopReason = "toolUse";
155
157
  }
156
158
  }
157
159
  // Capture usage metadata if available
158
160
  if (chunk.usageMetadata) {
159
- usage = {
161
+ output.usage = {
160
162
  input: chunk.usageMetadata.promptTokenCount || 0,
161
163
  output: (chunk.usageMetadata.candidatesTokenCount || 0) + (chunk.usageMetadata.thoughtsTokenCount || 0),
162
164
  cacheRead: chunk.usageMetadata.cachedContentTokenCount || 0,
@@ -169,9 +171,10 @@ export class GoogleLLM {
169
171
  total: 0,
170
172
  },
171
173
  };
174
+ calculateCost(this.modelInfo, output.usage);
172
175
  }
173
176
  }
174
- // Save final block if exists
177
+ // Finalize last block
175
178
  if (currentBlock) {
176
179
  if (currentBlock.type === "text") {
177
180
  options?.onEvent?.({ type: "text_end", content: currentBlock.text });
@@ -179,43 +182,22 @@ export class GoogleLLM {
179
182
  else {
180
183
  options?.onEvent?.({ type: "thinking_end", content: currentBlock.thinking });
181
184
  }
182
- blocks.push(currentBlock);
183
185
  }
184
- calculateCost(this.model, usage);
185
- const output = {
186
- role: "assistant",
187
- content: blocks,
188
- provider: this.model.provider,
189
- model: this.model.id,
190
- usage,
191
- stopReason,
192
- };
193
- options?.onEvent?.({ type: "done", reason: stopReason, message: output });
186
+ options?.onEvent?.({ type: "done", reason: output.stopReason, message: output });
194
187
  return output;
195
188
  }
196
189
  catch (error) {
197
- const output = {
198
- role: "assistant",
199
- content: [],
200
- provider: this.model.provider,
201
- model: this.model.id,
202
- usage: {
203
- input: 0,
204
- output: 0,
205
- cacheRead: 0,
206
- cacheWrite: 0,
207
- cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
208
- },
209
- stopReason: "error",
210
- error: error instanceof Error ? error.message : JSON.stringify(error),
211
- };
190
+ output.stopReason = "error";
191
+ output.error = error instanceof Error ? error.message : JSON.stringify(error);
212
192
  options?.onEvent?.({ type: "error", error: output.error });
213
193
  return output;
214
194
  }
215
195
  }
216
196
  convertMessages(messages) {
217
197
  const contents = [];
218
- for (const msg of messages) {
198
+ // Transform messages for cross-provider compatibility
199
+ const transformedMessages = transformMessages(messages, this.modelInfo);
200
+ for (const msg of transformedMessages) {
219
201
  if (msg.role === "user") {
220
202
  // Handle both string and array content
221
203
  if (typeof msg.content === "string") {