@omnicross/core 0.1.4 → 0.1.5

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 (67) hide show
  1. package/dist/auth/GeminiCodeAssistProjectResolver.cjs +6 -5
  2. package/dist/auth/GeminiCodeAssistProjectResolver.js +4 -3
  3. package/dist/{chunk-SU2GCLAC.cjs → chunk-3Q6Z6JTO.cjs} +124 -16
  4. package/dist/chunk-3Z5BQZFM.cjs +52 -0
  5. package/dist/{chunk-4VAVYUZS.cjs → chunk-4XMYPW46.cjs} +9 -9
  6. package/dist/{chunk-S4WBV25P.js → chunk-6QZGDLL4.js} +106 -23
  7. package/dist/{chunk-C72S6TTV.cjs → chunk-7FEBOPJO.cjs} +5 -4
  8. package/dist/{chunk-TIER4SUC.js → chunk-BODMAL6G.js} +119 -11
  9. package/dist/{chunk-DKPXN34V.cjs → chunk-CGKLE6IW.cjs} +145 -30
  10. package/dist/{chunk-XK5CIRMQ.js → chunk-D3TDKWRP.js} +60 -2
  11. package/dist/{chunk-RSJ3TWJQ.cjs → chunk-DDMRUL76.cjs} +5 -5
  12. package/dist/{chunk-QYTT6GE3.js → chunk-FH2P4OCD.js} +124 -9
  13. package/dist/{chunk-Z7LUNECE.js → chunk-IB3FDI4O.js} +5 -4
  14. package/dist/{chunk-7Y47UCF2.js → chunk-IFXJ2BG7.js} +5 -38
  15. package/dist/{chunk-C7PSERMH.js → chunk-IWQAX3CS.js} +1 -1
  16. package/dist/{chunk-YGXJGRFI.cjs → chunk-JWVTXXPX.cjs} +106 -23
  17. package/dist/{chunk-7YN22L2H.cjs → chunk-K52THW2C.cjs} +5 -5
  18. package/dist/{chunk-Z7Y2NPHY.js → chunk-MFZ5437A.js} +1 -1
  19. package/dist/{chunk-VPBAUQ2M.js → chunk-OQWKZCXP.js} +15 -8
  20. package/dist/{chunk-OCEUVQHW.cjs → chunk-PG7PS2NN.cjs} +61 -3
  21. package/dist/chunk-SYQF7OIR.js +52 -0
  22. package/dist/{chunk-E3UCVHLP.cjs → chunk-UNWKG6EI.cjs} +5 -38
  23. package/dist/{chunk-RGTR7CIO.cjs → chunk-ZCIQ3L3R.cjs} +19 -12
  24. package/dist/completion/CompletionService.cjs +13 -12
  25. package/dist/completion/CompletionService.js +12 -11
  26. package/dist/completion.cjs +13 -12
  27. package/dist/completion.js +12 -11
  28. package/dist/index.cjs +15 -14
  29. package/dist/index.js +14 -13
  30. package/dist/outbound-api/auditCapture.cjs +2 -2
  31. package/dist/outbound-api/auditCapture.d.cts +5 -3
  32. package/dist/outbound-api/auditCapture.d.ts +5 -3
  33. package/dist/outbound-api/auditCapture.js +1 -1
  34. package/dist/outbound-api.cjs +13 -12
  35. package/dist/outbound-api.js +12 -11
  36. package/dist/pipeline/upstreamFetch.cjs +3 -2
  37. package/dist/pipeline/upstreamFetch.d.cts +6 -0
  38. package/dist/pipeline/upstreamFetch.d.ts +6 -0
  39. package/dist/pipeline/upstreamFetch.js +2 -1
  40. package/dist/pipeline/upstreamTrace.cjs +14 -0
  41. package/dist/pipeline/upstreamTrace.d.cts +85 -0
  42. package/dist/pipeline/upstreamTrace.d.ts +85 -0
  43. package/dist/pipeline/upstreamTrace.js +14 -0
  44. package/dist/provider-proxy/ProviderProxy.cjs +13 -12
  45. package/dist/provider-proxy/ProviderProxy.js +12 -11
  46. package/dist/provider-proxy/ingress/providerProxyShared.cjs +15 -12
  47. package/dist/provider-proxy/ingress/providerProxyShared.d.cts +17 -1
  48. package/dist/provider-proxy/ingress/providerProxyShared.d.ts +17 -1
  49. package/dist/provider-proxy/ingress/providerProxyShared.js +14 -11
  50. package/dist/provider-proxy.cjs +13 -12
  51. package/dist/provider-proxy.js +12 -11
  52. package/dist/transformer/transformers/AnthropicTransformer.cjs +2 -2
  53. package/dist/transformer/transformers/AnthropicTransformer.js +1 -1
  54. package/dist/transformer/transformers/GeminiCodeAssistTransformer.cjs +3 -3
  55. package/dist/transformer/transformers/GeminiCodeAssistTransformer.js +2 -2
  56. package/dist/transformer/transformers/GeminiTransformer.cjs +3 -3
  57. package/dist/transformer/transformers/GeminiTransformer.js +2 -2
  58. package/dist/transformer/transformers/OpenAIResponseTransformer.cjs +2 -2
  59. package/dist/transformer/transformers/OpenAIResponseTransformer.js +1 -1
  60. package/dist/transformer/transformers/OpenCodeGoTransformer.cjs +2 -2
  61. package/dist/transformer/transformers/OpenCodeGoTransformer.js +1 -1
  62. package/dist/transformer/transformers.cjs +9 -9
  63. package/dist/transformer/transformers.js +9 -9
  64. package/dist/transformer.cjs +11 -11
  65. package/dist/transformer.js +10 -10
  66. package/package.json +1 -1
  67. package/dist/{chunk-FTQ7IQUC.js → chunk-C6OV7GCC.js} +8 -8
