codex-multi-auth 2.15.0 → 2.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +22 -1
- package/config/README.md +2 -2
- package/config/codex-legacy.json +109 -184
- package/config/codex-modern.json +44 -114
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -4
- package/dist/lib/account-policy.d.ts +4 -0
- package/dist/lib/account-policy.d.ts.map +1 -1
- package/dist/lib/account-policy.js +8 -0
- package/dist/lib/accounts/rate-limits.d.ts.map +1 -1
- package/dist/lib/accounts/rate-limits.js +2 -0
- package/dist/lib/accounts.d.ts +21 -3
- package/dist/lib/accounts.d.ts.map +1 -1
- package/dist/lib/accounts.js +229 -17
- package/dist/lib/api-route-store.d.ts +24 -0
- package/dist/lib/api-route-store.d.ts.map +1 -0
- package/dist/lib/api-route-store.js +145 -0
- package/dist/lib/auth/account-access.d.ts +115 -0
- package/dist/lib/auth/account-access.d.ts.map +1 -0
- package/dist/lib/auth/account-access.js +214 -0
- package/dist/lib/auth/token-utils.d.ts +54 -1
- package/dist/lib/auth/token-utils.d.ts.map +1 -1
- package/dist/lib/auth/token-utils.js +92 -7
- package/dist/lib/cli.d.ts +1 -1
- package/dist/lib/cli.d.ts.map +1 -1
- package/dist/lib/cli.js +4 -0
- package/dist/lib/codex-cli/state.d.ts +7 -0
- package/dist/lib/codex-cli/state.d.ts.map +1 -1
- package/dist/lib/codex-cli/state.js +18 -0
- package/dist/lib/codex-cli/writer.d.ts.map +1 -1
- package/dist/lib/codex-cli/writer.js +60 -8
- package/dist/lib/codex-manager/account-manager-commands.d.ts.map +1 -1
- package/dist/lib/codex-manager/account-manager-commands.js +1 -0
- package/dist/lib/codex-manager/account-pool-write.d.ts +3 -1
- package/dist/lib/codex-manager/account-pool-write.d.ts.map +1 -1
- package/dist/lib/codex-manager/account-pool-write.js +4 -0
- package/dist/lib/codex-manager/api-login-menu.d.ts +14 -0
- package/dist/lib/codex-manager/api-login-menu.d.ts.map +1 -0
- package/dist/lib/codex-manager/api-login-menu.js +224 -0
- package/dist/lib/codex-manager/commands/account.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/account.js +27 -0
- package/dist/lib/codex-manager/commands/best.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/best.js +6 -2
- package/dist/lib/codex-manager/commands/check.d.ts +7 -1
- package/dist/lib/codex-manager/commands/check.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/check.js +24 -3
- package/dist/lib/codex-manager/commands/forecast.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/forecast.js +5 -1
- package/dist/lib/codex-manager/commands/report.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/report.js +5 -1
- package/dist/lib/codex-manager/commands/resets.d.ts +2 -0
- package/dist/lib/codex-manager/commands/resets.d.ts.map +1 -0
- package/dist/lib/codex-manager/commands/resets.js +67 -0
- package/dist/lib/codex-manager/commands/rotation.d.ts +2 -2
- package/dist/lib/codex-manager/commands/rotation.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/rotation.js +63 -12
- package/dist/lib/codex-manager/commands/status.d.ts +12 -1
- package/dist/lib/codex-manager/commands/status.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/status.js +166 -22
- package/dist/lib/codex-manager/commands/uninstall.js +1 -1
- package/dist/lib/codex-manager/formatters/quota-formatters.d.ts.map +1 -1
- package/dist/lib/codex-manager/formatters/quota-formatters.js +3 -2
- package/dist/lib/codex-manager/health-check.d.ts +3 -0
- package/dist/lib/codex-manager/health-check.d.ts.map +1 -1
- package/dist/lib/codex-manager/health-check.js +56 -6
- package/dist/lib/codex-manager/help.d.ts.map +1 -1
- package/dist/lib/codex-manager/help.js +4 -2
- package/dist/lib/codex-manager/login-flow.d.ts.map +1 -1
- package/dist/lib/codex-manager/login-flow.js +69 -7
- package/dist/lib/codex-manager/login-menu-data.d.ts.map +1 -1
- package/dist/lib/codex-manager/login-menu-data.js +14 -5
- package/dist/lib/codex-manager/login-oauth.d.ts +3 -0
- package/dist/lib/codex-manager/login-oauth.d.ts.map +1 -1
- package/dist/lib/codex-manager/login-oauth.js +6 -1
- package/dist/lib/codex-manager/login-workspace-choice.d.ts +11 -0
- package/dist/lib/codex-manager/login-workspace-choice.d.ts.map +1 -0
- package/dist/lib/codex-manager/login-workspace-choice.js +37 -0
- package/dist/lib/codex-manager/persist-selected-account.d.ts.map +1 -1
- package/dist/lib/codex-manager/persist-selected-account.js +2 -1
- package/dist/lib/codex-manager/repair-commands.d.ts +13 -0
- package/dist/lib/codex-manager/repair-commands.d.ts.map +1 -1
- package/dist/lib/codex-manager/repair-commands.js +143 -8
- package/dist/lib/codex-manager.d.ts.map +1 -1
- package/dist/lib/codex-manager.js +25 -6
- package/dist/lib/concurrency.d.ts +3 -0
- package/dist/lib/concurrency.d.ts.map +1 -0
- package/dist/lib/concurrency.js +31 -0
- package/dist/lib/context-budget/model-context-windows.d.ts +1 -1
- package/dist/lib/context-budget/model-context-windows.d.ts.map +1 -1
- package/dist/lib/context-budget/model-context-windows.js +9 -10
- package/dist/lib/model-route-policy.d.ts +52 -0
- package/dist/lib/model-route-policy.d.ts.map +1 -0
- package/dist/lib/model-route-policy.js +159 -0
- package/dist/lib/policy/runtime-policy.d.ts +1 -0
- package/dist/lib/policy/runtime-policy.d.ts.map +1 -1
- package/dist/lib/policy/runtime-policy.js +3 -0
- package/dist/lib/preemptive-quota-scheduler.d.ts +2 -0
- package/dist/lib/preemptive-quota-scheduler.d.ts.map +1 -1
- package/dist/lib/preemptive-quota-scheduler.js +4 -0
- package/dist/lib/prompts/codex.d.ts.map +1 -1
- package/dist/lib/prompts/codex.js +3 -1
- package/dist/lib/quota-probe.d.ts +5 -0
- package/dist/lib/quota-probe.d.ts.map +1 -1
- package/dist/lib/quota-probe.js +26 -2
- package/dist/lib/request/client-cancellation.d.ts +5 -0
- package/dist/lib/request/client-cancellation.d.ts.map +1 -0
- package/dist/lib/request/client-cancellation.js +7 -0
- package/dist/lib/request/error-classification.d.ts.map +1 -1
- package/dist/lib/request/error-classification.js +39 -25
- package/dist/lib/request/fetch-helpers.js +1 -1
- package/dist/lib/request/helpers/model-map.d.ts +12 -2
- package/dist/lib/request/helpers/model-map.d.ts.map +1 -1
- package/dist/lib/request/helpers/model-map.js +174 -147
- package/dist/lib/request/response-outcome.d.ts +25 -0
- package/dist/lib/request/response-outcome.d.ts.map +1 -0
- package/dist/lib/request/response-outcome.js +49 -0
- package/dist/lib/request/stream-failover-runtime.d.ts +2 -1
- package/dist/lib/request/stream-failover-runtime.d.ts.map +1 -1
- package/dist/lib/request/stream-failover-runtime.js +29 -10
- package/dist/lib/runtime/account-check.d.ts.map +1 -1
- package/dist/lib/runtime/account-check.js +2 -8
- package/dist/lib/runtime/account-model-catalog.d.ts +64 -0
- package/dist/lib/runtime/account-model-catalog.d.ts.map +1 -0
- package/dist/lib/runtime/account-model-catalog.js +154 -0
- package/dist/lib/runtime/account-pool.d.ts +3 -1
- package/dist/lib/runtime/account-pool.d.ts.map +1 -1
- package/dist/lib/runtime/account-pool.js +4 -0
- package/dist/lib/runtime/account-reset-credits.d.ts +42 -0
- package/dist/lib/runtime/account-reset-credits.d.ts.map +1 -0
- package/dist/lib/runtime/account-reset-credits.js +82 -0
- package/dist/lib/runtime/api-model-capabilities.d.ts +30 -0
- package/dist/lib/runtime/api-model-capabilities.d.ts.map +1 -0
- package/dist/lib/runtime/api-model-capabilities.js +434 -0
- package/dist/lib/runtime/api-model-runtime.d.ts +42 -0
- package/dist/lib/runtime/api-model-runtime.d.ts.map +1 -0
- package/dist/lib/runtime/api-model-runtime.js +358 -0
- package/dist/lib/runtime/app-bind.d.ts +19 -1
- package/dist/lib/runtime/app-bind.d.ts.map +1 -1
- package/dist/lib/runtime/app-bind.js +79 -9
- package/dist/lib/runtime/automatic-account-checks.d.ts +31 -0
- package/dist/lib/runtime/automatic-account-checks.d.ts.map +1 -0
- package/dist/lib/runtime/automatic-account-checks.js +113 -0
- package/dist/lib/runtime/automatic-subscription-checks.d.ts +7 -0
- package/dist/lib/runtime/automatic-subscription-checks.d.ts.map +1 -0
- package/dist/lib/runtime/automatic-subscription-checks.js +57 -0
- package/dist/lib/runtime/catalog-capabilities.d.ts +8 -0
- package/dist/lib/runtime/catalog-capabilities.d.ts.map +1 -0
- package/dist/lib/runtime/catalog-capabilities.js +61 -0
- package/dist/lib/runtime/inference-activity.d.ts +15 -0
- package/dist/lib/runtime/inference-activity.d.ts.map +1 -0
- package/dist/lib/runtime/inference-activity.js +95 -0
- package/dist/lib/runtime/model-discovery-status.d.ts +100 -0
- package/dist/lib/runtime/model-discovery-status.d.ts.map +1 -0
- package/dist/lib/runtime/model-discovery-status.js +387 -0
- package/dist/lib/runtime/native-account-storage.d.ts +11 -0
- package/dist/lib/runtime/native-account-storage.d.ts.map +1 -0
- package/dist/lib/runtime/native-account-storage.js +50 -0
- package/dist/lib/runtime/native-account-sync.d.ts +19 -0
- package/dist/lib/runtime/native-account-sync.d.ts.map +1 -0
- package/dist/lib/runtime/native-account-sync.js +62 -0
- package/dist/lib/runtime/native-binding-lock.d.ts +3 -0
- package/dist/lib/runtime/native-binding-lock.d.ts.map +1 -0
- package/dist/lib/runtime/native-binding-lock.js +5 -0
- package/dist/lib/runtime/native-client-auth.d.ts +3 -0
- package/dist/lib/runtime/native-client-auth.d.ts.map +1 -0
- package/dist/lib/runtime/native-client-auth.js +42 -0
- package/dist/lib/runtime/native-provider-config.d.ts +4 -0
- package/dist/lib/runtime/native-provider-config.d.ts.map +1 -0
- package/dist/lib/runtime/native-provider-config.js +52 -0
- package/dist/lib/runtime/native-rate-limits.d.ts +18 -0
- package/dist/lib/runtime/native-rate-limits.d.ts.map +1 -0
- package/dist/lib/runtime/native-rate-limits.js +135 -0
- package/dist/lib/runtime/reset-credit-routing.d.ts +41 -0
- package/dist/lib/runtime/reset-credit-routing.d.ts.map +1 -0
- package/dist/lib/runtime/reset-credit-routing.js +66 -0
- package/dist/lib/runtime/reset-credits.d.ts +101 -0
- package/dist/lib/runtime/reset-credits.d.ts.map +1 -0
- package/dist/lib/runtime/reset-credits.js +162 -0
- package/dist/lib/runtime/response-output-history.d.ts +17 -0
- package/dist/lib/runtime/response-output-history.d.ts.map +1 -0
- package/dist/lib/runtime/response-output-history.js +85 -0
- package/dist/lib/runtime/responses-websocket.d.ts +31 -0
- package/dist/lib/runtime/responses-websocket.d.ts.map +1 -0
- package/dist/lib/runtime/responses-websocket.js +636 -0
- package/dist/lib/runtime/resume-picker.d.ts +41 -0
- package/dist/lib/runtime/resume-picker.d.ts.map +1 -0
- package/dist/lib/runtime/resume-picker.js +169 -0
- package/dist/lib/runtime/rotation-account-selection.d.ts +6 -0
- package/dist/lib/runtime/rotation-account-selection.d.ts.map +1 -1
- package/dist/lib/runtime/rotation-account-selection.js +63 -0
- package/dist/lib/runtime/rotation-proxy-state.d.ts +33 -0
- package/dist/lib/runtime/rotation-proxy-state.d.ts.map +1 -1
- package/dist/lib/runtime/rotation-server-types.d.ts +18 -0
- package/dist/lib/runtime/rotation-server-types.d.ts.map +1 -1
- package/dist/lib/runtime/runtime-capability-failures.d.ts +14 -0
- package/dist/lib/runtime/runtime-capability-failures.d.ts.map +1 -0
- package/dist/lib/runtime/runtime-capability-failures.js +76 -0
- package/dist/lib/runtime/runtime-observability.d.ts +7 -0
- package/dist/lib/runtime/runtime-observability.d.ts.map +1 -1
- package/dist/lib/runtime/runtime-observability.js +42 -2
- package/dist/lib/runtime/subscription-first-use.d.ts +10 -0
- package/dist/lib/runtime/subscription-first-use.d.ts.map +1 -0
- package/dist/lib/runtime/subscription-first-use.js +64 -0
- package/dist/lib/runtime/subscription-quota-event.d.ts +6 -0
- package/dist/lib/runtime/subscription-quota-event.d.ts.map +1 -0
- package/dist/lib/runtime/subscription-quota-event.js +31 -0
- package/dist/lib/runtime/subscription-quota-order.d.ts +17 -0
- package/dist/lib/runtime/subscription-quota-order.d.ts.map +1 -0
- package/dist/lib/runtime/subscription-quota-order.js +31 -0
- package/dist/lib/runtime/workspace-model-scopes.d.ts +15 -0
- package/dist/lib/runtime/workspace-model-scopes.d.ts.map +1 -0
- package/dist/lib/runtime/workspace-model-scopes.js +34 -0
- package/dist/lib/runtime-constants.d.ts +3 -0
- package/dist/lib/runtime-constants.d.ts.map +1 -1
- package/dist/lib/runtime-constants.js +5 -0
- package/dist/lib/runtime-paths.d.ts.map +1 -1
- package/dist/lib/runtime-paths.js +4 -1
- package/dist/lib/runtime-rotation-proxy.d.ts.map +1 -1
- package/dist/lib/runtime-rotation-proxy.js +855 -46
- package/dist/lib/schemas.d.ts +20 -0
- package/dist/lib/schemas.d.ts.map +1 -1
- package/dist/lib/schemas.js +3 -0
- package/dist/lib/storage/credential-sidecars.d.ts +13 -0
- package/dist/lib/storage/credential-sidecars.d.ts.map +1 -0
- package/dist/lib/storage/credential-sidecars.js +52 -0
- package/dist/lib/storage/file-lock.d.ts +9 -0
- package/dist/lib/storage/file-lock.d.ts.map +1 -0
- package/dist/lib/storage/file-lock.js +186 -0
- package/dist/lib/storage/flagged-storage.d.ts.map +1 -1
- package/dist/lib/storage/flagged-storage.js +12 -0
- package/dist/lib/storage/path-state.d.ts +2 -0
- package/dist/lib/storage/path-state.d.ts.map +1 -1
- package/dist/lib/storage/path-state.js +9 -0
- package/dist/lib/storage/paths.js +4 -4
- package/dist/lib/storage/pending-auth.d.ts +17 -0
- package/dist/lib/storage/pending-auth.d.ts.map +1 -0
- package/dist/lib/storage/pending-auth.js +153 -0
- package/dist/lib/storage/public-types.d.ts +13 -0
- package/dist/lib/storage/public-types.d.ts.map +1 -1
- package/dist/lib/storage/snapshot-merge.d.ts +16 -0
- package/dist/lib/storage/snapshot-merge.d.ts.map +1 -0
- package/dist/lib/storage/snapshot-merge.js +206 -0
- package/dist/lib/storage/transactions.d.ts.map +1 -1
- package/dist/lib/storage/transactions.js +5 -4
- package/dist/lib/storage.d.ts +6 -0
- package/dist/lib/storage.d.ts.map +1 -1
- package/dist/lib/storage.js +77 -7
- package/dist/lib/ui/auth-menu-builder.d.ts +2 -0
- package/dist/lib/ui/auth-menu-builder.d.ts.map +1 -1
- package/dist/lib/ui/auth-menu-builder.js +1 -0
- package/dist/lib/ui/auth-menu.d.ts.map +1 -1
- package/dist/lib/ui/auth-menu.js +1 -0
- package/dist/lib/ui/check-progress.d.ts +8 -0
- package/dist/lib/ui/check-progress.d.ts.map +1 -0
- package/dist/lib/ui/check-progress.js +30 -0
- package/dist/lib/ui/format.d.ts +3 -1
- package/dist/lib/ui/format.d.ts.map +1 -1
- package/dist/lib/ui/format.js +8 -0
- package/dist/lib/ui/ui-copy.d.ts +2 -2
- package/dist/lib/ui/ui-copy.js +2 -2
- package/dist/lib/usage/pricing.d.ts +19 -2
- package/dist/lib/usage/pricing.d.ts.map +1 -1
- package/dist/lib/usage/pricing.js +101 -40
- package/dist/lib/usage/usage-extraction.d.ts +3 -1
- package/dist/lib/usage/usage-extraction.d.ts.map +1 -1
- package/dist/lib/usage/usage-extraction.js +46 -9
- package/package.json +7 -4
- package/scripts/codex-app-router.js +7 -0
- package/scripts/codex-bin-resolver.js +40 -8
- package/scripts/codex-routing.js +1 -0
- package/scripts/codex.js +209 -126
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
import { mapWithConcurrency } from "../concurrency.js";
|
|
2
|
+
import { classifyCapabilityFailure } from "./runtime-capability-failures.js";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
import { canonicalServiceTier, } from "../model-route-policy.js";
|
|
5
|
+
import { isRecord } from "../utils.js";
|
|
6
|
+
const efforts = new Set([
|
|
7
|
+
"none",
|
|
8
|
+
"minimal",
|
|
9
|
+
"low",
|
|
10
|
+
"medium",
|
|
11
|
+
"high",
|
|
12
|
+
"xhigh",
|
|
13
|
+
"max",
|
|
14
|
+
]);
|
|
15
|
+
/** Read the explicit model-specific statement, never surrounding examples or another model's settings. */
|
|
16
|
+
export function parseApiReasoningDocumentation(id, text) {
|
|
17
|
+
if (text.match(/^Model ID:\s*`([^`]+)`/m)?.[1] !== id)
|
|
18
|
+
return [];
|
|
19
|
+
const statement = text.match(/`?reasoning\.effort`?\s+supports\s*:?\s*([^\n.]+)\./i)?.[1];
|
|
20
|
+
if (!statement)
|
|
21
|
+
return [];
|
|
22
|
+
const values = statement
|
|
23
|
+
.replace(/`|\(default\)/g, " ")
|
|
24
|
+
.split(/,|\band\b/)
|
|
25
|
+
.map((s) => s.trim())
|
|
26
|
+
.filter(Boolean);
|
|
27
|
+
if (!values.length ||
|
|
28
|
+
values.length > 16 ||
|
|
29
|
+
values.some((v) => !/^[a-z][a-z0-9_-]{0,31}$/.test(v) ||
|
|
30
|
+
v === "ultra" ||
|
|
31
|
+
v === "persistent"))
|
|
32
|
+
return [];
|
|
33
|
+
return [...new Set(values)];
|
|
34
|
+
}
|
|
35
|
+
/** Only the exact model's input declaration can enable native image attachments. */
|
|
36
|
+
function parseInputModalities(id, text) {
|
|
37
|
+
if (text.match(/^Model ID:\s*`([^`]+)`/m)?.[1] !== id)
|
|
38
|
+
return undefined;
|
|
39
|
+
const details = text.split(/^## Model details[ \t]*\r?\n/m)[1]?.split(/^## /m)[0];
|
|
40
|
+
const declaration = details?.match(/^- Input modalities:[ \t]*([^\r\n]+)$/m)?.[1];
|
|
41
|
+
if (!declaration)
|
|
42
|
+
return undefined;
|
|
43
|
+
const modalities = declaration.split(",").map(value => value.trim());
|
|
44
|
+
if (!modalities.length || modalities.some(value => !["text", "image", "audio", "video"].includes(value)))
|
|
45
|
+
return undefined;
|
|
46
|
+
// The native coding picker currently accepts text and image inputs.
|
|
47
|
+
return [...new Set(modalities.filter(value => value === "text" || value === "image"))];
|
|
48
|
+
}
|
|
49
|
+
/** Codes and params that say the key, organization or project itself lacks access. */
|
|
50
|
+
const CREDENTIAL_ACCESS_CODES = new Set([
|
|
51
|
+
"invalid_api_key", "insufficient_permissions", "permission_denied", "unauthorized",
|
|
52
|
+
"organization_deactivated", "account_deactivated", "project_not_found", "project_archived",
|
|
53
|
+
"ip_not_authorized", "unsupported_country_region_territory",
|
|
54
|
+
]);
|
|
55
|
+
/**
|
|
56
|
+
* A 403 either removes the credential's access ("lost"), denies the whole model
|
|
57
|
+
* on this credential ("model"), denies only the probed setting ("setting"), or
|
|
58
|
+
* explains nothing ("ambiguous").
|
|
59
|
+
*/
|
|
60
|
+
function classifyProbe403(data, setting) {
|
|
61
|
+
const error = isRecord(data) && isRecord(data.error) ? data.error : null;
|
|
62
|
+
if (!error)
|
|
63
|
+
return "ambiguous";
|
|
64
|
+
const code = String(error.code ?? ""), param = String(error.param ?? "");
|
|
65
|
+
if (CREDENTIAL_ACCESS_CODES.has(code) || ["api_key", "organization", "project"].includes(param))
|
|
66
|
+
return "lost";
|
|
67
|
+
// Same model-level denial codes the runtime capability classifier uses.
|
|
68
|
+
if (classifyCapabilityFailure(403, data) === "model")
|
|
69
|
+
return "model";
|
|
70
|
+
// Compatibility and tier probes also carry an effort, but only an effort probe
|
|
71
|
+
// tests it: an effort-param 403 elsewhere explains nothing about the probed setting.
|
|
72
|
+
const effortProbe = Boolean(setting.effort) && !setting.tier && !setting.compatibility;
|
|
73
|
+
if (effortProbe && ["reasoning.effort", "reasoning"].includes(param))
|
|
74
|
+
return "setting";
|
|
75
|
+
if (setting.tier && param === "service_tier")
|
|
76
|
+
return "setting";
|
|
77
|
+
if (setting.compatibility && ["tools", "tool_choice"].includes(param))
|
|
78
|
+
return "setting";
|
|
79
|
+
return "ambiguous";
|
|
80
|
+
}
|
|
81
|
+
export class ApiModelCapabilities {
|
|
82
|
+
fetchImpl;
|
|
83
|
+
now;
|
|
84
|
+
activeProbes = 0;
|
|
85
|
+
probeWaiters = [];
|
|
86
|
+
async withProbeSlot(operation) {
|
|
87
|
+
if (this.activeProbes >= 4)
|
|
88
|
+
await new Promise((resolve) => this.probeWaiters.push(resolve));
|
|
89
|
+
else
|
|
90
|
+
this.activeProbes++;
|
|
91
|
+
try {
|
|
92
|
+
return await operation();
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
const next = this.probeWaiters.shift();
|
|
96
|
+
if (next)
|
|
97
|
+
next();
|
|
98
|
+
else
|
|
99
|
+
this.activeProbes--;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
inFlight = new Map();
|
|
103
|
+
probes = new Map();
|
|
104
|
+
cache = new Map();
|
|
105
|
+
constructor(fetchImpl = fetch, now = Date.now) {
|
|
106
|
+
this.fetchImpl = fetchImpl;
|
|
107
|
+
this.now = now;
|
|
108
|
+
}
|
|
109
|
+
/** Probe results keyed by an opaque hash, for a fresh CLI process to honour the 15-minute cache. */
|
|
110
|
+
exportProbes() {
|
|
111
|
+
return [...this.probes];
|
|
112
|
+
}
|
|
113
|
+
importProbes(entries) {
|
|
114
|
+
for (const [key, value] of entries.slice(-1000)) {
|
|
115
|
+
if (this.probes.has(key) || value.at > this.now())
|
|
116
|
+
continue;
|
|
117
|
+
this.probes.set(key, value);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
async reasoning(id, refresh = false) {
|
|
121
|
+
return (await this.documentation(id, refresh)).levels;
|
|
122
|
+
}
|
|
123
|
+
async documentation(id, refresh = false) {
|
|
124
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/.test(id))
|
|
125
|
+
return { levels: [] };
|
|
126
|
+
const cached = this.cache.get(id);
|
|
127
|
+
if (!refresh && cached && cached.at + 60000 > this.now())
|
|
128
|
+
return cached;
|
|
129
|
+
let metadata = { levels: [] };
|
|
130
|
+
try {
|
|
131
|
+
const response = await this.fetchImpl(`https://developers.openai.com/api/docs/models/${encodeURIComponent(id)}.md`, { redirect: "error", signal: AbortSignal.timeout(5000) });
|
|
132
|
+
if (!response.ok) {
|
|
133
|
+
await response.body?.cancel();
|
|
134
|
+
throw Error("Documentation unavailable");
|
|
135
|
+
}
|
|
136
|
+
const reader = response.body?.getReader();
|
|
137
|
+
if (!reader)
|
|
138
|
+
throw Error("No documentation");
|
|
139
|
+
const chunks = [];
|
|
140
|
+
let size = 0;
|
|
141
|
+
try {
|
|
142
|
+
for (;;) {
|
|
143
|
+
const { done, value } = await reader.read();
|
|
144
|
+
if (done)
|
|
145
|
+
break;
|
|
146
|
+
size += value.byteLength;
|
|
147
|
+
if (size > 256 * 1024)
|
|
148
|
+
throw Error("Documentation too large");
|
|
149
|
+
chunks.push(value);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
finally {
|
|
153
|
+
await reader.cancel();
|
|
154
|
+
}
|
|
155
|
+
const text = Buffer.concat(chunks).toString("utf8");
|
|
156
|
+
metadata = {
|
|
157
|
+
levels: parseApiReasoningDocumentation(id, text),
|
|
158
|
+
inputModalities: parseInputModalities(id, text),
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// An outage is not a capability revocation. Keep last successful evidence.
|
|
163
|
+
metadata = cached ?? metadata;
|
|
164
|
+
}
|
|
165
|
+
if (this.cache.size >= 1000)
|
|
166
|
+
this.cache.delete(this.cache.keys().next().value ?? "");
|
|
167
|
+
this.cache.set(id, { ...metadata, at: this.now() });
|
|
168
|
+
return metadata;
|
|
169
|
+
}
|
|
170
|
+
async probe(route, id, documented, force = false) {
|
|
171
|
+
const key = createHash("sha256")
|
|
172
|
+
.update(route.id)
|
|
173
|
+
.update("\0")
|
|
174
|
+
.update(route.apiKey)
|
|
175
|
+
.update("\0")
|
|
176
|
+
.update(id)
|
|
177
|
+
.digest("hex");
|
|
178
|
+
const old = this.probes.get(key);
|
|
179
|
+
// A probe cut short by 401/403/429 is retried after a minute, not trusted for 15.
|
|
180
|
+
const freshFor = old?.status.retry === "transient" ? 60_000 : 900_000;
|
|
181
|
+
if (!force && old && old.at + freshFor > this.now())
|
|
182
|
+
return old;
|
|
183
|
+
const running = this.inFlight.get(key);
|
|
184
|
+
if (running)
|
|
185
|
+
return running;
|
|
186
|
+
const pending = this.runProbe(route, id, documented, key).finally(() => this.inFlight.delete(key));
|
|
187
|
+
this.inFlight.set(key, pending);
|
|
188
|
+
return pending;
|
|
189
|
+
}
|
|
190
|
+
async runProbe(route, id, documented, key) {
|
|
191
|
+
const result = {
|
|
192
|
+
at: this.now(),
|
|
193
|
+
levels: [...documented],
|
|
194
|
+
tiers: [],
|
|
195
|
+
status: {},
|
|
196
|
+
};
|
|
197
|
+
let credentialUnavailable = false;
|
|
198
|
+
// 401/403 means this credential lost access: nothing it verified before
|
|
199
|
+
// may still be advertised. A throttle (429) or transport failure is only
|
|
200
|
+
// inconclusive and keeps what an earlier probe verified. Only
|
|
201
|
+
// "unsupported" or "downgraded" removes a setting otherwise.
|
|
202
|
+
let lostAccess = false;
|
|
203
|
+
// A model-level denial hides the model on this credential: no efforts, no tiers.
|
|
204
|
+
let modelDenied = false;
|
|
205
|
+
const previous = this.probes.get(key);
|
|
206
|
+
const keep = (name, status) => status === "unverified" && !lostAccess && !modelDenied && previous?.status[name] === "verified" ? "verified" : status;
|
|
207
|
+
const attempt = async (setting) => {
|
|
208
|
+
// Lost access drops everything this credential verified; a model-level
|
|
209
|
+
// denial hides the model; a 403 naming the probed setting removes only it.
|
|
210
|
+
// An unexplained 403 changes nothing and the probe is retried soon.
|
|
211
|
+
const denied403 = (data) => {
|
|
212
|
+
const kind = classifyProbe403(data, setting);
|
|
213
|
+
if (kind === "lost") {
|
|
214
|
+
credentialUnavailable = true;
|
|
215
|
+
lostAccess = true;
|
|
216
|
+
return "unverified";
|
|
217
|
+
}
|
|
218
|
+
if (kind === "model") {
|
|
219
|
+
modelDenied = true;
|
|
220
|
+
return "unsupported";
|
|
221
|
+
}
|
|
222
|
+
if (kind === "setting")
|
|
223
|
+
return "unsupported";
|
|
224
|
+
credentialUnavailable = true;
|
|
225
|
+
return "unverified";
|
|
226
|
+
};
|
|
227
|
+
return this.withProbeSlot(async () => {
|
|
228
|
+
if (credentialUnavailable || modelDenied)
|
|
229
|
+
return "unverified";
|
|
230
|
+
try {
|
|
231
|
+
const response = await this.fetchImpl("https://api.openai.com/v1/responses", {
|
|
232
|
+
method: "POST",
|
|
233
|
+
headers: {
|
|
234
|
+
authorization: `Bearer ${route.apiKey}`,
|
|
235
|
+
"content-type": "application/json",
|
|
236
|
+
},
|
|
237
|
+
redirect: "error",
|
|
238
|
+
signal: AbortSignal.timeout(15000),
|
|
239
|
+
body: JSON.stringify({
|
|
240
|
+
model: id,
|
|
241
|
+
input: "Reply OK.",
|
|
242
|
+
store: false,
|
|
243
|
+
max_output_tokens: 16,
|
|
244
|
+
...(setting.compatibility
|
|
245
|
+
? {
|
|
246
|
+
tools: [
|
|
247
|
+
{
|
|
248
|
+
type: "function",
|
|
249
|
+
name: "capability_probe",
|
|
250
|
+
parameters: {
|
|
251
|
+
type: "object",
|
|
252
|
+
properties: {},
|
|
253
|
+
required: [],
|
|
254
|
+
additionalProperties: false,
|
|
255
|
+
},
|
|
256
|
+
strict: true,
|
|
257
|
+
},
|
|
258
|
+
],
|
|
259
|
+
tool_choice: {
|
|
260
|
+
type: "function",
|
|
261
|
+
name: "capability_probe",
|
|
262
|
+
},
|
|
263
|
+
}
|
|
264
|
+
: {}),
|
|
265
|
+
...(setting.effort
|
|
266
|
+
? { reasoning: { effort: setting.effort } }
|
|
267
|
+
: {}),
|
|
268
|
+
...(setting.tier ? { service_tier: setting.tier } : {}),
|
|
269
|
+
}),
|
|
270
|
+
});
|
|
271
|
+
if ([401, 429].includes(response.status))
|
|
272
|
+
credentialUnavailable = true;
|
|
273
|
+
if (response.status === 401)
|
|
274
|
+
lostAccess = true;
|
|
275
|
+
// Probe bodies are tiny, but an upstream error must not grow local memory unboundedly.
|
|
276
|
+
const reader = response.body?.getReader();
|
|
277
|
+
if (!reader)
|
|
278
|
+
return response.status === 403 ? denied403(null) : "unverified";
|
|
279
|
+
const chunks = [];
|
|
280
|
+
let bytes = 0;
|
|
281
|
+
try {
|
|
282
|
+
for (;;) {
|
|
283
|
+
const { done, value } = await reader.read();
|
|
284
|
+
if (done)
|
|
285
|
+
break;
|
|
286
|
+
bytes += value.byteLength;
|
|
287
|
+
if (bytes > 256 * 1024)
|
|
288
|
+
throw Error("Probe response too large");
|
|
289
|
+
chunks.push(value);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
finally {
|
|
293
|
+
await reader.cancel();
|
|
294
|
+
}
|
|
295
|
+
let data;
|
|
296
|
+
try {
|
|
297
|
+
data = JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
298
|
+
}
|
|
299
|
+
catch {
|
|
300
|
+
return response.status === 403 ? denied403(null) : "unverified";
|
|
301
|
+
}
|
|
302
|
+
if (response.status === 403)
|
|
303
|
+
return denied403(data);
|
|
304
|
+
if (!response.ok) {
|
|
305
|
+
if (setting.compatibility) {
|
|
306
|
+
const error = isRecord(data) && isRecord(data.error) ? data.error : null;
|
|
307
|
+
return classifyCapabilityFailure(response.status, data) ===
|
|
308
|
+
"model" ||
|
|
309
|
+
(response.status === 400 &&
|
|
310
|
+
error &&
|
|
311
|
+
["tools", "tool_choice"].includes(String(error.param)) &&
|
|
312
|
+
["unsupported_parameter", "unsupported_value"].includes(String(error.code)))
|
|
313
|
+
? "unsupported"
|
|
314
|
+
: "unverified";
|
|
315
|
+
}
|
|
316
|
+
const error = isRecord(data) && isRecord(data.error) ? data.error : null;
|
|
317
|
+
return response.status === 400 &&
|
|
318
|
+
error &&
|
|
319
|
+
typeof error.param === "string" &&
|
|
320
|
+
["reasoning.effort", "reasoning", "service_tier"].includes(error.param)
|
|
321
|
+
? "unsupported"
|
|
322
|
+
: "unverified";
|
|
323
|
+
}
|
|
324
|
+
if (setting.compatibility)
|
|
325
|
+
return isRecord(data) &&
|
|
326
|
+
Array.isArray(data.output) &&
|
|
327
|
+
data.output.some((item) => isRecord(item) &&
|
|
328
|
+
item.type === "function_call" &&
|
|
329
|
+
item.name === "capability_probe")
|
|
330
|
+
? "verified"
|
|
331
|
+
: "unverified";
|
|
332
|
+
if (!setting.tier)
|
|
333
|
+
return isRecord(data) &&
|
|
334
|
+
isRecord(data.reasoning) &&
|
|
335
|
+
data.reasoning.effort === setting.effort
|
|
336
|
+
? "verified"
|
|
337
|
+
: "unverified";
|
|
338
|
+
if (!isRecord(data) || typeof data.service_tier !== "string")
|
|
339
|
+
return "unverified";
|
|
340
|
+
return canonicalServiceTier(data.service_tier) ===
|
|
341
|
+
canonicalServiceTier(setting.tier)
|
|
342
|
+
? "verified"
|
|
343
|
+
: "downgraded";
|
|
344
|
+
}
|
|
345
|
+
catch {
|
|
346
|
+
return "unverified";
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
};
|
|
350
|
+
{
|
|
351
|
+
const checked = await Promise.all([...efforts]
|
|
352
|
+
.filter((effort) => !documented.includes(effort))
|
|
353
|
+
.map(async (effort) => ({
|
|
354
|
+
effort,
|
|
355
|
+
status: await attempt({ effort }),
|
|
356
|
+
})));
|
|
357
|
+
for (const { effort, status } of checked) {
|
|
358
|
+
const effective = keep(`effort:${effort}`, status);
|
|
359
|
+
result.status[`effort:${effort}`] = effective;
|
|
360
|
+
if (effective === "verified")
|
|
361
|
+
result.levels.push(effort);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
const effort = result.levels.includes("low") ? "low" : result.levels[0];
|
|
365
|
+
result.status.responses = keep("responses", await attempt({ compatibility: true, effort }));
|
|
366
|
+
const checkedTiers = await Promise.all(["fast", "ultrafast"].map(async (tier) => ({
|
|
367
|
+
tier,
|
|
368
|
+
status: await attempt({ tier: tier === "fast" ? "priority" : tier, effort }),
|
|
369
|
+
})));
|
|
370
|
+
for (const { tier, status } of checkedTiers) {
|
|
371
|
+
const effective = keep(tier, status);
|
|
372
|
+
result.status[tier] = effective;
|
|
373
|
+
if (effective === "verified")
|
|
374
|
+
result.tiers.push(tier);
|
|
375
|
+
}
|
|
376
|
+
if (modelDenied) {
|
|
377
|
+
result.levels = [];
|
|
378
|
+
result.tiers = [];
|
|
379
|
+
for (const name of Object.keys(result.status))
|
|
380
|
+
result.status[name] = "unsupported";
|
|
381
|
+
result.status.responses = "unsupported";
|
|
382
|
+
}
|
|
383
|
+
if (credentialUnavailable && !modelDenied)
|
|
384
|
+
result.status.retry = "transient";
|
|
385
|
+
result.at = this.now();
|
|
386
|
+
if (this.probes.size >= 1000)
|
|
387
|
+
this.probes.delete(this.probes.keys().next().value ?? "");
|
|
388
|
+
this.probes.set(key, result);
|
|
389
|
+
return result;
|
|
390
|
+
}
|
|
391
|
+
async enrich(models, refresh = false, route, forceProbes = false) {
|
|
392
|
+
return mapWithConcurrency(models, 3, async (model) => {
|
|
393
|
+
const documented = await this.documentation(model.slug, refresh);
|
|
394
|
+
let levels = documented.levels;
|
|
395
|
+
let extra = {};
|
|
396
|
+
if (route?.enabled && route.probeCapabilities) {
|
|
397
|
+
const probed = await this.probe(route, model.slug, levels, forceProbes);
|
|
398
|
+
levels = probed.levels;
|
|
399
|
+
extra = {
|
|
400
|
+
service_tiers: probed.tiers.map((id) => ({
|
|
401
|
+
id: id === "fast" ? "priority" : id,
|
|
402
|
+
name: id === "fast" ? "Fast" : "Ultrafast",
|
|
403
|
+
description: "Verified by an API probe; runtime capacity can still downgrade processing.",
|
|
404
|
+
})),
|
|
405
|
+
default_service_tier: "default",
|
|
406
|
+
additional_speed_tiers: probed.tiers,
|
|
407
|
+
capability_probe_status: probed.status,
|
|
408
|
+
capability_checked_at: probed.at,
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
// Ultra is a native orchestration mode. Codex resolves it to this
|
|
412
|
+
// supported wire effort; it is not an API entitlement named "ultra".
|
|
413
|
+
const multiAgentEffort = ["max", "xhigh", "high"].find((level) => levels.includes(level)) ?? null;
|
|
414
|
+
const nativeLevels = multiAgentEffort
|
|
415
|
+
? [...levels, "ultra"]
|
|
416
|
+
: levels;
|
|
417
|
+
return {
|
|
418
|
+
...model,
|
|
419
|
+
...extra,
|
|
420
|
+
...(documented.inputModalities ? { input_modalities: documented.inputModalities } : {}),
|
|
421
|
+
multi_agent_reasoning_effort: multiAgentEffort,
|
|
422
|
+
supported_reasoning_levels: nativeLevels.map((effort) => ({
|
|
423
|
+
effort,
|
|
424
|
+
description: effort === "ultra"
|
|
425
|
+
? "Proactive multi-agent mode using a supported API reasoning effort"
|
|
426
|
+
: `${effort} reasoning effort`,
|
|
427
|
+
})),
|
|
428
|
+
default_reasoning_level: levels.includes("medium")
|
|
429
|
+
? "medium"
|
|
430
|
+
: (levels[0] ?? null),
|
|
431
|
+
};
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ApiRouteCredential } from "../api-route-store.js";
|
|
2
|
+
import { type RouteCatalog, type RouteModel, modelEntitlements } from "../model-route-policy.js";
|
|
3
|
+
/** Endpoint-family exclusions, not a fixed allowlist of text model releases.
|
|
4
|
+
* Model ID discovery alone does not prove Responses/tool compatibility. */
|
|
5
|
+
export declare function isNonResponsesModel(id: string): boolean;
|
|
6
|
+
/** Conservative native-picker metadata: discovery proves an ID, not optional tool capabilities. */
|
|
7
|
+
export declare function apiPickerModel(id: string): RouteModel;
|
|
8
|
+
export declare function boundedJson(response: Response, max?: number): Promise<unknown>;
|
|
9
|
+
export interface ApiCatalogStatus {
|
|
10
|
+
id: string;
|
|
11
|
+
kind: "api" | "zdr";
|
|
12
|
+
label: string;
|
|
13
|
+
priority: number;
|
|
14
|
+
checkedAt: number;
|
|
15
|
+
error: boolean;
|
|
16
|
+
availableModels: string[];
|
|
17
|
+
visibleModels: string[];
|
|
18
|
+
entitlements: ReturnType<typeof modelEntitlements>[];
|
|
19
|
+
}
|
|
20
|
+
export declare class ApiModelRuntime {
|
|
21
|
+
private readonly fetchImpl;
|
|
22
|
+
private readonly now;
|
|
23
|
+
private readonly updateDiscovery?;
|
|
24
|
+
private readonly enrichModels?;
|
|
25
|
+
private readonly onCatalogUpdated?;
|
|
26
|
+
private readonly discoveryUpdates;
|
|
27
|
+
lastPersistenceError: string | null;
|
|
28
|
+
private readonly failures;
|
|
29
|
+
private readonly visibility;
|
|
30
|
+
private readonly snapshots;
|
|
31
|
+
private activeKeys;
|
|
32
|
+
cachedCatalogs(): RouteCatalog[];
|
|
33
|
+
private readonly cache;
|
|
34
|
+
constructor(fetchImpl?: typeof fetch, now?: () => number, updateDiscovery?: ((route: ApiRouteCredential, models: string[]) => Promise<ApiRouteCredential>) | undefined, enrichModels?: ((models: RouteModel[], refresh: boolean, route: ApiRouteCredential, forceProbes: boolean) => Promise<RouteModel[]>) | undefined, onCatalogUpdated?: (() => void) | undefined);
|
|
35
|
+
private key;
|
|
36
|
+
catalogs(routes: ApiRouteCredential[], refresh?: boolean, forceProbes?: boolean, waitForCapabilities?: boolean, waitForPersistence?: boolean, requestKind?: "oauth" | "api" | "zdr"): Promise<RouteCatalog[]>;
|
|
37
|
+
statuses(routes: ApiRouteCredential[]): ApiCatalogStatus[];
|
|
38
|
+
request(alias: string, body: Record<string, unknown>, routes: ApiRouteCredential[], signal?: AbortSignal, onAttempt?: (credentialIndex: number) => void): Promise<Response>;
|
|
39
|
+
recordStreamFailure(credential: ApiRouteCredential, alias: string, body: Record<string, unknown>, error: unknown): void;
|
|
40
|
+
private failure;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=api-model-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-model-runtime.d.ts","sourceRoot":"","sources":["../../../lib/runtime/api-model-runtime.ts"],"names":[],"mappings":"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"}
|