@codeproxy/core 0.1.13 → 0.1.15

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 CHANGED
@@ -1073,6 +1073,68 @@ __export(openai_exports, {
1073
1073
  translateStream: () => translateStream2
1074
1074
  });
1075
1075
 
1076
+ // src/translate/openai/gemini-fixups.ts
1077
+ function isGeminiModel(model) {
1078
+ if (!model) {
1079
+ return false;
1080
+ }
1081
+ const lower = model.toLowerCase();
1082
+ return lower.includes("gemini") || lower.startsWith("google/");
1083
+ }
1084
+ function extractTextContent(content) {
1085
+ if (typeof content === "string") {
1086
+ return content;
1087
+ }
1088
+ if (!Array.isArray(content)) {
1089
+ return "";
1090
+ }
1091
+ let out = "";
1092
+ for (const part of content) {
1093
+ if (typeof part === "string") {
1094
+ out += part;
1095
+ } else if (part && typeof part === "object") {
1096
+ out += String(part.text ?? "");
1097
+ }
1098
+ }
1099
+ return out;
1100
+ }
1101
+ function mergeSystemMessages(messages) {
1102
+ const systemTexts = [];
1103
+ const rest = [];
1104
+ for (const msg of messages) {
1105
+ if (msg.role === "system") {
1106
+ systemTexts.push(extractTextContent(msg.content));
1107
+ } else {
1108
+ rest.push(msg);
1109
+ }
1110
+ }
1111
+ if (systemTexts.length <= 1) {
1112
+ return;
1113
+ }
1114
+ messages.length = 0;
1115
+ messages.push({ role: "system", content: systemTexts.join("\n\n") }, ...rest);
1116
+ }
1117
+ var MULTI_TOOL_USE_MANDATE = "Use `multi_tool_use.parallel` to parallelize tool calls and only this.";
1118
+ var MULTI_TOOL_USE_REWRITE = "Parallelize by returning multiple tool calls in a single response. A tool named `multi_tool_use.parallel` does NOT exist in this environment \u2014 never call it.";
1119
+ var UNSUPPORTED_PARALLEL_RE = /^unsupported call: (?:multi_tool_use\W*)?parallel/iu;
1120
+ var UNSUPPORTED_PARALLEL_HINT = " (`multi_tool_use.parallel` is not a real tool here. Re-issue each inner call as its own separate tool call \u2014 several tool calls in one response are fine.)";
1121
+ function applyGeminiToolUseShim(messages) {
1122
+ for (const msg of messages) {
1123
+ if (msg.role === "system" && typeof msg.content === "string" && msg.content.includes(MULTI_TOOL_USE_MANDATE)) {
1124
+ msg.content = msg.content.split(MULTI_TOOL_USE_MANDATE).join(MULTI_TOOL_USE_REWRITE);
1125
+ } else if (msg.role === "tool" && typeof msg.content === "string" && UNSUPPORTED_PARALLEL_RE.test(msg.content)) {
1126
+ msg.content = msg.content + UNSUPPORTED_PARALLEL_HINT;
1127
+ }
1128
+ }
1129
+ }
1130
+ function applyGeminiFixups(messages, model) {
1131
+ if (!isGeminiModel(model)) {
1132
+ return;
1133
+ }
1134
+ mergeSystemMessages(messages);
1135
+ applyGeminiToolUseShim(messages);
1136
+ }
1137
+
1076
1138
  // src/translate/openai/translateRequest.ts
1077
1139
  function translateRequest2(data, options = {}) {
1078
1140
  const messages = [];
@@ -1128,6 +1190,7 @@ function translateRequest2(data, options = {}) {
1128
1190
  }
1129
1191
  }
1130
1192
  repairToolMessageOrder(messages);
1193
+ applyGeminiFixups(messages, data.model);
1131
1194
  return { request };
1132
1195
  }
