heibaiapi 0.6.1 → 0.7.0

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
@@ -5,11 +5,11 @@ import fs from "node:fs/promises";
5
5
  import os from "node:os";
6
6
  import path from "node:path";
7
7
  import { randomUUID } from "node:crypto";
8
- import { getProxyForUrl } from "proxy-from-env";
9
- import { Agent, ProxyAgent, setGlobalDispatcher } from "undici";
10
8
  import clipboard from "clipboardy";
11
9
  import { serve } from "srvx";
12
10
  import invariant from "tiny-invariant";
11
+ import { getProxyForUrl } from "proxy-from-env";
12
+ import { Agent, ProxyAgent, setGlobalDispatcher } from "undici";
13
13
  import { execSync } from "node:child_process";
14
14
  import process$1 from "node:process";
15
15
  import { Hono } from "hono";
@@ -19,7 +19,7 @@ import { streamSSE } from "hono/streaming";
19
19
  import { events } from "fetch-event-stream";
20
20
 
21
21
  //#region src/lib/paths.ts
22
- const APP_DIR = path.join(os.homedir(), ".local", "share", "heibaiapi");
22
+ const APP_DIR = path.join(os.homedir(), ".local", "share", "copilot-api");
23
23
  const GITHUB_TOKEN_PATH = path.join(APP_DIR, "github_token");
24
24
  const PATHS = {
25
25
  APP_DIR,
@@ -401,7 +401,7 @@ async function getDebugInfo() {
401
401
  };
402
402
  }
