@jeffreycao/copilot-api 2.6.24 → 2.6.25

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.
Files changed (33) hide show
  1. package/README.md +2 -2
  2. package/README.zh-CN.md +2 -2
  3. package/dist/{auth-CiQGjfAS.js → auth-BM1NSmaY.js} +6 -4
  4. package/dist/auth-BM1NSmaY.js.map +1 -0
  5. package/dist/auth-DGt1r0Ik.js +2 -0
  6. package/dist/{config-B_pC8QXv.js → config-AlcbghlW.js} +24 -370
  7. package/dist/config-AlcbghlW.js.map +1 -0
  8. package/dist/config-store--1vrPTFC.js +363 -0
  9. package/dist/config-store--1vrPTFC.js.map +1 -0
  10. package/dist/{debug-C4rsL806.js → debug-Cykqg-GL.js} +3 -2
  11. package/dist/{debug-C4rsL806.js.map → debug-Cykqg-GL.js.map} +1 -1
  12. package/dist/github-copilot-provider-BWQdEbDy.js +79 -0
  13. package/dist/github-copilot-provider-BWQdEbDy.js.map +1 -0
  14. package/dist/main.js +6 -4
  15. package/dist/main.js.map +1 -1
  16. package/dist/{models-DG6m2Cfd.js → models-DKDMBzWM.js} +2 -2
  17. package/dist/{models-DG6m2Cfd.js.map → models-DKDMBzWM.js.map} +1 -1
  18. package/dist/provider-C38mrz76.js +36 -0
  19. package/dist/provider-C38mrz76.js.map +1 -0
  20. package/dist/provider-management-B8wlMJ5F.js +61 -0
  21. package/dist/provider-management-B8wlMJ5F.js.map +1 -0
  22. package/dist/{server-D-oBVjPR.js → server-ihCUW7FV.js} +144 -27
  23. package/dist/server-ihCUW7FV.js.map +1 -0
  24. package/dist/{start-DqY0wdWh.js → start-lTEXu1xj.js} +12 -9
  25. package/dist/{start-DqY0wdWh.js.map → start-lTEXu1xj.js.map} +1 -1
  26. package/dist/{token-6Ld3Ff3c.js → token-CnzxfSWL.js} +16 -63
  27. package/dist/token-CnzxfSWL.js.map +1 -0
  28. package/package.json +2 -1
  29. package/dist/auth-CiQGjfAS.js.map +0 -1
  30. package/dist/auth-D2amX0hm.js +0 -2
  31. package/dist/config-B_pC8QXv.js.map +0 -1
  32. package/dist/server-D-oBVjPR.js.map +0 -1
  33. package/dist/token-6Ld3Ff3c.js.map +0 -1
