@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
package/src/usage/summary.ts
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import { baseProviderLabel } from "../providers/label";
|
|
2
2
|
import { canonicalAntigravityUsageModel } from "../providers/antigravity-models";
|
|
3
3
|
import { usageDisplayTotalTokens } from "./totals";
|
|
4
|
-
import type
|
|
5
|
-
import { estimateComboCost, estimateRequestCost,
|
|
4
|
+
import { isCodexUsageAccountLogLabel, type PersistedUsageEntry, type UsageStatus } from "./log";
|
|
5
|
+
import { estimateAttemptCost, estimateComboCost, estimateRequestCost, serviceTierContext } from "./cost";
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Canonical range members. The warm-up loop in the management usage route
|
|
9
|
+
* iterates this constant rather than its own literal: the two used to be
|
|
10
|
+
* written separately, and a subset literal type-checks perfectly happily, so a
|
|
11
|
+
* range added to the union but forgotten in the loop was never warmed and
|
|
12
|
+
* never invalidated alongside its siblings.
|
|
13
|
+
*/
|
|
14
|
+
export const USAGE_RANGES = ["today", "7d", "30d", "all"] as const;
|
|
15
|
+
export type UsageRange = typeof USAGE_RANGES[number];
|
|
16
|
+
export const USAGE_SURFACES = ["all", "codex", "claude", "grok"] as const;
|
|
17
|
+
export type UsageSurface = typeof USAGE_SURFACES[number];
|
|
9
18
|
|
|
10
19
|
export interface UsageSummaryTotals {
|
|
11
20
|
requests: number;
|
|
@@ -40,6 +49,8 @@ export interface UsageDay {
|
|
|
40
49
|
measuredRequests: number;
|
|
41
50
|
reportedRequests: number;
|
|
42
51
|
totalTokens: number;
|
|
52
|
+
/** Display-time estimated cost for this local day, summed from its model rows. */
|
|
53
|
+
estimatedCostUsd: number;
|
|
43
54
|
models: UsageDayModel[];
|
|
44
55
|
}
|
|
45
56
|
|
|
@@ -49,6 +60,8 @@ export interface UsageDayModel {
|
|
|
49
60
|
requests: number;
|
|
50
61
|
attemptCount: number;
|
|
51
62
|
totalTokens: number;
|
|
63
|
+
/** Display-time estimated cost attributed to this provider/model on this day. */
|
|
64
|
+
estimatedCostUsd: number;
|
|
52
65
|
}
|
|
53
66
|
|
|
54
67
|
export interface UsageModel {
|
|
@@ -79,6 +92,28 @@ export interface UsageProvider {
|
|
|
79
92
|
estimatedCostUsd?: number;
|
|
80
93
|
}
|
|
81
94
|
|
|
95
|
+
export interface UsageAccount {
|
|
96
|
+
accountLogLabel: string;
|
|
97
|
+
ambiguous: boolean;
|
|
98
|
+
requests: number;
|
|
99
|
+
attemptCount: number;
|
|
100
|
+
measuredAttempts: number;
|
|
101
|
+
reportedAttempts: number;
|
|
102
|
+
estimatedAttempts: number;
|
|
103
|
+
unmeteredAttempts: number;
|
|
104
|
+
inputTokens: number;
|
|
105
|
+
outputTokens: number;
|
|
106
|
+
cacheReadInputTokens: number;
|
|
107
|
+
cacheCreationInputTokens: number;
|
|
108
|
+
reasoningOutputTokens: number;
|
|
109
|
+
totalTokens: number;
|
|
110
|
+
usageCoverageRatio: number;
|
|
111
|
+
estimatedCostUsd?: number;
|
|
112
|
+
pricedAttempts: number;
|
|
113
|
+
unpricedAttempts: number;
|
|
114
|
+
priceCoverageRatio: number;
|
|
115
|
+
}
|
|
116
|
+
|
|
82
117
|
export interface UsageSummary {
|
|
83
118
|
range: UsageRange;
|
|
84
119
|
surface: UsageSurface;
|
|
@@ -88,6 +123,27 @@ export interface UsageSummary {
|
|
|
88
123
|
days: UsageDay[];
|
|
89
124
|
models: UsageModel[];
|
|
90
125
|
providers: UsageProvider[];
|
|
126
|
+
accounts: UsageAccount[];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Echo of an applied provider/model projection.
|
|
131
|
+
*
|
|
132
|
+
* Present only on a filtered response so a consumer can distinguish "no rows
|
|
133
|
+
* matched" from "no traffic in this window", and can tell that the totals it
|
|
134
|
+
* is reading are a projection rather than the whole window.
|
|
135
|
+
*/
|
|
136
|
+
export interface UsageFilterEcho {
|
|
137
|
+
provider: string | null;
|
|
138
|
+
model: string | null;
|
|
139
|
+
matched: boolean;
|
|
140
|
+
/**
|
|
141
|
+
* True when a retained row came from a combo attribution. Cost partitions
|
|
142
|
+
* cleanly across attempts, but a combo request is counted once per
|
|
143
|
+
* participating model, so a filtered REQUEST count can exceed the number of
|
|
144
|
+
* distinct requests. Cost is unaffected.
|
|
145
|
+
*/
|
|
146
|
+
comboOverlap: boolean;
|
|
91
147
|
}
|
|
92
148
|
|
|
93
149
|
const DAY_MS = 86_400_000;
|
|
@@ -104,6 +160,10 @@ function retainedBreakdownRows<T>(
|
|
|
104
160
|
}
|
|
105
161
|
|
|
106
162
|
export function parseRange(input: string | null | undefined): UsageRange {
|
|
163
|
+
// `1d` normalises here rather than becoming a second union member: a second
|
|
164
|
+
// member would need its own cache slot, its own grid arm and its own test
|
|
165
|
+
// matrix for no user-visible gain.
|
|
166
|
+
if (input === "today" || input === "1d") return "today";
|
|
107
167
|
if (input === "7d" || input === "30d" || input === "all") return input;
|
|
108
168
|
return "30d";
|
|
109
169
|
}
|
|
@@ -113,9 +173,28 @@ export function parseUsageSurface(input: string | null | undefined): UsageSurfac
|
|
|
113
173
|
return "all";
|
|
114
174
|
}
|
|
115
175
|
|
|
116
|
-
function
|
|
117
|
-
|
|
118
|
-
|
|
176
|
+
function startOfLocalDay(ts: number): number {
|
|
177
|
+
const d = new Date(ts);
|
|
178
|
+
d.setHours(0, 0, 0, 0);
|
|
179
|
+
return d.getTime();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export function rangeWindow(range: UsageRange, now: number): { since: number | null; days: number } {
|
|
183
|
+
// Handled before the others because the fallthrough below is the `all`
|
|
184
|
+
// window: a range that reaches it is silently reported as all-time history,
|
|
185
|
+
// which for a cost surface is a plausible-looking wrong answer rather than a
|
|
186
|
+
// visible failure.
|
|
187
|
+
if (range === "today") return { since: startOfLocalDay(now), days: 1 };
|
|
188
|
+
if (range === "7d") {
|
|
189
|
+
const start = new Date(startOfLocalDay(now));
|
|
190
|
+
start.setDate(start.getDate() - 6);
|
|
191
|
+
return { since: start.getTime(), days: 7 };
|
|
192
|
+
}
|
|
193
|
+
if (range === "30d") {
|
|
194
|
+
const start = new Date(startOfLocalDay(now));
|
|
195
|
+
start.setDate(start.getDate() - 29);
|
|
196
|
+
return { since: start.getTime(), days: 30 };
|
|
197
|
+
}
|
|
119
198
|
return { since: null, days: 0 };
|
|
120
199
|
}
|
|
121
200
|
|
|
@@ -286,7 +365,7 @@ function addEstimatedCost(
|
|
|
286
365
|
totals.unmeteredRequests += 1;
|
|
287
366
|
return;
|
|
288
367
|
}
|
|
289
|
-
const tier =
|
|
368
|
+
const tier = serviceTierContext(entry);
|
|
290
369
|
const estimate = entry.attempts?.length
|
|
291
370
|
? estimateComboCost(entry.attempts, undefined, tier)
|
|
292
371
|
: estimateRequestCost({ provider: entry.provider, model: entry.model, usage: entry.usage, usageStatus: entry.usageStatus, serviceTier: tier });
|
|
@@ -298,6 +377,33 @@ function addEstimatedCost(
|
|
|
298
377
|
totals.estimatedCostUsd += estimate.cost.total;
|
|
299
378
|
}
|
|
300
379
|
|
|
380
|
+
/**
|
|
381
|
+
* Per-attribution cost for one entry, keyed by `provider/model`.
|
|
382
|
+
*
|
|
383
|
+
* Mirrors the attribution branch in {@link buildModels}: a combo request is
|
|
384
|
+
* priced per attempt and each attempt's cost belongs to its own model, so cost
|
|
385
|
+
* partitions across models rather than being counted once per participant. A
|
|
386
|
+
* single-target request contributes its whole cost to the entry's own model.
|
|
387
|
+
*/
|
|
388
|
+
function dayAttributionCosts(entry: PersistedUsageEntry): Map<string, number> {
|
|
389
|
+
const costs = new Map<string, number>();
|
|
390
|
+
const tier = serviceTierContext(entry);
|
|
391
|
+
const estimate = entry.attempts?.length
|
|
392
|
+
? estimateComboCost(entry.attempts, undefined, tier)
|
|
393
|
+
: estimateRequestCost({ provider: entry.provider, model: entry.model, usage: entry.usage, usageStatus: entry.usageStatus, serviceTier: tier });
|
|
394
|
+
if (!estimate) return costs;
|
|
395
|
+
const add = (provider: string, model: string, amount: number): void => {
|
|
396
|
+
const key = usageModelKey(baseProviderLabel(provider), antigravityUsageModel(provider, model));
|
|
397
|
+
costs.set(key, (costs.get(key) ?? 0) + amount);
|
|
398
|
+
};
|
|
399
|
+
if (entry.attempts?.length && estimate.attempts) {
|
|
400
|
+
for (const attempt of estimate.attempts) add(attempt.provider, attempt.model, attempt.cost.total);
|
|
401
|
+
} else {
|
|
402
|
+
add(entry.provider, entry.model, estimate.cost.total);
|
|
403
|
+
}
|
|
404
|
+
return costs;
|
|
405
|
+
}
|
|
406
|
+
|
|
301
407
|
function buildDayGrid(range: UsageRange, since: number | null, now: number, entries: PersistedUsageEntry[]): UsageDay[] {
|
|
302
408
|
const window = rangeWindow(range, now);
|
|
303
409
|
const days = range === "all" ? dayCountForAllRange(entries, now) : window.days;
|
|
@@ -306,14 +412,14 @@ function buildDayGrid(range: UsageRange, since: number | null, now: number, entr
|
|
|
306
412
|
// render a per-model stacked bar with a hover tooltip without a second pass over the entries.
|
|
307
413
|
const dayModels = new Map<string, Map<string, UsageDayModel>>();
|
|
308
414
|
const dayModelRequests = new Map<string, Set<string>>();
|
|
309
|
-
const bumpDayModel = (dayKey: string, attribution: UsageAttribution): void => {
|
|
415
|
+
const bumpDayModel = (dayKey: string, attribution: UsageAttribution, costUsd: number): void => {
|
|
310
416
|
let models = dayModels.get(dayKey);
|
|
311
417
|
if (!models) { models = new Map(); dayModels.set(dayKey, models); }
|
|
312
418
|
const providerKey = baseProviderLabel(attribution.provider);
|
|
313
419
|
const mKey = usageModelKey(providerKey, attribution.model);
|
|
314
420
|
let m = models.get(mKey);
|
|
315
421
|
if (!m) {
|
|
316
|
-
m = { model: attribution.model, provider: providerKey, requests: 0, attemptCount: 0, totalTokens: 0 };
|
|
422
|
+
m = { model: attribution.model, provider: providerKey, requests: 0, attemptCount: 0, totalTokens: 0, estimatedCostUsd: 0 };
|
|
317
423
|
models.set(mKey, m);
|
|
318
424
|
}
|
|
319
425
|
const requestKey = `${dayKey}\0${mKey}`;
|
|
@@ -323,23 +429,44 @@ function buildDayGrid(range: UsageRange, since: number | null, now: number, entr
|
|
|
323
429
|
m.requests = requests.size;
|
|
324
430
|
m.attemptCount += 1;
|
|
325
431
|
m.totalTokens += usageDisplayTotalTokens(attribution.usage, attribution.totalTokens) ?? 0;
|
|
432
|
+
m.estimatedCostUsd += costUsd;
|
|
326
433
|
};
|
|
434
|
+
const startOfToday = startOfLocalDay(now);
|
|
327
435
|
for (let i = days - 1; i >= 0; i--) {
|
|
328
|
-
const
|
|
329
|
-
|
|
436
|
+
const d = new Date(startOfToday);
|
|
437
|
+
d.setDate(d.getDate() - i);
|
|
438
|
+
const key = localDateKey(d.getTime());
|
|
439
|
+
grid.set(key, { date: key, requests: 0, measuredRequests: 0, reportedRequests: 0, totalTokens: 0, estimatedCostUsd: 0, models: [] });
|
|
330
440
|
}
|
|
331
441
|
for (const entry of entries) {
|
|
332
442
|
const key = localDateKey(entry.timestamp);
|
|
333
443
|
let day = grid.get(key);
|
|
334
444
|
if (!day) {
|
|
335
|
-
day = { date: key, requests: 0, measuredRequests: 0, reportedRequests: 0, totalTokens: 0, models: [] };
|
|
445
|
+
day = { date: key, requests: 0, measuredRequests: 0, reportedRequests: 0, totalTokens: 0, estimatedCostUsd: 0, models: [] };
|
|
336
446
|
grid.set(key, day);
|
|
337
447
|
}
|
|
338
448
|
day.requests += 1;
|
|
339
449
|
if (isMeasuredStatus(entry.usageStatus)) day.measuredRequests += 1;
|
|
340
450
|
if (entry.usageStatus === "reported") day.reportedRequests += 1;
|
|
341
451
|
day.totalTokens += usageDisplayTotalTokens(entry.usage, entry.totalTokens) ?? 0;
|
|
342
|
-
|
|
452
|
+
// Price through the same seam buildModels uses: combo attempts are priced
|
|
453
|
+
// per attempt and attributed to their own model, everything else to the
|
|
454
|
+
// entry's model. Re-deriving a price here would make days[] disagree with
|
|
455
|
+
// models[] for exactly the combo traffic where nobody would notice.
|
|
456
|
+
const attributionCosts = dayAttributionCosts(entry);
|
|
457
|
+
for (const attribution of usageAttributions(entry)) {
|
|
458
|
+
const attributionKey = usageModelKey(baseProviderLabel(attribution.provider), attribution.model);
|
|
459
|
+
// Spend each key's cost ONCE. `attributionCosts` already holds the SUM of every
|
|
460
|
+
// attempt that shares a provider/model key, while `usageAttributions` yields one
|
|
461
|
+
// entry per attempt — so a retry onto the same model would otherwise add that
|
|
462
|
+
// pair's total twice and double the day against `summary.estimatedCostUsd`.
|
|
463
|
+
// Deleting on read keeps the first attribution carrying the group's cost and gives
|
|
464
|
+
// its siblings zero, which is what `buildModels` already does per attempt.
|
|
465
|
+
const costUsd = attributionCosts.get(attributionKey) ?? 0;
|
|
466
|
+
attributionCosts.delete(attributionKey);
|
|
467
|
+
bumpDayModel(key, attribution, costUsd);
|
|
468
|
+
day.estimatedCostUsd += costUsd;
|
|
469
|
+
}
|
|
343
470
|
}
|
|
344
471
|
void since;
|
|
345
472
|
const out = [...grid.values()].sort((a, b) => a.date.localeCompare(b.date));
|
|
@@ -351,13 +478,15 @@ function buildDayGrid(range: UsageRange, since: number | null, now: number, entr
|
|
|
351
478
|
const requests = new Set<string>();
|
|
352
479
|
let attemptCount = 0;
|
|
353
480
|
let totalTokens = 0;
|
|
481
|
+
let estimatedCostUsd = 0;
|
|
354
482
|
for (const model of overflow) {
|
|
355
483
|
attemptCount += model.attemptCount;
|
|
356
484
|
totalTokens += model.totalTokens;
|
|
485
|
+
estimatedCostUsd += model.estimatedCostUsd;
|
|
357
486
|
const requestKey = `${day.date}\0${usageModelKey(model.provider, model.model)}`;
|
|
358
487
|
for (const requestId of dayModelRequests.get(requestKey) ?? []) requests.add(requestId);
|
|
359
488
|
}
|
|
360
|
-
return { model: "other", provider: "other", requests: requests.size, attemptCount, totalTokens };
|
|
489
|
+
return { model: "other", provider: "other", requests: requests.size, attemptCount, totalTokens, estimatedCostUsd };
|
|
361
490
|
});
|
|
362
491
|
}
|
|
363
492
|
}
|
|
@@ -415,7 +544,7 @@ function buildModels(entries: PersistedUsageEntry[], totalTokens: number): Usage
|
|
|
415
544
|
}
|
|
416
545
|
// Accumulate per-model estimated cost
|
|
417
546
|
for (const entry of entries) {
|
|
418
|
-
const tier =
|
|
547
|
+
const tier = serviceTierContext(entry);
|
|
419
548
|
const estimate = entry.attempts?.length
|
|
420
549
|
? estimateComboCost(entry.attempts, undefined, tier)
|
|
421
550
|
: estimateRequestCost({ provider: entry.provider, model: entry.model, usage: entry.usage, usageStatus: entry.usageStatus, serviceTier: tier });
|
|
@@ -524,7 +653,7 @@ function buildProviders(entries: PersistedUsageEntry[], totalTokens: number): Us
|
|
|
524
653
|
}
|
|
525
654
|
}
|
|
526
655
|
for (const entry of entries) {
|
|
527
|
-
const tier =
|
|
656
|
+
const tier = serviceTierContext(entry);
|
|
528
657
|
const estimate = entry.attempts?.length
|
|
529
658
|
? estimateComboCost(entry.attempts, undefined, tier)
|
|
530
659
|
: estimateRequestCost({ provider: entry.provider, model: entry.model, usage: entry.usage, usageStatus: entry.usageStatus, serviceTier: tier });
|
|
@@ -547,6 +676,143 @@ function buildProviders(entries: PersistedUsageEntry[], totalTokens: number): Us
|
|
|
547
676
|
return providers.sort((a, b) => b.requests - a.requests);
|
|
548
677
|
}
|
|
549
678
|
|
|
679
|
+
const LEGACY_AMBIGUOUS_ACCOUNT_LABEL = "legacy-ambiguous";
|
|
680
|
+
|
|
681
|
+
function legacyCodexAccountLabel(provider: string): string | null {
|
|
682
|
+
if (baseProviderLabel(provider) !== "openai") return null;
|
|
683
|
+
const suffix = provider.match(/-(main|p[a-f0-9]{6})$/)?.[1];
|
|
684
|
+
return suffix ?? LEGACY_AMBIGUOUS_ACCOUNT_LABEL;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
/**
|
|
688
|
+
* An explicitly stamped label of EITHER family is authoritative for any provider (#2699).
|
|
689
|
+
*
|
|
690
|
+
* No `o`-label branch is needed here: `isCodexUsageAccountLogLabel` now accepts both families,
|
|
691
|
+
* and adding a second predicate call would be a no-op guarded by a comment claiming otherwise.
|
|
692
|
+
*
|
|
693
|
+
* The legacy fallback stays openai-only on purpose. It infers an account from the PROVIDER
|
|
694
|
+
* string, and inferring for a non-Codex row would merge unrelated accounts under one label --
|
|
695
|
+
* so an unlabeled xai row is dropped from the account table rather than guessed at.
|
|
696
|
+
*/
|
|
697
|
+
function accountLabelForAttribution(provider: string, explicit: unknown): string | null {
|
|
698
|
+
if (isCodexUsageAccountLogLabel(explicit)) return explicit;
|
|
699
|
+
return legacyCodexAccountLabel(provider);
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
function buildAccounts(entries: PersistedUsageEntry[]): UsageAccount[] {
|
|
703
|
+
const byLabel = new Map<string, UsageAccount>();
|
|
704
|
+
const requestIds = new Map<string, Set<string>>();
|
|
705
|
+
|
|
706
|
+
const add = (input: {
|
|
707
|
+
requestId: string;
|
|
708
|
+
provider: string;
|
|
709
|
+
accountLogLabel?: string;
|
|
710
|
+
usageStatus: UsageStatus;
|
|
711
|
+
usage?: PersistedUsageEntry["usage"];
|
|
712
|
+
totalTokens?: number;
|
|
713
|
+
estimate: ReturnType<typeof estimateRequestCost>;
|
|
714
|
+
}): void => {
|
|
715
|
+
const label = accountLabelForAttribution(input.provider, input.accountLogLabel);
|
|
716
|
+
if (!label) return;
|
|
717
|
+
let row = byLabel.get(label);
|
|
718
|
+
if (!row) {
|
|
719
|
+
row = {
|
|
720
|
+
accountLogLabel: label,
|
|
721
|
+
ambiguous: label === LEGACY_AMBIGUOUS_ACCOUNT_LABEL,
|
|
722
|
+
requests: 0,
|
|
723
|
+
attemptCount: 0,
|
|
724
|
+
measuredAttempts: 0,
|
|
725
|
+
reportedAttempts: 0,
|
|
726
|
+
estimatedAttempts: 0,
|
|
727
|
+
unmeteredAttempts: 0,
|
|
728
|
+
inputTokens: 0,
|
|
729
|
+
outputTokens: 0,
|
|
730
|
+
cacheReadInputTokens: 0,
|
|
731
|
+
cacheCreationInputTokens: 0,
|
|
732
|
+
reasoningOutputTokens: 0,
|
|
733
|
+
totalTokens: 0,
|
|
734
|
+
usageCoverageRatio: 0,
|
|
735
|
+
pricedAttempts: 0,
|
|
736
|
+
unpricedAttempts: 0,
|
|
737
|
+
priceCoverageRatio: 0,
|
|
738
|
+
};
|
|
739
|
+
byLabel.set(label, row);
|
|
740
|
+
requestIds.set(label, new Set());
|
|
741
|
+
}
|
|
742
|
+
requestIds.get(label)!.add(input.requestId);
|
|
743
|
+
row.requests = requestIds.get(label)!.size;
|
|
744
|
+
row.attemptCount += 1;
|
|
745
|
+
const measured = input.usage !== undefined && isMeasuredStatus(input.usageStatus);
|
|
746
|
+
if (!measured) {
|
|
747
|
+
row.unmeteredAttempts += 1;
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
row.measuredAttempts += 1;
|
|
752
|
+
if (input.usageStatus === "reported") row.reportedAttempts += 1;
|
|
753
|
+
else if (input.usageStatus === "estimated") row.estimatedAttempts += 1;
|
|
754
|
+
row.inputTokens += input.usage!.inputTokens;
|
|
755
|
+
row.outputTokens += input.usage!.outputTokens;
|
|
756
|
+
const creation = input.usage!.cacheCreationInputTokens;
|
|
757
|
+
const read = typeof input.usage!.cacheReadInputTokens === "number"
|
|
758
|
+
? input.usage!.cacheReadInputTokens
|
|
759
|
+
: typeof input.usage!.cachedInputTokens === "number" && typeof creation === "number"
|
|
760
|
+
? Math.max(0, input.usage!.cachedInputTokens - creation)
|
|
761
|
+
: input.usage!.cachedInputTokens;
|
|
762
|
+
if (typeof read === "number") row.cacheReadInputTokens += read;
|
|
763
|
+
if (typeof creation === "number") row.cacheCreationInputTokens += creation;
|
|
764
|
+
if (typeof input.usage!.reasoningOutputTokens === "number") {
|
|
765
|
+
row.reasoningOutputTokens += input.usage!.reasoningOutputTokens;
|
|
766
|
+
}
|
|
767
|
+
row.totalTokens += usageDisplayTotalTokens(input.usage, input.totalTokens) ?? 0;
|
|
768
|
+
if (input.estimate) {
|
|
769
|
+
row.pricedAttempts += 1;
|
|
770
|
+
row.estimatedCostUsd = (row.estimatedCostUsd ?? 0) + input.estimate.cost.total;
|
|
771
|
+
} else {
|
|
772
|
+
row.unpricedAttempts += 1;
|
|
773
|
+
}
|
|
774
|
+
};
|
|
775
|
+
|
|
776
|
+
for (const entry of entries) {
|
|
777
|
+
const tier = serviceTierContext(entry);
|
|
778
|
+
if (entry.attempts?.length) {
|
|
779
|
+
for (const attempt of entry.attempts) {
|
|
780
|
+
add({
|
|
781
|
+
requestId: entry.requestId,
|
|
782
|
+
provider: attempt.provider,
|
|
783
|
+
...(attempt.accountLogLabel ? { accountLogLabel: attempt.accountLogLabel } : {}),
|
|
784
|
+
usageStatus: attempt.usageStatus,
|
|
785
|
+
...(attempt.usage ? { usage: attempt.usage } : {}),
|
|
786
|
+
...(attempt.totalTokens !== undefined ? { totalTokens: attempt.totalTokens } : {}),
|
|
787
|
+
estimate: estimateAttemptCost(attempt, undefined, tier),
|
|
788
|
+
});
|
|
789
|
+
}
|
|
790
|
+
continue;
|
|
791
|
+
}
|
|
792
|
+
add({
|
|
793
|
+
requestId: entry.requestId,
|
|
794
|
+
provider: entry.provider,
|
|
795
|
+
...(entry.accountLogLabel ? { accountLogLabel: entry.accountLogLabel } : {}),
|
|
796
|
+
usageStatus: entry.usageStatus,
|
|
797
|
+
...(entry.usage ? { usage: entry.usage } : {}),
|
|
798
|
+
...(entry.totalTokens !== undefined ? { totalTokens: entry.totalTokens } : {}),
|
|
799
|
+
estimate: estimateRequestCost({
|
|
800
|
+
provider: entry.provider,
|
|
801
|
+
model: entry.model,
|
|
802
|
+
usage: entry.usage,
|
|
803
|
+
usageStatus: entry.usageStatus,
|
|
804
|
+
serviceTier: tier,
|
|
805
|
+
}),
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
for (const row of byLabel.values()) {
|
|
810
|
+
row.usageCoverageRatio = row.attemptCount === 0 ? 0 : row.measuredAttempts / row.attemptCount;
|
|
811
|
+
row.priceCoverageRatio = row.measuredAttempts === 0 ? 0 : row.pricedAttempts / row.measuredAttempts;
|
|
812
|
+
}
|
|
813
|
+
return [...byLabel.values()].sort((a, b) => b.totalTokens - a.totalTokens);
|
|
814
|
+
}
|
|
815
|
+
|
|
550
816
|
export function summarizeUsage(
|
|
551
817
|
entries: PersistedUsageEntry[],
|
|
552
818
|
range: UsageRange,
|
|
@@ -581,5 +847,110 @@ export function summarizeUsage(
|
|
|
581
847
|
days: buildDayGrid(range, since, now, filteredEntries),
|
|
582
848
|
models: buildModels(filteredEntries, totals.totalTokens),
|
|
583
849
|
providers: buildProviders(filteredEntries, totals.totalTokens),
|
|
850
|
+
accounts: buildAccounts(filteredEntries),
|
|
851
|
+
};
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
function normalizeFilterValue(input: string | null | undefined): string | null {
|
|
855
|
+
const trimmed = typeof input === "string" ? input.trim() : "";
|
|
856
|
+
return trimmed === "" ? null : trimmed.toLowerCase();
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
/**
|
|
860
|
+
* Narrow an already-summarised window to one provider and/or model.
|
|
861
|
+
*
|
|
862
|
+
* Deliberately a projection over a finished summary rather than a parameter to
|
|
863
|
+
* {@link summarizeUsage}. The management route caches summaries under
|
|
864
|
+
* `range:surface` and warms that key space as a cross-product; a filtered
|
|
865
|
+
* summary that reached either would be served to the next UNFILTERED caller,
|
|
866
|
+
* the dashboard included. Keeping the filter outside the producer makes that
|
|
867
|
+
* mistake unrepresentable rather than merely discouraged.
|
|
868
|
+
*
|
|
869
|
+
* Totals are recomputed from the retained rows. For combo traffic a request is
|
|
870
|
+
* counted once per participating model, so a filtered request count can exceed
|
|
871
|
+
* the number of distinct requests; `comboOverlap` reports when that is
|
|
872
|
+
* possible. Cost is unaffected — combo cost is attributed per attempt, so it
|
|
873
|
+
* partitions across models rather than repeating.
|
|
874
|
+
*
|
|
875
|
+
* `accounts` is emptied whenever a filter is active: account rows are not
|
|
876
|
+
* provider-partitioned in a way this projection could honestly re-derive, and
|
|
877
|
+
* unfiltered account totals sitting beside filtered model totals would invite
|
|
878
|
+
* exactly the wrong reading.
|
|
879
|
+
*/
|
|
880
|
+
export function projectUsageSummary<T extends UsageSummary>(
|
|
881
|
+
summary: T,
|
|
882
|
+
filter: { provider?: string | null; model?: string | null },
|
|
883
|
+
entries?: PersistedUsageEntry[],
|
|
884
|
+
): T & { filter?: UsageFilterEcho } {
|
|
885
|
+
const provider = normalizeFilterValue(filter.provider);
|
|
886
|
+
const model = normalizeFilterValue(filter.model);
|
|
887
|
+
if (provider === null && model === null) return summary;
|
|
888
|
+
|
|
889
|
+
// Re-summarise from the entries the summary was built from, rather than
|
|
890
|
+
// projecting over its rows.
|
|
891
|
+
//
|
|
892
|
+
// Projecting rows looked cheaper and was wrong in three ways that only show
|
|
893
|
+
// up together: breakdown rows past MAX_USAGE_MODEL_BREAKDOWN_ROWS are
|
|
894
|
+
// collapsed into a synthetic "other" row, so a provider living only in that
|
|
895
|
+
// tail is unfindable and reports matched:false despite real usage; a
|
|
896
|
+
// provider row is a whole-provider aggregate, so a model filter kept the
|
|
897
|
+
// provider's OTHER models in providers[] while models[] and the totals
|
|
898
|
+
// excluded them, contradicting itself inside one response; and a model row
|
|
899
|
+
// carries a single optional cost, so priced/unpriced/unmetered counts could
|
|
900
|
+
// only be guessed per model rather than counted per request.
|
|
901
|
+
//
|
|
902
|
+
// The entries are already in hand on every path that filters, so the honest
|
|
903
|
+
// computation is also the simple one.
|
|
904
|
+
const matches = (rowProvider: string, rowModel: string): boolean => {
|
|
905
|
+
if (provider !== null && baseProviderLabel(rowProvider).toLowerCase() !== provider) return false;
|
|
906
|
+
if (model !== null && rowModel.toLowerCase() !== model) return false;
|
|
907
|
+
return true;
|
|
908
|
+
};
|
|
909
|
+
|
|
910
|
+
// Narrow to matching ATTRIBUTIONS, not matching entries.
|
|
911
|
+
//
|
|
912
|
+
// Keeping a whole combo entry because one of its attempts matched drags the
|
|
913
|
+
// other attempts' tokens and cost into the filtered totals: a two-attempt
|
|
914
|
+
// combo filtered to its cheap model reported the expensive model's spend
|
|
915
|
+
// too. Rewriting the entry down to its matching attempts is what makes the
|
|
916
|
+
// filtered numbers mean what the flag says.
|
|
917
|
+
const source = entries ?? [];
|
|
918
|
+
let comboOverlap = false;
|
|
919
|
+
const filtered: PersistedUsageEntry[] = [];
|
|
920
|
+
for (const entry of source) {
|
|
921
|
+
if (!entry.attempts?.length) {
|
|
922
|
+
if (matches(entry.provider, antigravityUsageModel(entry.provider, entry.model))) filtered.push(entry);
|
|
923
|
+
continue;
|
|
924
|
+
}
|
|
925
|
+
const attempts = entry.attempts.filter(a => matches(a.provider, antigravityUsageModel(a.provider, a.model)));
|
|
926
|
+
if (attempts.length === 0) continue;
|
|
927
|
+
// A combo is still counted once per participating model, so a filtered
|
|
928
|
+
// request count can exceed the number of distinct requests. That is the
|
|
929
|
+
// documented overlap, and it is why comboOverlap exists.
|
|
930
|
+
if (entry.attempts.length > 1) comboOverlap = true;
|
|
931
|
+
filtered.push({ ...entry, attempts });
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
const projected = summarizeUsage(filtered, summary.range, summary.generatedAt, summary.surface);
|
|
935
|
+
// matched reflects usage inside the requested WINDOW, not anywhere in the
|
|
936
|
+
// log: summarizeUsage applies the range and surface predicates, and the CLI
|
|
937
|
+
// uses this flag to decide between a table and "no usage recorded".
|
|
938
|
+
const matched = projected.summary.requests > 0;
|
|
939
|
+
// A combo entry survives the entry filter as a whole, so its non-matching
|
|
940
|
+
// attributions can still appear as rows. Drop those so every row in the
|
|
941
|
+
// response satisfies the filter the caller asked for.
|
|
942
|
+
const models = projected.models.filter(row => matches(row.provider, row.model));
|
|
943
|
+
const retainedProviders = new Set(models.map(row => row.provider));
|
|
944
|
+
return {
|
|
945
|
+
...summary,
|
|
946
|
+
summary: projected.summary,
|
|
947
|
+
days: projected.days.map(day => ({ ...day, models: day.models.filter(row => matches(row.provider, row.model)) })),
|
|
948
|
+
models,
|
|
949
|
+
providers: projected.providers.filter(row => retainedProviders.has(row.provider)),
|
|
950
|
+
// Account rows are not provider-partitioned in a way this projection could
|
|
951
|
+
// honestly re-derive, and unfiltered account totals sitting beside filtered
|
|
952
|
+
// model totals would invite exactly the wrong reading.
|
|
953
|
+
accounts: [],
|
|
954
|
+
filter: { provider, model, matched, comboOverlap },
|
|
584
955
|
};
|
|
585
956
|
}
|