@yourgpt/llm-sdk 0.1.0 → 1.0.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.
Files changed (56) hide show
  1. package/README.md +61 -40
  2. package/dist/adapters/index.d.mts +4 -258
  3. package/dist/adapters/index.d.ts +4 -258
  4. package/dist/adapters/index.js +0 -113
  5. package/dist/adapters/index.js.map +1 -1
  6. package/dist/adapters/index.mjs +1 -112
  7. package/dist/adapters/index.mjs.map +1 -1
  8. package/dist/base-D_FyHFKj.d.mts +235 -0
  9. package/dist/base-D_FyHFKj.d.ts +235 -0
  10. package/dist/index.d.mts +209 -451
  11. package/dist/index.d.ts +209 -451
  12. package/dist/index.js +1905 -311
  13. package/dist/index.js.map +1 -1
  14. package/dist/index.mjs +1895 -309
  15. package/dist/index.mjs.map +1 -1
  16. package/dist/providers/anthropic/index.d.mts +61 -0
  17. package/dist/providers/anthropic/index.d.ts +61 -0
  18. package/dist/providers/anthropic/index.js +939 -0
  19. package/dist/providers/anthropic/index.js.map +1 -0
  20. package/dist/providers/anthropic/index.mjs +934 -0
  21. package/dist/providers/anthropic/index.mjs.map +1 -0
  22. package/dist/providers/azure/index.d.mts +38 -0
  23. package/dist/providers/azure/index.d.ts +38 -0
  24. package/dist/providers/azure/index.js +380 -0
  25. package/dist/providers/azure/index.js.map +1 -0
  26. package/dist/providers/azure/index.mjs +377 -0
  27. package/dist/providers/azure/index.mjs.map +1 -0
  28. package/dist/providers/google/index.d.mts +72 -0
  29. package/dist/providers/google/index.d.ts +72 -0
  30. package/dist/providers/google/index.js +790 -0
  31. package/dist/providers/google/index.js.map +1 -0
  32. package/dist/providers/google/index.mjs +785 -0
  33. package/dist/providers/google/index.mjs.map +1 -0
  34. package/dist/providers/ollama/index.d.mts +24 -0
  35. package/dist/providers/ollama/index.d.ts +24 -0
  36. package/dist/providers/ollama/index.js +235 -0
  37. package/dist/providers/ollama/index.js.map +1 -0
  38. package/dist/providers/ollama/index.mjs +232 -0
  39. package/dist/providers/ollama/index.mjs.map +1 -0
  40. package/dist/providers/openai/index.d.mts +82 -0
  41. package/dist/providers/openai/index.d.ts +82 -0
  42. package/dist/providers/openai/index.js +679 -0
  43. package/dist/providers/openai/index.js.map +1 -0
  44. package/dist/providers/openai/index.mjs +674 -0
  45. package/dist/providers/openai/index.mjs.map +1 -0
  46. package/dist/providers/xai/index.d.mts +78 -0
  47. package/dist/providers/xai/index.d.ts +78 -0
  48. package/dist/providers/xai/index.js +671 -0
  49. package/dist/providers/xai/index.js.map +1 -0
  50. package/dist/providers/xai/index.mjs +666 -0
  51. package/dist/providers/xai/index.mjs.map +1 -0
  52. package/dist/types-BBCZ3Fxy.d.mts +308 -0
  53. package/dist/types-CdORv1Yu.d.mts +338 -0
  54. package/dist/types-CdORv1Yu.d.ts +338 -0
  55. package/dist/types-DcoCaVVC.d.ts +308 -0
  56. package/package.json +34 -3
package/dist/index.mjs CHANGED
@@ -2,7 +2,1694 @@ import { generateMessageId, generateToolCallId, createMessage } from '@yourgpt/c
2
2
  import { Hono } from 'hono';
3
3
  import { cors } from 'hono/cors';
4
4
 