@@ -0,0 +1,79 @@
1
+ import { c as getConfig } from "./config-store--1vrPTFC.js";
2
+ import consola from "consola";
3
+ //#region src/lib/error.ts
4
+ var HTTPError = class extends Error {
5
+ response;
6
+ constructor(message, response) {
7
+ super(message);
8
+ this.response = response;
9
+ }
10
+ };
11
+ var UpstreamHeadersTimeoutError = class extends Error {
12
+ timeoutMs;
13
+ constructor(timeoutMs) {
14
+ super(`Upstream did not return headers within ${timeoutMs}ms`);
15
+ this.name = "UpstreamHeadersTimeoutError";
16
+ this.timeoutMs = timeoutMs;
17
+ }
18
+ };
19
+ var UpstreamStreamInactivityTimeoutError = class extends Error {
20
+ timeoutMs;
21
+ constructor(timeoutMs) {
22
+ super(`Upstream stream was inactive for ${timeoutMs}ms`);
23
+ this.name = "UpstreamStreamInactivityTimeoutError";
24
+ this.timeoutMs = timeoutMs;
25
+ }
26
+ };
27
+ async function forwardError(c, error) {
28
+ if (error instanceof UpstreamHeadersTimeoutError || error instanceof UpstreamStreamInactivityTimeoutError) {
29
+ consola.error("Error occurred:", error);
30
+ return c.json({ error: {
31
+ message: error.message,
32
+ type: "upstream_timeout"
33
+ } }, 504);
34
+ }
35
+ if (c.req.raw.signal.aborted || isAbortError(error)) return new Response(null, {
36
+ status: 499,
37
+ statusText: "Client Closed Request"
38
+ });
39
+ consola.error("Error occurred:", error);
40
+ if (error instanceof HTTPError) {
41
+ if (error.response.status === 429) for (const [name, value] of error.response.headers) {
42
+ const lowerName = name.toLowerCase();
43
+ if (lowerName === "retry-after" || lowerName.startsWith("x-")) c.header(name, value);
44
+ }
45
+ const errorText = await error.response.text();
46
+ let errorJson;
47
+ try {
48
+ errorJson = JSON.parse(errorText);
49
+ } catch {
50
+ errorJson = errorText;
51
+ }
52
+ consola.error("HTTP error:", errorJson);
53
+ return c.json({ error: {
54
+ message: errorText,
55
+ type: "error"
56
+ } }, error.response.status);
57
+ }
58
+ return c.json({ error: {
59
+ message: error.message,
60
+ type: "error"
61
+ } }, 500);
62
+ }
63
+ const isAbortError = (error) => error instanceof Error && error.name === "AbortError";
64
+ //#endregion
65
+ //#region src/lib/github-copilot-provider.ts
66
+ const GITHUB_COPILOT_PROVIDER = "github-copilot";
67
+ function isGitHubCopilotEnabled(config = getConfig()) {
68
+ return config.providers?.[GITHUB_COPILOT_PROVIDER]?.enabled !== false;
69
+ }
70
+ function assertGitHubCopilotEnabled() {
71
+ if (!isGitHubCopilotEnabled()) throw new HTTPError("GitHub Copilot provider is disabled", Response.json({ error: {
72
+ message: "GitHub Copilot provider is disabled",
73
+ type: "provider_disabled"
74
+ } }, { status: 403 }));
75
+ }
76
+ //#endregion
77
+ export { UpstreamHeadersTimeoutError as a, HTTPError as i, assertGitHubCopilotEnabled as n, UpstreamStreamInactivityTimeoutError as o, isGitHubCopilotEnabled as r, forwardError as s, GITHUB_COPILOT_PROVIDER as t };
78
+
79
+ //# sourceMappingURL=github-copilot-provider-BWQdEbDy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-copilot-provider-BWQdEbDy.js","names":[],"sources":["../src/lib/error.ts","../src/lib/github-copilot-provider.ts"],"sourcesContent":["import type { Context } from \"hono\"\nimport type { ContentfulStatusCode } from \"hono/utils/http-status\"\n\nimport consola from \"consola\"\n\nexport class HTTPError extends Error {\n response: Response\n\n constructor(message: string, response: Response) {\n super(message)\n this.response = response\n }\n}\n\nexport class UpstreamHeadersTimeoutError extends Error {\n readonly timeoutMs: number\n\n constructor(timeoutMs: number) {\n super(`Upstream did not return headers within ${timeoutMs}ms`)\n this.name = \"UpstreamHeadersTimeoutError\"\n this.timeoutMs = timeoutMs\n }\n}\n\nexport class UpstreamStreamInactivityTimeoutError extends Error {\n readonly timeoutMs: number\n\n constructor(timeoutMs: number) {\n super(`Upstream stream was inactive for ${timeoutMs}ms`)\n this.name = \"UpstreamStreamInactivityTimeoutError\"\n this.timeoutMs = timeoutMs\n }\n}\n\nexport async function forwardError(\n c: Context,\n error: unknown,\n): Promise<Response> {\n if (\n error instanceof UpstreamHeadersTimeoutError\n || error instanceof UpstreamStreamInactivityTimeoutError\n ) {\n consola.error(\"Error occurred:\", error)\n return c.json(\n {\n error: {\n message: error.message,\n type: \"upstream_timeout\",\n },\n },\n 504,\n )\n }\n\n if (c.req.raw.signal.aborted || isAbortError(error)) {\n return new Response(null, {\n status: 499,\n statusText: \"Client Closed Request\",\n })\n }\n\n consola.error(\"Error occurred:\", error)\n\n if (error instanceof HTTPError) {\n if (error.response.status === 429) {\n for (const [name, value] of error.response.headers) {\n const lowerName = name.toLowerCase()\n if (lowerName === \"retry-after\" || lowerName.startsWith(\"x-\")) {\n c.header(name, value)\n }\n }\n }\n\n const errorText = await error.response.text()\n let errorJson: unknown\n try {\n errorJson = JSON.parse(errorText)\n } catch {\n errorJson = errorText\n }\n consola.error(\"HTTP error:\", errorJson)\n return c.json(\n {\n error: {\n message: errorText,\n type: \"error\",\n },\n },\n error.response.status as ContentfulStatusCode,\n )\n }\n\n return c.json(\n {\n error: {\n message: (error as Error).message,\n type: \"error\",\n },\n },\n 500,\n )\n}\n\nconst isAbortError = (error: unknown): boolean =>\n error instanceof Error && error.name === \"AbortError\"\n","import { getConfig, type AppConfig } from \"./config-store\"\nimport { HTTPError } from \"./error\"\n\nexport const GITHUB_COPILOT_PROVIDER = \"github-copilot\"\n\n// Missing configuration preserves the legacy builtin Copilot behavior.\nexport function isGitHubCopilotEnabled(\n config: AppConfig = getConfig(),\n): boolean {\n return config.providers?.[GITHUB_COPILOT_PROVIDER]?.enabled !== false\n}\n\nexport function assertGitHubCopilotEnabled(): void {\n if (!isGitHubCopilotEnabled()) {\n throw new HTTPError(\n \"GitHub Copilot provider is disabled\",\n Response.json(\n {\n error: {\n message: \"GitHub Copilot provider is disabled\",\n type: \"provider_disabled\",\n },\n },\n { status: 403 },\n ),\n )\n }\n}\n"],"mappings":";;;AAKA,IAAa,YAAb,cAA+B,MAAM;CACnC;CAEA,YAAY,SAAiB,UAAoB;EAC/C,MAAM,OAAO;EACb,KAAK,WAAW;CAClB;AACF;AAEA,IAAa,8BAAb,cAAiD,MAAM;CACrD;CAEA,YAAY,WAAmB;EAC7B,MAAM,0CAA0C,UAAU,GAAG;EAC7D,KAAK,OAAO;EACZ,KAAK,YAAY;CACnB;AACF;AAEA,IAAa,uCAAb,cAA0D,MAAM;CAC9D;CAEA,YAAY,WAAmB;EAC7B,MAAM,oCAAoC,UAAU,GAAG;EACvD,KAAK,OAAO;EACZ,KAAK,YAAY;CACnB;AACF;AAEA,eAAsB,aACpB,GACA,OACmB;CACnB,IACE,iBAAiB,+BACd,iBAAiB,sCACpB;EACA,QAAQ,MAAM,mBAAmB,KAAK;EACtC,OAAO,EAAE,KACP,EACE,OAAO;GACL,SAAS,MAAM;GACf,MAAM;EACR,EACF,GACA,GACF;CACF;CAEA,IAAI,EAAE,IAAI,IAAI,OAAO,WAAW,aAAa,KAAK,GAChD,OAAO,IAAI,SAAS,MAAM;EACxB,QAAQ;EACR,YAAY;CACd,CAAC;CAGH,QAAQ,MAAM,mBAAmB,KAAK;CAEtC,IAAI,iBAAiB,WAAW;EAC9B,IAAI,MAAM,SAAS,WAAW,KAC5B,KAAK,MAAM,CAAC,MAAM,UAAU,MAAM,SAAS,SAAS;GAClD,MAAM,YAAY,KAAK,YAAY;GACnC,IAAI,cAAc,iBAAiB,UAAU,WAAW,IAAI,GAC1D,EAAE,OAAO,MAAM,KAAK;EAExB;EAGF,MAAM,YAAY,MAAM,MAAM,SAAS,KAAK;EAC5C,IAAI;EACJ,IAAI;GACF,YAAY,KAAK,MAAM,SAAS;EAClC,QAAQ;GACN,YAAY;EACd;EACA,QAAQ,MAAM,eAAe,SAAS;EACtC,OAAO,EAAE,KACP,EACE,OAAO;GACL,SAAS;GACT,MAAM;EACR,EACF,GACA,MAAM,SAAS,MACjB;CACF;CAEA,OAAO,EAAE,KACP,EACE,OAAO;EACL,SAAU,MAAgB;EAC1B,MAAM;CACR,EACF,GACA,GACF;AACF;AAEA,MAAM,gBAAgB,UACpB,iBAAiB,SAAS,MAAM,SAAS;;;ACrG3C,MAAa,0BAA0B;AAGvC,SAAgB,uBACd,SAAoB,UAAU,GACrB;CACT,OAAO,OAAO,YAAY,wBAAwB,EAAE,YAAY;AAClE;AAEA,SAAgB,6BAAmC;CACjD,IAAI,CAAC,uBAAuB,GAC1B,MAAM,IAAI,UACR,uCACA,SAAS,KACP,EACE,OAAO;EACL,SAAS;EACT,MAAM;CACR,EACF,GACA,EAAE,QAAQ,IAAI,CAChB,CACF;AAEJ"}
package/dist/main.js CHANGED
@@ -27,10 +27,11 @@ if (isMcpFastPath(process.argv)) {
27
27
  if (process.platform === "win32" && process.stdout.isTTY && !process.env.WT_SESSION) process.env.WT_SESSION = "copilot-api";
28
28
  const { bindElectronFetch } = await import("./electron-fetch-DsMaRX6v.js");
29
29
  bindElectronFetch();
30
- const { auth } = await import("./auth-D2amX0hm.js");
31
- const { debug } = await import("./debug-C4rsL806.js");
30
+ const { auth } = await import("./auth-DGt1r0Ik.js");
31
+ const { debug } = await import("./debug-Cykqg-GL.js");
32
32
  const { mcp } = await import("./mcp-Byz9h_xz.js");
33
- const { start } = await import("./start-DqY0wdWh.js");
33
+ const { start } = await import("./start-lTEXu1xj.js");
34
+ const { provider } = await import("./provider-C38mrz76.js");
34
35
  await runMain(defineCommand({
35
36
  meta: {
36
37
  name: "copilot-api",
@@ -40,7 +41,8 @@ if (isMcpFastPath(process.argv)) {
40
41
  auth,
41
42
  start,
42
43
  debug,
43
- mcp
44
+ mcp,
45
+ provider
44
46
  },
45
47
  args: cliArgs
46
48
  }));
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","names":[],"sources":["../src/main.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { isMcpFastPath } from \"./lib/fast-path\"\n\n// Fast path: `copilot-api mcp` starts the MCP bridge without loading citty\n// or the gateway modules, keeping MCP client startup fast.\nif (isMcpFastPath(process.argv)) {\n const { runMcpServer } = await import(\"./lib/mcp-server\")\n await runMcpServer()\n} else {\n const { defineCommand, runMain, parseArgs } = await import(\"citty\")\n\n const cliArgs = {\n \"api-home\": {\n type: \"string\",\n description: \"Path to the API home directory.\",\n },\n \"oauth-app\": {\n type: \"string\",\n description: \"OAuth app identifier.\",\n },\n \"enterprise-url\": {\n type: \"string\",\n description: \"Enterprise URL for GitHub.\",\n },\n } as const\n\n const args = parseArgs(process.argv, cliArgs)\n\n // Set environment variables before loading other modules\n if (typeof args[\"api-home\"] === \"string\") {\n process.env.COPILOT_API_HOME = args[\"api-home\"]\n }\n if (typeof args[\"oauth-app\"] === \"string\") {\n process.env.COPILOT_API_OAUTH_APP = args[\"oauth-app\"]\n }\n if (typeof args[\"enterprise-url\"] === \"string\") {\n process.env.COPILOT_API_ENTERPRISE_URL = args[\"enterprise-url\"]\n }\n\n // Work around unjs/consola#392 until consola ships the upstream fix.\n if (\n process.platform === \"win32\"\n && process.stdout.isTTY\n && !process.env.WT_SESSION\n ) {\n process.env.WT_SESSION = \"copilot-api\"\n }\n\n const { bindElectronFetch } = await import(\"./lib/electron-fetch\")\n bindElectronFetch()\n\n // Dynamically import other modules to ensure environment variables are set\n const { auth } = await import(\"./auth\")\n const { debug } = await import(\"./debug\")\n const { mcp } = await import(\"./mcp\")\n const { start } = await import(\"./start\")\n\n const main = defineCommand({\n meta: {\n name: \"copilot-api\",\n description:\n \"A wrapper around GitHub Copilot API to make it OpenAI compatible, making it usable for other tools.\",\n },\n subCommands: { auth, start, debug, mcp },\n args: cliArgs,\n })\n\n await runMain(main)\n}\n"],"mappings":";;;AAMA,IAAI,cAAc,QAAQ,IAAI,GAAG;CAC/B,MAAM,EAAE,iBAAiB,MAAM,OAAO;CACtC,MAAM,aAAa;AACrB,OAAO;CACL,MAAM,EAAE,eAAe,SAAS,cAAc,MAAM,OAAO;CAE3D,MAAM,UAAU;EACd,YAAY;GACV,MAAM;GACN,aAAa;EACf;EACA,aAAa;GACX,MAAM;GACN,aAAa;EACf;EACA,kBAAkB;GAChB,MAAM;GACN,aAAa;EACf;CACF;CAEA,MAAM,OAAO,UAAU,QAAQ,MAAM,OAAO;CAG5C,IAAI,OAAO,KAAK,gBAAgB,UAC9B,QAAQ,IAAI,mBAAmB,KAAK;CAEtC,IAAI,OAAO,KAAK,iBAAiB,UAC/B,QAAQ,IAAI,wBAAwB,KAAK;CAE3C,IAAI,OAAO,KAAK,sBAAsB,UACpC,QAAQ,IAAI,6BAA6B,KAAK;CAIhD,IACE,QAAQ,aAAa,WAClB,QAAQ,OAAO,SACf,CAAC,QAAQ,IAAI,YAEhB,QAAQ,IAAI,aAAa;CAG3B,MAAM,EAAE,sBAAsB,MAAM,OAAO;CAC3C,kBAAkB;CAGlB,MAAM,EAAE,SAAS,MAAM,OAAO;CAC9B,MAAM,EAAE,UAAU,MAAM,OAAO;CAC/B,MAAM,EAAE,QAAQ,MAAM,OAAO;CAC7B,MAAM,EAAE,UAAU,MAAM,OAAO;CAY/B,MAAM,QAVO,cAAc;EACzB,MAAM;GACJ,MAAM;GACN,aACE;EACJ;EACA,aAAa;GAAE;GAAM;GAAO;GAAO;EAAI;EACvC,MAAM;CACR,CAEiB,CAAC;AACpB"}
1
+ {"version":3,"file":"main.js","names":[],"sources":["../src/main.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { isMcpFastPath } from \"./lib/fast-path\"\n\n// Fast path: `copilot-api mcp` starts the MCP bridge without loading citty\n// or the gateway modules, keeping MCP client startup fast.\nif (isMcpFastPath(process.argv)) {\n const { runMcpServer } = await import(\"./lib/mcp-server\")\n await runMcpServer()\n} else {\n const { defineCommand, runMain, parseArgs } = await import(\"citty\")\n\n const cliArgs = {\n \"api-home\": {\n type: \"string\",\n description: \"Path to the API home directory.\",\n },\n \"oauth-app\": {\n type: \"string\",\n description: \"OAuth app identifier.\",\n },\n \"enterprise-url\": {\n type: \"string\",\n description: \"Enterprise URL for GitHub.\",\n },\n } as const\n\n const args = parseArgs(process.argv, cliArgs)\n\n // Set environment variables before loading other modules\n if (typeof args[\"api-home\"] === \"string\") {\n process.env.COPILOT_API_HOME = args[\"api-home\"]\n }\n if (typeof args[\"oauth-app\"] === \"string\") {\n process.env.COPILOT_API_OAUTH_APP = args[\"oauth-app\"]\n }\n if (typeof args[\"enterprise-url\"] === \"string\") {\n process.env.COPILOT_API_ENTERPRISE_URL = args[\"enterprise-url\"]\n }\n\n // Work around unjs/consola#392 until consola ships the upstream fix.\n if (\n process.platform === \"win32\"\n && process.stdout.isTTY\n && !process.env.WT_SESSION\n ) {\n process.env.WT_SESSION = \"copilot-api\"\n }\n\n const { bindElectronFetch } = await import(\"./lib/electron-fetch\")\n bindElectronFetch()\n\n // Dynamically import other modules to ensure environment variables are set\n const { auth } = await import(\"./auth\")\n const { debug } = await import(\"./debug\")\n const { mcp } = await import(\"./mcp\")\n const { start } = await import(\"./start\")\n const { provider } = await import(\"./provider\")\n\n const main = defineCommand({\n meta: {\n name: \"copilot-api\",\n description:\n \"A wrapper around GitHub Copilot API to make it OpenAI compatible, making it usable for other tools.\",\n },\n subCommands: { auth, start, debug, mcp, provider },\n args: cliArgs,\n })\n\n await runMain(main)\n}\n"],"mappings":";;;AAMA,IAAI,cAAc,QAAQ,IAAI,GAAG;CAC/B,MAAM,EAAE,iBAAiB,MAAM,OAAO;CACtC,MAAM,aAAa;AACrB,OAAO;CACL,MAAM,EAAE,eAAe,SAAS,cAAc,MAAM,OAAO;CAE3D,MAAM,UAAU;EACd,YAAY;GACV,MAAM;GACN,aAAa;EACf;EACA,aAAa;GACX,MAAM;GACN,aAAa;EACf;EACA,kBAAkB;GAChB,MAAM;GACN,aAAa;EACf;CACF;CAEA,MAAM,OAAO,UAAU,QAAQ,MAAM,OAAO;CAG5C,IAAI,OAAO,KAAK,gBAAgB,UAC9B,QAAQ,IAAI,mBAAmB,KAAK;CAEtC,IAAI,OAAO,KAAK,iBAAiB,UAC/B,QAAQ,IAAI,wBAAwB,KAAK;CAE3C,IAAI,OAAO,KAAK,sBAAsB,UACpC,QAAQ,IAAI,6BAA6B,KAAK;CAIhD,IACE,QAAQ,aAAa,WAClB,QAAQ,OAAO,SACf,CAAC,QAAQ,IAAI,YAEhB,QAAQ,IAAI,aAAa;CAG3B,MAAM,EAAE,sBAAsB,MAAM,OAAO;CAC3C,kBAAkB;CAGlB,MAAM,EAAE,SAAS,MAAM,OAAO;CAC9B,MAAM,EAAE,UAAU,MAAM,OAAO;CAC/B,MAAM,EAAE,QAAQ,MAAM,OAAO;CAC7B,MAAM,EAAE,UAAU,MAAM,OAAO;CAC/B,MAAM,EAAE,aAAa,MAAM,OAAO;CAYlC,MAAM,QAVO,cAAc;EACzB,MAAM;GACJ,MAAM;GACN,aACE;EACJ;EACA,aAAa;GAAE;GAAM;GAAO;GAAO;GAAK;EAAS;EACjD,MAAM;CACR,CAEiB,CAAC;AACpB"}
@@ -1,4 +1,4 @@
1
- import { Z as state } from "./token-6Ld3Ff3c.js";
1
+ import { Z as state } from "./token-CnzxfSWL.js";
2
2
  //#region src/lib/models.ts