403
403
  function printDebugInfoPlain(info) {
404
- consola.info(`heibaiapi debug
404
+ consola.info(`copilot-api debug
405
405
 
406
406
  Version: ${info.version}
407
407
  Runtime: ${info.runtime.name} ${info.runtime.version} (${info.runtime.platform} ${info.runtime.arch})
@@ -487,8 +487,7 @@ function getShell() {
487
487
  const { platform, ppid, env } = process$1;
488
488
  if (platform === "win32") {
489
489
  try {
490
- const command = `wmic process get ParentProcessId,Name | findstr "${ppid}"`;
491
- if (execSync(command, { stdio: "pipe" }).toString().toLowerCase().includes("powershell.exe")) return "powershell";
490
+ if (execSync(`wmic process get ParentProcessId,Name | findstr "${ppid}"`, { stdio: "pipe" }).toString().toLowerCase().includes("powershell.exe")) return "powershell";
492
491
  } catch {
493
492
  return "cmd";
494
493
  }
@@ -748,8 +747,7 @@ const numTokensForTools = (tools, encoder, constants) => {
748
747
  * Calculate the token count of messages, supporting multiple GPT encoders
749
748
  */
750
749
  const getTokenCount = async (payload, model) => {
751
- const tokenizer = getTokenizerFromModel(model);
752
- const encoder = await getEncodeChatFunction(tokenizer);
750
+ const encoder = await getEncodeChatFunction(getTokenizerFromModel(model));
753
751
  const simplifiedMessages = payload.messages;
754
752
  const inputMessages = simplifiedMessages.filter((msg) => msg.role !== "assistant");
755
753
  const outputMessages = simplifiedMessages.filter((msg) => msg.role === "assistant");
@@ -794,10 +792,8 @@ async function handleCompletion$1(c) {
794
792
  consola.debug("Request payload:", JSON.stringify(payload).slice(-400));
795
793
  const selectedModel = state.models?.data.find((model) => model.id === payload.model);
796
794
  try {
797
- if (selectedModel) {
798
- const tokenCount = await getTokenCount(payload, selectedModel);
799
- consola.info("Current token count:", tokenCount);
800
- } else consola.warn("No model selected, skipping token count calculation");
795
+ if (selectedModel) consola.info(`[ModelTranslation_OpenAI] 客户端请求: ${payload.model} -> 服务端使用: ${selectedModel.id}`);
796
+ else consola.warn("No model selected, skipping token count calculation");
801
797
  } catch (error) {
802
798
  consola.warn("Failed to calculate token count:", error);
803
799
  }
@@ -853,8 +849,7 @@ const createEmbeddings = async (payload) => {
853
849
  const embeddingRoutes = new Hono();
854
850
  embeddingRoutes.post("/", async (c) => {
855
851
  try {
856
- const paylod = await c.req.json();
857
- const response = await createEmbeddings(paylod);
852
+ const response = await createEmbeddings(await c.req.json());
858
853
  return c.json(response);
859
854
  } catch (error) {
860
855
  return await forwardError(c, error);
@@ -890,9 +885,14 @@ function translateToOpenAI(payload) {
890
885
  };
891
886
  }
892
887
  function translateModelName(model) {
893
- if (model.startsWith("claude-sonnet-4-")) return model.replace(/^claude-sonnet-4-.*/, "claude-sonnet-4");
894
- else if (model.startsWith("claude-opus-")) return model.replace(/^claude-opus-4-.*/, "claude-opus-4");
895
- return model;
888
+ let serverModel;
889
+ serverModel = model;
890
+ if (model.includes("claude-3-5")) serverModel = "claude-3.5-sonnet";
891
+ else if (model.includes("claude-opus")) serverModel = "claude-sonnet-4.5";
892
+ else if (model.includes("claude-sonnet-4.5")) serverModel = "claude-sonnet-4.5";
893
+ else if (model.includes("claude-sonnet-4")) serverModel = "claude-sonnet-4";
894
+ consola.info(`[ModelTranslation] 客户端请求: ${model} -> 服务端使用: ${serverModel}`);
895
+ return serverModel;
896
896
  }
897
897
  function translateAnthropicMessagesToOpenAI(anthropicMessages, system) {
898
898
  const systemMessages = handleSystemPrompt(system);
@@ -1083,7 +1083,6 @@ async function handleCountTokens(c) {
1083
1083
  let finalTokenCount = tokenCount.input + tokenCount.output;
1084
1084
  if (anthropicPayload.model.startsWith("claude")) finalTokenCount = Math.round(finalTokenCount * 1.15);
1085
1085
  else if (anthropicPayload.model.startsWith("grok")) finalTokenCount = Math.round(finalTokenCount * 1.03);
1086
- consola.info("Token count:", finalTokenCount);
1087
1086
  return c.json({ input_tokens: finalTokenCount });
1088
1087
  } catch (error) {
1089
1088
  consola.error("Error counting tokens:", error);
@@ -1091,850 +1090,6 @@ async function handleCountTokens(c) {
1091
1090
  }
1092
1091
  }
1093
1092
 
1094
- //#endregion
1095
- //#region src/services/copilot/create-responses.ts
1096
- const createResponses = async (payload, { vision, initiator }) => {
1097
- if (!state.copilotToken) throw new Error("Copilot token not found");
1098
- const headers = {
1099
- ...copilotHeaders(state, vision),
1100
- "X-Initiator": initiator
1101
- };
1102
- const response = await fetch(`${copilotBaseUrl(state)}/responses`, {
1103
- method: "POST",
1104
- headers,
1105
- body: JSON.stringify(payload)
1106
- });
1107
- if (!response.ok) {
1108
- consola.error("Failed to create responses", response);
1109
- throw new HTTPError("Failed to create responses", response);
1110
- }
1111
- if (payload.stream) return events(response);
1112
- return await response.json();
1113
- };
1114
-
1115
- //#endregion
1116
- //#region src/routes/messages/responses-translation.ts
1117
- const MESSAGE_TYPE = "message";
1118
- const translateAnthropicMessagesToResponsesPayload = (payload) => {
1119
- const input = [];
1120
- for (const message of payload.messages) input.push(...translateMessage(message));
1121
- const translatedTools = convertAnthropicTools(payload.tools);
1122
- const toolChoice = convertAnthropicToolChoice(payload.tool_choice);
1123
- const { safetyIdentifier, promptCacheKey } = parseUserId(payload.metadata?.user_id);
1124
- return {
1125
- model: payload.model,
1126
- input,
1127
- instructions: translateSystemPrompt(payload.system),
1128
- temperature: payload.temperature ?? null,
1129
- top_p: payload.top_p ?? null,
1130
- max_output_tokens: payload.max_tokens,
1131
- tools: translatedTools,
1132
- tool_choice: toolChoice,
1133
- metadata: payload.metadata ? { ...payload.metadata } : null,
1134
- safety_identifier: safetyIdentifier,
1135
- prompt_cache_key: promptCacheKey,
1136
- stream: payload.stream ?? null,
1137
- store: false,
1138
- parallel_tool_calls: true,
1139
- reasoning: {
1140
- effort: "high",
1141
- summary: "auto"
1142
- },
1143
- include: ["reasoning.encrypted_content"]
1144
- };
1145
- };
1146
- const translateMessage = (message) => {
1147
- if (message.role === "user") return translateUserMessage(message);
1148
- return translateAssistantMessage(message);
1149
- };
1150
- const translateUserMessage = (message) => {
1151
- if (typeof message.content === "string") return [createMessage("user", message.content)];
1152
- if (!Array.isArray(message.content)) return [];
1153
- const items = [];
1154
- const pendingContent = [];
1155
- for (const block of message.content) {
1156
- if (block.type === "tool_result") {
1157
- flushPendingContent("user", pendingContent, items);
1158
- items.push(createFunctionCallOutput(block));
1159
- continue;
1160
- }
1161
- const converted = translateUserContentBlock(block);
1162
- if (converted) pendingContent.push(converted);
1163
- }
1164
- flushPendingContent("user", pendingContent, items);
1165
- return items;
1166
- };
1167
- const translateAssistantMessage = (message) => {
1168
- if (typeof message.content === "string") return [createMessage("assistant", message.content)];
1169
- if (!Array.isArray(message.content)) return [];
1170
- const items = [];
1171
- const pendingContent = [];
1172
- for (const block of message.content) {
1173
- if (block.type === "tool_use") {
1174
- flushPendingContent("assistant", pendingContent, items);
1175
- items.push(createFunctionToolCall(block));
1176
- continue;
1177
- }
1178
- if (block.type === "thinking") {
1179
- flushPendingContent("assistant", pendingContent, items);
1180
- items.push(createReasoningContent(block));
1181
- continue;
1182
- }
1183
- const converted = translateAssistantContentBlock(block);
1184
- if (converted) pendingContent.push(converted);
1185
- }
1186
- flushPendingContent("assistant", pendingContent, items);
1187
- return items;
1188
- };
1189
- const translateUserContentBlock = (block) => {
1190
- switch (block.type) {
1191
- case "text": return createTextContent(block.text);
1192
- case "image": return createImageContent(block);
1193
- default: return;
1194
- }
1195
- };
1196
- const translateAssistantContentBlock = (block) => {
1197
- switch (block.type) {
1198
- case "text": return createOutPutTextContent(block.text);
1199
- default: return;
1200
- }
1201
- };
1202
- const flushPendingContent = (role, pendingContent, target) => {
1203
- if (pendingContent.length === 0) return;
1204
- const messageContent = pendingContent.length === 1 && isPlainText(pendingContent[0]) ? pendingContent[0].text : [...pendingContent];
1205
- target.push(createMessage(role, messageContent));
1206
- pendingContent.length = 0;
1207
- };
1208
- const createMessage = (role, content) => ({
1209
- type: MESSAGE_TYPE,
1210
- role,
1211
- content
1212
- });
1213
- const createTextContent = (text) => ({
1214
- type: "input_text",
1215
- text
1216
- });
1217
- const createOutPutTextContent = (text) => ({
1218
- type: "output_text",
1219
- text
1220
- });
1221
- const createImageContent = (block) => ({
1222
- 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
1232
- });
1233
- const createFunctionToolCall = (block) => ({
1234
- type: "function_call",
1235
- call_id: block.id,
1236
- name: block.name,
1237
- arguments: JSON.stringify(block.input),
1238
- status: "completed"
1239
- });
1240
- const createFunctionCallOutput = (block) => ({
1241
- type: "function_call_output",
1242
- call_id: block.tool_use_id,
1243
- output: convertToolResultContent(block.content),
1244
- status: block.is_error ? "incomplete" : "completed"
1245
- });
1246
- const translateSystemPrompt = (system) => {
1247
- 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;
1263
- const text = system.map((block, index) => {
1264
- if (index === 0) return block.text + toolUsePrompt;
1265
- return block.text;
1266
- }).join(" ");
1267
- return text.length > 0 ? text : null;
1268
- };
1269
- const convertAnthropicTools = (tools) => {
1270
- if (!tools || tools.length === 0) return null;
1271
- return tools.map((tool) => ({
1272
- type: "function",
1273
- name: tool.name,
1274
- parameters: tool.input_schema,
1275
- strict: false,
1276
- ...tool.description ? { description: tool.description } : {}
1277
- }));
1278
- };
1279
- const convertAnthropicToolChoice = (choice) => {
1280
- if (!choice) return;
1281
- switch (choice.type) {
1282
- case "auto": return "auto";
1283
- case "any": return "required";
1284
- case "tool": return choice.name ? {
1285
- type: "function",
1286
- name: choice.name
1287
- } : void 0;
1288
- case "none": return "none";
1289
- default: return;
1290
- }
1291
- };
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
- const translateResponsesResultToAnthropic = (response) => {
1297
- const contentBlocks = mapOutputToAnthropicContent(response.output);
1298
- const usage = mapResponsesUsage(response);
1299
- let anthropicContent = fallbackContentBlocks(response.output_text);
1300
- if (contentBlocks.length > 0) anthropicContent = contentBlocks;
1301
- const stopReason = mapResponsesStopReason(response);
1302
- return {
1303
- id: response.id,
1304
- type: "message",
1305
- role: "assistant",
1306
- content: anthropicContent,
1307
- model: response.model,
1308
- stop_reason: stopReason,
1309
- stop_sequence: null,
1310
- usage
1311
- };
1312
- };
1313
- const mapOutputToAnthropicContent = (output) => {
1314
- const contentBlocks = [];
1315
- for (const item of output) switch (item.type) {
1316
- case "reasoning": {
1317
- const thinkingText = extractReasoningText(item);
1318
- if (thinkingText.length > 0) contentBlocks.push({
1319
- type: "thinking",
1320
- thinking: thinkingText,
1321
- signature: item.encrypted_content ?? ""
1322
- });
1323
- break;
1324
- }
1325
- case "function_call": {
1326
- const toolUseBlock = createToolUseContentBlock(item);
1327
- if (toolUseBlock) contentBlocks.push(toolUseBlock);
1328
- break;
1329
- }
1330
- case "message": {
1331
- const combinedText = combineMessageTextContent(item.content);
1332
- if (combinedText.length > 0) contentBlocks.push({
1333
- type: "text",
1334
- text: combinedText
1335
- });
1336
- break;
1337
- }
1338
- default: {
1339
- const combinedText = combineMessageTextContent(item.content);
1340
- if (combinedText.length > 0) contentBlocks.push({
1341
- type: "text",
1342
- text: combinedText
1343
- });
1344
- }
1345
- }
1346
- return contentBlocks;
1347
- };
1348
- const combineMessageTextContent = (content) => {
1349
- if (!Array.isArray(content)) return "";
1350
- let aggregated = "";
1351
- for (const block of content) {
1352
- if (isResponseOutputText(block)) {
1353
- aggregated += block.text;
1354
- continue;
1355
- }
1356
- if (isResponseOutputRefusal(block)) {
1357
- aggregated += block.refusal;
1358
- continue;
1359
- }
1360
- if (typeof block.text === "string") {
1361
- aggregated += block.text;
1362
- continue;
1363
- }
1364
- if (typeof block.reasoning === "string") {
1365
- aggregated += block.reasoning;
1366
- continue;
1367
- }
1368
- }
1369
- return aggregated;
1370
- };
1371
- const extractReasoningText = (item) => {
1372
- const segments = [];
1373
- const collectFromBlocks = (blocks) => {
1374
- if (!Array.isArray(blocks)) return;
1375
- for (const block of blocks) if (typeof block.text === "string") {
1376
- segments.push(block.text);
1377
- continue;
1378
- }
1379
- };
1380
- collectFromBlocks(item.summary);
1381
- return segments.join("").trim();
1382
- };
1383
- const createToolUseContentBlock = (call) => {
1384
- const toolId = call.call_id ?? call.id;
1385
- if (!call.name || !toolId) return null;
1386
- const input = parseFunctionCallArguments(call.arguments);
1387
- return {
1388
- type: "tool_use",
1389
- id: toolId,
1390
- name: call.name,
1391
- input
1392
- };
1393
- };
1394
- const parseFunctionCallArguments = (rawArguments) => {
1395
- if (typeof rawArguments !== "string" || rawArguments.trim().length === 0) return {};
1396
- try {
1397
- const parsed = JSON.parse(rawArguments);
1398
- if (Array.isArray(parsed)) return { arguments: parsed };
1399
- if (parsed && typeof parsed === "object") return parsed;
1400
- } catch (error) {
1401
- consola.warn("Failed to parse function call arguments", {
1402
- error,
1403
- rawArguments
1404
- });
1405
- }
1406
- return { raw_arguments: rawArguments };
1407
- };
1408
- const fallbackContentBlocks = (outputText) => {
1409
- if (!outputText) return [];
1410
- return [{
1411
- type: "text",
1412
- text: outputText
1413
- }];
1414
- };
1415
- const mapResponsesStopReason = (response) => {
1416
- const { status, incomplete_details: incompleteDetails } = response;
1417
- if (status === "completed") return "end_turn";
1418
- if (status === "incomplete") {
1419
- if (incompleteDetails?.reason === "max_output_tokens") return "max_tokens";
1420
- if (incompleteDetails?.reason === "content_filter") return "end_turn";
1421
- if (incompleteDetails?.reason === "tool_use") return "tool_use";
1422
- }
1423
- return null;
1424
- };
1425
- const mapResponsesUsage = (response) => {
1426
- const inputTokens = response.usage?.input_tokens ?? 0;
1427
- const outputTokens = response.usage?.output_tokens ?? 0;
1428
- const inputCachedTokens = response.usage?.input_tokens_details?.cached_tokens;
1429
- return {
1430
- input_tokens: inputTokens - (inputCachedTokens ?? 0),
1431
- output_tokens: outputTokens,
1432
- ...response.usage?.input_tokens_details?.cached_tokens !== void 0 && { cache_read_input_tokens: response.usage.input_tokens_details.cached_tokens }
1433
- };
1434
- };
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";
1438
- const parseUserId = (userId) => {
1439
- if (!userId || typeof userId !== "string") return {
1440
- safetyIdentifier: null,
1441
- promptCacheKey: null
1442
- };
1443
- const userMatch = userId.match(/user_([^_]+)_account/);
1444
- const safetyIdentifier = userMatch ? userMatch[1] : null;
1445
- const sessionMatch = userId.match(/_session_(.+)$/);
1446
- const promptCacheKey = sessionMatch ? sessionMatch[1] : null;
1447
- return {
1448
- safetyIdentifier,
1449
- promptCacheKey
1450
- };
1451
- };
1452
- const convertToolResultContent = (content) => {
1453
- if (typeof content === "string") return content;
1454
- if (Array.isArray(content)) {
1455
- const result = [];
1456
- for (const block of content) switch (block.type) {
1457
- case "text":
1458
- result.push(createTextContent(block.text));
1459
- break;
1460
- case "image":
1461
- result.push(createImageContent(block));
1462
- break;
1463
- default: break;
1464
- }
1465
- return result;
1466
- }
1467
- return "";
1468
- };
1469
-
1470
- //#endregion
1471
- //#region src/routes/messages/responses-stream-translation.ts
1472
- const createResponsesStreamState = () => ({
1473
- messageStartSent: false,
1474
- messageCompleted: false,
1475
- nextContentBlockIndex: 0,
1476
- blockIndexByKey: /* @__PURE__ */ new Map(),
1477
- openBlocks: /* @__PURE__ */ new Set(),
1478
- blockHasDelta: /* @__PURE__ */ new Set(),
1479
- functionCallStateByOutputIndex: /* @__PURE__ */ new Map(),
1480
- functionCallOutputIndexByItemId: /* @__PURE__ */ new Map()
1481
- });
1482
- const translateResponsesStreamEvent = (rawEvent, state$1) => {
1483
- const eventType = typeof rawEvent.type === "string" ? rawEvent.type : void 0;
1484
- if (!eventType) return [];
1485
- switch (eventType) {
1486
- case "response.created": return handleResponseCreated(rawEvent, state$1);
1487
- case "response.reasoning_summary_text.delta": return handleReasoningSummaryTextDelta(rawEvent, state$1);
1488
- case "response.output_text.delta": return handleOutputTextDelta(rawEvent, state$1);
1489
- case "response.reasoning_summary_part.done": return handleReasoningSummaryPartDone(rawEvent, state$1);
1490
- case "response.output_text.done": return handleOutputTextDone(rawEvent, state$1);
1491
- case "response.output_item.added": return handleOutputItemAdded(rawEvent, state$1);
1492
- case "response.output_item.done": return handleOutputItemDone(rawEvent, state$1);
1493
- case "response.function_call_arguments.delta": return handleFunctionCallArgumentsDelta(rawEvent, state$1);
1494
- case "response.function_call_arguments.done": return handleFunctionCallArgumentsDone(rawEvent, state$1);
1495
- case "response.completed":
1496
- case "response.incomplete": return handleResponseCompleted(rawEvent, state$1);
1497
- case "response.failed": return handleResponseFailed(rawEvent, state$1);
1498
- case "error": return handleErrorEvent(rawEvent, state$1);
1499
- default: return [];
1500
- }
1501
- };
1502
- const handleResponseCreated = (rawEvent, state$1) => {
1503
- const response = toResponsesResult(rawEvent.response);
1504
- if (response) cacheResponseMetadata(state$1, response);
1505
- return ensureMessageStart(state$1, response);
1506
- };
1507
- 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);
1511
- if (!functionCallDetails) return events$1;
1512
- const { outputIndex, toolCallId, name, initialArguments, itemId } = functionCallDetails;
1513
- if (itemId) state$1.functionCallOutputIndexByItemId.set(itemId, outputIndex);
1514
- const blockIndex = openFunctionCallBlock(state$1, {
1515
- outputIndex,
1516
- toolCallId,
1517
- name,
1518
- events: events$1
1519
- });
1520
- if (initialArguments !== void 0 && initialArguments.length > 0) {
1521
- events$1.push({
1522
- type: "content_block_delta",
1523
- index: blockIndex,
1524
- delta: {
1525
- type: "input_json_delta",
1526
- partial_json: initialArguments
1527
- }
1528
- });
1529
- state$1.blockHasDelta.add(blockIndex);
1530
- }
1531
- return events$1;
1532
- };
1533
- 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);
1539
- const blockIndex = openThinkingBlockIfNeeded(state$1, outputIndex, events$1);
1540
- const signature = typeof item.encrypted_content === "string" ? item.encrypted_content : "";
1541
- if (signature) {
1542
- events$1.push({
1543
- type: "content_block_delta",
1544
- index: blockIndex,
1545
- delta: {
1546
- type: "signature_delta",
1547
- signature
1548
- }
1549
- });
1550
- state$1.blockHasDelta.add(blockIndex);
1551
- }
1552
- closeBlockIfOpen(state$1, blockIndex, events$1);
1553
- return events$1;
1554
- };
1555
- 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;
1561
- const blockIndex = openFunctionCallBlock(state$1, {
1562
- outputIndex,
1563
- events: events$1
1564
- });
1565
- events$1.push({
1566
- type: "content_block_delta",
1567
- index: blockIndex,
1568
- delta: {
1569
- type: "input_json_delta",
1570
- partial_json: deltaText
1571
- }
1572
- });
1573
- state$1.blockHasDelta.add(blockIndex);
1574
- return events$1;
1575
- };
1576
- 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;
1580
- const blockIndex = openFunctionCallBlock(state$1, {
1581
- outputIndex,
1582
- events: events$1
1583
- });
1584
- const finalArguments = typeof rawEvent.arguments === "string" ? rawEvent.arguments : void 0;
1585
- if (!state$1.blockHasDelta.has(blockIndex) && finalArguments) {
1586
- events$1.push({
1587
- type: "content_block_delta",
1588
- index: blockIndex,
1589
- delta: {
1590
- type: "input_json_delta",
1591
- partial_json: finalArguments
1592
- }
1593
- });
1594
- state$1.blockHasDelta.add(blockIndex);
1595
- }
1596
- closeBlockIfOpen(state$1, blockIndex, events$1);
1597
- const existingState = state$1.functionCallStateByOutputIndex.get(outputIndex);
1598
- if (existingState) state$1.functionCallOutputIndexByItemId.delete(existingState.toolCallId);
1599
- state$1.functionCallStateByOutputIndex.delete(outputIndex);
1600
- const itemId = toNonEmptyString(rawEvent.item_id);
1601
- if (itemId) state$1.functionCallOutputIndexByItemId.delete(itemId);
1602
- return events$1;
1603
- };
1604
- 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 : "";
1609
- if (!deltaText) return events$1;
1610
- const blockIndex = openTextBlockIfNeeded(state$1, {
1611
- outputIndex,
1612
- contentIndex,
1613
- events: events$1
1614
- });
1615
- events$1.push({
1616
- type: "content_block_delta",
1617
- index: blockIndex,
1618
- delta: {
1619
- type: "text_delta",
1620
- text: deltaText
1621
- }
1622
- });
1623
- state$1.blockHasDelta.add(blockIndex);
1624
- return events$1;
1625
- };
1626
- 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;
1631
- const blockIndex = openThinkingBlockIfNeeded(state$1, outputIndex, events$1);
1632
- events$1.push({
1633
- type: "content_block_delta",
1634
- index: blockIndex,
1635
- delta: {
1636
- type: "thinking_delta",
1637
- thinking: deltaText
1638
- }
1639
- });
1640
- state$1.blockHasDelta.add(blockIndex);
1641
- return events$1;
1642
- };
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 : "";
1648
- const blockIndex = openThinkingBlockIfNeeded(state$1, outputIndex, events$1);
1649
- if (text && !state$1.blockHasDelta.has(blockIndex)) events$1.push({
1650
- type: "content_block_delta",
1651
- index: blockIndex,
1652
- delta: {
1653
- type: "thinking_delta",
1654
- thinking: text
1655
- }
1656
- });
1657
- return events$1;
1658
- };
1659
- 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 : "";
1664
- const blockIndex = openTextBlockIfNeeded(state$1, {
1665
- outputIndex,
1666
- contentIndex,
1667
- events: events$1
1668
- });
1669
- if (text && !state$1.blockHasDelta.has(blockIndex)) events$1.push({
1670
- type: "content_block_delta",
1671
- index: blockIndex,
1672
- delta: {
1673
- type: "text_delta",
1674
- text
1675
- }
1676
- });
1677
- closeBlockIfOpen(state$1, blockIndex, events$1);
1678
- return events$1;
1679
- };
1680
- const handleResponseCompleted = (rawEvent, state$1) => {
1681
- const response = toResponsesResult(rawEvent.response);
1682
- const events$1 = ensureMessageStart(state$1, response);
1683
- 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({
1695
- type: "message_delta",
1696
- delta: {
1697
- stop_reason: null,
1698
- stop_sequence: null
1699
- }
1700
- });
1701
- events$1.push({ type: "message_stop" });
1702
- state$1.messageCompleted = true;
1703
- return events$1;
1704
- };
1705
- const handleResponseFailed = (rawEvent, state$1) => {
1706
- const response = toResponsesResult(rawEvent.response);
1707
- const events$1 = ensureMessageStart(state$1, response);
1708
- closeAllOpenBlocks(state$1, events$1);
1709
- const message = typeof rawEvent.error === "string" ? rawEvent.error : "Response generation failed.";
1710
- events$1.push(buildErrorEvent(message));
1711
- state$1.messageCompleted = true;
1712
- return events$1;
1713
- };
1714
- const handleErrorEvent = (rawEvent, state$1) => {
1715
- const message = typeof rawEvent.message === "string" ? rawEvent.message : "An unexpected error occurred during streaming.";
1716
- state$1.messageCompleted = true;
1717
- return [buildErrorEvent(message)];
1718
- };
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 ?? "";
1724
- state$1.messageStartSent = true;
1725
- const inputTokens = (state$1.initialInputTokens ?? 0) - (state$1.initialInputCachedTokens ?? 0);
1726
- return [{
1727
- type: "message_start",
1728
- message: {
1729
- id,
1730
- type: "message",
1731
- role: "assistant",
1732
- content: [],
1733
- model,
1734
- stop_reason: null,
1735
- stop_sequence: null,
1736
- usage: {
1737
- input_tokens: inputTokens,
1738
- output_tokens: 0,
1739
- ...state$1.initialInputCachedTokens !== void 0 && { cache_creation_input_tokens: state$1.initialInputCachedTokens }
1740
- }
1741
- }
1742
- }];
1743
- };
1744
- const openTextBlockIfNeeded = (state$1, params) => {
1745
- const { outputIndex, contentIndex, events: events$1 } = params;
1746
- const key = getBlockKey(outputIndex, contentIndex);
1747
- let blockIndex = state$1.blockIndexByKey.get(key);
1748
- if (blockIndex === void 0) {
1749
- blockIndex = state$1.nextContentBlockIndex;
1750
- state$1.nextContentBlockIndex += 1;
1751
- state$1.blockIndexByKey.set(key, blockIndex);
1752
- }
1753
- if (!state$1.openBlocks.has(blockIndex)) {
1754
- events$1.push({
1755
- type: "content_block_start",
1756
- index: blockIndex,
1757
- content_block: {
1758
- type: "text",
1759
- text: ""
1760
- }
1761
- });
1762
- state$1.openBlocks.add(blockIndex);
1763
- }
1764
- return blockIndex;
1765
- };
1766
- const openThinkingBlockIfNeeded = (state$1, outputIndex, events$1) => {
1767
- const key = getBlockKey(outputIndex, 0);
1768
- let blockIndex = state$1.blockIndexByKey.get(key);
1769
- if (blockIndex === void 0) {
1770
- blockIndex = state$1.nextContentBlockIndex;
1771
- state$1.nextContentBlockIndex += 1;
1772
- state$1.blockIndexByKey.set(key, blockIndex);
1773
- }
1774
- if (!state$1.openBlocks.has(blockIndex)) {
1775
- events$1.push({
1776
- type: "content_block_start",
1777
- index: blockIndex,
1778
- content_block: {
1779
- type: "thinking",
1780
- thinking: ""
1781
- }
1782
- });
1783
- state$1.openBlocks.add(blockIndex);
1784
- }
1785
- return blockIndex;
1786
- };
1787
- const closeBlockIfOpen = (state$1, blockIndex, events$1) => {
1788
- if (!state$1.openBlocks.has(blockIndex)) return;
1789
- events$1.push({
1790
- type: "content_block_stop",
1791
- index: blockIndex
1792
- });
1793
- state$1.openBlocks.delete(blockIndex);
1794
- state$1.blockHasDelta.delete(blockIndex);
1795
- };
1796
- const closeAllOpenBlocks = (state$1, events$1) => {
1797
- for (const blockIndex of state$1.openBlocks) closeBlockIfOpen(state$1, blockIndex, events$1);
1798
- 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
- };
1807
- const buildErrorEvent = (message) => ({
1808
- type: "error",
1809
- error: {
1810
- type: "api_error",
1811
- message
1812
- }
1813
- });
1814
- 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
- const openFunctionCallBlock = (state$1, params) => {
1827
- const { outputIndex, toolCallId, name, events: events$1 } = params;
1828
- let functionCallState = state$1.functionCallStateByOutputIndex.get(outputIndex);
1829
- if (!functionCallState) {
1830
- const blockIndex$1 = state$1.nextContentBlockIndex;
1831
- state$1.nextContentBlockIndex += 1;
1832
- const resolvedToolCallId = toolCallId ?? `tool_call_${blockIndex$1}`;
1833
- functionCallState = {
1834
- blockIndex: blockIndex$1,
1835
- toolCallId: resolvedToolCallId,
1836
- name: name ?? "function"
1837
- };
1838
- state$1.functionCallStateByOutputIndex.set(outputIndex, functionCallState);
1839
- state$1.functionCallOutputIndexByItemId.set(resolvedToolCallId, outputIndex);
1840
- }
1841
- const { blockIndex } = functionCallState;
1842
- if (!state$1.openBlocks.has(blockIndex)) {
1843
- events$1.push({
1844
- type: "content_block_start",
1845
- index: blockIndex,
1846
- content_block: {
1847
- type: "tool_use",
1848
- id: functionCallState.toolCallId,
1849
- name: functionCallState.name,
1850
- input: {}
1851
- }
1852
- });
1853
- state$1.openBlocks.add(blockIndex);
1854
- }
1855
- return blockIndex;
1856
- };
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;
1868
- return {
1869
- outputIndex,
1870
- toolCallId,
1871
- name,
1872
- initialArguments,
1873
- itemId
1874
- };
1875
- };
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
-
1905
- //#endregion
1906
- //#region src/routes/responses/utils.ts
1907
- const getResponsesRequestOptions = (payload) => {
1908
- const vision = hasVisionInput(payload);
1909
- const initiator = hasAgentInitiator(payload) ? "agent" : "user";
1910
- return {
1911
- vision,
1912
- initiator
1913
- };
1914
- };
1915
- const hasAgentInitiator = (payload) => getPayloadItems(payload).some((item) => {
1916
- if (!("role" in item) || !item.role) return true;
1917
- return (typeof item.role === "string" ? item.role.toLowerCase() : "") === "assistant";
1918
- });
1919
- const hasVisionInput = (payload) => {
1920
- return getPayloadItems(payload).some((item) => containsVisionContent(item));
1921
- };
1922
- const getPayloadItems = (payload) => {
1923
- const result = [];
1924
- const { input } = payload;
1925
- if (Array.isArray(input)) result.push(...input);
1926
- return result;
1927
- };
1928
- const containsVisionContent = (value) => {
1929
- if (!value) return false;
1930
- if (Array.isArray(value)) return value.some((entry) => containsVisionContent(entry));
1931
- if (typeof value !== "object") return false;
1932
- const record = value;
1933
- if ((typeof record.type === "string" ? record.type.toLowerCase() : void 0) === "input_image") return true;
1934
- if (Array.isArray(record.content)) return record.content.some((entry) => containsVisionContent(entry));
1935
- return false;
1936
- };
1937
-
1938
1093
  //#endregion
