@amux.ai/adapter-google 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,850 @@
1
+ 'use strict';
2
+
3
+ // src/inbound/request-parser.ts
4
+ function isOpenAIFormat(request) {
5
+ const req = request;
6
+ return Array.isArray(req.messages);
7
+ }
8
+ function parseRequest(request) {
9
+ if (isOpenAIFormat(request)) {
10
+ return parseOpenAIRequest(request);
11
+ }
12
+ return parseGeminiRequest(request);
13
+ }
14
+ function parseOpenAIRequest(req) {
15
+ const messages = [];
16
+ for (const msg of req.messages) {
17
+ messages.push({
18
+ role: msg.role,
19
+ content: parseOpenAIContent(msg.content),
20
+ name: msg.name,
21
+ toolCalls: msg.tool_calls,
22
+ toolCallId: msg.tool_call_id
23
+ });
24
+ }
25
+ const tools = req.tools?.map((tool) => ({
26
+ type: "function",
27
+ function: {
28
+ name: tool.function.name,
29
+ description: tool.function.description,
30
+ parameters: tool.function.parameters
31
+ }
32
+ }));
33
+ let toolChoice;
34
+ if (req.tool_choice) {
35
+ if (typeof req.tool_choice === "string") {
36
+ toolChoice = req.tool_choice;
37
+ } else {
38
+ toolChoice = {
39
+ type: "function",
40
+ function: { name: req.tool_choice.function.name }
41
+ };
42
+ }
43
+ }
44
+ return {
45
+ messages,
46
+ model: req.model,
47
+ tools,
48
+ toolChoice,
49
+ stream: req.stream,
50
+ generation: {
51
+ temperature: req.temperature,
52
+ topP: req.top_p,
53
+ maxTokens: req.max_tokens,
54
+ stopSequences: req.stop ? Array.isArray(req.stop) ? req.stop : [req.stop] : void 0
55
+ },
56
+ raw: req
57
+ };
58
+ }
59
+ function parseOpenAIContent(content) {
60
+ if (content === null || content === void 0) {
61
+ return "";
62
+ }
63
+ if (typeof content === "string") {
64
+ return content;
65
+ }
66
+ return content.map((part) => {
67
+ if (part.type === "text") {
68
+ return {
69
+ type: "text",
70
+ text: part.text ?? ""
71
+ };
72
+ }
73
+ if (part.type === "image_url" && part.image_url) {
74
+ const url = part.image_url.url;
75
+ if (url.startsWith("data:")) {
76
+ const match = url.match(/^data:([^;]+);base64,(.+)$/);
77
+ if (match) {
78
+ return {
79
+ type: "image",
80
+ source: {
81
+ type: "base64",
82
+ mediaType: match[1],
83
+ data: match[2]
84
+ }
85
+ };
86
+ }
87
+ }
88
+ return {
89
+ type: "image",
90
+ source: {
91
+ type: "url",
92
+ url
93
+ }
94
+ };
95
+ }
96
+ return {
97
+ type: "text",
98
+ text: JSON.stringify(part)
99
+ };
100
+ });
101
+ }
102
+ function parseGeminiRequest(req) {
103
+ let system;
104
+ if (req.systemInstruction?.parts) {
105
+ system = req.systemInstruction.parts.map((p) => p.text).join("\n");
106
+ }
107
+ const messages = req.contents.flatMap((content) => parseGeminiContent(content));
108
+ const tools = req.tools?.[0]?.functionDeclarations?.map((fn) => ({
109
+ type: "function",
110
+ function: {
111
+ name: fn.name,
112
+ description: fn.description,
113
+ parameters: fn.parameters ? {
114
+ type: fn.parameters.type,
115
+ properties: fn.parameters.properties,
116
+ required: fn.parameters.required
117
+ } : void 0
118
+ }
119
+ }));
120
+ let toolChoice;
121
+ if (req.toolConfig?.functionCallingConfig) {
122
+ const mode = req.toolConfig.functionCallingConfig.mode;
123
+ if (mode === "AUTO") toolChoice = "auto";
124
+ else if (mode === "NONE") toolChoice = "none";
125
+ else if (mode === "ANY") toolChoice = "required";
126
+ }
127
+ return {
128
+ messages,
129
+ tools,
130
+ toolChoice,
131
+ system,
132
+ generation: req.generationConfig ? {
133
+ temperature: req.generationConfig.temperature,
134
+ topP: req.generationConfig.topP,
135
+ topK: req.generationConfig.topK,
136
+ maxTokens: req.generationConfig.maxOutputTokens,
137
+ stopSequences: req.generationConfig.stopSequences,
138
+ responseFormat: req.generationConfig.responseMimeType === "application/json" ? { type: "json_object" } : void 0
139
+ } : void 0,
140
+ raw: req
141
+ };
142
+ }
143
+ function parseGeminiContent(content) {
144
+ const role = content.role === "model" ? "assistant" : "user";
145
+ const parts = [];
146
+ const toolCalls = [];
147
+ const toolResults = [];
148
+ for (const part of content.parts) {
149
+ if ("text" in part) {
150
+ parts.push({
151
+ type: "text",
152
+ text: part.text
153
+ });
154
+ } else if ("inlineData" in part) {
155
+ parts.push({
156
+ type: "image",
157
+ source: {
158
+ type: "base64",
159
+ mediaType: part.inlineData.mimeType,
160
+ data: part.inlineData.data
161
+ }
162
+ });
163
+ } else if ("fileData" in part) {
164
+ parts.push({
165
+ type: "image",
166
+ source: {
167
+ type: "url",
168
+ url: part.fileData.fileUri
169
+ }
170
+ });
171
+ } else if ("functionCall" in part) {
172
+ toolCalls.push({
173
+ id: `call_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
174
+ type: "function",
175
+ function: {
176
+ name: part.functionCall.name,
177
+ arguments: JSON.stringify(part.functionCall.args)
178
+ }
179
+ });
180
+ } else if ("functionResponse" in part) {
181
+ toolResults.push({
182
+ role: "tool",
183
+ content: JSON.stringify(part.functionResponse.response),
184
+ toolCallId: `call_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
185
+ name: part.functionResponse.name
186
+ });
187
+ }
188
+ }
189
+ const messages = [];
190
+ if (parts.length > 0 || toolCalls.length > 0) {
191
+ const allText = parts.every((p) => p.type === "text");
192
+ const messageContent = allText && parts.length === 1 ? parts[0].text : parts.length > 0 ? parts : "";
193
+ const message = {
194
+ role,
195
+ content: messageContent
196
+ };
197
+ if (toolCalls.length > 0) {
198
+ message.toolCalls = toolCalls;
199
+ }
200
+ messages.push(message);
201
+ }
202
+ messages.push(...toolResults);
203
+ return messages;
204
+ }
205
+
206
+ // src/inbound/response-parser.ts
207
+ function mapFinishReason(reason) {
208
+ if (!reason) return "stop";
209
+ const reasonMap = {
210
+ STOP: "stop",
211
+ MAX_TOKENS: "length",
212
+ SAFETY: "content_filter",
213
+ RECITATION: "content_filter",
214
+ OTHER: "stop"
215
+ };
216
+ return reasonMap[reason] ?? "stop";
217
+ }
218
+ function parseResponse(response) {
219
+ const res = response;
220
+ const choices = res.candidates.map((candidate, index) => {
221
+ const { contentParts, toolCalls } = parseParts(candidate.content.parts);
222
+ const allText = contentParts.every((p) => p.type === "text");
223
+ const content = allText && contentParts.length === 1 ? contentParts[0].text : contentParts;
224
+ return {
225
+ index: candidate.index ?? index,
226
+ message: {
227
+ role: "assistant",
228
+ content,
229
+ toolCalls: toolCalls.length > 0 ? toolCalls : void 0
230
+ },
231
+ finishReason: mapFinishReason(candidate.finishReason)
232
+ };
233
+ });
234
+ return {
235
+ id: res.responseId ?? `gemini-${Date.now()}`,
236
+ model: res.modelVersion ?? "gemini",
237
+ choices,
238
+ usage: res.usageMetadata ? {
239
+ promptTokens: res.usageMetadata.promptTokenCount,
240
+ completionTokens: res.usageMetadata.candidatesTokenCount,
241
+ totalTokens: res.usageMetadata.totalTokenCount,
242
+ details: res.usageMetadata.cachedContentTokenCount ? { cachedTokens: res.usageMetadata.cachedContentTokenCount } : void 0
243
+ } : void 0,
244
+ raw: response
245
+ };
246
+ }
247
+ function parseParts(parts) {
248
+ const contentParts = [];
249
+ const toolCalls = [];
250
+ for (const part of parts) {
251
+ if ("text" in part) {
252
+ contentParts.push({
253
+ type: "text",
254
+ text: part.text
255
+ });
256
+ } else if ("functionCall" in part) {
257
+ toolCalls.push({
258
+ id: `call_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
259
+ type: "function",
260
+ function: {
261
+ name: part.functionCall.name,
262
+ arguments: JSON.stringify(part.functionCall.args)
263
+ }
264
+ });
265
+ }
266
+ }
267
+ return { contentParts, toolCalls };
268
+ }
269
+
270
+ // src/inbound/stream-parser.ts
271
+ function mapFinishReason2(reason) {
272
+ if (!reason) return "stop";
273
+ const reasonMap = {
274
+ STOP: "stop",
275
+ MAX_TOKENS: "length",
276
+ SAFETY: "content_filter",
277
+ RECITATION: "content_filter",
278
+ OTHER: "stop",
279
+ // OpenAI-compatible reasons
280
+ stop: "stop",
281
+ length: "length",
282
+ tool_calls: "tool_calls",
283
+ content_filter: "content_filter"
284
+ };
285
+ return reasonMap[reason] ?? "stop";
286
+ }
287
+ function isOpenAIFormat2(chunk) {
288
+ const c = chunk;
289
+ return Array.isArray(c.choices) && c.choices.length > 0 && "delta" in c.choices[0];
290
+ }
291
+ function parseStream(chunk) {
292
+ if (isOpenAIFormat2(chunk)) {
293
+ return parseOpenAIStream(chunk);
294
+ }
295
+ return parseGeminiStream(chunk);
296
+ }
297
+ function parseOpenAIStream(data) {
298
+ if (!data.choices || data.choices.length === 0) {
299
+ if (data.usage) {
300
+ return {
301
+ type: "end",
302
+ id: data.id,
303
+ model: data.model,
304
+ usage: {
305
+ promptTokens: data.usage.prompt_tokens,
306
+ completionTokens: data.usage.completion_tokens,
307
+ totalTokens: data.usage.total_tokens
308
+ },
309
+ raw: data
310
+ };
311
+ }
312
+ return null;
313
+ }
314
+ const choice = data.choices[0];
315
+ if (!choice) return null;
316
+ const delta = choice.delta;
317
+ if (choice.index === 0 && !delta.content && !delta.tool_calls && !choice.finish_reason) {
318
+ return {
319
+ type: "start",
320
+ id: data.id,
321
+ model: data.model,
322
+ raw: data
323
+ };
324
+ }
325
+ if (delta.content) {
326
+ return {
327
+ type: "content",
328
+ id: data.id,
329
+ model: data.model,
330
+ content: {
331
+ type: "content",
332
+ delta: delta.content,
333
+ index: choice.index
334
+ },
335
+ raw: data
336
+ };
337
+ }
338
+ if (delta.tool_calls && delta.tool_calls.length > 0) {
339
+ const toolCall = delta.tool_calls[0];
340
+ if (toolCall) {
341
+ return {
342
+ type: "tool_call",
343
+ id: data.id,
344
+ model: data.model,
345
+ toolCall: {
346
+ type: "tool_call",
347
+ id: toolCall.id,
348
+ name: toolCall.function?.name,
349
+ arguments: toolCall.function?.arguments,
350
+ index: toolCall.index
351
+ },
352
+ raw: data
353
+ };
354
+ }
355
+ }
356
+ if (choice.finish_reason) {
357
+ return {
358
+ type: "end",
359
+ id: data.id,
360
+ model: data.model,
361
+ finishReason: mapFinishReason2(choice.finish_reason),
362
+ usage: data.usage ? {
363
+ promptTokens: data.usage.prompt_tokens,
364
+ completionTokens: data.usage.completion_tokens,
365
+ totalTokens: data.usage.total_tokens
366
+ } : void 0,
367
+ raw: data
368
+ };
369
+ }
370
+ return null;
371
+ }
372
+ function parseGeminiStream(data) {
373
+ if (!data.candidates || data.candidates.length === 0) {
374
+ if (data.usageMetadata) {
375
+ return {
376
+ type: "end",
377
+ model: data.modelVersion,
378
+ usage: {
379
+ promptTokens: data.usageMetadata.promptTokenCount,
380
+ completionTokens: data.usageMetadata.candidatesTokenCount,
381
+ totalTokens: data.usageMetadata.totalTokenCount
382
+ },
383
+ raw: data
384
+ };
385
+ }
386
+ return null;
387
+ }
388
+ const candidate = data.candidates[0];
389
+ if (!candidate) return null;
390
+ const events = [];
391
+ if (candidate.content?.parts) {
392
+ for (const part of candidate.content.parts) {
393
+ if ("text" in part) {
394
+ events.push({
395
+ type: "content",
396
+ model: data.modelVersion,
397
+ content: {
398
+ type: "content",
399
+ delta: part.text,
400
+ index: candidate.index ?? 0
401
+ },
402
+ raw: data
403
+ });
404
+ } else if ("functionCall" in part) {
405
+ events.push({
406
+ type: "tool_call",
407
+ model: data.modelVersion,
408
+ toolCall: {
409
+ type: "tool_call",
410
+ id: `call_${Date.now()}_${part.functionCall.name}`,
411
+ name: part.functionCall.name,
412
+ arguments: JSON.stringify(part.functionCall.args),
413
+ index: candidate.index ?? 0
414
+ },
415
+ raw: data
416
+ });
417
+ }
418
+ }
419
+ }
420
+ if (candidate.finishReason) {
421
+ events.push({
422
+ type: "end",
423
+ model: data.modelVersion,
424
+ finishReason: mapFinishReason2(candidate.finishReason),
425
+ usage: data.usageMetadata ? {
426
+ promptTokens: data.usageMetadata.promptTokenCount,
427
+ completionTokens: data.usageMetadata.candidatesTokenCount,
428
+ totalTokens: data.usageMetadata.totalTokenCount
429
+ } : void 0,
430
+ raw: data
431
+ });
432
+ }
433
+ if (events.length === 0) {
434
+ return null;
435
+ }
436
+ const firstEvent = events[0];
437
+ return events.length === 1 && firstEvent ? firstEvent : events;
438
+ }
439
+
440
+ // src/inbound/error-parser.ts
441
+ function parseError(error) {
442
+ if (error && typeof error === "object" && "error" in error) {
443
+ const err = error.error;
444
+ return {
445
+ type: mapErrorType(err.status, err.code),
446
+ message: err.message,
447
+ code: err.status,
448
+ status: err.code,
449
+ raw: error
450
+ };
451
+ }
452
+ return {
453
+ type: "unknown",
454
+ message: String(error),
455
+ raw: error
456
+ };
457
+ }
458
+ function mapErrorType(status, code) {
459
+ if (code) {
460
+ const codeMap = {
461
+ 400: "validation",
462
+ 401: "authentication",
463
+ 403: "permission",
464
+ 404: "not_found",
465
+ 429: "rate_limit",
466
+ 500: "server"
467
+ };
468
+ if (codeMap[code]) return codeMap[code];
469
+ }
470
+ if (status) {
471
+ const statusMap = {
472
+ INVALID_ARGUMENT: "validation",
473
+ UNAUTHENTICATED: "authentication",
474
+ PERMISSION_DENIED: "permission",
475
+ NOT_FOUND: "not_found",
476
+ RESOURCE_EXHAUSTED: "rate_limit",
477
+ INTERNAL: "server"
478
+ };
479
+ if (statusMap[status]) return statusMap[status];
480
+ }
481
+ return "unknown";
482
+ }
483
+
484
+ // src/outbound/request-builder.ts
485
+ function buildRequest(ir) {
486
+ const request = {
487
+ contents: []
488
+ };
489
+ if (ir.system) {
490
+ request.systemInstruction = {
491
+ parts: [{ text: ir.system }]
492
+ };
493
+ }
494
+ for (const msg of ir.messages) {
495
+ if (msg.role === "system") continue;
496
+ if (msg.role === "tool") {
497
+ const resultContent = typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content);
498
+ request.contents.push({
499
+ role: "user",
500
+ parts: [{
501
+ functionResponse: {
502
+ name: msg.name ?? "unknown",
503
+ response: { result: resultContent }
504
+ }
505
+ }]
506
+ });
507
+ continue;
508
+ }
509
+ const content = buildContent(msg);
510
+ if (content) {
511
+ request.contents.push(content);
512
+ }
513
+ }
514
+ if (ir.tools && ir.tools.length > 0) {
515
+ request.tools = [
516
+ {
517
+ functionDeclarations: ir.tools.map((tool) => ({
518
+ name: tool.function.name,
519
+ description: tool.function.description,
520
+ parameters: tool.function.parameters ? {
521
+ type: tool.function.parameters.type ?? "object",
522
+ properties: tool.function.parameters.properties,
523
+ required: tool.function.parameters.required
524
+ } : void 0
525
+ }))
526
+ }
527
+ ];
528
+ }
529
+ if (ir.toolChoice) {
530
+ let mode = "AUTO";
531
+ if (ir.toolChoice === "none") mode = "NONE";
532
+ else if (ir.toolChoice === "required") mode = "ANY";
533
+ else if (ir.toolChoice === "auto") mode = "AUTO";
534
+ else if (typeof ir.toolChoice === "object") {
535
+ mode = "ANY";
536
+ request.toolConfig = {
537
+ functionCallingConfig: {
538
+ mode,
539
+ allowedFunctionNames: [ir.toolChoice.function.name]
540
+ }
541
+ };
542
+ }
543
+ if (!request.toolConfig) {
544
+ request.toolConfig = {
545
+ functionCallingConfig: { mode }
546
+ };
547
+ }
548
+ }
549
+ if (ir.generation) {
550
+ request.generationConfig = {};
551
+ if (ir.generation.temperature !== void 0) {
552
+ request.generationConfig.temperature = ir.generation.temperature;
553
+ }
554
+ if (ir.generation.topP !== void 0) {
555
+ request.generationConfig.topP = ir.generation.topP;
556
+ }
557
+ if (ir.generation.topK !== void 0) {
558
+ request.generationConfig.topK = ir.generation.topK;
559
+ }
560
+ if (ir.generation.maxTokens !== void 0) {
561
+ request.generationConfig.maxOutputTokens = ir.generation.maxTokens;
562
+ }
563
+ if (ir.generation.stopSequences && ir.generation.stopSequences.length > 0) {
564
+ request.generationConfig.stopSequences = ir.generation.stopSequences;
565
+ }
566
+ if (ir.generation.responseFormat?.type === "json_object") {
567
+ request.generationConfig.responseMimeType = "application/json";
568
+ }
569
+ }
570
+ return request;
571
+ }
572
+ function buildContent(msg) {
573
+ const role = msg.role === "assistant" ? "model" : "user";
574
+ const parts = [];
575
+ if (typeof msg.content === "string") {
576
+ if (msg.content) {
577
+ parts.push({ text: msg.content });
578
+ }
579
+ } else if (Array.isArray(msg.content)) {
580
+ for (const part of msg.content) {
581
+ if (part.type === "text") {
582
+ parts.push({ text: part.text });
583
+ } else if (part.type === "image") {
584
+ const imgPart = part;
585
+ if (imgPart.source.type === "base64") {
586
+ parts.push({
587
+ inlineData: {
588
+ mimeType: imgPart.source.mediaType,
589
+ data: imgPart.source.data
590
+ }
591
+ });
592
+ } else {
593
+ parts.push({
594
+ fileData: {
595
+ mimeType: "image/*",
596
+ fileUri: imgPart.source.url
597
+ }
598
+ });
599
+ }
600
+ }
601
+ }
602
+ }
603
+ if (msg.toolCalls && Array.isArray(msg.toolCalls)) {
604
+ for (const toolCall of msg.toolCalls) {
605
+ parts.push({
606
+ functionCall: {
607
+ name: toolCall.function.name,
608
+ args: JSON.parse(toolCall.function.arguments)
609
+ }
610
+ });
611
+ }
612
+ }
613
+ if (parts.length === 0) {
614
+ return null;
615
+ }
616
+ return { role, parts };
617
+ }
618
+
619
+ // src/outbound/response-builder.ts
620
+ function mapFinishReason3(reason) {
621
+ if (!reason) return "STOP";
622
+ const reasonMap = {
623
+ stop: "STOP",
624
+ length: "MAX_TOKENS",
625
+ tool_calls: "STOP",
626
+ content_filter: "SAFETY",
627
+ error: "OTHER"
628
+ };
629
+ return reasonMap[reason] ?? "STOP";
630
+ }
631
+ function buildResponse(ir) {
632
+ return {
633
+ candidates: ir.choices.map((choice) => ({
634
+ content: {
635
+ role: "model",
636
+ parts: buildParts(choice.message.content, choice.message.toolCalls)
637
+ },
638
+ finishReason: mapFinishReason3(choice.finishReason),
639
+ index: choice.index
640
+ })),
641
+ usageMetadata: ir.usage ? {
642
+ promptTokenCount: ir.usage.promptTokens,
643
+ candidatesTokenCount: ir.usage.completionTokens,
644
+ totalTokenCount: ir.usage.totalTokens,
645
+ cachedContentTokenCount: ir.usage.details?.cachedTokens
646
+ } : void 0,
647
+ responseId: ir.id,
648
+ modelVersion: ir.model
649
+ };
650
+ }
651
+ function buildParts(content, toolCalls) {
652
+ const parts = [];
653
+ if (typeof content === "string") {
654
+ if (content) {
655
+ parts.push({ text: content });
656
+ }
657
+ } else if (Array.isArray(content)) {
658
+ for (const part of content) {
659
+ if (part.type === "text") {
660
+ parts.push({ text: part.text });
661
+ }
662
+ }
663
+ }
664
+ if (toolCalls) {
665
+ for (const toolCall of toolCalls) {
666
+ parts.push({
667
+ functionCall: {
668
+ name: toolCall.function.name,
669
+ args: JSON.parse(toolCall.function.arguments)
670
+ }
671
+ });
672
+ }
673
+ }
674
+ return parts;
675
+ }
676
+
677
+ // src/outbound/stream-builder.ts
678
+ function createStreamBuilder() {
679
+ let responseId = `gemini-${Date.now()}`;
680
+ let model = "";
681
+ return {
682
+ process(event) {
683
+ const events = [];
684
+ if (event.id) responseId = event.id;
685
+ if (event.model) model = event.model;
686
+ if (event.type === "start") {
687
+ return events;
688
+ }
689
+ if (event.type === "content" && event.content?.delta) {
690
+ events.push({
691
+ event: "data",
692
+ data: {
693
+ candidates: [{
694
+ content: {
695
+ role: "model",
696
+ parts: [{ text: event.content.delta }]
697
+ },
698
+ index: 0
699
+ }],
700
+ modelVersion: model,
701
+ responseId
702
+ }
703
+ });
704
+ }
705
+ if (event.type === "tool_call" && event.toolCall) {
706
+ if (event.toolCall.name) {
707
+ let args = {};
708
+ if (event.toolCall.arguments) {
709
+ try {
710
+ args = JSON.parse(event.toolCall.arguments);
711
+ } catch {
712
+ args = {};
713
+ }
714
+ }
715
+ events.push({
716
+ event: "data",
717
+ data: {
718
+ candidates: [{
719
+ content: {
720
+ role: "model",
721
+ parts: [{
722
+ functionCall: {
723
+ name: event.toolCall.name,
724
+ args
725
+ }
726
+ }]
727
+ },
728
+ index: 0
729
+ }],
730
+ modelVersion: model,
731
+ responseId
732
+ }
733
+ });
734
+ }
735
+ }
736
+ if (event.type === "end") {
737
+ const finishReason = mapFinishReason4(event.finishReason);
738
+ const finalChunk = {
739
+ candidates: [{
740
+ content: {
741
+ role: "model",
742
+ parts: [{ text: "" }]
743
+ },
744
+ finishReason,
745
+ index: 0
746
+ }],
747
+ modelVersion: model,
748
+ responseId
749
+ };
750
+ if (event.usage) {
751
+ finalChunk.usageMetadata = {
752
+ promptTokenCount: event.usage.promptTokens ?? 0,
753
+ candidatesTokenCount: event.usage.completionTokens ?? 0,
754
+ totalTokenCount: event.usage.totalTokens ?? 0
755
+ };
756
+ }
757
+ events.push({ event: "data", data: finalChunk });
758
+ }
759
+ if (event.type === "error" && event.error) {
760
+ events.push({
761
+ event: "data",
762
+ data: {
763
+ error: {
764
+ code: 500,
765
+ message: event.error.message,
766
+ status: "INTERNAL"
767
+ }
768
+ }
769
+ });
770
+ }
771
+ return events;
772
+ }
773
+ };
774
+ }
775
+ function mapFinishReason4(reason) {
776
+ if (!reason) return "STOP";
777
+ const reasonMap = {
778
+ stop: "STOP",
779
+ length: "MAX_TOKENS",
780
+ tool_calls: "STOP",
781
+ content_filter: "SAFETY",
782
+ end_turn: "STOP",
783
+ max_tokens: "MAX_TOKENS"
784
+ };
785
+ return reasonMap[reason] ?? "STOP";
786
+ }
787
+
788
+ // src/adapter.ts
789
+ var googleAdapter = {
790
+ name: "google",
791
+ version: "1.0.0",
792
+ capabilities: {
793
+ streaming: true,
794
+ tools: true,
795
+ vision: true,
796
+ multimodal: true,
797
+ // Supports images, audio, video, PDFs
798
+ systemPrompt: true,
799
+ // Via systemInstruction
800
+ toolChoice: true,
801
+ // Via functionCallingConfig
802
+ reasoning: false,
803
+ webSearch: false,
804
+ jsonMode: true,
805
+ logprobs: false,
806
+ seed: false
807
+ },
808
+ inbound: {
809
+ parseRequest: (request) => {
810
+ return parseRequest(request);
811
+ },
812
+ parseResponse: (response) => {
813
+ return parseResponse(response);
814
+ },
815
+ parseStream: (chunk) => {
816
+ return parseStream(chunk);
817
+ },
818
+ parseError: (error) => {
819
+ return parseError(error);
820
+ }
821
+ },
822
+ outbound: {
823
+ buildRequest: (ir) => {
824
+ return buildRequest(ir);
825
+ },
826
+ buildResponse: (ir) => {
827
+ return buildResponse(ir);
828
+ },
829
+ createStreamBuilder
830
+ },
831
+ getInfo() {
832
+ return {
833
+ name: this.name,
834
+ version: this.version,
835
+ capabilities: this.capabilities,
836
+ endpoint: {
837
+ baseUrl: "https://generativelanguage.googleapis.com",
838
+ chatPath: "/v1beta/models/{model}:streamGenerateContent",
839
+ // Use streaming endpoint
840
+ modelsPath: "/v1beta/models"
841
+ }
842
+ };
843
+ }
844
+ };
845
+ var geminiAdapter = googleAdapter;
846
+
847
+ exports.geminiAdapter = geminiAdapter;
848
+ exports.googleAdapter = googleAdapter;
849
+ //# sourceMappingURL=index.cjs.map
850
+ //# sourceMappingURL=index.cjs.map