@@ -1,11 +1,12 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class;
2
2
 
3
3
 
4
- var _chunkRSJ3TWJQcjs = require('../chunk-RSJ3TWJQ.cjs');
5
- require('../chunk-YGXJGRFI.cjs');
4
+ var _chunkDDMRUL76cjs = require('../chunk-DDMRUL76.cjs');
5
+ require('../chunk-JWVTXXPX.cjs');
6
6
 
7
7
 
8
- var _chunkOCEUVQHWcjs = require('../chunk-OCEUVQHW.cjs');
8
+ var _chunkPG7PS2NNcjs = require('../chunk-PG7PS2NN.cjs');
9
+ require('../chunk-3Z5BQZFM.cjs');
9
10
 
10
11
  // src/auth/GeminiCodeAssistProjectResolver.ts
11
12
  var FREE_TIER_ID = "free-tier";
@@ -25,7 +26,7 @@ var GeminiCodeAssistHandshakeError = class extends Error {
25
26
  var GeminiCodeAssistProjectResolver = (_class = class {
26
27
  // upstream-proxy: the Code Assist handshake is upstream egress → honor the
27
28
  // gemini proxy by default (still injectable for tests).
28
- constructor(fetchImpl = (url, init) => _chunkOCEUVQHWcjs.fetchUpstream.call(void 0, url, init, { providerId: "gemini" })) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);
29
+ constructor(fetchImpl = (url, init) => _chunkPG7PS2NNcjs.fetchUpstream.call(void 0, url, init, { providerId: "gemini" })) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);
29
30
  this.fetchImpl = fetchImpl;
30
31
  }
31
32
 