3
3
  /**
4
4
  * Converts a Copilot upstream model ID to a client-friendly ID that Claude Code
@@ -87,4 +87,4 @@ const normalizeSdkModelId = (sdkModelId) => {
87
87
  //#endregion
88
88
  export { toClientModelId as i, getLatestModelForFamily as n, normalizeSdkModelId as r, findEndpointModel as t };
89
89
 
90
- //# sourceMappingURL=models-DG6m2Cfd.js.map
90
+ //# sourceMappingURL=models-DKDMBzWM.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"models-DG6m2Cfd.js","names":[],"sources":["../src/lib/models.ts"],"sourcesContent":["import type { Model } from \"~/lib/types/models\"\n\nimport { state } from \"~/lib/state\"\n\n/**\n * Converts a Copilot upstream model ID to a client-friendly ID that Claude Code\n * and Claude Desktop recognize (dots in version replaced with hyphens).\n * e.g. \"claude-sonnet-4.6\" -> \"claude-sonnet-4-6\"\n * Non-Claude models are returned unchanged.\n */\nexport const toClientModelId = (modelId: string): string => {\n const normalized = normalizeSdkModelId(modelId)\n if (!normalized) return modelId\n const versionHyphenated = normalized.version.replaceAll(\".\", \"-\")\n return `claude-${normalized.family}-${versionHyphenated}`\n}\n\nexport interface NormalizedSdkModelId {\n family: string\n version: string\n}\n\nexport const findEndpointModel = (sdkModelId: string): Model | undefined => {\n const models = state.models?.data ?? []\n const exactMatch = models.find((m) => m.id === sdkModelId)\n if (exactMatch) {\n return exactMatch\n }\n\n const normalized = normalizeSdkModelId(sdkModelId)\n if (!normalized) {\n return undefined\n }\n\n const modelName = `claude-${normalized.family}-${normalized.version}`\n const model = models.find((m) => m.id === modelName)\n if (model) {\n return model\n }\n\n return undefined\n}\n\n/**\n * Finds the latest available model for a given Claude family (e.g. \"opus\",\n * \"sonnet\", \"haiku\") among the models currently cached in `state.models`.\n * \"Latest\" is determined by the highest semantic version parsed from the model\n * ID. Returns `undefined` when no model of that family is available.\n */\nexport const getLatestModelForFamily = (family: string): Model | undefined => {\n const models = state.models?.data ?? []\n\n let best: { model: Model; major: number; minor: number } | undefined\n\n for (const model of models) {\n const normalized = normalizeSdkModelId(model.id)\n if (!normalized || normalized.family !== family) {\n continue\n }\n\n const [majorPart, minorPart = \"0\"] = normalized.version.split(\".\")\n const major = Number.parseInt(majorPart, 10)\n const minor = Number.parseInt(minorPart, 10)\n if (Number.isNaN(major) || Number.isNaN(minor)) {\n continue\n }\n\n if (\n !best\n || major > best.major\n || (major === best.major && minor > best.minor)\n ) {\n best = { model, major, minor }\n }\n }\n\n return best?.model\n}\n\n/**\n * Normalizes an SDK model ID to extract the model family and version.\n * this method from github copilot extension\n * Examples:\n * - \"claude-opus-4-5-20251101\" -> { family: \"opus\", version: \"4.5\" }\n * - \"claude-3-5-sonnet-20241022\" -> { family: \"sonnet\", version: \"3.5\" }\n * - \"claude-sonnet-4-20250514\" -> { family: \"sonnet\", version: \"4\" }\n * - \"claude-haiku-3-5-20250514\" -> { family: \"haiku\", version: \"3.5\" }\n * - \"claude-haiku-4.5\" -> { family: \"haiku\", version: \"4.5\" }\n */\nexport const normalizeSdkModelId = (\n sdkModelId: string,\n): NormalizedSdkModelId | undefined => {\n const lower = sdkModelId.toLowerCase()\n\n // Strip date suffix (8 digits at the end)\n const withoutDate = lower.replace(/-\\d{8}$/, \"\")\n\n // Pattern 1: claude-{family}-{major}.{minor} (e.g., claude-haiku-4.5)\n const pattern1 = withoutDate.match(/^claude-(\\w+)-(\\d+)\\.(\\d+)$/)\n if (pattern1) {\n return { family: pattern1[1], version: `${pattern1[2]}.${pattern1[3]}` }\n }\n\n // Pattern 2: claude-{family}-{major}-{minor} (e.g., claude-opus-4-5, claude-haiku-3-5)\n const pattern2 = withoutDate.match(/^claude-(\\w+)-(\\d+)-(\\d+)$/)\n if (pattern2) {\n return { family: pattern2[1], version: `${pattern2[2]}.${pattern2[3]}` }\n }\n\n // Pattern 3: claude-{major}-{minor}-{family} (e.g., claude-3-5-sonnet)\n const pattern3 = withoutDate.match(/^claude-(\\d+)-(\\d+)-(\\w+)$/)\n if (pattern3) {\n return { family: pattern3[3], version: `${pattern3[1]}.${pattern3[2]}` }\n }\n\n // Pattern 4: claude-{family}-{major} (e.g., claude-sonnet-4)\n const pattern4 = withoutDate.match(/^claude-(\\w+)-(\\d+)$/)\n if (pattern4) {\n return { family: pattern4[1], version: pattern4[2] }\n }\n\n // Pattern 5: claude-{major}-{family} (e.g., claude-3-opus)\n const pattern5 = withoutDate.match(/^claude-(\\d+)-(\\w+)$/)\n if (pattern5) {\n return { family: pattern5[2], version: pattern5[1] }\n }\n\n return undefined\n}\n"],"mappings":";;;;;;;;AAUA,MAAa,mBAAmB,YAA4B;CAC1D,MAAM,aAAa,oBAAoB,OAAO;CAC9C,IAAI,CAAC,YAAY,OAAO;CACxB,MAAM,oBAAoB,WAAW,QAAQ,WAAW,KAAK,GAAG;CAChE,OAAO,UAAU,WAAW,OAAO,GAAG;AACxC;AAOA,MAAa,qBAAqB,eAA0C;CAC1E,MAAM,SAAS,MAAM,QAAQ,QAAQ,CAAC;CACtC,MAAM,aAAa,OAAO,MAAM,MAAM,EAAE,OAAO,UAAU;CACzD,IAAI,YACF,OAAO;CAGT,MAAM,aAAa,oBAAoB,UAAU;CACjD,IAAI,CAAC,YACH;CAGF,MAAM,YAAY,UAAU,WAAW,OAAO,GAAG,WAAW;CAC5D,MAAM,QAAQ,OAAO,MAAM,MAAM,EAAE,OAAO,SAAS;CACnD,IAAI,OACF,OAAO;AAIX;;;;;;;AAQA,MAAa,2BAA2B,WAAsC;CAC5E,MAAM,SAAS,MAAM,QAAQ,QAAQ,CAAC;CAEtC,IAAI;CAEJ,KAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,aAAa,oBAAoB,MAAM,EAAE;EAC/C,IAAI,CAAC,cAAc,WAAW,WAAW,QACvC;EAGF,MAAM,CAAC,WAAW,YAAY,OAAO,WAAW,QAAQ,MAAM,GAAG;EACjE,MAAM,QAAQ,OAAO,SAAS,WAAW,EAAE;EAC3C,MAAM,QAAQ,OAAO,SAAS,WAAW,EAAE;EAC3C,IAAI,OAAO,MAAM,KAAK,KAAK,OAAO,MAAM,KAAK,GAC3C;EAGF,IACE,CAAC,QACE,QAAQ,KAAK,SACZ,UAAU,KAAK,SAAS,QAAQ,KAAK,OAEzC,OAAO;GAAE;GAAO;GAAO;EAAM;CAEjC;CAEA,OAAO,MAAM;AACf;;;;;;;;;;;AAYA,MAAa,uBACX,eACqC;CAIrC,MAAM,cAHQ,WAAW,YAGD,CAAC,CAAC,QAAQ,WAAW,EAAE;CAG/C,MAAM,WAAW,YAAY,MAAM,6BAA6B;CAChE,IAAI,UACF,OAAO;EAAE,QAAQ,SAAS;EAAI,SAAS,GAAG,SAAS,GAAG,GAAG,SAAS;CAAK;CAIzE,MAAM,WAAW,YAAY,MAAM,4BAA4B;CAC/D,IAAI,UACF,OAAO;EAAE,QAAQ,SAAS;EAAI,SAAS,GAAG,SAAS,GAAG,GAAG,SAAS;CAAK;CAIzE,MAAM,WAAW,YAAY,MAAM,4BAA4B;CAC/D,IAAI,UACF,OAAO;EAAE,QAAQ,SAAS;EAAI,SAAS,GAAG,SAAS,GAAG,GAAG,SAAS;CAAK;CAIzE,MAAM,WAAW,YAAY,MAAM,sBAAsB;CACzD,IAAI,UACF,OAAO;EAAE,QAAQ,SAAS;EAAI,SAAS,SAAS;CAAG;CAIrD,MAAM,WAAW,YAAY,MAAM,sBAAsB;CACzD,IAAI,UACF,OAAO;EAAE,QAAQ,SAAS;EAAI,SAAS,SAAS;CAAG;AAIvD"}
1
+ {"version":3,"file":"models-DKDMBzWM.js","names":[],"sources":["../src/lib/models.ts"],"sourcesContent":["import type { Model } from \"~/lib/types/models\"\n\nimport { state } from \"~/lib/state\"\n\n/**\n * Converts a Copilot upstream model ID to a client-friendly ID that Claude Code\n * and Claude Desktop recognize (dots in version replaced with hyphens).\n * e.g. \"claude-sonnet-4.6\" -> \"claude-sonnet-4-6\"\n * Non-Claude models are returned unchanged.\n */\nexport const toClientModelId = (modelId: string): string => {\n const normalized = normalizeSdkModelId(modelId)\n if (!normalized) return modelId\n const versionHyphenated = normalized.version.replaceAll(\".\", \"-\")\n return `claude-${normalized.family}-${versionHyphenated}`\n}\n\nexport interface NormalizedSdkModelId {\n family: string\n version: string\n}\n\nexport const findEndpointModel = (sdkModelId: string): Model | undefined => {\n const models = state.models?.data ?? []\n const exactMatch = models.find((m) => m.id === sdkModelId)\n if (exactMatch) {\n return exactMatch\n }\n\n const normalized = normalizeSdkModelId(sdkModelId)\n if (!normalized) {\n return undefined\n }\n\n const modelName = `claude-${normalized.family}-${normalized.version}`\n const model = models.find((m) => m.id === modelName)\n if (model) {\n return model\n }\n\n return undefined\n}\n\n/**\n * Finds the latest available model for a given Claude family (e.g. \"opus\",\n * \"sonnet\", \"haiku\") among the models currently cached in `state.models`.\n * \"Latest\" is determined by the highest semantic version parsed from the model\n * ID. Returns `undefined` when no model of that family is available.\n */\nexport const getLatestModelForFamily = (family: string): Model | undefined => {\n const models = state.models?.data ?? []\n\n let best: { model: Model; major: number; minor: number } | undefined\n\n for (const model of models) {\n const normalized = normalizeSdkModelId(model.id)\n if (!normalized || normalized.family !== family) {\n continue\n }\n\n const [majorPart, minorPart = \"0\"] = normalized.version.split(\".\")\n const major = Number.parseInt(majorPart, 10)\n const minor = Number.parseInt(minorPart, 10)\n if (Number.isNaN(major) || Number.isNaN(minor)) {\n continue\n }\n\n if (\n !best\n || major > best.major\n || (major === best.major && minor > best.minor)\n ) {\n best = { model, major, minor }\n }\n }\n\n return best?.model\n}\n\n/**\n * Normalizes an SDK model ID to extract the model family and version.\n * this method from github copilot extension\n * Examples:\n * - \"claude-opus-4-5-20251101\" -> { family: \"opus\", version: \"4.5\" }\n * - \"claude-3-5-sonnet-20241022\" -> { family: \"sonnet\", version: \"3.5\" }\n * - \"claude-sonnet-4-20250514\" -> { family: \"sonnet\", version: \"4\" }\n * - \"claude-haiku-3-5-20250514\" -> { family: \"haiku\", version: \"3.5\" }\n * - \"claude-haiku-4.5\" -> { family: \"haiku\", version: \"4.5\" }\n */\nexport const normalizeSdkModelId = (\n sdkModelId: string,\n): NormalizedSdkModelId | undefined => {\n const lower = sdkModelId.toLowerCase()\n\n // Strip date suffix (8 digits at the end)\n const withoutDate = lower.replace(/-\\d{8}$/, \"\")\n\n // Pattern 1: claude-{family}-{major}.{minor} (e.g., claude-haiku-4.5)\n const pattern1 = withoutDate.match(/^claude-(\\w+)-(\\d+)\\.(\\d+)$/)\n if (pattern1) {\n return { family: pattern1[1], version: `${pattern1[2]}.${pattern1[3]}` }\n }\n\n // Pattern 2: claude-{family}-{major}-{minor} (e.g., claude-opus-4-5, claude-haiku-3-5)\n const pattern2 = withoutDate.match(/^claude-(\\w+)-(\\d+)-(\\d+)$/)\n if (pattern2) {\n return { family: pattern2[1], version: `${pattern2[2]}.${pattern2[3]}` }\n }\n\n // Pattern 3: claude-{major}-{minor}-{family} (e.g., claude-3-5-sonnet)\n const pattern3 = withoutDate.match(/^claude-(\\d+)-(\\d+)-(\\w+)$/)\n if (pattern3) {\n return { family: pattern3[3], version: `${pattern3[1]}.${pattern3[2]}` }\n }\n\n // Pattern 4: claude-{family}-{major} (e.g., claude-sonnet-4)\n const pattern4 = withoutDate.match(/^claude-(\\w+)-(\\d+)$/)\n if (pattern4) {\n return { family: pattern4[1], version: pattern4[2] }\n }\n\n // Pattern 5: claude-{major}-{family} (e.g., claude-3-opus)\n const pattern5 = withoutDate.match(/^claude-(\\d+)-(\\w+)$/)\n if (pattern5) {\n return { family: pattern5[2], version: pattern5[1] }\n }\n\n return undefined\n}\n"],"mappings":";;;;;;;;AAUA,MAAa,mBAAmB,YAA4B;CAC1D,MAAM,aAAa,oBAAoB,OAAO;CAC9C,IAAI,CAAC,YAAY,OAAO;CACxB,MAAM,oBAAoB,WAAW,QAAQ,WAAW,KAAK,GAAG;CAChE,OAAO,UAAU,WAAW,OAAO,GAAG;AACxC;AAOA,MAAa,qBAAqB,eAA0C;CAC1E,MAAM,SAAS,MAAM,QAAQ,QAAQ,CAAC;CACtC,MAAM,aAAa,OAAO,MAAM,MAAM,EAAE,OAAO,UAAU;CACzD,IAAI,YACF,OAAO;CAGT,MAAM,aAAa,oBAAoB,UAAU;CACjD,IAAI,CAAC,YACH;CAGF,MAAM,YAAY,UAAU,WAAW,OAAO,GAAG,WAAW;CAC5D,MAAM,QAAQ,OAAO,MAAM,MAAM,EAAE,OAAO,SAAS;CACnD,IAAI,OACF,OAAO;AAIX;;;;;;;AAQA,MAAa,2BAA2B,WAAsC;CAC5E,MAAM,SAAS,MAAM,QAAQ,QAAQ,CAAC;CAEtC,IAAI;CAEJ,KAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,aAAa,oBAAoB,MAAM,EAAE;EAC/C,IAAI,CAAC,cAAc,WAAW,WAAW,QACvC;EAGF,MAAM,CAAC,WAAW,YAAY,OAAO,WAAW,QAAQ,MAAM,GAAG;EACjE,MAAM,QAAQ,OAAO,SAAS,WAAW,EAAE;EAC3C,MAAM,QAAQ,OAAO,SAAS,WAAW,EAAE;EAC3C,IAAI,OAAO,MAAM,KAAK,KAAK,OAAO,MAAM,KAAK,GAC3C;EAGF,IACE,CAAC,QACE,QAAQ,KAAK,SACZ,UAAU,KAAK,SAAS,QAAQ,KAAK,OAEzC,OAAO;GAAE;GAAO;GAAO;EAAM;CAEjC;CAEA,OAAO,MAAM;AACf;;;;;;;;;;;AAYA,MAAa,uBACX,eACqC;CAIrC,MAAM,cAHQ,WAAW,YAGD,CAAC,CAAC,QAAQ,WAAW,EAAE;CAG/C,MAAM,WAAW,YAAY,MAAM,6BAA6B;CAChE,IAAI,UACF,OAAO;EAAE,QAAQ,SAAS;EAAI,SAAS,GAAG,SAAS,GAAG,GAAG,SAAS;CAAK;CAIzE,MAAM,WAAW,YAAY,MAAM,4BAA4B;CAC/D,IAAI,UACF,OAAO;EAAE,QAAQ,SAAS;EAAI,SAAS,GAAG,SAAS,GAAG,GAAG,SAAS;CAAK;CAIzE,MAAM,WAAW,YAAY,MAAM,4BAA4B;CAC/D,IAAI,UACF,OAAO;EAAE,QAAQ,SAAS;EAAI,SAAS,GAAG,SAAS,GAAG,GAAG,SAAS;CAAK;CAIzE,MAAM,WAAW,YAAY,MAAM,sBAAsB;CACzD,IAAI,UACF,OAAO;EAAE,QAAQ,SAAS;EAAI,SAAS,SAAS;CAAG;CAIrD,MAAM,WAAW,YAAY,MAAM,sBAAsB;CACzD,IAAI,UACF,OAAO;EAAE,QAAQ,SAAS;EAAI,SAAS,SAAS;CAAG;AAIvD"}
@@ -0,0 +1,36 @@
1
+ import { r as saveProviderManagementConfig } from "./provider-management-B8wlMJ5F.js";
2
+ import { defineCommand } from "citty";
3
+ //#region src/provider.ts
4
+ function providerStateCommand(enabled) {
5
+ return defineCommand({
6
+ meta: { description: `${enabled ? "Enable" : "Disable"} a configured provider` },
7
+ args: { name: {
8
+ type: "positional",
9
+ required: true,
10
+ description: "Provider name"
11
+ } },
12
+ run({ args }) {
13
+ try {
14
+ saveProviderManagementConfig({ providers: { [args.name]: { enabled } } });
15
+ process.stdout.write(`Provider '${args.name}' ${enabled ? "enabled" : "disabled"}. Restart the running server to apply the change.\n`);
16
+ } catch (error) {
17
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
18
+ process.exitCode = 1;
19
+ }
20
+ }
21
+ });
22
+ }
23
+ const provider = defineCommand({
24
+ meta: {
25
+ name: "provider",
26
+ description: "Manage configured providers"
27
+ },
28
+ subCommands: {
29
+ enable: providerStateCommand(true),
30
+ disable: providerStateCommand(false)
31
+ }
32
+ });
33
+ //#endregion
34
+ export { provider };
35
+
36
+ //# sourceMappingURL=provider-C38mrz76.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-C38mrz76.js","names":[],"sources":["../src/provider.ts"],"sourcesContent":["import { defineCommand } from \"citty\"\n\nimport { saveProviderManagementConfig } from \"./lib/provider-management\"\n\nfunction providerStateCommand(enabled: boolean) {\n return defineCommand({\n meta: {\n description: `${enabled ? \"Enable\" : \"Disable\"} a configured provider`,\n },\n args: {\n name: {\n type: \"positional\",\n required: true,\n description: \"Provider name\",\n },\n },\n run({ args }) {\n try {\n saveProviderManagementConfig({\n providers: { [args.name]: { enabled } },\n })\n process.stdout.write(\n `Provider '${args.name}' ${enabled ? \"enabled\" : \"disabled\"}. Restart the running server to apply the change.\\n`,\n )\n } catch (error) {\n process.stderr.write(\n `${error instanceof Error ? error.message : String(error)}\\n`,\n )\n process.exitCode = 1\n }\n },\n })\n}\n\nexport const provider = defineCommand({\n meta: { name: \"provider\", description: \"Manage configured providers\" },\n subCommands: {\n enable: providerStateCommand(true),\n disable: providerStateCommand(false),\n },\n})\n"],"mappings":";;;AAIA,SAAS,qBAAqB,SAAkB;CAC9C,OAAO,cAAc;EACnB,MAAM,EACJ,aAAa,GAAG,UAAU,WAAW,UAAU,wBACjD;EACA,MAAM,EACJ,MAAM;GACJ,MAAM;GACN,UAAU;GACV,aAAa;EACf,EACF;EACA,IAAI,EAAE,QAAQ;GACZ,IAAI;IACF,6BAA6B,EAC3B,WAAW,GAAG,KAAK,OAAO,EAAE,QAAQ,EAAE,EACxC,CAAC;IACD,QAAQ,OAAO,MACb,aAAa,KAAK,KAAK,IAAI,UAAU,YAAY,WAAW,oDAC9D;GACF,SAAS,OAAO;IACd,QAAQ,OAAO,MACb,GAAG,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,GAC5D;IACA,QAAQ,WAAW;GACrB;EACF;CACF,CAAC;AACH;AAEA,MAAa,WAAW,cAAc;CACpC,MAAM;EAAE,MAAM;EAAY,aAAa;CAA8B;CACrE,aAAa;EACX,QAAQ,qBAAqB,IAAI;EACjC,SAAS,qBAAqB,KAAK;CACrC;AACF,CAAC"}
@@ -0,0 +1,61 @@
1
+ import { _ as readEditableConfigFromDisk, b as writeConfigToDisk, d as invalidateConfigCache, x as PATHS } from "./config-store--1vrPTFC.js";
2
+ import { t as GITHUB_COPILOT_PROVIDER } from "./github-copilot-provider-BWQdEbDy.js";
3
+ import { z } from "zod";
4
+ //#region src/lib/provider-management.ts
5
+ const updateSchema = z.object({ providers: z.record(z.string(), z.object({
6
+ enabled: z.boolean().optional(),
7
+ codexModels: z.array(z.string().trim().min(1)).nullable().optional()
8
+ }).strict()).optional() }).strict();
9
+ function getProviderCodexModels(provider) {
10
+ const models = provider?.codexModels;
11
+ if (!Array.isArray(models) || !models.every((id) => typeof id === "string")) return;
12
+ return [...new Set(models.map((id) => id.trim()).filter(Boolean))];
13
+ }
14
+ function isProviderCodexModelVisible(provider, modelId) {
15
+ if (provider?.enabled === false) return false;
16
+ const models = getProviderCodexModels(provider);
17
+ return models === void 0 || models.includes(modelId);
18
+ }
19
+ function getProviderManagementConfig(config = readEditableConfigFromDisk()) {
20
+ const providers = {
21
+ [GITHUB_COPILOT_PROVIDER]: {},
22
+ ...config.providers
23
+ };
24
+ return {
25
+ configPath: PATHS.CONFIG_PATH,
26
+ providers: Object.entries(providers).filter(([name]) => name !== "copilot").map(([name, provider]) => ({
27
+ name,
28
+ type: name === "github-copilot" ? "github-copilot" : provider.type ?? "anthropic",
29
+ enabled: provider.enabled !== false,
30
+ codexModels: getProviderCodexModels(provider)
31
+ }))
32
+ };
33
+ }
34
+ function applyProviderManagementUpdate(config, input) {
35
+ const parsed = updateSchema.safeParse(input);
36
+ if (!parsed.success) throw new Error(parsed.error.issues[0]?.message ?? "Invalid provider update");
37
+ const { providers: updates } = parsed.data;
38
+ const providers = { ...config.providers };
39
+ for (const [name, update] of Object.entries(updates ?? {})) {
40
+ if (name === "copilot" || name !== "github-copilot" && !Object.hasOwn(providers, name)) throw new Error(`Provider '${name}' is not configured`);
41
+ const provider = { ...providers[name] };
42
+ if (update.enabled !== void 0) provider.enabled = update.enabled;
43
+ if (update.codexModels === null) delete provider.codexModels;
44
+ else if (update.codexModels !== void 0) provider.codexModels = [...new Set(update.codexModels)];
45
+ providers[name] = provider;
46
+ }
47
+ return {
48
+ ...config,
49
+ ...updates !== void 0 ? { providers } : {}
50
+ };
51
+ }
52
+ function saveProviderManagementConfig(input) {
53
+ const updated = applyProviderManagementUpdate(readEditableConfigFromDisk(), input);
54
+ writeConfigToDisk(updated);
55
+ invalidateConfigCache();
56
+ return getProviderManagementConfig(updated);
57
+ }
58
+ //#endregion
59
+ export { isProviderCodexModelVisible as n, saveProviderManagementConfig as r, getProviderCodexModels as t };
60
+
61
+ //# sourceMappingURL=provider-management-B8wlMJ5F.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-management-B8wlMJ5F.js","names":[],"sources":["../src/lib/provider-management.ts"],"sourcesContent":["import { z } from \"zod\"\n\nimport { GITHUB_COPILOT_PROVIDER } from \"./github-copilot-provider\"\n\nimport {\n invalidateConfigCache,\n readEditableConfigFromDisk,\n writeConfigToDisk,\n type AppConfig,\n type ProviderConfig,\n} from \"./config-store\"\nimport { PATHS } from \"./paths\"\nimport type { ProviderManagementConfig } from \"./types/provider-management\"\nexport type {\n ProviderManagementConfig,\n ProviderManagementUpdate,\n} from \"./types/provider-management\"\n\nconst updateSchema = z\n .object({\n providers: z\n .record(\n z.string(),\n z\n .object({\n enabled: z.boolean().optional(),\n codexModels: z\n .array(z.string().trim().min(1))\n .nullable()\n .optional(),\n })\n .strict(),\n )\n .optional(),\n })\n .strict()\n\nexport function getProviderCodexModels(\n provider: ProviderConfig | null | undefined,\n): Array<string> | undefined {\n const models = provider?.codexModels\n if (!Array.isArray(models) || !models.every((id) => typeof id === \"string\")) {\n return undefined\n }\n return [...new Set(models.map((id) => id.trim()).filter(Boolean))]\n}\n\nexport function isProviderCodexModelVisible(\n provider: ProviderConfig | null | undefined,\n modelId: string,\n): boolean {\n if (provider?.enabled === false) return false\n const models = getProviderCodexModels(provider)\n return models === undefined || models.includes(modelId)\n}\n\nexport function getProviderManagementConfig(\n config: AppConfig = readEditableConfigFromDisk(),\n): ProviderManagementConfig {\n const providers: NonNullable<AppConfig[\"providers\"]> = {\n [GITHUB_COPILOT_PROVIDER]: {},\n ...config.providers,\n }\n return {\n configPath: PATHS.CONFIG_PATH,\n providers: Object.entries(providers)\n .filter(([name]) => name !== \"copilot\")\n .map(([name, provider]) => ({\n name,\n type:\n name === GITHUB_COPILOT_PROVIDER ? \"github-copilot\" : (\n (provider.type ?? \"anthropic\")\n ),\n enabled: provider.enabled !== false,\n codexModels: getProviderCodexModels(provider),\n })),\n }\n}\n\nexport function applyProviderManagementUpdate(\n config: AppConfig,\n input: unknown,\n): AppConfig {\n const parsed = updateSchema.safeParse(input)\n if (!parsed.success) {\n throw new Error(\n parsed.error.issues[0]?.message ?? \"Invalid provider update\",\n )\n }\n const { providers: updates } = parsed.data\n const providers = { ...config.providers }\n for (const [name, update] of Object.entries(updates ?? {})) {\n if (\n name === \"copilot\"\n || (name !== GITHUB_COPILOT_PROVIDER && !Object.hasOwn(providers, name))\n ) {\n throw new Error(`Provider '${name}' is not configured`)\n }\n const provider = { ...providers[name] }\n if (update.enabled !== undefined) provider.enabled = update.enabled\n if (update.codexModels === null) {\n delete provider.codexModels\n } else if (update.codexModels !== undefined) {\n provider.codexModels = [...new Set(update.codexModels)]\n }\n providers[name] = provider\n }\n return {\n ...config,\n ...(updates !== undefined ? { providers } : {}),\n }\n}\n\nexport function saveProviderManagementConfig(\n input: unknown,\n): ProviderManagementConfig {\n const updated = applyProviderManagementUpdate(\n readEditableConfigFromDisk(),\n input,\n )\n writeConfigToDisk(updated)\n invalidateConfigCache()\n return getProviderManagementConfig(updated)\n}\n"],"mappings":";;;;AAkBA,MAAM,eAAe,EAClB,OAAO,EACN,WAAW,EACR,OACC,EAAE,OAAO,GACT,EACG,OAAO;CACN,SAAS,EAAE,QAAQ,CAAC,CAAC,SAAS;CAC9B,aAAa,EACV,MAAM,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAC/B,SAAS,CAAC,CACV,SAAS;AACd,CAAC,CAAC,CACD,OAAO,CACZ,CAAC,CACA,SAAS,EACd,CAAC,CAAC,CACD,OAAO;AAEV,SAAgB,uBACd,UAC2B;CAC3B,MAAM,SAAS,UAAU;CACzB,IAAI,CAAC,MAAM,QAAQ,MAAM,KAAK,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,QAAQ,GACxE;CAEF,OAAO,CAAC,GAAG,IAAI,IAAI,OAAO,KAAK,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC;AACnE;AAEA,SAAgB,4BACd,UACA,SACS;CACT,IAAI,UAAU,YAAY,OAAO,OAAO;CACxC,MAAM,SAAS,uBAAuB,QAAQ;CAC9C,OAAO,WAAW,KAAA,KAAa,OAAO,SAAS,OAAO;AACxD;AAEA,SAAgB,4BACd,SAAoB,2BAA2B,GACrB;CAC1B,MAAM,YAAiD;GACpD,0BAA0B,CAAC;EAC5B,GAAG,OAAO;CACZ;CACA,OAAO;EACL,YAAY,MAAM;EAClB,WAAW,OAAO,QAAQ,SAAS,CAAC,CACjC,QAAQ,CAAC,UAAU,SAAS,SAAS,CAAC,CACtC,KAAK,CAAC,MAAM,eAAe;GAC1B;GACA,MACE,SAAA,mBAAmC,mBAChC,SAAS,QAAQ;GAEtB,SAAS,SAAS,YAAY;GAC9B,aAAa,uBAAuB,QAAQ;EAC9C,EAAE;CACN;AACF;AAEA,SAAgB,8BACd,QACA,OACW;CACX,MAAM,SAAS,aAAa,UAAU,KAAK;CAC3C,IAAI,CAAC,OAAO,SACV,MAAM,IAAI,MACR,OAAO,MAAM,OAAO,EAAE,EAAE,WAAW,yBACrC;CAEF,MAAM,EAAE,WAAW,YAAY,OAAO;CACtC,MAAM,YAAY,EAAE,GAAG,OAAO,UAAU;CACxC,KAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,WAAW,CAAC,CAAC,GAAG;EAC1D,IACE,SAAS,aACL,SAAA,oBAAoC,CAAC,OAAO,OAAO,WAAW,IAAI,GAEtE,MAAM,IAAI,MAAM,aAAa,KAAK,oBAAoB;EAExD,MAAM,WAAW,EAAE,GAAG,UAAU,MAAM;EACtC,IAAI,OAAO,YAAY,KAAA,GAAW,SAAS,UAAU,OAAO;EAC5D,IAAI,OAAO,gBAAgB,MACzB,OAAO,SAAS;OACX,IAAI,OAAO,gBAAgB,KAAA,GAChC,SAAS,cAAc,CAAC,GAAG,IAAI,IAAI,OAAO,WAAW,CAAC;EAExD,UAAU,QAAQ;CACpB;CACA,OAAO;EACL,GAAG;EACH,GAAI,YAAY,KAAA,IAAY,EAAE,UAAU,IAAI,CAAC;CAC/C;AACF;AAEA,SAAgB,6BACd,OAC0B;CAC1B,MAAM,UAAU,8BACd,2BAA2B,GAC3B,KACF;CACA,kBAAkB,OAAO;CACzB,sBAAsB;CACtB,OAAO,4BAA4B,OAAO;AAC5C"}
@@ -1,7 +1,10 @@
1
- import { B as PATHS, C as resolveMappedModel, D as getAnthropicApiKey, E as getAlphaSearchModel, F as isResponsesApiWebSearchEnabled, I as isResponsesApiWebSocketEnabled, M as getUpstreamTransportConfig, N as isAlphaSearchCodexPriorityEnabled, O as getClaudeAutoModel, P as isMessagesApiEnabled, S as isGpt56OrAbove, _ as getReasoningEffortForModel, b as isContextManagementEnabledForMessages, d as getOpencodeGoModelRecords, g as getModelResponsesApiCompactThreshold$1, h as getModelMappings, i as listEnabledProviders, j as getMessageApiWebSearchModel, k as getClaudeTokenMultiplier, l as getOpencodeGoModelConfig, m as getExtraPromptForModel, n as getRawProviderConfig, o as resolveEffectiveProviderType, s as resolveProviderConfigForModel, t as getProviderConfig, u as getOpencodeGoModelIds, v as getSmallModel, w as setModelMappings, x as isContextManagementEnabledForResponses, y as getSmallModelForProvider } from "./config-B_pC8QXv.js";
2
- import { $ as forwardError, B as forwardCodexResponses, C as copilotWebSocketHeaders, E as prepareMessageProxyHeaders, G as createResponsesHttpEventStream, H as requestContext, J as getResponsesStreamTerminalDisposition, K as createResponsesSafeStream, M as compactTextOnlyGuard, N as createAuthMiddleware, O as compactAutoContinuePromptStarts, P as getConfiguredAdminApiKeys, Q as HTTPError, R as CODEX_API_BASE_URL, T as prepareInteractionHeaders, U as resolveTraceId$1, V as generateTraceId, W as fetchUpstreamWithLifecycle, X as createWebSocketUrl, Y as createPooledWebSocketStream, Z as state, b as copilotBaseUrl, d as getUUID, f as isAsyncIterable, g as getCopilotUsage, h as parseUserIdMetadata, j as compactSystemPromptStarts, k as compactMessageSections, l as generateRequestIdFromPayload, m as isResponsesStream, o as setupCodexToken, p as isNullish, q as encodePoolKeyPart, u as getRootSessionId, w as prepareForCompact, x as copilotHeaders, z as buildCodexRequestHeaders } from "./token-6Ld3Ff3c.js";
1
+ import { a as getAnthropicApiKey, f as isAlphaSearchCodexPriorityEnabled, h as isResponsesApiWebSocketEnabled, i as getAlphaSearchModel, l as getMessageApiWebSearchModel, m as isResponsesApiWebSearchEnabled, o as getClaudeAutoModel, p as isMessagesApiEnabled, s as getClaudeTokenMultiplier, u as getUpstreamTransportConfig, x as PATHS } from "./config-store--1vrPTFC.js";
2
+ import { C as resolveMappedModel, S as isGpt56OrAbove, _ as getReasoningEffortForModel, b as isContextManagementEnabledForMessages, d as getOpencodeGoModelRecords, g as getModelResponsesApiCompactThreshold$1, h as getModelMappings, i as listEnabledProviders, l as getOpencodeGoModelConfig, m as getExtraPromptForModel, n as getRawProviderConfig, o as resolveEffectiveProviderType, s as resolveProviderConfigForModel, t as getProviderConfig, u as getOpencodeGoModelIds, v as getSmallModel, w as setModelMappings, x as isContextManagementEnabledForResponses, y as getSmallModelForProvider } from "./config-AlcbghlW.js";
3
+ import { i as HTTPError, r as isGitHubCopilotEnabled, s as forwardError } from "./github-copilot-provider-BWQdEbDy.js";
4
+ import { $ as stripInternalRequestHeaders, B as forwardCodexResponses, C as copilotWebSocketHeaders, E as prepareMessageProxyHeaders, G as createResponsesHttpEventStream, H as requestContext, J as getResponsesStreamTerminalDisposition, K as createResponsesSafeStream, M as compactTextOnlyGuard, N as createAuthMiddleware, O as compactAutoContinuePromptStarts, P as getConfiguredAdminApiKeys, R as CODEX_API_BASE_URL, T as prepareInteractionHeaders, U as resolveTraceId$1, V as generateTraceId, W as fetchUpstreamWithLifecycle, X as createWebSocketUrl, Y as createPooledWebSocketStream, Z as state, b as copilotBaseUrl, d as getUUID, f as isAsyncIterable, g as getCopilotUsage, h as parseUserIdMetadata, j as compactSystemPromptStarts, k as compactMessageSections, l as generateRequestIdFromPayload, m as isResponsesStream, o as setupCodexToken, p as isNullish, q as encodePoolKeyPart, u as getRootSessionId, w as prepareForCompact, x as copilotHeaders, z as buildCodexRequestHeaders } from "./token-CnzxfSWL.js";
3
5
  import { a as isDeferredToolName, c as parseMcpToolSearchSentinel, d as shouldEnableResponsesToolSearch, i as isBridgeToolSearchName, l as resolveBridgeToolSearchName, o as listDeferredToolNames, r as formatToolSearchBridgeArguments, s as normalizeToolSearchBridgeArguments, t as BRIDGE_TOOL_SEARCH_NAME, u as selectDeferredToolsByNames } from "./tool-search-BgFcDbNQ.js";
