@bastani/pi-ai 0.9.16-alpha.7 → 0.9.16-alpha.8

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.
@@ -1 +1 @@
1
- {"version":3,"file":"github-copilot.d.ts","sourceRoot":"","sources":["../../../src/auth/oauth/github-copilot.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,SAAS,EAA4C,MAAM,aAAa,CAAC;AAsevF,eAAO,MAAM,kBAAkB,EAAE,SAchC,CAAC","sourcesContent":["/**\n * GitHub Copilot OAuth flow\n */\n\nimport { GITHUB_COPILOT_MODELS } from \"../../providers/github-copilot.models.ts\";\nimport { sleep } from \"../../utils/sleep.ts\";\nimport type { OAuthAuth, OAuthCredential, ProviderAuthInteraction } from \"../types.ts\";\nimport { pollOAuthDeviceCodeFlow } from \"./device-code.ts\";\n\nconst decode = (s: string) => atob(s);\nconst CLIENT_ID = decode(\"SXYxLmI1MDdhMDhjODdlY2ZlOTg=\");\n\nconst COPILOT_HEADERS = {\n\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\"Editor-Version\": \"vscode/1.107.0\",\n\t\"Editor-Plugin-Version\": \"copilot-chat/0.35.0\",\n\t\"Copilot-Integration-Id\": \"vscode-chat\",\n} as const;\nconst COPILOT_API_VERSION = \"2026-06-01\";\n\ntype DeviceCodeResponse = {\n\tdevice_code: string;\n\tuser_code: string;\n\tverification_uri: string;\n\tinterval?: number;\n\texpires_in: number;\n};\n\ntype DeviceTokenSuccessResponse = {\n\taccess_token: string;\n\ttoken_type?: string;\n\tscope?: string;\n};\n\ntype DeviceTokenErrorResponse = {\n\terror: string;\n\terror_description?: string;\n\tinterval?: number;\n};\n\nfunction normalizeDomain(input: string): string | null {\n\tconst trimmed = input.trim();\n\tif (!trimmed) return null;\n\ttry {\n\t\tconst url = trimmed.includes(\"://\") ? new URL(trimmed) : new URL(`https://${trimmed}`);\n\t\treturn url.hostname;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction getUrls(domain: string): {\n\tdeviceCodeUrl: string;\n\taccessTokenUrl: string;\n\tcopilotTokenUrl: string;\n} {\n\treturn {\n\t\tdeviceCodeUrl: `https://${domain}/login/device/code`,\n\t\taccessTokenUrl: `https://${domain}/login/oauth/access_token`,\n\t\tcopilotTokenUrl: `https://api.${domain}/copilot_internal/v2/token`,\n\t};\n}\n\n/**\n * Parse the proxy-ep from a Copilot token and convert to API base URL.\n * Token format: tid=...;exp=...;proxy-ep=proxy.individual.githubcopilot.com;...\n * Returns API URL like https://api.individual.githubcopilot.com\n */\nfunction getBaseUrlFromToken(token: string): string | null {\n\tconst match = token.match(/proxy-ep=([^;]+)/);\n\tif (!match) return null;\n\tconst proxyHost = match[1];\n\t// Convert proxy.xxx to api.xxx\n\tconst apiHost = proxyHost.replace(/^proxy\\./, \"api.\");\n\treturn `https://${apiHost}`;\n}\n\nfunction getGitHubCopilotBaseUrl(token?: string, enterpriseDomain?: string): string {\n\t// If we have a token, extract the base URL from proxy-ep\n\tif (token) {\n\t\tconst urlFromToken = getBaseUrlFromToken(token);\n\t\tif (urlFromToken) return urlFromToken;\n\t}\n\t// Fallback for enterprise or if token parsing fails\n\tif (enterpriseDomain) return `https://copilot-api.${enterpriseDomain}`;\n\treturn \"https://api.individual.githubcopilot.com\";\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n\treturn value && typeof value === \"object\" ? (value as Record<string, unknown>) : undefined;\n}\n\nfunction parseGitHubCopilotModelCatalog(raw: unknown, allowPolicyFallback: boolean) {\n\tconst data = asRecord(raw)?.data;\n\tif (!Array.isArray(data)) {\n\t\tthrow new Error(\"Invalid Copilot models response\");\n\t}\n\n\tconst accountModels = data.flatMap((rawItem) => {\n\t\tconst item = asRecord(rawItem);\n\t\tconst id = item?.id;\n\t\tif (!item || typeof id !== \"string\") return [];\n\n\t\tconst capabilities = asRecord(item.capabilities);\n\t\tconst supports = asRecord(capabilities?.supports);\n\t\tif (supports?.tool_calls === false) return [];\n\n\t\treturn [\n\t\t\t{\n\t\t\t\tid,\n\t\t\t\tpickerEnabled: item.model_picker_enabled === true,\n\t\t\t\tpolicyState: asRecord(item.policy)?.state,\n\t\t\t},\n\t\t];\n\t});\n\tconst pickerModelIds = accountModels\n\t\t.filter((model) => model.pickerEnabled && model.policyState !== \"disabled\")\n\t\t.map((model) => model.id);\n\tconst usePolicyFallback = allowPolicyFallback && pickerModelIds.length === 0;\n\tconst availableModelIds =\n\t\tpickerModelIds.length > 0 || !allowPolicyFallback\n\t\t\t? pickerModelIds\n\t\t\t: accountModels.filter((model) => model.policyState === \"enabled\").map((model) => model.id);\n\tconst policyModelIds = accountModels\n\t\t.filter(\n\t\t\t(model) =>\n\t\t\t\tmodel.policyState === \"unconfigured\" &&\n\t\t\t\tObject.hasOwn(GITHUB_COPILOT_MODELS, model.id) &&\n\t\t\t\t(model.pickerEnabled || usePolicyFallback),\n\t\t)\n\t\t.map((model) => model.id);\n\treturn { availableModelIds, policyModelIds };\n}\n\nasync function fetchWithRateLimitRetry(\n\turl: string,\n\tinit: RequestInit,\n\tsignal: AbortSignal,\n\tretryPolicy: { maxRetries: number; maxElapsedMs: number },\n): Promise<Response> {\n\tconst retryBudgetSignal =\n\t\tretryPolicy.maxRetries > 0 && retryPolicy.maxElapsedMs > 0\n\t\t\t? AbortSignal.timeout(retryPolicy.maxElapsedMs)\n\t\t\t: undefined;\n\tconst requestSignal = retryBudgetSignal ? AbortSignal.any([signal, retryBudgetSignal]) : signal;\n\tconst retryDeadline = retryBudgetSignal ? Date.now() + retryPolicy.maxElapsedMs : undefined;\n\tfor (let retry = 0; ; retry++) {\n\t\tconst response = await fetch(url, {\n\t\t\t...init,\n\t\t\tsignal: AbortSignal.any([requestSignal, AbortSignal.timeout(5000)]),\n\t\t});\n\t\tif (response.status !== 429 || retry === retryPolicy.maxRetries) return response;\n\n\t\tconst retryAfter = response.headers.get(\"retry-after\");\n\t\tlet delayMs = 500 * 2 ** retry;\n\t\tif (retryAfter) {\n\t\t\tconst seconds = Number.parseFloat(retryAfter);\n\t\t\tdelayMs = Number.isNaN(seconds) ? Date.parse(retryAfter) - Date.now() : seconds * 1000;\n\t\t\tif (!Number.isFinite(delayMs)) return response;\n\t\t}\n\t\tdelayMs = Math.max(0, delayMs);\n\t\tif (retryDeadline !== undefined && delayMs >= retryDeadline - Date.now()) return response;\n\t\tawait response.body?.cancel();\n\t\tawait sleep(delayMs, requestSignal);\n\t}\n}\n\nasync function fetchGitHubCopilotModels(\n\tcopilotToken: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n\tretryPolicy: { maxRetries: number; maxElapsedMs: number },\n) {\n\tconst baseUrl = getGitHubCopilotBaseUrl(copilotToken, enterpriseDomain);\n\t// Some Individual accounts return false for every picker flag despite explicit enabled policies.\n\t// Limit the fallback to that endpoint so other account types keep strict picker semantics.\n\tconst allowPolicyFallback = baseUrl === \"https://api.individual.githubcopilot.com\";\n\tconst response = await fetchWithRateLimitRetry(\n\t\t`${baseUrl}/models`,\n\t\t{\n\t\t\theaders: {\n\t\t\t\tAccept: \"application/json\",\n\t\t\t\tAuthorization: `Bearer ${copilotToken}`,\n\t\t\t\t...COPILOT_HEADERS,\n\t\t\t\t\"X-GitHub-Api-Version\": COPILOT_API_VERSION,\n\t\t\t},\n\t\t},\n\t\tsignal,\n\t\tretryPolicy,\n\t);\n\tif (!response.ok) {\n\t\tthrow new Error(`${response.status} ${response.statusText}: ${await response.text()}`);\n\t}\n\treturn parseGitHubCopilotModelCatalog(await response.json(), allowPolicyFallback);\n}\n\nasync function fetchJson(url: string, init: RequestInit): Promise<unknown> {\n\tconst response = await fetch(url, init);\n\tif (!response.ok) {\n\t\tconst text = await response.text();\n\t\tthrow new Error(`${response.status} ${response.statusText}: ${text}`);\n\t}\n\treturn response.json();\n}\n\nasync function startDeviceFlow(domain: string, signal: AbortSignal): Promise<DeviceCodeResponse> {\n\tconst urls = getUrls(domain);\n\tconst data = await fetchJson(urls.deviceCodeUrl, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\tAccept: \"application/json\",\n\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\t},\n\t\tbody: new URLSearchParams({\n\t\t\tclient_id: CLIENT_ID,\n\t\t\tscope: \"read:user\",\n\t\t}),\n\t\tsignal,\n\t});\n\n\tif (!data || typeof data !== \"object\") {\n\t\tthrow new Error(\"Invalid device code response\");\n\t}\n\n\tconst deviceCode = (data as Record<string, unknown>).device_code;\n\tconst userCode = (data as Record<string, unknown>).user_code;\n\tconst verificationUri = (data as Record<string, unknown>).verification_uri;\n\tconst interval = (data as Record<string, unknown>).interval;\n\tconst expiresIn = (data as Record<string, unknown>).expires_in;\n\n\tif (\n\t\ttypeof deviceCode !== \"string\" ||\n\t\ttypeof userCode !== \"string\" ||\n\t\ttypeof verificationUri !== \"string\" ||\n\t\t(interval !== undefined && typeof interval !== \"number\") ||\n\t\ttypeof expiresIn !== \"number\"\n\t) {\n\t\tthrow new Error(\"Invalid device code response fields\");\n\t}\n\n\t// The verification URI is opened in the user's browser and to prevent `open` from\n\t// opening an executable or similar, we force it to be a URL.\n\tlet parsedUri: URL;\n\ttry {\n\t\tparsedUri = new URL(verificationUri);\n\t} catch {\n\t\tthrow new Error(\"Untrusted verification_uri in device code response\");\n\t}\n\tif (parsedUri.protocol !== \"https:\" && parsedUri.protocol !== \"http:\") {\n\t\tthrow new Error(\"Untrusted verification_uri in device code response\");\n\t}\n\n\treturn {\n\t\tdevice_code: deviceCode,\n\t\tuser_code: userCode,\n\t\tverification_uri: parsedUri.href,\n\t\tinterval,\n\t\texpires_in: expiresIn,\n\t};\n}\n\nasync function pollForGitHubAccessToken(\n\tdomain: string,\n\tdevice: DeviceCodeResponse,\n\tsignal: AbortSignal,\n): Promise<string> {\n\tconst urls = getUrls(domain);\n\treturn pollOAuthDeviceCodeFlow<string>({\n\t\tintervalSeconds: device.interval,\n\t\texpiresInSeconds: device.expires_in,\n\t\twaitBeforeFirstPoll: true,\n\t\tsignal,\n\t\tpoll: async () => {\n\t\t\tconst raw = await fetchJson(urls.accessTokenUrl, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\tAccept: \"application/json\",\n\t\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\t\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\t\t\t},\n\t\t\t\tbody: new URLSearchParams({\n\t\t\t\t\tclient_id: CLIENT_ID,\n\t\t\t\t\tdevice_code: device.device_code,\n\t\t\t\t\tgrant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n\t\t\t\t}),\n\t\t\t\tsignal,\n\t\t\t});\n\n\t\t\tif (raw && typeof raw === \"object\" && typeof (raw as DeviceTokenSuccessResponse).access_token === \"string\") {\n\t\t\t\treturn { status: \"complete\", value: (raw as DeviceTokenSuccessResponse).access_token };\n\t\t\t}\n\n\t\t\tif (raw && typeof raw === \"object\" && typeof (raw as DeviceTokenErrorResponse).error === \"string\") {\n\t\t\t\tconst { error, error_description: description, interval } = raw as DeviceTokenErrorResponse;\n\t\t\t\tif (error === \"authorization_pending\") {\n\t\t\t\t\treturn { status: \"pending\" };\n\t\t\t\t}\n\n\t\t\t\tif (error === \"slow_down\") {\n\t\t\t\t\treturn { status: \"slow_down\", intervalSeconds: typeof interval === \"number\" ? interval : undefined };\n\t\t\t\t}\n\n\t\t\t\tconst descriptionSuffix = description ? `: ${description}` : \"\";\n\t\t\t\treturn { status: \"failed\", message: `Device flow failed: ${error}${descriptionSuffix}` };\n\t\t\t}\n\n\t\t\treturn { status: \"failed\", message: \"Invalid device token response\" };\n\t\t},\n\t});\n}\n\nasync function refreshGitHubCopilotAccessToken(\n\trefreshToken: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<OAuthCredential> {\n\tconst domain = enterpriseDomain || \"github.com\";\n\tconst urls = getUrls(domain);\n\n\tconst raw = await fetchJson(urls.copilotTokenUrl, {\n\t\theaders: {\n\t\t\tAccept: \"application/json\",\n\t\t\tAuthorization: `Bearer ${refreshToken}`,\n\t\t\t...COPILOT_HEADERS,\n\t\t},\n\t\tsignal,\n\t});\n\n\tif (!raw || typeof raw !== \"object\") {\n\t\tthrow new Error(\"Invalid Copilot token response\");\n\t}\n\n\tconst token = (raw as Record<string, unknown>).token;\n\tconst expiresAt = (raw as Record<string, unknown>).expires_at;\n\n\tif (typeof token !== \"string\" || typeof expiresAt !== \"number\") {\n\t\tthrow new Error(\"Invalid Copilot token response fields\");\n\t}\n\n\treturn {\n\t\ttype: \"oauth\",\n\t\trefresh: refreshToken,\n\t\taccess: token,\n\t\texpires: expiresAt * 1000 - 5 * 60 * 1000,\n\t\tenterpriseUrl: enterpriseDomain,\n\t};\n}\n\n/**\n * Refresh GitHub Copilot token\n */\nasync function refreshGitHubCopilotToken(\n\trefreshToken: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<OAuthCredential> {\n\tconst credentials = await refreshGitHubCopilotAccessToken(refreshToken, enterpriseDomain, signal);\n\tconst { availableModelIds } = await fetchGitHubCopilotModels(credentials.access, enterpriseDomain, signal, {\n\t\tmaxRetries: 0,\n\t\tmaxElapsedMs: 0,\n\t});\n\treturn {\n\t\t...credentials,\n\t\tavailableModelIds,\n\t};\n}\n\n/**\n * Enable a model for the user's GitHub Copilot account.\n * This is required for some models (like Claude, Grok) before they can be used.\n */\nasync function enableGitHubCopilotModel(\n\ttoken: string,\n\tmodelId: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<boolean> {\n\tconst baseUrl = getGitHubCopilotBaseUrl(token, enterpriseDomain);\n\tconst url = `${baseUrl}/models/${modelId}/policy`;\n\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetchWithRateLimitRetry(\n\t\t\turl,\n\t\t\t{\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\t\t...COPILOT_HEADERS,\n\t\t\t\t\t\"openai-intent\": \"chat-policy\",\n\t\t\t\t\t\"x-interaction-type\": \"chat-policy\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({ state: \"enabled\" }),\n\t\t\t},\n\t\t\tsignal,\n\t\t\t{ maxRetries: 2, maxElapsedMs: 5000 },\n\t\t);\n\t} catch (error) {\n\t\tif (signal.aborted) throw error;\n\t\treturn false;\n\t}\n\tif (response.status === 429) {\n\t\tthrow new Error(`${response.status} ${response.statusText}: ${await response.text()}`);\n\t}\n\treturn response.ok;\n}\n\n/**\n * Enable the requested GitHub Copilot models and return the successful IDs.\n * Policy updates are best effort; exhausted rate limiting stops the batch.\n */\nasync function enableGitHubCopilotModels(\n\ttoken: string,\n\tmodelIds: readonly string[],\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<string[]> {\n\tconst enabledModelIds: string[] = [];\n\tfor (const modelId of modelIds) {\n\t\ttry {\n\t\t\tif (await enableGitHubCopilotModel(token, modelId, enterpriseDomain, signal)) {\n\t\t\t\tenabledModelIds.push(modelId);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (signal.aborted) throw error;\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn enabledModelIds;\n}\n\nasync function loginGitHubCopilot(interaction: ProviderAuthInteraction): Promise<OAuthCredential> {\n\tconst input = await interaction.prompt({\n\t\ttype: \"text\",\n\t\tmessage: \"GitHub Enterprise URL/domain (blank for github.com)\",\n\t\tplaceholder: \"company.ghe.com\",\n\t});\n\tif (interaction.signal.aborted) throw new Error(\"Login cancelled\");\n\n\tconst trimmed = input.trim();\n\tconst enterpriseDomain = normalizeDomain(input);\n\tif (trimmed && !enterpriseDomain) throw new Error(\"Invalid GitHub Enterprise URL/domain\");\n\tconst domain = enterpriseDomain || \"github.com\";\n\n\tconst device = await startDeviceFlow(domain, interaction.signal);\n\tinteraction.notify({\n\t\ttype: \"device_code\",\n\t\tuserCode: device.user_code,\n\t\tverificationUri: device.verification_uri,\n\t\tintervalSeconds: device.interval,\n\t\texpiresInSeconds: device.expires_in,\n\t});\n\n\tconst githubAccessToken = await pollForGitHubAccessToken(domain, device, interaction.signal);\n\tconst credentials = await refreshGitHubCopilotAccessToken(\n\t\tgithubAccessToken,\n\t\tenterpriseDomain ?? undefined,\n\t\tinteraction.signal,\n\t);\n\tconst models = await fetchGitHubCopilotModels(\n\t\tcredentials.access,\n\t\tenterpriseDomain ?? undefined,\n\t\tinteraction.signal,\n\t\t{\n\t\t\tmaxRetries: 2,\n\t\t\tmaxElapsedMs: 5000,\n\t\t},\n\t);\n\tlet enabledModelIds: string[] = [];\n\tif (models.policyModelIds.length > 0) {\n\t\tinteraction.notify({ type: \"progress\", message: \"Enabling models...\" });\n\t\tenabledModelIds = await enableGitHubCopilotModels(\n\t\t\tcredentials.access,\n\t\t\tmodels.policyModelIds,\n\t\t\tenterpriseDomain ?? undefined,\n\t\t\tinteraction.signal,\n\t\t);\n\t}\n\treturn {\n\t\t...credentials,\n\t\tavailableModelIds: [...new Set([...models.availableModelIds, ...enabledModelIds])],\n\t};\n}\n\nfunction copilotEnterpriseDomain(credential: OAuthCredential): string | undefined {\n\tconst enterpriseUrl = credential.enterpriseUrl;\n\tif (typeof enterpriseUrl !== \"string\" || !enterpriseUrl) return undefined;\n\treturn normalizeDomain(enterpriseUrl) ?? undefined;\n}\n\nexport const githubCopilotOAuth: OAuthAuth = {\n\tname: \"GitHub Copilot\",\n\tisSubscription: true,\n\tlogin: loginGitHubCopilot,\n\trefresh: (credential, signal) =>\n\t\trefreshGitHubCopilotToken(credential.refresh, copilotEnterpriseDomain(credential), signal),\n\n\t/** Derive the credential-specific proxy endpoint for each request. */\n\tasync toAuth(credential) {\n\t\treturn {\n\t\t\tapiKey: credential.access,\n\t\t\tbaseUrl: getGitHubCopilotBaseUrl(credential.access, copilotEnterpriseDomain(credential)),\n\t\t};\n\t},\n};\n"]}
1
+ {"version":3,"file":"github-copilot.d.ts","sourceRoot":"","sources":["../../../src/auth/oauth/github-copilot.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,SAAS,EAA4C,MAAM,aAAa,CAAC;AAkfvF,eAAO,MAAM,kBAAkB,EAAE,SAchC,CAAC","sourcesContent":["/**\n * GitHub Copilot OAuth flow\n */\n\nimport { GITHUB_COPILOT_MODELS } from \"../../providers/github-copilot.models.ts\";\nimport { sleep } from \"../../utils/sleep.ts\";\nimport type { OAuthAuth, OAuthCredential, ProviderAuthInteraction } from \"../types.ts\";\nimport { pollOAuthDeviceCodeFlow } from \"./device-code.ts\";\n\nconst decode = (s: string) => atob(s);\nconst CLIENT_ID = decode(\"SXYxLmI1MDdhMDhjODdlY2ZlOTg=\");\n\nconst COPILOT_HEADERS = {\n\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\"Editor-Version\": \"vscode/1.107.0\",\n\t\"Editor-Plugin-Version\": \"copilot-chat/0.35.0\",\n\t\"Copilot-Integration-Id\": \"vscode-chat\",\n} as const;\nconst COPILOT_API_VERSION = \"2026-06-01\";\n\ntype DeviceCodeResponse = {\n\tdevice_code: string;\n\tuser_code: string;\n\tverification_uri: string;\n\tinterval?: number;\n\texpires_in: number;\n};\n\ntype DeviceTokenSuccessResponse = {\n\taccess_token: string;\n\ttoken_type?: string;\n\tscope?: string;\n};\n\ntype DeviceTokenErrorResponse = {\n\terror: string;\n\terror_description?: string;\n\tinterval?: number;\n};\n\nfunction normalizeDomain(input: string): string | null {\n\tconst trimmed = input.trim();\n\tif (!trimmed) return null;\n\ttry {\n\t\tconst url = trimmed.includes(\"://\") ? new URL(trimmed) : new URL(`https://${trimmed}`);\n\t\treturn url.hostname;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction getUrls(domain: string): {\n\tdeviceCodeUrl: string;\n\taccessTokenUrl: string;\n\tcopilotTokenUrl: string;\n} {\n\treturn {\n\t\tdeviceCodeUrl: `https://${domain}/login/device/code`,\n\t\taccessTokenUrl: `https://${domain}/login/oauth/access_token`,\n\t\tcopilotTokenUrl: `https://api.${domain}/copilot_internal/v2/token`,\n\t};\n}\n\n/**\n * Parse the proxy-ep from a Copilot token and convert to API base URL.\n * Token format: tid=...;exp=...;proxy-ep=proxy.individual.githubcopilot.com;...\n * Returns API URL like https://api.individual.githubcopilot.com\n */\nfunction getBaseUrlFromToken(token: string): string | null {\n\tconst match = token.match(/proxy-ep=([^;]+)/);\n\tif (!match) return null;\n\tconst proxyHost = match[1];\n\t// Convert proxy.xxx to api.xxx\n\tconst apiHost = proxyHost.replace(/^proxy\\./, \"api.\");\n\treturn `https://${apiHost}`;\n}\n\nfunction getGitHubCopilotBaseUrl(token?: string, enterpriseDomain?: string): string {\n\t// If we have a token, extract the base URL from proxy-ep\n\tif (token) {\n\t\tconst urlFromToken = getBaseUrlFromToken(token);\n\t\tif (urlFromToken) return urlFromToken;\n\t}\n\t// Fallback for enterprise or if token parsing fails\n\tif (enterpriseDomain) return `https://copilot-api.${enterpriseDomain}`;\n\treturn \"https://api.individual.githubcopilot.com\";\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n\treturn value && typeof value === \"object\" ? (value as Record<string, unknown>) : undefined;\n}\n\nfunction parseGitHubCopilotModelCatalog(raw: unknown, allowPolicyFallback: boolean) {\n\tconst data = asRecord(raw)?.data;\n\tif (!Array.isArray(data)) {\n\t\tthrow new Error(\"Invalid Copilot models response\");\n\t}\n\n\tconst accountModels = data.flatMap((rawItem) => {\n\t\tconst item = asRecord(rawItem);\n\t\tconst id = item?.id;\n\t\tif (!item || typeof id !== \"string\") return [];\n\n\t\tconst capabilities = asRecord(item.capabilities);\n\t\tconst supports = asRecord(capabilities?.supports);\n\t\tif (supports?.tool_calls === false) return [];\n\n\t\treturn [\n\t\t\t{\n\t\t\t\tid,\n\t\t\t\tpickerEnabled: item.model_picker_enabled === true,\n\t\t\t\tpolicyState: asRecord(item.policy)?.state,\n\t\t\t},\n\t\t];\n\t});\n\tconst pickerModelIds = accountModels\n\t\t.filter((model) => model.pickerEnabled && model.policyState !== \"disabled\")\n\t\t.map((model) => model.id);\n\tconst usePolicyFallback = allowPolicyFallback && pickerModelIds.length === 0;\n\tconst availableModelIds =\n\t\tpickerModelIds.length > 0 || !allowPolicyFallback\n\t\t\t? pickerModelIds\n\t\t\t: accountModels\n\t\t\t\t\t.filter((model) => !model.id.endsWith(\"-fast\") && model.policyState === \"enabled\")\n\t\t\t\t\t.map((model) => model.id);\n\tconst fastModelIds = accountModels\n\t\t.filter((model) => model.id.endsWith(\"-fast\") && model.policyState !== \"disabled\")\n\t\t.map((model) => model.id);\n\tconst policyModelIds = accountModels\n\t\t.filter(\n\t\t\t(model) =>\n\t\t\t\tmodel.policyState === \"unconfigured\" &&\n\t\t\t\tObject.hasOwn(GITHUB_COPILOT_MODELS, model.id) &&\n\t\t\t\t(model.pickerEnabled || usePolicyFallback),\n\t\t)\n\t\t.map((model) => model.id);\n\treturn { availableModelIds, fastModelIds, policyModelIds };\n}\n\nasync function fetchWithRateLimitRetry(\n\turl: string,\n\tinit: RequestInit,\n\tsignal: AbortSignal,\n\tretryPolicy: { maxRetries: number; maxElapsedMs: number },\n): Promise<Response> {\n\tconst retryBudgetSignal =\n\t\tretryPolicy.maxRetries > 0 && retryPolicy.maxElapsedMs > 0\n\t\t\t? AbortSignal.timeout(retryPolicy.maxElapsedMs)\n\t\t\t: undefined;\n\tconst requestSignal = retryBudgetSignal ? AbortSignal.any([signal, retryBudgetSignal]) : signal;\n\tconst retryDeadline = retryBudgetSignal ? Date.now() + retryPolicy.maxElapsedMs : undefined;\n\tfor (let retry = 0; ; retry++) {\n\t\tconst response = await fetch(url, {\n\t\t\t...init,\n\t\t\tsignal: AbortSignal.any([requestSignal, AbortSignal.timeout(5000)]),\n\t\t});\n\t\tif (response.status !== 429 || retry === retryPolicy.maxRetries) return response;\n\n\t\tconst retryAfter = response.headers.get(\"retry-after\");\n\t\tlet delayMs = 500 * 2 ** retry;\n\t\tif (retryAfter) {\n\t\t\tconst seconds = Number.parseFloat(retryAfter);\n\t\t\tdelayMs = Number.isNaN(seconds) ? Date.parse(retryAfter) - Date.now() : seconds * 1000;\n\t\t\tif (!Number.isFinite(delayMs)) return response;\n\t\t}\n\t\tdelayMs = Math.max(0, delayMs);\n\t\tif (retryDeadline !== undefined && delayMs >= retryDeadline - Date.now()) return response;\n\t\tawait response.body?.cancel();\n\t\tawait sleep(delayMs, requestSignal);\n\t}\n}\n\nasync function fetchGitHubCopilotModels(\n\tcopilotToken: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n\tretryPolicy: { maxRetries: number; maxElapsedMs: number },\n) {\n\tconst baseUrl = getGitHubCopilotBaseUrl(copilotToken, enterpriseDomain);\n\t// Some Individual accounts return false for every picker flag despite explicit enabled policies.\n\t// Limit the fallback to that endpoint so other account types keep strict picker semantics.\n\tconst allowPolicyFallback = baseUrl === \"https://api.individual.githubcopilot.com\";\n\tconst response = await fetchWithRateLimitRetry(\n\t\t`${baseUrl}/models`,\n\t\t{\n\t\t\theaders: {\n\t\t\t\tAccept: \"application/json\",\n\t\t\t\tAuthorization: `Bearer ${copilotToken}`,\n\t\t\t\t...COPILOT_HEADERS,\n\t\t\t\t\"X-GitHub-Api-Version\": COPILOT_API_VERSION,\n\t\t\t},\n\t\t},\n\t\tsignal,\n\t\tretryPolicy,\n\t);\n\tif (!response.ok) {\n\t\tthrow new Error(`${response.status} ${response.statusText}: ${await response.text()}`);\n\t}\n\treturn parseGitHubCopilotModelCatalog(await response.json(), allowPolicyFallback);\n}\n\nasync function fetchJson(url: string, init: RequestInit): Promise<unknown> {\n\tconst response = await fetch(url, init);\n\tif (!response.ok) {\n\t\tconst text = await response.text();\n\t\tthrow new Error(`${response.status} ${response.statusText}: ${text}`);\n\t}\n\treturn response.json();\n}\n\nasync function startDeviceFlow(domain: string, signal: AbortSignal): Promise<DeviceCodeResponse> {\n\tconst urls = getUrls(domain);\n\tconst data = await fetchJson(urls.deviceCodeUrl, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\tAccept: \"application/json\",\n\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\t},\n\t\tbody: new URLSearchParams({\n\t\t\tclient_id: CLIENT_ID,\n\t\t\tscope: \"read:user\",\n\t\t}),\n\t\tsignal,\n\t});\n\n\tif (!data || typeof data !== \"object\") {\n\t\tthrow new Error(\"Invalid device code response\");\n\t}\n\n\tconst deviceCode = (data as Record<string, unknown>).device_code;\n\tconst userCode = (data as Record<string, unknown>).user_code;\n\tconst verificationUri = (data as Record<string, unknown>).verification_uri;\n\tconst interval = (data as Record<string, unknown>).interval;\n\tconst expiresIn = (data as Record<string, unknown>).expires_in;\n\n\tif (\n\t\ttypeof deviceCode !== \"string\" ||\n\t\ttypeof userCode !== \"string\" ||\n\t\ttypeof verificationUri !== \"string\" ||\n\t\t(interval !== undefined && typeof interval !== \"number\") ||\n\t\ttypeof expiresIn !== \"number\"\n\t) {\n\t\tthrow new Error(\"Invalid device code response fields\");\n\t}\n\n\t// The verification URI is opened in the user's browser and to prevent `open` from\n\t// opening an executable or similar, we force it to be a URL.\n\tlet parsedUri: URL;\n\ttry {\n\t\tparsedUri = new URL(verificationUri);\n\t} catch {\n\t\tthrow new Error(\"Untrusted verification_uri in device code response\");\n\t}\n\tif (parsedUri.protocol !== \"https:\" && parsedUri.protocol !== \"http:\") {\n\t\tthrow new Error(\"Untrusted verification_uri in device code response\");\n\t}\n\n\treturn {\n\t\tdevice_code: deviceCode,\n\t\tuser_code: userCode,\n\t\tverification_uri: parsedUri.href,\n\t\tinterval,\n\t\texpires_in: expiresIn,\n\t};\n}\n\nasync function pollForGitHubAccessToken(\n\tdomain: string,\n\tdevice: DeviceCodeResponse,\n\tsignal: AbortSignal,\n): Promise<string> {\n\tconst urls = getUrls(domain);\n\treturn pollOAuthDeviceCodeFlow<string>({\n\t\tintervalSeconds: device.interval,\n\t\texpiresInSeconds: device.expires_in,\n\t\twaitBeforeFirstPoll: true,\n\t\tsignal,\n\t\tpoll: async () => {\n\t\t\tconst raw = await fetchJson(urls.accessTokenUrl, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\tAccept: \"application/json\",\n\t\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\t\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\t\t\t},\n\t\t\t\tbody: new URLSearchParams({\n\t\t\t\t\tclient_id: CLIENT_ID,\n\t\t\t\t\tdevice_code: device.device_code,\n\t\t\t\t\tgrant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n\t\t\t\t}),\n\t\t\t\tsignal,\n\t\t\t});\n\n\t\t\tif (raw && typeof raw === \"object\" && typeof (raw as DeviceTokenSuccessResponse).access_token === \"string\") {\n\t\t\t\treturn { status: \"complete\", value: (raw as DeviceTokenSuccessResponse).access_token };\n\t\t\t}\n\n\t\t\tif (raw && typeof raw === \"object\" && typeof (raw as DeviceTokenErrorResponse).error === \"string\") {\n\t\t\t\tconst { error, error_description: description, interval } = raw as DeviceTokenErrorResponse;\n\t\t\t\tif (error === \"authorization_pending\") {\n\t\t\t\t\treturn { status: \"pending\" };\n\t\t\t\t}\n\n\t\t\t\tif (error === \"slow_down\") {\n\t\t\t\t\treturn { status: \"slow_down\", intervalSeconds: typeof interval === \"number\" ? interval : undefined };\n\t\t\t\t}\n\n\t\t\t\tconst descriptionSuffix = description ? `: ${description}` : \"\";\n\t\t\t\treturn { status: \"failed\", message: `Device flow failed: ${error}${descriptionSuffix}` };\n\t\t\t}\n\n\t\t\treturn { status: \"failed\", message: \"Invalid device token response\" };\n\t\t},\n\t});\n}\n\nasync function refreshGitHubCopilotAccessToken(\n\trefreshToken: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<OAuthCredential> {\n\tconst domain = enterpriseDomain || \"github.com\";\n\tconst urls = getUrls(domain);\n\n\tconst raw = await fetchJson(urls.copilotTokenUrl, {\n\t\theaders: {\n\t\t\tAccept: \"application/json\",\n\t\t\tAuthorization: `Bearer ${refreshToken}`,\n\t\t\t...COPILOT_HEADERS,\n\t\t},\n\t\tsignal,\n\t});\n\n\tif (!raw || typeof raw !== \"object\") {\n\t\tthrow new Error(\"Invalid Copilot token response\");\n\t}\n\n\tconst token = (raw as Record<string, unknown>).token;\n\tconst expiresAt = (raw as Record<string, unknown>).expires_at;\n\n\tif (typeof token !== \"string\" || typeof expiresAt !== \"number\") {\n\t\tthrow new Error(\"Invalid Copilot token response fields\");\n\t}\n\n\treturn {\n\t\ttype: \"oauth\",\n\t\trefresh: refreshToken,\n\t\taccess: token,\n\t\texpires: expiresAt * 1000 - 5 * 60 * 1000,\n\t\tenterpriseUrl: enterpriseDomain,\n\t};\n}\n\n/**\n * Refresh GitHub Copilot token\n */\nasync function refreshGitHubCopilotToken(\n\trefreshToken: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<OAuthCredential> {\n\tconst credentials = await refreshGitHubCopilotAccessToken(refreshToken, enterpriseDomain, signal);\n\tconst { availableModelIds, fastModelIds } = await fetchGitHubCopilotModels(\n\t\tcredentials.access,\n\t\tenterpriseDomain,\n\t\tsignal,\n\t\t{\n\t\t\tmaxRetries: 0,\n\t\t\tmaxElapsedMs: 0,\n\t\t},\n\t);\n\treturn {\n\t\t...credentials,\n\t\tavailableModelIds,\n\t\tfastModelIds,\n\t};\n}\n\n/**\n * Enable a model for the user's GitHub Copilot account.\n * This is required for some models (like Claude, Grok) before they can be used.\n */\nasync function enableGitHubCopilotModel(\n\ttoken: string,\n\tmodelId: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<boolean> {\n\tconst baseUrl = getGitHubCopilotBaseUrl(token, enterpriseDomain);\n\tconst url = `${baseUrl}/models/${modelId}/policy`;\n\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetchWithRateLimitRetry(\n\t\t\turl,\n\t\t\t{\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\t\t...COPILOT_HEADERS,\n\t\t\t\t\t\"openai-intent\": \"chat-policy\",\n\t\t\t\t\t\"x-interaction-type\": \"chat-policy\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({ state: \"enabled\" }),\n\t\t\t},\n\t\t\tsignal,\n\t\t\t{ maxRetries: 2, maxElapsedMs: 5000 },\n\t\t);\n\t} catch (error) {\n\t\tif (signal.aborted) throw error;\n\t\treturn false;\n\t}\n\tif (response.status === 429) {\n\t\tthrow new Error(`${response.status} ${response.statusText}: ${await response.text()}`);\n\t}\n\treturn response.ok;\n}\n\n/**\n * Enable the requested GitHub Copilot models and return the successful IDs.\n * Policy updates are best effort; exhausted rate limiting stops the batch.\n */\nasync function enableGitHubCopilotModels(\n\ttoken: string,\n\tmodelIds: readonly string[],\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<string[]> {\n\tconst enabledModelIds: string[] = [];\n\tfor (const modelId of modelIds) {\n\t\ttry {\n\t\t\tif (await enableGitHubCopilotModel(token, modelId, enterpriseDomain, signal)) {\n\t\t\t\tenabledModelIds.push(modelId);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (signal.aborted) throw error;\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn enabledModelIds;\n}\n\nasync function loginGitHubCopilot(interaction: ProviderAuthInteraction): Promise<OAuthCredential> {\n\tconst input = await interaction.prompt({\n\t\ttype: \"text\",\n\t\tmessage: \"GitHub Enterprise URL/domain (blank for github.com)\",\n\t\tplaceholder: \"company.ghe.com\",\n\t});\n\tif (interaction.signal.aborted) throw new Error(\"Login cancelled\");\n\n\tconst trimmed = input.trim();\n\tconst enterpriseDomain = normalizeDomain(input);\n\tif (trimmed && !enterpriseDomain) throw new Error(\"Invalid GitHub Enterprise URL/domain\");\n\tconst domain = enterpriseDomain || \"github.com\";\n\n\tconst device = await startDeviceFlow(domain, interaction.signal);\n\tinteraction.notify({\n\t\ttype: \"device_code\",\n\t\tuserCode: device.user_code,\n\t\tverificationUri: device.verification_uri,\n\t\tintervalSeconds: device.interval,\n\t\texpiresInSeconds: device.expires_in,\n\t});\n\n\tconst githubAccessToken = await pollForGitHubAccessToken(domain, device, interaction.signal);\n\tconst credentials = await refreshGitHubCopilotAccessToken(\n\t\tgithubAccessToken,\n\t\tenterpriseDomain ?? undefined,\n\t\tinteraction.signal,\n\t);\n\tconst models = await fetchGitHubCopilotModels(\n\t\tcredentials.access,\n\t\tenterpriseDomain ?? undefined,\n\t\tinteraction.signal,\n\t\t{\n\t\t\tmaxRetries: 2,\n\t\t\tmaxElapsedMs: 5000,\n\t\t},\n\t);\n\tlet enabledModelIds: string[] = [];\n\tif (models.policyModelIds.length > 0) {\n\t\tinteraction.notify({ type: \"progress\", message: \"Enabling models...\" });\n\t\tenabledModelIds = await enableGitHubCopilotModels(\n\t\t\tcredentials.access,\n\t\t\tmodels.policyModelIds,\n\t\t\tenterpriseDomain ?? undefined,\n\t\t\tinteraction.signal,\n\t\t);\n\t}\n\treturn {\n\t\t...credentials,\n\t\tavailableModelIds: [...new Set([...models.availableModelIds, ...enabledModelIds])],\n\t\tfastModelIds: models.fastModelIds,\n\t};\n}\n\nfunction copilotEnterpriseDomain(credential: OAuthCredential): string | undefined {\n\tconst enterpriseUrl = credential.enterpriseUrl;\n\tif (typeof enterpriseUrl !== \"string\" || !enterpriseUrl) return undefined;\n\treturn normalizeDomain(enterpriseUrl) ?? undefined;\n}\n\nexport const githubCopilotOAuth: OAuthAuth = {\n\tname: \"GitHub Copilot\",\n\tisSubscription: true,\n\tlogin: loginGitHubCopilot,\n\trefresh: (credential, signal) =>\n\t\trefreshGitHubCopilotToken(credential.refresh, copilotEnterpriseDomain(credential), signal),\n\n\t/** Derive the credential-specific proxy endpoint for each request. */\n\tasync toAuth(credential) {\n\t\treturn {\n\t\t\tapiKey: credential.access,\n\t\t\tbaseUrl: getGitHubCopilotBaseUrl(credential.access, copilotEnterpriseDomain(credential)),\n\t\t};\n\t},\n};\n"]}
@@ -89,13 +89,18 @@ function parseGitHubCopilotModelCatalog(raw, allowPolicyFallback) {
89
89
  const usePolicyFallback = allowPolicyFallback && pickerModelIds.length === 0;
90
90
  const availableModelIds = pickerModelIds.length > 0 || !allowPolicyFallback
91
91
  ? pickerModelIds
92
- : accountModels.filter((model) => model.policyState === "enabled").map((model) => model.id);
92
+ : accountModels
93
+ .filter((model) => !model.id.endsWith("-fast") && model.policyState === "enabled")
94
+ .map((model) => model.id);
95
+ const fastModelIds = accountModels
96
+ .filter((model) => model.id.endsWith("-fast") && model.policyState !== "disabled")
97
+ .map((model) => model.id);
93
98
  const policyModelIds = accountModels
94
99
  .filter((model) => model.policyState === "unconfigured" &&
95
100
  Object.hasOwn(GITHUB_COPILOT_MODELS, model.id) &&
96
101
  (model.pickerEnabled || usePolicyFallback))
97
102
  .map((model) => model.id);
98
- return { availableModelIds, policyModelIds };
103
+ return { availableModelIds, fastModelIds, policyModelIds };
99
104
  }
100
105
  async function fetchWithRateLimitRetry(url, init, signal, retryPolicy) {
101
106
  const retryBudgetSignal = retryPolicy.maxRetries > 0 && retryPolicy.maxElapsedMs > 0
@@ -273,13 +278,14 @@ async function refreshGitHubCopilotAccessToken(refreshToken, enterpriseDomain, s
273
278
  */
274
279
  async function refreshGitHubCopilotToken(refreshToken, enterpriseDomain, signal) {
275
280
  const credentials = await refreshGitHubCopilotAccessToken(refreshToken, enterpriseDomain, signal);
276
- const { availableModelIds } = await fetchGitHubCopilotModels(credentials.access, enterpriseDomain, signal, {
281
+ const { availableModelIds, fastModelIds } = await fetchGitHubCopilotModels(credentials.access, enterpriseDomain, signal, {
277
282
  maxRetries: 0,
278
283
  maxElapsedMs: 0,
279
284
  });
280
285
  return {
281
286
  ...credentials,
282
287
  availableModelIds,
288
+ fastModelIds,
283
289
  };
284
290
  }
285
291
  /**
@@ -368,6 +374,7 @@ async function loginGitHubCopilot(interaction) {
368
374
  return {
369
375
  ...credentials,
370
376
  availableModelIds: [...new Set([...models.availableModelIds, ...enabledModelIds])],
377
+ fastModelIds: models.fastModelIds,
371
378
  };
372
379
  }
373
380
  function copilotEnterpriseDomain(credential) {
@@ -1 +1 @@
1
- {"version":3,"file":"github-copilot.js","sourceRoot":"","sources":["../../../src/auth/oauth/github-copilot.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * GitHub Copilot OAuth flow\n */\n\nimport { GITHUB_COPILOT_MODELS } from \"../../providers/github-copilot.models.ts\";\nimport { sleep } from \"../../utils/sleep.ts\";\nimport type { OAuthAuth, OAuthCredential, ProviderAuthInteraction } from \"../types.ts\";\nimport { pollOAuthDeviceCodeFlow } from \"./device-code.ts\";\n\nconst decode = (s: string) => atob(s);\nconst CLIENT_ID = decode(\"SXYxLmI1MDdhMDhjODdlY2ZlOTg=\");\n\nconst COPILOT_HEADERS = {\n\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\"Editor-Version\": \"vscode/1.107.0\",\n\t\"Editor-Plugin-Version\": \"copilot-chat/0.35.0\",\n\t\"Copilot-Integration-Id\": \"vscode-chat\",\n} as const;\nconst COPILOT_API_VERSION = \"2026-06-01\";\n\ntype DeviceCodeResponse = {\n\tdevice_code: string;\n\tuser_code: string;\n\tverification_uri: string;\n\tinterval?: number;\n\texpires_in: number;\n};\n\ntype DeviceTokenSuccessResponse = {\n\taccess_token: string;\n\ttoken_type?: string;\n\tscope?: string;\n};\n\ntype DeviceTokenErrorResponse = {\n\terror: string;\n\terror_description?: string;\n\tinterval?: number;\n};\n\nfunction normalizeDomain(input: string): string | null {\n\tconst trimmed = input.trim();\n\tif (!trimmed) return null;\n\ttry {\n\t\tconst url = trimmed.includes(\"://\") ? new URL(trimmed) : new URL(`https://${trimmed}`);\n\t\treturn url.hostname;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction getUrls(domain: string): {\n\tdeviceCodeUrl: string;\n\taccessTokenUrl: string;\n\tcopilotTokenUrl: string;\n} {\n\treturn {\n\t\tdeviceCodeUrl: `https://${domain}/login/device/code`,\n\t\taccessTokenUrl: `https://${domain}/login/oauth/access_token`,\n\t\tcopilotTokenUrl: `https://api.${domain}/copilot_internal/v2/token`,\n\t};\n}\n\n/**\n * Parse the proxy-ep from a Copilot token and convert to API base URL.\n * Token format: tid=...;exp=...;proxy-ep=proxy.individual.githubcopilot.com;...\n * Returns API URL like https://api.individual.githubcopilot.com\n */\nfunction getBaseUrlFromToken(token: string): string | null {\n\tconst match = token.match(/proxy-ep=([^;]+)/);\n\tif (!match) return null;\n\tconst proxyHost = match[1];\n\t// Convert proxy.xxx to api.xxx\n\tconst apiHost = proxyHost.replace(/^proxy\\./, \"api.\");\n\treturn `https://${apiHost}`;\n}\n\nfunction getGitHubCopilotBaseUrl(token?: string, enterpriseDomain?: string): string {\n\t// If we have a token, extract the base URL from proxy-ep\n\tif (token) {\n\t\tconst urlFromToken = getBaseUrlFromToken(token);\n\t\tif (urlFromToken) return urlFromToken;\n\t}\n\t// Fallback for enterprise or if token parsing fails\n\tif (enterpriseDomain) return `https://copilot-api.${enterpriseDomain}`;\n\treturn \"https://api.individual.githubcopilot.com\";\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n\treturn value && typeof value === \"object\" ? (value as Record<string, unknown>) : undefined;\n}\n\nfunction parseGitHubCopilotModelCatalog(raw: unknown, allowPolicyFallback: boolean) {\n\tconst data = asRecord(raw)?.data;\n\tif (!Array.isArray(data)) {\n\t\tthrow new Error(\"Invalid Copilot models response\");\n\t}\n\n\tconst accountModels = data.flatMap((rawItem) => {\n\t\tconst item = asRecord(rawItem);\n\t\tconst id = item?.id;\n\t\tif (!item || typeof id !== \"string\") return [];\n\n\t\tconst capabilities = asRecord(item.capabilities);\n\t\tconst supports = asRecord(capabilities?.supports);\n\t\tif (supports?.tool_calls === false) return [];\n\n\t\treturn [\n\t\t\t{\n\t\t\t\tid,\n\t\t\t\tpickerEnabled: item.model_picker_enabled === true,\n\t\t\t\tpolicyState: asRecord(item.policy)?.state,\n\t\t\t},\n\t\t];\n\t});\n\tconst pickerModelIds = accountModels\n\t\t.filter((model) => model.pickerEnabled && model.policyState !== \"disabled\")\n\t\t.map((model) => model.id);\n\tconst usePolicyFallback = allowPolicyFallback && pickerModelIds.length === 0;\n\tconst availableModelIds =\n\t\tpickerModelIds.length > 0 || !allowPolicyFallback\n\t\t\t? pickerModelIds\n\t\t\t: accountModels.filter((model) => model.policyState === \"enabled\").map((model) => model.id);\n\tconst policyModelIds = accountModels\n\t\t.filter(\n\t\t\t(model) =>\n\t\t\t\tmodel.policyState === \"unconfigured\" &&\n\t\t\t\tObject.hasOwn(GITHUB_COPILOT_MODELS, model.id) &&\n\t\t\t\t(model.pickerEnabled || usePolicyFallback),\n\t\t)\n\t\t.map((model) => model.id);\n\treturn { availableModelIds, policyModelIds };\n}\n\nasync function fetchWithRateLimitRetry(\n\turl: string,\n\tinit: RequestInit,\n\tsignal: AbortSignal,\n\tretryPolicy: { maxRetries: number; maxElapsedMs: number },\n): Promise<Response> {\n\tconst retryBudgetSignal =\n\t\tretryPolicy.maxRetries > 0 && retryPolicy.maxElapsedMs > 0\n\t\t\t? AbortSignal.timeout(retryPolicy.maxElapsedMs)\n\t\t\t: undefined;\n\tconst requestSignal = retryBudgetSignal ? AbortSignal.any([signal, retryBudgetSignal]) : signal;\n\tconst retryDeadline = retryBudgetSignal ? Date.now() + retryPolicy.maxElapsedMs : undefined;\n\tfor (let retry = 0; ; retry++) {\n\t\tconst response = await fetch(url, {\n\t\t\t...init,\n\t\t\tsignal: AbortSignal.any([requestSignal, AbortSignal.timeout(5000)]),\n\t\t});\n\t\tif (response.status !== 429 || retry === retryPolicy.maxRetries) return response;\n\n\t\tconst retryAfter = response.headers.get(\"retry-after\");\n\t\tlet delayMs = 500 * 2 ** retry;\n\t\tif (retryAfter) {\n\t\t\tconst seconds = Number.parseFloat(retryAfter);\n\t\t\tdelayMs = Number.isNaN(seconds) ? Date.parse(retryAfter) - Date.now() : seconds * 1000;\n\t\t\tif (!Number.isFinite(delayMs)) return response;\n\t\t}\n\t\tdelayMs = Math.max(0, delayMs);\n\t\tif (retryDeadline !== undefined && delayMs >= retryDeadline - Date.now()) return response;\n\t\tawait response.body?.cancel();\n\t\tawait sleep(delayMs, requestSignal);\n\t}\n}\n\nasync function fetchGitHubCopilotModels(\n\tcopilotToken: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n\tretryPolicy: { maxRetries: number; maxElapsedMs: number },\n) {\n\tconst baseUrl = getGitHubCopilotBaseUrl(copilotToken, enterpriseDomain);\n\t// Some Individual accounts return false for every picker flag despite explicit enabled policies.\n\t// Limit the fallback to that endpoint so other account types keep strict picker semantics.\n\tconst allowPolicyFallback = baseUrl === \"https://api.individual.githubcopilot.com\";\n\tconst response = await fetchWithRateLimitRetry(\n\t\t`${baseUrl}/models`,\n\t\t{\n\t\t\theaders: {\n\t\t\t\tAccept: \"application/json\",\n\t\t\t\tAuthorization: `Bearer ${copilotToken}`,\n\t\t\t\t...COPILOT_HEADERS,\n\t\t\t\t\"X-GitHub-Api-Version\": COPILOT_API_VERSION,\n\t\t\t},\n\t\t},\n\t\tsignal,\n\t\tretryPolicy,\n\t);\n\tif (!response.ok) {\n\t\tthrow new Error(`${response.status} ${response.statusText}: ${await response.text()}`);\n\t}\n\treturn parseGitHubCopilotModelCatalog(await response.json(), allowPolicyFallback);\n}\n\nasync function fetchJson(url: string, init: RequestInit): Promise<unknown> {\n\tconst response = await fetch(url, init);\n\tif (!response.ok) {\n\t\tconst text = await response.text();\n\t\tthrow new Error(`${response.status} ${response.statusText}: ${text}`);\n\t}\n\treturn response.json();\n}\n\nasync function startDeviceFlow(domain: string, signal: AbortSignal): Promise<DeviceCodeResponse> {\n\tconst urls = getUrls(domain);\n\tconst data = await fetchJson(urls.deviceCodeUrl, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\tAccept: \"application/json\",\n\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\t},\n\t\tbody: new URLSearchParams({\n\t\t\tclient_id: CLIENT_ID,\n\t\t\tscope: \"read:user\",\n\t\t}),\n\t\tsignal,\n\t});\n\n\tif (!data || typeof data !== \"object\") {\n\t\tthrow new Error(\"Invalid device code response\");\n\t}\n\n\tconst deviceCode = (data as Record<string, unknown>).device_code;\n\tconst userCode = (data as Record<string, unknown>).user_code;\n\tconst verificationUri = (data as Record<string, unknown>).verification_uri;\n\tconst interval = (data as Record<string, unknown>).interval;\n\tconst expiresIn = (data as Record<string, unknown>).expires_in;\n\n\tif (\n\t\ttypeof deviceCode !== \"string\" ||\n\t\ttypeof userCode !== \"string\" ||\n\t\ttypeof verificationUri !== \"string\" ||\n\t\t(interval !== undefined && typeof interval !== \"number\") ||\n\t\ttypeof expiresIn !== \"number\"\n\t) {\n\t\tthrow new Error(\"Invalid device code response fields\");\n\t}\n\n\t// The verification URI is opened in the user's browser and to prevent `open` from\n\t// opening an executable or similar, we force it to be a URL.\n\tlet parsedUri: URL;\n\ttry {\n\t\tparsedUri = new URL(verificationUri);\n\t} catch {\n\t\tthrow new Error(\"Untrusted verification_uri in device code response\");\n\t}\n\tif (parsedUri.protocol !== \"https:\" && parsedUri.protocol !== \"http:\") {\n\t\tthrow new Error(\"Untrusted verification_uri in device code response\");\n\t}\n\n\treturn {\n\t\tdevice_code: deviceCode,\n\t\tuser_code: userCode,\n\t\tverification_uri: parsedUri.href,\n\t\tinterval,\n\t\texpires_in: expiresIn,\n\t};\n}\n\nasync function pollForGitHubAccessToken(\n\tdomain: string,\n\tdevice: DeviceCodeResponse,\n\tsignal: AbortSignal,\n): Promise<string> {\n\tconst urls = getUrls(domain);\n\treturn pollOAuthDeviceCodeFlow<string>({\n\t\tintervalSeconds: device.interval,\n\t\texpiresInSeconds: device.expires_in,\n\t\twaitBeforeFirstPoll: true,\n\t\tsignal,\n\t\tpoll: async () => {\n\t\t\tconst raw = await fetchJson(urls.accessTokenUrl, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\tAccept: \"application/json\",\n\t\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\t\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\t\t\t},\n\t\t\t\tbody: new URLSearchParams({\n\t\t\t\t\tclient_id: CLIENT_ID,\n\t\t\t\t\tdevice_code: device.device_code,\n\t\t\t\t\tgrant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n\t\t\t\t}),\n\t\t\t\tsignal,\n\t\t\t});\n\n\t\t\tif (raw && typeof raw === \"object\" && typeof (raw as DeviceTokenSuccessResponse).access_token === \"string\") {\n\t\t\t\treturn { status: \"complete\", value: (raw as DeviceTokenSuccessResponse).access_token };\n\t\t\t}\n\n\t\t\tif (raw && typeof raw === \"object\" && typeof (raw as DeviceTokenErrorResponse).error === \"string\") {\n\t\t\t\tconst { error, error_description: description, interval } = raw as DeviceTokenErrorResponse;\n\t\t\t\tif (error === \"authorization_pending\") {\n\t\t\t\t\treturn { status: \"pending\" };\n\t\t\t\t}\n\n\t\t\t\tif (error === \"slow_down\") {\n\t\t\t\t\treturn { status: \"slow_down\", intervalSeconds: typeof interval === \"number\" ? interval : undefined };\n\t\t\t\t}\n\n\t\t\t\tconst descriptionSuffix = description ? `: ${description}` : \"\";\n\t\t\t\treturn { status: \"failed\", message: `Device flow failed: ${error}${descriptionSuffix}` };\n\t\t\t}\n\n\t\t\treturn { status: \"failed\", message: \"Invalid device token response\" };\n\t\t},\n\t});\n}\n\nasync function refreshGitHubCopilotAccessToken(\n\trefreshToken: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<OAuthCredential> {\n\tconst domain = enterpriseDomain || \"github.com\";\n\tconst urls = getUrls(domain);\n\n\tconst raw = await fetchJson(urls.copilotTokenUrl, {\n\t\theaders: {\n\t\t\tAccept: \"application/json\",\n\t\t\tAuthorization: `Bearer ${refreshToken}`,\n\t\t\t...COPILOT_HEADERS,\n\t\t},\n\t\tsignal,\n\t});\n\n\tif (!raw || typeof raw !== \"object\") {\n\t\tthrow new Error(\"Invalid Copilot token response\");\n\t}\n\n\tconst token = (raw as Record<string, unknown>).token;\n\tconst expiresAt = (raw as Record<string, unknown>).expires_at;\n\n\tif (typeof token !== \"string\" || typeof expiresAt !== \"number\") {\n\t\tthrow new Error(\"Invalid Copilot token response fields\");\n\t}\n\n\treturn {\n\t\ttype: \"oauth\",\n\t\trefresh: refreshToken,\n\t\taccess: token,\n\t\texpires: expiresAt * 1000 - 5 * 60 * 1000,\n\t\tenterpriseUrl: enterpriseDomain,\n\t};\n}\n\n/**\n * Refresh GitHub Copilot token\n */\nasync function refreshGitHubCopilotToken(\n\trefreshToken: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<OAuthCredential> {\n\tconst credentials = await refreshGitHubCopilotAccessToken(refreshToken, enterpriseDomain, signal);\n\tconst { availableModelIds } = await fetchGitHubCopilotModels(credentials.access, enterpriseDomain, signal, {\n\t\tmaxRetries: 0,\n\t\tmaxElapsedMs: 0,\n\t});\n\treturn {\n\t\t...credentials,\n\t\tavailableModelIds,\n\t};\n}\n\n/**\n * Enable a model for the user's GitHub Copilot account.\n * This is required for some models (like Claude, Grok) before they can be used.\n */\nasync function enableGitHubCopilotModel(\n\ttoken: string,\n\tmodelId: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<boolean> {\n\tconst baseUrl = getGitHubCopilotBaseUrl(token, enterpriseDomain);\n\tconst url = `${baseUrl}/models/${modelId}/policy`;\n\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetchWithRateLimitRetry(\n\t\t\turl,\n\t\t\t{\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\t\t...COPILOT_HEADERS,\n\t\t\t\t\t\"openai-intent\": \"chat-policy\",\n\t\t\t\t\t\"x-interaction-type\": \"chat-policy\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({ state: \"enabled\" }),\n\t\t\t},\n\t\t\tsignal,\n\t\t\t{ maxRetries: 2, maxElapsedMs: 5000 },\n\t\t);\n\t} catch (error) {\n\t\tif (signal.aborted) throw error;\n\t\treturn false;\n\t}\n\tif (response.status === 429) {\n\t\tthrow new Error(`${response.status} ${response.statusText}: ${await response.text()}`);\n\t}\n\treturn response.ok;\n}\n\n/**\n * Enable the requested GitHub Copilot models and return the successful IDs.\n * Policy updates are best effort; exhausted rate limiting stops the batch.\n */\nasync function enableGitHubCopilotModels(\n\ttoken: string,\n\tmodelIds: readonly string[],\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<string[]> {\n\tconst enabledModelIds: string[] = [];\n\tfor (const modelId of modelIds) {\n\t\ttry {\n\t\t\tif (await enableGitHubCopilotModel(token, modelId, enterpriseDomain, signal)) {\n\t\t\t\tenabledModelIds.push(modelId);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (signal.aborted) throw error;\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn enabledModelIds;\n}\n\nasync function loginGitHubCopilot(interaction: ProviderAuthInteraction): Promise<OAuthCredential> {\n\tconst input = await interaction.prompt({\n\t\ttype: \"text\",\n\t\tmessage: \"GitHub Enterprise URL/domain (blank for github.com)\",\n\t\tplaceholder: \"company.ghe.com\",\n\t});\n\tif (interaction.signal.aborted) throw new Error(\"Login cancelled\");\n\n\tconst trimmed = input.trim();\n\tconst enterpriseDomain = normalizeDomain(input);\n\tif (trimmed && !enterpriseDomain) throw new Error(\"Invalid GitHub Enterprise URL/domain\");\n\tconst domain = enterpriseDomain || \"github.com\";\n\n\tconst device = await startDeviceFlow(domain, interaction.signal);\n\tinteraction.notify({\n\t\ttype: \"device_code\",\n\t\tuserCode: device.user_code,\n\t\tverificationUri: device.verification_uri,\n\t\tintervalSeconds: device.interval,\n\t\texpiresInSeconds: device.expires_in,\n\t});\n\n\tconst githubAccessToken = await pollForGitHubAccessToken(domain, device, interaction.signal);\n\tconst credentials = await refreshGitHubCopilotAccessToken(\n\t\tgithubAccessToken,\n\t\tenterpriseDomain ?? undefined,\n\t\tinteraction.signal,\n\t);\n\tconst models = await fetchGitHubCopilotModels(\n\t\tcredentials.access,\n\t\tenterpriseDomain ?? undefined,\n\t\tinteraction.signal,\n\t\t{\n\t\t\tmaxRetries: 2,\n\t\t\tmaxElapsedMs: 5000,\n\t\t},\n\t);\n\tlet enabledModelIds: string[] = [];\n\tif (models.policyModelIds.length > 0) {\n\t\tinteraction.notify({ type: \"progress\", message: \"Enabling models...\" });\n\t\tenabledModelIds = await enableGitHubCopilotModels(\n\t\t\tcredentials.access,\n\t\t\tmodels.policyModelIds,\n\t\t\tenterpriseDomain ?? undefined,\n\t\t\tinteraction.signal,\n\t\t);\n\t}\n\treturn {\n\t\t...credentials,\n\t\tavailableModelIds: [...new Set([...models.availableModelIds, ...enabledModelIds])],\n\t};\n}\n\nfunction copilotEnterpriseDomain(credential: OAuthCredential): string | undefined {\n\tconst enterpriseUrl = credential.enterpriseUrl;\n\tif (typeof enterpriseUrl !== \"string\" || !enterpriseUrl) return undefined;\n\treturn normalizeDomain(enterpriseUrl) ?? undefined;\n}\n\nexport const githubCopilotOAuth: OAuthAuth = {\n\tname: \"GitHub Copilot\",\n\tisSubscription: true,\n\tlogin: loginGitHubCopilot,\n\trefresh: (credential, signal) =>\n\t\trefreshGitHubCopilotToken(credential.refresh, copilotEnterpriseDomain(credential), signal),\n\n\t/** Derive the credential-specific proxy endpoint for each request. */\n\tasync toAuth(credential) {\n\t\treturn {\n\t\t\tapiKey: credential.access,\n\t\t\tbaseUrl: getGitHubCopilotBaseUrl(credential.access, copilotEnterpriseDomain(credential)),\n\t\t};\n\t},\n};\n"]}
1
+ {"version":3,"file":"github-copilot.js","sourceRoot":"","sources":["../../../src/auth/oauth/github-copilot.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * GitHub Copilot OAuth flow\n */\n\nimport { GITHUB_COPILOT_MODELS } from \"../../providers/github-copilot.models.ts\";\nimport { sleep } from \"../../utils/sleep.ts\";\nimport type { OAuthAuth, OAuthCredential, ProviderAuthInteraction } from \"../types.ts\";\nimport { pollOAuthDeviceCodeFlow } from \"./device-code.ts\";\n\nconst decode = (s: string) => atob(s);\nconst CLIENT_ID = decode(\"SXYxLmI1MDdhMDhjODdlY2ZlOTg=\");\n\nconst COPILOT_HEADERS = {\n\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\"Editor-Version\": \"vscode/1.107.0\",\n\t\"Editor-Plugin-Version\": \"copilot-chat/0.35.0\",\n\t\"Copilot-Integration-Id\": \"vscode-chat\",\n} as const;\nconst COPILOT_API_VERSION = \"2026-06-01\";\n\ntype DeviceCodeResponse = {\n\tdevice_code: string;\n\tuser_code: string;\n\tverification_uri: string;\n\tinterval?: number;\n\texpires_in: number;\n};\n\ntype DeviceTokenSuccessResponse = {\n\taccess_token: string;\n\ttoken_type?: string;\n\tscope?: string;\n};\n\ntype DeviceTokenErrorResponse = {\n\terror: string;\n\terror_description?: string;\n\tinterval?: number;\n};\n\nfunction normalizeDomain(input: string): string | null {\n\tconst trimmed = input.trim();\n\tif (!trimmed) return null;\n\ttry {\n\t\tconst url = trimmed.includes(\"://\") ? new URL(trimmed) : new URL(`https://${trimmed}`);\n\t\treturn url.hostname;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction getUrls(domain: string): {\n\tdeviceCodeUrl: string;\n\taccessTokenUrl: string;\n\tcopilotTokenUrl: string;\n} {\n\treturn {\n\t\tdeviceCodeUrl: `https://${domain}/login/device/code`,\n\t\taccessTokenUrl: `https://${domain}/login/oauth/access_token`,\n\t\tcopilotTokenUrl: `https://api.${domain}/copilot_internal/v2/token`,\n\t};\n}\n\n/**\n * Parse the proxy-ep from a Copilot token and convert to API base URL.\n * Token format: tid=...;exp=...;proxy-ep=proxy.individual.githubcopilot.com;...\n * Returns API URL like https://api.individual.githubcopilot.com\n */\nfunction getBaseUrlFromToken(token: string): string | null {\n\tconst match = token.match(/proxy-ep=([^;]+)/);\n\tif (!match) return null;\n\tconst proxyHost = match[1];\n\t// Convert proxy.xxx to api.xxx\n\tconst apiHost = proxyHost.replace(/^proxy\\./, \"api.\");\n\treturn `https://${apiHost}`;\n}\n\nfunction getGitHubCopilotBaseUrl(token?: string, enterpriseDomain?: string): string {\n\t// If we have a token, extract the base URL from proxy-ep\n\tif (token) {\n\t\tconst urlFromToken = getBaseUrlFromToken(token);\n\t\tif (urlFromToken) return urlFromToken;\n\t}\n\t// Fallback for enterprise or if token parsing fails\n\tif (enterpriseDomain) return `https://copilot-api.${enterpriseDomain}`;\n\treturn \"https://api.individual.githubcopilot.com\";\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n\treturn value && typeof value === \"object\" ? (value as Record<string, unknown>) : undefined;\n}\n\nfunction parseGitHubCopilotModelCatalog(raw: unknown, allowPolicyFallback: boolean) {\n\tconst data = asRecord(raw)?.data;\n\tif (!Array.isArray(data)) {\n\t\tthrow new Error(\"Invalid Copilot models response\");\n\t}\n\n\tconst accountModels = data.flatMap((rawItem) => {\n\t\tconst item = asRecord(rawItem);\n\t\tconst id = item?.id;\n\t\tif (!item || typeof id !== \"string\") return [];\n\n\t\tconst capabilities = asRecord(item.capabilities);\n\t\tconst supports = asRecord(capabilities?.supports);\n\t\tif (supports?.tool_calls === false) return [];\n\n\t\treturn [\n\t\t\t{\n\t\t\t\tid,\n\t\t\t\tpickerEnabled: item.model_picker_enabled === true,\n\t\t\t\tpolicyState: asRecord(item.policy)?.state,\n\t\t\t},\n\t\t];\n\t});\n\tconst pickerModelIds = accountModels\n\t\t.filter((model) => model.pickerEnabled && model.policyState !== \"disabled\")\n\t\t.map((model) => model.id);\n\tconst usePolicyFallback = allowPolicyFallback && pickerModelIds.length === 0;\n\tconst availableModelIds =\n\t\tpickerModelIds.length > 0 || !allowPolicyFallback\n\t\t\t? pickerModelIds\n\t\t\t: accountModels\n\t\t\t\t\t.filter((model) => !model.id.endsWith(\"-fast\") && model.policyState === \"enabled\")\n\t\t\t\t\t.map((model) => model.id);\n\tconst fastModelIds = accountModels\n\t\t.filter((model) => model.id.endsWith(\"-fast\") && model.policyState !== \"disabled\")\n\t\t.map((model) => model.id);\n\tconst policyModelIds = accountModels\n\t\t.filter(\n\t\t\t(model) =>\n\t\t\t\tmodel.policyState === \"unconfigured\" &&\n\t\t\t\tObject.hasOwn(GITHUB_COPILOT_MODELS, model.id) &&\n\t\t\t\t(model.pickerEnabled || usePolicyFallback),\n\t\t)\n\t\t.map((model) => model.id);\n\treturn { availableModelIds, fastModelIds, policyModelIds };\n}\n\nasync function fetchWithRateLimitRetry(\n\turl: string,\n\tinit: RequestInit,\n\tsignal: AbortSignal,\n\tretryPolicy: { maxRetries: number; maxElapsedMs: number },\n): Promise<Response> {\n\tconst retryBudgetSignal =\n\t\tretryPolicy.maxRetries > 0 && retryPolicy.maxElapsedMs > 0\n\t\t\t? AbortSignal.timeout(retryPolicy.maxElapsedMs)\n\t\t\t: undefined;\n\tconst requestSignal = retryBudgetSignal ? AbortSignal.any([signal, retryBudgetSignal]) : signal;\n\tconst retryDeadline = retryBudgetSignal ? Date.now() + retryPolicy.maxElapsedMs : undefined;\n\tfor (let retry = 0; ; retry++) {\n\t\tconst response = await fetch(url, {\n\t\t\t...init,\n\t\t\tsignal: AbortSignal.any([requestSignal, AbortSignal.timeout(5000)]),\n\t\t});\n\t\tif (response.status !== 429 || retry === retryPolicy.maxRetries) return response;\n\n\t\tconst retryAfter = response.headers.get(\"retry-after\");\n\t\tlet delayMs = 500 * 2 ** retry;\n\t\tif (retryAfter) {\n\t\t\tconst seconds = Number.parseFloat(retryAfter);\n\t\t\tdelayMs = Number.isNaN(seconds) ? Date.parse(retryAfter) - Date.now() : seconds * 1000;\n\t\t\tif (!Number.isFinite(delayMs)) return response;\n\t\t}\n\t\tdelayMs = Math.max(0, delayMs);\n\t\tif (retryDeadline !== undefined && delayMs >= retryDeadline - Date.now()) return response;\n\t\tawait response.body?.cancel();\n\t\tawait sleep(delayMs, requestSignal);\n\t}\n}\n\nasync function fetchGitHubCopilotModels(\n\tcopilotToken: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n\tretryPolicy: { maxRetries: number; maxElapsedMs: number },\n) {\n\tconst baseUrl = getGitHubCopilotBaseUrl(copilotToken, enterpriseDomain);\n\t// Some Individual accounts return false for every picker flag despite explicit enabled policies.\n\t// Limit the fallback to that endpoint so other account types keep strict picker semantics.\n\tconst allowPolicyFallback = baseUrl === \"https://api.individual.githubcopilot.com\";\n\tconst response = await fetchWithRateLimitRetry(\n\t\t`${baseUrl}/models`,\n\t\t{\n\t\t\theaders: {\n\t\t\t\tAccept: \"application/json\",\n\t\t\t\tAuthorization: `Bearer ${copilotToken}`,\n\t\t\t\t...COPILOT_HEADERS,\n\t\t\t\t\"X-GitHub-Api-Version\": COPILOT_API_VERSION,\n\t\t\t},\n\t\t},\n\t\tsignal,\n\t\tretryPolicy,\n\t);\n\tif (!response.ok) {\n\t\tthrow new Error(`${response.status} ${response.statusText}: ${await response.text()}`);\n\t}\n\treturn parseGitHubCopilotModelCatalog(await response.json(), allowPolicyFallback);\n}\n\nasync function fetchJson(url: string, init: RequestInit): Promise<unknown> {\n\tconst response = await fetch(url, init);\n\tif (!response.ok) {\n\t\tconst text = await response.text();\n\t\tthrow new Error(`${response.status} ${response.statusText}: ${text}`);\n\t}\n\treturn response.json();\n}\n\nasync function startDeviceFlow(domain: string, signal: AbortSignal): Promise<DeviceCodeResponse> {\n\tconst urls = getUrls(domain);\n\tconst data = await fetchJson(urls.deviceCodeUrl, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\tAccept: \"application/json\",\n\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\t},\n\t\tbody: new URLSearchParams({\n\t\t\tclient_id: CLIENT_ID,\n\t\t\tscope: \"read:user\",\n\t\t}),\n\t\tsignal,\n\t});\n\n\tif (!data || typeof data !== \"object\") {\n\t\tthrow new Error(\"Invalid device code response\");\n\t}\n\n\tconst deviceCode = (data as Record<string, unknown>).device_code;\n\tconst userCode = (data as Record<string, unknown>).user_code;\n\tconst verificationUri = (data as Record<string, unknown>).verification_uri;\n\tconst interval = (data as Record<string, unknown>).interval;\n\tconst expiresIn = (data as Record<string, unknown>).expires_in;\n\n\tif (\n\t\ttypeof deviceCode !== \"string\" ||\n\t\ttypeof userCode !== \"string\" ||\n\t\ttypeof verificationUri !== \"string\" ||\n\t\t(interval !== undefined && typeof interval !== \"number\") ||\n\t\ttypeof expiresIn !== \"number\"\n\t) {\n\t\tthrow new Error(\"Invalid device code response fields\");\n\t}\n\n\t// The verification URI is opened in the user's browser and to prevent `open` from\n\t// opening an executable or similar, we force it to be a URL.\n\tlet parsedUri: URL;\n\ttry {\n\t\tparsedUri = new URL(verificationUri);\n\t} catch {\n\t\tthrow new Error(\"Untrusted verification_uri in device code response\");\n\t}\n\tif (parsedUri.protocol !== \"https:\" && parsedUri.protocol !== \"http:\") {\n\t\tthrow new Error(\"Untrusted verification_uri in device code response\");\n\t}\n\n\treturn {\n\t\tdevice_code: deviceCode,\n\t\tuser_code: userCode,\n\t\tverification_uri: parsedUri.href,\n\t\tinterval,\n\t\texpires_in: expiresIn,\n\t};\n}\n\nasync function pollForGitHubAccessToken(\n\tdomain: string,\n\tdevice: DeviceCodeResponse,\n\tsignal: AbortSignal,\n): Promise<string> {\n\tconst urls = getUrls(domain);\n\treturn pollOAuthDeviceCodeFlow<string>({\n\t\tintervalSeconds: device.interval,\n\t\texpiresInSeconds: device.expires_in,\n\t\twaitBeforeFirstPoll: true,\n\t\tsignal,\n\t\tpoll: async () => {\n\t\t\tconst raw = await fetchJson(urls.accessTokenUrl, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\tAccept: \"application/json\",\n\t\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\t\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\t\t\t},\n\t\t\t\tbody: new URLSearchParams({\n\t\t\t\t\tclient_id: CLIENT_ID,\n\t\t\t\t\tdevice_code: device.device_code,\n\t\t\t\t\tgrant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n\t\t\t\t}),\n\t\t\t\tsignal,\n\t\t\t});\n\n\t\t\tif (raw && typeof raw === \"object\" && typeof (raw as DeviceTokenSuccessResponse).access_token === \"string\") {\n\t\t\t\treturn { status: \"complete\", value: (raw as DeviceTokenSuccessResponse).access_token };\n\t\t\t}\n\n\t\t\tif (raw && typeof raw === \"object\" && typeof (raw as DeviceTokenErrorResponse).error === \"string\") {\n\t\t\t\tconst { error, error_description: description, interval } = raw as DeviceTokenErrorResponse;\n\t\t\t\tif (error === \"authorization_pending\") {\n\t\t\t\t\treturn { status: \"pending\" };\n\t\t\t\t}\n\n\t\t\t\tif (error === \"slow_down\") {\n\t\t\t\t\treturn { status: \"slow_down\", intervalSeconds: typeof interval === \"number\" ? interval : undefined };\n\t\t\t\t}\n\n\t\t\t\tconst descriptionSuffix = description ? `: ${description}` : \"\";\n\t\t\t\treturn { status: \"failed\", message: `Device flow failed: ${error}${descriptionSuffix}` };\n\t\t\t}\n\n\t\t\treturn { status: \"failed\", message: \"Invalid device token response\" };\n\t\t},\n\t});\n}\n\nasync function refreshGitHubCopilotAccessToken(\n\trefreshToken: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<OAuthCredential> {\n\tconst domain = enterpriseDomain || \"github.com\";\n\tconst urls = getUrls(domain);\n\n\tconst raw = await fetchJson(urls.copilotTokenUrl, {\n\t\theaders: {\n\t\t\tAccept: \"application/json\",\n\t\t\tAuthorization: `Bearer ${refreshToken}`,\n\t\t\t...COPILOT_HEADERS,\n\t\t},\n\t\tsignal,\n\t});\n\n\tif (!raw || typeof raw !== \"object\") {\n\t\tthrow new Error(\"Invalid Copilot token response\");\n\t}\n\n\tconst token = (raw as Record<string, unknown>).token;\n\tconst expiresAt = (raw as Record<string, unknown>).expires_at;\n\n\tif (typeof token !== \"string\" || typeof expiresAt !== \"number\") {\n\t\tthrow new Error(\"Invalid Copilot token response fields\");\n\t}\n\n\treturn {\n\t\ttype: \"oauth\",\n\t\trefresh: refreshToken,\n\t\taccess: token,\n\t\texpires: expiresAt * 1000 - 5 * 60 * 1000,\n\t\tenterpriseUrl: enterpriseDomain,\n\t};\n}\n\n/**\n * Refresh GitHub Copilot token\n */\nasync function refreshGitHubCopilotToken(\n\trefreshToken: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<OAuthCredential> {\n\tconst credentials = await refreshGitHubCopilotAccessToken(refreshToken, enterpriseDomain, signal);\n\tconst { availableModelIds, fastModelIds } = await fetchGitHubCopilotModels(\n\t\tcredentials.access,\n\t\tenterpriseDomain,\n\t\tsignal,\n\t\t{\n\t\t\tmaxRetries: 0,\n\t\t\tmaxElapsedMs: 0,\n\t\t},\n\t);\n\treturn {\n\t\t...credentials,\n\t\tavailableModelIds,\n\t\tfastModelIds,\n\t};\n}\n\n/**\n * Enable a model for the user's GitHub Copilot account.\n * This is required for some models (like Claude, Grok) before they can be used.\n */\nasync function enableGitHubCopilotModel(\n\ttoken: string,\n\tmodelId: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<boolean> {\n\tconst baseUrl = getGitHubCopilotBaseUrl(token, enterpriseDomain);\n\tconst url = `${baseUrl}/models/${modelId}/policy`;\n\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetchWithRateLimitRetry(\n\t\t\turl,\n\t\t\t{\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\t\t...COPILOT_HEADERS,\n\t\t\t\t\t\"openai-intent\": \"chat-policy\",\n\t\t\t\t\t\"x-interaction-type\": \"chat-policy\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({ state: \"enabled\" }),\n\t\t\t},\n\t\t\tsignal,\n\t\t\t{ maxRetries: 2, maxElapsedMs: 5000 },\n\t\t);\n\t} catch (error) {\n\t\tif (signal.aborted) throw error;\n\t\treturn false;\n\t}\n\tif (response.status === 429) {\n\t\tthrow new Error(`${response.status} ${response.statusText}: ${await response.text()}`);\n\t}\n\treturn response.ok;\n}\n\n/**\n * Enable the requested GitHub Copilot models and return the successful IDs.\n * Policy updates are best effort; exhausted rate limiting stops the batch.\n */\nasync function enableGitHubCopilotModels(\n\ttoken: string,\n\tmodelIds: readonly string[],\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<string[]> {\n\tconst enabledModelIds: string[] = [];\n\tfor (const modelId of modelIds) {\n\t\ttry {\n\t\t\tif (await enableGitHubCopilotModel(token, modelId, enterpriseDomain, signal)) {\n\t\t\t\tenabledModelIds.push(modelId);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (signal.aborted) throw error;\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn enabledModelIds;\n}\n\nasync function loginGitHubCopilot(interaction: ProviderAuthInteraction): Promise<OAuthCredential> {\n\tconst input = await interaction.prompt({\n\t\ttype: \"text\",\n\t\tmessage: \"GitHub Enterprise URL/domain (blank for github.com)\",\n\t\tplaceholder: \"company.ghe.com\",\n\t});\n\tif (interaction.signal.aborted) throw new Error(\"Login cancelled\");\n\n\tconst trimmed = input.trim();\n\tconst enterpriseDomain = normalizeDomain(input);\n\tif (trimmed && !enterpriseDomain) throw new Error(\"Invalid GitHub Enterprise URL/domain\");\n\tconst domain = enterpriseDomain || \"github.com\";\n\n\tconst device = await startDeviceFlow(domain, interaction.signal);\n\tinteraction.notify({\n\t\ttype: \"device_code\",\n\t\tuserCode: device.user_code,\n\t\tverificationUri: device.verification_uri,\n\t\tintervalSeconds: device.interval,\n\t\texpiresInSeconds: device.expires_in,\n\t});\n\n\tconst githubAccessToken = await pollForGitHubAccessToken(domain, device, interaction.signal);\n\tconst credentials = await refreshGitHubCopilotAccessToken(\n\t\tgithubAccessToken,\n\t\tenterpriseDomain ?? undefined,\n\t\tinteraction.signal,\n\t);\n\tconst models = await fetchGitHubCopilotModels(\n\t\tcredentials.access,\n\t\tenterpriseDomain ?? undefined,\n\t\tinteraction.signal,\n\t\t{\n\t\t\tmaxRetries: 2,\n\t\t\tmaxElapsedMs: 5000,\n\t\t},\n\t);\n\tlet enabledModelIds: string[] = [];\n\tif (models.policyModelIds.length > 0) {\n\t\tinteraction.notify({ type: \"progress\", message: \"Enabling models...\" });\n\t\tenabledModelIds = await enableGitHubCopilotModels(\n\t\t\tcredentials.access,\n\t\t\tmodels.policyModelIds,\n\t\t\tenterpriseDomain ?? undefined,\n\t\t\tinteraction.signal,\n\t\t);\n\t}\n\treturn {\n\t\t...credentials,\n\t\tavailableModelIds: [...new Set([...models.availableModelIds, ...enabledModelIds])],\n\t\tfastModelIds: models.fastModelIds,\n\t};\n}\n\nfunction copilotEnterpriseDomain(credential: OAuthCredential): string | undefined {\n\tconst enterpriseUrl = credential.enterpriseUrl;\n\tif (typeof enterpriseUrl !== \"string\" || !enterpriseUrl) return undefined;\n\treturn normalizeDomain(enterpriseUrl) ?? undefined;\n}\n\nexport const githubCopilotOAuth: OAuthAuth = {\n\tname: \"GitHub Copilot\",\n\tisSubscription: true,\n\tlogin: loginGitHubCopilot,\n\trefresh: (credential, signal) =>\n\t\trefreshGitHubCopilotToken(credential.refresh, copilotEnterpriseDomain(credential), signal),\n\n\t/** Derive the credential-specific proxy endpoint for each request. */\n\tasync toAuth(credential) {\n\t\treturn {\n\t\t\tapiKey: credential.access,\n\t\t\tbaseUrl: getGitHubCopilotBaseUrl(credential.access, copilotEnterpriseDomain(credential)),\n\t\t};\n\t},\n};\n"]}
@@ -1 +1 @@
1
- {"schemaVersion":3,"generatedAt":"2026-08-26T23:45:32.869Z","structureHash":"40a1c3b5d354aa74df73cc7063303dcfd7a82e2d8122ad311ddb3687585be737","files":{"amazon-bedrock.json":"681b69fb339cc8dce9f90d4ecfff4f9d5ee766d5aade5c9159f6de6df727eaab","ant-ling.json":"4979fe79d99ed97382d7ce40170c6132e932e77906de1eb54464c042e7d63633","anthropic.json":"4d44dd3f78d21dd1d0fba878bd58026914ba98dba3083212059b4710dc13eeb3","azure-openai-responses.json":"37d12c5cbfc29bfd9a802a0516f5d3209320bd4aa8ef9cd7c219af208244afa3","baseten.json":"950433e7fcf9357ae3423b27fc0d32568b6e0990bb35c6e961dcb9740a6bba1b","cerebras.json":"38272a7525d6680c71bb4bb3c4085e871768b400832e2013b0e7fd92f8fd4f05","cloudflare-ai-gateway.json":"1ddcb8d8e2923adbf5e897209dcda642856bc0da3d1fe110f854994ab92c383c","cloudflare-workers-ai.json":"ebdb4faeacc7d77e701fb02d068512c5e620792fa5204dc37d376f5f0c6fbf70","deepseek.json":"8cc5e02a8eb3f1ead25da01d6ebac7dbd9aa5134c561026de2076cc990eb3349","fireworks.json":"2c85d89cd04288b15ff8a23af5eba72779cae9221f4bcfed1720ce6d41629fcc","github-copilot.json":"d235f33b932953739618c54a365e65eebfacedd10b24ec130abf8d73769de12c","google-vertex.json":"fb7586fc955da7b7d7d11d641954f496fbbb42cf3e4cbba66d7116ea3b37d5ed","google.json":"b5572904165d37ab594eafc3ab7f29774e35747b5dd211144ec01532db9217c1","groq.json":"f1eb899453e70b5e4479fe6eb78869ee99121fa6d4a019a5a05ab42d2ada8992","huggingface.json":"e39ede613cf4585a053a8c9fd215ab5f963796d60782ad26b2df9300d0523ab4","kimi-coding.json":"5e28e32e5b16df506a3a1c620ed7870fa7e5e57d8ede4a2aa44dbb24ecf1ba2f","minimax-cn.json":"65d37e55a6d9585855f94b3fb7739308d107fe248ebd9e1001d1c5d4606ad2c4","minimax.json":"c7dc5765995ae77242916430929c7cc9a782589f7e483e13f7e01663190d028e","mistral.json":"e3a109306644bf2f2fa38fece50b2d3ce1dbe3b87b1f1b9e2d70cce7eb5c0ea1","moonshotai-cn.json":"1e6146ff3477883636448c0f44222f0a52b3c4562ef8f4eecf7e941cdd59d12e","moonshotai.json":"d8d5209873058ddccd37c1f026833e2ea3f9476c3dc9628b4a940d407acc0b2e","nvidia.json":"692d2a610e5ee1c5513c559a0eb49925cef079b0b061460768e94f7ff9659dcc","openai-codex.json":"2712c2924a4a75213dddc743c0e5f08d50a781fe807f16d5afb5fb65b41c64c7","openai.json":"2f32f5796138f03153a0314edf4c8ee27531d62f3477de0da46e51095f5e4782","opencode-go.json":"df4d0f5fdb7cc54cc6fbca058675aa3efabc431826674a74f7459f090687dd0c","opencode.json":"e22f5df999f0abe3a58709715e4f89d35b464a0391f073180004371a5d738f4a","openrouter.json":"21f5e1290defd51f99fd3479933bc2954eb0adda9d10cfaeaec1a4d7c5af1241","qwen-token-plan-cn.json":"700cb41cdee4c0ae2a5159eb3ab43f4cedc9d43e87c6fd1bcd410d71431f9856","qwen-token-plan-individual.json":"5649fd4075ada766ec65a7a162cd65f096a7ecc29960ace04b2e6a6a4a995a41","qwen-token-plan.json":"f85715f7f2023a162c47d1a84ba73747e2580d0a9aa33799b3232ce19527c1ab","together.json":"f7c9ba0441c1cbb8af41aaea3cfaa12559e1235a7335898e705d5918dc308c97","vercel-ai-gateway.json":"090f31f56b561e530f9a97aabdd77e0ca7bb60e91e2609bcb895256207a3169f","xai.json":"9668b607ac69237089e84efa3f0590dc1e28d8e24c9d1afa3a2b7cf72efa30e0","xiaomi-token-plan-ams.json":"a36446cb9e3cb4f7054617676fd711092245a74f703ba89573f21d2673b85fa8","xiaomi-token-plan-cn.json":"c295dadf4097b5d86af15e924fb2a1a6342bae9e0a9a5839c9fca216308c51e5","xiaomi-token-plan-sgp.json":"93d359575c2348c97d79a2b14e1e9437199bd4aee948d58611b3fbab75cd9fb3","xiaomi.json":"f06f1011d606d22311b1f4c50eb36d38b8cd99abf5760faee657d5559e87452b","zai-coding-cn.json":"d3c969020a7ab978497837a3301c7bca364d704082832221cfe61e6596333e56","zai.json":"f42790c77fb4681a656897a9d860b939916c0ddf979a5f16856bce9573cdf64e"}}
1
+ {"schemaVersion":3,"generatedAt":"2026-08-28T03:18:00.918Z","structureHash":"48420b6b34b0afb6fd771f6c599e7141f78233ac06305ec550a82ad672199437","files":{"amazon-bedrock.json":"681b69fb339cc8dce9f90d4ecfff4f9d5ee766d5aade5c9159f6de6df727eaab","ant-ling.json":"4979fe79d99ed97382d7ce40170c6132e932e77906de1eb54464c042e7d63633","anthropic.json":"4d44dd3f78d21dd1d0fba878bd58026914ba98dba3083212059b4710dc13eeb3","azure-openai-responses.json":"37d12c5cbfc29bfd9a802a0516f5d3209320bd4aa8ef9cd7c219af208244afa3","baseten.json":"13e74fc464f37293aef8c56a4aa908448598913abbdd9393527f02dad1418e62","cerebras.json":"38272a7525d6680c71bb4bb3c4085e871768b400832e2013b0e7fd92f8fd4f05","cloudflare-ai-gateway.json":"1ddcb8d8e2923adbf5e897209dcda642856bc0da3d1fe110f854994ab92c383c","cloudflare-workers-ai.json":"ebdb4faeacc7d77e701fb02d068512c5e620792fa5204dc37d376f5f0c6fbf70","deepseek.json":"8cc5e02a8eb3f1ead25da01d6ebac7dbd9aa5134c561026de2076cc990eb3349","fireworks.json":"f1d0e31cd57167e24be469fff31929ec18ec6eb6a761295832282b056264d9f2","github-copilot.json":"ed891c9e927e196e7d5a754231958b6df6e982bcdea635e916d69d7d5fe4ac68","google-vertex.json":"fb7586fc955da7b7d7d11d641954f496fbbb42cf3e4cbba66d7116ea3b37d5ed","google.json":"b5572904165d37ab594eafc3ab7f29774e35747b5dd211144ec01532db9217c1","groq.json":"f1eb899453e70b5e4479fe6eb78869ee99121fa6d4a019a5a05ab42d2ada8992","huggingface.json":"e39ede613cf4585a053a8c9fd215ab5f963796d60782ad26b2df9300d0523ab4","kimi-coding.json":"5e28e32e5b16df506a3a1c620ed7870fa7e5e57d8ede4a2aa44dbb24ecf1ba2f","minimax-cn.json":"65d37e55a6d9585855f94b3fb7739308d107fe248ebd9e1001d1c5d4606ad2c4","minimax.json":"c7dc5765995ae77242916430929c7cc9a782589f7e483e13f7e01663190d028e","mistral.json":"e3a109306644bf2f2fa38fece50b2d3ce1dbe3b87b1f1b9e2d70cce7eb5c0ea1","moonshotai-cn.json":"1e6146ff3477883636448c0f44222f0a52b3c4562ef8f4eecf7e941cdd59d12e","moonshotai.json":"d8d5209873058ddccd37c1f026833e2ea3f9476c3dc9628b4a940d407acc0b2e","nvidia.json":"8456358498bb363f23ee735992d9a7eb7344a81c251b772d702cb58b2494da94","openai-codex.json":"2712c2924a4a75213dddc743c0e5f08d50a781fe807f16d5afb5fb65b41c64c7","openai.json":"2f32f5796138f03153a0314edf4c8ee27531d62f3477de0da46e51095f5e4782","opencode-go.json":"df4d0f5fdb7cc54cc6fbca058675aa3efabc431826674a74f7459f090687dd0c","opencode.json":"e22f5df999f0abe3a58709715e4f89d35b464a0391f073180004371a5d738f4a","openrouter.json":"b32dbddd73e03582a1b87f82c8d253fa2afe06f726e4cda34ffa730042d6809f","qwen-token-plan-cn.json":"700cb41cdee4c0ae2a5159eb3ab43f4cedc9d43e87c6fd1bcd410d71431f9856","qwen-token-plan-individual.json":"5649fd4075ada766ec65a7a162cd65f096a7ecc29960ace04b2e6a6a4a995a41","qwen-token-plan.json":"f85715f7f2023a162c47d1a84ba73747e2580d0a9aa33799b3232ce19527c1ab","together.json":"c2b03c476d6b4d4059ed18a80f34d274c754dc84fe2591ae79fe2986512f2a51","vercel-ai-gateway.json":"86f68d0b00080f6b6d71ca2309e4388f34988e74bc533c22057b304b5d3b8630","xai.json":"9668b607ac69237089e84efa3f0590dc1e28d8e24c9d1afa3a2b7cf72efa30e0","xiaomi-token-plan-ams.json":"a36446cb9e3cb4f7054617676fd711092245a74f703ba89573f21d2673b85fa8","xiaomi-token-plan-cn.json":"c295dadf4097b5d86af15e924fb2a1a6342bae9e0a9a5839c9fca216308c51e5","xiaomi-token-plan-sgp.json":"93d359575c2348c97d79a2b14e1e9437199bd4aee948d58611b3fbab75cd9fb3","xiaomi.json":"f06f1011d606d22311b1f4c50eb36d38b8cd99abf5760faee657d5559e87452b","zai-coding-cn.json":"d3c969020a7ab978497837a3301c7bca364d704082832221cfe61e6596333e56","zai.json":"f42790c77fb4681a656897a9d860b939916c0ddf979a5f16856bce9573cdf64e"}}
@@ -1 +1 @@
1
- {"openai-completions":{"deepseek-ai/DeepSeek-V4-Flash-0731":{"id":"deepseek-ai/DeepSeek-V4-Flash-0731","name":"DeepSeek V4 Flash 0731","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":"minimal","low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"input":["text"],"cost":{"input":0.13,"output":0.26,"cacheRead":0.028,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"openai"},"contextWindow":1048576,"maxTokens":384000},"deepseek-ai/DeepSeek-V4-Pro":{"id":"deepseek-ai/DeepSeek-V4-Pro","name":"DeepSeek V4 Pro","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":"minimal","low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"input":["text"],"cost":{"input":1.74,"output":3.48,"cacheRead":0.145,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"openai"},"contextWindow":1048576,"maxTokens":262144},"deepseek-ai/DeepSeek-V4-Pro-0813":{"id":"deepseek-ai/DeepSeek-V4-Pro-0813","name":"DeepSeek V4 Pro 0813","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":"low","medium":null,"high":"high","xhigh":null,"max":"max"},"input":["text"],"cost":{"input":1.32,"output":3.96,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"openai"},"contextWindow":1048576,"maxTokens":262144},"moonshotai/Kimi-K2.5":{"id":"moonshotai/Kimi-K2.5","name":"Kimi K2.5","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"off","minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":null},"input":["text","image"],"cost":{"input":0.6,"output":3,"cacheRead":0.12,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"baseten","chatTemplateArgs":{"enable_thinking":{"$var":"thinking.enabled"}}},"contextWindow":262000,"maxTokens":262000},"moonshotai/Kimi-K2.6":{"id":"moonshotai/Kimi-K2.6","name":"Kimi K2.6","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"off","minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":null},"input":["text","image"],"cost":{"input":0.95,"output":4,"cacheRead":0.16,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"baseten","chatTemplateArgs":{"enable_thinking":{"$var":"thinking.enabled"}}},"contextWindow":262000,"maxTokens":262000},"moonshotai/Kimi-K2.7-Code":{"id":"moonshotai/Kimi-K2.7-Code","name":"Kimi K2.7 Code","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"off","minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":null},"input":["text","image"],"cost":{"input":0.95,"output":4,"cacheRead":0.16,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"baseten","chatTemplateArgs":{"enable_thinking":{"$var":"thinking.enabled"}}},"contextWindow":262000,"maxTokens":262000},"moonshotai/Kimi-K3":{"id":"moonshotai/Kimi-K3","name":"Kimi K3","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":"low","medium":null,"high":"high","xhigh":null,"max":"max"},"input":["text","image"],"cost":{"input":3,"output":15,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"openai"},"contextWindow":1048576,"maxTokens":262144},"nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B":{"id":"nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B","name":"Nemotron Ultra","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"off","minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":null},"input":["text"],"cost":{"input":0.6,"output":2.4,"cacheRead":0.12,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"baseten","chatTemplateArgs":{"enable_thinking":{"$var":"thinking.enabled"}}},"contextWindow":202800,"maxTokens":202800},"nvidia/Nemotron-120B-A12B":{"id":"nvidia/Nemotron-120B-A12B","name":"Nemotron Super","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"off","minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":null},"input":["text"],"cost":{"input":0.3,"output":0.75,"cacheRead":0.06,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"baseten","chatTemplateArgs":{"enable_thinking":{"$var":"thinking.enabled"}}},"contextWindow":202800,"maxTokens":202800},"openai/gpt-oss-120b":{"id":"openai/gpt-oss-120b","name":"OpenAI GPT 120B","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":"minimal","low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"input":["text"],"cost":{"input":0.1,"output":0.5,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"openai"},"contextWindow":128072,"maxTokens":128072},"thinkingmachines/inkling":{"id":"thinkingmachines/inkling","name":"Inkling","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":"minimal","low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"input":["text","image"],"cost":{"input":1,"output":4.05,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"openai"},"contextWindow":1048576,"maxTokens":32768},"thinkingmachines/inkling-small":{"id":"thinkingmachines/inkling-small","name":"Inkling Small","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":"minimal","low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"input":["text","image"],"cost":{"input":0.5,"output":1.2,"cacheRead":0.1,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"openai"},"contextWindow":1048576,"maxTokens":32768},"zai-org/GLM-4.7":{"id":"zai-org/GLM-4.7","name":"GLM 4.7","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"off","minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":null},"input":["text"],"cost":{"input":0.6,"output":2.2,"cacheRead":0.12,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"baseten","chatTemplateArgs":{"enable_thinking":{"$var":"thinking.enabled"}}},"contextWindow":200000,"maxTokens":200000},"zai-org/GLM-5":{"id":"zai-org/GLM-5","name":"GLM 5","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"off","minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":null},"input":["text"],"cost":{"input":0.95,"output":3.15,"cacheRead":0.2,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"baseten","chatTemplateArgs":{"enable_thinking":{"$var":"thinking.enabled"}}},"contextWindow":202800,"maxTokens":202800},"zai-org/GLM-5.1":{"id":"zai-org/GLM-5.1","name":"GLM 5.1","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"off","minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":null},"input":["text"],"cost":{"input":1.3,"output":4.3,"cacheRead":0.26,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"baseten","chatTemplateArgs":{"enable_thinking":{"$var":"thinking.enabled"}}},"contextWindow":202800,"maxTokens":202800},"zai-org/GLM-5.2":{"id":"zai-org/GLM-5.2","name":"GLM 5.2","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":"max"},"input":["text","image"],"cost":{"input":1.4,"output":4.4,"cacheRead":0.3,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"baseten","chatTemplateArgs":{"enable_thinking":{"$var":"thinking.enabled"}}},"contextWindow":1048576,"maxTokens":262144},"zai-org/GLM-5.2-Fast":{"id":"zai-org/GLM-5.2-Fast","name":"GLM 5.2 Fast","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":"max"},"input":["text","image"],"cost":{"input":2.1,"output":6.6,"cacheRead":0.21,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"baseten","chatTemplateArgs":{"enable_thinking":{"$var":"thinking.enabled"}}},"contextWindow":1048576,"maxTokens":262144}}}
1
+ {"openai-completions":{"deepseek-ai/DeepSeek-V4-Flash-0731":{"id":"deepseek-ai/DeepSeek-V4-Flash-0731","name":"DeepSeek V4 Flash 0731","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":"minimal","low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"input":["text"],"cost":{"input":0.13,"output":0.26,"cacheRead":0.028,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"openai"},"contextWindow":1048576,"maxTokens":384000},"deepseek-ai/DeepSeek-V4-Pro":{"id":"deepseek-ai/DeepSeek-V4-Pro","name":"DeepSeek V4 Pro","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":"minimal","low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"input":["text"],"cost":{"input":1.74,"output":3.48,"cacheRead":0.145,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"openai"},"contextWindow":1048576,"maxTokens":262144},"deepseek-ai/DeepSeek-V4-Pro-0813":{"id":"deepseek-ai/DeepSeek-V4-Pro-0813","name":"DeepSeek V4 Pro 0813","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":"low","medium":null,"high":"high","xhigh":null,"max":"max"},"input":["text"],"cost":{"input":1.32,"output":3.96,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"openai"},"contextWindow":1048576,"maxTokens":262144},"moonshotai/Kimi-K2.5":{"id":"moonshotai/Kimi-K2.5","name":"Kimi K2.5","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"off","minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":null},"input":["text","image"],"cost":{"input":0.6,"output":3,"cacheRead":0.12,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"baseten","chatTemplateArgs":{"enable_thinking":{"$var":"thinking.enabled"}}},"contextWindow":262000,"maxTokens":262000},"moonshotai/Kimi-K2.6":{"id":"moonshotai/Kimi-K2.6","name":"Kimi K2.6","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"off","minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":null},"input":["text","image"],"cost":{"input":0.95,"output":4,"cacheRead":0.16,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"baseten","chatTemplateArgs":{"enable_thinking":{"$var":"thinking.enabled"}}},"contextWindow":262000,"maxTokens":262000},"moonshotai/Kimi-K2.7-Code":{"id":"moonshotai/Kimi-K2.7-Code","name":"Kimi K2.7 Code","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"off","minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":null},"input":["text","image"],"cost":{"input":0.95,"output":4,"cacheRead":0.16,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"baseten","chatTemplateArgs":{"enable_thinking":{"$var":"thinking.enabled"}}},"contextWindow":262000,"maxTokens":262000},"moonshotai/Kimi-K3":{"id":"moonshotai/Kimi-K3","name":"Kimi K3","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":"low","medium":null,"high":"high","xhigh":null,"max":"max"},"input":["text","image"],"cost":{"input":3,"output":15,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"openai"},"contextWindow":1048576,"maxTokens":262144},"nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B":{"id":"nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B","name":"Nemotron Ultra","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"off","minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":null},"input":["text"],"cost":{"input":0.6,"output":2.4,"cacheRead":0.12,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"baseten","chatTemplateArgs":{"enable_thinking":{"$var":"thinking.enabled"}}},"contextWindow":202800,"maxTokens":202800},"nvidia/Nemotron-120B-A12B":{"id":"nvidia/Nemotron-120B-A12B","name":"Nemotron Super","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"off","minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":null},"input":["text"],"cost":{"input":0.3,"output":0.75,"cacheRead":0.06,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"baseten","chatTemplateArgs":{"enable_thinking":{"$var":"thinking.enabled"}}},"contextWindow":202800,"maxTokens":202800},"openai/gpt-oss-120b":{"id":"openai/gpt-oss-120b","name":"OpenAI GPT 120B","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":"minimal","low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"input":["text"],"cost":{"input":0.1,"output":0.5,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"openai"},"contextWindow":128072,"maxTokens":128072},"thinkingmachines/inkling":{"id":"thinkingmachines/inkling","name":"Inkling","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":"minimal","low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"input":["text","image"],"cost":{"input":1,"output":4.05,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"openai"},"contextWindow":1048576,"maxTokens":32768},"thinkingmachines/inkling-small":{"id":"thinkingmachines/inkling-small","name":"Inkling Small","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":"minimal","low":"low","medium":"medium","high":"high","xhigh":"xhigh","max":"max"},"input":["text","image"],"cost":{"input":0.5,"output":1.2,"cacheRead":0.1,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"openai"},"contextWindow":1048576,"maxTokens":32768},"zai-org/GLM-4.7":{"id":"zai-org/GLM-4.7","name":"GLM 4.7","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"off","minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":null},"input":["text"],"cost":{"input":0.6,"output":2.2,"cacheRead":0.12,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"baseten","chatTemplateArgs":{"enable_thinking":{"$var":"thinking.enabled"}}},"contextWindow":200000,"maxTokens":200000},"zai-org/GLM-5":{"id":"zai-org/GLM-5","name":"GLM 5","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"off","minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":null},"input":["text"],"cost":{"input":0.95,"output":3.15,"cacheRead":0.2,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"baseten","chatTemplateArgs":{"enable_thinking":{"$var":"thinking.enabled"}}},"contextWindow":202800,"maxTokens":202800},"zai-org/GLM-5.1":{"id":"zai-org/GLM-5.1","name":"GLM 5.1","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"off","minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":null},"input":["text"],"cost":{"input":1.3,"output":4.3,"cacheRead":0.26,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"baseten","chatTemplateArgs":{"enable_thinking":{"$var":"thinking.enabled"}}},"contextWindow":202800,"maxTokens":202800},"zai-org/GLM-5.2":{"id":"zai-org/GLM-5.2","name":"GLM 5.2","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":"max"},"input":["text","image"],"cost":{"input":1.4,"output":4.4,"cacheRead":0.3,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"baseten","chatTemplateArgs":{"enable_thinking":{"$var":"thinking.enabled"}}},"contextWindow":1048576,"maxTokens":262144},"zai-org/GLM-5.2-Fast":{"id":"zai-org/GLM-5.2-Fast","name":"GLM 5.2 Fast","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":null,"max":"max"},"input":["text","image"],"cost":{"input":2.1,"output":6.6,"cacheRead":0.21,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"baseten","chatTemplateArgs":{"enable_thinking":{"$var":"thinking.enabled"}}},"contextWindow":1048576,"maxTokens":262144},"zai-org/GLM-5.3-Flash":{"id":"zai-org/GLM-5.3-Flash","name":"GLM 5.3 Flash","api":"openai-completions","provider":"baseten","baseUrl":"https://inference.baseten.co/v1","reasoning":true,"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":null,"high":"high","xhigh":null,"max":"max"},"input":["text","image"],"cost":{"input":0.15,"output":0.5,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"supportsUsageInStreaming":true,"maxTokensField":"max_tokens","supportsStrictMode":true,"supportsLongCacheRetention":false,"thinkingFormat":"openai"},"contextWindow":1048576,"maxTokens":131072}}}
@@ -1 +1 @@
1
- {"anthropic-messages":{"accounts/fireworks/models/deepseek-v4-flash":{"id":"accounts/fireworks/models/deepseek-v4-flash","name":"DeepSeek V4 Flash","provider":"fireworks","reasoning":true,"input":["text"],"cost":{"input":0.14,"output":0.28,"cacheRead":0.028,"cacheWrite":0},"contextWindow":1000000,"maxTokens":384000,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/deepseek-v4-flash-0731":{"id":"accounts/fireworks/models/deepseek-v4-flash-0731","name":"DeepSeek V4 Flash 0731","provider":"fireworks","reasoning":true,"input":["text"],"cost":{"input":0.14,"output":0.28,"cacheRead":0.028,"cacheWrite":0},"contextWindow":1000000,"maxTokens":384000,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/deepseek-v4-pro":{"id":"accounts/fireworks/models/deepseek-v4-pro","name":"DeepSeek V4 Pro","provider":"fireworks","reasoning":true,"input":["text"],"cost":{"input":1.74,"output":3.48,"cacheRead":0.145,"cacheWrite":0},"contextWindow":1000000,"maxTokens":384000,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/deepseek-v4-pro-0813":{"id":"accounts/fireworks/models/deepseek-v4-pro-0813","name":"DeepSeek V4 Pro 0813","provider":"fireworks","reasoning":true,"input":["text"],"cost":{"input":1.32,"output":3.96,"cacheRead":0.044,"cacheWrite":0},"contextWindow":1000000,"maxTokens":384000,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/gpt-oss-120b":{"id":"accounts/fireworks/models/gpt-oss-120b","name":"GPT OSS 120B","provider":"fireworks","reasoning":true,"input":["text"],"cost":{"input":0.15,"output":0.6,"cacheRead":0.015,"cacheWrite":0},"contextWindow":131072,"maxTokens":32768,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/gpt-oss-20b":{"id":"accounts/fireworks/models/gpt-oss-20b","name":"GPT OSS 20B","provider":"fireworks","reasoning":true,"input":["text"],"cost":{"input":0.07,"output":0.3,"cacheRead":0.035,"cacheWrite":0},"contextWindow":131072,"maxTokens":32768,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/inkling":{"id":"accounts/fireworks/models/inkling","name":"Inkling","provider":"fireworks","reasoning":true,"input":["text","image"],"cost":{"input":1,"output":4.05,"cacheRead":0.17,"cacheWrite":0},"contextWindow":1048576,"maxTokens":1048576,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/kimi-k2p6":{"id":"accounts/fireworks/models/kimi-k2p6","name":"Kimi K2.6","provider":"fireworks","reasoning":true,"input":["text","image"],"cost":{"input":0.95,"output":4,"cacheRead":0.16,"cacheWrite":0},"contextWindow":262000,"maxTokens":262000,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/kimi-k2p7-code":{"id":"accounts/fireworks/models/kimi-k2p7-code","name":"Kimi K2.7 Code","provider":"fireworks","reasoning":true,"input":["text","image"],"cost":{"input":0.95,"output":4,"cacheRead":0.19,"cacheWrite":0},"contextWindow":262000,"maxTokens":262000,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/minimax-m2p7":{"id":"accounts/fireworks/models/minimax-m2p7","name":"MiniMax-M2.7","provider":"fireworks","reasoning":true,"input":["text"],"cost":{"input":0.3,"output":1.2,"cacheRead":0.06,"cacheWrite":0},"contextWindow":196608,"maxTokens":196608,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/minimax-m3":{"id":"accounts/fireworks/models/minimax-m3","name":"MiniMax-M3","provider":"fireworks","reasoning":true,"input":["text","image"],"cost":{"input":0.3,"output":1.2,"cacheRead":0.06,"cacheWrite":0},"contextWindow":512000,"maxTokens":512000,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/muse-glimmer-30b":{"id":"accounts/fireworks/models/muse-glimmer-30b","name":"Muse Glimmer 30B","provider":"fireworks","reasoning":true,"input":["text","image"],"cost":{"input":0.35,"output":1.5,"cacheRead":0.04,"cacheWrite":0},"contextWindow":131072,"maxTokens":131072,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/nemotron-3-ultra-nvfp4":{"id":"accounts/fireworks/models/nemotron-3-ultra-nvfp4","name":"Nemotron 3 Ultra 550B A55B","provider":"fireworks","reasoning":true,"input":["text"],"cost":{"input":0.6,"output":2.4,"cacheRead":0.119,"cacheWrite":0},"contextWindow":262144,"maxTokens":128000,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/nemotron-lightning-3p5-30b-a3b":{"id":"accounts/fireworks/models/nemotron-lightning-3p5-30b-a3b","name":"Nemotron 3.5 Lightning 30B A3B","provider":"fireworks","reasoning":true,"input":["text"],"cost":{"input":0.05,"output":0.2,"cacheRead":0.01,"cacheWrite":0},"contextWindow":262144,"maxTokens":262144,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/qwen3p7-plus":{"id":"accounts/fireworks/models/qwen3p7-plus","name":"Qwen 3.7 Plus","provider":"fireworks","reasoning":true,"input":["text","image"],"cost":{"input":0.4,"output":1.6,"cacheRead":0.08,"cacheWrite":0},"contextWindow":262144,"maxTokens":65536,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/qwen3p8-max":{"id":"accounts/fireworks/models/qwen3p8-max","name":"Qwen3.8 Max","provider":"fireworks","reasoning":true,"input":["text"],"cost":{"input":2,"output":6,"cacheRead":0.25,"cacheWrite":0},"contextWindow":262144,"maxTokens":131072,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/routers/kimi-k2p6-fast":{"id":"accounts/fireworks/routers/kimi-k2p6-fast","name":"Kimi K2.6 Fast","provider":"fireworks","reasoning":true,"input":["text","image"],"cost":{"input":2,"output":8,"cacheRead":0.3,"cacheWrite":0},"contextWindow":262000,"maxTokens":262000,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/routers/kimi-k2p6-turbo":{"id":"accounts/fireworks/routers/kimi-k2p6-turbo","name":"Kimi K2.6 Turbo","provider":"fireworks","reasoning":true,"input":["text","image"],"cost":{"input":2,"output":8,"cacheRead":0.3,"cacheWrite":0},"contextWindow":262000,"maxTokens":262000,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/routers/kimi-k2p7-code-fast":{"id":"accounts/fireworks/routers/kimi-k2p7-code-fast","name":"Kimi K2.7 Code Fast","provider":"fireworks","reasoning":true,"input":["text","image"],"cost":{"input":1.9,"output":8,"cacheRead":0.38,"cacheWrite":0},"contextWindow":262000,"maxTokens":262000,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}}},"openai-completions":{"accounts/fireworks/models/glm-5p2":{"id":"accounts/fireworks/models/glm-5p2","name":"GLM 5.2","provider":"fireworks","reasoning":true,"input":["text"],"cost":{"input":1.4,"output":4.4,"cacheRead":0.14,"cacheWrite":0},"contextWindow":1048575,"maxTokens":131072,"api":"openai-completions","baseUrl":"https://api.fireworks.ai/inference/v1","compat":{"supportsStore":false,"supportsDeveloperRole":false,"sendSessionAffinityHeaders":true,"supportsLongCacheRetention":false},"thinkingLevelMap":{"off":"none","minimal":null,"low":"high","medium":"high","high":"high","xhigh":null,"max":"max"}},"accounts/fireworks/models/kimi-k3":{"id":"accounts/fireworks/models/kimi-k3","name":"Kimi K3","provider":"fireworks","reasoning":true,"input":["text","image"],"cost":{"input":3,"output":15,"cacheRead":0.3,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"api":"openai-completions","baseUrl":"https://api.fireworks.ai/inference/v1","compat":{"supportsStore":false,"supportsDeveloperRole":false,"sendSessionAffinityHeaders":true,"supportsLongCacheRetention":false,"requiresReasoningContentOnAssistantMessages":true,"thinkingFormat":"openai","deferredToolsMode":"kimi"},"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":null,"max":"max"}},"accounts/fireworks/routers/glm-5p2-fast":{"id":"accounts/fireworks/routers/glm-5p2-fast","name":"GLM 5.2 Fast","provider":"fireworks","reasoning":true,"input":["text"],"cost":{"input":2.1,"output":6.6,"cacheRead":0.21,"cacheWrite":0},"contextWindow":1048575,"maxTokens":131072,"api":"openai-completions","baseUrl":"https://api.fireworks.ai/inference/v1","compat":{"supportsStore":false,"supportsDeveloperRole":false,"sendSessionAffinityHeaders":true,"supportsLongCacheRetention":false},"thinkingLevelMap":{"off":"none","minimal":null,"low":"high","medium":"high","high":"high","xhigh":null,"max":"max"}},"accounts/fireworks/routers/kimi-k3-fast":{"id":"accounts/fireworks/routers/kimi-k3-fast","name":"Kimi K3 Fast","provider":"fireworks","reasoning":true,"input":["text","image"],"cost":{"input":4.5,"output":22.5,"cacheRead":0.45,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"api":"openai-completions","baseUrl":"https://api.fireworks.ai/inference/v1","compat":{"supportsStore":false,"supportsDeveloperRole":false,"sendSessionAffinityHeaders":true,"supportsLongCacheRetention":false,"requiresReasoningContentOnAssistantMessages":true,"thinkingFormat":"openai","deferredToolsMode":"kimi"},"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":null,"max":"max"}}}}
1
+ {"anthropic-messages":{"accounts/fireworks/models/deepseek-v4-flash":{"id":"accounts/fireworks/models/deepseek-v4-flash","name":"DeepSeek V4 Flash","provider":"fireworks","reasoning":true,"input":["text"],"cost":{"input":0.14,"output":0.28,"cacheRead":0.028,"cacheWrite":0},"contextWindow":1000000,"maxTokens":384000,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/deepseek-v4-flash-0731":{"id":"accounts/fireworks/models/deepseek-v4-flash-0731","name":"DeepSeek V4 Flash 0731","provider":"fireworks","reasoning":true,"input":["text"],"cost":{"input":0.14,"output":0.28,"cacheRead":0.028,"cacheWrite":0},"contextWindow":1000000,"maxTokens":384000,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/deepseek-v4-pro-0813":{"id":"accounts/fireworks/models/deepseek-v4-pro-0813","name":"DeepSeek V4 Pro 0813","provider":"fireworks","reasoning":true,"input":["text"],"cost":{"input":1.32,"output":3.96,"cacheRead":0.044,"cacheWrite":0},"contextWindow":1000000,"maxTokens":384000,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/gpt-oss-120b":{"id":"accounts/fireworks/models/gpt-oss-120b","name":"GPT OSS 120B","provider":"fireworks","reasoning":true,"input":["text"],"cost":{"input":0.15,"output":0.6,"cacheRead":0.015,"cacheWrite":0},"contextWindow":131072,"maxTokens":32768,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/inkling":{"id":"accounts/fireworks/models/inkling","name":"Inkling","provider":"fireworks","reasoning":true,"input":["text","image"],"cost":{"input":1,"output":4.05,"cacheRead":0.17,"cacheWrite":0},"contextWindow":1048576,"maxTokens":1048576,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/kimi-k2p6":{"id":"accounts/fireworks/models/kimi-k2p6","name":"Kimi K2.6","provider":"fireworks","reasoning":true,"input":["text","image"],"cost":{"input":0.95,"output":4,"cacheRead":0.16,"cacheWrite":0},"contextWindow":262000,"maxTokens":262000,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/kimi-k2p7-code":{"id":"accounts/fireworks/models/kimi-k2p7-code","name":"Kimi K2.7 Code","provider":"fireworks","reasoning":true,"input":["text","image"],"cost":{"input":0.95,"output":4,"cacheRead":0.19,"cacheWrite":0},"contextWindow":262000,"maxTokens":262000,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/minimax-m3":{"id":"accounts/fireworks/models/minimax-m3","name":"MiniMax-M3","provider":"fireworks","reasoning":true,"input":["text","image"],"cost":{"input":0.3,"output":1.2,"cacheRead":0.06,"cacheWrite":0},"contextWindow":512000,"maxTokens":512000,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/muse-glimmer-30b":{"id":"accounts/fireworks/models/muse-glimmer-30b","name":"Muse Glimmer 30B","provider":"fireworks","reasoning":true,"input":["text","image"],"cost":{"input":0.35,"output":1.5,"cacheRead":0.04,"cacheWrite":0},"contextWindow":131072,"maxTokens":131072,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/nemotron-3-ultra-nvfp4":{"id":"accounts/fireworks/models/nemotron-3-ultra-nvfp4","name":"Nemotron 3 Ultra 550B A55B","provider":"fireworks","reasoning":true,"input":["text"],"cost":{"input":0.6,"output":2.4,"cacheRead":0.119,"cacheWrite":0},"contextWindow":262144,"maxTokens":128000,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/nemotron-lightning-3p5-30b-a3b":{"id":"accounts/fireworks/models/nemotron-lightning-3p5-30b-a3b","name":"Nemotron 3.5 Lightning 30B A3B","provider":"fireworks","reasoning":true,"input":["text"],"cost":{"input":0.05,"output":0.2,"cacheRead":0.01,"cacheWrite":0},"contextWindow":262144,"maxTokens":262144,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/qwen3p7-plus":{"id":"accounts/fireworks/models/qwen3p7-plus","name":"Qwen 3.7 Plus","provider":"fireworks","reasoning":true,"input":["text","image"],"cost":{"input":0.4,"output":1.6,"cacheRead":0.08,"cacheWrite":0},"contextWindow":262144,"maxTokens":65536,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}},"accounts/fireworks/models/qwen3p8-max":{"id":"accounts/fireworks/models/qwen3p8-max","name":"Qwen3.8 Max","provider":"fireworks","reasoning":true,"input":["text"],"cost":{"input":2,"output":6,"cacheRead":0.25,"cacheWrite":0},"contextWindow":262144,"maxTokens":131072,"api":"anthropic-messages","baseUrl":"https://api.fireworks.ai/inference","compat":{"sendSessionAffinityHeaders":true,"supportsEagerToolInputStreaming":false,"supportsCacheControlOnTools":false,"supportsLongCacheRetention":false}}},"openai-completions":{"accounts/fireworks/models/glm-5p2":{"id":"accounts/fireworks/models/glm-5p2","name":"GLM 5.2","provider":"fireworks","reasoning":true,"input":["text"],"cost":{"input":1.4,"output":4.4,"cacheRead":0.14,"cacheWrite":0},"contextWindow":1048575,"maxTokens":131072,"api":"openai-completions","baseUrl":"https://api.fireworks.ai/inference/v1","compat":{"supportsStore":false,"supportsDeveloperRole":false,"sendSessionAffinityHeaders":true,"supportsLongCacheRetention":false},"thinkingLevelMap":{"off":"none","minimal":null,"low":"high","medium":"high","high":"high","xhigh":null,"max":"max"}},"accounts/fireworks/models/kimi-k3":{"id":"accounts/fireworks/models/kimi-k3","name":"Kimi K3","provider":"fireworks","reasoning":true,"input":["text","image"],"cost":{"input":3,"output":15,"cacheRead":0.3,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"api":"openai-completions","baseUrl":"https://api.fireworks.ai/inference/v1","compat":{"supportsStore":false,"supportsDeveloperRole":false,"sendSessionAffinityHeaders":true,"supportsLongCacheRetention":false,"requiresReasoningContentOnAssistantMessages":true,"thinkingFormat":"openai","deferredToolsMode":"kimi"},"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":null,"max":"max"}},"accounts/fireworks/routers/glm-5p2-fast":{"id":"accounts/fireworks/routers/glm-5p2-fast","name":"GLM 5.2 Fast","provider":"fireworks","reasoning":true,"input":["text"],"cost":{"input":2.1,"output":6.6,"cacheRead":0.21,"cacheWrite":0},"contextWindow":1048575,"maxTokens":131072,"api":"openai-completions","baseUrl":"https://api.fireworks.ai/inference/v1","compat":{"supportsStore":false,"supportsDeveloperRole":false,"sendSessionAffinityHeaders":true,"supportsLongCacheRetention":false},"thinkingLevelMap":{"off":"none","minimal":null,"low":"high","medium":"high","high":"high","xhigh":null,"max":"max"}},"accounts/fireworks/routers/kimi-k3-fast":{"id":"accounts/fireworks/routers/kimi-k3-fast","name":"Kimi K3 Fast","provider":"fireworks","reasoning":true,"input":["text","image"],"cost":{"input":4.5,"output":22.5,"cacheRead":0.45,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"api":"openai-completions","baseUrl":"https://api.fireworks.ai/inference/v1","compat":{"supportsStore":false,"supportsDeveloperRole":false,"sendSessionAffinityHeaders":true,"supportsLongCacheRetention":false,"requiresReasoningContentOnAssistantMessages":true,"thinkingFormat":"openai","deferredToolsMode":"kimi"},"thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":null,"max":"max"}}}}