5
- // src/server/runtime.ts
5
+ // src/core/tool.ts
6
+ function tool(config) {
7
+ return {
8
+ description: config.description,
9
+ parameters: config.parameters,
10
+ execute: config.execute
11
+ };
12
+ }
13
+ function toolToJsonSchema(toolDef) {
14
+ const schema = zodToJsonSchema(toolDef.parameters);
15
+ return {
16
+ type: "object",
17
+ properties: schema.properties ?? {},
18
+ required: schema.required
19
+ };
20
+ }
21
+ function zodToJsonSchema(schema) {
22
+ const def = schema._def;
23
+ const typeName = def.typeName;
24
+ const description = def.description;
25
+ switch (typeName) {
26
+ case "ZodString":
27
+ return { type: "string", description };
28
+ case "ZodNumber":
29
+ return { type: "number", description };
30
+ case "ZodBoolean":
31
+ return { type: "boolean", description };
32
+ case "ZodEnum": {
33
+ const values = def.values;
34
+ return { type: "string", enum: values, description };
35
+ }
36
+ case "ZodArray": {
37
+ const innerType = def.type;
38
+ return {
39
+ type: "array",
40
+ items: zodToJsonSchema(innerType),
41
+ description
42
+ };
43
+ }
44
+ case "ZodObject": {
45
+ const shape = def.shape;
46
+ const shapeObj = shape();
47
+ const properties = {};
48
+ const required = [];
49
+ for (const [key, value] of Object.entries(shapeObj)) {
50
+ properties[key] = zodToJsonSchema(value);
51
+ const valueDef = value._def;
52
+ const isOptional = valueDef.typeName === "ZodOptional" || valueDef.typeName === "ZodNullable" || valueDef.typeName === "ZodDefault";
53
+ if (!isOptional) {
54
+ required.push(key);
55
+ }
56
+ }
57
+ return {
58
+ type: "object",
59
+ properties,
60
+ required: required.length > 0 ? required : void 0,
61
+ description
62
+ };
63
+ }
64
+ case "ZodOptional":
65
+ case "ZodNullable": {
66
+ const innerType = def.innerType;
67
+ return zodToJsonSchema(innerType);
68
+ }
69
+ case "ZodDefault": {
70
+ const innerType = def.innerType;
71
+ return zodToJsonSchema(innerType);
72
+ }
73
+ case "ZodLiteral": {
74
+ const value = def.value;
75
+ if (typeof value === "string") {
76
+ return { type: "string", enum: [value], description };
77
+ }
78
+ if (typeof value === "number") {
79
+ return { type: "number", enum: [value], description };
80
+ }
81
+ if (typeof value === "boolean") {
82
+ return { type: "boolean", enum: [value], description };
83
+ }
84
+ return { description };
85
+ }
86
+ case "ZodUnion": {
87
+ const options = def.options;
88
+ const stringLiterals = [];
89
+ for (const option of options) {
90
+ const optDef = option._def;
91
+ if (optDef.typeName === "ZodLiteral" && typeof optDef.value === "string") {
92
+ stringLiterals.push(optDef.value);
93
+ }
94
+ }
95
+ if (stringLiterals.length === options.length) {
96
+ return { type: "string", enum: stringLiterals, description };
97
+ }
98
+ return zodToJsonSchema(options[0]);
99
+ }
100
+ default:
101
+ return { type: "string", description };
102
+ }
103
+ }
104
+ function formatToolsForOpenAI(tools) {
105
+ return Object.entries(tools).map(([name, toolDef]) => ({
106
+ type: "function",
107
+ function: {
108
+ name,
109
+ description: toolDef.description,
110
+ parameters: toolToJsonSchema(toolDef)
111
+ }
112
+ }));
113
+ }
114
+ function formatToolsForAnthropic(tools) {
115
+ return Object.entries(tools).map(([name, toolDef]) => ({
116
+ name,
117
+ description: toolDef.description,
118
+ input_schema: toolToJsonSchema(toolDef)
119
+ }));
120
+ }
121
+ function formatToolsForGoogle(tools) {
122
+ return [
123
+ {
124
+ functionDeclarations: Object.entries(tools).map(([name, toolDef]) => ({
125
+ name,
126
+ description: toolDef.description,
127
+ parameters: toolToJsonSchema(toolDef)
128
+ }))
129
+ }
130
+ ];
131
+ }
132
+
133
+ // src/core/generate-text.ts
134
+ async function generateText(params) {
135
+ const { model, tools, maxSteps = 1, signal } = params;
136
+ let messages = buildMessages(params);
137
+ const steps = [];
138
+ const allToolCalls = [];
139
+ const allToolResults = [];
140
+ for (let step = 0; step < maxSteps; step++) {
141
+ if (signal?.aborted) {
142
+ throw new Error("Generation aborted");
143
+ }
144
+ const formattedTools = tools ? formatToolsForProvider(tools, model.provider) : void 0;
145
+ const result = await model.doGenerate({
146
+ messages,
147
+ tools: formattedTools,
148
+ temperature: params.temperature,
149
+ maxTokens: params.maxTokens,
150
+ signal
151
+ });
152
+ const stepToolResults = [];
153
+ if (result.toolCalls && result.toolCalls.length > 0 && tools) {
154
+ allToolCalls.push(...result.toolCalls);
155
+ for (const call of result.toolCalls) {
156
+ const toolDef = tools[call.name];
157
+ if (!toolDef) {
158
+ const errorResult = {
159
+ toolCallId: call.id,
160
+ result: { error: `Tool not found: ${call.name}` }
161
+ };
162
+ stepToolResults.push(errorResult);
163
+ allToolResults.push(errorResult);
164
+ continue;
165
+ }
166
+ try {
167
+ const parsedArgs = toolDef.parameters.parse(call.args);
168
+ const toolResult = await toolDef.execute(parsedArgs, {
169
+ toolCallId: call.id,
170
+ abortSignal: signal,
171
+ messages
172
+ });
173
+ const result2 = {
174
+ toolCallId: call.id,
175
+ result: toolResult
176
+ };
177
+ stepToolResults.push(result2);
178
+ allToolResults.push(result2);
179
+ } catch (error) {
180
+ const errorResult = {
181
+ toolCallId: call.id,
182
+ result: {
183
+ error: error instanceof Error ? error.message : "Tool execution failed"
184
+ }
185
+ };
186
+ stepToolResults.push(errorResult);
187
+ allToolResults.push(errorResult);
188
+ }
189
+ }
190
+ }
191
+ steps.push({
192
+ text: result.text,
193
+ toolCalls: result.toolCalls,
194
+ toolResults: stepToolResults,
195
+ finishReason: result.finishReason,
196
+ usage: result.usage
197
+ });
198
+ if (!result.toolCalls || result.toolCalls.length === 0) {
199
+ break;
200
+ }
201
+ const assistantMessage = {
202
+ role: "assistant",
203
+ content: result.text || null,
204
+ toolCalls: result.toolCalls
205
+ };
206
+ messages = [...messages, assistantMessage];
207
+ for (const tr of stepToolResults) {
208
+ const toolMessage = {
209
+ role: "tool",
210
+ toolCallId: tr.toolCallId,
211
+ content: JSON.stringify(tr.result)
212
+ };
213
+ messages = [...messages, toolMessage];
214
+ }
215
+ }
216
+ const lastStep = steps[steps.length - 1];
217
+ return {
218
+ text: lastStep?.text ?? "",
219
+ usage: sumUsage(steps),
220
+ finishReason: lastStep?.finishReason ?? "stop",
221
+ steps,
222
+ toolCalls: allToolCalls,
223
+ toolResults: allToolResults,
224
+ response: {
225
+ messages
226
+ }
227
+ };
228
+ }
229
+ function buildMessages(params) {
230
+ const messages = [];
231
+ if (params.system) {
232
+ messages.push({ role: "system", content: params.system });
233
+ }
234
+ if (params.messages) {
235
+ messages.push(...params.messages);
236
+ }
237
+ if (params.prompt) {
238
+ messages.push({ role: "user", content: params.prompt });
239
+ }
240
+ return messages;
241
+ }
242
+ function formatToolsForProvider(tools, provider) {
243
+ switch (provider) {
244
+ case "anthropic":
245
+ return formatToolsForAnthropic(tools);
246
+ case "openai":
247
+ case "xai":
248
+ case "azure":
249
+ default:
250
+ return formatToolsForOpenAI(tools);
251
+ }
252
+ }
253
+ function sumUsage(steps) {
254
+ return steps.reduce(
255
+ (acc, step) => ({
256
+ promptTokens: acc.promptTokens + (step.usage?.promptTokens ?? 0),
257
+ completionTokens: acc.completionTokens + (step.usage?.completionTokens ?? 0),
258
+ totalTokens: acc.totalTokens + (step.usage?.totalTokens ?? 0)
259
+ }),
260
+ { promptTokens: 0, completionTokens: 0, totalTokens: 0 }
261
+ );
262
+ }
263
+
264
+ // src/core/stream-text.ts
265
+ async function streamText(params) {
266
+ const { model, tools, maxSteps = 1, signal } = params;
267
+ let fullText = "";
268
+ let finalUsage = {
269
+ promptTokens: 0,
270
+ completionTokens: 0,
271
+ totalTokens: 0
272
+ };
273
+ let finalFinishReason = "stop";
274
+ async function* createFullStream() {
275
+ let messages = buildMessages2(params);
276
+ for (let step = 0; step < maxSteps; step++) {
277
+ yield { type: "step-start", step };
278
+ if (signal?.aborted) {
279
+ yield { type: "error", error: new Error("Stream aborted") };
280
+ return;
281
+ }
282
+ const formattedTools = tools ? formatToolsForProvider2(tools, model.provider) : void 0;
283
+ let stepText = "";
284
+ const toolCalls = [];
285
+ let stepFinishReason = "stop";
286
+ try {
287
+ for await (const chunk of model.doStream({
288
+ messages,
289
+ tools: formattedTools,
290
+ temperature: params.temperature,
291
+ maxTokens: params.maxTokens,
292
+ signal
293
+ })) {
294
+ switch (chunk.type) {
295
+ case "text-delta":
296
+ stepText += chunk.text;
297
+ fullText += chunk.text;
298
+ yield { type: "text-delta", text: chunk.text };
299
+ break;
300
+ case "tool-call":
301
+ toolCalls.push(chunk.toolCall);
302
+ yield {
303
+ type: "tool-call-complete",
304
+ toolCall: chunk.toolCall
305
+ };
306
+ break;
307
+ case "finish":
308
+ stepFinishReason = chunk.finishReason;
309
+ finalFinishReason = chunk.finishReason;
310
+ if (chunk.usage) {
311
+ finalUsage = {
312
+ promptTokens: finalUsage.promptTokens + chunk.usage.promptTokens,
313
+ completionTokens: finalUsage.completionTokens + chunk.usage.completionTokens,
314
+ totalTokens: finalUsage.totalTokens + chunk.usage.totalTokens
315
+ };
316
+ }
317
+ break;
318
+ case "error":
319
+ yield { type: "error", error: chunk.error };
320
+ return;
321
+ }
322
+ }
323
+ } catch (error) {
324
+ yield {
325
+ type: "error",
326
+ error: error instanceof Error ? error : new Error(String(error))
327
+ };
328
+ return;
329
+ }
330
+ yield { type: "step-finish", step, finishReason: stepFinishReason };
331
+ if (toolCalls.length === 0 || !tools) {
332
+ break;
333
+ }
334
+ const assistantMessage = {
335
+ role: "assistant",
336
+ content: stepText || null,
337
+ toolCalls
338
+ };
339
+ messages = [...messages, assistantMessage];
340
+ for (const call of toolCalls) {
341
+ const toolDef = tools[call.name];
342
+ if (!toolDef) {
343
+ const errorResult = { error: `Tool not found: ${call.name}` };
344
+ yield {
345
+ type: "tool-result",
346
+ toolCallId: call.id,
347
+ result: errorResult
348
+ };
349
+ messages = [
350
+ ...messages,
351
+ {
352
+ role: "tool",
353
+ toolCallId: call.id,
354
+ content: JSON.stringify(errorResult)
355
+ }
356
+ ];
357
+ continue;
358
+ }
359
+ try {
360
+ const parsedArgs = toolDef.parameters.parse(call.args);
361
+ const result = await toolDef.execute(parsedArgs, {
362
+ toolCallId: call.id,
363
+ abortSignal: signal,
364
+ messages
365
+ });
366
+ yield { type: "tool-result", toolCallId: call.id, result };
367
+ messages = [
368
+ ...messages,
369
+ {
370
+ role: "tool",
371
+ toolCallId: call.id,
372
+ content: JSON.stringify(result)
373
+ }
374
+ ];
375
+ } catch (error) {
376
+ const errorResult = {
377
+ error: error instanceof Error ? error.message : "Tool execution failed"
378
+ };
379
+ yield {
380
+ type: "tool-result",
381
+ toolCallId: call.id,
382
+ result: errorResult
383
+ };
384
+ messages = [
385
+ ...messages,
386
+ {
387
+ role: "tool",
388
+ toolCallId: call.id,
389
+ content: JSON.stringify(errorResult)
390
+ }
391
+ ];
392
+ }
393
+ }
394
+ }
395
+ yield {
396
+ type: "finish",
397
+ finishReason: finalFinishReason,
398
+ usage: finalUsage
399
+ };
400
+ }
401
+ async function* createTextStream() {
402
+ for await (const part of createFullStream()) {
403
+ if (part.type === "text-delta") {
404
+ yield part.text;
405
+ }
406
+ }
407
+ }
408
+ let textPromise;
409
+ let usagePromise;
410
+ let finishReasonPromise;
411
+ async function consumeStream() {
412
+ for await (const _ of createFullStream()) {
413
+ }
414
+ }
415
+ return {
416
+ textStream: createTextStream(),
417
+ fullStream: createFullStream(),
418
+ get text() {
419
+ if (!textPromise) {
420
+ textPromise = consumeStream().then(() => fullText);
421
+ }
422
+ return textPromise;
423
+ },
424
+ get usage() {
425
+ if (!usagePromise) {
426
+ usagePromise = consumeStream().then(() => finalUsage);
427
+ }
428
+ return usagePromise;
429
+ },
430
+ get finishReason() {
431
+ if (!finishReasonPromise) {
432
+ finishReasonPromise = consumeStream().then(() => finalFinishReason);
433
+ }
434
+ return finishReasonPromise;
435
+ },
436
+ toTextStreamResponse(options) {
437
+ const stream = createTextStreamReadable(createTextStream());
438
+ return new Response(stream, {
439
+ status: options?.status ?? 200,
440
+ headers: {
441
+ "Content-Type": "text/plain; charset=utf-8",
442
+ "Cache-Control": "no-cache",
443
+ Connection: "keep-alive",
444
+ ...options?.headers
445
+ }
446
+ });
447
+ },
448
+ toDataStreamResponse(options) {
449
+ const stream = createDataStreamReadable(createFullStream());
450
+ return new Response(stream, {
451
+ status: options?.status ?? 200,
452
+ headers: {
453
+ "Content-Type": "text/event-stream",
454
+ "Cache-Control": "no-cache",
455
+ Connection: "keep-alive",
456
+ ...options?.headers
457
+ }
458
+ });
459
+ }
460
+ };
461
+ }
462
+ function buildMessages2(params) {
463
+ const messages = [];
464
+ if (params.system) {
465
+ messages.push({ role: "system", content: params.system });
466
+ }
467
+ if (params.messages) {
468
+ messages.push(...params.messages);
469
+ }
470
+ if (params.prompt) {
471
+ messages.push({ role: "user", content: params.prompt });
472
+ }
473
+ return messages;
474
+ }
475
+ function formatToolsForProvider2(tools, provider) {
476
+ switch (provider) {
477
+ case "anthropic":
478
+ return formatToolsForAnthropic(tools);
479
+ case "openai":
480
+ case "xai":
481
+ case "azure":
482
+ default:
483
+ return formatToolsForOpenAI(tools);
484
+ }
485
+ }
486
+ function createTextStreamReadable(textStream) {
487
+ const encoder = new TextEncoder();
488
+ return new ReadableStream({
489
+ async start(controller) {
490
+ try {
491
+ for await (const text of textStream) {
492
+ controller.enqueue(encoder.encode(text));
493
+ }
494
+ controller.close();
495
+ } catch (error) {
496
+ controller.error(error);
497
+ }
498
+ }
499
+ });
500
+ }
501
+ function createDataStreamReadable(fullStream) {
502
+ const encoder = new TextEncoder();
503
+ return new ReadableStream({
504
+ async start(controller) {
505
+ try {
506
+ for await (const part of fullStream) {
507
+ const data = JSON.stringify(part);
508
+ controller.enqueue(encoder.encode(`data: ${data}
509
+
510
+ `));
511
+ }
512
+ controller.enqueue(encoder.encode("data: [DONE]\n\n"));
513
+ controller.close();
514
+ } catch (error) {
515
+ const errorData = JSON.stringify({
516
+ type: "error",
517
+ error: error instanceof Error ? error.message : String(error)
518
+ });
519
+ controller.enqueue(encoder.encode(`data: ${errorData}
520
+
521
+ `));
522
+ controller.close();
523
+ }
524
+ }
525
+ });
526
+ }
527
+
528
+ // src/core/types.ts
529
+ var DEFAULT_CAPABILITIES = {
530
+ supportsVision: false,
531
+ supportsTools: true,
532
+ supportsStreaming: true,
533
+ supportsJsonMode: false,
534
+ supportsThinking: false,
535
+ supportsPDF: false,
536
+ maxTokens: 8192,
537
+ supportedImageTypes: []
538
+ };
539
+
540
+ // src/providers/openai/provider.ts
541
+ var OPENAI_MODELS = {
542
+ // GPT-4o series
543
+ "gpt-4o": { vision: true, tools: true, jsonMode: true, maxTokens: 128e3 },
544
+ "gpt-4o-mini": {
545
+ vision: true,
546
+ tools: true,
547
+ jsonMode: true,
548
+ maxTokens: 128e3
549
+ },
550
+ "gpt-4o-2024-11-20": {
551
+ vision: true,
552
+ tools: true,
553
+ jsonMode: true,
554
+ maxTokens: 128e3
555
+ },
556
+ "gpt-4o-2024-08-06": {
557
+ vision: true,
558
+ tools: true,
559
+ jsonMode: true,
560
+ maxTokens: 128e3
561
+ },
562
+ // GPT-4 Turbo
563
+ "gpt-4-turbo": {
564
+ vision: true,
565
+ tools: true,
566
+ jsonMode: true,
567
+ maxTokens: 128e3
568
+ },
569
+ "gpt-4-turbo-preview": {
570
+ vision: false,
571
+ tools: true,
572
+ jsonMode: true,
573
+ maxTokens: 128e3
574
+ },
575
+ // GPT-4
576
+ "gpt-4": { vision: false, tools: true, jsonMode: false, maxTokens: 8192 },
577
+ "gpt-4-32k": {
578
+ vision: false,
579
+ tools: true,
580
+ jsonMode: false,
581
+ maxTokens: 32768
582
+ },
583
+ // GPT-3.5
584
+ "gpt-3.5-turbo": {
585
+ vision: false,
586
+ tools: true,
587
+ jsonMode: true,
588
+ maxTokens: 16385
589
+ },
590
+ // O1 series (reasoning)
591
+ o1: { vision: true, tools: false, jsonMode: false, maxTokens: 128e3 },
592
+ "o1-mini": { vision: true, tools: false, jsonMode: false, maxTokens: 128e3 },
593
+ "o1-preview": {
594
+ vision: true,
595
+ tools: false,
596
+ jsonMode: false,
597
+ maxTokens: 128e3
598
+ },
599
+ // O3 series
600
+ "o3-mini": { vision: true, tools: false, jsonMode: false, maxTokens: 128e3 }
601
+ };
602
+ function openai(modelId, options = {}) {
603
+ const apiKey = options.apiKey ?? process.env.OPENAI_API_KEY;
604
+ const baseURL = options.baseURL ?? "https://api.openai.com/v1";
605
+ let client = null;
606
+ async function getClient() {
607
+ if (!client) {
608
+ const { default: OpenAI } = await import('openai');
609
+ client = new OpenAI({
610
+ apiKey,
611
+ baseURL,
612
+ organization: options.organization,
613
+ defaultHeaders: options.headers
614
+ });
615
+ }
616
+ return client;
617
+ }
618
+ const modelConfig = OPENAI_MODELS[modelId] ?? OPENAI_MODELS["gpt-4o"];
619
+ return {
620
+ provider: "openai",
621
+ modelId,
622
+ capabilities: {
623
+ supportsVision: modelConfig.vision,
624
+ supportsTools: modelConfig.tools,
625
+ supportsStreaming: true,
626
+ supportsJsonMode: modelConfig.jsonMode,
627
+ supportsThinking: false,
628
+ supportsPDF: false,
629
+ maxTokens: modelConfig.maxTokens,
630
+ supportedImageTypes: modelConfig.vision ? ["image/png", "image/jpeg", "image/gif", "image/webp"] : []
631
+ },
632
+ async doGenerate(params) {
633
+ const client2 = await getClient();
634
+ const messages = formatMessagesForOpenAI(params.messages);
635
+ const response = await client2.chat.completions.create({
636
+ model: modelId,
637
+ messages,
638
+ tools: params.tools,
639
+ temperature: params.temperature,
640
+ max_tokens: params.maxTokens
641
+ });
642
+ const choice = response.choices[0];
643
+ const message = choice.message;
644
+ const toolCalls = (message.tool_calls ?? []).map(
645
+ (tc) => ({
646
+ id: tc.id,
647
+ name: tc.function.name,
648
+ args: JSON.parse(tc.function.arguments || "{}")
649
+ })
650
+ );
651
+ return {
652
+ text: message.content ?? "",
653
+ toolCalls,
654
+ finishReason: mapFinishReason(choice.finish_reason),
655
+ usage: {
656
+ promptTokens: response.usage?.prompt_tokens ?? 0,
657
+ completionTokens: response.usage?.completion_tokens ?? 0,
658
+ totalTokens: response.usage?.total_tokens ?? 0
659
+ },
660
+ rawResponse: response
661
+ };
662
+ },
663
+ async *doStream(params) {
664
+ const client2 = await getClient();
665
+ const messages = formatMessagesForOpenAI(params.messages);
666
+ const stream = await client2.chat.completions.create({
667
+ model: modelId,
668
+ messages,
669
+ tools: params.tools,
670
+ temperature: params.temperature,
671
+ max_tokens: params.maxTokens,
672
+ stream: true
673
+ });
674
+ let currentToolCall = null;
675
+ let totalPromptTokens = 0;
676
+ let totalCompletionTokens = 0;
677
+ for await (const chunk of stream) {
678
+ if (params.signal?.aborted) {
679
+ yield { type: "error", error: new Error("Aborted") };
680
+ return;
681
+ }
682
+ const choice = chunk.choices[0];
683
+ const delta = choice?.delta;
684
+ if (delta?.content) {
685
+ yield { type: "text-delta", text: delta.content };
686
+ }
687
+ if (delta?.tool_calls) {
688
+ for (const tc of delta.tool_calls) {
689
+ if (tc.id) {
690
+ if (currentToolCall) {
691
+ yield {
692
+ type: "tool-call",
693
+ toolCall: {
694
+ id: currentToolCall.id,
695
+ name: currentToolCall.name,
696
+ args: JSON.parse(currentToolCall.arguments || "{}")
697
+ }
698
+ };
699
+ }
700
+ currentToolCall = {
701
+ id: tc.id,
702
+ name: tc.function?.name ?? "",
703
+ arguments: tc.function?.arguments ?? ""
704
+ };
705
+ } else if (currentToolCall && tc.function?.arguments) {
706
+ currentToolCall.arguments += tc.function.arguments;
707
+ }
708
+ }
709
+ }
710
+ if (choice?.finish_reason) {
711
+ if (currentToolCall) {
712
+ yield {
713
+ type: "tool-call",
714
+ toolCall: {
715
+ id: currentToolCall.id,
716
+ name: currentToolCall.name,
717
+ args: JSON.parse(currentToolCall.arguments || "{}")
718
+ }
719
+ };
720
+ currentToolCall = null;
721
+ }
722
+ if (chunk.usage) {
723
+ totalPromptTokens = chunk.usage.prompt_tokens;
724
+ totalCompletionTokens = chunk.usage.completion_tokens;
725
+ }
726
+ yield {
727
+ type: "finish",
728
+ finishReason: mapFinishReason(choice.finish_reason),
729
+ usage: {
730
+ promptTokens: totalPromptTokens,
731
+ completionTokens: totalCompletionTokens,
732
+ totalTokens: totalPromptTokens + totalCompletionTokens
733
+ }
734
+ };
735
+ }
736
+ }
737
+ }
738
+ };
739
+ }
740
+ function mapFinishReason(reason) {
741
+ switch (reason) {
742
+ case "stop":
743
+ return "stop";
744
+ case "length":
745
+ return "length";
746
+ case "tool_calls":
747
+ case "function_call":
748
+ return "tool-calls";
749
+ case "content_filter":
750
+ return "content-filter";
751
+ default:
752
+ return "unknown";
753
+ }
754
+ }
755
+ function formatMessagesForOpenAI(messages) {
756
+ return messages.map((msg) => {
757
+ switch (msg.role) {
758
+ case "system":
759
+ return { role: "system", content: msg.content };
760
+ case "user":
761
+ if (typeof msg.content === "string") {
762
+ return { role: "user", content: msg.content };
763
+ }
764
+ return {
765
+ role: "user",
766
+ content: msg.content.map((part) => {
767
+ if (part.type === "text") {
768
+ return { type: "text", text: part.text };
769
+ }
770
+ if (part.type === "image") {
771
+ const imageData = typeof part.image === "string" ? part.image : Buffer.from(part.image).toString("base64");
772
+ const url = imageData.startsWith("data:") ? imageData : `data:${part.mimeType ?? "image/png"};base64,${imageData}`;
773
+ return { type: "image_url", image_url: { url, detail: "auto" } };
774
+ }
775
+ return { type: "text", text: "" };
776
+ })
777
+ };
778
+ case "assistant":
779
+ const assistantMsg = {
780
+ role: "assistant",
781
+ content: msg.content
782
+ };
783
+ if (msg.toolCalls && msg.toolCalls.length > 0) {
784
+ assistantMsg.tool_calls = msg.toolCalls.map((tc) => ({
785
+ id: tc.id,
786
+ type: "function",
787
+ function: {
788
+ name: tc.name,
789
+ arguments: JSON.stringify(tc.args)
790
+ }
791
+ }));
792
+ }
793
+ return assistantMsg;
794
+ case "tool":
795
+ return {
796
+ role: "tool",
797
+ tool_call_id: msg.toolCallId,
798
+ content: msg.content
799
+ };
800
+ default:
801
+ return msg;
802
+ }
803
+ });
804
+ }
805
+
806
+ // src/providers/anthropic/provider.ts
807
+ var ANTHROPIC_MODELS = {
808
+ // Claude 4 series
809
+ "claude-sonnet-4-20250514": {
810
+ vision: true,
811
+ tools: true,
812
+ thinking: true,
813
+ pdf: true,
814
+ maxTokens: 2e5
815
+ },
816
+ "claude-opus-4-20250514": {
817
+ vision: true,
818
+ tools: true,
819
+ thinking: true,
820
+ pdf: true,
821
+ maxTokens: 2e5
822
+ },
823
+ // Claude 3.7 series
824
+ "claude-3-7-sonnet-20250219": {
825
+ vision: true,
826
+ tools: true,
827
+ thinking: true,
828
+ pdf: true,
829
+ maxTokens: 2e5
830
+ },
831
+ "claude-3-7-sonnet-latest": {
832
+ vision: true,
833
+ tools: true,
834
+ thinking: true,
835
+ pdf: true,
836
+ maxTokens: 2e5
837
+ },
838
+ // Claude 3.5 series
839
+ "claude-3-5-sonnet-20241022": {
840
+ vision: true,
841
+ tools: true,
842
+ thinking: false,
843
+ pdf: true,
844
+ maxTokens: 2e5
845
+ },
846
+ "claude-3-5-sonnet-latest": {
847
+ vision: true,
848
+ tools: true,
849
+ thinking: false,
850
+ pdf: true,
851
+ maxTokens: 2e5
852
+ },
853
+ "claude-3-5-haiku-20241022": {
854
+ vision: true,
855
+ tools: true,
856
+ thinking: false,
857
+ pdf: false,
858
+ maxTokens: 2e5
859
+ },
860
+ "claude-3-5-haiku-latest": {
861
+ vision: true,
862
+ tools: true,
863
+ thinking: false,
864
+ pdf: false,
865
+ maxTokens: 2e5
866
+ },
867
+ // Claude 3 series
868
+ "claude-3-opus-20240229": {
869
+ vision: true,
870
+ tools: true,
871
+ thinking: false,
872
+ pdf: false,
873
+ maxTokens: 2e5
874
+ },
875
+ "claude-3-sonnet-20240229": {
876
+ vision: true,
877
+ tools: true,
878
+ thinking: false,
879
+ pdf: false,
880
+ maxTokens: 2e5
881
+ },
882
+ "claude-3-haiku-20240307": {
883
+ vision: true,
884
+ tools: true,
885
+ thinking: false,
886
+ pdf: false,
887
+ maxTokens: 2e5
888
+ }
889
+ };
890
+ function anthropic(modelId, options = {}) {
891
+ const apiKey = options.apiKey ?? process.env.ANTHROPIC_API_KEY;
892
+ let client = null;
893
+ async function getClient() {
894
+ if (!client) {
895
+ const { default: Anthropic } = await import('@anthropic-ai/sdk');
896
+ client = new Anthropic({
897
+ apiKey,
898
+ baseURL: options.baseURL
899
+ });
900
+ }
901
+ return client;
902
+ }
903
+ const modelConfig = ANTHROPIC_MODELS[modelId] ?? ANTHROPIC_MODELS["claude-3-5-sonnet-latest"];
904
+ return {
905
+ provider: "anthropic",
906
+ modelId,
907
+ capabilities: {
908
+ supportsVision: modelConfig.vision,
909
+ supportsTools: modelConfig.tools,
910
+ supportsStreaming: true,
911
+ supportsJsonMode: false,
912
+ supportsThinking: modelConfig.thinking,
913
+ supportsPDF: modelConfig.pdf,
914
+ maxTokens: modelConfig.maxTokens,
915
+ supportedImageTypes: modelConfig.vision ? ["image/png", "image/jpeg", "image/gif", "image/webp"] : []
916
+ },
917
+ async doGenerate(params) {
918
+ const client2 = await getClient();
919
+ const { system, messages } = formatMessagesForAnthropic(params.messages);
920
+ const requestOptions = {
921
+ model: modelId,
922
+ max_tokens: params.maxTokens ?? 4096,
923
+ system: system || void 0,
924
+ messages,
925
+ tools: params.tools
926
+ };
927
+ if (params.temperature !== void 0) {
928
+ requestOptions.temperature = params.temperature;
929
+ }
930
+ if (options.thinking?.enabled && modelConfig.thinking) {
931
+ requestOptions.thinking = {
932
+ type: "enabled",
933
+ budget_tokens: options.thinking.budgetTokens ?? 1e4
934
+ };
935
+ }
936
+ const response = await client2.messages.create(requestOptions);
937
+ let text = "";
938
+ const toolCalls = [];
939
+ for (const block of response.content) {
940
+ if (block.type === "text") {
941
+ text += block.text;
942
+ } else if (block.type === "tool_use") {
943
+ toolCalls.push({
944
+ id: block.id,
945
+ name: block.name,
946
+ args: block.input
947
+ });
948
+ }
949
+ }
950
+ return {
951
+ text,
952
+ toolCalls,
953
+ finishReason: mapFinishReason2(response.stop_reason),
954
+ usage: {
955
+ promptTokens: response.usage?.input_tokens ?? 0,
956
+ completionTokens: response.usage?.output_tokens ?? 0,
957
+ totalTokens: (response.usage?.input_tokens ?? 0) + (response.usage?.output_tokens ?? 0)
958
+ },
959
+ rawResponse: response
960
+ };
961
+ },
962
+ async *doStream(params) {
963
+ const client2 = await getClient();
964
+ const { system, messages } = formatMessagesForAnthropic(params.messages);
965
+ const requestOptions = {
966
+ model: modelId,
967
+ max_tokens: params.maxTokens ?? 4096,
968
+ system: system || void 0,
969
+ messages,
970
+ tools: params.tools
971
+ };
972
+ if (params.temperature !== void 0) {
973
+ requestOptions.temperature = params.temperature;
974
+ }
975
+ if (options.thinking?.enabled && modelConfig.thinking) {
976
+ requestOptions.thinking = {
977
+ type: "enabled",
978
+ budget_tokens: options.thinking.budgetTokens ?? 1e4
979
+ };
980
+ }
981
+ const stream = await client2.messages.stream(requestOptions);
982
+ let currentToolUse = null;
983
+ let inputTokens = 0;
984
+ let outputTokens = 0;
985
+ for await (const event of stream) {
986
+ if (params.signal?.aborted) {
987
+ yield { type: "error", error: new Error("Aborted") };
988
+ return;
989
+ }
990
+ switch (event.type) {
991
+ case "message_start":
992
+ if (event.message?.usage) {
993
+ inputTokens = event.message.usage.input_tokens ?? 0;
994
+ }
995
+ break;
996
+ case "content_block_start":
997
+ if (event.content_block?.type === "tool_use") {
998
+ currentToolUse = {
999
+ id: event.content_block.id,
1000
+ name: event.content_block.name,
1001
+ input: ""
1002
+ };
1003
+ }
1004
+ break;
1005
+ case "content_block_delta":
1006
+ if (event.delta?.type === "text_delta") {
1007
+ yield { type: "text-delta", text: event.delta.text };
1008
+ } else if (event.delta?.type === "input_json_delta" && currentToolUse) {
1009
+ currentToolUse.input += event.delta.partial_json;
1010
+ }
1011
+ break;
1012
+ case "content_block_stop":
1013
+ if (currentToolUse) {
1014
+ yield {
1015
+ type: "tool-call",
1016
+ toolCall: {
1017
+ id: currentToolUse.id,
1018
+ name: currentToolUse.name,
1019
+ args: JSON.parse(currentToolUse.input || "{}")
1020
+ }
1021
+ };
1022
+ currentToolUse = null;
1023
+ }
1024
+ break;
1025
+ case "message_delta":
1026
+ if (event.usage) {
1027
+ outputTokens = event.usage.output_tokens ?? 0;
1028
+ }
1029
+ if (event.delta?.stop_reason) {
1030
+ yield {
1031
+ type: "finish",
1032
+ finishReason: mapFinishReason2(event.delta.stop_reason),
1033
+ usage: {
1034
+ promptTokens: inputTokens,
1035
+ completionTokens: outputTokens,
1036
+ totalTokens: inputTokens + outputTokens
1037
+ }
1038
+ };
1039
+ }
1040
+ break;
1041
+ }
1042
+ }
1043
+ }
1044
+ };
1045
+ }
1046
+ function mapFinishReason2(reason) {
1047
+ switch (reason) {
1048
+ case "end_turn":
1049
+ case "stop_sequence":
1050
+ return "stop";
1051
+ case "max_tokens":
1052
+ return "length";
1053
+ case "tool_use":
1054
+ return "tool-calls";
1055
+ default:
1056
+ return "unknown";
1057
+ }
1058
+ }
1059
+ function formatMessagesForAnthropic(messages) {
1060
+ let system = "";
1061
+ const formatted = [];
1062
+ const pendingToolResults = [];
1063
+ for (const msg of messages) {
1064
+ if (msg.role === "system") {
1065
+ system += (system ? "\n" : "") + msg.content;
1066
+ continue;
1067
+ }
1068
+ if (msg.role === "assistant" && pendingToolResults.length > 0) {
1069
+ formatted.push({
1070
+ role: "user",
1071
+ content: pendingToolResults.map((tr) => ({
1072
+ type: "tool_result",
1073
+ tool_use_id: tr.toolCallId,
1074
+ content: tr.content
1075
+ }))
1076
+ });
1077
+ pendingToolResults.length = 0;
1078
+ }
1079
+ if (msg.role === "user") {
1080
+ if (pendingToolResults.length > 0) {
1081
+ formatted.push({
1082
+ role: "user",
1083
+ content: pendingToolResults.map((tr) => ({
1084
+ type: "tool_result",
1085
+ tool_use_id: tr.toolCallId,
1086
+ content: tr.content
1087
+ }))
1088
+ });
1089
+ pendingToolResults.length = 0;
1090
+ }
1091
+ if (typeof msg.content === "string") {
1092
+ formatted.push({ role: "user", content: msg.content });
1093
+ } else {
1094
+ const content = [];
1095
+ for (const part of msg.content) {
1096
+ if (part.type === "text") {
1097
+ content.push({ type: "text", text: part.text });
1098
+ } else if (part.type === "image") {
1099
+ const imageData = typeof part.image === "string" ? part.image : Buffer.from(part.image).toString("base64");
1100
+ if (imageData.startsWith("http")) {
1101
+ content.push({
1102
+ type: "image",
1103
+ source: { type: "url", url: imageData }
1104
+ });
1105
+ } else {
1106
+ const base64 = imageData.startsWith("data:") ? imageData.split(",")[1] : imageData;
1107
+ content.push({
1108
+ type: "image",
1109
+ source: {
1110
+ type: "base64",
1111
+ media_type: part.mimeType ?? "image/png",
1112
+ data: base64
1113
+ }
1114
+ });
1115
+ }
1116
+ }
1117
+ }
1118
+ formatted.push({ role: "user", content });
1119
+ }
1120
+ } else if (msg.role === "assistant") {
1121
+ const content = [];
1122
+ if (msg.content) {
1123
+ content.push({ type: "text", text: msg.content });
1124
+ }
1125
+ if (msg.toolCalls && msg.toolCalls.length > 0) {
1126
+ for (const tc of msg.toolCalls) {
1127
+ content.push({
1128
+ type: "tool_use",
1129
+ id: tc.id,
1130
+ name: tc.name,
1131
+ input: tc.args
1132
+ });
1133
+ }
1134
+ }
1135
+ if (content.length > 0) {
1136
+ formatted.push({ role: "assistant", content });
1137
+ }
1138
+ } else if (msg.role === "tool") {
1139
+ pendingToolResults.push({
1140
+ toolCallId: msg.toolCallId,
1141
+ content: msg.content
1142
+ });
1143
+ }
1144
+ }
1145
+ if (pendingToolResults.length > 0) {
1146
+ formatted.push({
1147
+ role: "user",
1148
+ content: pendingToolResults.map((tr) => ({
1149
+ type: "tool_result",
1150
+ tool_use_id: tr.toolCallId,
1151
+ content: tr.content
1152
+ }))
1153
+ });
1154
+ }
1155
+ return { system, messages: formatted };
1156
+ }
1157
+
1158
+ // src/providers/xai/provider.ts
1159
+ var XAI_MODELS = {
1160
+ // Grok 4.1 Fast (Latest - December 2025)
1161
+ "grok-4-1-fast-reasoning": { vision: false, tools: true, maxTokens: 2e6 },
1162
+ "grok-4-1-fast-non-reasoning": {
1163
+ vision: false,
1164
+ tools: true,
1165
+ maxTokens: 2e6
1166
+ },
1167
+ // Grok 4 Fast (September 2025)
1168
+ "grok-4-fast-reasoning": { vision: false, tools: true, maxTokens: 2e6 },
1169
+ "grok-4-fast-non-reasoning": {
1170
+ vision: false,
1171
+ tools: true,
1172
+ maxTokens: 2e6
1173
+ },
1174
+ // Grok 4 (July 2025)
1175
+ "grok-4": { vision: true, tools: true, maxTokens: 256e3 },
1176
+ "grok-4-0709": { vision: true, tools: true, maxTokens: 256e3 },
1177
+ // Grok 3 (February 2025) - Stable
1178
+ "grok-3-beta": { vision: true, tools: true, maxTokens: 131072 },
1179
+ "grok-3-fast-beta": { vision: false, tools: true, maxTokens: 131072 },
1180
+ "grok-3-mini-beta": { vision: false, tools: true, maxTokens: 32768 },
1181
+ "grok-3-mini-fast-beta": { vision: false, tools: true, maxTokens: 32768 },
1182
+ // Grok Code Fast (August 2025)
1183
+ "grok-code-fast-1": { vision: false, tools: true, maxTokens: 256e3 },
1184
+ // Grok 2 (Legacy)
1185
+ "grok-2": { vision: true, tools: true, maxTokens: 131072 },
1186
+ "grok-2-latest": { vision: true, tools: true, maxTokens: 131072 },
1187
+ "grok-2-mini": { vision: false, tools: true, maxTokens: 131072 }
1188
+ };
1189
+ function xai(modelId, options = {}) {
1190
+ const apiKey = options.apiKey ?? process.env.XAI_API_KEY;
1191
+ const baseURL = options.baseURL ?? "https://api.x.ai/v1";
1192
+ let client = null;
1193
+ async function getClient() {
1194
+ if (!client) {
1195
+ const { default: OpenAI } = await import('openai');
1196
+ client = new OpenAI({
1197
+ apiKey,
1198
+ baseURL
1199
+ });
1200
+ }
1201
+ return client;
1202
+ }
1203
+ const modelConfig = XAI_MODELS[modelId] ?? XAI_MODELS["grok-3-fast-beta"];
1204
+ return {
1205
+ provider: "xai",
1206
+ modelId,
1207
+ capabilities: {
1208
+ supportsVision: modelConfig.vision,
1209
+ supportsTools: modelConfig.tools,
1210
+ supportsStreaming: true,
1211
+ supportsJsonMode: false,
1212
+ // xAI doesn't support JSON mode yet
1213
+ supportsThinking: false,
1214
+ supportsPDF: false,
1215
+ maxTokens: modelConfig.maxTokens,
1216
+ supportedImageTypes: modelConfig.vision ? ["image/png", "image/jpeg", "image/gif", "image/webp"] : []
1217
+ },
1218
+ async doGenerate(params) {
1219
+ const client2 = await getClient();
1220
+ const messages = formatMessagesForXAI(params.messages);
1221
+ const response = await client2.chat.completions.create({
1222
+ model: modelId,
1223
+ messages,
1224
+ tools: params.tools,
1225
+ temperature: params.temperature,
1226
+ max_tokens: params.maxTokens
1227
+ });
1228
+ const choice = response.choices[0];
1229
+ const message = choice.message;
1230
+ const toolCalls = (message.tool_calls ?? []).map(
1231
+ (tc) => ({
1232
+ id: tc.id,
1233
+ name: tc.function.name,
1234
+ args: JSON.parse(tc.function.arguments || "{}")
1235
+ })
1236
+ );
1237
+ return {
1238
+ text: message.content ?? "",
1239
+ toolCalls,
1240
+ finishReason: mapFinishReason3(choice.finish_reason),
1241
+ usage: {
1242
+ promptTokens: response.usage?.prompt_tokens ?? 0,
1243
+ completionTokens: response.usage?.completion_tokens ?? 0,
1244
+ totalTokens: response.usage?.total_tokens ?? 0
1245
+ },
1246
+ rawResponse: response
1247
+ };
1248
+ },
1249
+ async *doStream(params) {
1250
+ const client2 = await getClient();
1251
+ const messages = formatMessagesForXAI(params.messages);
1252
+ const stream = await client2.chat.completions.create({
1253
+ model: modelId,
1254
+ messages,
1255
+ tools: params.tools,
1256
+ temperature: params.temperature,
1257
+ max_tokens: params.maxTokens,
1258
+ stream: true
1259
+ });
1260
+ let currentToolCall = null;
1261
+ let totalPromptTokens = 0;
1262
+ let totalCompletionTokens = 0;
1263
+ for await (const chunk of stream) {
1264
+ if (params.signal?.aborted) {
1265
+ yield { type: "error", error: new Error("Aborted") };
1266
+ return;
1267
+ }
1268
+ const choice = chunk.choices[0];
1269
+ const delta = choice?.delta;
1270
+ if (delta?.content) {
1271
+ yield { type: "text-delta", text: delta.content };
1272
+ }
1273
+ if (delta?.tool_calls) {
1274
+ for (const tc of delta.tool_calls) {
1275
+ if (tc.id) {
1276
+ if (currentToolCall) {
1277
+ yield {
1278
+ type: "tool-call",
1279
+ toolCall: {
1280
+ id: currentToolCall.id,
1281
+ name: currentToolCall.name,
1282
+ args: JSON.parse(currentToolCall.arguments || "{}")
1283
+ }
1284
+ };
1285
+ }
1286
+ currentToolCall = {
1287
+ id: tc.id,
1288
+ name: tc.function?.name ?? "",
1289
+ arguments: tc.function?.arguments ?? ""
1290
+ };
1291
+ } else if (currentToolCall && tc.function?.arguments) {
1292
+ currentToolCall.arguments += tc.function.arguments;
1293
+ }
1294
+ }
1295
+ }
1296
+ if (choice?.finish_reason) {
1297
+ if (currentToolCall) {
1298
+ yield {
1299
+ type: "tool-call",
1300
+ toolCall: {
1301
+ id: currentToolCall.id,
1302
+ name: currentToolCall.name,
1303
+ args: JSON.parse(currentToolCall.arguments || "{}")
1304
+ }
1305
+ };
1306
+ currentToolCall = null;
1307
+ }
1308
+ if (chunk.usage) {
1309
+ totalPromptTokens = chunk.usage.prompt_tokens;
1310
+ totalCompletionTokens = chunk.usage.completion_tokens;
1311
+ }
1312
+ yield {
1313
+ type: "finish",
1314
+ finishReason: mapFinishReason3(choice.finish_reason),
1315
+ usage: {
1316
+ promptTokens: totalPromptTokens,
1317
+ completionTokens: totalCompletionTokens,
1318
+ totalTokens: totalPromptTokens + totalCompletionTokens
1319
+ }
1320
+ };
1321
+ }
1322
+ }
1323
+ }
1324
+ };
1325
+ }
1326
+ function mapFinishReason3(reason) {
1327
+ switch (reason) {
1328
+ case "stop":
1329
+ return "stop";
1330
+ case "length":
1331
+ return "length";
1332
+ case "tool_calls":
1333
+ case "function_call":
1334
+ return "tool-calls";
1335
+ case "content_filter":
1336
+ return "content-filter";
1337
+ default:
1338
+ return "unknown";
1339
+ }
1340
+ }
1341
+ function formatMessagesForXAI(messages) {
1342
+ return messages.map((msg) => {
1343
+ switch (msg.role) {
1344
+ case "system":
1345
+ return { role: "system", content: msg.content };
1346
+ case "user":
1347
+ if (typeof msg.content === "string") {
1348
+ return { role: "user", content: msg.content };
1349
+ }
1350
+ return {
1351
+ role: "user",
1352
+ content: msg.content.map((part) => {
1353
+ if (part.type === "text") {
1354
+ return { type: "text", text: part.text };
1355
+ }
1356
+ if (part.type === "image") {
1357
+ const imageData = typeof part.image === "string" ? part.image : Buffer.from(part.image).toString("base64");
1358
+ const url = imageData.startsWith("data:") ? imageData : `data:${part.mimeType ?? "image/png"};base64,${imageData}`;
1359
+ return { type: "image_url", image_url: { url, detail: "auto" } };
1360
+ }
1361
+ return { type: "text", text: "" };
1362
+ })
1363
+ };
1364
+ case "assistant":
1365
+ const assistantMsg = {
1366
+ role: "assistant",
1367
+ content: msg.content
1368
+ };
1369
+ if (msg.toolCalls && msg.toolCalls.length > 0) {
1370
+ assistantMsg.tool_calls = msg.toolCalls.map((tc) => ({
1371
+ id: tc.id,
1372
+ type: "function",
1373
+ function: {
1374
+ name: tc.name,
1375
+ arguments: JSON.stringify(tc.args)
1376
+ }
1377
+ }));
1378
+ }
1379
+ return assistantMsg;
1380
+ case "tool":
1381
+ return {
1382
+ role: "tool",
1383
+ tool_call_id: msg.toolCallId,
1384
+ content: msg.content
1385
+ };
1386
+ default:
1387
+ return msg;
1388
+ }
1389
+ });
1390
+ }
1391
+
1392
+ // src/providers/google/provider.ts
1393
+ var GOOGLE_MODELS = {
1394
+ // Gemini 2.0
1395
+ "gemini-2.0-flash": {
1396
+ vision: true,
1397
+ tools: true,
1398
+ audio: true,
1399
+ video: true,
1400
+ maxTokens: 1048576
1401
+ },
1402
+ "gemini-2.0-flash-exp": {
1403
+ vision: true,
1404
+ tools: true,
1405
+ audio: true,
1406
+ video: true,
1407
+ maxTokens: 1048576
1408
+ },
1409
+ "gemini-2.0-flash-thinking-exp": {
1410
+ vision: true,
1411
+ tools: false,
1412
+ audio: false,
1413
+ video: false,
1414
+ maxTokens: 32767
1415
+ },
1416
+ // Gemini 1.5
1417
+ "gemini-1.5-pro": {
1418
+ vision: true,
1419
+ tools: true,
1420
+ audio: true,
1421
+ video: true,
1422
+ maxTokens: 2097152
1423
+ },
1424
+ "gemini-1.5-pro-latest": {
1425
+ vision: true,
1426
+ tools: true,
1427
+ audio: true,
1428
+ video: true,
1429
+ maxTokens: 2097152
1430
+ },
1431
+ "gemini-1.5-flash": {
1432
+ vision: true,
1433
+ tools: true,
1434
+ audio: true,
1435
+ video: true,
1436
+ maxTokens: 1048576
1437
+ },
1438
+ "gemini-1.5-flash-latest": {
1439
+ vision: true,
1440
+ tools: true,
1441
+ audio: true,
1442
+ video: true,
1443
+ maxTokens: 1048576
1444
+ },
1445
+ "gemini-1.5-flash-8b": {
1446
+ vision: true,
1447
+ tools: true,
1448
+ audio: false,
1449
+ video: false,
1450
+ maxTokens: 1048576
1451
+ }
1452
+ };
1453
+ function google(modelId, options = {}) {
1454
+ const apiKey = options.apiKey ?? process.env.GOOGLE_API_KEY ?? process.env.GEMINI_API_KEY;
1455
+ let client = null;
1456
+ async function getClient() {
1457
+ if (!client) {
1458
+ const { GoogleGenerativeAI } = await import('@google/generative-ai');
1459
+ client = new GoogleGenerativeAI(apiKey);
1460
+ }
1461
+ return client;
1462
+ }
1463
+ const modelConfig = GOOGLE_MODELS[modelId] ?? GOOGLE_MODELS["gemini-2.0-flash"];
1464
+ return {
1465
+ provider: "google",
1466
+ modelId,
1467
+ capabilities: {
1468
+ supportsVision: modelConfig.vision,
1469
+ supportsTools: modelConfig.tools,
1470
+ supportsStreaming: true,
1471
+ supportsJsonMode: true,
1472
+ supportsThinking: modelId.includes("thinking"),
1473
+ supportsPDF: true,
1474
+ maxTokens: modelConfig.maxTokens,
1475
+ supportedImageTypes: modelConfig.vision ? ["image/png", "image/jpeg", "image/gif", "image/webp"] : []
1476
+ },
1477
+ async doGenerate(params) {
1478
+ const client2 = await getClient();
1479
+ const model = client2.getGenerativeModel({
1480
+ model: modelId,
1481
+ safetySettings: options.safetySettings
1482
+ });
1483
+ const { systemInstruction, contents } = formatMessagesForGemini(
1484
+ params.messages
1485
+ );
1486
+ const chat = model.startChat({
1487
+ history: contents.slice(0, -1),
1488
+ systemInstruction: systemInstruction ? { parts: [{ text: systemInstruction }] } : void 0,
1489
+ tools: params.tools ? [{ functionDeclarations: formatToolsForGemini(params.tools) }] : void 0,
1490
+ generationConfig: {
1491
+ temperature: params.temperature,
1492
+ maxOutputTokens: params.maxTokens
1493
+ }
1494
+ });
1495
+ const lastMessage = contents[contents.length - 1];
1496
+ const result = await chat.sendMessage(lastMessage.parts);
1497
+ const response = result.response;
1498
+ let text = "";
1499
+ const toolCalls = [];
1500
+ let toolCallIndex = 0;
1501
+ const candidate = response.candidates?.[0];
1502
+ if (candidate?.content?.parts) {
1503
+ for (const part of candidate.content.parts) {
1504
+ if ("text" in part && part.text) {
1505
+ text += part.text;
1506
+ }
1507
+ if ("functionCall" in part && part.functionCall) {
1508
+ toolCalls.push({
1509
+ id: `call_${toolCallIndex++}`,
1510
+ name: part.functionCall.name,
1511
+ args: part.functionCall.args || {}
1512
+ });
1513
+ }
1514
+ }
1515
+ }
1516
+ return {
1517
+ text,
1518
+ toolCalls,
1519
+ finishReason: mapFinishReason4(candidate?.finishReason),
1520
+ usage: {
1521
+ promptTokens: response.usageMetadata?.promptTokenCount ?? 0,
1522
+ completionTokens: response.usageMetadata?.candidatesTokenCount ?? 0,
1523
+ totalTokens: response.usageMetadata?.totalTokenCount ?? 0
1524
+ },
1525
+ rawResponse: response
1526
+ };
1527
+ },
1528
+ async *doStream(params) {
1529
+ const client2 = await getClient();
1530
+ const model = client2.getGenerativeModel({
1531
+ model: modelId,
1532
+ safetySettings: options.safetySettings
1533
+ });
1534
+ const { systemInstruction, contents } = formatMessagesForGemini(
1535
+ params.messages
1536
+ );
1537
+ const chat = model.startChat({
1538
+ history: contents.slice(0, -1),
1539
+ systemInstruction: systemInstruction ? { parts: [{ text: systemInstruction }] } : void 0,
1540
+ tools: params.tools ? [{ functionDeclarations: formatToolsForGemini(params.tools) }] : void 0,
1541
+ generationConfig: {
1542
+ temperature: params.temperature,
1543
+ maxOutputTokens: params.maxTokens
1544
+ }
1545
+ });
1546
+ const lastMessage = contents[contents.length - 1];
1547
+ const result = await chat.sendMessageStream(lastMessage.parts);
1548
+ let toolCallIndex = 0;
1549
+ let promptTokens = 0;
1550
+ let completionTokens = 0;
1551
+ try {
1552
+ for await (const chunk of result.stream) {
1553
+ if (params.signal?.aborted) {
1554
+ yield { type: "error", error: new Error("Aborted") };
1555
+ return;
1556
+ }
1557
+ const candidate = chunk.candidates?.[0];
1558
+ if (!candidate?.content?.parts) continue;
1559
+ for (const part of candidate.content.parts) {
1560
+ if ("text" in part && part.text) {
1561
+ yield { type: "text-delta", text: part.text };
1562
+ }
1563
+ if ("functionCall" in part && part.functionCall) {
1564
+ yield {
1565
+ type: "tool-call",
1566
+ toolCall: {
1567
+ id: `call_${toolCallIndex++}`,
1568
+ name: part.functionCall.name,
1569
+ args: part.functionCall.args || {}
1570
+ }
1571
+ };
1572
+ }
1573
+ }
1574
+ if (chunk.usageMetadata) {
1575
+ promptTokens = chunk.usageMetadata.promptTokenCount ?? 0;
1576
+ completionTokens = chunk.usageMetadata.candidatesTokenCount ?? 0;
1577
+ }
1578
+ if (candidate.finishReason) {
1579
+ yield {
1580
+ type: "finish",
1581
+ finishReason: mapFinishReason4(candidate.finishReason),
1582
+ usage: {
1583
+ promptTokens,
1584
+ completionTokens,
1585
+ totalTokens: promptTokens + completionTokens
1586
+ }
1587
+ };
1588
+ }
1589
+ }
1590
+ } catch (error) {
1591
+ yield {
1592
+ type: "error",
1593
+ error: error instanceof Error ? error : new Error(String(error))
1594
+ };
1595
+ }
1596
+ }
1597
+ };
1598
+ }
1599
+ function mapFinishReason4(reason) {
1600
+ switch (reason) {
1601
+ case "STOP":
1602
+ return "stop";
1603
+ case "MAX_TOKENS":
1604
+ return "length";
1605
+ case "SAFETY":
1606
+ return "content-filter";
1607
+ default:
1608
+ return "unknown";
1609
+ }
1610
+ }
1611
+ function formatMessagesForGemini(messages) {
1612
+ let systemInstruction = "";
1613
+ const contents = [];
1614
+ for (const msg of messages) {
1615
+ if (msg.role === "system") {
1616
+ systemInstruction += (systemInstruction ? "\n" : "") + msg.content;
1617
+ continue;
1618
+ }
1619
+ const parts = [];
1620
+ if (msg.role === "user") {
1621
+ if (typeof msg.content === "string") {
1622
+ parts.push({ text: msg.content });
1623
+ } else {
1624
+ for (const part of msg.content) {
1625
+ if (part.type === "text") {
1626
+ parts.push({ text: part.text });
1627
+ } else if (part.type === "image") {
1628
+ const imageData = typeof part.image === "string" ? part.image : Buffer.from(part.image).toString("base64");
1629
+ const base64 = imageData.startsWith("data:") ? imageData.split(",")[1] : imageData;
1630
+ parts.push({
1631
+ inlineData: {
1632
+ mimeType: part.mimeType ?? "image/png",
1633
+ data: base64
1634
+ }
1635
+ });
1636
+ }
1637
+ }
1638
+ }
1639
+ contents.push({ role: "user", parts });
1640
+ } else if (msg.role === "assistant") {
1641
+ if (msg.content) {
1642
+ parts.push({ text: msg.content });
1643
+ }
1644
+ if (msg.toolCalls?.length) {
1645
+ for (const tc of msg.toolCalls) {
1646
+ parts.push({
1647
+ functionCall: {
1648
+ name: tc.name,
1649
+ args: tc.args
1650
+ }
1651
+ });
1652
+ }
1653
+ }
1654
+ if (parts.length > 0) {
1655
+ contents.push({ role: "model", parts });
1656
+ }
1657
+ } else if (msg.role === "tool") {
1658
+ contents.push({
1659
+ role: "user",
1660
+ parts: [
1661
+ {
1662
+ functionResponse: {
1663
+ name: "tool",
1664
+ // Gemini doesn't track by ID
1665
+ response: JSON.parse(msg.content || "{}")
1666
+ }
1667
+ }
1668
+ ]
1669
+ });
1670
+ }
1671
+ }
1672
+ if (contents.length === 0 || contents[0].role !== "user") {
1673
+ contents.unshift({ role: "user", parts: [{ text: "" }] });
1674
+ }
1675
+ const merged = [];
1676
+ for (const content of contents) {
1677
+ const last = merged[merged.length - 1];
1678
+ if (last && last.role === content.role) {
1679
+ last.parts.push(...content.parts);
1680
+ } else {
1681
+ merged.push({ ...content, parts: [...content.parts] });
1682
+ }
1683
+ }
1684
+ return { systemInstruction, contents: merged };
1685
+ }
1686
+ function formatToolsForGemini(tools) {
1687
+ return tools.map((t) => ({
1688
+ name: t.function.name,
1689
+ description: t.function.description,
1690
+ parameters: t.function.parameters
1691
+ }));
1692
+ }
6
1693
 