@@ -59,7 +60,7 @@ var GeminiCodeAssistProjectResolver = (_class = class {
59
60
  return run;
60
61
  }
61
62
  codeAssistUrl(method) {
62
- return `${_chunkRSJ3TWJQcjs.resolveCodeAssistEndpoint.call(void 0, )}/${_chunkRSJ3TWJQcjs.resolveCodeAssistApiVersion.call(void 0, )}:${method}`;
63
+ return `${_chunkDDMRUL76cjs.resolveCodeAssistEndpoint.call(void 0, )}/${_chunkDDMRUL76cjs.resolveCodeAssistApiVersion.call(void 0, )}:${method}`;
63
64
  }
64
65
  /** Seed project id from env; reject a purely-numeric value (project NUMBER). */
65
66
  seedProjectId() {
@@ -1,11 +1,12 @@
1
1
  import {
2
2
  resolveCodeAssistApiVersion,
3
3
  resolveCodeAssistEndpoint
4
- } from "../chunk-Z7Y2NPHY.js";
5
- import "../chunk-S4WBV25P.js";
4
+ } from "../chunk-MFZ5437A.js";
5
+ import "../chunk-6QZGDLL4.js";
6
6
  import {
7
7
  fetchUpstream
8
- } from "../chunk-XK5CIRMQ.js";
8
+ } from "../chunk-D3TDKWRP.js";
9
+ import "../chunk-SYQF7OIR.js";
9
10
 
10
11
  // src/auth/GeminiCodeAssistProjectResolver.ts
11
12
  var FREE_TIER_ID = "free-tier";
