jeopi-catalog 16.2.13
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 +523 -0
- package/README.md +43 -0
- package/dist/types/build.d.ts +3 -0
- package/dist/types/compat/anthropic.d.ts +11 -0
- package/dist/types/compat/apply.d.ts +7 -0
- package/dist/types/compat/devin.d.ts +9 -0
- package/dist/types/compat/openai.d.ts +28 -0
- package/dist/types/discovery/antigravity.d.ts +70 -0
- package/dist/types/discovery/codex.d.ts +38 -0
- package/dist/types/discovery/cursor-gen/agent_pb.d.ts +13022 -0
- package/dist/types/discovery/cursor.d.ts +23 -0
- package/dist/types/discovery/devin-gen/buf/validate/validate_pb.d.ts +1715 -0
- package/dist/types/discovery/devin-gen/exa/analytics_pb/analytics_pb.d.ts +693 -0
- package/dist/types/discovery/devin-gen/exa/api_server_pb/api_server_pb.d.ts +9158 -0
- package/dist/types/discovery/devin-gen/exa/auth_pb/auth_pb.d.ts +52 -0
- package/dist/types/discovery/devin-gen/exa/auto_cascade_common_pb/auto_cascade_common_pb.d.ts +276 -0
- package/dist/types/discovery/devin-gen/exa/bug_checker_pb/bug_checker_pb.d.ts +78 -0
- package/dist/types/discovery/devin-gen/exa/cascade_plugins_pb/cascade_plugins_pb.d.ts +999 -0
- package/dist/types/discovery/devin-gen/exa/chat_pb/chat_pb.d.ts +1704 -0
- package/dist/types/discovery/devin-gen/exa/code_edit/code_edit_pb/code_edit_pb.d.ts +656 -0
- package/dist/types/discovery/devin-gen/exa/codeium_common_pb/codeium_common_pb.d.ts +15014 -0
- package/dist/types/discovery/devin-gen/exa/context_module_pb/context_module_pb.d.ts +607 -0
- package/dist/types/discovery/devin-gen/exa/cortex_pb/cortex_pb.d.ts +11830 -0
- package/dist/types/discovery/devin-gen/exa/diff_action_pb/diff_action_pb.d.ts +248 -0
- package/dist/types/discovery/devin-gen/exa/index_pb/index_pb.d.ts +1747 -0
- package/dist/types/discovery/devin-gen/exa/knowledge_base_pb/knowledge_base_pb.d.ts +509 -0
- package/dist/types/discovery/devin-gen/exa/language_server_pb/language_server_pb.d.ts +9048 -0
- package/dist/types/discovery/devin-gen/exa/opensearch_clients_pb/opensearch_clients_pb.d.ts +1760 -0
- package/dist/types/discovery/devin-gen/exa/prompt_pb/prompt_pb.d.ts +286 -0
- package/dist/types/discovery/devin-gen/exa/reactive_component_pb/reactive_component_pb.d.ts +405 -0
- package/dist/types/discovery/devin-gen/exa/trust_pb/trust_pb.d.ts +582 -0
- package/dist/types/discovery/devin.d.ts +24 -0
- package/dist/types/discovery/gemini.d.ts +25 -0
- package/dist/types/discovery/gitlab-duo-workflow.d.ts +30 -0
- package/dist/types/discovery/index.d.ts +5 -0
- package/dist/types/discovery/openai-compatible.d.ts +74 -0
- package/dist/types/effort.d.ts +9 -0
- package/dist/types/fireworks-model-id.d.ts +23 -0
- package/dist/types/hosts.d.ts +137 -0
- package/dist/types/identity/bundled.d.ts +3 -0
- package/dist/types/identity/classify.d.ts +69 -0
- package/dist/types/identity/dialect.d.ts +3 -0
- package/dist/types/identity/family.d.ts +139 -0
- package/dist/types/identity/id.d.ts +12 -0
- package/dist/types/identity/index.d.ts +8 -0
- package/dist/types/identity/markers.d.ts +4 -0
- package/dist/types/identity/priority.d.ts +1 -0
- package/dist/types/identity/reference.d.ts +23 -0
- package/dist/types/index.d.ts +17 -0
- package/dist/types/model-cache.d.ts +17 -0
- package/dist/types/model-manager.d.ts +68 -0
- package/dist/types/model-thinking.d.ts +79 -0
- package/dist/types/models.d.ts +12 -0
- package/dist/types/provider-models/bundled-references.d.ts +11 -0
- package/dist/types/provider-models/descriptor-types.d.ts +74 -0
- package/dist/types/provider-models/descriptors.d.ts +427 -0
- package/dist/types/provider-models/google.d.ts +27 -0
- package/dist/types/provider-models/index.d.ts +6 -0
- package/dist/types/provider-models/ollama.d.ts +9 -0
- package/dist/types/provider-models/openai-compat.d.ts +450 -0
- package/dist/types/provider-models/special.d.ts +33 -0
- package/dist/types/types.d.ts +656 -0
- package/dist/types/utils.d.ts +20 -0
- package/dist/types/variant-collapse.d.ts +133 -0
- package/dist/types/wire/codex.d.ts +26 -0
- package/dist/types/wire/coreweave.d.ts +12 -0
- package/dist/types/wire/gemini-headers.d.ts +37 -0
- package/dist/types/wire/github-copilot.d.ts +45 -0
- package/package.json +101 -0
- package/src/build.ts +47 -0
- package/src/compat/anthropic.ts +93 -0
- package/src/compat/apply.ts +15 -0
- package/src/compat/devin.ts +12 -0
- package/src/compat/openai.ts +689 -0
- package/src/discovery/antigravity.ts +253 -0
- package/src/discovery/codex.ts +371 -0
- package/src/discovery/cursor-gen/agent_pb.ts +15274 -0
- package/src/discovery/cursor.ts +314 -0
- package/src/discovery/devin-gen/buf/validate/validate_pb.ts +1862 -0
- package/src/discovery/devin-gen/exa/analytics_pb/analytics_pb.ts +871 -0
- package/src/discovery/devin-gen/exa/api_server_pb/api_server_pb.ts +11083 -0
- package/src/discovery/devin-gen/exa/auth_pb/auth_pb.ts +71 -0
- package/src/discovery/devin-gen/exa/auto_cascade_common_pb/auto_cascade_common_pb.ts +348 -0
- package/src/discovery/devin-gen/exa/bug_checker_pb/bug_checker_pb.ts +103 -0
- package/src/discovery/devin-gen/exa/cascade_plugins_pb/cascade_plugins_pb.ts +1198 -0
- package/src/discovery/devin-gen/exa/chat_pb/chat_pb.ts +2063 -0
- package/src/discovery/devin-gen/exa/code_edit/code_edit_pb/code_edit_pb.ts +810 -0
- package/src/discovery/devin-gen/exa/codeium_common_pb/codeium_common_pb.ts +18354 -0
- package/src/discovery/devin-gen/exa/context_module_pb/context_module_pb.ts +732 -0
- package/src/discovery/devin-gen/exa/cortex_pb/cortex_pb.ts +14277 -0
- package/src/discovery/devin-gen/exa/diff_action_pb/diff_action_pb.ts +312 -0
- package/src/discovery/devin-gen/exa/index_pb/index_pb.ts +2106 -0
- package/src/discovery/devin-gen/exa/knowledge_base_pb/knowledge_base_pb.ts +623 -0
- package/src/discovery/devin-gen/exa/language_server_pb/language_server_pb.ts +10918 -0
- package/src/discovery/devin-gen/exa/opensearch_clients_pb/opensearch_clients_pb.ts +2125 -0
- package/src/discovery/devin-gen/exa/prompt_pb/prompt_pb.ts +361 -0
- package/src/discovery/devin-gen/exa/reactive_component_pb/reactive_component_pb.ts +450 -0
- package/src/discovery/devin-gen/exa/trust_pb/trust_pb.ts +712 -0
- package/src/discovery/devin.ts +151 -0
- package/src/discovery/gemini.ts +260 -0
- package/src/discovery/gitlab-duo-workflow.ts +855 -0
- package/src/discovery/index.ts +5 -0
- package/src/discovery/openai-compatible.ts +249 -0
- package/src/effort.ts +16 -0
- package/src/fireworks-model-id.ts +50 -0
- package/src/hosts.ts +129 -0
- package/src/identity/bundled.ts +28 -0
- package/src/identity/classify.ts +214 -0
- package/src/identity/dialect.ts +42 -0
- package/src/identity/family.ts +296 -0
- package/src/identity/id.ts +81 -0
- package/src/identity/index.ts +8 -0
- package/src/identity/markers.ts +49 -0
- package/src/identity/priority.ts +57 -0
- package/src/identity/reference.ts +148 -0
- package/src/index.ts +17 -0
- package/src/model-cache.ts +171 -0
- package/src/model-manager.ts +520 -0
- package/src/model-thinking.ts +760 -0
- package/src/models.json +88898 -0
- package/src/models.json.d.ts +9 -0
- package/src/models.ts +64 -0
- package/src/provider-models/bundled-references.ts +58 -0
- package/src/provider-models/descriptor-types.ts +79 -0
- package/src/provider-models/descriptors.ts +503 -0
- package/src/provider-models/google.ts +107 -0
- package/src/provider-models/index.ts +6 -0
- package/src/provider-models/ollama.ts +172 -0
- package/src/provider-models/openai-compat.ts +4283 -0
- package/src/provider-models/special.ts +159 -0
- package/src/types.ts +786 -0
- package/src/utils.ts +69 -0
- package/src/variant-collapse.ts +1065 -0
- package/src/wire/codex.ts +43 -0
- package/src/wire/coreweave.ts +51 -0
- package/src/wire/gemini-headers.ts +74 -0
- package/src/wire/github-copilot.ts +121 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constants for OpenAI Codex (ChatGPT OAuth) backend
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export const CODEX_BASE_URL = "https://chatgpt.com/backend-api";
|
|
6
|
+
|
|
7
|
+
export const OPENAI_HEADERS = {
|
|
8
|
+
BETA: "OpenAI-Beta",
|
|
9
|
+
ACCOUNT_ID: "chatgpt-account-id",
|
|
10
|
+
ORIGINATOR: "originator",
|
|
11
|
+
SESSION_ID: "session_id",
|
|
12
|
+
CONVERSATION_ID: "conversation_id",
|
|
13
|
+
} as const;
|
|
14
|
+
|
|
15
|
+
export const OPENAI_HEADER_VALUES = {
|
|
16
|
+
BETA_RESPONSES: "responses=experimental",
|
|
17
|
+
BETA_RESPONSES_WEBSOCKETS_V2: "responses_websockets=2026-02-06",
|
|
18
|
+
ORIGINATOR_CODEX: "pi",
|
|
19
|
+
} as const;
|
|
20
|
+
|
|
21
|
+
export const URL_PATHS = {
|
|
22
|
+
RESPONSES: "/responses",
|
|
23
|
+
CODEX_RESPONSES: "/codex/responses",
|
|
24
|
+
} as const;
|
|
25
|
+
|
|
26
|
+
export const JWT_CLAIM_PATH = "https://api.openai.com/auth" as const;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Extract account ID from a Codex JWT access token.
|
|
30
|
+
* Returns undefined if the token is not a valid Codex JWT.
|
|
31
|
+
*/
|
|
32
|
+
export function getCodexAccountId(accessToken: string): string | undefined {
|
|
33
|
+
try {
|
|
34
|
+
const parts = accessToken.split(".");
|
|
35
|
+
if (parts.length !== 3) return undefined;
|
|
36
|
+
const decoded = Buffer.from(parts[1] ?? "", "base64").toString("utf-8");
|
|
37
|
+
const payload = JSON.parse(decoded) as Record<string, unknown>;
|
|
38
|
+
const auth = payload[JWT_CLAIM_PATH] as { chatgpt_account_id?: string } | undefined;
|
|
39
|
+
return auth?.chatgpt_account_id ?? undefined;
|
|
40
|
+
} catch {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export const COREWEAVE_PROJECT_HEADER = "OpenAI-Project" as const;
|
|
2
|
+
|
|
3
|
+
export interface CoreWeaveProjectEnv {
|
|
4
|
+
[key: string]: string | undefined;
|
|
5
|
+
COREWEAVE_PROJECT?: string;
|
|
6
|
+
WANDB_INFERENCE_PROJECT?: string;
|
|
7
|
+
WANDB_ENTITY?: string;
|
|
8
|
+
WANDB_PROJECT?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function cleanEnvValue(value: string | undefined): string | undefined {
|
|
12
|
+
const trimmed = value?.trim();
|
|
13
|
+
return trimmed ? trimmed : undefined;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function resolveCoreWeaveProject(env: CoreWeaveProjectEnv): string | undefined {
|
|
17
|
+
const explicitProject = cleanEnvValue(env.COREWEAVE_PROJECT) ?? cleanEnvValue(env.WANDB_INFERENCE_PROJECT);
|
|
18
|
+
if (explicitProject) {
|
|
19
|
+
return explicitProject;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const wandbProject = cleanEnvValue(env.WANDB_PROJECT);
|
|
23
|
+
if (!wandbProject) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
if (wandbProject.includes("/")) {
|
|
27
|
+
return wandbProject;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const wandbEntity = cleanEnvValue(env.WANDB_ENTITY);
|
|
31
|
+
return wandbEntity ? `${wandbEntity}/${wandbProject}` : undefined;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function coreWeaveProjectHeaders(env: CoreWeaveProjectEnv): Record<string, string> | undefined {
|
|
35
|
+
const project = resolveCoreWeaveProject(env);
|
|
36
|
+
return project ? { [COREWEAVE_PROJECT_HEADER]: project } : undefined;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function hasCoreWeaveProjectHeader(headers: Record<string, string>): boolean {
|
|
40
|
+
const normalized = COREWEAVE_PROJECT_HEADER.toLowerCase();
|
|
41
|
+
return Object.entries(headers).some(([header, value]) => header.toLowerCase() === normalized && value.trim() !== "");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function removeBlankCoreWeaveProjectHeaders(headers: Record<string, string>): void {
|
|
45
|
+
const normalized = COREWEAVE_PROJECT_HEADER.toLowerCase();
|
|
46
|
+
for (const [header, value] of Object.entries(headers)) {
|
|
47
|
+
if (header.toLowerCase() === normalized && value.trim() === "") {
|
|
48
|
+
delete headers[header];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build a User-Agent string that identifies as Gemini CLI to unlock higher rate limits.
|
|
3
|
+
* Uses the same format as the official Gemini CLI (v0.35+):
|
|
4
|
+
* GeminiCLI/VERSION/MODEL (PLATFORM; ARCH; SURFACE)
|
|
5
|
+
*/
|
|
6
|
+
export function getGeminiCliUserAgent(modelId = "gemini-3.1-pro-preview"): string {
|
|
7
|
+
const version = process.env.PI_AI_GEMINI_CLI_VERSION || "0.46.0";
|
|
8
|
+
const platform = process.platform === "win32" ? "win32" : process.platform;
|
|
9
|
+
const arch = process.arch === "x64" ? "x64" : process.arch;
|
|
10
|
+
return `GeminiCLI/${version}/${modelId} (${platform}; ${arch}; terminal)`;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const getGeminiCliHeaders = (modelId?: string) => ({
|
|
14
|
+
"User-Agent": getGeminiCliUserAgent(modelId),
|
|
15
|
+
"Client-Metadata": "ideType=IDE_UNSPECIFIED,platform=PLATFORM_UNSPECIFIED,pluginType=GEMINI",
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export const ANTIGRAVITY_SYSTEM_INSTRUCTION =
|
|
19
|
+
"You are Antigravity, a powerful agentic AI coding assistant designed by the Google Deepmind team working on Advanced Agentic Coding." +
|
|
20
|
+
"You are pair programming with a USER to solve their coding task. The task may require creating a new codebase, modifying or debugging an existing codebase, or simply answering a question." +
|
|
21
|
+
"**Absolute paths only**" +
|
|
22
|
+
"**Proactiveness**";
|
|
23
|
+
/**
|
|
24
|
+
* Antigravity / Cloud Code Assist user agent. Lives in its own file so discovery
|
|
25
|
+
* and usage code can read it without pulling the heavy google-gemini-cli provider
|
|
26
|
+
* (and its @google/genai → google-auth-library dependency chain) into the startup
|
|
27
|
+
* parse graph.
|
|
28
|
+
*/
|
|
29
|
+
export let getAntigravityUserAgent = () => {
|
|
30
|
+
const DEFAULT_ANTIGRAVITY_VERSION = "2.1.4";
|
|
31
|
+
const version = process.env.PI_AI_ANTIGRAVITY_VERSION || DEFAULT_ANTIGRAVITY_VERSION;
|
|
32
|
+
// Map Node.js platform/arch to Antigravity's expected format.
|
|
33
|
+
// Verified against Antigravity source: _qn() and wqn() in main.js.
|
|
34
|
+
// process.platform: win32→windows, others pass through (darwin, linux)
|
|
35
|
+
// process.arch: x64→amd64, ia32→386, others pass through (arm64)
|
|
36
|
+
const os = process.platform === "win32" ? "windows" : process.platform;
|
|
37
|
+
const arch = process.arch === "x64" ? "amd64" : process.arch === "ia32" ? "386" : process.arch;
|
|
38
|
+
const userAgent = `antigravity/hub/${version} ${os}/${arch}`;
|
|
39
|
+
getAntigravityUserAgent = () => userAgent;
|
|
40
|
+
return userAgent;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Per-wire-id Antigravity Cloud Code Assist request constants, captured from the
|
|
45
|
+
* real `antigravity/hub` client against `daily-cloudcode-pa`. `modelEnum` is the
|
|
46
|
+
* opaque `labels.model_enum` token the client tags each request with — optional
|
|
47
|
+
* because Anthropic-backed wire ids (e.g. `claude-sonnet-4-6`,
|
|
48
|
+
* `claude-opus-4-6-thinking`) are accepted without one; the label is purely
|
|
49
|
+
* telemetry. `maxOutputTokens` is the fixed `generationConfig.maxOutputTokens`
|
|
50
|
+
* the backend enforces regardless of the thinking budget (Claude caps at
|
|
51
|
+
* 64000, Gemini accepts the discovered cap). Keyed by the routed upstream wire
|
|
52
|
+
* id (post effort-routing), not the collapsed logical id. Checkpoint-only ids
|
|
53
|
+
* (e.g. `gemini-3.1-flash-lite`) are intentionally absent — this provider only
|
|
54
|
+
* emits agent requests.
|
|
55
|
+
*/
|
|
56
|
+
export interface AntigravityModelWireProfile {
|
|
57
|
+
modelEnum?: string;
|
|
58
|
+
maxOutputTokens: number;
|
|
59
|
+
}
|
|
60
|
+
export const ANTIGRAVITY_MODEL_WIRE_PROFILES: Readonly<Record<string, AntigravityModelWireProfile>> = {
|
|
61
|
+
"gemini-3.5-flash-extra-low": { modelEnum: "MODEL_PLACEHOLDER_M187", maxOutputTokens: 65536 },
|
|
62
|
+
"gemini-3.5-flash-low": { modelEnum: "MODEL_PLACEHOLDER_M20", maxOutputTokens: 65536 },
|
|
63
|
+
"gemini-3-flash-agent": { modelEnum: "MODEL_PLACEHOLDER_M132", maxOutputTokens: 65536 },
|
|
64
|
+
"gemini-3.1-pro-low": { modelEnum: "MODEL_PLACEHOLDER_M36", maxOutputTokens: 65535 },
|
|
65
|
+
"gemini-pro-agent": { modelEnum: "MODEL_PLACEHOLDER_M16", maxOutputTokens: 65535 },
|
|
66
|
+
// Claude on `daily-cloudcode-pa` rejects `maxOutputTokens > 64000` with a
|
|
67
|
+
// 400 (`Request contains an invalid argument`). The model_enum label is
|
|
68
|
+
// untracked for these ids; the backend does not require it.
|
|
69
|
+
"claude-sonnet-4-6": { maxOutputTokens: 64000 },
|
|
70
|
+
"claude-opus-4-6-thinking": { maxOutputTokens: 64000 },
|
|
71
|
+
};
|
|
72
|
+
export function getAntigravityModelWireProfile(wireModelId: string): AntigravityModelWireProfile | undefined {
|
|
73
|
+
return ANTIGRAVITY_MODEL_WIRE_PROFILES[wireModelId];
|
|
74
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub Copilot wire metadata: API-key envelope parsing and endpoint
|
|
3
|
+
* derivation shared by catalog discovery and the pi-ai OAuth flow. The device
|
|
4
|
+
* login / token refresh flow lives in `jeopi-ai`'s registry.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export const COPILOT_USER_AGENT = "opencode/1.3.15" as const;
|
|
8
|
+
|
|
9
|
+
export const OPENCODE_HEADERS = {
|
|
10
|
+
"User-Agent": COPILOT_USER_AGENT,
|
|
11
|
+
} as const;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Copilot API version sent on `api.githubcopilot.com` requests (`/models`,
|
|
15
|
+
* chat endpoints). Newer versions unlock tiered context metadata: `/models`
|
|
16
|
+
* reports the full long-context window in `capabilities.limits` plus per-tier
|
|
17
|
+
* boundaries/prices under `billing.token_prices.{default,long_context}`.
|
|
18
|
+
* Without it the endpoint serves default-tier limits only (e.g. 264k instead
|
|
19
|
+
* of 1M for Claude Opus). Never send this to `api.github.com` REST endpoints —
|
|
20
|
+
* they validate `X-GitHub-Api-Version` against the REST version vocabulary.
|
|
21
|
+
*/
|
|
22
|
+
export const COPILOT_API_VERSION = "2026-06-01" as const;
|
|
23
|
+
|
|
24
|
+
/** Headers for `api.githubcopilot.com` (capi) requests: discovery, chat, policy. */
|
|
25
|
+
export const COPILOT_API_HEADERS = {
|
|
26
|
+
...OPENCODE_HEADERS,
|
|
27
|
+
"X-GitHub-Api-Version": COPILOT_API_VERSION,
|
|
28
|
+
} as const;
|
|
29
|
+
|
|
30
|
+
type GitHubCopilotApiKeyPayload = {
|
|
31
|
+
token?: unknown;
|
|
32
|
+
enterpriseUrl?: unknown;
|
|
33
|
+
apiEndpoint?: unknown;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export type ParsedGitHubCopilotApiKey = {
|
|
37
|
+
accessToken: string;
|
|
38
|
+
enterpriseUrl?: string;
|
|
39
|
+
apiEndpoint?: string;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const PUBLIC_GITHUB_HOSTS = new Set(["api.github.com", "github.com", "www.github.com"]);
|
|
43
|
+
|
|
44
|
+
export function isPublicGitHubHost(host: string): boolean {
|
|
45
|
+
return PUBLIC_GITHUB_HOSTS.has(host.trim().toLowerCase());
|
|
46
|
+
}
|
|
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
|
+
*/
|
|
55
|
+
export const PERSONAL_GITHUB_COPILOT_BASE_URL = "https://api.githubcopilot.com" as const;
|
|
56
|
+
|
|
57
|
+
/** `true` when the resolved base URL is the canonical personal-Copilot host. */
|
|
58
|
+
export function isPersonalGitHubCopilotBaseUrl(baseUrl: string | undefined): boolean {
|
|
59
|
+
return baseUrl === PERSONAL_GITHUB_COPILOT_BASE_URL;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function normalizeGitHubCopilotEnterpriseDomain(input: string | undefined): string | undefined {
|
|
63
|
+
const trimmed = input?.trim();
|
|
64
|
+
if (!trimmed) return undefined;
|
|
65
|
+
const normalized = normalizeDomain(trimmed) ?? trimmed.toLowerCase();
|
|
66
|
+
if (!normalized || isPublicGitHubHost(normalized)) return undefined;
|
|
67
|
+
return normalized;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function normalizeGitHubCopilotApiEndpoint(input: string | undefined): string | undefined {
|
|
71
|
+
const trimmed = input?.trim();
|
|
72
|
+
if (!trimmed?.startsWith("https://")) return undefined;
|
|
73
|
+
try {
|
|
74
|
+
const url = new URL(trimmed);
|
|
75
|
+
if (url.protocol !== "https:" || !url.hostname) return undefined;
|
|
76
|
+
return trimmed.replace(/\/+$/, "");
|
|
77
|
+
} catch {
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function parseGitHubCopilotApiKey(apiKeyRaw: string): ParsedGitHubCopilotApiKey {
|
|
83
|
+
try {
|
|
84
|
+
const parsed = JSON.parse(apiKeyRaw) as GitHubCopilotApiKeyPayload;
|
|
85
|
+
if (typeof parsed.token === "string") {
|
|
86
|
+
return {
|
|
87
|
+
accessToken: parsed.token,
|
|
88
|
+
enterpriseUrl:
|
|
89
|
+
typeof parsed.enterpriseUrl === "string"
|
|
90
|
+
? normalizeGitHubCopilotEnterpriseDomain(parsed.enterpriseUrl)
|
|
91
|
+
: undefined,
|
|
92
|
+
apiEndpoint:
|
|
93
|
+
typeof parsed.apiEndpoint === "string"
|
|
94
|
+
? normalizeGitHubCopilotApiEndpoint(parsed.apiEndpoint)
|
|
95
|
+
: undefined,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
} catch {}
|
|
99
|
+
|
|
100
|
+
return { accessToken: apiKeyRaw };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function normalizeDomain(input: string): string | null {
|
|
104
|
+
const trimmed = input.trim();
|
|
105
|
+
if (!trimmed) return null;
|
|
106
|
+
try {
|
|
107
|
+
const url = trimmed.includes("://") ? new URL(trimmed) : new URL(`https://${trimmed}`);
|
|
108
|
+
return url.hostname;
|
|
109
|
+
} catch {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function getGitHubCopilotBaseUrl(enterpriseDomain?: string): string {
|
|
115
|
+
const normalizedEnterpriseDomain = normalizeGitHubCopilotEnterpriseDomain(enterpriseDomain);
|
|
116
|
+
if (!normalizedEnterpriseDomain) return "https://api.githubcopilot.com";
|
|
117
|
+
const host = normalizedEnterpriseDomain.startsWith("copilot-api.")
|
|
118
|
+
? normalizedEnterpriseDomain
|
|
119
|
+
: `copilot-api.${normalizedEnterpriseDomain}`;
|
|
120
|
+
return `https://${host}`;
|
|
121
|
+
}
|