1939
1094
  //#region src/routes/messages/stream-translation.ts
1940
1095
  function isToolBlockOpen(state$1) {
@@ -2065,15 +1220,9 @@ async function handleCompletion(c) {
2065
1220
  await checkRateLimit(state);
2066
1221
  const anthropicPayload = await c.req.json();
2067
1222
  consola.debug("Anthropic request payload:", JSON.stringify(anthropicPayload));
2068
- const useResponsesApi = shouldUseResponsesApi(anthropicPayload.model);
2069
- if (state.manualApprove) await awaitApproval();
2070
- if (useResponsesApi) return await handleWithResponsesApi(c, anthropicPayload);
2071
- return await handleWithChatCompletions(c, anthropicPayload);
2072
- }
2073
- const RESPONSES_ENDPOINT$1 = "/responses";
2074
- const handleWithChatCompletions = async (c, anthropicPayload) => {
2075
1223
  const openAIPayload = translateToOpenAI(anthropicPayload);
2076
1224
  consola.debug("Translated OpenAI request payload:", JSON.stringify(openAIPayload));
1225
+ if (state.manualApprove) await awaitApproval();
2077
1226
  const response = await createChatCompletions(openAIPayload);
2078
1227
  if (isNonStreaming(response)) {
2079
1228
  consola.debug("Non-streaming response from Copilot:", JSON.stringify(response).slice(-400));
@@ -2093,8 +1242,7 @@ const handleWithChatCompletions = async (c, anthropicPayload) => {
2093
1242
  consola.debug("Copilot raw stream event:", JSON.stringify(rawEvent));
2094
1243
  if (rawEvent.data === "[DONE]") break;
2095
1244
  if (!rawEvent.data) continue;
2096
- const chunk = JSON.parse(rawEvent.data);
2097
- const events$1 = translateChunkToAnthropicEvents(chunk, streamState);
1245
+ const events$1 = translateChunkToAnthropicEvents(JSON.parse(rawEvent.data), streamState);
2098
1246
  for (const event of events$1) {
2099
1247
  consola.debug("Translated Anthropic event:", JSON.stringify(event));
2100
1248
  await stream.writeSSE({
@@ -2104,70 +1252,8 @@ const handleWithChatCompletions = async (c, anthropicPayload) => {
2104
1252
  }
2105
1253
  }
2106
1254
  });
2107
- };
2108
- const handleWithResponsesApi = async (c, anthropicPayload) => {
2109
- const responsesPayload = translateAnthropicMessagesToResponsesPayload(anthropicPayload);
2110
- consola.debug("Translated Responses payload:", JSON.stringify(responsesPayload));
2111
- const { vision, initiator } = getResponsesRequestOptions(responsesPayload);
2112
- const response = await createResponses(responsesPayload, {
2113
- vision,
2114
- initiator
2115
- });
2116
- if (responsesPayload.stream && isAsyncIterable$1(response)) {
2117
- consola.debug("Streaming response from Copilot (Responses API)");
2118
- return streamSSE(c, async (stream) => {
2119
- const streamState = createResponsesStreamState();
2120
- for await (const chunk of response) {
2121
- consola.debug("Responses raw stream event:", JSON.stringify(chunk));
2122
- if (chunk.event === "ping") {
2123
- await stream.writeSSE({
2124
- event: "ping",
2125
- data: ""
2126
- });
2127
- continue;
2128
- }
2129
- const data = chunk.data;
2130
- if (!data) continue;
2131
- if (data === "[DONE]") break;
2132
- const parsed = safeJsonParse(data);
2133
- if (!parsed) continue;
2134
- const events$1 = translateResponsesStreamEvent(parsed, streamState);
2135
- for (const event of events$1) {
2136
- consola.debug("Translated Anthropic event:", JSON.stringify(event));
2137
- await stream.writeSSE({
2138
- event: event.type,
2139
- data: JSON.stringify(event)
2140
- });
2141
- }
2142
- }
2143
- if (!streamState.messageCompleted) {
2144
- consola.warn("Responses stream ended without completion; sending fallback message_stop");
2145
- const fallback = { type: "message_stop" };
2146
- await stream.writeSSE({
2147
- event: fallback.type,
2148
- data: JSON.stringify(fallback)
2149
- });
2150
- }
2151
- });
2152
- }
2153
- consola.debug("Non-streaming Responses result:", JSON.stringify(response).slice(-400));
2154
- const anthropicResponse = translateResponsesResultToAnthropic(response);
2155
- consola.debug("Translated Anthropic response:", JSON.stringify(anthropicResponse));
2156
- return c.json(anthropicResponse);
2157
- };
2158
- const shouldUseResponsesApi = (modelId) => {
2159
- return (state.models?.data.find((model) => model.id === modelId))?.supported_endpoints?.includes(RESPONSES_ENDPOINT$1) ?? false;
2160
- };
1255
+ }
2161
1256
  const isNonStreaming = (response) => Object.hasOwn(response, "choices");
2162
- 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
1257
 
2172
1258
  //#endregion
2173
1259
  //#region src/routes/messages/route.ts
@@ -2212,68 +1298,6 @@ modelRoutes.get("/", async (c) => {
2212
1298
  }
2213
1299
  });
2214
1300
 
2215
- //#endregion
2216
- //#region src/routes/responses/handler.ts
2217
- const RESPONSES_ENDPOINT = "/responses";
2218
- const handleResponses = async (c) => {
2219
- await checkRateLimit(state);
2220
- const payload = await c.req.json();
2221
- consola.debug("Responses request payload:", JSON.stringify(payload));
2222
- if (!((state.models?.data.find((model) => model.id === payload.model))?.supported_endpoints?.includes(RESPONSES_ENDPOINT) ?? false)) return c.json({ error: {
2223
- message: "This model does not support the responses endpoint. Please choose a different model.",
2224
- type: "invalid_request_error"
2225
- } }, 400);
2226
- const { vision, initiator } = getResponsesRequestOptions(payload);
2227
- if (state.manualApprove) await awaitApproval();
2228
- const response = await createResponses(payload, {
2229
- vision,
2230
- initiator
2231
- });
2232
- if (isStreamingRequested(payload) && isAsyncIterable(response)) {
2233
- consola.debug("Forwarding native Responses stream");
2234
- return streamSSE(c, async (stream) => {
2235
- const pingInterval = setInterval(async () => {
2236
- try {
2237
- await stream.writeSSE({
2238
- event: "ping",
2239
- data: JSON.stringify({ timestamp: Date.now() })
2240
- });
2241
- } catch (error) {
2242
- consola.warn("Failed to send ping:", error);
2243
- clearInterval(pingInterval);
2244
- }
2245
- }, 3e3);
2246
- try {
2247
- for await (const chunk of response) {
2248
- consola.debug("Responses stream chunk:", JSON.stringify(chunk));
2249
- await stream.writeSSE({
2250
- id: chunk.id,
2251
- event: chunk.event,
2252
- data: chunk.data ?? ""
2253
- });
2254
- }
2255
- } finally {
2256
- clearInterval(pingInterval);
2257
- }
2258
- });
2259
- }
2260
- consola.debug("Forwarding native Responses result:", JSON.stringify(response).slice(-400));
2261
- return c.json(response);
2262
- };
2263
- const isAsyncIterable = (value) => Boolean(value) && typeof value[Symbol.asyncIterator] === "function";
2264
- const isStreamingRequested = (payload) => Boolean(payload.stream);
2265
-
2266
- //#endregion
2267
- //#region src/routes/responses/route.ts
2268
- const responsesRoutes = new Hono();
2269
- responsesRoutes.post("/", async (c) => {
2270
- try {
2271
- return await handleResponses(c);
2272
- } catch (error) {
2273
- return await forwardError(c, error);
2274
- }
2275
- });
2276
-
2277
1301
  //#endregion
2278
1302
  //#region src/routes/token/route.ts
2279
1303
  const tokenRoute = new Hono();
@@ -2313,16 +1337,15 @@ server.route("/models", modelRoutes);
2313
1337
  server.route("/embeddings", embeddingRoutes);
2314
1338
  server.route("/usage", usageRoute);
2315
1339
  server.route("/token", tokenRoute);
2316
- server.route("/responses", responsesRoutes);
2317
1340
  server.route("/v1/chat/completions", completionRoutes);
2318
1341
  server.route("/v1/models", modelRoutes);
2319
1342
  server.route("/v1/embeddings", embeddingRoutes);
2320
- server.route("/v1/responses", responsesRoutes);
2321
1343
  server.route("/v1/messages", messageRoutes);
2322
1344
 
2323
1345
  //#endregion
2324
1346
  //#region src/start.ts
2325
1347
  async function runServer(options) {
1348
+ if (options.proxyEnv) initProxyFromEnv();
2326
1349
  if (options.verbose) {
2327
1350
  consola.level = 5;
2328
1351
  consola.info("Verbose logging enabled");
@@ -2432,6 +1455,11 @@ const start = defineCommand({
2432
1455
  type: "boolean",
2433
1456
  default: false,
2434
1457
  description: "Show GitHub and Copilot tokens on fetch and refresh"
1458
+ },
1459
+ "proxy-env": {
1460
+ type: "boolean",
1461
+ default: false,
1462
+ description: "Initialize proxy from environment variables"
2435
1463
  }
2436
1464
  },
2437
1465
  run({ args }) {
@@ -2446,16 +1474,17 @@ const start = defineCommand({
2446
1474
  rateLimitWait: args.wait,
2447
1475
  githubToken: args["github-token"],
2448
1476
  claudeCode: args["claude-code"],
2449
- showToken: args["show-token"]
1477
+ showToken: args["show-token"],
1478
+ proxyEnv: args["proxy-env"]
2450
1479
  });
2451
1480
  }
2452
1481
  });
2453
1482
 
2454
1483
  //#endregion
2455
1484
  //#region src/main.ts
2456
- const main = defineCommand({
1485
+ await runMain(defineCommand({
2457
1486
  meta: {
2458
- name: "heibaiapi",
1487
+ name: "copilot-api",
2459
1488
  description: "A wrapper around GitHub Copilot API to make it OpenAI compatible, making it usable for other tools."
2460
1489
  },
2461
1490
  subCommands: {
@@ -2464,9 +1493,7 @@ const main = defineCommand({
2464
1493
  "check-usage": checkUsage,
2465
1494
  debug
2466
1495
  }
2467
- });
2468
- initProxyFromEnv();
2469
- await runMain(main);
1496
+ }));
2470
1497
 
2471
1498
  //#endregion
2472
1499
  export { };