@nick3/copilot-api 1.4.6 → 1.4.9
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/{account-DhQb2A6q.js → account-CipKmikF.js} +2 -2
- package/dist/{account-DhQb2A6q.js.map → account-CipKmikF.js.map} +1 -1
- package/dist/{accounts-manager-B8Y2Y4ab.js → accounts-manager-Cjrd_el_.js} +22 -37
- package/dist/accounts-manager-Cjrd_el_.js.map +1 -0
- package/dist/{accounts-registry-c7rs5Ed9.js → accounts-registry-CQYvRe65.js} +3 -3
- package/dist/{accounts-registry-c7rs5Ed9.js.map → accounts-registry-CQYvRe65.js.map} +1 -1
- package/dist/{auth-Bt0FGr8C.js → auth-1gAffrpI.js} +6 -6
- package/dist/{auth-Bt0FGr8C.js.map → auth-1gAffrpI.js.map} +1 -1
- package/dist/{check-usage-By-sJOch.js → check-usage-CsRu467P.js} +5 -5
- package/dist/{check-usage-By-sJOch.js.map → check-usage-CsRu467P.js.map} +1 -1
- package/dist/{debug-hQJWwXtC.js → debug-BzR5ZQUk.js} +3 -3
- package/dist/{debug-hQJWwXtC.js.map → debug-BzR5ZQUk.js.map} +1 -1
- package/dist/{get-copilot-token-Q4FXtOE9.js → get-copilot-token-BbpphnmV.js} +3 -3
- package/dist/{get-copilot-token-Q4FXtOE9.js.map → get-copilot-token-BbpphnmV.js.map} +1 -1
- package/dist/main.js +6 -7
- package/dist/main.js.map +1 -1
- package/dist/{paths-DoT4SZ8f.js → paths-Cvzy-eLX.js} +2 -2
- package/dist/{paths-DoT4SZ8f.js.map → paths-Cvzy-eLX.js.map} +1 -1
- package/dist/{poll-access-token-Cp_DfHGH.js → poll-access-token-CGfLFzMq.js} +3 -3
- package/dist/{poll-access-token-Cp_DfHGH.js.map → poll-access-token-CGfLFzMq.js.map} +1 -1
- package/dist/{server-Cln-GCLU.js → server-DqwhClJ-.js} +68 -94
- package/dist/server-DqwhClJ-.js.map +1 -0
- package/dist/{start-DH-QnZxL.js → start-B1_Ols5Z.js} +15 -17
- package/dist/{start-DH-QnZxL.js.map → start-B1_Ols5Z.js.map} +1 -1
- package/dist/{utils-SV0FyqXk.js → utils-DY-jLXwO.js} +34 -10
- package/dist/utils-DY-jLXwO.js.map +1 -0
- package/package.json +3 -1
- package/dist/accounts-manager-B8Y2Y4ab.js.map +0 -1
- package/dist/server-Cln-GCLU.js.map +0 -1
- package/dist/utils-SV0FyqXk.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-usage-
|
|
1
|
+
{"version":3,"file":"check-usage-CsRu467P.js","names":[],"sources":["../src/lib/token.ts","../src/check-usage.ts"],"sourcesContent":["import consola from \"consola\"\nimport fs from \"node:fs/promises\"\nimport { setTimeout as delay } from \"node:timers/promises\"\n\nimport { isOpencodeOauthApp } from \"~/lib/api-config\"\nimport { PATHS } from \"~/lib/paths\"\nimport { getCopilotToken } from \"~/services/github/get-copilot-token\"\nimport { getDeviceCode } from \"~/services/github/get-device-code\"\nimport { getGitHubUser } from \"~/services/github/get-user\"\nimport { pollAccessToken } from \"~/services/github/poll-access-token\"\n\nimport { HTTPError } from \"./error\"\nimport { state } from \"./state\"\n\nlet copilotRefreshLoopController: AbortController | null = null\n\nexport const stopCopilotRefreshLoop = () => {\n if (!copilotRefreshLoopController) {\n return\n }\n\n copilotRefreshLoopController.abort()\n copilotRefreshLoopController = null\n}\n\nconst readGithubToken = () => fs.readFile(PATHS.GITHUB_TOKEN_PATH, \"utf8\")\n\nconst writeGithubToken = (token: string) =>\n fs.writeFile(PATHS.GITHUB_TOKEN_PATH, token)\n\nexport const setupCopilotToken = async () => {\n if (isOpencodeOauthApp()) {\n if (!state.githubToken) throw new Error(`opencode token not found`)\n\n state.copilotToken = state.githubToken\n\n consola.debug(\"GitHub Copilot token set from opencode auth token\")\n if (state.showToken) {\n consola.info(\"Copilot token:\", state.copilotToken)\n }\n\n stopCopilotRefreshLoop()\n return\n }\n\n const { token, refresh_in } = await getCopilotToken()\n state.copilotToken = token\n\n // Display the Copilot token to the screen\n consola.debug(\"GitHub Copilot Token fetched successfully!\")\n if (state.showToken) {\n consola.info(\"Copilot token:\", token)\n }\n\n stopCopilotRefreshLoop()\n\n const controller = new AbortController()\n copilotRefreshLoopController = controller\n\n runCopilotRefreshLoop(refresh_in, controller.signal)\n .catch(() => {\n consola.warn(\"Copilot token refresh loop stopped\")\n })\n .finally(() => {\n if (copilotRefreshLoopController === controller) {\n copilotRefreshLoopController = null\n }\n })\n}\n\nconst runCopilotRefreshLoop = async (\n refreshIn: number,\n signal: AbortSignal,\n) => {\n let nextRefreshDelayMs = (refreshIn - 60) * 1000\n\n while (!signal.aborted) {\n await delay(nextRefreshDelayMs, undefined, { signal })\n\n consola.debug(\"Refreshing Copilot token\")\n\n try {\n const { token, refresh_in } = await getCopilotToken()\n state.copilotToken = token\n consola.debug(\"Copilot token refreshed\")\n if (state.showToken) {\n consola.info(\"Refreshed Copilot token:\", token)\n }\n\n nextRefreshDelayMs = (refresh_in - 60) * 1000\n } catch (error) {\n consola.error(\"Failed to refresh Copilot token:\", error)\n nextRefreshDelayMs = 15_000\n consola.warn(`Retrying Copilot token refresh in ${nextRefreshDelayMs}ms`)\n }\n }\n}\n\ninterface SetupGitHubTokenOptions {\n force?: boolean\n}\n\nexport async function setupGitHubToken(\n options?: SetupGitHubTokenOptions,\n): Promise<void> {\n try {\n const githubToken = await readGithubToken()\n\n if (githubToken && !options?.force) {\n state.githubToken = githubToken\n if (state.showToken) {\n consola.info(\"GitHub token:\", githubToken)\n }\n await logUser()\n\n return\n }\n\n consola.info(\"Not logged in, getting new access token\")\n const response = await getDeviceCode()\n consola.debug(\"Device code response:\", response)\n\n consola.info(\n `Please enter the code \"${response.user_code}\" in ${response.verification_uri}`,\n )\n\n const token = await pollAccessToken(response)\n await writeGithubToken(token)\n state.githubToken = token\n\n if (state.showToken) {\n consola.info(\"GitHub token:\", token)\n }\n await logUser()\n } catch (error) {\n if (error instanceof HTTPError) {\n consola.error(\"Failed to get GitHub token:\", await error.response.json())\n throw error\n }\n\n consola.error(\"Failed to get GitHub token:\", error)\n throw error\n }\n}\n\nasync function logUser() {\n const user = await getGitHubUser()\n consola.info(`Logged in as ${user.login}`)\n}\n","import { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { ensurePaths } from \"./lib/paths\"\nimport { setupGitHubToken } from \"./lib/token\"\nimport {\n getCopilotUsage,\n type QuotaDetail,\n} from \"./services/github/get-copilot-usage\"\n\nexport const checkUsage = defineCommand({\n meta: {\n name: \"check-usage\",\n description: \"Show current GitHub Copilot usage/quota information\",\n },\n async run() {\n await ensurePaths()\n await setupGitHubToken()\n try {\n const usage = await getCopilotUsage()\n const premium = usage.quota_snapshots.premium_interactions\n const premiumTotal = premium.entitlement\n const premiumUsed = premiumTotal - premium.remaining\n const premiumPercentUsed =\n premiumTotal > 0 ? (premiumUsed / premiumTotal) * 100 : 0\n const premiumPercentRemaining = premium.percent_remaining\n\n // Helper to summarize a quota snapshot\n function summarizeQuota(name: string, snap: QuotaDetail | undefined) {\n if (!snap) return `${name}: N/A`\n const total = snap.entitlement\n const used = total - snap.remaining\n const percentUsed = total > 0 ? (used / total) * 100 : 0\n const percentRemaining = snap.percent_remaining\n return `${name}: ${used}/${total} used (${percentUsed.toFixed(1)}% used, ${percentRemaining.toFixed(1)}% remaining)`\n }\n\n const premiumLine = `Premium: ${premiumUsed}/${premiumTotal} used (${premiumPercentUsed.toFixed(1)}% used, ${premiumPercentRemaining.toFixed(1)}% remaining)`\n const chatLine = summarizeQuota(\"Chat\", usage.quota_snapshots.chat)\n const completionsLine = summarizeQuota(\n \"Completions\",\n usage.quota_snapshots.completions,\n )\n\n consola.box(\n `Copilot Usage (plan: ${usage.copilot_plan})\\n`\n + `Quota resets: ${usage.quota_reset_date}\\n`\n + `\\nQuotas:\\n`\n + ` ${premiumLine}\\n`\n + ` ${chatLine}\\n`\n + ` ${completionsLine}`,\n )\n } catch (err) {\n consola.error(\"Failed to fetch Copilot usage:\", err)\n process.exit(1)\n }\n },\n})\n"],"mappings":";;;;;;;;;AAyBA,MAAM,wBAAwB,GAAG,SAAS,MAAM,mBAAmB,OAAO;AAE1E,MAAM,oBAAoB,UACxB,GAAG,UAAU,MAAM,mBAAmB,MAAM;AA0E9C,eAAsB,iBACpB,SACe;AACf,KAAI;EACF,MAAM,cAAc,MAAM,iBAAiB;AAE3C,MAAI,eAAe,CAAC,SAAS,OAAO;AAClC,SAAM,cAAc;AACpB,OAAI,MAAM,UACR,SAAQ,KAAK,iBAAiB,YAAY;AAE5C,SAAM,SAAS;AAEf;;AAGF,UAAQ,KAAK,0CAA0C;EACvD,MAAM,WAAW,MAAM,eAAe;AACtC,UAAQ,MAAM,yBAAyB,SAAS;AAEhD,UAAQ,KACN,0BAA0B,SAAS,UAAU,OAAO,SAAS,mBAC9D;EAED,MAAM,QAAQ,MAAM,gBAAgB,SAAS;AAC7C,QAAM,iBAAiB,MAAM;AAC7B,QAAM,cAAc;AAEpB,MAAI,MAAM,UACR,SAAQ,KAAK,iBAAiB,MAAM;AAEtC,QAAM,SAAS;UACR,OAAO;AACd,MAAI,iBAAiB,WAAW;AAC9B,WAAQ,MAAM,+BAA+B,MAAM,MAAM,SAAS,MAAM,CAAC;AACzE,SAAM;;AAGR,UAAQ,MAAM,+BAA+B,MAAM;AACnD,QAAM;;;AAIV,eAAe,UAAU;CACvB,MAAM,OAAO,MAAM,eAAe;AAClC,SAAQ,KAAK,gBAAgB,KAAK,QAAQ;;;;;ACzI5C,MAAa,aAAa,cAAc;CACtC,MAAM;EACJ,MAAM;EACN,aAAa;EACd;CACD,MAAM,MAAM;AACV,QAAM,aAAa;AACnB,QAAM,kBAAkB;AACxB,MAAI;GACF,MAAM,QAAQ,MAAM,iBAAiB;GACrC,MAAM,UAAU,MAAM,gBAAgB;GACtC,MAAM,eAAe,QAAQ;GAC7B,MAAM,cAAc,eAAe,QAAQ;GAC3C,MAAM,qBACJ,eAAe,IAAK,cAAc,eAAgB,MAAM;GAC1D,MAAM,0BAA0B,QAAQ;GAGxC,SAAS,eAAe,MAAc,MAA+B;AACnE,QAAI,CAAC,KAAM,QAAO,GAAG,KAAK;IAC1B,MAAM,QAAQ,KAAK;IACnB,MAAM,OAAO,QAAQ,KAAK;IAC1B,MAAM,cAAc,QAAQ,IAAK,OAAO,QAAS,MAAM;IACvD,MAAM,mBAAmB,KAAK;AAC9B,WAAO,GAAG,KAAK,IAAI,KAAK,GAAG,MAAM,SAAS,YAAY,QAAQ,EAAE,CAAC,UAAU,iBAAiB,QAAQ,EAAE,CAAC;;GAGzG,MAAM,cAAc,YAAY,YAAY,GAAG,aAAa,SAAS,mBAAmB,QAAQ,EAAE,CAAC,UAAU,wBAAwB,QAAQ,EAAE,CAAC;GAChJ,MAAM,WAAW,eAAe,QAAQ,MAAM,gBAAgB,KAAK;GACnE,MAAM,kBAAkB,eACtB,eACA,MAAM,gBAAgB,YACvB;AAED,WAAQ,IACN,wBAAwB,MAAM,aAAa,mBACtB,MAAM,iBAAiB,iBAEnC,YAAY,MACZ,SAAS,MACT,kBACV;WACM,KAAK;AACZ,WAAQ,MAAM,kCAAkC,IAAI;AACpD,WAAQ,KAAK,EAAE;;;CAGpB,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PATHS } from "./paths-
|
|
1
|
+
import { t as PATHS } from "./paths-Cvzy-eLX.js";
|
|
2
2
|
import { defineCommand } from "citty";
|
|
3
3
|
import consola from "consola";
|
|
4
4
|
import fs from "node:fs/promises";
|
|
@@ -78,5 +78,5 @@ const debug = defineCommand({
|
|
|
78
78
|
});
|
|
79
79
|
|
|
80
80
|
//#endregion
|
|
81
|
-
export { debug };
|
|
82
|
-
//# sourceMappingURL=debug-
|
|
81
|
+
export { debug, runDebug };
|
|
82
|
+
//# sourceMappingURL=debug-BzR5ZQUk.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debug-
|
|
1
|
+
{"version":3,"file":"debug-BzR5ZQUk.js","names":[],"sources":["../src/debug.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\nimport fs from \"node:fs/promises\"\nimport os from \"node:os\"\n\nimport { PATHS } from \"./lib/paths\"\n\ninterface DebugInfo {\n version: string\n runtime: {\n name: string\n version: string\n platform: string\n arch: string\n }\n paths: {\n APP_DIR: string\n GITHUB_TOKEN_PATH: string\n }\n tokenExists: boolean\n}\n\ninterface RunDebugOptions {\n json: boolean\n}\n\nasync function getPackageVersion(): Promise<string> {\n try {\n const packageJsonPath = new URL(\"../package.json\", import.meta.url).pathname\n // @ts-expect-error https://github.com/sindresorhus/eslint-plugin-unicorn/blob/v59.0.1/docs/rules/prefer-json-parse-buffer.md\n // JSON.parse() can actually parse buffers\n const packageJson = JSON.parse(await fs.readFile(packageJsonPath)) as {\n version: string\n }\n return packageJson.version\n } catch {\n return \"unknown\"\n }\n}\n\nfunction getRuntimeInfo() {\n const isBun = typeof Bun !== \"undefined\"\n\n return {\n name: isBun ? \"bun\" : \"node\",\n version: isBun ? Bun.version : process.version.slice(1),\n platform: os.platform(),\n arch: os.arch(),\n }\n}\n\nasync function checkTokenExists(): Promise<boolean> {\n try {\n const stats = await fs.stat(PATHS.GITHUB_TOKEN_PATH)\n if (!stats.isFile()) return false\n\n const content = await fs.readFile(PATHS.GITHUB_TOKEN_PATH, \"utf8\")\n return content.trim().length > 0\n } catch {\n return false\n }\n}\n\nasync function getDebugInfo(): Promise<DebugInfo> {\n const [version, tokenExists] = await Promise.all([\n getPackageVersion(),\n checkTokenExists(),\n ])\n\n return {\n version,\n runtime: getRuntimeInfo(),\n paths: {\n APP_DIR: PATHS.APP_DIR,\n GITHUB_TOKEN_PATH: PATHS.GITHUB_TOKEN_PATH,\n },\n tokenExists,\n }\n}\n\nfunction printDebugInfoPlain(info: DebugInfo): void {\n consola.info(`copilot-api debug\n\nVersion: ${info.version}\nRuntime: ${info.runtime.name} ${info.runtime.version} (${info.runtime.platform} ${info.runtime.arch})\n\nPaths:\n- APP_DIR: ${info.paths.APP_DIR}\n- GITHUB_TOKEN_PATH: ${info.paths.GITHUB_TOKEN_PATH}\n\nToken exists: ${info.tokenExists ? \"Yes\" : \"No\"}`)\n}\n\nfunction printDebugInfoJson(info: DebugInfo): void {\n console.log(JSON.stringify(info, null, 2))\n}\n\nexport async function runDebug(options: RunDebugOptions): Promise<void> {\n const debugInfo = await getDebugInfo()\n\n if (options.json) {\n printDebugInfoJson(debugInfo)\n } else {\n printDebugInfoPlain(debugInfo)\n }\n}\n\nexport const debug = defineCommand({\n meta: {\n name: \"debug\",\n description: \"Print debug information about the application\",\n },\n args: {\n json: {\n type: \"boolean\",\n default: false,\n description: \"Output debug information as JSON\",\n },\n },\n run({ args }) {\n return runDebug({\n json: args.json,\n })\n },\n})\n"],"mappings":";;;;;;;AA4BA,eAAe,oBAAqC;AAClD,KAAI;EACF,MAAM,kBAAkB,IAAI,IAAI,mBAAmB,OAAO,KAAK,IAAI,CAAC;AAMpE,SAHoB,KAAK,MAAM,MAAM,GAAG,SAAS,gBAAgB,CAAC,CAG/C;SACb;AACN,SAAO;;;AAIX,SAAS,iBAAiB;CACxB,MAAM,QAAQ,OAAO,QAAQ;AAE7B,QAAO;EACL,MAAM,QAAQ,QAAQ;EACtB,SAAS,QAAQ,IAAI,UAAU,QAAQ,QAAQ,MAAM,EAAE;EACvD,UAAU,GAAG,UAAU;EACvB,MAAM,GAAG,MAAM;EAChB;;AAGH,eAAe,mBAAqC;AAClD,KAAI;AAEF,MAAI,EADU,MAAM,GAAG,KAAK,MAAM,kBAAkB,EACzC,QAAQ,CAAE,QAAO;AAG5B,UADgB,MAAM,GAAG,SAAS,MAAM,mBAAmB,OAAO,EACnD,MAAM,CAAC,SAAS;SACzB;AACN,SAAO;;;AAIX,eAAe,eAAmC;CAChD,MAAM,CAAC,SAAS,eAAe,MAAM,QAAQ,IAAI,CAC/C,mBAAmB,EACnB,kBAAkB,CACnB,CAAC;AAEF,QAAO;EACL;EACA,SAAS,gBAAgB;EACzB,OAAO;GACL,SAAS,MAAM;GACf,mBAAmB,MAAM;GAC1B;EACD;EACD;;AAGH,SAAS,oBAAoB,MAAuB;AAClD,SAAQ,KAAK;;WAEJ,KAAK,QAAQ;WACb,KAAK,QAAQ,KAAK,GAAG,KAAK,QAAQ,QAAQ,IAAI,KAAK,QAAQ,SAAS,GAAG,KAAK,QAAQ,KAAK;;;aAGvF,KAAK,MAAM,QAAQ;uBACT,KAAK,MAAM,kBAAkB;;gBAEpC,KAAK,cAAc,QAAQ,OAAO;;AAGlD,SAAS,mBAAmB,MAAuB;AACjD,SAAQ,IAAI,KAAK,UAAU,MAAM,MAAM,EAAE,CAAC;;AAG5C,eAAsB,SAAS,SAAyC;CACtE,MAAM,YAAY,MAAM,cAAc;AAEtC,KAAI,QAAQ,KACV,oBAAmB,UAAU;KAE7B,qBAAoB,UAAU;;AAIlC,MAAa,QAAQ,cAAc;CACjC,MAAM;EACJ,MAAM;EACN,aAAa;EACd;CACD,MAAM,EACJ,MAAM;EACJ,MAAM;EACN,SAAS;EACT,aAAa;EACd,EACF;CACD,IAAI,EAAE,QAAQ;AACZ,SAAO,SAAS,EACd,MAAM,KAAK,MACZ,CAAC;;CAEL,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { E as accountFromState, m as HTTPError, v as getGitHubApiBaseUrl, x as githubHeaders } from "./utils-DY-jLXwO.js";
|
|
2
2
|
|
|
3
3
|
//#region src/services/github/get-copilot-token.ts
|
|
4
4
|
const getCopilotToken = async (account) => {
|
|
@@ -9,5 +9,5 @@ const getCopilotToken = async (account) => {
|
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
//#endregion
|
|
12
|
-
export { getCopilotToken };
|
|
13
|
-
//# sourceMappingURL=get-copilot-token-
|
|
12
|
+
export { getCopilotToken as t };
|
|
13
|
+
//# sourceMappingURL=get-copilot-token-BbpphnmV.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-copilot-token-
|
|
1
|
+
{"version":3,"file":"get-copilot-token-BbpphnmV.js","names":[],"sources":["../src/services/github/get-copilot-token.ts"],"sourcesContent":["import type { AccountContext } from \"~/lib/types/account\"\n\nimport { getGitHubApiBaseUrl, githubHeaders } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { accountFromState } from \"~/lib/state\"\n\nexport const getCopilotToken = async (account?: AccountContext) => {\n const ctx = account ?? accountFromState()\n const response = await fetch(\n `${getGitHubApiBaseUrl()}/copilot_internal/v2/token`,\n {\n headers: githubHeaders(ctx),\n },\n )\n\n if (!response.ok) throw new HTTPError(\"Failed to get Copilot token\", response)\n\n return (await response.json()) as GetCopilotTokenResponse\n}\n\n// Trimmed for the sake of simplicity\nexport interface GetCopilotTokenResponse {\n expires_at: number\n refresh_in: number\n token: string\n}\n"],"mappings":";;;AAMA,MAAa,kBAAkB,OAAO,YAA6B;CACjE,MAAM,MAAM,WAAW,kBAAkB;CACzC,MAAM,WAAW,MAAM,MACrB,GAAG,qBAAqB,CAAC,6BACzB,EACE,SAAS,cAAc,IAAI,EAC5B,CACF;AAED,KAAI,CAAC,SAAS,GAAI,OAAM,IAAI,UAAU,+BAA+B,SAAS;AAE9E,QAAQ,MAAM,SAAS,MAAM"}
|
package/dist/main.js
CHANGED
|
@@ -20,11 +20,11 @@ const args = parseArgs(process.argv, cliArgs);
|
|
|
20
20
|
if (typeof args["api-home"] === "string") process.env.COPILOT_API_HOME = args["api-home"];
|
|
21
21
|
if (typeof args["oauth-app"] === "string") process.env.COPILOT_API_OAUTH_APP = args["oauth-app"];
|
|
22
22
|
if (typeof args["enterprise-url"] === "string") process.env.COPILOT_API_ENTERPRISE_URL = args["enterprise-url"];
|
|
23
|
-
const { auth } = await import("./auth-
|
|
24
|
-
const { checkUsage } = await import("./check-usage-
|
|
25
|
-
const { debug } = await import("./debug-
|
|
26
|
-
const { start } = await import("./start-
|
|
27
|
-
|
|
23
|
+
const { auth } = await import("./auth-1gAffrpI.js");
|
|
24
|
+
const { checkUsage } = await import("./check-usage-CsRu467P.js");
|
|
25
|
+
const { debug } = await import("./debug-BzR5ZQUk.js");
|
|
26
|
+
const { start } = await import("./start-B1_Ols5Z.js");
|
|
27
|
+
await runMain(defineCommand({
|
|
28
28
|
meta: {
|
|
29
29
|
name: "copilot-api",
|
|
30
30
|
description: "A wrapper around GitHub Copilot API to make it OpenAI compatible, making it usable for other tools."
|
|
@@ -36,8 +36,7 @@ const main = defineCommand({
|
|
|
36
36
|
debug
|
|
37
37
|
},
|
|
38
38
|
args: cliArgs
|
|
39
|
-
});
|
|
40
|
-
await runMain(main);
|
|
39
|
+
}));
|
|
41
40
|
|
|
42
41
|
//#endregion
|
|
43
42
|
export { };
|
package/dist/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","names":[],"sources":["../src/main.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { defineCommand, runMain, parseArgs } from \"citty\"\n\nconst cliArgs = {\n \"api-home\": {\n type: \"string\",\n description: \"Path to the API home directory.\",\n },\n \"oauth-app\": {\n type: \"string\",\n description: \"OAuth app identifier.\",\n },\n \"enterprise-url\": {\n type: \"string\",\n description: \"Enterprise URL for GitHub.\",\n },\n} as const\n\nconst args = parseArgs(process.argv, cliArgs)\n\n// Set environment variables before loading other modules\nif (typeof args[\"api-home\"] === \"string\") {\n process.env.COPILOT_API_HOME = args[\"api-home\"]\n}\nif (typeof args[\"oauth-app\"] === \"string\") {\n process.env.COPILOT_API_OAUTH_APP = args[\"oauth-app\"]\n}\nif (typeof args[\"enterprise-url\"] === \"string\") {\n process.env.COPILOT_API_ENTERPRISE_URL = args[\"enterprise-url\"]\n}\n\n// Dynamically import other modules to ensure environment variables are set\nconst { auth } = await import(\"./auth\")\nconst { checkUsage } = await import(\"./check-usage\")\nconst { debug } = await import(\"./debug\")\nconst { start } = await import(\"./start\")\n\nconst main = defineCommand({\n meta: {\n name: \"copilot-api\",\n description:\n \"A wrapper around GitHub Copilot API to make it OpenAI compatible, making it usable for other tools.\",\n },\n subCommands: { auth, start, \"check-usage\": checkUsage, debug },\n args: cliArgs,\n})\n\nawait runMain(main)\n"],"mappings":";;;;AAIA,MAAM,UAAU;CACd,YAAY;EACV,MAAM;EACN,aAAa;EACd;CACD,aAAa;EACX,MAAM;EACN,aAAa;EACd;CACD,kBAAkB;EAChB,MAAM;EACN,aAAa;EACd;CACF;AAED,MAAM,OAAO,UAAU,QAAQ,MAAM,QAAQ;AAG7C,IAAI,OAAO,KAAK,gBAAgB,SAC9B,SAAQ,IAAI,mBAAmB,KAAK;AAEtC,IAAI,OAAO,KAAK,iBAAiB,SAC/B,SAAQ,IAAI,wBAAwB,KAAK;AAE3C,IAAI,OAAO,KAAK,sBAAsB,SACpC,SAAQ,IAAI,6BAA6B,KAAK;AAIhD,MAAM,EAAE,SAAS,MAAM,OAAO;AAC9B,MAAM,EAAE,eAAe,MAAM,OAAO;AACpC,MAAM,EAAE,UAAU,MAAM,OAAO;AAC/B,MAAM,EAAE,UAAU,MAAM,OAAO;
|
|
1
|
+
{"version":3,"file":"main.js","names":[],"sources":["../src/main.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { defineCommand, runMain, parseArgs } from \"citty\"\n\nconst cliArgs = {\n \"api-home\": {\n type: \"string\",\n description: \"Path to the API home directory.\",\n },\n \"oauth-app\": {\n type: \"string\",\n description: \"OAuth app identifier.\",\n },\n \"enterprise-url\": {\n type: \"string\",\n description: \"Enterprise URL for GitHub.\",\n },\n} as const\n\nconst args = parseArgs(process.argv, cliArgs)\n\n// Set environment variables before loading other modules\nif (typeof args[\"api-home\"] === \"string\") {\n process.env.COPILOT_API_HOME = args[\"api-home\"]\n}\nif (typeof args[\"oauth-app\"] === \"string\") {\n process.env.COPILOT_API_OAUTH_APP = args[\"oauth-app\"]\n}\nif (typeof args[\"enterprise-url\"] === \"string\") {\n process.env.COPILOT_API_ENTERPRISE_URL = args[\"enterprise-url\"]\n}\n\n// Dynamically import other modules to ensure environment variables are set\nconst { auth } = await import(\"./auth\")\nconst { checkUsage } = await import(\"./check-usage\")\nconst { debug } = await import(\"./debug\")\nconst { start } = await import(\"./start\")\n\nconst main = defineCommand({\n meta: {\n name: \"copilot-api\",\n description:\n \"A wrapper around GitHub Copilot API to make it OpenAI compatible, making it usable for other tools.\",\n },\n subCommands: { auth, start, \"check-usage\": checkUsage, debug },\n args: cliArgs,\n})\n\nawait runMain(main)\n"],"mappings":";;;;AAIA,MAAM,UAAU;CACd,YAAY;EACV,MAAM;EACN,aAAa;EACd;CACD,aAAa;EACX,MAAM;EACN,aAAa;EACd;CACD,kBAAkB;EAChB,MAAM;EACN,aAAa;EACd;CACF;AAED,MAAM,OAAO,UAAU,QAAQ,MAAM,QAAQ;AAG7C,IAAI,OAAO,KAAK,gBAAgB,SAC9B,SAAQ,IAAI,mBAAmB,KAAK;AAEtC,IAAI,OAAO,KAAK,iBAAiB,SAC/B,SAAQ,IAAI,wBAAwB,KAAK;AAE3C,IAAI,OAAO,KAAK,sBAAsB,SACpC,SAAQ,IAAI,6BAA6B,KAAK;AAIhD,MAAM,EAAE,SAAS,MAAM,OAAO;AAC9B,MAAM,EAAE,eAAe,MAAM,OAAO;AACpC,MAAM,EAAE,UAAU,MAAM,OAAO;AAC/B,MAAM,EAAE,UAAU,MAAM,OAAO;AAY/B,MAAM,QAVO,cAAc;CACzB,MAAM;EACJ,MAAM;EACN,aACE;EACH;CACD,aAAa;EAAE;EAAM;EAAO,eAAe;EAAY;EAAO;CAC9D,MAAM;CACP,CAAC,CAEiB"}
|
|
@@ -45,5 +45,5 @@ async function ensureFile(filePath) {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
//#endregion
|
|
48
|
-
export {
|
|
49
|
-
//# sourceMappingURL=paths-
|
|
48
|
+
export { accountTokenPath as n, ensurePaths as r, PATHS as t };
|
|
49
|
+
//# sourceMappingURL=paths-Cvzy-eLX.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths-
|
|
1
|
+
{"version":3,"file":"paths-Cvzy-eLX.js","names":[],"sources":["../src/lib/paths.ts"],"sourcesContent":["import fs from \"node:fs/promises\"\nimport os from \"node:os\"\nimport path from \"node:path\"\n\nconst AUTH_APP = process.env.COPILOT_API_OAUTH_APP?.trim() || \"\"\nconst ENTERPRISE_PREFIX = process.env.COPILOT_API_ENTERPRISE_URL ? \"ent_\" : \"\"\n\nconst DEFAULT_DIR = path.join(os.homedir(), \".local\", \"share\", \"copilot-api\")\nconst APP_DIR = process.env.COPILOT_API_HOME || DEFAULT_DIR\n\nconst GITHUB_TOKEN_PATH = path.join(\n APP_DIR,\n AUTH_APP,\n ENTERPRISE_PREFIX + \"github_token\",\n)\nconst CONFIG_PATH = path.join(APP_DIR, \"config.json\")\nconst MODELS_PATH = path.join(APP_DIR, \"models.json\")\n\n// Multi-account paths\nconst TOKENS_DIR = path.join(APP_DIR, \"tokens\")\nconst ACCOUNTS_REGISTRY_PATH = path.join(APP_DIR, \"accounts-registry.json\")\n\nexport const PATHS = {\n APP_DIR,\n GITHUB_TOKEN_PATH,\n CONFIG_PATH,\n MODELS_PATH,\n TOKENS_DIR,\n ACCOUNTS_REGISTRY_PATH,\n}\n\n/**\n * Get the token file path for a specific account.\n * @param id - The account ID (GitHub login)\n * @returns The absolute path to the account's token file\n */\nexport function accountTokenPath(id: string): string {\n return path.join(TOKENS_DIR, `github_${id}`)\n}\n\nexport async function ensurePaths(): Promise<void> {\n await fs.mkdir(PATHS.APP_DIR, { recursive: true })\n await fs.mkdir(path.join(PATHS.APP_DIR, AUTH_APP), { recursive: true })\n await fs.mkdir(PATHS.TOKENS_DIR, { recursive: true })\n await ensureFile(PATHS.GITHUB_TOKEN_PATH)\n await ensureFile(PATHS.CONFIG_PATH)\n}\n\nasync function ensureFile(filePath: string): Promise<void> {\n try {\n await fs.access(filePath, fs.constants.W_OK)\n } catch {\n await fs.writeFile(filePath, \"\")\n await fs.chmod(filePath, 0o600)\n }\n}\n"],"mappings":";;;;;AAIA,MAAM,WAAW,QAAQ,IAAI,uBAAuB,MAAM,IAAI;AAC9D,MAAM,oBAAoB,QAAQ,IAAI,6BAA6B,SAAS;AAE5E,MAAM,cAAc,KAAK,KAAK,GAAG,SAAS,EAAE,UAAU,SAAS,cAAc;AAC7E,MAAM,UAAU,QAAQ,IAAI,oBAAoB;AAEhD,MAAM,oBAAoB,KAAK,KAC7B,SACA,UACA,oBAAoB,eACrB;AACD,MAAM,cAAc,KAAK,KAAK,SAAS,cAAc;AACrD,MAAM,cAAc,KAAK,KAAK,SAAS,cAAc;AAGrD,MAAM,aAAa,KAAK,KAAK,SAAS,SAAS;AAC/C,MAAM,yBAAyB,KAAK,KAAK,SAAS,yBAAyB;AAE3E,MAAa,QAAQ;CACnB;CACA;CACA;CACA;CACA;CACA;CACD;;;;;;AAOD,SAAgB,iBAAiB,IAAoB;AACnD,QAAO,KAAK,KAAK,YAAY,UAAU,KAAK;;AAG9C,eAAsB,cAA6B;AACjD,OAAM,GAAG,MAAM,MAAM,SAAS,EAAE,WAAW,MAAM,CAAC;AAClD,OAAM,GAAG,MAAM,KAAK,KAAK,MAAM,SAAS,SAAS,EAAE,EAAE,WAAW,MAAM,CAAC;AACvE,OAAM,GAAG,MAAM,MAAM,YAAY,EAAE,WAAW,MAAM,CAAC;AACrD,OAAM,WAAW,MAAM,kBAAkB;AACzC,OAAM,WAAW,MAAM,YAAY;;AAGrC,eAAe,WAAW,UAAiC;AACzD,KAAI;AACF,QAAM,GAAG,OAAO,UAAU,GAAG,UAAU,KAAK;SACtC;AACN,QAAM,GAAG,UAAU,UAAU,GAAG;AAChC,QAAM,GAAG,MAAM,UAAU,IAAM"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { b as getOauthUrls, m as HTTPError, u as sleep, y as getOauthAppConfig } from "./utils-DY-jLXwO.js";
|
|
2
2
|
import consola from "consola";
|
|
3
3
|
|
|
4
4
|
//#region src/services/github/get-device-code.ts
|
|
@@ -48,5 +48,5 @@ async function pollAccessToken(deviceCode) {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
//#endregion
|
|
51
|
-
export { getDeviceCode, pollAccessToken };
|
|
52
|
-
//# sourceMappingURL=poll-access-token-
|
|
51
|
+
export { getDeviceCode as n, pollAccessToken as t };
|
|
52
|
+
//# sourceMappingURL=poll-access-token-CGfLFzMq.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"poll-access-token-
|
|
1
|
+
{"version":3,"file":"poll-access-token-CGfLFzMq.js","names":[],"sources":["../src/services/github/get-device-code.ts","../src/services/github/poll-access-token.ts"],"sourcesContent":["import { getOauthAppConfig, getOauthUrls } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\n\nexport async function getDeviceCode(): Promise<DeviceCodeResponse> {\n const { clientId, headers, scope } = getOauthAppConfig()\n const { deviceCodeUrl } = getOauthUrls()\n\n const response = await fetch(deviceCodeUrl, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n client_id: clientId,\n scope,\n }),\n })\n\n if (!response.ok) throw new HTTPError(\"Failed to get device code\", response)\n\n return (await response.json()) as DeviceCodeResponse\n}\n\nexport interface DeviceCodeResponse {\n device_code: string\n user_code: string\n verification_uri: string\n expires_in: number\n interval: number\n}\n","import consola from \"consola\"\n\nimport { getOauthAppConfig, getOauthUrls } from \"~/lib/api-config\"\nimport { sleep } from \"~/lib/utils\"\n\nimport type { DeviceCodeResponse } from \"./get-device-code\"\n\nexport async function pollAccessToken(\n deviceCode: DeviceCodeResponse,\n): Promise<string> {\n const { clientId, headers } = getOauthAppConfig()\n const { accessTokenUrl } = getOauthUrls()\n\n // Interval is in seconds, we need to multiply by 1000 to get milliseconds\n // I'm also adding another second, just to be safe\n const sleepDuration = (deviceCode.interval + 1) * 1000\n consola.debug(`Polling access token with interval of ${sleepDuration}ms`)\n\n while (true) {\n const response = await fetch(accessTokenUrl, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n client_id: clientId,\n device_code: deviceCode.device_code,\n grant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n }),\n })\n\n if (!response.ok) {\n await sleep(sleepDuration)\n consola.error(\"Failed to poll access token:\", await response.text())\n\n continue\n }\n\n const json = await response.json()\n consola.debug(\"Polling access token response:\", json)\n\n const { access_token } = json as AccessTokenResponse\n\n if (access_token) {\n return access_token\n } else {\n await sleep(sleepDuration)\n }\n }\n}\n\ninterface AccessTokenResponse {\n access_token: string\n token_type: string\n scope: string\n}\n"],"mappings":";;;;AAGA,eAAsB,gBAA6C;CACjE,MAAM,EAAE,UAAU,SAAS,UAAU,mBAAmB;CACxD,MAAM,EAAE,kBAAkB,cAAc;CAExC,MAAM,WAAW,MAAM,MAAM,eAAe;EAC1C,QAAQ;EACR;EACA,MAAM,KAAK,UAAU;GACnB,WAAW;GACX;GACD,CAAC;EACH,CAAC;AAEF,KAAI,CAAC,SAAS,GAAI,OAAM,IAAI,UAAU,6BAA6B,SAAS;AAE5E,QAAQ,MAAM,SAAS,MAAM;;;;;ACX/B,eAAsB,gBACpB,YACiB;CACjB,MAAM,EAAE,UAAU,YAAY,mBAAmB;CACjD,MAAM,EAAE,mBAAmB,cAAc;CAIzC,MAAM,iBAAiB,WAAW,WAAW,KAAK;AAClD,SAAQ,MAAM,yCAAyC,cAAc,IAAI;AAEzE,QAAO,MAAM;EACX,MAAM,WAAW,MAAM,MAAM,gBAAgB;GAC3C,QAAQ;GACR;GACA,MAAM,KAAK,UAAU;IACnB,WAAW;IACX,aAAa,WAAW;IACxB,YAAY;IACb,CAAC;GACH,CAAC;AAEF,MAAI,CAAC,SAAS,IAAI;AAChB,SAAM,MAAM,cAAc;AAC1B,WAAQ,MAAM,gCAAgC,MAAM,SAAS,MAAM,CAAC;AAEpE;;EAGF,MAAM,OAAO,MAAM,SAAS,MAAM;AAClC,UAAQ,MAAM,kCAAkC,KAAK;EAErD,MAAM,EAAE,iBAAiB;AAEzB,MAAI,aACF,QAAO;MAEP,OAAM,MAAM,cAAc"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { PATHS } from "./paths-
|
|
2
|
-
import { listAccountsFromRegistry } from "./accounts-registry-
|
|
3
|
-
import {
|
|
4
|
-
import "./get-copilot-token-
|
|
5
|
-
import {
|
|
1
|
+
import { t as PATHS } from "./paths-Cvzy-eLX.js";
|
|
2
|
+
import { i as listAccountsFromRegistry } from "./accounts-registry-CQYvRe65.js";
|
|
3
|
+
import { C as prepareInteractionHeaders, D as state, E as accountFromState, S as prepareForCompact, T as resolveTraceId, _ as copilotHeaders, a as generateRequestIdFromPayload, c as isNullish, g as copilotBaseUrl, h as forwardError, l as parseUserIdMetadata, m as HTTPError, n as cacheModels, o as getRootSessionId, p as getCopilotUsage, s as getUUID, u as sleep, w as requestContext } from "./utils-DY-jLXwO.js";
|
|
4
|
+
import "./get-copilot-token-BbpphnmV.js";
|
|
5
|
+
import { _ as isMessagesApiEnabled, a as getClaudeTokenMultiplier, b as mergeConfigWithDefaults, c as getModelAliases, d as getProviderConfig, f as getReasoningEffortForModel, g as isMessageStartInputTokensFallbackEnabled, h as isForceAgentEnabled, i as getAnthropicApiKey, l as getModelAliasesInfo, m as isAccountAffinityEnabled, n as PROVIDER_TYPE_ANTHROPIC, o as getConfig, p as getSmallModel, r as getAliasTargetSet, s as getExtraPromptForModel, t as accountsManager, u as getModelRefreshIntervalMs, v as isResponsesApiContextManagementModel, x as shouldCompactUseSmallModel, y as isResponsesApiWebSearchEnabled } from "./accounts-manager-Cjrd_el_.js";
|
|
6
6
|
import consola from "consola";
|
|
7
7
|
import fs, { readFile } from "node:fs/promises";
|
|
8
8
|
import * as path$1 from "node:path";
|
|
@@ -12,7 +12,6 @@ import { Hono } from "hono";
|
|
|
12
12
|
import { cors } from "hono/cors";
|
|
13
13
|
import { logger } from "hono/logger";
|
|
14
14
|
import fs$1, { existsSync } from "node:fs";
|
|
15
|
-
import { AsyncLocalStorage } from "node:async_hooks";
|
|
16
15
|
import { Database } from "bun:sqlite";
|
|
17
16
|
import { fileURLToPath } from "node:url";
|
|
18
17
|
import { streamSSE } from "hono/streaming";
|
|
@@ -105,26 +104,6 @@ function createAuthMiddleware(options = {}) {
|
|
|
105
104
|
};
|
|
106
105
|
}
|
|
107
106
|
|
|
108
|
-
//#endregion
|
|
109
|
-
//#region src/lib/request-context.ts
|
|
110
|
-
const TRACE_ID_MAX_LENGTH = 64;
|
|
111
|
-
const TRACE_ID_PATTERN = /^\w[\w.-]*$/;
|
|
112
|
-
const asyncLocalStorage = new AsyncLocalStorage();
|
|
113
|
-
const requestContext = {
|
|
114
|
-
getStore: () => asyncLocalStorage.getStore(),
|
|
115
|
-
run: (context, callback) => asyncLocalStorage.run(context, callback)
|
|
116
|
-
};
|
|
117
|
-
function generateTraceId() {
|
|
118
|
-
const timestamp = Date.now().toString(36);
|
|
119
|
-
const random = Math.random().toString(36).slice(2, 8);
|
|
120
|
-
return `${timestamp}-${random}`;
|
|
121
|
-
}
|
|
122
|
-
function resolveTraceId(traceId) {
|
|
123
|
-
const candidate = traceId?.trim();
|
|
124
|
-
if (!candidate || candidate.length > TRACE_ID_MAX_LENGTH || !TRACE_ID_PATTERN.test(candidate)) return generateTraceId();
|
|
125
|
-
return candidate;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
107
|
//#endregion
|
|
129
108
|
//#region src/lib/trace.ts
|
|
130
109
|
const traceIdMiddleware = async (c, next) => {
|
|
@@ -132,7 +111,8 @@ const traceIdMiddleware = async (c, next) => {
|
|
|
132
111
|
c.header("x-trace-id", traceId);
|
|
133
112
|
const context = {
|
|
134
113
|
traceId,
|
|
135
|
-
startTime: Date.now()
|
|
114
|
+
startTime: Date.now(),
|
|
115
|
+
userAgent: c.req.header("user-agent") || ""
|
|
136
116
|
};
|
|
137
117
|
await requestContext.run(context, async () => {
|
|
138
118
|
await next();
|
|
@@ -377,14 +357,11 @@ function normalizeMessagesUsage(usage) {
|
|
|
377
357
|
const output = usage.output_tokens;
|
|
378
358
|
const hasInput = typeof input === "number";
|
|
379
359
|
const hasOutput = typeof output === "number";
|
|
380
|
-
const tokensInput = hasInput ? Math.max(0, input - cached) : void 0;
|
|
381
|
-
const tokensOutput = hasOutput ? output : void 0;
|
|
382
|
-
const tokensTotal = hasInput || hasOutput ? (input ?? 0) + (output ?? 0) : void 0;
|
|
383
360
|
return {
|
|
384
361
|
tokensCachedInput: cached,
|
|
385
|
-
tokensInput,
|
|
386
|
-
tokensOutput,
|
|
387
|
-
tokensTotal,
|
|
362
|
+
tokensInput: hasInput ? Math.max(0, input - cached) : void 0,
|
|
363
|
+
tokensOutput: hasOutput ? output : void 0,
|
|
364
|
+
tokensTotal: hasInput || hasOutput ? (input ?? 0) + (output ?? 0) : void 0,
|
|
388
365
|
usageJson: JSON.stringify(usage)
|
|
389
366
|
};
|
|
390
367
|
}
|
|
@@ -598,10 +575,9 @@ var RequestHistoryStore = class {
|
|
|
598
575
|
const rows = this.db.query(sql).all(...values, limit + 1);
|
|
599
576
|
const items = rows.slice(0, limit);
|
|
600
577
|
const hasMore = rows.length > limit;
|
|
601
|
-
const nextCursorId = hasMore ? items.at(-1)?.id : void 0;
|
|
602
578
|
return {
|
|
603
579
|
items,
|
|
604
|
-
nextCursorId,
|
|
580
|
+
nextCursorId: hasMore ? items.at(-1)?.id : void 0,
|
|
605
581
|
hasMore
|
|
606
582
|
};
|
|
607
583
|
}
|
|
@@ -1309,12 +1285,10 @@ function parseAdminModelDetailsItem(raw, aliasesByTarget) {
|
|
|
1309
1285
|
if (!isPlainObject(raw)) return null;
|
|
1310
1286
|
const id = parseNonEmptyString(raw.id);
|
|
1311
1287
|
if (!id) return null;
|
|
1312
|
-
const name = parseNonEmptyString(raw.name) ?? id;
|
|
1313
|
-
const preview = toBooleanOrUndefined(raw.preview) ?? false;
|
|
1314
1288
|
return {
|
|
1315
1289
|
id,
|
|
1316
|
-
name,
|
|
1317
|
-
preview,
|
|
1290
|
+
name: parseNonEmptyString(raw.name) ?? id,
|
|
1291
|
+
preview: toBooleanOrUndefined(raw.preview) ?? false,
|
|
1318
1292
|
billing: parseBilling(raw.billing),
|
|
1319
1293
|
supported_endpoints: parseStringArray(raw.supported_endpoints),
|
|
1320
1294
|
capabilities: parseCapabilities(raw.capabilities),
|
|
@@ -2207,8 +2181,7 @@ const createHandlerLogger = (name) => {
|
|
|
2207
2181
|
const filePath = path.join(LOG_DIR, `${sanitizedName}-${dateKey}.log`);
|
|
2208
2182
|
const message = formatArgs(logObj.args);
|
|
2209
2183
|
const traceIdStr = traceId ? ` [${traceId}]` : "";
|
|
2210
|
-
|
|
2211
|
-
appendLine(filePath, line);
|
|
2184
|
+
appendLine(filePath, `[${timestamp}] [${logObj.type}] [${logObj.tag || name}]${traceIdStr}${message ? ` ${message}` : ""}`);
|
|
2212
2185
|
} });
|
|
2213
2186
|
return instance;
|
|
2214
2187
|
};
|
|
@@ -2440,8 +2413,7 @@ const numTokensForTools = (tools, encoder, constants) => {
|
|
|
2440
2413
|
* Calculate the token count of messages, supporting multiple GPT encoders
|
|
2441
2414
|
*/
|
|
2442
2415
|
const getTokenCount = async (payload, model) => {
|
|
2443
|
-
const
|
|
2444
|
-
const encoder = await getEncodeChatFunction(tokenizer);
|
|
2416
|
+
const encoder = await getEncodeChatFunction(getTokenizerFromModel(model));
|
|
2445
2417
|
const simplifiedMessages = payload.messages;
|
|
2446
2418
|
const inputMessages = simplifiedMessages.filter((msg) => msg.role !== "assistant");
|
|
2447
2419
|
const outputMessages = simplifiedMessages.filter((msg) => msg.role === "assistant");
|
|
@@ -2532,13 +2504,11 @@ async function handleCompletion$1(c) {
|
|
|
2532
2504
|
});
|
|
2533
2505
|
}
|
|
2534
2506
|
logger$6.debug("Request payload:", JSON.stringify(payload).slice(-400));
|
|
2507
|
+
const upstreamRequestId = generateRequestIdFromPayload(payload, normalizedPromptCacheKey);
|
|
2535
2508
|
const selection = await accountsManager.selectAccountForRequest([{
|
|
2536
2509
|
modelId: clientModel,
|
|
2537
2510
|
endpoint: CHAT_COMPLETIONS_ENDPOINT$1
|
|
2538
|
-
}], {
|
|
2539
|
-
promptCacheKey: normalizedPromptCacheKey,
|
|
2540
|
-
safetyIdentifier: normalizedSafetyIdentifier
|
|
2541
|
-
});
|
|
2511
|
+
}], { requestId: upstreamRequestId });
|
|
2542
2512
|
if (!selection.ok) {
|
|
2543
2513
|
recordSelectionFailure$2(store, {
|
|
2544
2514
|
request,
|
|
@@ -2567,7 +2537,6 @@ async function handleCompletion$1(c) {
|
|
|
2567
2537
|
if (state.manualApprove) await awaitApproval();
|
|
2568
2538
|
const payloadWithMaxTokens = applyDefaultMaxTokens(upstreamPayload, selectedModel);
|
|
2569
2539
|
const accountCtx = toAccountContext(account);
|
|
2570
|
-
const upstreamRequestId = generateRequestIdFromPayload(payloadWithMaxTokens);
|
|
2571
2540
|
const upstreamSessionId = getUUID(upstreamRequestId);
|
|
2572
2541
|
request.upstreamRequestId = upstreamRequestId;
|
|
2573
2542
|
request.upstreamSessionId = upstreamSessionId;
|
|
@@ -2600,7 +2569,6 @@ function buildRequestContext$1(c) {
|
|
|
2600
2569
|
const method = c.req.raw.method;
|
|
2601
2570
|
const path$2 = new URL(c.req.url, "http://local").pathname;
|
|
2602
2571
|
const { ip: clientIp, source: clientIpSource } = getClientIpInfo(c);
|
|
2603
|
-
const userAgent = c.req.header("user-agent") ?? void 0;
|
|
2604
2572
|
return {
|
|
2605
2573
|
requestId,
|
|
2606
2574
|
startedAtMs,
|
|
@@ -2608,7 +2576,7 @@ function buildRequestContext$1(c) {
|
|
|
2608
2576
|
path: path$2,
|
|
2609
2577
|
clientIp,
|
|
2610
2578
|
clientIpSource,
|
|
2611
|
-
userAgent
|
|
2579
|
+
userAgent: c.req.header("user-agent") ?? void 0
|
|
2612
2580
|
};
|
|
2613
2581
|
}
|
|
2614
2582
|
function insertRequestLog$2(store, request, record) {
|
|
@@ -2954,7 +2922,6 @@ embeddingRoutes.post("/", async (c) => {
|
|
|
2954
2922
|
const method = c.req.raw.method;
|
|
2955
2923
|
const path$2 = new URL(c.req.url, "http://local").pathname;
|
|
2956
2924
|
const { ip: clientIp, source: clientIpSource } = getClientIpInfo(c);
|
|
2957
|
-
const userAgent = c.req.header("user-agent") ?? void 0;
|
|
2958
2925
|
const ctx = {
|
|
2959
2926
|
requestId,
|
|
2960
2927
|
startedAtMs,
|
|
@@ -2962,7 +2929,7 @@ embeddingRoutes.post("/", async (c) => {
|
|
|
2962
2929
|
path: path$2,
|
|
2963
2930
|
clientIp,
|
|
2964
2931
|
clientIpSource,
|
|
2965
|
-
userAgent
|
|
2932
|
+
userAgent: c.req.header("user-agent") ?? void 0
|
|
2966
2933
|
};
|
|
2967
2934
|
const payload = await c.req.json();
|
|
2968
2935
|
const clientModel = payload.model;
|
|
@@ -2986,15 +2953,14 @@ embeddingRoutes.post("/", async (c) => {
|
|
|
2986
2953
|
});
|
|
2987
2954
|
return selectionFailureResponse$1(c, clientModel, selection.reason);
|
|
2988
2955
|
}
|
|
2989
|
-
const upstreamPayload = {
|
|
2990
|
-
...payload,
|
|
2991
|
-
model: selection.selectedModel.id
|
|
2992
|
-
};
|
|
2993
2956
|
return await runEmbeddingsWithAccount({
|
|
2994
2957
|
c,
|
|
2995
2958
|
store,
|
|
2996
2959
|
ctx,
|
|
2997
|
-
payload:
|
|
2960
|
+
payload: {
|
|
2961
|
+
...payload,
|
|
2962
|
+
model: selection.selectedModel.id
|
|
2963
|
+
},
|
|
2998
2964
|
clientModel,
|
|
2999
2965
|
selection
|
|
3000
2966
|
});
|
|
@@ -3043,8 +3009,7 @@ async function runEmbeddingsWithAccount({ c, store, ctx, payload, clientModel, s
|
|
|
3043
3009
|
let errorMessage;
|
|
3044
3010
|
let finishedAtMs;
|
|
3045
3011
|
try {
|
|
3046
|
-
const
|
|
3047
|
-
const response = await createEmbeddings(payload, accountCtx);
|
|
3012
|
+
const response = await createEmbeddings(payload, toAccountContext(account));
|
|
3048
3013
|
usage = normalizeEmbeddingsUsage(response.usage);
|
|
3049
3014
|
finishedAtMs = Date.now();
|
|
3050
3015
|
return c.json(response);
|
|
@@ -3199,6 +3164,32 @@ const mergeToolResultForClaude = (anthropicPayload) => {
|
|
|
3199
3164
|
msg.content = mergeToolResult(toolResults, textBlocks);
|
|
3200
3165
|
}
|
|
3201
3166
|
};
|
|
3167
|
+
const stripUnsupportedCacheControl = (block) => {
|
|
3168
|
+
const cacheControl = block.cache_control;
|
|
3169
|
+
if (!cacheControl || typeof cacheControl !== "object" || Array.isArray(cacheControl)) return;
|
|
3170
|
+
const type = cacheControl.type;
|
|
3171
|
+
if (typeof type === "string") {
|
|
3172
|
+
block.cache_control = { type };
|
|
3173
|
+
return;
|
|
3174
|
+
}
|
|
3175
|
+
delete block.cache_control;
|
|
3176
|
+
};
|
|
3177
|
+
const stripTextBlockCacheControl = (block) => {
|
|
3178
|
+
if (!block || typeof block !== "object" || Array.isArray(block)) return;
|
|
3179
|
+
const record = block;
|
|
3180
|
+
if (record.type !== "text") return;
|
|
3181
|
+
stripUnsupportedCacheControl(record);
|
|
3182
|
+
};
|
|
3183
|
+
const stripCacheControl = (anthropicPayload) => {
|
|
3184
|
+
if (Array.isArray(anthropicPayload.system)) for (const block of anthropicPayload.system) stripTextBlockCacheControl(block);
|
|
3185
|
+
for (const msg of anthropicPayload.messages) {
|
|
3186
|
+
if (!Array.isArray(msg.content)) continue;
|
|
3187
|
+
for (const block of msg.content) {
|
|
3188
|
+
stripTextBlockCacheControl(block);
|
|
3189
|
+
if (block.type === "tool_result" && Array.isArray(block.content)) for (const nestedBlock of block.content) stripTextBlockCacheControl(nestedBlock);
|
|
3190
|
+
}
|
|
3191
|
+
}
|
|
3192
|
+
};
|
|
3202
3193
|
const estimateInputTokens = async (payload, selectedModel, logger$7) => {
|
|
3203
3194
|
try {
|
|
3204
3195
|
return (await getTokenCount(payload, selectedModel)).input;
|
|
@@ -3562,7 +3553,7 @@ async function handleCountTokens(c) {
|
|
|
3562
3553
|
}
|
|
3563
3554
|
}
|
|
3564
3555
|
let finalTokenCount = tokenCount.input + tokenCount.output;
|
|
3565
|
-
if (anthropicPayload.model.startsWith("claude")) finalTokenCount = Math.round(finalTokenCount *
|
|
3556
|
+
if (anthropicPayload.model.startsWith("claude")) finalTokenCount = Math.round(finalTokenCount * getClaudeTokenMultiplier());
|
|
3566
3557
|
consola.info("Token count:", finalTokenCount);
|
|
3567
3558
|
return c.json({ input_tokens: finalTokenCount });
|
|
3568
3559
|
} catch (error) {
|
|
@@ -3991,9 +3982,8 @@ const mapResponsesStopReason = (response) => {
|
|
|
3991
3982
|
const mapResponsesUsage = (response) => {
|
|
3992
3983
|
const inputTokens = response.usage?.input_tokens ?? 0;
|
|
3993
3984
|
const outputTokens = response.usage?.output_tokens ?? 0;
|
|
3994
|
-
const inputCachedTokens = response.usage?.input_tokens_details?.cached_tokens;
|
|
3995
3985
|
return {
|
|
3996
|
-
input_tokens: inputTokens - (
|
|
3986
|
+
input_tokens: inputTokens - (response.usage?.input_tokens_details?.cached_tokens ?? 0),
|
|
3997
3987
|
output_tokens: outputTokens,
|
|
3998
3988
|
...response.usage?.input_tokens_details?.cached_tokens !== void 0 && { cache_read_input_tokens: response.usage.input_tokens_details.cached_tokens }
|
|
3999
3989
|
};
|
|
@@ -4413,10 +4403,9 @@ const openFunctionCallBlock = (state$1, params) => {
|
|
|
4413
4403
|
if (!functionCallState) {
|
|
4414
4404
|
const blockIndex$1 = state$1.nextContentBlockIndex;
|
|
4415
4405
|
state$1.nextContentBlockIndex += 1;
|
|
4416
|
-
const resolvedToolCallId = toolCallId ?? `tool_call_${blockIndex$1}`;
|
|
4417
4406
|
functionCallState = {
|
|
4418
4407
|
blockIndex: blockIndex$1,
|
|
4419
|
-
toolCallId:
|
|
4408
|
+
toolCallId: toolCallId ?? `tool_call_${blockIndex$1}`,
|
|
4420
4409
|
name: name ?? "function",
|
|
4421
4410
|
consecutiveWhitespaceCount: 0
|
|
4422
4411
|
};
|
|
@@ -4442,26 +4431,20 @@ const openFunctionCallBlock = (state$1, params) => {
|
|
|
4442
4431
|
const extractFunctionCallDetails = (rawEvent) => {
|
|
4443
4432
|
const item = rawEvent.item;
|
|
4444
4433
|
if (item.type !== "function_call") return;
|
|
4445
|
-
const outputIndex = rawEvent.output_index;
|
|
4446
|
-
const toolCallId = item.call_id;
|
|
4447
|
-
const name = item.name;
|
|
4448
|
-
const initialArguments = item.arguments;
|
|
4449
4434
|
return {
|
|
4450
|
-
outputIndex,
|
|
4451
|
-
toolCallId,
|
|
4452
|
-
name,
|
|
4453
|
-
initialArguments
|
|
4435
|
+
outputIndex: rawEvent.output_index,
|
|
4436
|
+
toolCallId: item.call_id,
|
|
4437
|
+
name: item.name,
|
|
4438
|
+
initialArguments: item.arguments
|
|
4454
4439
|
};
|
|
4455
4440
|
};
|
|
4456
4441
|
|
|
4457
4442
|
//#endregion
|
|
4458
4443
|
//#region src/routes/responses/utils.ts
|
|
4459
4444
|
const getResponsesRequestOptions = (payload) => {
|
|
4460
|
-
const vision = hasVisionInput(payload);
|
|
4461
|
-
const initiator = hasAgentInitiator(payload) ? "agent" : "user";
|
|
4462
4445
|
return {
|
|
4463
|
-
vision,
|
|
4464
|
-
initiator
|
|
4446
|
+
vision: hasVisionInput(payload),
|
|
4447
|
+
initiator: hasAgentInitiator(payload) ? "agent" : "user"
|
|
4465
4448
|
};
|
|
4466
4449
|
};
|
|
4467
4450
|
const hasAgentInitiator = (payload) => {
|
|
@@ -4953,11 +4936,7 @@ async function handleCompletion(c) {
|
|
|
4953
4936
|
modelId: endpointModel?.id ?? openAIPayload.model,
|
|
4954
4937
|
endpoint: CHAT_COMPLETIONS_ENDPOINT
|
|
4955
4938
|
});
|
|
4956
|
-
const selection = await accountsManager.selectAccountForRequest(candidates, {
|
|
4957
|
-
promptCacheKey: normalizedPromptCacheKey,
|
|
4958
|
-
sessionId,
|
|
4959
|
-
safetyIdentifier: normalizedSafetyIdentifier
|
|
4960
|
-
});
|
|
4939
|
+
const selection = await accountsManager.selectAccountForRequest(candidates, { requestId: upstreamRequestId });
|
|
4961
4940
|
if (!selection.ok) return handleSelectionFailure({
|
|
4962
4941
|
c,
|
|
4963
4942
|
store,
|
|
@@ -5166,10 +5145,9 @@ function insertRequestLog$1(instr, record) {
|
|
|
5166
5145
|
async function finalizeQuotaAndGetPremiumSnapshot(instr) {
|
|
5167
5146
|
await accountsManager.finalizeQuota(instr.account, instr.reservation);
|
|
5168
5147
|
const premiumRemainingAfter = instr.account.premiumRemaining;
|
|
5169
|
-
const premiumUnlimitedAfter = instr.account.unlimited;
|
|
5170
5148
|
return {
|
|
5171
5149
|
premiumRemainingAfter,
|
|
5172
|
-
premiumUnlimitedAfter,
|
|
5150
|
+
premiumUnlimitedAfter: instr.account.unlimited,
|
|
5173
5151
|
premiumRemainingDiff: computeDiff(instr.premiumRemainingBefore, premiumRemainingAfter)
|
|
5174
5152
|
};
|
|
5175
5153
|
}
|
|
@@ -5557,6 +5535,7 @@ async function streamMessagesAndLog(params) {
|
|
|
5557
5535
|
}
|
|
5558
5536
|
const handleWithMessagesApi = async (params) => {
|
|
5559
5537
|
const { c, anthropicPayload, anthropicBetaHeader, initiatorOverride, subagentMarker, sessionId, instr, selectedModel, isCompact } = params;
|
|
5538
|
+
stripCacheControl(anthropicPayload);
|
|
5560
5539
|
for (const msg of anthropicPayload.messages) if (msg.role === "assistant" && Array.isArray(msg.content)) msg.content = msg.content.filter((block) => {
|
|
5561
5540
|
if (block.type !== "thinking") return true;
|
|
5562
5541
|
return block.thinking && block.thinking !== "Thinking..." && block.signature && !block.signature.includes("@");
|
|
@@ -5781,7 +5760,7 @@ async function forwardProviderModels(providerConfig, requestHeaders) {
|
|
|
5781
5760
|
//#region src/routes/provider/messages/handler.ts
|
|
5782
5761
|
const logger$3 = createHandlerLogger("provider-messages-handler");
|
|
5783
5762
|
async function handleProviderMessages(c) {
|
|
5784
|
-
const provider = c.req.param("provider");
|
|
5763
|
+
const provider = c.req.param("provider") ?? "";
|
|
5785
5764
|
const providerConfig = getProviderConfig(provider);
|
|
5786
5765
|
if (!providerConfig) return c.json({ error: {
|
|
5787
5766
|
message: `Provider '${provider}' not found or disabled`,
|
|
@@ -5972,13 +5951,11 @@ const handleResponses = async (c) => {
|
|
|
5972
5951
|
message: "This model is only available via an alias. Please use the alias model name."
|
|
5973
5952
|
});
|
|
5974
5953
|
}
|
|
5954
|
+
const upstreamRequestId = generateRequestIdFromPayload({ messages: payload.input }, normalizedPromptCacheKey);
|
|
5975
5955
|
const selection = await accountsManager.selectAccountForRequest([{
|
|
5976
5956
|
modelId: clientModel,
|
|
5977
5957
|
endpoint: RESPONSES_ENDPOINT
|
|
5978
|
-
}], {
|
|
5979
|
-
promptCacheKey: normalizedPromptCacheKey,
|
|
5980
|
-
safetyIdentifier: normalizedSafetyIdentifier
|
|
5981
|
-
});
|
|
5958
|
+
}], { requestId: upstreamRequestId });
|
|
5982
5959
|
if (!selection.ok) {
|
|
5983
5960
|
recordSelectionFailure(store, {
|
|
5984
5961
|
request,
|
|
@@ -6004,7 +5981,6 @@ const handleResponses = async (c) => {
|
|
|
6004
5981
|
request.initiator = initiator;
|
|
6005
5982
|
if (state.manualApprove) await awaitApproval();
|
|
6006
5983
|
const accountCtx = toAccountContext(account);
|
|
6007
|
-
const upstreamRequestId = generateRequestIdFromPayload({ messages: upstreamPayload.input });
|
|
6008
5984
|
const upstreamSessionId = getUUID(upstreamRequestId);
|
|
6009
5985
|
request.upstreamRequestId = upstreamRequestId;
|
|
6010
5986
|
request.upstreamSessionId = upstreamSessionId;
|
|
@@ -6041,7 +6017,6 @@ function buildRequestContext(c) {
|
|
|
6041
6017
|
const method = c.req.raw.method;
|
|
6042
6018
|
const path$2 = new URL(c.req.url, "http://local").pathname;
|
|
6043
6019
|
const { ip: clientIp, source: clientIpSource } = getClientIpInfo(c);
|
|
6044
|
-
const userAgent = c.req.header("user-agent") ?? void 0;
|
|
6045
6020
|
return {
|
|
6046
6021
|
requestId,
|
|
6047
6022
|
startedAtMs,
|
|
@@ -6049,7 +6024,7 @@ function buildRequestContext(c) {
|
|
|
6049
6024
|
path: path$2,
|
|
6050
6025
|
clientIp,
|
|
6051
6026
|
clientIpSource,
|
|
6052
|
-
userAgent
|
|
6027
|
+
userAgent: c.req.header("user-agent") ?? void 0
|
|
6053
6028
|
};
|
|
6054
6029
|
}
|
|
6055
6030
|
function insertRequestLog(store, request, record) {
|
|
@@ -6098,8 +6073,7 @@ function selectionFailureResponse(c, params) {
|
|
|
6098
6073
|
function extractUsageFromChunkData(data) {
|
|
6099
6074
|
if (!data) return void 0;
|
|
6100
6075
|
try {
|
|
6101
|
-
const
|
|
6102
|
-
const usage = extractResponsesUsageFromStreamEvent(event);
|
|
6076
|
+
const usage = extractResponsesUsageFromStreamEvent(JSON.parse(data));
|
|
6103
6077
|
return usage.usageJson ? usage : void 0;
|
|
6104
6078
|
} catch {
|
|
6105
6079
|
return;
|
|
@@ -6495,4 +6469,4 @@ server.route("/:provider/v1/models", providerModelRoutes);
|
|
|
6495
6469
|
|
|
6496
6470
|
//#endregion
|
|
6497
6471
|
export { server };
|
|
6498
|
-
//# sourceMappingURL=server-
|
|
6472
|
+
//# sourceMappingURL=server-DqwhClJ-.js.map
|