heibaiapi 0.6.1 → 0.6.2

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/main.js CHANGED
@@ -17,17 +17,21 @@ import { cors } from "hono/cors";
17
17
  import { logger } from "hono/logger";
18
18
  import { streamSSE } from "hono/streaming";
19
19
  import { events } from "fetch-event-stream";
20
+ import fs$1 from "node:fs";
20
21
 
21
22
  //#region src/lib/paths.ts
22
- const APP_DIR = path.join(os.homedir(), ".local", "share", "heibaiapi");
23
+ const APP_DIR = path.join(os.homedir(), ".local", "share", "copilot-api");
23
24
  const GITHUB_TOKEN_PATH = path.join(APP_DIR, "github_token");
25
+ const CONFIG_PATH = path.join(APP_DIR, "config.json");
24
26
  const PATHS = {
25
27
  APP_DIR,
26
- GITHUB_TOKEN_PATH
28
+ GITHUB_TOKEN_PATH,
29
+ CONFIG_PATH
27
30
  };
28
31
  async function ensurePaths() {
29
32
  await fs.mkdir(PATHS.APP_DIR, { recursive: true });
30
33
  await ensureFile(PATHS.GITHUB_TOKEN_PATH);
34
+ await ensureFile(PATHS.CONFIG_PATH);
31
35
  }
