@iislee/opencodex 2.11.0 → 2.35.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/AGENTS_INSTALL.md +109 -0
- package/README.md +117 -22
- package/bin/ocx.mjs +245 -88
- package/bin/package-main.mjs +1 -1
- package/gui/dist/assets/index-Be1sDpWw.css +1 -0
- package/gui/dist/assets/index-D4OKgUV4.js +114 -0
- package/gui/dist/index.html +2 -2
- package/gui/dist/provider-icons/alibaba-color.svg +1 -1
- package/gui/dist/provider-icons/antigravity-color.svg +1 -1
- package/gui/dist/provider-icons/claude-color.svg +1 -1
- package/gui/dist/provider-icons/cline-color.svg +16 -0
- package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/commandcode-color.svg +1 -0
- package/gui/dist/provider-icons/copilot-color.svg +1 -1
- package/gui/dist/provider-icons/cursor-color.svg +1 -1
- package/gui/dist/provider-icons/deepseek-color.svg +1 -1
- package/gui/dist/provider-icons/firepass-color.svg +1 -1
- package/gui/dist/provider-icons/fireworks-color.svg +1 -1
- package/gui/dist/provider-icons/gemini-color.svg +1 -1
- package/gui/dist/provider-icons/github-copilot-color.svg +1 -1
- package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -1
- package/gui/dist/provider-icons/grok.svg +1 -1
- package/gui/dist/provider-icons/groq-color.svg +1 -1
- package/gui/dist/provider-icons/huggingface-color.svg +1 -1
- package/gui/dist/provider-icons/kimi-color.svg +1 -1
- package/gui/dist/provider-icons/kiro-color.svg +2 -2
- package/gui/dist/provider-icons/lm-studio-color.svg +1 -1
- package/gui/dist/provider-icons/mistral-color.svg +1 -1
- package/gui/dist/provider-icons/moonshot-color.svg +1 -1
- package/gui/dist/provider-icons/nvidia-color.svg +1 -1
- package/gui/dist/provider-icons/ollama-color.svg +1 -1
- package/gui/dist/provider-icons/openai.svg +1 -1
- package/gui/dist/provider-icons/opencode.svg +2 -1
- package/gui/dist/provider-icons/openrouter-color.svg +1 -1
- package/gui/dist/provider-icons/pi.svg +2 -2
- package/gui/dist/provider-icons/qianfan-color.svg +1 -1
- package/gui/dist/provider-icons/qwen-portal-color.svg +1 -1
- package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/vllm-color.svg +1 -1
- package/gui/dist/provider-icons/xiaomi-color.svg +1 -1
- package/package.json +21 -10
- package/src/adapters/anthropic-output-schema.ts +137 -0
- package/src/adapters/anthropic.ts +475 -62
- package/src/adapters/base.ts +82 -7
- package/src/adapters/client-fingerprint.ts +18 -12
- package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
- package/src/adapters/command-code.ts +637 -0
- package/src/adapters/cursor/call-id.ts +44 -0
- package/src/adapters/cursor/catalog.ts +541 -0
- package/src/adapters/cursor/checkpoint-store.ts +308 -0
- package/src/adapters/cursor/cursor-errors.ts +144 -6
- package/src/adapters/cursor/discovery.ts +122 -14
- package/src/adapters/cursor/effort-map.ts +106 -4
- package/src/adapters/cursor/envelope-echo.ts +290 -0
- package/src/adapters/cursor/framing.ts +39 -0
- package/src/adapters/cursor/h2-pool.ts +123 -0
- package/src/adapters/cursor/http1-bidi.ts +361 -0
- package/src/adapters/cursor/images.ts +704 -0
- package/src/adapters/cursor/live-models.ts +180 -59
- package/src/adapters/cursor/live-transport.ts +623 -170
- package/src/adapters/cursor/message-mapper.ts +4 -1
- package/src/adapters/cursor/native-exec-common.ts +23 -2
- package/src/adapters/cursor/native-exec-desktop.ts +23 -0
- package/src/adapters/cursor/native-exec-fs.ts +10 -7
- package/src/adapters/cursor/native-exec-network.ts +1 -1
- package/src/adapters/cursor/native-exec-shell.ts +5 -3
- package/src/adapters/cursor/native-exec.ts +121 -14
- package/src/adapters/cursor/protobuf-events.ts +829 -11
- package/src/adapters/cursor/protobuf-request.ts +447 -75
- package/src/adapters/cursor/request-builder.ts +271 -35
- package/src/adapters/cursor/tool-definitions.ts +252 -12
- package/src/adapters/cursor/tool-result-normalize.ts +115 -0
- package/src/adapters/cursor/transport.ts +22 -0
- package/src/adapters/cursor/types.ts +48 -1
- package/src/adapters/cursor.ts +336 -39
- package/src/adapters/exec-tool-result-normalize.ts +99 -0
- package/src/adapters/google-antigravity-replay.ts +713 -41
- package/src/adapters/google-antigravity-wire.ts +48 -10
- package/src/adapters/google-errors.ts +44 -12
- package/src/adapters/google-http.ts +38 -10
- package/src/adapters/google-tool-schema.ts +80 -15
- package/src/adapters/google-truncation.ts +11 -0
- package/src/adapters/google.ts +742 -86
- package/src/adapters/identity.ts +39 -6
- package/src/adapters/image.ts +1 -1
- package/src/adapters/kiro-constants.ts +27 -0
- package/src/adapters/kiro-errors.ts +11 -0
- package/src/adapters/kiro-events.ts +19 -1
- package/src/adapters/kiro-thinking.ts +18 -2
- package/src/adapters/kiro-tools.ts +65 -17
- package/src/adapters/kiro.ts +270 -73
- package/src/adapters/mimo-free.ts +17 -0
- package/src/adapters/openai-chat-url.ts +11 -0
- package/src/adapters/openai-chat.ts +1377 -344
- package/src/adapters/openai-responses-url.ts +16 -0
- package/src/adapters/openai-responses.ts +1164 -64
- package/src/adapters/registry.ts +175 -0
- package/src/adapters/responses-tool-schema.ts +67 -0
- package/src/adapters/run-turn-queue.ts +36 -1
- package/src/adapters/tool-call-id.ts +119 -0
- package/src/adapters/tool-catalog-nudge.ts +105 -21
- package/src/adapters/xai-tool-schema.ts +436 -0
- package/src/adapters/xai-web-search.ts +186 -0
- package/src/bridge.ts +512 -92
- package/src/chat/inbound.ts +57 -20
- package/src/chat/outbound.ts +97 -33
- package/src/claude/agents-inject.ts +40 -10
- package/src/claude/context-windows.ts +37 -14
- package/src/claude/desktop-3p.ts +243 -9
- package/src/claude/gateway-cache.ts +41 -4
- package/src/claude/inbound.ts +72 -3
- package/src/claude/model-info.ts +38 -15
- package/src/claude/outbound.ts +88 -21
- package/src/cli/access.ts +46 -3
- package/src/cli/account-api.ts +150 -19
- package/src/cli/account-auth.ts +33 -6
- package/src/cli/account-catalog-refresh.ts +14 -0
- package/src/cli/account-extended.ts +648 -28
- package/src/cli/account-main.ts +317 -0
- package/src/cli/account.ts +97 -19
- package/src/cli/agent.ts +53 -2
- package/src/cli/alias.ts +66 -0
- package/src/cli/capabilities-command.ts +94 -0
- package/src/cli/capabilities.ts +496 -0
- package/src/cli/claude-agent-startup-sync.ts +73 -0
- package/src/cli/claude-desktop.ts +60 -15
- package/src/cli/claude.ts +129 -35
- package/src/cli/codex-log-guard-doctor.ts +103 -0
- package/src/cli/codex-shim-autorestore.ts +2 -0
- package/src/cli/codex-shim-readiness.ts +76 -0
- package/src/cli/combo.ts +8 -0
- package/src/cli/config-command.ts +74 -10
- package/src/cli/dispatch.ts +821 -0
- package/src/cli/doctor.ts +440 -56
- package/src/cli/ensure-desired-integrations.ts +152 -0
- package/src/cli/export-command.ts +46 -20
- package/src/cli/help.ts +34 -274
- package/src/cli/index.ts +417 -528
- package/src/cli/init.ts +5 -17
- package/src/cli/inspect.ts +230 -0
- package/src/cli/integrations.ts +120 -2
- package/src/cli/lab.ts +607 -0
- package/src/cli/launcher-context.ts +77 -0
- package/src/cli/minimax.ts +497 -0
- package/src/cli/models-runtime.ts +130 -2
- package/src/cli/models.ts +118 -16
- package/src/cli/observe.ts +123 -11
- package/src/cli/opencode.ts +4 -2
- package/src/cli/provider-runtime.ts +34 -3
- package/src/cli/provider.ts +25 -3
- package/src/cli/ready.ts +301 -0
- package/src/cli/registry.ts +476 -0
- package/src/cli/root.ts +86 -0
- package/src/cli/route-policy.ts +92 -0
- package/src/cli/runtime-api.ts +57 -10
- package/src/cli/star-prompt.ts +71 -15
- package/src/cli/status.ts +51 -4
- package/src/cli/storage.ts +234 -0
- package/src/cli/system-command.ts +16 -0
- package/src/cli/system-restart-client.ts +146 -0
- package/src/cli/tray-proxy.ts +153 -6
- package/src/cli/usage-report.ts +184 -0
- package/src/cli/v2.ts +137 -18
- package/src/cli/version-skew.ts +46 -0
- package/src/cli.ts +1 -1
- package/src/clients/config-export.ts +1442 -23
- package/src/clients/effective-status.ts +30 -2
- package/src/clients/probes/cline.ts +81 -0
- package/src/codex/account-label.ts +35 -1
- package/src/codex/account-lifecycle.ts +130 -13
- package/src/codex/account-namespaces.ts +49 -3
- package/src/codex/account-pause.ts +2 -1
- package/src/codex/account-priority.ts +84 -0
- package/src/codex/account-store.ts +29 -2
- package/src/codex/account-usability.ts +25 -2
- package/src/codex/admission.ts +256 -0
- package/src/codex/affinity-debug.ts +162 -0
- package/src/codex/app-server-processes.ts +570 -107
- package/src/codex/app-server-restart-service.ts +232 -0
- package/src/codex/auth-api.ts +893 -246
- package/src/codex/auth-collision.ts +5 -3
- package/src/codex/auth-context.ts +348 -32
- package/src/codex/autostart-health.ts +24 -1
- package/src/codex/catalog/account-models.ts +67 -0
- package/src/codex/catalog/aggregation.ts +86 -10
- package/src/codex/catalog/bundled.ts +331 -33
- package/src/codex/catalog/effort.ts +138 -32
- package/src/codex/catalog/filesystem-evidence.ts +302 -0
- package/src/codex/catalog/kinds.ts +2 -0
- package/src/codex/catalog/metadata.ts +555 -45
- package/src/codex/catalog/native-models.ts +75 -0
- package/src/codex/catalog/parsing.ts +269 -30
- package/src/codex/catalog/provider-fetch.ts +1626 -144
- package/src/codex/catalog/sync.ts +1576 -187
- package/src/codex/catalog-admission.ts +199 -0
- package/src/codex/catalog-refresh-status.ts +105 -0
- package/src/codex/catalog-write-serialization.ts +242 -0
- package/src/codex/catalog.ts +6 -3
- package/src/codex/codex-write-lock.ts +386 -0
- package/src/codex/convergence-types.ts +614 -0
- package/src/codex/convergence.ts +676 -0
- package/src/codex/coordinator-doctor.ts +332 -0
- package/src/codex/custom-model-catalog-migration.ts +176 -0
- package/src/codex/desired-state.ts +230 -0
- package/src/codex/desktop-app-restart.ts +355 -0
- package/src/codex/features.ts +636 -39
- package/src/codex/generation.ts +202 -0
- package/src/codex/history-job.ts +436 -0
- package/src/codex/history-lock.ts +242 -0
- package/src/codex/history-manifest.ts +112 -0
- package/src/codex/history-migration-guardian.ts +30 -24
- package/src/codex/history-provider.ts +1016 -235
- package/src/codex/history-transition.ts +105 -0
- package/src/codex/history-worker.ts +223 -0
- package/src/codex/inject-coordination.ts +373 -0
- package/src/codex/inject.ts +1114 -152
- package/src/codex/injected-marker.ts +37 -3
- package/src/codex/integration-record.ts +266 -0
- package/src/codex/internal/catalog-writer.ts +203 -0
- package/src/codex/internal/history-writer.ts +81 -0
- package/src/codex/journal.ts +66 -4
- package/src/codex/log-guard/inspect.ts +524 -0
- package/src/codex/log-guard/lock.ts +150 -0
- package/src/codex/log-guard/maintenance.ts +403 -0
- package/src/codex/log-guard/path-safety.ts +88 -0
- package/src/codex/log-guard/policy.ts +44 -0
- package/src/codex/log-guard/processes.ts +205 -0
- package/src/codex/log-guard/protection.ts +489 -0
- package/src/codex/log-guard/sqlite-errors.ts +9 -0
- package/src/codex/main-account-cache.ts +24 -0
- package/src/codex/main-account.ts +29 -1
- package/src/codex/management-convergence.ts +167 -0
- package/src/codex/model-cache.ts +56 -10
- package/src/codex/model-entitlements.ts +360 -0
- package/src/codex/native-main-admission.ts +47 -0
- package/src/codex/native-main-auth-temp.ts +187 -0
- package/src/codex/native-main-claim.ts +178 -0
- package/src/codex/native-main-lock-file.ts +162 -0
- package/src/codex/native-main-owner.ts +329 -0
- package/src/codex/native-profile-api.ts +247 -0
- package/src/codex/native-profile-manager.ts +1531 -0
- package/src/codex/native-profile-processes.ts +121 -0
- package/src/codex/native-profile-recovery.ts +99 -0
- package/src/codex/native-profile-stage-store.ts +387 -0
- package/src/codex/native-profile-startup.ts +622 -0
- package/src/codex/native-profile-store.ts +855 -0
- package/src/codex/native-profile-types.ts +120 -0
- package/src/codex/native-residue.ts +675 -0
- package/src/codex/paths.ts +80 -1
- package/src/codex/plan-from-token.ts +140 -0
- package/src/codex/plan.ts +40 -0
- package/src/codex/plugins-doctor.ts +1 -1
- package/src/codex/pool-rotation.ts +74 -4
- package/src/codex/project-config-warnings.ts +20 -6
- package/src/codex/prompt-journal.ts +352 -0
- package/src/codex/prompt-layers.ts +1313 -0
- package/src/codex/prompt-lock.ts +143 -0
- package/src/codex/prompt-text-probe.ts +238 -0
- package/src/codex/quota-rejection.ts +298 -0
- package/src/codex/quota.ts +264 -21
- package/src/codex/refresh.ts +11 -2
- package/src/codex/reset-credit-recovery.ts +1044 -0
- package/src/codex/routing.ts +514 -94
- package/src/codex/runtime.ts +159 -38
- package/src/codex/shim.ts +1065 -31
- package/src/codex/subagent-model-fallback.ts +437 -43
- package/src/codex/sync.ts +191 -2
- package/src/codex/transition-state.ts +720 -0
- package/src/codex/upstream-host-health.ts +368 -0
- package/src/codex/user-identity.ts +557 -0
- package/src/codex/warmup.ts +187 -81
- package/src/codex/write-coordination.ts +114 -0
- package/src/combos/failover.ts +47 -0
- package/src/combos/index.ts +4 -0
- package/src/combos/request.ts +32 -0
- package/src/combos/types.ts +91 -9
- package/src/compatibility/index.ts +26 -0
- package/src/compatibility/manifest.ts +253 -0
- package/src/compatibility/openai-responses.ts +121 -0
- package/src/config/atomic-write.ts +219 -0
- package/src/config/paths.ts +40 -0
- package/src/config/process-state.ts +309 -0
- package/src/config/provider-name.ts +24 -0
- package/src/config/provider-validation.ts +177 -0
- package/src/config/rebase-provenance.ts +68 -0
- package/src/config.ts +1713 -709
- package/src/generated/compatibility-version.json +3324 -0
- package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
- package/src/grok/inject.ts +16 -5
- package/src/grok/inspect.ts +45 -0
- package/src/grok/sync.ts +2 -2
- package/src/images/loop.ts +157 -33
- package/src/images/plan.ts +24 -13
- package/src/integrations/config-io.ts +269 -0
- package/src/integrations/journal.ts +315 -0
- package/src/integrations/merge.ts +135 -0
- package/src/integrations/mutation-flight.ts +71 -0
- package/src/integrations/native/ownership-preflight.ts +202 -0
- package/src/integrations/omp-yaml-source.ts +358 -0
- package/src/integrations/owned-refresh.ts +74 -0
- package/src/integrations/ownership-policy.ts +160 -0
- package/src/integrations/ownership.ts +155 -0
- package/src/integrations/registry.ts +166 -0
- package/src/integrations/serialize.ts +314 -0
- package/src/integrations/state.ts +433 -0
- package/src/integrations/store.ts +103 -0
- package/src/integrations/writer-lock.ts +98 -0
- package/src/integrations/writer.ts +715 -0
- package/src/lab/artifacts/sanitize.ts +586 -0
- package/src/lab/artifacts/secure-fs.ts +475 -0
- package/src/lab/artifacts/store.ts +310 -0
- package/src/lab/automation/budgets.ts +78 -0
- package/src/lab/automation/config-persistence.ts +256 -0
- package/src/lab/automation/constants.ts +39 -0
- package/src/lab/automation/cooldown.ts +103 -0
- package/src/lab/automation/dispatch.ts +211 -0
- package/src/lab/automation/index.ts +13 -0
- package/src/lab/automation/orchestrator.ts +499 -0
- package/src/lab/automation/persistence.ts +512 -0
- package/src/lab/automation/planner.ts +371 -0
- package/src/lab/automation/policy.ts +136 -0
- package/src/lab/automation/queue.ts +191 -0
- package/src/lab/automation/recovery.ts +24 -0
- package/src/lab/automation/route-context.ts +21 -0
- package/src/lab/automation/run-key.ts +44 -0
- package/src/lab/automation/runs-query.ts +34 -0
- package/src/lab/automation/types.ts +160 -0
- package/src/lab/conformance/assertion.ts +325 -0
- package/src/lab/conformance/digest.ts +22 -0
- package/src/lab/conformance/executor.ts +741 -0
- package/src/lab/conformance/fixture-provider.ts +27 -0
- package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
- package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
- package/src/lab/conformance/harness-budget.ts +47 -0
- package/src/lab/conformance/index.ts +5 -0
- package/src/lab/conformance/jcs.ts +64 -0
- package/src/lab/conformance/json-pointer.ts +39 -0
- package/src/lab/conformance/manifest.ts +180 -0
- package/src/lab/conformance/mcp-stub.ts +179 -0
- package/src/lab/conformance/negative-controls.ts +164 -0
- package/src/lab/conformance/observation.ts +355 -0
- package/src/lab/conformance/runner.ts +68 -0
- package/src/lab/conformance/sse-normalize.ts +59 -0
- package/src/lab/conformance/suite-manifest.ts +78 -0
- package/src/lab/conformance/types.ts +214 -0
- package/src/lab/constants.ts +126 -0
- package/src/lab/digest.ts +64 -0
- package/src/lab/events/errors.ts +9 -0
- package/src/lab/events/limits.ts +117 -0
- package/src/lab/events/types.ts +229 -0
- package/src/lab/events/validate.ts +781 -0
- package/src/lab/fabric/constants.ts +40 -0
- package/src/lab/fabric/executor.ts +492 -0
- package/src/lab/fabric/index.ts +80 -0
- package/src/lab/fabric/manifest.ts +222 -0
- package/src/lab/fabric/observe.ts +489 -0
- package/src/lab/fabric/patch.ts +79 -0
- package/src/lab/fabric/producer-child.ts +139 -0
- package/src/lab/fabric/producer-isolate.ts +276 -0
- package/src/lab/fabric/producer-protocol.ts +61 -0
- package/src/lab/fabric/scratch.ts +439 -0
- package/src/lab/fabric/subject.ts +106 -0
- package/src/lab/fabric/types.ts +134 -0
- package/src/lab/fabric/verifier.ts +98 -0
- package/src/lab/index.ts +54 -0
- package/src/lab/ledger/artifact-refs.ts +127 -0
- package/src/lab/ledger/invalidation.ts +136 -0
- package/src/lab/ledger/purge.ts +310 -0
- package/src/lab/ledger/store.ts +532 -0
- package/src/lab/live/credential-lease.ts +53 -0
- package/src/lab/live/destination.ts +155 -0
- package/src/lab/live/executor.ts +336 -0
- package/src/lab/live/inert-tools.ts +56 -0
- package/src/lab/live/manifest.ts +85 -0
- package/src/lab/live/mcp-loopback.ts +57 -0
- package/src/lab/live/runner.ts +19 -0
- package/src/lab/live/sandbox.ts +61 -0
- package/src/lab/live/suite-manifest.ts +41 -0
- package/src/lab/live/transport.ts +118 -0
- package/src/lab/live/types.ts +197 -0
- package/src/lab/observe/from-conformance.ts +301 -0
- package/src/lab/observe/from-live.ts +117 -0
- package/src/lab/paths.ts +153 -0
- package/src/lab/projection/rebuild.ts +495 -0
- package/src/lab/projection/schema.ts +135 -0
- package/src/lab/projection/verdicts.ts +474 -0
- package/src/lab/projection/verification.ts +412 -0
- package/src/lab/public/bundle.ts +217 -0
- package/src/lab/public/community-authority.ts +175 -0
- package/src/lab/public/community-files.ts +29 -0
- package/src/lab/public/community.ts +479 -0
- package/src/lab/public/file-safety.ts +155 -0
- package/src/lab/public/ids.ts +26 -0
- package/src/lab/public/index.ts +16 -0
- package/src/lab/public/mutation-lock.ts +424 -0
- package/src/lab/public/operator.ts +353 -0
- package/src/lab/public/origin-purge.ts +79 -0
- package/src/lab/public/origin.ts +203 -0
- package/src/lab/public/privacy.ts +143 -0
- package/src/lab/public/private-file.ts +261 -0
- package/src/lab/public/project.ts +124 -0
- package/src/lab/public/purge-test-fault.ts +21 -0
- package/src/lab/public/purge.ts +223 -0
- package/src/lab/public/registry.ts +44 -0
- package/src/lab/public/revocation.ts +252 -0
- package/src/lab/public/signature.ts +243 -0
- package/src/lab/public/storage.ts +105 -0
- package/src/lab/public/strict-json.ts +206 -0
- package/src/lab/public/time.ts +26 -0
- package/src/lab/public/types.ts +172 -0
- package/src/lab/public/validate.ts +391 -0
- package/src/lab/query/catalog.ts +101 -0
- package/src/lab/query/connection.ts +107 -0
- package/src/lab/query/constants.ts +4 -0
- package/src/lab/query/cursor.ts +132 -0
- package/src/lab/query/dto-map.ts +277 -0
- package/src/lab/query/errors.ts +22 -0
- package/src/lab/query/freshness.ts +53 -0
- package/src/lab/query/index.ts +45 -0
- package/src/lab/query/latest-observation.ts +59 -0
- package/src/lab/query/passive-production.ts +159 -0
- package/src/lab/query/queries.ts +444 -0
- package/src/lab/query/types.ts +266 -0
- package/src/lab/subject/behavior-fingerprint.ts +77 -0
- package/src/lab/subject/installation-salt.ts +112 -0
- package/src/lab/subject/protocol-subject.ts +80 -0
- package/src/lab/subject/route-subject.ts +74 -0
- package/src/lib/admin-secrets.ts +24 -0
- package/src/lib/app-owned-memory-stores.ts +22 -0
- package/src/lib/bounded-body.ts +167 -11
- package/src/lib/bun-runtime.ts +125 -12
- package/src/lib/bun-stream-caps.ts +13 -9
- package/src/lib/codex-restart-contract.ts +120 -0
- package/src/lib/config-ownership.ts +26 -2
- package/src/lib/destination-policy.ts +65 -1
- package/src/lib/errors.ts +80 -5
- package/src/lib/fabric-task-execution-authority.ts +7 -0
- package/src/lib/fabric-task-host.ts +29 -0
- package/src/lib/lab-activation.ts +223 -0
- package/src/lib/lab-live-execution-authority.ts +13 -0
- package/src/lib/lab-live-host.ts +30 -0
- package/src/lib/lab-live-pinned-sender.ts +56 -0
- package/src/lib/lab-live-route-production.ts +130 -0
- package/src/lib/lab-passive-linker-registration.ts +26 -0
- package/src/lib/local-management-attestation.ts +51 -0
- package/src/lib/local-management-capability.ts +100 -0
- package/src/lib/local-provider-reload-contract.ts +100 -0
- package/src/lib/optional-shutdown-hooks.ts +57 -0
- package/src/lib/package-tree-integrity.ts +101 -0
- package/src/lib/pinned-http.ts +145 -26
- package/src/lib/process-control.ts +6 -2
- package/src/lib/provider-outbound.ts +49 -9
- package/src/lib/redact.ts +419 -3
- package/src/lib/self-launch-argv.ts +15 -0
- package/src/lib/server-resource-ownership.ts +71 -0
- package/src/lib/service-secrets.ts +15 -0
- package/src/lib/shadow-call.ts +35 -4
- package/src/lib/sse-decoder.ts +41 -0
- package/src/lib/state-store-registrations.ts +10 -2
- package/src/lib/system-restart-contract.ts +73 -0
- package/src/lib/token-estimate.ts +19 -2
- package/src/lib/tool-argument-integers.ts +253 -0
- package/src/lib/translator-budget.ts +44 -0
- package/src/lib/upstream-http-version.ts +57 -0
- package/src/lib/upstream-reachability.ts +95 -0
- package/src/lib/upstream-retry.ts +156 -3
- package/src/lib/windows-atomic-replace.ts +155 -0
- package/src/lib/windows-elevation.ts +70 -2
- package/src/lib/windows-secret-acl.ts +409 -69
- package/src/lib/windows-service-wrappers.ts +72 -0
- package/src/lib/windows-text.ts +106 -0
- package/src/lib/windows-user-principal.ts +341 -0
- package/src/lib/winsw.ts +33 -5
- package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
- package/src/oauth/account-import/index.ts +15 -0
- package/src/oauth/account-import/parser.ts +83 -0
- package/src/oauth/account-import/registry.ts +18 -0
- package/src/oauth/account-import/service.ts +75 -0
- package/src/oauth/account-import/types.ts +91 -0
- package/src/oauth/anthropic.ts +12 -1
- package/src/oauth/callback-server.ts +30 -4
- package/src/oauth/chatgpt.ts +12 -1
- package/src/oauth/cline.ts +203 -0
- package/src/oauth/command-code.ts +239 -0
- package/src/oauth/cursor.ts +46 -5
- package/src/oauth/generic-account-failover.ts +231 -0
- package/src/oauth/google-antigravity.ts +35 -3
- package/src/oauth/health.ts +20 -12
- package/src/oauth/index.ts +462 -71
- package/src/oauth/key-providers.ts +25 -0
- package/src/oauth/kimi.ts +25 -3
- package/src/oauth/kiro.ts +95 -6
- package/src/oauth/local-token-detect.ts +13 -2
- package/src/oauth/log.ts +3 -1
- package/src/oauth/login-cli.ts +88 -28
- package/src/oauth/nous.ts +798 -0
- package/src/oauth/open-browser-choice.ts +26 -0
- package/src/oauth/store.ts +133 -26
- package/src/oauth/token-guardian.ts +9 -3
- package/src/oauth/types.ts +15 -0
- package/src/pi/models.ts +2 -2
- package/src/providers/alibaba-region-migration.ts +1 -1
- package/src/providers/antigravity-models.ts +521 -31
- package/src/providers/auto-compact-budget.ts +65 -0
- package/src/providers/base-url-choices.ts +10 -0
- package/src/providers/codex-capacity.ts +292 -0
- package/src/providers/command-code-efforts.ts +176 -0
- package/src/providers/context-cap.ts +26 -8
- package/src/providers/cursor-pool.ts +72 -0
- package/src/providers/default-aliases.ts +65 -0
- package/src/providers/derive.ts +281 -6
- package/src/providers/fastwire.ts +507 -0
- package/src/providers/free-directory.ts +10 -7
- package/src/providers/google-vertex-location.ts +14 -0
- package/src/providers/key-failover.ts +71 -3
- package/src/providers/label.ts +35 -2
- package/src/providers/model-discovery-limits.ts +16 -0
- package/src/providers/model-discovery.ts +115 -22
- package/src/providers/model-presets.ts +119 -0
- package/src/providers/model-rename-migration.ts +255 -0
- package/src/providers/model-rename-startup.ts +28 -0
- package/src/providers/new-model-policy.ts +146 -0
- package/src/providers/openai-sidecar.ts +72 -4
- package/src/providers/openai-tier-startup.ts +31 -2
- package/src/providers/openai-tiers.ts +119 -4
- package/src/providers/openai-virtual-models.ts +1 -0
- package/src/providers/opencode-zen-rate-limit.ts +102 -0
- package/src/providers/provider-id-rewrite.ts +30 -0
- package/src/providers/quota.ts +1379 -40
- package/src/providers/registry.ts +1545 -112
- package/src/providers/request-pacing.ts +310 -0
- package/src/providers/service-tier.ts +277 -0
- package/src/providers/slug-codec.ts +94 -6
- package/src/providers/static-model-discovery.ts +86 -0
- package/src/providers/xai-responses-opt-in.ts +15 -0
- package/src/providers/xai-transport.ts +32 -4
- package/src/reasoning-effort.ts +68 -3
- package/src/responses/apply-patch-envelope.ts +63 -0
- package/src/responses/code-mode-helper-compat.ts +50 -0
- package/src/responses/compaction.ts +26 -1
- package/src/responses/custom-tool-compat.ts +384 -0
- package/src/responses/hosted-tool-policy.ts +9 -0
- package/src/responses/namespace-tool-compat.ts +435 -0
- package/src/responses/parser.ts +225 -38
- package/src/responses/provider-continuation.ts +98 -0
- package/src/responses/provider-opaque-metadata.ts +73 -0
- package/src/responses/reasoning-envelope.ts +9 -1
- package/src/responses/reasoning-replay-cache.ts +504 -0
- package/src/responses/schema.ts +12 -2
- package/src/responses/spill-store.ts +75 -10
- package/src/responses/state.ts +659 -31
- package/src/responses/thought-signature-replay.ts +364 -0
- package/src/responses/tool-search-compat.ts +301 -0
- package/src/responses/truncated-stop-reason.ts +60 -0
- package/src/responses/turn-termination.ts +107 -0
- package/src/router.ts +405 -31
- package/src/routing/analytics.ts +379 -0
- package/src/routing/capability.ts +244 -0
- package/src/routing/compatibility/assemble.ts +73 -0
- package/src/routing/compatibility/behavior.ts +278 -0
- package/src/routing/compatibility/catalog.ts +99 -0
- package/src/routing/compatibility/endpoint.ts +52 -0
- package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
- package/src/routing/compatibility/policy.ts +181 -0
- package/src/routing/compatibility/provider-slot.ts +56 -0
- package/src/routing/compatibility/reader.ts +110 -0
- package/src/routing/compatibility/subject.ts +191 -0
- package/src/routing/compatibility/types.ts +64 -0
- package/src/routing/compatibility/version.ts +104 -0
- package/src/routing/cost.ts +77 -0
- package/src/routing/evaluator.ts +495 -0
- package/src/routing/health.ts +412 -0
- package/src/routing/history/cursor.ts +43 -0
- package/src/routing/history/indexer.ts +605 -0
- package/src/routing/history/schema.ts +72 -0
- package/src/routing/profile-namespace.ts +15 -0
- package/src/routing/profile.ts +547 -0
- package/src/routing/quota.ts +155 -0
- package/src/routing/request-evidence.ts +45 -0
- package/src/routing/trace.ts +776 -0
- package/src/server/adapter-resolve.ts +2 -29
- package/src/server/auth-cors.ts +289 -48
- package/src/server/background-lifecycle.ts +182 -0
- package/src/server/chat-completions.ts +154 -72
- package/src/server/chat-native-sse.ts +331 -0
- package/src/server/chat-native.ts +445 -0
- package/src/server/claude-messages.ts +160 -44
- package/src/server/direct-local-http.ts +347 -0
- package/src/server/effort-policy.ts +18 -0
- package/src/server/github-copilot-responses-repair.ts +338 -0
- package/src/server/gui-static.ts +39 -10
- package/src/server/images.ts +94 -12
- package/src/server/index.ts +1021 -190
- package/src/server/lifecycle.ts +336 -14
- package/src/server/live.ts +136 -17
- package/src/server/local-management-read-client.ts +90 -0
- package/src/server/local-provider-reload-client.ts +137 -0
- package/src/server/management/agent-settings-routes.ts +433 -116
- package/src/server/management/api-key-usage.ts +31 -5
- package/src/server/management/body.ts +6 -0
- package/src/server/management/codex-prompt-routes.ts +570 -0
- package/src/server/management/combo-routes.ts +64 -25
- package/src/server/management/config-routes.ts +511 -51
- package/src/server/management/context.ts +89 -2
- package/src/server/management/integration-routes.ts +498 -0
- package/src/server/management/lab-automation-routes.ts +206 -0
- package/src/server/management/lab-routes.ts +563 -0
- package/src/server/management/logs-usage-routes.ts +127 -52
- package/src/server/management/model-routes.ts +461 -133
- package/src/server/management/model-rows.ts +167 -0
- package/src/server/management/native-integration-routes.ts +770 -0
- package/src/server/management/oauth-account-routes.ts +90 -8
- package/src/server/management/provider-capability-config.ts +48 -0
- package/src/server/management/provider-routes.ts +836 -159
- package/src/server/management/request-history-routes.ts +191 -0
- package/src/server/management/route-registry.ts +332 -0
- package/src/server/management/routing-analytics-routes.ts +74 -0
- package/src/server/management/routing-profile-routes.ts +380 -0
- package/src/server/management/shared.ts +27 -11
- package/src/server/management/sidebar-routes.ts +47 -31
- package/src/server/management/storage-log-guard-routes.ts +186 -0
- package/src/server/management/sync-response.ts +69 -0
- package/src/server/management/system-restart.ts +289 -33
- package/src/server/management/system-routes.ts +77 -0
- package/src/server/management/usage-summary-cache.ts +9 -1
- package/src/server/management/vision-sidecar-options.ts +167 -0
- package/src/server/management/web-search-sidecar-options.ts +120 -0
- package/src/server/management-api.ts +126 -23
- package/src/server/management-auth.ts +220 -5
- package/src/server/passive-route-linker.ts +66 -0
- package/src/server/port-reclaim.ts +1 -1
- package/src/server/ports.ts +41 -1
- package/src/server/proxy-liveness.ts +161 -10
- package/src/server/readiness.ts +99 -0
- package/src/server/relay-eager.ts +221 -54
- package/src/server/relay.ts +479 -87
- package/src/server/request-decompress.ts +113 -6
- package/src/server/request-log-conversation.ts +51 -0
- package/src/server/request-log.ts +298 -31
- package/src/server/responses/agent-task-recovery-cache.ts +143 -0
- package/src/server/responses/agent-task-recovery.ts +465 -0
- package/src/server/responses/codex-auth-error.ts +55 -0
- package/src/server/responses/collaboration.ts +239 -36
- package/src/server/responses/combo-stream-preflight.ts +178 -0
- package/src/server/responses/compact.ts +444 -72
- package/src/server/responses/core.ts +3579 -436
- package/src/server/responses/empty-completion-guard.ts +333 -0
- package/src/server/responses/encrypted-payload.ts +62 -39
- package/src/server/responses/fetch-helpers.ts +89 -99
- package/src/server/responses/input-admission.ts +187 -0
- package/src/server/responses/pacing-overload.ts +13 -0
- package/src/server/responses/passthrough-error.ts +33 -9
- package/src/server/responses/policy-fallback.ts +178 -0
- package/src/server/responses/responses-field-backfill.ts +343 -0
- package/src/server/responses/terminal-guard.ts +26 -5
- package/src/server/responses/upstream-error.ts +5 -0
- package/src/server/responses/ws-upstream.ts +381 -0
- package/src/server/responses-custom-tool-repair.ts +363 -0
- package/src/server/responses-item-id-repair.ts +54 -6
- package/src/server/responses-json-events.ts +90 -0
- package/src/server/responses-model-rewrite.ts +29 -0
- package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
- package/src/server/responses-snapshot-repair.ts +621 -0
- package/src/server/responses-terminal-repair.ts +363 -0
- package/src/server/responses-tool-search-repair.ts +267 -0
- package/src/server/responses-undeclared-tool-guard.ts +376 -0
- package/src/server/responses.ts +18 -2
- package/src/server/search.ts +78 -13
- package/src/server/sse-frame-buffer.ts +319 -0
- package/src/server/sse-payload-rewrite.ts +110 -22
- package/src/server/startup-action-control.ts +8 -1
- package/src/server/startup-health-cache.ts +19 -1
- package/src/server/system-env.ts +80 -9
- package/src/server/ws-bridge.ts +53 -40
- package/src/service-manager-probe.ts +892 -0
- package/src/service.ts +1153 -94
- package/src/sidecar/auth.ts +92 -0
- package/src/sidecar/candidates.ts +83 -0
- package/src/storage/cleanup.ts +2 -2
- package/src/storage/policy-job.ts +14 -4
- package/src/storage/policy.ts +88 -23
- package/src/storage/scanner.ts +1 -1
- package/src/storage/worker-lifecycle.ts +14 -14
- package/src/tray/windows-tray.ps1 +83 -9
- package/src/tray/windows.ts +43 -16
- package/src/types/accounts.ts +37 -0
- package/src/types/config.ts +911 -0
- package/src/types/provider.ts +614 -0
- package/src/types/request.ts +397 -0
- package/src/types/tools.ts +236 -0
- package/src/types/wire.ts +80 -0
- package/src/types.ts +107 -1237
- package/src/update/index.ts +37 -23
- package/src/update/job.ts +445 -68
- package/src/update/notify.ts +12 -6
- package/src/update/npm-cache-preflight.d.mts +47 -0
- package/src/update/npm-cache-preflight.mjs +201 -0
- package/src/update/transactional-install.d.mts +22 -0
- package/src/update/transactional-install.mjs +266 -0
- package/src/usage/cost.ts +0 -0
- package/src/usage/expected-prices.ts +287 -16
- package/src/usage/log.ts +666 -50
- package/src/usage/summary.ts +388 -17
- package/src/usage/user-cost-overlay-reconciler.ts +313 -0
- package/src/usage/user-cost-overlays.ts +314 -0
- package/src/vision/anthropic-describe.ts +10 -6
- package/src/vision/backends.ts +97 -0
- package/src/vision/describe.ts +27 -16
- package/src/vision/eligibility.ts +250 -0
- package/src/vision/index.ts +238 -24
- package/src/vision/reasoning.ts +55 -0
- package/src/vision/routed-describe.ts +175 -0
- package/src/vision/timeout-bounds.ts +9 -0
- package/src/web-search/anthropic-executor.ts +13 -7
- package/src/web-search/backends.ts +108 -0
- package/src/web-search/exa-executor.ts +119 -0
- package/src/web-search/executor.ts +21 -6
- package/src/web-search/gemini-executor.ts +141 -0
- package/src/web-search/index.ts +150 -15
- package/src/web-search/loop.ts +284 -54
- package/src/web-search/parse.ts +125 -30
- package/src/web-search/sources.ts +60 -0
- package/src/web-search/xai-executor.ts +219 -0
- package/gui/dist/assets/index-DTpMHS4F.js +0 -67
- package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
- package/gui/dist/provider-icons/antigravity.svg +0 -1
- package/gui/dist/provider-icons/claude.svg +0 -1
- package/gui/dist/provider-icons/copilot.svg +0 -1
- package/gui/dist/provider-icons/cursor.svg +0 -2
- package/gui/dist/provider-icons/gemini.svg +0 -1
- package/gui/dist/provider-icons/grok-color.svg +0 -1
- package/gui/dist/provider-icons/kiro.svg +0 -14
- package/src/cli/internal-dispatch.ts +0 -20
|
@@ -2,19 +2,26 @@ import { existsSync, readFileSync } from "node:fs";
|
|
|
2
2
|
import type { ResponsesTerminalStatus } from "../bridge";
|
|
3
3
|
import {
|
|
4
4
|
classifyError,
|
|
5
|
+
CYBER_POLICY_ERROR_CODE,
|
|
5
6
|
httpStatusFromTerminalError as httpStatusFromClassifiedTerminalError,
|
|
6
7
|
isClientClosedMessage,
|
|
8
|
+
isCyberPolicyCode,
|
|
9
|
+
isCyberPolicyMessage,
|
|
7
10
|
} from "../lib/errors";
|
|
8
11
|
import { CODEX_CONFIG_PATH, readRootTomlString } from "../codex/paths";
|
|
9
12
|
import { readCodexCatalogPath } from "../codex/catalog";
|
|
10
|
-
import type { OcxUsage } from "../types";
|
|
13
|
+
import type { AttemptTierOutcome, OcxUsage } from "../types";
|
|
14
|
+
import { normalizeRouteDecisionTrace, type RouteDecisionTraceV1 } from "../routing/trace";
|
|
11
15
|
import type { AdapterRequest } from "../adapters/base";
|
|
12
|
-
import {
|
|
16
|
+
import type { AdapterTierMetadata } from "../providers/fastwire";
|
|
17
|
+
import { redactSecretString, sanitizeLogMetadataString } from "../lib/redact";
|
|
13
18
|
import {
|
|
14
19
|
appendUsageEntry,
|
|
15
20
|
isKnownAdmissionKind,
|
|
16
21
|
isKnownInboundProtocol,
|
|
17
22
|
isKnownUsageSurface,
|
|
23
|
+
isCodexUsageAccountLogLabel,
|
|
24
|
+
isValidReasoningWireValue,
|
|
18
25
|
readRecentUsageEntries,
|
|
19
26
|
usageForFinalLog,
|
|
20
27
|
usageStatusForFinalLog,
|
|
@@ -33,6 +40,10 @@ import {
|
|
|
33
40
|
} from "../usage/debug";
|
|
34
41
|
import { matchesLogConversationId } from "./request-log-conversation";
|
|
35
42
|
import { enforceAppOwnedMemoryBudget, type RetainedStoreSnapshot } from "../lib/app-owned-memory";
|
|
43
|
+
import { capEstimateAtContextWindow } from "../lib/token-estimate";
|
|
44
|
+
import { inferCursorContextWindow } from "../adapters/cursor/discovery";
|
|
45
|
+
import { KIRO_MODEL_CONTEXT_WINDOWS, normalizeKiroModelId } from "../providers/kiro-models";
|
|
46
|
+
import { modelRecordValue } from "../reasoning-effort";
|
|
36
47
|
|
|
37
48
|
export interface RequestLogContext {
|
|
38
49
|
model: string;
|
|
@@ -52,20 +63,38 @@ export interface RequestLogContext {
|
|
|
52
63
|
* product: widening that enum would merge Responses and Chat Completions,
|
|
53
64
|
* since both leave it undefined. */
|
|
54
65
|
inboundProtocol?: "responses" | "chat" | "messages";
|
|
66
|
+
/**
|
|
67
|
+
* Set when an adapter answered the turn locally and no upstream request was made
|
|
68
|
+
* (`ProviderAdapter.localTerminal`). A fixed identifier naming the code path, never
|
|
69
|
+
* conversation-derived: it exists so a request log showing zero sends is explainable
|
|
70
|
+
* rather than looking like a lost request.
|
|
71
|
+
*/
|
|
72
|
+
localTerminalReason?: string;
|
|
73
|
+
/** Stable non-PII Codex Pool account identity for durable usage attribution. */
|
|
74
|
+
accountLogLabel?: string;
|
|
55
75
|
requestedModel?: string;
|
|
76
|
+
/** User-facing alias selector when routing resolved one; native model remains `model`. */
|
|
77
|
+
requestedAlias?: string;
|
|
78
|
+
/** Original bare helper model when the opt-in shadow-call route rewrote this request. */
|
|
79
|
+
shadowCallRewrittenFrom?: string;
|
|
56
80
|
/** Internal structural combo identity; omitted from RequestLogEntry/JSONL. */
|
|
57
81
|
comboId?: string;
|
|
58
82
|
requestedEffort?: string;
|
|
59
83
|
effectiveEffort?: string;
|
|
60
84
|
reasoningWireField?: string;
|
|
61
|
-
reasoningWireValue?: string | number;
|
|
85
|
+
reasoningWireValue?: string | number | boolean;
|
|
86
|
+
callerServiceTier?: string;
|
|
62
87
|
requestedServiceTier?: string;
|
|
63
88
|
requestedSpeedLabel?: string;
|
|
64
89
|
configuredServiceTier?: string;
|
|
65
90
|
configuredSpeedLabel?: string;
|
|
66
91
|
modelSupportsServiceTier?: boolean;
|
|
67
92
|
responseServiceTier?: string;
|
|
93
|
+
/** Final-attempt tier summary; attempt rows remain the accounting source of truth. */
|
|
94
|
+
tierOutcome?: AttemptTierOutcome;
|
|
68
95
|
resolvedModel?: string;
|
|
96
|
+
/** Internal: client-facing response metadata must not replace the physical routed model. */
|
|
97
|
+
preserveResolvedModelFromRoute?: boolean;
|
|
69
98
|
usage?: OcxUsage;
|
|
70
99
|
usageLogInputTokens?: number;
|
|
71
100
|
attempts?: PersistedUsageAttempt[];
|
|
@@ -73,6 +102,8 @@ export interface RequestLogContext {
|
|
|
73
102
|
activeAttempt?: PersistedUsageAttempt;
|
|
74
103
|
/** Internal wall-clock origin for the committed final attempt; never persisted. */
|
|
75
104
|
activeAttemptStartedAt?: number;
|
|
105
|
+
/** Internal adapter response observer paired with activeAttempt.tierOutcome. */
|
|
106
|
+
activeTierMetadata?: AdapterTierMetadata;
|
|
76
107
|
usageDebugBodyKind?: UsageDebugBodyKind;
|
|
77
108
|
usageDebugBodySample?: string;
|
|
78
109
|
usageDebugContentType?: string;
|
|
@@ -90,11 +121,15 @@ export interface RequestLogContext {
|
|
|
90
121
|
upstreamError?: string;
|
|
91
122
|
/** HTTP status derived from a terminal `response.failed` SSE payload (429/401/503/etc.). */
|
|
92
123
|
terminalHttpStatus?: number;
|
|
124
|
+
/** Recognized structured terminal code whose exact identity must survive status mapping. */
|
|
125
|
+
terminalErrorCode?: typeof CYBER_POLICY_ERROR_CODE;
|
|
93
126
|
/** Structured reason from `response.incomplete`; internal-only input to log classification. */
|
|
94
127
|
terminalIncompleteReason?: string;
|
|
95
128
|
affinity?: "reused" | "new_bind" | "rebound" | "cleared";
|
|
96
129
|
transportPhase?: "pre_headers" | "mid_stream" | "terminal_sse";
|
|
97
130
|
terminalSource?: "upstream" | "synthetic";
|
|
131
|
+
/** Bounded route-decision trace (RI-01); never contains secrets. */
|
|
132
|
+
routeDecision?: RouteDecisionTraceV1;
|
|
98
133
|
}
|
|
99
134
|
|
|
100
135
|
export interface RequestLogEntry {
|
|
@@ -105,6 +140,12 @@ export interface RequestLogEntry {
|
|
|
105
140
|
/** TTFT: ms from request start to the first non-empty model output delta; unset for non-streaming/tool-only. */
|
|
106
141
|
firstOutputMs?: number;
|
|
107
142
|
surface?: "claude" | "claude-desktop" | "grok";
|
|
143
|
+
/**
|
|
144
|
+
* Set when the proxy answered this turn locally and sent nothing upstream. Without it a zero-send
|
|
145
|
+
* row is indistinguishable from a request that vanished. A fixed adapter-supplied identifier,
|
|
146
|
+
* never conversation-derived.
|
|
147
|
+
*/
|
|
148
|
+
localTerminalReason?: string;
|
|
108
149
|
/** The matched configured key's id. Set ONLY for admissionKind "configured" —
|
|
109
150
|
* never a sentinel, so a hand-edited entry whose id happens to be "loopback"
|
|
110
151
|
* cannot absorb unrelated traffic. */
|
|
@@ -115,19 +156,25 @@ export interface RequestLogEntry {
|
|
|
115
156
|
* product: widening that enum would merge Responses and Chat Completions,
|
|
116
157
|
* since both leave it undefined. */
|
|
117
158
|
inboundProtocol?: "responses" | "chat" | "messages";
|
|
159
|
+
accountLogLabel?: string;
|
|
118
160
|
/** Best-effort chat/session correlation for Logs grouping (#330). */
|
|
119
161
|
conversationId?: string;
|
|
120
162
|
requestedModel?: string;
|
|
163
|
+
requestedAlias?: string;
|
|
164
|
+
/** Original bare helper model when the opt-in shadow-call route rewrote this request. */
|
|
165
|
+
shadowCallRewrittenFrom?: string;
|
|
121
166
|
requestedEffort?: string;
|
|
122
167
|
effectiveEffort?: string;
|
|
123
168
|
reasoningWireField?: string;
|
|
124
|
-
reasoningWireValue?: string | number;
|
|
169
|
+
reasoningWireValue?: string | number | boolean;
|
|
170
|
+
callerServiceTier?: string;
|
|
125
171
|
requestedServiceTier?: string;
|
|
126
172
|
requestedSpeedLabel?: string;
|
|
127
173
|
configuredServiceTier?: string;
|
|
128
174
|
configuredSpeedLabel?: string;
|
|
129
175
|
modelSupportsServiceTier?: boolean;
|
|
130
176
|
responseServiceTier?: string;
|
|
177
|
+
tierOutcome?: AttemptTierOutcome;
|
|
131
178
|
resolvedModel?: string;
|
|
132
179
|
status: number;
|
|
133
180
|
durationMs: number;
|
|
@@ -146,6 +193,8 @@ export interface RequestLogEntry {
|
|
|
146
193
|
transportPhase?: "pre_headers" | "mid_stream" | "terminal_sse";
|
|
147
194
|
/** Whether the terminal came from a real upstream SSE event or a proxy synthetic tail. */
|
|
148
195
|
terminalSource?: "upstream" | "synthetic";
|
|
196
|
+
/** Bounded route-decision trace (RI-01); never contains secrets. */
|
|
197
|
+
routeDecision?: RouteDecisionTraceV1;
|
|
149
198
|
}
|
|
150
199
|
|
|
151
200
|
const requestLog: RequestLogEntry[] = [];
|
|
@@ -214,6 +263,7 @@ function asCloseReason(value: string | undefined): RequestLogEntry["closeReason"
|
|
|
214
263
|
export function requestLogEntryFromPersistedUsage(entry: PersistedUsageEntry): RequestLogEntry {
|
|
215
264
|
const terminalStatus = asTerminalStatus(entry.terminalStatus);
|
|
216
265
|
const closeReason = asCloseReason(entry.closeReason);
|
|
266
|
+
const routeDecision = normalizeRouteDecisionTraceForLog(entry.routeDecision);
|
|
217
267
|
return {
|
|
218
268
|
requestId: entry.requestId,
|
|
219
269
|
timestamp: entry.timestamp,
|
|
@@ -222,11 +272,19 @@ export function requestLogEntryFromPersistedUsage(entry: PersistedUsageEntry): R
|
|
|
222
272
|
...(entry.firstOutputMs !== undefined ? { firstOutputMs: entry.firstOutputMs } : {}),
|
|
223
273
|
...(isKnownUsageSurface(entry.surface) ? { surface: entry.surface } : {}),
|
|
224
274
|
...(entry.conversationId ? { conversationId: entry.conversationId } : {}),
|
|
275
|
+
...(isCodexUsageAccountLogLabel(entry.accountLogLabel)
|
|
276
|
+
? { accountLogLabel: entry.accountLogLabel }
|
|
277
|
+
: {}),
|
|
225
278
|
...(entry.requestedModel ? { requestedModel: entry.requestedModel } : {}),
|
|
279
|
+
...(entry.requestedAlias ? { requestedAlias: entry.requestedAlias } : {}),
|
|
280
|
+
...(entry.shadowCallRewrittenFrom
|
|
281
|
+
? { shadowCallRewrittenFrom: entry.shadowCallRewrittenFrom }
|
|
282
|
+
: {}),
|
|
226
283
|
...(entry.requestedEffort ? { requestedEffort: entry.requestedEffort } : {}),
|
|
227
284
|
...(entry.effectiveEffort ? { effectiveEffort: entry.effectiveEffort } : {}),
|
|
228
285
|
...(entry.reasoningWireField ? { reasoningWireField: entry.reasoningWireField } : {}),
|
|
229
286
|
...(entry.reasoningWireValue !== undefined ? { reasoningWireValue: entry.reasoningWireValue } : {}),
|
|
287
|
+
...(entry.callerServiceTier ? { callerServiceTier: entry.callerServiceTier } : {}),
|
|
230
288
|
...(entry.requestedServiceTier ? { requestedServiceTier: entry.requestedServiceTier } : {}),
|
|
231
289
|
...(entry.requestedSpeedLabel ? { requestedSpeedLabel: entry.requestedSpeedLabel } : {}),
|
|
232
290
|
...(entry.configuredServiceTier ? { configuredServiceTier: entry.configuredServiceTier } : {}),
|
|
@@ -235,6 +293,7 @@ export function requestLogEntryFromPersistedUsage(entry: PersistedUsageEntry): R
|
|
|
235
293
|
? { modelSupportsServiceTier: entry.modelSupportsServiceTier }
|
|
236
294
|
: {}),
|
|
237
295
|
...(entry.responseServiceTier ? { responseServiceTier: entry.responseServiceTier } : {}),
|
|
296
|
+
...(entry.tierOutcome ? { tierOutcome: entry.tierOutcome } : {}),
|
|
238
297
|
...(entry.resolvedModel ? { resolvedModel: entry.resolvedModel } : {}),
|
|
239
298
|
status: entry.status,
|
|
240
299
|
durationMs: entry.durationMs,
|
|
@@ -245,10 +304,22 @@ export function requestLogEntryFromPersistedUsage(entry: PersistedUsageEntry): R
|
|
|
245
304
|
usageStatus: entry.usageStatus,
|
|
246
305
|
...(entry.usage ? { usage: entry.usage } : {}),
|
|
247
306
|
...(entry.totalTokens !== undefined ? { totalTokens: entry.totalTokens } : {}),
|
|
248
|
-
...(entry.attempts
|
|
307
|
+
...(entry.attempts !== undefined ? { attempts: entry.attempts } : {}),
|
|
308
|
+
...(routeDecision ? { routeDecision } : {}),
|
|
249
309
|
};
|
|
250
310
|
}
|
|
251
311
|
|
|
312
|
+
/**
|
|
313
|
+
* Hydration guard: persisted traces are re-normalized before they enter the
|
|
314
|
+
* in-memory ring buffer so a hand-edited or corrupt row cannot poison the DTO.
|
|
315
|
+
* A row that fails validation is dropped, never forwarded unvalidated.
|
|
316
|
+
*/
|
|
317
|
+
function normalizeRouteDecisionTraceForLog(
|
|
318
|
+
entry: RouteDecisionTraceV1 | undefined,
|
|
319
|
+
): RouteDecisionTraceV1 | null {
|
|
320
|
+
return entry ? normalizeRouteDecisionTrace(entry) : null;
|
|
321
|
+
}
|
|
322
|
+
|
|
252
323
|
/**
|
|
253
324
|
* Seed the in-memory Logs ring buffer from usage.jsonl so GUI /api/logs survives
|
|
254
325
|
* `ocx stop` / `ocx start` (process restart). Idempotent per process; no-ops when
|
|
@@ -281,6 +352,20 @@ export function hydrateRequestLogsFromDisk(
|
|
|
281
352
|
}
|
|
282
353
|
|
|
283
354
|
export function addRequestLog(entry: RequestLogEntry) {
|
|
355
|
+
// Sanitize ONCE, at the ingress, and use that one value for both destinations.
|
|
356
|
+
//
|
|
357
|
+
// `addFinalRequestLog` is not the only way in: `addRequestLog` is exported and callable
|
|
358
|
+
// directly, and it retained the caller's entry verbatim in the in-memory ring while only the
|
|
359
|
+
// field-by-field disk projection below saw a sanitized value. That split let `/api/logs`
|
|
360
|
+
// serve a raw upstream-supplied marker — a newline in it can forge a record boundary in a
|
|
361
|
+
// line-oriented viewer — while `usage.jsonl` looked clean, which is the worst shape for a
|
|
362
|
+
// sanitization bug because the safe surface is the one you check.
|
|
363
|
+
const shadowCallRewrittenFrom = sanitizeLogMetadataString(entry.shadowCallRewrittenFrom);
|
|
364
|
+
const retained: RequestLogEntry = shadowCallRewrittenFrom === entry.shadowCallRewrittenFrom
|
|
365
|
+
? entry
|
|
366
|
+
: { ...entry, ...(shadowCallRewrittenFrom ? { shadowCallRewrittenFrom } : {}) };
|
|
367
|
+
if (!shadowCallRewrittenFrom && retained !== entry) delete retained.shadowCallRewrittenFrom;
|
|
368
|
+
entry = retained;
|
|
284
369
|
retainRequestLogEntry(entry);
|
|
285
370
|
try {
|
|
286
371
|
// Failure diagnostics survive the 200-entry ring buffer by riding the persisted
|
|
@@ -306,13 +391,21 @@ export function addRequestLog(entry: RequestLogEntry) {
|
|
|
306
391
|
...(entry.apiKeyId ? { apiKeyId: entry.apiKeyId } : {}),
|
|
307
392
|
...(isKnownAdmissionKind(entry.admissionKind) ? { admissionKind: entry.admissionKind } : {}),
|
|
308
393
|
...(isKnownInboundProtocol(entry.inboundProtocol) ? { inboundProtocol: entry.inboundProtocol } : {}),
|
|
394
|
+
...(isCodexUsageAccountLogLabel(entry.accountLogLabel)
|
|
395
|
+
? { accountLogLabel: entry.accountLogLabel }
|
|
396
|
+
: {}),
|
|
309
397
|
...(entry.conversationId ? { conversationId: entry.conversationId } : {}),
|
|
310
398
|
...(entry.resolvedModel ? { resolvedModel: entry.resolvedModel } : {}),
|
|
311
399
|
...(entry.requestedModel ? { requestedModel: entry.requestedModel } : {}),
|
|
400
|
+
...(entry.requestedAlias ? { requestedAlias: entry.requestedAlias } : {}),
|
|
401
|
+
...(entry.shadowCallRewrittenFrom
|
|
402
|
+
? { shadowCallRewrittenFrom: entry.shadowCallRewrittenFrom }
|
|
403
|
+
: {}),
|
|
312
404
|
...(entry.requestedEffort ? { requestedEffort: entry.requestedEffort } : {}),
|
|
313
405
|
...(entry.effectiveEffort ? { effectiveEffort: entry.effectiveEffort } : {}),
|
|
314
406
|
...(entry.reasoningWireField ? { reasoningWireField: entry.reasoningWireField } : {}),
|
|
315
407
|
...(entry.reasoningWireValue !== undefined ? { reasoningWireValue: entry.reasoningWireValue } : {}),
|
|
408
|
+
...(entry.callerServiceTier ? { callerServiceTier: entry.callerServiceTier } : {}),
|
|
316
409
|
...(entry.requestedServiceTier ? { requestedServiceTier: entry.requestedServiceTier } : {}),
|
|
317
410
|
...(entry.requestedSpeedLabel ? { requestedSpeedLabel: entry.requestedSpeedLabel } : {}),
|
|
318
411
|
...(entry.configuredServiceTier ? { configuredServiceTier: entry.configuredServiceTier } : {}),
|
|
@@ -321,14 +414,16 @@ export function addRequestLog(entry: RequestLogEntry) {
|
|
|
321
414
|
? { modelSupportsServiceTier: entry.modelSupportsServiceTier }
|
|
322
415
|
: {}),
|
|
323
416
|
...(entry.responseServiceTier ? { responseServiceTier: entry.responseServiceTier } : {}),
|
|
417
|
+
...(entry.tierOutcome ? { tierOutcome: entry.tierOutcome } : {}),
|
|
324
418
|
status: entry.status,
|
|
325
419
|
durationMs: entry.durationMs,
|
|
326
420
|
...(entry.firstOutputMs !== undefined ? { firstOutputMs: entry.firstOutputMs } : {}),
|
|
327
421
|
usageStatus: entry.usageStatus,
|
|
328
422
|
...(entry.usage ? { usage: entry.usage } : {}),
|
|
329
423
|
...(entry.totalTokens !== undefined ? { totalTokens: entry.totalTokens } : {}),
|
|
330
|
-
...(entry.attempts
|
|
424
|
+
...(entry.attempts !== undefined ? { attempts: entry.attempts } : {}),
|
|
331
425
|
...failureDiagnostics,
|
|
426
|
+
...(entry.routeDecision ? { routeDecision: entry.routeDecision } : {}),
|
|
332
427
|
});
|
|
333
428
|
} catch {
|
|
334
429
|
/* request logging must never fail a user request */
|
|
@@ -399,12 +494,11 @@ export function recordAdapterReasoning(
|
|
|
399
494
|
const reasoning = raw as Record<string, unknown>;
|
|
400
495
|
if (typeof reasoning.effectiveEffort !== "string" || !reasoning.effectiveEffort
|
|
401
496
|
|| (reasoning.wireField !== "reasoning_effort"
|
|
497
|
+
&& reasoning.wireField !== "reasoning.enabled"
|
|
498
|
+
&& reasoning.wireField !== "reasoning.effort"
|
|
402
499
|
&& reasoning.wireField !== "thinking_budget"
|
|
403
500
|
&& reasoning.wireField !== "thinking.type")
|
|
404
|
-
||
|
|
405
|
-
&& !(typeof reasoning.wireValue === "number"
|
|
406
|
-
&& Number.isFinite(reasoning.wireValue)
|
|
407
|
-
&& reasoning.wireValue >= 0))) {
|
|
501
|
+
|| !isValidReasoningWireValue(reasoning.wireField, reasoning.wireValue)) {
|
|
408
502
|
return;
|
|
409
503
|
}
|
|
410
504
|
|
|
@@ -425,12 +519,55 @@ export function recordAdapterReasoning(
|
|
|
425
519
|
}
|
|
426
520
|
}
|
|
427
521
|
|
|
428
|
-
|
|
522
|
+
/** Attach the serializing adapter's tier observation to the active durable attempt. */
|
|
523
|
+
export function recordAdapterTier(
|
|
524
|
+
logCtx: RequestLogContext,
|
|
525
|
+
request: AdapterRequest,
|
|
526
|
+
): void {
|
|
527
|
+
recordAdapterTierMetadata(logCtx, request.tierLog);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/** Attach adapter-owned metadata for transports that expose no AdapterRequest (runTurn). */
|
|
531
|
+
export function recordAdapterTierMetadata(
|
|
532
|
+
logCtx: RequestLogContext,
|
|
533
|
+
metadata: AdapterTierMetadata | undefined,
|
|
534
|
+
): void {
|
|
535
|
+
delete logCtx.tierOutcome;
|
|
536
|
+
delete logCtx.activeTierMetadata;
|
|
537
|
+
const attempt = logCtx.activeAttempt;
|
|
538
|
+
if (attempt) delete attempt.tierOutcome;
|
|
539
|
+
|
|
540
|
+
try {
|
|
541
|
+
const outcome = metadata?.outcome;
|
|
542
|
+
if (!metadata || !outcome) return;
|
|
543
|
+
logCtx.tierOutcome = outcome;
|
|
544
|
+
logCtx.activeTierMetadata = metadata;
|
|
545
|
+
if (attempt) attempt.tierOutcome = outcome;
|
|
546
|
+
} catch {
|
|
547
|
+
// Request logging is best-effort and must not affect request delivery.
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
export function requestLogErrorCode(
|
|
552
|
+
status: number,
|
|
553
|
+
upstreamError?: string,
|
|
554
|
+
terminalErrorCode?: string,
|
|
555
|
+
): string | undefined {
|
|
429
556
|
if (status >= 200 && status < 400) return undefined;
|
|
557
|
+
// A structured terminal code is authoritative even when the provider message is localized,
|
|
558
|
+
// generic, or absent. Only preserve the one narrowly recognized policy code here: broadly
|
|
559
|
+
// forwarding arbitrary upstream codes would change unrelated request-log taxonomy.
|
|
560
|
+
if (isCyberPolicyCode(terminalErrorCode)) return CYBER_POLICY_ERROR_CODE;
|
|
561
|
+
const classifiedCode = upstreamError?.trim()
|
|
562
|
+
? classifyError(status, "upstream_error", upstreamError).code
|
|
563
|
+
: undefined;
|
|
430
564
|
// Defense in depth: mid-stream web-search aborts used to land as 502 with this message.
|
|
431
|
-
if (status === 499 ||
|
|
565
|
+
if (status === 499 || classifiedCode === "client_closed_request") {
|
|
432
566
|
return "client_closed_request";
|
|
433
567
|
}
|
|
568
|
+
// Keep the high-confidence message fallback for runtimes/providers that stripped the
|
|
569
|
+
// structured code before emitting response.failed.
|
|
570
|
+
if (classifiedCode === CYBER_POLICY_ERROR_CODE) return CYBER_POLICY_ERROR_CODE;
|
|
434
571
|
if (status === 400 || status === 409) return "invalid_request_error";
|
|
435
572
|
if (status === 401) return "invalid_api_key";
|
|
436
573
|
if (status === 403) {
|
|
@@ -493,9 +630,19 @@ export function applyResponseLogMetadata(logCtx: RequestLogContext, payload: unk
|
|
|
493
630
|
: payload;
|
|
494
631
|
if (!source || typeof source !== "object") return;
|
|
495
632
|
const model = (source as { model?: unknown }).model;
|
|
496
|
-
if (
|
|
633
|
+
if (
|
|
634
|
+
!logCtx.preserveResolvedModelFromRoute
|
|
635
|
+
&& typeof model === "string"
|
|
636
|
+
&& model.trim()
|
|
637
|
+
) logCtx.resolvedModel = model;
|
|
497
638
|
const serviceTier = (source as { service_tier?: unknown }).service_tier;
|
|
498
|
-
if (typeof serviceTier === "string" && serviceTier.trim())
|
|
639
|
+
if (typeof serviceTier === "string" && serviceTier.trim()) {
|
|
640
|
+
const sanitized = sanitizeLogMetadataString(serviceTier);
|
|
641
|
+
if (sanitized) logCtx.responseServiceTier = sanitized;
|
|
642
|
+
logCtx.activeTierMetadata?.observeResponseServiceTier(serviceTier);
|
|
643
|
+
} else if (Object.prototype.hasOwnProperty.call(source, "service_tier")) {
|
|
644
|
+
logCtx.activeTierMetadata?.observeResponseServiceTier(serviceTier);
|
|
645
|
+
}
|
|
499
646
|
const usage = usageFromResponsesPayload((source as { usage?: unknown }).usage);
|
|
500
647
|
if (usage && !logCtx.usageFromBridge) {
|
|
501
648
|
logCtx.usage = usage;
|
|
@@ -561,6 +708,7 @@ export function inspectResponseLogJson(logCtx: RequestLogContext, text: string):
|
|
|
561
708
|
try {
|
|
562
709
|
applyResponseLogMetadata(logCtx, JSON.parse(text));
|
|
563
710
|
} catch {
|
|
711
|
+
logCtx.activeTierMetadata?.markResponseUnparseable();
|
|
564
712
|
/* body may not be JSON; request log metadata is best-effort only */
|
|
565
713
|
}
|
|
566
714
|
captureUpstreamError(logCtx, text);
|
|
@@ -591,6 +739,7 @@ export function inspectResponseLogSsePayloadParsed(
|
|
|
591
739
|
const debugEnabled = isUsageDebugEnabled();
|
|
592
740
|
const sseAlreadyMarked = logCtx.usageDebugBodyKind === "sse";
|
|
593
741
|
if (parsed !== undefined) applyResponseLogMetadata(logCtx, parsed);
|
|
742
|
+
else logCtx.activeTierMetadata?.markResponseUnparseable();
|
|
594
743
|
captureUpstreamErrorParsed(logCtx, payload, parsed);
|
|
595
744
|
if (debugEnabled) {
|
|
596
745
|
if (!sseAlreadyMarked) {
|
|
@@ -634,7 +783,7 @@ function captureUpstreamErrorParsed(
|
|
|
634
783
|
last_error?: { message?: unknown };
|
|
635
784
|
response?: {
|
|
636
785
|
error?: { type?: unknown; code?: unknown; message?: unknown };
|
|
637
|
-
incomplete_details?: { reason?: unknown };
|
|
786
|
+
incomplete_details?: { reason?: unknown; message?: unknown };
|
|
638
787
|
};
|
|
639
788
|
};
|
|
640
789
|
captureTerminalHttpStatus(logCtx, json);
|
|
@@ -648,7 +797,8 @@ function captureUpstreamErrorParsed(
|
|
|
648
797
|
if (logCtx.upstreamError) return;
|
|
649
798
|
const message = json?.error?.message
|
|
650
799
|
?? json?.last_error?.message
|
|
651
|
-
?? json?.response?.error?.message
|
|
800
|
+
?? json?.response?.error?.message
|
|
801
|
+
?? json?.response?.incomplete_details?.message;
|
|
652
802
|
if (typeof message === "string" && message.trim()) {
|
|
653
803
|
logCtx.upstreamError = redactSecretString(message).slice(0, 500);
|
|
654
804
|
return;
|
|
@@ -687,17 +837,43 @@ function captureTerminalHttpStatus(
|
|
|
687
837
|
logCtx: RequestLogContext,
|
|
688
838
|
json: {
|
|
689
839
|
type?: unknown;
|
|
690
|
-
|
|
840
|
+
code?: unknown;
|
|
841
|
+
message?: unknown;
|
|
842
|
+
error?: { type?: unknown; code?: unknown; message?: unknown };
|
|
843
|
+
last_error?: { type?: unknown; code?: unknown; message?: unknown };
|
|
844
|
+
response?: {
|
|
845
|
+
error?: { type?: unknown; code?: unknown; message?: unknown };
|
|
846
|
+
incomplete_details?: { code?: unknown; message?: unknown };
|
|
847
|
+
};
|
|
691
848
|
},
|
|
692
849
|
): void {
|
|
693
850
|
if (logCtx.terminalHttpStatus !== undefined) return;
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
851
|
+
const type = json.type;
|
|
852
|
+
if (type !== "response.failed" && type !== "response.incomplete" && type !== "error") return;
|
|
853
|
+
const responseError = json.response?.error;
|
|
854
|
+
const responseDetails = json.response?.incomplete_details;
|
|
855
|
+
const candidates = [json.error, json.last_error, responseError, responseDetails, json];
|
|
856
|
+
const policy = candidates.some(candidate => (
|
|
857
|
+
candidate?.code === null || typeof candidate?.code === "string"
|
|
858
|
+
) && isCyberPolicyCode(candidate.code as string | null | undefined))
|
|
859
|
+
|| candidates.some(candidate => (
|
|
860
|
+
typeof candidate?.message === "string"
|
|
861
|
+
&& candidate.message.trim().length > 0
|
|
862
|
+
&& isCyberPolicyMessage(candidate.message)
|
|
863
|
+
));
|
|
864
|
+
if (policy) {
|
|
865
|
+
logCtx.terminalErrorCode = CYBER_POLICY_ERROR_CODE;
|
|
866
|
+
logCtx.terminalHttpStatus = 400;
|
|
867
|
+
return;
|
|
868
|
+
}
|
|
869
|
+
if (type !== "response.failed" || !responseError || typeof responseError !== "object") return;
|
|
870
|
+
const responseCode = responseError.code === null || typeof responseError.code === "string"
|
|
871
|
+
? responseError.code
|
|
872
|
+
: undefined;
|
|
697
873
|
logCtx.terminalHttpStatus = httpStatusFromTerminalError({
|
|
698
|
-
type: typeof
|
|
699
|
-
code:
|
|
700
|
-
message: typeof
|
|
874
|
+
type: typeof responseError.type === "string" ? responseError.type : undefined,
|
|
875
|
+
code: responseCode,
|
|
876
|
+
message: typeof responseError.message === "string" ? responseError.message : undefined,
|
|
701
877
|
});
|
|
702
878
|
}
|
|
703
879
|
|
|
@@ -752,7 +928,11 @@ export function addFinalRequestLog(
|
|
|
752
928
|
const effectiveStatus = status >= 500 && logCtx.upstreamError && isClientClosedMessage(logCtx.upstreamError)
|
|
753
929
|
? 499
|
|
754
930
|
: status;
|
|
755
|
-
const errorCode = requestLogErrorCode(
|
|
931
|
+
const errorCode = requestLogErrorCode(
|
|
932
|
+
effectiveStatus,
|
|
933
|
+
logCtx.upstreamError,
|
|
934
|
+
logCtx.terminalErrorCode,
|
|
935
|
+
);
|
|
756
936
|
// A response.failed whose classified status is 499 is still a client cancel, not an upstream
|
|
757
937
|
// terminal failure — keep /api/logs closeReason aligned with that.
|
|
758
938
|
const closeReason = effectiveStatus === 499
|
|
@@ -765,22 +945,35 @@ export function addFinalRequestLog(
|
|
|
765
945
|
Date.now() - (logCtx.activeAttemptStartedAt ?? start),
|
|
766
946
|
logCtx.usage,
|
|
767
947
|
);
|
|
948
|
+
// The final row and its active physical attempt describe the same terminal. Preserve the
|
|
949
|
+
// semantic code on both so detailed attempt telemetry cannot regress to a generic status code.
|
|
950
|
+
if (errorCode) logCtx.activeAttempt.errorCode = errorCode;
|
|
951
|
+
else delete logCtx.activeAttempt.errorCode;
|
|
768
952
|
}
|
|
769
953
|
const existing = finalizedUsage(
|
|
770
954
|
logCtx.providerAdapter ?? logCtx.provider,
|
|
771
955
|
logCtx.usage,
|
|
772
956
|
logCtx.usageLogInputTokens,
|
|
957
|
+
contextWindowForModel(logCtx.providerAdapter ?? logCtx.provider, logCtx.model),
|
|
958
|
+
logCtx.localTerminalReason !== undefined,
|
|
773
959
|
);
|
|
774
960
|
const attempts = logCtx.attempts?.map(attempt => ({
|
|
775
961
|
...attempt,
|
|
776
962
|
recoveryKinds: [...attempt.recoveryKinds],
|
|
777
963
|
...(attempt.usage ? { usage: { ...attempt.usage } } : {}),
|
|
964
|
+
...(attempt.tierOutcome ? { tierOutcome: { ...attempt.tierOutcome } } : {}),
|
|
778
965
|
}));
|
|
779
966
|
const isCombo = logCtx.comboId !== undefined && (attempts?.length ?? 0) > 0;
|
|
780
967
|
const aggregate = isCombo ? aggregateAttemptUsage(attempts ?? []) : null;
|
|
781
968
|
const loggedUsage = aggregate?.usage ?? existing.usage;
|
|
782
969
|
const usageStatus = aggregate?.status ?? existing.status;
|
|
783
970
|
const totalTokens = aggregate?.totalTokens ?? existing.totalTokens;
|
|
971
|
+
// Sanitize at the logging layer, not only at the one call site that populates this today.
|
|
972
|
+
// The value originates in an upstream-supplied model id, so an unsanitized newline would
|
|
973
|
+
// let a single field forge a record boundary in any line-oriented log viewer. Doing it here
|
|
974
|
+
// means a future caller cannot reintroduce the hole by forgetting to sanitize first, and
|
|
975
|
+
// the in-memory /api/logs row matches what usage.jsonl already stores.
|
|
976
|
+
const shadowCallRewrittenFrom = sanitizeLogMetadataString(logCtx.shadowCallRewrittenFrom);
|
|
784
977
|
addLog({
|
|
785
978
|
requestId,
|
|
786
979
|
timestamp: start,
|
|
@@ -790,18 +983,30 @@ export function addFinalRequestLog(
|
|
|
790
983
|
...(logCtx.apiKeyId ? { apiKeyId: logCtx.apiKeyId } : {}),
|
|
791
984
|
...(logCtx.admissionKind ? { admissionKind: logCtx.admissionKind } : {}),
|
|
792
985
|
...(logCtx.inboundProtocol ? { inboundProtocol: logCtx.inboundProtocol } : {}),
|
|
986
|
+
...(logCtx.localTerminalReason
|
|
987
|
+
? { localTerminalReason: sanitizeLogMetadataString(logCtx.localTerminalReason) }
|
|
988
|
+
: {}),
|
|
989
|
+
...(isCodexUsageAccountLogLabel(logCtx.accountLogLabel)
|
|
990
|
+
? { accountLogLabel: logCtx.accountLogLabel }
|
|
991
|
+
: {}),
|
|
793
992
|
...(logCtx.conversationId ? { conversationId: logCtx.conversationId } : {}),
|
|
794
993
|
...(logCtx.requestedModel ? { requestedModel: logCtx.requestedModel } : {}),
|
|
994
|
+
...(logCtx.requestedAlias ? { requestedAlias: logCtx.requestedAlias } : {}),
|
|
995
|
+
...(shadowCallRewrittenFrom ? { shadowCallRewrittenFrom } : {}),
|
|
795
996
|
...(logCtx.requestedEffort ? { requestedEffort: logCtx.requestedEffort } : {}),
|
|
796
997
|
...(logCtx.effectiveEffort ? { effectiveEffort: logCtx.effectiveEffort } : {}),
|
|
797
998
|
...(logCtx.reasoningWireField ? { reasoningWireField: logCtx.reasoningWireField } : {}),
|
|
798
999
|
...(logCtx.reasoningWireValue !== undefined ? { reasoningWireValue: logCtx.reasoningWireValue } : {}),
|
|
1000
|
+
...(logCtx.callerServiceTier ? { callerServiceTier: logCtx.callerServiceTier } : {}),
|
|
799
1001
|
...(logCtx.requestedServiceTier ? { requestedServiceTier: logCtx.requestedServiceTier } : {}),
|
|
800
1002
|
...(logCtx.requestedSpeedLabel ? { requestedSpeedLabel: logCtx.requestedSpeedLabel } : {}),
|
|
801
1003
|
...(logCtx.configuredServiceTier ? { configuredServiceTier: logCtx.configuredServiceTier } : {}),
|
|
802
1004
|
...(logCtx.configuredSpeedLabel ? { configuredSpeedLabel: logCtx.configuredSpeedLabel } : {}),
|
|
803
1005
|
...(logCtx.modelSupportsServiceTier !== undefined ? { modelSupportsServiceTier: logCtx.modelSupportsServiceTier } : {}),
|
|
804
1006
|
...(logCtx.responseServiceTier ? { responseServiceTier: logCtx.responseServiceTier } : {}),
|
|
1007
|
+
...((attempts?.at(-1)?.tierOutcome ?? logCtx.tierOutcome)
|
|
1008
|
+
? { tierOutcome: attempts?.at(-1)?.tierOutcome ?? { ...logCtx.tierOutcome! } }
|
|
1009
|
+
: {}),
|
|
805
1010
|
...(logCtx.resolvedModel ? { resolvedModel: logCtx.resolvedModel } : {}),
|
|
806
1011
|
status: effectiveStatus,
|
|
807
1012
|
durationMs: Date.now() - start,
|
|
@@ -813,10 +1018,11 @@ export function addFinalRequestLog(
|
|
|
813
1018
|
usageStatus,
|
|
814
1019
|
...(loggedUsage ? { usage: loggedUsage } : {}),
|
|
815
1020
|
...(totalTokens !== undefined ? { totalTokens } : {}),
|
|
816
|
-
...(attempts
|
|
1021
|
+
...(attempts !== undefined ? { attempts } : {}),
|
|
817
1022
|
...(logCtx.affinity ? { affinity: logCtx.affinity } : {}),
|
|
818
1023
|
...(logCtx.transportPhase ? { transportPhase: logCtx.transportPhase } : {}),
|
|
819
1024
|
...(logCtx.terminalSource ? { terminalSource: logCtx.terminalSource } : {}),
|
|
1025
|
+
...(logCtx.routeDecision ? { routeDecision: logCtx.routeDecision } : {}),
|
|
820
1026
|
});
|
|
821
1027
|
if (isUsageDebugEnabled()) {
|
|
822
1028
|
appendUsageDebug({
|
|
@@ -844,6 +1050,15 @@ export function filterRequestLogs(logs: RequestLogEntry[], params: URLSearchPara
|
|
|
844
1050
|
if (conversationId) {
|
|
845
1051
|
filtered = filtered.filter(entry => matchesLogConversationId(entry.conversationId, conversationId));
|
|
846
1052
|
}
|
|
1053
|
+
// #2704: there was no `model` clause at all, so `?model=x` was ACCEPTED and silently
|
|
1054
|
+
// ignored -- worse than an error, because it yields wrong conclusions from output that
|
|
1055
|
+
// looks correct. Attempts are matched for the same reason `provider` matches them: a
|
|
1056
|
+
// request that failed over should be findable by the model that actually served it.
|
|
1057
|
+
const model = params.get("model")?.trim();
|
|
1058
|
+
if (model) {
|
|
1059
|
+
filtered = filtered.filter(entry => entry.model === model
|
|
1060
|
+
|| entry.attempts?.some(attempt => attempt.model === model));
|
|
1061
|
+
}
|
|
847
1062
|
const status = params.get("status")?.trim().toLowerCase();
|
|
848
1063
|
if (status) {
|
|
849
1064
|
filtered = /^[1-5]xx$/.test(status)
|
|
@@ -887,27 +1102,70 @@ interface FinalizedUsageResult {
|
|
|
887
1102
|
totalTokens?: number;
|
|
888
1103
|
}
|
|
889
1104
|
|
|
1105
|
+
/**
|
|
1106
|
+
* Context window for the routed model, used to cap the token estimate (codex-router PR #140):
|
|
1107
|
+
* a request the provider answered cannot have exceeded the window, so the estimate must never
|
|
1108
|
+
* claim it did. The family is picked by the route ADAPTER, not the model id alone, because
|
|
1109
|
+
* claude-family ids are shared between Kiro and Cursor with different windows. Kiro "auto" is
|
|
1110
|
+
* a router with no fixed window and is never guessed; unknown adapters/models stay uncapped.
|
|
1111
|
+
*/
|
|
1112
|
+
function contextWindowForModel(adapter: string, modelId: string | undefined): number | undefined {
|
|
1113
|
+
if (!modelId) return undefined;
|
|
1114
|
+
if (adapter === "kiro" || adapter.startsWith("kiro-")) {
|
|
1115
|
+
const normalized = normalizeKiroModelId(modelId);
|
|
1116
|
+
if (normalized === "auto") return undefined;
|
|
1117
|
+
return modelRecordValue(KIRO_MODEL_CONTEXT_WINDOWS, modelId)
|
|
1118
|
+
?? modelRecordValue(KIRO_MODEL_CONTEXT_WINDOWS, normalized);
|
|
1119
|
+
}
|
|
1120
|
+
if (adapter === "cursor" || adapter.startsWith("cursor-")) {
|
|
1121
|
+
return inferCursorContextWindow(modelId);
|
|
1122
|
+
}
|
|
1123
|
+
return undefined;
|
|
1124
|
+
}
|
|
1125
|
+
|
|
890
1126
|
function finalizedUsage(
|
|
891
1127
|
adapter: string,
|
|
892
1128
|
usage: OcxUsage | undefined,
|
|
893
1129
|
inputTokenEstimate: number | undefined,
|
|
1130
|
+
contextWindow: number | undefined,
|
|
1131
|
+
locallyAnswered = false,
|
|
894
1132
|
): FinalizedUsageResult {
|
|
1133
|
+
// The ESTIMATE itself is capped at the model's context window (codex-router PR #140). The
|
|
1134
|
+
// combined value below keeps its max(inputTokens, estimate) behavior — a provider-reported
|
|
1135
|
+
// positive count is never reduced by this cap, only the estimate that could substitute it.
|
|
895
1136
|
const estimate = typeof inputTokenEstimate === "number"
|
|
896
1137
|
&& Number.isFinite(inputTokenEstimate)
|
|
897
1138
|
&& inputTokenEstimate >= 0
|
|
898
|
-
? inputTokenEstimate
|
|
1139
|
+
? capEstimateAtContextWindow(inputTokenEstimate, contextWindow)
|
|
899
1140
|
: undefined;
|
|
900
|
-
const finalUsage = usageForFinalLog(adapter, usage);
|
|
1141
|
+
const finalUsage = usageForFinalLog(adapter, usage, locallyAnswered);
|
|
901
1142
|
const usageFallback = !finalUsage && estimate !== undefined
|
|
902
1143
|
? { inputTokens: estimate, outputTokens: 0, estimated: true }
|
|
903
1144
|
: undefined;
|
|
904
|
-
const
|
|
1145
|
+
const combinedInputTokens = finalUsage && estimate !== undefined
|
|
1146
|
+
? Math.max(finalUsage.inputTokens, estimate)
|
|
1147
|
+
: undefined;
|
|
1148
|
+
const loggedUsage = finalUsage && combinedInputTokens !== undefined
|
|
905
1149
|
? {
|
|
906
1150
|
...finalUsage,
|
|
907
|
-
inputTokens:
|
|
1151
|
+
inputTokens: combinedInputTokens,
|
|
1152
|
+
totalTokens: combinedInputTokens + finalUsage.outputTokens,
|
|
908
1153
|
estimated: true,
|
|
909
1154
|
}
|
|
910
|
-
:
|
|
1155
|
+
: finalUsage
|
|
1156
|
+
// When the adapter alone produced an estimated count and no local estimate
|
|
1157
|
+
// exists, cap it at the context window — an adapter estimate above the window
|
|
1158
|
+
// misleads the usage dashboard. The combined branch (above) already caps the
|
|
1159
|
+
// ESTIMATE via capEstimateAtContextWindow, and Math.max preserves a real
|
|
1160
|
+
// provider-reported count, so it needs no further reduction.
|
|
1161
|
+
? (finalUsage.estimated && contextWindow !== undefined && finalUsage.inputTokens > contextWindow
|
|
1162
|
+
? {
|
|
1163
|
+
...finalUsage,
|
|
1164
|
+
inputTokens: contextWindow,
|
|
1165
|
+
totalTokens: contextWindow + finalUsage.outputTokens,
|
|
1166
|
+
}
|
|
1167
|
+
: finalUsage)
|
|
1168
|
+
: usageFallback;
|
|
911
1169
|
const totalTokens = usageTotalTokens(loggedUsage);
|
|
912
1170
|
return {
|
|
913
1171
|
status: usageStatusForFinalLog(loggedUsage),
|
|
@@ -939,10 +1197,12 @@ export function sealRequestAttemptIdentity(
|
|
|
939
1197
|
attempt: PersistedUsageAttempt | undefined,
|
|
940
1198
|
provider: string,
|
|
941
1199
|
adapter: string,
|
|
1200
|
+
accountLogLabel?: string,
|
|
942
1201
|
): void {
|
|
943
1202
|
if (!attempt) return;
|
|
944
1203
|
attempt.provider = provider;
|
|
945
1204
|
attempt.adapter = adapter;
|
|
1205
|
+
if (isCodexUsageAccountLogLabel(accountLogLabel)) attempt.accountLogLabel = accountLogLabel;
|
|
946
1206
|
}
|
|
947
1207
|
|
|
948
1208
|
export function noteAttemptSend(
|
|
@@ -955,7 +1215,12 @@ export function noteAttemptSend(
|
|
|
955
1215
|
if (typeof inputTokenEstimate === "number"
|
|
956
1216
|
&& Number.isFinite(inputTokenEstimate)
|
|
957
1217
|
&& inputTokenEstimate >= 0) {
|
|
958
|
-
|
|
1218
|
+
// Store the ESTIMATE field already capped at the model's window (codex-router PR #140):
|
|
1219
|
+
// what gets persisted, and later merged into usage, never claims a count above the window.
|
|
1220
|
+
attempt.inputTokenEstimate = capEstimateAtContextWindow(
|
|
1221
|
+
inputTokenEstimate,
|
|
1222
|
+
contextWindowForModel(attempt.adapter, attempt.model),
|
|
1223
|
+
);
|
|
959
1224
|
}
|
|
960
1225
|
if (recovery && !attempt.recoveryKinds.includes(recovery)) {
|
|
961
1226
|
attempt.recoveryKinds.push(recovery);
|
|
@@ -972,6 +1237,8 @@ export function finishRequestAttempt(
|
|
|
972
1237
|
attempt.adapter,
|
|
973
1238
|
usage ?? attempt.usage,
|
|
974
1239
|
attempt.inputTokenEstimate,
|
|
1240
|
+
contextWindowForModel(attempt.adapter, attempt.model),
|
|
1241
|
+
attempt.locallyAnswered === true,
|
|
975
1242
|
);
|
|
976
1243
|
attempt.status = status;
|
|
977
1244
|
attempt.durationMs = Math.max(0, durationMs);
|