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