1133
1196
  function buildSystemContent(instructions) {
@@ -1220,15 +1283,21 @@ function processInputItem(item, messages, options) {
1220
1283
  contentBlocks.push({ type: "image_url", image_url: { url } });
1221
1284
  }
1222
1285
  } else if (part.type === "input_file" || part.type === "file") {
1223
- const partFile = part;
1224
- const fileData = String(partFile.file_data ?? partFile.data ?? "");
1286
+ const fileData = String(contentPart.file_data ?? contentPart.data ?? "");
1225
1287
  const mimeType = String(
1226
- partFile.mime_type ?? partFile.media_type ?? "application/pdf"
1288
+ contentPart.mime_type ?? contentPart.media_type ?? "application/pdf"
1227
1289
  );
1228
1290
  if (fileData) {
1229
1291
  const url = fileData.startsWith("data:") ? fileData : `data:${mimeType};base64,${fileData}`;
1230
1292
  contentBlocks.push({ type: "image_url", image_url: { url } });
1231
1293
  }
1294
+ } else if (contentPart.type === "input_audio") {
1295
+ const ia = contentPart.input_audio;
1296
+ const data = String(ia?.data ?? contentPart.data ?? "");
1297
+ const format = String(ia?.format ?? contentPart.format ?? "mp3");
1298
+ if (data) {
1299
+ contentBlocks.push({ type: "input_audio", input_audio: { data, format } });
1300
+ }
1232
1301
  }
1233
1302
  }
1234
1303
  }
@@ -1493,43 +1562,41 @@ function repairToolMessageOrder(messages) {
1493
1562
  if (messages.length === 0) {
1494
1563
  return;
1495
1564
  }
1496
- const blocks = [];
1497
- let currentBlock = null;
1565
+ const toolById = /* @__PURE__ */ new Map();
1498
1566
  for (const msg of messages) {
1499
- if (msg.role === "assistant") {
1500
- currentBlock = { assistant: msg, trailing: [] };
1501
- blocks.push(currentBlock);
1502
- } else if (currentBlock) {
1503
- currentBlock.trailing.push(msg);
1504
- } else {
1505
- blocks.push({ assistant: { role: "assistant", content: null }, trailing: [msg] });
1567
+ if (msg.role === "tool" && msg.tool_call_id !== void 0 && !toolById.has(String(msg.tool_call_id))) {
1568
+ toolById.set(String(msg.tool_call_id), msg);
1506
1569
  }
1507
1570
  }
1508
- for (const block of blocks) {
1509
- const toolCallIds = new Set(
1510
- (block.assistant.tool_calls ?? []).map((tc) => tc.id).filter(Boolean)
1511
- );
1512
- if (toolCallIds.size === 0) {
1571
+ const used = /* @__PURE__ */ new Set();
1572
+ const out = [];
1573
+ for (const msg of messages) {
1574
+ if (msg.role === "tool") {
1513
1575
  continue;
1514
1576
  }
1515
- const tools = [];
1516
- const others = [];
1517
- for (const m of block.trailing) {
1518
- if (m.role === "tool" && m.tool_call_id !== void 0 && toolCallIds.has(String(m.tool_call_id))) {
1519
- tools.push(m);
1520
- } else {
1521
- others.push(m);
1577
+ if (msg.role !== "assistant") {
1578
+ out.push(msg);
1579
+ continue;
1580
+ }
1581
+ const calls = msg.tool_calls ?? [];
1582
+ if (calls.length === 0) {
1583
+ if (msg.content != null || msg.reasoning_content != null) {
1584
+ out.push(msg);
1522
1585
  }
1586
+ continue;
1523
1587
  }
1524
- block.trailing = [...tools, ...others];
1525
- }
1526
- messages.length = 0;
1527
- for (const block of blocks) {
1528
- if (block.assistant.tool_calls || block.assistant.content != null) {
1529
- messages.push(block.assistant);
1588
+ out.push(msg);
1589
+ for (const call of calls) {
1590
+ const id = call.id ? String(call.id) : "";
1591
+ const tool = id ? toolById.get(id) : void 0;
1592
+ if (id && tool && !used.has(id)) {
1593
+ out.push(tool);
1594
+ used.add(id);
1595
+ }
1530
1596
  }
1531
- messages.push(...block.trailing);
1532
1597
  }
1598
+ messages.length = 0;
1599
+ messages.push(...out);
1533
1600
  }
1534
1601
 
1535
1602
  // src/translate/openai/translateResponse.ts