@oh-my-pi/pi-catalog 16.4.1 → 16.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [16.4.3] - 2026-07-11
6
+
7
+ ### Fixed
8
+
9
+ - Fixed parsing of SAP AI Core Claude model IDs in version-first format (e.g., anthropic--claude-4.8-opus), restoring adaptive thinking metadata and capability gates.
10
+ - Fixed GitHub Copilot Business and Enterprise model discovery to correctly preserve vision capabilities instead of downgrading models to text-only.
11
+
12
+ ## [16.4.2] - 2026-07-10
13
+
14
+ ### Fixed
15
+
16
+ - Fixed OpenAI Codex model discovery to include the Codex version header alongside the client_version query parameter.
17
+
5
18
  ## [16.4.1] - 2026-07-10
6
19
 
7
20
  ### Added
@@ -19,8 +19,6 @@ export interface CodexModelDiscoveryOptions {
19
19
  signal?: AbortSignal;
20
20
  /** Optional fetch implementation override for tests. */
21
21
  fetchFn?: typeof fetch;
22
- /** Optional registry fetch implementation override for client version lookup. */
23
- registryFetchFn?: typeof fetch;
24
22
  }
25
23
  /**
26
24
  * Normalized Codex discovery response.
@@ -2,10 +2,15 @@
2
2
  * Constants for OpenAI Codex (ChatGPT OAuth) backend
3
3
  */
4
4
  export declare const CODEX_BASE_URL = "https://chatgpt.com/backend-api";
5
+ /**
6
+ * Pinned OpenAI Codex client version (corresponds to @openai/codex package version).
7
+ */
8
+ export declare const CODEX_CLIENT_VERSION = "0.144.1";
5
9
  export declare const OPENAI_HEADERS: {
6
10
  readonly BETA: "OpenAI-Beta";
7
11
  readonly ACCOUNT_ID: "chatgpt-account-id";
8
12
  readonly ORIGINATOR: "originator";
13
+ readonly VERSION: "version";
9
14
  readonly SESSION_ID: "session_id";
10
15
  readonly CONVERSATION_ID: "conversation_id";
11
16
  readonly SCOPED_SESSION_ID: "session-id";
@@ -28,13 +28,7 @@ export type ParsedGitHubCopilotApiKey = {
28
28
  apiEndpoint?: string;
29
29
  };
30
30
  export declare function isPublicGitHubHost(host: string): boolean;
31
- /**
32
- * Canonical personal-Copilot API host. The business
33
- * (`api.business.githubcopilot.com`) and enterprise (`copilot-api.{domain}`)
34
- * endpoints respond with HTTP 400 "vision is not supported" on image inputs,
35
- * so catalog discovery and capability gates MUST honour the upstream's
36
- * `supports.vision` flag only for this exact base URL.
37
- */
31
+ /** Canonical personal-Copilot API host. */
38
32
  export declare const PERSONAL_GITHUB_COPILOT_BASE_URL: "https://api.githubcopilot.com";
39
33
  /** `true` when the resolved base URL is the canonical personal-Copilot host. */
40
34
  export declare function isPersonalGitHubCopilotBaseUrl(baseUrl: string | undefined): boolean;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/pi-catalog",
4
- "version": "16.4.1",
4
+ "version": "16.4.3",
5
5
  "description": "Model catalog for omp: bundled model database, provider discovery descriptors, model identity, classification, and equivalence",
6
6
  "homepage": "https://omp.sh",
7
7
  "author": "Can Boluk",
@@ -34,12 +34,12 @@
34
34
  },
35
35
  "dependencies": {
36
36
  "@bufbuild/protobuf": "^2.12.0",
37
- "@oh-my-pi/pi-utils": "16.4.1",
38
- "arktype": "^2.2.0",
37
+ "@oh-my-pi/pi-utils": "16.4.3",
38
+ "arktype": "2.2.2",
39
39
  "zod": "^4"
40
40
  },
41
41
  "devDependencies": {
42
- "@oh-my-pi/pi-ai": "16.4.1",
42
+ "@oh-my-pi/pi-ai": "16.4.3",
43
43
  "@types/bun": "^1.3.14"
44
44
  },