4
- import { i as toClientModelId, r as normalizeSdkModelId, t as findEndpointModel } from "./models-DG6m2Cfd.js";
6
+ import { n as isProviderCodexModelVisible, t as getProviderCodexModels } from "./provider-management-B8wlMJ5F.js";
7
+ import { i as toClientModelId, r as normalizeSdkModelId, t as findEndpointModel } from "./models-DKDMBzWM.js";
5
8
  import consola from "consola";
6
9
  import { createHash } from "node:crypto";
7
10
  import fs, { createWriteStream, readFileSync, rmSync } from "node:fs";
@@ -1488,7 +1491,8 @@ function resolveTokenUsageCost(input) {
1488
1491
  const outputPrice = normalizePrice(pricing.output);
1489
1492
  const cacheReadPrice = resolveCacheReadPrice(pricing, input);
1490
1493
  const cacheCreationPrice = resolveCacheCreationPrice(pricing);
1491
- const totalCostNanos = costNanosForTokens(input.input_tokens, inputPrice) + costNanosForTokens(input.output_tokens, outputPrice) + costNanosForTokens(input.cache_read_input_tokens, cacheReadPrice) + costNanosForTokens(input.cache_creation_input_tokens, cacheCreationPrice);
1494
+ const baseCostNanos = costNanosForTokens(input.input_tokens, inputPrice) + costNanosForTokens(input.output_tokens, outputPrice) + costNanosForTokens(input.cache_read_input_tokens, cacheReadPrice) + costNanosForTokens(input.cache_creation_input_tokens, cacheCreationPrice);
1495
+ const totalCostNanos = Math.round(baseCostNanos * resolveCodexServiceTierMultiplier(input, providerName));
1492
1496
  if (totalCostNanos <= 0) return null;
1493
1497
  return {
1494
1498
  currency,
@@ -1496,6 +1500,15 @@ function resolveTokenUsageCost(input) {
1496
1500
  total_cost_nanos: totalCostNanos
1497
1501
  };
1498
1502
  }
1503
+ function resolveCodexServiceTierMultiplier(input, providerName) {
1504
+ if (providerName.toLowerCase() !== "codex") return 1;
1505
+ switch (input.serviceTier?.trim().toLowerCase()) {
1506
+ case "priority":
1507
+ case "fast": return 2;
1508
+ case "ultrafast": return 6;
1509
+ default: return 1;
1510
+ }
1511
+ }
1499
1512
  function resolveReportedProviderCost(input) {
1500
1513
  const cost = normalizePrice(input.cost);
1501
1514
  if (cost === null) return null;
@@ -1523,7 +1536,8 @@ function resolveProviderPricing(providerName, model, configuredPricing) {
1523
1536
  pricing: configuredPricing,
1524
1537
  source: "config"
1525
1538
  };
1526
- const builtinPricing = builtinProviderModelRegistry.getModelConfig(providerName, model)?.pricing;
1539
+ const pricingModel = providerName.toLowerCase() === "codex" && model.trim().toLowerCase() === "gpt-5.6" ? "gpt-5.6-sol" : model;
1540
+ const builtinPricing = builtinProviderModelRegistry.getModelConfig(providerName, pricingModel)?.pricing;
1527
1541
  if (!builtinPricing) return null;
1528
1542
  return {
1529
1543
  pricing: builtinPricing,
@@ -9019,6 +9033,71 @@ messageRoutes.post("/count_tokens", async (c) => {
9019
9033
  return await forwardError(c, error);
9020
9034
  }
9021
9035
  });
9036
+ const DEFAULT_EXCLUSION_THRESHOLD = 20;
9037
+ const DEFAULT_EXCLUDED_MODELS = /* @__PURE__ */ new Set([
9038
+ "gpt-5.6-sol",
9039
+ "gpt-5.6-terra",
9040
+ "gpt-5.6-luna",
9041
+ "gpt-5.5",
9042
+ "claude-sonnet-5",
9043
+ "gemini-3.5-flash",
9044
+ "gemini-3.6-flash",
9045
+ "gemini-3.7-flash",
9046
+ "gpt-5.3-codex",
9047
+ "gpt-5.4-mini",
9048
+ "gpt-5.4",
9049
+ "grok-4.5",
9050
+ "gpt-5-mini",
9051
+ "mai-code-1.1-flash"
9052
+ ]);
9053
+ function isModernCodexClient(url, headers) {
9054
+ const versions = [
9055
+ new URL(url).searchParams.get("client_version"),
9056
+ headers.get("version"),
9057
+ headers.get("user-agent")?.match(/\bcodex[^/\s]*\/(\d+\.\d+\.\d+)/iu)?.[1]
9058
+ ];
9059
+ for (const version of versions) {
9060
+ const match = version?.match(/^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/u);
9061
+ if (!match) continue;
9062
+ return Number(match[1]) > 0 || Number(match[2]) >= 160;
9063
+ }
9064
+ return false;
9065
+ }
9066
+ function normalizeCodexInstructions(model, modern, fallback) {
9067
+ if (!modern) return model;
9068
+ const { base_instructions: legacy, ...normalized } = model;
9069
+ const messages = model.model_messages;
9070
+ if (typeof messages?.instructions_template !== "string") normalized.model_messages = {
9071
+ ...messages ?? fallback,
9072
+ instructions_template: typeof legacy === "string" ? legacy : fallback.instructions_template
9073
+ };
9074
+ return normalized;
9075
+ }
9076
+ function serializeCodexModelCatalog(response, options) {
9077
+ const models = response.models.map((model) => normalizeCodexInstructions(model, options.modern, options.fallback));
9078
+ if (options.headers.get("x-full-model-catalog")?.trim().toLowerCase() === "true") return JSON.stringify({
9079
+ ...response,
9080
+ models
9081
+ });
9082
+ const envelope = JSON.stringify({
9083
+ ...response,
9084
+ models: []
9085
+ });
9086
+ let bytes = Buffer.byteLength(envelope, "utf8");
9087
+ if (bytes > 1048576) return null;
9088
+ const selected = /* @__PURE__ */ new Set();
9089
+ const ordered = [...models.length > DEFAULT_EXCLUSION_THRESHOLD ? models.filter((model) => options.explicitSlugs.has(model.slug) || !DEFAULT_EXCLUDED_MODELS.has(model.slug.split("/").at(-1) ?? model.slug)) : models].sort((a, b) => Number(options.explicitSlugs.has(b.slug)) - Number(options.explicitSlugs.has(a.slug)));
9090
+ for (const model of ordered) {
9091
+ const additionalBytes = Buffer.byteLength(JSON.stringify(model), "utf8") + (selected.size > 0 ? 1 : 0);
9092
+ if (bytes + additionalBytes > 1048576) continue;
9093
+ selected.add(model);
9094
+ bytes += additionalBytes;
9095
+ }
9096
+ return JSON.stringify({
9097
+ ...response,
9098
+ models: models.filter((model) => selected.has(model))
9099
+ });
9100
+ }
9022
9101
  //#endregion
9023
9102
  //#region src/routes/models/models.json
9024
9103
  var models = [
@@ -10568,7 +10647,7 @@ const COPILOT_PRIORITY_BASE = 2e3;
10568
10647
  const OPENCODE_GO_PRIORITY_BASE = 3e3;
10569
10648
  const PROVIDER_PRIORITY_BASE = 4e3;
10570
10649
  const FALLBACK_CODEX_MODELS = models;
10571
- const FALLBACK_BASE_INSTRUCTIONS = FALLBACK_CODEX_MODELS.find((model) => model.base_instructions?.trim())?.base_instructions ?? "";
10650
+ const FALLBACK_BASE_INSTRUCTIONS = FALLBACK_CODEX_MODELS.find((model) => model.base_instructions?.trim())?.base_instructions ?? FALLBACK_CODEX_MODELS.find((model) => model.model_messages?.instructions_template?.trim())?.model_messages.instructions_template ?? "";
10572
10651
  function isCodexUserAgent(userAgent) {
10573
10652
  return CODEX_USER_AGENT_PATTERN.test(userAgent?.trim() ?? "");
10574
10653
  }
@@ -10589,7 +10668,18 @@ async function handleCodexModelsProxy(c, resolvedProviderConfig) {
10589
10668
  message: "Provider 'codex' not found or disabled",
10590
10669
  type: "invalid_request_error"
10591
10670
  } }, 404);
10592
- return createProviderProxyResponse(await forwardCodexModels(c.req.url, c.req.raw.headers));
10671
+ const upstreamResponse = await forwardCodexModels(c.req.url, c.req.raw.headers);
10672
+ if (!upstreamResponse.ok) return createProviderProxyResponse(upstreamResponse);
10673
+ const catalog = await upstreamResponse.json().catch(() => null);
10674
+ if (!isCodexModelsResponse(catalog)) return c.json({ error: {
10675
+ message: "Invalid Codex model catalog",
10676
+ type: "api_error"
10677
+ } }, 502);
10678
+ const providerConfig = getRawProviderConfig("codex");
10679
+ return createCodexCatalogResponse(c, {
10680
+ ...catalog,
10681
+ models: catalog.models.filter((model) => isProviderCodexModelVisible(providerConfig, model.slug))
10682
+ }, new Set(getProviderCodexModels(providerConfig)), FALLBACK_CODEX_MODELS[0].model_messages);
10593
10683
  }