7
1694
  // src/adapters/base.ts
8
1695
  function formatMessages(messages, systemPrompt) {
@@ -195,7 +1882,7 @@ function messageToOpenAIContent(message) {
195
1882
  }
196
1883
  return blocks;
197
1884
  }
198
- function formatMessagesForAnthropic(messages, systemPrompt) {
1885
+ function formatMessagesForAnthropic2(messages, systemPrompt) {
199
1886
  const formatted = [];
200
1887
  for (let i = 0; i < messages.length; i++) {
201
1888
  const msg = messages[i];
@@ -254,7 +1941,7 @@ function formatMessagesForAnthropic(messages, systemPrompt) {
254
1941
  messages: formatted
255
1942
  };
256
1943
  }
257
- function formatMessagesForOpenAI(messages, systemPrompt) {
1944
+ function formatMessagesForOpenAI2(messages, systemPrompt) {
258
1945
  const formatted = [];
259
1946
  if (systemPrompt) {
260
1947
  formatted.push({ role: "system", content: systemPrompt });
@@ -347,7 +2034,7 @@ var OpenAIAdapter = class {
347
2034
  messages = processedMessages;
348
2035
  }
349
2036
  } else {
350
- messages = formatMessagesForOpenAI(
2037
+ messages = formatMessagesForOpenAI2(
351
2038
  request.messages,
352
2039
  request.systemPrompt
353
2040
  );
@@ -595,7 +2282,7 @@ var AnthropicAdapter = class {
595
2282
  if (request.rawMessages && request.rawMessages.length > 0) {
596
2283
  messages = this.convertToAnthropicMessages(request.rawMessages);
597
2284
  } else {
598
- const formatted = formatMessagesForAnthropic(request.messages);
2285
+ const formatted = formatMessagesForAnthropic2(request.messages);
599
2286
  messages = formatted.messages;
600
2287
  }
601
2288
  const tools = request.actions?.map((action) => ({
@@ -741,117 +2428,6 @@ var AnthropicAdapter = class {
741
2428
  function createAnthropicAdapter(config) {
742
2429
  return new AnthropicAdapter(config);
743
2430
  }
744
- var GroqAdapter = class {
745
- constructor(config) {
746
- this.provider = "groq";
747
- this.config = config;
748
- this.model = config.model || "llama-3.1-70b-versatile";
749
- }
750
- async *stream(request) {
751
- const messages = formatMessages(request.messages, request.systemPrompt);
752
- const tools = request.actions?.length ? formatTools(request.actions) : void 0;
753
- const messageId = generateMessageId();
754
- yield { type: "message:start", id: messageId };
755
- try {
756
- const response = await fetch(
757
- "https://api.groq.com/openai/v1/chat/completions",
758
- {
759
- method: "POST",
760
- headers: {
761
- "Content-Type": "application/json",
762
- Authorization: `Bearer ${this.config.apiKey}`
763
- },
764
- body: JSON.stringify({
765
- model: request.config?.model || this.model,
766
- messages,
767
- tools,
768
- temperature: request.config?.temperature ?? this.config.temperature,
769
- max_tokens: request.config?.maxTokens ?? this.config.maxTokens,
770
- stream: true
771
- }),
772
- signal: request.signal
773
- }
774
- );
775
- if (!response.ok) {
776
- throw new Error(`Groq API error: ${response.status}`);
777
- }
778
- if (!response.body) {
779
- throw new Error("No response body");
780
- }
781
- const reader = response.body.getReader();
782
- const decoder = new TextDecoder();
783
- let buffer = "";
784
- let currentToolCall = null;
785
- while (true) {
786
- const { done, value } = await reader.read();
787
- if (done) break;
788
- buffer += decoder.decode(value, { stream: true });
789
- const lines = buffer.split("\n");
790
- buffer = lines.pop() || "";
791
- for (const line of lines) {
792
- if (!line.startsWith("data: ")) continue;
793
- const data = line.slice(6).trim();
794
- if (data === "[DONE]") continue;
795
- try {
796
- const chunk = JSON.parse(data);
797
- const delta = chunk.choices?.[0]?.delta;
798
- if (delta?.content) {
799
- yield { type: "message:delta", content: delta.content };
800
- }
801
- if (delta?.tool_calls) {
802
- for (const toolCall of delta.tool_calls) {
803
- if (toolCall.id) {
804
- if (currentToolCall) {
805
- yield {
806
- type: "action:args",
807
- id: currentToolCall.id,
808
- args: currentToolCall.arguments
809
- };
810
- }
811
- currentToolCall = {
812
- id: toolCall.id,
813
- name: toolCall.function?.name || "",
814
- arguments: toolCall.function?.arguments || ""
815
- };
816
- yield {
817
- type: "action:start",
818
- id: currentToolCall.id,
819
- name: currentToolCall.name
820
- };
821
- } else if (currentToolCall && toolCall.function?.arguments) {
822
- currentToolCall.arguments += toolCall.function.arguments;
823
- }
824
- }
825
- }
826
- if (chunk.choices?.[0]?.finish_reason && currentToolCall) {
827
- yield {
828
- type: "action:args",
829
- id: currentToolCall.id,
830
- args: currentToolCall.arguments
831
- };
832
- }
833
- } catch {
834
- }
835
- }
836
- }
837
- yield { type: "message:end" };
838
- yield { type: "done" };
839
- } catch (error) {
840
- if (error.name === "AbortError") {
841
- yield { type: "done" };
842
- } else {
843
- yield {
844
- type: "error",
845
- message: error instanceof Error ? error.message : "Unknown error",
846
- code: "GROQ_ERROR"
847
- };
848
- }
849
- }
850
- }
851
- };
852
- function createGroqAdapter(config) {
853
- return new GroqAdapter(config);
854
- }
855
2431
  var OllamaAdapter = class {
856
2432
  constructor(config = {}) {
857
2433
  this.provider = "ollama";
@@ -1018,7 +2594,7 @@ function messageToGeminiContent(msg) {
1018
2594
  parts
1019
2595
  };
1020
2596
  }
1021
- function formatToolsForGemini(actions) {
2597
+ function formatToolsForGemini2(actions) {
1022
2598
  if (!actions || actions.length === 0) return void 0;
1023
2599
  return {
1024
2600
  functionDeclarations: actions.map((action) => ({
@@ -1104,7 +2680,7 @@ var GoogleAdapter = class {
1104
2680
  mergedContents.push({ ...content, parts: [...content.parts] });
1105
2681
  }
1106
2682
  }
1107
- const tools = formatToolsForGemini(request.actions);
2683
+ const tools = formatToolsForGemini2(request.actions);
1108
2684
  const messageId = generateMessageId();
1109
2685
  yield { type: "message:start", id: messageId };
1110
2686
  try {
@@ -1210,7 +2786,7 @@ var GoogleAdapter = class {
1210
2786
  mergedContents.push({ ...content, parts: [...content.parts] });
1211
2787
  }
1212
2788
  }
1213
- const tools = formatToolsForGemini(request.actions);
2789
+ const tools = formatToolsForGemini2(request.actions);
1214
2790
  const chat = model.startChat({
1215
2791
  history: mergedContents.slice(0, -1),
1216
2792
  systemInstruction: systemInstruction ? { parts: [{ text: systemInstruction }] } : void 0,
@@ -1308,7 +2884,7 @@ var XAIAdapter = class {
1308
2884
  messages = processedMessages;
1309
2885
  }
1310
2886
  } else {
1311
- messages = formatMessagesForOpenAI(
2887
+ messages = formatMessagesForOpenAI2(
1312
2888
  request.messages,
1313
2889
  request.systemPrompt
1314
2890
  );
@@ -1397,7 +2973,7 @@ var XAIAdapter = class {
1397
2973
  }
1398
2974
  }
1399
2975
  } else {
1400
- messages = formatMessagesForOpenAI(
2976
+ messages = formatMessagesForOpenAI2(
1401
2977
  request.messages,
1402
2978
  request.systemPrompt
1403
2979
  );
@@ -1494,7 +3070,7 @@ var AzureAdapter = class {
1494
3070
  messages = processedMessages;
1495
3071
  }
1496
3072
  } else {
1497
- messages = formatMessagesForOpenAI(
3073
+ messages = formatMessagesForOpenAI2(
1498
3074
  request.messages,
1499
3075
  request.systemPrompt
1500
3076
  );
@@ -1584,7 +3160,7 @@ var AzureAdapter = class {
1584
3160
  }
1585
3161
  }
1586
3162
  } else {
1587
- messages = formatMessagesForOpenAI(
3163
+ messages = formatMessagesForOpenAI2(
1588
3164
  request.messages,
1589
3165
  request.systemPrompt
1590
3166
  );
@@ -1658,23 +3234,23 @@ function createSSEResponse(generator) {
1658
3234
  }
1659
3235
 
1660
3236
  // src/server/runtime.ts
1661
- function buildToolResultForAI(tool, result, args) {
3237
+ function buildToolResultForAI(tool2, result, args) {
1662
3238
  const typedResult = result;
1663
- const responseMode = typedResult?._aiResponseMode ?? tool?.aiResponseMode ?? "full";
3239
+ const responseMode = typedResult?._aiResponseMode ?? tool2?.aiResponseMode ?? "full";
1664
3240
  if (typedResult?._aiContent && typedResult._aiContent.length > 0) {
1665
3241
  return typedResult._aiContent;
1666
3242
  }
1667
3243
  let aiContext;
1668
3244
  if (typedResult?._aiContext) {
1669
3245
  aiContext = typedResult._aiContext;
1670
- } else if (tool?.aiContext) {
1671
- aiContext = typeof tool.aiContext === "function" ? tool.aiContext(typedResult, args) : tool.aiContext;
3246
+ } else if (tool2?.aiContext) {
3247
+ aiContext = typeof tool2.aiContext === "function" ? tool2.aiContext(typedResult, args) : tool2.aiContext;
1672
3248
  }
1673
3249
  switch (responseMode) {
1674
3250
  case "none":
1675
3251
  return aiContext ?? "[Result displayed to user]";
1676
3252
  case "brief":
1677
- return aiContext ?? `[Tool ${tool?.name ?? "unknown"} executed successfully]`;
3253
+ return aiContext ?? `[Tool ${tool2?.name ?? "unknown"} executed successfully]`;
1678
3254
  case "full":
1679
3255
  default:
1680
3256
  const fullData = JSON.stringify(result);
@@ -1743,8 +3319,8 @@ var Runtime = class {
1743
3319
  }
1744
3320
  }
1745
3321
  if (config.tools) {
1746
- for (const tool of config.tools) {
1747
- this.tools.set(tool.name, tool);
3322
+ for (const tool2 of config.tools) {
3323
+ this.tools.set(tool2.name, tool2);
1748
3324
  }
1749
3325
  }
1750
3326
  }
@@ -1774,13 +3350,6 @@ var Runtime = class {
1774
3350
  temperature: llm.temperature,
1775
3351
  maxTokens: llm.maxTokens
1776
3352
  });
1777
- case "groq":
1778
- return createGroqAdapter({
1779
- apiKey: llm.apiKey,
1780
- model: llm.model,
1781
- temperature: llm.temperature,
1782
- maxTokens: llm.maxTokens
1783
- });
1784
3353
  case "ollama":
1785
3354
  return createOllamaAdapter({
1786
3355
  model: llm.model,
@@ -1861,8 +3430,28 @@ var Runtime = class {
1861
3430
  }
1862
3431
  /**
1863
3432
  * Handle HTTP request (for use with any framework)
3433
+ *
3434
+ * @param request - The HTTP request
3435
+ * @param options - Optional configuration including onFinish callback for persistence
3436
+ *
3437
+ * @example
3438
+ * ```typescript
3439
+ * // Basic usage
3440
+ * return runtime.handleRequest(request);
3441
+ *
3442
+ * // With server-side persistence
3443
+ * return runtime.handleRequest(request, {
3444
+ * onFinish: async ({ messages, threadId }) => {
3445
+ * await db.thread.upsert({
3446
+ * where: { id: threadId },
3447
+ * update: { messages, updatedAt: new Date() },
3448
+ * create: { id: threadId, messages },
3449
+ * });
3450
+ * },
3451
+ * });
3452
+ * ```
1864
3453
  */
1865
- async handleRequest(request) {
3454
+ async handleRequest(request, options) {
1866
3455
  try {
1867
3456
  const body = await request.json();
1868
3457
  if (this.config.debug) {
@@ -1876,11 +3465,17 @@ var Runtime = class {
1876
3465
  body,
1877
3466
  signal,
1878
3467
  useAgentLoop || false,
1879
- request
3468
+ request,
3469
+ options
1880
3470
  );
1881
3471
  }
1882
3472
  const generator = useAgentLoop ? this.processChatWithLoop(body, signal, void 0, void 0, request) : this.processChat(body, signal);
1883
- return createSSEResponse(generator);
3473
+ const wrappedGenerator = this.wrapGeneratorWithOnFinish(
3474
+ generator,
3475
+ body.threadId,
3476
+ options
3477
+ );
3478
+ return createSSEResponse(wrappedGenerator);
1884
3479
  } catch (error) {
1885
3480
  console.error("[Copilot SDK] Error:", error);
1886
3481
  return new Response(
@@ -1894,10 +3489,34 @@ var Runtime = class {
1894
3489
  );
1895
3490
  }
1896
3491
  }
3492
+ /**
3493
+ * Wrap a generator to intercept the done event and call onFinish
3494
+ */
3495
+ async *wrapGeneratorWithOnFinish(generator, threadId, options) {
3496
+ let doneMessages;
3497
+ for await (const event of generator) {
3498
+ if (event.type === "done" && event.messages) {
3499
+ doneMessages = event.messages;
3500
+ }
3501
+ yield event;
3502
+ }
3503
+ if (options?.onFinish && doneMessages) {
3504
+ try {
3505
+ const result = {
3506
+ messages: doneMessages,
3507
+ threadId
3508
+ // TODO: Add usage tracking when available from adapter
3509
+ };
3510
+ await options.onFinish(result);
3511
+ } catch (error) {
3512
+ console.error("[Copilot SDK] onFinish callback error:", error);
3513
+ }
3514
+ }
3515
+ }
1897
3516
  /**
1898
3517
  * Handle non-streaming request - returns JSON instead of SSE
1899
3518
  */
1900
- async handleNonStreamingRequest(body, signal, useAgentLoop, httpRequest) {
3519
+ async handleNonStreamingRequest(body, signal, useAgentLoop, httpRequest, options) {
1901
3520
  try {
1902
3521
  const generator = useAgentLoop ? this.processChatWithLoop(
1903
3522
  body,
@@ -1949,6 +3568,20 @@ var Runtime = class {
1949
3568
  break;
1950
3569
  }
1951
3570
  }
3571
+ if (options?.onFinish && messages && !error) {
3572
+ try {
3573
+ const result = {
3574
+ messages,
3575
+ threadId: body.threadId
3576
+ };
3577
+ await options.onFinish(result);
3578
+ } catch (callbackError) {
3579
+ console.error(
3580
+ "[Copilot SDK] onFinish callback error:",
3581
+ callbackError
3582
+ );
3583
+ }
3584
+ }
1952
3585
  const response = {
1953
3586
  success: !error,
1954
3587
  content,
@@ -2012,8 +3645,8 @@ var Runtime = class {
2012
3645
  /**
2013
3646
  * Register a new tool
2014
3647
  */
2015
- registerTool(tool) {
2016
- this.tools.set(tool.name, tool);
3648
+ registerTool(tool2) {
3649
+ this.tools.set(tool2.name, tool2);
2017
3650
  }
2018
3651
  /**
2019
3652
  * Unregister a tool
@@ -2092,12 +3725,12 @@ var Runtime = class {
2092
3725
  this.config.agentLoop?.maxIterations || 20;
2093
3726
  const allTools = [...this.tools.values()];
2094
3727
  if (request.tools) {
2095
- for (const tool of request.tools) {
3728
+ for (const tool2 of request.tools) {
2096
3729
  allTools.push({
2097
- name: tool.name,
2098
- description: tool.description,
3730
+ name: tool2.name,
3731
+ description: tool2.description,
2099
3732
  location: "client",
2100
- inputSchema: tool.inputSchema
3733
+ inputSchema: tool2.inputSchema
2101
3734
  });
2102
3735
  }
2103
3736
  }
@@ -2202,8 +3835,8 @@ var Runtime = class {
2202
3835
  const serverToolCalls = [];
2203
3836
  const clientToolCalls = [];
2204
3837
  for (const tc of toolCalls) {
2205
- const tool = allTools.find((t) => t.name === tc.name);
2206
- if (tool?.location === "server" && tool.handler) {
3838
+ const tool2 = allTools.find((t) => t.name === tc.name);
3839
+ if (tool2?.location === "server" && tool2.handler) {
2207
3840
  serverToolCalls.push(tc);
2208
3841
  } else {
2209
3842
  clientToolCalls.push(tc);
@@ -2212,8 +3845,8 @@ var Runtime = class {
2212
3845
  const serverToolResults = [];
2213
3846
  const toolContextData = "toolContext" in this.config ? this.config.toolContext : void 0;
2214
3847
  for (const tc of serverToolCalls) {
2215
- const tool = allTools.find((t) => t.name === tc.name);
2216
- if (tool?.handler) {
3848
+ const tool2 = allTools.find((t) => t.name === tc.name);
3849
+ if (tool2?.handler) {
2217
3850
  if (debug) {
2218
3851
  console.log(`[Copilot SDK] Executing server-side tool: ${tc.name}`);
2219
3852
  }
@@ -2225,13 +3858,13 @@ var Runtime = class {
2225
3858
  toolContextData
2226
3859
  );
2227
3860
  try {
2228
- const result = await tool.handler(tc.args, toolContext);
3861
+ const result = await tool2.handler(tc.args, toolContext);
2229
3862
  serverToolResults.push({
2230
3863
  id: tc.id,
2231
3864
  name: tc.name,
2232
3865
  args: tc.args,
2233
3866
  result,
2234
- tool
3867
+ tool: tool2
2235
3868
  });
2236
3869
  yield {
2237
3870
  type: "action:end",
@@ -2248,7 +3881,7 @@ var Runtime = class {
2248
3881
  name: tc.name,
2249
3882
  args: tc.args,
2250
3883
  result: errorResult,
2251
- tool
3884
+ tool: tool2
2252
3885
  });
2253
3886
  yield {
2254
3887
  type: "action:end",
@@ -2367,12 +4000,12 @@ var Runtime = class {
2367
4000
  const maxIterations = this.config.agentLoop?.maxIterations || 20;
2368
4001
  const allTools = [...this.tools.values()];
2369
4002
  if (request.tools) {
2370
- for (const tool of request.tools) {
4003
+ for (const tool2 of request.tools) {
2371
4004
  allTools.push({
2372
- name: tool.name,
2373
- description: tool.description,
4005
+ name: tool2.name,
4006
+ description: tool2.description,
2374
4007
  location: "client",
2375
- inputSchema: tool.inputSchema
4008
+ inputSchema: tool2.inputSchema
2376
4009
  });
2377
4010
  }
2378
4011
  }
@@ -2437,8 +4070,8 @@ var Runtime = class {
2437
4070
  const serverToolCalls = [];
2438
4071
  const clientToolCalls = [];
2439
4072
  for (const tc of result.toolCalls) {
2440
- const tool = allTools.find((t) => t.name === tc.name);
2441
- if (tool?.location === "server" && tool.handler) {
4073
+ const tool2 = allTools.find((t) => t.name === tc.name);
4074
+ if (tool2?.location === "server" && tool2.handler) {
2442
4075
  serverToolCalls.push(tc);
2443
4076
  } else {
2444
4077
  clientToolCalls.push({
@@ -2463,8 +4096,8 @@ var Runtime = class {
2463
4096
  const serverToolResults = [];
2464
4097
  const toolContextData = "toolContext" in this.config ? this.config.toolContext : void 0;
2465
4098
  for (const tc of serverToolCalls) {
2466
- const tool = allTools.find((t) => t.name === tc.name);
2467
- if (tool?.handler) {
4099
+ const tool2 = allTools.find((t) => t.name === tc.name);
4100
+ if (tool2?.handler) {
2468
4101
  if (debug) {
2469
4102
  console.log(`[Copilot SDK] Executing tool: ${tc.name}`);
2470
4103
  }
@@ -2476,13 +4109,13 @@ var Runtime = class {
2476
4109
  toolContextData
2477
4110
  );
2478
4111
  try {
2479
- const toolResult = await tool.handler(tc.args, toolContext);
4112
+ const toolResult = await tool2.handler(tc.args, toolContext);
2480
4113
  serverToolResults.push({
2481
4114
  id: tc.id,
2482
4115
  name: tc.name,
2483
4116
  args: tc.args,
2484
4117
  result: toolResult,
2485
- tool
4118
+ tool: tool2
2486
4119
  });
2487
4120
  yield {
2488
4121
  type: "action:end",
@@ -2499,7 +4132,7 @@ var Runtime = class {
2499
4132
  name: tc.name,
2500
4133
  args: tc.args,
2501
4134
  result: errorResult,
2502
- tool
4135
+ tool: tool2
2503
4136
  });
2504
4137
  yield {
2505
4138
  type: "action:end",
@@ -2606,11 +4239,11 @@ var Runtime = class {
2606
4239
  * Convert tools to legacy action format (for adapter compatibility)
2607
4240
  */
2608
4241
  convertToolsToActions(tools) {
2609
- return tools.map((tool) => ({
2610
- name: tool.name,
2611
- description: tool.description,
2612
- parameters: this.convertInputSchemaToParameters(tool.inputSchema),
2613
- handler: tool.handler || (async () => ({ handled: false }))
4242
+ return tools.map((tool2) => ({
4243
+ name: tool2.name,
4244
+ description: tool2.description,
4245
+ parameters: this.convertInputSchemaToParameters(tool2.inputSchema),
4246
+ handler: tool2.handler || (async () => ({ handled: false }))
2614
4247
  }));
2615
4248
  }
2616
4249
  /**
@@ -2832,7 +4465,7 @@ function getModelCapabilities(providerName, modelId) {
2832
4465
  }
2833
4466
 
2834
4467
  // src/providers/openai/index.ts
2835
- var OPENAI_MODELS = {
4468
+ var OPENAI_MODELS2 = {
2836
4469
  // GPT-4o series
2837
4470
  "gpt-4o": {
2838
4471
  vision: true,
@@ -2943,7 +4576,7 @@ function createOpenAI(config = {}) {
2943
4576
  const apiKey = config.apiKey ?? process.env.OPENAI_API_KEY ?? "";
2944
4577
  return {
2945
4578
  name: "openai",
2946
- supportedModels: Object.keys(OPENAI_MODELS),
4579
+ supportedModels: Object.keys(OPENAI_MODELS2),
2947
4580
  languageModel(modelId) {
2948
4581
  return createOpenAIAdapter({
2949
4582
  apiKey,
@@ -2952,7 +4585,7 @@ function createOpenAI(config = {}) {
2952
4585
  });
2953
4586
  },
2954
4587
  getCapabilities(modelId) {
2955
- const model = OPENAI_MODELS[modelId] ?? OPENAI_MODELS["gpt-4o"];
4588
+ const model = OPENAI_MODELS2[modelId] ?? OPENAI_MODELS2["gpt-4o"];
2956
4589
  return {
2957
4590
  supportsVision: model.vision,
2958
4591
  supportsTools: model.tools,
@@ -2974,7 +4607,7 @@ function createOpenAI(config = {}) {
2974
4607
  }
2975
4608
 
2976
4609
  // src/providers/anthropic/index.ts
2977
- var ANTHROPIC_MODELS = {
4610
+ var ANTHROPIC_MODELS2 = {
2978
4611
  // Claude 4 series (latest)
2979
4612
  "claude-sonnet-4-20250514": {
2980
4613
  vision: true,
@@ -3043,7 +4676,7 @@ function createAnthropic(config = {}) {
3043
4676
  const apiKey = config.apiKey ?? process.env.ANTHROPIC_API_KEY ?? "";
3044
4677
  return {
3045
4678
  name: "anthropic",
3046
- supportedModels: Object.keys(ANTHROPIC_MODELS),
4679
+ supportedModels: Object.keys(ANTHROPIC_MODELS2),
3047
4680
  languageModel(modelId) {
3048
4681
  return createAnthropicAdapter({
3049
4682
  apiKey,
@@ -3053,7 +4686,7 @@ function createAnthropic(config = {}) {
3053
4686
  });
3054
4687
  },
3055
4688
  getCapabilities(modelId) {
3056
- const model = ANTHROPIC_MODELS[modelId] ?? ANTHROPIC_MODELS["claude-3-5-sonnet-latest"];
4689
+ const model = ANTHROPIC_MODELS2[modelId] ?? ANTHROPIC_MODELS2["claude-3-5-sonnet-latest"];
3057
4690
  return {
3058
4691
  supportsVision: model.vision,
3059
4692
  supportsTools: model.tools,
@@ -3078,90 +4711,6 @@ function createAnthropic(config = {}) {
3078
4711
  };
3079
4712
  }
3080
4713
 
3081
- // src/providers/groq/index.ts
3082
- var GROQ_MODELS = {
3083
- // Llama 3.3 series
3084
- "llama-3.3-70b-versatile": {
3085
- vision: false,
3086
- tools: true,
3087
- maxTokens: 32768
3088
- },
3089
- "llama-3.3-70b-specdec": {
3090
- vision: false,
3091
- tools: true,
3092
- maxTokens: 8192
3093
- },
3094
- // Llama 3.2 Vision series
3095
- "llama-3.2-90b-vision-preview": {
3096
- vision: true,
3097
- tools: true,
3098
- maxTokens: 8192
3099
- },
3100
- "llama-3.2-11b-vision-preview": {
3101
- vision: true,
3102
- tools: true,
3103
- maxTokens: 8192
3104
- },
3105
- // Llama 3.1 series
3106
- "llama-3.1-70b-versatile": {
3107
- vision: false,
3108
- tools: true,
3109
- maxTokens: 32768
3110
- },
3111
- "llama-3.1-8b-instant": {
3112
- vision: false,
3113
- tools: true,
3114
- maxTokens: 8192
3115
- },
3116
- // Mixtral series
3117
- "mixtral-8x7b-32768": {
3118
- vision: false,
3119
- tools: true,
3120
- maxTokens: 32768
3121
- },
3122
- // Gemma series
3123
- "gemma2-9b-it": {
3124
- vision: false,
3125
- tools: false,
3126
- maxTokens: 8192
3127
- },
3128
- // DeepSeek
3129
- "deepseek-r1-distill-llama-70b": {
3130
- vision: false,
3131
- tools: true,
3132
- maxTokens: 8192
3133
- }
3134
- };
3135
- function createGroq(config = {}) {
3136
- const apiKey = config.apiKey ?? process.env.GROQ_API_KEY ?? "";
3137
- return {
3138
- name: "groq",
3139
- supportedModels: Object.keys(GROQ_MODELS),
3140
- languageModel(modelId) {
3141
- return createGroqAdapter({
3142
- apiKey,
3143
- model: modelId
3144
- });
3145
- },
3146
- getCapabilities(modelId) {
3147
- const model = GROQ_MODELS[modelId] ?? GROQ_MODELS["llama-3.3-70b-versatile"];
3148
- return {
3149
- supportsVision: model.vision,
3150
- supportsTools: model.tools,
3151
- supportsThinking: false,
3152
- supportsStreaming: true,
3153
- supportsPDF: false,
3154
- supportsAudio: false,
3155
- supportsVideo: false,
3156
- maxTokens: model.maxTokens,
3157
- supportedImageTypes: model.vision ? ["image/png", "image/jpeg", "image/gif", "image/webp"] : [],
3158
- supportsJsonMode: true,
3159
- supportsSystemMessages: true
3160
- };
3161
- }
3162
- };
3163
- }
3164
-
3165
4714
  // src/providers/ollama/index.ts
3166
4715
  var OLLAMA_MODELS = {
3167
4716
  // Llama series
@@ -3295,7 +4844,7 @@ function createOllama(config = {}) {
3295
4844
  }
3296
4845
 
3297
4846
  // src/providers/google/index.ts
3298
- var GOOGLE_MODELS = {
4847
+ var GOOGLE_MODELS2 = {
3299
4848
  // Gemini 2.0 series (latest)
3300
4849
  "gemini-2.0-flash": {
3301
4850
  vision: true,
@@ -3395,7 +4944,7 @@ function createGoogle(config = {}) {
3395
4944
  const apiKey = config.apiKey ?? process.env.GOOGLE_API_KEY ?? "";
3396
4945
  return {
3397
4946
  name: "google",
3398
- supportedModels: Object.keys(GOOGLE_MODELS),
4947
+ supportedModels: Object.keys(GOOGLE_MODELS2),
3399
4948
  languageModel(modelId) {
3400
4949
  return createGoogleAdapter({
3401
4950
  apiKey,
@@ -3405,7 +4954,7 @@ function createGoogle(config = {}) {
3405
4954
  });
3406
4955
  },
3407
4956
  getCapabilities(modelId) {
3408
- const model = GOOGLE_MODELS[modelId] ?? GOOGLE_MODELS["gemini-2.0-flash"];
4957
+ const model = GOOGLE_MODELS2[modelId] ?? GOOGLE_MODELS2["gemini-2.0-flash"];
3409
4958
  return {
3410
4959
  supportsVision: model.vision,
3411
4960
  supportsTools: model.tools,
@@ -3449,56 +4998,95 @@ function createGoogle(config = {}) {
3449
4998
  }
3450
4999
 
3451
5000
  // src/providers/xai/index.ts
3452
- var XAI_MODELS = {
3453
- // Grok 2 series (latest)
3454
- "grok-2": {
5001
+ var XAI_MODELS2 = {
5002
+ // Grok 4.1 Fast (Latest - December 2025)
5003
+ "grok-4-1-fast-reasoning": {
5004
+ vision: false,
5005
+ tools: true,
5006
+ maxTokens: 2e6,
5007
+ outputTokens: 16384
5008
+ },
5009
+ "grok-4-1-fast-non-reasoning": {
5010
+ vision: false,
5011
+ tools: true,
5012
+ maxTokens: 2e6,
5013
+ outputTokens: 16384
5014
+ },
5015
+ // Grok 4 Fast (September 2025)
5016
+ "grok-4-fast-reasoning": {
5017
+ vision: false,
5018
+ tools: true,
5019
+ maxTokens: 2e6,
5020
+ outputTokens: 16384
5021
+ },
5022
+ "grok-4-fast-non-reasoning": {
5023
+ vision: false,
5024
+ tools: true,
5025
+ maxTokens: 2e6,
5026
+ outputTokens: 16384
5027
+ },
5028
+ // Grok 4 (July 2025)
5029
+ "grok-4": {
3455
5030
  vision: true,
3456
5031
  tools: true,
3457
- maxTokens: 131072,
3458
- outputTokens: 4096
5032
+ maxTokens: 256e3,
5033
+ outputTokens: 16384
3459
5034
  },
3460
- "grok-2-latest": {
5035
+ "grok-4-0709": {
3461
5036
  vision: true,
3462
5037
  tools: true,
3463
- maxTokens: 131072,
3464
- outputTokens: 4096
5038
+ maxTokens: 256e3,
5039
+ outputTokens: 16384
3465
5040
  },
3466
- "grok-2-mini": {
3467
- vision: false,
5041
+ // Grok 3 (February 2025) - Stable
5042
+ "grok-3-beta": {
5043
+ vision: true,
3468
5044
  tools: true,
3469
5045
  maxTokens: 131072,
3470
- outputTokens: 4096
5046
+ outputTokens: 8192
3471
5047
  },
3472
- "grok-2-mini-latest": {
5048
+ "grok-3-fast-beta": {
3473
5049
  vision: false,
3474
5050
  tools: true,
3475
5051
  maxTokens: 131072,
3476
- outputTokens: 4096
5052
+ outputTokens: 8192
3477
5053
  },
3478
- // Grok Vision
3479
- "grok-2-vision": {
3480
- vision: true,
5054
+ "grok-3-mini-beta": {
5055
+ vision: false,
3481
5056
  tools: true,
3482
5057
  maxTokens: 32768,
3483
- outputTokens: 4096
5058
+ outputTokens: 8192
3484
5059
  },
3485
- "grok-2-vision-latest": {
3486
- vision: true,
5060
+ "grok-3-mini-fast-beta": {
5061
+ vision: false,
3487
5062
  tools: true,
3488
5063
  maxTokens: 32768,
3489
- outputTokens: 4096
5064
+ outputTokens: 8192
3490
5065
  },
3491
- // Grok Beta (legacy)
3492
- "grok-beta": {
5066
+ // Grok Code Fast (August 2025)
5067
+ "grok-code-fast-1": {
3493
5068
  vision: false,
3494
5069
  tools: true,
5070
+ maxTokens: 256e3,
5071
+ outputTokens: 16384
5072
+ },
5073
+ // Grok 2 (Legacy - for backward compatibility)
5074
+ "grok-2": {
5075
+ vision: true,
5076
+ tools: true,
3495
5077
  maxTokens: 131072,
3496
5078
  outputTokens: 4096
3497
5079
  },
3498
- "grok-vision-beta": {
5080
+ "grok-2-latest": {
3499
5081
  vision: true,
3500
5082
  tools: true,
3501
- maxTokens: 8192,
5083
+ maxTokens: 131072,
5084
+ outputTokens: 4096
5085
+ },
5086
+ "grok-2-mini": {
5087
+ vision: false,
5088
+ tools: true,
5089
+ maxTokens: 131072,
3502
5090
  outputTokens: 4096
3503
5091
  }
3504
5092
  };
@@ -3506,7 +5094,7 @@ function createXAI(config = {}) {
3506
5094
  const apiKey = config.apiKey ?? process.env.XAI_API_KEY ?? "";
3507
5095
  return {
3508
5096
  name: "xai",
3509
- supportedModels: Object.keys(XAI_MODELS),
5097
+ supportedModels: Object.keys(XAI_MODELS2),
3510
5098
  languageModel(modelId) {
3511
5099
  return createXAIAdapter({
3512
5100
  apiKey,
@@ -3515,7 +5103,7 @@ function createXAI(config = {}) {
3515
5103
  });
3516
5104
  },
3517
5105
  getCapabilities(modelId) {
3518
- const model = XAI_MODELS[modelId] ?? XAI_MODELS["grok-2"];
5106
+ const model = XAI_MODELS2[modelId] ?? XAI_MODELS2["grok-3-fast-beta"];
3519
5107
  return {
3520
5108
  supportsVision: model.vision,
3521
5109
  supportsTools: model.tools,
@@ -3594,12 +5182,12 @@ function createAzure(config) {
3594
5182
 
3595
5183
  // src/providers/openai.ts
3596
5184
  function transformTools(tools) {
3597
- return tools.map((tool) => ({
5185
+ return tools.map((tool2) => ({
3598
5186
  type: "function",
3599
5187
  function: {
3600
- name: tool.name,
3601
- description: tool.description,
3602
- parameters: tool.inputSchema
5188
+ name: tool2.name,
5189
+ description: tool2.description,
5190
+ parameters: tool2.inputSchema
3603
5191
  }
3604
5192
  }));
3605
5193
  }
@@ -3685,10 +5273,10 @@ var openaiFormatter = {
3685
5273
 
3686
5274
  // src/providers/anthropic.ts
3687
5275
  function transformTools2(tools) {
3688
- return tools.map((tool) => ({
3689
- name: tool.name,
3690
- description: tool.description,
3691
- input_schema: tool.inputSchema
5276
+ return tools.map((tool2) => ({
5277
+ name: tool2.name,
5278
+ description: tool2.description,
5279
+ input_schema: tool2.inputSchema
3692
5280
  }));
3693
5281
  }
3694
5282
  function parseToolCalls2(response) {
@@ -3766,10 +5354,10 @@ var anthropicFormatter = {
3766
5354
  function transformTools3(tools) {
3767
5355
  return [
3768
5356
  {
3769
- functionDeclarations: tools.map((tool) => ({
3770
- name: tool.name,
3771
- description: tool.description,
3772
- parameters: tool.inputSchema
5357
+ functionDeclarations: tools.map((tool2) => ({
5358
+ name: tool2.name,
5359
+ description: tool2.description,
5360
+ parameters: tool2.inputSchema
3773
5361
  }))
3774
5362
  }
3775
5363
  ];
@@ -3895,7 +5483,6 @@ var formatters = {
3895
5483
  gemini: geminiFormatter,
3896
5484
  // Alias
3897
5485
  // OpenAI-compatible providers use openaiFormatter
3898
- groq: openaiFormatter,
3899
5486
  ollama: openaiFormatter,
3900
5487
  xai: openaiFormatter,
3901
5488
  azure: openaiFormatter
@@ -3919,7 +5506,6 @@ function getSupportedProviders() {
3919
5506
  // src/providers/index.ts
3920
5507
  registerProvider("openai", (config) => createOpenAI(config));
3921
5508
  registerProvider("anthropic", (config) => createAnthropic(config));
3922
- registerProvider("groq", (config) => createGroq(config));
3923
5509
  registerProvider("ollama", (config) => createOllama(config));
3924
5510
  registerProvider("google", (config) => createGoogle(config));
3925
5511
  registerProvider("xai", (config) => createXAI(config));
@@ -4078,8 +5664,8 @@ function buildConversation(messages, systemPrompt) {
4078
5664
  async function executeToolCalls(toolCalls, tools, executeServerTool, waitForClientToolResult, emitEvent, debug) {
4079
5665
  const results = [];
4080
5666
  for (const toolCall of toolCalls) {
4081
- const tool = tools.find((t) => t.name === toolCall.name);
4082
- if (!tool) {
5667
+ const tool2 = tools.find((t) => t.name === toolCall.name);
5668
+ if (!tool2) {
4083
5669
  if (debug) {
4084
5670
  console.warn(`[AgentLoop] Unknown tool: ${toolCall.name}`);
4085
5671
  }
@@ -4106,9 +5692,9 @@ async function executeToolCalls(toolCalls, tools, executeServerTool, waitForClie
4106
5692
  });
4107
5693
  try {
4108
5694
  let response;
4109
- if (tool.location === "server") {
4110
- if (tool.handler) {
4111
- response = await tool.handler(toolCall.input);
5695
+ if (tool2.location === "server") {
5696
+ if (tool2.handler) {
5697
+ response = await tool2.handler(toolCall.input);
4112
5698
  } else if (executeServerTool) {
4113
5699
  response = await executeServerTool(toolCall.name, toolCall.input);
4114
5700
  } else {
@@ -4165,6 +5751,6 @@ async function executeToolCalls(toolCalls, tools, executeServerTool, waitForClie
4165
5751
  return results;
4166
5752
  }
4167
5753
 
4168
- export { AnthropicAdapter, AzureAdapter, DEFAULT_MAX_ITERATIONS, GoogleAdapter, GroqAdapter, OllamaAdapter, OpenAIAdapter, Runtime, XAIAdapter, anthropicFormatter, createAnthropic, createAnthropicAdapter, createAzure, createAzureAdapter, createEventStream, createExpressMiddleware, createGoogle, createGoogleAdapter, createGroq, createGroqAdapter, createHonoApp, createNextHandler, createNodeHandler, createOllama, createOllamaAdapter, createOpenAI, createOpenAIAdapter, createRuntime, createSSEHeaders, createSSEResponse, createXAI, createXAIAdapter, formatSSEData, geminiFormatter, getAvailableProviders, getFormatter, getModelCapabilities, getProvider, getSupportedProviders, hasProvider, isProviderSupported, listProviders, openaiFormatter, registerProvider, runAgentLoop };
5754
+ export { AnthropicAdapter, AzureAdapter, DEFAULT_CAPABILITIES, DEFAULT_MAX_ITERATIONS, GoogleAdapter, OllamaAdapter, OpenAIAdapter, Runtime, XAIAdapter, anthropic, anthropicFormatter, createAnthropic, createAnthropicAdapter, createAzure, createAzureAdapter, createEventStream, createExpressMiddleware, createGoogle, createGoogleAdapter, createHonoApp, createNextHandler, createNodeHandler, createOllama, createOllamaAdapter, createOpenAI, createOpenAIAdapter, createRuntime, createSSEHeaders, createSSEResponse, createXAI, createXAIAdapter, formatSSEData, formatToolsForAnthropic, formatToolsForGoogle, formatToolsForOpenAI, geminiFormatter, generateText, getAvailableProviders, getFormatter, getModelCapabilities, getProvider, getSupportedProviders, google, hasProvider, isProviderSupported, listProviders, openai, openaiFormatter, registerProvider, runAgentLoop, streamText, tool, xai };
4169
5755
  //# sourceMappingURL=index.mjs.map
4170
5756
  //# sourceMappingURL=index.mjs.map