copilot-api-plus 1.0.52 → 1.0.54
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/README.md +9 -20
- package/dist/error-CBKWgD6B.js +3 -0
- package/dist/{error-SzJ4KHd8.js → error-CTmiDu8a.js} +11 -8
- package/dist/error-CTmiDu8a.js.map +1 -0
- package/dist/get-user-D1SF4af1.js +5 -0
- package/dist/{get-user-DEDD9jIs.js → get-user-DOjM9pn9.js} +2 -2
- package/dist/{get-user-DEDD9jIs.js.map → get-user-DOjM9pn9.js.map} +1 -1
- package/dist/main.js +10 -85
- package/dist/main.js.map +1 -1
- package/dist/token-2K-Nf49r.js +7 -0
- package/dist/{token-CpxbiiIw.js → token-CnocHC_C.js} +3 -3
- package/dist/{token-CpxbiiIw.js.map → token-CnocHC_C.js.map} +1 -1
- package/package.json +2 -2
- package/dist/error-DNWWcl_s.js +0 -3
- package/dist/error-SzJ4KHd8.js.map +0 -1
- package/dist/get-user-HhhC3uQr.js +0 -5
- package/dist/token-DkNaoDp7.js +0 -7
package/README.md
CHANGED
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
| 🌐 **代理支持** | 支持 HTTP/HTTPS 代理,配置持久化 |
|
|
43
43
|
| 🐳 **Docker 支持** | 提供完整的 Docker 部署方案 |
|
|
44
44
|
| 🔑 **API Key 认证** | 可选的 API Key 鉴权,保护公开部署的服务 |
|
|
45
|
-
| ✂️
|
|
45
|
+
| ✂️ **上下文透传** | 全量透传上下文至上游 API,由客户端(如 Claude Code)自行管理压缩 |
|
|
46
46
|
| 🔍 **智能模型匹配** | 自动处理模型名格式差异(日期后缀、dash/dot 版本号等) |
|
|
47
47
|
| 🔁 **Antigravity 端点容错** | 双端点自动切换,按模型族追踪速率限制,指数退避重试 |
|
|
48
48
|
|
|
@@ -648,14 +648,12 @@ curl http://localhost:4141/v1/messages \
|
|
|
648
648
|
|
|
649
649
|
## 🔧 技术细节
|
|
650
650
|
|
|
651
|
-
###
|
|
651
|
+
### 上下文管理
|
|
652
652
|
|
|
653
|
-
|
|
653
|
+
代理层不做上下文截断,全量透传消息至上游 API。上下文压缩由客户端负责:
|
|
654
654
|
|
|
655
|
-
-
|
|
656
|
-
-
|
|
657
|
-
- **工具调用分组**:assistant 的 tool_calls 和对应的 tool result 消息作为一组,不会被拆散
|
|
658
|
-
- **5% 安全余量**:实际限制为模型上下文窗口的 95%,避免边界情况
|
|
655
|
+
- **Claude Code**:通过 `/count_tokens` 端点获取当前 token 数,接近上限时自动触发 `/compact` 压缩
|
|
656
|
+
- **其他客户端**:如果上游 API 返回 400(token 超限),客户端自行处理重试
|
|
659
657
|
|
|
660
658
|
### 智能模型名匹配
|
|
661
659
|
|
|
@@ -680,20 +678,11 @@ Google Antigravity 模式内置了可靠性保障:
|
|
|
680
678
|
|
|
681
679
|
### 请求日志
|
|
682
680
|
|
|
683
|
-
每次 API
|
|
681
|
+
每次 API 请求会输出一行日志,包含模型名、状态码和耗时:
|
|
684
682
|
|
|
685
|
-
```
|
|
686
|
-
[claude-opus-4-6] 13:13:39
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
- `in` — 输入 token 数(不含缓存命中部分)
|
|
690
|
-
- `out` — 输出 token 数
|
|
691
|
-
- `cache_read` — 缓存命中的 token 数(仅在有缓存时显示)
|
|
692
|
-
|
|
693
|
-
触发上下文压缩时会额外输出一行:
|
|
694
|
-
|
|
695
|
-
```
|
|
696
|
-
Truncated: 190385 -> 117537 tokens (-59 msgs)
|
|
683
|
+
```log
|
|
684
|
+
[claude-opus-4-6] 13:13:39 <-- POST /v1/messages?beta=true
|
|
685
|
+
[claude-opus-4-6] 13:13:59 --> POST /v1/messages?beta=true 200 20.1s
|
|
697
686
|
```
|
|
698
687
|
|
|
699
688
|
### 网络重试
|
|
@@ -9,7 +9,6 @@ var HTTPError = class extends Error {
|
|
|
9
9
|
}
|
|
10
10
|
};
|
|
11
11
|
async function forwardError(c, error) {
|
|
12
|
-
consola.error("Error occurred:", error);
|
|
13
12
|
if (error instanceof HTTPError) {
|
|
14
13
|
let errorText;
|
|
15
14
|
try {
|
|
@@ -17,18 +16,22 @@ async function forwardError(c, error) {
|
|
|
17
16
|
} catch {
|
|
18
17
|
errorText = error.message;
|
|
19
18
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
if (error.response.status === 400) {} else {
|
|
20
|
+
let errorJson;
|
|
21
|
+
try {
|
|
22
|
+
errorJson = JSON.parse(errorText);
|
|
23
|
+
} catch {
|
|
24
|
+
errorJson = errorText;
|
|
25
|
+
}
|
|
26
|
+
consola.error("Error occurred:", error);
|
|
27
|
+
consola.error("HTTP error:", errorJson);
|
|
25
28
|
}
|
|
26
|
-
consola.error("HTTP error:", errorJson);
|
|
27
29
|
return c.json({ error: {
|
|
28
30
|
message: errorText,
|
|
29
31
|
type: "error"
|
|
30
32
|
} }, error.response.status);
|
|
31
33
|
}
|
|
34
|
+
consola.error("Error occurred:", error);
|
|
32
35
|
return c.json({ error: {
|
|
33
36
|
message: error.message,
|
|
34
37
|
type: "error"
|
|
@@ -37,4 +40,4 @@ async function forwardError(c, error) {
|
|
|
37
40
|
|
|
38
41
|
//#endregion
|
|
39
42
|
export { HTTPError, forwardError };
|
|
40
|
-
//# sourceMappingURL=error-
|
|
43
|
+
//# sourceMappingURL=error-CTmiDu8a.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-CTmiDu8a.js","names":["errorText: string","errorJson: unknown"],"sources":["../src/lib/error.ts"],"sourcesContent":["import type { Context } from \"hono\"\nimport type { ContentfulStatusCode } from \"hono/utils/http-status\"\n\nimport consola from \"consola\"\n\nexport class HTTPError extends Error {\n response: Response\n\n constructor(message: string, response: Response) {\n super(message)\n this.response = response\n }\n}\n\nexport async function forwardError(c: Context, error: unknown) {\n if (error instanceof HTTPError) {\n // Try to read error body, but it may already be consumed by the caller\n let errorText: string\n try {\n errorText = await error.response.text()\n } catch {\n // Body already read — fall back to the error message\n errorText = error.message\n }\n\n // 400 errors: concise log, already detailed upstream\n if (error.response.status === 400) {\n // no extra logging, upstream already printed details\n } else {\n let errorJson: unknown\n try {\n errorJson = JSON.parse(errorText)\n } catch {\n errorJson = errorText\n }\n consola.error(\"Error occurred:\", error)\n consola.error(\"HTTP error:\", errorJson)\n }\n\n return c.json(\n {\n error: {\n message: errorText,\n type: \"error\",\n },\n },\n error.response.status as ContentfulStatusCode,\n )\n }\n\n consola.error(\"Error occurred:\", error)\n return c.json(\n {\n error: {\n message: (error as Error).message,\n type: \"error\",\n },\n },\n 500,\n )\n}\n"],"mappings":";;;AAKA,IAAa,YAAb,cAA+B,MAAM;CACnC;CAEA,YAAY,SAAiB,UAAoB;AAC/C,QAAM,QAAQ;AACd,OAAK,WAAW;;;AAIpB,eAAsB,aAAa,GAAY,OAAgB;AAC7D,KAAI,iBAAiB,WAAW;EAE9B,IAAIA;AACJ,MAAI;AACF,eAAY,MAAM,MAAM,SAAS,MAAM;UACjC;AAEN,eAAY,MAAM;;AAIpB,MAAI,MAAM,SAAS,WAAW,KAAK,QAE5B;GACL,IAAIC;AACJ,OAAI;AACF,gBAAY,KAAK,MAAM,UAAU;WAC3B;AACN,gBAAY;;AAEd,WAAQ,MAAM,mBAAmB,MAAM;AACvC,WAAQ,MAAM,eAAe,UAAU;;AAGzC,SAAO,EAAE,KACP,EACE,OAAO;GACL,SAAS;GACT,MAAM;GACP,EACF,EACD,MAAM,SAAS,OAChB;;AAGH,SAAQ,MAAM,mBAAmB,MAAM;AACvC,QAAO,EAAE,KACP,EACE,OAAO;EACL,SAAU,MAAgB;EAC1B,MAAM;EACP,EACF,EACD,IACD"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { state } from "./state-CcLGr8VN.js";
|
|
2
|
-
import { HTTPError } from "./error-
|
|
2
|
+
import { HTTPError } from "./error-CTmiDu8a.js";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
|
|
5
5
|
//#region src/lib/api-config.ts
|
|
@@ -58,4 +58,4 @@ async function getGitHubUser() {
|
|
|
58
58
|
|
|
59
59
|
//#endregion
|
|
60
60
|
export { GITHUB_API_BASE_URL, GITHUB_APP_SCOPES, GITHUB_BASE_URL, GITHUB_CLIENT_ID, copilotBaseUrl, copilotHeaders, getGitHubUser, githubHeaders, standardHeaders };
|
|
61
|
-
//# sourceMappingURL=get-user-
|
|
61
|
+
//# sourceMappingURL=get-user-DOjM9pn9.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-user-
|
|
1
|
+
{"version":3,"file":"get-user-DOjM9pn9.js","names":["state","headers: Record<string, string>"],"sources":["../src/lib/api-config.ts","../src/services/github/get-user.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\"\n\nimport type { State } from \"./state\"\n\nexport const standardHeaders = () => ({\n \"content-type\": \"application/json\",\n accept: \"application/json\",\n})\n\nconst COPILOT_VERSION = \"0.26.7\"\nconst EDITOR_PLUGIN_VERSION = `copilot-chat/${COPILOT_VERSION}`\nconst USER_AGENT = `GitHubCopilotChat/${COPILOT_VERSION}`\n\n// Updated to match latest Zed implementation - 2025-05-01 returns Claude models\nconst API_VERSION = \"2025-05-01\"\n\n// Use the API endpoint from token response if available, otherwise fall back to default\nexport const copilotBaseUrl = (state: State) => {\n if (state.copilotApiEndpoint) {\n return state.copilotApiEndpoint\n }\n return state.accountType === \"individual\" ?\n \"https://api.githubcopilot.com\"\n : `https://api.${state.accountType}.githubcopilot.com`\n}\nexport const copilotHeaders = (state: State, vision: boolean = false) => {\n const headers: Record<string, string> = {\n Authorization: `Bearer ${state.copilotToken}`,\n \"content-type\": standardHeaders()[\"content-type\"],\n \"copilot-integration-id\": \"vscode-chat\",\n \"editor-version\": `vscode/${state.vsCodeVersion}`,\n \"editor-plugin-version\": EDITOR_PLUGIN_VERSION,\n \"user-agent\": USER_AGENT,\n \"openai-intent\": \"conversation-panel\",\n \"x-github-api-version\": API_VERSION,\n \"x-request-id\": randomUUID(),\n \"x-vscode-user-agent-library-version\": \"electron-fetch\",\n }\n\n if (vision) headers[\"copilot-vision-request\"] = \"true\"\n\n return headers\n}\n\nexport const GITHUB_API_BASE_URL = \"https://api.github.com\"\nexport const githubHeaders = (state: State) => ({\n ...standardHeaders(),\n authorization: `token ${state.githubToken}`,\n \"editor-version\": `vscode/${state.vsCodeVersion}`,\n \"editor-plugin-version\": EDITOR_PLUGIN_VERSION,\n \"user-agent\": USER_AGENT,\n \"x-github-api-version\": API_VERSION,\n \"x-vscode-user-agent-library-version\": \"electron-fetch\",\n})\n\nexport const GITHUB_BASE_URL = \"https://github.com\"\nexport const GITHUB_CLIENT_ID = \"Iv1.b507a08c87ecfe98\"\nexport const GITHUB_APP_SCOPES = [\"read:user\"].join(\" \")\n","import { GITHUB_API_BASE_URL, standardHeaders } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { state } from \"~/lib/state\"\n\nexport async function getGitHubUser() {\n const response = await fetch(`${GITHUB_API_BASE_URL}/user`, {\n headers: {\n authorization: `token ${state.githubToken}`,\n ...standardHeaders(),\n },\n })\n\n if (!response.ok) throw new HTTPError(\"Failed to get GitHub user\", response)\n\n return (await response.json()) as GithubUserResponse\n}\n\n// Trimmed for the sake of simplicity\ninterface GithubUserResponse {\n login: string\n}\n"],"mappings":";;;;;AAIA,MAAa,yBAAyB;CACpC,gBAAgB;CAChB,QAAQ;CACT;AAED,MAAM,kBAAkB;AACxB,MAAM,wBAAwB,gBAAgB;AAC9C,MAAM,aAAa,qBAAqB;AAGxC,MAAM,cAAc;AAGpB,MAAa,kBAAkB,YAAiB;AAC9C,KAAIA,QAAM,mBACR,QAAOA,QAAM;AAEf,QAAOA,QAAM,gBAAgB,eACzB,kCACA,eAAeA,QAAM,YAAY;;AAEvC,MAAa,kBAAkB,SAAc,SAAkB,UAAU;CACvE,MAAMC,UAAkC;EACtC,eAAe,UAAUD,QAAM;EAC/B,gBAAgB,iBAAiB,CAAC;EAClC,0BAA0B;EAC1B,kBAAkB,UAAUA,QAAM;EAClC,yBAAyB;EACzB,cAAc;EACd,iBAAiB;EACjB,wBAAwB;EACxB,gBAAgB,YAAY;EAC5B,uCAAuC;EACxC;AAED,KAAI,OAAQ,SAAQ,4BAA4B;AAEhD,QAAO;;AAGT,MAAa,sBAAsB;AACnC,MAAa,iBAAiB,aAAkB;CAC9C,GAAG,iBAAiB;CACpB,eAAe,SAASA,QAAM;CAC9B,kBAAkB,UAAUA,QAAM;CAClC,yBAAyB;CACzB,cAAc;CACd,wBAAwB;CACxB,uCAAuC;CACxC;AAED,MAAa,kBAAkB;AAC/B,MAAa,mBAAmB;AAChC,MAAa,oBAAoB,CAAC,YAAY,CAAC,KAAK,IAAI;;;;ACrDxD,eAAsB,gBAAgB;CACpC,MAAM,WAAW,MAAM,MAAM,GAAG,oBAAoB,QAAQ,EAC1D,SAAS;EACP,eAAe,SAAS,MAAM;EAC9B,GAAG,iBAAiB;EACrB,EACF,CAAC;AAEF,KAAI,CAAC,SAAS,GAAI,OAAM,IAAI,UAAU,6BAA6B,SAAS;AAE5E,QAAQ,MAAM,SAAS,MAAM"}
|
package/dist/main.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { PATHS, ensurePaths } from "./paths-CVYLp61D.js";
|
|
3
3
|
import { state } from "./state-CcLGr8VN.js";
|
|
4
|
-
import { GITHUB_API_BASE_URL, copilotBaseUrl, copilotHeaders, githubHeaders } from "./get-user-
|
|
5
|
-
import { HTTPError, forwardError } from "./error-
|
|
6
|
-
import { cacheModels, cacheVSCodeVersion, clearGithubToken, findModel, isNullish, refreshCopilotToken, setupCopilotToken, setupGitHubToken, sleep } from "./token-
|
|
4
|
+
import { GITHUB_API_BASE_URL, copilotBaseUrl, copilotHeaders, githubHeaders } from "./get-user-DOjM9pn9.js";
|
|
5
|
+
import { HTTPError, forwardError } from "./error-CTmiDu8a.js";
|
|
6
|
+
import { cacheModels, cacheVSCodeVersion, clearGithubToken, findModel, isNullish, refreshCopilotToken, setupCopilotToken, setupGitHubToken, sleep } from "./token-CnocHC_C.js";
|
|
7
7
|
import { clearAntigravityAuth, disableCurrentAccount, getAntigravityAuthPath, getApiKey, getCurrentProjectId, getValidAccessToken, rotateAccount } from "./auth-CWGl6kMf.js";
|
|
8
8
|
import { clearZenAuth, getZenAuthPath } from "./auth-BrdL89xk.js";
|
|
9
9
|
import { getAntigravityModels, getAntigravityUsage, isThinkingModel } from "./get-models-uEbEgq0L.js";
|
|
@@ -1194,27 +1194,6 @@ const apiKeyAuthMiddleware = async (c, next) => {
|
|
|
1194
1194
|
//#endregion
|
|
1195
1195
|
//#region src/lib/model-logger.ts
|
|
1196
1196
|
/**
|
|
1197
|
-
* Global token usage store for passing usage info from handlers to logger.
|
|
1198
|
-
* Handlers call setTokenUsage() when usage is available,
|
|
1199
|
-
* logger reads and clears it after await next().
|
|
1200
|
-
*
|
|
1201
|
-
* For streaming responses, usage arrives after next() returns.
|
|
1202
|
-
* In that case the handler calls signalStreamDone() when the stream ends,
|
|
1203
|
-
* and the logger waits for it with a timeout.
|
|
1204
|
-
*/
|
|
1205
|
-
let pendingTokenUsage;
|
|
1206
|
-
let streamDoneResolve;
|
|
1207
|
-
function setTokenUsage(usage) {
|
|
1208
|
-
pendingTokenUsage = usage;
|
|
1209
|
-
}
|
|
1210
|
-
/**
|
|
1211
|
-
* Notify the logger that a streaming response has finished sending.
|
|
1212
|
-
* Must be called at the end of streamSSE callbacks.
|
|
1213
|
-
*/
|
|
1214
|
-
function signalStreamDone() {
|
|
1215
|
-
streamDoneResolve?.();
|
|
1216
|
-
}
|
|
1217
|
-
/**
|
|
1218
1197
|
* Get timestamp string in format HH:mm:ss
|
|
1219
1198
|
*/
|
|
1220
1199
|
function getTime() {
|
|
@@ -1228,15 +1207,6 @@ function formatDuration(ms) {
|
|
|
1228
1207
|
return `${(ms / 1e3).toFixed(1)}s`;
|
|
1229
1208
|
}
|
|
1230
1209
|
/**
|
|
1231
|
-
* Format token usage for log output
|
|
1232
|
-
*/
|
|
1233
|
-
function formatTokenUsage(usage) {
|
|
1234
|
-
const parts = [`in:${usage.inputTokens}`, `out:${usage.outputTokens}`];
|
|
1235
|
-
if (usage.cacheReadTokens) parts.push(`cache_read:${usage.cacheReadTokens}`);
|
|
1236
|
-
if (usage.cacheCreationTokens) parts.push(`cache_create:${usage.cacheCreationTokens}`);
|
|
1237
|
-
return parts.join(" ");
|
|
1238
|
-
}
|
|
1239
|
-
/**
|
|
1240
1210
|
* Extract model name from request body
|
|
1241
1211
|
*/
|
|
1242
1212
|
async function extractModel(c) {
|
|
@@ -1251,7 +1221,7 @@ async function extractModel(c) {
|
|
|
1251
1221
|
*
|
|
1252
1222
|
* Output format:
|
|
1253
1223
|
* [model] HH:mm:ss <-- METHOD /path
|
|
1254
|
-
* [model] HH:mm:ss --> METHOD /path STATUS DURATION
|
|
1224
|
+
* [model] HH:mm:ss --> METHOD /path STATUS DURATION
|
|
1255
1225
|
*/
|
|
1256
1226
|
function modelLogger() {
|
|
1257
1227
|
return async (c, next) => {
|
|
@@ -1263,23 +1233,12 @@ function modelLogger() {
|
|
|
1263
1233
|
if (method === "POST" && c.req.header("content-type")?.includes("json")) model = await extractModel(c);
|
|
1264
1234
|
const modelPrefix = model ? `[${model}] ` : "";
|
|
1265
1235
|
const startTime = getTime();
|
|
1266
|
-
pendingTokenUsage = void 0;
|
|
1267
|
-
const localStreamDone = new Promise((resolve) => {
|
|
1268
|
-
streamDoneResolve = resolve;
|
|
1269
|
-
});
|
|
1270
1236
|
console.log(`${modelPrefix}${startTime} <-- ${method} ${fullPath}`);
|
|
1271
1237
|
const start$1 = Date.now();
|
|
1272
1238
|
await next();
|
|
1273
|
-
if (c.res.headers.get("content-type")?.includes("text/event-stream") && !pendingTokenUsage) {
|
|
1274
|
-
const timeout = new Promise((resolve) => setTimeout(resolve, 12e4));
|
|
1275
|
-
await Promise.race([localStreamDone, timeout]);
|
|
1276
|
-
}
|
|
1277
1239
|
const duration = Date.now() - start$1;
|
|
1278
1240
|
const endTime = getTime();
|
|
1279
|
-
|
|
1280
|
-
pendingTokenUsage = void 0;
|
|
1281
|
-
const usageSuffix = usage ? ` [${formatTokenUsage(usage)}]` : "";
|
|
1282
|
-
console.log(`${modelPrefix}${endTime} --> ${method} ${fullPath} ${c.res.status} ${formatDuration(duration)}${usageSuffix}`);
|
|
1241
|
+
console.log(`${modelPrefix}${endTime} --> ${method} ${fullPath} ${c.res.status} ${formatDuration(duration)}`);
|
|
1283
1242
|
};
|
|
1284
1243
|
}
|
|
1285
1244
|
|
|
@@ -2688,7 +2647,8 @@ const createChatCompletions = async (payload) => {
|
|
|
2688
2647
|
}
|
|
2689
2648
|
if (!response.ok) {
|
|
2690
2649
|
const errorBody = await response.text();
|
|
2691
|
-
|
|
2650
|
+
if (response.status === 400) consola.warn(`400: ${errorBody}`);
|
|
2651
|
+
else consola.error("Failed to create chat completions", {
|
|
2692
2652
|
status: response.status,
|
|
2693
2653
|
statusText: response.statusText,
|
|
2694
2654
|
body: errorBody
|
|
@@ -2727,34 +2687,14 @@ async function handleCompletion$1(c) {
|
|
|
2727
2687
|
const response = await createChatCompletions(payload);
|
|
2728
2688
|
if (isNonStreaming$1(response)) {
|
|
2729
2689
|
consola.debug("Non-streaming response:", JSON.stringify(response));
|
|
2730
|
-
if (response.usage) setTokenUsage({
|
|
2731
|
-
inputTokens: response.usage.prompt_tokens,
|
|
2732
|
-
outputTokens: response.usage.completion_tokens,
|
|
2733
|
-
cacheReadTokens: response.usage.prompt_tokens_details?.cached_tokens
|
|
2734
|
-
});
|
|
2735
2690
|
return c.json(response);
|
|
2736
2691
|
}
|
|
2737
2692
|
consola.debug("Streaming response");
|
|
2738
2693
|
return streamSSE(c, async (stream) => {
|
|
2739
2694
|
for await (const chunk of response) {
|
|
2740
2695
|
consola.debug("Streaming chunk:", JSON.stringify(chunk));
|
|
2741
|
-
try {
|
|
2742
|
-
const sseChunk = chunk;
|
|
2743
|
-
if (sseChunk.data && sseChunk.data !== "[DONE]") {
|
|
2744
|
-
const parsed = JSON.parse(sseChunk.data);
|
|
2745
|
-
if (parsed.usage) {
|
|
2746
|
-
const usage = {
|
|
2747
|
-
inputTokens: parsed.usage.prompt_tokens ?? 0,
|
|
2748
|
-
outputTokens: parsed.usage.completion_tokens ?? 0,
|
|
2749
|
-
cacheReadTokens: parsed.usage.prompt_tokens_details?.cached_tokens
|
|
2750
|
-
};
|
|
2751
|
-
setTokenUsage(usage);
|
|
2752
|
-
}
|
|
2753
|
-
}
|
|
2754
|
-
} catch {}
|
|
2755
2696
|
await stream.writeSSE(chunk);
|
|
2756
2697
|
}
|
|
2757
|
-
signalStreamDone();
|
|
2758
2698
|
});
|
|
2759
2699
|
}
|
|
2760
2700
|
const isNonStreaming$1 = (response) => Object.hasOwn(response, "choices");
|
|
@@ -3372,12 +3312,6 @@ async function handleCompletion(c) {
|
|
|
3372
3312
|
const response = await createChatCompletions(openAIPayload);
|
|
3373
3313
|
if (isNonStreaming(response)) {
|
|
3374
3314
|
const anthropicResponse = translateToAnthropic(response);
|
|
3375
|
-
setTokenUsage({
|
|
3376
|
-
inputTokens: anthropicResponse.usage.input_tokens,
|
|
3377
|
-
outputTokens: anthropicResponse.usage.output_tokens,
|
|
3378
|
-
cacheReadTokens: anthropicResponse.usage.cache_read_input_tokens,
|
|
3379
|
-
cacheCreationTokens: anthropicResponse.usage.cache_creation_input_tokens
|
|
3380
|
-
});
|
|
3381
3315
|
return c.json(anthropicResponse);
|
|
3382
3316
|
}
|
|
3383
3317
|
return streamSSE(c, async (stream) => {
|
|
@@ -3392,20 +3326,11 @@ async function handleCompletion(c) {
|
|
|
3392
3326
|
if (!rawEvent.data) continue;
|
|
3393
3327
|
const chunk = JSON.parse(rawEvent.data);
|
|
3394
3328
|
const events$1 = translateChunkToAnthropicEvents(chunk, streamState);
|
|
3395
|
-
if (chunk.usage) {
|
|
3396
|
-
const usage = {
|
|
3397
|
-
inputTokens: chunk.usage.prompt_tokens - (chunk.usage.prompt_tokens_details?.cached_tokens ?? 0),
|
|
3398
|
-
outputTokens: chunk.usage.completion_tokens,
|
|
3399
|
-
cacheReadTokens: chunk.usage.prompt_tokens_details?.cached_tokens
|
|
3400
|
-
};
|
|
3401
|
-
setTokenUsage(usage);
|
|
3402
|
-
}
|
|
3403
3329
|
for (const event of events$1) await stream.writeSSE({
|
|
3404
3330
|
event: event.type,
|
|
3405
3331
|
data: JSON.stringify(event)
|
|
3406
3332
|
});
|
|
3407
3333
|
}
|
|
3408
|
-
signalStreamDone();
|
|
3409
3334
|
});
|
|
3410
3335
|
}
|
|
3411
3336
|
const isNonStreaming = (response) => Object.hasOwn(response, "choices");
|
|
@@ -3978,7 +3903,7 @@ async function runServer(options$1) {
|
|
|
3978
3903
|
state.githubToken = options$1.githubToken;
|
|
3979
3904
|
consola.info("Using provided GitHub token");
|
|
3980
3905
|
try {
|
|
3981
|
-
const { getGitHubUser } = await import("./get-user-
|
|
3906
|
+
const { getGitHubUser } = await import("./get-user-D1SF4af1.js");
|
|
3982
3907
|
const user = await getGitHubUser();
|
|
3983
3908
|
consola.info(`Logged in as ${user.login}`);
|
|
3984
3909
|
} catch (error) {
|
|
@@ -3989,10 +3914,10 @@ async function runServer(options$1) {
|
|
|
3989
3914
|
try {
|
|
3990
3915
|
await setupCopilotToken();
|
|
3991
3916
|
} catch (error) {
|
|
3992
|
-
const { HTTPError: HTTPError$1 } = await import("./error-
|
|
3917
|
+
const { HTTPError: HTTPError$1 } = await import("./error-CBKWgD6B.js");
|
|
3993
3918
|
if (error instanceof HTTPError$1 && error.response.status === 401) {
|
|
3994
3919
|
consola.error("Failed to get Copilot token - GitHub token may be invalid or Copilot access revoked");
|
|
3995
|
-
const { clearGithubToken: clearGithubToken$1 } = await import("./token-
|
|
3920
|
+
const { clearGithubToken: clearGithubToken$1 } = await import("./token-2K-Nf49r.js");
|
|
3996
3921
|
await clearGithubToken$1();
|
|
3997
3922
|
consola.info("Please restart to re-authenticate");
|
|
3998
3923
|
}
|