10594
10684
  async function handleMergedCodexModels(c, candidatesRequest, options = {}) {
10595
10685
  const [upstreamCatalogResult, candidates] = await Promise.all([tryGetCodexCatalog(c), Promise.resolve(candidatesRequest).catch((error) => {
@@ -10600,8 +10690,25 @@ async function handleMergedCodexModels(c, candidatesRequest, options = {}) {
10600
10690
  const upstreamModels = upstreamCatalog?.models ?? FALLBACK_CODEX_MODELS;
10601
10691
  const template = selectTemplate(upstreamModels);
10602
10692
  const catalogModelsBySlug = new Map(upstreamModels.map((model) => [model.slug, model]));
10603
- const seenSlugs = new Set(upstreamModels.map((model) => model.slug));
10604
- const codexProviderAliases = options.includeCodexProviderAliases ? upstreamModels.flatMap((model, index) => {
10693
+ const codexConfig = getRawProviderConfig("codex");
10694
+ const copilotConfig = getRawProviderConfig("github-copilot");
10695
+ const visibleUpstreamModels = upstreamModels.filter((model) => isProviderCodexModelVisible(codexConfig, model.slug) && (upstreamCatalog !== void 0 || codexConfig !== null || isProviderCodexModelVisible(copilotConfig, model.slug)));
10696
+ const explicitSlugs = /* @__PURE__ */ new Set();
10697
+ const codexSelection = getProviderCodexModels(codexConfig);
10698
+ for (const model of visibleUpstreamModels) if (codexSelection?.includes(model.slug)) {
10699
+ explicitSlugs.add(model.slug);
10700
+ explicitSlugs.add(`codex/${model.slug}`);
10701
+ }
10702
+ const visibleCandidates = candidates.filter((candidate) => {
10703
+ const providerName = candidate.providerName ?? "github-copilot";
10704
+ const modelId = candidate.catalogSlug ?? (candidate.providerName ? candidate.slug.slice(providerName.length + 1) : candidate.slug);
10705
+ const config = getRawProviderConfig(providerName);
10706
+ if (!isProviderCodexModelVisible(config, modelId)) return false;
10707
+ if (getProviderCodexModels(config)?.includes(modelId)) explicitSlugs.add(candidate.slug);
10708
+ return true;
10709
+ });
10710
+ const seenSlugs = new Set(visibleUpstreamModels.map((model) => model.slug));
10711
+ const codexProviderAliases = options.includeCodexProviderAliases ? visibleUpstreamModels.flatMap((model, index) => {
10605
10712
  const slug = `codex/${model.slug}`;
10606
10713
  if (seenSlugs.has(slug)) return [];
10607
10714
  seenSlugs.add(slug);
@@ -10610,7 +10717,7 @@ async function handleMergedCodexModels(c, candidatesRequest, options = {}) {
10610
10717
  priority: CODEX_ALIAS_PRIORITY_BASE + index
10611
10718
  }];
10612
10719
  }) : [];
10613
- const syntheticModels = candidates.filter((candidate) => !seenSlugs.has(candidate.slug)).flatMap((candidate, index) => {
10720
+ const syntheticModels = visibleCandidates.filter((candidate) => !seenSlugs.has(candidate.slug)).flatMap((candidate, index) => {
10614
10721
  const priorityBase = getCandidatePriorityBase(candidate);
10615
10722
  const catalogModel = candidate.catalogSlug ? catalogModelsBySlug.get(candidate.catalogSlug) : void 0;
10616
10723
  if (catalogModel) return [{
@@ -10621,20 +10728,30 @@ async function handleMergedCodexModels(c, candidatesRequest, options = {}) {
10621
10728
  return [createSyntheticCodexModel(candidate, template, priorityBase + index)];
10622
10729
  });
10623
10730
  const models = [
10624
- ...upstreamModels,
10731
+ ...visibleUpstreamModels,
10625
10732
  ...codexProviderAliases,
10626
10733
  ...syntheticModels
10627
10734
  ].sort((a, b) => getModelPriority(a) - getModelPriority(b));
10628
- const response = {
10735
+ return createCodexCatalogResponse(c, {
10629
10736
  ...upstreamCatalog ?? {},
10630
10737
  models
10631
- };
10632
- const result = c.json(response);
10633
- if (upstreamCatalogResult?.etag) {
10634
- result.headers.set("ETag", upstreamCatalogResult.etag);
10635
- result.headers.set("Cache-Control", "private, no-store");
10636
- }
10637
- return result;
10738
+ }, explicitSlugs, template.model_messages ?? FALLBACK_CODEX_MODELS[0].model_messages);
10739
+ }
10740
+ function createCodexCatalogResponse(c, response, explicitSlugs, fallback) {
10741
+ const body = serializeCodexModelCatalog(response, {
10742
+ headers: c.req.raw.headers,
10743
+ modern: isModernCodexClient(c.req.url, c.req.raw.headers),
10744
+ explicitSlugs,
10745
+ fallback
10746
+ });
10747
+ if (body === null) return c.json({ error: {
10748
+ message: "Codex model catalog metadata exceeds 1 MiB",
10749
+ type: "api_error"
10750
+ } }, 502);
10751
+ return c.body(body, 200, {
10752
+ "Content-Type": "application/json",
10753
+ "Cache-Control": "private, no-store"
10754
+ });
10638
10755
  }
10639
10756
  function createCatalogAlias(model, slug, providerName) {
10640
10757
  const alias = {
@@ -10722,10 +10839,7 @@ async function tryGetCodexCatalog(c) {
10722
10839
  logger$8.warn("models.codex.catalog_invalid");
10723
10840
  return null;
10724
10841
  }
10725
- return {
10726
- catalog: body,
10727
- etag: response.headers.get("ETag")
10728
- };
10842
+ return { catalog: body };
10729
10843
  } catch (error) {
10730
10844
  logger$8.warn("models.codex.catalog_error", { error });
10731
10845
  return null;
@@ -10848,7 +10962,7 @@ async function getProviderModels(provider, requestHeaders) {
10848
10962
  }
10849
10963
  }
10850
10964
  async function getAggregatedModels(requestHeaders) {
10851
- const copilotModels = state.models?.data.map(normalizeCopilotModel) ?? [];
10965
+ const copilotModels = isGitHubCopilotEnabled() ? state.models?.data.map(normalizeCopilotModel) ?? [] : [];
10852
10966
  const providerModelsByProvider = await Promise.all(listEnabledProviders().map((provider) => getProviderModels(provider, requestHeaders)));
10853
10967
  const models = [...copilotModels, ...providerModelsByProvider.flat()];
10854
10968
  const seenModelIds = /* @__PURE__ */ new Set();
@@ -10880,6 +10994,7 @@ async function getSyntheticCodexModels(requestHeaders, providers) {
10880
10994
  }
10881
10995
  function getCopilotCodexCandidates() {
10882
10996
  const candidates = [];
10997
+ if (!isGitHubCopilotEnabled()) return candidates;
10883
10998
  for (const model of state.models?.data ?? []) try {
10884
10999
  if (isCopilotCodexCandidate(model)) candidates.push(createCopilotCodexCandidate(model));
10885
11000
  } catch (error) {
@@ -10904,6 +11019,7 @@ function createCopilotCodexCandidate(model) {
10904
11019
  const reasoningEfforts = normalizeReasoningEfforts(model.capabilities.supports.reasoning_effort);
10905
11020
  return {
10906
11021
  slug: toClientModelId(model.id),
11022
+ catalogSlug: model.id,
10907
11023
  displayName: model.name,
10908
11024
  description: describeCopilotAdapter(model),
10909
11025
  contextWindow: positiveNumber(model.capabilities.limits.max_prompt_tokens, 256e3),
@@ -11027,12 +11143,12 @@ modelRoutes.get("/", async (c) => {
11027
11143
  if (isCodexUserAgent(c.req.header("user-agent"))) {
11028
11144
  const enabledProviders = listEnabledProviders();
11029
11145
  const codexProviderName = enabledProviders.find((provider) => provider === "codex");
11030
- return await handleMergedCodexModels(c, getSyntheticCodexModels(c.req.raw.headers, enabledProviders), {
11146
+ return await handleMergedCodexModels(c, getSyntheticCodexModels(stripInternalRequestHeaders(c.req.raw.headers), enabledProviders), {
11031
11147
  includeCodexProviderAliases: codexProviderName !== void 0,
11032
11148
  codexProviderName
11033
11149
  });
11034
11150
  }
11035
- const models = await getAggregatedModels(c.req.raw.headers);
11151
+ const models = await getAggregatedModels(stripInternalRequestHeaders(c.req.raw.headers));
11036
11152
  return c.json({
11037
11153
  object: "list",
11038
11154
  data: models,
@@ -12203,6 +12319,7 @@ const createProviderResponsesUsageRecorder = (payload, provider, modelConfig, pr
12203
12319
  pricing: modelConfig?.pricing,
12204
12320
  pricingCurrency,
12205
12321
  providerName: provider,
12322
+ serviceTier: payload.service_tier,
12206
12323
  sessionId: sessionAffinity ?? ""
12207
12324
  });
12208
12325
  };
@@ -12672,4 +12789,4 @@ createServer();
12672
12789
  //#endregion
12673
12790
  export { createServer };
12674
12791
 
12675
- //# sourceMappingURL=server-D-oBVjPR.js.map
12792
+ //# sourceMappingURL=server-ihCUW7FV.js.map