@bitkyc08/opencodex 2.58.0 → 2.60.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/README.md +28 -10
- package/gui/dist/assets/index-BTuCbqQd.css +1 -0
- package/gui/dist/assets/index-DoBVdPHP.js +134 -0
- package/gui/dist/index.html +2 -2
- package/gui/dist/provider-icons/crusoe.svg +1 -0
- package/gui/dist/provider-icons/opper.svg +3 -0
- package/package.json +4 -1
- package/src/adapters/anthropic-image-codec.ts +16 -2
- package/src/adapters/anthropic-image-normalize.ts +49 -2
- package/src/adapters/anthropic.ts +4 -1
- package/src/adapters/base.ts +34 -1
- package/src/adapters/coding-agent/turn.ts +22 -2
- package/src/adapters/command-code.ts +50 -3
- package/src/adapters/cursor/catalog.ts +11 -0
- package/src/adapters/cursor/checkpoint-store.ts +3 -0
- package/src/adapters/cursor/discovery.ts +11 -8
- package/src/adapters/cursor/effort-map.ts +16 -2
- package/src/adapters/cursor/envelope-echo.ts +55 -2
- package/src/adapters/cursor/live-transport.ts +26 -9
- package/src/adapters/cursor/message-mapper.ts +3 -2
- package/src/adapters/cursor/protobuf-request.ts +8 -5
- package/src/adapters/cursor/request-builder.ts +21 -4
- package/src/adapters/cursor/thread-continuity.ts +105 -31
- package/src/adapters/cursor/tool-guidance.ts +5 -4
- package/src/adapters/cursor/transport.ts +19 -0
- package/src/adapters/cursor.ts +45 -2
- package/src/adapters/devin/cloud-direct/chat.ts +14 -3
- package/src/adapters/devin/cloud-direct/index.ts +7 -0
- package/src/adapters/devin/cloud-direct/stated-reset-retry.ts +140 -0
- package/src/adapters/devin.ts +125 -26
- package/src/adapters/google-antigravity-replay.ts +1 -1
- package/src/adapters/google-antigravity-wire.ts +55 -4
- package/src/adapters/google-http.ts +57 -11
- package/src/adapters/google-tool-schema.ts +595 -31
- package/src/adapters/google-wire-compiler.ts +93 -10
- package/src/adapters/google-wire-shape.ts +461 -0
- package/src/adapters/google.ts +60 -10
- package/src/adapters/openai-chat/response-events.ts +61 -0
- package/src/adapters/openai-chat-images.ts +3 -1
- package/src/adapters/openai-chat.ts +10 -11
- package/src/adapters/openai-responses/image-gen.ts +8 -6
- package/src/adapters/openai-responses/passthrough.ts +25 -4
- package/src/adapters/openai-responses/reasoning.ts +7 -0
- package/src/adapters/openai-responses/tool-output-recovery.ts +75 -0
- package/src/adapters/openai-responses/tool-schema.ts +19 -7
- package/src/adapters/opencode-go-additional-tools.ts +12 -2
- package/src/adapters/responses-tool-schema.ts +76 -46
- package/src/adapters/run-turn-queue.ts +17 -4
- package/src/bridge/response-json.ts +1 -1
- package/src/bridge/sse.ts +28 -35
- package/src/claude/context-windows.ts +22 -0
- package/src/claude/outbound.ts +35 -4
- package/src/cli/account-api.ts +4 -3
- package/src/cli/account-extended.ts +26 -6
- package/src/cli/account-orca-import.ts +63 -0
- package/src/cli/account.ts +32 -4
- package/src/cli/capabilities.ts +40 -0
- package/src/cli/claude.ts +29 -1
- package/src/cli/codex-cli-update.ts +97 -2
- package/src/cli/dispatch.ts +57 -3
- package/src/cli/doctor.ts +218 -4
- package/src/cli/help.ts +4 -1
- package/src/cli/hub.ts +3 -2
- package/src/cli/index.ts +95 -22
- package/src/cli/models-runtime.ts +33 -4
- package/src/cli/opencode.ts +2 -2
- package/src/cli/provider.ts +13 -1
- package/src/cli/registry.ts +11 -1
- package/src/cli/runtime-api.ts +44 -0
- package/src/cli/start-args.ts +94 -0
- package/src/cli/system-command.ts +2 -0
- package/src/client/machine-api.ts +6 -5
- package/src/client/machine-listener.ts +16 -3
- package/src/client/runtime.ts +26 -2
- package/src/clients/config-export/constants.ts +2 -3
- package/src/clients/config-export.ts +5 -5
- package/src/codex/account-store.ts +146 -5
- package/src/codex/auth-api/account-list.ts +19 -11
- package/src/codex/auth-api/pool-quota-probe.ts +44 -10
- package/src/codex/auth-api/routes.ts +17 -2
- package/src/codex/auth-context.ts +16 -12
- package/src/codex/catalog/build-entries.ts +25 -4
- package/src/codex/catalog/derive-entry.ts +8 -1
- package/src/codex/catalog/effort.ts +10 -6
- package/src/codex/catalog/gather-capture.ts +22 -2
- package/src/codex/catalog/model-hints.ts +66 -33
- package/src/codex/catalog/parsing.ts +90 -5
- package/src/codex/catalog/provider-models.ts +19 -2
- package/src/codex/catalog/reserve-warn.ts +96 -0
- package/src/codex/catalog/retained-sync.ts +41 -26
- package/src/codex/catalog/routed-gather.ts +61 -3
- package/src/codex/cli-installation-identity.ts +210 -0
- package/src/codex/cli-installation-targets.ts +158 -0
- package/src/codex/context-compat.ts +5 -2
- package/src/codex/convergence.ts +5 -0
- package/src/codex/desired-state.ts +4 -1
- package/src/codex/history-job.ts +6 -6
- package/src/codex/history-provider.ts +24 -167
- package/src/codex/history-rollout-read.ts +174 -0
- package/src/codex/history-state-open.ts +105 -0
- package/src/codex/inject/config-toml.ts +44 -2
- package/src/codex/inject.ts +3 -2
- package/src/codex/internal/catalog-writer.ts +33 -1
- package/src/codex/lineage.ts +83 -32
- package/src/codex/loopback-target.ts +31 -0
- package/src/codex/main-account-hard-lock.ts +2 -1
- package/src/codex/main-account.ts +10 -3
- package/src/codex/main-device-reauth.ts +17 -9
- package/src/codex/model-cache.ts +47 -0
- package/src/codex/model-entitlements.ts +80 -2
- package/src/codex/observed-model-denials.ts +230 -0
- package/src/codex/orca-auth-source.ts +94 -0
- package/src/codex/orca-import.ts +219 -0
- package/src/codex/prompt-text-probe.ts +289 -16
- package/src/codex/quota-401-recovery.ts +12 -0
- package/src/codex/quota-types.ts +65 -0
- package/src/codex/quota.ts +24 -19
- package/src/codex/routing/cooldown-math.ts +8 -47
- package/src/codex/routing/pin-drain.ts +57 -0
- package/src/codex/routing.ts +20 -16
- package/src/codex/shim.ts +1 -1
- package/src/codex/subagent-model-fallback.ts +114 -2
- package/src/codex/windows-installation-files.ts +224 -0
- package/src/combos/failover.ts +125 -5
- package/src/config/admitted-identity.ts +222 -0
- package/src/config/diagnostics.ts +43 -1
- package/src/config/feature-flags.ts +5 -0
- package/src/config/load-degrade.ts +33 -0
- package/src/config/pending-teardown.ts +8 -0
- package/src/config/process-state.ts +36 -3
- package/src/config/provider-relative-send-path.ts +16 -0
- package/src/config/proxy-env.ts +31 -7
- package/src/config/schema/compaction-triggers.ts +11 -0
- package/src/config/schema/config-schema.ts +25 -0
- package/src/config/schema/leaf-validators.ts +76 -17
- package/src/config.ts +2 -2
- package/src/generated/compatibility-version.json +410 -258
- package/src/generated/model-metadata.ts +1 -1
- package/src/grok/reset-coupons.ts +38 -19
- package/src/images/loop.ts +6 -1
- package/src/integrations/aside-profile-context.ts +37 -3
- package/src/integrations/aside-profile-journal.ts +68 -3
- package/src/integrations/aside-profiles.ts +128 -3
- package/src/integrations/mutation-plan.ts +815 -0
- package/src/integrations/writer.ts +85 -99
- package/src/lab/live/transport.ts +4 -0
- package/src/lab/live/types.ts +5 -0
- package/src/lab/subject/behavior-fingerprint.ts +1 -1
- package/src/lib/admin-secrets.ts +9 -1
- package/src/lib/bounded-body.ts +4 -2
- package/src/lib/debug-log-buffer.ts +6 -1
- package/src/lib/debug.ts +23 -0
- package/src/lib/destination-policy.ts +48 -6
- package/src/lib/errors.ts +82 -15
- package/src/lib/http-response-semantics.ts +57 -0
- package/src/lib/lab-live-pinned-sender.ts +26 -12
- package/src/lib/local-destinations.ts +32 -5
- package/src/lib/pinned-http.ts +142 -2
- package/src/lib/plain-data.ts +103 -0
- package/src/lib/process-control.ts +13 -5
- package/src/lib/provider-outbound.ts +53 -5
- package/src/lib/proxy-env.ts +70 -3
- package/src/lib/request-execution-budget.ts +11 -3
- package/src/lib/response-body-inactivity.ts +193 -0
- package/src/lib/retry-delay.ts +69 -0
- package/src/lib/socks5-fetch.ts +741 -0
- package/src/lib/spend-ledger-owner.ts +364 -0
- package/src/lib/spend-reservation-ledger.ts +332 -35
- package/src/lib/windows-system-proxy.ts +16 -11
- package/src/lib/workflow-budget.ts +145 -8
- package/src/oauth/account-quota-rank.ts +72 -15
- package/src/oauth/callback-server.ts +4 -3
- package/src/oauth/generic-account-failover.ts +41 -27
- package/src/oauth/health.ts +12 -1
- package/src/oauth/index.ts +3 -107
- package/src/oauth/login-flow-state.ts +127 -0
- package/src/oauth/orcarouter.ts +15 -2
- package/src/oauth/store.ts +8 -0
- package/src/providers/codex-capacity.ts +9 -0
- package/src/providers/derive.ts +34 -17
- package/src/providers/devin-cli-authmode-migration.ts +14 -10
- package/src/providers/devin-provider-merge-migration.ts +33 -12
- package/src/providers/free-directory.ts +20 -2
- package/src/providers/key-failover.ts +327 -25
- package/src/providers/model-rename-migration.ts +56 -1
- package/src/providers/model-rename-startup.ts +7 -5
- package/src/providers/openai-sidecar.ts +4 -0
- package/src/providers/openai-virtual-models.ts +42 -2
- package/src/providers/opencode-go-transport.ts +14 -5
- package/src/providers/quota/antigravity.ts +22 -2
- package/src/providers/quota/report-cache.ts +3 -0
- package/src/providers/quota/vendor-probes-key.ts +1 -1
- package/src/providers/registry/entries-core.ts +39 -17
- package/src/providers/registry/entries-extended.ts +131 -1
- package/src/providers/registry/model-ids.ts +168 -0
- package/src/providers/registry/model-seeds.ts +87 -21
- package/src/providers/registry/types.ts +2 -0
- package/src/providers/resolved-model-policy-merge.ts +167 -0
- package/src/providers/resolved-model-policy.ts +406 -0
- package/src/providers/stale-vision-classification-migration.ts +137 -0
- package/src/responses/apply-patch-envelope.ts +32 -11
- package/src/responses/bridge-search-replay-cache.ts +152 -0
- package/src/responses/code-mode-helper-compat.ts +26 -16
- package/src/responses/custom-tool-compat.ts +1 -1
- package/src/responses/freeform-wrapper-scan.ts +279 -0
- package/src/responses/hosted-tool-policy.ts +85 -2
- package/src/responses/legacy-dotted-tool-name-repair.ts +134 -0
- package/src/responses/progressive-freeform-input.ts +130 -0
- package/src/responses/reasoning-envelope.ts +30 -0
- package/src/responses/schema.ts +9 -2
- package/src/responses/state.ts +5 -12
- package/src/responses/tool-name-aliases.ts +15 -1
- package/src/router.ts +91 -115
- package/src/routing/compatibility/behavior.ts +9 -0
- package/src/routing/compatibility/subject.ts +16 -1
- package/src/server/adapter-resolve.ts +9 -0
- package/src/server/auth-cors.ts +29 -0
- package/src/server/chat-completions.ts +13 -5
- package/src/server/chat-native-sse.ts +26 -9
- package/src/server/chat-native.ts +10 -4
- package/src/server/claude-messages.ts +30 -5
- package/src/server/effort-row.ts +11 -3
- package/src/server/grok-responses-control-frame.ts +160 -1
- package/src/server/gui-static.ts +36 -2
- package/src/server/inbound-body-admission.ts +187 -0
- package/src/server/index/serve-options.ts +86 -29
- package/src/server/index/spend-ledger-lifecycle.ts +66 -0
- package/src/server/index/websocket-handler.ts +6 -1
- package/src/server/index.ts +24 -25
- package/src/server/management/api-access.ts +3 -4
- package/src/server/management/aside-profile-routes.ts +266 -7
- package/src/server/management/config-routes.ts +48 -7
- package/src/server/management/context.ts +3 -0
- package/src/server/management/integration-routes.ts +287 -5
- package/src/server/management/metrics-routes.ts +20 -0
- package/src/server/management/model-rows.ts +224 -12
- package/src/server/management/provider-capability-config.ts +35 -7
- package/src/server/management/provider-routes.ts +70 -18
- package/src/server/management/route-registry.ts +14 -0
- package/src/server/management/shared.ts +10 -3
- package/src/server/management/system-restart.ts +7 -2
- package/src/server/management/system-routes.ts +2 -0
- package/src/server/management/usage-aggregate-cache.ts +4 -0
- package/src/server/management-api.ts +2 -0
- package/src/server/management-auth.ts +15 -1
- package/src/server/proxy-liveness.ts +97 -2
- package/src/server/readiness.ts +29 -10
- package/src/server/relay-eager.ts +24 -2
- package/src/server/relay.ts +136 -34
- package/src/server/request-log.ts +80 -3
- package/src/server/request-metrics.ts +236 -0
- package/src/server/responses/adapter-continuation.ts +74 -30
- package/src/server/responses/adapter-delivery.ts +39 -8
- package/src/server/responses/adapter-dispatch.ts +63 -30
- package/src/server/responses/compact.ts +89 -18
- package/src/server/responses/compaction-routing.ts +111 -0
- package/src/server/responses/core-codex-account.ts +90 -24
- package/src/server/responses/core-combo.ts +7 -7
- package/src/server/responses/core-normalize.ts +16 -15
- package/src/server/responses/core-opaque-recovery.ts +1 -0
- package/src/server/responses/core-options.ts +4 -0
- package/src/server/responses/encrypted-payload.ts +20 -2
- package/src/server/responses/fetch-helpers.ts +68 -2
- package/src/server/responses/passthrough-delivery.ts +41 -15
- package/src/server/responses/passthrough-dispatch.ts +145 -53
- package/src/server/responses/passthrough-execution.ts +11 -1
- package/src/server/responses/policy-fallback.ts +5 -13
- package/src/server/responses/request-prepare.ts +96 -17
- package/src/server/responses/request-send-budget.ts +89 -8
- package/src/server/responses/request-sidecar-auth.ts +17 -9
- package/src/server/responses/request-spend.ts +38 -9
- package/src/server/responses/request-transport.ts +15 -12
- package/src/server/responses/run-turn-execution.ts +45 -8
- package/src/server/responses/sidecar-execution.ts +19 -2
- package/src/server/responses/ws-upstream.ts +16 -28
- package/src/server/responses-custom-tool-repair.ts +29 -56
- package/src/server/responses-undeclared-tool-guard.ts +31 -1
- package/src/server/sse-frame-buffer.ts +12 -10
- package/src/server/sse-payload-rewrite.ts +37 -10
- package/src/server/system-env-shell.ts +5 -1
- package/src/server/system-env.ts +7 -1
- package/src/server/workflow-refusal.ts +56 -2
- package/src/service/cli.ts +16 -6
- package/src/service/guards.ts +10 -0
- package/src/service/health.ts +43 -0
- package/src/service/state.ts +7 -2
- package/src/tray/windows-tray.ps1 +155 -3
- package/src/types/accounts.ts +4 -0
- package/src/types/config.ts +111 -6
- package/src/types/provider.ts +37 -0
- package/src/types/request.ts +9 -1
- package/src/types/tools.ts +14 -0
- package/src/types/wire.ts +9 -1
- package/src/types.ts +1 -0
- package/src/usage/expected-prices.ts +28 -0
- package/src/usage/log.ts +87 -4
- package/src/vision/eligibility.ts +88 -9
- package/src/vision/plan.ts +34 -10
- package/src/web-search/executor.ts +41 -2
- package/src/web-search/loop.ts +6 -1
- package/src/web-search/passthrough-bridge.ts +39 -5
- package/gui/dist/assets/index-BbrHOIY0.js +0 -128
- package/gui/dist/assets/index-C5-RdDmD.css +0 -1
|
@@ -177,6 +177,15 @@ export const META_MUSE_REASONING_EFFORTS = ["minimal", "low", "medium", "high",
|
|
|
177
177
|
export const META_MUSE_REASONING_EFFORT_MAP: Record<string, string> = Object.fromEntries(
|
|
178
178
|
META_MUSE_REASONING_EFFORTS.map(effort => [effort, effort]),
|
|
179
179
|
);
|
|
180
|
+
/*
|
|
181
|
+
* Muse Code credentials have a separate capability contract. Meta's authenticated
|
|
182
|
+
* /muse-code/models roster advertises max for both 1.3 models, and the Responses API
|
|
183
|
+
* accepts it when the request identifies the Muse client surface.
|
|
184
|
+
*/
|
|
185
|
+
export const META_MUSE_CODE_REASONING_EFFORTS = [...META_MUSE_REASONING_EFFORTS, "max"];
|
|
186
|
+
export const META_MUSE_CODE_REASONING_EFFORT_MAP: Record<string, string> = Object.fromEntries(
|
|
187
|
+
META_MUSE_CODE_REASONING_EFFORTS.map(effort => [effort, effort]),
|
|
188
|
+
);
|
|
180
189
|
/** Both Muse Spark 1.3 tiers publish a 1,048,576-token window (dev.meta.ai/docs/models). */
|
|
181
190
|
export const META_MUSE_CONTEXT_WINDOW = 1_048_576;
|
|
182
191
|
export const META_MUSE_MODELS = ["muse-spark-1.3", "muse-spark-1.3-contributor"];
|
|
@@ -315,6 +324,13 @@ export const DEEPSEEK_VISION_PREVIEW_MODEL = "deepseek-v4-flash-vision-exp";
|
|
|
315
324
|
*/
|
|
316
325
|
export const COMMAND_CODE_IMAGE_MODELS = [
|
|
317
326
|
`deepseek/${DEEPSEEK_VISION_PREVIEW_MODEL}`,
|
|
327
|
+
// Probed 2026-09-18 through a running 2.58.0 proxy: a 3x3 random-color grid
|
|
328
|
+
// (180x180 PNG, six candidate colors) came back 9/9 correct both as a user
|
|
329
|
+
// message and as a tool_result, and the request logs show the route served
|
|
330
|
+
// the image natively — no vision-sidecar call in either window. #4505 asked
|
|
331
|
+
// for exactly this upstream probe before promoting the id. The sibling
|
|
332
|
+
// deepseek/deepseek-v4-flash route remains verified-negative above.
|
|
333
|
+
"deepseek/deepseek-v4.1-flash",
|
|
318
334
|
"gpt-5.6-luna",
|
|
319
335
|
"gpt-5.6-sol",
|
|
320
336
|
"MiniMaxAI/MiniMax-M3",
|
|
@@ -334,20 +350,19 @@ export const COMMAND_CODE_IMAGE_MODELS = [
|
|
|
334
350
|
/**
|
|
335
351
|
* Native image stays sourced from COMMAND_CODE_IMAGE_MODELS. Text-only routes
|
|
336
352
|
* sit beside that list so the catalog can still advertise sidecar coverage
|
|
337
|
-
* without claiming the gateway itself accepts a picture.
|
|
338
|
-
*
|
|
339
|
-
* The gateway-prefixed DeepSeek V4.1 Flash route has no verified native image
|
|
340
|
-
* support, so declaring it image-capable would hand it a picture it drops. A
|
|
341
|
-
* positive text-only declaration makes it a vision-sidecar consumer
|
|
353
|
+
* without claiming the gateway itself accepts a picture. A positive text-only
|
|
354
|
+
* declaration makes the route a vision-sidecar consumer
|
|
342
355
|
* (src/vision/eligibility.ts), so the catalog advertises image input on its
|
|
343
|
-
* behalf
|
|
344
|
-
*
|
|
345
|
-
*
|
|
346
|
-
*
|
|
356
|
+
* behalf — without claiming native vision — and modelInputModalities is
|
|
357
|
+
* per-key filled, so that reaches an existing install even when noVisionModels
|
|
358
|
+
* was persisted before the id joined a list.
|
|
359
|
+
*
|
|
360
|
+
* Empty as of 2026-09-18. Its only entry, deepseek/deepseek-v4.1-flash, moved
|
|
361
|
+
* to COMMAND_CODE_IMAGE_MODELS once the #4505-requested probe passed on both
|
|
362
|
+
* the user-message and tool-result paths (see the note at that entry). The
|
|
363
|
+
* mechanism stays for the next route that measures text-only.
|
|
347
364
|
*/
|
|
348
|
-
export const COMMAND_CODE_TEXT_ONLY_MODELS = [
|
|
349
|
-
"deepseek/deepseek-v4.1-flash",
|
|
350
|
-
] as const;
|
|
365
|
+
export const COMMAND_CODE_TEXT_ONLY_MODELS = [] as const;
|
|
351
366
|
export const COMMAND_CODE_MODEL_INPUT_MODALITIES: Record<string, ["text"] | ["text", "image"]> = {
|
|
352
367
|
...Object.fromEntries(COMMAND_CODE_IMAGE_MODELS.map(id => [id, ["text", "image"] as ["text", "image"]])),
|
|
353
368
|
...Object.fromEntries(COMMAND_CODE_TEXT_ONLY_MODELS.map(id => [id, ["text"] as ["text"]])),
|
|
@@ -439,9 +454,15 @@ export const deepseekReasoningMapFor = (modelId: string): Record<string, string>
|
|
|
439
454
|
// https://help.aliyun.com/en/model-studio/token-plan-quickstart
|
|
440
455
|
// 260909 refresh, re-probed against the live gateway (both regions, both tiers):
|
|
441
456
|
// https://github.com/oliver-mee/alibaba-token-plan-wiki (machine-readable catalog).
|
|
442
|
-
// glm-5.3
|
|
443
|
-
//
|
|
444
|
-
//
|
|
457
|
+
// 260918: glm-5.3 returns. The 260909 removal was correct at the time (the id
|
|
458
|
+
// 404'd on every plan key), but the gateway started serving glm-5.3 on 260917:
|
|
459
|
+
// it now appears on /models for global Team, global Personal, and CN Team, and
|
|
460
|
+
// answers a completion on a Personal key (probed 260918). Contract on the plan
|
|
461
|
+
// gateway: effort low/high/max (default max), thinking always-on (the gateway
|
|
462
|
+
// rejects enable_thinking:false with 400), 1M context, 131,072 max output,
|
|
463
|
+
// text-only input, strict json_schema accepted. glm-5.3-flash REMAINS OUT:
|
|
464
|
+
// still never served by the Token Plan gateway (docs.z.ai VLM id, not plan
|
|
465
|
+
// entitlement).
|
|
445
466
|
// The Beijing preset keeps the Personal Edition subset; non-chat ids (audio/image/
|
|
446
467
|
// video families) stay out: they answer only on async endpoints openai-chat cannot
|
|
447
468
|
// reach. deepseek-v4-pro-0813 is callable but NOT listed by /models, which is the
|
|
@@ -457,7 +478,7 @@ export const deepseekReasoningMapFor = (modelId: string): Record<string, string>
|
|
|
457
478
|
// drifting ones.
|
|
458
479
|
export const ALIBABA_TOKEN_PLAN_MODELS = [
|
|
459
480
|
"qwen3.8-max", "qwen3.8-flash", "qwen3.7-max", "qwen3.7-plus", "qwen3.6-flash",
|
|
460
|
-
"deepseek-v4-pro", "deepseek-v4-flash-0731", "deepseek-v4.1-flash", "glm-5.2",
|
|
481
|
+
"deepseek-v4-pro", "deepseek-v4-flash-0731", "deepseek-v4.1-flash", "glm-5.2", "glm-5.3",
|
|
461
482
|
];
|
|
462
483
|
export const ALIBABA_TOKEN_PLAN_QWEN_MODELS = [
|
|
463
484
|
"qwen3.8-max", "qwen3.8-flash", "qwen3.7-max", "qwen3.7-plus", "qwen3.6-flash",
|
|
@@ -474,6 +495,7 @@ export const ALIBABA_TOKEN_PLAN_INPUT_MODALITIES: Record<string, string[]> = {
|
|
|
474
495
|
// Vision probed on the plan gateway 260915 (user message and tool result, both 200).
|
|
475
496
|
"deepseek-v4.1-flash": ["text", "image"],
|
|
476
497
|
"glm-5.2": ["text"],
|
|
498
|
+
"glm-5.3": ["text"],
|
|
477
499
|
};
|
|
478
500
|
|
|
479
501
|
// 260721 Alibaba Token Plan International (ap-southeast-1 / Singapore, hardened 260721).
|
|
@@ -487,7 +509,7 @@ export const ALIBABA_INTL_TOKEN_PLAN_MODELS = [
|
|
|
487
509
|
"qwen3.8-max", "qwen3.8-flash", "qwen3.7-max", "qwen3.7-plus", "qwen3.6-plus", "qwen3.6-flash",
|
|
488
510
|
"deepseek-v4-pro", "deepseek-v4-pro-0813", "deepseek-v4-flash", "deepseek-v4-flash-0731", "deepseek-v4.1-flash", "deepseek-v3.2",
|
|
489
511
|
"kimi-k2.7-code", "kimi-k2.6", "kimi-k2.5",
|
|
490
|
-
"glm-5.2", "glm-5.1", "glm-5",
|
|
512
|
+
"glm-5.2", "glm-5.3", "glm-5.1", "glm-5",
|
|
491
513
|
"MiniMax-M2.5",
|
|
492
514
|
];
|
|
493
515
|
export const ALIBABA_INTL_TOKEN_PLAN_QWEN_MODELS = [
|
|
@@ -589,7 +611,7 @@ export const ALIBABA_TOKEN_PLAN_CONTEXT_WINDOWS: Record<string, number> = {
|
|
|
589
611
|
"deepseek-v4-pro": 1_000_000, "deepseek-v4-pro-0813": 1_000_000, "deepseek-v4-flash": 1_000_000,
|
|
590
612
|
"deepseek-v4-flash-0731": 1_000_000, "deepseek-v4.1-flash": 1_000_000, "deepseek-v3.2": 131_072,
|
|
591
613
|
"kimi-k2.7-code": 262_144, "kimi-k2.6": 262_144, "kimi-k2.5": 262_144,
|
|
592
|
-
"glm-5.2": 1_000_000, "glm-5.1": 202_752, "glm-5": 202_752,
|
|
614
|
+
"glm-5.2": 1_000_000, "glm-5.3": 1_000_000, "glm-5.1": 202_752, "glm-5": 202_752,
|
|
593
615
|
"MiniMax-M2.5": 196_608,
|
|
594
616
|
};
|
|
595
617
|
export const ALIBABA_TOKEN_PLAN_MAX_OUTPUT_TOKENS: Record<string, number> = {
|
|
@@ -598,17 +620,17 @@ export const ALIBABA_TOKEN_PLAN_MAX_OUTPUT_TOKENS: Record<string, number> = {
|
|
|
598
620
|
"deepseek-v4-pro": 393_216, "deepseek-v4-pro-0813": 393_216, "deepseek-v4-flash": 393_216,
|
|
599
621
|
"deepseek-v4-flash-0731": 393_216, "deepseek-v4.1-flash": 393_216, "deepseek-v3.2": 65_536,
|
|
600
622
|
"kimi-k2.7-code": 262_144, "kimi-k2.6": 262_144, "kimi-k2.5": 98_304,
|
|
601
|
-
"glm-5.2": 131_072, "glm-5.1": 128_000, "glm-5": 16_384,
|
|
623
|
+
"glm-5.2": 131_072, "glm-5.3": 131_072, "glm-5.1": 128_000, "glm-5": 16_384,
|
|
602
624
|
"MiniMax-M2.5": 32_768,
|
|
603
625
|
};
|
|
604
626
|
export const ALIBABA_TOKEN_PLAN_NO_VISION = [
|
|
605
627
|
"qwen3.7-max", "deepseek-v4-pro", "deepseek-v4-pro-0813", "deepseek-v4-flash",
|
|
606
|
-
"deepseek-v4-flash-0731", "deepseek-v3.2", "glm-5.2", "glm-5.1", "glm-5", "MiniMax-M2.5",
|
|
628
|
+
"deepseek-v4-flash-0731", "deepseek-v3.2", "glm-5.2", "glm-5.3", "glm-5.1", "glm-5", "MiniMax-M2.5",
|
|
607
629
|
];
|
|
608
630
|
export const ALIBABA_TOKEN_PLAN_PRESERVE_REASONING = [
|
|
609
631
|
"qwen3.8-max", "qwen3.8-flash", "qwen3.7-max", "qwen3.7-plus", "qwen3.6-plus", "qwen3.6-flash",
|
|
610
632
|
"deepseek-v4-pro", "deepseek-v4-pro-0813", "deepseek-v4-flash", "deepseek-v4-flash-0731",
|
|
611
|
-
"deepseek-v4.1-flash", "glm-5.2",
|
|
633
|
+
"deepseek-v4.1-flash", "glm-5.2", "glm-5.3",
|
|
612
634
|
];
|
|
613
635
|
|
|
614
636
|
// 260717 Kimi K3: the subscription endpoint uses one upstream id (`k3`) for both
|
|
@@ -960,3 +982,47 @@ export const CLINE_PASS_TEXT_ONLY_MODELS = CLINE_PASS_MODALITY_KNOWN_MODELS.filt
|
|
|
960
982
|
export const CLINE_PASS_MODEL_INPUT_MODALITIES: Record<string, string[]> = Object.fromEntries(
|
|
961
983
|
CLINE_PASS_MODALITY_KNOWN_MODELS.map(id => [id, CLINE_PASS_IMAGE_MODELS.has(id) ? ["text", "image"] : ["text"]]),
|
|
962
984
|
);
|
|
985
|
+
|
|
986
|
+
// Opper seed: bare *pool* names. A pool is every provider Opper serves that model through; Opper
|
|
987
|
+
// picks the route per request. Each name is the `.model` of a `pooled: true` entry in the public
|
|
988
|
+
// catalogue snapshot supplied by the original provider author
|
|
989
|
+
// (https://api.opper.ai/v3/models?limit=2000, captured 2026-09-14); `vendor/model` ids
|
|
990
|
+
// (anthropic/claude-sonnet-4-6) pin one route and stay valid, they are just not seeded.
|
|
991
|
+
export const OPPER_MODELS = [
|
|
992
|
+
"claude-sonnet-4-6",
|
|
993
|
+
"claude-opus-5",
|
|
994
|
+
"gpt-5.5",
|
|
995
|
+
"gpt-5.4-mini",
|
|
996
|
+
"gemini-3.8-flash",
|
|
997
|
+
"deepseek-v4-pro",
|
|
998
|
+
"kimi-k3",
|
|
999
|
+
"mistral-large-2512",
|
|
1000
|
+
];
|
|
1001
|
+
// Smallest value across each pool's members in that snapshot, capped at the lab model's own limit
|
|
1002
|
+
// (kimi-k3 output); live discovery owns which models exist.
|
|
1003
|
+
export const OPPER_MODEL_CONTEXT_WINDOWS: Record<string, number> = {
|
|
1004
|
+
"claude-sonnet-4-6": 1_000_000,
|
|
1005
|
+
"claude-opus-5": 1_000_000,
|
|
1006
|
+
"gpt-5.5": 1_050_000,
|
|
1007
|
+
"gpt-5.4-mini": 400_000,
|
|
1008
|
+
"gemini-3.8-flash": 1_048_576,
|
|
1009
|
+
"deepseek-v4-pro": 1_000_000,
|
|
1010
|
+
"kimi-k3": 1_048_576,
|
|
1011
|
+
"mistral-large-2512": 256_000,
|
|
1012
|
+
};
|
|
1013
|
+
export const OPPER_MODEL_MAX_OUTPUT_TOKENS: Record<string, number> = {
|
|
1014
|
+
"claude-sonnet-4-6": 64_000,
|
|
1015
|
+
"claude-opus-5": 128_000,
|
|
1016
|
+
"gpt-5.5": 128_000,
|
|
1017
|
+
"gpt-5.4-mini": 128_000,
|
|
1018
|
+
"gemini-3.8-flash": 65_536,
|
|
1019
|
+
"deepseek-v4-pro": 65_536,
|
|
1020
|
+
"kimi-k3": 131_072,
|
|
1021
|
+
"mistral-large-2512": 8_192,
|
|
1022
|
+
};
|
|
1023
|
+
// Pools whose members do not all accept image input (deepseek-v4-pro: no member does; kimi-k3: the
|
|
1024
|
+
// sference route is text-only), so the shared modality set is text.
|
|
1025
|
+
export const OPPER_TEXT_ONLY_MODELS = ["deepseek-v4-pro", "kimi-k3"];
|
|
1026
|
+
export const OPPER_MODEL_INPUT_MODALITIES: Record<string, string[]> = Object.fromEntries(
|
|
1027
|
+
OPPER_MODELS.map(id => [id, OPPER_TEXT_ONLY_MODELS.includes(id) ? ["text"] : ["text", "image"]]),
|
|
1028
|
+
);
|
|
@@ -264,6 +264,8 @@ export interface ProviderRegistryEntry {
|
|
|
264
264
|
modelServiceTierCapabilityBaseUrlGuard?: (baseUrl: string) => boolean;
|
|
265
265
|
/** Registry default for plaintext reasoning replay; see `OcxProviderConfig.preserveResponsesReasoningContent`. Registry-only like `supportsServiceTier`. */
|
|
266
266
|
preserveResponsesReasoningContent?: boolean;
|
|
267
|
+
/** Registry default for dropping replayed reasoning items for Responses upstreams that reject them. */
|
|
268
|
+
dropResponsesReasoningItems?: boolean;
|
|
267
269
|
/** Registry defaults for per-model Codex reasoning propagation; explicit user keys win during enrichment. */
|
|
268
270
|
modelSupportsReasoningSummaries?: Record<string, boolean>;
|
|
269
271
|
/** Registry defaults for per-model Codex Responses verbosity support. */
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import type { OcxProviderConfig } from "../types";
|
|
2
|
+
import { MODEL_ADAPTER_OVERRIDE_ALLOWED } from "../types";
|
|
3
|
+
import type { InboundWire, ModelWireDefault, ProviderRegistryEntry } from "./registry/types";
|
|
4
|
+
|
|
5
|
+
export type StaticPolicySource =
|
|
6
|
+
| "operator" | "operator-capability" | "captured-auth"
|
|
7
|
+
| "registry" | "hard-pin" | "provider-default" | "unknown";
|
|
8
|
+
|
|
9
|
+
export function detachedClone<T>(value: T): T {
|
|
10
|
+
if (Array.isArray(value)) return value.map(item => detachedClone(item)) as T;
|
|
11
|
+
if (value && typeof value === "object") {
|
|
12
|
+
return Object.fromEntries(Object.entries(value as Record<string, unknown>)
|
|
13
|
+
.map(([key, nested]) => [key, detachedClone(nested)])) as T;
|
|
14
|
+
}
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function recursivelyFreeze<T>(value: T): T {
|
|
19
|
+
if (!value || typeof value !== "object" || Object.isFrozen(value)) return value;
|
|
20
|
+
for (const nested of Object.values(value as Record<string, unknown>)) recursivelyFreeze(nested);
|
|
21
|
+
return Object.freeze(value);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function scalar<T>(operator: T | undefined, registry: T | undefined): [T | undefined, StaticPolicySource] {
|
|
25
|
+
if (operator !== undefined) return [detachedClone(operator), "operator"];
|
|
26
|
+
if (registry !== undefined) return [detachedClone(registry), "registry"];
|
|
27
|
+
return [undefined, "unknown"];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function mapFill<T>(
|
|
31
|
+
registry: Readonly<Record<string, T>> | undefined,
|
|
32
|
+
operator: Readonly<Record<string, T>> | undefined,
|
|
33
|
+
): [Record<string, T> | undefined, StaticPolicySource] {
|
|
34
|
+
if (!registry && !operator) return [undefined, "unknown"];
|
|
35
|
+
return [detachedClone({ ...(registry ?? {}), ...(operator ?? {}) }), operator ? "operator" : "registry"];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function nestedMapFill(
|
|
39
|
+
registry: Readonly<Record<string, Record<string, string>>> | undefined,
|
|
40
|
+
operator: Readonly<Record<string, Record<string, string>>> | undefined,
|
|
41
|
+
): [Record<string, Record<string, string>> | undefined, StaticPolicySource] {
|
|
42
|
+
if (!registry && !operator) return [undefined, "unknown"];
|
|
43
|
+
const merged: Record<string, Record<string, string>> = {};
|
|
44
|
+
for (const [key, value] of Object.entries(registry ?? {})) merged[key] = { ...value };
|
|
45
|
+
for (const [key, value] of Object.entries(operator ?? {})) {
|
|
46
|
+
merged[key] = { ...(merged[key] ?? {}), ...value };
|
|
47
|
+
}
|
|
48
|
+
return [merged, operator ? "operator" : "registry"];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function positiveCapMap(
|
|
52
|
+
registry: Readonly<Record<string, number>> | undefined,
|
|
53
|
+
operator: Readonly<Record<string, number>> | undefined,
|
|
54
|
+
): [Record<string, number> | undefined, StaticPolicySource] {
|
|
55
|
+
if (!registry && !operator) return [undefined, "unknown"];
|
|
56
|
+
const merged = { ...(registry ?? {}) };
|
|
57
|
+
for (const [key, value] of Object.entries(operator ?? {})) {
|
|
58
|
+
merged[key] = typeof merged[key] === "number" ? Math.min(merged[key]!, value) : value;
|
|
59
|
+
}
|
|
60
|
+
return [merged, operator ? "operator" : "registry"];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function stableUnion(
|
|
64
|
+
registry: readonly string[] | undefined,
|
|
65
|
+
operator: readonly string[] | undefined,
|
|
66
|
+
): [string[] | undefined, StaticPolicySource] {
|
|
67
|
+
if (!registry && !operator) return [undefined, "unknown"];
|
|
68
|
+
return [[...new Set([...(registry ?? []), ...(operator ?? [])])], operator ? "operator" : "registry"];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function staticHeaders(
|
|
72
|
+
registry: Readonly<Record<string, string>> | undefined,
|
|
73
|
+
operator: Readonly<Record<string, string>> | undefined,
|
|
74
|
+
): [Record<string, string> | undefined, StaticPolicySource] {
|
|
75
|
+
if (!registry && !operator) return [undefined, "unknown"];
|
|
76
|
+
if (!registry) return [{ ...(operator ?? {}) }, "operator"];
|
|
77
|
+
if (!operator) return [{ ...registry }, "registry"];
|
|
78
|
+
const claimed = new Set(Object.keys(operator).map(name => name.toLowerCase()));
|
|
79
|
+
const merged: Record<string, string> = { ...operator };
|
|
80
|
+
for (const [name, value] of Object.entries(registry)) {
|
|
81
|
+
if (!claimed.has(name.toLowerCase())) merged[name] = value;
|
|
82
|
+
}
|
|
83
|
+
return [merged, "operator"];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function resolvedBaseUrl(
|
|
87
|
+
entry: Readonly<ProviderRegistryEntry> | undefined,
|
|
88
|
+
provider: Readonly<OcxProviderConfig>,
|
|
89
|
+
): [string, StaticPolicySource] {
|
|
90
|
+
if (!entry) return [provider.baseUrl, "operator"];
|
|
91
|
+
const configured = typeof provider.baseUrl === "string" ? provider.baseUrl.trim() : "";
|
|
92
|
+
const configuredIsResolved = configured.length > 0 && !/\{[^}]*\}/.test(configured);
|
|
93
|
+
if (entry.allowBaseUrlOverride && !configuredIsResolved) {
|
|
94
|
+
throw new Error(`Invalid baseUrl for provider "${entry.id}": expected a nonblank URL without unresolved placeholders`);
|
|
95
|
+
}
|
|
96
|
+
return (/\{[^}]*\}/.test(entry.baseUrl) || entry.allowBaseUrlOverride) && configuredIsResolved
|
|
97
|
+
? [configured, "operator"]
|
|
98
|
+
: [entry.baseUrl, "registry"];
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function sameStringArray(left: readonly string[] | undefined, right: readonly string[]): boolean {
|
|
102
|
+
return left?.length === right.length && left.every((value, index) => value === right[index]);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Legacy config-map lookup: exact id, colon family, then case-folded exact id. */
|
|
106
|
+
export function legacyModelValue<T>(record: Readonly<Record<string, T>> | undefined, modelId: string): T | undefined {
|
|
107
|
+
if (!record) return undefined;
|
|
108
|
+
if (Object.hasOwn(record, modelId)) return record[modelId];
|
|
109
|
+
const colon = modelId.indexOf(":");
|
|
110
|
+
if (colon > 0 && Object.hasOwn(record, modelId.slice(0, colon))) return record[modelId.slice(0, colon)];
|
|
111
|
+
const folded = modelId.toLowerCase();
|
|
112
|
+
return Object.entries(record).find(([key]) => key.toLowerCase() === folded)?.[1];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Provenance from the same merged-key walk as legacyModelValue. */
|
|
116
|
+
export function legacyModelSource<T>(
|
|
117
|
+
operator: Readonly<Record<string, T>> | undefined,
|
|
118
|
+
registry: Readonly<Record<string, T>> | undefined,
|
|
119
|
+
modelId: string,
|
|
120
|
+
): StaticPolicySource {
|
|
121
|
+
const merged = { ...(registry ?? {}), ...(operator ?? {}) };
|
|
122
|
+
let winningKey: string | undefined;
|
|
123
|
+
if (Object.hasOwn(merged, modelId)) winningKey = modelId;
|
|
124
|
+
const colon = modelId.indexOf(":");
|
|
125
|
+
if (winningKey === undefined && colon > 0 && Object.hasOwn(merged, modelId.slice(0, colon))) {
|
|
126
|
+
winningKey = modelId.slice(0, colon);
|
|
127
|
+
}
|
|
128
|
+
if (winningKey === undefined) {
|
|
129
|
+
const folded = modelId.toLowerCase();
|
|
130
|
+
winningKey = Object.keys(merged).find(key => key.toLowerCase() === folded);
|
|
131
|
+
}
|
|
132
|
+
if (winningKey === undefined) return "unknown";
|
|
133
|
+
return Object.hasOwn(operator ?? {}, winningKey) ? "operator" : "registry";
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function anthropicFamilyContextWindow(
|
|
137
|
+
record: Readonly<Record<string, number>> | undefined,
|
|
138
|
+
id: string,
|
|
139
|
+
): number | undefined {
|
|
140
|
+
if (!record || !id.toLowerCase().startsWith("claude-")) return undefined;
|
|
141
|
+
let candidate = id;
|
|
142
|
+
while (true) {
|
|
143
|
+
const cut = candidate.lastIndexOf("-");
|
|
144
|
+
if (cut <= 0 || !/^\d+$/.test(candidate.slice(cut + 1))) return undefined;
|
|
145
|
+
candidate = candidate.slice(0, cut);
|
|
146
|
+
const value = record[candidate]
|
|
147
|
+
?? Object.entries(record).find(([key]) => key.toLowerCase() === candidate.toLowerCase())?.[1];
|
|
148
|
+
if (typeof value === "number" && value > 0) return value;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export function wireDefault(
|
|
153
|
+
declared: ModelWireDefault | undefined,
|
|
154
|
+
provider: Readonly<OcxProviderConfig>,
|
|
155
|
+
entry: Readonly<ProviderRegistryEntry> | undefined,
|
|
156
|
+
inbound: InboundWire,
|
|
157
|
+
effectiveAuthMode: OcxProviderConfig["authMode"] | undefined,
|
|
158
|
+
): string | undefined {
|
|
159
|
+
if (declared === undefined || !MODEL_ADAPTER_OVERRIDE_ALLOWED.has(provider.adapter)) return undefined;
|
|
160
|
+
if (typeof declared !== "string") {
|
|
161
|
+
if (!declared.inbound.includes(inbound)) return undefined;
|
|
162
|
+
const authMode = effectiveAuthMode ?? provider.authMode ?? entry?.authKind;
|
|
163
|
+
if (declared.authModes && authMode && !declared.authModes.includes(authMode)) return undefined;
|
|
164
|
+
}
|
|
165
|
+
const wire = typeof declared === "string" ? declared : declared.wire;
|
|
166
|
+
return MODEL_ADAPTER_OVERRIDE_ALLOWED.has(wire) ? wire : undefined;
|
|
167
|
+
}
|