@iowarp/clio-coder 0.3.3 → 0.3.6
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/CHANGELOG.md +74 -0
- package/CONTRIBUTING.md +7 -7
- package/README.md +3 -3
- package/dist/{acp-P2AQILE2.js → acp-2BEHC4DL.js} +9 -8
- package/dist/{agents-72W3BI7I.js → agents-LNNFTM53.js} +29 -24
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-5TWEIYDN.js → auth-KXXFI2VS.js} +14 -10
- package/dist/{chunk-GGXXDWE4.js → chunk-22NAGB7X.js} +2 -2
- package/dist/{chunk-YCWGATWI.js → chunk-24I7BN55.js} +2 -2
- package/dist/{chunk-EKMEHE4H.js → chunk-33YXPOE3.js} +2 -3
- package/dist/chunk-3BPUFZDL.js +37 -0
- package/dist/chunk-43AOLP7E.js +375 -0
- package/dist/{chunk-ZDOOVTXZ.js → chunk-4OC57DA6.js} +27 -4
- package/dist/{chunk-6SGHMWE3.js → chunk-5JGRAMKL.js} +5 -5
- package/dist/{chunk-V6RTAOC2.js → chunk-6US73PDB.js} +572 -51
- package/dist/{chunk-5UFT4SUX.js → chunk-6XXKFVSN.js} +3 -3
- package/dist/{chunk-A3CYT5EX.js → chunk-AD2SYQYC.js} +55 -2
- package/dist/chunk-AOCYTWAV.js +449 -0
- package/dist/chunk-CFGTUFWB.js +67 -0
- package/dist/chunk-CJUB2JJ2.js +1478 -0
- package/dist/{chunk-FNTMWMX5.js → chunk-CKXWIANG.js} +14 -12
- package/dist/{chunk-PIWWS5BL.js → chunk-CYQKWTG3.js} +63 -78
- package/dist/{chunk-LZSJBIVT.js → chunk-DJVECN66.js} +271 -762
- package/dist/{chunk-CBCAPZAA.js → chunk-E25LMLRW.js} +2 -2
- package/dist/{chunk-ZWMF7253.js → chunk-E2ER4LJF.js} +304 -9
- package/dist/{chunk-STBPMHSX.js → chunk-EKY57CSP.js} +51 -84
- package/dist/{chunk-DUYJ5IO6.js → chunk-EYPA3EGJ.js} +12 -4
- package/dist/{chunk-M6SHUN7Q.js → chunk-FO5ZOVUY.js} +2 -2
- package/dist/chunk-FYYLNIL5.js +313 -0
- package/dist/{chunk-OQ33BKR3.js → chunk-G7MUEIGA.js} +3 -60
- package/dist/chunk-GEYXPTRF.js +613 -0
- package/dist/chunk-GOXNB3AO.js +261 -0
- package/dist/{chunk-G4BMMOKF.js → chunk-HVDIIIQW.js} +2 -2
- package/dist/chunk-HWUFFB6L.js +83 -0
- package/dist/{chunk-4XUGQOHA.js → chunk-K7T3E2SR.js} +15 -8
- package/dist/chunk-K7VKOLQQ.js +15 -0
- package/dist/{chunk-UFIIWP2H.js → chunk-KHSFENX2.js} +8 -8
- package/dist/{chunk-BMEMKKIT.js → chunk-KOHPCX4K.js} +2 -2
- package/dist/chunk-LCGCVYZ4.js +57 -0
- package/dist/chunk-LL4KHSZI.js +22 -0
- package/dist/{chunk-PAJK6MAQ.js → chunk-LYF7OHWH.js} +42 -15
- package/dist/{chunk-POHLU5DW.js → chunk-M6L6IDJG.js} +3 -3
- package/dist/{chunk-5UUP6MWO.js → chunk-MV3K5QF2.js} +5 -436
- package/dist/{chunk-X4RCMKVQ.js → chunk-NDINPTJ4.js} +2 -2
- package/dist/{chunk-TZK7PACC.js → chunk-NILBFAPG.js} +14 -8
- package/dist/chunk-ODFEOB4F.js +1082 -0
- package/dist/{chunk-AGYYIBLL.js → chunk-OH3TOQTB.js} +6 -2
- package/dist/chunk-OZNBF4L3.js +23 -0
- package/dist/{chunk-DSELYM6W.js → chunk-PBTHKCPN.js} +30 -10
- package/dist/{verify-375KUB3Y.js → chunk-PCZJO5TI.js} +127 -42
- package/dist/{chunk-ED4KHGC3.js → chunk-PPAMZ32Z.js} +9 -2
- package/dist/{chunk-SRDMMSEP.js → chunk-QM3F2GKX.js} +1063 -1645
- package/dist/{chunk-X6IAEBZR.js → chunk-QNQHSOLF.js} +7 -7
- package/dist/{chunk-OC7FIQPC.js → chunk-R46L2BIR.js} +10 -7
- package/dist/{chunk-2TLUCQVG.js → chunk-RD5U66HV.js} +3 -3
- package/dist/{chunk-6N5PTWMY.js → chunk-RY3LY4J5.js} +50 -13
- package/dist/{chunk-OKGUZO2U.js → chunk-SPULKLCF.js} +4 -3
- package/dist/{chunk-OOJYHWRB.js → chunk-TSHXZTOQ.js} +6 -5
- package/dist/chunk-TZSKNMZG.js +434 -0
- package/dist/{chunk-7MNJORFF.js → chunk-UL3WSD3F.js} +6 -1
- package/dist/{chunk-VJWL6YS5.js → chunk-UUVG37B4.js} +2 -2
- package/dist/{chunk-COU2UHX6.js → chunk-VEZEGCGW.js} +170 -2
- package/dist/chunk-W6GROXXM.js +69 -0
- package/dist/{chunk-OAO4GE4M.js → chunk-WHGPSPT5.js} +2 -2
- package/dist/chunk-WHJYKASB.js +677 -0
- package/dist/{chunk-ORBHGJC5.js → chunk-WR67VIZY.js} +3 -3
- package/dist/{chunk-YHZX5GEU.js → chunk-XAKHZX5N.js} +2 -2
- package/dist/{chunk-TZTZS7QK.js → chunk-XE2VEJHX.js} +5 -3
- package/dist/{chunk-LM5TQCJZ.js → chunk-XF5N4U5A.js} +8 -7
- package/dist/{chunk-LWLEKMDQ.js → chunk-XXQNGV4M.js} +1073 -552
- package/dist/{chunk-KZWTDYJF.js → chunk-XYDYPRZI.js} +7 -7
- package/dist/chunk-ZGVHUX3M.js +66 -0
- package/dist/{chunk-LW6DSM3M.js → chunk-ZRGEBJ4T.js} +1192 -1119
- package/dist/{chunk-2DJ2KNFG.js → chunk-ZXF4XRKW.js} +202 -40
- package/dist/chunk-ZZMN5OM4.js +122 -0
- package/dist/cli/index.js +34 -30
- package/dist/{clio-JOU4FXVA.js → clio-M2KGYUFZ.js} +7 -6
- package/dist/{code-nav-7AX6FYE6.js → code-nav-GQNL7XA6.js} +8 -6
- package/dist/codewiki/build-worker.js +4 -4
- package/dist/{components-KELWS457.js → components-5TTYYX6G.js} +3 -3
- package/dist/{config-XCDVKR23.js → config-XUUYQIWO.js} +47 -35
- package/dist/{configure-4GAP54ZW.js → configure-IHJ7YOMV.js} +18 -15
- package/dist/{context-77FM5DV5.js → context-74JLXAWD.js} +18 -10
- package/dist/{context-4UOGGLQ5.js → context-75MIWW3U.js} +41 -29
- package/dist/{context-5VKGUVJJ.js → context-ZQ7SIFJV.js} +85 -9
- package/dist/{context-clear-XXJRLCJJ.js → context-clear-GYKWNUML.js} +41 -29
- package/dist/{context-index-BZ4UYMTC.js → context-index-SSR5ECNE.js} +3 -3
- package/dist/context-working-set-UX5KEP4J.js +1553 -0
- package/dist/{dispatch-runner-QPRDDBDX.js → dispatch-runner-GIJBHNFL.js} +47 -32
- package/dist/{docs-2C2LTVT2.js → docs-6FZSCG5B.js} +3 -3
- package/dist/{doctor-HR46URBJ.js → doctor-SVJ5BZCW.js} +12 -12
- package/dist/{eval-XSSNATB4.js → eval-CG6LLBLD.js} +54 -238
- package/dist/{evidence-6HG2PY2B.js → evidence-ZYFIEN42.js} +57 -28
- package/dist/{evolve-K7YU3NCY.js → evolve-QGEXEMDW.js} +36 -25
- package/dist/{extensions-QVDOHDGJ.js → extensions-ADGNCJJD.js} +3 -3
- package/dist/{fleet-VY3HHKN6.js → fleet-S5R4ZOQY.js} +73 -44
- package/dist/{fleet-preflight-DDN536IT.js → fleet-preflight-BHSNPBMH.js} +3 -3
- package/dist/{init-JYGXI3FK.js → init-5DRU55YR.js} +49 -37
- package/dist/memory-7YKKR6UC.js +467 -0
- package/dist/{models-I5QWSEOM.js → models-ZPOLRU2C.js} +24 -21
- package/dist/{monitor-GE4ID3IA.js → monitor-US5F5YGZ.js} +73 -46
- package/dist/{orchestrator-EM5MC3HM.js → orchestrator-E2AL4T5N.js} +1624 -1007
- package/dist/{paths-UXLN5YYZ.js → paths-E7KYAQWE.js} +3 -3
- package/dist/{reset-L2FQEE3E.js → reset-KZ652EK6.js} +6 -5
- package/dist/{run-ZU3QMZPZ.js → run-SRNBKDWD.js} +76 -54
- package/dist/{share-S5BZQC5I.js → share-CGZE33UP.js} +7 -6
- package/dist/{skills-X5VXCRNQ.js → skills-S2X4DLY5.js} +4 -4
- package/dist/{skills-eval-WKIHWTHR.js → skills-eval-W2GGIC4R.js} +40 -29
- package/dist/{targets-SNCPI2NR.js → targets-54SWINWB.js} +28 -23
- package/dist/{terminal-lease-BNAHVHBS.js → terminal-lease-SAIF2OGY.js} +6 -4
- package/dist/{uninstall-FZCQCDKC.js → uninstall-BVLWXKBT.js} +3 -3
- package/dist/{upgrade-JQHHPQ4K.js → upgrade-JKAR27XC.js} +20 -19
- package/dist/{usage-OR4O5SMZ.js → usage-MSAWCLX4.js} +79 -36
- package/dist/verifiers-NCBTHHN2.js +1220 -0
- package/dist/verify-X5HDROLA.js +25 -0
- package/dist/{wiki-generate-UEXP2ARI.js → wiki-generate-GUSOQ6ZP.js} +50 -37
- package/dist/worker/entry.js +90 -70
- package/dist/{workspace-G4ZWUIPR.js → workspace-ZJ6BFM3Q.js} +4 -4
- package/docs/README.md +8 -7
- package/docs/acp.md +1 -1
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +2 -2
- package/docs/artifact-placement.md +1 -2
- package/docs/artifact-versions.md +1 -1
- package/docs/built-in-agents.md +1 -1
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +60 -26
- package/docs/config-knobs-audit.md +1 -2
- package/docs/configuration-and-targets.md +26 -1
- package/docs/context-engine.md +67 -13
- package/docs/context-working-set.md +194 -0
- package/docs/development-pipeline.md +1 -1
- package/docs/documentation-coverage.md +6 -6
- package/docs/documentation-guide.md +7 -6
- package/docs/environment-variables.md +2 -1
- package/docs/eval-runner.md +1 -1
- package/docs/evals-internal.md +4 -32
- package/docs/evidence-and-memory.md +139 -7
- package/docs/evolution.md +1 -1
- package/docs/exit-codes-and-output.md +1 -1
- package/docs/extensions-and-sharing.md +2 -2
- package/docs/fleet-dispatch.md +49 -8
- package/docs/glossary.md +21 -1
- package/docs/installation-and-lifecycle.md +2 -2
- package/docs/middleware-and-components.md +19 -2
- package/docs/model-catalog.md +7 -9
- package/docs/observability.md +4 -4
- package/docs/proactive-memory.md +26 -16
- package/docs/prompt-envelope-and-tools.md +7 -5
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/release-cut-checklist.md +43 -40
- package/docs/safety-model.md +49 -8
- package/docs/scientific-validation.md +21 -3
- package/docs/session-lifecycle.md +3 -3
- package/docs/skills-marketplace.md +1 -1
- package/docs/tool-usage.md +79 -12
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +1 -1
- package/docs/tui-design.md +38 -4
- package/docs/worker-dispatch-mechanics.md +11 -1
- package/package.json +13 -13
- package/skills/meta/clio-test/SKILL.md +20 -17
- package/skills/meta/clio-test/evals.md +3 -3
- package/skills/meta/clio-test/references/harness.md +35 -6
- package/skills/meta/clio-test/references/test-map.md +20 -10
- package/skills/registry.yaml +2 -2
- package/skills/skill-marketplace.json +1 -1
- package/src/cli/agents.ts +2 -3
- package/src/cli/argv.ts +14 -1
- package/src/cli/context-working-set.ts +513 -0
- package/src/cli/context.ts +8 -0
- package/src/cli/evidence.ts +20 -2
- package/src/cli/fleet.ts +15 -0
- package/src/cli/index.ts +5 -1
- package/src/cli/memory.ts +272 -10
- package/src/cli/modes/json-stream.ts +2 -2
- package/src/cli/modes/print.ts +12 -1
- package/src/cli/run.ts +22 -2
- package/src/cli/targets.ts +12 -3
- package/src/cli/usage.ts +55 -7
- package/src/cli/verifiers.ts +325 -0
- package/src/core/bash-exec.ts +39 -14
- package/src/core/bus-events.ts +22 -4
- package/src/core/config.ts +54 -0
- package/src/core/defaults.ts +50 -3
- package/src/core/response-model-id.ts +134 -0
- package/src/core/toml.ts +62 -0
- package/src/core/verification-scripts.ts +6 -0
- package/src/core/workspace-files.ts +0 -1
- package/src/domains/agents/builtins/architect.md +1 -1
- package/src/domains/agents/builtins/verifier.md +3 -0
- package/src/domains/agents/catalog.ts +5 -4
- package/src/domains/agents/recipe.ts +54 -14
- package/src/domains/agents/result-contract.ts +7 -4
- package/src/domains/config/classify.ts +1 -0
- package/src/domains/context/bootstrap.ts +36 -27
- package/src/domains/context/project-metadata.ts +19 -63
- package/src/domains/context/prompt-context.ts +8 -0
- package/src/domains/context/working-set/contract.ts +161 -0
- package/src/domains/context/working-set/defaults.ts +28 -0
- package/src/domains/context/working-set/engine.ts +203 -0
- package/src/domains/context/working-set/fold.ts +62 -0
- package/src/domains/context/working-set/horizon.ts +38 -0
- package/src/domains/context/working-set/marker.ts +103 -0
- package/src/domains/context/working-set/path-index.ts +436 -0
- package/src/domains/context/working-set/payload.ts +152 -0
- package/src/domains/context/working-set/policies/age-horizon.ts +55 -0
- package/src/domains/context/working-set/policies/index.ts +20 -0
- package/src/domains/context/working-set/policies/structural.ts +160 -0
- package/src/domains/context/working-set/project.ts +132 -0
- package/src/domains/context/working-set/protect.ts +109 -0
- package/src/domains/context/working-set/recall.ts +177 -0
- package/src/domains/context/working-set/replay/controls.ts +112 -0
- package/src/domains/context/working-set/replay/load-clio.ts +199 -0
- package/src/domains/context/working-set/replay/metrics.ts +185 -0
- package/src/domains/context/working-set/replay/reference-graph.ts +79 -0
- package/src/domains/context/working-set/replay/report.ts +139 -0
- package/src/domains/context/working-set/replay/runner.ts +325 -0
- package/src/domains/context/working-set/replay/synthetic.ts +422 -0
- package/src/domains/context/working-set/replay/trace.ts +21 -0
- package/src/domains/context/working-set/visible.ts +54 -0
- package/src/domains/dispatch/budget-envelope.ts +396 -0
- package/src/domains/dispatch/contract.ts +2 -0
- package/src/domains/dispatch/extension.ts +81 -27
- package/src/domains/dispatch/orphan-recovery.ts +1 -0
- package/src/domains/dispatch/receipt-integrity.ts +4 -0
- package/src/domains/dispatch/state.ts +1 -0
- package/src/domains/dispatch/types.ts +10 -3
- package/src/domains/dispatch/validation.ts +14 -0
- package/src/domains/dispatch/worker-spawn.ts +14 -3
- package/src/domains/eval/metrics/evidence.ts +0 -116
- package/src/domains/eval/metrics/invariants.ts +1 -1
- package/src/domains/eval/runners/clio-run.ts +1 -10
- package/src/domains/eval/runners/external-command.ts +2 -29
- package/src/domains/eval/schema/suite.ts +0 -7
- package/src/domains/eval/suites/run.ts +1 -7
- package/src/domains/evidence/build.ts +112 -45
- package/src/domains/evidence/eval.ts +24 -7
- package/src/domains/evidence/index.ts +53 -0
- package/src/domains/evidence/ordering.ts +12 -0
- package/src/domains/evidence/run-trust.ts +221 -0
- package/src/domains/evidence/store.ts +46 -6
- package/src/domains/evidence/trust-status.ts +854 -0
- package/src/domains/evidence/types.ts +26 -0
- package/src/domains/memory/index.ts +22 -0
- package/src/domains/memory/operations.ts +58 -1
- package/src/domains/memory/promotion.ts +281 -0
- package/src/domains/memory/prompt-section.ts +25 -5
- package/src/domains/memory/proposal.ts +51 -7
- package/src/domains/memory/task-bank.ts +3 -2
- package/src/domains/memory/task-memory-handoff.ts +181 -24
- package/src/domains/memory/task-memory-policy.ts +3 -1
- package/src/domains/memory/types.ts +37 -0
- package/src/domains/memory/validate.ts +178 -0
- package/src/domains/middleware/memory-intervention.ts +38 -25
- package/src/domains/middleware/runtime.ts +6 -0
- package/src/domains/middleware/skills-reminder.ts +19 -4
- package/src/domains/middleware/stalled-turn.ts +208 -5
- package/src/domains/middleware/types.ts +10 -0
- package/src/domains/observability/contract.ts +6 -1
- package/src/domains/observability/cost.ts +20 -4
- package/src/domains/observability/extension.ts +2 -2
- package/src/domains/providers/index.ts +3 -0
- package/src/domains/providers/model-discovery.ts +9 -0
- package/src/domains/providers/runtime-resolution.ts +38 -1
- package/src/domains/providers/runtimes/common/probe-helpers.ts +97 -16
- package/src/domains/providers/types/context-window-slots.ts +18 -0
- package/src/domains/providers/types/runtime-descriptor.ts +3 -1
- package/src/domains/safety/autonomy.ts +1 -1
- package/src/domains/safety/call-target.ts +211 -14
- package/src/domains/safety/decision-presentation.ts +268 -0
- package/src/domains/safety/default-path-policy.ts +8 -0
- package/src/domains/safety/finish-contract.ts +4 -3
- package/src/domains/safety/policy-engine.ts +48 -6
- package/src/domains/safety/redaction.ts +73 -0
- package/src/domains/session/compaction/compact.ts +23 -1
- package/src/domains/session/compaction/cut-point.ts +2 -0
- package/src/domains/session/compaction/tokens.ts +16 -1
- package/src/domains/session/context-ledger.ts +12 -1
- package/src/domains/session/decision-board.ts +4 -0
- package/src/domains/session/entries.ts +110 -1
- package/src/domains/session/history.ts +68 -19
- package/src/domains/session/manager.ts +9 -2
- package/src/domains/session/migrations/index.ts +22 -3
- package/src/domains/session/usage.ts +24 -7
- package/src/engine/acp/event-mapper.ts +7 -0
- package/src/engine/acp/server.ts +32 -2
- package/src/engine/agent.ts +18 -1
- package/src/engine/apis/lmstudio.ts +25 -4
- package/src/engine/apis/openai-completions.ts +147 -22
- package/src/engine/claude/sdk-runtime.ts +8 -2
- package/src/engine/claude/tool-safety.ts +13 -0
- package/src/engine/loop-guard.ts +27 -3
- package/src/engine/session.ts +9 -3
- package/src/engine/worker-events.ts +4 -3
- package/src/engine/worker-runtime.ts +59 -54
- package/src/entry/orchestrator.ts +34 -5
- package/src/interactive/chat-loop-messages.ts +40 -6
- package/src/interactive/chat-loop.ts +13 -0
- package/src/interactive/chat-panel.ts +17 -1
- package/src/interactive/chat-renderer.ts +49 -24
- package/src/interactive/clio-editor.ts +44 -7
- package/src/interactive/context-meter.ts +10 -0
- package/src/interactive/context-overlay.ts +120 -7
- package/src/interactive/context-recall-command.ts +110 -0
- package/src/interactive/cost-overlay.ts +39 -8
- package/src/interactive/dispatch-board.ts +212 -35
- package/src/interactive/footer/widgets.ts +13 -0
- package/src/interactive/interactive-application.ts +6 -1
- package/src/interactive/interactive-input-runtime.ts +11 -1
- package/src/interactive/interactive-presentation.ts +11 -1
- package/src/interactive/interactive-slash-runtime.ts +37 -1
- package/src/interactive/memory-overlay.ts +89 -4
- package/src/interactive/model-session-replay.ts +21 -0
- package/src/interactive/overlay-ask-user-lifecycle.ts +1 -1
- package/src/interactive/overlay-frame.ts +5 -2
- package/src/interactive/overlay-general-openers.ts +46 -1
- package/src/interactive/overlay-key-routing.ts +41 -1
- package/src/interactive/overlay-lifecycle.ts +11 -4
- package/src/interactive/overlay-permission-lifecycle.ts +23 -8
- package/src/interactive/overlay-session-lifecycle.ts +8 -4
- package/src/interactive/overlay-transitions.ts +11 -0
- package/src/interactive/overlays/ask-user.ts +74 -30
- package/src/interactive/overlays/decisions.ts +3 -1
- package/src/interactive/permission-hint.ts +35 -0
- package/src/interactive/permission-overlay.ts +95 -45
- package/src/interactive/renderers/tool-execution.ts +37 -51
- package/src/interactive/session-last-turn.ts +8 -1
- package/src/interactive/session-transcript.ts +2 -2
- package/src/interactive/session-usage-reseed.ts +36 -10
- package/src/interactive/slash-commands.ts +31 -4
- package/src/interactive/status/summary.ts +5 -0
- package/src/interactive/status/types.ts +5 -0
- package/src/interactive/terminal-lease.ts +1 -0
- package/src/interactive/turn-context.ts +333 -110
- package/src/interactive/turn-middleware.ts +7 -6
- package/src/interactive/turn-runtime.ts +37 -8
- package/src/interactive/turn-state.ts +3 -0
- package/src/interactive/worker-progress.ts +440 -0
- package/src/interactive/worker-stream.ts +51 -110
- package/src/tools/agent-tools.ts +39 -7
- package/src/tools/ask-user.ts +21 -1
- package/src/tools/bash.ts +144 -82
- package/src/tools/builtin-tool-catalog.ts +11 -5
- package/src/tools/context/index.ts +107 -5
- package/src/tools/context/surface.ts +3 -2
- package/src/tools/core-bootstrap.ts +21 -0
- package/src/tools/dispatch-arguments.ts +8 -0
- package/src/tools/dispatch-event-text.ts +19 -0
- package/src/tools/dispatch-runner.ts +9 -7
- package/src/tools/dispatch.ts +24 -1
- package/src/tools/monitor.ts +43 -20
- package/src/tools/registry.ts +72 -10
- package/src/tools/result-disposition.ts +706 -0
- package/src/tools/result-shaping.ts +321 -20
- package/src/tools/safe-exec.ts +2 -0
- package/src/tools/verify/authoring.ts +1120 -0
- package/src/tools/verify/catalog.ts +346 -0
- package/src/tools/verify/index.ts +13 -3
- package/src/tools/verify/scripts.ts +135 -37
- package/src/tools/verify/surface.ts +9 -5
- package/src/tools/worker-evidence.ts +54 -12
- package/src/worker/spec-contract.ts +43 -3
- package/dist/chunk-J7CWMCQD.js +0 -255
- package/dist/chunk-T6YILFSB.js +0 -80
- package/dist/chunk-VAKQQHWR.js +0 -434
- package/dist/chunk-VPAYEGVX.js +0 -184
- package/dist/chunk-XBXAASKX.js +0 -18
- package/dist/memory-WFZMGYHX.js +0 -236
- package/src/domains/eval/metrics/chaos-stream.ts +0 -93
|
@@ -2,9 +2,11 @@ import { homedir } from "node:os";
|
|
|
2
2
|
import { relative } from "node:path";
|
|
3
3
|
import { BusChannels } from "../core/bus-events.js";
|
|
4
4
|
import type { SafeEventBus } from "../core/event-bus.js";
|
|
5
|
+
import type { WorkingSetView } from "../domains/context/working-set/contract.js";
|
|
6
|
+
import { formatContextWindowSlots } from "../domains/providers/index.js";
|
|
5
7
|
import type { ContextLedger, ContextLedgerGroup } from "../domains/session/context-ledger.js";
|
|
6
8
|
import { type OverlayHandle, Text, type TUI, visibleWidth } from "../engine/tui.js";
|
|
7
|
-
import { contextCategorySwatch, renderContextMeterGrid } from "./context-meter.js";
|
|
9
|
+
import { contextCategorySwatch, renderContextMeterGrid, renderEvictedTokensLine } from "./context-meter.js";
|
|
8
10
|
import { buildHint, showClioOverlayFrame } from "./overlay-frame.js";
|
|
9
11
|
import { abbreviateModelId, type ClioToken, clioTheme, formatContextPercent } from "./theme/index.js";
|
|
10
12
|
|
|
@@ -81,7 +83,85 @@ function legendRow(group: ContextLedgerGroup, contentWidth: number): string {
|
|
|
81
83
|
return `${swatch} ${theme.fg(labelToken, labelText)} ${theme.fg("muted", right)}`;
|
|
82
84
|
}
|
|
83
85
|
|
|
84
|
-
|
|
86
|
+
function evictedTokens(view: WorkingSetView): number {
|
|
87
|
+
let total = 0;
|
|
88
|
+
for (const state of view.evicted.values()) total += state.tokensFreed;
|
|
89
|
+
return total;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function formatChurn(view: WorkingSetView): string {
|
|
93
|
+
if (view.itemsEvicted === 0) return "n/a";
|
|
94
|
+
return (view.recalls / view.itemsEvicted).toFixed(2);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Prose for one cache-disturbance reason. The wire values are stamped by
|
|
99
|
+
* `noteColdReason` in turn-context.ts and persisted on the assistant entry's
|
|
100
|
+
* `promptCache.expectedColdReasons`; the overlay reads them back, so an unknown
|
|
101
|
+
* reason renders as itself rather than disappearing.
|
|
102
|
+
*/
|
|
103
|
+
function coldReasonLabel(reason: string): string {
|
|
104
|
+
switch (reason) {
|
|
105
|
+
case "working_set_evict":
|
|
106
|
+
return "working-set eviction";
|
|
107
|
+
case "compaction":
|
|
108
|
+
return "compaction";
|
|
109
|
+
case "dispatch":
|
|
110
|
+
return "dispatch traffic";
|
|
111
|
+
default:
|
|
112
|
+
return reason;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** The operator's working-set configuration, as `/context` states it. */
|
|
117
|
+
export interface WorkingSetConfigView {
|
|
118
|
+
enabled: boolean;
|
|
119
|
+
policy: string;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* The working-set section: what the projection has taken out of the window
|
|
124
|
+
* and how often the model has asked for it back. Churn is recalls over items
|
|
125
|
+
* evicted; a high number means the policy evicts what is still needed.
|
|
126
|
+
*/
|
|
127
|
+
/**
|
|
128
|
+
* The policy line names what is configured, not what last ran. `lastPolicyId`
|
|
129
|
+
* is stamped by the first applied event, and eviction runs only when pressure
|
|
130
|
+
* crosses `compaction.threshold`, so a whole session at the shipped default
|
|
131
|
+
* read `policy none` (issue #190). With no configuration in hand (older
|
|
132
|
+
* callers) the last applied policy is still the best available claim.
|
|
133
|
+
*/
|
|
134
|
+
function workingSetPolicyLabel(view: WorkingSetView, config: WorkingSetConfigView | null | undefined): string {
|
|
135
|
+
if (config === null || config === undefined) return `policy ${view.lastPolicyId ?? "none"}`;
|
|
136
|
+
if (!config.enabled) return "disabled";
|
|
137
|
+
const state = view.evictionEvents === 0 ? " · no events yet" : "";
|
|
138
|
+
const lastRan =
|
|
139
|
+
view.lastPolicyId !== null && view.lastPolicyId !== config.policy ? ` (last event by ${view.lastPolicyId})` : "";
|
|
140
|
+
return `policy ${config.policy}${lastRan}${state}`;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function renderWorkingSetLines(view: WorkingSetView, config: WorkingSetConfigView | null | undefined): string[] {
|
|
144
|
+
const theme = clioTheme();
|
|
145
|
+
const items = view.evicted.size;
|
|
146
|
+
const summary = [
|
|
147
|
+
`${items} evicted item${items === 1 ? "" : "s"}`,
|
|
148
|
+
`${formatTokens(evictedTokens(view))} tokens`,
|
|
149
|
+
`${view.evictionEvents} event${view.evictionEvents === 1 ? "" : "s"}`,
|
|
150
|
+
`${view.recalls} recall${view.recalls === 1 ? "" : "s"}`,
|
|
151
|
+
`churn ${formatChurn(view)}`,
|
|
152
|
+
].join(" · ");
|
|
153
|
+
return [
|
|
154
|
+
`${theme.fg("muted", "working set")} ${theme.fg("dim", "·")} ${theme.fg("accent", workingSetPolicyLabel(view, config))}`,
|
|
155
|
+
theme.fg("dim", summary),
|
|
156
|
+
];
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function renderContextLedgerLines(
|
|
160
|
+
ledger: ContextLedger,
|
|
161
|
+
contentWidth: number,
|
|
162
|
+
workingSet?: WorkingSetView | null,
|
|
163
|
+
workingSetConfig?: WorkingSetConfigView | null,
|
|
164
|
+
): string[] {
|
|
85
165
|
const theme = clioTheme();
|
|
86
166
|
const lines: string[] = [];
|
|
87
167
|
|
|
@@ -98,7 +178,14 @@ export function renderContextLedgerLines(ledger: ContextLedger, contentWidth: nu
|
|
|
98
178
|
|
|
99
179
|
if (ledger.contextWindow > 0) {
|
|
100
180
|
const source = ledger.measured ? "measured" : "≈ estimated";
|
|
101
|
-
|
|
181
|
+
// `196,608 (786,432 / 4 slots)`: a llama.cpp window that is one slot's
|
|
182
|
+
// share of the server's KV budget names the split, because the bare
|
|
183
|
+
// number reads as the whole server and the meter is measured against
|
|
184
|
+
// the share (issue #187).
|
|
185
|
+
const window = ledger.contextWindowSlots
|
|
186
|
+
? formatContextWindowSlots(ledger.contextWindow, ledger.contextWindowSlots)
|
|
187
|
+
: formatTokens(ledger.contextWindow);
|
|
188
|
+
const summary = `${formatTokens(ledger.usedTokens)} / ${window} tokens (${formatContextPercent(ledger.percent)})`;
|
|
102
189
|
const provenance = contextWindowProvenanceLabel(ledger.contextWindowSource);
|
|
103
190
|
const trailer = provenance ? `${provenance} window · ${source}` : source;
|
|
104
191
|
lines.push(`${theme.fg("title", summary)} ${theme.fg("dim", "·")} ${theme.fg("muted", trailer)}`);
|
|
@@ -110,8 +197,13 @@ export function renderContextLedgerLines(ledger: ContextLedger, contentWidth: nu
|
|
|
110
197
|
lines.push("");
|
|
111
198
|
|
|
112
199
|
for (const group of ledger.meter) lines.push(legendRow(group, contentWidth));
|
|
200
|
+
if (workingSet && workingSet.evicted.size > 0) lines.push(renderEvictedTokensLine(evictedTokens(workingSet), theme));
|
|
113
201
|
|
|
114
202
|
lines.push("");
|
|
203
|
+
if (workingSet) {
|
|
204
|
+
for (const line of renderWorkingSetLines(workingSet, workingSetConfig)) lines.push(line);
|
|
205
|
+
lines.push("");
|
|
206
|
+
}
|
|
115
207
|
if (ledger.projectPreload && ledger.groups.some((group) => group.category === "project")) {
|
|
116
208
|
lines.push(theme.fg("dim", `project preload: ${ledger.projectPreload}`));
|
|
117
209
|
}
|
|
@@ -141,11 +233,21 @@ export function renderContextLedgerLines(ledger: ContextLedger, contentWidth: nu
|
|
|
141
233
|
const uncached =
|
|
142
234
|
cache.uncachedInputTokens !== null ? `uncached input ${formatTokens(cache.uncachedInputTokens)}` : null;
|
|
143
235
|
const line = ["prompt cache:", shell, "·", backend, "·", read, ...(uncached ? ["·", uncached] : [])].join(" ");
|
|
236
|
+
// Reasons Clio recorded before the run: working-set eviction, summary
|
|
237
|
+
// compaction, and dispatch traffic all move the byte prefix a local
|
|
238
|
+
// single-slot backend caches, so a cold turn after one of them is the
|
|
239
|
+
// expected outcome rather than a provider surprise.
|
|
240
|
+
const coldReasons = cache.backendVerdict === "cold" ? (cache.expectedColdReasons ?? []) : [];
|
|
144
241
|
// A reused shell with a cold backend means Clio kept the bytes stable
|
|
145
242
|
// but the provider re-prefilled anyway; surface that disagreement
|
|
146
|
-
// instead of hiding it.
|
|
147
|
-
|
|
243
|
+
// instead of hiding it. An expected reason explains the same numbers, so
|
|
244
|
+
// it is reported on its own line and not as a warning.
|
|
245
|
+
const misleading = cache.shellReused && cache.backendVerdict === "cold" && coldReasons.length === 0;
|
|
148
246
|
lines.push(theme.fg(misleading ? "warning" : "dim", line));
|
|
247
|
+
if (coldReasons.length > 0) {
|
|
248
|
+
const reasons = coldReasons.map(coldReasonLabel).join(", ");
|
|
249
|
+
lines.push(theme.fg("dim", `last cold turn: ${reasons} (expected)`));
|
|
250
|
+
}
|
|
149
251
|
}
|
|
150
252
|
|
|
151
253
|
if (ledger.lastCompaction) {
|
|
@@ -170,6 +272,10 @@ export interface OpenContextOverlayOptions {
|
|
|
170
272
|
onEvent(handler: (event: { type: string }) => void): () => void;
|
|
171
273
|
isStreaming(): boolean;
|
|
172
274
|
};
|
|
275
|
+
/** Working-set fold at the live leaf; null or absent hides the section. */
|
|
276
|
+
getWorkingSet?: () => WorkingSetView | null;
|
|
277
|
+
/** The configured `context.workingSet` block, so the policy line states what is set. */
|
|
278
|
+
getWorkingSetConfig?: () => WorkingSetConfigView | null;
|
|
173
279
|
}
|
|
174
280
|
|
|
175
281
|
/**
|
|
@@ -183,7 +289,14 @@ export function openContextOverlay(
|
|
|
183
289
|
getLedger: () => ContextLedger,
|
|
184
290
|
options?: OpenContextOverlayOptions,
|
|
185
291
|
): OverlayHandle {
|
|
186
|
-
const
|
|
292
|
+
const render = (): string =>
|
|
293
|
+
renderContextLedgerLines(
|
|
294
|
+
getLedger(),
|
|
295
|
+
DEFAULT_CONTENT_WIDTH,
|
|
296
|
+
options?.getWorkingSet?.() ?? null,
|
|
297
|
+
options?.getWorkingSetConfig?.() ?? null,
|
|
298
|
+
).join("\n");
|
|
299
|
+
const text = new Text(render(), 0, 0);
|
|
187
300
|
const handle = showClioOverlayFrame(tui, text, {
|
|
188
301
|
anchor: "center",
|
|
189
302
|
width: CONTEXT_OVERLAY_WIDTH,
|
|
@@ -192,7 +305,7 @@ export function openContextOverlay(
|
|
|
192
305
|
});
|
|
193
306
|
|
|
194
307
|
const refresh = (): void => {
|
|
195
|
-
text.setText(
|
|
308
|
+
text.setText(render());
|
|
196
309
|
text.invalidate();
|
|
197
310
|
tui.requestRender();
|
|
198
311
|
};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `/context recall <ref>`: the operator's half of working-set recall.
|
|
3
|
+
*
|
|
4
|
+
* The model recalls through `context(scope="recall", ref=...)`, which puts the
|
|
5
|
+
* body back in front of the model at the tail of the working set. This command
|
|
6
|
+
* answers a different question, asked by a person: what was in the result the
|
|
7
|
+
* marker replaced. So the body goes to the transcript and nowhere else. It is
|
|
8
|
+
* never submitted as a turn, never replayed, and never counted against the
|
|
9
|
+
* context window, which is why an operator can read a 40k-line build log back
|
|
10
|
+
* without paying for it.
|
|
11
|
+
*
|
|
12
|
+
* Everything else is identical to the tool path, deliberately: the same
|
|
13
|
+
* `resolveRecall` over the same fold at the same live leaf, the same
|
|
14
|
+
* `contextRecall` ledger entry (with `trigger: "operator"`), and the same
|
|
15
|
+
* `BusChannels.ContextRecalled` publication. A recall is a churn signal
|
|
16
|
+
* whoever asked for it, and a policy that keeps evicting something a human
|
|
17
|
+
* keeps reading back is a policy worth changing.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import type { ContextRecalledPayload } from "../core/bus-events.js";
|
|
21
|
+
import type { EvictedState } from "../domains/context/working-set/contract.js";
|
|
22
|
+
import { foldWorkingSet } from "../domains/context/working-set/fold.js";
|
|
23
|
+
import {
|
|
24
|
+
buildRecallFields,
|
|
25
|
+
recallErrorMessage,
|
|
26
|
+
recallParentTurnId,
|
|
27
|
+
resolveRecall,
|
|
28
|
+
} from "../domains/context/working-set/recall.js";
|
|
29
|
+
import type { SessionEntryInput } from "../domains/session/contract.js";
|
|
30
|
+
import type { SessionEntry } from "../domains/session/entries.js";
|
|
31
|
+
|
|
32
|
+
/** Ledger access the command needs, mirroring the context tool's `ContextSessionDeps`. */
|
|
33
|
+
export interface OperatorRecallDeps {
|
|
34
|
+
hasSession(): boolean;
|
|
35
|
+
readEntries(): ReadonlyArray<SessionEntry>;
|
|
36
|
+
/** The live append point (`/tree` pin or tree leaf); undefined lets the fold infer it. */
|
|
37
|
+
activeLeafTurnId(): string | undefined;
|
|
38
|
+
appendEntry(entry: SessionEntryInput): SessionEntry;
|
|
39
|
+
/** Publisher for `BusChannels.ContextRecalled`; the runtime supplies the bus. */
|
|
40
|
+
onRecalled?: (payload: ContextRecalledPayload) => void;
|
|
41
|
+
now?: () => number;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type OperatorRecallOutcome =
|
|
45
|
+
| {
|
|
46
|
+
ok: true;
|
|
47
|
+
/** One-line summary for the notice bar. */
|
|
48
|
+
headline: string;
|
|
49
|
+
/** The original body, byte-exact, for the transcript. */
|
|
50
|
+
body: string;
|
|
51
|
+
}
|
|
52
|
+
| { ok: false; message: string };
|
|
53
|
+
|
|
54
|
+
function formatTokens(tokens: number): string {
|
|
55
|
+
return tokens.toLocaleString("en-US");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Ref, why it left, what it costs to read, and where the full artifact lives
|
|
60
|
+
* when the original result was offloaded. Nothing else: the body is on the next
|
|
61
|
+
* line and the operator is already looking at it.
|
|
62
|
+
*/
|
|
63
|
+
function headlineFor(ref: string, tokens: number, state: EvictedState | undefined, offloadPath?: string): string {
|
|
64
|
+
const parts = [ref];
|
|
65
|
+
if (state !== undefined) {
|
|
66
|
+
parts.push(state.by === undefined ? `evicted: ${state.reason}` : `evicted: ${state.reason} by ${state.by}`);
|
|
67
|
+
}
|
|
68
|
+
parts.push(`${formatTokens(tokens)} tokens`);
|
|
69
|
+
if (offloadPath !== undefined) parts.push(`offload: ${offloadPath}`);
|
|
70
|
+
return `[/context recall] ${parts.join(" · ")}`;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function runOperatorRecall(ref: string, deps: OperatorRecallDeps): OperatorRecallOutcome {
|
|
74
|
+
if (!deps.hasSession()) {
|
|
75
|
+
return { ok: false, message: "[/context recall] no active session; start one with /new or /resume first" };
|
|
76
|
+
}
|
|
77
|
+
const trimmed = ref.trim();
|
|
78
|
+
if (trimmed.length === 0) {
|
|
79
|
+
return { ok: false, message: "[/context recall] needs a ref: the turnId named in an [evicted ...] marker" };
|
|
80
|
+
}
|
|
81
|
+
const entries = deps.readEntries();
|
|
82
|
+
const leaf = deps.activeLeafTurnId();
|
|
83
|
+
const view = foldWorkingSet(entries, leaf);
|
|
84
|
+
const resolved = resolveRecall(entries, view, trimmed, leaf);
|
|
85
|
+
// A ref that resolves to nothing is usually a typo or a stale marker; the
|
|
86
|
+
// shared message ends with the refs the operator could have typed instead.
|
|
87
|
+
if (!resolved.ok)
|
|
88
|
+
return { ok: false, message: `[/context recall] ${recallErrorMessage(resolved.error, entries, view)}` };
|
|
89
|
+
const { result } = resolved;
|
|
90
|
+
const fields = buildRecallFields(result, { trigger: "operator" });
|
|
91
|
+
try {
|
|
92
|
+
deps.appendEntry({ ...fields, parentTurnId: recallParentTurnId(entries, leaf) });
|
|
93
|
+
} catch (err) {
|
|
94
|
+
return {
|
|
95
|
+
ok: false,
|
|
96
|
+
message: `[/context recall] recall of ${result.ref.entry} could not be recorded: ${err instanceof Error ? err.message : String(err)}`,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
deps.onRecalled?.({
|
|
100
|
+
ref: result.ref.entry,
|
|
101
|
+
trigger: "operator",
|
|
102
|
+
tokensReadmitted: result.tokens,
|
|
103
|
+
at: deps.now?.() ?? Date.now(),
|
|
104
|
+
});
|
|
105
|
+
return {
|
|
106
|
+
ok: true,
|
|
107
|
+
headline: headlineFor(result.ref.entry, result.tokens, view.evicted.get(result.ref.entry), result.offloadPath),
|
|
108
|
+
body: result.body,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
addResponseModelIdObservationCounts,
|
|
3
|
+
type ResponseModelIdObservationCounts,
|
|
4
|
+
responseModelIdObservationCountsLabel,
|
|
5
|
+
} from "../core/response-model-id.js";
|
|
1
6
|
import {
|
|
2
7
|
aggregateCostAmounts,
|
|
3
8
|
type CostAggregate,
|
|
@@ -16,7 +21,9 @@ export const COST_OVERLAY_WIDTH = DEFAULT_CONTENT_WIDTH + 4;
|
|
|
16
21
|
|
|
17
22
|
export interface CostRow {
|
|
18
23
|
providerId: string;
|
|
19
|
-
|
|
24
|
+
attributedModelId: string;
|
|
25
|
+
requestedModelIds: string[];
|
|
26
|
+
responseModelIdObservationCounts: ResponseModelIdObservationCounts;
|
|
20
27
|
runs: number;
|
|
21
28
|
tokens: number;
|
|
22
29
|
input: number;
|
|
@@ -33,9 +40,17 @@ function formatTokens(n: number): string {
|
|
|
33
40
|
}
|
|
34
41
|
|
|
35
42
|
export function aggregateCostEntries(entries: ReadonlyArray<CostEntry>): CostRow[] {
|
|
36
|
-
const grouped = new Map<
|
|
43
|
+
const grouped = new Map<
|
|
44
|
+
string,
|
|
45
|
+
{
|
|
46
|
+
row: Omit<CostRow, "cost" | "requestedModelIds" | "responseModelIdObservationCounts">;
|
|
47
|
+
requestedModelIds: Set<string>;
|
|
48
|
+
responseModelIdObservationCounts: ResponseModelIdObservationCounts;
|
|
49
|
+
entries: CostEntry[];
|
|
50
|
+
}
|
|
51
|
+
>();
|
|
37
52
|
for (const entry of entries) {
|
|
38
|
-
const key = `${entry.providerId}::${entry.
|
|
53
|
+
const key = `${entry.providerId}::${entry.attributedModelId}`;
|
|
39
54
|
const existing = grouped.get(key);
|
|
40
55
|
if (existing) {
|
|
41
56
|
existing.row.runs += 1;
|
|
@@ -46,13 +61,18 @@ export function aggregateCostEntries(entries: ReadonlyArray<CostEntry>): CostRow
|
|
|
46
61
|
existing.row.cacheWrite += entry.cacheWrite;
|
|
47
62
|
existing.row.reasoningTokens += entry.reasoningTokens;
|
|
48
63
|
existing.row.apiCalls += entry.apiCalls ?? 1;
|
|
64
|
+
for (const requestedModelId of entry.requestedModelIds) existing.requestedModelIds.add(requestedModelId);
|
|
65
|
+
addResponseModelIdObservationCounts(
|
|
66
|
+
existing.responseModelIdObservationCounts,
|
|
67
|
+
entry.responseModelIdObservationCounts,
|
|
68
|
+
);
|
|
49
69
|
existing.entries.push(entry);
|
|
50
70
|
continue;
|
|
51
71
|
}
|
|
52
72
|
grouped.set(key, {
|
|
53
73
|
row: {
|
|
54
74
|
providerId: entry.providerId,
|
|
55
|
-
|
|
75
|
+
attributedModelId: entry.attributedModelId,
|
|
56
76
|
runs: 1,
|
|
57
77
|
tokens: entry.tokens,
|
|
58
78
|
input: entry.input,
|
|
@@ -62,22 +82,31 @@ export function aggregateCostEntries(entries: ReadonlyArray<CostEntry>): CostRow
|
|
|
62
82
|
reasoningTokens: entry.reasoningTokens,
|
|
63
83
|
apiCalls: entry.apiCalls ?? 1,
|
|
64
84
|
},
|
|
85
|
+
requestedModelIds: new Set(entry.requestedModelIds),
|
|
86
|
+
responseModelIdObservationCounts: { ...entry.responseModelIdObservationCounts },
|
|
65
87
|
entries: [entry],
|
|
66
88
|
});
|
|
67
89
|
}
|
|
68
|
-
const rows = Array.from(grouped.values(), ({ row, entries }) => ({
|
|
90
|
+
const rows = Array.from(grouped.values(), ({ row, entries, requestedModelIds, responseModelIdObservationCounts }) => ({
|
|
69
91
|
...row,
|
|
92
|
+
requestedModelIds: [...requestedModelIds].sort(),
|
|
93
|
+
responseModelIdObservationCounts,
|
|
70
94
|
cost: aggregateCostAmounts(entries.map((entry) => ({ usd: entry.usd, provenance: entry.provenance }))),
|
|
71
95
|
}));
|
|
72
96
|
rows.sort((a, b) => {
|
|
73
97
|
if (a.providerId !== b.providerId) return a.providerId < b.providerId ? -1 : 1;
|
|
74
|
-
if (a.
|
|
98
|
+
if (a.attributedModelId !== b.attributedModelId) return a.attributedModelId < b.attributedModelId ? -1 : 1;
|
|
75
99
|
return 0;
|
|
76
100
|
});
|
|
77
101
|
return rows;
|
|
78
102
|
}
|
|
79
103
|
|
|
80
|
-
function sumRows(
|
|
104
|
+
function sumRows(
|
|
105
|
+
rows: ReadonlyArray<CostRow>,
|
|
106
|
+
): Omit<
|
|
107
|
+
CostRow,
|
|
108
|
+
"providerId" | "attributedModelId" | "requestedModelIds" | "responseModelIdObservationCounts" | "cost"
|
|
109
|
+
> {
|
|
81
110
|
return rows.reduce(
|
|
82
111
|
(acc, row) => ({
|
|
83
112
|
runs: acc.runs + row.runs,
|
|
@@ -156,6 +185,8 @@ function modelBlock(row: CostRow): string[] {
|
|
|
156
185
|
// block with token rows and no cost row.
|
|
157
186
|
const cost = formatCostAggregate(row.cost);
|
|
158
187
|
return kvBlock([
|
|
188
|
+
["requested model ids", row.requestedModelIds.join(", ")],
|
|
189
|
+
["response model id observation", responseModelIdObservationCountsLabel(row.responseModelIdObservationCounts)],
|
|
159
190
|
["turns", formatTokens(row.runs)],
|
|
160
191
|
["model calls", formatTokens(row.apiCalls)],
|
|
161
192
|
...(cost === null ? [] : [["cost", cost] as const]),
|
|
@@ -185,7 +216,7 @@ export function formatCostOverlayBodyLines(
|
|
|
185
216
|
} else {
|
|
186
217
|
for (const [index, row] of rows.entries()) {
|
|
187
218
|
if (index > 0) lines.push("");
|
|
188
|
-
lines.push(theme.style("accent", `${row.providerId} · ${row.
|
|
219
|
+
lines.push(theme.style("accent", `${row.providerId} · attributed model ${row.attributedModelId}`, { bold: true }));
|
|
189
220
|
for (const line of modelBlock(row)) {
|
|
190
221
|
lines.push(line);
|
|
191
222
|
}
|