ghc-proxy 0.1.1 → 0.1.3
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 +67 -4
- package/dist/main.js.map +1 -1
- package/package.json +5 -2
package/dist/main.js
CHANGED
|
@@ -169,6 +169,14 @@ async function forwardError(c, error) {
|
|
|
169
169
|
type: "error"
|
|
170
170
|
} }, error.response.status);
|
|
171
171
|
}
|
|
172
|
+
if (error instanceof DOMException && error.name === "AbortError") return c.json({ error: {
|
|
173
|
+
message: "Upstream request was aborted",
|
|
174
|
+
type: "timeout_error"
|
|
175
|
+
} }, 504);
|
|
176
|
+
if (error instanceof Error && error.name === "AbortError") return c.json({ error: {
|
|
177
|
+
message: "Upstream request was aborted",
|
|
178
|
+
type: "timeout_error"
|
|
179
|
+
} }, 504);
|
|
172
180
|
return c.json({ error: {
|
|
173
181
|
message: error.message,
|
|
174
182
|
type: "error"
|
|
@@ -975,6 +983,34 @@ async function getTokenCount(payload, model) {
|
|
|
975
983
|
};
|
|
976
984
|
}
|
|
977
985
|
|
|
986
|
+
//#endregion
|
|
987
|
+
//#region src/lib/upstream-signal.ts
|
|
988
|
+
const DEFAULT_TIMEOUT_MS = 3e5;
|
|
989
|
+
function createUpstreamSignal(options) {
|
|
990
|
+
const { clientSignal, timeoutMs = DEFAULT_TIMEOUT_MS } = options ?? {};
|
|
991
|
+
const controller = new AbortController();
|
|
992
|
+
const timeout = setTimeout(() => {
|
|
993
|
+
controller.abort();
|
|
994
|
+
}, timeoutMs);
|
|
995
|
+
let listenerAdded = false;
|
|
996
|
+
let abortListener;
|
|
997
|
+
if (clientSignal && !clientSignal.aborted) {
|
|
998
|
+
abortListener = () => {
|
|
999
|
+
controller.abort();
|
|
1000
|
+
};
|
|
1001
|
+
clientSignal.addEventListener("abort", abortListener);
|
|
1002
|
+
listenerAdded = true;
|
|
1003
|
+
}
|
|
1004
|
+
const cleanup = () => {
|
|
1005
|
+
clearTimeout(timeout);
|
|
1006
|
+
if (listenerAdded && clientSignal && abortListener) clientSignal.removeEventListener("abort", abortListener);
|
|
1007
|
+
};
|
|
1008
|
+
return {
|
|
1009
|
+
signal: controller.signal,
|
|
1010
|
+
cleanup
|
|
1011
|
+
};
|
|
1012
|
+
}
|
|
1013
|
+
|
|
978
1014
|
//#endregion
|
|
979
1015
|
//#region src/lib/validation.ts
|
|
980
1016
|
const openAIMessageSchema = z.object({
|
|
@@ -1055,9 +1091,14 @@ async function handleCompletion$1(c) {
|
|
|
1055
1091
|
};
|
|
1056
1092
|
consola.debug("Set max_tokens to:", JSON.stringify(payload.max_tokens));
|
|
1057
1093
|
}
|
|
1058
|
-
const
|
|
1094
|
+
const { signal, cleanup } = createUpstreamSignal({
|
|
1095
|
+
clientSignal: c.req.raw.signal,
|
|
1096
|
+
timeoutMs: (state.config.upstreamTimeoutSeconds ?? 300) * 1e3
|
|
1097
|
+
});
|
|
1098
|
+
const response = await new CopilotClient(state.auth, getClientConfig(state)).createChatCompletions(payload, { signal });
|
|
1059
1099
|
if (isNonStreaming$1(response)) {
|
|
1060
1100
|
consola.debug("Non-streaming response:", JSON.stringify(response));
|
|
1101
|
+
cleanup();
|
|
1061
1102
|
return c.json(response);
|
|
1062
1103
|
}
|
|
1063
1104
|
consola.debug("Streaming response");
|
|
@@ -1067,7 +1108,9 @@ async function handleCompletion$1(c) {
|
|
|
1067
1108
|
consola.debug("Streaming chunk:", JSON.stringify(chunk));
|
|
1068
1109
|
await stream.writeSSE(chunk);
|
|
1069
1110
|
}
|
|
1070
|
-
} finally {
|
|
1111
|
+
} finally {
|
|
1112
|
+
cleanup();
|
|
1113
|
+
}
|
|
1071
1114
|
});
|
|
1072
1115
|
}
|
|
1073
1116
|
function isNonStreaming$1(response) {
|
|
@@ -1522,11 +1565,16 @@ async function handleCompletion(c) {
|
|
|
1522
1565
|
});
|
|
1523
1566
|
consola.debug("Claude Code requested model:", anthropicPayload.model, "-> Copilot model:", openAIPayload.model);
|
|
1524
1567
|
consola.debug("Translated OpenAI request payload:", JSON.stringify(openAIPayload));
|
|
1525
|
-
const
|
|
1568
|
+
const { signal, cleanup } = createUpstreamSignal({
|
|
1569
|
+
clientSignal: c.req.raw.signal,
|
|
1570
|
+
timeoutMs: (state.config.upstreamTimeoutSeconds ?? 300) * 1e3
|
|
1571
|
+
});
|
|
1572
|
+
const response = await new CopilotClient(state.auth, getClientConfig(state)).createChatCompletions(openAIPayload, { signal });
|
|
1526
1573
|
if (isNonStreaming(response)) {
|
|
1527
1574
|
consola.debug("Non-streaming response from Copilot:", JSON.stringify(response).slice(-400));
|
|
1528
1575
|
const anthropicResponse = translator.fromOpenAI(response);
|
|
1529
1576
|
consola.debug("Translated Anthropic response:", JSON.stringify(anthropicResponse));
|
|
1577
|
+
cleanup();
|
|
1530
1578
|
return c.json(anthropicResponse);
|
|
1531
1579
|
}
|
|
1532
1580
|
consola.debug("Streaming response from Copilot");
|
|
@@ -1558,6 +1606,8 @@ async function handleCompletion(c) {
|
|
|
1558
1606
|
event: event.type,
|
|
1559
1607
|
data: JSON.stringify(event)
|
|
1560
1608
|
});
|
|
1609
|
+
} finally {
|
|
1610
|
+
cleanup();
|
|
1561
1611
|
}
|
|
1562
1612
|
});
|
|
1563
1613
|
}
|
|
@@ -1677,6 +1727,7 @@ async function runServer(options) {
|
|
|
1677
1727
|
state.config.rateLimitSeconds = options.rateLimit;
|
|
1678
1728
|
state.config.rateLimitWait = options.rateLimitWait;
|
|
1679
1729
|
state.config.showToken = options.showToken;
|
|
1730
|
+
state.config.upstreamTimeoutSeconds = options.upstreamTimeoutSeconds;
|
|
1680
1731
|
await ensurePaths();
|
|
1681
1732
|
await readConfig();
|
|
1682
1733
|
await cacheVSCodeVersion();
|
|
@@ -1765,6 +1816,11 @@ const start = defineCommand({
|
|
|
1765
1816
|
type: "string",
|
|
1766
1817
|
default: "120",
|
|
1767
1818
|
description: "Bun server idle timeout in seconds"
|
|
1819
|
+
},
|
|
1820
|
+
"upstream-timeout": {
|
|
1821
|
+
type: "string",
|
|
1822
|
+
default: "300",
|
|
1823
|
+
description: "Upstream request timeout in seconds (0 to disable)"
|
|
1768
1824
|
}
|
|
1769
1825
|
},
|
|
1770
1826
|
run({ args }) {
|
|
@@ -1776,6 +1832,12 @@ const start = defineCommand({
|
|
|
1776
1832
|
consola.warn(`Invalid --idle-timeout value "${idleTimeoutRaw}". Falling back to Bun default.`);
|
|
1777
1833
|
idleTimeoutSeconds = void 0;
|
|
1778
1834
|
}
|
|
1835
|
+
const upstreamTimeoutRaw = args["upstream-timeout"];
|
|
1836
|
+
let upstreamTimeoutSeconds = upstreamTimeoutRaw === void 0 ? void 0 : Number.parseInt(upstreamTimeoutRaw, 10);
|
|
1837
|
+
if (upstreamTimeoutSeconds !== void 0 && (Number.isNaN(upstreamTimeoutSeconds) || upstreamTimeoutSeconds < 0)) {
|
|
1838
|
+
consola.warn(`Invalid --upstream-timeout value "${upstreamTimeoutRaw}". Falling back to default (300s).`);
|
|
1839
|
+
upstreamTimeoutSeconds = void 0;
|
|
1840
|
+
}
|
|
1779
1841
|
return runServer({
|
|
1780
1842
|
port: Number.parseInt(args.port, 10),
|
|
1781
1843
|
verbose: args.verbose,
|
|
@@ -1787,7 +1849,8 @@ const start = defineCommand({
|
|
|
1787
1849
|
claudeCode: args["claude-code"],
|
|
1788
1850
|
showToken: args["show-token"],
|
|
1789
1851
|
proxyEnv: args["proxy-env"],
|
|
1790
|
-
idleTimeoutSeconds
|
|
1852
|
+
idleTimeoutSeconds,
|
|
1853
|
+
upstreamTimeoutSeconds
|
|
1791
1854
|
});
|
|
1792
1855
|
}
|
|
1793
1856
|
});
|
package/dist/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","names":["cachedConfig: ConfigFile","error: unknown","existing: ConfigFile","state: AppState","headers: Record<string, string>","auth","errorJson: unknown","auth","headers: Record<string, string>","auth","token","commandBlock: string","start","methodColors: Record<string, Parameters<typeof colorize>[0]>","requestLogger: MiddlewareHandler","path","state","requestGuard: MiddlewareHandler","handleCompletion","isNonStreaming","handleCompletion","events: Array<AnthropicStreamEventData>","events","DEFAULT_FALLBACKS: ModelFallbackConfig","cachedConfig","allTextBlocks: Array<AnthropicTextBlock>","allToolUseBlocks: Array<AnthropicToolUseBlock>","stopReason: 'stop' | 'length' | 'tool_calls' | 'content_filter' | null","newMessages: Array<Message>","contentParts: Array<ContentPart>","events","accountType: ReturnType<typeof getClientConfig>['accountType']","clientConfig: ReturnType<typeof getClientConfig>"],"sources":["../src/lib/paths.ts","../src/lib/config.ts","../src/lib/state.ts","../src/lib/api-config.ts","../src/lib/error.ts","../src/clients/copilot-client.ts","../src/lib/client-config.ts","../src/lib/utils.ts","../src/clients/github-client.ts","../src/clients/vscode-client.ts","../src/lib/token.ts","../src/auth.ts","../src/check-usage.ts","../src/debug.ts","../src/lib/proxy.ts","../src/lib/shell.ts","../src/lib/request-logger.ts","../src/lib/approval.ts","../src/lib/rate-limit.ts","../src/routes/middleware/request-guard.ts","../src/lib/tokenizer.ts","../src/lib/validation.ts","../src/routes/chat-completions/handler.ts","../src/routes/chat-completions/route.ts","../src/routes/embeddings/route.ts","../src/translator/anthropic/shared.ts","../src/translator/anthropic/anthropic-stream-translator.ts","../src/lib/model-resolver.ts","../src/translator/anthropic/anthropic-translator.ts","../src/routes/messages/count-tokens-handler.ts","../src/routes/messages/handler.ts","../src/routes/messages/route.ts","../src/routes/models/route.ts","../src/routes/token/route.ts","../src/routes/usage/route.ts","../src/server.ts","../src/start.ts","../src/main.ts"],"sourcesContent":["import fs from 'node:fs/promises'\nimport os from 'node:os'\nimport path from 'node:path'\n\nconst APP_DIR = path.join(os.homedir(), '.local', 'share', 'ghc-proxy')\n\nconst CONFIG_PATH = path.join(APP_DIR, 'config.json')\n\nexport const PATHS = {\n APP_DIR,\n CONFIG_PATH,\n}\n\nexport async function ensurePaths(): Promise<void> {\n await fs.mkdir(PATHS.APP_DIR, { recursive: true })\n}\n","import fs from 'node:fs/promises'\nimport consola from 'consola'\n\nimport { PATHS } from './paths'\n\ninterface ModelFallbackFileConfig {\n claudeOpus?: string\n claudeSonnet?: string\n claudeHaiku?: string\n}\n\nexport interface ConfigFile {\n githubToken?: string\n modelFallback?: ModelFallbackFileConfig\n}\n\nlet cachedConfig: ConfigFile = {}\n\nexport async function readConfig(): Promise<ConfigFile> {\n try {\n const content = await fs.readFile(PATHS.CONFIG_PATH, 'utf8')\n\n if (!content.trim()) {\n cachedConfig = {}\n return {}\n }\n\n const parsed = JSON.parse(content) as unknown\n\n if (\n typeof parsed !== 'object'\n || parsed === null\n || Array.isArray(parsed)\n ) {\n consola.warn('config.json is not a valid object. Using defaults.')\n cachedConfig = {}\n return {}\n }\n\n cachedConfig = parsed as ConfigFile\n return cachedConfig\n }\n catch (error: unknown) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n cachedConfig = {}\n return {}\n }\n\n consola.warn(\n `Failed to parse config.json: ${(error as Error).message}. Using defaults.`,\n )\n cachedConfig = {}\n return {}\n }\n}\n\nexport function getCachedConfig(): ConfigFile {\n return cachedConfig\n}\n\nexport async function writeConfigField(\n field: string,\n value: unknown,\n): Promise<void> {\n try {\n let existing: ConfigFile = {}\n try {\n const content = await fs.readFile(PATHS.CONFIG_PATH, 'utf8')\n if (content.trim()) {\n existing = JSON.parse(content) as ConfigFile\n }\n }\n catch (error: unknown) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n consola.warn(\n `Could not read existing config.json: ${\n (error as Error).message\n }. Starting fresh.`,\n )\n }\n }\n\n const merged = { ...existing, [field]: value }\n\n await fs.writeFile(\n PATHS.CONFIG_PATH,\n JSON.stringify(merged, null, 2),\n 'utf8',\n )\n await fs.chmod(PATHS.CONFIG_PATH, 0o600)\n\n cachedConfig = merged\n }\n catch (error: unknown) {\n consola.error(`Failed to write config.json: ${(error as Error).message}`)\n throw error\n }\n}\n","import type { ModelsResponse } from '~/types'\n\nexport interface AuthState {\n githubToken?: string\n copilotToken?: string\n}\n\nexport interface RuntimeConfig {\n accountType: 'individual' | 'business' | 'enterprise'\n manualApprove: boolean\n rateLimitSeconds?: number\n rateLimitWait: boolean\n showToken: boolean\n}\n\nexport interface CacheState {\n models?: ModelsResponse\n vsCodeVersion?: string\n}\n\nexport interface RateLimitState {\n lastRequestTimestamp?: number\n}\n\nexport interface AppState {\n auth: AuthState\n config: RuntimeConfig\n cache: CacheState\n rateLimit: RateLimitState\n}\n\nexport const state: AppState = {\n auth: {},\n config: {\n accountType: 'individual',\n manualApprove: false,\n rateLimitWait: false,\n showToken: false,\n },\n cache: {},\n rateLimit: {},\n}\n","import type { ClientAuth, ClientConfig } from '~/clients'\n\nimport { randomUUID } from 'node:crypto'\n\nexport function standardHeaders() {\n return {\n 'content-type': 'application/json',\n 'accept': 'application/json',\n }\n}\n\nconst COPILOT_VERSION = '0.26.7'\nconst EDITOR_PLUGIN_VERSION = `copilot-chat/${COPILOT_VERSION}`\nconst USER_AGENT = `GitHubCopilotChat/${COPILOT_VERSION}`\n\nconst API_VERSION = '2025-04-01'\n\nexport function copilotBaseUrl(config: ClientConfig) {\n return config.accountType === 'individual'\n ? 'https://api.githubcopilot.com'\n : `https://api.${config.accountType}.githubcopilot.com`\n}\nexport function copilotHeaders(auth: ClientAuth, config: ClientConfig, vision: boolean = false) {\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${auth.copilotToken}`,\n 'content-type': standardHeaders()['content-type'],\n 'copilot-integration-id': 'vscode-chat',\n 'editor-version': `vscode/${config.vsCodeVersion ?? 'unknown'}`,\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)\n headers['copilot-vision-request'] = 'true'\n\n return headers\n}\n\nexport const GITHUB_API_BASE_URL = 'https://api.github.com'\nexport function githubHeaders(auth: ClientAuth, config: ClientConfig) {\n return {\n ...standardHeaders(),\n 'authorization': `token ${auth.githubToken}`,\n 'editor-version': `vscode/${config.vsCodeVersion ?? 'unknown'}`,\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}\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 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 consola.error('Error occurred:', error)\n\n if (error instanceof HTTPError) {\n const errorText = await error.response.text()\n let errorJson: unknown\n try {\n errorJson = JSON.parse(errorText)\n }\n catch {\n errorJson = errorText\n }\n consola.error('HTTP error:', errorJson)\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 return c.json(\n {\n error: {\n message: (error as Error).message,\n type: 'error',\n },\n },\n 500,\n )\n}\n","import type { ClientAuth, ClientConfig, ClientDeps } from './types'\nimport type {\n ChatCompletionResponse,\n ChatCompletionsPayload,\n EmbeddingRequest,\n EmbeddingResponse,\n ModelsResponse,\n} from '~/types'\n\nimport consola from 'consola'\n\nimport { events } from 'fetch-event-stream'\nimport { copilotBaseUrl, copilotHeaders } from '~/lib/api-config'\n\nimport { HTTPError } from '~/lib/error'\n\nexport class CopilotClient {\n private auth: ClientAuth\n private config: ClientConfig\n private fetchImpl: typeof fetch\n\n constructor(auth: ClientAuth, config: ClientConfig, deps?: ClientDeps) {\n this.auth = auth\n this.config = config\n this.fetchImpl = deps?.fetch ?? fetch\n }\n\n async createChatCompletions(\n payload: ChatCompletionsPayload,\n options?: { signal?: AbortSignal },\n ) {\n if (!this.auth.copilotToken)\n throw new Error('Copilot token not found')\n\n const enableVision = payload.messages.some(\n x =>\n typeof x.content !== 'string'\n && x.content?.some(content => content.type === 'image_url'),\n )\n\n // Agent/user check for X-Initiator header\n const isAgentCall = payload.messages.some(msg =>\n ['assistant', 'tool'].includes(msg.role),\n )\n\n const headers: Record<string, string> = {\n ...copilotHeaders(this.auth, this.config, enableVision),\n 'X-Initiator': isAgentCall ? 'agent' : 'user',\n }\n\n const response = await this.fetchImpl(\n `${copilotBaseUrl(this.config)}/chat/completions`,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(payload),\n signal: options?.signal,\n },\n )\n\n if (!response.ok) {\n consola.error('Failed to create chat completions', response)\n throw new HTTPError('Failed to create chat completions', response)\n }\n\n if (payload.stream) {\n return events(response)\n }\n\n return (await response.json()) as ChatCompletionResponse\n }\n\n async createEmbeddings(\n payload: EmbeddingRequest,\n ): Promise<EmbeddingResponse> {\n if (!this.auth.copilotToken)\n throw new Error('Copilot token not found')\n\n const response = await this.fetchImpl(\n `${copilotBaseUrl(this.config)}/embeddings`,\n {\n method: 'POST',\n headers: copilotHeaders(this.auth, this.config),\n body: JSON.stringify(payload),\n },\n )\n\n if (!response.ok) {\n throw new HTTPError('Failed to create embeddings', response)\n }\n\n return (await response.json()) as EmbeddingResponse\n }\n\n async getModels(): Promise<ModelsResponse> {\n const response = await this.fetchImpl(\n `${copilotBaseUrl(this.config)}/models`,\n {\n headers: copilotHeaders(this.auth, this.config),\n },\n )\n\n if (!response.ok)\n throw new HTTPError('Failed to get models', response)\n\n return (await response.json()) as ModelsResponse\n }\n}\n","import type { AppState } from './state'\n\nimport type { ClientConfig } from '~/clients'\n\nexport function getClientConfig(appState: AppState): ClientConfig {\n return {\n accountType: appState.config.accountType,\n vsCodeVersion: appState.cache.vsCodeVersion,\n }\n}\n","import consola from 'consola'\n\nimport { CopilotClient, getVSCodeVersion } from '~/clients'\n\nimport { getClientConfig } from './client-config'\nimport { state } from './state'\n\nexport function sleep(ms: number) {\n return new Promise((resolve) => {\n setTimeout(resolve, ms)\n })\n}\n\nexport function isNullish(value: unknown): value is null | undefined {\n return value === null || value === undefined\n}\n\nexport async function cacheModels(client?: CopilotClient): Promise<void> {\n const copilotClient\n = client ?? new CopilotClient(state.auth, getClientConfig(state))\n\n const models = await copilotClient.getModels()\n\n state.cache.models = models\n}\n\nexport async function cacheVSCodeVersion() {\n const response = await getVSCodeVersion()\n state.cache.vsCodeVersion = response\n\n consola.info(`Using VSCode version: ${response}`)\n}\n","import type { ClientAuth, ClientConfig, ClientDeps } from './types'\n\nimport type {\n CopilotUsageResponse,\n DeviceCodeResponse,\n GetCopilotTokenResponse,\n GithubUserResponse,\n} from '~/types'\n\nimport consola from 'consola'\nimport {\n GITHUB_API_BASE_URL,\n GITHUB_APP_SCOPES,\n GITHUB_BASE_URL,\n GITHUB_CLIENT_ID,\n githubHeaders,\n standardHeaders,\n} from '~/lib/api-config'\nimport { HTTPError } from '~/lib/error'\n\nimport { sleep } from '~/lib/utils'\n\nexport class GitHubClient {\n private auth: ClientAuth\n private config: ClientConfig\n private fetchImpl: typeof fetch\n\n constructor(auth: ClientAuth, config: ClientConfig, deps?: ClientDeps) {\n this.auth = auth\n this.config = config\n this.fetchImpl = deps?.fetch ?? fetch\n }\n\n async getCopilotUsage(): Promise<CopilotUsageResponse> {\n const response = await this.fetchImpl(\n `${GITHUB_API_BASE_URL}/copilot_internal/user`,\n {\n headers: githubHeaders(this.auth, this.config),\n },\n )\n\n if (!response.ok) {\n throw new HTTPError('Failed to get Copilot usage', response)\n }\n\n return (await response.json()) as CopilotUsageResponse\n }\n\n async getCopilotToken(): Promise<GetCopilotTokenResponse> {\n const response = await this.fetchImpl(\n `${GITHUB_API_BASE_URL}/copilot_internal/v2/token`,\n {\n headers: githubHeaders(this.auth, this.config),\n },\n )\n\n if (!response.ok) {\n throw new HTTPError('Failed to get Copilot token', response)\n }\n\n return (await response.json()) as GetCopilotTokenResponse\n }\n\n async getDeviceCode(): Promise<DeviceCodeResponse> {\n const response = await this.fetchImpl(\n `${GITHUB_BASE_URL}/login/device/code`,\n {\n method: 'POST',\n headers: standardHeaders(),\n body: JSON.stringify({\n client_id: GITHUB_CLIENT_ID,\n scope: GITHUB_APP_SCOPES,\n }),\n },\n )\n\n if (!response.ok) {\n throw new HTTPError('Failed to get device code', response)\n }\n\n return (await response.json()) as DeviceCodeResponse\n }\n\n async pollAccessToken(deviceCode: DeviceCodeResponse): Promise<string> {\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 this.fetchImpl(\n `${GITHUB_BASE_URL}/login/oauth/access_token`,\n {\n method: 'POST',\n headers: standardHeaders(),\n body: JSON.stringify({\n client_id: GITHUB_CLIENT_ID,\n device_code: deviceCode.device_code,\n grant_type: 'urn:ietf:params:oauth:grant-type:device_code',\n }),\n },\n )\n\n if (!response.ok) {\n await sleep(sleepDuration)\n consola.error('Failed to poll access token:', await response.text())\n continue\n }\n\n const json = (await response.json()) as AccessTokenResponse\n consola.debug('Polling access token response:', json)\n\n if (json.access_token) {\n return json.access_token\n }\n\n await sleep(sleepDuration)\n }\n }\n\n async getGitHubUser(): Promise<GithubUserResponse> {\n const response = await this.fetchImpl(`${GITHUB_API_BASE_URL}/user`, {\n headers: {\n authorization: `token ${this.auth.githubToken}`,\n ...standardHeaders(),\n },\n })\n\n if (!response.ok) {\n throw new HTTPError('Failed to get GitHub user', response)\n }\n\n return (await response.json()) as GithubUserResponse\n }\n}\n\ninterface AccessTokenResponse {\n access_token: string\n token_type: string\n scope: string\n}\n","const FALLBACK = '1.104.3'\n\nexport async function getVSCodeVersion() {\n const controller = new AbortController()\n const timeout = setTimeout(() => {\n controller.abort()\n }, 5000)\n\n try {\n const response = await fetch(\n 'https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h=visual-studio-code-bin',\n {\n signal: controller.signal,\n },\n )\n\n const pkgbuild = await response.text()\n const pkgverRegex = /pkgver=([0-9.]+)/\n const match = pkgbuild.match(pkgverRegex)\n\n if (match) {\n return match[1]\n }\n\n return FALLBACK\n }\n catch {\n return FALLBACK\n }\n finally {\n clearTimeout(timeout)\n }\n}\n","import consola from 'consola'\n\nimport { GitHubClient } from '~/clients'\n\nimport { getClientConfig } from './client-config'\nimport { getCachedConfig, writeConfigField } from './config'\nimport { HTTPError } from './error'\nimport { state } from './state'\nimport { cacheVSCodeVersion } from './utils'\n\nasync function writeGithubToken(token: string): Promise<void> {\n await writeConfigField('githubToken', token)\n}\n\nexport async function setupCopilotToken() {\n await ensureVSCodeVersion()\n const githubClient = createGitHubClient()\n const { token, refresh_in } = await githubClient.getCopilotToken()\n state.auth.copilotToken = token\n\n // Display the Copilot token to the screen\n consola.debug('GitHub Copilot Token fetched successfully!')\n if (state.config.showToken) {\n consola.info('Copilot token:', token)\n }\n\n const refreshInterval = (refresh_in - 60) * 1000\n const refreshCopilotToken = async () => {\n consola.debug('Refreshing Copilot token')\n try {\n const { token } = await githubClient.getCopilotToken()\n state.auth.copilotToken = token\n consola.debug('Copilot token refreshed')\n if (state.config.showToken) {\n consola.info('Refreshed Copilot token:', token)\n }\n }\n catch (error) {\n consola.error('Failed to refresh Copilot token:', error)\n }\n }\n\n setInterval(() => {\n void refreshCopilotToken()\n }, refreshInterval)\n}\n\ninterface SetupGitHubTokenOptions {\n force?: boolean\n}\n\nexport async function setupGitHubToken(\n options?: SetupGitHubTokenOptions,\n): Promise<void> {\n try {\n await ensureVSCodeVersion()\n\n const cachedToken = getCachedConfig().githubToken\n const githubToken = cachedToken?.trim() || ''\n\n if (githubToken && !options?.force) {\n state.auth.githubToken = githubToken\n if (state.config.showToken) {\n consola.info('GitHub token:', githubToken)\n }\n try {\n await logUser()\n return\n }\n catch (error) {\n if (isAuthError(error) && !options?.force) {\n consola.warn(\n 'Stored GitHub token invalid or expired. Re-authenticating...',\n )\n await setupGitHubToken({ force: true })\n return\n }\n throw error\n }\n }\n\n consola.info('Not logged in, getting new access token')\n const githubClient = createGitHubClient()\n const response = await githubClient.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 githubClient.pollAccessToken(response)\n await writeGithubToken(token)\n state.auth.githubToken = token\n\n if (state.config.showToken) {\n consola.info('GitHub token:', token)\n }\n await logUser()\n }\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\nfunction isAuthError(error: unknown) {\n return error instanceof HTTPError\n && (error.response.status === 401 || error.response.status === 403)\n}\n\nasync function logUser() {\n const githubClient = createGitHubClient()\n const user = await githubClient.getGitHubUser()\n consola.info(`Logged in as ${user.login}`)\n}\n\nfunction createGitHubClient() {\n return new GitHubClient(state.auth, getClientConfig(state))\n}\n\nasync function ensureVSCodeVersion() {\n if (!state.cache.vsCodeVersion) {\n await cacheVSCodeVersion()\n }\n}\n","#!/usr/bin/env node\n\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\n\nimport { readConfig } from './lib/config'\nimport { ensurePaths } from './lib/paths'\nimport { state } from './lib/state'\nimport { setupGitHubToken } from './lib/token'\nimport { cacheVSCodeVersion } from './lib/utils'\n\ninterface RunAuthOptions {\n verbose: boolean\n showToken: boolean\n}\n\nexport async function runAuth(options: RunAuthOptions): Promise<void> {\n if (options.verbose) {\n consola.level = 5\n consola.info('Verbose logging enabled')\n }\n\n state.config.showToken = options.showToken\n\n await ensurePaths()\n await readConfig()\n await cacheVSCodeVersion()\n await setupGitHubToken({ force: true })\n consola.success('GitHub token written to config.json')\n}\n\nexport const auth = defineCommand({\n meta: {\n name: 'auth',\n description: 'Run GitHub auth flow without running the server',\n },\n args: {\n 'verbose': {\n alias: 'v',\n type: 'boolean',\n default: false,\n description: 'Enable verbose logging',\n },\n 'show-token': {\n type: 'boolean',\n default: false,\n description: 'Show GitHub token on auth',\n },\n },\n run({ args }) {\n return runAuth({\n verbose: args.verbose,\n showToken: args['show-token'],\n })\n },\n})\n","import type { QuotaDetail } from '~/types'\nimport process from 'node:process'\nimport { defineCommand } from 'citty'\n\nimport consola from 'consola'\n\nimport { GitHubClient } from '~/clients'\n\nimport { getClientConfig } from './lib/client-config'\nimport { readConfig } from './lib/config'\nimport { ensurePaths } from './lib/paths'\nimport { state } from './lib/state'\nimport { setupGitHubToken } from './lib/token'\nimport { cacheVSCodeVersion } from './lib/utils'\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 readConfig()\n await cacheVSCodeVersion()\n await setupGitHubToken()\n try {\n const githubClient = new GitHubClient(state.auth, getClientConfig(state))\n const usage = await githubClient.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)\n 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 }\n catch (err) {\n consola.error('Failed to fetch Copilot usage:', err)\n process.exit(1)\n }\n },\n})\n","#!/usr/bin/env node\n\nimport fs from 'node:fs/promises'\nimport os from 'node:os'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\n\nimport { getCachedConfig } from './lib/config'\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 CONFIG_PATH: string\n }\n configExists: boolean\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 }\n catch {\n return 'unknown'\n }\n}\n\nfunction getRuntimeInfo() {\n return {\n name: 'bun',\n version: Bun.version,\n platform: os.platform(),\n arch: os.arch(),\n }\n}\n\nfunction hasToken(): boolean {\n try {\n const config = getCachedConfig()\n return Boolean(config.githubToken?.trim())\n }\n catch {\n return false\n }\n}\n\nasync function checkConfigExists(): Promise<boolean> {\n try {\n const stats = await fs.stat(PATHS.CONFIG_PATH)\n if (!stats.isFile())\n return false\n\n const content = await fs.readFile(PATHS.CONFIG_PATH, 'utf8')\n return content.trim().length > 0\n }\n catch {\n return false\n }\n}\n\nasync function getDebugInfo(): Promise<DebugInfo> {\n const [version, configExists] = await Promise.all([\n getPackageVersion(),\n checkConfigExists(),\n ])\n\n return {\n version,\n runtime: getRuntimeInfo(),\n paths: {\n APP_DIR: PATHS.APP_DIR,\n CONFIG_PATH: PATHS.CONFIG_PATH,\n },\n configExists,\n tokenExists: hasToken(),\n }\n}\n\nfunction printDebugInfoPlain(info: DebugInfo): void {\n consola.info(`ghc-proxy 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- CONFIG_PATH: ${info.paths.CONFIG_PATH}\n\nConfig exists: ${info.configExists ? 'Yes' : 'No'}\nToken exists: ${info.tokenExists ? 'Yes' : 'No'}`)\n}\n\nexport async function runDebug(options: RunDebugOptions): Promise<void> {\n const debugInfo = await getDebugInfo()\n\n if (options.json) {\n await Bun.write(Bun.stdout, `${JSON.stringify(debugInfo, null, 2)}\\n`)\n }\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","import type { Dispatcher } from 'undici'\nimport consola from 'consola'\nimport { getProxyForUrl } from 'proxy-from-env'\nimport { Agent, ProxyAgent, setGlobalDispatcher } from 'undici'\n\nexport function initProxyFromEnv(): void {\n if (typeof Bun !== 'undefined')\n return\n\n try {\n const direct = new Agent()\n const proxies = new Map<string, ProxyAgent>()\n\n // We only need a minimal dispatcher that implements `dispatch` at runtime.\n // Typing the object as `Dispatcher` forces TypeScript to require many\n // additional methods. Instead, keep a plain object and cast when passing\n // to `setGlobalDispatcher`.\n const dispatcher = {\n dispatch(\n options: Dispatcher.DispatchOptions,\n handler: Dispatcher.DispatchHandler,\n ) {\n try {\n const origin\n = typeof options.origin === 'string'\n ? new URL(options.origin)\n : (options.origin as URL)\n const get = getProxyForUrl as unknown as (\n u: string,\n ) => string | undefined\n const raw = get(origin.toString())\n const proxyUrl = raw && raw.length > 0 ? raw : undefined\n if (!proxyUrl) {\n consola.debug(`HTTP proxy bypass: ${origin.hostname}`)\n return (direct as unknown as Dispatcher).dispatch(options, handler)\n }\n let agent = proxies.get(proxyUrl)\n if (!agent) {\n agent = new ProxyAgent(proxyUrl)\n proxies.set(proxyUrl, agent)\n }\n let label = proxyUrl\n try {\n const u = new URL(proxyUrl)\n label = `${u.protocol}//${u.host}`\n }\n catch {\n /* noop */\n }\n consola.debug(`HTTP proxy route: ${origin.hostname} via ${label}`)\n return (agent as unknown as Dispatcher).dispatch(options, handler)\n }\n catch {\n return (direct as unknown as Dispatcher).dispatch(options, handler)\n }\n },\n close() {\n return direct.close()\n },\n destroy() {\n return direct.destroy()\n },\n }\n\n setGlobalDispatcher(dispatcher as unknown as Dispatcher)\n consola.debug('HTTP proxy configured from environment (per-URL)')\n }\n catch (err) {\n consola.debug('Proxy setup skipped:', err)\n }\n}\n","import { execSync } from 'node:child_process'\nimport process from 'node:process'\n\ntype ShellName = 'bash' | 'zsh' | 'fish' | 'powershell' | 'cmd' | 'sh'\ntype EnvVars = Record<string, string | undefined>\n\nfunction getShell(): ShellName {\n const { platform, ppid, env } = process\n\n if (platform === 'win32') {\n try {\n const command = `wmic process get ParentProcessId,Name | findstr \"${ppid}\"`\n const parentProcess = execSync(command, { stdio: 'pipe' }).toString()\n\n if (parentProcess.toLowerCase().includes('powershell.exe')) {\n return 'powershell'\n }\n }\n catch {\n return 'cmd'\n }\n\n return 'cmd'\n }\n else {\n const shellPath = env.SHELL\n if (shellPath) {\n if (shellPath.endsWith('zsh'))\n return 'zsh'\n if (shellPath.endsWith('fish'))\n return 'fish'\n if (shellPath.endsWith('bash'))\n return 'bash'\n }\n\n return 'sh'\n }\n}\n\n/**\n * Generates a copy-pasteable script to set multiple environment variables\n * and run a subsequent command.\n * @param {EnvVars} envVars - An object of environment variables to set.\n * @param {string} commandToRun - The command to run after setting the variables.\n * @returns {string} The formatted script string.\n */\nexport function generateEnvScript(\n envVars: EnvVars,\n commandToRun: string = '',\n): string {\n const shell = getShell()\n const filteredEnvVars = Object.entries(envVars).filter(\n ([, value]) => value !== undefined,\n ) as Array<[string, string]>\n\n let commandBlock: string\n\n switch (shell) {\n case 'powershell': {\n commandBlock = filteredEnvVars\n .map(([key, value]) => `$env:${key} = ${value}`)\n .join('; ')\n break\n }\n case 'cmd': {\n commandBlock = filteredEnvVars\n .map(([key, value]) => `set ${key}=${value}`)\n .join(' & ')\n break\n }\n case 'fish': {\n commandBlock = filteredEnvVars\n .map(([key, value]) => `set -gx ${key} ${value}`)\n .join('; ')\n break\n }\n default: {\n // bash, zsh, sh\n const assignments = filteredEnvVars\n .map(([key, value]) => `${key}=${value}`)\n .join(' ')\n commandBlock = filteredEnvVars.length > 0 ? `export ${assignments}` : ''\n break\n }\n }\n\n if (commandBlock && commandToRun) {\n const separator = shell === 'cmd' ? ' & ' : ' && '\n return `${commandBlock}${separator}${commandToRun}`\n }\n\n return commandBlock || commandToRun\n}\n","import type { Context, MiddlewareHandler } from 'hono'\n\nimport consola from 'consola'\nimport { colorize } from 'consola/utils'\n\nexport interface ModelMappingInfo {\n originalModel?: string\n mappedModel?: string\n}\n\nfunction formatElapsed(start: number) {\n const delta = Date.now() - start\n return delta < 1000 ? `${delta}ms` : `${Math.round(delta / 1000)}s`\n}\n\nfunction formatPath(rawUrl: string) {\n try {\n const url = new URL(rawUrl)\n return `${url.pathname}${url.search}`\n }\n catch {\n return rawUrl\n }\n}\n\nfunction colorizeStatus(status: number): string {\n if (status >= 500)\n return colorize('red', status)\n if (status >= 400)\n return colorize('yellow', status)\n if (status >= 300)\n return colorize('cyan', status)\n return colorize('green', status)\n}\n\nconst methodColors: Record<string, Parameters<typeof colorize>[0]> = {\n GET: 'cyan',\n POST: 'magenta',\n PUT: 'yellow',\n PATCH: 'yellow',\n DELETE: 'red',\n}\n\nfunction colorizeMethod(method: string): string {\n return colorize(methodColors[method] ?? 'white', method)\n}\n\nfunction formatModelMapping(info: ModelMappingInfo | undefined): string {\n if (!info)\n return ''\n\n const { originalModel, mappedModel } = info\n if (!originalModel && !mappedModel)\n return ''\n\n const original = originalModel ?? '-'\n const mapped = mappedModel ?? '-'\n\n if (original === mapped) {\n return ` ${colorize('dim', 'model=')}${colorize('blueBright', original)}`\n }\n\n return ` ${colorize('dim', 'model=')}${colorize('blueBright', original)} ${colorize('dim', '→')} ${colorize('greenBright', mapped)}`\n}\n\nexport const requestLogger: MiddlewareHandler = async (c, next) => {\n const { method, url } = c.req\n const path = formatPath(url)\n const start = Date.now()\n\n try {\n await next()\n }\n finally {\n const elapsed = formatElapsed(start)\n const status = c.res.status\n const modelInfo = c.get('modelMappingInfo')\n\n const line = [\n colorizeMethod(method),\n colorize('white', path),\n colorizeStatus(status),\n colorize('dim', elapsed),\n ].join(' ')\n\n consola.info(`${line}${formatModelMapping(modelInfo)}`)\n }\n}\n\nexport function setModelMappingInfo(c: Context, info: ModelMappingInfo) {\n c.set('modelMappingInfo', info)\n}\n","import consola from 'consola'\n\nimport { HTTPError } from './error'\n\nexport async function awaitApproval() {\n const response = await consola.prompt(`Accept incoming request?`, {\n type: 'confirm',\n })\n\n if (!response) {\n throw new HTTPError(\n 'Request rejected',\n Response.json({ message: 'Request rejected' }, { status: 403 }),\n )\n }\n}\n","import type { AppState } from './state'\n\nimport consola from 'consola'\n\nimport { HTTPError } from './error'\nimport { sleep } from './utils'\n\nexport async function checkRateLimit(state: AppState) {\n if (state.config.rateLimitSeconds === undefined)\n return\n\n const now = Date.now()\n\n if (!state.rateLimit.lastRequestTimestamp) {\n state.rateLimit.lastRequestTimestamp = now\n return\n }\n\n const elapsedSeconds = (now - state.rateLimit.lastRequestTimestamp) / 1000\n\n if (elapsedSeconds > state.config.rateLimitSeconds) {\n state.rateLimit.lastRequestTimestamp = now\n return\n }\n\n const waitTimeSeconds = Math.ceil(\n state.config.rateLimitSeconds - elapsedSeconds,\n )\n\n if (!state.config.rateLimitWait) {\n consola.warn(\n `Rate limit exceeded. Need to wait ${waitTimeSeconds} more seconds.`,\n )\n throw new HTTPError(\n 'Rate limit exceeded',\n Response.json({ message: 'Rate limit exceeded' }, { status: 429 }),\n )\n }\n\n const waitTimeMs = waitTimeSeconds * 1000\n consola.warn(\n `Rate limit reached. Waiting ${waitTimeSeconds} seconds before proceeding...`,\n )\n await sleep(waitTimeMs)\n\n state.rateLimit.lastRequestTimestamp = now\n consola.info('Rate limit wait completed, proceeding with request')\n}\n","import type { MiddlewareHandler } from 'hono'\n\nimport { awaitApproval } from '~/lib/approval'\nimport { checkRateLimit } from '~/lib/rate-limit'\nimport { state } from '~/lib/state'\n\nexport const requestGuard: MiddlewareHandler = async (c, next) => {\n void c\n await checkRateLimit(state)\n\n if (state.config.manualApprove) {\n await awaitApproval()\n }\n\n await next()\n}\n","import type {\n ChatCompletionsPayload,\n ContentPart,\n Message,\n Model,\n Tool,\n ToolCall,\n} from '~/types'\n\n// Encoder type mapping\nconst ENCODING_MAP = {\n o200k_base: () => import('gpt-tokenizer/encoding/o200k_base'),\n cl100k_base: () => import('gpt-tokenizer/encoding/cl100k_base'),\n p50k_base: () => import('gpt-tokenizer/encoding/p50k_base'),\n p50k_edit: () => import('gpt-tokenizer/encoding/p50k_edit'),\n r50k_base: () => import('gpt-tokenizer/encoding/r50k_base'),\n} as const\n\ntype SupportedEncoding = keyof typeof ENCODING_MAP\n\n// Define encoder interface\ninterface Encoder {\n encode: (text: string) => Array<number>\n}\n\n// Cache loaded encoders to avoid repeated imports\nconst encodingCache = new Map<string, Encoder>()\n\n/**\n * Calculate tokens for tool calls\n */\nfunction calculateToolCallsTokens(toolCalls: Array<ToolCall>, encoder: Encoder, constants: ReturnType<typeof getModelConstants>): number {\n let tokens = 0\n for (const toolCall of toolCalls) {\n tokens += constants.funcInit\n tokens += encoder.encode(JSON.stringify(toolCall)).length\n }\n tokens += constants.funcEnd\n return tokens\n}\n\n/**\n * Calculate tokens for content parts\n */\nfunction calculateContentPartsTokens(contentParts: Array<ContentPart>, encoder: Encoder): number {\n let tokens = 0\n for (const part of contentParts) {\n if (part.type === 'image_url') {\n tokens += encoder.encode(part.image_url.url).length + 85\n }\n else if (part.text) {\n tokens += encoder.encode(part.text).length\n }\n }\n return tokens\n}\n\n/**\n * Calculate tokens for a single message\n */\nfunction calculateMessageTokens(message: Message, encoder: Encoder, constants: ReturnType<typeof getModelConstants>): number {\n const tokensPerMessage = 3\n const tokensPerName = 1\n let tokens = tokensPerMessage\n for (const [key, value] of Object.entries(message)) {\n if (typeof value === 'string') {\n tokens += encoder.encode(value).length\n }\n if (key === 'name') {\n tokens += tokensPerName\n }\n if (key === 'tool_calls') {\n tokens += calculateToolCallsTokens(\n value as Array<ToolCall>,\n encoder,\n constants,\n )\n }\n if (key === 'content' && Array.isArray(value)) {\n tokens += calculateContentPartsTokens(\n value as Array<ContentPart>,\n encoder,\n )\n }\n }\n return tokens\n}\n\n/**\n * Calculate tokens using custom algorithm\n */\nfunction calculateTokens(messages: Array<Message>, encoder: Encoder, constants: ReturnType<typeof getModelConstants>): number {\n if (messages.length === 0) {\n return 0\n }\n let numTokens = 0\n for (const message of messages) {\n numTokens += calculateMessageTokens(message, encoder, constants)\n }\n // every reply is primed with <|start|>assistant<|message|>\n numTokens += 3\n return numTokens\n}\n\n/**\n * Get the corresponding encoder module based on encoding type\n */\nasync function getEncodeChatFunction(encoding: string): Promise<Encoder> {\n if (encodingCache.has(encoding)) {\n const cached = encodingCache.get(encoding)\n if (cached) {\n return cached\n }\n }\n\n const supportedEncoding = encoding as SupportedEncoding\n if (!(supportedEncoding in ENCODING_MAP)) {\n const fallbackModule = (await ENCODING_MAP.o200k_base()) as Encoder\n encodingCache.set(encoding, fallbackModule)\n return fallbackModule\n }\n\n const encodingModule = (await ENCODING_MAP[supportedEncoding]()) as Encoder\n encodingCache.set(encoding, encodingModule)\n return encodingModule\n}\n\n/**\n * Get tokenizer type from model information\n */\nexport function getTokenizerFromModel(model: Model): string {\n return model.capabilities.tokenizer || 'o200k_base'\n}\n\n/**\n * Get model-specific constants for token calculation\n */\nfunction getModelConstants(model: Model) {\n return model.id === 'gpt-3.5-turbo' || model.id === 'gpt-4'\n ? {\n funcInit: 10,\n propInit: 3,\n propKey: 3,\n enumInit: -3,\n enumItem: 3,\n funcEnd: 12,\n }\n : {\n funcInit: 7,\n propInit: 3,\n propKey: 3,\n enumInit: -3,\n enumItem: 3,\n funcEnd: 12,\n }\n}\n\n/**\n * Calculate tokens for a single parameter\n */\nfunction calculateParameterTokens(key: string, prop: unknown, context: {\n encoder: Encoder\n constants: ReturnType<typeof getModelConstants>\n}): number {\n const { encoder, constants } = context\n let tokens = constants.propKey\n\n // Early return if prop is not an object\n if (typeof prop !== 'object' || prop === null) {\n return tokens\n }\n\n // Type assertion for parameter properties\n const param = prop as {\n type?: string\n description?: string\n enum?: Array<unknown>\n [key: string]: unknown\n }\n\n const paramName = key\n const paramType = param.type || 'string'\n let paramDesc = param.description || ''\n\n // Handle enum values\n if (param.enum && Array.isArray(param.enum)) {\n tokens += constants.enumInit\n for (const item of param.enum) {\n tokens += constants.enumItem\n tokens += encoder.encode(String(item)).length\n }\n }\n\n // Clean up description\n if (paramDesc.endsWith('.')) {\n paramDesc = paramDesc.slice(0, -1)\n }\n\n // Encode the main parameter line\n const line = `${paramName}:${paramType}:${paramDesc}`\n tokens += encoder.encode(line).length\n\n // Handle additional properties (excluding standard ones)\n const excludedKeys = new Set(['type', 'description', 'enum'])\n for (const propertyName of Object.keys(param)) {\n if (!excludedKeys.has(propertyName)) {\n const propertyValue = param[propertyName]\n const propertyText\n = typeof propertyValue === 'string'\n ? propertyValue\n : (\n JSON.stringify(propertyValue)\n )\n tokens += encoder.encode(`${propertyName}:${propertyText}`).length\n }\n }\n\n return tokens\n}\n\n/**\n * Calculate tokens for function parameters\n */\nfunction calculateParametersTokens(parameters: unknown, encoder: Encoder, constants: ReturnType<typeof getModelConstants>): number {\n if (!parameters || typeof parameters !== 'object') {\n return 0\n }\n\n const params = parameters as Record<string, unknown>\n let tokens = 0\n\n for (const [key, value] of Object.entries(params)) {\n if (key === 'properties') {\n const properties = value as Record<string, unknown>\n if (Object.keys(properties).length > 0) {\n tokens += constants.propInit\n for (const propKey of Object.keys(properties)) {\n tokens += calculateParameterTokens(propKey, properties[propKey], {\n encoder,\n constants,\n })\n }\n }\n }\n else {\n const paramText\n = typeof value === 'string' ? value : JSON.stringify(value)\n tokens += encoder.encode(`${key}:${paramText}`).length\n }\n }\n\n return tokens\n}\n\n/**\n * Calculate tokens for a single tool\n */\nfunction calculateToolTokens(tool: Tool, encoder: Encoder, constants: ReturnType<typeof getModelConstants>): number {\n let tokens = constants.funcInit\n const func = tool.function\n const fName = func.name\n let fDesc = func.description || ''\n if (fDesc.endsWith('.')) {\n fDesc = fDesc.slice(0, -1)\n }\n const line = `${fName}:${fDesc}`\n tokens += encoder.encode(line).length\n if (\n typeof func.parameters === 'object'\n && func.parameters !== null\n ) {\n tokens += calculateParametersTokens(func.parameters, encoder, constants)\n }\n return tokens\n}\n\n/**\n * Calculate token count for tools based on model\n */\nexport function numTokensForTools(tools: Array<Tool>, encoder: Encoder, constants: ReturnType<typeof getModelConstants>): number {\n let funcTokenCount = 0\n for (const tool of tools) {\n funcTokenCount += calculateToolTokens(tool, encoder, constants)\n }\n funcTokenCount += constants.funcEnd\n return funcTokenCount\n}\n\n/**\n * Calculate the token count of messages, supporting multiple GPT encoders\n */\nexport async function getTokenCount(payload: ChatCompletionsPayload, model: Model): Promise<{ input: number, output: number }> {\n // Get tokenizer string\n const tokenizer = getTokenizerFromModel(model)\n\n // Get corresponding encoder module\n const encoder = await getEncodeChatFunction(tokenizer)\n\n const simplifiedMessages = payload.messages\n const inputMessages = simplifiedMessages.filter(\n msg => msg.role !== 'assistant',\n )\n const outputMessages = simplifiedMessages.filter(\n msg => msg.role === 'assistant',\n )\n\n const constants = getModelConstants(model)\n let inputTokens = calculateTokens(inputMessages, encoder, constants)\n if (payload.tools && payload.tools.length > 0) {\n inputTokens += numTokensForTools(payload.tools, encoder, constants)\n }\n const outputTokens = calculateTokens(outputMessages, encoder, constants)\n\n return {\n input: inputTokens,\n output: outputTokens,\n }\n}\n","import type {\n AnthropicCountTokensPayload,\n AnthropicMessagesPayload,\n} from '~/translator'\nimport type { ChatCompletionsPayload, EmbeddingRequest } from '~/types'\n\nimport consola from 'consola'\nimport { z } from 'zod'\n\nimport { HTTPError } from './error'\n\nconst openAIMessageSchema = z\n .object({\n role: z.string(),\n content: z.union([z.string(), z.array(z.any()), z.null()]),\n name: z.string().optional(),\n tool_calls: z.array(z.any()).optional(),\n tool_call_id: z.string().optional(),\n })\n .loose()\n\nconst openAIChatPayloadSchema = z\n .object({\n model: z.string(),\n messages: z.array(openAIMessageSchema).min(1),\n })\n .loose()\n\nconst anthropicMessageSchema = z\n .object({\n role: z.enum(['user', 'assistant']),\n content: z.union([z.string(), z.array(z.any())]),\n })\n .loose()\n\nconst anthropicMessagesBasePayloadSchema = z\n .object({\n model: z.string(),\n messages: z.array(anthropicMessageSchema).min(1),\n })\n .loose()\n\nconst anthropicMessagesPayloadSchema = anthropicMessagesBasePayloadSchema\n .extend({\n max_tokens: z.number(),\n })\n .loose()\n\nconst anthropicCountTokensPayloadSchema = anthropicMessagesBasePayloadSchema\n .extend({\n max_tokens: z.number().optional(),\n })\n .loose()\n\nconst embeddingRequestSchema = z\n .object({\n input: z.union([z.string(), z.array(z.string())]),\n model: z.string(),\n })\n .loose()\n\nfunction throwInvalidPayload(context: string, issues: Array<z.core.$ZodIssue>) {\n consola.warn('Invalid request payload', { context, issues })\n throw new HTTPError(\n 'Invalid request payload',\n new Response('Invalid request payload', { status: 400 }),\n )\n}\n\nexport function parseOpenAIChatPayload(payload: unknown): ChatCompletionsPayload {\n const result = openAIChatPayloadSchema.safeParse(payload)\n if (!result.success) {\n throwInvalidPayload('openai.chat', result.error.issues)\n }\n return result.data as ChatCompletionsPayload\n}\n\nexport function parseAnthropicMessagesPayload(payload: unknown): AnthropicMessagesPayload {\n const result = anthropicMessagesPayloadSchema.safeParse(payload)\n if (!result.success) {\n throwInvalidPayload('anthropic.messages', result.error.issues)\n }\n return result.data as AnthropicMessagesPayload\n}\n\nexport function parseAnthropicCountTokensPayload(payload: unknown): AnthropicCountTokensPayload {\n const result = anthropicCountTokensPayloadSchema.safeParse(payload)\n if (!result.success) {\n throwInvalidPayload('anthropic.messages.count_tokens', result.error.issues)\n }\n return result.data as AnthropicCountTokensPayload\n}\n\nexport function parseEmbeddingRequest(payload: unknown): EmbeddingRequest {\n const result = embeddingRequestSchema.safeParse(payload)\n if (!result.success) {\n throwInvalidPayload('openai.embeddings', result.error.issues)\n }\n return result.data as EmbeddingRequest\n}\n","import type { Context } from 'hono'\n\nimport type { SSEMessage } from 'hono/streaming'\nimport type { ChatCompletionResponse } from '~/types'\n\nimport consola from 'consola'\nimport { streamSSE } from 'hono/streaming'\n\nimport { CopilotClient } from '~/clients'\nimport { getClientConfig } from '~/lib/client-config'\nimport { state } from '~/lib/state'\nimport { getTokenCount } from '~/lib/tokenizer'\nimport { isNullish } from '~/lib/utils'\nimport { parseOpenAIChatPayload } from '~/lib/validation'\n\nexport async function handleCompletion(c: Context) {\n let payload = parseOpenAIChatPayload(await c.req.json())\n consola.debug('Request payload:', JSON.stringify(payload).slice(-400))\n\n // Find the selected model\n const selectedModel = state.cache.models?.data.find(\n model => model.id === payload.model,\n )\n\n // Calculate and display token count\n try {\n if (selectedModel) {\n const tokenCount = await getTokenCount(payload, selectedModel)\n consola.info('Current token count:', tokenCount)\n }\n else {\n consola.warn('No model selected, skipping token count calculation')\n }\n }\n catch (error) {\n consola.warn('Failed to calculate token count:', error)\n }\n\n if (isNullish(payload.max_tokens)) {\n payload = {\n ...payload,\n max_tokens: selectedModel?.capabilities.limits.max_output_tokens,\n }\n consola.debug('Set max_tokens to:', JSON.stringify(payload.max_tokens))\n }\n\n const copilotClient = new CopilotClient(state.auth, getClientConfig(state))\n const response = await copilotClient.createChatCompletions(payload, {\n signal: c.req.raw.signal,\n })\n\n if (isNonStreaming(response)) {\n consola.debug('Non-streaming response:', JSON.stringify(response))\n return c.json(response)\n }\n\n consola.debug('Streaming response')\n return streamSSE(c, async (stream) => {\n try {\n for await (const chunk of response) {\n consola.debug('Streaming chunk:', JSON.stringify(chunk))\n await stream.writeSSE(chunk as SSEMessage)\n }\n }\n finally {\n // No cleanup needed without keepalive.\n }\n })\n}\n\nfunction isNonStreaming(response: Awaited<ReturnType<CopilotClient['createChatCompletions']>>): response is ChatCompletionResponse {\n return Object.hasOwn(response, 'choices')\n}\n","import { Hono } from 'hono'\n\nimport { requestGuard } from '~/routes/middleware/request-guard'\n\nimport { handleCompletion } from './handler'\n\nexport const completionRoutes = new Hono()\n\ncompletionRoutes.post('/', requestGuard, c => handleCompletion(c))\n","import { Hono } from 'hono'\n\nimport { CopilotClient } from '~/clients'\nimport { getClientConfig } from '~/lib/client-config'\nimport { state } from '~/lib/state'\nimport { parseEmbeddingRequest } from '~/lib/validation'\n\nexport const embeddingRoutes = new Hono()\n\nembeddingRoutes.post('/', async (c) => {\n const payload = parseEmbeddingRequest(await c.req.json())\n const copilotClient = new CopilotClient(state.auth, getClientConfig(state))\n const response = await copilotClient.createEmbeddings(payload)\n\n return c.json(response)\n})\n","import type { AnthropicResponse } from './types'\n\nexport function mapOpenAIStopReasonToAnthropic(\n finishReason: 'stop' | 'length' | 'tool_calls' | 'content_filter' | null,\n): AnthropicResponse['stop_reason'] {\n if (finishReason === null) {\n return null\n }\n const stopReasonMap = {\n stop: 'end_turn',\n length: 'max_tokens',\n tool_calls: 'tool_use',\n content_filter: 'end_turn',\n } as const\n return stopReasonMap[finishReason]\n}\n","import type { AnthropicStreamEventData, AnthropicStreamState } from './types'\n\nimport type { ChatCompletionChunk } from '~/types'\n\nimport { mapOpenAIStopReasonToAnthropic } from './shared'\n\nexport class AnthropicStreamTranslator {\n private state: AnthropicStreamState\n\n constructor() {\n this.state = {\n messageStartSent: false,\n contentBlockIndex: 0,\n contentBlockOpen: false,\n toolCalls: {},\n }\n }\n\n onChunk(chunk: ChatCompletionChunk): Array<AnthropicStreamEventData> {\n if (chunk.choices.length === 0) {\n return []\n }\n\n const events: Array<AnthropicStreamEventData> = []\n const choice = chunk.choices[0]\n const { delta } = choice\n\n this.appendMessageStart(events, chunk)\n this.appendContentDelta(events, delta.content)\n this.appendToolCalls(events, delta.tool_calls)\n this.appendFinish(events, chunk, choice.finish_reason)\n\n return events\n }\n\n onError(error?: unknown): Array<AnthropicStreamEventData> {\n const message = this.getErrorMessage(error)\n return [\n {\n type: 'error',\n error: {\n type: 'api_error',\n message,\n },\n },\n ]\n }\n\n private getErrorMessage(error: unknown): string {\n if (this.isTimeoutError(error)) {\n return 'Upstream streaming request timed out. Please retry.'\n }\n return 'An unexpected error occurred during streaming.'\n }\n\n private isTimeoutError(error: unknown): boolean {\n if (error instanceof DOMException) {\n return error.name === 'TimeoutError'\n }\n if (error instanceof Error) {\n return error.name === 'TimeoutError'\n }\n return false\n }\n\n private isToolBlockOpen(): boolean {\n if (!this.state.contentBlockOpen) {\n return false\n }\n return Object.values(this.state.toolCalls).some((tc) => {\n return (\n tc !== undefined\n && tc.anthropicBlockIndex === this.state.contentBlockIndex\n )\n })\n }\n\n private appendMessageStart(\n events: Array<AnthropicStreamEventData>,\n chunk: ChatCompletionChunk,\n ) {\n if (this.state.messageStartSent) {\n return\n }\n\n events.push({\n type: 'message_start',\n message: {\n id: chunk.id,\n type: 'message',\n role: 'assistant',\n content: [],\n model: chunk.model,\n stop_reason: null,\n stop_sequence: null,\n usage: {\n input_tokens:\n (chunk.usage?.prompt_tokens ?? 0)\n - (chunk.usage?.prompt_tokens_details?.cached_tokens ?? 0),\n output_tokens: 0,\n ...(chunk.usage?.prompt_tokens_details?.cached_tokens\n !== undefined && {\n cache_read_input_tokens:\n chunk.usage.prompt_tokens_details.cached_tokens,\n }),\n },\n },\n })\n this.state.messageStartSent = true\n }\n\n private appendContentDelta(\n events: Array<AnthropicStreamEventData>,\n content: string | null | undefined,\n ) {\n if (!content) {\n return\n }\n\n if (this.isToolBlockOpen()) {\n events.push({\n type: 'content_block_stop',\n index: this.state.contentBlockIndex,\n })\n this.state.contentBlockIndex++\n this.state.contentBlockOpen = false\n }\n\n if (!this.state.contentBlockOpen) {\n events.push({\n type: 'content_block_start',\n index: this.state.contentBlockIndex,\n content_block: {\n type: 'text',\n text: '',\n },\n })\n this.state.contentBlockOpen = true\n }\n\n events.push({\n type: 'content_block_delta',\n index: this.state.contentBlockIndex,\n delta: {\n type: 'text_delta',\n text: content,\n },\n })\n }\n\n private appendToolCalls(\n events: Array<AnthropicStreamEventData>,\n toolCalls:\n | Array<{\n index: number\n id?: string\n type?: 'function'\n function?: {\n name?: string\n arguments?: string\n }\n }>\n | undefined,\n ) {\n if (!toolCalls || toolCalls.length === 0) {\n return\n }\n\n for (const toolCall of toolCalls) {\n if (toolCall.id && toolCall.function?.name) {\n if (this.state.contentBlockOpen) {\n events.push({\n type: 'content_block_stop',\n index: this.state.contentBlockIndex,\n })\n this.state.contentBlockIndex++\n this.state.contentBlockOpen = false\n }\n\n const anthropicBlockIndex = this.state.contentBlockIndex\n this.state.toolCalls[toolCall.index] = {\n id: toolCall.id,\n name: toolCall.function.name,\n anthropicBlockIndex,\n }\n\n events.push({\n type: 'content_block_start',\n index: anthropicBlockIndex,\n content_block: {\n type: 'tool_use',\n id: toolCall.id,\n name: toolCall.function.name,\n input: {},\n },\n })\n this.state.contentBlockOpen = true\n }\n\n if (toolCall.function?.arguments) {\n const toolCallInfo = this.state.toolCalls[toolCall.index]\n if (!toolCallInfo) {\n continue\n }\n\n events.push({\n type: 'content_block_delta',\n index: toolCallInfo.anthropicBlockIndex,\n delta: {\n type: 'input_json_delta',\n partial_json: toolCall.function.arguments,\n },\n })\n }\n }\n }\n\n private appendFinish(\n events: Array<AnthropicStreamEventData>,\n chunk: ChatCompletionChunk,\n finishReason: 'stop' | 'length' | 'tool_calls' | 'content_filter' | null,\n ) {\n if (!finishReason) {\n return\n }\n\n if (this.state.contentBlockOpen) {\n events.push({\n type: 'content_block_stop',\n index: this.state.contentBlockIndex,\n })\n this.state.contentBlockOpen = false\n }\n\n events.push(\n {\n type: 'message_delta',\n delta: {\n stop_reason: mapOpenAIStopReasonToAnthropic(finishReason),\n stop_sequence: null,\n },\n usage: {\n input_tokens:\n (chunk.usage?.prompt_tokens ?? 0)\n - (chunk.usage?.prompt_tokens_details?.cached_tokens ?? 0),\n output_tokens: chunk.usage?.completion_tokens ?? 0,\n ...(chunk.usage?.prompt_tokens_details?.cached_tokens\n !== undefined && {\n cache_read_input_tokens:\n chunk.usage.prompt_tokens_details.cached_tokens,\n }),\n },\n },\n {\n type: 'message_stop',\n },\n )\n }\n}\n","import process from 'node:process'\n\nimport { getCachedConfig } from './config'\n\nexport interface ModelFallbackConfig {\n claudeOpus: string\n claudeSonnet: string\n claudeHaiku: string\n}\n\nexport const DEFAULT_FALLBACKS: ModelFallbackConfig = {\n claudeOpus: 'claude-opus-4.6',\n claudeSonnet: 'claude-sonnet-4.5',\n claudeHaiku: 'claude-haiku-4.5',\n}\n\nexport function getModelFallbackConfig(): ModelFallbackConfig {\n const cachedConfig = getCachedConfig()\n return {\n claudeOpus:\n process.env.MODEL_FALLBACK_CLAUDE_OPUS\n || cachedConfig.modelFallback?.claudeOpus\n || DEFAULT_FALLBACKS.claudeOpus,\n claudeSonnet:\n process.env.MODEL_FALLBACK_CLAUDE_SONNET\n || cachedConfig.modelFallback?.claudeSonnet\n || DEFAULT_FALLBACKS.claudeSonnet,\n claudeHaiku:\n process.env.MODEL_FALLBACK_CLAUDE_HAIKU\n || cachedConfig.modelFallback?.claudeHaiku\n || DEFAULT_FALLBACKS.claudeHaiku,\n }\n}\n\nexport function resolveModel(\n modelId: string,\n knownModelIds: Set<string> | undefined,\n config: ModelFallbackConfig,\n): string {\n if (knownModelIds?.has(modelId)) {\n return modelId\n }\n if (modelId.startsWith('claude-opus-'))\n return config.claudeOpus\n if (modelId.startsWith('claude-sonnet-'))\n return config.claudeSonnet\n if (modelId.startsWith('claude-haiku-'))\n return config.claudeHaiku\n return modelId\n}\n","import type {\n AnthropicAssistantContentBlock,\n AnthropicAssistantMessage,\n AnthropicMessage,\n AnthropicMessagesPayload,\n AnthropicResponse,\n AnthropicTextBlock,\n AnthropicThinkingBlock,\n AnthropicTool,\n AnthropicToolResultBlock,\n AnthropicToolUseBlock,\n AnthropicUserContentBlock,\n AnthropicUserMessage,\n} from './types'\n\nimport type {\n ChatCompletionResponse,\n ChatCompletionsPayload,\n ContentPart,\n Message,\n TextPart,\n Tool,\n ToolCall,\n} from '~/types'\nimport { getModelFallbackConfig, resolveModel } from '~/lib/model-resolver'\n\nimport { state } from '~/lib/state'\n\nimport { AnthropicStreamTranslator } from './anthropic-stream-translator'\nimport { mapOpenAIStopReasonToAnthropic } from './shared'\n\nexport class AnthropicTranslator {\n toOpenAI(payload: AnthropicMessagesPayload): ChatCompletionsPayload {\n return {\n model: this.translateModelName(payload.model),\n messages: this.translateAnthropicMessagesToOpenAI(\n payload.messages,\n payload.system,\n ),\n max_tokens: payload.max_tokens,\n stop: payload.stop_sequences,\n stream: payload.stream,\n temperature: payload.temperature,\n top_p: payload.top_p,\n user: payload.metadata?.user_id,\n tools: this.translateAnthropicToolsToOpenAI(payload.tools),\n tool_choice: this.translateAnthropicToolChoiceToOpenAI(\n payload.tool_choice,\n ),\n }\n }\n\n fromOpenAI(response: ChatCompletionResponse): AnthropicResponse {\n const allTextBlocks: Array<AnthropicTextBlock> = []\n const allToolUseBlocks: Array<AnthropicToolUseBlock> = []\n let stopReason: 'stop' | 'length' | 'tool_calls' | 'content_filter' | null\n = null\n stopReason = response.choices[0]?.finish_reason ?? stopReason\n\n for (const choice of response.choices) {\n const textBlocks = this.getAnthropicTextBlocks(choice.message.content)\n const toolUseBlocks = this.getAnthropicToolUseBlocks(\n choice.message.tool_calls,\n )\n\n allTextBlocks.push(...textBlocks)\n allToolUseBlocks.push(...toolUseBlocks)\n\n if (choice.finish_reason === 'tool_calls' || stopReason === 'stop') {\n stopReason = choice.finish_reason\n }\n }\n\n return {\n id: response.id,\n type: 'message',\n role: 'assistant',\n model: response.model,\n content: [...allTextBlocks, ...allToolUseBlocks],\n stop_reason: mapOpenAIStopReasonToAnthropic(stopReason),\n stop_sequence: null,\n usage: {\n input_tokens:\n (response.usage?.prompt_tokens ?? 0)\n - (response.usage?.prompt_tokens_details?.cached_tokens ?? 0),\n output_tokens: response.usage?.completion_tokens ?? 0,\n ...(response.usage?.prompt_tokens_details?.cached_tokens\n !== undefined && {\n cache_read_input_tokens:\n response.usage.prompt_tokens_details.cached_tokens,\n }),\n },\n }\n }\n\n createStreamTranslator() {\n return new AnthropicStreamTranslator()\n }\n\n private translateModelName(model: string): string {\n const knownModelIds\n = state.cache.models\n ? new Set(state.cache.models.data.map(m => m.id))\n : undefined\n const config = getModelFallbackConfig()\n return resolveModel(model, knownModelIds, config)\n }\n\n private translateAnthropicMessagesToOpenAI(\n anthropicMessages: Array<AnthropicMessage>,\n system: string | Array<AnthropicTextBlock> | undefined,\n ): Array<Message> {\n const systemMessages = this.handleSystemPrompt(system)\n\n const otherMessages = anthropicMessages.flatMap(message =>\n message.role === 'user'\n ? this.handleUserMessage(message)\n : this.handleAssistantMessage(message),\n )\n\n return [...systemMessages, ...otherMessages]\n }\n\n private handleSystemPrompt(\n system: string | Array<AnthropicTextBlock> | undefined,\n ): Array<Message> {\n if (!system) {\n return []\n }\n\n if (typeof system === 'string') {\n return [{ role: 'system', content: system }]\n }\n\n const systemText = system.map(block => block.text).join('\\n\\n')\n return [{ role: 'system', content: systemText }]\n }\n\n private handleUserMessage(message: AnthropicUserMessage): Array<Message> {\n const newMessages: Array<Message> = []\n\n if (Array.isArray(message.content)) {\n const toolResultBlocks = message.content.filter(\n (block): block is AnthropicToolResultBlock =>\n block.type === 'tool_result',\n )\n const otherBlocks = message.content.filter(\n block => block.type !== 'tool_result',\n )\n\n for (const block of toolResultBlocks) {\n newMessages.push({\n role: 'tool',\n tool_call_id: block.tool_use_id,\n content: this.mapContent(block.content),\n })\n }\n\n if (otherBlocks.length > 0) {\n newMessages.push({\n role: 'user',\n content: this.mapContent(otherBlocks),\n })\n }\n }\n else {\n newMessages.push({\n role: 'user',\n content: this.mapContent(message.content),\n })\n }\n\n return newMessages\n }\n\n private handleAssistantMessage(\n message: AnthropicAssistantMessage,\n ): Array<Message> {\n if (!Array.isArray(message.content)) {\n return [\n {\n role: 'assistant',\n content: this.mapContent(message.content),\n },\n ]\n }\n\n const toolUseBlocks = message.content.filter(\n (block): block is AnthropicToolUseBlock => block.type === 'tool_use',\n )\n\n const textBlocks = message.content.filter(\n (block): block is AnthropicTextBlock => block.type === 'text',\n )\n\n const thinkingBlocks = message.content.filter(\n (block): block is AnthropicThinkingBlock => block.type === 'thinking',\n )\n\n const allTextContent = [\n ...textBlocks.map(b => b.text),\n ...thinkingBlocks.map(b => b.thinking),\n ].join('\\n\\n')\n\n return toolUseBlocks.length > 0\n ? [\n {\n role: 'assistant',\n content: allTextContent || null,\n tool_calls: toolUseBlocks.map(toolUse => ({\n id: toolUse.id,\n type: 'function',\n function: {\n name: toolUse.name,\n arguments: JSON.stringify(toolUse.input),\n },\n })),\n },\n ]\n : [\n {\n role: 'assistant',\n content: this.mapContent(message.content),\n },\n ]\n }\n\n private mapContent(\n content:\n | string\n | Array<AnthropicUserContentBlock | AnthropicAssistantContentBlock>,\n ): string | Array<ContentPart> | null {\n if (typeof content === 'string') {\n return content\n }\n if (!Array.isArray(content)) {\n return null\n }\n\n const hasImage = content.some(block => block.type === 'image')\n if (!hasImage) {\n return content\n .filter(\n (block): block is AnthropicTextBlock | AnthropicThinkingBlock =>\n block.type === 'text' || block.type === 'thinking',\n )\n .map(block => (block.type === 'text' ? block.text : block.thinking))\n .join('\\n\\n')\n }\n\n const contentParts: Array<ContentPart> = []\n for (const block of content) {\n switch (block.type) {\n case 'text': {\n contentParts.push({ type: 'text', text: block.text })\n break\n }\n case 'thinking': {\n contentParts.push({ type: 'text', text: block.thinking })\n break\n }\n case 'image': {\n contentParts.push({\n type: 'image_url',\n image_url: {\n url: `data:${block.source.media_type};base64,${block.source.data}`,\n },\n })\n break\n }\n default: {\n break\n }\n }\n }\n return contentParts\n }\n\n private translateAnthropicToolsToOpenAI(\n anthropicTools: Array<AnthropicTool> | undefined,\n ): Array<Tool> | undefined {\n if (!anthropicTools) {\n return undefined\n }\n return anthropicTools.map(tool => ({\n type: 'function',\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.input_schema,\n },\n }))\n }\n\n private translateAnthropicToolChoiceToOpenAI(\n anthropicToolChoice: AnthropicMessagesPayload['tool_choice'],\n ): ChatCompletionsPayload['tool_choice'] {\n if (!anthropicToolChoice) {\n return undefined\n }\n\n switch (anthropicToolChoice.type) {\n case 'auto': {\n return 'auto'\n }\n case 'any': {\n return 'required'\n }\n case 'tool': {\n if (anthropicToolChoice.name) {\n return {\n type: 'function',\n function: { name: anthropicToolChoice.name },\n }\n }\n return undefined\n }\n case 'none': {\n return 'none'\n }\n default: {\n return undefined\n }\n }\n }\n\n private getAnthropicTextBlocks(\n messageContent: Message['content'],\n ): Array<AnthropicTextBlock> {\n if (typeof messageContent === 'string') {\n return [{ type: 'text', text: messageContent }]\n }\n\n if (Array.isArray(messageContent)) {\n return messageContent\n .filter((part): part is TextPart => part.type === 'text')\n .map(part => ({ type: 'text', text: part.text }))\n }\n\n return []\n }\n\n private getAnthropicToolUseBlocks(\n toolCalls: Array<ToolCall> | undefined,\n ): Array<AnthropicToolUseBlock> {\n if (!toolCalls) {\n return []\n }\n return toolCalls.map(toolCall => ({\n type: 'tool_use',\n id: toolCall.id,\n name: toolCall.function.name,\n input: JSON.parse(toolCall.function.arguments) as Record<string, unknown>,\n }))\n }\n}\n","import type { Context } from 'hono'\n\nimport consola from 'consola'\n\nimport { HTTPError } from '~/lib/error'\nimport { state } from '~/lib/state'\nimport { getTokenCount } from '~/lib/tokenizer'\nimport { parseAnthropicCountTokensPayload } from '~/lib/validation'\nimport { AnthropicTranslator } from '~/translator'\n\n/**\n * Handles token counting for Anthropic messages\n */\nexport async function handleCountTokens(c: Context) {\n const anthropicBeta = c.req.header('anthropic-beta')\n const anthropicPayload = parseAnthropicCountTokensPayload(await c.req.json())\n const normalizedPayload = {\n ...anthropicPayload,\n max_tokens: anthropicPayload.max_tokens ?? 0,\n }\n\n const translator = new AnthropicTranslator()\n const openAIPayload = translator.toOpenAI(normalizedPayload)\n\n const selectedModel = state.cache.models?.data.find(\n model => model.id === openAIPayload.model,\n )\n\n if (!selectedModel) {\n throw new HTTPError(\n `Model not found for token counting: \"${openAIPayload.model}\"`,\n new Response(\n `Model not found for token counting: \"${openAIPayload.model}\"`,\n {\n status: 400,\n },\n ),\n )\n }\n\n const tokenCount = await getTokenCount(openAIPayload, selectedModel)\n\n if (anthropicPayload.tools && anthropicPayload.tools.length > 0) {\n let mcpToolExist = false\n if (anthropicBeta?.startsWith('claude-code')) {\n mcpToolExist = anthropicPayload.tools.some(tool =>\n tool.name.startsWith('mcp__'),\n )\n }\n if (!mcpToolExist) {\n if (anthropicPayload.model.startsWith('claude')) {\n // https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#pricing\n tokenCount.input = tokenCount.input + 346\n }\n else if (anthropicPayload.model.startsWith('grok')) {\n tokenCount.input = tokenCount.input + 480\n }\n }\n }\n\n let finalTokenCount = tokenCount.input + tokenCount.output\n if (anthropicPayload.model.startsWith('claude')) {\n finalTokenCount = Math.round(finalTokenCount * 1.15)\n }\n else if (anthropicPayload.model.startsWith('grok')) {\n finalTokenCount = Math.round(finalTokenCount * 1.03)\n }\n\n consola.info('Token count:', finalTokenCount)\n\n return c.json({\n input_tokens: finalTokenCount,\n })\n}\n","import type { Context } from 'hono'\n\nimport type { ChatCompletionChunk, ChatCompletionResponse } from '~/types'\nimport consola from 'consola'\n\nimport { streamSSE } from 'hono/streaming'\n\nimport { CopilotClient } from '~/clients'\nimport { getClientConfig } from '~/lib/client-config'\nimport { setModelMappingInfo } from '~/lib/request-logger'\nimport { state } from '~/lib/state'\nimport { parseAnthropicMessagesPayload } from '~/lib/validation'\nimport { AnthropicTranslator } from '~/translator'\n\nexport async function handleCompletion(c: Context) {\n const anthropicPayload = parseAnthropicMessagesPayload(await c.req.json())\n consola.debug('Anthropic request payload:', JSON.stringify(anthropicPayload))\n\n const translator = new AnthropicTranslator()\n const openAIPayload = translator.toOpenAI(anthropicPayload)\n setModelMappingInfo(c, {\n originalModel: anthropicPayload.model,\n mappedModel: openAIPayload.model,\n })\n consola.debug(\n 'Claude Code requested model:',\n anthropicPayload.model,\n '-> Copilot model:',\n openAIPayload.model,\n )\n consola.debug(\n 'Translated OpenAI request payload:',\n JSON.stringify(openAIPayload),\n )\n\n const copilotClient = new CopilotClient(state.auth, getClientConfig(state))\n const response = await copilotClient.createChatCompletions(openAIPayload, {\n signal: c.req.raw.signal,\n })\n\n if (isNonStreaming(response)) {\n consola.debug(\n 'Non-streaming response from Copilot:',\n JSON.stringify(response).slice(-400),\n )\n const anthropicResponse = translator.fromOpenAI(response)\n consola.debug(\n 'Translated Anthropic response:',\n JSON.stringify(anthropicResponse),\n )\n return c.json(anthropicResponse)\n }\n\n consola.debug('Streaming response from Copilot')\n return streamSSE(c, async (stream) => {\n const streamTranslator = translator.createStreamTranslator()\n\n try {\n for await (const rawEvent of response) {\n consola.debug('Copilot raw stream event:', JSON.stringify(rawEvent))\n if (rawEvent.data === '[DONE]') {\n break\n }\n\n if (!rawEvent.data) {\n continue\n }\n\n const chunk = JSON.parse(rawEvent.data) as ChatCompletionChunk\n const events = streamTranslator.onChunk(chunk)\n\n for (const event of events) {\n consola.debug('Translated Anthropic event:', JSON.stringify(event))\n await stream.writeSSE({\n event: event.type,\n data: JSON.stringify(event),\n })\n }\n }\n }\n catch (error) {\n if (c.req.raw.signal.aborted) {\n consola.debug('Client disconnected during Anthropic stream')\n return\n }\n\n consola.error('Error streaming Anthropic response:', error)\n const errorEvents = streamTranslator.onError(error)\n for (const event of errorEvents) {\n await stream.writeSSE({\n event: event.type,\n data: JSON.stringify(event),\n })\n }\n }\n })\n}\n\nfunction isNonStreaming(response: Awaited<ReturnType<CopilotClient['createChatCompletions']>>): response is ChatCompletionResponse {\n return Object.hasOwn(response, 'choices')\n}\n","import { Hono } from 'hono'\n\nimport { requestGuard } from '~/routes/middleware/request-guard'\n\nimport { handleCountTokens } from './count-tokens-handler'\nimport { handleCompletion } from './handler'\n\nexport const messageRoutes = new Hono()\n\nmessageRoutes.post('/', requestGuard, c => handleCompletion(c))\n\nmessageRoutes.post('/count_tokens', c => handleCountTokens(c))\n","import { Hono } from 'hono'\n\nimport { CopilotClient } from '~/clients'\nimport { getClientConfig } from '~/lib/client-config'\nimport { state } from '~/lib/state'\nimport { cacheModels } from '~/lib/utils'\n\nexport const modelRoutes = new Hono()\n\nmodelRoutes.get('/', async (c) => {\n if (!state.cache.models) {\n // This should be handled by startup logic, but as a fallback.\n const copilotClient = new CopilotClient(state.auth, getClientConfig(state))\n await cacheModels(copilotClient)\n }\n\n const models = state.cache.models?.data.map(model => ({\n id: model.id,\n object: 'model',\n type: 'model',\n created: 0, // No date available from source\n created_at: new Date(0).toISOString(), // No date available from source\n owned_by: model.vendor,\n display_name: model.name,\n }))\n\n return c.json({\n object: 'list',\n data: models,\n has_more: false,\n })\n})\n","import { Hono } from 'hono'\n\nimport { state } from '~/lib/state'\n\nexport const tokenRoute = new Hono()\n\ntokenRoute.get('/', (c) => {\n return c.json({\n token: state.auth.copilotToken,\n })\n})\n","import { Hono } from 'hono'\n\nimport { GitHubClient } from '~/clients'\nimport { getClientConfig } from '~/lib/client-config'\nimport { state } from '~/lib/state'\n\nexport const usageRoute = new Hono()\n\nusageRoute.get('/', async (c) => {\n const githubClient = new GitHubClient(state.auth, getClientConfig(state))\n const usage = await githubClient.getCopilotUsage()\n return c.json(usage)\n})\n","import { Hono } from 'hono'\nimport { cors } from 'hono/cors'\n\nimport { forwardError } from './lib/error'\nimport { requestLogger } from './lib/request-logger'\nimport { completionRoutes } from './routes/chat-completions/route'\nimport { embeddingRoutes } from './routes/embeddings/route'\nimport { messageRoutes } from './routes/messages/route'\nimport { modelRoutes } from './routes/models/route'\nimport { tokenRoute } from './routes/token/route'\nimport { usageRoute } from './routes/usage/route'\n\nexport const server = new Hono()\n\nserver.use(requestLogger)\nserver.use(cors())\nserver.onError((error, c) => forwardError(c, error))\n\nserver.get('/', c => c.text('Server running'))\n\nserver.route('/chat/completions', completionRoutes)\nserver.route('/models', modelRoutes)\nserver.route('/embeddings', embeddingRoutes)\nserver.route('/usage', usageRoute)\nserver.route('/token', tokenRoute)\n\n// Compatibility with tools that expect v1/ prefix\nserver.route('/v1/chat/completions', completionRoutes)\nserver.route('/v1/models', modelRoutes)\nserver.route('/v1/embeddings', embeddingRoutes)\n\n// Anthropic compatible endpoints\nserver.route('/v1/messages', messageRoutes)\n","#!/usr/bin/env node\n\nimport type { ServerHandler } from 'srvx'\nimport { defineCommand } from 'citty'\nimport clipboard from 'clipboardy'\nimport consola from 'consola'\nimport { serve } from 'srvx'\nimport invariant from 'tiny-invariant'\n\nimport { CopilotClient } from '~/clients'\n\nimport { getClientConfig } from './lib/client-config'\nimport { readConfig } from './lib/config'\nimport { ensurePaths } from './lib/paths'\nimport { initProxyFromEnv } from './lib/proxy'\nimport { generateEnvScript } from './lib/shell'\nimport { state } from './lib/state'\nimport { setupCopilotToken, setupGitHubToken } from './lib/token'\nimport { cacheModels, cacheVSCodeVersion } from './lib/utils'\nimport { server } from './server'\n\ninterface RunServerOptions {\n port: number\n verbose: boolean\n accountType: string\n manual: boolean\n rateLimit?: number\n rateLimitWait: boolean\n githubToken?: string\n claudeCode: boolean\n showToken: boolean\n proxyEnv: boolean\n idleTimeoutSeconds?: number\n}\n\nasync function maybeCopyClaudeCodeCommand(serverUrl: string): Promise<void> {\n if (!state.cache.models) {\n return\n }\n\n const selectableModels = state.cache.models.data.filter(\n model => model.model_picker_enabled,\n )\n const modelOptions\n = selectableModels.length > 0 ? selectableModels : state.cache.models.data\n\n const selectedModel = await consola.prompt(\n 'Select a model to use with Claude Code',\n {\n type: 'select',\n options: modelOptions.map(model => model.id),\n },\n )\n\n const selectedSmallModel = await consola.prompt(\n 'Select a small model to use with Claude Code',\n {\n type: 'select',\n options: modelOptions.map(model => model.id),\n },\n )\n\n const command = generateEnvScript(\n {\n ANTHROPIC_BASE_URL: serverUrl,\n ANTHROPIC_AUTH_TOKEN: 'dummy',\n ANTHROPIC_MODEL: selectedModel,\n ANTHROPIC_DEFAULT_SONNET_MODEL: selectedModel,\n ANTHROPIC_SMALL_FAST_MODEL: selectedSmallModel,\n ANTHROPIC_DEFAULT_HAIKU_MODEL: selectedSmallModel,\n DISABLE_NON_ESSENTIAL_MODEL_CALLS: '1',\n CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1',\n },\n 'claude',\n )\n\n try {\n clipboard.writeSync(command)\n consola.success('Copied Claude Code command to clipboard!')\n }\n catch {\n consola.warn(\n 'Failed to copy to clipboard. Here is the Claude Code command:',\n )\n consola.log(command)\n }\n}\n\nexport async function runServer(options: RunServerOptions): Promise<void> {\n const accountType: ReturnType<typeof getClientConfig>['accountType']\n = (\n options.accountType === 'individual'\n || options.accountType === 'business'\n || options.accountType === 'enterprise'\n )\n ? options.accountType\n : 'individual'\n\n if (accountType !== options.accountType) {\n consola.warn(\n `Unknown account type \"${options.accountType}\". Falling back to \"individual\".`,\n )\n }\n\n if (options.proxyEnv) {\n initProxyFromEnv()\n }\n\n if (options.verbose) {\n consola.level = 5\n consola.info('Verbose logging enabled')\n }\n\n state.config.accountType = accountType\n if (accountType !== 'individual') {\n consola.info(`Using ${accountType} plan GitHub account`)\n }\n\n if (options.githubToken) {\n state.auth.githubToken = options.githubToken\n consola.info('Using provided GitHub token')\n }\n\n state.config.manualApprove = options.manual\n state.config.rateLimitSeconds = options.rateLimit\n state.config.rateLimitWait = options.rateLimitWait\n state.config.showToken = options.showToken\n\n await ensurePaths()\n await readConfig()\n await cacheVSCodeVersion()\n\n if (!options.githubToken) {\n await setupGitHubToken()\n }\n\n await setupCopilotToken()\n\n const clientConfig: ReturnType<typeof getClientConfig> = {\n ...getClientConfig(state),\n accountType,\n }\n const copilotClient = new CopilotClient(state.auth, clientConfig)\n await cacheModels(copilotClient)\n\n consola.info(\n `Available models: \\n${state.cache.models?.data.map(model => `- ${model.id}`).join('\\n')}`,\n )\n\n const serverUrl = `http://localhost:${options.port}`\n\n if (options.claudeCode) {\n invariant(state.cache.models, 'Models should be loaded by now')\n await maybeCopyClaudeCodeCommand(serverUrl)\n }\n\n serve({\n fetch: server.fetch as ServerHandler,\n port: options.port,\n bun:\n options.idleTimeoutSeconds === undefined\n ? undefined\n : { idleTimeout: options.idleTimeoutSeconds },\n })\n}\n\nexport const start = defineCommand({\n meta: {\n name: 'start',\n description: 'Start the Copilot API server',\n },\n args: {\n 'port': {\n alias: 'p',\n type: 'string',\n default: '4141',\n description: 'Port to listen on',\n },\n 'verbose': {\n alias: 'v',\n type: 'boolean',\n default: false,\n description: 'Enable verbose logging',\n },\n 'account-type': {\n alias: 'a',\n type: 'string',\n default: 'individual',\n description: 'Account type to use (individual, business, enterprise)',\n },\n 'manual': {\n type: 'boolean',\n default: false,\n description: 'Enable manual request approval',\n },\n 'rate-limit': {\n alias: 'r',\n type: 'string',\n description: 'Rate limit in seconds between requests',\n },\n 'wait': {\n alias: 'w',\n type: 'boolean',\n default: false,\n description:\n 'Wait instead of error when rate limit is hit. Has no effect if rate limit is not set',\n },\n 'github-token': {\n alias: 'g',\n type: 'string',\n description:\n 'Provide GitHub token directly (must be generated using the `auth` subcommand)',\n },\n 'claude-code': {\n alias: 'c',\n type: 'boolean',\n default: false,\n description:\n 'Generate a command to launch Claude Code with Copilot API config',\n },\n 'show-token': {\n type: 'boolean',\n default: false,\n description: 'Show GitHub and Copilot tokens on fetch and refresh',\n },\n 'proxy-env': {\n type: 'boolean',\n default: false,\n description: 'Initialize proxy from environment variables',\n },\n 'idle-timeout': {\n type: 'string',\n default: '120',\n description: 'Bun server idle timeout in seconds',\n },\n },\n run({ args }) {\n const rateLimitRaw = args['rate-limit']\n const rateLimit\n = rateLimitRaw === undefined ? undefined : Number.parseInt(rateLimitRaw, 10)\n const idleTimeoutRaw = args['idle-timeout']\n let idleTimeoutSeconds\n = idleTimeoutRaw === undefined\n ? undefined\n : (\n Number.parseInt(idleTimeoutRaw, 10)\n )\n if (\n idleTimeoutSeconds !== undefined\n && (Number.isNaN(idleTimeoutSeconds) || idleTimeoutSeconds < 0)\n ) {\n consola.warn(\n `Invalid --idle-timeout value \"${idleTimeoutRaw}\". Falling back to Bun default.`,\n )\n idleTimeoutSeconds = undefined\n }\n\n return runServer({\n port: Number.parseInt(args.port, 10),\n verbose: args.verbose,\n accountType: args['account-type'],\n manual: args.manual,\n rateLimit,\n rateLimitWait: args.wait,\n githubToken: args['github-token'],\n claudeCode: args['claude-code'],\n showToken: args['show-token'],\n proxyEnv: args['proxy-env'],\n idleTimeoutSeconds,\n })\n },\n})\n","#!/usr/bin/env node\n\nimport process from 'node:process'\nimport { defineCommand, runMain } from 'citty'\nimport consola from 'consola'\n\nimport { auth } from './auth'\nimport { checkUsage } from './check-usage'\nimport { debug } from './debug'\nimport { start } from './start'\n\nconst main = defineCommand({\n meta: {\n name: 'ghc-proxy',\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})\n\nrunMain(main).catch((error) => {\n consola.error('Failed to start CLI:', error)\n process.exitCode = 1\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"main.js","names":["cachedConfig: ConfigFile","error: unknown","existing: ConfigFile","state: AppState","headers: Record<string, string>","auth","errorJson: unknown","auth","headers: Record<string, string>","auth","token","commandBlock: string","start","methodColors: Record<string, Parameters<typeof colorize>[0]>","requestLogger: MiddlewareHandler","path","state","requestGuard: MiddlewareHandler","abortListener: (() => void) | undefined","handleCompletion","isNonStreaming","handleCompletion","events: Array<AnthropicStreamEventData>","events","DEFAULT_FALLBACKS: ModelFallbackConfig","cachedConfig","allTextBlocks: Array<AnthropicTextBlock>","allToolUseBlocks: Array<AnthropicToolUseBlock>","stopReason: 'stop' | 'length' | 'tool_calls' | 'content_filter' | null","newMessages: Array<Message>","contentParts: Array<ContentPart>","events","accountType: ReturnType<typeof getClientConfig>['accountType']","clientConfig: ReturnType<typeof getClientConfig>"],"sources":["../src/lib/paths.ts","../src/lib/config.ts","../src/lib/state.ts","../src/lib/api-config.ts","../src/lib/error.ts","../src/clients/copilot-client.ts","../src/lib/client-config.ts","../src/lib/utils.ts","../src/clients/github-client.ts","../src/clients/vscode-client.ts","../src/lib/token.ts","../src/auth.ts","../src/check-usage.ts","../src/debug.ts","../src/lib/proxy.ts","../src/lib/shell.ts","../src/lib/request-logger.ts","../src/lib/approval.ts","../src/lib/rate-limit.ts","../src/routes/middleware/request-guard.ts","../src/lib/tokenizer.ts","../src/lib/upstream-signal.ts","../src/lib/validation.ts","../src/routes/chat-completions/handler.ts","../src/routes/chat-completions/route.ts","../src/routes/embeddings/route.ts","../src/translator/anthropic/shared.ts","../src/translator/anthropic/anthropic-stream-translator.ts","../src/lib/model-resolver.ts","../src/translator/anthropic/anthropic-translator.ts","../src/routes/messages/count-tokens-handler.ts","../src/routes/messages/handler.ts","../src/routes/messages/route.ts","../src/routes/models/route.ts","../src/routes/token/route.ts","../src/routes/usage/route.ts","../src/server.ts","../src/start.ts","../src/main.ts"],"sourcesContent":["import fs from 'node:fs/promises'\nimport os from 'node:os'\nimport path from 'node:path'\n\nconst APP_DIR = path.join(os.homedir(), '.local', 'share', 'ghc-proxy')\n\nconst CONFIG_PATH = path.join(APP_DIR, 'config.json')\n\nexport const PATHS = {\n APP_DIR,\n CONFIG_PATH,\n}\n\nexport async function ensurePaths(): Promise<void> {\n await fs.mkdir(PATHS.APP_DIR, { recursive: true })\n}\n","import fs from 'node:fs/promises'\nimport consola from 'consola'\n\nimport { PATHS } from './paths'\n\ninterface ModelFallbackFileConfig {\n claudeOpus?: string\n claudeSonnet?: string\n claudeHaiku?: string\n}\n\nexport interface ConfigFile {\n githubToken?: string\n modelFallback?: ModelFallbackFileConfig\n}\n\nlet cachedConfig: ConfigFile = {}\n\nexport async function readConfig(): Promise<ConfigFile> {\n try {\n const content = await fs.readFile(PATHS.CONFIG_PATH, 'utf8')\n\n if (!content.trim()) {\n cachedConfig = {}\n return {}\n }\n\n const parsed = JSON.parse(content) as unknown\n\n if (\n typeof parsed !== 'object'\n || parsed === null\n || Array.isArray(parsed)\n ) {\n consola.warn('config.json is not a valid object. Using defaults.')\n cachedConfig = {}\n return {}\n }\n\n cachedConfig = parsed as ConfigFile\n return cachedConfig\n }\n catch (error: unknown) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n cachedConfig = {}\n return {}\n }\n\n consola.warn(\n `Failed to parse config.json: ${(error as Error).message}. Using defaults.`,\n )\n cachedConfig = {}\n return {}\n }\n}\n\nexport function getCachedConfig(): ConfigFile {\n return cachedConfig\n}\n\nexport async function writeConfigField(\n field: string,\n value: unknown,\n): Promise<void> {\n try {\n let existing: ConfigFile = {}\n try {\n const content = await fs.readFile(PATHS.CONFIG_PATH, 'utf8')\n if (content.trim()) {\n existing = JSON.parse(content) as ConfigFile\n }\n }\n catch (error: unknown) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n consola.warn(\n `Could not read existing config.json: ${\n (error as Error).message\n }. Starting fresh.`,\n )\n }\n }\n\n const merged = { ...existing, [field]: value }\n\n await fs.writeFile(\n PATHS.CONFIG_PATH,\n JSON.stringify(merged, null, 2),\n 'utf8',\n )\n await fs.chmod(PATHS.CONFIG_PATH, 0o600)\n\n cachedConfig = merged\n }\n catch (error: unknown) {\n consola.error(`Failed to write config.json: ${(error as Error).message}`)\n throw error\n }\n}\n","import type { ModelsResponse } from '~/types'\n\nexport interface AuthState {\n githubToken?: string\n copilotToken?: string\n}\n\nexport interface RuntimeConfig {\n accountType: 'individual' | 'business' | 'enterprise'\n manualApprove: boolean\n rateLimitSeconds?: number\n rateLimitWait: boolean\n showToken: boolean\n upstreamTimeoutSeconds?: number\n}\n\nexport interface CacheState {\n models?: ModelsResponse\n vsCodeVersion?: string\n}\n\nexport interface RateLimitState {\n lastRequestTimestamp?: number\n}\n\nexport interface AppState {\n auth: AuthState\n config: RuntimeConfig\n cache: CacheState\n rateLimit: RateLimitState\n}\n\nexport const state: AppState = {\n auth: {},\n config: {\n accountType: 'individual',\n manualApprove: false,\n rateLimitWait: false,\n showToken: false,\n },\n cache: {},\n rateLimit: {},\n}\n","import type { ClientAuth, ClientConfig } from '~/clients'\n\nimport { randomUUID } from 'node:crypto'\n\nexport function standardHeaders() {\n return {\n 'content-type': 'application/json',\n 'accept': 'application/json',\n }\n}\n\nconst COPILOT_VERSION = '0.26.7'\nconst EDITOR_PLUGIN_VERSION = `copilot-chat/${COPILOT_VERSION}`\nconst USER_AGENT = `GitHubCopilotChat/${COPILOT_VERSION}`\n\nconst API_VERSION = '2025-04-01'\n\nexport function copilotBaseUrl(config: ClientConfig) {\n return config.accountType === 'individual'\n ? 'https://api.githubcopilot.com'\n : `https://api.${config.accountType}.githubcopilot.com`\n}\nexport function copilotHeaders(auth: ClientAuth, config: ClientConfig, vision: boolean = false) {\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${auth.copilotToken}`,\n 'content-type': standardHeaders()['content-type'],\n 'copilot-integration-id': 'vscode-chat',\n 'editor-version': `vscode/${config.vsCodeVersion ?? 'unknown'}`,\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)\n headers['copilot-vision-request'] = 'true'\n\n return headers\n}\n\nexport const GITHUB_API_BASE_URL = 'https://api.github.com'\nexport function githubHeaders(auth: ClientAuth, config: ClientConfig) {\n return {\n ...standardHeaders(),\n 'authorization': `token ${auth.githubToken}`,\n 'editor-version': `vscode/${config.vsCodeVersion ?? 'unknown'}`,\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}\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 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 consola.error('Error occurred:', error)\n\n if (error instanceof HTTPError) {\n const errorText = await error.response.text()\n let errorJson: unknown\n try {\n errorJson = JSON.parse(errorText)\n }\n catch {\n errorJson = errorText\n }\n consola.error('HTTP error:', errorJson)\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 if (error instanceof DOMException && error.name === 'AbortError') {\n return c.json({ error: { message: 'Upstream request was aborted', type: 'timeout_error' } }, 504)\n }\n\n if (error instanceof Error && error.name === 'AbortError') {\n return c.json({ error: { message: 'Upstream request was aborted', type: 'timeout_error' } }, 504)\n }\n\n return c.json(\n {\n error: {\n message: (error as Error).message,\n type: 'error',\n },\n },\n 500,\n )\n}\n","import type { ClientAuth, ClientConfig, ClientDeps } from './types'\nimport type {\n ChatCompletionResponse,\n ChatCompletionsPayload,\n EmbeddingRequest,\n EmbeddingResponse,\n ModelsResponse,\n} from '~/types'\n\nimport consola from 'consola'\n\nimport { events } from 'fetch-event-stream'\nimport { copilotBaseUrl, copilotHeaders } from '~/lib/api-config'\n\nimport { HTTPError } from '~/lib/error'\n\nexport class CopilotClient {\n private auth: ClientAuth\n private config: ClientConfig\n private fetchImpl: typeof fetch\n\n constructor(auth: ClientAuth, config: ClientConfig, deps?: ClientDeps) {\n this.auth = auth\n this.config = config\n this.fetchImpl = deps?.fetch ?? fetch\n }\n\n async createChatCompletions(\n payload: ChatCompletionsPayload,\n options?: { signal?: AbortSignal },\n ) {\n if (!this.auth.copilotToken)\n throw new Error('Copilot token not found')\n\n const enableVision = payload.messages.some(\n x =>\n typeof x.content !== 'string'\n && x.content?.some(content => content.type === 'image_url'),\n )\n\n // Agent/user check for X-Initiator header\n const isAgentCall = payload.messages.some(msg =>\n ['assistant', 'tool'].includes(msg.role),\n )\n\n const headers: Record<string, string> = {\n ...copilotHeaders(this.auth, this.config, enableVision),\n 'X-Initiator': isAgentCall ? 'agent' : 'user',\n }\n\n const response = await this.fetchImpl(\n `${copilotBaseUrl(this.config)}/chat/completions`,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(payload),\n signal: options?.signal,\n },\n )\n\n if (!response.ok) {\n consola.error('Failed to create chat completions', response)\n throw new HTTPError('Failed to create chat completions', response)\n }\n\n if (payload.stream) {\n return events(response)\n }\n\n return (await response.json()) as ChatCompletionResponse\n }\n\n async createEmbeddings(\n payload: EmbeddingRequest,\n ): Promise<EmbeddingResponse> {\n if (!this.auth.copilotToken)\n throw new Error('Copilot token not found')\n\n const response = await this.fetchImpl(\n `${copilotBaseUrl(this.config)}/embeddings`,\n {\n method: 'POST',\n headers: copilotHeaders(this.auth, this.config),\n body: JSON.stringify(payload),\n },\n )\n\n if (!response.ok) {\n throw new HTTPError('Failed to create embeddings', response)\n }\n\n return (await response.json()) as EmbeddingResponse\n }\n\n async getModels(): Promise<ModelsResponse> {\n const response = await this.fetchImpl(\n `${copilotBaseUrl(this.config)}/models`,\n {\n headers: copilotHeaders(this.auth, this.config),\n },\n )\n\n if (!response.ok)\n throw new HTTPError('Failed to get models', response)\n\n return (await response.json()) as ModelsResponse\n }\n}\n","import type { AppState } from './state'\n\nimport type { ClientConfig } from '~/clients'\n\nexport function getClientConfig(appState: AppState): ClientConfig {\n return {\n accountType: appState.config.accountType,\n vsCodeVersion: appState.cache.vsCodeVersion,\n }\n}\n","import consola from 'consola'\n\nimport { CopilotClient, getVSCodeVersion } from '~/clients'\n\nimport { getClientConfig } from './client-config'\nimport { state } from './state'\n\nexport function sleep(ms: number) {\n return new Promise((resolve) => {\n setTimeout(resolve, ms)\n })\n}\n\nexport function isNullish(value: unknown): value is null | undefined {\n return value === null || value === undefined\n}\n\nexport async function cacheModels(client?: CopilotClient): Promise<void> {\n const copilotClient\n = client ?? new CopilotClient(state.auth, getClientConfig(state))\n\n const models = await copilotClient.getModels()\n\n state.cache.models = models\n}\n\nexport async function cacheVSCodeVersion() {\n const response = await getVSCodeVersion()\n state.cache.vsCodeVersion = response\n\n consola.info(`Using VSCode version: ${response}`)\n}\n","import type { ClientAuth, ClientConfig, ClientDeps } from './types'\n\nimport type {\n CopilotUsageResponse,\n DeviceCodeResponse,\n GetCopilotTokenResponse,\n GithubUserResponse,\n} from '~/types'\n\nimport consola from 'consola'\nimport {\n GITHUB_API_BASE_URL,\n GITHUB_APP_SCOPES,\n GITHUB_BASE_URL,\n GITHUB_CLIENT_ID,\n githubHeaders,\n standardHeaders,\n} from '~/lib/api-config'\nimport { HTTPError } from '~/lib/error'\n\nimport { sleep } from '~/lib/utils'\n\nexport class GitHubClient {\n private auth: ClientAuth\n private config: ClientConfig\n private fetchImpl: typeof fetch\n\n constructor(auth: ClientAuth, config: ClientConfig, deps?: ClientDeps) {\n this.auth = auth\n this.config = config\n this.fetchImpl = deps?.fetch ?? fetch\n }\n\n async getCopilotUsage(): Promise<CopilotUsageResponse> {\n const response = await this.fetchImpl(\n `${GITHUB_API_BASE_URL}/copilot_internal/user`,\n {\n headers: githubHeaders(this.auth, this.config),\n },\n )\n\n if (!response.ok) {\n throw new HTTPError('Failed to get Copilot usage', response)\n }\n\n return (await response.json()) as CopilotUsageResponse\n }\n\n async getCopilotToken(): Promise<GetCopilotTokenResponse> {\n const response = await this.fetchImpl(\n `${GITHUB_API_BASE_URL}/copilot_internal/v2/token`,\n {\n headers: githubHeaders(this.auth, this.config),\n },\n )\n\n if (!response.ok) {\n throw new HTTPError('Failed to get Copilot token', response)\n }\n\n return (await response.json()) as GetCopilotTokenResponse\n }\n\n async getDeviceCode(): Promise<DeviceCodeResponse> {\n const response = await this.fetchImpl(\n `${GITHUB_BASE_URL}/login/device/code`,\n {\n method: 'POST',\n headers: standardHeaders(),\n body: JSON.stringify({\n client_id: GITHUB_CLIENT_ID,\n scope: GITHUB_APP_SCOPES,\n }),\n },\n )\n\n if (!response.ok) {\n throw new HTTPError('Failed to get device code', response)\n }\n\n return (await response.json()) as DeviceCodeResponse\n }\n\n async pollAccessToken(deviceCode: DeviceCodeResponse): Promise<string> {\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 this.fetchImpl(\n `${GITHUB_BASE_URL}/login/oauth/access_token`,\n {\n method: 'POST',\n headers: standardHeaders(),\n body: JSON.stringify({\n client_id: GITHUB_CLIENT_ID,\n device_code: deviceCode.device_code,\n grant_type: 'urn:ietf:params:oauth:grant-type:device_code',\n }),\n },\n )\n\n if (!response.ok) {\n await sleep(sleepDuration)\n consola.error('Failed to poll access token:', await response.text())\n continue\n }\n\n const json = (await response.json()) as AccessTokenResponse\n consola.debug('Polling access token response:', json)\n\n if (json.access_token) {\n return json.access_token\n }\n\n await sleep(sleepDuration)\n }\n }\n\n async getGitHubUser(): Promise<GithubUserResponse> {\n const response = await this.fetchImpl(`${GITHUB_API_BASE_URL}/user`, {\n headers: {\n authorization: `token ${this.auth.githubToken}`,\n ...standardHeaders(),\n },\n })\n\n if (!response.ok) {\n throw new HTTPError('Failed to get GitHub user', response)\n }\n\n return (await response.json()) as GithubUserResponse\n }\n}\n\ninterface AccessTokenResponse {\n access_token: string\n token_type: string\n scope: string\n}\n","const FALLBACK = '1.104.3'\n\nexport async function getVSCodeVersion() {\n const controller = new AbortController()\n const timeout = setTimeout(() => {\n controller.abort()\n }, 5000)\n\n try {\n const response = await fetch(\n 'https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h=visual-studio-code-bin',\n {\n signal: controller.signal,\n },\n )\n\n const pkgbuild = await response.text()\n const pkgverRegex = /pkgver=([0-9.]+)/\n const match = pkgbuild.match(pkgverRegex)\n\n if (match) {\n return match[1]\n }\n\n return FALLBACK\n }\n catch {\n return FALLBACK\n }\n finally {\n clearTimeout(timeout)\n }\n}\n","import consola from 'consola'\n\nimport { GitHubClient } from '~/clients'\n\nimport { getClientConfig } from './client-config'\nimport { getCachedConfig, writeConfigField } from './config'\nimport { HTTPError } from './error'\nimport { state } from './state'\nimport { cacheVSCodeVersion } from './utils'\n\nasync function writeGithubToken(token: string): Promise<void> {\n await writeConfigField('githubToken', token)\n}\n\nexport async function setupCopilotToken() {\n await ensureVSCodeVersion()\n const githubClient = createGitHubClient()\n const { token, refresh_in } = await githubClient.getCopilotToken()\n state.auth.copilotToken = token\n\n // Display the Copilot token to the screen\n consola.debug('GitHub Copilot Token fetched successfully!')\n if (state.config.showToken) {\n consola.info('Copilot token:', token)\n }\n\n const refreshInterval = (refresh_in - 60) * 1000\n const refreshCopilotToken = async () => {\n consola.debug('Refreshing Copilot token')\n try {\n const { token } = await githubClient.getCopilotToken()\n state.auth.copilotToken = token\n consola.debug('Copilot token refreshed')\n if (state.config.showToken) {\n consola.info('Refreshed Copilot token:', token)\n }\n }\n catch (error) {\n consola.error('Failed to refresh Copilot token:', error)\n }\n }\n\n setInterval(() => {\n void refreshCopilotToken()\n }, refreshInterval)\n}\n\ninterface SetupGitHubTokenOptions {\n force?: boolean\n}\n\nexport async function setupGitHubToken(\n options?: SetupGitHubTokenOptions,\n): Promise<void> {\n try {\n await ensureVSCodeVersion()\n\n const cachedToken = getCachedConfig().githubToken\n const githubToken = cachedToken?.trim() || ''\n\n if (githubToken && !options?.force) {\n state.auth.githubToken = githubToken\n if (state.config.showToken) {\n consola.info('GitHub token:', githubToken)\n }\n try {\n await logUser()\n return\n }\n catch (error) {\n if (isAuthError(error) && !options?.force) {\n consola.warn(\n 'Stored GitHub token invalid or expired. Re-authenticating...',\n )\n await setupGitHubToken({ force: true })\n return\n }\n throw error\n }\n }\n\n consola.info('Not logged in, getting new access token')\n const githubClient = createGitHubClient()\n const response = await githubClient.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 githubClient.pollAccessToken(response)\n await writeGithubToken(token)\n state.auth.githubToken = token\n\n if (state.config.showToken) {\n consola.info('GitHub token:', token)\n }\n await logUser()\n }\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\nfunction isAuthError(error: unknown) {\n return error instanceof HTTPError\n && (error.response.status === 401 || error.response.status === 403)\n}\n\nasync function logUser() {\n const githubClient = createGitHubClient()\n const user = await githubClient.getGitHubUser()\n consola.info(`Logged in as ${user.login}`)\n}\n\nfunction createGitHubClient() {\n return new GitHubClient(state.auth, getClientConfig(state))\n}\n\nasync function ensureVSCodeVersion() {\n if (!state.cache.vsCodeVersion) {\n await cacheVSCodeVersion()\n }\n}\n","#!/usr/bin/env node\n\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\n\nimport { readConfig } from './lib/config'\nimport { ensurePaths } from './lib/paths'\nimport { state } from './lib/state'\nimport { setupGitHubToken } from './lib/token'\nimport { cacheVSCodeVersion } from './lib/utils'\n\ninterface RunAuthOptions {\n verbose: boolean\n showToken: boolean\n}\n\nexport async function runAuth(options: RunAuthOptions): Promise<void> {\n if (options.verbose) {\n consola.level = 5\n consola.info('Verbose logging enabled')\n }\n\n state.config.showToken = options.showToken\n\n await ensurePaths()\n await readConfig()\n await cacheVSCodeVersion()\n await setupGitHubToken({ force: true })\n consola.success('GitHub token written to config.json')\n}\n\nexport const auth = defineCommand({\n meta: {\n name: 'auth',\n description: 'Run GitHub auth flow without running the server',\n },\n args: {\n 'verbose': {\n alias: 'v',\n type: 'boolean',\n default: false,\n description: 'Enable verbose logging',\n },\n 'show-token': {\n type: 'boolean',\n default: false,\n description: 'Show GitHub token on auth',\n },\n },\n run({ args }) {\n return runAuth({\n verbose: args.verbose,\n showToken: args['show-token'],\n })\n },\n})\n","import type { QuotaDetail } from '~/types'\nimport process from 'node:process'\nimport { defineCommand } from 'citty'\n\nimport consola from 'consola'\n\nimport { GitHubClient } from '~/clients'\n\nimport { getClientConfig } from './lib/client-config'\nimport { readConfig } from './lib/config'\nimport { ensurePaths } from './lib/paths'\nimport { state } from './lib/state'\nimport { setupGitHubToken } from './lib/token'\nimport { cacheVSCodeVersion } from './lib/utils'\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 readConfig()\n await cacheVSCodeVersion()\n await setupGitHubToken()\n try {\n const githubClient = new GitHubClient(state.auth, getClientConfig(state))\n const usage = await githubClient.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)\n 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 }\n catch (err) {\n consola.error('Failed to fetch Copilot usage:', err)\n process.exit(1)\n }\n },\n})\n","#!/usr/bin/env node\n\nimport fs from 'node:fs/promises'\nimport os from 'node:os'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\n\nimport { getCachedConfig } from './lib/config'\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 CONFIG_PATH: string\n }\n configExists: boolean\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 }\n catch {\n return 'unknown'\n }\n}\n\nfunction getRuntimeInfo() {\n return {\n name: 'bun',\n version: Bun.version,\n platform: os.platform(),\n arch: os.arch(),\n }\n}\n\nfunction hasToken(): boolean {\n try {\n const config = getCachedConfig()\n return Boolean(config.githubToken?.trim())\n }\n catch {\n return false\n }\n}\n\nasync function checkConfigExists(): Promise<boolean> {\n try {\n const stats = await fs.stat(PATHS.CONFIG_PATH)\n if (!stats.isFile())\n return false\n\n const content = await fs.readFile(PATHS.CONFIG_PATH, 'utf8')\n return content.trim().length > 0\n }\n catch {\n return false\n }\n}\n\nasync function getDebugInfo(): Promise<DebugInfo> {\n const [version, configExists] = await Promise.all([\n getPackageVersion(),\n checkConfigExists(),\n ])\n\n return {\n version,\n runtime: getRuntimeInfo(),\n paths: {\n APP_DIR: PATHS.APP_DIR,\n CONFIG_PATH: PATHS.CONFIG_PATH,\n },\n configExists,\n tokenExists: hasToken(),\n }\n}\n\nfunction printDebugInfoPlain(info: DebugInfo): void {\n consola.info(`ghc-proxy 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- CONFIG_PATH: ${info.paths.CONFIG_PATH}\n\nConfig exists: ${info.configExists ? 'Yes' : 'No'}\nToken exists: ${info.tokenExists ? 'Yes' : 'No'}`)\n}\n\nexport async function runDebug(options: RunDebugOptions): Promise<void> {\n const debugInfo = await getDebugInfo()\n\n if (options.json) {\n await Bun.write(Bun.stdout, `${JSON.stringify(debugInfo, null, 2)}\\n`)\n }\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","import type { Dispatcher } from 'undici'\nimport consola from 'consola'\nimport { getProxyForUrl } from 'proxy-from-env'\nimport { Agent, ProxyAgent, setGlobalDispatcher } from 'undici'\n\nexport function initProxyFromEnv(): void {\n if (typeof Bun !== 'undefined')\n return\n\n try {\n const direct = new Agent()\n const proxies = new Map<string, ProxyAgent>()\n\n // We only need a minimal dispatcher that implements `dispatch` at runtime.\n // Typing the object as `Dispatcher` forces TypeScript to require many\n // additional methods. Instead, keep a plain object and cast when passing\n // to `setGlobalDispatcher`.\n const dispatcher = {\n dispatch(\n options: Dispatcher.DispatchOptions,\n handler: Dispatcher.DispatchHandler,\n ) {\n try {\n const origin\n = typeof options.origin === 'string'\n ? new URL(options.origin)\n : (options.origin as URL)\n const get = getProxyForUrl as unknown as (\n u: string,\n ) => string | undefined\n const raw = get(origin.toString())\n const proxyUrl = raw && raw.length > 0 ? raw : undefined\n if (!proxyUrl) {\n consola.debug(`HTTP proxy bypass: ${origin.hostname}`)\n return (direct as unknown as Dispatcher).dispatch(options, handler)\n }\n let agent = proxies.get(proxyUrl)\n if (!agent) {\n agent = new ProxyAgent(proxyUrl)\n proxies.set(proxyUrl, agent)\n }\n let label = proxyUrl\n try {\n const u = new URL(proxyUrl)\n label = `${u.protocol}//${u.host}`\n }\n catch {\n /* noop */\n }\n consola.debug(`HTTP proxy route: ${origin.hostname} via ${label}`)\n return (agent as unknown as Dispatcher).dispatch(options, handler)\n }\n catch {\n return (direct as unknown as Dispatcher).dispatch(options, handler)\n }\n },\n close() {\n return direct.close()\n },\n destroy() {\n return direct.destroy()\n },\n }\n\n setGlobalDispatcher(dispatcher as unknown as Dispatcher)\n consola.debug('HTTP proxy configured from environment (per-URL)')\n }\n catch (err) {\n consola.debug('Proxy setup skipped:', err)\n }\n}\n","import { execSync } from 'node:child_process'\nimport process from 'node:process'\n\ntype ShellName = 'bash' | 'zsh' | 'fish' | 'powershell' | 'cmd' | 'sh'\ntype EnvVars = Record<string, string | undefined>\n\nfunction getShell(): ShellName {\n const { platform, ppid, env } = process\n\n if (platform === 'win32') {\n try {\n const command = `wmic process get ParentProcessId,Name | findstr \"${ppid}\"`\n const parentProcess = execSync(command, { stdio: 'pipe' }).toString()\n\n if (parentProcess.toLowerCase().includes('powershell.exe')) {\n return 'powershell'\n }\n }\n catch {\n return 'cmd'\n }\n\n return 'cmd'\n }\n else {\n const shellPath = env.SHELL\n if (shellPath) {\n if (shellPath.endsWith('zsh'))\n return 'zsh'\n if (shellPath.endsWith('fish'))\n return 'fish'\n if (shellPath.endsWith('bash'))\n return 'bash'\n }\n\n return 'sh'\n }\n}\n\n/**\n * Generates a copy-pasteable script to set multiple environment variables\n * and run a subsequent command.\n * @param {EnvVars} envVars - An object of environment variables to set.\n * @param {string} commandToRun - The command to run after setting the variables.\n * @returns {string} The formatted script string.\n */\nexport function generateEnvScript(\n envVars: EnvVars,\n commandToRun: string = '',\n): string {\n const shell = getShell()\n const filteredEnvVars = Object.entries(envVars).filter(\n ([, value]) => value !== undefined,\n ) as Array<[string, string]>\n\n let commandBlock: string\n\n switch (shell) {\n case 'powershell': {\n commandBlock = filteredEnvVars\n .map(([key, value]) => `$env:${key} = ${value}`)\n .join('; ')\n break\n }\n case 'cmd': {\n commandBlock = filteredEnvVars\n .map(([key, value]) => `set ${key}=${value}`)\n .join(' & ')\n break\n }\n case 'fish': {\n commandBlock = filteredEnvVars\n .map(([key, value]) => `set -gx ${key} ${value}`)\n .join('; ')\n break\n }\n default: {\n // bash, zsh, sh\n const assignments = filteredEnvVars\n .map(([key, value]) => `${key}=${value}`)\n .join(' ')\n commandBlock = filteredEnvVars.length > 0 ? `export ${assignments}` : ''\n break\n }\n }\n\n if (commandBlock && commandToRun) {\n const separator = shell === 'cmd' ? ' & ' : ' && '\n return `${commandBlock}${separator}${commandToRun}`\n }\n\n return commandBlock || commandToRun\n}\n","import type { Context, MiddlewareHandler } from 'hono'\n\nimport consola from 'consola'\nimport { colorize } from 'consola/utils'\n\nexport interface ModelMappingInfo {\n originalModel?: string\n mappedModel?: string\n}\n\nfunction formatElapsed(start: number) {\n const delta = Date.now() - start\n return delta < 1000 ? `${delta}ms` : `${Math.round(delta / 1000)}s`\n}\n\nfunction formatPath(rawUrl: string) {\n try {\n const url = new URL(rawUrl)\n return `${url.pathname}${url.search}`\n }\n catch {\n return rawUrl\n }\n}\n\nfunction colorizeStatus(status: number): string {\n if (status >= 500)\n return colorize('red', status)\n if (status >= 400)\n return colorize('yellow', status)\n if (status >= 300)\n return colorize('cyan', status)\n return colorize('green', status)\n}\n\nconst methodColors: Record<string, Parameters<typeof colorize>[0]> = {\n GET: 'cyan',\n POST: 'magenta',\n PUT: 'yellow',\n PATCH: 'yellow',\n DELETE: 'red',\n}\n\nfunction colorizeMethod(method: string): string {\n return colorize(methodColors[method] ?? 'white', method)\n}\n\nfunction formatModelMapping(info: ModelMappingInfo | undefined): string {\n if (!info)\n return ''\n\n const { originalModel, mappedModel } = info\n if (!originalModel && !mappedModel)\n return ''\n\n const original = originalModel ?? '-'\n const mapped = mappedModel ?? '-'\n\n if (original === mapped) {\n return ` ${colorize('dim', 'model=')}${colorize('blueBright', original)}`\n }\n\n return ` ${colorize('dim', 'model=')}${colorize('blueBright', original)} ${colorize('dim', '→')} ${colorize('greenBright', mapped)}`\n}\n\nexport const requestLogger: MiddlewareHandler = async (c, next) => {\n const { method, url } = c.req\n const path = formatPath(url)\n const start = Date.now()\n\n try {\n await next()\n }\n finally {\n const elapsed = formatElapsed(start)\n const status = c.res.status\n const modelInfo = c.get('modelMappingInfo')\n\n const line = [\n colorizeMethod(method),\n colorize('white', path),\n colorizeStatus(status),\n colorize('dim', elapsed),\n ].join(' ')\n\n consola.info(`${line}${formatModelMapping(modelInfo)}`)\n }\n}\n\nexport function setModelMappingInfo(c: Context, info: ModelMappingInfo) {\n c.set('modelMappingInfo', info)\n}\n","import consola from 'consola'\n\nimport { HTTPError } from './error'\n\nexport async function awaitApproval() {\n const response = await consola.prompt(`Accept incoming request?`, {\n type: 'confirm',\n })\n\n if (!response) {\n throw new HTTPError(\n 'Request rejected',\n Response.json({ message: 'Request rejected' }, { status: 403 }),\n )\n }\n}\n","import type { AppState } from './state'\n\nimport consola from 'consola'\n\nimport { HTTPError } from './error'\nimport { sleep } from './utils'\n\nexport async function checkRateLimit(state: AppState) {\n if (state.config.rateLimitSeconds === undefined)\n return\n\n const now = Date.now()\n\n if (!state.rateLimit.lastRequestTimestamp) {\n state.rateLimit.lastRequestTimestamp = now\n return\n }\n\n const elapsedSeconds = (now - state.rateLimit.lastRequestTimestamp) / 1000\n\n if (elapsedSeconds > state.config.rateLimitSeconds) {\n state.rateLimit.lastRequestTimestamp = now\n return\n }\n\n const waitTimeSeconds = Math.ceil(\n state.config.rateLimitSeconds - elapsedSeconds,\n )\n\n if (!state.config.rateLimitWait) {\n consola.warn(\n `Rate limit exceeded. Need to wait ${waitTimeSeconds} more seconds.`,\n )\n throw new HTTPError(\n 'Rate limit exceeded',\n Response.json({ message: 'Rate limit exceeded' }, { status: 429 }),\n )\n }\n\n const waitTimeMs = waitTimeSeconds * 1000\n consola.warn(\n `Rate limit reached. Waiting ${waitTimeSeconds} seconds before proceeding...`,\n )\n await sleep(waitTimeMs)\n\n state.rateLimit.lastRequestTimestamp = now\n consola.info('Rate limit wait completed, proceeding with request')\n}\n","import type { MiddlewareHandler } from 'hono'\n\nimport { awaitApproval } from '~/lib/approval'\nimport { checkRateLimit } from '~/lib/rate-limit'\nimport { state } from '~/lib/state'\n\nexport const requestGuard: MiddlewareHandler = async (c, next) => {\n void c\n await checkRateLimit(state)\n\n if (state.config.manualApprove) {\n await awaitApproval()\n }\n\n await next()\n}\n","import type {\n ChatCompletionsPayload,\n ContentPart,\n Message,\n Model,\n Tool,\n ToolCall,\n} from '~/types'\n\n// Encoder type mapping\nconst ENCODING_MAP = {\n o200k_base: () => import('gpt-tokenizer/encoding/o200k_base'),\n cl100k_base: () => import('gpt-tokenizer/encoding/cl100k_base'),\n p50k_base: () => import('gpt-tokenizer/encoding/p50k_base'),\n p50k_edit: () => import('gpt-tokenizer/encoding/p50k_edit'),\n r50k_base: () => import('gpt-tokenizer/encoding/r50k_base'),\n} as const\n\ntype SupportedEncoding = keyof typeof ENCODING_MAP\n\n// Define encoder interface\ninterface Encoder {\n encode: (text: string) => Array<number>\n}\n\n// Cache loaded encoders to avoid repeated imports\nconst encodingCache = new Map<string, Encoder>()\n\n/**\n * Calculate tokens for tool calls\n */\nfunction calculateToolCallsTokens(toolCalls: Array<ToolCall>, encoder: Encoder, constants: ReturnType<typeof getModelConstants>): number {\n let tokens = 0\n for (const toolCall of toolCalls) {\n tokens += constants.funcInit\n tokens += encoder.encode(JSON.stringify(toolCall)).length\n }\n tokens += constants.funcEnd\n return tokens\n}\n\n/**\n * Calculate tokens for content parts\n */\nfunction calculateContentPartsTokens(contentParts: Array<ContentPart>, encoder: Encoder): number {\n let tokens = 0\n for (const part of contentParts) {\n if (part.type === 'image_url') {\n tokens += encoder.encode(part.image_url.url).length + 85\n }\n else if (part.text) {\n tokens += encoder.encode(part.text).length\n }\n }\n return tokens\n}\n\n/**\n * Calculate tokens for a single message\n */\nfunction calculateMessageTokens(message: Message, encoder: Encoder, constants: ReturnType<typeof getModelConstants>): number {\n const tokensPerMessage = 3\n const tokensPerName = 1\n let tokens = tokensPerMessage\n for (const [key, value] of Object.entries(message)) {\n if (typeof value === 'string') {\n tokens += encoder.encode(value).length\n }\n if (key === 'name') {\n tokens += tokensPerName\n }\n if (key === 'tool_calls') {\n tokens += calculateToolCallsTokens(\n value as Array<ToolCall>,\n encoder,\n constants,\n )\n }\n if (key === 'content' && Array.isArray(value)) {\n tokens += calculateContentPartsTokens(\n value as Array<ContentPart>,\n encoder,\n )\n }\n }\n return tokens\n}\n\n/**\n * Calculate tokens using custom algorithm\n */\nfunction calculateTokens(messages: Array<Message>, encoder: Encoder, constants: ReturnType<typeof getModelConstants>): number {\n if (messages.length === 0) {\n return 0\n }\n let numTokens = 0\n for (const message of messages) {\n numTokens += calculateMessageTokens(message, encoder, constants)\n }\n // every reply is primed with <|start|>assistant<|message|>\n numTokens += 3\n return numTokens\n}\n\n/**\n * Get the corresponding encoder module based on encoding type\n */\nasync function getEncodeChatFunction(encoding: string): Promise<Encoder> {\n if (encodingCache.has(encoding)) {\n const cached = encodingCache.get(encoding)\n if (cached) {\n return cached\n }\n }\n\n const supportedEncoding = encoding as SupportedEncoding\n if (!(supportedEncoding in ENCODING_MAP)) {\n const fallbackModule = (await ENCODING_MAP.o200k_base()) as Encoder\n encodingCache.set(encoding, fallbackModule)\n return fallbackModule\n }\n\n const encodingModule = (await ENCODING_MAP[supportedEncoding]()) as Encoder\n encodingCache.set(encoding, encodingModule)\n return encodingModule\n}\n\n/**\n * Get tokenizer type from model information\n */\nexport function getTokenizerFromModel(model: Model): string {\n return model.capabilities.tokenizer || 'o200k_base'\n}\n\n/**\n * Get model-specific constants for token calculation\n */\nfunction getModelConstants(model: Model) {\n return model.id === 'gpt-3.5-turbo' || model.id === 'gpt-4'\n ? {\n funcInit: 10,\n propInit: 3,\n propKey: 3,\n enumInit: -3,\n enumItem: 3,\n funcEnd: 12,\n }\n : {\n funcInit: 7,\n propInit: 3,\n propKey: 3,\n enumInit: -3,\n enumItem: 3,\n funcEnd: 12,\n }\n}\n\n/**\n * Calculate tokens for a single parameter\n */\nfunction calculateParameterTokens(key: string, prop: unknown, context: {\n encoder: Encoder\n constants: ReturnType<typeof getModelConstants>\n}): number {\n const { encoder, constants } = context\n let tokens = constants.propKey\n\n // Early return if prop is not an object\n if (typeof prop !== 'object' || prop === null) {\n return tokens\n }\n\n // Type assertion for parameter properties\n const param = prop as {\n type?: string\n description?: string\n enum?: Array<unknown>\n [key: string]: unknown\n }\n\n const paramName = key\n const paramType = param.type || 'string'\n let paramDesc = param.description || ''\n\n // Handle enum values\n if (param.enum && Array.isArray(param.enum)) {\n tokens += constants.enumInit\n for (const item of param.enum) {\n tokens += constants.enumItem\n tokens += encoder.encode(String(item)).length\n }\n }\n\n // Clean up description\n if (paramDesc.endsWith('.')) {\n paramDesc = paramDesc.slice(0, -1)\n }\n\n // Encode the main parameter line\n const line = `${paramName}:${paramType}:${paramDesc}`\n tokens += encoder.encode(line).length\n\n // Handle additional properties (excluding standard ones)\n const excludedKeys = new Set(['type', 'description', 'enum'])\n for (const propertyName of Object.keys(param)) {\n if (!excludedKeys.has(propertyName)) {\n const propertyValue = param[propertyName]\n const propertyText\n = typeof propertyValue === 'string'\n ? propertyValue\n : (\n JSON.stringify(propertyValue)\n )\n tokens += encoder.encode(`${propertyName}:${propertyText}`).length\n }\n }\n\n return tokens\n}\n\n/**\n * Calculate tokens for function parameters\n */\nfunction calculateParametersTokens(parameters: unknown, encoder: Encoder, constants: ReturnType<typeof getModelConstants>): number {\n if (!parameters || typeof parameters !== 'object') {\n return 0\n }\n\n const params = parameters as Record<string, unknown>\n let tokens = 0\n\n for (const [key, value] of Object.entries(params)) {\n if (key === 'properties') {\n const properties = value as Record<string, unknown>\n if (Object.keys(properties).length > 0) {\n tokens += constants.propInit\n for (const propKey of Object.keys(properties)) {\n tokens += calculateParameterTokens(propKey, properties[propKey], {\n encoder,\n constants,\n })\n }\n }\n }\n else {\n const paramText\n = typeof value === 'string' ? value : JSON.stringify(value)\n tokens += encoder.encode(`${key}:${paramText}`).length\n }\n }\n\n return tokens\n}\n\n/**\n * Calculate tokens for a single tool\n */\nfunction calculateToolTokens(tool: Tool, encoder: Encoder, constants: ReturnType<typeof getModelConstants>): number {\n let tokens = constants.funcInit\n const func = tool.function\n const fName = func.name\n let fDesc = func.description || ''\n if (fDesc.endsWith('.')) {\n fDesc = fDesc.slice(0, -1)\n }\n const line = `${fName}:${fDesc}`\n tokens += encoder.encode(line).length\n if (\n typeof func.parameters === 'object'\n && func.parameters !== null\n ) {\n tokens += calculateParametersTokens(func.parameters, encoder, constants)\n }\n return tokens\n}\n\n/**\n * Calculate token count for tools based on model\n */\nexport function numTokensForTools(tools: Array<Tool>, encoder: Encoder, constants: ReturnType<typeof getModelConstants>): number {\n let funcTokenCount = 0\n for (const tool of tools) {\n funcTokenCount += calculateToolTokens(tool, encoder, constants)\n }\n funcTokenCount += constants.funcEnd\n return funcTokenCount\n}\n\n/**\n * Calculate the token count of messages, supporting multiple GPT encoders\n */\nexport async function getTokenCount(payload: ChatCompletionsPayload, model: Model): Promise<{ input: number, output: number }> {\n // Get tokenizer string\n const tokenizer = getTokenizerFromModel(model)\n\n // Get corresponding encoder module\n const encoder = await getEncodeChatFunction(tokenizer)\n\n const simplifiedMessages = payload.messages\n const inputMessages = simplifiedMessages.filter(\n msg => msg.role !== 'assistant',\n )\n const outputMessages = simplifiedMessages.filter(\n msg => msg.role === 'assistant',\n )\n\n const constants = getModelConstants(model)\n let inputTokens = calculateTokens(inputMessages, encoder, constants)\n if (payload.tools && payload.tools.length > 0) {\n inputTokens += numTokensForTools(payload.tools, encoder, constants)\n }\n const outputTokens = calculateTokens(outputMessages, encoder, constants)\n\n return {\n input: inputTokens,\n output: outputTokens,\n }\n}\n","interface UpstreamSignalOptions {\n clientSignal?: AbortSignal\n timeoutMs?: number\n}\n\ninterface UpstreamSignalResult {\n signal: AbortSignal\n cleanup: () => void\n}\n\nconst DEFAULT_TIMEOUT_MS = 300_000 // 5 minutes\n\nexport function createUpstreamSignal(\n options?: UpstreamSignalOptions,\n): UpstreamSignalResult {\n const { clientSignal, timeoutMs = DEFAULT_TIMEOUT_MS } = options ?? {}\n\n const controller = new AbortController()\n const timeout = setTimeout(() => {\n controller.abort()\n }, timeoutMs)\n\n let listenerAdded = false\n let abortListener: (() => void) | undefined\n\n // Only add listener if clientSignal exists and is not already aborted\n if (clientSignal && !clientSignal.aborted) {\n abortListener = () => {\n controller.abort()\n }\n clientSignal.addEventListener('abort', abortListener)\n listenerAdded = true\n }\n\n const cleanup = () => {\n clearTimeout(timeout)\n\n if (listenerAdded && clientSignal && abortListener) {\n clientSignal.removeEventListener('abort', abortListener)\n }\n }\n\n return {\n signal: controller.signal,\n cleanup,\n }\n}\n","import type {\n AnthropicCountTokensPayload,\n AnthropicMessagesPayload,\n} from '~/translator'\nimport type { ChatCompletionsPayload, EmbeddingRequest } from '~/types'\n\nimport consola from 'consola'\nimport { z } from 'zod'\n\nimport { HTTPError } from './error'\n\nconst openAIMessageSchema = z\n .object({\n role: z.string(),\n content: z.union([z.string(), z.array(z.any()), z.null()]),\n name: z.string().optional(),\n tool_calls: z.array(z.any()).optional(),\n tool_call_id: z.string().optional(),\n })\n .loose()\n\nconst openAIChatPayloadSchema = z\n .object({\n model: z.string(),\n messages: z.array(openAIMessageSchema).min(1),\n })\n .loose()\n\nconst anthropicMessageSchema = z\n .object({\n role: z.enum(['user', 'assistant']),\n content: z.union([z.string(), z.array(z.any())]),\n })\n .loose()\n\nconst anthropicMessagesBasePayloadSchema = z\n .object({\n model: z.string(),\n messages: z.array(anthropicMessageSchema).min(1),\n })\n .loose()\n\nconst anthropicMessagesPayloadSchema = anthropicMessagesBasePayloadSchema\n .extend({\n max_tokens: z.number(),\n })\n .loose()\n\nconst anthropicCountTokensPayloadSchema = anthropicMessagesBasePayloadSchema\n .extend({\n max_tokens: z.number().optional(),\n })\n .loose()\n\nconst embeddingRequestSchema = z\n .object({\n input: z.union([z.string(), z.array(z.string())]),\n model: z.string(),\n })\n .loose()\n\nfunction throwInvalidPayload(context: string, issues: Array<z.core.$ZodIssue>) {\n consola.warn('Invalid request payload', { context, issues })\n throw new HTTPError(\n 'Invalid request payload',\n new Response('Invalid request payload', { status: 400 }),\n )\n}\n\nexport function parseOpenAIChatPayload(payload: unknown): ChatCompletionsPayload {\n const result = openAIChatPayloadSchema.safeParse(payload)\n if (!result.success) {\n throwInvalidPayload('openai.chat', result.error.issues)\n }\n return result.data as ChatCompletionsPayload\n}\n\nexport function parseAnthropicMessagesPayload(payload: unknown): AnthropicMessagesPayload {\n const result = anthropicMessagesPayloadSchema.safeParse(payload)\n if (!result.success) {\n throwInvalidPayload('anthropic.messages', result.error.issues)\n }\n return result.data as AnthropicMessagesPayload\n}\n\nexport function parseAnthropicCountTokensPayload(payload: unknown): AnthropicCountTokensPayload {\n const result = anthropicCountTokensPayloadSchema.safeParse(payload)\n if (!result.success) {\n throwInvalidPayload('anthropic.messages.count_tokens', result.error.issues)\n }\n return result.data as AnthropicCountTokensPayload\n}\n\nexport function parseEmbeddingRequest(payload: unknown): EmbeddingRequest {\n const result = embeddingRequestSchema.safeParse(payload)\n if (!result.success) {\n throwInvalidPayload('openai.embeddings', result.error.issues)\n }\n return result.data as EmbeddingRequest\n}\n","import type { Context } from 'hono'\n\nimport type { SSEMessage } from 'hono/streaming'\nimport type { ChatCompletionResponse } from '~/types'\n\nimport consola from 'consola'\nimport { streamSSE } from 'hono/streaming'\n\nimport { CopilotClient } from '~/clients'\nimport { getClientConfig } from '~/lib/client-config'\nimport { state } from '~/lib/state'\nimport { getTokenCount } from '~/lib/tokenizer'\nimport { createUpstreamSignal } from '~/lib/upstream-signal'\nimport { isNullish } from '~/lib/utils'\nimport { parseOpenAIChatPayload } from '~/lib/validation'\n\nexport async function handleCompletion(c: Context) {\n let payload = parseOpenAIChatPayload(await c.req.json())\n consola.debug('Request payload:', JSON.stringify(payload).slice(-400))\n\n // Find the selected model\n const selectedModel = state.cache.models?.data.find(\n model => model.id === payload.model,\n )\n\n // Calculate and display token count\n try {\n if (selectedModel) {\n const tokenCount = await getTokenCount(payload, selectedModel)\n consola.info('Current token count:', tokenCount)\n }\n else {\n consola.warn('No model selected, skipping token count calculation')\n }\n }\n catch (error) {\n consola.warn('Failed to calculate token count:', error)\n }\n\n if (isNullish(payload.max_tokens)) {\n payload = {\n ...payload,\n max_tokens: selectedModel?.capabilities.limits.max_output_tokens,\n }\n consola.debug('Set max_tokens to:', JSON.stringify(payload.max_tokens))\n }\n\n const { signal, cleanup } = createUpstreamSignal({\n clientSignal: c.req.raw.signal,\n timeoutMs: (state.config.upstreamTimeoutSeconds ?? 300) * 1000,\n })\n\n const copilotClient = new CopilotClient(state.auth, getClientConfig(state))\n const response = await copilotClient.createChatCompletions(payload, {\n signal,\n })\n\n if (isNonStreaming(response)) {\n consola.debug('Non-streaming response:', JSON.stringify(response))\n cleanup()\n return c.json(response)\n }\n\n consola.debug('Streaming response')\n return streamSSE(c, async (stream) => {\n try {\n for await (const chunk of response) {\n consola.debug('Streaming chunk:', JSON.stringify(chunk))\n await stream.writeSSE(chunk as SSEMessage)\n }\n }\n finally {\n cleanup()\n }\n })\n}\n\nfunction isNonStreaming(response: Awaited<ReturnType<CopilotClient['createChatCompletions']>>): response is ChatCompletionResponse {\n return Object.hasOwn(response, 'choices')\n}\n","import { Hono } from 'hono'\n\nimport { requestGuard } from '~/routes/middleware/request-guard'\n\nimport { handleCompletion } from './handler'\n\nexport const completionRoutes = new Hono()\n\ncompletionRoutes.post('/', requestGuard, c => handleCompletion(c))\n","import { Hono } from 'hono'\n\nimport { CopilotClient } from '~/clients'\nimport { getClientConfig } from '~/lib/client-config'\nimport { state } from '~/lib/state'\nimport { parseEmbeddingRequest } from '~/lib/validation'\n\nexport const embeddingRoutes = new Hono()\n\nembeddingRoutes.post('/', async (c) => {\n const payload = parseEmbeddingRequest(await c.req.json())\n const copilotClient = new CopilotClient(state.auth, getClientConfig(state))\n const response = await copilotClient.createEmbeddings(payload)\n\n return c.json(response)\n})\n","import type { AnthropicResponse } from './types'\n\nexport function mapOpenAIStopReasonToAnthropic(\n finishReason: 'stop' | 'length' | 'tool_calls' | 'content_filter' | null,\n): AnthropicResponse['stop_reason'] {\n if (finishReason === null) {\n return null\n }\n const stopReasonMap = {\n stop: 'end_turn',\n length: 'max_tokens',\n tool_calls: 'tool_use',\n content_filter: 'end_turn',\n } as const\n return stopReasonMap[finishReason]\n}\n","import type { AnthropicStreamEventData, AnthropicStreamState } from './types'\n\nimport type { ChatCompletionChunk } from '~/types'\n\nimport { mapOpenAIStopReasonToAnthropic } from './shared'\n\nexport class AnthropicStreamTranslator {\n private state: AnthropicStreamState\n\n constructor() {\n this.state = {\n messageStartSent: false,\n contentBlockIndex: 0,\n contentBlockOpen: false,\n toolCalls: {},\n }\n }\n\n onChunk(chunk: ChatCompletionChunk): Array<AnthropicStreamEventData> {\n if (chunk.choices.length === 0) {\n return []\n }\n\n const events: Array<AnthropicStreamEventData> = []\n const choice = chunk.choices[0]\n const { delta } = choice\n\n this.appendMessageStart(events, chunk)\n this.appendContentDelta(events, delta.content)\n this.appendToolCalls(events, delta.tool_calls)\n this.appendFinish(events, chunk, choice.finish_reason)\n\n return events\n }\n\n onError(error?: unknown): Array<AnthropicStreamEventData> {\n const message = this.getErrorMessage(error)\n return [\n {\n type: 'error',\n error: {\n type: 'api_error',\n message,\n },\n },\n ]\n }\n\n private getErrorMessage(error: unknown): string {\n if (this.isTimeoutError(error)) {\n return 'Upstream streaming request timed out. Please retry.'\n }\n return 'An unexpected error occurred during streaming.'\n }\n\n private isTimeoutError(error: unknown): boolean {\n if (error instanceof DOMException) {\n return error.name === 'TimeoutError'\n }\n if (error instanceof Error) {\n return error.name === 'TimeoutError'\n }\n return false\n }\n\n private isToolBlockOpen(): boolean {\n if (!this.state.contentBlockOpen) {\n return false\n }\n return Object.values(this.state.toolCalls).some((tc) => {\n return (\n tc !== undefined\n && tc.anthropicBlockIndex === this.state.contentBlockIndex\n )\n })\n }\n\n private appendMessageStart(\n events: Array<AnthropicStreamEventData>,\n chunk: ChatCompletionChunk,\n ) {\n if (this.state.messageStartSent) {\n return\n }\n\n events.push({\n type: 'message_start',\n message: {\n id: chunk.id,\n type: 'message',\n role: 'assistant',\n content: [],\n model: chunk.model,\n stop_reason: null,\n stop_sequence: null,\n usage: {\n input_tokens:\n (chunk.usage?.prompt_tokens ?? 0)\n - (chunk.usage?.prompt_tokens_details?.cached_tokens ?? 0),\n output_tokens: 0,\n ...(chunk.usage?.prompt_tokens_details?.cached_tokens\n !== undefined && {\n cache_read_input_tokens:\n chunk.usage.prompt_tokens_details.cached_tokens,\n }),\n },\n },\n })\n this.state.messageStartSent = true\n }\n\n private appendContentDelta(\n events: Array<AnthropicStreamEventData>,\n content: string | null | undefined,\n ) {\n if (!content) {\n return\n }\n\n if (this.isToolBlockOpen()) {\n events.push({\n type: 'content_block_stop',\n index: this.state.contentBlockIndex,\n })\n this.state.contentBlockIndex++\n this.state.contentBlockOpen = false\n }\n\n if (!this.state.contentBlockOpen) {\n events.push({\n type: 'content_block_start',\n index: this.state.contentBlockIndex,\n content_block: {\n type: 'text',\n text: '',\n },\n })\n this.state.contentBlockOpen = true\n }\n\n events.push({\n type: 'content_block_delta',\n index: this.state.contentBlockIndex,\n delta: {\n type: 'text_delta',\n text: content,\n },\n })\n }\n\n private appendToolCalls(\n events: Array<AnthropicStreamEventData>,\n toolCalls:\n | Array<{\n index: number\n id?: string\n type?: 'function'\n function?: {\n name?: string\n arguments?: string\n }\n }>\n | undefined,\n ) {\n if (!toolCalls || toolCalls.length === 0) {\n return\n }\n\n for (const toolCall of toolCalls) {\n if (toolCall.id && toolCall.function?.name) {\n if (this.state.contentBlockOpen) {\n events.push({\n type: 'content_block_stop',\n index: this.state.contentBlockIndex,\n })\n this.state.contentBlockIndex++\n this.state.contentBlockOpen = false\n }\n\n const anthropicBlockIndex = this.state.contentBlockIndex\n this.state.toolCalls[toolCall.index] = {\n id: toolCall.id,\n name: toolCall.function.name,\n anthropicBlockIndex,\n }\n\n events.push({\n type: 'content_block_start',\n index: anthropicBlockIndex,\n content_block: {\n type: 'tool_use',\n id: toolCall.id,\n name: toolCall.function.name,\n input: {},\n },\n })\n this.state.contentBlockOpen = true\n }\n\n if (toolCall.function?.arguments) {\n const toolCallInfo = this.state.toolCalls[toolCall.index]\n if (!toolCallInfo) {\n continue\n }\n\n events.push({\n type: 'content_block_delta',\n index: toolCallInfo.anthropicBlockIndex,\n delta: {\n type: 'input_json_delta',\n partial_json: toolCall.function.arguments,\n },\n })\n }\n }\n }\n\n private appendFinish(\n events: Array<AnthropicStreamEventData>,\n chunk: ChatCompletionChunk,\n finishReason: 'stop' | 'length' | 'tool_calls' | 'content_filter' | null,\n ) {\n if (!finishReason) {\n return\n }\n\n if (this.state.contentBlockOpen) {\n events.push({\n type: 'content_block_stop',\n index: this.state.contentBlockIndex,\n })\n this.state.contentBlockOpen = false\n }\n\n events.push(\n {\n type: 'message_delta',\n delta: {\n stop_reason: mapOpenAIStopReasonToAnthropic(finishReason),\n stop_sequence: null,\n },\n usage: {\n input_tokens:\n (chunk.usage?.prompt_tokens ?? 0)\n - (chunk.usage?.prompt_tokens_details?.cached_tokens ?? 0),\n output_tokens: chunk.usage?.completion_tokens ?? 0,\n ...(chunk.usage?.prompt_tokens_details?.cached_tokens\n !== undefined && {\n cache_read_input_tokens:\n chunk.usage.prompt_tokens_details.cached_tokens,\n }),\n },\n },\n {\n type: 'message_stop',\n },\n )\n }\n}\n","import process from 'node:process'\n\nimport { getCachedConfig } from './config'\n\nexport interface ModelFallbackConfig {\n claudeOpus: string\n claudeSonnet: string\n claudeHaiku: string\n}\n\nexport const DEFAULT_FALLBACKS: ModelFallbackConfig = {\n claudeOpus: 'claude-opus-4.6',\n claudeSonnet: 'claude-sonnet-4.5',\n claudeHaiku: 'claude-haiku-4.5',\n}\n\nexport function getModelFallbackConfig(): ModelFallbackConfig {\n const cachedConfig = getCachedConfig()\n return {\n claudeOpus:\n process.env.MODEL_FALLBACK_CLAUDE_OPUS\n || cachedConfig.modelFallback?.claudeOpus\n || DEFAULT_FALLBACKS.claudeOpus,\n claudeSonnet:\n process.env.MODEL_FALLBACK_CLAUDE_SONNET\n || cachedConfig.modelFallback?.claudeSonnet\n || DEFAULT_FALLBACKS.claudeSonnet,\n claudeHaiku:\n process.env.MODEL_FALLBACK_CLAUDE_HAIKU\n || cachedConfig.modelFallback?.claudeHaiku\n || DEFAULT_FALLBACKS.claudeHaiku,\n }\n}\n\nexport function resolveModel(\n modelId: string,\n knownModelIds: Set<string> | undefined,\n config: ModelFallbackConfig,\n): string {\n if (knownModelIds?.has(modelId)) {\n return modelId\n }\n if (modelId.startsWith('claude-opus-'))\n return config.claudeOpus\n if (modelId.startsWith('claude-sonnet-'))\n return config.claudeSonnet\n if (modelId.startsWith('claude-haiku-'))\n return config.claudeHaiku\n return modelId\n}\n","import type {\n AnthropicAssistantContentBlock,\n AnthropicAssistantMessage,\n AnthropicMessage,\n AnthropicMessagesPayload,\n AnthropicResponse,\n AnthropicTextBlock,\n AnthropicThinkingBlock,\n AnthropicTool,\n AnthropicToolResultBlock,\n AnthropicToolUseBlock,\n AnthropicUserContentBlock,\n AnthropicUserMessage,\n} from './types'\n\nimport type {\n ChatCompletionResponse,\n ChatCompletionsPayload,\n ContentPart,\n Message,\n TextPart,\n Tool,\n ToolCall,\n} from '~/types'\nimport { getModelFallbackConfig, resolveModel } from '~/lib/model-resolver'\n\nimport { state } from '~/lib/state'\n\nimport { AnthropicStreamTranslator } from './anthropic-stream-translator'\nimport { mapOpenAIStopReasonToAnthropic } from './shared'\n\nexport class AnthropicTranslator {\n toOpenAI(payload: AnthropicMessagesPayload): ChatCompletionsPayload {\n return {\n model: this.translateModelName(payload.model),\n messages: this.translateAnthropicMessagesToOpenAI(\n payload.messages,\n payload.system,\n ),\n max_tokens: payload.max_tokens,\n stop: payload.stop_sequences,\n stream: payload.stream,\n temperature: payload.temperature,\n top_p: payload.top_p,\n user: payload.metadata?.user_id,\n tools: this.translateAnthropicToolsToOpenAI(payload.tools),\n tool_choice: this.translateAnthropicToolChoiceToOpenAI(\n payload.tool_choice,\n ),\n }\n }\n\n fromOpenAI(response: ChatCompletionResponse): AnthropicResponse {\n const allTextBlocks: Array<AnthropicTextBlock> = []\n const allToolUseBlocks: Array<AnthropicToolUseBlock> = []\n let stopReason: 'stop' | 'length' | 'tool_calls' | 'content_filter' | null\n = null\n stopReason = response.choices[0]?.finish_reason ?? stopReason\n\n for (const choice of response.choices) {\n const textBlocks = this.getAnthropicTextBlocks(choice.message.content)\n const toolUseBlocks = this.getAnthropicToolUseBlocks(\n choice.message.tool_calls,\n )\n\n allTextBlocks.push(...textBlocks)\n allToolUseBlocks.push(...toolUseBlocks)\n\n if (choice.finish_reason === 'tool_calls' || stopReason === 'stop') {\n stopReason = choice.finish_reason\n }\n }\n\n return {\n id: response.id,\n type: 'message',\n role: 'assistant',\n model: response.model,\n content: [...allTextBlocks, ...allToolUseBlocks],\n stop_reason: mapOpenAIStopReasonToAnthropic(stopReason),\n stop_sequence: null,\n usage: {\n input_tokens:\n (response.usage?.prompt_tokens ?? 0)\n - (response.usage?.prompt_tokens_details?.cached_tokens ?? 0),\n output_tokens: response.usage?.completion_tokens ?? 0,\n ...(response.usage?.prompt_tokens_details?.cached_tokens\n !== undefined && {\n cache_read_input_tokens:\n response.usage.prompt_tokens_details.cached_tokens,\n }),\n },\n }\n }\n\n createStreamTranslator() {\n return new AnthropicStreamTranslator()\n }\n\n private translateModelName(model: string): string {\n const knownModelIds\n = state.cache.models\n ? new Set(state.cache.models.data.map(m => m.id))\n : undefined\n const config = getModelFallbackConfig()\n return resolveModel(model, knownModelIds, config)\n }\n\n private translateAnthropicMessagesToOpenAI(\n anthropicMessages: Array<AnthropicMessage>,\n system: string | Array<AnthropicTextBlock> | undefined,\n ): Array<Message> {\n const systemMessages = this.handleSystemPrompt(system)\n\n const otherMessages = anthropicMessages.flatMap(message =>\n message.role === 'user'\n ? this.handleUserMessage(message)\n : this.handleAssistantMessage(message),\n )\n\n return [...systemMessages, ...otherMessages]\n }\n\n private handleSystemPrompt(\n system: string | Array<AnthropicTextBlock> | undefined,\n ): Array<Message> {\n if (!system) {\n return []\n }\n\n if (typeof system === 'string') {\n return [{ role: 'system', content: system }]\n }\n\n const systemText = system.map(block => block.text).join('\\n\\n')\n return [{ role: 'system', content: systemText }]\n }\n\n private handleUserMessage(message: AnthropicUserMessage): Array<Message> {\n const newMessages: Array<Message> = []\n\n if (Array.isArray(message.content)) {\n const toolResultBlocks = message.content.filter(\n (block): block is AnthropicToolResultBlock =>\n block.type === 'tool_result',\n )\n const otherBlocks = message.content.filter(\n block => block.type !== 'tool_result',\n )\n\n for (const block of toolResultBlocks) {\n newMessages.push({\n role: 'tool',\n tool_call_id: block.tool_use_id,\n content: this.mapContent(block.content),\n })\n }\n\n if (otherBlocks.length > 0) {\n newMessages.push({\n role: 'user',\n content: this.mapContent(otherBlocks),\n })\n }\n }\n else {\n newMessages.push({\n role: 'user',\n content: this.mapContent(message.content),\n })\n }\n\n return newMessages\n }\n\n private handleAssistantMessage(\n message: AnthropicAssistantMessage,\n ): Array<Message> {\n if (!Array.isArray(message.content)) {\n return [\n {\n role: 'assistant',\n content: this.mapContent(message.content),\n },\n ]\n }\n\n const toolUseBlocks = message.content.filter(\n (block): block is AnthropicToolUseBlock => block.type === 'tool_use',\n )\n\n const textBlocks = message.content.filter(\n (block): block is AnthropicTextBlock => block.type === 'text',\n )\n\n const thinkingBlocks = message.content.filter(\n (block): block is AnthropicThinkingBlock => block.type === 'thinking',\n )\n\n const allTextContent = [\n ...textBlocks.map(b => b.text),\n ...thinkingBlocks.map(b => b.thinking),\n ].join('\\n\\n')\n\n return toolUseBlocks.length > 0\n ? [\n {\n role: 'assistant',\n content: allTextContent || null,\n tool_calls: toolUseBlocks.map(toolUse => ({\n id: toolUse.id,\n type: 'function',\n function: {\n name: toolUse.name,\n arguments: JSON.stringify(toolUse.input),\n },\n })),\n },\n ]\n : [\n {\n role: 'assistant',\n content: this.mapContent(message.content),\n },\n ]\n }\n\n private mapContent(\n content:\n | string\n | Array<AnthropicUserContentBlock | AnthropicAssistantContentBlock>,\n ): string | Array<ContentPart> | null {\n if (typeof content === 'string') {\n return content\n }\n if (!Array.isArray(content)) {\n return null\n }\n\n const hasImage = content.some(block => block.type === 'image')\n if (!hasImage) {\n return content\n .filter(\n (block): block is AnthropicTextBlock | AnthropicThinkingBlock =>\n block.type === 'text' || block.type === 'thinking',\n )\n .map(block => (block.type === 'text' ? block.text : block.thinking))\n .join('\\n\\n')\n }\n\n const contentParts: Array<ContentPart> = []\n for (const block of content) {\n switch (block.type) {\n case 'text': {\n contentParts.push({ type: 'text', text: block.text })\n break\n }\n case 'thinking': {\n contentParts.push({ type: 'text', text: block.thinking })\n break\n }\n case 'image': {\n contentParts.push({\n type: 'image_url',\n image_url: {\n url: `data:${block.source.media_type};base64,${block.source.data}`,\n },\n })\n break\n }\n default: {\n break\n }\n }\n }\n return contentParts\n }\n\n private translateAnthropicToolsToOpenAI(\n anthropicTools: Array<AnthropicTool> | undefined,\n ): Array<Tool> | undefined {\n if (!anthropicTools) {\n return undefined\n }\n return anthropicTools.map(tool => ({\n type: 'function',\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.input_schema,\n },\n }))\n }\n\n private translateAnthropicToolChoiceToOpenAI(\n anthropicToolChoice: AnthropicMessagesPayload['tool_choice'],\n ): ChatCompletionsPayload['tool_choice'] {\n if (!anthropicToolChoice) {\n return undefined\n }\n\n switch (anthropicToolChoice.type) {\n case 'auto': {\n return 'auto'\n }\n case 'any': {\n return 'required'\n }\n case 'tool': {\n if (anthropicToolChoice.name) {\n return {\n type: 'function',\n function: { name: anthropicToolChoice.name },\n }\n }\n return undefined\n }\n case 'none': {\n return 'none'\n }\n default: {\n return undefined\n }\n }\n }\n\n private getAnthropicTextBlocks(\n messageContent: Message['content'],\n ): Array<AnthropicTextBlock> {\n if (typeof messageContent === 'string') {\n return [{ type: 'text', text: messageContent }]\n }\n\n if (Array.isArray(messageContent)) {\n return messageContent\n .filter((part): part is TextPart => part.type === 'text')\n .map(part => ({ type: 'text', text: part.text }))\n }\n\n return []\n }\n\n private getAnthropicToolUseBlocks(\n toolCalls: Array<ToolCall> | undefined,\n ): Array<AnthropicToolUseBlock> {\n if (!toolCalls) {\n return []\n }\n return toolCalls.map(toolCall => ({\n type: 'tool_use',\n id: toolCall.id,\n name: toolCall.function.name,\n input: JSON.parse(toolCall.function.arguments) as Record<string, unknown>,\n }))\n }\n}\n","import type { Context } from 'hono'\n\nimport consola from 'consola'\n\nimport { HTTPError } from '~/lib/error'\nimport { state } from '~/lib/state'\nimport { getTokenCount } from '~/lib/tokenizer'\nimport { parseAnthropicCountTokensPayload } from '~/lib/validation'\nimport { AnthropicTranslator } from '~/translator'\n\n/**\n * Handles token counting for Anthropic messages\n */\nexport async function handleCountTokens(c: Context) {\n const anthropicBeta = c.req.header('anthropic-beta')\n const anthropicPayload = parseAnthropicCountTokensPayload(await c.req.json())\n const normalizedPayload = {\n ...anthropicPayload,\n max_tokens: anthropicPayload.max_tokens ?? 0,\n }\n\n const translator = new AnthropicTranslator()\n const openAIPayload = translator.toOpenAI(normalizedPayload)\n\n const selectedModel = state.cache.models?.data.find(\n model => model.id === openAIPayload.model,\n )\n\n if (!selectedModel) {\n throw new HTTPError(\n `Model not found for token counting: \"${openAIPayload.model}\"`,\n new Response(\n `Model not found for token counting: \"${openAIPayload.model}\"`,\n {\n status: 400,\n },\n ),\n )\n }\n\n const tokenCount = await getTokenCount(openAIPayload, selectedModel)\n\n if (anthropicPayload.tools && anthropicPayload.tools.length > 0) {\n let mcpToolExist = false\n if (anthropicBeta?.startsWith('claude-code')) {\n mcpToolExist = anthropicPayload.tools.some(tool =>\n tool.name.startsWith('mcp__'),\n )\n }\n if (!mcpToolExist) {\n if (anthropicPayload.model.startsWith('claude')) {\n // https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#pricing\n tokenCount.input = tokenCount.input + 346\n }\n else if (anthropicPayload.model.startsWith('grok')) {\n tokenCount.input = tokenCount.input + 480\n }\n }\n }\n\n let finalTokenCount = tokenCount.input + tokenCount.output\n if (anthropicPayload.model.startsWith('claude')) {\n finalTokenCount = Math.round(finalTokenCount * 1.15)\n }\n else if (anthropicPayload.model.startsWith('grok')) {\n finalTokenCount = Math.round(finalTokenCount * 1.03)\n }\n\n consola.info('Token count:', finalTokenCount)\n\n return c.json({\n input_tokens: finalTokenCount,\n })\n}\n","import type { Context } from 'hono'\n\nimport type { ChatCompletionChunk, ChatCompletionResponse } from '~/types'\nimport consola from 'consola'\n\nimport { streamSSE } from 'hono/streaming'\n\nimport { CopilotClient } from '~/clients'\nimport { getClientConfig } from '~/lib/client-config'\nimport { setModelMappingInfo } from '~/lib/request-logger'\nimport { state } from '~/lib/state'\nimport { createUpstreamSignal } from '~/lib/upstream-signal'\nimport { parseAnthropicMessagesPayload } from '~/lib/validation'\nimport { AnthropicTranslator } from '~/translator'\n\nexport async function handleCompletion(c: Context) {\n const anthropicPayload = parseAnthropicMessagesPayload(await c.req.json())\n consola.debug('Anthropic request payload:', JSON.stringify(anthropicPayload))\n\n const translator = new AnthropicTranslator()\n const openAIPayload = translator.toOpenAI(anthropicPayload)\n setModelMappingInfo(c, {\n originalModel: anthropicPayload.model,\n mappedModel: openAIPayload.model,\n })\n consola.debug(\n 'Claude Code requested model:',\n anthropicPayload.model,\n '-> Copilot model:',\n openAIPayload.model,\n )\n consola.debug(\n 'Translated OpenAI request payload:',\n JSON.stringify(openAIPayload),\n )\n\n const { signal, cleanup } = createUpstreamSignal({\n clientSignal: c.req.raw.signal,\n timeoutMs: (state.config.upstreamTimeoutSeconds ?? 300) * 1000,\n })\n\n const copilotClient = new CopilotClient(state.auth, getClientConfig(state))\n const response = await copilotClient.createChatCompletions(openAIPayload, {\n signal,\n })\n\n if (isNonStreaming(response)) {\n consola.debug(\n 'Non-streaming response from Copilot:',\n JSON.stringify(response).slice(-400),\n )\n const anthropicResponse = translator.fromOpenAI(response)\n consola.debug(\n 'Translated Anthropic response:',\n JSON.stringify(anthropicResponse),\n )\n cleanup()\n return c.json(anthropicResponse)\n }\n\n consola.debug('Streaming response from Copilot')\n return streamSSE(c, async (stream) => {\n const streamTranslator = translator.createStreamTranslator()\n\n try {\n for await (const rawEvent of response) {\n consola.debug('Copilot raw stream event:', JSON.stringify(rawEvent))\n if (rawEvent.data === '[DONE]') {\n break\n }\n\n if (!rawEvent.data) {\n continue\n }\n\n const chunk = JSON.parse(rawEvent.data) as ChatCompletionChunk\n const events = streamTranslator.onChunk(chunk)\n\n for (const event of events) {\n consola.debug('Translated Anthropic event:', JSON.stringify(event))\n await stream.writeSSE({\n event: event.type,\n data: JSON.stringify(event),\n })\n }\n }\n }\n catch (error) {\n if (c.req.raw.signal.aborted) {\n consola.debug('Client disconnected during Anthropic stream')\n return\n }\n\n consola.error('Error streaming Anthropic response:', error)\n const errorEvents = streamTranslator.onError(error)\n for (const event of errorEvents) {\n await stream.writeSSE({\n event: event.type,\n data: JSON.stringify(event),\n })\n }\n }\n finally {\n cleanup()\n }\n })\n}\n\nfunction isNonStreaming(response: Awaited<ReturnType<CopilotClient['createChatCompletions']>>): response is ChatCompletionResponse {\n return Object.hasOwn(response, 'choices')\n}\n","import { Hono } from 'hono'\n\nimport { requestGuard } from '~/routes/middleware/request-guard'\n\nimport { handleCountTokens } from './count-tokens-handler'\nimport { handleCompletion } from './handler'\n\nexport const messageRoutes = new Hono()\n\nmessageRoutes.post('/', requestGuard, c => handleCompletion(c))\n\nmessageRoutes.post('/count_tokens', c => handleCountTokens(c))\n","import { Hono } from 'hono'\n\nimport { CopilotClient } from '~/clients'\nimport { getClientConfig } from '~/lib/client-config'\nimport { state } from '~/lib/state'\nimport { cacheModels } from '~/lib/utils'\n\nexport const modelRoutes = new Hono()\n\nmodelRoutes.get('/', async (c) => {\n if (!state.cache.models) {\n // This should be handled by startup logic, but as a fallback.\n const copilotClient = new CopilotClient(state.auth, getClientConfig(state))\n await cacheModels(copilotClient)\n }\n\n const models = state.cache.models?.data.map(model => ({\n id: model.id,\n object: 'model',\n type: 'model',\n created: 0, // No date available from source\n created_at: new Date(0).toISOString(), // No date available from source\n owned_by: model.vendor,\n display_name: model.name,\n }))\n\n return c.json({\n object: 'list',\n data: models,\n has_more: false,\n })\n})\n","import { Hono } from 'hono'\n\nimport { state } from '~/lib/state'\n\nexport const tokenRoute = new Hono()\n\ntokenRoute.get('/', (c) => {\n return c.json({\n token: state.auth.copilotToken,\n })\n})\n","import { Hono } from 'hono'\n\nimport { GitHubClient } from '~/clients'\nimport { getClientConfig } from '~/lib/client-config'\nimport { state } from '~/lib/state'\n\nexport const usageRoute = new Hono()\n\nusageRoute.get('/', async (c) => {\n const githubClient = new GitHubClient(state.auth, getClientConfig(state))\n const usage = await githubClient.getCopilotUsage()\n return c.json(usage)\n})\n","import { Hono } from 'hono'\nimport { cors } from 'hono/cors'\n\nimport { forwardError } from './lib/error'\nimport { requestLogger } from './lib/request-logger'\nimport { completionRoutes } from './routes/chat-completions/route'\nimport { embeddingRoutes } from './routes/embeddings/route'\nimport { messageRoutes } from './routes/messages/route'\nimport { modelRoutes } from './routes/models/route'\nimport { tokenRoute } from './routes/token/route'\nimport { usageRoute } from './routes/usage/route'\n\nexport const server = new Hono()\n\nserver.use(requestLogger)\nserver.use(cors())\nserver.onError((error, c) => forwardError(c, error))\n\nserver.get('/', c => c.text('Server running'))\n\nserver.route('/chat/completions', completionRoutes)\nserver.route('/models', modelRoutes)\nserver.route('/embeddings', embeddingRoutes)\nserver.route('/usage', usageRoute)\nserver.route('/token', tokenRoute)\n\n// Compatibility with tools that expect v1/ prefix\nserver.route('/v1/chat/completions', completionRoutes)\nserver.route('/v1/models', modelRoutes)\nserver.route('/v1/embeddings', embeddingRoutes)\n\n// Anthropic compatible endpoints\nserver.route('/v1/messages', messageRoutes)\n","#!/usr/bin/env node\n\nimport type { ServerHandler } from 'srvx'\nimport { defineCommand } from 'citty'\nimport clipboard from 'clipboardy'\nimport consola from 'consola'\nimport { serve } from 'srvx'\nimport invariant from 'tiny-invariant'\n\nimport { CopilotClient } from '~/clients'\n\nimport { getClientConfig } from './lib/client-config'\nimport { readConfig } from './lib/config'\nimport { ensurePaths } from './lib/paths'\nimport { initProxyFromEnv } from './lib/proxy'\nimport { generateEnvScript } from './lib/shell'\nimport { state } from './lib/state'\nimport { setupCopilotToken, setupGitHubToken } from './lib/token'\nimport { cacheModels, cacheVSCodeVersion } from './lib/utils'\nimport { server } from './server'\n\ninterface RunServerOptions {\n port: number\n verbose: boolean\n accountType: string\n manual: boolean\n rateLimit?: number\n rateLimitWait: boolean\n githubToken?: string\n claudeCode: boolean\n showToken: boolean\n proxyEnv: boolean\n idleTimeoutSeconds?: number\n upstreamTimeoutSeconds?: number\n}\n\nasync function maybeCopyClaudeCodeCommand(serverUrl: string): Promise<void> {\n if (!state.cache.models) {\n return\n }\n\n const selectableModels = state.cache.models.data.filter(\n model => model.model_picker_enabled,\n )\n const modelOptions\n = selectableModels.length > 0 ? selectableModels : state.cache.models.data\n\n const selectedModel = await consola.prompt(\n 'Select a model to use with Claude Code',\n {\n type: 'select',\n options: modelOptions.map(model => model.id),\n },\n )\n\n const selectedSmallModel = await consola.prompt(\n 'Select a small model to use with Claude Code',\n {\n type: 'select',\n options: modelOptions.map(model => model.id),\n },\n )\n\n const command = generateEnvScript(\n {\n ANTHROPIC_BASE_URL: serverUrl,\n ANTHROPIC_AUTH_TOKEN: 'dummy',\n ANTHROPIC_MODEL: selectedModel,\n ANTHROPIC_DEFAULT_SONNET_MODEL: selectedModel,\n ANTHROPIC_SMALL_FAST_MODEL: selectedSmallModel,\n ANTHROPIC_DEFAULT_HAIKU_MODEL: selectedSmallModel,\n DISABLE_NON_ESSENTIAL_MODEL_CALLS: '1',\n CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1',\n },\n 'claude',\n )\n\n try {\n clipboard.writeSync(command)\n consola.success('Copied Claude Code command to clipboard!')\n }\n catch {\n consola.warn(\n 'Failed to copy to clipboard. Here is the Claude Code command:',\n )\n consola.log(command)\n }\n}\n\nexport async function runServer(options: RunServerOptions): Promise<void> {\n const accountType: ReturnType<typeof getClientConfig>['accountType']\n = (\n options.accountType === 'individual'\n || options.accountType === 'business'\n || options.accountType === 'enterprise'\n )\n ? options.accountType\n : 'individual'\n\n if (accountType !== options.accountType) {\n consola.warn(\n `Unknown account type \"${options.accountType}\". Falling back to \"individual\".`,\n )\n }\n\n if (options.proxyEnv) {\n initProxyFromEnv()\n }\n\n if (options.verbose) {\n consola.level = 5\n consola.info('Verbose logging enabled')\n }\n\n state.config.accountType = accountType\n if (accountType !== 'individual') {\n consola.info(`Using ${accountType} plan GitHub account`)\n }\n\n if (options.githubToken) {\n state.auth.githubToken = options.githubToken\n consola.info('Using provided GitHub token')\n }\n\n state.config.manualApprove = options.manual\n state.config.rateLimitSeconds = options.rateLimit\n state.config.rateLimitWait = options.rateLimitWait\n state.config.showToken = options.showToken\n state.config.upstreamTimeoutSeconds = options.upstreamTimeoutSeconds\n\n await ensurePaths()\n await readConfig()\n await cacheVSCodeVersion()\n\n if (!options.githubToken) {\n await setupGitHubToken()\n }\n\n await setupCopilotToken()\n\n const clientConfig: ReturnType<typeof getClientConfig> = {\n ...getClientConfig(state),\n accountType,\n }\n const copilotClient = new CopilotClient(state.auth, clientConfig)\n await cacheModels(copilotClient)\n\n consola.info(\n `Available models: \\n${state.cache.models?.data.map(model => `- ${model.id}`).join('\\n')}`,\n )\n\n const serverUrl = `http://localhost:${options.port}`\n\n if (options.claudeCode) {\n invariant(state.cache.models, 'Models should be loaded by now')\n await maybeCopyClaudeCodeCommand(serverUrl)\n }\n\n serve({\n fetch: server.fetch as ServerHandler,\n port: options.port,\n bun:\n options.idleTimeoutSeconds === undefined\n ? undefined\n : { idleTimeout: options.idleTimeoutSeconds },\n })\n}\n\nexport const start = defineCommand({\n meta: {\n name: 'start',\n description: 'Start the Copilot API server',\n },\n args: {\n 'port': {\n alias: 'p',\n type: 'string',\n default: '4141',\n description: 'Port to listen on',\n },\n 'verbose': {\n alias: 'v',\n type: 'boolean',\n default: false,\n description: 'Enable verbose logging',\n },\n 'account-type': {\n alias: 'a',\n type: 'string',\n default: 'individual',\n description: 'Account type to use (individual, business, enterprise)',\n },\n 'manual': {\n type: 'boolean',\n default: false,\n description: 'Enable manual request approval',\n },\n 'rate-limit': {\n alias: 'r',\n type: 'string',\n description: 'Rate limit in seconds between requests',\n },\n 'wait': {\n alias: 'w',\n type: 'boolean',\n default: false,\n description:\n 'Wait instead of error when rate limit is hit. Has no effect if rate limit is not set',\n },\n 'github-token': {\n alias: 'g',\n type: 'string',\n description:\n 'Provide GitHub token directly (must be generated using the `auth` subcommand)',\n },\n 'claude-code': {\n alias: 'c',\n type: 'boolean',\n default: false,\n description:\n 'Generate a command to launch Claude Code with Copilot API config',\n },\n 'show-token': {\n type: 'boolean',\n default: false,\n description: 'Show GitHub and Copilot tokens on fetch and refresh',\n },\n 'proxy-env': {\n type: 'boolean',\n default: false,\n description: 'Initialize proxy from environment variables',\n },\n 'idle-timeout': {\n type: 'string',\n default: '120',\n description: 'Bun server idle timeout in seconds',\n },\n 'upstream-timeout': {\n type: 'string',\n default: '300',\n description: 'Upstream request timeout in seconds (0 to disable)',\n },\n },\n run({ args }) {\n const rateLimitRaw = args['rate-limit']\n const rateLimit\n = rateLimitRaw === undefined ? undefined : Number.parseInt(rateLimitRaw, 10)\n const idleTimeoutRaw = args['idle-timeout']\n let idleTimeoutSeconds\n = idleTimeoutRaw === undefined\n ? undefined\n : (\n Number.parseInt(idleTimeoutRaw, 10)\n )\n if (\n idleTimeoutSeconds !== undefined\n && (Number.isNaN(idleTimeoutSeconds) || idleTimeoutSeconds < 0)\n ) {\n consola.warn(\n `Invalid --idle-timeout value \"${idleTimeoutRaw}\". Falling back to Bun default.`,\n )\n idleTimeoutSeconds = undefined\n }\n\n const upstreamTimeoutRaw = args['upstream-timeout']\n let upstreamTimeoutSeconds\n = upstreamTimeoutRaw === undefined\n ? undefined\n : Number.parseInt(upstreamTimeoutRaw, 10)\n if (\n upstreamTimeoutSeconds !== undefined\n && (Number.isNaN(upstreamTimeoutSeconds) || upstreamTimeoutSeconds < 0)\n ) {\n consola.warn(\n `Invalid --upstream-timeout value \"${upstreamTimeoutRaw}\". Falling back to default (300s).`,\n )\n upstreamTimeoutSeconds = undefined\n }\n\n return runServer({\n port: Number.parseInt(args.port, 10),\n verbose: args.verbose,\n accountType: args['account-type'],\n manual: args.manual,\n rateLimit,\n rateLimitWait: args.wait,\n githubToken: args['github-token'],\n claudeCode: args['claude-code'],\n showToken: args['show-token'],\n proxyEnv: args['proxy-env'],\n idleTimeoutSeconds,\n upstreamTimeoutSeconds,\n })\n },\n})\n","#!/usr/bin/env node\n\nimport process from 'node:process'\nimport { defineCommand, runMain } from 'citty'\nimport consola from 'consola'\n\nimport { auth } from './auth'\nimport { checkUsage } from './check-usage'\nimport { debug } from './debug'\nimport { start } from './start'\n\nconst main = defineCommand({\n meta: {\n name: 'ghc-proxy',\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})\n\nrunMain(main).catch((error) => {\n consola.error('Failed to start CLI:', error)\n process.exitCode = 1\n})\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ghc-proxy",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.3",
|
|
5
5
|
"description": "GitHub Copilot to OpenAI/Anthropic API proxy - Use Copilot with Claude Code, Cursor, and more",
|
|
6
6
|
"author": "wxxb789 <wxxb789@outlook.com>",
|
|
7
7
|
"homepage": "https://github.com/wxxb789/ghc-proxy",
|
|
@@ -29,7 +29,10 @@
|
|
|
29
29
|
"lint:all": "eslint --cache .",
|
|
30
30
|
"prepack": "bun run build",
|
|
31
31
|
"prepare": "simple-git-hooks",
|
|
32
|
-
"release": "
|
|
32
|
+
"release": "bun run release:patch",
|
|
33
|
+
"release:patch": "bumpp patch --yes --commit --tag",
|
|
34
|
+
"release:minor": "bumpp minor --yes --commit --tag",
|
|
35
|
+
"release:major": "bumpp major --yes --commit --tag",
|
|
33
36
|
"start": "NODE_ENV=production bun run ./src/main.ts",
|
|
34
37
|
"typecheck": "tsc"
|
|
35
38
|
},
|