@@ -45,10 +45,12 @@ var OpenAIResponseTransformer = (_class = class {constructor() { _class.prototyp
45
45
  if (msg.role === "assistant" && _optionalChain([msg, 'access', _ => _.tool_calls, 'optionalAccess', _2 => _2.length])) {
46
46
  input.push(entry);
47
47
  for (const tc of msg.tool_calls) {
48
+ const callId = tc.id;
49
+ const itemId = callId.startsWith("fc_") ? callId : `fc_${callId.replace(/^(call_|fc_)/, "")}`;
48
50
  input.push({
49
51
  type: "function_call",
50
- id: tc.id,
51
- call_id: tc.id,
52
+ id: itemId,
53
+ call_id: callId,
52
54
  name: tc.function.name,
53
55
  arguments: tc.function.arguments
54
56
  });
@@ -61,7 +63,11 @@ var OpenAIResponseTransformer = (_class = class {constructor() { _class.prototyp
61
63
  const body = {
62
64
  model: request.model,
63
65
  input,
64
- stream: _nullishCoalesce(request.stream, () => ( false)),
66
+ // codex's backend REQUIRES `stream:true` (it 400s with "Stream must be
67
+ // set to true" otherwise). Always force it; a non-streaming CLIENT is
68
+ // served by aggregating the SSE upstream of the wire (the ingress buffers
69
+ // it into a single message), not by asking codex for a non-streaming reply.
70
+ stream: true,
65
71
  // `store:false` is required by the codex backend and accepted by the
66
72
  // public Responses API (which defaults to store:true). Always set it so
67
73
  // codex relays (no discoverable url token) work without configuration.
@@ -335,6 +341,7 @@ function convertResponseApiStreamToOpenAI(responseApiStream) {
335
341
  const messageId = `chatcmpl-${Date.now()}`;
336
342
  let model = "unknown";
337
343
  let hasEmittedRole = false;
344
+ let hasToolCalls = false;
338
345
  const safeEnqueue = (str) => {
339
346
  if (!isClosed) {
340
347
  try {
@@ -391,22 +398,58 @@ function convertResponseApiStreamToOpenAI(responseApiStream) {
391
398
  }]);
392
399
  }
393
400
  break;
401
+ case "response.output_item.added": {
402
+ const item = event.item;
403
+ if (_optionalChain([item, 'optionalAccess', _18 => _18.type]) !== "function_call") break;
404
+ if (!hasEmittedRole) {
405
+ emitChunk([{ index: 0, delta: { role: "assistant", content: null }, finish_reason: null }]);
406
+ hasEmittedRole = true;
407
+ }
408
+ hasToolCalls = true;
409
+ emitChunk([{
410
+ index: 0,
411
+ delta: {
412
+ tool_calls: [{
413
+ index: _nullishCoalesce(event.output_index, () => ( 0)),
414
+ id: item.call_id,
415
+ type: "function",
416
+ function: { name: item.name, arguments: "" }
417
+ }]
418
+ },
419
+ finish_reason: null
420
+ }]);
421
+ break;
422
+ }
423
+ case "response.function_call_arguments.delta": {
424
+ hasToolCalls = true;
425
+ emitChunk([{
426
+ index: 0,
427
+ delta: {
428
+ tool_calls: [{
429
+ index: _nullishCoalesce(event.output_index, () => ( 0)),
430
+ function: { arguments: _nullishCoalesce(event.delta, () => ( "")) }
431
+ }]
432
+ },
433
+ finish_reason: null
434
+ }]);
435
+ break;
436
+ }
394
437
  case "response.completed": {
395
438
  const resp = event.response;
396
- const respUsage = _optionalChain([resp, 'optionalAccess', _18 => _18.usage]);
439
+ const respUsage = _optionalChain([resp, 'optionalAccess', _19 => _19.usage]);
397
440
  const usage = respUsage ? {
398
441
  prompt_tokens: respUsage.input_tokens || 0,
399
442
  completion_tokens: respUsage.output_tokens || 0,
400
443
  total_tokens: (respUsage.input_tokens || 0) + (respUsage.output_tokens || 0)
401
444
  } : void 0;
402
- emitChunk([{ index: 0, delta: {}, finish_reason: "stop" }], usage);
445
+ emitChunk([{ index: 0, delta: {}, finish_reason: hasToolCalls ? "tool_calls" : "stop" }], usage);
403
446
  safeEnqueue("data: [DONE]\n\n");
404
447
  break;
405
448
  }
406
449
  case "error":
407
450
  emitChunk([{
408
451
  index: 0,
409
- delta: { content: `[Error: ${_optionalChain([event, 'access', _19 => _19.error, 'optionalAccess', _20 => _20.message]) || "Unknown error"}]` },
452
+ delta: { content: `[Error: ${_optionalChain([event, 'access', _20 => _20.error, 'optionalAccess', _21 => _21.message]) || "Unknown error"}]` },
410
453
  finish_reason: "stop"
411
454
  }]);
412
455
  break;
@@ -442,6 +485,9 @@ function convertOpenAIStreamToResponseApi(openaiStream) {
442
485
  let accumulatedContent = "";
443
486
  let model = "unknown";
444
487
  const responseId = `resp_${Date.now()}`;
488
+ const toolCalls = /* @__PURE__ */ new Map();
489
+ const toolOutputIndex = /* @__PURE__ */ new Map();
490
+ let nextOutputIndex = 1;
445
491
  const safeEnqueue = (str) => {
446
492
  if (!isClosed) {
447
493
  try {
@@ -474,34 +520,96 @@ function convertOpenAIStreamToResponseApi(openaiStream) {
474
520
  if (data === "[DONE]") continue;
475
521
  try {
476
522
  const chunk = JSON.parse(data);
477
- const choice = _optionalChain([chunk, 'access', _21 => _21.choices, 'optionalAccess', _22 => _22[0]]);
523
+ const choice = _optionalChain([chunk, 'access', _22 => _22.choices, 'optionalAccess', _23 => _23[0]]);
478
524
  model = chunk.model || model;
479
525
  if (!choice) continue;
480
- if (_optionalChain([choice, 'access', _23 => _23.delta, 'optionalAccess', _24 => _24.content])) {
526
+ if (_optionalChain([choice, 'access', _24 => _24.delta, 'optionalAccess', _25 => _25.content])) {
481
527
  accumulatedContent += choice.delta.content;
482
528
  emitEvent({ type: "response.output_text.delta", delta: choice.delta.content });
483
529
  }
484
- if (_optionalChain([choice, 'access', _25 => _25.delta, 'optionalAccess', _26 => _26.thinking, 'optionalAccess', _27 => _27.content])) {
530
+ if (_optionalChain([choice, 'access', _26 => _26.delta, 'optionalAccess', _27 => _27.thinking, 'optionalAccess', _28 => _28.content])) {
485
531
  emitEvent({
486
532
  type: "response.reasoning_summary_text.delta",
487
533
  delta: choice.delta.thinking.content
488
534
  });
489
535
  }
536
+ if (_optionalChain([choice, 'access', _29 => _29.delta, 'optionalAccess', _30 => _30.tool_calls])) {
537
+ for (const tc of choice.delta.tool_calls) {
538
+ const tcIndex = typeof tc["index"] === "number" ? tc["index"] : 0;
539
+ const func = _nullishCoalesce(tc["function"], () => ( {}));
540
+ let entry = toolCalls.get(tcIndex);
541
+ if (!entry) {
542
+ const callId = typeof tc["id"] === "string" ? tc["id"] : `call_${Date.now()}_${tcIndex}`;
543
+ const name = typeof func["name"] === "string" ? func["name"] : "";
544
+ entry = { callId, name, arguments: "" };
545
+ toolCalls.set(tcIndex, entry);
546
+ const outIdx = nextOutputIndex++;
547
+ toolOutputIndex.set(tcIndex, outIdx);
548
+ const itemId = callId.startsWith("fc_") ? callId : `fc_${callId.replace(/^(call_|fc_)/, "")}`;
549
+ emitEvent({
550
+ type: "response.output_item.added",
551
+ output_index: outIdx,
552
+ item: {
553
+ id: itemId,
554
+ type: "function_call",
555
+ status: "in_progress",
556
+ call_id: callId,
557
+ name,
558
+ arguments: ""
559
+ }
560
+ });
561
+ }
562
+ const argsFragment = typeof func["arguments"] === "string" ? func["arguments"] : "";
563
+ if (argsFragment) {
564
+ entry.arguments += argsFragment;
565
+ emitEvent({
566
+ type: "response.function_call_arguments.delta",
567
+ output_index: toolOutputIndex.get(tcIndex),
568
+ delta: argsFragment
569
+ });
570
+ }
571
+ }
572
+ }
490
573
  if (choice.finish_reason) {
491
574
  emitEvent({ type: "response.output_text.done", text: accumulatedContent });
575
+ const output = [];
576
+ if (accumulatedContent) {
577
+ output.push({
578
+ type: "message",
579
+ role: "assistant",
580
+ content: [{ type: "output_text", text: accumulatedContent }]
581
+ });
582
+ }
583
+ for (const [tcIndex, entry] of toolCalls) {
584
+ const itemId = entry.callId.startsWith("fc_") ? entry.callId : `fc_${entry.callId.replace(/^(call_|fc_)/, "")}`;
585
+ output.push({
586
+ id: itemId,
587
+ type: "function_call",
588
+ status: "completed",
589
+ call_id: entry.callId,
590
+ name: entry.name,
591
+ arguments: entry.arguments
592
+ });
593
+ emitEvent({
594
+ type: "response.output_item.done",
595
+ output_index: toolOutputIndex.get(tcIndex),
596
+ item: {
597
+ id: itemId,
598
+ type: "function_call",
599
+ status: "completed",
600
+ call_id: entry.callId,
601
+ name: entry.name,
602
+ arguments: entry.arguments
603
+ }
604
+ });
605
+ }
492
606
  emitEvent({
493
607
  type: "response.completed",
494
608
  response: {
495
609
  id: responseId,
496
610
  status: "completed",
497
611
  model,
498
- output: [
499
- {
500
- type: "message",
501
- role: "assistant",
502
- content: [{ type: "output_text", text: accumulatedContent }]
503
- }
504
- ],
612
+ output,
505
613
  usage: chunk.usage ? {
506
614
  input_tokens: chunk.usage.prompt_tokens || 0,
507
615
  output_tokens: chunk.usage.completion_tokens || 0,
@@ -0,0 +1,52 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/pipeline/upstreamTrace.ts
2
+ var _promises = require('fs/promises');
3
+ var _path = require('path');
4
+ var tracePath = null;
5
+ var SECRET_HEADER_NAMES = /* @__PURE__ */ new Set([
6
+ "authorization",
7
+ "api-key",
8
+ "x-api-key",
9
+ "x-goog-api-key"
10
+ ]);
11
+ function setUpstreamTracePath(path) {
12
+ tracePath = typeof path === "string" && path.trim() ? path.trim() : null;
13
+ }
14
+ function getUpstreamTracePath() {
15
+ return tracePath;
16
+ }
17
+ function redactHeaders(headers) {
18
+ const out = {};
19
+ if (!headers) return out;
20
+ let entries;
21
+ if (Array.isArray(headers)) {
22
+ entries = headers;
23
+ } else if (typeof headers.entries === "function") {
24
+ entries = Array.from(headers.entries());
25
+ } else {
26
+ entries = Object.entries(headers);
27
+ }
28
+ for (const [key, value] of entries) {
29
+ out[key] = SECRET_HEADER_NAMES.has(key.toLowerCase()) ? "***REDACTED***" : String(value);
30
+ }
31
+ return out;
32
+ }
33
+ async function writeUpstreamTrace(record) {
34
+ const path = tracePath;
35
+ if (!path) return;
36
+ try {
37
+ await _promises.mkdir.call(void 0, _path.dirname.call(void 0, path), { recursive: true });
38
+ await _promises.appendFile.call(void 0, path, JSON.stringify(record) + "\n", "utf8");
39
+ } catch (e) {
40
+ }
41
+ }
42
+ function __resetUpstreamTraceForTests() {
43
+ tracePath = null;
44
+ }
45
+
46
+
47
+
48
+
49
+
50
+
51
+
52
+ exports.setUpstreamTracePath = setUpstreamTracePath; exports.getUpstreamTracePath = getUpstreamTracePath; exports.redactHeaders = redactHeaders; exports.writeUpstreamTrace = writeUpstreamTrace; exports.__resetUpstreamTraceForTests = __resetUpstreamTraceForTests;
@@ -237,6 +237,14 @@ function convertOpenAIResponseToAnthropic(openaiResponse) {
237
237
  }
238
238
  const message = choice.message;
239
239
  const content = [];
240
+ const thinking = message.thinking;
241
+ if (_optionalChain([thinking, 'optionalAccess', _13 => _13.content])) {
242
+ content.push({
243
+ type: "thinking",
244
+ thinking: thinking.content,
245
+ signature: thinking.signature
246
+ });
247
+ }
240
248
  if (message.content) {
241
249
  content.push({
242
250
  type: "text",
@@ -244,7 +252,7 @@ function convertOpenAIResponseToAnthropic(openaiResponse) {
244
252
  });
245
253
  }
246
254
  const toolCalls = message.tool_calls;
247
- if (_optionalChain([toolCalls, 'optionalAccess', _13 => _13.length])) {
255
+ if (_optionalChain([toolCalls, 'optionalAccess', _14 => _14.length])) {
248
256
  for (const toolCall of toolCalls) {
249
257
  const func = toolCall.function;
250
258
  let parsedInput = {};
@@ -262,14 +270,6 @@ function convertOpenAIResponseToAnthropic(openaiResponse) {
262
270
  });
263
271
  }
264
272
  }
265
- const thinking = message.thinking;
266
- if (_optionalChain([thinking, 'optionalAccess', _14 => _14.content])) {
267
- content.push({
268
- type: "thinking",
269
- thinking: thinking.content,
270
- signature: thinking.signature
271
- });
272
- }
273
273
  const finishReason = choice.finish_reason;
274
274
  const stopReasonMapping = {
275
275
  stop: "end_turn",
@@ -321,6 +321,7 @@ function handleStreamResponse(response, providerName, logger) {
321
321
  let pendingContent = "";
322
322
  let contentIndex = 0;
323
323
  let toolCallIndex = -1;
324
+ let textBuffered = false;
324
325
  const stream = new ReadableStream({
325
326
  async start(controller) {
326
327
  const reader = response.body.getReader();
@@ -338,6 +339,7 @@ function handleStreamResponse(response, providerName, logger) {
338
339
  }
339
340
  const candidate = chunk.candidates[0];
340
341
  const parts = candidate.content?.parts || [];
342
+ textBuffered = false;
341
343
  parts.filter((part) => part.text && part.thought === true).forEach((part) => {
342
344
  hasThinkingContent = true;
343
345
  const thinkingChunk = createChunk({
@@ -415,7 +417,7 @@ function handleStreamResponse(response, providerName, logger) {
415
417
  if (hasThinkingContent && textContent && !signatureSent) {
416
418
  if (chunk.modelVersion?.includes("3")) {
417
419
  pendingContent += textContent;
418
- return;
420
+ textBuffered = true;
419
421
  } else {
420
422
  const signatureChunk = createChunk({
421
423
  responseId: chunk.responseId,
@@ -433,7 +435,7 @@ function handleStreamResponse(response, providerName, logger) {
433
435
  signatureSent = true;
434
436
  }
435
437
  }
436
- if (textContent) {
438
+ if (textContent && !textBuffered) {
437
439
  if (!pendingContent) contentIndex++;
438
440
  const contentChunk = createChunk({
439
441
  responseId: chunk.responseId,
@@ -854,35 +856,116 @@ function transformRequestOut(request) {
854
856
  tool_choice: toolChoice
855
857
  };
856
858
  if (Array.isArray(contents)) {
859
+ const toolCallIdsByName = /* @__PURE__ */ new Map();
857
860
  for (const content of contents) {
858
861
  if (typeof content === "string") {
859
- unifiedRequest.messages.push({
860
- role: "user",
861
- content
862
- });
863
- } else if ("text" in content && typeof content.text === "string") {
862
+ unifiedRequest.messages.push({ role: "user", content });
863
+ continue;
864
+ }
865
+ if (content && typeof content === "object" && "text" in content && typeof content.text === "string" && !("parts" in content)) {
864
866
  unifiedRequest.messages.push({
865
867
  role: "user",
866
868
  content: content.text || null
867
869
  });
868
- } else if ("role" in content && content.role === "user") {
869
- const geminiContent = content;
870
- unifiedRequest.messages.push({
871
- role: "user",
872
- content: geminiContent.parts?.map((part) => ({
873
- type: "text",
874
- text: part.text || ""
875
- })) || []
876
- });
877
- } else if (content.role === "model") {
870
+ continue;
871
+ }
872
+ if (!content || typeof content !== "object" || !("role" in content)) {
873
+ continue;
874
+ }
875
+ const geminiContent = content;
876
+ const isModel = geminiContent.role === "model";
877
+ const role = isModel ? "assistant" : "user";
878
+ const parts = geminiContent.parts ?? [];
879
+ const functionResponses = [];
880
+ const functionCalls = [];
881
+ const textParts = [];
882
+ const contentParts = [];
883
+ let thinkingText = "";
884
+ let signature;
885
+ for (const part of parts) {
886
+ if ("thoughtSignature" in part) {
887
+ signature = part.thoughtSignature;
888
+ }
889
+ if ("functionResponse" in part) {
890
+ functionResponses.push(part);
891
+ } else if ("functionCall" in part) {
892
+ functionCalls.push(part);
893
+ } else if ("inlineData" in part || "file_data" in part) {
894
+ const inline = part.inlineData;
895
+ const fileData = part.file_data;
896
+ if (inline?.data) {
897
+ const mime = inline.mime_type || "image/png";
898
+ contentParts.push({
899
+ type: "image_url",
900
+ image_url: { url: `data:${mime};base64,${inline.data}` },
901
+ media_type: mime
902
+ });
903
+ } else if (fileData?.file_uri) {
904
+ contentParts.push({
905
+ type: "image_url",
906
+ image_url: { url: fileData.file_uri },
907
+ media_type: fileData.mime_type
908
+ });
909
+ }
910
+ } else if ("text" in part) {
911
+ if (part.thought === true) {
912
+ thinkingText += part.text ?? "";
913
+ } else {
914
+ textParts.push(part);
915
+ }
916
+ }
917
+ }
918
+ for (const fr of functionResponses) {
919
+ const fnName = fr.functionResponse.name ?? "";
920
+ const queue = toolCallIdsByName.get(fnName);
921
+ const id = queue && queue.length > 0 ? queue.shift() : `tool_${Math.random().toString(36).substring(2, 15)}`;
922
+ const response = fr.functionResponse.response;
923
+ const result = response?.result;
924
+ const toolContent = typeof result === "string" ? result : result !== void 0 ? JSON.stringify(result) : response !== void 0 ? JSON.stringify(response) : "";
878
925
  unifiedRequest.messages.push({
879
- role: "assistant",
880
- content: content.parts?.map((part) => ({
881
- type: "text",
882
- text: part.text || ""
883
- })) || []
926
+ role: "tool",
927
+ tool_call_id: id,
928
+ content: toolContent
884
929
  });
885
930
  }
931
+ const toolCalls = functionCalls.map((p) => {
932
+ const id = p.functionCall.id || `tool_${Math.random().toString(36).substring(2, 15)}`;
933
+ if (p.functionCall.name) {
934
+ const arr = toolCallIdsByName.get(p.functionCall.name) ?? [];
935
+ arr.push(id);
936
+ toolCallIdsByName.set(p.functionCall.name, arr);
937
+ }
938
+ return {
939
+ id,
940
+ type: "function",
941
+ function: {
942
+ name: p.functionCall.name,
943
+ arguments: JSON.stringify(p.functionCall.args ?? {})
944
+ }
945
+ };
946
+ });
947
+ const onlyToolResults = functionResponses.length > 0 && textParts.length === 0 && functionCalls.length === 0 && contentParts.length === 0 && !thinkingText && !signature;
948
+ if (onlyToolResults) continue;
949
+ let messageContent;
950
+ if (contentParts.length > 0) {
951
+ messageContent = [
952
+ ...textParts.map((p) => ({ type: "text", text: p.text })),
953
+ ...contentParts
954
+ ];
955
+ } else {
956
+ messageContent = textParts.map((p) => p.text).join("\n") || null;
957
+ }
958
+ const message = {
959
+ role,
960
+ content: messageContent
961
+ };
962
+ if (toolCalls.length > 0) {
963
+ message.tool_calls = toolCalls;
964
+ }
965
+ if (signature || thinkingText) {
966
+ message.thinking = { content: thinkingText || "", signature };
967
+ }
968
+ unifiedRequest.messages.push(message);
886
969
  }
887
970
  }
888
971
  if (Array.isArray(tools)) {
@@ -895,7 +978,7 @@ function transformRequestOut(request) {
895
978
  function: {
896
979
  name: funcDecl.name,
897
980
  description: funcDecl.description ?? "",
898
- parameters: funcDecl.parameters ?? {}
981
+ parameters: funcDecl.parameters ?? funcDecl.parametersJsonSchema ?? {}
899
982
  }
900
983
  });
901
984
  }
@@ -15,10 +15,11 @@ var OpenCodeGoTransformer = (_class = class {constructor() { _class.prototype.__
15
15
  async transformRequestIn(request, _provider, _context) {
16
16
  const messages = request.messages.map((m) => {
17
17
  const content = m.content;
18
- if (Array.isArray(content) && content.length === 1 && _optionalChain([content, 'access', _ => _[0], 'optionalAccess', _2 => _2.type]) === "text") {
19
- return { ...m, content: content[0].text };
20
- }
21
- return m;
18
+ const normalizedContent = Array.isArray(content) && content.length === 1 && _optionalChain([content, 'access', _ => _[0], 'optionalAccess', _2 => _2.type]) === "text" ? content[0].text : content;
19
+ const out2 = { role: m.role, content: normalizedContent };
20
+ if (m.tool_calls) out2.tool_calls = m.tool_calls;
21
+ if (m.tool_call_id) out2.tool_call_id = m.tool_call_id;
22
+ return out2;
22
23
  });
23
24
  const out = {
24
25
  model: request.model,