@codeproxy/core 0.1.6 → 0.1.7

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.d.cts CHANGED
@@ -23,6 +23,8 @@ interface CreateResponsesFetchOptions {
23
23
  passthroughFetch?: typeof fetch;
24
24
  /** Drop image/file parts from user messages (e.g. DeepSeek text-only models). */
25
25
  dropImages?: boolean;
26
+ /** Fallback thought signature for Gemini OpenAI-compatible tool histories. */
27
+ fallbackThoughtSignature?: string;
26
28
  /** Optional callback to receive cache statistics. */
27
29
  onCacheStats?: (stats: CacheStats) => void;
28
30
  /** Override reasoning_effort sent to the upstream model (OpenAI Chat / Anthropic). */
@@ -94,6 +96,7 @@ interface ResponsesFunctionCallItem {
94
96
  call_id?: string;
95
97
  name?: string;
96
98
  arguments?: string | Record<string, unknown>;
99
+ thought_signature?: string;
97
100
  [key: string]: unknown;
98
101
  }
99
102
  interface ResponsesFunctionCallOutputItem {
@@ -239,6 +242,7 @@ interface ResponsesOutputFunctionCall {
239
242
  name?: string;
240
243
  arguments?: string;
241
244
  call_id?: string;
245
+ thought_signature?: string;
242
246
  action?: {
243
247
  type?: string;
244
248
  command?: string[];
@@ -488,10 +492,18 @@ declare namespace index$2 {
488
492
  interface OpenAiChatToolCall {
489
493
  id?: string;
490
494
  type?: 'function' | string;
495
+ extra_content?: {
496
+ google?: {
497
+ thought_signature?: string;
498
+ [key: string]: unknown;
499
+ };
500
+ [key: string]: unknown;
501
+ };
491
502
  function?: {
492
503
  name?: string;
493
504
  arguments?: string | Record<string, unknown>;
494
505
  };
506
+ thought_signature?: string;
495
507
  }
496
508
  interface OpenAiChatMessage {
497
509
  role: 'system' | 'user' | 'assistant' | 'tool' | string;
@@ -575,10 +587,12 @@ interface OpenAiChatStreamDeltaToolCall {
575
587
  index: number;
576
588
  id?: string;
577
589
  type?: string;
590
+ extra_content?: OpenAiChatToolCall['extra_content'];
578
591
  function?: {
579
592
  name?: string;
580
593
  arguments?: string | Record<string, unknown>;
581
594
  };
595
+ thought_signature?: string;
582
596
  }
583
597
  interface OpenAiChatStreamDelta {
584
598
  role?: string;
@@ -613,6 +627,8 @@ interface TranslateRequestOptions {
613
627
  /** If true, strip `strict` from function tools (some upstreams reject it). */
614
628
  /** If true, drop image/file parts from user messages (e.g. DeepSeek text-only models). */
615
629
  dropImages?: boolean;
630
+ /** Fallback signature for Gemini OpenAI histories that lack returned signatures. */
631
+ fallbackThoughtSignature?: string;
616
632
  }
617
633
  interface TranslateRequestResult {
618
634
  request: OpenAiChatRequest;
package/dist/index.d.ts CHANGED
@@ -23,6 +23,8 @@ interface CreateResponsesFetchOptions {
23
23
  passthroughFetch?: typeof fetch;
24
24
  /** Drop image/file parts from user messages (e.g. DeepSeek text-only models). */
25
25
  dropImages?: boolean;
26
+ /** Fallback thought signature for Gemini OpenAI-compatible tool histories. */
27
+ fallbackThoughtSignature?: string;
26
28
  /** Optional callback to receive cache statistics. */
27
29
  onCacheStats?: (stats: CacheStats) => void;
28
30
  /** Override reasoning_effort sent to the upstream model (OpenAI Chat / Anthropic). */
@@ -94,6 +96,7 @@ interface ResponsesFunctionCallItem {
94
96
  call_id?: string;
95
97
  name?: string;
96
98
  arguments?: string | Record<string, unknown>;
99
+ thought_signature?: string;
97
100
  [key: string]: unknown;
98
101
  }
99
102
  interface ResponsesFunctionCallOutputItem {
@@ -239,6 +242,7 @@ interface ResponsesOutputFunctionCall {
239
242
  name?: string;
240
243
  arguments?: string;
241
244
  call_id?: string;
245
+ thought_signature?: string;
242
246
  action?: {
243
247
  type?: string;
244
248
  command?: string[];
@@ -488,10 +492,18 @@ declare namespace index$2 {
488
492
  interface OpenAiChatToolCall {
489
493
  id?: string;
490
494
  type?: 'function' | string;
495
+ extra_content?: {
496
+ google?: {
497
+ thought_signature?: string;
498
+ [key: string]: unknown;
499
+ };
500
+ [key: string]: unknown;
501
+ };
491
502
  function?: {
492
503
  name?: string;
493
504
  arguments?: string | Record<string, unknown>;
494
505
  };
506
+ thought_signature?: string;
495
507
  }
496
508
  interface OpenAiChatMessage {
497
509
  role: 'system' | 'user' | 'assistant' | 'tool' | string;
@@ -575,10 +587,12 @@ interface OpenAiChatStreamDeltaToolCall {
575
587
  index: number;
576
588
  id?: string;
577
589
  type?: string;
590
+ extra_content?: OpenAiChatToolCall['extra_content'];
578
591
  function?: {
579
592
  name?: string;
580
593
  arguments?: string | Record<string, unknown>;
581
594
  };
595
+ thought_signature?: string;
582
596
  }
583
597
  interface OpenAiChatStreamDelta {
584
598
  role?: string;
@@ -613,6 +627,8 @@ interface TranslateRequestOptions {
613
627
  /** If true, strip `strict` from function tools (some upstreams reject it). */
614
628
  /** If true, drop image/file parts from user messages (e.g. DeepSeek text-only models). */
615
629
  dropImages?: boolean;
630
+ /** Fallback signature for Gemini OpenAI histories that lack returned signatures. */
631
+ fallbackThoughtSignature?: string;
616
632
  }
617
633
  interface TranslateRequestResult {
618
634
  request: OpenAiChatRequest;
package/dist/index.js CHANGED
@@ -525,9 +525,14 @@ function ensureEndsWithUser(messages) {
525
525
  return [...messages, { role: "user", content: [{ type: "text", text: "Continue." }] }];
526
526
  }
527
527
  function markBlocksForCache(blocks) {
528
+ let count = 0;
528
529
  for (const block of blocks) {
529
530
  if (!block.cache_control) {
530
531
  block.cache_control = { type: "ephemeral" };
532
+ count++;
533
+ if (count >= 3) {
534
+ break;
535
+ }
531
536
  }
532
537
  }
533
538
  return blocks;
@@ -836,6 +841,8 @@ var StreamTranslator = class {
836
841
  *finalize() {
837
842
  const items = [];
838
843
  if (this.textItem) {
844
+ this.textItem.status = "completed";
845
+ this.textItem.content[0].text = this.textBuffer;
839
846
  items.push({ index: this.textItemIndex, item: this.textItem });
840
847
  }
841
848
  for (const block of this.blocks.values()) {
@@ -947,15 +954,22 @@ var StreamTranslator = class {
947
954
  if (btype === "tool_use") {
948
955
  const outputIndex = this.outputCounter++;
949
956
  const callId = block.id ?? makeId("call");
957
+ const initialInput = typeof block.input === "object" && block.input !== null ? jsonStringifySafe(block.input) : "";
958
+ const hasInitialInput = initialInput !== "" && initialInput !== "{}";
950
959
  const item = {
951
960
  id: callId,
952
961
  type: "function_call",
953
962
  status: "in_progress",
954
963
  name: block.name ?? "",
955
- arguments: "",
964
+ arguments: hasInitialInput ? initialInput : "",
956
965
  call_id: callId
957
966
  };
958
- this.blocks.set(index, { type: "tool_use", outputIndex, item, buffer: "" });
967
+ this.blocks.set(index, {
968
+ type: "tool_use",
969
+ outputIndex,
970
+ item,
971
+ buffer: hasInitialInput ? initialInput : ""
972
+ });
959
973
  yield this.makeEvent("response.output_item.added", {
960
974
  response_id: this.responseId,
961
975
  output_index: outputIndex,
@@ -1074,7 +1088,7 @@ function translateRequest2(data, options = {}) {
1074
1088
  continue;
1075
1089
  }
1076
1090
  const rawItem = raw;
1077
- processInputItem(rawItem, messages, options.dropImages);
1091
+ processInputItem(rawItem, messages, options);
1078
1092
  }
1079
1093
  const request = {
1080
1094
  model: data.model,
@@ -1134,7 +1148,7 @@ function buildSystemContent(instructions) {
1134
1148
  }
1135
1149
  return out;
1136
1150
  }
1137
- function processInputItem(item, messages, dropImages) {
1151
+ function processInputItem(item, messages, options) {
1138
1152
  const itemType = String(item.type) || "message";
1139
1153
  const getLastAssistant = () => {
1140
1154
  const last = messages[messages.length - 1];
@@ -1196,7 +1210,7 @@ function processInputItem(item, messages, dropImages) {
1196
1210
  } else if (contentPart.type === "reasoning_text") {
1197
1211
  reasoningContent += String(contentPart.text ?? "");
1198
1212
  } else if (contentPart.type === "input_image" || contentPart.type === "image" || contentPart.type === "image_url") {
1199
- if (dropImages) {
1213
+ if (options.dropImages) {
1200
1214
  continue;
1201
1215
  }
1202
1216
  let url = "";
@@ -1271,7 +1285,7 @@ function processInputItem(item, messages, dropImages) {
1271
1285
  return;
1272
1286
  }
1273
1287
  if (itemType === "function_call" || itemType === "commandExecution" || itemType === "local_shell_call" || itemType === "fileChange" || itemType === "custom_tool_call" || itemType === "web_search_call") {
1274
- processToolCall(item, messages, getLastAssistant);
1288
+ processToolCall(item, messages, getLastAssistant, options.fallbackThoughtSignature);
1275
1289
  return;
1276
1290
  }
1277
1291
  if (itemType === "function_call_output" || itemType === "commandExecutionOutput" || itemType === "fileChangeOutput" || itemType === "custom_tool_call_output") {
@@ -1279,7 +1293,7 @@ function processInputItem(item, messages, dropImages) {
1279
1293
  return;
1280
1294
  }
1281
1295
  }
1282
- function processToolCall(item, messages, getLastAssistant) {
1296
+ function processToolCall(item, messages, getLastAssistant, fallbackThoughtSignature) {
1283
1297
  const callId = String(item.call_id ?? "") || String(item.id ?? "") || makeId("call");
1284
1298
  let name = item.name === void 0 ? void 0 : String(item.name);
1285
1299
  const itemType = item.type === void 0 ? void 0 : String(item.type);
@@ -1325,16 +1339,18 @@ function processToolCall(item, messages, getLastAssistant) {
1325
1339
  if (!amsg.tool_calls) {
1326
1340
  amsg.tool_calls = [];
1327
1341
  }
1328
- amsg.tool_calls.push({
1342
+ const toolCall = {
1329
1343
  id: callId,
1330
1344
  type: "function",
1331
1345
  function: { name, arguments: argsStr }
1332
- });
1333
- const sig = item.thought_signature;
1346
+ };
1347
+ const sig = item.thought_signature ?? fallbackThoughtSignature;
1334
1348
  const thought = item.thought;
1335
1349
  if (typeof sig === "string" && sig) {
1350
+ toolCall.extra_content = { google: { thought_signature: sig } };
1336
1351
  amsg.thought_signature = sig;
1337
1352
  }
1353
+ amsg.tool_calls.push(toolCall);
1338
1354
  if (typeof thought === "string" && thought) {
1339
1355
  amsg.reasoning_content = (amsg.reasoning_content ?? "") + thought;
1340
1356
  }
@@ -1538,6 +1554,10 @@ function mapToolCallToOutput(tc) {
1538
1554
  arguments: args,
1539
1555
  call_id: callId
1540
1556
  };
1557
+ const thoughtSignature = getThoughtSignature(tc);
1558
+ if (thoughtSignature) {
1559
+ item.thought_signature = thoughtSignature;
1560
+ }
1541
1561
  if (SHELL_TOOL_NAMES3.has(name)) {
1542
1562
  item.type = "local_shell_call";
1543
1563
  const parsed = safeJsonParse(args);
@@ -1545,6 +1565,10 @@ function mapToolCallToOutput(tc) {
1545
1565
  }
1546
1566
  return item;
1547
1567
  }
1568
+ function getThoughtSignature(tc) {
1569
+ const sig = tc.extra_content?.google?.thought_signature ?? tc.thought_signature;
1570
+ return typeof sig === "string" && sig ? sig : void 0;
1571
+ }
1548
1572
 
1549
1573
  // src/translate/openai/translateStream.ts
1550
1574
  var SHELL_TOOL_NAMES4 = /* @__PURE__ */ new Set(["shell", "container.exec", "shell_command"]);
@@ -1647,6 +1671,10 @@ var StreamTranslator2 = class {
1647
1671
  });
1648
1672
  }
1649
1673
  const fn = tc.function;
1674
+ const thoughtSignature = getThoughtSignature2(tc);
1675
+ if (thoughtSignature) {
1676
+ state.item.thought_signature = thoughtSignature;
1677
+ }
1650
1678
  if (fn?.name) {
1651
1679
  state.item.name = (state.item.name ?? "") + fn.name;
1652
1680
  }
@@ -1758,6 +1786,10 @@ var StreamTranslator2 = class {
1758
1786
  };
1759
1787
  }
1760
1788
  };
1789
+ function getThoughtSignature2(tc) {
1790
+ const sig = tc.extra_content?.google?.thought_signature ?? tc.thought_signature;
1791
+ return typeof sig === "string" && sig ? sig : void 0;
1792
+ }
1761
1793
 
1762
1794
  // src/fetch.ts
1763
1795
  function createResponsesFetch(options) {
@@ -1765,7 +1797,7 @@ function createResponsesFetch(options) {
1765
1797
  throw new Error("baseUrl is required");
1766
1798
  }
1767
1799
  const rawFormat = options.upstreamFormat;
1768
- const format = rawFormat ? normalizeFormat(rawFormat) : inferFormatFromUrl(options.baseUrl) ?? "openai-chat";
1800
+ const format = rawFormat ? normalizeFormat(rawFormat) : inferFormatFromUrl(options.baseUrl) ?? inferFormatFromModel(options.model) ?? "openai-chat";
1769
1801
  if (!format) {
1770
1802
  throw new Error(
1771
1803
  `Unsupported upstream format: ${options.upstreamFormat}. Use 'anthropic' or 'openai-chat'`
@@ -1936,7 +1968,8 @@ async function handleResponses(request, format, options, baseFetch, incomingHead
1936
1968
  options.baseUrl,
1937
1969
  dropImages,
1938
1970
  options.reasoning_effort,
1939
- options.thinking
1971
+ options.thinking,
1972
+ options.fallbackThoughtSignature
1940
1973
  );
1941
1974
  const upstreamHeaders = buildUpstreamHeaders(format, options, incomingHeaders);
1942
1975
  const upstream = await baseFetch(resolvedUrl, {
@@ -1992,7 +2025,7 @@ function buildRequestMetadata(request, temperature, top_p) {
1992
2025
  metadata: request.metadata ?? {}
1993
2026
  };
1994
2027
  }
1995
- function buildUpstreamBody(request, format, streaming, baseUrl, dropImages, reasoning_effort, thinking) {
2028
+ function buildUpstreamBody(request, format, streaming, baseUrl, dropImages, reasoning_effort, thinking, fallbackThoughtSignature) {
1996
2029
  if (format === "anthropic") {
1997
2030
  const { request: ar } = translateRequest(request);
1998
2031
  ar.stream = streaming;
@@ -2023,7 +2056,10 @@ function buildUpstreamBody(request, format, streaming, baseUrl, dropImages, reas
2023
2056
  requestMetadata: buildRequestMetadata(request, ar.temperature, ar.top_p)
2024
2057
  };
2025
2058
  }
2026
- const { request: cr } = translateRequest2(request, { dropImages });
2059
+ const { request: cr } = translateRequest2(request, {
2060
+ dropImages,
2061
+ fallbackThoughtSignature
2062
+ });
2027
2063
  cr.stream = streaming;
2028
2064
  if (streaming) {
2029
2065
  cr.stream_options = { include_usage: true };