45
45
  "engines": {
@@ -595,12 +595,13 @@ export function buildOpenAIResponsesCompat(spec: OpenAIResponsesSpecLike): Resol
595
595
  // Azure OpenAI and GitHub Copilot Responses paths require tool results
596
596
  // to strictly match prior tool calls when building Responses inputs.
597
597
  strictResponsesPairing: isAzure || spec.provider === "github-copilot",
598
- // GitHub Copilot's Responses endpoint rejects the `detail: "original"`
599
- // image hint with a 400; every other host preserves native-resolution
600
- // frames (snapcompact relies on `original`). Detect Copilot by provider id
601
- // or base-URL host (mirroring the Anthropic compat builder) so a model
602
- // pointed at the Copilot host under a different provider id still clamps.
603
- supportsImageDetailOriginal: !modelMatchesHost({ provider: spec.provider, baseUrl }, "githubCopilot"),
598
+ // GitHub Copilot and xAI OAuth reject `detail: "original"` (400 / 422).
599
+ // Every other host preserves native-resolution frames (snapcompact relies
600
+ // on `original`). Detect Copilot by provider id or base-URL host so a
601
+ // model pointed at the Copilot host under a different provider id still
602
+ // clamps; xai-oauth is provider-id only (same host family as paid `xai`).
603
+ supportsImageDetailOriginal:
604
+ spec.provider !== "xai-oauth" && !modelMatchesHost({ provider: spec.provider, baseUrl }, "githubCopilot"),
604
605
  reasoningEffortMap: {},
605
606
  supportsReasoningParams: true,
606
607
  thinkingFormat,
@@ -1,14 +1,11 @@
1
- import type { FetchImpl } from "@oh-my-pi/pi-utils";
2
1
  import { type } from "arktype";
3
2
  import type { ModelSpec } from "../types";
4
- import { discoveryFetch, isRecord } from "../utils";
5
- import { CODEX_BASE_URL, OPENAI_HEADER_VALUES, OPENAI_HEADERS } from "../wire/codex";
3
+ import { discoveryFetch } from "../utils";
4
+ import { CODEX_BASE_URL, CODEX_CLIENT_VERSION, OPENAI_HEADER_VALUES, OPENAI_HEADERS } from "../wire/codex";
6
5
 
7
6
  const DEFAULT_MODEL_LIST_PATHS = ["/codex/models", "/models"] as const;
8
7
  const DEFAULT_CONTEXT_WINDOW = 272_000;
9
8
  const DEFAULT_MAX_TOKENS = 128_000;
10
- const DEFAULT_CODEX_CLIENT_VERSION = "0.99.0";
11
- const NPM_CODEX_LATEST_URL = "https://registry.npmjs.org/@openai%2Fcodex/latest";
12
9
  const CODEX_REMOTE_COMPACTION = {
13
10
  enabled: true,
14
11
  api: "openai-codex-responses",
@@ -64,8 +61,6 @@ export interface CodexModelDiscoveryOptions {
64
61
  signal?: AbortSignal;
65
62
  /** Optional fetch implementation override for tests. */
66
63
  fetchFn?: typeof fetch;
67
- /** Optional registry fetch implementation override for client version lookup. */
68
- registryFetchFn?: typeof fetch;
69
64
  }
70
65
 
71
66
  /**
@@ -86,12 +81,8 @@ export async function fetchCodexModels(options: CodexModelDiscoveryOptions): Pro
86
81
  const fetchFn = discoveryFetch(options.fetchFn);
87
82
  const baseUrl = normalizeBaseUrl(options.baseUrl);
88
83
  const paths = normalizePaths(options.paths);
89
- const headers = buildCodexHeaders(options);
90
- const clientVersion = await resolveCodexClientVersion(
91
- options.clientVersion,
92
- options.registryFetchFn ?? fetchFn,
93
- options.signal,
94
- );
84
+ const clientVersion = normalizeClientVersion(options.clientVersion) ?? CODEX_CLIENT_VERSION;
85
+ const headers = buildCodexHeaders(options, clientVersion);
95
86
 
96
87
  let sawSuccessfulResponse = false;
97
88
  for (const path of paths) {
@@ -156,7 +147,7 @@ function buildModelsUrl(baseUrl: string, path: string, clientVersion: string | u
156
147
  return url.toString();
157
148
  }
158
149
 
159
- function buildCodexHeaders(options: CodexModelDiscoveryOptions): Headers {
150
+ function buildCodexHeaders(options: CodexModelDiscoveryOptions, clientVersion: string): Headers {
160
151
  const headers = new Headers(options.headers);
161
152
  headers.set("Authorization", `Bearer ${options.accessToken}`);
162
153
  if (options.accountId && options.accountId.trim().length > 0) {
@@ -164,42 +155,11 @@ function buildCodexHeaders(options: CodexModelDiscoveryOptions): Headers {
164
155
  }
165
156
  headers.set(OPENAI_HEADERS.BETA, OPENAI_HEADER_VALUES.BETA_RESPONSES);
166
157
  headers.set(OPENAI_HEADERS.ORIGINATOR, OPENAI_HEADER_VALUES.ORIGINATOR_CODEX);
158
+ headers.set(OPENAI_HEADERS.VERSION, clientVersion);
167
159
  headers.set("accept", "application/json");
168
160
  return headers;
169
161
  }
170
162
 
171
- async function resolveCodexClientVersion(
172
- clientVersion: string | undefined,
173
- fetchFn: FetchImpl,
174
- signal: AbortSignal | undefined,
175
- ): Promise<string> {
176
- const normalizedClientVersion = normalizeClientVersion(clientVersion);
177
- if (normalizedClientVersion) {
178
- return normalizedClientVersion;
179
- }
180
- try {
181
- const response = await fetchFn(NPM_CODEX_LATEST_URL, {
182
- method: "GET",
183
- headers: { Accept: "application/json" },
184
- signal,
185
- });
186
- if (!response.ok) {
187
- return DEFAULT_CODEX_CLIENT_VERSION;
188
- }
189
- const payload: unknown = await response.json();
190
- if (!isRecord(payload)) {
191
- return DEFAULT_CODEX_CLIENT_VERSION;
192
- }
193
- const npmVersion = normalizeClientVersion(payload.version);
194
- return npmVersion ?? DEFAULT_CODEX_CLIENT_VERSION;
195
- } catch (error) {
196
- if (isAbortError(error)) {
197
- throw error;
198
- }
199
- return DEFAULT_CODEX_CLIENT_VERSION;
200
- }
201
- }
202
-
203
163
  function normalizeClientVersion(value: unknown): string | undefined {
204
164
  if (typeof value !== "string") {
205
165
  return undefined;
@@ -211,10 +171,6 @@ function normalizeClientVersion(value: unknown): string | undefined {
211
171
  return trimmed;
212
172
  }
213
173
 
214
- function isAbortError(error: unknown): error is Error {
215
- return error instanceof Error && error.name === "AbortError";
216
- }
217
-
218
174
  function normalizeCodexModels(payload: unknown, baseUrl: string): ModelSpec<"openai-codex-responses">[] | null {
219
175
  const parsedResponse = codexModelsResponseSchema(payload);
220
176
  if (parsedResponse instanceof type.errors) {
@@ -106,15 +106,20 @@ export const parseGeminiModel = parser((modelId): GeminiModel | null => {
106
106
  });
107
107
 
108
108
  export const parseAnthropicModel = parser((modelId): AnthropicModel | null => {
109
- const match = /claude-(opus|sonnet|fable|mythos)-(\d{1,2}(?:[.-]\d{1,2}){0,2})\b/.exec(modelId);
110
- if (!match) {
109
+ const kindFirst = /claude-(opus|sonnet|fable|mythos)-(\d{1,2}(?:[.-]\d{1,2}){0,2})\b/.exec(modelId);
110
+ const versionFirst = kindFirst
111
+ ? null
112
+ : /claude-(\d{1,2}(?:[.-]\d{1,2}){0,2})-(opus|sonnet|fable|mythos)\b/.exec(modelId);
113
+ const kind = kindFirst?.[1] ?? versionFirst?.[2];
114
+ const versionInput = kindFirst?.[2] ?? versionFirst?.[1];
115
+ if (!kind || !versionInput) {
111
116
  return null;
112
117
  }
113
- const version = parseSemVer(match[2]);
118
+ const version = parseSemVer(versionInput);
114
119
  if (!version) {
115
120
  return null;
116
121
  }
117
- return { family: "anthropic", kind: match[1] as AnthropicKind, version };
122
+ return { family: "anthropic", kind: kind as AnthropicKind, version };
118
123
  });
119
124
 
120
125
  export const parseOpenAIModel = parser((modelId): OpenAIModel | null => {
@@ -351,11 +351,14 @@ function fingerprintStatic<TApi extends Api>(
351
351
  function mergeDynamicModel<TApi extends Api>(existingModel: Model<TApi>, dynamicModel: Model<TApi>): Model<TApi> {
352
352
  // When discovery resolves the same model id to a different endpoint (e.g.
353
353
  // a GitHub Copilot business/enterprise host), the bundled reference's
354
- // capabilities are pinned to the canonical host and no longer apply
355
- // honour the dynamic value alone. Same-endpoint merges still OR-upgrade so
356
- // a discovery that omits the capability flag doesn't drop bundled vision.
354
+ // capabilities are pinned to another endpoint and no longer apply. Copilot
355
+ // dynamic discovery also pre-applies the correct image fallback for omitted
356
+ // `supports.vision`, so its explicit `false` must not be OR-upgraded by the
357
+ // canonical bundled model.
357
358
  const endpointChanged = existingModel.baseUrl !== dynamicModel.baseUrl;
358
- const supportsImage = endpointChanged
359
+ const dynamicInputAuthoritative =
360
+ endpointChanged || (existingModel.provider === "github-copilot" && dynamicModel.provider === "github-copilot");
361
+ const supportsImage = dynamicInputAuthoritative
359
362
  ? dynamicModel.input.includes("image")
360
363
  : existingModel.input.includes("image") || dynamicModel.input.includes("image");
361
364
  // Re-build from spec stage: sparse compat comes from `compatConfig` (the
package/src/models.json CHANGED
@@ -17387,6 +17387,26 @@
17387
17387
  "contextWindow": 200000,
17388
17388
  "maxTokens": 64000
17389
17389
  },
17390
+ "nemotron-3-ultra-nvfp4": {
17391
+ "id": "nemotron-3-ultra-nvfp4",
17392
+ "name": "Nemotron 3 Ultra",
17393
+ "api": "devin-agent",
17394
+ "provider": "devin",
17395
+ "baseUrl": "https://server.codeium.com",
17396
+ "reasoning": true,
17397
+ "input": [
17398
+ "text"
17399
+ ],
17400
+ "supportsTools": true,
17401
+ "cost": {
17402
+ "input": 0,
17403
+ "output": 0,
17404
+ "cacheRead": 0,
17405
+ "cacheWrite": 0
17406
+ },
17407
+ "contextWindow": 262144,
17408
+ "maxTokens": 64000
17409
+ },
17390
17410
  "swe-1-6": {
17391
17411
  "id": "swe-1-6",
17392
17412
  "name": "SWE-1.6",
@@ -31094,7 +31114,7 @@
31094
31114
  },
31095
31115
  "openai/gpt-5.6-terra": {
31096
31116
  "id": "openai/gpt-5.6-terra",
31097
- "name": "GPT-5.6 Terra",
31117
+ "name": "GPT-5.6 Terra (new)",
31098
31118
  "api": "openai-completions",
31099
31119
  "provider": "kilo",
31100
31120
  "baseUrl": "https://api.kilo.ai/api/gateway",
@@ -62693,6 +62713,36 @@
62693
62713
  ]
62694
62714
  }
62695
62715
  },
62716
+ "gpt-realtime-2.1": {
62717
+ "id": "gpt-realtime-2.1",
62718
+ "name": "GPT-Realtime-2.1",
62719
+ "api": "openai-responses",
62720
+ "provider": "openai",
62721
+ "baseUrl": "https://api.openai.com/v1",
62722
+ "reasoning": true,
62723
+ "input": [
62724
+ "text",
62725
+ "image"
62726
+ ],
62727
+ "cost": {
62728
+ "input": 4,
62729
+ "output": 24,
62730
+ "cacheRead": 0.4,
62731
+ "cacheWrite": 0
62732
+ },
62733
+ "contextWindow": 128000,
62734
+ "maxTokens": 32000,
62735
+ "thinking": {
62736
+ "mode": "effort",
62737
+ "efforts": [
62738
+ "minimal",
62739
+ "low",
62740
+ "medium",
62741
+ "high",
62742
+ "xhigh"
62743
+ ]
62744
+ }
62745
+ },
62696
62746
  "o1": {
62697
62747
  "id": "o1",
62698
62748
  "name": "o1",
@@ -87250,7 +87300,8 @@
87250
87300
  "includeEncryptedReasoning": false,
87251
87301
  "filterReasoningHistory": true,
87252
87302
  "omitReasoningEffort": true,
87253
- "supportsReasoningEffort": false
87303
+ "supportsReasoningEffort": false,
87304
+ "supportsImageDetailOriginal": false
87254
87305
  }
87255
87306
  },
87256
87307
  "grok-4.20-0309-reasoning": {
@@ -87279,7 +87330,8 @@
87279
87330
  "includeEncryptedReasoning": false,
87280
87331
  "filterReasoningHistory": true,
87281
87332
  "omitReasoningEffort": true,
87282
- "supportsReasoningEffort": false
87333
+ "supportsReasoningEffort": false,
87334
+ "supportsImageDetailOriginal": false
87283
87335
  }
87284
87336
  },
87285
87337
  "grok-4.20-multi-agent-0309": {
@@ -87320,7 +87372,8 @@
87320
87372
  "includeEncryptedReasoning": false,
87321
87373
  "filterReasoningHistory": true,
87322
87374
  "omitReasoningEffort": false,
87323
- "supportsReasoningEffort": true
87375
+ "supportsReasoningEffort": true,
87376
+ "supportsImageDetailOriginal": false
87324
87377
  }
87325
87378
  },
87326
87379
  "grok-4.3": {
@@ -87362,7 +87415,8 @@
87362
87415
  "includeEncryptedReasoning": false,
87363
87416
  "filterReasoningHistory": true,
87364
87417
  "omitReasoningEffort": false,
87365
- "supportsReasoningEffort": true
87418
+ "supportsReasoningEffort": true,
87419
+ "supportsImageDetailOriginal": false
87366
87420
  }
87367
87421
  },
87368
87422
  "grok-4.5": {
@@ -87404,7 +87458,8 @@
87404
87458
  "includeEncryptedReasoning": false,
87405
87459
  "filterReasoningHistory": true,
87406
87460
  "omitReasoningEffort": false,
87407
- "supportsReasoningEffort": true
87461
+ "supportsReasoningEffort": true,
87462
+ "supportsImageDetailOriginal": false
87408
87463
  }
87409
87464
  },
87410
87465
  "grok-build": {
@@ -87433,7 +87488,8 @@
87433
87488
  "includeEncryptedReasoning": false,
87434
87489
  "filterReasoningHistory": true,
87435
87490
  "omitReasoningEffort": true,
87436
- "supportsReasoningEffort": false
87491
+ "supportsReasoningEffort": false,
87492
+ "supportsImageDetailOriginal": false
87437
87493
  }
87438
87494
  },
87439
87495
  "grok-build-0.1": {
@@ -87462,7 +87518,8 @@
87462
87518
  "includeEncryptedReasoning": false,
87463
87519
  "filterReasoningHistory": true,
87464
87520
  "omitReasoningEffort": true,
87465
- "supportsReasoningEffort": false
87521
+ "supportsReasoningEffort": false,
87522
+ "supportsImageDetailOriginal": false
87466
87523
  }
87467
87524
  },
87468
87525
  "grok-composer-2.5-fast": {
@@ -87490,7 +87547,8 @@
87490
87547
  "includeEncryptedReasoning": false,
87491
87548
  "filterReasoningHistory": true,
87492
87549
  "omitReasoningEffort": true,
87493
- "supportsReasoningEffort": false
87550
+ "supportsReasoningEffort": false,
87551
+ "supportsImageDetailOriginal": false
87494
87552
  }
87495
87553
  }
87496
87554
  },
@@ -1176,6 +1176,7 @@ function withXaiOAuthCompatDefaults(model: ModelSpec<"openai-responses">): Model
1176
1176
  ...(model.compat ?? {}),
1177
1177
  includeEncryptedReasoning: model.compat?.includeEncryptedReasoning ?? false,
1178
1178
  filterReasoningHistory: model.compat?.filterReasoningHistory ?? true,
1179
+ supportsImageDetailOriginal: model.compat?.supportsImageDetailOriginal ?? false,
1179
1180
  omitReasoningEffort: model.compat?.omitReasoningEffort ?? !isGrokReasoningEffortCapable(model.id),
1180
1181
  };
1181
1182
  return { ...model, compat };
@@ -1218,6 +1219,7 @@ function mergeCuratedIntoModel(
1218
1219
  reasoningEffortMap: { ...XAI_REASONING_EFFORT_MAP, ...(base.compat?.reasoningEffortMap ?? {}) },
1219
1220
  includeEncryptedReasoning: base.compat?.includeEncryptedReasoning ?? false,
1220
1221
  filterReasoningHistory: base.compat?.filterReasoningHistory ?? true,
1222
+ supportsImageDetailOriginal: base.compat?.supportsImageDetailOriginal ?? false,
1221
1223
  omitReasoningEffort: !effortCapable,
1222
1224
  supportsReasoningEffort: effortCapable,
1223
1225
  };
@@ -3922,16 +3924,13 @@ export function githubCopilotModelManagerOptions(config?: GithubCopilotModelMana
3922
3924
  ? entry.name
3923
3925
  : (reference?.name ?? defaults.name);
3924
3926
  const api = inferCopilotApi(defaults.id);
3925
- // `supports.vision` reports the model's intrinsic capability, but
3926
- // the business/enterprise endpoints respond `400 vision is not
3927
- // supported` on image inputs. Only honour the flag for the
3928
- // canonical personal-Copilot host.
3929
3927
  const supportsVision = extractCopilotSupportsVision(entry);
3930
- const input: ModelSpec<Api>["input"] = isPersonalGitHubCopilotBaseUrl(baseUrl)
3931
- ? supportsVision
3928
+ const input: ModelSpec<Api>["input"] =
3929
+ supportsVision === true
3932
3930
  ? ["text", "image"]
3933
- : (reference?.input ?? defaults.input)
3934
- : ["text"];
3931
+ : supportsVision === false || !isPersonalGitHubCopilotBaseUrl(baseUrl)
3932
+ ? ["text"]
3933
+ : (reference?.input ?? defaults.input);
3935
3934
  // With COPILOT_API_HEADERS the served window is the long-context
3936
3935
  // ceiling; the default tier ends at token_prices.default.context_max
3937
3936
  // prompt tokens. Cap the base entry to the default tier — the long
package/src/wire/codex.ts CHANGED
@@ -4,10 +4,16 @@
4
4
 
5
5
  export const CODEX_BASE_URL = "https://chatgpt.com/backend-api";
6
6
 
7
+ /**
8
+ * Pinned OpenAI Codex client version (corresponds to @openai/codex package version).
9
+ */
10
+ export const CODEX_CLIENT_VERSION = "0.144.1";
11
+
7
12
  export const OPENAI_HEADERS = {
8
13
  BETA: "OpenAI-Beta",
9
14
  ACCOUNT_ID: "chatgpt-account-id",
10
15
  ORIGINATOR: "originator",
16
+ VERSION: "version",
11
17
  SESSION_ID: "session_id",
12
18
  CONVERSATION_ID: "conversation_id",
13
19
  SCOPED_SESSION_ID: "session-id",
@@ -45,13 +45,7 @@ export function isPublicGitHubHost(host: string): boolean {
45
45
  return PUBLIC_GITHUB_HOSTS.has(host.trim().toLowerCase());
46
46
  }
47
47
 
48
- /**
49
- * Canonical personal-Copilot API host. The business
50
- * (`api.business.githubcopilot.com`) and enterprise (`copilot-api.{domain}`)
51
- * endpoints respond with HTTP 400 "vision is not supported" on image inputs,
52
- * so catalog discovery and capability gates MUST honour the upstream's
53
- * `supports.vision` flag only for this exact base URL.
54
- */
48
+ /** Canonical personal-Copilot API host. */
55
49
  export const PERSONAL_GITHUB_COPILOT_BASE_URL = "https://api.githubcopilot.com" as const;
56
50
 
57
51
  /** `true` when the resolved base URL is the canonical personal-Copilot host. */