32
36
  async function ensureFile(filePath) {
33
37
  try {
@@ -401,7 +405,7 @@ async function getDebugInfo() {
401
405
  };
402
406
  }
403
407
  function printDebugInfoPlain(info) {
404
- consola.info(`heibaiapi debug
408
+ consola.info(`copilot-api debug
405
409
 
406
410
  Version: ${info.version}
407
411
  Runtime: ${info.runtime.name} ${info.runtime.version} (${info.runtime.platform} ${info.runtime.arch})
@@ -487,8 +491,7 @@ function getShell() {
487
491
  const { platform, ppid, env } = process$1;
488
492
  if (platform === "win32") {
489
493
  try {
490
- const command = `wmic process get ParentProcessId,Name | findstr "${ppid}"`;
491
- if (execSync(command, { stdio: "pipe" }).toString().toLowerCase().includes("powershell.exe")) return "powershell";
494
+ if (execSync(`wmic process get ParentProcessId,Name | findstr "${ppid}"`, { stdio: "pipe" }).toString().toLowerCase().includes("powershell.exe")) return "powershell";
492
495
  } catch {
493
496
  return "cmd";
494
497
  }
@@ -748,8 +751,7 @@ const numTokensForTools = (tools, encoder, constants) => {
748
751
  * Calculate the token count of messages, supporting multiple GPT encoders
749
752
  */
750
753
  const getTokenCount = async (payload, model) => {
751
- const tokenizer = getTokenizerFromModel(model);
752
- const encoder = await getEncodeChatFunction(tokenizer);
754
+ const encoder = await getEncodeChatFunction(getTokenizerFromModel(model));
753
755
  const simplifiedMessages = payload.messages;
754
756
  const inputMessages = simplifiedMessages.filter((msg) => msg.role !== "assistant");
755
757
  const outputMessages = simplifiedMessages.filter((msg) => msg.role === "assistant");
@@ -853,8 +855,7 @@ const createEmbeddings = async (payload) => {
853
855
  const embeddingRoutes = new Hono();
854
856
  embeddingRoutes.post("/", async (c) => {
855
857
  try {
856
- const paylod = await c.req.json();
857
- const response = await createEmbeddings(paylod);
858
+ const response = await createEmbeddings(await c.req.json());
858
859
  return c.json(response);
859
860
  } catch (error) {
860
861
  return await forwardError(c, error);
@@ -1112,6 +1113,60 @@ const createResponses = async (payload, { vision, initiator }) => {
1112
1113
  return await response.json();
1113
1114
  };
1114
1115
 
1116
+ //#endregion
1117
+ //#region src/lib/config.ts
1118
+ const defaultConfig = { extraPrompts: { "gpt-5-codex": `
1119
+ ## Tool use
1120
+ - You have access to many tools. If a tool exists to perform a specific task, you MUST use that tool instead of running a terminal command to perform that task.
1121
+ ### Bash tool
1122
+ When using the Bash tool, follow these rules:
1123
+ - always run_in_background set to false, unless you are running a long-running command (e.g., a server or a watch command).
1124
+ ### BashOutput tool
1125
+ When using the BashOutput tool, follow these rules:
1126
+ - Only Bash Tool run_in_background set to true, Use BashOutput to read the output later
1127
+ ### TodoWrite tool
1128
+ When using the TodoWrite tool, follow these rules:
1129
+ - Skip using the TodoWrite tool for tasks with three or fewer steps.
1130
+ - Do not make single-step todo lists.
1131
+ - When you made a todo, update it after having performed one of the sub-tasks that you shared on the todo list.
1132
+ ## Special user requests
1133
+ - If the user makes a simple request (such as asking for the time) which you can fulfill by running a terminal command (such as 'date'), you should do so.
1134
+ ` } };
1135
+ let cachedConfig = null;
1136
+ function ensureConfigFile() {
1137
+ try {
1138
+ fs$1.accessSync(PATHS.CONFIG_PATH, fs$1.constants.R_OK | fs$1.constants.W_OK);
1139
+ } catch {
1140
+ fs$1.writeFileSync(PATHS.CONFIG_PATH, `${JSON.stringify(defaultConfig, null, 2)}\n`, "utf8");
1141
+ try {
1142
+ fs$1.chmodSync(PATHS.CONFIG_PATH, 384);
1143
+ } catch {
1144
+ return;
1145
+ }
1146
+ }
1147
+ }
1148
+ function readConfigFromDisk() {
1149
+ ensureConfigFile();
1150
+ try {
1151
+ const raw = fs$1.readFileSync(PATHS.CONFIG_PATH, "utf8");
1152
+ if (!raw.trim()) {
1153
+ fs$1.writeFileSync(PATHS.CONFIG_PATH, `${JSON.stringify(defaultConfig, null, 2)}\n`, "utf8");
1154
+ return defaultConfig;
1155
+ }
1156
+ return JSON.parse(raw);
1157
+ } catch (error) {
1158
+ consola.error("Failed to read config file, using default config", error);
1159
+ return defaultConfig;
1160
+ }
1161
+ }
1162
+ function getConfig() {
1163
+ if (!cachedConfig) cachedConfig = readConfigFromDisk();
1164
+ return cachedConfig;
1165
+ }
1166
+ function getExtraPromptForModel(model) {
1167
+ return getConfig().extraPrompts?.[model] ?? "";
1168
+ }
1169
+
1115
1170
  //#endregion
1116
1171
  //#region src/routes/messages/responses-translation.ts
1117
1172
  const MESSAGE_TYPE = "message";
@@ -1124,7 +1179,7 @@ const translateAnthropicMessagesToResponsesPayload = (payload) => {
1124
1179
  return {
1125
1180
  model: payload.model,
1126
1181
  input,
1127
- instructions: translateSystemPrompt(payload.system),
1182
+ instructions: translateSystemPrompt(payload.system, payload.model),
1128
1183
  temperature: payload.temperature ?? null,
1129
1184
  top_p: payload.top_p ?? null,
1130
1185
  max_output_tokens: payload.max_tokens,
@@ -1138,7 +1193,7 @@ const translateAnthropicMessagesToResponsesPayload = (payload) => {
1138
1193
  parallel_tool_calls: true,
1139
1194
  reasoning: {
1140
1195
  effort: "high",
1141
- summary: "auto"
1196
+ summary: "detailed"
1142
1197
  },
1143
1198
  include: ["reasoning.encrypted_content"]
1144
1199
  };
@@ -1175,7 +1230,7 @@ const translateAssistantMessage = (message) => {
1175
1230
  items.push(createFunctionToolCall(block));
1176
1231
  continue;
1177
1232
  }
1178
- if (block.type === "thinking") {
1233
+ if (block.type === "thinking" && block.signature && block.signature.includes("@")) {
1179
1234
  flushPendingContent("assistant", pendingContent, items);
1180
1235
  items.push(createReasoningContent(block));
1181
1236
  continue;
@@ -1201,7 +1256,7 @@ const translateAssistantContentBlock = (block) => {
1201
1256
  };
1202
1257
  const flushPendingContent = (role, pendingContent, target) => {
1203
1258
  if (pendingContent.length === 0) return;
1204
- const messageContent = pendingContent.length === 1 && isPlainText(pendingContent[0]) ? pendingContent[0].text : [...pendingContent];
1259
+ const messageContent = [...pendingContent];
1205
1260
  target.push(createMessage(role, messageContent));
1206
1261
  pendingContent.length = 0;
1207
1262
  };
@@ -1220,16 +1275,22 @@ const createOutPutTextContent = (text) => ({
1220
1275
  });
1221
1276
  const createImageContent = (block) => ({
1222
1277
  type: "input_image",
1223
- image_url: `data:${block.source.media_type};base64,${block.source.data}`
1224
- });
1225
- const createReasoningContent = (block) => ({
1226
- type: "reasoning",
1227
- summary: [{
1228
- type: "summary_text",
1229
- text: block.thinking
1230
- }],
1231
- encrypted_content: block.signature
1278
+ image_url: `data:${block.source.media_type};base64,${block.source.data}`,
1279
+ detail: "auto"
1232
1280
  });
1281
+ const createReasoningContent = (block) => {
1282
+ const array = block.signature.split("@");
1283
+ const signature = array[0];
1284
+ return {
1285
+ id: array[1],
1286
+ type: "reasoning",
1287
+ summary: [{
1288
+ type: "summary_text",
1289
+ text: block.thinking
1290
+ }],
1291
+ encrypted_content: signature
1292
+ };
1293
+ };
1233
1294
  const createFunctionToolCall = (block) => ({
1234
1295
  type: "function_call",
1235
1296
  call_id: block.id,
@@ -1243,25 +1304,12 @@ const createFunctionCallOutput = (block) => ({
1243
1304
  output: convertToolResultContent(block.content),
1244
1305
  status: block.is_error ? "incomplete" : "completed"
1245
1306
  });
1246
- const translateSystemPrompt = (system) => {
1307
+ const translateSystemPrompt = (system, model) => {
1247
1308
  if (!system) return null;
1248
- const toolUsePrompt = `
1249
- ## Tool use
1250
- - You have access to many tools. If a tool exists to perform a specific task, you MUST use that tool instead of running a terminal command to perform that task.
1251
- ### Bash tool
1252
- When using the Bash tool, follow these rules:
1253
- - always run_in_background set to false, unless you are running a long-running command (e.g., a server or a watch command).
1254
- ### BashOutput tool
1255
- When using the BashOutput tool, follow these rules:
1256
- - Only Bash Tool run_in_background set to true, Use BashOutput to read the output later
1257
- ### TodoWrite tool
1258
- When using the TodoWrite tool, follow these rules:
1259
- - Skip using the TodoWrite tool for simple or straightforward tasks (roughly the easiest 25%).
1260
- - Do not make single-step todo lists.
1261
- - When you made a todo, update it after having performed one of the sub-tasks that you shared on the todo list.`;
1262
- if (typeof system === "string") return system + toolUsePrompt;
1309
+ const extraPrompt = getExtraPromptForModel(model);
1310
+ if (typeof system === "string") return system + extraPrompt;
1263
1311
  const text = system.map((block, index) => {
1264
- if (index === 0) return block.text + toolUsePrompt;
1312
+ if (index === 0) return block.text + extraPrompt;
1265
1313
  return block.text;
1266
1314
  }).join(" ");
1267
1315
  return text.length > 0 ? text : null;
@@ -1277,22 +1325,18 @@ const convertAnthropicTools = (tools) => {
1277
1325
  }));
1278
1326
  };
1279
1327
  const convertAnthropicToolChoice = (choice) => {
1280
- if (!choice) return;
1328
+ if (!choice) return "auto";
1281
1329
  switch (choice.type) {
1282
1330
  case "auto": return "auto";
1283
1331
  case "any": return "required";
1284
1332
  case "tool": return choice.name ? {
1285
1333
  type: "function",
1286
1334
  name: choice.name
1287
- } : void 0;
1335
+ } : "auto";
1288
1336
  case "none": return "none";
1289
- default: return;
1337
+ default: return "auto";
1290
1338
  }
1291
1339
  };
1292
- const isPlainText = (content) => {
1293
- if (typeof content !== "object") return false;
1294
- return "text" in content && typeof content.text === "string" && !("image_url" in content);
1295
- };
1296
1340
  const translateResponsesResultToAnthropic = (response) => {
1297
1341
  const contentBlocks = mapOutputToAnthropicContent(response.output);
1298
1342
  const usage = mapResponsesUsage(response);
@@ -1318,7 +1362,7 @@ const mapOutputToAnthropicContent = (output) => {
1318
1362
  if (thinkingText.length > 0) contentBlocks.push({
1319
1363
  type: "thinking",
1320
1364
  thinking: thinkingText,
1321
- signature: item.encrypted_content ?? ""
1365
+ signature: (item.encrypted_content ?? "") + "@" + item.id
1322
1366
  });
1323
1367
  break;
1324
1368
  }
@@ -1381,7 +1425,7 @@ const extractReasoningText = (item) => {
1381
1425
  return segments.join("").trim();
1382
1426
  };
1383
1427
  const createToolUseContentBlock = (call) => {
1384
- const toolId = call.call_id ?? call.id;
1428
+ const toolId = call.call_id;
1385
1429
  if (!call.name || !toolId) return null;
1386
1430
  const input = parseFunctionCallArguments(call.arguments);
1387
1431
  return {
@@ -1418,23 +1462,21 @@ const mapResponsesStopReason = (response) => {
1418
1462
  if (status === "incomplete") {
1419
1463
  if (incompleteDetails?.reason === "max_output_tokens") return "max_tokens";
1420
1464
  if (incompleteDetails?.reason === "content_filter") return "end_turn";
1421
- if (incompleteDetails?.reason === "tool_use") return "tool_use";
1422
1465
  }
1423
1466
  return null;
1424
1467
  };
1425
1468
  const mapResponsesUsage = (response) => {
1426
1469
  const inputTokens = response.usage?.input_tokens ?? 0;
1427
1470
  const outputTokens = response.usage?.output_tokens ?? 0;
1428
- const inputCachedTokens = response.usage?.input_tokens_details?.cached_tokens;
1429
1471
  return {
1430
- input_tokens: inputTokens - (inputCachedTokens ?? 0),
1472
+ input_tokens: inputTokens - (response.usage?.input_tokens_details?.cached_tokens ?? 0),
1431
1473
  output_tokens: outputTokens,
1432
1474
  ...response.usage?.input_tokens_details?.cached_tokens !== void 0 && { cache_read_input_tokens: response.usage.input_tokens_details.cached_tokens }
1433
1475
  };
1434
1476
  };
1435
- const isRecord$1 = (value) => typeof value === "object" && value !== null;
1436
- const isResponseOutputText = (block) => isRecord$1(block) && "type" in block && block.type === "output_text";
1437
- const isResponseOutputRefusal = (block) => isRecord$1(block) && "type" in block && block.type === "refusal";
1477
+ const isRecord = (value) => typeof value === "object" && value !== null;
1478
+ const isResponseOutputText = (block) => isRecord(block) && "type" in block && block.type === "output_text";
1479
+ const isResponseOutputRefusal = (block) => isRecord(block) && "type" in block && block.type === "refusal";
1438
1480
  const parseUserId = (userId) => {
1439
1481
  if (!userId || typeof userId !== "string") return {
1440
1482
  safetyIdentifier: null,
@@ -1443,10 +1485,9 @@ const parseUserId = (userId) => {
1443
1485
  const userMatch = userId.match(/user_([^_]+)_account/);
1444
1486
  const safetyIdentifier = userMatch ? userMatch[1] : null;
1445
1487
  const sessionMatch = userId.match(/_session_(.+)$/);
1446
- const promptCacheKey = sessionMatch ? sessionMatch[1] : null;
1447
1488
  return {
1448
1489
  safetyIdentifier,
1449
- promptCacheKey
1490
+ promptCacheKey: sessionMatch ? sessionMatch[1] : null
1450
1491
  };
1451
1492
  };
1452
1493
  const convertToolResultContent = (content) => {
@@ -1476,19 +1517,17 @@ const createResponsesStreamState = () => ({
1476
1517
  blockIndexByKey: /* @__PURE__ */ new Map(),
1477
1518
  openBlocks: /* @__PURE__ */ new Set(),
1478
1519
  blockHasDelta: /* @__PURE__ */ new Set(),
1479
- functionCallStateByOutputIndex: /* @__PURE__ */ new Map(),
1480
- functionCallOutputIndexByItemId: /* @__PURE__ */ new Map()
1520
+ functionCallStateByOutputIndex: /* @__PURE__ */ new Map()
1481
1521
  });
1482
1522
  const translateResponsesStreamEvent = (rawEvent, state$1) => {
1483
- const eventType = typeof rawEvent.type === "string" ? rawEvent.type : void 0;
1484
- if (!eventType) return [];
1523
+ const eventType = rawEvent.type;
1485
1524
  switch (eventType) {
1486
1525
  case "response.created": return handleResponseCreated(rawEvent, state$1);
1526
+ case "response.output_item.added": return handleOutputItemAdded(rawEvent, state$1);
1487
1527
  case "response.reasoning_summary_text.delta": return handleReasoningSummaryTextDelta(rawEvent, state$1);
1488
1528
  case "response.output_text.delta": return handleOutputTextDelta(rawEvent, state$1);
1489
- case "response.reasoning_summary_part.done": return handleReasoningSummaryPartDone(rawEvent, state$1);
1529
+ case "response.reasoning_summary_text.done": return handleReasoningSummaryTextDone(rawEvent, state$1);
1490
1530
  case "response.output_text.done": return handleOutputTextDone(rawEvent, state$1);
1491
- case "response.output_item.added": return handleOutputItemAdded(rawEvent, state$1);
1492
1531
  case "response.output_item.done": return handleOutputItemDone(rawEvent, state$1);
1493
1532
  case "response.function_call_arguments.delta": return handleFunctionCallArgumentsDelta(rawEvent, state$1);
1494
1533
  case "response.function_call_arguments.done": return handleFunctionCallArgumentsDone(rawEvent, state$1);
@@ -1496,21 +1535,19 @@ const translateResponsesStreamEvent = (rawEvent, state$1) => {
1496
1535
  case "response.incomplete": return handleResponseCompleted(rawEvent, state$1);
1497
1536
  case "response.failed": return handleResponseFailed(rawEvent, state$1);
1498
1537
  case "error": return handleErrorEvent(rawEvent, state$1);
1499
- default: return [];
1538
+ default:
1539
+ consola.debug("Unknown Responses stream event type:", eventType);
1540
+ return [];
1500
1541
  }
1501
1542
  };
1502
1543
  const handleResponseCreated = (rawEvent, state$1) => {
1503
- const response = toResponsesResult(rawEvent.response);
1504
- if (response) cacheResponseMetadata(state$1, response);
1505
- return ensureMessageStart(state$1, response);
1544
+ return messageStart(state$1, rawEvent.response);
1506
1545
  };
1507
1546
  const handleOutputItemAdded = (rawEvent, state$1) => {
1508
- const response = toResponsesResult(rawEvent.response);
1509
- const events$1 = ensureMessageStart(state$1, response);
1510
- const functionCallDetails = extractFunctionCallDetails(rawEvent, state$1);
1547
+ const events$1 = new Array();
1548
+ const functionCallDetails = extractFunctionCallDetails(rawEvent);
1511
1549
  if (!functionCallDetails) return events$1;
1512
- const { outputIndex, toolCallId, name, initialArguments, itemId } = functionCallDetails;
1513
- if (itemId) state$1.functionCallOutputIndexByItemId.set(itemId, outputIndex);
1550
+ const { outputIndex, toolCallId, name, initialArguments } = functionCallDetails;
1514
1551
  const blockIndex = openFunctionCallBlock(state$1, {
1515
1552
  outputIndex,
1516
1553
  toolCallId,
@@ -1531,13 +1568,12 @@ const handleOutputItemAdded = (rawEvent, state$1) => {
1531
1568
  return events$1;
1532
1569
  };
1533
1570
  const handleOutputItemDone = (rawEvent, state$1) => {
1534
- const events$1 = ensureMessageStart(state$1);
1535
- const item = isRecord(rawEvent.item) ? rawEvent.item : void 0;
1536
- if (!item) return events$1;
1537
- if ((typeof item.type === "string" ? item.type : void 0) !== "reasoning") return events$1;
1538
- const outputIndex = toNumber(rawEvent.output_index);
1571
+ const events$1 = new Array();
1572
+ const item = rawEvent.item;
1573
+ if (item.type !== "reasoning") return events$1;
1574
+ const outputIndex = rawEvent.output_index;
1539
1575
  const blockIndex = openThinkingBlockIfNeeded(state$1, outputIndex, events$1);
1540
- const signature = typeof item.encrypted_content === "string" ? item.encrypted_content : "";
1576
+ const signature = (item.encrypted_content ?? "") + "@" + item.id;
1541
1577
  if (signature) {
1542
1578
  events$1.push({
1543
1579
  type: "content_block_delta",
@@ -1553,11 +1589,9 @@ const handleOutputItemDone = (rawEvent, state$1) => {
1553
1589
  return events$1;
1554
1590
  };
1555
1591
  const handleFunctionCallArgumentsDelta = (rawEvent, state$1) => {
1556
- const events$1 = ensureMessageStart(state$1);
1557
- const outputIndex = resolveFunctionCallOutputIndex(state$1, rawEvent);
1558
- if (outputIndex === void 0) return events$1;
1559
- const deltaText = typeof rawEvent.delta === "string" ? rawEvent.delta : "";
1560
- if (!deltaText) return events$1;
1592
+ const events$1 = new Array();
1593
+ const outputIndex = rawEvent.output_index;
1594
+ const deltaText = rawEvent.delta;
1561
1595
  const blockIndex = openFunctionCallBlock(state$1, {
1562
1596
  outputIndex,
1563
1597
  events: events$1
@@ -1574,9 +1608,8 @@ const handleFunctionCallArgumentsDelta = (rawEvent, state$1) => {
1574
1608
  return events$1;
1575
1609
  };
1576
1610
  const handleFunctionCallArgumentsDone = (rawEvent, state$1) => {
1577
- const events$1 = ensureMessageStart(state$1);
1578
- const outputIndex = resolveFunctionCallOutputIndex(state$1, rawEvent);
1579
- if (outputIndex === void 0) return events$1;
1611
+ const events$1 = new Array();
1612
+ const outputIndex = rawEvent.output_index;
1580
1613
  const blockIndex = openFunctionCallBlock(state$1, {
1581
1614
  outputIndex,
1582
1615
  events: events$1
@@ -1594,18 +1627,14 @@ const handleFunctionCallArgumentsDone = (rawEvent, state$1) => {
1594
1627
  state$1.blockHasDelta.add(blockIndex);
1595
1628
  }
1596
1629
  closeBlockIfOpen(state$1, blockIndex, events$1);
1597
- const existingState = state$1.functionCallStateByOutputIndex.get(outputIndex);
1598
- if (existingState) state$1.functionCallOutputIndexByItemId.delete(existingState.toolCallId);
1599
1630
  state$1.functionCallStateByOutputIndex.delete(outputIndex);
1600
- const itemId = toNonEmptyString(rawEvent.item_id);
1601
- if (itemId) state$1.functionCallOutputIndexByItemId.delete(itemId);
1602
1631
  return events$1;
1603
1632
  };
1604
1633
  const handleOutputTextDelta = (rawEvent, state$1) => {
1605
- const events$1 = ensureMessageStart(state$1);
1606
- const outputIndex = toNumber(rawEvent.output_index);
1607
- const contentIndex = toNumber(rawEvent.content_index);
1608
- const deltaText = typeof rawEvent.delta === "string" ? rawEvent.delta : "";
1634
+ const events$1 = new Array();
1635
+ const outputIndex = rawEvent.output_index;
1636
+ const contentIndex = rawEvent.content_index;
1637
+ const deltaText = rawEvent.delta;
1609
1638
  if (!deltaText) return events$1;
1610
1639
  const blockIndex = openTextBlockIfNeeded(state$1, {
1611
1640
  outputIndex,
@@ -1624,10 +1653,9 @@ const handleOutputTextDelta = (rawEvent, state$1) => {
1624
1653
  return events$1;
1625
1654
  };
1626
1655
  const handleReasoningSummaryTextDelta = (rawEvent, state$1) => {
1627
- const events$1 = ensureMessageStart(state$1);
1628
- const outputIndex = toNumber(rawEvent.output_index);
1629
- const deltaText = typeof rawEvent.delta === "string" ? rawEvent.delta : "";
1630
- if (!deltaText) return events$1;
1656
+ const outputIndex = rawEvent.output_index;
1657
+ const deltaText = rawEvent.delta;
1658
+ const events$1 = new Array();
1631
1659
  const blockIndex = openThinkingBlockIfNeeded(state$1, outputIndex, events$1);
1632
1660
  events$1.push({
1633
1661
  type: "content_block_delta",
@@ -1640,11 +1668,10 @@ const handleReasoningSummaryTextDelta = (rawEvent, state$1) => {
1640
1668
  state$1.blockHasDelta.add(blockIndex);
1641
1669
  return events$1;
1642
1670
  };
1643
- const handleReasoningSummaryPartDone = (rawEvent, state$1) => {
1644
- const events$1 = ensureMessageStart(state$1);
1645
- const outputIndex = toNumber(rawEvent.output_index);
1646
- const part = isRecord(rawEvent.part) ? rawEvent.part : void 0;
1647
- const text = part && typeof part.text === "string" ? part.text : "";
1671
+ const handleReasoningSummaryTextDone = (rawEvent, state$1) => {
1672
+ const outputIndex = rawEvent.output_index;
1673
+ const text = rawEvent.text;
1674
+ const events$1 = new Array();
1648
1675
  const blockIndex = openThinkingBlockIfNeeded(state$1, outputIndex, events$1);
1649
1676
  if (text && !state$1.blockHasDelta.has(blockIndex)) events$1.push({
1650
1677
  type: "content_block_delta",
@@ -1657,10 +1684,10 @@ const handleReasoningSummaryPartDone = (rawEvent, state$1) => {
1657
1684
  return events$1;
1658
1685
  };
1659
1686
  const handleOutputTextDone = (rawEvent, state$1) => {
1660
- const events$1 = ensureMessageStart(state$1);
1661
- const outputIndex = toNumber(rawEvent.output_index);
1662
- const contentIndex = toNumber(rawEvent.content_index);
1663
- const text = typeof rawEvent.text === "string" ? rawEvent.text : "";
1687
+ const events$1 = new Array();
1688
+ const outputIndex = rawEvent.output_index;
1689
+ const contentIndex = rawEvent.content_index;
1690
+ const text = rawEvent.text;
1664
1691
  const blockIndex = openTextBlockIfNeeded(state$1, {
1665
1692
  outputIndex,
1666
1693
  contentIndex,
@@ -1678,35 +1705,26 @@ const handleOutputTextDone = (rawEvent, state$1) => {
1678
1705
  return events$1;
1679
1706
  };
1680
1707
  const handleResponseCompleted = (rawEvent, state$1) => {
1681
- const response = toResponsesResult(rawEvent.response);
1682
- const events$1 = ensureMessageStart(state$1, response);
1708
+ const response = rawEvent.response;
1709
+ const events$1 = new Array();
1683
1710
  closeAllOpenBlocks(state$1, events$1);
1684
- if (response) {
1685
- const anthropic = translateResponsesResultToAnthropic(response);
1686
- events$1.push({
1687
- type: "message_delta",
1688
- delta: {
1689
- stop_reason: anthropic.stop_reason,
1690
- stop_sequence: anthropic.stop_sequence
1691
- },
1692
- usage: anthropic.usage
1693
- });
1694
- } else events$1.push({
1711
+ const anthropic = translateResponsesResultToAnthropic(response);
1712
+ events$1.push({
1695
1713
  type: "message_delta",
1696
1714
  delta: {
1697
- stop_reason: null,
1698
- stop_sequence: null
1699
- }
1700
- });
1701
- events$1.push({ type: "message_stop" });
1715
+ stop_reason: anthropic.stop_reason,
1716
+ stop_sequence: anthropic.stop_sequence
1717
+ },
1718
+ usage: anthropic.usage
1719
+ }, { type: "message_stop" });
1702
1720
  state$1.messageCompleted = true;
1703
1721
  return events$1;
1704
1722
  };
1705
1723
  const handleResponseFailed = (rawEvent, state$1) => {
1706
- const response = toResponsesResult(rawEvent.response);
1707
- const events$1 = ensureMessageStart(state$1, response);
1724
+ const response = rawEvent.response;
1725
+ const events$1 = new Array();
1708
1726
  closeAllOpenBlocks(state$1, events$1);
1709
- const message = typeof rawEvent.error === "string" ? rawEvent.error : "Response generation failed.";
1727
+ const message = response.error?.message ?? "The response failed due to an unknown error.";
1710
1728
  events$1.push(buildErrorEvent(message));
1711
1729
  state$1.messageCompleted = true;
1712
1730
  return events$1;
@@ -1716,27 +1734,24 @@ const handleErrorEvent = (rawEvent, state$1) => {
1716
1734
  state$1.messageCompleted = true;
1717
1735
  return [buildErrorEvent(message)];
1718
1736
  };
1719
- const ensureMessageStart = (state$1, response) => {
1720
- if (state$1.messageStartSent) return [];
1721
- if (response) cacheResponseMetadata(state$1, response);
1722
- const id = response?.id ?? state$1.currentResponseId ?? "response";
1723
- const model = response?.model ?? state$1.currentModel ?? "";
1737
+ const messageStart = (state$1, response) => {
1724
1738
  state$1.messageStartSent = true;
1725
- const inputTokens = (state$1.initialInputTokens ?? 0) - (state$1.initialInputCachedTokens ?? 0);
1739
+ const inputCachedTokens = response.usage?.input_tokens_details?.cached_tokens;
1740
+ const inputTokens = (response.usage?.input_tokens ?? 0) - (inputCachedTokens ?? 0);
1726
1741
  return [{
1727
1742
  type: "message_start",
1728
1743
  message: {
1729
- id,
1744
+ id: response.id,
1730
1745
  type: "message",
1731
1746
  role: "assistant",
1732
1747
  content: [],
1733
- model,
1748
+ model: response.model,
1734
1749
  stop_reason: null,
1735
1750
  stop_sequence: null,
1736
1751
  usage: {
1737
1752
  input_tokens: inputTokens,
1738
1753
  output_tokens: 0,
1739
- ...state$1.initialInputCachedTokens !== void 0 && { cache_creation_input_tokens: state$1.initialInputCachedTokens }
1754
+ ...inputCachedTokens !== void 0 && { cache_creation_input_tokens: inputCachedTokens }
1740
1755
  }
1741
1756
  }
1742
1757
  }];
@@ -1796,13 +1811,6 @@ const closeBlockIfOpen = (state$1, blockIndex, events$1) => {
1796
1811
  const closeAllOpenBlocks = (state$1, events$1) => {
1797
1812
  for (const blockIndex of state$1.openBlocks) closeBlockIfOpen(state$1, blockIndex, events$1);
1798
1813
  state$1.functionCallStateByOutputIndex.clear();
1799
- state$1.functionCallOutputIndexByItemId.clear();
1800
- };
1801
- const cacheResponseMetadata = (state$1, response) => {
1802
- state$1.currentResponseId = response.id;
1803
- state$1.currentModel = response.model;
1804
- state$1.initialInputTokens = response.usage?.input_tokens ?? 0;
1805
- state$1.initialInputCachedTokens = response.usage?.input_tokens_details?.cached_tokens;
1806
1814
  };
1807
1815
  const buildErrorEvent = (message) => ({
1808
1816
  type: "error",
@@ -1812,31 +1820,18 @@ const buildErrorEvent = (message) => ({
1812
1820
  }
1813
1821
  });
1814
1822
  const getBlockKey = (outputIndex, contentIndex) => `${outputIndex}:${contentIndex}`;
1815
- const resolveFunctionCallOutputIndex = (state$1, rawEvent) => {
1816
- if (typeof rawEvent.output_index === "number" || typeof rawEvent.output_index === "string" && rawEvent.output_index.length > 0) {
1817
- const parsed = toOptionalNumber(rawEvent.output_index);
1818
- if (parsed !== void 0) return parsed;
1819
- }
1820
- const itemId = toNonEmptyString(rawEvent.item_id);
1821
- if (itemId) {
1822
- const mapped = state$1.functionCallOutputIndexByItemId.get(itemId);
1823
- if (mapped !== void 0) return mapped;
1824
- }
1825
- };
1826
1823
  const openFunctionCallBlock = (state$1, params) => {
1827
1824
  const { outputIndex, toolCallId, name, events: events$1 } = params;
1828
1825
  let functionCallState = state$1.functionCallStateByOutputIndex.get(outputIndex);
1829
1826
  if (!functionCallState) {
1830
1827
  const blockIndex$1 = state$1.nextContentBlockIndex;
1831
1828
  state$1.nextContentBlockIndex += 1;
1832
- const resolvedToolCallId = toolCallId ?? `tool_call_${blockIndex$1}`;
1833
1829
  functionCallState = {
1834
1830
  blockIndex: blockIndex$1,
1835
- toolCallId: resolvedToolCallId,
1831
+ toolCallId: toolCallId ?? `tool_call_${blockIndex$1}`,
1836
1832
  name: name ?? "function"
1837
1833
  };
1838
1834
  state$1.functionCallStateByOutputIndex.set(outputIndex, functionCallState);
1839
- state$1.functionCallOutputIndexByItemId.set(resolvedToolCallId, outputIndex);
1840
1835
  }
1841
1836
  const { blockIndex } = functionCallState;
1842
1837
  if (!state$1.openBlocks.has(blockIndex)) {
@@ -1854,62 +1849,23 @@ const openFunctionCallBlock = (state$1, params) => {
1854
1849
  }
1855
1850
  return blockIndex;
1856
1851
  };
1857
- const extractFunctionCallDetails = (rawEvent, state$1) => {
1858
- const item = isRecord(rawEvent.item) ? rawEvent.item : void 0;
1859
- if (!item) return;
1860
- if ((typeof item.type === "string" ? item.type : void 0) !== "function_call") return;
1861
- const outputIndex = resolveFunctionCallOutputIndex(state$1, rawEvent);
1862
- if (outputIndex === void 0) return;
1863
- const callId = toNonEmptyString(item.call_id);
1864
- const itemId = toNonEmptyString(item.id);
1865
- const name = toNonEmptyString(item.name) ?? "function";
1866
- const toolCallId = callId ?? itemId ?? `tool_call_${outputIndex}`;
1867
- const initialArguments = typeof item.arguments === "string" ? item.arguments : void 0;
1852
+ const extractFunctionCallDetails = (rawEvent) => {
1853
+ const item = rawEvent.item;
1854
+ if (item.type !== "function_call") return;
1868
1855
  return {
1869
- outputIndex,
1870
- toolCallId,
1871
- name,
1872
- initialArguments,
1873
- itemId
1856
+ outputIndex: rawEvent.output_index,
1857
+ toolCallId: item.call_id,
1858
+ name: item.name,
1859
+ initialArguments: item.arguments
1874
1860
  };
1875
1861
  };
1876
- const toResponsesResult = (value) => isResponsesResult(value) ? value : void 0;
1877
- const toOptionalNumber = (value) => {
1878
- if (typeof value === "number" && Number.isFinite(value)) return value;
1879
- if (typeof value === "string" && value.length > 0) {
1880
- const parsed = Number(value);
1881
- if (Number.isFinite(parsed)) return parsed;
1882
- }
1883
- };
1884
- const toNonEmptyString = (value) => {
1885
- if (typeof value === "string" && value.length > 0) return value;
1886
- };
1887
- const toNumber = (value) => {
1888
- if (typeof value === "number" && Number.isFinite(value)) return value;
1889
- if (typeof value === "string") {
1890
- const parsed = Number(value);
1891
- if (Number.isFinite(parsed)) return parsed;
1892
- }
1893
- return 0;
1894
- };
1895
- const isResponsesResult = (value) => {
1896
- if (!isRecord(value)) return false;
1897
- if (typeof value.id !== "string") return false;
1898
- if (typeof value.model !== "string") return false;
1899
- if (!Array.isArray(value.output)) return false;
1900
- if (typeof value.object !== "string") return false;
1901
- return true;
1902
- };
1903
- const isRecord = (value) => typeof value === "object" && value !== null;
1904
1862
 
1905
1863
  //#endregion
1906
1864
  //#region src/routes/responses/utils.ts
1907
1865
  const getResponsesRequestOptions = (payload) => {
1908
- const vision = hasVisionInput(payload);
1909
- const initiator = hasAgentInitiator(payload) ? "agent" : "user";
1910
1866
  return {
1911
- vision,
1912
- initiator
1867
+ vision: hasVisionInput(payload),
1868
+ initiator: hasAgentInitiator(payload) ? "agent" : "user"
1913
1869
  };
1914
1870
  };
1915
1871
  const hasAgentInitiator = (payload) => getPayloadItems(payload).some((item) => {
@@ -2093,8 +2049,7 @@ const handleWithChatCompletions = async (c, anthropicPayload) => {
2093
2049
  consola.debug("Copilot raw stream event:", JSON.stringify(rawEvent));
2094
2050
  if (rawEvent.data === "[DONE]") break;
2095
2051
  if (!rawEvent.data) continue;
2096
- const chunk = JSON.parse(rawEvent.data);
2097
- const events$1 = translateChunkToAnthropicEvents(chunk, streamState);
2052
+ const events$1 = translateChunkToAnthropicEvents(JSON.parse(rawEvent.data), streamState);
2098
2053
  for (const event of events$1) {
2099
2054
  consola.debug("Translated Anthropic event:", JSON.stringify(event));
2100
2055
  await stream.writeSSE({
@@ -2118,7 +2073,6 @@ const handleWithResponsesApi = async (c, anthropicPayload) => {
2118
2073
  return streamSSE(c, async (stream) => {
2119
2074
  const streamState = createResponsesStreamState();
2120
2075
  for await (const chunk of response) {
2121
- consola.debug("Responses raw stream event:", JSON.stringify(chunk));
2122
2076
  if (chunk.event === "ping") {
2123
2077
  await stream.writeSSE({
2124
2078
  event: "ping",
@@ -2128,15 +2082,14 @@ const handleWithResponsesApi = async (c, anthropicPayload) => {
2128
2082
  }
2129
2083
  const data = chunk.data;
2130
2084
  if (!data) continue;
2131
- if (data === "[DONE]") break;
2132
- const parsed = safeJsonParse(data);
2133
- if (!parsed) continue;
2134
- const events$1 = translateResponsesStreamEvent(parsed, streamState);
2085
+ consola.debug("Responses raw stream event:", data);
2086
+ const events$1 = translateResponsesStreamEvent(JSON.parse(data), streamState);
2135
2087
  for (const event of events$1) {
2136
- consola.debug("Translated Anthropic event:", JSON.stringify(event));
2088
+ const eventData = JSON.stringify(event);
2089
+ consola.debug("Translated Anthropic event:", eventData);
2137
2090
  await stream.writeSSE({
2138
2091
  event: event.type,
2139
- data: JSON.stringify(event)
2092
+ data: eventData
2140
2093
  });
2141
2094
  }
2142
2095
  }
@@ -2160,14 +2113,6 @@ const shouldUseResponsesApi = (modelId) => {
2160
2113
  };
2161
2114
  const isNonStreaming = (response) => Object.hasOwn(response, "choices");
2162
2115
  const isAsyncIterable$1 = (value) => Boolean(value) && typeof value[Symbol.asyncIterator] === "function";
2163
- const safeJsonParse = (value) => {
2164
- try {
2165
- return JSON.parse(value);
2166
- } catch (error) {
2167
- consola.warn("Failed to parse Responses stream chunk:", value, error);
2168
- return;
2169
- }
2170
- };
2171
2116
 
2172
2117
  //#endregion
2173
2118
  //#region src/routes/messages/route.ts
@@ -2455,7 +2400,7 @@ const start = defineCommand({
2455
2400
  //#region src/main.ts
2456
2401
  const main = defineCommand({
2457
2402
  meta: {
2458
- name: "heibaiapi",
2403
+ name: "copilot-api",
2459
2404
  description: "A wrapper around GitHub Copilot API to make it OpenAI compatible, making it usable for other tools."
2460
2405
  },
2461
2406
  subCommands: {