@openhoo/hoopilot 0.5.4 → 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/dist/cli.js +19 -0
- package/dist/cli.js.map +1 -1
- package/dist/codexx.js +11 -2
- package/dist/codexx.js.map +1 -1
- package/dist/index.cjs +19 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/codexx.js
CHANGED
|
@@ -20,12 +20,21 @@ function buildCodexxInvocation(argv, env = process.env) {
|
|
|
20
20
|
const baseUrl = env.CODEXX_BASE_URL ?? DEFAULT_BASE_URL;
|
|
21
21
|
const apiKey = env.CODEXX_API_KEY ?? env.HOOPILOT_API_KEY ?? env.OPENAI_API_KEY ?? DEFAULT_API_KEY;
|
|
22
22
|
const command = env.CODEXX_CODEX_BIN ?? DEFAULT_CODEX_BIN;
|
|
23
|
+
const providerConfig = [
|
|
24
|
+
'{ name = "Hoopilot"',
|
|
25
|
+
`base_url = ${JSON.stringify(baseUrl)}`,
|
|
26
|
+
'env_key = "OPENAI_API_KEY"',
|
|
27
|
+
'wire_api = "responses"',
|
|
28
|
+
"supports_websockets = false }"
|
|
29
|
+
].join(", ");
|
|
23
30
|
return {
|
|
24
31
|
args: [
|
|
25
32
|
"--disable",
|
|
26
33
|
"network_proxy",
|
|
27
34
|
"-c",
|
|
28
|
-
|
|
35
|
+
'model_provider="hoopilot"',
|
|
36
|
+
"-c",
|
|
37
|
+
`model_providers.hoopilot=${providerConfig}`,
|
|
29
38
|
...argv
|
|
30
39
|
],
|
|
31
40
|
command,
|
|
@@ -80,7 +89,7 @@ Environment:
|
|
|
80
89
|
OPENAI_API_KEY Used as the API key when both CODEXX_API_KEY and HOOPILOT_API_KEY are unset.
|
|
81
90
|
CODEXX_CODEX_BIN Codex executable to run. Default: ${DEFAULT_CODEX_BIN}
|
|
82
91
|
|
|
83
|
-
codexx does not start Hoopilot and does not change your shell environment. It disables Codex's network_proxy feature and removes proxy variables only from the spawned Codex process.`;
|
|
92
|
+
codexx does not start Hoopilot and does not change your shell environment. It selects a temporary Hoopilot model provider with Responses WebSockets disabled, disables Codex's network_proxy feature, and removes proxy variables only from the spawned Codex process.`;
|
|
84
93
|
}
|
|
85
94
|
function signalNumber(signal) {
|
|
86
95
|
return osConstants.signals[signal] ?? 1;
|
package/dist/codexx.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/codexx.ts"],"sourcesContent":["#!/usr/bin/env bun\n\nimport { spawn } from \"node:child_process\";\nimport { constants as osConstants } from \"node:os\";\n\nconst DEFAULT_BASE_URL = \"http://127.0.0.1:4141/v1\";\nconst DEFAULT_API_KEY = \"local-key\";\nconst DEFAULT_CODEX_BIN = \"codex\";\nconst PROXY_ENV_KEYS = [\n \"ALL_PROXY\",\n \"HTTPS_PROXY\",\n \"HTTP_PROXY\",\n \"NO_PROXY\",\n \"all_proxy\",\n \"https_proxy\",\n \"http_proxy\",\n \"no_proxy\",\n];\n\nexport interface CodexxInvocation {\n args: string[];\n command: string;\n env: NodeJS.ProcessEnv;\n}\n\nexport function buildCodexxInvocation(\n argv: string[],\n env: NodeJS.ProcessEnv = process.env,\n): CodexxInvocation {\n const baseUrl = env.CODEXX_BASE_URL ?? DEFAULT_BASE_URL;\n const apiKey =\n env.CODEXX_API_KEY ?? env.HOOPILOT_API_KEY ?? env.OPENAI_API_KEY ?? DEFAULT_API_KEY;\n const command = env.CODEXX_CODEX_BIN ?? DEFAULT_CODEX_BIN;\n\n return {\n args: [\n \"--disable\",\n \"network_proxy\",\n \"-c\",\n `
|
|
1
|
+
{"version":3,"sources":["../src/codexx.ts"],"sourcesContent":["#!/usr/bin/env bun\n\nimport { spawn } from \"node:child_process\";\nimport { constants as osConstants } from \"node:os\";\n\nconst DEFAULT_BASE_URL = \"http://127.0.0.1:4141/v1\";\nconst DEFAULT_API_KEY = \"local-key\";\nconst DEFAULT_CODEX_BIN = \"codex\";\nconst PROXY_ENV_KEYS = [\n \"ALL_PROXY\",\n \"HTTPS_PROXY\",\n \"HTTP_PROXY\",\n \"NO_PROXY\",\n \"all_proxy\",\n \"https_proxy\",\n \"http_proxy\",\n \"no_proxy\",\n];\n\nexport interface CodexxInvocation {\n args: string[];\n command: string;\n env: NodeJS.ProcessEnv;\n}\n\nexport function buildCodexxInvocation(\n argv: string[],\n env: NodeJS.ProcessEnv = process.env,\n): CodexxInvocation {\n const baseUrl = env.CODEXX_BASE_URL ?? DEFAULT_BASE_URL;\n const apiKey =\n env.CODEXX_API_KEY ?? env.HOOPILOT_API_KEY ?? env.OPENAI_API_KEY ?? DEFAULT_API_KEY;\n const command = env.CODEXX_CODEX_BIN ?? DEFAULT_CODEX_BIN;\n const providerConfig = [\n '{ name = \"Hoopilot\"',\n `base_url = ${JSON.stringify(baseUrl)}`,\n 'env_key = \"OPENAI_API_KEY\"',\n 'wire_api = \"responses\"',\n \"supports_websockets = false }\",\n ].join(\", \");\n\n return {\n args: [\n \"--disable\",\n \"network_proxy\",\n \"-c\",\n 'model_provider=\"hoopilot\"',\n \"-c\",\n `model_providers.hoopilot=${providerConfig}`,\n ...argv,\n ],\n command,\n env: withoutProxyEnv({\n ...env,\n OPENAI_API_KEY: apiKey,\n }),\n };\n}\n\nfunction withoutProxyEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {\n const next = { ...env };\n for (const key of PROXY_ENV_KEYS) {\n delete next[key];\n }\n return next;\n}\n\nexport async function main(argv = Bun.argv.slice(2), env = process.env): Promise<void> {\n if (argv.length === 1 && (argv[0] === \"--help\" || argv[0] === \"-h\")) {\n console.log(helpText());\n return;\n }\n\n const invocation = buildCodexxInvocation(argv, env);\n const child = spawn(invocation.command, invocation.args, {\n env: invocation.env,\n shell: process.platform === \"win32\",\n stdio: \"inherit\",\n });\n\n const exitCode = await new Promise<number>((resolve, reject) => {\n child.once(\"error\", reject);\n child.once(\"exit\", (code, signal) => {\n if (typeof code === \"number\") {\n resolve(code);\n return;\n }\n resolve(signal ? 128 + signalNumber(signal) : 1);\n });\n });\n\n process.exitCode = exitCode;\n}\n\nfunction helpText(): string {\n return `codexx\n\nRun Codex against an already-running local Hoopilot server.\n\nUsage:\n codexx [codex options] [prompt]\n\nEnvironment:\n CODEXX_BASE_URL OpenAI-compatible base URL. Default: ${DEFAULT_BASE_URL}\n CODEXX_API_KEY API key sent to the local Hoopilot server.\n HOOPILOT_API_KEY Used as the API key when CODEXX_API_KEY is unset.\n OPENAI_API_KEY Used as the API key when both CODEXX_API_KEY and HOOPILOT_API_KEY are unset.\n CODEXX_CODEX_BIN Codex executable to run. Default: ${DEFAULT_CODEX_BIN}\n\ncodexx does not start Hoopilot and does not change your shell environment. It selects a temporary Hoopilot model provider with Responses WebSockets disabled, disables Codex's network_proxy feature, and removes proxy variables only from the spawned Codex process.`;\n}\n\nfunction signalNumber(signal: NodeJS.Signals): number {\n return osConstants.signals[signal] ?? 1;\n}\n\nif (import.meta.main) {\n main().catch((error: unknown) => {\n console.error(error instanceof Error ? error.message : String(error));\n process.exit(1);\n });\n}\n"],"mappings":";;;AAEA,SAAS,aAAa;AACtB,SAAS,aAAa,mBAAmB;AAEzC,IAAM,mBAAmB;AACzB,IAAM,kBAAkB;AACxB,IAAM,oBAAoB;AAC1B,IAAM,iBAAiB;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAQO,SAAS,sBACd,MACA,MAAyB,QAAQ,KACf;AAClB,QAAM,UAAU,IAAI,mBAAmB;AACvC,QAAM,SACJ,IAAI,kBAAkB,IAAI,oBAAoB,IAAI,kBAAkB;AACtE,QAAM,UAAU,IAAI,oBAAoB;AACxC,QAAM,iBAAiB;AAAA,IACrB;AAAA,IACA,cAAc,KAAK,UAAU,OAAO,CAAC;AAAA,IACrC;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AAEX,SAAO;AAAA,IACL,MAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,4BAA4B,cAAc;AAAA,MAC1C,GAAG;AAAA,IACL;AAAA,IACA;AAAA,IACA,KAAK,gBAAgB;AAAA,MACnB,GAAG;AAAA,MACH,gBAAgB;AAAA,IAClB,CAAC;AAAA,EACH;AACF;AAEA,SAAS,gBAAgB,KAA2C;AAClE,QAAM,OAAO,EAAE,GAAG,IAAI;AACtB,aAAW,OAAO,gBAAgB;AAChC,WAAO,KAAK,GAAG;AAAA,EACjB;AACA,SAAO;AACT;AAEA,eAAsB,KAAK,OAAO,IAAI,KAAK,MAAM,CAAC,GAAG,MAAM,QAAQ,KAAoB;AACrF,MAAI,KAAK,WAAW,MAAM,KAAK,CAAC,MAAM,YAAY,KAAK,CAAC,MAAM,OAAO;AACnE,YAAQ,IAAI,SAAS,CAAC;AACtB;AAAA,EACF;AAEA,QAAM,aAAa,sBAAsB,MAAM,GAAG;AAClD,QAAM,QAAQ,MAAM,WAAW,SAAS,WAAW,MAAM;AAAA,IACvD,KAAK,WAAW;AAAA,IAChB,OAAO,QAAQ,aAAa;AAAA,IAC5B,OAAO;AAAA,EACT,CAAC;AAED,QAAM,WAAW,MAAM,IAAI,QAAgB,CAAC,SAAS,WAAW;AAC9D,UAAM,KAAK,SAAS,MAAM;AAC1B,UAAM,KAAK,QAAQ,CAAC,MAAM,WAAW;AACnC,UAAI,OAAO,SAAS,UAAU;AAC5B,gBAAQ,IAAI;AACZ;AAAA,MACF;AACA,cAAQ,SAAS,MAAM,aAAa,MAAM,IAAI,CAAC;AAAA,IACjD,CAAC;AAAA,EACH,CAAC;AAED,UAAQ,WAAW;AACrB;AAEA,SAAS,WAAmB;AAC1B,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,8DAQqD,gBAAgB;AAAA;AAAA;AAAA;AAAA,2DAInB,iBAAiB;AAAA;AAAA;AAG5E;AAEA,SAAS,aAAa,QAAgC;AACpD,SAAO,YAAY,QAAQ,MAAM,KAAK;AACxC;AAEA,IAAI,YAAY,MAAM;AACpB,OAAK,EAAE,MAAM,CAAC,UAAmB;AAC/B,YAAQ,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AACpE,YAAQ,KAAK,CAAC;AAAA,EAChB,CAAC;AACH;","names":[]}
|
package/dist/index.cjs
CHANGED
|
@@ -999,6 +999,13 @@ function createHoopilotHandler(options = {}) {
|
|
|
999
999
|
{ logger: requestLogger, requestId, startedAt }
|
|
1000
1000
|
);
|
|
1001
1001
|
}
|
|
1002
|
+
if (request.method === "GET" && apiPath === "/v1/responses") {
|
|
1003
|
+
return finishResponse(websocketUnsupportedResponse(), {
|
|
1004
|
+
logger: requestLogger,
|
|
1005
|
+
requestId,
|
|
1006
|
+
startedAt
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1002
1009
|
if (request.method === "GET" && apiPath === "/v1/models") {
|
|
1003
1010
|
return finishResponse(await handleModels(client, request.signal, requestLogger), {
|
|
1004
1011
|
logger: requestLogger,
|
|
@@ -1210,6 +1217,15 @@ function jsonError(status, code, message) {
|
|
|
1210
1217
|
status
|
|
1211
1218
|
);
|
|
1212
1219
|
}
|
|
1220
|
+
function websocketUnsupportedResponse() {
|
|
1221
|
+
const response = jsonError(
|
|
1222
|
+
426,
|
|
1223
|
+
"websocket_not_supported",
|
|
1224
|
+
"Hoopilot does not support Responses WebSocket transport; retry with HTTP Responses API."
|
|
1225
|
+
);
|
|
1226
|
+
response.headers.set("upgrade", "websocket");
|
|
1227
|
+
return response;
|
|
1228
|
+
}
|
|
1213
1229
|
function corsHeaders() {
|
|
1214
1230
|
return {
|
|
1215
1231
|
"access-control-allow-headers": "authorization, content-type, x-api-key",
|
|
@@ -1319,6 +1335,9 @@ function routeFor(method, path) {
|
|
|
1319
1335
|
if (method === "POST" && path === "/v1/responses") {
|
|
1320
1336
|
return "responses";
|
|
1321
1337
|
}
|
|
1338
|
+
if (method === "GET" && path === "/v1/responses") {
|
|
1339
|
+
return "responses_websocket";
|
|
1340
|
+
}
|
|
1322
1341
|
return "not_found";
|
|
1323
1342
|
}
|
|
1324
1343
|
function isStreamingResponse(response) {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/auth-store.ts","../src/auth.ts","../src/copilot.ts","../src/github-device.ts","../src/logger.ts","../src/openai.ts","../src/server.ts"],"sourcesContent":["export { CopilotAuth, CopilotAuthError } from \"./auth\";\nexport { authStorePath, readStoredCopilotAuth, writeStoredCopilotAuth } from \"./auth-store\";\nexport { CopilotClient } from \"./copilot\";\nexport { githubCopilotDeviceLogin } from \"./github-device\";\nexport {\n createHoopilotLogger,\n DEFAULT_LOG_FORMAT,\n DEFAULT_LOG_LEVEL,\n noopLogger,\n parseLogFormat,\n parseLogLevel,\n} from \"./logger\";\nexport {\n chatCompletionToCompletion,\n chatCompletionToResponse,\n completionsRequestToChatCompletion,\n DEFAULT_MODEL,\n fallbackModels,\n normalizeModelsResponse,\n responsesRequestToChatCompletion,\n responsesStreamFromChatStream,\n} from \"./openai\";\nexport { createHoopilotHandler, startHoopilotServer } from \"./server\";\nexport type {\n CopilotAccess,\n CopilotAuthOptions,\n FetchLike,\n HoopilotLogger,\n HoopilotLoggerOptions,\n HoopilotServerOptions,\n JsonObject,\n LogFields,\n LogFormat,\n Logger,\n LogLevel,\n LogMethod,\n StartedHoopilotServer,\n} from \"./types\";\n","import { chmodSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\nexport interface StoredCopilotAuth {\n apiBaseUrl?: string;\n createdAt?: string;\n githubDomain?: string;\n source?: string;\n token: string;\n}\n\nexport function authStorePath(env: NodeJS.ProcessEnv = process.env): string {\n if (env.HOOPILOT_AUTH_FILE) {\n return env.HOOPILOT_AUTH_FILE;\n }\n\n const base =\n env.XDG_CONFIG_HOME ??\n env.APPDATA ??\n (env.HOME ? join(env.HOME, \".config\") : join(process.cwd(), \".config\"));\n return join(base, \"hoopilot\", \"auth.json\");\n}\n\nexport function readStoredCopilotAuth(path = authStorePath()): StoredCopilotAuth | undefined {\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf8\"));\n if (!parsed || typeof parsed !== \"object\") {\n return undefined;\n }\n const token = typeof parsed.token === \"string\" ? parsed.token.trim() : \"\";\n if (!token) {\n return undefined;\n }\n return {\n apiBaseUrl: typeof parsed.apiBaseUrl === \"string\" ? parsed.apiBaseUrl : undefined,\n createdAt: typeof parsed.createdAt === \"string\" ? parsed.createdAt : undefined,\n githubDomain: typeof parsed.githubDomain === \"string\" ? parsed.githubDomain : undefined,\n source: typeof parsed.source === \"string\" ? parsed.source : undefined,\n token,\n };\n } catch {\n return undefined;\n }\n}\n\nexport function writeStoredCopilotAuth(auth: StoredCopilotAuth, path = authStorePath()): void {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(\n path,\n `${JSON.stringify(\n {\n ...auth,\n createdAt: auth.createdAt ?? new Date().toISOString(),\n },\n null,\n 2,\n )}\\n`,\n { mode: 0o600 },\n );\n try {\n chmodSync(path, 0o600);\n } catch {\n // chmod is best-effort on Windows.\n }\n}\n","import { readStoredCopilotAuth } from \"./auth-store\";\nimport type { CopilotAccess, CopilotAuthOptions } from \"./types\";\n\nconst DEFAULT_COPILOT_API_BASE_URL = \"https://api.githubcopilot.com\";\nconst REFRESH_SKEW_MS = 60_000;\nconst STORED_TOKEN_TTL_MS = 10 * 60_000;\n\nexport class CopilotAuthError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"CopilotAuthError\";\n }\n}\n\nexport class CopilotAuth {\n readonly #authStorePath?: string;\n readonly #copilotApiBaseUrl: string;\n #cachedAccess?: CopilotAccess;\n\n constructor(options: CopilotAuthOptions = {}) {\n this.#authStorePath = options.authStorePath ?? options.env?.HOOPILOT_AUTH_FILE;\n this.#copilotApiBaseUrl = trimTrailingSlash(\n options.copilotApiBaseUrl ??\n options.env?.COPILOT_API_BASE_URL ??\n DEFAULT_COPILOT_API_BASE_URL,\n );\n }\n\n async getAccess(): Promise<CopilotAccess> {\n if (this.#cachedAccess && this.#cachedAccess.expiresAtMs - REFRESH_SKEW_MS > Date.now()) {\n return this.#cachedAccess;\n }\n\n const stored = readStoredCopilotAuth(this.#authStorePath);\n if (stored) {\n return this.#cacheAccess({\n apiBaseUrl: trimTrailingSlash(stored.apiBaseUrl ?? this.#copilotApiBaseUrl),\n expiresAtMs: Date.now() + STORED_TOKEN_TTL_MS,\n source: \"github-copilot-oauth\",\n token: stored.token,\n });\n }\n\n throw new CopilotAuthError(\n \"No GitHub Copilot OAuth credential found. Run `hoopilot login` to sign in through your browser.\",\n );\n }\n\n #cacheAccess(access: CopilotAccess): CopilotAccess {\n this.#cachedAccess = access;\n return access;\n }\n}\n\nfunction trimTrailingSlash(value: string): string {\n return value.replace(/\\/+$/, \"\");\n}\n","import { CopilotAuth } from \"./auth\";\nimport type { CopilotAuthOptions, FetchLike, JsonObject } from \"./types\";\n\nexport class CopilotClient {\n readonly #auth: CopilotAuth;\n readonly #fetch: FetchLike;\n\n constructor(options: CopilotAuthOptions = {}) {\n this.#auth = new CopilotAuth(options);\n this.#fetch = options.fetch ?? fetch;\n }\n\n async chatCompletions(body: JsonObject, signal?: AbortSignal): Promise<Response> {\n return this.fetchCopilot(\"/chat/completions\", {\n body: JSON.stringify(body),\n headers: {\n \"content-type\": \"application/json\",\n },\n method: \"POST\",\n signal,\n });\n }\n\n async forwardChatCompletions(body: string, signal?: AbortSignal): Promise<Response> {\n return this.fetchCopilot(\"/chat/completions\", {\n body,\n headers: {\n \"content-type\": \"application/json\",\n },\n method: \"POST\",\n signal,\n });\n }\n\n async models(signal?: AbortSignal): Promise<Response> {\n return this.fetchCopilot(\"/models\", {\n headers: {\n accept: \"application/json\",\n },\n method: \"GET\",\n signal,\n });\n }\n\n async fetchCopilot(path: string, init: RequestInit): Promise<Response> {\n const access = await this.#auth.getAccess();\n const headers = new Headers(init.headers);\n headers.set(\"accept\", headers.get(\"accept\") ?? \"application/json\");\n headers.set(\"authorization\", `Bearer ${access.token}`);\n headers.set(\"copilot-integration-id\", \"vscode-chat\");\n headers.set(\"editor-plugin-version\", \"hoopilot/0.1.0\");\n headers.set(\"editor-version\", \"Hoopilot/0.1.0\");\n headers.set(\"openai-intent\", \"conversation-panel\");\n headers.set(\"user-agent\", \"hoopilot/0.1.0\");\n headers.set(\"x-github-api-version\", \"2026-06-01\");\n\n return this.#fetch(`${access.apiBaseUrl}${path}`, {\n ...init,\n headers,\n });\n }\n}\n","import { setTimeout as sleep } from \"node:timers/promises\";\nimport type { FetchLike, Logger } from \"./types\";\n\nexport const DEFAULT_GITHUB_COPILOT_CLIENT_ID = \"Iv23lijnNxm2e9UX3CF8\";\nconst DEFAULT_GITHUB_DOMAIN = \"github.com\";\nconst DEVICE_GRANT_TYPE = \"urn:ietf:params:oauth:grant-type:device_code\";\nconst POLLING_SAFETY_MARGIN_MS = 3_000;\n\nexport interface GithubCopilotDeviceLoginOptions {\n clientId?: string;\n domain?: string;\n env?: NodeJS.ProcessEnv;\n fetch?: FetchLike;\n logger?: Logger;\n openBrowser?: (url: string) => void | Promise<void>;\n sleep?: (ms: number) => Promise<void>;\n}\n\nexport interface GithubCopilotDeviceLoginResult {\n domain: string;\n token: string;\n}\n\ninterface DeviceCodeResponse {\n device_code?: string;\n expires_in?: number;\n interval?: number;\n user_code?: string;\n verification_uri?: string;\n}\n\ninterface DeviceTokenResponse {\n access_token?: string;\n error?: string;\n error_description?: string;\n interval?: number;\n}\n\nexport async function githubCopilotDeviceLogin(\n options: GithubCopilotDeviceLoginOptions = {},\n): Promise<GithubCopilotDeviceLoginResult> {\n const env = options.env ?? process.env;\n const fetcher = options.fetch ?? fetch;\n const sleeper = options.sleep ?? sleep;\n const domain = normalizeDomain(\n options.domain ?? env.HOOPILOT_GITHUB_DOMAIN ?? DEFAULT_GITHUB_DOMAIN,\n );\n const clientId =\n options.clientId ??\n env.HOOPILOT_GITHUB_CLIENT_ID ??\n env.COPILOT_GITHUB_CLIENT_ID ??\n DEFAULT_GITHUB_COPILOT_CLIENT_ID;\n\n const device = await requestDeviceCode(fetcher, domain, clientId);\n const verificationUrl = device.verification_uri;\n const userCode = device.user_code;\n const deviceCode = device.device_code;\n if (!verificationUrl || !userCode || !deviceCode) {\n throw new Error(\"GitHub device authorization response is missing required fields.\");\n }\n\n options.logger?.info(`First copy your one-time code: ${userCode}`);\n options.logger?.info(`Open ${verificationUrl} in your browser to authorize Hoopilot.`);\n await options.openBrowser?.(verificationUrl);\n\n return {\n domain,\n token: await pollForAccessToken(fetcher, sleeper, domain, clientId, {\n deviceCode,\n expiresIn: positiveSeconds(device.expires_in, 900),\n interval: positiveSeconds(device.interval, 5),\n }),\n };\n}\n\nasync function requestDeviceCode(\n fetcher: FetchLike,\n domain: string,\n clientId: string,\n): Promise<DeviceCodeResponse> {\n const response = await fetcher(`https://${domain}/login/device/code`, {\n body: JSON.stringify({\n client_id: clientId,\n scope: \"read:user\",\n }),\n headers: oauthHeaders(),\n method: \"POST\",\n });\n if (!response.ok) {\n throw new Error(\n `GitHub device authorization failed with ${response.status}: ${await safeResponseText(\n response,\n )}`,\n );\n }\n return (await response.json()) as DeviceCodeResponse;\n}\n\nasync function pollForAccessToken(\n fetcher: FetchLike,\n sleeper: (ms: number) => Promise<void>,\n domain: string,\n clientId: string,\n device: { deviceCode: string; expiresIn: number; interval: number },\n): Promise<string> {\n let intervalMs = device.interval * 1000 + POLLING_SAFETY_MARGIN_MS;\n const deadline = Date.now() + device.expiresIn * 1000;\n\n while (Date.now() < deadline) {\n await sleeper(intervalMs);\n const response = await fetcher(`https://${domain}/login/oauth/access_token`, {\n body: JSON.stringify({\n client_id: clientId,\n device_code: device.deviceCode,\n grant_type: DEVICE_GRANT_TYPE,\n }),\n headers: oauthHeaders(),\n method: \"POST\",\n });\n\n if (!response.ok) {\n throw new Error(\n `GitHub device token exchange failed with ${response.status}: ${await safeResponseText(\n response,\n )}`,\n );\n }\n\n const data = (await response.json()) as DeviceTokenResponse;\n if (data.access_token) {\n return data.access_token;\n }\n\n if (data.error === \"authorization_pending\") {\n continue;\n }\n if (data.error === \"slow_down\") {\n intervalMs =\n positiveSeconds(data.interval, device.interval + 5) * 1000 + POLLING_SAFETY_MARGIN_MS;\n continue;\n }\n if (data.error === \"expired_token\") {\n throw new Error(\"GitHub device login expired. Run `hoopilot login` again.\");\n }\n if (data.error === \"access_denied\") {\n throw new Error(\"GitHub device login was cancelled.\");\n }\n if (data.error) {\n throw new Error(data.error_description || `GitHub device login failed: ${data.error}`);\n }\n }\n\n throw new Error(\"GitHub device login timed out. Run `hoopilot login` again.\");\n}\n\nfunction oauthHeaders(): Headers {\n const headers = new Headers();\n headers.set(\"accept\", \"application/json\");\n headers.set(\"content-type\", \"application/json\");\n headers.set(\"user-agent\", \"hoopilot\");\n return headers;\n}\n\nfunction normalizeDomain(value: string): string {\n return value.replace(/^https?:\\/\\//, \"\").replace(/\\/+$/, \"\");\n}\n\nfunction positiveSeconds(value: unknown, fallback: number): number {\n return typeof value === \"number\" && Number.isFinite(value) && value > 0 ? value : fallback;\n}\n\nasync function safeResponseText(response: Response): Promise<string> {\n const text = await response.text();\n return text.slice(0, 500);\n}\n","import pino from \"pino\";\nimport pretty from \"pino-pretty\";\nimport type { HoopilotLogger, HoopilotLoggerOptions, LogFormat, LogLevel } from \"./types\";\n\nexport const DEFAULT_LOG_FORMAT: LogFormat = \"pretty\";\nexport const DEFAULT_LOG_LEVEL: LogLevel = \"info\";\n\nconst LOG_FORMATS = [\"json\", \"pretty\"] as const;\nconst LOG_LEVELS = [\"trace\", \"debug\", \"info\", \"warn\", \"error\", \"fatal\", \"silent\"] as const;\nconst REDACT_PATHS = [\n \"apiKey\",\n \"authorization\",\n \"cookie\",\n \"headers.authorization\",\n \"headers.Authorization\",\n \"headers.cookie\",\n \"headers.Cookie\",\n \"headers.x-api-key\",\n \"headers.X-Api-Key\",\n \"token\",\n \"*.apiKey\",\n \"*.authorization\",\n \"*.cookie\",\n \"*.token\",\n \"*.headers.authorization\",\n \"*.headers.Authorization\",\n \"*.headers.cookie\",\n \"*.headers.Cookie\",\n \"*.headers.x-api-key\",\n \"*.headers.X-Api-Key\",\n];\n\nexport const noopLogger: HoopilotLogger = {\n child: () => noopLogger,\n debug: () => {},\n error: () => {},\n fatal: () => {},\n info: () => {},\n trace: () => {},\n warn: () => {},\n};\n\nexport function createHoopilotLogger(options: HoopilotLoggerOptions = {}): HoopilotLogger {\n const env = options.env ?? process.env;\n const level = parseLogLevel(options.level ?? env.HOOPILOT_LOG_LEVEL);\n const format = parseLogFormat(options.format ?? env.HOOPILOT_LOG_FORMAT);\n const pinoOptions: pino.LoggerOptions = {\n base: {\n service: \"hoopilot\",\n ...options.base,\n },\n level,\n redact: {\n censor: \"[Redacted]\",\n paths: REDACT_PATHS,\n },\n timestamp: pino.stdTimeFunctions.isoTime,\n };\n\n if (format === \"pretty\") {\n return pino(\n pinoOptions,\n pretty({\n colorize: options.colorize ?? process.stderr.isTTY,\n destination: options.stream ?? 1,\n ignore: \"pid,hostname\",\n singleLine: true,\n translateTime: \"SYS:standard\",\n }),\n ) as HoopilotLogger;\n }\n\n if (options.stream) {\n return pino(pinoOptions, options.stream as pino.DestinationStream) as HoopilotLogger;\n }\n return pino(pinoOptions) as HoopilotLogger;\n}\n\nexport function parseLogFormat(value: string | undefined): LogFormat {\n if (!value) {\n return DEFAULT_LOG_FORMAT;\n }\n if (isLogFormat(value)) {\n return value;\n }\n throw new Error(`Invalid log format: ${value}. Expected one of: ${LOG_FORMATS.join(\", \")}.`);\n}\n\nexport function parseLogLevel(value: string | undefined): LogLevel {\n if (!value) {\n return DEFAULT_LOG_LEVEL;\n }\n if (isLogLevel(value)) {\n return value;\n }\n throw new Error(`Invalid log level: ${value}. Expected one of: ${LOG_LEVELS.join(\", \")}.`);\n}\n\nexport function shouldCreateLogger(options: {\n env?: NodeJS.ProcessEnv;\n logFormat?: string;\n logger?: HoopilotLogger;\n logLevel?: string;\n}): boolean {\n return Boolean(\n options.logger ||\n options.logFormat ||\n options.logLevel ||\n options.env?.HOOPILOT_LOG_FORMAT ||\n options.env?.HOOPILOT_LOG_LEVEL,\n );\n}\n\nfunction isLogFormat(value: string): value is LogFormat {\n return (LOG_FORMATS as readonly string[]).includes(value);\n}\n\nfunction isLogLevel(value: string): value is LogLevel {\n return (LOG_LEVELS as readonly string[]).includes(value);\n}\n","import type { JsonObject } from \"./types\";\n\nexport const DEFAULT_MODEL = \"gpt-4.1\";\n\ninterface ResponseStreamOptions {\n model: string;\n responseId?: string;\n}\n\ninterface AccumulatedToolCall {\n arguments: string;\n id: string;\n index: number;\n name: string;\n}\n\nexport function responsesRequestToChatCompletion(request: JsonObject): JsonObject {\n const messages: unknown[] = [];\n const instructions = contentToText(request.instructions);\n if (instructions) {\n messages.push({ content: instructions, role: \"system\" });\n }\n\n for (const message of inputToMessages(request.input)) {\n messages.push(message);\n }\n\n return removeUndefined({\n frequency_penalty: request.frequency_penalty,\n max_tokens: request.max_output_tokens ?? request.max_tokens,\n messages,\n metadata: request.metadata,\n model: contentToText(request.model) || DEFAULT_MODEL,\n presence_penalty: request.presence_penalty,\n reasoning_effort: asRecord(request.reasoning).effort,\n response_format: asRecord(request.text).format,\n seed: request.seed,\n stream: request.stream === true,\n temperature: request.temperature,\n tool_choice: chatToolChoice(request.tool_choice),\n tools: chatTools(request.tools),\n top_p: request.top_p,\n });\n}\n\nexport function completionsRequestToChatCompletion(request: JsonObject): JsonObject {\n return removeUndefined({\n max_tokens: request.max_tokens,\n messages: [{ content: promptToText(request.prompt), role: \"user\" }],\n model: contentToText(request.model) || DEFAULT_MODEL,\n stream: request.stream === true,\n temperature: request.temperature,\n top_p: request.top_p,\n });\n}\n\nexport function chatCompletionToResponse(completion: JsonObject, responseId?: string): JsonObject {\n const id = responseId ?? `resp_${randomId()}`;\n const choice = firstChoice(completion);\n const message = asRecord(choice.message);\n const model = contentToText(completion.model) || DEFAULT_MODEL;\n const output = outputItemsFromMessage(message);\n const usage = responseUsage(completion.usage);\n\n return removeUndefined({\n created_at: epochSeconds(),\n error: null,\n id,\n incomplete_details: null,\n instructions: null,\n max_output_tokens: null,\n metadata: {},\n model,\n object: \"response\",\n output,\n output_text: outputText(output),\n parallel_tool_calls: true,\n status: \"completed\",\n temperature: null,\n tool_choice: \"auto\",\n tools: [],\n top_p: null,\n usage,\n });\n}\n\nexport function chatCompletionToCompletion(completion: JsonObject): JsonObject {\n const choice = firstChoice(completion);\n const message = asRecord(choice.message);\n return removeUndefined({\n choices: [\n {\n finish_reason: choice.finish_reason ?? \"stop\",\n index: 0,\n logprobs: null,\n text: contentToText(message.content),\n },\n ],\n created: completion.created ?? epochSeconds(),\n id: completion.id ?? `cmpl_${randomId()}`,\n model: completion.model ?? DEFAULT_MODEL,\n object: \"text_completion\",\n usage: completion.usage,\n });\n}\n\nexport function normalizeModelsResponse(upstream: unknown): JsonObject {\n const record = asRecord(upstream);\n const data = Array.isArray(record.data) ? record.data : Array.isArray(upstream) ? upstream : [];\n const models = data\n .map((model) => asRecord(model))\n .filter((model) => typeof model.id === \"string\")\n .map((model) => ({\n created: model.created ?? 0,\n id: model.id,\n object: \"model\",\n owned_by: model.owned_by ?? \"github-copilot\",\n }));\n\n return {\n data: models.length > 0 ? models : fallbackModels(),\n object: \"list\",\n };\n}\n\nexport function fallbackModels(): Array<JsonObject> {\n return [\n {\n created: 0,\n id: DEFAULT_MODEL,\n object: \"model\",\n owned_by: \"github-copilot\",\n },\n ];\n}\n\nexport function responsesStreamFromChatStream(\n chatStream: ReadableStream<Uint8Array>,\n options: ResponseStreamOptions,\n): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n const decoder = new TextDecoder();\n const responseId = options.responseId ?? `resp_${randomId()}`;\n const messageId = `msg_${randomId()}`;\n const createdAt = epochSeconds();\n let buffer = \"\";\n let text = \"\";\n const tools = new Map<number, AccumulatedToolCall>();\n\n return new ReadableStream<Uint8Array>({\n async start(controller) {\n const enqueue = (event: string, data: JsonObject | \"[DONE]\") => {\n controller.enqueue(encoder.encode(encodeSse(event, data)));\n };\n\n enqueue(\"response.created\", {\n response: baseStreamResponse(responseId, options.model, createdAt, \"in_progress\", []),\n type: \"response.created\",\n });\n enqueue(\"response.output_item.added\", {\n item: {\n content: [],\n id: messageId,\n role: \"assistant\",\n status: \"in_progress\",\n type: \"message\",\n },\n output_index: 0,\n type: \"response.output_item.added\",\n });\n enqueue(\"response.content_part.added\", {\n content_index: 0,\n item_id: messageId,\n output_index: 0,\n part: {\n annotations: [],\n text: \"\",\n type: \"output_text\",\n },\n type: \"response.content_part.added\",\n });\n\n const reader = chatStream.getReader();\n try {\n while (true) {\n const result = await reader.read();\n if (result.done) {\n break;\n }\n buffer += decoder.decode(result.value, { stream: true });\n const lines = buffer.split(/\\r?\\n/);\n buffer = lines.pop() ?? \"\";\n for (const line of lines) {\n processChatSseLine(line, enqueue, tools, (delta) => {\n text += delta;\n });\n }\n }\n if (buffer) {\n processChatSseLine(buffer, enqueue, tools, (delta) => {\n text += delta;\n });\n }\n\n const output = streamOutputItems(messageId, text, [...tools.values()]);\n enqueue(\"response.output_text.done\", {\n content_index: 0,\n item_id: messageId,\n output_index: 0,\n text,\n type: \"response.output_text.done\",\n });\n enqueue(\"response.content_part.done\", {\n content_index: 0,\n item_id: messageId,\n output_index: 0,\n part: {\n annotations: [],\n text,\n type: \"output_text\",\n },\n type: \"response.content_part.done\",\n });\n enqueue(\"response.output_item.done\", {\n item: output[0],\n output_index: 0,\n type: \"response.output_item.done\",\n });\n\n tools.forEach((tool, index) => {\n const item = functionCallItem(tool);\n const outputIndex = index + 1;\n enqueue(\"response.output_item.added\", {\n item,\n output_index: outputIndex,\n type: \"response.output_item.added\",\n });\n enqueue(\"response.function_call_arguments.done\", {\n arguments: tool.arguments,\n item_id: item.id,\n output_index: outputIndex,\n type: \"response.function_call_arguments.done\",\n });\n enqueue(\"response.output_item.done\", {\n item,\n output_index: outputIndex,\n type: \"response.output_item.done\",\n });\n });\n\n enqueue(\"response.completed\", {\n response: baseStreamResponse(responseId, options.model, createdAt, \"completed\", output),\n type: \"response.completed\",\n });\n enqueue(\"done\", \"[DONE]\");\n controller.close();\n } catch (error) {\n controller.error(error);\n } finally {\n reader.releaseLock();\n }\n },\n });\n}\n\nfunction inputToMessages(input: unknown): unknown[] {\n if (typeof input === \"string\") {\n return [{ content: input, role: \"user\" }];\n }\n if (!Array.isArray(input)) {\n return [];\n }\n\n const messages: unknown[] = [];\n for (const item of input) {\n const record = asRecord(item);\n if (record.type === \"function_call_output\") {\n messages.push({\n content: contentToText(record.output),\n role: \"tool\",\n tool_call_id: contentToText(record.call_id),\n });\n continue;\n }\n if (record.type === \"function_call\") {\n messages.push({\n role: \"assistant\",\n tool_calls: [\n {\n function: {\n arguments: contentToText(record.arguments),\n name: contentToText(record.name),\n },\n id: contentToText(record.call_id) || contentToText(record.id),\n type: \"function\",\n },\n ],\n });\n continue;\n }\n const role = roleToChatRole(contentToText(record.role));\n const content = chatMessageContent(record.content);\n if (role && content !== undefined) {\n messages.push({ content, role });\n }\n }\n return messages;\n}\n\nfunction chatMessageContent(content: unknown): string | Array<JsonObject> | undefined {\n if (typeof content === \"string\") {\n return content;\n }\n if (!Array.isArray(content)) {\n return contentToText(content) || undefined;\n }\n\n const parts: JsonObject[] = [];\n for (const part of content) {\n const record = asRecord(part);\n const type = contentToText(record.type);\n if (type === \"input_text\" || type === \"output_text\" || type === \"text\") {\n parts.push({ text: contentToText(record.text), type: \"text\" });\n }\n if (type === \"input_image\") {\n const imageUrl = contentToText(record.image_url);\n if (imageUrl) {\n parts.push({ image_url: { url: imageUrl }, type: \"image_url\" });\n }\n }\n }\n\n if (parts.length === 0) {\n return undefined;\n }\n if (parts.every((part) => part.type === \"text\")) {\n return parts.map((part) => contentToText(part.text)).join(\"\\n\");\n }\n return parts;\n}\n\nfunction promptToText(prompt: unknown): string {\n if (Array.isArray(prompt)) {\n return prompt.map((item) => contentToText(item)).join(\"\\n\");\n }\n return contentToText(prompt);\n}\n\nfunction contentToText(content: unknown): string {\n if (typeof content === \"string\") {\n return content;\n }\n if (typeof content === \"number\" || typeof content === \"boolean\") {\n return String(content);\n }\n if (Array.isArray(content)) {\n return content\n .map((item) => contentToText(item))\n .filter(Boolean)\n .join(\"\\n\");\n }\n if (content && typeof content === \"object\") {\n const record = content as Record<string, unknown>;\n if (typeof record.text === \"string\") {\n return record.text;\n }\n if (typeof record.output_text === \"string\") {\n return record.output_text;\n }\n return JSON.stringify(content);\n }\n return \"\";\n}\n\nfunction roleToChatRole(role: string): string | undefined {\n if (role === \"assistant\" || role === \"developer\" || role === \"system\" || role === \"tool\") {\n return role === \"developer\" ? \"system\" : role;\n }\n return \"user\";\n}\n\nfunction chatTools(tools: unknown): unknown[] | undefined {\n if (!Array.isArray(tools)) {\n return undefined;\n }\n const converted = tools\n .map((tool) => asRecord(tool))\n .filter((tool) => tool.type === \"function\")\n .map((tool) => ({\n function: removeUndefined({\n description: tool.description,\n name: tool.name,\n parameters: tool.parameters,\n strict: tool.strict,\n }),\n type: \"function\",\n }));\n return converted.length > 0 ? converted : undefined;\n}\n\nfunction chatToolChoice(toolChoice: unknown): unknown {\n if (typeof toolChoice === \"string\" || toolChoice === undefined) {\n return toolChoice;\n }\n const record = asRecord(toolChoice);\n if (record.type === \"function\" && typeof record.name === \"string\") {\n return { function: { name: record.name }, type: \"function\" };\n }\n return toolChoice;\n}\n\nfunction outputItemsFromMessage(message: Record<string, unknown>): JsonObject[] {\n const output: JsonObject[] = [];\n const text = contentToText(message.content);\n if (text) {\n output.push(messageOutputItem(text));\n }\n const toolCalls = Array.isArray(message.tool_calls) ? message.tool_calls : [];\n for (const toolCall of toolCalls) {\n const record = asRecord(toolCall);\n const fn = asRecord(record.function);\n output.push(\n functionCallItem({\n arguments: contentToText(fn.arguments),\n id: contentToText(record.id) || `call_${randomId()}`,\n index: output.length,\n name: contentToText(fn.name),\n }),\n );\n }\n return output;\n}\n\nfunction messageOutputItem(text: string, id = `msg_${randomId()}`): JsonObject {\n return {\n content: [\n {\n annotations: [],\n text,\n type: \"output_text\",\n },\n ],\n id,\n role: \"assistant\",\n status: \"completed\",\n type: \"message\",\n };\n}\n\nfunction functionCallItem(tool: AccumulatedToolCall): JsonObject {\n return {\n arguments: tool.arguments,\n call_id: tool.id,\n id: `fc_${randomId()}`,\n name: tool.name,\n status: \"completed\",\n type: \"function_call\",\n };\n}\n\nfunction outputText(output: JsonObject[]): string {\n return output\n .flatMap((item) => {\n const content = item.content;\n return Array.isArray(content) ? content : [];\n })\n .map((part) => contentToText(asRecord(part).text))\n .filter(Boolean)\n .join(\"\");\n}\n\nfunction responseUsage(usage: unknown): JsonObject | null {\n const record = asRecord(usage);\n if (Object.keys(record).length === 0) {\n return null;\n }\n return removeUndefined({\n input_tokens: record.prompt_tokens,\n input_tokens_details: record.prompt_tokens_details,\n output_tokens: record.completion_tokens,\n output_tokens_details: record.completion_tokens_details,\n total_tokens: record.total_tokens,\n });\n}\n\nfunction firstChoice(completion: JsonObject): Record<string, unknown> {\n const choices = Array.isArray(completion.choices) ? completion.choices : [];\n return asRecord(choices[0]);\n}\n\nfunction processChatSseLine(\n line: string,\n enqueue: (event: string, data: JsonObject | \"[DONE]\") => void,\n tools: Map<number, AccumulatedToolCall>,\n appendText: (delta: string) => void,\n): void {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"data:\")) {\n return;\n }\n const data = trimmed.slice(\"data:\".length).trim();\n if (!data || data === \"[DONE]\") {\n return;\n }\n\n const parsed = parseJson(data);\n if (!parsed) {\n return;\n }\n const choice = firstChoice(parsed);\n const delta = asRecord(choice.delta);\n const content = contentToText(delta.content);\n if (content) {\n appendText(content);\n enqueue(\"response.output_text.delta\", {\n content_index: 0,\n delta: content,\n item_id: \"\",\n output_index: 0,\n type: \"response.output_text.delta\",\n });\n }\n\n const toolCalls = Array.isArray(delta.tool_calls) ? delta.tool_calls : [];\n for (const toolCall of toolCalls) {\n const record = asRecord(toolCall);\n const fn = asRecord(record.function);\n const index = typeof record.index === \"number\" ? record.index : tools.size;\n const existing = tools.get(index) ?? {\n arguments: \"\",\n id: contentToText(record.id) || `call_${randomId()}`,\n index,\n name: \"\",\n };\n existing.id = contentToText(record.id) || existing.id;\n existing.name += contentToText(fn.name);\n existing.arguments += contentToText(fn.arguments);\n tools.set(index, existing);\n }\n}\n\nfunction streamOutputItems(\n messageId: string,\n text: string,\n tools: AccumulatedToolCall[],\n): JsonObject[] {\n return [messageOutputItem(text, messageId), ...tools.map((tool) => functionCallItem(tool))];\n}\n\nfunction baseStreamResponse(\n id: string,\n model: string,\n createdAt: number,\n status: \"in_progress\" | \"completed\",\n output: JsonObject[],\n): JsonObject {\n return {\n created_at: createdAt,\n error: null,\n id,\n incomplete_details: null,\n instructions: null,\n max_output_tokens: null,\n metadata: {},\n model,\n object: \"response\",\n output,\n parallel_tool_calls: true,\n status,\n temperature: null,\n tool_choice: \"auto\",\n tools: [],\n top_p: null,\n };\n}\n\nfunction encodeSse(event: string, data: JsonObject | \"[DONE]\"): string {\n if (data === \"[DONE]\") {\n return \"data: [DONE]\\n\\n\";\n }\n return `event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`;\n}\n\nfunction parseJson(data: string): JsonObject | undefined {\n try {\n return asRecord(JSON.parse(data));\n } catch {\n return undefined;\n }\n}\n\nfunction removeUndefined(record: JsonObject): JsonObject {\n return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined));\n}\n\nfunction asRecord(value: unknown): JsonObject {\n return value && typeof value === \"object\" && !Array.isArray(value) ? (value as JsonObject) : {};\n}\n\nfunction randomId(): string {\n return crypto.randomUUID().replaceAll(\"-\", \"\");\n}\n\nfunction epochSeconds(): number {\n return Math.floor(Date.now() / 1000);\n}\n","import { CopilotAuthError } from \"./auth\";\nimport { CopilotClient } from \"./copilot\";\nimport { createHoopilotLogger, noopLogger, shouldCreateLogger } from \"./logger\";\nimport {\n chatCompletionToCompletion,\n chatCompletionToResponse,\n completionsRequestToChatCompletion,\n fallbackModels,\n normalizeModelsResponse,\n responsesRequestToChatCompletion,\n responsesStreamFromChatStream,\n} from \"./openai\";\nimport type {\n HoopilotLogger,\n HoopilotServerOptions,\n JsonObject,\n LogFields,\n StartedHoopilotServer,\n} from \"./types\";\n\nconst DEFAULT_HOST = \"127.0.0.1\";\nconst DEFAULT_PORT = 4141;\nconst INVALID_JSON_MESSAGE = \"Request body must be valid JSON.\";\n\nexport function createHoopilotHandler(options: HoopilotServerOptions = {}) {\n const client = new CopilotClient(options);\n const apiKey = options.apiKey ?? options.env?.HOOPILOT_API_KEY;\n const logger = serverLogger(options);\n\n return async (request: Request): Promise<Response> => {\n const startedAt = performance.now();\n const url = new URL(request.url);\n const apiPath = canonicalApiPath(url.pathname);\n const requestId = requestIdFor(request);\n const requestLogger = logger.child({\n method: request.method,\n path: url.pathname,\n requestId,\n route: routeFor(request.method, apiPath),\n });\n\n if (request.method === \"OPTIONS\") {\n return finishResponse(new Response(null, { headers: corsHeaders() }), {\n logger: requestLogger,\n requestId,\n startedAt,\n });\n }\n\n if (!isAuthorized(request, apiKey)) {\n requestLogger.warn({ event: \"http.request.unauthorized\" }, \"invalid hoopilot api key\");\n return finishResponse(\n jsonError(401, \"invalid_api_key\", \"Invalid or missing Hoopilot API key.\"),\n {\n logger: requestLogger,\n requestId,\n startedAt,\n },\n );\n }\n\n try {\n if (request.method === \"GET\" && (apiPath === \"/\" || apiPath === \"/healthz\")) {\n return finishResponse(\n jsonResponse({\n name: \"hoopilot\",\n object: \"health\",\n status: \"ok\",\n }),\n { logger: requestLogger, requestId, startedAt },\n );\n }\n if (request.method === \"GET\" && apiPath === \"/v1/models\") {\n return finishResponse(await handleModels(client, request.signal, requestLogger), {\n logger: requestLogger,\n requestId,\n startedAt,\n });\n }\n if (request.method === \"POST\" && apiPath === \"/v1/chat/completions\") {\n return finishResponse(await handleChatCompletions(client, request, requestLogger), {\n logger: requestLogger,\n requestId,\n startedAt,\n });\n }\n if (request.method === \"POST\" && apiPath === \"/v1/completions\") {\n return finishResponse(await handleCompletions(client, request, requestLogger), {\n logger: requestLogger,\n requestId,\n startedAt,\n });\n }\n if (request.method === \"POST\" && apiPath === \"/v1/responses\") {\n return finishResponse(await handleResponses(client, request, requestLogger), {\n logger: requestLogger,\n requestId,\n startedAt,\n });\n }\n return finishResponse(\n jsonError(404, \"not_found\", `No route for ${request.method} ${url.pathname}.`),\n { logger: requestLogger, requestId, startedAt },\n );\n } catch (error) {\n if (error instanceof CopilotAuthError) {\n requestLogger.warn(\n { err: errorDetails(error), event: \"copilot.auth.missing\" },\n \"copilot auth failed\",\n );\n return finishResponse(jsonError(401, \"copilot_auth_error\", error.message), {\n logger: requestLogger,\n requestId,\n startedAt,\n });\n }\n const message = errorMessage(error);\n if (message === INVALID_JSON_MESSAGE) {\n requestLogger.warn(\n { err: errorDetails(error), event: \"http.request.failed\" },\n \"request body was invalid json\",\n );\n } else {\n requestLogger.error(\n { err: errorDetails(error), event: \"http.request.failed\" },\n \"request failed\",\n );\n }\n return finishResponse(jsonError(500, \"internal_error\", message), {\n logger: requestLogger,\n requestId,\n startedAt,\n });\n }\n };\n}\n\nexport function startHoopilotServer(options: HoopilotServerOptions = {}): StartedHoopilotServer {\n const host = options.host ?? options.env?.HOST ?? DEFAULT_HOST;\n const port = Number(options.port ?? options.env?.PORT ?? DEFAULT_PORT);\n const apiKey = options.apiKey ?? options.env?.HOOPILOT_API_KEY;\n const allowUnauthenticated =\n options.allowUnauthenticated ?? options.env?.HOOPILOT_ALLOW_UNAUTHENTICATED === \"1\";\n\n if (!isLoopbackHost(host) && !apiKey && !allowUnauthenticated) {\n throw new Error(\n \"Refusing to listen on a non-loopback host without HOOPILOT_API_KEY. Set an API key or pass --allow-unauthenticated.\",\n );\n }\n\n const server = Bun.serve({\n fetch: createHoopilotHandler({\n ...options,\n apiKey,\n host,\n port,\n }),\n hostname: host,\n port,\n });\n\n return {\n server,\n url: `http://${host}:${server.port}`,\n };\n}\n\nasync function handleModels(\n client: CopilotClient,\n signal: AbortSignal,\n logger: HoopilotLogger,\n): Promise<Response> {\n const upstream = await client.models(signal);\n if (!upstream.ok) {\n if (isUpstreamAuthStatus(upstream.status)) {\n return proxyError(upstream, logger);\n }\n logger.warn(\n {\n event: \"copilot.models.fallback\",\n upstreamPath: \"/models\",\n upstreamStatus: upstream.status,\n },\n \"falling back to built-in model list\",\n );\n return jsonResponse({ data: fallbackModels(), object: \"list\" });\n }\n logUpstreamSuccess(logger, \"/models\", upstream.status);\n return jsonResponse(normalizeModelsResponse(await upstream.json()));\n}\n\nasync function handleChatCompletions(\n client: CopilotClient,\n request: Request,\n logger: HoopilotLogger,\n): Promise<Response> {\n const upstream = await client.forwardChatCompletions(await request.text(), request.signal);\n if (!upstream.ok) {\n return proxyError(upstream, logger);\n }\n logUpstreamSuccess(logger, \"/chat/completions\", upstream.status);\n return proxyResponse(upstream);\n}\n\nasync function handleCompletions(\n client: CopilotClient,\n request: Request,\n logger: HoopilotLogger,\n): Promise<Response> {\n const body = await readJson(request);\n const upstream = await client.chatCompletions(\n completionsRequestToChatCompletion(body),\n request.signal,\n );\n if (!upstream.ok) {\n return proxyError(upstream, logger);\n }\n logUpstreamSuccess(logger, \"/chat/completions\", upstream.status);\n return jsonResponse(chatCompletionToCompletion(await upstream.json()));\n}\n\nasync function handleResponses(\n client: CopilotClient,\n request: Request,\n logger: HoopilotLogger,\n): Promise<Response> {\n const body = await readJson(request);\n const chatRequest = responsesRequestToChatCompletion(body);\n const upstream = await client.chatCompletions(chatRequest, request.signal);\n if (!upstream.ok) {\n return proxyError(upstream, logger);\n }\n logUpstreamSuccess(logger, \"/chat/completions\", upstream.status);\n\n if (body.stream === true && upstream.body) {\n return new Response(\n responsesStreamFromChatStream(upstream.body, {\n model: typeof chatRequest.model === \"string\" ? chatRequest.model : \"gpt-4.1\",\n }),\n {\n headers: {\n ...corsHeaders(),\n \"cache-control\": \"no-cache\",\n connection: \"keep-alive\",\n \"content-type\": \"text/event-stream; charset=utf-8\",\n },\n },\n );\n }\n\n return jsonResponse(chatCompletionToResponse(await upstream.json()));\n}\n\nasync function proxyError(upstream: Response, logger: HoopilotLogger): Promise<Response> {\n const text = await upstream.text();\n if (isUpstreamAuthStatus(upstream.status)) {\n logger.warn(\n { event: \"copilot.auth.rejected\", upstreamStatus: upstream.status },\n \"copilot rejected credential or account access\",\n );\n return jsonError(401, \"copilot_auth_error\", upstreamAuthMessage(text || upstream.statusText));\n }\n logger.warn(\n { event: \"copilot.request.failed\", upstreamStatus: upstream.status },\n \"copilot upstream request failed\",\n );\n return jsonError(upstream.status, \"copilot_error\", text || upstream.statusText);\n}\n\nfunction proxyResponse(upstream: Response): Response {\n const headers = new Headers(upstream.headers);\n headers.delete(\"content-encoding\");\n headers.delete(\"content-length\");\n headers.delete(\"transfer-encoding\");\n for (const [key, value] of Object.entries(corsHeaders())) {\n headers.set(key, value);\n }\n return new Response(upstream.body, {\n headers,\n status: upstream.status,\n statusText: upstream.statusText,\n });\n}\n\nasync function readJson(request: Request): Promise<JsonObject> {\n try {\n const value = await request.json();\n return value && typeof value === \"object\" && !Array.isArray(value) ? (value as JsonObject) : {};\n } catch {\n throw new Error(INVALID_JSON_MESSAGE);\n }\n}\n\nfunction jsonResponse(body: JsonObject, status = 200): Response {\n return new Response(JSON.stringify(body), {\n headers: {\n ...corsHeaders(),\n \"content-type\": \"application/json; charset=utf-8\",\n },\n status,\n });\n}\n\nfunction jsonError(status: number, code: string, message: string): Response {\n return jsonResponse(\n {\n error: {\n code,\n message,\n type: code,\n },\n },\n status,\n );\n}\n\nfunction corsHeaders(): Record<string, string> {\n return {\n \"access-control-allow-headers\": \"authorization, content-type, x-api-key\",\n \"access-control-allow-methods\": \"GET, POST, OPTIONS\",\n \"access-control-allow-origin\": \"*\",\n };\n}\n\nfunction isAuthorized(request: Request, apiKey: string | undefined): boolean {\n if (!apiKey) {\n return true;\n }\n const authorization = request.headers.get(\"authorization\") ?? \"\";\n const bearer = authorization.match(/^Bearer\\s+(.+)$/i)?.[1];\n return bearer === apiKey || request.headers.get(\"x-api-key\") === apiKey;\n}\n\nfunction isUpstreamAuthStatus(status: number): boolean {\n return status === 401 || status === 403;\n}\n\nfunction upstreamAuthMessage(message: string): string {\n return `GitHub Copilot rejected the credential or account access: ${message}`;\n}\n\nfunction isLoopbackHost(host: string): boolean {\n return host === \"localhost\" || host === \"127.0.0.1\" || host === \"::1\";\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction serverLogger(options: HoopilotServerOptions): HoopilotLogger {\n if (options.logger) {\n return options.logger.child({ component: \"server\" });\n }\n if (shouldCreateLogger(options)) {\n return createHoopilotLogger({\n env: options.env,\n format: options.logFormat,\n level: options.logLevel,\n }).child({ component: \"server\" });\n }\n return noopLogger;\n}\n\nfunction finishResponse(\n response: Response,\n options: { logger: HoopilotLogger; requestId: string; startedAt: number },\n): Response {\n const withRequestId = responseWithRequestId(response, options.requestId);\n logRequestCompleted(options.logger, withRequestId, options.startedAt);\n return withRequestId;\n}\n\nfunction responseWithRequestId(response: Response, requestId: string): Response {\n const headers = new Headers(response.headers);\n headers.set(\"x-request-id\", requestId);\n return new Response(response.body, {\n headers,\n status: response.status,\n statusText: response.statusText,\n });\n}\n\nfunction logRequestCompleted(logger: HoopilotLogger, response: Response, startedAt: number): void {\n const fields: LogFields = {\n durationMs: Math.round((performance.now() - startedAt) * 100) / 100,\n event: \"http.request.completed\",\n status: response.status,\n stream: isStreamingResponse(response),\n };\n if (response.status >= 500) {\n logger.error(fields, \"request completed with server error\");\n return;\n }\n if (response.status >= 400) {\n logger.warn(fields, \"request completed with client error\");\n return;\n }\n logger.info(fields, \"request completed\");\n}\n\nfunction requestIdFor(request: Request): string {\n const existing = request.headers.get(\"x-request-id\")?.trim();\n return existing || crypto.randomUUID();\n}\n\nfunction canonicalApiPath(path: string): string {\n const withoutTrailingSlash = path.length > 1 ? path.replace(/\\/+$/, \"\") : path;\n switch (withoutTrailingSlash) {\n case \"/models\":\n return \"/v1/models\";\n case \"/chat/completions\":\n return \"/v1/chat/completions\";\n case \"/completions\":\n return \"/v1/completions\";\n case \"/responses\":\n return \"/v1/responses\";\n default:\n return withoutTrailingSlash;\n }\n}\n\nfunction routeFor(method: string, path: string): string {\n if (method === \"OPTIONS\") {\n return \"cors.preflight\";\n }\n if (method === \"GET\" && (path === \"/\" || path === \"/healthz\")) {\n return \"health\";\n }\n if (method === \"GET\" && path === \"/v1/models\") {\n return \"models\";\n }\n if (method === \"POST\" && path === \"/v1/chat/completions\") {\n return \"chat_completions\";\n }\n if (method === \"POST\" && path === \"/v1/completions\") {\n return \"completions\";\n }\n if (method === \"POST\" && path === \"/v1/responses\") {\n return \"responses\";\n }\n return \"not_found\";\n}\n\nfunction isStreamingResponse(response: Response): boolean {\n return response.headers.get(\"content-type\")?.includes(\"text/event-stream\") ?? false;\n}\n\nfunction logUpstreamSuccess(logger: HoopilotLogger, upstreamPath: string, status: number): void {\n logger.debug(\n {\n event: \"copilot.request.completed\",\n upstreamPath,\n upstreamStatus: status,\n },\n \"copilot upstream request completed\",\n );\n}\n\nfunction errorDetails(error: unknown): LogFields {\n if (error instanceof Error) {\n return {\n message: error.message,\n name: error.name,\n stack: error.stack,\n };\n }\n return { message: String(error) };\n}\n"],"mappings":"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","names":["sleep","pino","pretty"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/auth-store.ts","../src/auth.ts","../src/copilot.ts","../src/github-device.ts","../src/logger.ts","../src/openai.ts","../src/server.ts"],"sourcesContent":["export { CopilotAuth, CopilotAuthError } from \"./auth\";\nexport { authStorePath, readStoredCopilotAuth, writeStoredCopilotAuth } from \"./auth-store\";\nexport { CopilotClient } from \"./copilot\";\nexport { githubCopilotDeviceLogin } from \"./github-device\";\nexport {\n createHoopilotLogger,\n DEFAULT_LOG_FORMAT,\n DEFAULT_LOG_LEVEL,\n noopLogger,\n parseLogFormat,\n parseLogLevel,\n} from \"./logger\";\nexport {\n chatCompletionToCompletion,\n chatCompletionToResponse,\n completionsRequestToChatCompletion,\n DEFAULT_MODEL,\n fallbackModels,\n normalizeModelsResponse,\n responsesRequestToChatCompletion,\n responsesStreamFromChatStream,\n} from \"./openai\";\nexport { createHoopilotHandler, startHoopilotServer } from \"./server\";\nexport type {\n CopilotAccess,\n CopilotAuthOptions,\n FetchLike,\n HoopilotLogger,\n HoopilotLoggerOptions,\n HoopilotServerOptions,\n JsonObject,\n LogFields,\n LogFormat,\n Logger,\n LogLevel,\n LogMethod,\n StartedHoopilotServer,\n} from \"./types\";\n","import { chmodSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\nexport interface StoredCopilotAuth {\n apiBaseUrl?: string;\n createdAt?: string;\n githubDomain?: string;\n source?: string;\n token: string;\n}\n\nexport function authStorePath(env: NodeJS.ProcessEnv = process.env): string {\n if (env.HOOPILOT_AUTH_FILE) {\n return env.HOOPILOT_AUTH_FILE;\n }\n\n const base =\n env.XDG_CONFIG_HOME ??\n env.APPDATA ??\n (env.HOME ? join(env.HOME, \".config\") : join(process.cwd(), \".config\"));\n return join(base, \"hoopilot\", \"auth.json\");\n}\n\nexport function readStoredCopilotAuth(path = authStorePath()): StoredCopilotAuth | undefined {\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf8\"));\n if (!parsed || typeof parsed !== \"object\") {\n return undefined;\n }\n const token = typeof parsed.token === \"string\" ? parsed.token.trim() : \"\";\n if (!token) {\n return undefined;\n }\n return {\n apiBaseUrl: typeof parsed.apiBaseUrl === \"string\" ? parsed.apiBaseUrl : undefined,\n createdAt: typeof parsed.createdAt === \"string\" ? parsed.createdAt : undefined,\n githubDomain: typeof parsed.githubDomain === \"string\" ? parsed.githubDomain : undefined,\n source: typeof parsed.source === \"string\" ? parsed.source : undefined,\n token,\n };\n } catch {\n return undefined;\n }\n}\n\nexport function writeStoredCopilotAuth(auth: StoredCopilotAuth, path = authStorePath()): void {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(\n path,\n `${JSON.stringify(\n {\n ...auth,\n createdAt: auth.createdAt ?? new Date().toISOString(),\n },\n null,\n 2,\n )}\\n`,\n { mode: 0o600 },\n );\n try {\n chmodSync(path, 0o600);\n } catch {\n // chmod is best-effort on Windows.\n }\n}\n","import { readStoredCopilotAuth } from \"./auth-store\";\nimport type { CopilotAccess, CopilotAuthOptions } from \"./types\";\n\nconst DEFAULT_COPILOT_API_BASE_URL = \"https://api.githubcopilot.com\";\nconst REFRESH_SKEW_MS = 60_000;\nconst STORED_TOKEN_TTL_MS = 10 * 60_000;\n\nexport class CopilotAuthError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"CopilotAuthError\";\n }\n}\n\nexport class CopilotAuth {\n readonly #authStorePath?: string;\n readonly #copilotApiBaseUrl: string;\n #cachedAccess?: CopilotAccess;\n\n constructor(options: CopilotAuthOptions = {}) {\n this.#authStorePath = options.authStorePath ?? options.env?.HOOPILOT_AUTH_FILE;\n this.#copilotApiBaseUrl = trimTrailingSlash(\n options.copilotApiBaseUrl ??\n options.env?.COPILOT_API_BASE_URL ??\n DEFAULT_COPILOT_API_BASE_URL,\n );\n }\n\n async getAccess(): Promise<CopilotAccess> {\n if (this.#cachedAccess && this.#cachedAccess.expiresAtMs - REFRESH_SKEW_MS > Date.now()) {\n return this.#cachedAccess;\n }\n\n const stored = readStoredCopilotAuth(this.#authStorePath);\n if (stored) {\n return this.#cacheAccess({\n apiBaseUrl: trimTrailingSlash(stored.apiBaseUrl ?? this.#copilotApiBaseUrl),\n expiresAtMs: Date.now() + STORED_TOKEN_TTL_MS,\n source: \"github-copilot-oauth\",\n token: stored.token,\n });\n }\n\n throw new CopilotAuthError(\n \"No GitHub Copilot OAuth credential found. Run `hoopilot login` to sign in through your browser.\",\n );\n }\n\n #cacheAccess(access: CopilotAccess): CopilotAccess {\n this.#cachedAccess = access;\n return access;\n }\n}\n\nfunction trimTrailingSlash(value: string): string {\n return value.replace(/\\/+$/, \"\");\n}\n","import { CopilotAuth } from \"./auth\";\nimport type { CopilotAuthOptions, FetchLike, JsonObject } from \"./types\";\n\nexport class CopilotClient {\n readonly #auth: CopilotAuth;\n readonly #fetch: FetchLike;\n\n constructor(options: CopilotAuthOptions = {}) {\n this.#auth = new CopilotAuth(options);\n this.#fetch = options.fetch ?? fetch;\n }\n\n async chatCompletions(body: JsonObject, signal?: AbortSignal): Promise<Response> {\n return this.fetchCopilot(\"/chat/completions\", {\n body: JSON.stringify(body),\n headers: {\n \"content-type\": \"application/json\",\n },\n method: \"POST\",\n signal,\n });\n }\n\n async forwardChatCompletions(body: string, signal?: AbortSignal): Promise<Response> {\n return this.fetchCopilot(\"/chat/completions\", {\n body,\n headers: {\n \"content-type\": \"application/json\",\n },\n method: \"POST\",\n signal,\n });\n }\n\n async models(signal?: AbortSignal): Promise<Response> {\n return this.fetchCopilot(\"/models\", {\n headers: {\n accept: \"application/json\",\n },\n method: \"GET\",\n signal,\n });\n }\n\n async fetchCopilot(path: string, init: RequestInit): Promise<Response> {\n const access = await this.#auth.getAccess();\n const headers = new Headers(init.headers);\n headers.set(\"accept\", headers.get(\"accept\") ?? \"application/json\");\n headers.set(\"authorization\", `Bearer ${access.token}`);\n headers.set(\"copilot-integration-id\", \"vscode-chat\");\n headers.set(\"editor-plugin-version\", \"hoopilot/0.1.0\");\n headers.set(\"editor-version\", \"Hoopilot/0.1.0\");\n headers.set(\"openai-intent\", \"conversation-panel\");\n headers.set(\"user-agent\", \"hoopilot/0.1.0\");\n headers.set(\"x-github-api-version\", \"2026-06-01\");\n\n return this.#fetch(`${access.apiBaseUrl}${path}`, {\n ...init,\n headers,\n });\n }\n}\n","import { setTimeout as sleep } from \"node:timers/promises\";\nimport type { FetchLike, Logger } from \"./types\";\n\nexport const DEFAULT_GITHUB_COPILOT_CLIENT_ID = \"Iv23lijnNxm2e9UX3CF8\";\nconst DEFAULT_GITHUB_DOMAIN = \"github.com\";\nconst DEVICE_GRANT_TYPE = \"urn:ietf:params:oauth:grant-type:device_code\";\nconst POLLING_SAFETY_MARGIN_MS = 3_000;\n\nexport interface GithubCopilotDeviceLoginOptions {\n clientId?: string;\n domain?: string;\n env?: NodeJS.ProcessEnv;\n fetch?: FetchLike;\n logger?: Logger;\n openBrowser?: (url: string) => void | Promise<void>;\n sleep?: (ms: number) => Promise<void>;\n}\n\nexport interface GithubCopilotDeviceLoginResult {\n domain: string;\n token: string;\n}\n\ninterface DeviceCodeResponse {\n device_code?: string;\n expires_in?: number;\n interval?: number;\n user_code?: string;\n verification_uri?: string;\n}\n\ninterface DeviceTokenResponse {\n access_token?: string;\n error?: string;\n error_description?: string;\n interval?: number;\n}\n\nexport async function githubCopilotDeviceLogin(\n options: GithubCopilotDeviceLoginOptions = {},\n): Promise<GithubCopilotDeviceLoginResult> {\n const env = options.env ?? process.env;\n const fetcher = options.fetch ?? fetch;\n const sleeper = options.sleep ?? sleep;\n const domain = normalizeDomain(\n options.domain ?? env.HOOPILOT_GITHUB_DOMAIN ?? DEFAULT_GITHUB_DOMAIN,\n );\n const clientId =\n options.clientId ??\n env.HOOPILOT_GITHUB_CLIENT_ID ??\n env.COPILOT_GITHUB_CLIENT_ID ??\n DEFAULT_GITHUB_COPILOT_CLIENT_ID;\n\n const device = await requestDeviceCode(fetcher, domain, clientId);\n const verificationUrl = device.verification_uri;\n const userCode = device.user_code;\n const deviceCode = device.device_code;\n if (!verificationUrl || !userCode || !deviceCode) {\n throw new Error(\"GitHub device authorization response is missing required fields.\");\n }\n\n options.logger?.info(`First copy your one-time code: ${userCode}`);\n options.logger?.info(`Open ${verificationUrl} in your browser to authorize Hoopilot.`);\n await options.openBrowser?.(verificationUrl);\n\n return {\n domain,\n token: await pollForAccessToken(fetcher, sleeper, domain, clientId, {\n deviceCode,\n expiresIn: positiveSeconds(device.expires_in, 900),\n interval: positiveSeconds(device.interval, 5),\n }),\n };\n}\n\nasync function requestDeviceCode(\n fetcher: FetchLike,\n domain: string,\n clientId: string,\n): Promise<DeviceCodeResponse> {\n const response = await fetcher(`https://${domain}/login/device/code`, {\n body: JSON.stringify({\n client_id: clientId,\n scope: \"read:user\",\n }),\n headers: oauthHeaders(),\n method: \"POST\",\n });\n if (!response.ok) {\n throw new Error(\n `GitHub device authorization failed with ${response.status}: ${await safeResponseText(\n response,\n )}`,\n );\n }\n return (await response.json()) as DeviceCodeResponse;\n}\n\nasync function pollForAccessToken(\n fetcher: FetchLike,\n sleeper: (ms: number) => Promise<void>,\n domain: string,\n clientId: string,\n device: { deviceCode: string; expiresIn: number; interval: number },\n): Promise<string> {\n let intervalMs = device.interval * 1000 + POLLING_SAFETY_MARGIN_MS;\n const deadline = Date.now() + device.expiresIn * 1000;\n\n while (Date.now() < deadline) {\n await sleeper(intervalMs);\n const response = await fetcher(`https://${domain}/login/oauth/access_token`, {\n body: JSON.stringify({\n client_id: clientId,\n device_code: device.deviceCode,\n grant_type: DEVICE_GRANT_TYPE,\n }),\n headers: oauthHeaders(),\n method: \"POST\",\n });\n\n if (!response.ok) {\n throw new Error(\n `GitHub device token exchange failed with ${response.status}: ${await safeResponseText(\n response,\n )}`,\n );\n }\n\n const data = (await response.json()) as DeviceTokenResponse;\n if (data.access_token) {\n return data.access_token;\n }\n\n if (data.error === \"authorization_pending\") {\n continue;\n }\n if (data.error === \"slow_down\") {\n intervalMs =\n positiveSeconds(data.interval, device.interval + 5) * 1000 + POLLING_SAFETY_MARGIN_MS;\n continue;\n }\n if (data.error === \"expired_token\") {\n throw new Error(\"GitHub device login expired. Run `hoopilot login` again.\");\n }\n if (data.error === \"access_denied\") {\n throw new Error(\"GitHub device login was cancelled.\");\n }\n if (data.error) {\n throw new Error(data.error_description || `GitHub device login failed: ${data.error}`);\n }\n }\n\n throw new Error(\"GitHub device login timed out. Run `hoopilot login` again.\");\n}\n\nfunction oauthHeaders(): Headers {\n const headers = new Headers();\n headers.set(\"accept\", \"application/json\");\n headers.set(\"content-type\", \"application/json\");\n headers.set(\"user-agent\", \"hoopilot\");\n return headers;\n}\n\nfunction normalizeDomain(value: string): string {\n return value.replace(/^https?:\\/\\//, \"\").replace(/\\/+$/, \"\");\n}\n\nfunction positiveSeconds(value: unknown, fallback: number): number {\n return typeof value === \"number\" && Number.isFinite(value) && value > 0 ? value : fallback;\n}\n\nasync function safeResponseText(response: Response): Promise<string> {\n const text = await response.text();\n return text.slice(0, 500);\n}\n","import pino from \"pino\";\nimport pretty from \"pino-pretty\";\nimport type { HoopilotLogger, HoopilotLoggerOptions, LogFormat, LogLevel } from \"./types\";\n\nexport const DEFAULT_LOG_FORMAT: LogFormat = \"pretty\";\nexport const DEFAULT_LOG_LEVEL: LogLevel = \"info\";\n\nconst LOG_FORMATS = [\"json\", \"pretty\"] as const;\nconst LOG_LEVELS = [\"trace\", \"debug\", \"info\", \"warn\", \"error\", \"fatal\", \"silent\"] as const;\nconst REDACT_PATHS = [\n \"apiKey\",\n \"authorization\",\n \"cookie\",\n \"headers.authorization\",\n \"headers.Authorization\",\n \"headers.cookie\",\n \"headers.Cookie\",\n \"headers.x-api-key\",\n \"headers.X-Api-Key\",\n \"token\",\n \"*.apiKey\",\n \"*.authorization\",\n \"*.cookie\",\n \"*.token\",\n \"*.headers.authorization\",\n \"*.headers.Authorization\",\n \"*.headers.cookie\",\n \"*.headers.Cookie\",\n \"*.headers.x-api-key\",\n \"*.headers.X-Api-Key\",\n];\n\nexport const noopLogger: HoopilotLogger = {\n child: () => noopLogger,\n debug: () => {},\n error: () => {},\n fatal: () => {},\n info: () => {},\n trace: () => {},\n warn: () => {},\n};\n\nexport function createHoopilotLogger(options: HoopilotLoggerOptions = {}): HoopilotLogger {\n const env = options.env ?? process.env;\n const level = parseLogLevel(options.level ?? env.HOOPILOT_LOG_LEVEL);\n const format = parseLogFormat(options.format ?? env.HOOPILOT_LOG_FORMAT);\n const pinoOptions: pino.LoggerOptions = {\n base: {\n service: \"hoopilot\",\n ...options.base,\n },\n level,\n redact: {\n censor: \"[Redacted]\",\n paths: REDACT_PATHS,\n },\n timestamp: pino.stdTimeFunctions.isoTime,\n };\n\n if (format === \"pretty\") {\n return pino(\n pinoOptions,\n pretty({\n colorize: options.colorize ?? process.stderr.isTTY,\n destination: options.stream ?? 1,\n ignore: \"pid,hostname\",\n singleLine: true,\n translateTime: \"SYS:standard\",\n }),\n ) as HoopilotLogger;\n }\n\n if (options.stream) {\n return pino(pinoOptions, options.stream as pino.DestinationStream) as HoopilotLogger;\n }\n return pino(pinoOptions) as HoopilotLogger;\n}\n\nexport function parseLogFormat(value: string | undefined): LogFormat {\n if (!value) {\n return DEFAULT_LOG_FORMAT;\n }\n if (isLogFormat(value)) {\n return value;\n }\n throw new Error(`Invalid log format: ${value}. Expected one of: ${LOG_FORMATS.join(\", \")}.`);\n}\n\nexport function parseLogLevel(value: string | undefined): LogLevel {\n if (!value) {\n return DEFAULT_LOG_LEVEL;\n }\n if (isLogLevel(value)) {\n return value;\n }\n throw new Error(`Invalid log level: ${value}. Expected one of: ${LOG_LEVELS.join(\", \")}.`);\n}\n\nexport function shouldCreateLogger(options: {\n env?: NodeJS.ProcessEnv;\n logFormat?: string;\n logger?: HoopilotLogger;\n logLevel?: string;\n}): boolean {\n return Boolean(\n options.logger ||\n options.logFormat ||\n options.logLevel ||\n options.env?.HOOPILOT_LOG_FORMAT ||\n options.env?.HOOPILOT_LOG_LEVEL,\n );\n}\n\nfunction isLogFormat(value: string): value is LogFormat {\n return (LOG_FORMATS as readonly string[]).includes(value);\n}\n\nfunction isLogLevel(value: string): value is LogLevel {\n return (LOG_LEVELS as readonly string[]).includes(value);\n}\n","import type { JsonObject } from \"./types\";\n\nexport const DEFAULT_MODEL = \"gpt-4.1\";\n\ninterface ResponseStreamOptions {\n model: string;\n responseId?: string;\n}\n\ninterface AccumulatedToolCall {\n arguments: string;\n id: string;\n index: number;\n name: string;\n}\n\nexport function responsesRequestToChatCompletion(request: JsonObject): JsonObject {\n const messages: unknown[] = [];\n const instructions = contentToText(request.instructions);\n if (instructions) {\n messages.push({ content: instructions, role: \"system\" });\n }\n\n for (const message of inputToMessages(request.input)) {\n messages.push(message);\n }\n\n return removeUndefined({\n frequency_penalty: request.frequency_penalty,\n max_tokens: request.max_output_tokens ?? request.max_tokens,\n messages,\n metadata: request.metadata,\n model: contentToText(request.model) || DEFAULT_MODEL,\n presence_penalty: request.presence_penalty,\n reasoning_effort: asRecord(request.reasoning).effort,\n response_format: asRecord(request.text).format,\n seed: request.seed,\n stream: request.stream === true,\n temperature: request.temperature,\n tool_choice: chatToolChoice(request.tool_choice),\n tools: chatTools(request.tools),\n top_p: request.top_p,\n });\n}\n\nexport function completionsRequestToChatCompletion(request: JsonObject): JsonObject {\n return removeUndefined({\n max_tokens: request.max_tokens,\n messages: [{ content: promptToText(request.prompt), role: \"user\" }],\n model: contentToText(request.model) || DEFAULT_MODEL,\n stream: request.stream === true,\n temperature: request.temperature,\n top_p: request.top_p,\n });\n}\n\nexport function chatCompletionToResponse(completion: JsonObject, responseId?: string): JsonObject {\n const id = responseId ?? `resp_${randomId()}`;\n const choice = firstChoice(completion);\n const message = asRecord(choice.message);\n const model = contentToText(completion.model) || DEFAULT_MODEL;\n const output = outputItemsFromMessage(message);\n const usage = responseUsage(completion.usage);\n\n return removeUndefined({\n created_at: epochSeconds(),\n error: null,\n id,\n incomplete_details: null,\n instructions: null,\n max_output_tokens: null,\n metadata: {},\n model,\n object: \"response\",\n output,\n output_text: outputText(output),\n parallel_tool_calls: true,\n status: \"completed\",\n temperature: null,\n tool_choice: \"auto\",\n tools: [],\n top_p: null,\n usage,\n });\n}\n\nexport function chatCompletionToCompletion(completion: JsonObject): JsonObject {\n const choice = firstChoice(completion);\n const message = asRecord(choice.message);\n return removeUndefined({\n choices: [\n {\n finish_reason: choice.finish_reason ?? \"stop\",\n index: 0,\n logprobs: null,\n text: contentToText(message.content),\n },\n ],\n created: completion.created ?? epochSeconds(),\n id: completion.id ?? `cmpl_${randomId()}`,\n model: completion.model ?? DEFAULT_MODEL,\n object: \"text_completion\",\n usage: completion.usage,\n });\n}\n\nexport function normalizeModelsResponse(upstream: unknown): JsonObject {\n const record = asRecord(upstream);\n const data = Array.isArray(record.data) ? record.data : Array.isArray(upstream) ? upstream : [];\n const models = data\n .map((model) => asRecord(model))\n .filter((model) => typeof model.id === \"string\")\n .map((model) => ({\n created: model.created ?? 0,\n id: model.id,\n object: \"model\",\n owned_by: model.owned_by ?? \"github-copilot\",\n }));\n\n return {\n data: models.length > 0 ? models : fallbackModels(),\n object: \"list\",\n };\n}\n\nexport function fallbackModels(): Array<JsonObject> {\n return [\n {\n created: 0,\n id: DEFAULT_MODEL,\n object: \"model\",\n owned_by: \"github-copilot\",\n },\n ];\n}\n\nexport function responsesStreamFromChatStream(\n chatStream: ReadableStream<Uint8Array>,\n options: ResponseStreamOptions,\n): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n const decoder = new TextDecoder();\n const responseId = options.responseId ?? `resp_${randomId()}`;\n const messageId = `msg_${randomId()}`;\n const createdAt = epochSeconds();\n let buffer = \"\";\n let text = \"\";\n const tools = new Map<number, AccumulatedToolCall>();\n\n return new ReadableStream<Uint8Array>({\n async start(controller) {\n const enqueue = (event: string, data: JsonObject | \"[DONE]\") => {\n controller.enqueue(encoder.encode(encodeSse(event, data)));\n };\n\n enqueue(\"response.created\", {\n response: baseStreamResponse(responseId, options.model, createdAt, \"in_progress\", []),\n type: \"response.created\",\n });\n enqueue(\"response.output_item.added\", {\n item: {\n content: [],\n id: messageId,\n role: \"assistant\",\n status: \"in_progress\",\n type: \"message\",\n },\n output_index: 0,\n type: \"response.output_item.added\",\n });\n enqueue(\"response.content_part.added\", {\n content_index: 0,\n item_id: messageId,\n output_index: 0,\n part: {\n annotations: [],\n text: \"\",\n type: \"output_text\",\n },\n type: \"response.content_part.added\",\n });\n\n const reader = chatStream.getReader();\n try {\n while (true) {\n const result = await reader.read();\n if (result.done) {\n break;\n }\n buffer += decoder.decode(result.value, { stream: true });\n const lines = buffer.split(/\\r?\\n/);\n buffer = lines.pop() ?? \"\";\n for (const line of lines) {\n processChatSseLine(line, enqueue, tools, (delta) => {\n text += delta;\n });\n }\n }\n if (buffer) {\n processChatSseLine(buffer, enqueue, tools, (delta) => {\n text += delta;\n });\n }\n\n const output = streamOutputItems(messageId, text, [...tools.values()]);\n enqueue(\"response.output_text.done\", {\n content_index: 0,\n item_id: messageId,\n output_index: 0,\n text,\n type: \"response.output_text.done\",\n });\n enqueue(\"response.content_part.done\", {\n content_index: 0,\n item_id: messageId,\n output_index: 0,\n part: {\n annotations: [],\n text,\n type: \"output_text\",\n },\n type: \"response.content_part.done\",\n });\n enqueue(\"response.output_item.done\", {\n item: output[0],\n output_index: 0,\n type: \"response.output_item.done\",\n });\n\n tools.forEach((tool, index) => {\n const item = functionCallItem(tool);\n const outputIndex = index + 1;\n enqueue(\"response.output_item.added\", {\n item,\n output_index: outputIndex,\n type: \"response.output_item.added\",\n });\n enqueue(\"response.function_call_arguments.done\", {\n arguments: tool.arguments,\n item_id: item.id,\n output_index: outputIndex,\n type: \"response.function_call_arguments.done\",\n });\n enqueue(\"response.output_item.done\", {\n item,\n output_index: outputIndex,\n type: \"response.output_item.done\",\n });\n });\n\n enqueue(\"response.completed\", {\n response: baseStreamResponse(responseId, options.model, createdAt, \"completed\", output),\n type: \"response.completed\",\n });\n enqueue(\"done\", \"[DONE]\");\n controller.close();\n } catch (error) {\n controller.error(error);\n } finally {\n reader.releaseLock();\n }\n },\n });\n}\n\nfunction inputToMessages(input: unknown): unknown[] {\n if (typeof input === \"string\") {\n return [{ content: input, role: \"user\" }];\n }\n if (!Array.isArray(input)) {\n return [];\n }\n\n const messages: unknown[] = [];\n for (const item of input) {\n const record = asRecord(item);\n if (record.type === \"function_call_output\") {\n messages.push({\n content: contentToText(record.output),\n role: \"tool\",\n tool_call_id: contentToText(record.call_id),\n });\n continue;\n }\n if (record.type === \"function_call\") {\n messages.push({\n role: \"assistant\",\n tool_calls: [\n {\n function: {\n arguments: contentToText(record.arguments),\n name: contentToText(record.name),\n },\n id: contentToText(record.call_id) || contentToText(record.id),\n type: \"function\",\n },\n ],\n });\n continue;\n }\n const role = roleToChatRole(contentToText(record.role));\n const content = chatMessageContent(record.content);\n if (role && content !== undefined) {\n messages.push({ content, role });\n }\n }\n return messages;\n}\n\nfunction chatMessageContent(content: unknown): string | Array<JsonObject> | undefined {\n if (typeof content === \"string\") {\n return content;\n }\n if (!Array.isArray(content)) {\n return contentToText(content) || undefined;\n }\n\n const parts: JsonObject[] = [];\n for (const part of content) {\n const record = asRecord(part);\n const type = contentToText(record.type);\n if (type === \"input_text\" || type === \"output_text\" || type === \"text\") {\n parts.push({ text: contentToText(record.text), type: \"text\" });\n }\n if (type === \"input_image\") {\n const imageUrl = contentToText(record.image_url);\n if (imageUrl) {\n parts.push({ image_url: { url: imageUrl }, type: \"image_url\" });\n }\n }\n }\n\n if (parts.length === 0) {\n return undefined;\n }\n if (parts.every((part) => part.type === \"text\")) {\n return parts.map((part) => contentToText(part.text)).join(\"\\n\");\n }\n return parts;\n}\n\nfunction promptToText(prompt: unknown): string {\n if (Array.isArray(prompt)) {\n return prompt.map((item) => contentToText(item)).join(\"\\n\");\n }\n return contentToText(prompt);\n}\n\nfunction contentToText(content: unknown): string {\n if (typeof content === \"string\") {\n return content;\n }\n if (typeof content === \"number\" || typeof content === \"boolean\") {\n return String(content);\n }\n if (Array.isArray(content)) {\n return content\n .map((item) => contentToText(item))\n .filter(Boolean)\n .join(\"\\n\");\n }\n if (content && typeof content === \"object\") {\n const record = content as Record<string, unknown>;\n if (typeof record.text === \"string\") {\n return record.text;\n }\n if (typeof record.output_text === \"string\") {\n return record.output_text;\n }\n return JSON.stringify(content);\n }\n return \"\";\n}\n\nfunction roleToChatRole(role: string): string | undefined {\n if (role === \"assistant\" || role === \"developer\" || role === \"system\" || role === \"tool\") {\n return role === \"developer\" ? \"system\" : role;\n }\n return \"user\";\n}\n\nfunction chatTools(tools: unknown): unknown[] | undefined {\n if (!Array.isArray(tools)) {\n return undefined;\n }\n const converted = tools\n .map((tool) => asRecord(tool))\n .filter((tool) => tool.type === \"function\")\n .map((tool) => ({\n function: removeUndefined({\n description: tool.description,\n name: tool.name,\n parameters: tool.parameters,\n strict: tool.strict,\n }),\n type: \"function\",\n }));\n return converted.length > 0 ? converted : undefined;\n}\n\nfunction chatToolChoice(toolChoice: unknown): unknown {\n if (typeof toolChoice === \"string\" || toolChoice === undefined) {\n return toolChoice;\n }\n const record = asRecord(toolChoice);\n if (record.type === \"function\" && typeof record.name === \"string\") {\n return { function: { name: record.name }, type: \"function\" };\n }\n return toolChoice;\n}\n\nfunction outputItemsFromMessage(message: Record<string, unknown>): JsonObject[] {\n const output: JsonObject[] = [];\n const text = contentToText(message.content);\n if (text) {\n output.push(messageOutputItem(text));\n }\n const toolCalls = Array.isArray(message.tool_calls) ? message.tool_calls : [];\n for (const toolCall of toolCalls) {\n const record = asRecord(toolCall);\n const fn = asRecord(record.function);\n output.push(\n functionCallItem({\n arguments: contentToText(fn.arguments),\n id: contentToText(record.id) || `call_${randomId()}`,\n index: output.length,\n name: contentToText(fn.name),\n }),\n );\n }\n return output;\n}\n\nfunction messageOutputItem(text: string, id = `msg_${randomId()}`): JsonObject {\n return {\n content: [\n {\n annotations: [],\n text,\n type: \"output_text\",\n },\n ],\n id,\n role: \"assistant\",\n status: \"completed\",\n type: \"message\",\n };\n}\n\nfunction functionCallItem(tool: AccumulatedToolCall): JsonObject {\n return {\n arguments: tool.arguments,\n call_id: tool.id,\n id: `fc_${randomId()}`,\n name: tool.name,\n status: \"completed\",\n type: \"function_call\",\n };\n}\n\nfunction outputText(output: JsonObject[]): string {\n return output\n .flatMap((item) => {\n const content = item.content;\n return Array.isArray(content) ? content : [];\n })\n .map((part) => contentToText(asRecord(part).text))\n .filter(Boolean)\n .join(\"\");\n}\n\nfunction responseUsage(usage: unknown): JsonObject | null {\n const record = asRecord(usage);\n if (Object.keys(record).length === 0) {\n return null;\n }\n return removeUndefined({\n input_tokens: record.prompt_tokens,\n input_tokens_details: record.prompt_tokens_details,\n output_tokens: record.completion_tokens,\n output_tokens_details: record.completion_tokens_details,\n total_tokens: record.total_tokens,\n });\n}\n\nfunction firstChoice(completion: JsonObject): Record<string, unknown> {\n const choices = Array.isArray(completion.choices) ? completion.choices : [];\n return asRecord(choices[0]);\n}\n\nfunction processChatSseLine(\n line: string,\n enqueue: (event: string, data: JsonObject | \"[DONE]\") => void,\n tools: Map<number, AccumulatedToolCall>,\n appendText: (delta: string) => void,\n): void {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"data:\")) {\n return;\n }\n const data = trimmed.slice(\"data:\".length).trim();\n if (!data || data === \"[DONE]\") {\n return;\n }\n\n const parsed = parseJson(data);\n if (!parsed) {\n return;\n }\n const choice = firstChoice(parsed);\n const delta = asRecord(choice.delta);\n const content = contentToText(delta.content);\n if (content) {\n appendText(content);\n enqueue(\"response.output_text.delta\", {\n content_index: 0,\n delta: content,\n item_id: \"\",\n output_index: 0,\n type: \"response.output_text.delta\",\n });\n }\n\n const toolCalls = Array.isArray(delta.tool_calls) ? delta.tool_calls : [];\n for (const toolCall of toolCalls) {\n const record = asRecord(toolCall);\n const fn = asRecord(record.function);\n const index = typeof record.index === \"number\" ? record.index : tools.size;\n const existing = tools.get(index) ?? {\n arguments: \"\",\n id: contentToText(record.id) || `call_${randomId()}`,\n index,\n name: \"\",\n };\n existing.id = contentToText(record.id) || existing.id;\n existing.name += contentToText(fn.name);\n existing.arguments += contentToText(fn.arguments);\n tools.set(index, existing);\n }\n}\n\nfunction streamOutputItems(\n messageId: string,\n text: string,\n tools: AccumulatedToolCall[],\n): JsonObject[] {\n return [messageOutputItem(text, messageId), ...tools.map((tool) => functionCallItem(tool))];\n}\n\nfunction baseStreamResponse(\n id: string,\n model: string,\n createdAt: number,\n status: \"in_progress\" | \"completed\",\n output: JsonObject[],\n): JsonObject {\n return {\n created_at: createdAt,\n error: null,\n id,\n incomplete_details: null,\n instructions: null,\n max_output_tokens: null,\n metadata: {},\n model,\n object: \"response\",\n output,\n parallel_tool_calls: true,\n status,\n temperature: null,\n tool_choice: \"auto\",\n tools: [],\n top_p: null,\n };\n}\n\nfunction encodeSse(event: string, data: JsonObject | \"[DONE]\"): string {\n if (data === \"[DONE]\") {\n return \"data: [DONE]\\n\\n\";\n }\n return `event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`;\n}\n\nfunction parseJson(data: string): JsonObject | undefined {\n try {\n return asRecord(JSON.parse(data));\n } catch {\n return undefined;\n }\n}\n\nfunction removeUndefined(record: JsonObject): JsonObject {\n return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined));\n}\n\nfunction asRecord(value: unknown): JsonObject {\n return value && typeof value === \"object\" && !Array.isArray(value) ? (value as JsonObject) : {};\n}\n\nfunction randomId(): string {\n return crypto.randomUUID().replaceAll(\"-\", \"\");\n}\n\nfunction epochSeconds(): number {\n return Math.floor(Date.now() / 1000);\n}\n","import { CopilotAuthError } from \"./auth\";\nimport { CopilotClient } from \"./copilot\";\nimport { createHoopilotLogger, noopLogger, shouldCreateLogger } from \"./logger\";\nimport {\n chatCompletionToCompletion,\n chatCompletionToResponse,\n completionsRequestToChatCompletion,\n fallbackModels,\n normalizeModelsResponse,\n responsesRequestToChatCompletion,\n responsesStreamFromChatStream,\n} from \"./openai\";\nimport type {\n HoopilotLogger,\n HoopilotServerOptions,\n JsonObject,\n LogFields,\n StartedHoopilotServer,\n} from \"./types\";\n\nconst DEFAULT_HOST = \"127.0.0.1\";\nconst DEFAULT_PORT = 4141;\nconst INVALID_JSON_MESSAGE = \"Request body must be valid JSON.\";\n\nexport function createHoopilotHandler(options: HoopilotServerOptions = {}) {\n const client = new CopilotClient(options);\n const apiKey = options.apiKey ?? options.env?.HOOPILOT_API_KEY;\n const logger = serverLogger(options);\n\n return async (request: Request): Promise<Response> => {\n const startedAt = performance.now();\n const url = new URL(request.url);\n const apiPath = canonicalApiPath(url.pathname);\n const requestId = requestIdFor(request);\n const requestLogger = logger.child({\n method: request.method,\n path: url.pathname,\n requestId,\n route: routeFor(request.method, apiPath),\n });\n\n if (request.method === \"OPTIONS\") {\n return finishResponse(new Response(null, { headers: corsHeaders() }), {\n logger: requestLogger,\n requestId,\n startedAt,\n });\n }\n\n if (!isAuthorized(request, apiKey)) {\n requestLogger.warn({ event: \"http.request.unauthorized\" }, \"invalid hoopilot api key\");\n return finishResponse(\n jsonError(401, \"invalid_api_key\", \"Invalid or missing Hoopilot API key.\"),\n {\n logger: requestLogger,\n requestId,\n startedAt,\n },\n );\n }\n\n try {\n if (request.method === \"GET\" && (apiPath === \"/\" || apiPath === \"/healthz\")) {\n return finishResponse(\n jsonResponse({\n name: \"hoopilot\",\n object: \"health\",\n status: \"ok\",\n }),\n { logger: requestLogger, requestId, startedAt },\n );\n }\n if (request.method === \"GET\" && apiPath === \"/v1/responses\") {\n return finishResponse(websocketUnsupportedResponse(), {\n logger: requestLogger,\n requestId,\n startedAt,\n });\n }\n if (request.method === \"GET\" && apiPath === \"/v1/models\") {\n return finishResponse(await handleModels(client, request.signal, requestLogger), {\n logger: requestLogger,\n requestId,\n startedAt,\n });\n }\n if (request.method === \"POST\" && apiPath === \"/v1/chat/completions\") {\n return finishResponse(await handleChatCompletions(client, request, requestLogger), {\n logger: requestLogger,\n requestId,\n startedAt,\n });\n }\n if (request.method === \"POST\" && apiPath === \"/v1/completions\") {\n return finishResponse(await handleCompletions(client, request, requestLogger), {\n logger: requestLogger,\n requestId,\n startedAt,\n });\n }\n if (request.method === \"POST\" && apiPath === \"/v1/responses\") {\n return finishResponse(await handleResponses(client, request, requestLogger), {\n logger: requestLogger,\n requestId,\n startedAt,\n });\n }\n return finishResponse(\n jsonError(404, \"not_found\", `No route for ${request.method} ${url.pathname}.`),\n { logger: requestLogger, requestId, startedAt },\n );\n } catch (error) {\n if (error instanceof CopilotAuthError) {\n requestLogger.warn(\n { err: errorDetails(error), event: \"copilot.auth.missing\" },\n \"copilot auth failed\",\n );\n return finishResponse(jsonError(401, \"copilot_auth_error\", error.message), {\n logger: requestLogger,\n requestId,\n startedAt,\n });\n }\n const message = errorMessage(error);\n if (message === INVALID_JSON_MESSAGE) {\n requestLogger.warn(\n { err: errorDetails(error), event: \"http.request.failed\" },\n \"request body was invalid json\",\n );\n } else {\n requestLogger.error(\n { err: errorDetails(error), event: \"http.request.failed\" },\n \"request failed\",\n );\n }\n return finishResponse(jsonError(500, \"internal_error\", message), {\n logger: requestLogger,\n requestId,\n startedAt,\n });\n }\n };\n}\n\nexport function startHoopilotServer(options: HoopilotServerOptions = {}): StartedHoopilotServer {\n const host = options.host ?? options.env?.HOST ?? DEFAULT_HOST;\n const port = Number(options.port ?? options.env?.PORT ?? DEFAULT_PORT);\n const apiKey = options.apiKey ?? options.env?.HOOPILOT_API_KEY;\n const allowUnauthenticated =\n options.allowUnauthenticated ?? options.env?.HOOPILOT_ALLOW_UNAUTHENTICATED === \"1\";\n\n if (!isLoopbackHost(host) && !apiKey && !allowUnauthenticated) {\n throw new Error(\n \"Refusing to listen on a non-loopback host without HOOPILOT_API_KEY. Set an API key or pass --allow-unauthenticated.\",\n );\n }\n\n const server = Bun.serve({\n fetch: createHoopilotHandler({\n ...options,\n apiKey,\n host,\n port,\n }),\n hostname: host,\n port,\n });\n\n return {\n server,\n url: `http://${host}:${server.port}`,\n };\n}\n\nasync function handleModels(\n client: CopilotClient,\n signal: AbortSignal,\n logger: HoopilotLogger,\n): Promise<Response> {\n const upstream = await client.models(signal);\n if (!upstream.ok) {\n if (isUpstreamAuthStatus(upstream.status)) {\n return proxyError(upstream, logger);\n }\n logger.warn(\n {\n event: \"copilot.models.fallback\",\n upstreamPath: \"/models\",\n upstreamStatus: upstream.status,\n },\n \"falling back to built-in model list\",\n );\n return jsonResponse({ data: fallbackModels(), object: \"list\" });\n }\n logUpstreamSuccess(logger, \"/models\", upstream.status);\n return jsonResponse(normalizeModelsResponse(await upstream.json()));\n}\n\nasync function handleChatCompletions(\n client: CopilotClient,\n request: Request,\n logger: HoopilotLogger,\n): Promise<Response> {\n const upstream = await client.forwardChatCompletions(await request.text(), request.signal);\n if (!upstream.ok) {\n return proxyError(upstream, logger);\n }\n logUpstreamSuccess(logger, \"/chat/completions\", upstream.status);\n return proxyResponse(upstream);\n}\n\nasync function handleCompletions(\n client: CopilotClient,\n request: Request,\n logger: HoopilotLogger,\n): Promise<Response> {\n const body = await readJson(request);\n const upstream = await client.chatCompletions(\n completionsRequestToChatCompletion(body),\n request.signal,\n );\n if (!upstream.ok) {\n return proxyError(upstream, logger);\n }\n logUpstreamSuccess(logger, \"/chat/completions\", upstream.status);\n return jsonResponse(chatCompletionToCompletion(await upstream.json()));\n}\n\nasync function handleResponses(\n client: CopilotClient,\n request: Request,\n logger: HoopilotLogger,\n): Promise<Response> {\n const body = await readJson(request);\n const chatRequest = responsesRequestToChatCompletion(body);\n const upstream = await client.chatCompletions(chatRequest, request.signal);\n if (!upstream.ok) {\n return proxyError(upstream, logger);\n }\n logUpstreamSuccess(logger, \"/chat/completions\", upstream.status);\n\n if (body.stream === true && upstream.body) {\n return new Response(\n responsesStreamFromChatStream(upstream.body, {\n model: typeof chatRequest.model === \"string\" ? chatRequest.model : \"gpt-4.1\",\n }),\n {\n headers: {\n ...corsHeaders(),\n \"cache-control\": \"no-cache\",\n connection: \"keep-alive\",\n \"content-type\": \"text/event-stream; charset=utf-8\",\n },\n },\n );\n }\n\n return jsonResponse(chatCompletionToResponse(await upstream.json()));\n}\n\nasync function proxyError(upstream: Response, logger: HoopilotLogger): Promise<Response> {\n const text = await upstream.text();\n if (isUpstreamAuthStatus(upstream.status)) {\n logger.warn(\n { event: \"copilot.auth.rejected\", upstreamStatus: upstream.status },\n \"copilot rejected credential or account access\",\n );\n return jsonError(401, \"copilot_auth_error\", upstreamAuthMessage(text || upstream.statusText));\n }\n logger.warn(\n { event: \"copilot.request.failed\", upstreamStatus: upstream.status },\n \"copilot upstream request failed\",\n );\n return jsonError(upstream.status, \"copilot_error\", text || upstream.statusText);\n}\n\nfunction proxyResponse(upstream: Response): Response {\n const headers = new Headers(upstream.headers);\n headers.delete(\"content-encoding\");\n headers.delete(\"content-length\");\n headers.delete(\"transfer-encoding\");\n for (const [key, value] of Object.entries(corsHeaders())) {\n headers.set(key, value);\n }\n return new Response(upstream.body, {\n headers,\n status: upstream.status,\n statusText: upstream.statusText,\n });\n}\n\nasync function readJson(request: Request): Promise<JsonObject> {\n try {\n const value = await request.json();\n return value && typeof value === \"object\" && !Array.isArray(value) ? (value as JsonObject) : {};\n } catch {\n throw new Error(INVALID_JSON_MESSAGE);\n }\n}\n\nfunction jsonResponse(body: JsonObject, status = 200): Response {\n return new Response(JSON.stringify(body), {\n headers: {\n ...corsHeaders(),\n \"content-type\": \"application/json; charset=utf-8\",\n },\n status,\n });\n}\n\nfunction jsonError(status: number, code: string, message: string): Response {\n return jsonResponse(\n {\n error: {\n code,\n message,\n type: code,\n },\n },\n status,\n );\n}\n\nfunction websocketUnsupportedResponse(): Response {\n const response = jsonError(\n 426,\n \"websocket_not_supported\",\n \"Hoopilot does not support Responses WebSocket transport; retry with HTTP Responses API.\",\n );\n response.headers.set(\"upgrade\", \"websocket\");\n return response;\n}\n\nfunction corsHeaders(): Record<string, string> {\n return {\n \"access-control-allow-headers\": \"authorization, content-type, x-api-key\",\n \"access-control-allow-methods\": \"GET, POST, OPTIONS\",\n \"access-control-allow-origin\": \"*\",\n };\n}\n\nfunction isAuthorized(request: Request, apiKey: string | undefined): boolean {\n if (!apiKey) {\n return true;\n }\n const authorization = request.headers.get(\"authorization\") ?? \"\";\n const bearer = authorization.match(/^Bearer\\s+(.+)$/i)?.[1];\n return bearer === apiKey || request.headers.get(\"x-api-key\") === apiKey;\n}\n\nfunction isUpstreamAuthStatus(status: number): boolean {\n return status === 401 || status === 403;\n}\n\nfunction upstreamAuthMessage(message: string): string {\n return `GitHub Copilot rejected the credential or account access: ${message}`;\n}\n\nfunction isLoopbackHost(host: string): boolean {\n return host === \"localhost\" || host === \"127.0.0.1\" || host === \"::1\";\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction serverLogger(options: HoopilotServerOptions): HoopilotLogger {\n if (options.logger) {\n return options.logger.child({ component: \"server\" });\n }\n if (shouldCreateLogger(options)) {\n return createHoopilotLogger({\n env: options.env,\n format: options.logFormat,\n level: options.logLevel,\n }).child({ component: \"server\" });\n }\n return noopLogger;\n}\n\nfunction finishResponse(\n response: Response,\n options: { logger: HoopilotLogger; requestId: string; startedAt: number },\n): Response {\n const withRequestId = responseWithRequestId(response, options.requestId);\n logRequestCompleted(options.logger, withRequestId, options.startedAt);\n return withRequestId;\n}\n\nfunction responseWithRequestId(response: Response, requestId: string): Response {\n const headers = new Headers(response.headers);\n headers.set(\"x-request-id\", requestId);\n return new Response(response.body, {\n headers,\n status: response.status,\n statusText: response.statusText,\n });\n}\n\nfunction logRequestCompleted(logger: HoopilotLogger, response: Response, startedAt: number): void {\n const fields: LogFields = {\n durationMs: Math.round((performance.now() - startedAt) * 100) / 100,\n event: \"http.request.completed\",\n status: response.status,\n stream: isStreamingResponse(response),\n };\n if (response.status >= 500) {\n logger.error(fields, \"request completed with server error\");\n return;\n }\n if (response.status >= 400) {\n logger.warn(fields, \"request completed with client error\");\n return;\n }\n logger.info(fields, \"request completed\");\n}\n\nfunction requestIdFor(request: Request): string {\n const existing = request.headers.get(\"x-request-id\")?.trim();\n return existing || crypto.randomUUID();\n}\n\nfunction canonicalApiPath(path: string): string {\n const withoutTrailingSlash = path.length > 1 ? path.replace(/\\/+$/, \"\") : path;\n switch (withoutTrailingSlash) {\n case \"/models\":\n return \"/v1/models\";\n case \"/chat/completions\":\n return \"/v1/chat/completions\";\n case \"/completions\":\n return \"/v1/completions\";\n case \"/responses\":\n return \"/v1/responses\";\n default:\n return withoutTrailingSlash;\n }\n}\n\nfunction routeFor(method: string, path: string): string {\n if (method === \"OPTIONS\") {\n return \"cors.preflight\";\n }\n if (method === \"GET\" && (path === \"/\" || path === \"/healthz\")) {\n return \"health\";\n }\n if (method === \"GET\" && path === \"/v1/models\") {\n return \"models\";\n }\n if (method === \"POST\" && path === \"/v1/chat/completions\") {\n return \"chat_completions\";\n }\n if (method === \"POST\" && path === \"/v1/completions\") {\n return \"completions\";\n }\n if (method === \"POST\" && path === \"/v1/responses\") {\n return \"responses\";\n }\n if (method === \"GET\" && path === \"/v1/responses\") {\n return \"responses_websocket\";\n }\n return \"not_found\";\n}\n\nfunction isStreamingResponse(response: Response): boolean {\n return response.headers.get(\"content-type\")?.includes(\"text/event-stream\") ?? false;\n}\n\nfunction logUpstreamSuccess(logger: HoopilotLogger, upstreamPath: string, status: number): void {\n logger.debug(\n {\n event: \"copilot.request.completed\",\n upstreamPath,\n upstreamStatus: status,\n },\n \"copilot upstream request completed\",\n );\n}\n\nfunction errorDetails(error: unknown): LogFields {\n if (error instanceof Error) {\n return {\n message: error.message,\n name: error.name,\n stack: error.stack,\n };\n }\n return { message: String(error) };\n}\n"],"mappings":"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","names":["sleep","pino","pretty"]}
|
package/dist/index.js
CHANGED
|
@@ -941,6 +941,13 @@ function createHoopilotHandler(options = {}) {
|
|
|
941
941
|
{ logger: requestLogger, requestId, startedAt }
|
|
942
942
|
);
|
|
943
943
|
}
|
|
944
|
+
if (request.method === "GET" && apiPath === "/v1/responses") {
|
|
945
|
+
return finishResponse(websocketUnsupportedResponse(), {
|
|
946
|
+
logger: requestLogger,
|
|
947
|
+
requestId,
|
|
948
|
+
startedAt
|
|
949
|
+
});
|
|
950
|
+
}
|
|
944
951
|
if (request.method === "GET" && apiPath === "/v1/models") {
|
|
945
952
|
return finishResponse(await handleModels(client, request.signal, requestLogger), {
|
|
946
953
|
logger: requestLogger,
|
|
@@ -1152,6 +1159,15 @@ function jsonError(status, code, message) {
|
|
|
1152
1159
|
status
|
|
1153
1160
|
);
|
|
1154
1161
|
}
|
|
1162
|
+
function websocketUnsupportedResponse() {
|
|
1163
|
+
const response = jsonError(
|
|
1164
|
+
426,
|
|
1165
|
+
"websocket_not_supported",
|
|
1166
|
+
"Hoopilot does not support Responses WebSocket transport; retry with HTTP Responses API."
|
|
1167
|
+
);
|
|
1168
|
+
response.headers.set("upgrade", "websocket");
|
|
1169
|
+
return response;
|
|
1170
|
+
}
|
|
1155
1171
|
function corsHeaders() {
|
|
1156
1172
|
return {
|
|
1157
1173
|
"access-control-allow-headers": "authorization, content-type, x-api-key",
|
|
@@ -1261,6 +1277,9 @@ function routeFor(method, path) {
|
|
|
1261
1277
|
if (method === "POST" && path === "/v1/responses") {
|
|
1262
1278
|
return "responses";
|
|
1263
1279
|
}
|
|
1280
|
+
if (method === "GET" && path === "/v1/responses") {
|
|
1281
|
+
return "responses_websocket";
|
|
1282
|
+
}
|
|
1264
1283
|
return "not_found";
|
|
1265
1284
|
}
|
|
1266
1285
|
function isStreamingResponse(response) {
|