@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
|
@@ -1,10 +1,27 @@
|
|
|
1
1
|
import { createRequire as __clioCreateRequire } from "node:module"; const require = __clioCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
ShareDomainModule
|
|
4
|
+
} from "./chunk-WR67VIZY.js";
|
|
2
5
|
import {
|
|
3
6
|
bootstrapInputFromInitOptions,
|
|
4
7
|
modelBootstrapGenerate,
|
|
5
8
|
resolveBootstrapRoute
|
|
6
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-CKXWIANG.js";
|
|
7
10
|
import "./chunk-J5Q24KAG.js";
|
|
11
|
+
import {
|
|
12
|
+
DEFAULT_KEEP_RECENT_TOKENS,
|
|
13
|
+
DEFAULT_RESERVE_TOKENS,
|
|
14
|
+
buildEvictionFields,
|
|
15
|
+
calculateContextTokens,
|
|
16
|
+
compactionCut,
|
|
17
|
+
estimateTokens,
|
|
18
|
+
findCutPoint,
|
|
19
|
+
getLastAssistantUsage,
|
|
20
|
+
planEviction,
|
|
21
|
+
projectWorkingSet,
|
|
22
|
+
resolveWorkingSetPolicy,
|
|
23
|
+
selectVisibleEntries
|
|
24
|
+
} from "./chunk-WHJYKASB.js";
|
|
8
25
|
import {
|
|
9
26
|
assistantSessionPayload,
|
|
10
27
|
backendCacheVerdict,
|
|
@@ -37,37 +54,33 @@ import {
|
|
|
37
54
|
toolNamesFromAgentState,
|
|
38
55
|
toolResultSummary,
|
|
39
56
|
toolSignatureFromState
|
|
40
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-PBTHKCPN.js";
|
|
41
58
|
import {
|
|
42
59
|
SchedulingDomainModule,
|
|
43
60
|
createPromptsDomainModule,
|
|
44
61
|
renderAgentCatalogSectionsFromSpecs
|
|
45
|
-
} from "./chunk-
|
|
46
|
-
import {
|
|
47
|
-
ShareDomainModule
|
|
48
|
-
} from "./chunk-ORBHGJC5.js";
|
|
62
|
+
} from "./chunk-XF5N4U5A.js";
|
|
49
63
|
import {
|
|
50
64
|
AgentsDomainModule,
|
|
51
65
|
SafetyDomainModule
|
|
52
|
-
} from "./chunk-
|
|
66
|
+
} from "./chunk-LYF7OHWH.js";
|
|
53
67
|
import {
|
|
54
68
|
LifecycleDomainModule,
|
|
55
69
|
describeUpgradeNotice
|
|
56
|
-
} from "./chunk-
|
|
70
|
+
} from "./chunk-6XXKFVSN.js";
|
|
71
|
+
import {
|
|
72
|
+
ensureClioState,
|
|
73
|
+
takeUpgradeNotice
|
|
74
|
+
} from "./chunk-KHSFENX2.js";
|
|
57
75
|
import {
|
|
58
76
|
ConfigDomainModule,
|
|
59
77
|
createConfigDomainModule,
|
|
60
78
|
loadDomains
|
|
61
|
-
} from "./chunk-
|
|
62
|
-
import {
|
|
63
|
-
ensureClioState,
|
|
64
|
-
takeUpgradeNotice
|
|
65
|
-
} from "./chunk-UFIIWP2H.js";
|
|
79
|
+
} from "./chunk-R46L2BIR.js";
|
|
66
80
|
import {
|
|
67
81
|
compileScoutTransition,
|
|
68
82
|
createDispatchRunEventRegistry
|
|
69
|
-
} from "./chunk-
|
|
70
|
-
import "./chunk-XBXAASKX.js";
|
|
83
|
+
} from "./chunk-5JGRAMKL.js";
|
|
71
84
|
import {
|
|
72
85
|
monitorToolSurface
|
|
73
86
|
} from "./chunk-FJ3H4MN5.js";
|
|
@@ -78,9 +91,10 @@ import {
|
|
|
78
91
|
costAggregateForAmount,
|
|
79
92
|
formatCostAggregate,
|
|
80
93
|
readAccountabilitySummary
|
|
81
|
-
} from "./chunk-
|
|
94
|
+
} from "./chunk-K7T3E2SR.js";
|
|
82
95
|
import "./chunk-HC4CLZ2Y.js";
|
|
83
96
|
import "./chunk-HFSBBKSQ.js";
|
|
97
|
+
import "./chunk-3BPUFZDL.js";
|
|
84
98
|
import {
|
|
85
99
|
steerToolSurface
|
|
86
100
|
} from "./chunk-WEH5XRJQ.js";
|
|
@@ -88,11 +102,12 @@ import {
|
|
|
88
102
|
flushRawStdout,
|
|
89
103
|
writeRawStdout
|
|
90
104
|
} from "./chunk-2VTFPG5O.js";
|
|
91
|
-
import "./chunk-
|
|
105
|
+
import "./chunk-E25LMLRW.js";
|
|
92
106
|
import {
|
|
93
107
|
createContextDomainModule,
|
|
94
108
|
loadProjectClioMd
|
|
95
|
-
} from "./chunk-
|
|
109
|
+
} from "./chunk-CYQKWTG3.js";
|
|
110
|
+
import "./chunk-LCGCVYZ4.js";
|
|
96
111
|
import {
|
|
97
112
|
renderCodewikiDigest
|
|
98
113
|
} from "./chunk-5WIGXA4T.js";
|
|
@@ -102,12 +117,13 @@ import {
|
|
|
102
117
|
createTaskMemoryTrace,
|
|
103
118
|
describeTaskMemoryActivity,
|
|
104
119
|
loadMemoryRecordsSync,
|
|
120
|
+
proposeMemoryPromotion,
|
|
105
121
|
renderTaskMemoryHandoffSource,
|
|
106
122
|
seedTaskMemoryFromNewestHandoff,
|
|
107
123
|
taskMemoryBankSize,
|
|
108
124
|
taskMemoryHandoffSeedOffer,
|
|
109
125
|
taskMemoryTracePath
|
|
110
|
-
} from "./chunk-
|
|
126
|
+
} from "./chunk-6US73PDB.js";
|
|
111
127
|
import {
|
|
112
128
|
ACP_MAX_CHUNK_BYTES,
|
|
113
129
|
ACP_MAX_RAW_RECORD_BYTES,
|
|
@@ -118,31 +134,37 @@ import {
|
|
|
118
134
|
ACP_USAGE_META_KEY,
|
|
119
135
|
AcpRequestError,
|
|
120
136
|
AcpTimeoutError,
|
|
121
|
-
SessionDomainModule,
|
|
122
137
|
WORKER_OUTPUT_MAX_BYTES,
|
|
123
138
|
acpErrorMessage,
|
|
124
|
-
collectSessionEntries,
|
|
125
139
|
createDispatchDomainModule,
|
|
126
140
|
createRunReceiptQuality,
|
|
127
141
|
createStdioServerTransport,
|
|
128
142
|
durableAssistantTextFromEvent,
|
|
129
143
|
evidenceDirectory,
|
|
130
|
-
filterEntriesToActivePath,
|
|
131
144
|
inspectEvidence,
|
|
132
145
|
isGitRepository,
|
|
133
|
-
ledgerUsageCalls,
|
|
134
146
|
listEvidenceOverviews,
|
|
135
147
|
openLedger,
|
|
136
|
-
protectedArtifactEntryFromArtifact,
|
|
137
|
-
protectedArtifactStateFromSessionEntries,
|
|
138
148
|
protectedResidencyModels,
|
|
139
|
-
readAuditRows,
|
|
140
149
|
readGateDecisionArtifacts,
|
|
141
150
|
readPendingGateDecisions,
|
|
142
151
|
recoverCleanupReadyCompeteGroups,
|
|
143
152
|
requireAgentSteps
|
|
144
|
-
} from "./chunk-
|
|
145
|
-
import
|
|
153
|
+
} from "./chunk-QM3F2GKX.js";
|
|
154
|
+
import {
|
|
155
|
+
SessionDomainModule,
|
|
156
|
+
addResponseModelIdObservationCount,
|
|
157
|
+
addResponseModelIdObservationCounts,
|
|
158
|
+
attributedModelId,
|
|
159
|
+
collectSessionEntries,
|
|
160
|
+
emptyResponseModelIdObservationCounts,
|
|
161
|
+
ledgerUsageCalls,
|
|
162
|
+
protectedArtifactEntryFromArtifact,
|
|
163
|
+
protectedArtifactStateFromSessionEntries,
|
|
164
|
+
readAuditRows,
|
|
165
|
+
responseModelIdObservationCountsLabel,
|
|
166
|
+
responseModelIdObservationFromRecord
|
|
167
|
+
} from "./chunk-CJUB2JJ2.js";
|
|
146
168
|
import {
|
|
147
169
|
parseRigorOverride,
|
|
148
170
|
resolveRigor
|
|
@@ -150,8 +172,8 @@ import {
|
|
|
150
172
|
import {
|
|
151
173
|
isReceiptIntegrity,
|
|
152
174
|
verifyReceiptIntegrity
|
|
153
|
-
} from "./chunk-
|
|
154
|
-
import "./chunk-
|
|
175
|
+
} from "./chunk-OH3TOQTB.js";
|
|
176
|
+
import "./chunk-TSHXZTOQ.js";
|
|
155
177
|
import {
|
|
156
178
|
shellQuote
|
|
157
179
|
} from "./chunk-TXOTCRLG.js";
|
|
@@ -159,14 +181,24 @@ import {
|
|
|
159
181
|
emptyWorkspaceSnapshot,
|
|
160
182
|
probeGitStatusAsync,
|
|
161
183
|
probeWorkspaceAsync
|
|
162
|
-
} from "./chunk-
|
|
184
|
+
} from "./chunk-HVDIIIQW.js";
|
|
163
185
|
import {
|
|
164
186
|
listWikiPages,
|
|
165
187
|
wikiCompleteness,
|
|
166
188
|
wikiStaleness,
|
|
167
189
|
wikiStalenessAsync
|
|
168
|
-
} from "./chunk-
|
|
190
|
+
} from "./chunk-NDINPTJ4.js";
|
|
169
191
|
import "./chunk-MVVUPGPW.js";
|
|
192
|
+
import {
|
|
193
|
+
buildRecallFields,
|
|
194
|
+
recallErrorMessage,
|
|
195
|
+
recallParentTurnId,
|
|
196
|
+
recallableRefListing,
|
|
197
|
+
resolveRecall
|
|
198
|
+
} from "./chunk-ZZMN5OM4.js";
|
|
199
|
+
import {
|
|
200
|
+
foldWorkingSet
|
|
201
|
+
} from "./chunk-TZSKNMZG.js";
|
|
170
202
|
import {
|
|
171
203
|
createResourcesDomainModule
|
|
172
204
|
} from "./chunk-MFFY33HR.js";
|
|
@@ -182,6 +214,9 @@ import "./chunk-2SFS6XQE.js";
|
|
|
182
214
|
import {
|
|
183
215
|
ExtensionsDomainModule
|
|
184
216
|
} from "./chunk-ZWLZP4ZT.js";
|
|
217
|
+
import {
|
|
218
|
+
filterEntriesToActivePath
|
|
219
|
+
} from "./chunk-W6GROXXM.js";
|
|
185
220
|
import {
|
|
186
221
|
formatBootTrace,
|
|
187
222
|
traceBoot
|
|
@@ -190,13 +225,17 @@ import {
|
|
|
190
225
|
ASK_USER_OTHER_LABEL,
|
|
191
226
|
INTERACTIVE_LOOP_BLOCK_BUDGET,
|
|
192
227
|
askAxis,
|
|
228
|
+
askUserExposure,
|
|
193
229
|
assertRegisteredBuiltinTools,
|
|
194
230
|
cancelledAskUserResult,
|
|
231
|
+
classifyDecisionPresentation,
|
|
195
232
|
createEngineAgent,
|
|
196
233
|
createLoopGuardRegistration,
|
|
197
234
|
createProtectedArtifactsRegistration,
|
|
198
235
|
createRegistry,
|
|
199
|
-
|
|
236
|
+
decisionActionClass,
|
|
237
|
+
decisionFactsForAnswer,
|
|
238
|
+
decisionFactsForPermission,
|
|
200
239
|
diffWords,
|
|
201
240
|
finalizeAskUserInterviewForHost,
|
|
202
241
|
lazyTool,
|
|
@@ -207,14 +246,11 @@ import {
|
|
|
207
246
|
registerCoreTools,
|
|
208
247
|
resolveFdBinary,
|
|
209
248
|
resolveSessionTools,
|
|
210
|
-
sanitizeCallTargetText,
|
|
211
249
|
sanitizeLockedSynthesisMessage
|
|
212
|
-
} from "./chunk-
|
|
250
|
+
} from "./chunk-ZRGEBJ4T.js";
|
|
213
251
|
import {
|
|
214
|
-
HEADLESS_PERMISSION_DENIED_REASON
|
|
215
|
-
|
|
216
|
-
runBashCommand
|
|
217
|
-
} from "./chunk-J7CWMCQD.js";
|
|
252
|
+
HEADLESS_PERMISSION_DENIED_REASON
|
|
253
|
+
} from "./chunk-K7VKOLQQ.js";
|
|
218
254
|
import {
|
|
219
255
|
MIDDLEWARE_HOOK_TEXT_MAX_CHARS,
|
|
220
256
|
MiddlewareDomainModule,
|
|
@@ -230,7 +266,7 @@ import {
|
|
|
230
266
|
installUserHooks,
|
|
231
267
|
openDetachedBatchViews,
|
|
232
268
|
writeMiddlewareDiagnosticToStderr
|
|
233
|
-
} from "./chunk-
|
|
269
|
+
} from "./chunk-ZXF4XRKW.js";
|
|
234
270
|
import "./chunk-IR4CFBFN.js";
|
|
235
271
|
import "./chunk-UOV2BYIW.js";
|
|
236
272
|
import {
|
|
@@ -244,11 +280,11 @@ import {
|
|
|
244
280
|
stringArg,
|
|
245
281
|
timeoutMsArg,
|
|
246
282
|
withResolvedDispatchPlan
|
|
247
|
-
} from "./chunk-
|
|
283
|
+
} from "./chunk-EYPA3EGJ.js";
|
|
248
284
|
import {
|
|
249
285
|
TaskMemoryBank,
|
|
250
286
|
createTaskMemoryTelemetrySink
|
|
251
|
-
} from "./chunk-
|
|
287
|
+
} from "./chunk-WHGPSPT5.js";
|
|
252
288
|
import {
|
|
253
289
|
DISPATCH_BRIEFING_MAX_BYTES,
|
|
254
290
|
JUDGE_GATE_PROMPT,
|
|
@@ -257,53 +293,76 @@ import {
|
|
|
257
293
|
approvedRouteCandidates,
|
|
258
294
|
builtin,
|
|
259
295
|
classifyResourceRead,
|
|
260
|
-
|
|
261
|
-
|
|
296
|
+
cloneRunToolBudgetEnvelope,
|
|
297
|
+
combineBashOutput,
|
|
298
|
+
describeCallTarget,
|
|
299
|
+
formatBudgetPolicy,
|
|
300
|
+
formatBudgetReasons,
|
|
301
|
+
formatBudgetRequest,
|
|
302
|
+
formatEffectiveBudget,
|
|
262
303
|
isToolProfileName,
|
|
304
|
+
redactSecretString,
|
|
305
|
+
redactToolArgs,
|
|
306
|
+
runBashCommand,
|
|
263
307
|
runKindSupportsLiveSteering,
|
|
264
|
-
|
|
308
|
+
sanitizeCallTargetText,
|
|
265
309
|
toolPresentationPolicy
|
|
266
|
-
} from "./chunk-
|
|
310
|
+
} from "./chunk-XXQNGV4M.js";
|
|
311
|
+
import {
|
|
312
|
+
createTaskBoardStore,
|
|
313
|
+
foldSessionTaskHistory,
|
|
314
|
+
taskBoardCounts
|
|
315
|
+
} from "./chunk-43AOLP7E.js";
|
|
267
316
|
import {
|
|
268
|
-
DEFAULT_AUTONOMY_LEVEL,
|
|
269
317
|
DEFAULT_RECENT_ENTRY_LIMIT,
|
|
270
318
|
assessFinishContract,
|
|
271
319
|
parseScoutResult,
|
|
272
320
|
resultContractSourceId
|
|
273
|
-
} from "./chunk-
|
|
321
|
+
} from "./chunk-EKY57CSP.js";
|
|
274
322
|
import {
|
|
275
323
|
agentRoleFactsResolver,
|
|
276
324
|
defaultRoutingIntent,
|
|
277
325
|
gateDeciderAgentId,
|
|
278
326
|
requestExecutionRole,
|
|
279
327
|
sameRouteIdentity
|
|
280
|
-
} from "./chunk-
|
|
328
|
+
} from "./chunk-22NAGB7X.js";
|
|
329
|
+
import "./chunk-AOCYTWAV.js";
|
|
281
330
|
import {
|
|
282
331
|
CLIO_PROJECT_DIR,
|
|
283
332
|
toolMutationPaths
|
|
284
|
-
} from "./chunk-
|
|
333
|
+
} from "./chunk-MV3K5QF2.js";
|
|
285
334
|
import "./chunk-CMZWFGD2.js";
|
|
286
335
|
import "./chunk-I4HZDVNP.js";
|
|
287
336
|
import "./chunk-ZI647VB5.js";
|
|
288
|
-
import "./chunk-
|
|
337
|
+
import "./chunk-NILBFAPG.js";
|
|
338
|
+
import "./chunk-FYYLNIL5.js";
|
|
289
339
|
import {
|
|
290
340
|
VERIFICATION_SCRIPT_FAMILY_HINT
|
|
291
|
-
} from "./chunk-
|
|
341
|
+
} from "./chunk-UL3WSD3F.js";
|
|
292
342
|
import "./chunk-XN3L4EYL.js";
|
|
293
343
|
import {
|
|
294
344
|
escapeRegExp
|
|
295
345
|
} from "./chunk-VG7TBQIY.js";
|
|
296
346
|
import "./chunk-OQE5J4C6.js";
|
|
297
347
|
import "./chunk-ECH6PKUQ.js";
|
|
298
|
-
import "./chunk-
|
|
348
|
+
import "./chunk-SPULKLCF.js";
|
|
299
349
|
import {
|
|
300
350
|
SKILL_SUGGESTION_PREFIX,
|
|
301
351
|
isSkillActivation,
|
|
302
352
|
skillActivationFromToolDetails
|
|
303
|
-
} from "./chunk-
|
|
353
|
+
} from "./chunk-GOXNB3AO.js";
|
|
354
|
+
import {
|
|
355
|
+
DEFAULT_AUTONOMY_LEVEL
|
|
356
|
+
} from "./chunk-HWUFFB6L.js";
|
|
357
|
+
import {
|
|
358
|
+
sweepExpiredToolOffloads,
|
|
359
|
+
toolResultPresentationPolicy,
|
|
360
|
+
toolResultPresentationText
|
|
361
|
+
} from "./chunk-ODFEOB4F.js";
|
|
304
362
|
import {
|
|
305
363
|
formatSize
|
|
306
|
-
} from "./chunk-
|
|
364
|
+
} from "./chunk-OZNBF4L3.js";
|
|
365
|
+
import "./chunk-4BJ5BYCE.js";
|
|
307
366
|
import {
|
|
308
367
|
truncateUtf8
|
|
309
368
|
} from "./chunk-6XLNIQDB.js";
|
|
@@ -316,14 +375,14 @@ import {
|
|
|
316
375
|
import {
|
|
317
376
|
incompleteInstallationAdvice
|
|
318
377
|
} from "./chunk-65DEGPJ6.js";
|
|
319
|
-
import "./chunk-
|
|
320
|
-
import "./chunk-
|
|
321
|
-
import "./chunk-
|
|
378
|
+
import "./chunk-M6L6IDJG.js";
|
|
379
|
+
import "./chunk-XAKHZX5N.js";
|
|
380
|
+
import "./chunk-UUVG37B4.js";
|
|
322
381
|
import {
|
|
323
382
|
readCodewiki,
|
|
324
383
|
readCodewikiAsync
|
|
325
384
|
} from "./chunk-LBMZMYH2.js";
|
|
326
|
-
import "./chunk-
|
|
385
|
+
import "./chunk-33YXPOE3.js";
|
|
327
386
|
import {
|
|
328
387
|
getVersionInfo
|
|
329
388
|
} from "./chunk-XPLRXC72.js";
|
|
@@ -332,38 +391,24 @@ import {
|
|
|
332
391
|
InteropDomainModule,
|
|
333
392
|
delegationEntryForKind,
|
|
334
393
|
renderProposalEntry
|
|
335
|
-
} from "./chunk-
|
|
336
|
-
import "./chunk-
|
|
394
|
+
} from "./chunk-RD5U66HV.js";
|
|
395
|
+
import "./chunk-KOHPCX4K.js";
|
|
337
396
|
import {
|
|
338
397
|
source_default
|
|
339
398
|
} from "./chunk-5TSRNF4G.js";
|
|
340
399
|
import {
|
|
341
400
|
AGENT_ROLE_TOOLS_REQUIRED_REASON,
|
|
342
|
-
AutoCompactionTrigger,
|
|
343
|
-
DEFAULT_COMPACTION_THRESHOLD,
|
|
344
401
|
ProvidersDomainModule,
|
|
345
402
|
VALID_THINKING_LEVELS,
|
|
346
|
-
appendContextSnapshot,
|
|
347
403
|
applyModelCapabilityPatch,
|
|
348
|
-
buildContextLedger,
|
|
349
|
-
captureContextSnapshot,
|
|
350
|
-
ceilChars,
|
|
351
|
-
contentChars,
|
|
352
|
-
contextUsageSnapshot,
|
|
353
|
-
estimateAgentContextBreakdown,
|
|
354
|
-
estimateAgentContextTokens,
|
|
355
|
-
estimateAgentMessageTokens,
|
|
356
|
-
estimateReasoningTextTokens,
|
|
357
|
-
extractReasoningTokens,
|
|
358
404
|
firstRuntimeResolutionError,
|
|
359
|
-
|
|
405
|
+
formatContextWindowSlots,
|
|
360
406
|
getRuntimeRegistry,
|
|
361
407
|
isDispatchEligibleRuntime,
|
|
362
408
|
isOrchestratorEligibleRuntime,
|
|
363
409
|
modelCandidatesForStatus,
|
|
364
410
|
modelIdsForStatus,
|
|
365
411
|
modelResidencyForStatus,
|
|
366
|
-
reconcileSnapshot,
|
|
367
412
|
refineRuntimeTargetWithModelHints,
|
|
368
413
|
registerBuiltinRuntimes,
|
|
369
414
|
resolveModelCapabilities,
|
|
@@ -372,16 +417,15 @@ import {
|
|
|
372
417
|
resolveProviderReference,
|
|
373
418
|
resolveReservedOutputTokens,
|
|
374
419
|
resolveRuntimeTarget,
|
|
375
|
-
|
|
420
|
+
runtimeResolutionWarningsBesideThinkingNotice,
|
|
376
421
|
runtimeTargetSnapshot,
|
|
377
422
|
setProtectedModelsProvider,
|
|
378
|
-
shouldCompact,
|
|
379
|
-
snapshotInputTokens,
|
|
380
423
|
supportsAgentRoleTools,
|
|
381
424
|
thinkingLevelChoiceLabel,
|
|
382
425
|
thinkingLevelFromChoiceLabel,
|
|
383
426
|
withRunOverrides
|
|
384
|
-
} from "./chunk-
|
|
427
|
+
} from "./chunk-DJVECN66.js";
|
|
428
|
+
import "./chunk-CFGTUFWB.js";
|
|
385
429
|
import {
|
|
386
430
|
bindAgentProfileInSettings,
|
|
387
431
|
readSettings,
|
|
@@ -390,28 +434,19 @@ import {
|
|
|
390
434
|
setFleetProfileInSettings,
|
|
391
435
|
updateSettings,
|
|
392
436
|
useTargetInSettings
|
|
393
|
-
} from "./chunk-
|
|
437
|
+
} from "./chunk-AD2SYQYC.js";
|
|
394
438
|
import {
|
|
395
439
|
DEFAULT_DELEGATION_PERMISSION_TIMEOUT_MS,
|
|
396
440
|
DEFAULT_SETTINGS,
|
|
397
441
|
THINKING_LEVELS
|
|
398
|
-
} from "./chunk-
|
|
442
|
+
} from "./chunk-4OC57DA6.js";
|
|
443
|
+
import "./chunk-LL4KHSZI.js";
|
|
399
444
|
import {
|
|
400
445
|
targetRequiresAuth
|
|
401
446
|
} from "./chunk-4VP4KH3K.js";
|
|
402
|
-
import {
|
|
403
|
-
atomicWrite,
|
|
404
|
-
cwdHash,
|
|
405
|
-
openSession,
|
|
406
|
-
readSessionTailTurns,
|
|
407
|
-
sessionCurrentPath,
|
|
408
|
-
sessionPaths
|
|
409
|
-
} from "./chunk-M6SHUN7Q.js";
|
|
410
|
-
import "./chunk-R346GLFC.js";
|
|
411
|
-
import "./chunk-VPAYEGVX.js";
|
|
412
447
|
import {
|
|
413
448
|
setGitCommitAttributionEnabled
|
|
414
|
-
} from "./chunk-
|
|
449
|
+
} from "./chunk-VEZEGCGW.js";
|
|
415
450
|
import {
|
|
416
451
|
MAX_TIMER_DELAY_MS,
|
|
417
452
|
rawDurationMs
|
|
@@ -421,11 +456,37 @@ import "./chunk-3I7MS7N2.js";
|
|
|
421
456
|
import {
|
|
422
457
|
interopAgentKind
|
|
423
458
|
} from "./chunk-IHXBNWMM.js";
|
|
459
|
+
import {
|
|
460
|
+
AutoCompactionTrigger,
|
|
461
|
+
DEFAULT_COMPACTION_THRESHOLD,
|
|
462
|
+
appendContextSnapshot,
|
|
463
|
+
buildContextLedger,
|
|
464
|
+
captureContextSnapshot,
|
|
465
|
+
ceilChars,
|
|
466
|
+
contentChars,
|
|
467
|
+
contextUsageSnapshot,
|
|
468
|
+
estimateAgentContextBreakdown,
|
|
469
|
+
estimateAgentContextTokens,
|
|
470
|
+
estimateReasoningTextTokens,
|
|
471
|
+
extractReasoningTokens,
|
|
472
|
+
getLatestContextSnapshot,
|
|
473
|
+
reconcileSnapshot,
|
|
474
|
+
shouldCompact,
|
|
475
|
+
snapshotInputTokens
|
|
476
|
+
} from "./chunk-GEYXPTRF.js";
|
|
424
477
|
import "./chunk-SST6Z5JA.js";
|
|
478
|
+
import {
|
|
479
|
+
atomicWrite,
|
|
480
|
+
cwdHash,
|
|
481
|
+
openSession,
|
|
482
|
+
readSessionTailTurns,
|
|
483
|
+
sessionCurrentPath,
|
|
484
|
+
sessionPaths
|
|
485
|
+
} from "./chunk-FO5ZOVUY.js";
|
|
486
|
+
import "./chunk-R346GLFC.js";
|
|
425
487
|
import {
|
|
426
488
|
configureGuardrails
|
|
427
489
|
} from "./chunk-4ZG3XFUR.js";
|
|
428
|
-
import "./chunk-APJ265NV.js";
|
|
429
490
|
import {
|
|
430
491
|
StringEnum,
|
|
431
492
|
cleanupEngineSessionResources,
|
|
@@ -433,6 +494,7 @@ import {
|
|
|
433
494
|
isEngineRetryableAssistantError,
|
|
434
495
|
stream
|
|
435
496
|
} from "./chunk-FCSXB6T2.js";
|
|
497
|
+
import "./chunk-APJ265NV.js";
|
|
436
498
|
import "./chunk-YXLYO42X.js";
|
|
437
499
|
import {
|
|
438
500
|
clioConfigDir,
|
|
@@ -445,10 +507,12 @@ import {
|
|
|
445
507
|
safeResourceWrite
|
|
446
508
|
} from "./chunk-WEPFGWHJ.js";
|
|
447
509
|
import {
|
|
448
|
-
Box,
|
|
449
510
|
ClioEditor,
|
|
450
511
|
CombinedAutocompleteProvider,
|
|
451
512
|
Container,
|
|
513
|
+
DEFAULT_SELECT_THEME,
|
|
514
|
+
FILTER_HINT,
|
|
515
|
+
FocusBox,
|
|
452
516
|
GLYPH,
|
|
453
517
|
Input,
|
|
454
518
|
Markdown,
|
|
@@ -462,6 +526,8 @@ import {
|
|
|
462
526
|
abbreviateModelId,
|
|
463
527
|
barSep,
|
|
464
528
|
brandMark,
|
|
529
|
+
buildHint,
|
|
530
|
+
clioError,
|
|
465
531
|
clioTheme,
|
|
466
532
|
collapseHomePath,
|
|
467
533
|
createAgentProgress,
|
|
@@ -471,11 +537,13 @@ import {
|
|
|
471
537
|
detectTerminalKeySupport,
|
|
472
538
|
dotSep,
|
|
473
539
|
fgSequence,
|
|
540
|
+
fitHintEntries,
|
|
474
541
|
fitUnits,
|
|
475
542
|
formatCompactMs,
|
|
476
543
|
formatContextPercent,
|
|
477
544
|
formatInvalidKeybindingNotice,
|
|
478
545
|
formatPlatformKeybindingNotice,
|
|
546
|
+
formatRuntimeResolutionDiagnostic,
|
|
479
547
|
formatTargetLabel,
|
|
480
548
|
frame,
|
|
481
549
|
fuzzyFilter,
|
|
@@ -489,26 +557,30 @@ import {
|
|
|
489
557
|
markdownTheme,
|
|
490
558
|
matchesKey,
|
|
491
559
|
padAnsi,
|
|
560
|
+
permissionHintEntries,
|
|
492
561
|
rule,
|
|
562
|
+
runtimeResolutionDiagnosticLine,
|
|
493
563
|
screenTitle,
|
|
494
564
|
sectionTag,
|
|
495
565
|
selectListTheme,
|
|
496
|
-
|
|
566
|
+
showClioOverlayFrame,
|
|
497
567
|
spinnerFrame,
|
|
498
568
|
stripTerminalSequences,
|
|
499
569
|
truncateToWidth,
|
|
500
570
|
validateKeybindings,
|
|
501
571
|
visibleWidth,
|
|
502
572
|
wrapTextWithAnsi
|
|
503
|
-
} from "./chunk-
|
|
573
|
+
} from "./chunk-E2ER4LJF.js";
|
|
504
574
|
import {
|
|
505
575
|
getTerminationCoordinator
|
|
506
|
-
} from "./chunk-
|
|
576
|
+
} from "./chunk-XE2VEJHX.js";
|
|
577
|
+
import {
|
|
578
|
+
getSharedBus
|
|
579
|
+
} from "./chunk-ZGVHUX3M.js";
|
|
507
580
|
import {
|
|
508
581
|
BusChannels,
|
|
509
|
-
getSharedBus,
|
|
510
582
|
isRunAbortedPayload
|
|
511
|
-
} from "./chunk-
|
|
583
|
+
} from "./chunk-G7MUEIGA.js";
|
|
512
584
|
import "./chunk-JVCV3ICN.js";
|
|
513
585
|
import "./chunk-7CR24IG7.js";
|
|
514
586
|
import {
|
|
@@ -606,6 +678,10 @@ function recordToolEnd(stats, event) {
|
|
|
606
678
|
}
|
|
607
679
|
}
|
|
608
680
|
function addRunUsage(left, right) {
|
|
681
|
+
const responseModelIdObservationCounts = emptyResponseModelIdObservationCounts();
|
|
682
|
+
addResponseModelIdObservationCounts(responseModelIdObservationCounts, left.responseModelIdObservationCounts);
|
|
683
|
+
addResponseModelIdObservationCounts(responseModelIdObservationCounts, right.responseModelIdObservationCounts);
|
|
684
|
+
const last = right.hadUsage ? right : left;
|
|
609
685
|
return {
|
|
610
686
|
tokens: left.tokens + right.tokens,
|
|
611
687
|
costUsd: left.costUsd + right.costUsd,
|
|
@@ -616,7 +692,10 @@ function addRunUsage(left, right) {
|
|
|
616
692
|
reasoning: left.reasoning + right.reasoning,
|
|
617
693
|
apiCalls: left.apiCalls + right.apiCalls,
|
|
618
694
|
hadReasoning: left.hadReasoning || right.hadReasoning,
|
|
619
|
-
hadUsage:
|
|
695
|
+
hadUsage: left.hadUsage || right.hadUsage,
|
|
696
|
+
responseModelIdObservationCounts,
|
|
697
|
+
lastResponseModelIdObservation: last.lastResponseModelIdObservation,
|
|
698
|
+
lastDifferingResponseModelId: last.lastDifferingResponseModelId
|
|
620
699
|
};
|
|
621
700
|
}
|
|
622
701
|
function sortedToolStats(stats) {
|
|
@@ -1509,190 +1588,6 @@ ${truncate(entry.output, TOOL_RESULT_MAX_CHARS)}`);
|
|
|
1509
1588
|
return parts.join("\n\n");
|
|
1510
1589
|
}
|
|
1511
1590
|
|
|
1512
|
-
// src/domains/session/compaction/cut-point.ts
|
|
1513
|
-
init_esm_shims();
|
|
1514
|
-
|
|
1515
|
-
// src/domains/session/compaction/tokens.ts
|
|
1516
|
-
init_esm_shims();
|
|
1517
|
-
function estimateMessage(entry) {
|
|
1518
|
-
return estimateAgentMessageTokens(entry);
|
|
1519
|
-
}
|
|
1520
|
-
function estimateBashExecution(entry) {
|
|
1521
|
-
return ceilChars(entry.command.length + entry.output.length);
|
|
1522
|
-
}
|
|
1523
|
-
function estimateCustom(entry) {
|
|
1524
|
-
if (entry.data === void 0) return 0;
|
|
1525
|
-
return ceilChars(contentChars(entry.data));
|
|
1526
|
-
}
|
|
1527
|
-
function estimateSummary(entry) {
|
|
1528
|
-
return ceilChars(entry.summary.length);
|
|
1529
|
-
}
|
|
1530
|
-
function estimateTokens(entry) {
|
|
1531
|
-
switch (entry.kind) {
|
|
1532
|
-
case "message":
|
|
1533
|
-
return estimateMessage(entry);
|
|
1534
|
-
case "bashExecution":
|
|
1535
|
-
return estimateBashExecution(entry);
|
|
1536
|
-
case "custom":
|
|
1537
|
-
return estimateCustom(entry);
|
|
1538
|
-
case "skillActivation":
|
|
1539
|
-
return ceilChars(JSON.stringify(entry.activation).length);
|
|
1540
|
-
case "branchSummary":
|
|
1541
|
-
case "compactionSummary":
|
|
1542
|
-
return estimateSummary(entry);
|
|
1543
|
-
case "modelChange":
|
|
1544
|
-
case "thinkingLevelChange":
|
|
1545
|
-
case "fileEntry":
|
|
1546
|
-
case "sessionInfo":
|
|
1547
|
-
case "label":
|
|
1548
|
-
case "protectedArtifact":
|
|
1549
|
-
case "taskLedger":
|
|
1550
|
-
case "decisionLedger":
|
|
1551
|
-
case "workerRun":
|
|
1552
|
-
return 0;
|
|
1553
|
-
}
|
|
1554
|
-
}
|
|
1555
|
-
function usageTotalTokens(usage) {
|
|
1556
|
-
return usage.totalTokens || usage.input + usage.output + usage.cacheRead + usage.cacheWrite;
|
|
1557
|
-
}
|
|
1558
|
-
function extractUsage(payload) {
|
|
1559
|
-
if (!payload || typeof payload !== "object") return void 0;
|
|
1560
|
-
const p = payload;
|
|
1561
|
-
if (p.contextUsageInvalidated === true) return void 0;
|
|
1562
|
-
if (p.stopReason === "aborted" || p.stopReason === "error") return void 0;
|
|
1563
|
-
const u = p.usage;
|
|
1564
|
-
if (!u || typeof u !== "object") return void 0;
|
|
1565
|
-
const usage = u;
|
|
1566
|
-
if (typeof usage.input !== "number" || typeof usage.output !== "number") return void 0;
|
|
1567
|
-
return usage;
|
|
1568
|
-
}
|
|
1569
|
-
function getLastAssistantUsage(entries) {
|
|
1570
|
-
for (let i = entries.length - 1; i >= 0; i--) {
|
|
1571
|
-
const entry = entries[i];
|
|
1572
|
-
if (entry?.kind !== "message" || entry?.role !== "assistant") continue;
|
|
1573
|
-
const usage = extractUsage(entry.payload);
|
|
1574
|
-
if (usage) return usage;
|
|
1575
|
-
}
|
|
1576
|
-
return void 0;
|
|
1577
|
-
}
|
|
1578
|
-
function findLastAssistantUsageIndex(entries) {
|
|
1579
|
-
for (let i = entries.length - 1; i >= 0; i--) {
|
|
1580
|
-
const entry = entries[i];
|
|
1581
|
-
if (entry?.kind !== "message" || entry?.role !== "assistant") continue;
|
|
1582
|
-
if (extractUsage(entry.payload)) return i;
|
|
1583
|
-
}
|
|
1584
|
-
return -1;
|
|
1585
|
-
}
|
|
1586
|
-
function calculateContextTokens(entries, lastUsage) {
|
|
1587
|
-
const usage = lastUsage ?? getLastAssistantUsage(entries);
|
|
1588
|
-
if (usage) {
|
|
1589
|
-
const anchorTokens = usageTotalTokens(usage);
|
|
1590
|
-
const anchorIndex = findLastAssistantUsageIndex(entries);
|
|
1591
|
-
let trailing = 0;
|
|
1592
|
-
for (let i = anchorIndex + 1; i < entries.length; i++) {
|
|
1593
|
-
const entry = entries[i];
|
|
1594
|
-
if (entry) trailing += estimateTokens(entry);
|
|
1595
|
-
}
|
|
1596
|
-
return anchorTokens + trailing;
|
|
1597
|
-
}
|
|
1598
|
-
let total = 0;
|
|
1599
|
-
for (const entry of entries) total += estimateTokens(entry);
|
|
1600
|
-
return total;
|
|
1601
|
-
}
|
|
1602
|
-
|
|
1603
|
-
// src/domains/session/compaction/cut-point.ts
|
|
1604
|
-
function findTurnStartIndex(entries, entryIndex, startIndex = 0) {
|
|
1605
|
-
for (let i = entryIndex; i >= startIndex; i--) {
|
|
1606
|
-
const entry = entries[i];
|
|
1607
|
-
if (!entry) continue;
|
|
1608
|
-
if (entry.kind === "branchSummary") return i;
|
|
1609
|
-
if (entry.kind === "bashExecution") return i;
|
|
1610
|
-
if (entry.kind === "message" && entry.role === "user") return i;
|
|
1611
|
-
}
|
|
1612
|
-
return -1;
|
|
1613
|
-
}
|
|
1614
|
-
function isValidCutPoint(entry) {
|
|
1615
|
-
switch (entry.kind) {
|
|
1616
|
-
case "message":
|
|
1617
|
-
return entry.role !== "tool_result";
|
|
1618
|
-
case "bashExecution":
|
|
1619
|
-
case "custom":
|
|
1620
|
-
case "skillActivation":
|
|
1621
|
-
case "branchSummary":
|
|
1622
|
-
case "compactionSummary":
|
|
1623
|
-
return true;
|
|
1624
|
-
case "modelChange":
|
|
1625
|
-
case "thinkingLevelChange":
|
|
1626
|
-
case "fileEntry":
|
|
1627
|
-
case "sessionInfo":
|
|
1628
|
-
case "label":
|
|
1629
|
-
case "protectedArtifact":
|
|
1630
|
-
case "taskLedger":
|
|
1631
|
-
case "decisionLedger":
|
|
1632
|
-
case "workerRun":
|
|
1633
|
-
return false;
|
|
1634
|
-
}
|
|
1635
|
-
}
|
|
1636
|
-
function findValidCutPoints(entries, startIndex, endIndex) {
|
|
1637
|
-
const cuts = [];
|
|
1638
|
-
for (let i = startIndex; i < endIndex; i++) {
|
|
1639
|
-
const entry = entries[i];
|
|
1640
|
-
if (!entry) continue;
|
|
1641
|
-
if (isValidCutPoint(entry)) cuts.push(i);
|
|
1642
|
-
}
|
|
1643
|
-
return cuts;
|
|
1644
|
-
}
|
|
1645
|
-
function findCutPoint(entries, keepRecentTokens, opts = {}) {
|
|
1646
|
-
const startIndex = opts.startIndex ?? 0;
|
|
1647
|
-
const endIndex = opts.endIndex ?? entries.length;
|
|
1648
|
-
const cutPoints = findValidCutPoints(entries, startIndex, endIndex);
|
|
1649
|
-
if (cutPoints.length === 0) {
|
|
1650
|
-
return { firstKeptEntryIndex: startIndex, turnStartIndex: -1, isSplitTurn: false };
|
|
1651
|
-
}
|
|
1652
|
-
let accumulated = 0;
|
|
1653
|
-
let cutIndex = -1;
|
|
1654
|
-
for (let i = endIndex - 1; i >= startIndex; i--) {
|
|
1655
|
-
const entry = entries[i];
|
|
1656
|
-
if (!entry) continue;
|
|
1657
|
-
accumulated += estimateTokens(entry);
|
|
1658
|
-
if (accumulated >= keepRecentTokens) {
|
|
1659
|
-
for (const candidate of cutPoints) {
|
|
1660
|
-
if (candidate >= i) {
|
|
1661
|
-
cutIndex = candidate;
|
|
1662
|
-
break;
|
|
1663
|
-
}
|
|
1664
|
-
}
|
|
1665
|
-
break;
|
|
1666
|
-
}
|
|
1667
|
-
}
|
|
1668
|
-
if (cutIndex === -1) {
|
|
1669
|
-
const lastTurnStart = findTurnStartIndex(entries, endIndex - 1, startIndex);
|
|
1670
|
-
cutIndex = lastTurnStart !== -1 ? lastTurnStart : cutPoints[0] ?? startIndex;
|
|
1671
|
-
}
|
|
1672
|
-
while (cutIndex > startIndex) {
|
|
1673
|
-
const prev = entries[cutIndex - 1];
|
|
1674
|
-
if (!prev) break;
|
|
1675
|
-
if (prev.kind === "compactionSummary") break;
|
|
1676
|
-
if (prev.kind === "message" || prev.kind === "bashExecution" || prev.kind === "custom" || prev.kind === "skillActivation" || prev.kind === "branchSummary") {
|
|
1677
|
-
break;
|
|
1678
|
-
}
|
|
1679
|
-
cutIndex--;
|
|
1680
|
-
}
|
|
1681
|
-
const cutEntry = entries[cutIndex];
|
|
1682
|
-
const cutIsUserTurn = !!cutEntry && cutEntry.kind === "message" && cutEntry.role === "user";
|
|
1683
|
-
const turnStartIndex = cutIsUserTurn ? -1 : findTurnStartIndex(entries, cutIndex, startIndex);
|
|
1684
|
-
return {
|
|
1685
|
-
firstKeptEntryIndex: cutIndex,
|
|
1686
|
-
turnStartIndex,
|
|
1687
|
-
isSplitTurn: !cutIsUserTurn && turnStartIndex !== -1
|
|
1688
|
-
};
|
|
1689
|
-
}
|
|
1690
|
-
|
|
1691
|
-
// src/domains/session/compaction/defaults.ts
|
|
1692
|
-
init_esm_shims();
|
|
1693
|
-
var DEFAULT_RESERVE_TOKENS = 16384;
|
|
1694
|
-
var DEFAULT_KEEP_RECENT_TOKENS = 2e4;
|
|
1695
|
-
|
|
1696
1591
|
// src/domains/session/compaction/compact.ts
|
|
1697
1592
|
var COMPACTION_SYSTEM_PROMPT = [
|
|
1698
1593
|
"You are a context summarization assistant.",
|
|
@@ -1903,6 +1798,26 @@ ${modified.join("\n")}
|
|
|
1903
1798
|
|
|
1904
1799
|
${sections.join("\n\n")}` : "";
|
|
1905
1800
|
}
|
|
1801
|
+
function formatRecallableRefs(entries, firstKeptEntryIndex) {
|
|
1802
|
+
const entryIndexes = /* @__PURE__ */ new Map();
|
|
1803
|
+
for (let index = 0; index < entries.length; index += 1) {
|
|
1804
|
+
const entry = entries[index];
|
|
1805
|
+
if (entry) entryIndexes.set(entry.turnId, index);
|
|
1806
|
+
}
|
|
1807
|
+
const view = foldWorkingSet(entries);
|
|
1808
|
+
const evictedBeforeCut = new Map(
|
|
1809
|
+
[...view.evicted].filter(([ref]) => (entryIndexes.get(ref) ?? Number.POSITIVE_INFINITY) < firstKeptEntryIndex)
|
|
1810
|
+
);
|
|
1811
|
+
const listing = recallableRefListing(entries, { ...view, evicted: evictedBeforeCut });
|
|
1812
|
+
if (listing.refs.length === 0) return "";
|
|
1813
|
+
const rows = [...listing.refs];
|
|
1814
|
+
if (listing.remaining > 0) rows.push(`and ${listing.remaining} more`);
|
|
1815
|
+
return `
|
|
1816
|
+
|
|
1817
|
+
<recallable-refs>
|
|
1818
|
+
${rows.join("\n")}
|
|
1819
|
+
</recallable-refs>`;
|
|
1820
|
+
}
|
|
1906
1821
|
function numberOrZero(value) {
|
|
1907
1822
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
|
|
1908
1823
|
}
|
|
@@ -2016,7 +1931,10 @@ async function compact(input) {
|
|
|
2016
1931
|
${prefixSummary.text}`);
|
|
2017
1932
|
}
|
|
2018
1933
|
}
|
|
2019
|
-
const summary = `${summaryParts.join("\n\n---\n\n").trim()}${formatFileOperations(fileOps)}
|
|
1934
|
+
const summary = `${summaryParts.join("\n\n---\n\n").trim()}${formatFileOperations(fileOps)}${formatRecallableRefs(
|
|
1935
|
+
input.entries,
|
|
1936
|
+
cut.firstKeptEntryIndex
|
|
1937
|
+
)}`.trim();
|
|
2020
1938
|
return {
|
|
2021
1939
|
summary,
|
|
2022
1940
|
firstKeptEntryIndex: cut.firstKeptEntryIndex,
|
|
@@ -2077,6 +1995,7 @@ function finalizedInterviewEntryFields(policy) {
|
|
|
2077
1995
|
roundCount: policy.rounds.length,
|
|
2078
1996
|
...policy.summary ? { summary: policy.summary } : {},
|
|
2079
1997
|
...policy.transcriptPath ? { transcriptPath: policy.transcriptPath } : {},
|
|
1998
|
+
exposure: policy.exposure ?? "local",
|
|
2080
1999
|
decisions: [...decisionsByKey.values()]
|
|
2081
2000
|
};
|
|
2082
2001
|
}
|
|
@@ -2154,6 +2073,7 @@ function createDecisionBoardStore(deps = {}) {
|
|
|
2154
2073
|
roundCount: interview.roundCount,
|
|
2155
2074
|
...interview.summary ? { summary: interview.summary } : {},
|
|
2156
2075
|
...interview.transcriptPath ? { transcriptPath: interview.transcriptPath } : {},
|
|
2076
|
+
...interview.exposure ? { exposure: interview.exposure } : {},
|
|
2157
2077
|
decisions: interview.decisions.map((decision) => {
|
|
2158
2078
|
if (decision.key !== selected.key) return { ...decision };
|
|
2159
2079
|
const next = { ...decision, status: "superseded", revisedAt };
|
|
@@ -2684,8 +2604,8 @@ function boundRawRecord(value) {
|
|
|
2684
2604
|
return { truncated: true, bytes: originalRawRecordBytes(value) ?? boundedBytes };
|
|
2685
2605
|
}
|
|
2686
2606
|
var PATH_BEARING_TOOLS = /* @__PURE__ */ new Set(["read", "write", "edit", "ls", "grep", "find"]);
|
|
2687
|
-
function toolLocations(
|
|
2688
|
-
if (
|
|
2607
|
+
function toolLocations(toolName, args, cwd) {
|
|
2608
|
+
if (toolName === void 0 || !PATH_BEARING_TOOLS.has(toolName)) return null;
|
|
2689
2609
|
if (!isRecord3(args)) return null;
|
|
2690
2610
|
const path = args.path;
|
|
2691
2611
|
if (typeof path !== "string" || path.length === 0) return null;
|
|
@@ -2790,6 +2710,8 @@ function applyStopReason(active, message) {
|
|
|
2790
2710
|
function outputText(value) {
|
|
2791
2711
|
if (typeof value === "string") return value;
|
|
2792
2712
|
if (!isRecord3(value)) return "";
|
|
2713
|
+
const presentationText = toolResultPresentationText(value);
|
|
2714
|
+
if (presentationText !== null) return presentationText;
|
|
2793
2715
|
if (Array.isArray(value.content)) return contentText(value.content);
|
|
2794
2716
|
if (typeof value.output === "string") return value.output;
|
|
2795
2717
|
if (typeof value.text === "string") return value.text;
|
|
@@ -2919,11 +2841,11 @@ function handleChatEvent(rawEvent, transport, sessionId, active, cwd, diagnostic
|
|
|
2919
2841
|
onToolCallLimitReached();
|
|
2920
2842
|
return;
|
|
2921
2843
|
}
|
|
2922
|
-
const
|
|
2844
|
+
const toolName = eventString(event, "toolName");
|
|
2923
2845
|
const toolCallId = startToolCallId(active, eventString(event, "toolCallId"));
|
|
2924
2846
|
active.openToolCalls.add(toolCallId);
|
|
2925
2847
|
active.lastEmittedToolCallId = toolCallId;
|
|
2926
|
-
const locations = toolLocations(
|
|
2848
|
+
const locations = toolLocations(toolName, event.args, cwd);
|
|
2927
2849
|
const snapshot = {
|
|
2928
2850
|
rawInput: boundRawRecord(event.args),
|
|
2929
2851
|
...locations !== null ? { locations } : {}
|
|
@@ -2932,8 +2854,8 @@ function handleChatEvent(rawEvent, transport, sessionId, active, cwd, diagnostic
|
|
|
2932
2854
|
sendUpdate(transport, sessionId, active, {
|
|
2933
2855
|
sessionUpdate: "tool_call",
|
|
2934
2856
|
toolCallId,
|
|
2935
|
-
title: boundString(
|
|
2936
|
-
kind: toolKind(
|
|
2857
|
+
title: boundString(toolName ?? "tool", ACP_MAX_TOOL_TITLE_BYTES),
|
|
2858
|
+
kind: toolKind(toolName),
|
|
2937
2859
|
status: "in_progress",
|
|
2938
2860
|
rawInput: snapshot.rawInput,
|
|
2939
2861
|
...snapshot.locations !== void 0 ? { locations: snapshot.locations } : {}
|
|
@@ -2941,7 +2863,7 @@ function handleChatEvent(rawEvent, transport, sessionId, active, cwd, diagnostic
|
|
|
2941
2863
|
return;
|
|
2942
2864
|
}
|
|
2943
2865
|
if (event.type === "tool_execution_end") {
|
|
2944
|
-
const
|
|
2866
|
+
const toolName = eventString(event, "toolName");
|
|
2945
2867
|
const toolCallId = endToolCallId(active, eventString(event, "toolCallId"));
|
|
2946
2868
|
if (toolCallId === null) {
|
|
2947
2869
|
diagnostics?.("dropped tool_execution_end with no tool call to update");
|
|
@@ -2957,8 +2879,8 @@ function handleChatEvent(rawEvent, transport, sessionId, active, cwd, diagnostic
|
|
|
2957
2879
|
sendUpdate(transport, sessionId, active, {
|
|
2958
2880
|
sessionUpdate: "tool_call_update",
|
|
2959
2881
|
toolCallId,
|
|
2960
|
-
title: boundString(
|
|
2961
|
-
kind: toolKind(
|
|
2882
|
+
title: boundString(toolName ?? "tool", ACP_MAX_TOOL_TITLE_BYTES),
|
|
2883
|
+
kind: toolKind(toolName),
|
|
2962
2884
|
status: toolStatus(event),
|
|
2963
2885
|
...output.length > 0 ? { content: toolCallContent(output) } : {},
|
|
2964
2886
|
rawOutput: boundRawRecord({ result: event.result, isError: event.isError === true })
|
|
@@ -3280,6 +3202,17 @@ function installPermissionBridge(input) {
|
|
|
3280
3202
|
const queuedRequestDetails = /* @__PURE__ */ new Map();
|
|
3281
3203
|
const unregister = input.toolRegistry.onPermissionRequired((call, decision, meta) => {
|
|
3282
3204
|
if (queuedRequestIds.has(meta.requestId)) return;
|
|
3205
|
+
const presentation = classifyDecisionPresentation(
|
|
3206
|
+
decisionFactsForPermission({
|
|
3207
|
+
tool: call.tool,
|
|
3208
|
+
actionClass: decision.classification.actionClass,
|
|
3209
|
+
axis: meta.axis.startsWith("net:") ? { kind: "safety-net", ruleId: meta.axis.slice("net:".length) || "unknown" } : { kind: "autonomy", level: meta.axis.slice("autonomy:".length) || DEFAULT_AUTONOMY_LEVEL },
|
|
3210
|
+
origin: { kind: "main" },
|
|
3211
|
+
...call.tool === ToolNames.AskUser ? { exposure: askUserExposure(call.args) } : {}
|
|
3212
|
+
})
|
|
3213
|
+
);
|
|
3214
|
+
const approveAction = presentation.requiredActions.find((action) => action.id === "approve-once");
|
|
3215
|
+
const denyAction = presentation.requiredActions.find((action) => action.id === "deny");
|
|
3283
3216
|
queuedRequestIds.add(meta.requestId);
|
|
3284
3217
|
queuedRequestDetails.set(meta.requestId, {
|
|
3285
3218
|
tool: call.tool,
|
|
@@ -3369,8 +3302,16 @@ function installPermissionBridge(input) {
|
|
|
3369
3302
|
...snapshot.locations !== void 0 ? { locations: snapshot.locations } : {}
|
|
3370
3303
|
},
|
|
3371
3304
|
options: [
|
|
3372
|
-
{
|
|
3373
|
-
|
|
3305
|
+
{
|
|
3306
|
+
optionId: "allow-once",
|
|
3307
|
+
name: approveAction?.label ?? "Approve once",
|
|
3308
|
+
kind: "allow_once"
|
|
3309
|
+
},
|
|
3310
|
+
{
|
|
3311
|
+
optionId: "reject-once",
|
|
3312
|
+
name: denyAction?.label ?? "Deny this request",
|
|
3313
|
+
kind: "reject_once"
|
|
3314
|
+
}
|
|
3374
3315
|
]
|
|
3375
3316
|
},
|
|
3376
3317
|
input.permissionTimeoutMs
|
|
@@ -4237,17 +4178,17 @@ function resultText(result) {
|
|
|
4237
4178
|
function extractToolResultPayload(payload) {
|
|
4238
4179
|
const obj = isRecord4(payload) ? payload : { result: payload };
|
|
4239
4180
|
const result = obj.result ?? obj.output ?? obj.out ?? obj.content ?? payload;
|
|
4240
|
-
const
|
|
4241
|
-
return { obj, result, toolName
|
|
4181
|
+
const toolName = typeof obj.toolName === "string" && obj.toolName || typeof obj.name === "string" && obj.name || typeof obj.tool === "string" && obj.tool || "tool";
|
|
4182
|
+
return { obj, result, toolName };
|
|
4242
4183
|
}
|
|
4243
4184
|
function lineCount(text) {
|
|
4244
4185
|
if (text.length === 0) return 0;
|
|
4245
4186
|
return text.split(/\r\n|\r|\n/).length;
|
|
4246
4187
|
}
|
|
4247
|
-
function observationMarker(
|
|
4188
|
+
function observationMarker(toolName, text) {
|
|
4248
4189
|
const preview = text.trim().replace(/\s+/g, " ").slice(0, 160);
|
|
4249
4190
|
const suffix = preview.length > 0 ? ` Preview: ${preview}` : "";
|
|
4250
|
-
return `[Observation masked: ${
|
|
4191
|
+
return `[Observation masked: ${toolName} output was ${lineCount(text)} lines, ${text.length} chars - contents masked to save context. Re-run the tool for current content.]${suffix}`;
|
|
4251
4192
|
}
|
|
4252
4193
|
function maskedToolResult(original, marker) {
|
|
4253
4194
|
const details = isRecord4(original) && isRecord4(original.details) ? { ...original.details } : {};
|
|
@@ -4270,9 +4211,9 @@ function alreadyCompacted(payload) {
|
|
|
4270
4211
|
}
|
|
4271
4212
|
function maskObservation(entry) {
|
|
4272
4213
|
const next = cloneEntry(entry);
|
|
4273
|
-
const { obj, result, toolName
|
|
4214
|
+
const { obj, result, toolName } = extractToolResultPayload(next.payload);
|
|
4274
4215
|
const text = resultText(result);
|
|
4275
|
-
const marker = observationMarker(
|
|
4216
|
+
const marker = observationMarker(toolName, text);
|
|
4276
4217
|
next.payload = {
|
|
4277
4218
|
...obj,
|
|
4278
4219
|
result: maskedToolResult(result, marker),
|
|
@@ -4469,8 +4410,12 @@ function readPromptCompileManifest(meta, stateDir) {
|
|
|
4469
4410
|
}
|
|
4470
4411
|
}
|
|
4471
4412
|
|
|
4413
|
+
// src/interactive/model-session-replay.ts
|
|
4414
|
+
init_esm_shims();
|
|
4415
|
+
|
|
4472
4416
|
// src/interactive/chat-renderer.ts
|
|
4473
4417
|
init_esm_shims();
|
|
4418
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
4474
4419
|
|
|
4475
4420
|
// src/engine/messages.ts
|
|
4476
4421
|
init_esm_shims();
|
|
@@ -4799,39 +4744,6 @@ function truncate2(value, limit) {
|
|
|
4799
4744
|
function isPlainObject(value) {
|
|
4800
4745
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
4801
4746
|
}
|
|
4802
|
-
var SECRET_KEY_RE = /(?:api[-_]?key|access[-_]?key|auth(?:orization)?|credential|password|private[-_]?key|secret|token)/iu;
|
|
4803
|
-
var ENV_KEY_RE = /^env(?:ironment)?$/iu;
|
|
4804
|
-
var SECRET_STRING_RE = /(https?:\/\/[^\s/@]+:)[^\s/@]+@/giu;
|
|
4805
|
-
var SECRET_URL_PARAM_RE = /([?&](?:api[-_]?key|access[-_]?token|auth(?:orization)?|credential|password|secret|token)[^=\s]*=)[^&#\s]+/giu;
|
|
4806
|
-
var SECRET_ASSIGNMENT_RE = /(?<![A-Z0-9_])((?:[A-Z0-9_]*(?:ACCESS|API|AUTH|CREDENTIAL|KEY|PASS(?:WORD)?|PRIVATE|SECRET|TOKEN)[A-Z0-9_]*)=)[^\s;&|]+/giu;
|
|
4807
|
-
var SECRET_FLAG_RE = /(--?(?:[a-z0-9-]*(?:api[-_]?key|access[-_]?token|auth(?:orization)?|credential|password|secret|token)[a-z0-9-]*))(=|\s+)([^\s;&|]+)/giu;
|
|
4808
|
-
function redactSecretString(value) {
|
|
4809
|
-
return value.replace(SECRET_STRING_RE, "$1[redacted]@").replace(SECRET_URL_PARAM_RE, "$1[redacted]").replace(SECRET_ASSIGNMENT_RE, "$1[redacted]").replace(SECRET_FLAG_RE, "$1$2[redacted]");
|
|
4810
|
-
}
|
|
4811
|
-
function redactEnvironmentValue(value, depth) {
|
|
4812
|
-
if (depth > 8) return "[redacted nested values]";
|
|
4813
|
-
if (typeof value === "string") return "[redacted]";
|
|
4814
|
-
if (Array.isArray(value)) return value.map((item) => redactEnvironmentValue(item, depth + 1));
|
|
4815
|
-
if (!isPlainObject(value)) return value;
|
|
4816
|
-
const out = {};
|
|
4817
|
-
for (const [childKey, childValue] of Object.entries(value)) {
|
|
4818
|
-
out[childKey] = redactEnvironmentValue(childValue, depth + 1);
|
|
4819
|
-
}
|
|
4820
|
-
return out;
|
|
4821
|
-
}
|
|
4822
|
-
function redactToolArgs(value, key = "", depth = 0) {
|
|
4823
|
-
if (SECRET_KEY_RE.test(key)) return "[redacted]";
|
|
4824
|
-
if (ENV_KEY_RE.test(key)) return redactEnvironmentValue(value, depth);
|
|
4825
|
-
if (typeof value === "string") return redactSecretString(value);
|
|
4826
|
-
if (depth > 8) return "[redacted nested values]";
|
|
4827
|
-
if (Array.isArray(value)) return value.map((item) => redactToolArgs(item, key, depth + 1));
|
|
4828
|
-
if (!isPlainObject(value)) return value;
|
|
4829
|
-
const out = {};
|
|
4830
|
-
for (const [childKey, childValue] of Object.entries(value)) {
|
|
4831
|
-
out[childKey] = redactToolArgs(childValue, childKey, depth + 1);
|
|
4832
|
-
}
|
|
4833
|
-
return out;
|
|
4834
|
-
}
|
|
4835
4747
|
function readStringField(args, key) {
|
|
4836
4748
|
if (!isPlainObject(args)) return null;
|
|
4837
4749
|
const value = args[key];
|
|
@@ -4865,8 +4777,8 @@ function stripShellWrapperForDisplay(command) {
|
|
|
4865
4777
|
if (!match?.[1]) return command;
|
|
4866
4778
|
return unquoteShellScript(match[1]);
|
|
4867
4779
|
}
|
|
4868
|
-
function displayArg(
|
|
4869
|
-
return
|
|
4780
|
+
function displayArg(toolName, value) {
|
|
4781
|
+
return toolName === "bash" ? stripShellWrapperForDisplay(value) : value;
|
|
4870
4782
|
}
|
|
4871
4783
|
function optionalCompactMs(durationMs) {
|
|
4872
4784
|
if (durationMs === void 0 || !Number.isFinite(durationMs) || durationMs < 0) return null;
|
|
@@ -4896,8 +4808,8 @@ var PRIMARY_ARG_FIELD = {
|
|
|
4896
4808
|
steer: "run_id",
|
|
4897
4809
|
tasks: "action"
|
|
4898
4810
|
};
|
|
4899
|
-
function capturedPrimaryArg(
|
|
4900
|
-
const field2 = PRIMARY_ARG_FIELD[
|
|
4811
|
+
function capturedPrimaryArg(toolName, args) {
|
|
4812
|
+
const field2 = PRIMARY_ARG_FIELD[toolName];
|
|
4901
4813
|
if (field2 === void 0) return null;
|
|
4902
4814
|
return readStringField(args, field2);
|
|
4903
4815
|
}
|
|
@@ -4909,12 +4821,12 @@ function summarizeWebFetchArgs(args) {
|
|
|
4909
4821
|
}
|
|
4910
4822
|
return truncate2(jsonStringifySafe(Object.keys(compact2).length > 0 ? compact2 : args), WEB_FETCH_ARG_PREVIEW_LIMIT);
|
|
4911
4823
|
}
|
|
4912
|
-
function summarizeArgs(
|
|
4824
|
+
function summarizeArgs(toolName, args) {
|
|
4913
4825
|
if (isEmptyArgs(args)) return "";
|
|
4914
4826
|
const safeArgs = redactToolArgs(args);
|
|
4915
|
-
if (
|
|
4916
|
-
const primary = capturedPrimaryArg(
|
|
4917
|
-
if (primary !== null) return truncate2(displayArg(
|
|
4827
|
+
if (toolName === "web_fetch") return summarizeWebFetchArgs(safeArgs);
|
|
4828
|
+
const primary = capturedPrimaryArg(toolName, args);
|
|
4829
|
+
if (primary !== null) return truncate2(displayArg(toolName, primary), ARG_PREVIEW_LIMIT);
|
|
4918
4830
|
return truncate2(jsonStringifySafe(safeArgs), ARG_PREVIEW_LIMIT);
|
|
4919
4831
|
}
|
|
4920
4832
|
function detailsOf(result) {
|
|
@@ -4995,6 +4907,9 @@ function offloadPathOf(finished) {
|
|
|
4995
4907
|
const resultSize = detailsOf(finished.result)?.resultSize;
|
|
4996
4908
|
return isPlainObject(resultSize) ? stringField(resultSize, "offloadPath") : null;
|
|
4997
4909
|
}
|
|
4910
|
+
function offloadFileMissing(finished) {
|
|
4911
|
+
return finished.resultSummary?.offloadFileMissing === true;
|
|
4912
|
+
}
|
|
4998
4913
|
function shownBytesOf(finished) {
|
|
4999
4914
|
const observation = observationOf(finished);
|
|
5000
4915
|
const fromObservation = numberField(observation, "shownBytes");
|
|
@@ -5056,15 +4971,17 @@ function ledgerTail(finished) {
|
|
|
5056
4971
|
if (details?.outputCapped === true) parts.push("output capped");
|
|
5057
4972
|
}
|
|
5058
4973
|
if (finished.excludeFromContext === true) parts.push("excluded from context");
|
|
4974
|
+
if (finished.evictedReason !== void 0) parts.push("evicted", finished.evictedReason);
|
|
5059
4975
|
const offloadPath = executed ? offloadPathOf(finished) : null;
|
|
5060
4976
|
return {
|
|
5061
4977
|
facts: parts.length > 0 ? dim(` \xB7 ${parts.join(" \xB7 ")}`) : "",
|
|
5062
|
-
offload: offloadPath
|
|
4978
|
+
offload: offloadPath === null ? "" : offloadFileMissing(finished) ? dim(" \xB7 full: gone after the 14-day retention sweep") : dim(` \xB7 full: ${offloadPath}`)
|
|
5063
4979
|
};
|
|
5064
4980
|
}
|
|
5065
4981
|
var FAILURE_EXCERPT_LIMIT = 80;
|
|
5066
4982
|
function failureExcerpt(finished, width) {
|
|
5067
|
-
|
|
4983
|
+
const presentation = toolResultPresentationPolicy(finished.result) ?? toolPresentationPolicy(finished.toolName, finished.args);
|
|
4984
|
+
if (!finished.isError || !presentation.failureExcerpt) return "";
|
|
5068
4985
|
if (isNonExecutedOutcome(finished.outcome)) return "";
|
|
5069
4986
|
const text = unwrapResultEnvelope(finished.result);
|
|
5070
4987
|
if (typeof text !== "string") return "";
|
|
@@ -5111,8 +5028,8 @@ function statusGlyph(status, meta = {}) {
|
|
|
5111
5028
|
const reasonSuffix = reason ? dim(` \xB7 ${truncate2(reason, BLOCK_REASON_LIMIT)}`) : "";
|
|
5112
5029
|
return ` ${red(STATUS_ERROR_GLYPH)}${outcomeSuffix}${reasonSuffix}${exitSuffix}${durationSuffix}`;
|
|
5113
5030
|
}
|
|
5114
|
-
function headerLine(
|
|
5115
|
-
const body = styleSublineBody(buildSublineBody(
|
|
5031
|
+
function headerLine(toolName, args, status, meta = {}) {
|
|
5032
|
+
const body = styleSublineBody(buildSublineBody(toolName, args, status, void 0, meta.outcome));
|
|
5116
5033
|
const head = `${dim(HEADER_PREFIX_PLAIN)}${body}`;
|
|
5117
5034
|
return `${head}${statusGlyph(status, meta)}`;
|
|
5118
5035
|
}
|
|
@@ -5124,8 +5041,8 @@ function styleSublineBody(body) {
|
|
|
5124
5041
|
if (match?.groups?.lead === void 0 || match.groups.rest === void 0) return body;
|
|
5125
5042
|
return sublineLead(match.groups.lead, match.groups.rest);
|
|
5126
5043
|
}
|
|
5127
|
-
function buildGenericToolBody(
|
|
5128
|
-
const summary = summarizeArgs(
|
|
5044
|
+
function buildGenericToolBody(toolName, args) {
|
|
5045
|
+
const summary = summarizeArgs(toolName, args);
|
|
5129
5046
|
return summary.length > 0 ? `tool action ${summary}` : "tool action";
|
|
5130
5047
|
}
|
|
5131
5048
|
function buildFieldSublineBody(args, key, lead, options = {}) {
|
|
@@ -5217,25 +5134,25 @@ function webFetchMeta(result) {
|
|
|
5217
5134
|
function isNonExecutedOutcome(outcome) {
|
|
5218
5135
|
return outcome === "blocked";
|
|
5219
5136
|
}
|
|
5220
|
-
function buildSublineBody(
|
|
5137
|
+
function buildSublineBody(toolName, args, status, result, outcome) {
|
|
5221
5138
|
if (isNonExecutedOutcome(outcome)) {
|
|
5222
|
-
if (
|
|
5223
|
-
return buildFieldSublineBody(args, "command", "command ", { wrapInBackticks: true }) ?? buildGenericToolBody(
|
|
5139
|
+
if (toolName === "bash") {
|
|
5140
|
+
return buildFieldSublineBody(args, "command", "command ", { wrapInBackticks: true }) ?? buildGenericToolBody(toolName, args);
|
|
5224
5141
|
}
|
|
5225
|
-
return SUBLINE_BODY_BUILDERS[
|
|
5142
|
+
return SUBLINE_BODY_BUILDERS[toolName]?.(args) ?? buildGenericToolBody(toolName, args);
|
|
5226
5143
|
}
|
|
5227
|
-
if (
|
|
5144
|
+
if (toolName === "web_fetch") {
|
|
5228
5145
|
const meta = status === void 0 ? null : webFetchMeta(result);
|
|
5229
|
-
const body2 = SUBLINE_BODY_BUILDERS.web_fetch?.(args) ?? buildGenericToolBody(
|
|
5146
|
+
const body2 = SUBLINE_BODY_BUILDERS.web_fetch?.(args) ?? buildGenericToolBody(toolName, args);
|
|
5230
5147
|
return `${body2}${meta ? dim(` \xB7 ${meta}`) : ""}`;
|
|
5231
5148
|
}
|
|
5232
|
-
if (
|
|
5149
|
+
if (toolName === "bash") {
|
|
5233
5150
|
const lead = status === "ok" || status === "error" ? "ran " : "running ";
|
|
5234
|
-
return buildFieldSublineBody(args, "command", lead, { wrapInBackticks: true }) ?? buildGenericToolBody(
|
|
5151
|
+
return buildFieldSublineBody(args, "command", lead, { wrapInBackticks: true }) ?? buildGenericToolBody(toolName, args);
|
|
5235
5152
|
}
|
|
5236
|
-
const body = SUBLINE_BODY_BUILDERS[
|
|
5153
|
+
const body = SUBLINE_BODY_BUILDERS[toolName]?.(args);
|
|
5237
5154
|
if (body !== null && body !== void 0) return body;
|
|
5238
|
-
return buildGenericToolBody(
|
|
5155
|
+
return buildGenericToolBody(toolName, args);
|
|
5239
5156
|
}
|
|
5240
5157
|
function sublineParts(call, status, meta) {
|
|
5241
5158
|
const finished = "result" in call ? call : null;
|
|
@@ -5286,7 +5203,7 @@ function scalarArgValue(value) {
|
|
|
5286
5203
|
if (value === null) return dim("null");
|
|
5287
5204
|
return null;
|
|
5288
5205
|
}
|
|
5289
|
-
function renderArgsBody(
|
|
5206
|
+
function renderArgsBody(toolName, args, width, isError) {
|
|
5290
5207
|
if (isEmptyArgs(args)) return [];
|
|
5291
5208
|
const safeArgs = redactToolArgs(args);
|
|
5292
5209
|
if (!isPlainObject(safeArgs)) {
|
|
@@ -5294,7 +5211,7 @@ function renderArgsBody(toolName2, args, width, isError) {
|
|
|
5294
5211
|
const lines = tryRenderJson(safeArgs, bodyWidth2, { lineLimit: ARGS_BODY_LINE_LIMIT });
|
|
5295
5212
|
return lines?.flatMap((line) => indentAndWrap(line, width, isError)) ?? [];
|
|
5296
5213
|
}
|
|
5297
|
-
const primary = PRIMARY_ARG_FIELD[
|
|
5214
|
+
const primary = PRIMARY_ARG_FIELD[toolName];
|
|
5298
5215
|
const entries = Object.entries(safeArgs).filter(([key]) => key !== primary);
|
|
5299
5216
|
if (entries.length === 0) return [];
|
|
5300
5217
|
const out = [];
|
|
@@ -5321,6 +5238,8 @@ function renderArgsBody(toolName2, args, width, isError) {
|
|
|
5321
5238
|
}
|
|
5322
5239
|
function unwrapResultEnvelope(result) {
|
|
5323
5240
|
if (typeof result === "string" || result === null || result === void 0) return result;
|
|
5241
|
+
const presentationText = toolResultPresentationText(result);
|
|
5242
|
+
if (presentationText !== null) return presentationText;
|
|
5324
5243
|
const blocks = Array.isArray(result) ? result : isPlainObject(result) && Array.isArray(result.content) ? result.content : null;
|
|
5325
5244
|
if (blocks === null) return result;
|
|
5326
5245
|
const parts = [];
|
|
@@ -5453,6 +5372,7 @@ function outputFacts(finished) {
|
|
|
5453
5372
|
}
|
|
5454
5373
|
if (isPlainObject(finished.result) && finished.result.terminate === true) parts.push("terminal result");
|
|
5455
5374
|
if (finished.excludeFromContext === true) parts.push("excluded from context");
|
|
5375
|
+
if (finished.evictedReason !== void 0) parts.push("evicted", finished.evictedReason);
|
|
5456
5376
|
return parts;
|
|
5457
5377
|
}
|
|
5458
5378
|
function renderOutputMeta(finished, width, isError, label = "output") {
|
|
@@ -5463,7 +5383,10 @@ function renderOutputMeta(finished, width, isError, label = "output") {
|
|
|
5463
5383
|
function renderOutputFooter(finished, width, isError) {
|
|
5464
5384
|
const out = [];
|
|
5465
5385
|
const offloadPath = isNonExecutedOutcome(finished.outcome) ? null : offloadPathOf(finished);
|
|
5466
|
-
if (offloadPath !== null)
|
|
5386
|
+
if (offloadPath !== null) {
|
|
5387
|
+
const pointer = offloadFileMissing(finished) ? "gone after the 14-day retention sweep" : offloadPath;
|
|
5388
|
+
out.push(...indentAndWrap(`${yellow("full output")} ${pointer}`, width, isError));
|
|
5389
|
+
}
|
|
5467
5390
|
const hint = stringField(resultSizeOf(finished), "followUpHint") ?? stringField(finished.resultSummary ?? null, "followUpHint");
|
|
5468
5391
|
if (hint !== null) out.push(...indentAndWrap(`${dim("next")} ${hint}`, width, isError));
|
|
5469
5392
|
return out;
|
|
@@ -5511,7 +5434,8 @@ function sublineStatus(call) {
|
|
|
5511
5434
|
function foldedDiffRows(finished, width, opts) {
|
|
5512
5435
|
if (opts.foldedExtras === "none") return [];
|
|
5513
5436
|
if (finished.isError || isNonExecutedOutcome(finished.outcome)) return [];
|
|
5514
|
-
|
|
5437
|
+
const presentation = toolResultPresentationPolicy(finished.result) ?? toolPresentationPolicy(finished.toolName, finished.args);
|
|
5438
|
+
if (!presentation.showDiffWhenFolded) return [];
|
|
5515
5439
|
const diff = resultDiff(finished.result);
|
|
5516
5440
|
if (diff === null) return [];
|
|
5517
5441
|
return truncateRowsMiddle(
|
|
@@ -6288,6 +6212,10 @@ function renderContextMeterGrid(ledger, cols, rows, theme6 = clioTheme()) {
|
|
|
6288
6212
|
}
|
|
6289
6213
|
return lines;
|
|
6290
6214
|
}
|
|
6215
|
+
function renderEvictedTokensLine(evictedTokens2, theme6 = clioTheme()) {
|
|
6216
|
+
const tokens = Math.round(Math.max(0, evictedTokens2)).toLocaleString("en-US");
|
|
6217
|
+
return `${theme6.fg("dim", GLYPH.contextReserve)} ${theme6.fg("muted", "evicted (outside window)")} ${theme6.fg("dim", `${tokens} tokens`)}`;
|
|
6218
|
+
}
|
|
6291
6219
|
function contextCategorySwatch(category, theme6 = clioTheme()) {
|
|
6292
6220
|
return theme6.fg(CONTEXT_CATEGORY_TOKEN[category], contextCategoryGlyph(category));
|
|
6293
6221
|
}
|
|
@@ -6499,6 +6427,267 @@ function buildSegmentedContextBar(theme6, barWidth, contextWindow, breakdown) {
|
|
|
6499
6427
|
return `${systemPart}${toolPart}${conversationPart}${freePart}${contextPercentLabel(percent)}`;
|
|
6500
6428
|
}
|
|
6501
6429
|
|
|
6430
|
+
// src/interactive/worker-progress.ts
|
|
6431
|
+
init_esm_shims();
|
|
6432
|
+
var WORKER_LIVE_TAIL_LINES = 40;
|
|
6433
|
+
var WORKER_LIVE_TAIL_MAX_BYTES = 4096;
|
|
6434
|
+
var WORKER_TOOL_NAME_LIMIT = 8;
|
|
6435
|
+
var WORKER_ACTION_TRAIL_LIMIT = 4;
|
|
6436
|
+
var WORKER_PROGRESS_WINDOW_MS = 250;
|
|
6437
|
+
var WORKER_PROGRESS_WINDOW_BYTES = 16384;
|
|
6438
|
+
var TAIL_TRUNCATION_MARKER = "";
|
|
6439
|
+
function isRecord7(value) {
|
|
6440
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6441
|
+
}
|
|
6442
|
+
function nonEmptyString(value) {
|
|
6443
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
6444
|
+
}
|
|
6445
|
+
function workerTextDelta(event) {
|
|
6446
|
+
if (!isRecord7(event)) return "";
|
|
6447
|
+
if (event.type === "message_update") {
|
|
6448
|
+
const assistantEvent = isRecord7(event.assistantMessageEvent) ? event.assistantMessageEvent : null;
|
|
6449
|
+
if (assistantEvent?.type !== "text_delta") return "";
|
|
6450
|
+
return typeof assistantEvent.delta === "string" ? assistantEvent.delta : "";
|
|
6451
|
+
}
|
|
6452
|
+
if (event.type !== "text_delta") return "";
|
|
6453
|
+
if (typeof event.delta === "string") return event.delta;
|
|
6454
|
+
return typeof event.text === "string" ? event.text : "";
|
|
6455
|
+
}
|
|
6456
|
+
function isThinkingEvent(event) {
|
|
6457
|
+
if (event.type === "thinking_delta") return true;
|
|
6458
|
+
if (event.type !== "message_update") return false;
|
|
6459
|
+
const assistantEvent = isRecord7(event.assistantMessageEvent) ? event.assistantMessageEvent : null;
|
|
6460
|
+
return assistantEvent?.type === "thinking_delta";
|
|
6461
|
+
}
|
|
6462
|
+
function toolEventAction(event) {
|
|
6463
|
+
if (event.type !== "clio_tool_start" && event.type !== "clio_tool_finish") return null;
|
|
6464
|
+
const payload = isRecord7(event.payload) ? event.payload : null;
|
|
6465
|
+
const tool = nonEmptyString(payload?.tool);
|
|
6466
|
+
if (tool === void 0) return null;
|
|
6467
|
+
const toolCallId = nonEmptyString(payload?.toolCallId);
|
|
6468
|
+
const raw = isRecord7(payload?.action) ? payload.action : void 0;
|
|
6469
|
+
const verb = nonEmptyString(raw?.verb);
|
|
6470
|
+
if (verb === void 0) return { tool, ...toolCallId !== void 0 ? { toolCallId } : {} };
|
|
6471
|
+
const object = nonEmptyString(raw?.object);
|
|
6472
|
+
return {
|
|
6473
|
+
tool,
|
|
6474
|
+
...toolCallId !== void 0 ? { toolCallId } : {},
|
|
6475
|
+
descriptor: {
|
|
6476
|
+
verb,
|
|
6477
|
+
...object !== void 0 ? { object } : {},
|
|
6478
|
+
...raw?.truncated === true ? { truncated: true } : {}
|
|
6479
|
+
}
|
|
6480
|
+
};
|
|
6481
|
+
}
|
|
6482
|
+
function lineCount2(text) {
|
|
6483
|
+
if (text.length === 0) return 0;
|
|
6484
|
+
let lines = 1;
|
|
6485
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
6486
|
+
if (text[index] === "\n") lines += 1;
|
|
6487
|
+
}
|
|
6488
|
+
return lines;
|
|
6489
|
+
}
|
|
6490
|
+
function keepTailBytes(text, maxBytes) {
|
|
6491
|
+
const buffer = Buffer.from(text, "utf8");
|
|
6492
|
+
if (buffer.byteLength <= maxBytes) return text;
|
|
6493
|
+
let cut = buffer.byteLength - maxBytes;
|
|
6494
|
+
while (cut < buffer.byteLength) {
|
|
6495
|
+
const byte = buffer[cut];
|
|
6496
|
+
if (byte === void 0 || (byte & 192) !== 128) break;
|
|
6497
|
+
cut += 1;
|
|
6498
|
+
}
|
|
6499
|
+
return buffer.subarray(cut).toString("utf8");
|
|
6500
|
+
}
|
|
6501
|
+
function boundLiveTail(text) {
|
|
6502
|
+
const lines = text.split("\n");
|
|
6503
|
+
let droppedLines = 0;
|
|
6504
|
+
if (lines.length > WORKER_LIVE_TAIL_LINES) {
|
|
6505
|
+
droppedLines = lines.length - WORKER_LIVE_TAIL_LINES;
|
|
6506
|
+
lines.splice(0, droppedLines);
|
|
6507
|
+
}
|
|
6508
|
+
while (lines.length > 1 && Buffer.byteLength(lines.join("\n"), "utf8") > WORKER_LIVE_TAIL_MAX_BYTES) {
|
|
6509
|
+
lines.shift();
|
|
6510
|
+
droppedLines += 1;
|
|
6511
|
+
}
|
|
6512
|
+
const joined = lines.join("\n");
|
|
6513
|
+
const bytes = Buffer.byteLength(joined, "utf8");
|
|
6514
|
+
if (bytes <= WORKER_LIVE_TAIL_MAX_BYTES) return { text: joined, droppedLines, droppedBytes: 0 };
|
|
6515
|
+
const kept = keepTailBytes(joined, WORKER_LIVE_TAIL_MAX_BYTES);
|
|
6516
|
+
return { text: kept, droppedLines, droppedBytes: bytes - Buffer.byteLength(kept, "utf8") };
|
|
6517
|
+
}
|
|
6518
|
+
function boundSettledText(text) {
|
|
6519
|
+
const bounded = truncateUtf8(text, WORKER_OUTPUT_MAX_BYTES, TAIL_TRUNCATION_MARKER);
|
|
6520
|
+
if (bounded === text) return { text, dropped: 0 };
|
|
6521
|
+
return { text: bounded, dropped: Math.max(0, lineCount2(text) - lineCount2(bounded)) };
|
|
6522
|
+
}
|
|
6523
|
+
var EMPTY_SNAPSHOT = {
|
|
6524
|
+
revision: 0,
|
|
6525
|
+
phase: "starting",
|
|
6526
|
+
tailText: "",
|
|
6527
|
+
droppedLines: 0,
|
|
6528
|
+
droppedBytes: 0,
|
|
6529
|
+
currentAction: null,
|
|
6530
|
+
recentActions: [],
|
|
6531
|
+
toolNames: [],
|
|
6532
|
+
settled: false
|
|
6533
|
+
};
|
|
6534
|
+
function createWorkerProgressFold() {
|
|
6535
|
+
let revision = 0;
|
|
6536
|
+
let phase = "starting";
|
|
6537
|
+
let tailText = "";
|
|
6538
|
+
let droppedLines = 0;
|
|
6539
|
+
let droppedBytes = 0;
|
|
6540
|
+
let currentAction = null;
|
|
6541
|
+
const recentActions = [];
|
|
6542
|
+
const toolNames = [];
|
|
6543
|
+
let settled = false;
|
|
6544
|
+
let durable = "";
|
|
6545
|
+
const pendingActions = [];
|
|
6546
|
+
const pendingActionsById = /* @__PURE__ */ new Map();
|
|
6547
|
+
let windowStartMs = 0;
|
|
6548
|
+
let windowBytes = 0;
|
|
6549
|
+
let cached = EMPTY_SNAPSHOT;
|
|
6550
|
+
const touch = () => {
|
|
6551
|
+
revision += 1;
|
|
6552
|
+
cached = null;
|
|
6553
|
+
return true;
|
|
6554
|
+
};
|
|
6555
|
+
const setPhase = (next) => {
|
|
6556
|
+
if (phase === next) return false;
|
|
6557
|
+
phase = next;
|
|
6558
|
+
return touch();
|
|
6559
|
+
};
|
|
6560
|
+
const admitDelta = (delta, nowMs) => {
|
|
6561
|
+
if (nowMs - windowStartMs >= WORKER_PROGRESS_WINDOW_MS) {
|
|
6562
|
+
windowStartMs = nowMs;
|
|
6563
|
+
windowBytes = 0;
|
|
6564
|
+
}
|
|
6565
|
+
const bytes = Buffer.byteLength(delta, "utf8");
|
|
6566
|
+
if (windowBytes + bytes <= WORKER_PROGRESS_WINDOW_BYTES) {
|
|
6567
|
+
windowBytes += bytes;
|
|
6568
|
+
return delta;
|
|
6569
|
+
}
|
|
6570
|
+
windowBytes = WORKER_PROGRESS_WINDOW_BYTES;
|
|
6571
|
+
droppedBytes += bytes;
|
|
6572
|
+
return "";
|
|
6573
|
+
};
|
|
6574
|
+
const appendTail = (text) => {
|
|
6575
|
+
if (text.length === 0) return false;
|
|
6576
|
+
const bounded = boundLiveTail(tailText + text);
|
|
6577
|
+
tailText = bounded.text;
|
|
6578
|
+
droppedLines += bounded.droppedLines;
|
|
6579
|
+
droppedBytes += bounded.droppedBytes;
|
|
6580
|
+
return touch();
|
|
6581
|
+
};
|
|
6582
|
+
const noteToolName = (tool) => {
|
|
6583
|
+
if (toolNames.includes(tool) || toolNames.length >= WORKER_TOOL_NAME_LIMIT) return false;
|
|
6584
|
+
toolNames.push(tool);
|
|
6585
|
+
return touch();
|
|
6586
|
+
};
|
|
6587
|
+
const removePendingAction = (action) => {
|
|
6588
|
+
const index = pendingActions.lastIndexOf(action);
|
|
6589
|
+
if (index >= 0) pendingActions.splice(index, 1);
|
|
6590
|
+
if (action.toolCallId !== void 0 && pendingActionsById.get(action.toolCallId) === action) {
|
|
6591
|
+
pendingActionsById.delete(action.toolCallId);
|
|
6592
|
+
}
|
|
6593
|
+
};
|
|
6594
|
+
const lastPendingActionForTool = (tool) => {
|
|
6595
|
+
for (let index = pendingActions.length - 1; index >= 0; index -= 1) {
|
|
6596
|
+
const candidate = pendingActions[index];
|
|
6597
|
+
if (candidate?.tool === tool) return candidate;
|
|
6598
|
+
}
|
|
6599
|
+
return void 0;
|
|
6600
|
+
};
|
|
6601
|
+
return {
|
|
6602
|
+
observe(event, nowMs = Date.now()) {
|
|
6603
|
+
if (!isRecord7(event) || settled) return false;
|
|
6604
|
+
let changed = false;
|
|
6605
|
+
const delta = workerTextDelta(event);
|
|
6606
|
+
if (delta.length > 0) {
|
|
6607
|
+
changed = appendTail(admitDelta(delta, nowMs)) || changed;
|
|
6608
|
+
changed = setPhase("writing") || changed;
|
|
6609
|
+
} else if (isThinkingEvent(event)) {
|
|
6610
|
+
changed = setPhase("thinking") || changed;
|
|
6611
|
+
}
|
|
6612
|
+
const durableText = durableAssistantTextFromEvent(event);
|
|
6613
|
+
if (durableText.trim().length > 0) {
|
|
6614
|
+
durable = durableText;
|
|
6615
|
+
if (delta.length === 0 && tailText.trim().length === 0) {
|
|
6616
|
+
changed = appendTail(durableText) || changed;
|
|
6617
|
+
}
|
|
6618
|
+
}
|
|
6619
|
+
const action = toolEventAction(event);
|
|
6620
|
+
if (action !== null && event.type === "clio_tool_start") {
|
|
6621
|
+
if (action.toolCallId !== void 0) {
|
|
6622
|
+
const duplicate = pendingActionsById.get(action.toolCallId);
|
|
6623
|
+
if (duplicate !== void 0) removePendingAction(duplicate);
|
|
6624
|
+
pendingActionsById.set(action.toolCallId, action);
|
|
6625
|
+
}
|
|
6626
|
+
pendingActions.push(action);
|
|
6627
|
+
currentAction = action;
|
|
6628
|
+
noteToolName(action.tool);
|
|
6629
|
+
touch();
|
|
6630
|
+
setPhase("tool");
|
|
6631
|
+
changed = true;
|
|
6632
|
+
} else if (action !== null && event.type === "clio_tool_finish") {
|
|
6633
|
+
const finished = (action.toolCallId !== void 0 ? pendingActionsById.get(action.toolCallId) : void 0) ?? lastPendingActionForTool(action.tool) ?? action;
|
|
6634
|
+
removePendingAction(finished);
|
|
6635
|
+
currentAction = pendingActions[pendingActions.length - 1] ?? null;
|
|
6636
|
+
recentActions.unshift(finished);
|
|
6637
|
+
if (recentActions.length > WORKER_ACTION_TRAIL_LIMIT) recentActions.length = WORKER_ACTION_TRAIL_LIMIT;
|
|
6638
|
+
noteToolName(finished.tool);
|
|
6639
|
+
touch();
|
|
6640
|
+
setPhase(currentAction === null ? "waiting" : "tool");
|
|
6641
|
+
changed = true;
|
|
6642
|
+
}
|
|
6643
|
+
if (event.type === "agent_start") changed = setPhase("starting") || changed;
|
|
6644
|
+
return changed;
|
|
6645
|
+
},
|
|
6646
|
+
settle(text) {
|
|
6647
|
+
const sealed = nonEmptyString(text) ?? nonEmptyString(durable);
|
|
6648
|
+
if (sealed !== void 0) {
|
|
6649
|
+
const bounded = boundSettledText(sealed);
|
|
6650
|
+
tailText = bounded.text;
|
|
6651
|
+
droppedLines = bounded.dropped;
|
|
6652
|
+
}
|
|
6653
|
+
currentAction = null;
|
|
6654
|
+
pendingActions.length = 0;
|
|
6655
|
+
pendingActionsById.clear();
|
|
6656
|
+
settled = true;
|
|
6657
|
+
phase = "settled";
|
|
6658
|
+
touch();
|
|
6659
|
+
return true;
|
|
6660
|
+
},
|
|
6661
|
+
restart() {
|
|
6662
|
+
currentAction = null;
|
|
6663
|
+
pendingActions.length = 0;
|
|
6664
|
+
pendingActionsById.clear();
|
|
6665
|
+
durable = "";
|
|
6666
|
+
settled = false;
|
|
6667
|
+
phase = "starting";
|
|
6668
|
+
touch();
|
|
6669
|
+
},
|
|
6670
|
+
snapshot() {
|
|
6671
|
+
if (cached !== null) return cached;
|
|
6672
|
+
cached = {
|
|
6673
|
+
revision,
|
|
6674
|
+
phase,
|
|
6675
|
+
tailText,
|
|
6676
|
+
droppedLines,
|
|
6677
|
+
droppedBytes,
|
|
6678
|
+
currentAction: currentAction === null ? null : { ...currentAction },
|
|
6679
|
+
recentActions: recentActions.map((entry) => ({ ...entry })),
|
|
6680
|
+
toolNames: [...toolNames],
|
|
6681
|
+
settled
|
|
6682
|
+
};
|
|
6683
|
+
return cached;
|
|
6684
|
+
},
|
|
6685
|
+
durableText() {
|
|
6686
|
+
return durable;
|
|
6687
|
+
}
|
|
6688
|
+
};
|
|
6689
|
+
}
|
|
6690
|
+
|
|
6502
6691
|
// src/interactive/dispatch-board.ts
|
|
6503
6692
|
function isDispatchBoardRowSteerable(row2) {
|
|
6504
6693
|
return runKindSupportsLiveSteering(row2.runtimeKind) && (row2.status === "running" || row2.status === "stale" || row2.status === "enqueued");
|
|
@@ -6506,8 +6695,8 @@ function isDispatchBoardRowSteerable(row2) {
|
|
|
6506
6695
|
function isDispatchBoardRowCancellable(row2) {
|
|
6507
6696
|
return row2.status === "running" || row2.status === "stale" || row2.status === "enqueued" || row2.status === "retrying";
|
|
6508
6697
|
}
|
|
6509
|
-
var RECENT_TOOL_TRAIL_LIMIT = 4;
|
|
6510
6698
|
var TASK_SUMMARY_MAX_WIDTH = 240;
|
|
6699
|
+
var WORKER_PROGRESS_CARD_ROWS = 6;
|
|
6511
6700
|
var TASK_ISLAND_WIDTH = 44;
|
|
6512
6701
|
var STATUS_ORDER = {
|
|
6513
6702
|
running: 0,
|
|
@@ -6632,6 +6821,61 @@ function retryCountdown(retry, now = Date.now()) {
|
|
|
6632
6821
|
const remainingMs = Math.max(0, retry.dueAtMs - now);
|
|
6633
6822
|
return remainingMs === 0 ? "now" : `in ${formatCompactMs(remainingMs)}`;
|
|
6634
6823
|
}
|
|
6824
|
+
function actionPhrase(action) {
|
|
6825
|
+
const descriptor = action.descriptor;
|
|
6826
|
+
if (descriptor === void 0) return action.tool;
|
|
6827
|
+
const object = descriptor.object === void 0 ? "" : ` ${descriptor.object}${descriptor.truncated ? "\u2026" : ""}`;
|
|
6828
|
+
return `${action.tool} ${descriptor.verb}${object}`;
|
|
6829
|
+
}
|
|
6830
|
+
function progressPhaseUnit(theme6, progress) {
|
|
6831
|
+
switch (progress.phase) {
|
|
6832
|
+
case "thinking":
|
|
6833
|
+
return theme6.fg("reason", `${GLYPH.phaseThinking} thinking`);
|
|
6834
|
+
case "writing":
|
|
6835
|
+
return theme6.fg("accent", `${GLYPH.phaseWriting} writing`);
|
|
6836
|
+
case "tool":
|
|
6837
|
+
return theme6.fg("action", `${GLYPH.phaseTool} tool`);
|
|
6838
|
+
case "waiting":
|
|
6839
|
+
return theme6.fg("info", `${GLYPH.phaseWaiting} waiting`);
|
|
6840
|
+
case "settled":
|
|
6841
|
+
case "starting":
|
|
6842
|
+
return null;
|
|
6843
|
+
}
|
|
6844
|
+
}
|
|
6845
|
+
function progressActionLine(theme6, progress, contentWidth) {
|
|
6846
|
+
const phase = progressPhaseUnit(theme6, progress);
|
|
6847
|
+
const current = progress.currentAction;
|
|
6848
|
+
const recent = progress.recentActions[0];
|
|
6849
|
+
const units = [];
|
|
6850
|
+
if (phase !== null) units.push(phase);
|
|
6851
|
+
if (current !== null) units.push(theme6.fg("muted", actionPhrase(current)));
|
|
6852
|
+
else if (recent !== void 0) units.push(theme6.fg("dim", `last ${actionPhrase(recent)}`));
|
|
6853
|
+
if (units.length === 0) return null;
|
|
6854
|
+
return cardUnitsLine(theme6, "doing", units, contentWidth);
|
|
6855
|
+
}
|
|
6856
|
+
function progressAnswerLines(theme6, progress, runId, contentWidth) {
|
|
6857
|
+
if (progress.tailText.length === 0) return [];
|
|
6858
|
+
const gutter = CARD_KV_KEY_WIDTH + 1;
|
|
6859
|
+
const railWidth = Math.max(1, contentWidth - gutter - 2);
|
|
6860
|
+
const wrapped = [];
|
|
6861
|
+
for (const line of progress.tailText.split("\n")) {
|
|
6862
|
+
for (const row2 of wrapTextWithAnsi(sanitizeCallTargetText(line), railWidth)) wrapped.push(row2);
|
|
6863
|
+
}
|
|
6864
|
+
const shown = wrapped.slice(Math.max(0, wrapped.length - WORKER_PROGRESS_CARD_ROWS));
|
|
6865
|
+
const hiddenRows = wrapped.length - shown.length;
|
|
6866
|
+
const rail = theme6.fg("dim", `${GLYPH.rail} `);
|
|
6867
|
+
const body = shown.map((row2) => `${rail}${theme6.fg("muted", row2)}`);
|
|
6868
|
+
const hiddenLines = progress.droppedLines + hiddenRows;
|
|
6869
|
+
if (hiddenLines > 0 || progress.droppedBytes > 0) {
|
|
6870
|
+
const facts = [
|
|
6871
|
+
...hiddenLines > 0 ? [`${hiddenLines} more line${hiddenLines === 1 ? "" : "s"}`] : [],
|
|
6872
|
+
...progress.droppedBytes > 0 ? [`${progress.droppedBytes} bytes outran the view`] : [],
|
|
6873
|
+
`/view dispatch:${runId}`
|
|
6874
|
+
];
|
|
6875
|
+
body.push(`${rail}${theme6.fg("dim", truncateToWidth(facts.join(" \xB7 "), railWidth, "\u2026", false))}`);
|
|
6876
|
+
}
|
|
6877
|
+
return body.map((row2, index) => `${index === 0 ? cardKvKey(theme6, "answer") : " ".repeat(gutter)}${row2}`);
|
|
6878
|
+
}
|
|
6635
6879
|
function renderDispatchCard(row2, width, evidence, options = {}) {
|
|
6636
6880
|
const theme6 = clioTheme();
|
|
6637
6881
|
const contentWidth = Math.max(0, width - 4);
|
|
@@ -6675,6 +6919,20 @@ function renderDispatchCard(row2, width, evidence, options = {}) {
|
|
|
6675
6919
|
targetLine,
|
|
6676
6920
|
...row2.taskSummary ? [truncateToWidth(`${cardKvKey(theme6, "task")}${theme6.fg("muted", row2.taskSummary)}`, contentWidth, "\u2026", false)] : [],
|
|
6677
6921
|
cardUnitsLine(theme6, "status", statusUnits, contentWidth),
|
|
6922
|
+
...row2.budget !== void 0 ? [
|
|
6923
|
+
truncateToWidth(
|
|
6924
|
+
`${cardKvKey(theme6, "policy")}${theme6.fg("muted", `${formatBudgetPolicy(row2.budget)}; requested ${formatBudgetRequest(row2.budget)}`)}`,
|
|
6925
|
+
contentWidth,
|
|
6926
|
+
"\u2026",
|
|
6927
|
+
false
|
|
6928
|
+
),
|
|
6929
|
+
truncateToWidth(
|
|
6930
|
+
`${cardKvKey(theme6, "budget")}${theme6.fg("muted", `${formatEffectiveBudget(row2.budget)}; reason ${formatBudgetReasons(row2.budget)}`)}`,
|
|
6931
|
+
contentWidth,
|
|
6932
|
+
"\u2026",
|
|
6933
|
+
false
|
|
6934
|
+
)
|
|
6935
|
+
] : [],
|
|
6678
6936
|
cardUnitsLine(theme6, "telemetry", [up, down, total, ...contextUnit !== null ? [contextUnit] : []], contentWidth)
|
|
6679
6937
|
];
|
|
6680
6938
|
if (row2.retry) {
|
|
@@ -6700,6 +6958,11 @@ function renderDispatchCard(row2, width, evidence, options = {}) {
|
|
|
6700
6958
|
];
|
|
6701
6959
|
bodyLines2.push(cardUnitsLine(theme6, "tools", toolUnits, contentWidth));
|
|
6702
6960
|
}
|
|
6961
|
+
if (options.expanded === true && row2.progress) {
|
|
6962
|
+
const doing = progressActionLine(theme6, row2.progress, contentWidth);
|
|
6963
|
+
if (doing !== null) bodyLines2.push(doing);
|
|
6964
|
+
bodyLines2.push(...progressAnswerLines(theme6, row2.progress, row2.runId, contentWidth));
|
|
6965
|
+
}
|
|
6703
6966
|
if (row2.steerAcknowledgement) {
|
|
6704
6967
|
bodyLines2.push(
|
|
6705
6968
|
cardUnitsLine(
|
|
@@ -6745,7 +7008,7 @@ function renderTaskIslandRow(row2, width) {
|
|
|
6745
7008
|
const task = row2.taskSummary ? ` ${theme6.fg("muted", truncateToWidth(row2.taskSummary, Math.max(1, width - 2), "\u2026", false))}` : null;
|
|
6746
7009
|
return [padAnsi(line1, width), ...task ? [padAnsi(task, width)] : [], padAnsi(telemetry, width)];
|
|
6747
7010
|
}
|
|
6748
|
-
function formatDispatchBoardLines(rows, width = 76, observability, selectedRunId) {
|
|
7011
|
+
function formatDispatchBoardLines(rows, width = 76, observability, selectedRunId, detailExpanded = false) {
|
|
6749
7012
|
if (rows.length === 0) {
|
|
6750
7013
|
const theme6 = clioTheme();
|
|
6751
7014
|
const lines = ["", "No fleet runs yet", "Delegated runs appear here with task, status, and telemetry.", ""];
|
|
@@ -6756,7 +7019,8 @@ function formatDispatchBoardLines(rows, width = 76, observability, selectedRunId
|
|
|
6756
7019
|
}
|
|
6757
7020
|
const cards = rows.map(
|
|
6758
7021
|
(row2) => renderDispatchCard(row2, width, deriveRunEvidenceState(observability, row2.runId), {
|
|
6759
|
-
selected: row2.runId === selectedRunId
|
|
7022
|
+
selected: row2.runId === selectedRunId,
|
|
7023
|
+
expanded: detailExpanded && row2.runId === selectedRunId
|
|
6760
7024
|
})
|
|
6761
7025
|
);
|
|
6762
7026
|
const body = [];
|
|
@@ -6768,6 +7032,7 @@ function formatDispatchBoardLines(rows, width = 76, observability, selectedRunId
|
|
|
6768
7032
|
}
|
|
6769
7033
|
function createDispatchBoardView(rows, observability) {
|
|
6770
7034
|
let selectedRunId = null;
|
|
7035
|
+
let expanded = false;
|
|
6771
7036
|
const normalizeSelection = (currentRows) => {
|
|
6772
7037
|
if (currentRows.length === 0) {
|
|
6773
7038
|
selectedRunId = null;
|
|
@@ -6789,7 +7054,7 @@ function createDispatchBoardView(rows, observability) {
|
|
|
6789
7054
|
render(width) {
|
|
6790
7055
|
const currentRows = rows();
|
|
6791
7056
|
normalizeSelection(currentRows);
|
|
6792
|
-
return formatDispatchBoardLines(currentRows, Math.max(1, width), observability(), selectedRunId);
|
|
7057
|
+
return formatDispatchBoardLines(currentRows, Math.max(1, width), observability(), selectedRunId, expanded);
|
|
6793
7058
|
},
|
|
6794
7059
|
selectedRow() {
|
|
6795
7060
|
return normalizeSelection(rows());
|
|
@@ -6802,8 +7067,15 @@ function createDispatchBoardView(rows, observability) {
|
|
|
6802
7067
|
},
|
|
6803
7068
|
resetSelection() {
|
|
6804
7069
|
selectedRunId = null;
|
|
7070
|
+
expanded = false;
|
|
6805
7071
|
normalizeSelection(rows());
|
|
6806
7072
|
},
|
|
7073
|
+
toggleDetail() {
|
|
7074
|
+
expanded = !expanded;
|
|
7075
|
+
},
|
|
7076
|
+
detailExpanded() {
|
|
7077
|
+
return expanded;
|
|
7078
|
+
},
|
|
6807
7079
|
invalidate() {
|
|
6808
7080
|
}
|
|
6809
7081
|
};
|
|
@@ -6948,13 +7220,15 @@ function readRunningSnapshot(snapshot) {
|
|
|
6948
7220
|
for (const value of snapshot.running) {
|
|
6949
7221
|
const runId = parseRunId(value.runId);
|
|
6950
7222
|
if (!runId) continue;
|
|
7223
|
+
const budget = cloneRunToolBudgetEnvelope(value.budget);
|
|
6951
7224
|
running.set(runId, {
|
|
6952
7225
|
inputTokens: parseFiniteNumberOrZero(value.tokens.input),
|
|
6953
7226
|
outputTokens: parseFiniteNumberOrZero(value.tokens.output),
|
|
6954
7227
|
tokenCount: parseFiniteNumberOrZero(value.tokens.total),
|
|
6955
7228
|
costUsd: parseFiniteNumberOrZero(value.costUsd),
|
|
6956
7229
|
costProvenance: value.costProvenance ?? "unknown",
|
|
6957
|
-
outcomePhase: value.outcomePhase
|
|
7230
|
+
outcomePhase: value.outcomePhase,
|
|
7231
|
+
...budget !== void 0 ? { budget } : {}
|
|
6958
7232
|
});
|
|
6959
7233
|
}
|
|
6960
7234
|
} catch {
|
|
@@ -6969,7 +7243,9 @@ function resolveElapsedMs(entry, now) {
|
|
|
6969
7243
|
}
|
|
6970
7244
|
function toRow(entry, now) {
|
|
6971
7245
|
const retry = entry.retry;
|
|
7246
|
+
const progress = entry.progress.snapshot();
|
|
6972
7247
|
return {
|
|
7248
|
+
progress,
|
|
6973
7249
|
runId: entry.runId,
|
|
6974
7250
|
agentId: entry.agentId,
|
|
6975
7251
|
...entry.agentAudience !== void 0 ? { agentAudience: entry.agentAudience } : {},
|
|
@@ -6979,6 +7255,7 @@ function toRow(entry, now) {
|
|
|
6979
7255
|
targetId: entry.targetId,
|
|
6980
7256
|
wireModelId: entry.wireModelId,
|
|
6981
7257
|
...entry.taskSummary !== void 0 ? { taskSummary: entry.taskSummary } : {},
|
|
7258
|
+
...entry.budget !== void 0 ? { budget: entry.budget } : {},
|
|
6982
7259
|
status: retry ? "retrying" : entry.status,
|
|
6983
7260
|
elapsedMs: resolveElapsedMs(entry, now),
|
|
6984
7261
|
tokenCount: entry.tokenCount,
|
|
@@ -6995,8 +7272,10 @@ function toRow(entry, now) {
|
|
|
6995
7272
|
...entry.contextWindow !== void 0 ? { contextWindow: entry.contextWindow } : {},
|
|
6996
7273
|
lastContextTokens: entry.lastContextTokens,
|
|
6997
7274
|
...entry.receiptId !== void 0 ? { receiptId: entry.receiptId } : {},
|
|
6998
|
-
|
|
6999
|
-
|
|
7275
|
+
// Both tool fields are views of the one projection, so the compact card and
|
|
7276
|
+
// the expanded detail can never disagree about what is running.
|
|
7277
|
+
currentTool: retry ? null : progress.currentAction?.tool ?? null,
|
|
7278
|
+
recentTools: progress.recentActions.map((action) => action.tool),
|
|
7000
7279
|
...retry ? { retry: { ...retry } } : {},
|
|
7001
7280
|
...entry.steerAcknowledgement ? { steerAcknowledgement: { ...entry.steerAcknowledgement } } : {}
|
|
7002
7281
|
};
|
|
@@ -7020,10 +7299,14 @@ function pruneEntries(entries) {
|
|
|
7020
7299
|
entries.delete(entry.runId);
|
|
7021
7300
|
}
|
|
7022
7301
|
}
|
|
7023
|
-
function createDispatchBoardStore(bus, snapshot) {
|
|
7302
|
+
function createDispatchBoardStore(bus, snapshot, readReceipt) {
|
|
7024
7303
|
const entries = /* @__PURE__ */ new Map();
|
|
7025
7304
|
let nextSequence = 0;
|
|
7026
7305
|
let reconciledAtMs = Date.now();
|
|
7306
|
+
const settleFromReceipt = (entry) => {
|
|
7307
|
+
const text = readReceipt?.(entry.runId)?.text;
|
|
7308
|
+
entry.progress.settle(typeof text === "string" && text.trim().length > 0 ? text : void 0);
|
|
7309
|
+
};
|
|
7027
7310
|
const upsertBase = (raw, status, now) => {
|
|
7028
7311
|
const runId = parseRunId(raw.runId);
|
|
7029
7312
|
if (!runId) return null;
|
|
@@ -7035,6 +7318,7 @@ function createDispatchBoardStore(bus, snapshot) {
|
|
|
7035
7318
|
const rerouteCount = parsePositiveInt(raw.rerouteCount) ?? previous?.rerouteCount;
|
|
7036
7319
|
const contextWindow = parsePositiveInt(raw.contextWindow) ?? previous?.contextWindow;
|
|
7037
7320
|
const taskSummary = parseTaskSummary(raw, previous?.taskSummary);
|
|
7321
|
+
const budget = cloneRunToolBudgetEnvelope(raw.budget) ?? previous?.budget;
|
|
7038
7322
|
const entry = {
|
|
7039
7323
|
runId,
|
|
7040
7324
|
agentId: parseText(raw.agentId, previous?.agentId ?? "-"),
|
|
@@ -7045,6 +7329,7 @@ function createDispatchBoardStore(bus, snapshot) {
|
|
|
7045
7329
|
targetId: parseText(raw.targetId, previous?.targetId ?? "-"),
|
|
7046
7330
|
wireModelId: parseText(raw.wireModelId, previous?.wireModelId ?? "-"),
|
|
7047
7331
|
...taskSummary !== void 0 ? { taskSummary } : {},
|
|
7332
|
+
...budget !== void 0 ? { budget } : {},
|
|
7048
7333
|
status,
|
|
7049
7334
|
tokenCount: previous?.tokenCount ?? 0,
|
|
7050
7335
|
costUsd: previous?.costUsd ?? 0,
|
|
@@ -7065,8 +7350,7 @@ function createDispatchBoardStore(bus, snapshot) {
|
|
|
7065
7350
|
...contextWindow !== void 0 ? { contextWindow } : {},
|
|
7066
7351
|
lastContextTokens: previous?.lastContextTokens ?? 0,
|
|
7067
7352
|
...previous?.receiptId !== void 0 ? { receiptId: previous.receiptId } : {},
|
|
7068
|
-
|
|
7069
|
-
recentTools: previous?.recentTools ?? [],
|
|
7353
|
+
progress: previous?.progress ?? createWorkerProgressFold(),
|
|
7070
7354
|
...previous?.retry ? { retry: { ...previous.retry } } : {},
|
|
7071
7355
|
...previous?.steerAcknowledgement ? { steerAcknowledgement: { ...previous.steerAcknowledgement } } : {}
|
|
7072
7356
|
};
|
|
@@ -7101,7 +7385,7 @@ function createDispatchBoardStore(bus, snapshot) {
|
|
|
7101
7385
|
entry.costUsd = parseFiniteNumber(payload.costUsd, entry.costUsd);
|
|
7102
7386
|
entry.costProvenance = payload.costProvenance ?? "unknown";
|
|
7103
7387
|
entry.outcomeDetail = null;
|
|
7104
|
-
entry
|
|
7388
|
+
settleFromReceipt(entry);
|
|
7105
7389
|
entry.receiptId = entry.runId;
|
|
7106
7390
|
delete entry.retry;
|
|
7107
7391
|
if (typeof payload.inputTokenCount === "number") {
|
|
@@ -7127,7 +7411,7 @@ function createDispatchBoardStore(bus, snapshot) {
|
|
|
7127
7411
|
entry.costUsd = parseFiniteNumber(payload.costUsd, entry.costUsd);
|
|
7128
7412
|
entry.costProvenance = payload.costProvenance ?? "unknown";
|
|
7129
7413
|
entry.outcomeDetail = resolveFailureDetail(payload, entry.outcomeDetail);
|
|
7130
|
-
entry
|
|
7414
|
+
settleFromReceipt(entry);
|
|
7131
7415
|
if (payload.reason !== "retry_denied") entry.receiptId = entry.runId;
|
|
7132
7416
|
delete entry.retry;
|
|
7133
7417
|
if (typeof payload.inputTokenCount === "number") {
|
|
@@ -7147,7 +7431,7 @@ function createDispatchBoardStore(bus, snapshot) {
|
|
|
7147
7431
|
if (wasRetrying && raw?.startedAt === null) {
|
|
7148
7432
|
entry.status = "aborted";
|
|
7149
7433
|
entry.finishedAtMs = Date.now();
|
|
7150
|
-
entry.
|
|
7434
|
+
entry.progress.settle();
|
|
7151
7435
|
} else {
|
|
7152
7436
|
if (isTerminalStatus(entry.status) && !wasRetrying) return;
|
|
7153
7437
|
entry.status = "cancelling";
|
|
@@ -7169,7 +7453,7 @@ function createDispatchBoardStore(bus, snapshot) {
|
|
|
7169
7453
|
entry.status = status;
|
|
7170
7454
|
if (status === "dead") {
|
|
7171
7455
|
entry.finishedAtMs ??= Date.now();
|
|
7172
|
-
entry.
|
|
7456
|
+
entry.progress.settle();
|
|
7173
7457
|
delete entry.retry;
|
|
7174
7458
|
}
|
|
7175
7459
|
return;
|
|
@@ -7178,7 +7462,7 @@ function createDispatchBoardStore(bus, snapshot) {
|
|
|
7178
7462
|
entry.failoverHops = (entry.failoverHops ?? 0) + 1;
|
|
7179
7463
|
entry.status = "running";
|
|
7180
7464
|
entry.finishedAtMs = null;
|
|
7181
|
-
entry.
|
|
7465
|
+
entry.progress.restart();
|
|
7182
7466
|
delete entry.retry;
|
|
7183
7467
|
return;
|
|
7184
7468
|
}
|
|
@@ -7193,20 +7477,7 @@ function createDispatchBoardStore(bus, snapshot) {
|
|
|
7193
7477
|
entry.ttftMs = Math.round(performance3.now() - entry.startedAtClockMs);
|
|
7194
7478
|
}
|
|
7195
7479
|
}
|
|
7196
|
-
|
|
7197
|
-
const payload2 = workerEvent.payload;
|
|
7198
|
-
const tool = parseNonEmptyString(payload2?.tool);
|
|
7199
|
-
if (tool !== void 0) entry.currentTool = tool;
|
|
7200
|
-
}
|
|
7201
|
-
if (type === "clio_tool_finish") {
|
|
7202
|
-
const payload2 = workerEvent.payload;
|
|
7203
|
-
const tool = parseNonEmptyString(payload2?.tool);
|
|
7204
|
-
entry.currentTool = null;
|
|
7205
|
-
if (tool !== void 0) {
|
|
7206
|
-
entry.recentTools.unshift(tool);
|
|
7207
|
-
if (entry.recentTools.length > RECENT_TOOL_TRAIL_LIMIT) entry.recentTools.length = RECENT_TOOL_TRAIL_LIMIT;
|
|
7208
|
-
}
|
|
7209
|
-
}
|
|
7480
|
+
entry.progress.observe(payload.event);
|
|
7210
7481
|
if (type === "clio_steer_received") {
|
|
7211
7482
|
const steerPayload = workerEvent.payload;
|
|
7212
7483
|
entry.steerAcknowledgement = {
|
|
@@ -7229,7 +7500,7 @@ function createDispatchBoardStore(bus, snapshot) {
|
|
|
7229
7500
|
if (!status) return;
|
|
7230
7501
|
entry.status = status;
|
|
7231
7502
|
entry.finishedAtMs ??= Date.now();
|
|
7232
|
-
entry.
|
|
7503
|
+
entry.progress.settle();
|
|
7233
7504
|
delete entry.retry;
|
|
7234
7505
|
}
|
|
7235
7506
|
})
|
|
@@ -7271,7 +7542,6 @@ function createDispatchBoardStore(bus, snapshot) {
|
|
|
7271
7542
|
now
|
|
7272
7543
|
);
|
|
7273
7544
|
if (entry) {
|
|
7274
|
-
entry.currentTool = null;
|
|
7275
7545
|
entry.retry = { ...projection.retry };
|
|
7276
7546
|
if (entry.taskSummary === void 0 && projection.taskSummary !== void 0) {
|
|
7277
7547
|
entry.taskSummary = projection.taskSummary;
|
|
@@ -7287,6 +7557,7 @@ function createDispatchBoardStore(bus, snapshot) {
|
|
|
7287
7557
|
entry.tokenCount = live.tokenCount;
|
|
7288
7558
|
entry.costUsd = live.costUsd;
|
|
7289
7559
|
entry.costProvenance = live.costProvenance;
|
|
7560
|
+
if (live.budget !== void 0) entry.budget = live.budget;
|
|
7290
7561
|
if (live.outcomePhase === "aborting") {
|
|
7291
7562
|
if (entry.status !== "completed" && entry.status !== "aborted") {
|
|
7292
7563
|
entry.status = "cancelling";
|
|
@@ -7351,7 +7622,8 @@ function emptyRunTally() {
|
|
|
7351
7622
|
hadProviderReasoning: false,
|
|
7352
7623
|
hadEstimatedReasoning: false,
|
|
7353
7624
|
toolCount: 0,
|
|
7354
|
-
toolErrorCount: 0
|
|
7625
|
+
toolErrorCount: 0,
|
|
7626
|
+
responseModelIdObservation: { state: "not-observed" }
|
|
7355
7627
|
};
|
|
7356
7628
|
}
|
|
7357
7629
|
function foldMessageIntoRunTally(tally, message) {
|
|
@@ -7364,8 +7636,10 @@ function foldMessageIntoRunTally(tally, message) {
|
|
|
7364
7636
|
}
|
|
7365
7637
|
if (message.role !== "assistant") return tally;
|
|
7366
7638
|
const usage = message.usage;
|
|
7639
|
+
const record2 = message;
|
|
7367
7640
|
const next = {
|
|
7368
7641
|
...tally,
|
|
7642
|
+
responseModelIdObservation: responseModelIdObservationFromRecord(record2, "not-observed"),
|
|
7369
7643
|
inputTokens: tally.inputTokens + (usage ? finite2(usage.input) : 0),
|
|
7370
7644
|
outputTokens: tally.outputTokens + (usage ? finite2(usage.output) : 0),
|
|
7371
7645
|
cacheReadTokens: tally.cacheReadTokens + (usage ? finite2(usage.cacheRead) : 0),
|
|
@@ -7399,7 +7673,8 @@ function summaryFromRunTally(tally, input) {
|
|
|
7399
7673
|
stopReason: input.stopReason,
|
|
7400
7674
|
...input.stopDetail !== void 0 ? { stopDetail: input.stopDetail } : {},
|
|
7401
7675
|
watchdogPeak: input.watchdogPeak,
|
|
7402
|
-
truncated: input.truncated === true
|
|
7676
|
+
truncated: input.truncated === true,
|
|
7677
|
+
responseModelIdObservation: tally.responseModelIdObservation
|
|
7403
7678
|
};
|
|
7404
7679
|
if (tally.hadProviderReasoning || tally.hadEstimatedReasoning) {
|
|
7405
7680
|
summary.reasoningTokens = tally.reasoningTokens;
|
|
@@ -8979,7 +9254,7 @@ var ISO_8601_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{
|
|
|
8979
9254
|
function isIso8601(value) {
|
|
8980
9255
|
return typeof value === "string" && ISO_8601_REGEX.test(value) && !Number.isNaN(Date.parse(value));
|
|
8981
9256
|
}
|
|
8982
|
-
function
|
|
9257
|
+
function isRecord8(value) {
|
|
8983
9258
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
8984
9259
|
}
|
|
8985
9260
|
function isNonEmptyString(value) {
|
|
@@ -9058,7 +9333,7 @@ function readRunLedger(stateDir) {
|
|
|
9058
9333
|
const raw = readFileSync5(runLedgerPath(stateDir), "utf8").trim();
|
|
9059
9334
|
if (raw.length === 0) return [];
|
|
9060
9335
|
const parsed = JSON.parse(raw);
|
|
9061
|
-
return Array.isArray(parsed) ? parsed.filter(
|
|
9336
|
+
return Array.isArray(parsed) ? parsed.filter(isRecord8) : [];
|
|
9062
9337
|
} catch {
|
|
9063
9338
|
return [];
|
|
9064
9339
|
}
|
|
@@ -9080,7 +9355,7 @@ function validateToolStats(value) {
|
|
|
9080
9355
|
}
|
|
9081
9356
|
for (let i = 0; i < value.length; i++) {
|
|
9082
9357
|
const entry = value[i];
|
|
9083
|
-
if (!
|
|
9358
|
+
if (!isRecord8(entry)) {
|
|
9084
9359
|
return { ok: false, reason: `toolStats[${i}] not an object` };
|
|
9085
9360
|
}
|
|
9086
9361
|
if (!isNonEmptyString(entry.tool)) {
|
|
@@ -9120,7 +9395,7 @@ function verifyReceiptFile(stateDir, runId) {
|
|
|
9120
9395
|
} catch (err) {
|
|
9121
9396
|
return { ok: false, reason: `invalid json: ${err.message}` };
|
|
9122
9397
|
}
|
|
9123
|
-
if (!
|
|
9398
|
+
if (!isRecord8(parsed)) {
|
|
9124
9399
|
return { ok: false, reason: "receipt is not an object" };
|
|
9125
9400
|
}
|
|
9126
9401
|
const r = parsed;
|
|
@@ -9466,17 +9741,17 @@ var ReceiptArtifactProvider = class {
|
|
|
9466
9741
|
}
|
|
9467
9742
|
};
|
|
9468
9743
|
function resultText3(result) {
|
|
9469
|
-
if (!
|
|
9744
|
+
if (!isRecord8(result)) return "";
|
|
9470
9745
|
if (result.kind === "ok" && typeof result.output === "string") return result.output;
|
|
9471
9746
|
if (result.kind === "error" && typeof result.message === "string") return result.message;
|
|
9472
9747
|
return "";
|
|
9473
9748
|
}
|
|
9474
9749
|
function resultDetails(result) {
|
|
9475
|
-
return
|
|
9750
|
+
return isRecord8(result) && isRecord8(result.details) ? result.details : null;
|
|
9476
9751
|
}
|
|
9477
9752
|
function messagePayload(entry) {
|
|
9478
9753
|
if (entry.kind !== "message") return null;
|
|
9479
|
-
return
|
|
9754
|
+
return isRecord8(entry.payload) ? entry.payload : null;
|
|
9480
9755
|
}
|
|
9481
9756
|
function toolNameFor(entry) {
|
|
9482
9757
|
const payload = messagePayload(entry);
|
|
@@ -9497,12 +9772,12 @@ function dispatchResultForRun(entries, runId) {
|
|
|
9497
9772
|
for (const entry of entries) {
|
|
9498
9773
|
const payload = messagePayload(entry);
|
|
9499
9774
|
if (!payload) continue;
|
|
9500
|
-
const
|
|
9501
|
-
if (
|
|
9775
|
+
const toolName = typeof payload.toolName === "string" ? payload.toolName : "";
|
|
9776
|
+
if (toolName !== "dispatch") continue;
|
|
9502
9777
|
const details = resultDetails(payload.result);
|
|
9503
9778
|
const detailRunId = details?.runId;
|
|
9504
9779
|
const runIds = details?.runIds;
|
|
9505
|
-
const matches = detailRunId === runId || Array.isArray(runIds) && runIds.some((item) => item === runId) || Array.isArray(details?.runs) && details.runs.some((item) =>
|
|
9780
|
+
const matches = detailRunId === runId || Array.isArray(runIds) && runIds.some((item) => item === runId) || Array.isArray(details?.runs) && details.runs.some((item) => isRecord8(item) && item.runId === runId);
|
|
9506
9781
|
if (!matches) continue;
|
|
9507
9782
|
const text = resultText3(payload.result);
|
|
9508
9783
|
if (text.length > 0) return text;
|
|
@@ -9798,16 +10073,16 @@ var ToolOutputArtifactProvider = class {
|
|
|
9798
10073
|
};
|
|
9799
10074
|
}
|
|
9800
10075
|
toolResultArtifact(entry, path) {
|
|
9801
|
-
const
|
|
10076
|
+
const toolName = toolNameFor(entry);
|
|
9802
10077
|
const artifact = {
|
|
9803
10078
|
id: `tool:${entry.turnId}`,
|
|
9804
10079
|
category: this.category,
|
|
9805
|
-
title: safeTitle(`${
|
|
10080
|
+
title: safeTitle(`${toolName} \xB7 ${basename(path)}`, `${toolName} output`),
|
|
9806
10081
|
timestamp: parseTime(entry.timestamp),
|
|
9807
10082
|
sizeBytes: maybeSizeBytes(path),
|
|
9808
10083
|
path,
|
|
9809
|
-
toolName
|
|
9810
|
-
searchText: [
|
|
10084
|
+
toolName,
|
|
10085
|
+
searchText: [toolName, entry.turnId, path, basename(path)],
|
|
9811
10086
|
load: () => loadTextPath(path)
|
|
9812
10087
|
};
|
|
9813
10088
|
const payload = messagePayload(entry);
|
|
@@ -10179,7 +10454,7 @@ async function listViewArtifacts(providers) {
|
|
|
10179
10454
|
}
|
|
10180
10455
|
|
|
10181
10456
|
// src/interactive/worker-receipts.ts
|
|
10182
|
-
function
|
|
10457
|
+
function isRecord9(value) {
|
|
10183
10458
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10184
10459
|
}
|
|
10185
10460
|
function optionalString(value) {
|
|
@@ -10195,19 +10470,19 @@ function elapsedMsFrom(receipt) {
|
|
|
10195
10470
|
return Math.max(0, endedAt - startedAt);
|
|
10196
10471
|
}
|
|
10197
10472
|
function contractFrom(receipt) {
|
|
10198
|
-
const quality =
|
|
10473
|
+
const quality = isRecord9(receipt.quality) ? receipt.quality : null;
|
|
10199
10474
|
if (quality === null) return void 0;
|
|
10200
10475
|
if (!Object.hasOwn(quality, "resultContract")) return void 0;
|
|
10201
10476
|
const fact = quality.resultContract;
|
|
10202
10477
|
if (fact === null) return "unmeasured";
|
|
10203
|
-
if (!
|
|
10478
|
+
if (!isRecord9(fact)) return void 0;
|
|
10204
10479
|
const conformance = fact.conformance;
|
|
10205
10480
|
return conformance === "pass" || conformance === "fail" || conformance === "not-reached" ? conformance : void 0;
|
|
10206
10481
|
}
|
|
10207
10482
|
function workerReceiptFacts(receipt) {
|
|
10208
10483
|
const outcome = optionalString(receipt.outcome);
|
|
10209
10484
|
if (outcome === void 0) return null;
|
|
10210
|
-
const output =
|
|
10485
|
+
const output = isRecord9(receipt.output) ? receipt.output : null;
|
|
10211
10486
|
const contract = contractFrom(receipt);
|
|
10212
10487
|
const text = optionalString(output?.text);
|
|
10213
10488
|
const failureMessage = optionalString(receipt.failureMessage);
|
|
@@ -10231,7 +10506,7 @@ function workerReceiptFacts(receipt) {
|
|
|
10231
10506
|
function readReceiptFileFacts(runId, stateDir) {
|
|
10232
10507
|
try {
|
|
10233
10508
|
const parsed = JSON.parse(readFileSync6(receiptFilePath(stateDir, runId), "utf8"));
|
|
10234
|
-
return
|
|
10509
|
+
return isRecord9(parsed) ? workerReceiptFacts(parsed) : null;
|
|
10235
10510
|
} catch {
|
|
10236
10511
|
return null;
|
|
10237
10512
|
}
|
|
@@ -10246,7 +10521,7 @@ function findRunRow(runId, stateDir) {
|
|
|
10246
10521
|
const parsed = JSON.parse(readFileSync6(path, "utf8"));
|
|
10247
10522
|
if (!Array.isArray(parsed)) return null;
|
|
10248
10523
|
for (const entry of parsed) {
|
|
10249
|
-
if (
|
|
10524
|
+
if (isRecord9(entry) && entry.id === runId) return entry;
|
|
10250
10525
|
}
|
|
10251
10526
|
return null;
|
|
10252
10527
|
} catch {
|
|
@@ -10275,13 +10550,7 @@ init_esm_shims();
|
|
|
10275
10550
|
function workerAskedByModel(state) {
|
|
10276
10551
|
return state.parentToolCallId !== void 0 || state.origin === "agent";
|
|
10277
10552
|
}
|
|
10278
|
-
|
|
10279
|
-
var WORKER_TOOL_NAME_LIMIT = 8;
|
|
10280
|
-
var WORKER_TEXT_TRUNCATION_MARKER = "";
|
|
10281
|
-
function isRecord9(value) {
|
|
10282
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10283
|
-
}
|
|
10284
|
-
function nonEmptyString(value) {
|
|
10553
|
+
function nonEmptyString2(value) {
|
|
10285
10554
|
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
10286
10555
|
}
|
|
10287
10556
|
function finiteNumber(value) {
|
|
@@ -10296,11 +10565,11 @@ function workerRuntimeKind(runtimeKind, runtimeId) {
|
|
|
10296
10565
|
function runtimeIdentity(payload) {
|
|
10297
10566
|
const kind = workerRuntimeKind(payload.runtimeKind, payload.runtimeId);
|
|
10298
10567
|
if (kind === "acp") {
|
|
10299
|
-
const peerId =
|
|
10568
|
+
const peerId = nonEmptyString2(payload.agentId);
|
|
10300
10569
|
return { kind, ...peerId !== void 0 ? { peerId } : {} };
|
|
10301
10570
|
}
|
|
10302
|
-
const targetId =
|
|
10303
|
-
const wireModelId =
|
|
10571
|
+
const targetId = nonEmptyString2(payload.targetId);
|
|
10572
|
+
const wireModelId = nonEmptyString2(payload.wireModelId);
|
|
10304
10573
|
return {
|
|
10305
10574
|
kind,
|
|
10306
10575
|
...targetId !== void 0 ? { targetId } : {},
|
|
@@ -10314,44 +10583,8 @@ function workerTargetLabel(runtime) {
|
|
|
10314
10583
|
}
|
|
10315
10584
|
return runtime.targetId ?? runtime.wireModelId ?? "unknown";
|
|
10316
10585
|
}
|
|
10317
|
-
function textDelta(event) {
|
|
10318
|
-
if (!isRecord9(event)) return "";
|
|
10319
|
-
if (event.type === "message_update") {
|
|
10320
|
-
const assistantEvent = isRecord9(event.assistantMessageEvent) ? event.assistantMessageEvent : null;
|
|
10321
|
-
if (assistantEvent?.type !== "text_delta") return "";
|
|
10322
|
-
return typeof assistantEvent.delta === "string" ? assistantEvent.delta : "";
|
|
10323
|
-
}
|
|
10324
|
-
if (event.type !== "text_delta") return "";
|
|
10325
|
-
if (typeof event.delta === "string") return event.delta;
|
|
10326
|
-
return typeof event.text === "string" ? event.text : "";
|
|
10327
|
-
}
|
|
10328
|
-
function toolName(event) {
|
|
10329
|
-
if (!isRecord9(event)) return void 0;
|
|
10330
|
-
if (event.type !== "clio_tool_start" && event.type !== "clio_tool_finish") return void 0;
|
|
10331
|
-
const payload = isRecord9(event.payload) ? event.payload : null;
|
|
10332
|
-
return nonEmptyString(payload?.tool);
|
|
10333
|
-
}
|
|
10334
|
-
function lineCount2(text) {
|
|
10335
|
-
if (text.length === 0) return 0;
|
|
10336
|
-
let lines = 1;
|
|
10337
|
-
for (let index = 0; index < text.length; index += 1) {
|
|
10338
|
-
if (text[index] === "\n") lines += 1;
|
|
10339
|
-
}
|
|
10340
|
-
return lines;
|
|
10341
|
-
}
|
|
10342
|
-
function boundLiveText(text) {
|
|
10343
|
-
const lines = text.split("\n");
|
|
10344
|
-
if (lines.length <= WORKER_LIVE_TAIL_LINES) return { text, dropped: 0 };
|
|
10345
|
-
const dropped = lines.length - WORKER_LIVE_TAIL_LINES;
|
|
10346
|
-
return { text: lines.slice(dropped).join("\n"), dropped };
|
|
10347
|
-
}
|
|
10348
|
-
function boundSettledText(text) {
|
|
10349
|
-
const bounded = truncateUtf8(text, WORKER_OUTPUT_MAX_BYTES, WORKER_TEXT_TRUNCATION_MARKER);
|
|
10350
|
-
if (bounded === text) return { text, dropped: 0 };
|
|
10351
|
-
return { text: bounded, dropped: Math.max(0, lineCount2(text) - lineCount2(bounded)) };
|
|
10352
|
-
}
|
|
10353
10586
|
function terminalFacts(payload) {
|
|
10354
|
-
const detail =
|
|
10587
|
+
const detail = nonEmptyString2(payload.outcomeDetail);
|
|
10355
10588
|
const tokenCount = finiteNumber(payload.tokenCount);
|
|
10356
10589
|
const durationMs = finiteNumber(payload.durationMs);
|
|
10357
10590
|
const exitCode = finiteNumber(payload.exitCode);
|
|
@@ -10374,9 +10607,16 @@ function createWorkerStream(options = {}) {
|
|
|
10374
10607
|
const byAssignment = /* @__PURE__ */ new Map();
|
|
10375
10608
|
const attemptByAssignment = /* @__PURE__ */ new Map();
|
|
10376
10609
|
const assignmentByRun = /* @__PURE__ */ new Map();
|
|
10377
|
-
const
|
|
10610
|
+
const progressByAssignment = /* @__PURE__ */ new Map();
|
|
10611
|
+
const applyProgress = (entry, fold) => {
|
|
10612
|
+
const snapshot = fold.snapshot();
|
|
10613
|
+
entry.text = snapshot.tailText;
|
|
10614
|
+
entry.droppedLines = snapshot.droppedLines;
|
|
10615
|
+
entry.tools = [...snapshot.toolNames];
|
|
10616
|
+
entry.progress = snapshot;
|
|
10617
|
+
};
|
|
10378
10618
|
const currentEntryForRun = (runId) => {
|
|
10379
|
-
const id =
|
|
10619
|
+
const id = nonEmptyString2(runId);
|
|
10380
10620
|
if (id === void 0) return void 0;
|
|
10381
10621
|
const assignmentId = assignmentByRun.get(id);
|
|
10382
10622
|
const entry = assignmentId === void 0 ? void 0 : byAssignment.get(assignmentId);
|
|
@@ -10388,18 +10628,17 @@ function createWorkerStream(options = {}) {
|
|
|
10388
10628
|
entry.pending = false;
|
|
10389
10629
|
const attempt = entry.attempts[entry.attempts.length - 1];
|
|
10390
10630
|
if (attempt !== void 0) attempt.outcome = facts.outcome;
|
|
10391
|
-
const
|
|
10392
|
-
if (
|
|
10393
|
-
|
|
10394
|
-
entry
|
|
10395
|
-
entry.droppedLines = bounded.dropped;
|
|
10631
|
+
const fold = progressByAssignment.get(entry.assignmentId);
|
|
10632
|
+
if (fold !== void 0) {
|
|
10633
|
+
fold.settle(nonEmptyString2(facts.text));
|
|
10634
|
+
applyProgress(entry, fold);
|
|
10396
10635
|
}
|
|
10397
10636
|
return { kind: "updated", entry };
|
|
10398
10637
|
};
|
|
10399
10638
|
return {
|
|
10400
10639
|
started(payload) {
|
|
10401
|
-
const runId =
|
|
10402
|
-
const assignmentId =
|
|
10640
|
+
const runId = nonEmptyString2(payload.runId);
|
|
10641
|
+
const assignmentId = nonEmptyString2(payload.assignmentId) ?? runId;
|
|
10403
10642
|
if (runId === void 0 || assignmentId === void 0) return null;
|
|
10404
10643
|
const runtime = runtimeIdentity(payload);
|
|
10405
10644
|
const existing = byAssignment.get(assignmentId);
|
|
@@ -10412,10 +10651,16 @@ function createWorkerStream(options = {}) {
|
|
|
10412
10651
|
delete existing.receipt;
|
|
10413
10652
|
existing.attempts.push({ runId, targetLabel: workerTargetLabel(runtime) });
|
|
10414
10653
|
assignmentByRun.set(runId, assignmentId);
|
|
10654
|
+
const progress2 = progressByAssignment.get(assignmentId);
|
|
10655
|
+
if (progress2 !== void 0) {
|
|
10656
|
+
progress2.restart();
|
|
10657
|
+
applyProgress(existing, progress2);
|
|
10658
|
+
}
|
|
10415
10659
|
return { kind: "updated", entry: existing };
|
|
10416
10660
|
}
|
|
10417
10661
|
if (payload.requestOrigin !== "user" && payload.requestOrigin !== "agent") return null;
|
|
10418
10662
|
attemptByAssignment.set(assignmentId, payload.attempt);
|
|
10663
|
+
const progress = createWorkerProgressFold();
|
|
10419
10664
|
const entry = {
|
|
10420
10665
|
assignmentId,
|
|
10421
10666
|
runId,
|
|
@@ -10425,42 +10670,23 @@ function createWorkerStream(options = {}) {
|
|
|
10425
10670
|
text: "",
|
|
10426
10671
|
droppedLines: 0,
|
|
10427
10672
|
tools: [],
|
|
10673
|
+
progress: progress.snapshot(),
|
|
10428
10674
|
attempts: [{ runId, targetLabel: workerTargetLabel(runtime) }],
|
|
10429
10675
|
pending: true,
|
|
10430
10676
|
...payload.parentToolCallId !== void 0 ? { parentToolCallId: payload.parentToolCallId } : {}
|
|
10431
10677
|
};
|
|
10432
10678
|
byAssignment.set(assignmentId, entry);
|
|
10433
10679
|
assignmentByRun.set(runId, assignmentId);
|
|
10680
|
+
progressByAssignment.set(assignmentId, progress);
|
|
10434
10681
|
return { kind: "created", entry };
|
|
10435
10682
|
},
|
|
10436
10683
|
progress(payload) {
|
|
10437
10684
|
const entry = currentEntryForRun(payload.runId);
|
|
10438
10685
|
if (entry === void 0 || !entry.pending) return null;
|
|
10439
|
-
const
|
|
10440
|
-
|
|
10441
|
-
|
|
10442
|
-
|
|
10443
|
-
const bounded = boundLiveText(entry.text + delta);
|
|
10444
|
-
entry.text = bounded.text;
|
|
10445
|
-
entry.droppedLines += bounded.dropped;
|
|
10446
|
-
changed = true;
|
|
10447
|
-
}
|
|
10448
|
-
const durable = durableAssistantTextFromEvent(event);
|
|
10449
|
-
if (durable.trim().length > 0) {
|
|
10450
|
-
durableTextByRun.set(entry.runId, durable);
|
|
10451
|
-
if (delta.length === 0 && entry.text.trim().length === 0) {
|
|
10452
|
-
const bounded = boundLiveText(durable);
|
|
10453
|
-
entry.text = bounded.text;
|
|
10454
|
-
entry.droppedLines += bounded.dropped;
|
|
10455
|
-
}
|
|
10456
|
-
changed = true;
|
|
10457
|
-
}
|
|
10458
|
-
const tool = toolName(event);
|
|
10459
|
-
if (tool !== void 0 && !entry.tools.includes(tool) && entry.tools.length < WORKER_TOOL_NAME_LIMIT) {
|
|
10460
|
-
entry.tools.push(tool);
|
|
10461
|
-
changed = true;
|
|
10462
|
-
}
|
|
10463
|
-
return changed ? { kind: "updated", entry } : null;
|
|
10686
|
+
const fold = progressByAssignment.get(entry.assignmentId);
|
|
10687
|
+
if (fold === void 0 || !fold.observe(payload.event)) return null;
|
|
10688
|
+
applyProgress(entry, fold);
|
|
10689
|
+
return { kind: "updated", entry };
|
|
10464
10690
|
},
|
|
10465
10691
|
completed(payload) {
|
|
10466
10692
|
const entry = currentEntryForRun(payload.runId);
|
|
@@ -10476,7 +10702,7 @@ function createWorkerStream(options = {}) {
|
|
|
10476
10702
|
const entry = currentEntryForRun(payload.runId);
|
|
10477
10703
|
if (entry === void 0 || !entry.pending) return null;
|
|
10478
10704
|
const durationMs = finiteNumber(payload.elapsedMs);
|
|
10479
|
-
const failureMessage =
|
|
10705
|
+
const failureMessage = nonEmptyString2(payload.reason);
|
|
10480
10706
|
entry.pending = false;
|
|
10481
10707
|
entry.receipt = {
|
|
10482
10708
|
outcome: "canceled",
|
|
@@ -10495,7 +10721,7 @@ function createWorkerStream(options = {}) {
|
|
|
10495
10721
|
byAssignment.clear();
|
|
10496
10722
|
attemptByAssignment.clear();
|
|
10497
10723
|
assignmentByRun.clear();
|
|
10498
|
-
|
|
10724
|
+
progressByAssignment.clear();
|
|
10499
10725
|
}
|
|
10500
10726
|
};
|
|
10501
10727
|
}
|
|
@@ -10818,6 +11044,7 @@ function richMessageFromEntry(entry, maxTextChars) {
|
|
|
10818
11044
|
"api",
|
|
10819
11045
|
"provider",
|
|
10820
11046
|
"model",
|
|
11047
|
+
"responseModelIdObservation",
|
|
10821
11048
|
"responseModel",
|
|
10822
11049
|
"responseId",
|
|
10823
11050
|
"diagnostics",
|
|
@@ -10859,7 +11086,8 @@ function toolResultContent(result, unbounded = false) {
|
|
|
10859
11086
|
return [{ type: "text", text: stringifyPreview3(result, unbounded ? Number.POSITIVE_INFINITY : 1e4) }];
|
|
10860
11087
|
}
|
|
10861
11088
|
function displayReplayToolResult(result, unbounded = false) {
|
|
10862
|
-
const
|
|
11089
|
+
const presentationText = toolResultPresentationText(result);
|
|
11090
|
+
const content = presentationText === null ? toolResultContent(result, unbounded) : [{ type: "text", text: unbounded ? presentationText : truncateReplayText(presentationText) }];
|
|
10863
11091
|
const details = payloadObject3(result)?.details;
|
|
10864
11092
|
return details !== null && details !== void 0 && typeof details === "object" ? { content, details } : content;
|
|
10865
11093
|
}
|
|
@@ -10972,6 +11200,12 @@ function extractToolCall(entry) {
|
|
|
10972
11200
|
const args = obj?.arguments ?? obj?.args ?? obj?.input ?? parseMaybeJson(fn?.arguments) ?? block?.arguments ?? block?.args ?? void 0;
|
|
10973
11201
|
return { id, name, args };
|
|
10974
11202
|
}
|
|
11203
|
+
function replayResultSummary(result) {
|
|
11204
|
+
const summary = result.resultSummary ?? toolResultSummary(result.result);
|
|
11205
|
+
const offloadPath = typeof summary.offloadPath === "string" && summary.offloadPath.length > 0 ? summary.offloadPath : null;
|
|
11206
|
+
if (offloadPath === null) return result.resultSummary;
|
|
11207
|
+
return { ...summary, offloadFileMissing: !existsSync6(offloadPath) };
|
|
11208
|
+
}
|
|
10975
11209
|
function extractToolResult(entry) {
|
|
10976
11210
|
const payload = entry.payload;
|
|
10977
11211
|
const obj = payloadObject3(payload);
|
|
@@ -11091,12 +11325,6 @@ function truncateAtTurn(entries, uptoTurnId) {
|
|
|
11091
11325
|
if (index < 0) return [...entries];
|
|
11092
11326
|
return entries.slice(0, index + 1);
|
|
11093
11327
|
}
|
|
11094
|
-
function latestCompactionIndex(entries) {
|
|
11095
|
-
for (let i = entries.length - 1; i >= 0; i--) {
|
|
11096
|
-
if (entries[i]?.kind === "compactionSummary") return i;
|
|
11097
|
-
}
|
|
11098
|
-
return -1;
|
|
11099
|
-
}
|
|
11100
11328
|
function toolCallIdsInEntry(entry) {
|
|
11101
11329
|
if (entry.kind !== "message") return [];
|
|
11102
11330
|
if (entry.role === "tool_call") return [extractToolCall(entry).id];
|
|
@@ -11149,16 +11377,11 @@ function repairToolResultOrphans(allEntries, selected, compactionIndex) {
|
|
|
11149
11377
|
function selectReplayEntries(turns, options = {}) {
|
|
11150
11378
|
const active = filterEntriesToActivePath(turns, options.activeLeafTurnId ?? options.uptoTurnId);
|
|
11151
11379
|
const entries = truncateAtTurn(active, options.uptoTurnId);
|
|
11152
|
-
const
|
|
11153
|
-
if (compactionIndex < 0) return dropLegacyToolResultAssistantDuplicates(entries);
|
|
11154
|
-
const compaction = entries[compactionIndex];
|
|
11155
|
-
const selected = [compaction];
|
|
11156
|
-
|
|
11157
|
-
if (firstKeptIndex >= 0 && firstKeptIndex < compactionIndex) {
|
|
11158
|
-
selected.push(...entries.slice(firstKeptIndex, compactionIndex));
|
|
11159
|
-
}
|
|
11160
|
-
selected.push(...entries.slice(compactionIndex + 1));
|
|
11161
|
-
return dropLegacyToolResultAssistantDuplicates(repairToolResultOrphans(entries, selected, compactionIndex));
|
|
11380
|
+
const cut = compactionCut(entries);
|
|
11381
|
+
if (cut.compactionIndex < 0) return dropLegacyToolResultAssistantDuplicates(entries);
|
|
11382
|
+
const compaction = entries[cut.compactionIndex];
|
|
11383
|
+
const selected = [compaction, ...cut.visible];
|
|
11384
|
+
return dropLegacyToolResultAssistantDuplicates(repairToolResultOrphans(entries, selected, cut.compactionIndex));
|
|
11162
11385
|
}
|
|
11163
11386
|
function dropLegacyToolResultAssistantDuplicates(entries) {
|
|
11164
11387
|
const out = [];
|
|
@@ -11253,6 +11476,11 @@ function buildReplayAgentMessagesFromTurns(turns, options = {}) {
|
|
|
11253
11476
|
// It reaches the model only when an operator shares it, and a share
|
|
11254
11477
|
// is already a user message by the time it lands in the ledger.
|
|
11255
11478
|
case "workerRun":
|
|
11479
|
+
// Working-set entries are folded into a view by the context domain
|
|
11480
|
+
// and applied as a projection before this builder runs; the
|
|
11481
|
+
// entries themselves never become messages.
|
|
11482
|
+
case "contextEviction":
|
|
11483
|
+
case "contextRecall":
|
|
11256
11484
|
break;
|
|
11257
11485
|
}
|
|
11258
11486
|
}
|
|
@@ -11262,6 +11490,7 @@ function rehydrateChatPanelFromTurns(chatPanel, turns, options = {}) {
|
|
|
11262
11490
|
const pendingToolIds = [];
|
|
11263
11491
|
let runAssistantMessages = [];
|
|
11264
11492
|
const selected = selectReplayEntries(turns, options);
|
|
11493
|
+
const workingSet = foldWorkingSet(turns, options.activeLeafTurnId ?? options.uptoTurnId);
|
|
11265
11494
|
const workerStates = workerEntriesFromRunEntries(
|
|
11266
11495
|
selected.filter((entry) => entry.kind === "workerRun"),
|
|
11267
11496
|
options.readWorkerReceipt ?? readWorkerReceiptFactsForReplay
|
|
@@ -11306,6 +11535,8 @@ function rehydrateChatPanelFromTurns(chatPanel, turns, options = {}) {
|
|
|
11306
11535
|
}
|
|
11307
11536
|
if (entry.role === "tool_result") {
|
|
11308
11537
|
const result = extractToolResult(entry);
|
|
11538
|
+
const resultSummary = replayResultSummary(result);
|
|
11539
|
+
const evictedReason = workingSet.evicted.get(entry.turnId)?.reason;
|
|
11309
11540
|
const fallbackId = result.id ?? pendingToolIds.pop() ?? null;
|
|
11310
11541
|
if (fallbackId) {
|
|
11311
11542
|
const pendingIndex = pendingToolIds.indexOf(fallbackId);
|
|
@@ -11317,9 +11548,10 @@ function rehydrateChatPanelFromTurns(chatPanel, turns, options = {}) {
|
|
|
11317
11548
|
result: displayReplayToolResult(result.result, options.unboundedToolBodies === true),
|
|
11318
11549
|
isError: result.isError,
|
|
11319
11550
|
...result.durationMs !== void 0 ? { durationMs: result.durationMs } : {},
|
|
11320
|
-
...
|
|
11551
|
+
...resultSummary !== void 0 ? { resultSummary } : {},
|
|
11321
11552
|
...result.outcome !== void 0 ? { outcome: result.outcome } : {},
|
|
11322
|
-
...result.blockReason !== void 0 ? { blockReason: result.blockReason } : {}
|
|
11553
|
+
...result.blockReason !== void 0 ? { blockReason: result.blockReason } : {},
|
|
11554
|
+
...evictedReason !== void 0 ? { evictedReason } : {}
|
|
11323
11555
|
});
|
|
11324
11556
|
} else {
|
|
11325
11557
|
chatPanel.appendReplayBlock(
|
|
@@ -11330,9 +11562,10 @@ function rehydrateChatPanelFromTurns(chatPanel, turns, options = {}) {
|
|
|
11330
11562
|
result: displayReplayToolResult(result.result, options.unboundedToolBodies === true),
|
|
11331
11563
|
isError: result.isError,
|
|
11332
11564
|
...result.durationMs !== void 0 ? { durationMs: result.durationMs } : {},
|
|
11333
|
-
...
|
|
11565
|
+
...resultSummary !== void 0 ? { resultSummary } : {},
|
|
11334
11566
|
...result.outcome === "blocked" ? { outcome: "blocked" } : {},
|
|
11335
|
-
...result.blockReason !== void 0 ? { blockReason: result.blockReason } : {}
|
|
11567
|
+
...result.blockReason !== void 0 ? { blockReason: result.blockReason } : {},
|
|
11568
|
+
...evictedReason !== void 0 ? { evictedReason } : {}
|
|
11336
11569
|
},
|
|
11337
11570
|
width,
|
|
11338
11571
|
{ unbounded: options.unboundedToolBodies === true }
|
|
@@ -11417,6 +11650,8 @@ function rehydrateChatPanelFromTurns(chatPanel, turns, options = {}) {
|
|
|
11417
11650
|
case "label":
|
|
11418
11651
|
case "taskLedger":
|
|
11419
11652
|
case "decisionLedger":
|
|
11653
|
+
case "contextEviction":
|
|
11654
|
+
case "contextRecall":
|
|
11420
11655
|
break;
|
|
11421
11656
|
}
|
|
11422
11657
|
}
|
|
@@ -11432,6 +11667,13 @@ function rehydrateChatPanelFromTurns(chatPanel, turns, options = {}) {
|
|
|
11432
11667
|
chatPanel.clearFoldOverrides();
|
|
11433
11668
|
}
|
|
11434
11669
|
|
|
11670
|
+
// src/interactive/model-session-replay.ts
|
|
11671
|
+
function buildModelReplayAgentMessagesFromTurns(entries, options = {}) {
|
|
11672
|
+
const activeLeafTurnId = options.activeLeafTurnId ?? options.uptoTurnId;
|
|
11673
|
+
const projected = projectWorkingSet(entries, foldWorkingSet(entries, activeLeafTurnId));
|
|
11674
|
+
return buildReplayAgentMessagesFromTurns(projected, options);
|
|
11675
|
+
}
|
|
11676
|
+
|
|
11435
11677
|
// src/interactive/turn-context.ts
|
|
11436
11678
|
function createTurnContext(deps) {
|
|
11437
11679
|
const { state, middleware } = deps;
|
|
@@ -11444,20 +11686,37 @@ function createTurnContext(deps) {
|
|
|
11444
11686
|
let sessionPromptKey = null;
|
|
11445
11687
|
const sessionWorkingContextPaths = /* @__PURE__ */ new Set();
|
|
11446
11688
|
let pendingPromptLogEntry = null;
|
|
11689
|
+
let emptyAutoCompactTurnId = null;
|
|
11447
11690
|
const pendingColdReasons = /* @__PURE__ */ new Set();
|
|
11448
11691
|
let runExpectedColdReasons = [];
|
|
11449
|
-
let
|
|
11692
|
+
let nextAssistantColdReasons = [];
|
|
11693
|
+
const TIER_INDEPENDENT_COLD_REASONS = /* @__PURE__ */ new Set(["working_set_evict"]);
|
|
11694
|
+
const stampsOnTier = (reason, runtimeId) => TIER_INDEPENDENT_COLD_REASONS.has(reason) || runtimeId !== void 0 && deps.providers.getRuntime(runtimeId)?.tier === "local-native";
|
|
11695
|
+
const noteColdReason = (reason) => {
|
|
11696
|
+
if (!state.streaming) {
|
|
11697
|
+
pendingColdReasons.add(reason);
|
|
11698
|
+
return;
|
|
11699
|
+
}
|
|
11700
|
+
if (!stampsOnTier(reason, state.runtime?.runtimeId)) return;
|
|
11701
|
+
if (!runExpectedColdReasons.includes(reason)) runExpectedColdReasons.push(reason);
|
|
11702
|
+
if (nextAssistantColdReasons.includes(reason)) return;
|
|
11703
|
+
nextAssistantColdReasons.push(reason);
|
|
11704
|
+
deps.emitNotice(`[context engine] backend prefix cache likely cold this turn: ${reason}`);
|
|
11705
|
+
};
|
|
11450
11706
|
const unsubscribeColdReasonSources = [
|
|
11451
11707
|
...[BusChannels.DispatchStarted, BusChannels.DispatchCompleted, BusChannels.DispatchFailed].map(
|
|
11452
11708
|
(channel) => deps.bus?.on(channel, () => {
|
|
11453
|
-
|
|
11709
|
+
noteColdReason("dispatch");
|
|
11454
11710
|
}) ?? null
|
|
11455
11711
|
),
|
|
11456
11712
|
...[BusChannels.CompactionBegin, BusChannels.CompactionEnd].map(
|
|
11457
11713
|
(channel) => deps.bus?.on(channel, () => {
|
|
11458
|
-
|
|
11714
|
+
noteColdReason("compaction");
|
|
11459
11715
|
}) ?? null
|
|
11460
|
-
)
|
|
11716
|
+
),
|
|
11717
|
+
deps.bus?.on(BusChannels.ContextRecalled, (payload) => {
|
|
11718
|
+
middleware.fireCompactionHook("working_set_recall", payload.trigger);
|
|
11719
|
+
}) ?? null
|
|
11461
11720
|
];
|
|
11462
11721
|
let snapshotPersistPending = false;
|
|
11463
11722
|
let lastContextWindowWarning = null;
|
|
@@ -11509,6 +11768,50 @@ function createTurnContext(deps) {
|
|
|
11509
11768
|
}
|
|
11510
11769
|
return ceilChars(snapshot.pendingUserInput.length);
|
|
11511
11770
|
};
|
|
11771
|
+
const resolveWindowWithoutRuntime = () => {
|
|
11772
|
+
const settings = deps.getSettings();
|
|
11773
|
+
const targetId = settings.orchestrator?.target?.trim();
|
|
11774
|
+
const wireModelId = settings.orchestrator?.model?.trim();
|
|
11775
|
+
if (!targetId || !wireModelId) return null;
|
|
11776
|
+
const resolved = resolveRuntimeTarget(deps.providers, {
|
|
11777
|
+
targetId,
|
|
11778
|
+
wireModelId,
|
|
11779
|
+
requestedThinkingLevel: settings.orchestrator?.thinkingLevel ?? "off",
|
|
11780
|
+
use: "orchestrator",
|
|
11781
|
+
requireTools: false,
|
|
11782
|
+
requireOutputBudget: true
|
|
11783
|
+
});
|
|
11784
|
+
return resolved.ok ? resolved.target.contextWindowDetails : null;
|
|
11785
|
+
};
|
|
11786
|
+
const CONTEXT_WINDOW_SOURCES = /* @__PURE__ */ new Set([
|
|
11787
|
+
"catalog",
|
|
11788
|
+
"probe",
|
|
11789
|
+
"loaded",
|
|
11790
|
+
"target-override",
|
|
11791
|
+
"model-hint",
|
|
11792
|
+
"descriptor-default",
|
|
11793
|
+
"unknown"
|
|
11794
|
+
]);
|
|
11795
|
+
const snapshotWindowSource = (snapshot) => CONTEXT_WINDOW_SOURCES.has(snapshot.contextWindowSource) ? snapshot.contextWindowSource : null;
|
|
11796
|
+
const windowWithoutRuntime = () => {
|
|
11797
|
+
const details = resolveWindowWithoutRuntime();
|
|
11798
|
+
if (details) {
|
|
11799
|
+
return {
|
|
11800
|
+
contextWindow: details.effectiveContextWindow,
|
|
11801
|
+
contextWindowSource: details.contextWindowSource,
|
|
11802
|
+
contextWindowSlots: details.contextWindowSlots
|
|
11803
|
+
};
|
|
11804
|
+
}
|
|
11805
|
+
const snapshot = currentContextSnapshot;
|
|
11806
|
+
if (snapshot && snapshot.effectiveContextWindow > 0) {
|
|
11807
|
+
return {
|
|
11808
|
+
contextWindow: snapshot.effectiveContextWindow,
|
|
11809
|
+
contextWindowSource: snapshotWindowSource(snapshot),
|
|
11810
|
+
contextWindowSlots: null
|
|
11811
|
+
};
|
|
11812
|
+
}
|
|
11813
|
+
return { contextWindow: 0, contextWindowSource: null, contextWindowSlots: null };
|
|
11814
|
+
};
|
|
11512
11815
|
const liveContextEstimate = (agentRuntime, pendingUserText) => {
|
|
11513
11816
|
const contextWindow = agentRuntime.runtimeResolution.contextWindowDetails.effectiveContextWindow;
|
|
11514
11817
|
const estimateInput = {
|
|
@@ -11525,7 +11828,7 @@ function createTurnContext(deps) {
|
|
|
11525
11828
|
};
|
|
11526
11829
|
const refreshAgentMessagesFromSession = (agentRuntime) => {
|
|
11527
11830
|
const refreshedEntries = deps.readSessionEntries?.() ?? [];
|
|
11528
|
-
agentRuntime.agent.state.messages =
|
|
11831
|
+
agentRuntime.agent.state.messages = buildModelReplayAgentMessagesFromTurns(refreshedEntries, {
|
|
11529
11832
|
...state.lastTurnId ? { activeLeafTurnId: state.lastTurnId } : {}
|
|
11530
11833
|
});
|
|
11531
11834
|
state.replayedContextMessages = [];
|
|
@@ -11563,11 +11866,17 @@ function createTurnContext(deps) {
|
|
|
11563
11866
|
);
|
|
11564
11867
|
};
|
|
11565
11868
|
const runAutoCompact = async (agentRuntime, force, instructions, triggerOverride, pendingUserText) => {
|
|
11566
|
-
if (!deps.
|
|
11869
|
+
if (!deps.readSessionEntries) return false;
|
|
11870
|
+
const activeAutoTurnId = force ? null : state.activeUserTurnId;
|
|
11871
|
+
if (activeAutoTurnId && emptyAutoCompactTurnId === activeAutoTurnId) return false;
|
|
11567
11872
|
const settings = deps.getSettings();
|
|
11568
11873
|
const cfg = settings.compaction;
|
|
11569
11874
|
const autoEnabled = cfg?.auto !== false;
|
|
11570
11875
|
if (!force && !autoEnabled) return false;
|
|
11876
|
+
let preSummaryStageActed = false;
|
|
11877
|
+
const rememberEmptyAutomaticAttempt = () => {
|
|
11878
|
+
if (!force && !preSummaryStageActed && activeAutoTurnId) emptyAutoCompactTurnId = activeAutoTurnId;
|
|
11879
|
+
};
|
|
11571
11880
|
const compactionThreshold = cfg?.threshold ?? DEFAULT_COMPACTION_THRESHOLD;
|
|
11572
11881
|
const trigger = triggerOverride ?? (force ? "force" : "auto");
|
|
11573
11882
|
if (!force) {
|
|
@@ -11576,78 +11885,176 @@ function createTurnContext(deps) {
|
|
|
11576
11885
|
if (!verdict.shouldCompact) return false;
|
|
11577
11886
|
if (deps.session?.current()) {
|
|
11578
11887
|
const beforeSnapshotId2 = currentContextSnapshot?.snapshotId ?? null;
|
|
11579
|
-
|
|
11580
|
-
|
|
11581
|
-
|
|
11582
|
-
|
|
11583
|
-
|
|
11584
|
-
|
|
11585
|
-
|
|
11586
|
-
|
|
11587
|
-
|
|
11588
|
-
|
|
11589
|
-
|
|
11590
|
-
|
|
11591
|
-
|
|
11592
|
-
|
|
11593
|
-
|
|
11594
|
-
|
|
11595
|
-
|
|
11596
|
-
|
|
11597
|
-
|
|
11598
|
-
|
|
11599
|
-
|
|
11600
|
-
|
|
11601
|
-
|
|
11602
|
-
|
|
11603
|
-
|
|
11604
|
-
|
|
11605
|
-
|
|
11606
|
-
|
|
11607
|
-
|
|
11608
|
-
|
|
11609
|
-
|
|
11610
|
-
|
|
11611
|
-
|
|
11612
|
-
|
|
11613
|
-
|
|
11614
|
-
|
|
11615
|
-
|
|
11616
|
-
|
|
11617
|
-
|
|
11618
|
-
|
|
11619
|
-
|
|
11620
|
-
|
|
11621
|
-
|
|
11622
|
-
|
|
11623
|
-
|
|
11624
|
-
|
|
11625
|
-
|
|
11626
|
-
|
|
11627
|
-
|
|
11628
|
-
|
|
11629
|
-
|
|
11630
|
-
|
|
11888
|
+
if (process.env.CLIO_CODER_LEGACY_MASK === "1") {
|
|
11889
|
+
let masked;
|
|
11890
|
+
try {
|
|
11891
|
+
masked = maskStaleObservations(deps.readSessionEntries() ?? [], cfg?.excludeLastTurns ?? 6);
|
|
11892
|
+
} catch (error) {
|
|
11893
|
+
middleware.fireCompactionHook("mask_observations", trigger, estimate.tokens);
|
|
11894
|
+
deps.bus?.emit(BusChannels.CompactionBegin, { trigger, at: Date.now() });
|
|
11895
|
+
emitCompactionActivity("started", "compacting context (mask stage)");
|
|
11896
|
+
emitCompactionActivity("failed", compactionFailureMessage(error));
|
|
11897
|
+
deps.bus?.emit(BusChannels.CompactionEnd, { trigger, at: Date.now() });
|
|
11898
|
+
throw error;
|
|
11899
|
+
}
|
|
11900
|
+
if (masked.changed) {
|
|
11901
|
+
preSummaryStageActed = true;
|
|
11902
|
+
middleware.fireCompactionHook("mask_observations", trigger, estimate.tokens);
|
|
11903
|
+
deps.bus?.emit(BusChannels.CompactionBegin, { trigger, at: Date.now() });
|
|
11904
|
+
emitCompactionActivity("started", "compacting context (mask stage)");
|
|
11905
|
+
deps.session.replaceEntries(masked.entries);
|
|
11906
|
+
refreshAgentMessagesFromSession(agentRuntime);
|
|
11907
|
+
deps.bus?.emit(BusChannels.CompactionEnd, { trigger, at: Date.now() });
|
|
11908
|
+
const postMaskSnapshot = captureRuntimeContextSnapshot(
|
|
11909
|
+
agentRuntime,
|
|
11910
|
+
state.activeUserTurnId || "compaction",
|
|
11911
|
+
compactionThreshold
|
|
11912
|
+
);
|
|
11913
|
+
currentContextSnapshot = postMaskSnapshot;
|
|
11914
|
+
persistContextSnapshot(postMaskSnapshot);
|
|
11915
|
+
const tokensAfterMask = snapshotInputTokens(postMaskSnapshot);
|
|
11916
|
+
lastCompactionEvent = {
|
|
11917
|
+
stage: "mask_observations",
|
|
11918
|
+
tokensBefore: estimate.tokens,
|
|
11919
|
+
tokensAfter: tokensAfterMask,
|
|
11920
|
+
trigger
|
|
11921
|
+
};
|
|
11922
|
+
deps.bus?.emit(BusChannels.ContextPruned, {
|
|
11923
|
+
stage: "mask_observations",
|
|
11924
|
+
pressure: verdict.pressure,
|
|
11925
|
+
tokensBefore: estimate.tokens,
|
|
11926
|
+
tokensAfter: tokensAfterMask,
|
|
11927
|
+
maskedObservations: masked.maskedObservations,
|
|
11928
|
+
maskedThinkingBlocks: masked.maskedThinkingBlocks,
|
|
11929
|
+
maskedThinkingChars: masked.maskedThinkingChars,
|
|
11930
|
+
trigger,
|
|
11931
|
+
snapshotIdBefore: beforeSnapshotId2,
|
|
11932
|
+
snapshotIdAfter: postMaskSnapshot.snapshotId,
|
|
11933
|
+
at: Date.now()
|
|
11934
|
+
});
|
|
11935
|
+
emitCompactionActivity("completed", `${masked.maskedObservations} observations masked`);
|
|
11936
|
+
const thinkingNote = masked.maskedThinkingBlocks > 0 ? `, ${masked.maskedThinkingBlocks} thinking blocks dropped (~${masked.maskedThinkingChars} chars)` : "";
|
|
11937
|
+
deps.emitNotice(
|
|
11938
|
+
`[context engine] mask_observations: ${masked.maskedObservations} observations masked${thinkingNote}; ~${estimate.tokens} tokens -> ~${tokensAfterMask} tokens`
|
|
11939
|
+
);
|
|
11940
|
+
const after = liveContextEstimate(agentRuntime, pendingUserText);
|
|
11941
|
+
if (!shouldCompact(after.tokens, compactionThreshold, after.contextWindow).shouldCompact) return true;
|
|
11942
|
+
}
|
|
11943
|
+
} else if (settings.context.workingSet.enabled) {
|
|
11944
|
+
let planned;
|
|
11945
|
+
try {
|
|
11946
|
+
const entries = deps.readSessionEntries() ?? [];
|
|
11947
|
+
const view = foldWorkingSet(entries, state.lastTurnId ?? void 0);
|
|
11948
|
+
const policy = resolveWorkingSetPolicy(settings.context.workingSet.policy);
|
|
11949
|
+
planned = (deps.planEviction ?? planEviction)(policy, {
|
|
11950
|
+
entries: selectVisibleEntries(entries, state.lastTurnId ?? void 0),
|
|
11951
|
+
view,
|
|
11952
|
+
cwd: deps.session.current()?.cwd ?? null,
|
|
11953
|
+
settings: settings.context.workingSet,
|
|
11954
|
+
pressure: {
|
|
11955
|
+
tokens: estimate.tokens,
|
|
11956
|
+
contextWindow: estimate.contextWindow,
|
|
11957
|
+
threshold: compactionThreshold,
|
|
11958
|
+
target: settings.context.workingSet.target
|
|
11959
|
+
},
|
|
11960
|
+
estimateTokens
|
|
11961
|
+
});
|
|
11962
|
+
} catch (error) {
|
|
11963
|
+
middleware.fireCompactionHook("working_set_evict", "pressure", estimate.tokens);
|
|
11964
|
+
emitCompactionActivity("started", "compacting context (working-set eviction)");
|
|
11965
|
+
emitCompactionActivity("failed", compactionFailureMessage(error));
|
|
11966
|
+
throw error;
|
|
11967
|
+
}
|
|
11968
|
+
if (planned) {
|
|
11969
|
+
preSummaryStageActed = true;
|
|
11970
|
+
middleware.fireCompactionHook("working_set_evict", "pressure", estimate.tokens);
|
|
11971
|
+
emitCompactionActivity("started", "compacting context (working-set eviction)");
|
|
11972
|
+
try {
|
|
11973
|
+
deps.session.appendEntry({
|
|
11974
|
+
...buildEvictionFields(planned, {
|
|
11975
|
+
trigger: "pressure",
|
|
11976
|
+
pressureBefore: verdict.pressure,
|
|
11977
|
+
snapshotIdBefore: beforeSnapshotId2
|
|
11978
|
+
}),
|
|
11979
|
+
// appendEntry does not infer this anchor; the interactive
|
|
11980
|
+
// cursor is the leaf the next message will extend.
|
|
11981
|
+
parentTurnId: state.lastTurnId
|
|
11982
|
+
});
|
|
11983
|
+
noteColdReason("working_set_evict");
|
|
11984
|
+
refreshAgentMessagesFromSession(agentRuntime);
|
|
11985
|
+
const postEvictionSnapshot = captureRuntimeContextSnapshot(
|
|
11986
|
+
agentRuntime,
|
|
11987
|
+
state.activeUserTurnId || "compaction",
|
|
11988
|
+
compactionThreshold
|
|
11989
|
+
);
|
|
11990
|
+
currentContextSnapshot = postEvictionSnapshot;
|
|
11991
|
+
persistContextSnapshot(postEvictionSnapshot);
|
|
11992
|
+
lastCompactionEvent = {
|
|
11993
|
+
stage: "working_set",
|
|
11994
|
+
tokensBefore: planned.tokensBefore,
|
|
11995
|
+
tokensAfter: planned.tokensAfter,
|
|
11996
|
+
trigger
|
|
11997
|
+
};
|
|
11998
|
+
deps.bus?.emit(BusChannels.ContextPruned, {
|
|
11999
|
+
stage: "working_set",
|
|
12000
|
+
pressure: verdict.pressure,
|
|
12001
|
+
tokensBefore: planned.tokensBefore,
|
|
12002
|
+
tokensAfter: planned.tokensAfter,
|
|
12003
|
+
trigger,
|
|
12004
|
+
snapshotIdBefore: beforeSnapshotId2,
|
|
12005
|
+
snapshotIdAfter: postEvictionSnapshot.snapshotId,
|
|
12006
|
+
policyId: planned.policyId,
|
|
12007
|
+
evictedItems: planned.items.length,
|
|
12008
|
+
at: Date.now()
|
|
12009
|
+
});
|
|
12010
|
+
const itemsWord = planned.items.length === 1 ? "item" : "items";
|
|
12011
|
+
emitCompactionActivity("completed", `${planned.items.length} working-set ${itemsWord} evicted`);
|
|
12012
|
+
deps.emitNotice(
|
|
12013
|
+
`[context engine] working set: ${planned.items.length} ${itemsWord} evicted by ${planned.policyId}; ~${planned.tokensBefore} -> ~${planned.tokensAfter} tokens, recall by ref with context(scope="recall")`
|
|
12014
|
+
);
|
|
12015
|
+
const after = liveContextEstimate(agentRuntime, pendingUserText);
|
|
12016
|
+
if (!shouldCompact(after.tokens, compactionThreshold, after.contextWindow).shouldCompact) return true;
|
|
12017
|
+
} catch (error) {
|
|
12018
|
+
emitCompactionActivity("failed", compactionFailureMessage(error));
|
|
12019
|
+
throw error;
|
|
12020
|
+
}
|
|
12021
|
+
}
|
|
11631
12022
|
}
|
|
11632
12023
|
}
|
|
11633
12024
|
}
|
|
11634
|
-
|
|
11635
|
-
|
|
11636
|
-
|
|
12025
|
+
if (!deps.autoCompact) {
|
|
12026
|
+
rememberEmptyAutomaticAttempt();
|
|
12027
|
+
return false;
|
|
12028
|
+
}
|
|
12029
|
+
let summaryLifecycleStarted = false;
|
|
12030
|
+
const startSummaryLifecycle = () => {
|
|
12031
|
+
middleware.fireCompactionHook("llm_summary", trigger);
|
|
12032
|
+
deps.bus?.emit(BusChannels.CompactionBegin, { trigger, at: Date.now() });
|
|
12033
|
+
emitCompactionActivity("started", "compacting context (summary)");
|
|
12034
|
+
summaryLifecycleStarted = true;
|
|
12035
|
+
};
|
|
12036
|
+
if (force) startSummaryLifecycle();
|
|
11637
12037
|
let result = null;
|
|
11638
12038
|
const beforeSnapshotId = currentContextSnapshot?.snapshotId ?? null;
|
|
11639
12039
|
try {
|
|
11640
12040
|
result = await compactionTrigger.fire(() => (deps.autoCompact ?? (async () => null))(instructions, trigger));
|
|
11641
12041
|
} catch (error) {
|
|
12042
|
+
if (!summaryLifecycleStarted) startSummaryLifecycle();
|
|
11642
12043
|
emitCompactionActivity("failed", compactionFailureMessage(error));
|
|
11643
|
-
throw error;
|
|
11644
|
-
} finally {
|
|
11645
12044
|
deps.bus?.emit(BusChannels.CompactionEnd, { trigger, at: Date.now() });
|
|
12045
|
+
throw error;
|
|
11646
12046
|
}
|
|
11647
12047
|
if (!result || result.summary.length === 0) {
|
|
11648
|
-
|
|
12048
|
+
if (summaryLifecycleStarted) {
|
|
12049
|
+
deps.bus?.emit(BusChannels.CompactionEnd, { trigger, at: Date.now() });
|
|
12050
|
+
emitCompactionActivity("completed", "nothing to compact");
|
|
12051
|
+
} else {
|
|
12052
|
+
rememberEmptyAutomaticAttempt();
|
|
12053
|
+
}
|
|
11649
12054
|
return false;
|
|
11650
12055
|
}
|
|
12056
|
+
if (!summaryLifecycleStarted) startSummaryLifecycle();
|
|
12057
|
+
deps.bus?.emit(BusChannels.CompactionEnd, { trigger, at: Date.now() });
|
|
11651
12058
|
recordCompactionUsage(agentRuntime, result);
|
|
11652
12059
|
refreshAgentMessagesFromSession(agentRuntime);
|
|
11653
12060
|
const postCompactSnapshot = captureRuntimeContextSnapshot(
|
|
@@ -11861,8 +12268,7 @@ function createTurnContext(deps) {
|
|
|
11861
12268
|
return compacted ? continuationContextUpdate(agentRuntime) : void 0;
|
|
11862
12269
|
},
|
|
11863
12270
|
contextUsage() {
|
|
11864
|
-
|
|
11865
|
-
const effectiveWindow = state.runtime.runtimeResolution.contextWindowDetails.effectiveContextWindow;
|
|
12271
|
+
const effectiveWindow = state.runtime ? state.runtime.runtimeResolution.contextWindowDetails.effectiveContextWindow : windowWithoutRuntime().contextWindow;
|
|
11866
12272
|
if (!currentContextSnapshot) {
|
|
11867
12273
|
return contextUsageSnapshot(null, effectiveWindow);
|
|
11868
12274
|
}
|
|
@@ -11880,26 +12286,20 @@ function createTurnContext(deps) {
|
|
|
11880
12286
|
const settings = deps.getSettings();
|
|
11881
12287
|
const compactionThreshold = settings.compaction?.threshold ?? null;
|
|
11882
12288
|
const compactionAuto = settings.compaction?.auto !== false;
|
|
11883
|
-
|
|
11884
|
-
|
|
11885
|
-
|
|
11886
|
-
|
|
11887
|
-
|
|
11888
|
-
|
|
11889
|
-
|
|
11890
|
-
|
|
11891
|
-
}
|
|
11892
|
-
const windowDetails = state.runtime.runtimeResolution.contextWindowDetails;
|
|
11893
|
-
const effectiveWindow = windowDetails.effectiveContextWindow;
|
|
11894
|
-
const provider = state.runtime.targetId ?? settings.orchestrator?.target ?? null;
|
|
11895
|
-
const model = state.runtime.wireModelId ?? settings.orchestrator?.model ?? null;
|
|
12289
|
+
const window = state.runtime ? {
|
|
12290
|
+
contextWindow: state.runtime.runtimeResolution.contextWindowDetails.effectiveContextWindow,
|
|
12291
|
+
contextWindowSource: state.runtime.runtimeResolution.contextWindowDetails.contextWindowSource,
|
|
12292
|
+
contextWindowSlots: state.runtime.runtimeResolution.contextWindowDetails.contextWindowSlots
|
|
12293
|
+
} : windowWithoutRuntime();
|
|
12294
|
+
const provider = state.runtime?.targetId ?? settings.orchestrator?.target ?? null;
|
|
12295
|
+
const model = state.runtime?.wireModelId ?? settings.orchestrator?.model ?? null;
|
|
12296
|
+
const liveToolCount = state.runtime?.agent.state.tools.length ?? 0;
|
|
11896
12297
|
if (!currentContextSnapshot) {
|
|
11897
12298
|
return buildContextLedger({
|
|
11898
12299
|
provider,
|
|
11899
12300
|
model,
|
|
11900
|
-
|
|
11901
|
-
|
|
11902
|
-
toolCount: state.runtime.agent.state.tools.length,
|
|
12301
|
+
...window,
|
|
12302
|
+
toolCount: liveToolCount,
|
|
11903
12303
|
compactionThreshold,
|
|
11904
12304
|
compactionAuto,
|
|
11905
12305
|
promptCache: lastPromptCache
|
|
@@ -11912,15 +12312,14 @@ function createTurnContext(deps) {
|
|
|
11912
12312
|
return buildContextLedger({
|
|
11913
12313
|
provider,
|
|
11914
12314
|
model,
|
|
11915
|
-
|
|
11916
|
-
contextWindowSource: windowDetails.contextWindowSource,
|
|
12315
|
+
...window,
|
|
11917
12316
|
compactionThreshold,
|
|
11918
12317
|
compactionAuto,
|
|
11919
12318
|
systemPromptTokens: currentContextSnapshot.categories.system,
|
|
11920
12319
|
toolSchemaTokens: currentContextSnapshot.categories.tools,
|
|
11921
12320
|
// Persisted snapshots strip the captured schemas; fall back to
|
|
11922
12321
|
// the live agent state after a session resume.
|
|
11923
|
-
toolCount: currentContextSnapshot.activeToolSchemas?.length ??
|
|
12322
|
+
toolCount: currentContextSnapshot.activeToolSchemas?.length ?? liveToolCount,
|
|
11924
12323
|
messageTokens: currentContextSnapshot.categories.messages,
|
|
11925
12324
|
agentsTokens: currentContextSnapshot.categories.agents,
|
|
11926
12325
|
skillsTokens: currentContextSnapshot.categories.skills,
|
|
@@ -11943,13 +12342,13 @@ function createTurnContext(deps) {
|
|
|
11943
12342
|
},
|
|
11944
12343
|
consumeExpectedColdReasons(runtimeId) {
|
|
11945
12344
|
runExpectedColdReasons = [];
|
|
11946
|
-
|
|
12345
|
+
nextAssistantColdReasons = [];
|
|
11947
12346
|
if (pendingColdReasons.size > 0) {
|
|
11948
|
-
const reasons = [...pendingColdReasons];
|
|
12347
|
+
const reasons = [...pendingColdReasons].filter((reason) => stampsOnTier(reason, runtimeId));
|
|
11949
12348
|
pendingColdReasons.clear();
|
|
11950
|
-
if (
|
|
12349
|
+
if (reasons.length > 0) {
|
|
11951
12350
|
runExpectedColdReasons = reasons;
|
|
11952
|
-
|
|
12351
|
+
nextAssistantColdReasons = reasons;
|
|
11953
12352
|
deps.emitNotice(`[context engine] backend prefix cache likely cold this turn: ${reasons.join(", ")}`);
|
|
11954
12353
|
}
|
|
11955
12354
|
}
|
|
@@ -11964,9 +12363,9 @@ function createTurnContext(deps) {
|
|
|
11964
12363
|
cacheWrite,
|
|
11965
12364
|
backendVerdict: backendCacheVerdict(input, cacheRead)
|
|
11966
12365
|
};
|
|
11967
|
-
if (
|
|
11968
|
-
promptCache.expectedColdReasons = [...
|
|
11969
|
-
|
|
12366
|
+
if (nextAssistantColdReasons.length > 0) {
|
|
12367
|
+
promptCache.expectedColdReasons = [...nextAssistantColdReasons];
|
|
12368
|
+
nextAssistantColdReasons = [];
|
|
11970
12369
|
}
|
|
11971
12370
|
return promptCache;
|
|
11972
12371
|
},
|
|
@@ -11978,7 +12377,8 @@ function createTurnContext(deps) {
|
|
|
11978
12377
|
cacheReadTokens: cacheSummary.cacheRead > 0 || cacheSummary.cacheWrite > 0 ? cacheSummary.cacheRead : null,
|
|
11979
12378
|
cacheWriteTokens: cacheSummary.cacheRead > 0 || cacheSummary.cacheWrite > 0 ? cacheSummary.cacheWrite : null,
|
|
11980
12379
|
uncachedInputTokens: cacheSummary.input,
|
|
11981
|
-
backendVerdict: runFirstCallVerdict
|
|
12380
|
+
backendVerdict: runFirstCallVerdict,
|
|
12381
|
+
...runExpectedColdReasons.length > 0 ? { expectedColdReasons: [...runExpectedColdReasons] } : {}
|
|
11982
12382
|
};
|
|
11983
12383
|
}
|
|
11984
12384
|
},
|
|
@@ -11988,6 +12388,7 @@ function createTurnContext(deps) {
|
|
|
11988
12388
|
sessionPromptKey = null;
|
|
11989
12389
|
sessionWorkingContextPaths.clear();
|
|
11990
12390
|
pendingPromptLogEntry = null;
|
|
12391
|
+
emptyAutoCompactTurnId = null;
|
|
11991
12392
|
const session = deps.session?.current();
|
|
11992
12393
|
currentContextSnapshot = session ? getLatestContextSnapshot(session) : null;
|
|
11993
12394
|
},
|
|
@@ -12110,6 +12511,7 @@ function createTurnMiddleware(deps) {
|
|
|
12110
12511
|
runtimeTier: agentRuntime.runtimeResolution.runtimeTier ?? "",
|
|
12111
12512
|
activeToolNames: toolNamesFromAgentState(agentRuntime.agent.state.tools).join(","),
|
|
12112
12513
|
turnToolCalls: state.turnToolCalls,
|
|
12514
|
+
turnToolNames: state.turnToolNames.join(","),
|
|
12113
12515
|
sharedWorkerNote: state.turnSharedWorkerNote
|
|
12114
12516
|
};
|
|
12115
12517
|
if (terminalToolResult !== void 0) {
|
|
@@ -12141,9 +12543,9 @@ function createTurnMiddleware(deps) {
|
|
|
12141
12543
|
}
|
|
12142
12544
|
},
|
|
12143
12545
|
/**
|
|
12144
|
-
* Observe-only lifecycle point fired before each compaction
|
|
12145
|
-
*
|
|
12146
|
-
*
|
|
12546
|
+
* Observe-only lifecycle point fired before each compaction or working-set
|
|
12547
|
+
* stage. Consumers record telemetry or state around projected context
|
|
12548
|
+
* changes; returned effects are discarded by design.
|
|
12147
12549
|
*/
|
|
12148
12550
|
fireCompactionHook(stage, trigger, tokensBefore) {
|
|
12149
12551
|
if (!deps.middleware) return;
|
|
@@ -12794,8 +13196,8 @@ function count(pattern, text) {
|
|
|
12794
13196
|
while (pattern.exec(text)) matches += 1;
|
|
12795
13197
|
return matches;
|
|
12796
13198
|
}
|
|
12797
|
-
function toolPattern(
|
|
12798
|
-
const escaped = escapeRegExp(
|
|
13199
|
+
function toolPattern(toolName) {
|
|
13200
|
+
const escaped = escapeRegExp(toolName.trim().toLowerCase());
|
|
12799
13201
|
return escaped.replace(/[_-]+/g, "[ _-]+");
|
|
12800
13202
|
}
|
|
12801
13203
|
function normalizedToolNames(names) {
|
|
@@ -12817,8 +13219,8 @@ function assessToolProseLoop(input) {
|
|
|
12817
13219
|
const text = input.text.toLowerCase().replace(/\s+/g, " ");
|
|
12818
13220
|
let maxToolMatches = 0;
|
|
12819
13221
|
let matchedTool = "";
|
|
12820
|
-
for (const
|
|
12821
|
-
const name = toolPattern(
|
|
13222
|
+
for (const toolName of tools) {
|
|
13223
|
+
const name = toolPattern(toolName);
|
|
12822
13224
|
const patterns = [
|
|
12823
13225
|
new RegExp(`\\b(?:execute|call|make|use)\\s+the\\s+${name}\\s+tool\\s+call\\b`, "g"),
|
|
12824
13226
|
new RegExp(`\\b(?:execute|call|use)\\s+the\\s+${name}\\s+tool\\b`, "g"),
|
|
@@ -12827,7 +13229,7 @@ function assessToolProseLoop(input) {
|
|
|
12827
13229
|
const matches = patterns.reduce((sum, pattern) => sum + count(pattern, text), 0);
|
|
12828
13230
|
if (matches > maxToolMatches) {
|
|
12829
13231
|
maxToolMatches = matches;
|
|
12830
|
-
matchedTool =
|
|
13232
|
+
matchedTool = toolName;
|
|
12831
13233
|
}
|
|
12832
13234
|
}
|
|
12833
13235
|
const genericMatches = count(
|
|
@@ -12902,7 +13304,10 @@ function createTurnRuntime(deps) {
|
|
|
12902
13304
|
failure?.code ?? "admission-failed"
|
|
12903
13305
|
);
|
|
12904
13306
|
}
|
|
12905
|
-
for (const message of
|
|
13307
|
+
for (const message of runtimeResolutionWarningsBesideThinkingNotice(
|
|
13308
|
+
resolved.diagnostics,
|
|
13309
|
+
resolved.target.modelRuntime.thinking.notice
|
|
13310
|
+
)) {
|
|
12906
13311
|
const key = `${targetId}|${wireModelId}|${message}`;
|
|
12907
13312
|
if (announcedResolutionWarnings.has(key)) continue;
|
|
12908
13313
|
announcedResolutionWarnings.add(key);
|
|
@@ -12917,6 +13322,7 @@ function createTurnRuntime(deps) {
|
|
|
12917
13322
|
};
|
|
12918
13323
|
const TARGET_PROBE_TTL_MS = 5 * 60 * 1e3;
|
|
12919
13324
|
let lastTargetProbe = null;
|
|
13325
|
+
const targetProbesInFlight = /* @__PURE__ */ new Map();
|
|
12920
13326
|
const ensureLiveCapabilitiesForSelectedModel = async () => {
|
|
12921
13327
|
const settings = deps.getSettings();
|
|
12922
13328
|
const targetId = settings.orchestrator.target?.trim();
|
|
@@ -12927,15 +13333,28 @@ function createTurnRuntime(deps) {
|
|
|
12927
13333
|
const runtimeDesc = deps.providers.getRuntime(target.runtime);
|
|
12928
13334
|
if (!runtimeDesc || runtimeDesc.tier === "cloud") return;
|
|
12929
13335
|
const key = `${targetId}|${wireModelId}`;
|
|
13336
|
+
const inFlight = targetProbesInFlight.get(key);
|
|
13337
|
+
if (inFlight) {
|
|
13338
|
+
await inFlight;
|
|
13339
|
+
return;
|
|
13340
|
+
}
|
|
12930
13341
|
const now = Date.now();
|
|
12931
13342
|
if (lastTargetProbe?.key === key && now - lastTargetProbe.at < TARGET_PROBE_TTL_MS) return;
|
|
12932
13343
|
lastTargetProbe = { key, at: now };
|
|
12933
|
-
|
|
13344
|
+
const probe = (async () => {
|
|
13345
|
+
let status = null;
|
|
13346
|
+
try {
|
|
13347
|
+
status = await deps.providers.probeTarget(targetId);
|
|
13348
|
+
} catch {
|
|
13349
|
+
}
|
|
13350
|
+
announceColdModel(status, targetId, wireModelId);
|
|
13351
|
+
})();
|
|
13352
|
+
targetProbesInFlight.set(key, probe);
|
|
12934
13353
|
try {
|
|
12935
|
-
|
|
12936
|
-
}
|
|
13354
|
+
await probe;
|
|
13355
|
+
} finally {
|
|
13356
|
+
if (targetProbesInFlight.get(key) === probe) targetProbesInFlight.delete(key);
|
|
12937
13357
|
}
|
|
12938
|
-
announceColdModel(status, targetId, wireModelId);
|
|
12939
13358
|
};
|
|
12940
13359
|
const announcedColdModels = /* @__PURE__ */ new Set();
|
|
12941
13360
|
const announceColdModel = (status, targetId, wireModelId) => {
|
|
@@ -13154,6 +13573,7 @@ function createTurnRuntime(deps) {
|
|
|
13154
13573
|
middlewareToolChoice.toolStarted(event.toolName);
|
|
13155
13574
|
deps.toolStartTimes.set(event.toolCallId, eventClock);
|
|
13156
13575
|
state.turnToolCalls += 1;
|
|
13576
|
+
state.turnToolNames.push(event.toolName);
|
|
13157
13577
|
} else if (event.type === "tool_execution_end") {
|
|
13158
13578
|
toolsInFlight = Math.max(0, toolsInFlight - 1);
|
|
13159
13579
|
const startedAt = deps.toolStartTimes.get(event.toolCallId);
|
|
@@ -13235,7 +13655,11 @@ function createTurnRuntime(deps) {
|
|
|
13235
13655
|
if (summary.hadUsage && (summary.tokens > 0 || summary.costUsd > 0)) {
|
|
13236
13656
|
deps.observability.recordTokens(
|
|
13237
13657
|
localRuntime.targetId,
|
|
13238
|
-
|
|
13658
|
+
attributedModelId(
|
|
13659
|
+
summary.lastResponseModelIdObservation,
|
|
13660
|
+
localRuntime.wireModelId,
|
|
13661
|
+
summary.lastDifferingResponseModelId
|
|
13662
|
+
),
|
|
13239
13663
|
summary.tokens,
|
|
13240
13664
|
summary.costUsd,
|
|
13241
13665
|
{
|
|
@@ -13247,7 +13671,11 @@ function createTurnRuntime(deps) {
|
|
|
13247
13671
|
totalTokens: summary.tokens,
|
|
13248
13672
|
apiCalls: summary.apiCalls
|
|
13249
13673
|
},
|
|
13250
|
-
localRuntime.runtimeResolution.costProvenance
|
|
13674
|
+
localRuntime.runtimeResolution.costProvenance,
|
|
13675
|
+
{
|
|
13676
|
+
requestedModelIds: [localRuntime.wireModelId],
|
|
13677
|
+
responseModelIdObservationCounts: summary.responseModelIdObservationCounts
|
|
13678
|
+
}
|
|
13251
13679
|
);
|
|
13252
13680
|
}
|
|
13253
13681
|
if (summary.output > 0 && firstAssistantDeltaAt !== null) {
|
|
@@ -13372,6 +13800,7 @@ function createTurnState(initialThinkingLevel) {
|
|
|
13372
13800
|
streamStallReason: null,
|
|
13373
13801
|
toolProseAssessedChars: 0,
|
|
13374
13802
|
turnToolCalls: 0,
|
|
13803
|
+
turnToolNames: [],
|
|
13375
13804
|
turnSharedWorkerNote: false,
|
|
13376
13805
|
stalledTurnNudgeSpent: false,
|
|
13377
13806
|
pendingRequestContinuation: false,
|
|
@@ -13550,6 +13979,8 @@ function createChatLoop(deps) {
|
|
|
13550
13979
|
emitNotice,
|
|
13551
13980
|
toolStartTimes
|
|
13552
13981
|
});
|
|
13982
|
+
void turnRuntime.ensureLiveCapabilitiesForSelectedModel().catch(() => {
|
|
13983
|
+
});
|
|
13553
13984
|
const unsubscribeConfigReload = deps.bus?.on(BusChannels.ConfigHotReload, () => {
|
|
13554
13985
|
context.invalidateSessionPromptCache();
|
|
13555
13986
|
}) ?? null;
|
|
@@ -13631,6 +14062,7 @@ function createChatLoop(deps) {
|
|
|
13631
14062
|
return;
|
|
13632
14063
|
}
|
|
13633
14064
|
state.turnToolCalls = 0;
|
|
14065
|
+
state.turnToolNames = [];
|
|
13634
14066
|
state.turnSharedWorkerNote = isWorkerShareNote(text);
|
|
13635
14067
|
middlewareToolChoice.reset();
|
|
13636
14068
|
if (options.requestContinuation !== true) state.stalledTurnNudgeSpent = false;
|
|
@@ -13869,6 +14301,8 @@ function createChatLoop(deps) {
|
|
|
13869
14301
|
middlewareToolChoice.reset();
|
|
13870
14302
|
state.lastTurnId = leafTurnId;
|
|
13871
14303
|
context.resetForSession();
|
|
14304
|
+
void turnRuntime.ensureLiveCapabilitiesForSelectedModel().catch(() => {
|
|
14305
|
+
});
|
|
13872
14306
|
state.replayedContextMessages = replayMessages ? [...replayMessages] : [];
|
|
13873
14307
|
if (state.runtime) {
|
|
13874
14308
|
state.runtime.agent.state.messages = [...state.replayedContextMessages];
|
|
@@ -14031,264 +14465,6 @@ init_esm_shims();
|
|
|
14031
14465
|
// src/interactive/overlays/ask-user.ts
|
|
14032
14466
|
init_esm_shims();
|
|
14033
14467
|
|
|
14034
|
-
// src/interactive/overlay-frame.ts
|
|
14035
|
-
init_esm_shims();
|
|
14036
|
-
var DEFAULT_SELECT_THEME = selectListTheme(clioTheme());
|
|
14037
|
-
var DEFAULT_SETTINGS_THEME = settingsListTheme(clioTheme());
|
|
14038
|
-
var FocusBox = class extends Box {
|
|
14039
|
-
inputTarget;
|
|
14040
|
-
onInput;
|
|
14041
|
-
constructor(children, options) {
|
|
14042
|
-
super(options?.x ?? 1, options?.y ?? 0);
|
|
14043
|
-
const childList = Array.isArray(children) ? children : [children];
|
|
14044
|
-
for (const child of childList) this.addChild(child);
|
|
14045
|
-
this.inputTarget = options?.inputTarget === void 0 ? childList[0] ?? null : options.inputTarget;
|
|
14046
|
-
this.onInput = options?.onInput;
|
|
14047
|
-
}
|
|
14048
|
-
handleInput(data) {
|
|
14049
|
-
if (this.onInput) {
|
|
14050
|
-
this.onInput(data);
|
|
14051
|
-
return;
|
|
14052
|
-
}
|
|
14053
|
-
this.inputTarget?.handleInput?.(data);
|
|
14054
|
-
}
|
|
14055
|
-
};
|
|
14056
|
-
function resolveTone(tone) {
|
|
14057
|
-
return typeof tone === "function" ? tone() : tone;
|
|
14058
|
-
}
|
|
14059
|
-
function clioFrame(text, token = "frame") {
|
|
14060
|
-
return clioTheme().fg(token, text);
|
|
14061
|
-
}
|
|
14062
|
-
function clioTitle(text, token) {
|
|
14063
|
-
return token === void 0 ? screenTitle(clioTheme(), text) : clioTheme().style(token, text, { bold: true });
|
|
14064
|
-
}
|
|
14065
|
-
function clioError(text) {
|
|
14066
|
-
return clioTheme().fg("error", text);
|
|
14067
|
-
}
|
|
14068
|
-
function brandedTopBorder(label, innerWidth, tone) {
|
|
14069
|
-
const frame2 = (text) => clioFrame(text, tone ?? "frame");
|
|
14070
|
-
const clean = label.replace(/^[┌┐└┘├┤─│\s]+/, "").replace(/[┌┐└┘├┤─│\s]+$/, "");
|
|
14071
|
-
const formatted = clean.length > 0 ? `\u2500 ${clean} ` : "\u2500";
|
|
14072
|
-
const clipped = visibleWidth(formatted) > innerWidth ? truncateToWidth(formatted, innerWidth, "\u2026", true) : formatted;
|
|
14073
|
-
const fill = "\u2500".repeat(Math.max(0, innerWidth - visibleWidth(clipped)));
|
|
14074
|
-
const cleanIndex = clipped.indexOf(clean);
|
|
14075
|
-
if (cleanIndex !== -1) {
|
|
14076
|
-
const prefix = clipped.slice(0, cleanIndex);
|
|
14077
|
-
const suffix = clipped.slice(cleanIndex + clean.length);
|
|
14078
|
-
return `${frame2("\u250C")}${frame2(prefix)}${clioTitle(clean, tone)}${frame2(suffix)}${frame2(fill)}${frame2("\u2510")}`;
|
|
14079
|
-
}
|
|
14080
|
-
return `${frame2("\u250C")}${frame2(clipped)}${frame2(fill)}${frame2("\u2510")}`;
|
|
14081
|
-
}
|
|
14082
|
-
function isCriticalHintKey(key) {
|
|
14083
|
-
const canonical = canonicalizeKey(key);
|
|
14084
|
-
return canonical === "Esc" || canonical === "Enter" || canonical === "Enter/Space" || canonical === "type";
|
|
14085
|
-
}
|
|
14086
|
-
function isCriticalEntry(entry) {
|
|
14087
|
-
return entry.critical ?? isCriticalHintKey(entry.key);
|
|
14088
|
-
}
|
|
14089
|
-
function renderHintEntries(entries, short) {
|
|
14090
|
-
return entries.map((entry) => `[${canonicalizeKey(entry.key)}] ${short ? entry.short ?? entry.verb : entry.verb}`).join(" \xB7 ");
|
|
14091
|
-
}
|
|
14092
|
-
function fitHintEntries(entries, maxWidth) {
|
|
14093
|
-
if (entries.length === 0) return "";
|
|
14094
|
-
for (const short of [false, true]) {
|
|
14095
|
-
const rendered = renderHintEntries(entries, short);
|
|
14096
|
-
if (visibleWidth(rendered) <= maxWidth) return rendered;
|
|
14097
|
-
}
|
|
14098
|
-
const kept = [...entries];
|
|
14099
|
-
for (const criticalPass of [false, true]) {
|
|
14100
|
-
while (kept.length > 1) {
|
|
14101
|
-
const index = kept.findIndex((entry) => criticalPass || !isCriticalEntry(entry));
|
|
14102
|
-
if (index === -1) break;
|
|
14103
|
-
kept.splice(index, 1);
|
|
14104
|
-
const rendered = renderHintEntries(kept, true);
|
|
14105
|
-
if (visibleWidth(rendered) <= maxWidth) return rendered;
|
|
14106
|
-
}
|
|
14107
|
-
}
|
|
14108
|
-
return renderHintEntries(kept, true);
|
|
14109
|
-
}
|
|
14110
|
-
var FILTER_HINT = { key: "type", verb: "filter" };
|
|
14111
|
-
function canonicalizeKey(key) {
|
|
14112
|
-
const trimmed = key.trim();
|
|
14113
|
-
if (trimmed === "R") return "R";
|
|
14114
|
-
const lower = trimmed.toLowerCase();
|
|
14115
|
-
if (lower === "up/down" || lower === "updown" || lower === "\u2191/\u2193" || lower === "up/down/j/k" || lower === "\u2191\u2193")
|
|
14116
|
-
return "\u2191\u2193";
|
|
14117
|
-
if (lower === "enter/space") return "Enter/Space";
|
|
14118
|
-
if (lower === "enter") return "Enter";
|
|
14119
|
-
if (lower === "esc" || lower === "escape") return "Esc";
|
|
14120
|
-
if (lower === "space") return "Space";
|
|
14121
|
-
if (lower === "tab") return "Tab";
|
|
14122
|
-
if (lower === "r") return "r";
|
|
14123
|
-
if (lower === "type") return "type";
|
|
14124
|
-
return trimmed;
|
|
14125
|
-
}
|
|
14126
|
-
function buildHint(entries, esc = "close") {
|
|
14127
|
-
const finalEntries = [
|
|
14128
|
-
...entries.map((e) => ({ key: canonicalizeKey(e.key), verb: e.verb })),
|
|
14129
|
-
{ key: "Esc", verb: esc }
|
|
14130
|
-
];
|
|
14131
|
-
return finalEntries.map((e) => `[${e.key}] ${e.verb}`).join(" \xB7 ");
|
|
14132
|
-
}
|
|
14133
|
-
function buildResponsiveHint(entries, esc = "close") {
|
|
14134
|
-
const escEntry = esc === null ? null : typeof esc === "string" ? { key: "Esc", verb: esc } : esc;
|
|
14135
|
-
const all = escEntry ? [...entries, escEntry] : [...entries];
|
|
14136
|
-
return (innerWidth) => fitHintEntries(all, innerWidth - 3);
|
|
14137
|
-
}
|
|
14138
|
-
function elideHint(hint, maxCleanWidth) {
|
|
14139
|
-
const parts = hint.split(" \xB7 ");
|
|
14140
|
-
if (parts.length <= 2) return hint;
|
|
14141
|
-
const entries = parts.map((part) => {
|
|
14142
|
-
const match = /^\[([^\]]+)\] ([\s\S]+)$/u.exec(part);
|
|
14143
|
-
if (!match) return { key: "", verb: part, critical: false };
|
|
14144
|
-
return { key: match[1] ?? "", verb: match[2] ?? "" };
|
|
14145
|
-
});
|
|
14146
|
-
const rendered = fitHintEntries(entries, maxCleanWidth);
|
|
14147
|
-
return rendered.replace(/\[\] /gu, "");
|
|
14148
|
-
}
|
|
14149
|
-
function brandedBottomBorder(innerWidth, hint, tone) {
|
|
14150
|
-
const frame2 = (text) => clioFrame(text, tone ?? "frame");
|
|
14151
|
-
if (!hint || hint.trim().length === 0) {
|
|
14152
|
-
return `${frame2("\u2514")}${frame2("\u2500".repeat(innerWidth))}${frame2("\u2518")}`;
|
|
14153
|
-
}
|
|
14154
|
-
let clean = hint.trim();
|
|
14155
|
-
const maxCleanWidth = innerWidth - 3;
|
|
14156
|
-
if (clean.includes(" \xB7 ") && visibleWidth(`\u2500 ${clean} `) > innerWidth) {
|
|
14157
|
-
clean = elideHint(clean, maxCleanWidth);
|
|
14158
|
-
}
|
|
14159
|
-
const formatted = `\u2500 ${clean} `;
|
|
14160
|
-
const clipped = visibleWidth(formatted) > innerWidth ? truncateToWidth(formatted, innerWidth, "\u2026", true) : formatted;
|
|
14161
|
-
const fill = "\u2500".repeat(Math.max(0, innerWidth - visibleWidth(clipped)));
|
|
14162
|
-
const cleanIndex = clipped.indexOf(clean);
|
|
14163
|
-
if (cleanIndex !== -1) {
|
|
14164
|
-
const prefix = clipped.slice(0, cleanIndex);
|
|
14165
|
-
const suffix = clipped.slice(cleanIndex + clean.length);
|
|
14166
|
-
return `${frame2("\u2514")}${frame2(prefix)}${clioTheme().fg("dim", clean)}${frame2(suffix)}${frame2(fill)}${frame2("\u2518")}`;
|
|
14167
|
-
}
|
|
14168
|
-
return `${frame2("\u2514")}${frame2(clipped)}${frame2(fill)}${frame2("\u2518")}`;
|
|
14169
|
-
}
|
|
14170
|
-
function formatRuntimeResolutionDiagnostic(diagnostic) {
|
|
14171
|
-
return `${diagnostic.severity}: ${diagnostic.code}: ${diagnostic.message}`;
|
|
14172
|
-
}
|
|
14173
|
-
function diagnosticSeverityToken(severity) {
|
|
14174
|
-
return severity === "error" ? "error" : severity === "warning" ? "warning" : "muted";
|
|
14175
|
-
}
|
|
14176
|
-
function runtimeResolutionDiagnosticLine(diagnostic, width) {
|
|
14177
|
-
return clioTheme().fg(diagnosticSeverityToken(diagnostic.severity), fitDiagnosticLine(diagnostic, width));
|
|
14178
|
-
}
|
|
14179
|
-
function fitDiagnosticLine(diagnostic, width) {
|
|
14180
|
-
return padAnsi(formatRuntimeResolutionDiagnostic(diagnostic), Math.max(1, width));
|
|
14181
|
-
}
|
|
14182
|
-
function frameAlignForAnchor(anchor) {
|
|
14183
|
-
if (anchor === void 0) return "center";
|
|
14184
|
-
if (anchor === "left-center" || anchor.endsWith("-left")) return "left";
|
|
14185
|
-
if (anchor === "right-center" || anchor.endsWith("-right")) return "right";
|
|
14186
|
-
return "center";
|
|
14187
|
-
}
|
|
14188
|
-
function fitBody(lines, rowBudget, contentWidth) {
|
|
14189
|
-
if (rowBudget <= 0) return lines;
|
|
14190
|
-
const bodyBudget = Math.max(1, rowBudget - 2);
|
|
14191
|
-
if (lines.length <= bodyBudget) return lines;
|
|
14192
|
-
const kept = lines.slice(0, bodyBudget - 1);
|
|
14193
|
-
const hidden = lines.length - kept.length;
|
|
14194
|
-
return [...kept, clioTheme().fg("dim", truncateToWidth(`\u2026 ${hidden} more rows`, contentWidth, "", true))];
|
|
14195
|
-
}
|
|
14196
|
-
var ClioOverlayFrame = class {
|
|
14197
|
-
constructor(child, title, footerHint, boxWidth = 0, align = "center", tone) {
|
|
14198
|
-
this.child = child;
|
|
14199
|
-
this.title = title;
|
|
14200
|
-
this.footerHint = footerHint;
|
|
14201
|
-
this.boxWidth = boxWidth;
|
|
14202
|
-
this.align = align;
|
|
14203
|
-
this.tone = tone;
|
|
14204
|
-
}
|
|
14205
|
-
child;
|
|
14206
|
-
title;
|
|
14207
|
-
footerHint;
|
|
14208
|
-
boxWidth;
|
|
14209
|
-
align;
|
|
14210
|
-
tone;
|
|
14211
|
-
/**
|
|
14212
|
-
* Rows the box may occupy, or zero while unknown.
|
|
14213
|
-
*
|
|
14214
|
-
* `Component.render` is handed a width and nothing else, so the frame learns
|
|
14215
|
-
* its height budget from the engine's `visible` predicate, which is called
|
|
14216
|
-
* with the live terminal size immediately before the render pass that
|
|
14217
|
-
* composites this overlay.
|
|
14218
|
-
*/
|
|
14219
|
-
rowBudget = 0;
|
|
14220
|
-
/**
|
|
14221
|
-
* Last rendered box, keyed by everything that shapes it. `childLines` is
|
|
14222
|
-
* compared by array identity: a child that rebuilds its rows returns a fresh
|
|
14223
|
-
* array and correctly misses, and one that serves a cache returns the same
|
|
14224
|
-
* array and correctly hits.
|
|
14225
|
-
*/
|
|
14226
|
-
cachedRender;
|
|
14227
|
-
setRowBudget(rows) {
|
|
14228
|
-
this.rowBudget = Math.max(0, Math.floor(rows));
|
|
14229
|
-
}
|
|
14230
|
-
render(width) {
|
|
14231
|
-
const boxWidth = Math.max(5, Math.min(this.boxWidth > 0 ? this.boxWidth : width, width));
|
|
14232
|
-
const contentWidth = Math.max(1, boxWidth - 4);
|
|
14233
|
-
const childLines = this.child.render(contentWidth);
|
|
14234
|
-
const titleText = typeof this.title === "function" ? this.title() : this.title;
|
|
14235
|
-
const hint = typeof this.footerHint === "function" ? this.footerHint(contentWidth + 2) : this.footerHint;
|
|
14236
|
-
const tone = resolveTone(this.tone);
|
|
14237
|
-
const cached = this.cachedRender;
|
|
14238
|
-
if (cached !== void 0 && cached.width === width && cached.rowBudget === this.rowBudget && cached.childLines === childLines && cached.title === titleText && cached.hint === hint && cached.tone === tone) {
|
|
14239
|
-
return cached.lines;
|
|
14240
|
-
}
|
|
14241
|
-
const label = titleText.length > 0 ? `\u2500 ${titleText} ` : "\u2500 ";
|
|
14242
|
-
const side = clioFrame("\u2502", tone ?? "frame");
|
|
14243
|
-
const boxLines = [
|
|
14244
|
-
brandedTopBorder(label, contentWidth + 2, tone),
|
|
14245
|
-
...fitBody(childLines, this.rowBudget, contentWidth).map((line) => `${side} ${padAnsi(line, contentWidth)} ${side}`),
|
|
14246
|
-
brandedBottomBorder(contentWidth + 2, hint, tone)
|
|
14247
|
-
];
|
|
14248
|
-
const slack = Math.max(0, width - boxWidth);
|
|
14249
|
-
const lines = (() => {
|
|
14250
|
-
if (slack === 0) return boxLines;
|
|
14251
|
-
const leading = this.align === "left" ? 0 : this.align === "right" ? slack : Math.floor(slack / 2);
|
|
14252
|
-
const lead = " ".repeat(leading);
|
|
14253
|
-
const trail = " ".repeat(slack - leading);
|
|
14254
|
-
return boxLines.map((line) => `${lead}${line}${trail}`);
|
|
14255
|
-
})();
|
|
14256
|
-
this.cachedRender = { width, rowBudget: this.rowBudget, childLines, title: titleText, hint, tone, lines };
|
|
14257
|
-
return lines;
|
|
14258
|
-
}
|
|
14259
|
-
handleInput(data) {
|
|
14260
|
-
this.child.handleInput?.(data);
|
|
14261
|
-
}
|
|
14262
|
-
invalidate() {
|
|
14263
|
-
this.cachedRender = void 0;
|
|
14264
|
-
this.child.invalidate?.();
|
|
14265
|
-
}
|
|
14266
|
-
};
|
|
14267
|
-
function showClioOverlayFrame(tui, child, options) {
|
|
14268
|
-
const { title, footerHint, tone, width, visible, maxHeight, margin, ...overlayOptions } = options;
|
|
14269
|
-
const boxWidth = typeof width === "number" ? width : 0;
|
|
14270
|
-
const frame2 = new ClioOverlayFrame(child, title, footerHint, boxWidth, frameAlignForAnchor(options.anchor), tone);
|
|
14271
|
-
const marginRows = typeof margin === "number" ? margin * 2 : (margin?.top ?? 0) + (margin?.bottom ?? 0);
|
|
14272
|
-
return tui.showOverlay(frame2, {
|
|
14273
|
-
...overlayOptions,
|
|
14274
|
-
...margin !== void 0 ? { margin } : {},
|
|
14275
|
-
width: "100%",
|
|
14276
|
-
visible: (termWidth, termHeight) => {
|
|
14277
|
-
const available = Math.max(1, termHeight - marginRows);
|
|
14278
|
-
const requested = resolveRowSize(maxHeight, termHeight);
|
|
14279
|
-
frame2.setRowBudget(requested === null ? available : Math.min(requested, available));
|
|
14280
|
-
return visible ? visible(termWidth, termHeight) : true;
|
|
14281
|
-
}
|
|
14282
|
-
});
|
|
14283
|
-
}
|
|
14284
|
-
function resolveRowSize(value, termHeight) {
|
|
14285
|
-
if (typeof value === "number") return Math.max(1, Math.floor(value));
|
|
14286
|
-
if (typeof value !== "string") return null;
|
|
14287
|
-
const percent = /^(\d+(?:\.\d+)?)%$/u.exec(value.trim());
|
|
14288
|
-
if (!percent?.[1]) return null;
|
|
14289
|
-
return Math.max(1, Math.floor(termHeight * Number.parseFloat(percent[1]) / 100));
|
|
14290
|
-
}
|
|
14291
|
-
|
|
14292
14468
|
// src/interactive/view/view-overlay.ts
|
|
14293
14469
|
init_esm_shims();
|
|
14294
14470
|
var VIEW_OVERLAY_WIDTH = "100%";
|
|
@@ -14871,13 +15047,14 @@ function openViewOverlay(tui, options) {
|
|
|
14871
15047
|
}
|
|
14872
15048
|
|
|
14873
15049
|
// src/interactive/overlays/ask-user.ts
|
|
14874
|
-
var
|
|
14875
|
-
var
|
|
15050
|
+
var DEFAULT_ASK_USER_PRESENTATION = classifyDecisionPresentation(decisionFactsForAnswer("local"));
|
|
15051
|
+
var ASK_USER_DECISION_TONE = DEFAULT_ASK_USER_PRESENTATION.semanticToken;
|
|
15052
|
+
var ASK_USER_DECISION_TITLE = DEFAULT_ASK_USER_PRESENTATION.title;
|
|
14876
15053
|
var ASK_USER_WAITING_TITLE = "Ask User";
|
|
14877
15054
|
var ASK_USER_COMPACT_MAX_OPTIONS = 3;
|
|
14878
15055
|
var ASK_USER_DEFAULT_SURFACE = "panel";
|
|
14879
15056
|
var ASK_USER_SURFACE_GEOMETRY = {
|
|
14880
|
-
compact: { width: 68, maxInnerRows:
|
|
15057
|
+
compact: { width: 68, maxInnerRows: 14, anchor: "bottom-center", margin: { top: 1, right: 2, bottom: 1, left: 2 } },
|
|
14881
15058
|
panel: { width: 88, maxInnerRows: 18, anchor: "center", margin: 1 },
|
|
14882
15059
|
// The interview is a workspace, not a modal. A cap of 42 turned a 66-row
|
|
14883
15060
|
// terminal into a centered box with twenty blank rows around it, so the
|
|
@@ -14987,13 +15164,15 @@ var AskUserOverlayView = class {
|
|
|
14987
15164
|
contentRegionHeight = 1;
|
|
14988
15165
|
/** Rows the scroll region wanted on the last render. */
|
|
14989
15166
|
contentTotalRows = 0;
|
|
14990
|
-
|
|
15167
|
+
presentation = DEFAULT_ASK_USER_PRESENTATION;
|
|
15168
|
+
begin(questions, presentation = DEFAULT_ASK_USER_PRESENTATION) {
|
|
14991
15169
|
if (this.phase === "closed") return Promise.resolve(cancelledAskUserResult());
|
|
14992
15170
|
if (this.resolveCurrent) return Promise.resolve(cancelledAskUserResult());
|
|
14993
15171
|
this.phase = "asking";
|
|
14994
15172
|
this.index = 0;
|
|
14995
15173
|
this.status = "";
|
|
14996
15174
|
this.questions = [...questions];
|
|
15175
|
+
this.presentation = presentation;
|
|
14997
15176
|
this.states = this.questions.map((question) => createQuestionState(question));
|
|
14998
15177
|
this.list = null;
|
|
14999
15178
|
this.input = null;
|
|
@@ -15022,6 +15201,12 @@ var AskUserOverlayView = class {
|
|
|
15022
15201
|
currentSurface() {
|
|
15023
15202
|
return this.surface;
|
|
15024
15203
|
}
|
|
15204
|
+
decisionTitle() {
|
|
15205
|
+
return this.presentation.title;
|
|
15206
|
+
}
|
|
15207
|
+
decisionTone() {
|
|
15208
|
+
return this.presentation.semanticToken;
|
|
15209
|
+
}
|
|
15025
15210
|
invalidate() {
|
|
15026
15211
|
this.list?.invalidate();
|
|
15027
15212
|
this.input?.invalidate();
|
|
@@ -15083,9 +15268,16 @@ var AskUserOverlayView = class {
|
|
|
15083
15268
|
const statusLines = this.status.length > 0 ? ["", fitLine(clioTheme().fg("dim", this.status), safeWidth)] : [];
|
|
15084
15269
|
const headerLine4 = this.renderQuestionHeader(question, safeWidth);
|
|
15085
15270
|
const headerLines = headerLine4.length > 0 ? [headerLine4] : [];
|
|
15086
|
-
const
|
|
15087
|
-
const
|
|
15088
|
-
|
|
15271
|
+
const bottom = [...statusLines, "", ...controlLines];
|
|
15272
|
+
const topBudget = Math.max(1, maxRows - bottom.length);
|
|
15273
|
+
const contextLines = this.renderDecisionContext(safeWidth);
|
|
15274
|
+
const top = [
|
|
15275
|
+
contextLines[0] ?? "",
|
|
15276
|
+
...headerLines,
|
|
15277
|
+
...wrapTextWithAnsi(question.question, safeWidth),
|
|
15278
|
+
...contextLines.slice(1)
|
|
15279
|
+
].slice(0, topBudget);
|
|
15280
|
+
return [...top, ...bottom].slice(0, maxRows);
|
|
15089
15281
|
}
|
|
15090
15282
|
/**
|
|
15091
15283
|
* The interview, as a workspace with fixed chrome and a scrolling middle.
|
|
@@ -15103,7 +15295,12 @@ var AskUserOverlayView = class {
|
|
|
15103
15295
|
const headerLine4 = this.renderQuestionHeader(question, width);
|
|
15104
15296
|
const headerLines = headerLine4.length > 0 ? [headerLine4] : [];
|
|
15105
15297
|
const stripLines = [this.renderQuestionStrip(width), ""];
|
|
15106
|
-
const content = [
|
|
15298
|
+
const content = [
|
|
15299
|
+
...wrapTextWithAnsi(question.question, width),
|
|
15300
|
+
"",
|
|
15301
|
+
...this.renderDecisionContext(width),
|
|
15302
|
+
...this.renderAnswerLedger(width)
|
|
15303
|
+
];
|
|
15107
15304
|
let top = [...stripLines, ...headerLines];
|
|
15108
15305
|
let bottom = [...statusLines, "", ...controlLines];
|
|
15109
15306
|
const region = () => maxRows - top.length - bottom.length;
|
|
@@ -15167,26 +15364,40 @@ var AskUserOverlayView = class {
|
|
|
15167
15364
|
const question = this.currentQuestion();
|
|
15168
15365
|
const state = this.currentState();
|
|
15169
15366
|
if (!question || !state) return buildHint([]);
|
|
15367
|
+
const recordAnswer = this.presentation.requiredActions.find((action) => action.id === "record-answer")?.label.toLowerCase() ?? "record answer";
|
|
15170
15368
|
if (state.mode === "text") {
|
|
15171
15369
|
return this.questions.length > 1 ? this.withScrollHint([
|
|
15172
|
-
{ key: "Enter", verb:
|
|
15370
|
+
{ key: "Enter", verb: recordAnswer },
|
|
15173
15371
|
{ key: "Alt+Left/Right", verb: "question" }
|
|
15174
|
-
]) : this.withScrollHint([{ key: "Enter", verb:
|
|
15372
|
+
]) : this.withScrollHint([{ key: "Enter", verb: recordAnswer }]);
|
|
15175
15373
|
}
|
|
15176
15374
|
if (question.multi_select === true) {
|
|
15177
15375
|
return this.questions.length > 1 ? this.withScrollHint([
|
|
15178
15376
|
{ key: "Left/Right", verb: "question" },
|
|
15179
15377
|
{ key: "Space", verb: "toggle" },
|
|
15180
|
-
{ key: "Enter", verb:
|
|
15378
|
+
{ key: "Enter", verb: recordAnswer }
|
|
15181
15379
|
]) : this.withScrollHint([
|
|
15182
15380
|
{ key: "Space", verb: "toggle" },
|
|
15183
|
-
{ key: "Enter", verb:
|
|
15381
|
+
{ key: "Enter", verb: recordAnswer }
|
|
15184
15382
|
]);
|
|
15185
15383
|
}
|
|
15186
15384
|
return this.questions.length > 1 ? this.withScrollHint([
|
|
15187
15385
|
{ key: "Left/Right", verb: "question" },
|
|
15188
|
-
{ key: "Enter", verb:
|
|
15189
|
-
]) : this.withScrollHint([{ key: "Enter", verb:
|
|
15386
|
+
{ key: "Enter", verb: recordAnswer }
|
|
15387
|
+
]) : this.withScrollHint([{ key: "Enter", verb: recordAnswer }]);
|
|
15388
|
+
}
|
|
15389
|
+
renderDecisionContext(width) {
|
|
15390
|
+
const theme6 = clioTheme();
|
|
15391
|
+
const tier = theme6.style(this.presentation.semanticToken, this.presentation.tierLabel, { bold: true });
|
|
15392
|
+
const requested = theme6.fg("dim", `requested by ${this.presentation.requestedByCopy}`);
|
|
15393
|
+
const effect = `${theme6.fg("dim", "Effect:")} ${theme6.fg("muted", this.presentation.authorizationCopy)}`;
|
|
15394
|
+
return [
|
|
15395
|
+
fitLine(`${tier}${dotSep(theme6)}${requested}`, width),
|
|
15396
|
+
...wrapTextWithAnsi(effect, width).map((line) => fitLine(line, width)),
|
|
15397
|
+
...wrapTextWithAnsi(theme6.fg("muted", this.presentation.reversibilityCopy), width).map(
|
|
15398
|
+
(line) => fitLine(line, width)
|
|
15399
|
+
)
|
|
15400
|
+
];
|
|
15190
15401
|
}
|
|
15191
15402
|
/**
|
|
15192
15403
|
* The keys for this question, plus the scroll keys when there is something to
|
|
@@ -15624,8 +15835,8 @@ function openAskUserOverlay(tui, deps) {
|
|
|
15624
15835
|
// the terminal has left after the margins.
|
|
15625
15836
|
...geometry.maxInnerRows > 0 ? { maxHeight: geometry.maxInnerRows + ASK_USER_FRAME_ROWS } : {},
|
|
15626
15837
|
margin: geometry.margin,
|
|
15627
|
-
title: () => view.isDecisionPending() ?
|
|
15628
|
-
tone: () => view.isDecisionPending() ?
|
|
15838
|
+
title: () => view.isDecisionPending() ? view.decisionTitle() : ASK_USER_WAITING_TITLE,
|
|
15839
|
+
tone: () => view.isDecisionPending() ? view.decisionTone() : void 0,
|
|
15629
15840
|
footerHint: () => view.footerHint()
|
|
15630
15841
|
});
|
|
15631
15842
|
mounted = surface;
|
|
@@ -15644,7 +15855,7 @@ function openAskUserOverlay(tui, deps) {
|
|
|
15644
15855
|
focus: () => handle?.focus(),
|
|
15645
15856
|
unfocus: (options) => options ? handle?.unfocus(options) : handle?.unfocus(),
|
|
15646
15857
|
isFocused: () => handle?.isFocused() ?? false,
|
|
15647
|
-
ask: (questions) => view.begin(questions),
|
|
15858
|
+
ask: (questions, presentation) => view.begin(questions, presentation),
|
|
15648
15859
|
cancel: () => view.cancel(),
|
|
15649
15860
|
close,
|
|
15650
15861
|
hide: close,
|
|
@@ -15699,7 +15910,7 @@ function createOverlayAskUserLifecycle(deps) {
|
|
|
15699
15910
|
const activeSession = ensureSession();
|
|
15700
15911
|
if (!activeSession) return cancelledAskUserResult();
|
|
15701
15912
|
pendingCancel = cancel;
|
|
15702
|
-
const result = await activeSession.ask(questions);
|
|
15913
|
+
const result = await activeSession.ask(questions, invokeOptions?.decisionPresentation);
|
|
15703
15914
|
if (result.cancelled === true || !toolBacked) {
|
|
15704
15915
|
if (result.cancelled === true) cancelledForTurn = true;
|
|
15705
15916
|
close();
|
|
@@ -16192,7 +16403,50 @@ function legendRow2(group, contentWidth) {
|
|
|
16192
16403
|
const labelText = group.label.length > leftWidth ? group.label.slice(0, leftWidth) : group.label.padEnd(leftWidth);
|
|
16193
16404
|
return `${swatch} ${theme6.fg(labelToken, labelText)} ${theme6.fg("muted", right)}`;
|
|
16194
16405
|
}
|
|
16195
|
-
function
|
|
16406
|
+
function evictedTokens(view) {
|
|
16407
|
+
let total = 0;
|
|
16408
|
+
for (const state of view.evicted.values()) total += state.tokensFreed;
|
|
16409
|
+
return total;
|
|
16410
|
+
}
|
|
16411
|
+
function formatChurn(view) {
|
|
16412
|
+
if (view.itemsEvicted === 0) return "n/a";
|
|
16413
|
+
return (view.recalls / view.itemsEvicted).toFixed(2);
|
|
16414
|
+
}
|
|
16415
|
+
function coldReasonLabel(reason) {
|
|
16416
|
+
switch (reason) {
|
|
16417
|
+
case "working_set_evict":
|
|
16418
|
+
return "working-set eviction";
|
|
16419
|
+
case "compaction":
|
|
16420
|
+
return "compaction";
|
|
16421
|
+
case "dispatch":
|
|
16422
|
+
return "dispatch traffic";
|
|
16423
|
+
default:
|
|
16424
|
+
return reason;
|
|
16425
|
+
}
|
|
16426
|
+
}
|
|
16427
|
+
function workingSetPolicyLabel(view, config) {
|
|
16428
|
+
if (config === null || config === void 0) return `policy ${view.lastPolicyId ?? "none"}`;
|
|
16429
|
+
if (!config.enabled) return "disabled";
|
|
16430
|
+
const state = view.evictionEvents === 0 ? " \xB7 no events yet" : "";
|
|
16431
|
+
const lastRan = view.lastPolicyId !== null && view.lastPolicyId !== config.policy ? ` (last event by ${view.lastPolicyId})` : "";
|
|
16432
|
+
return `policy ${config.policy}${lastRan}${state}`;
|
|
16433
|
+
}
|
|
16434
|
+
function renderWorkingSetLines(view, config) {
|
|
16435
|
+
const theme6 = clioTheme();
|
|
16436
|
+
const items = view.evicted.size;
|
|
16437
|
+
const summary = [
|
|
16438
|
+
`${items} evicted item${items === 1 ? "" : "s"}`,
|
|
16439
|
+
`${formatTokens(evictedTokens(view))} tokens`,
|
|
16440
|
+
`${view.evictionEvents} event${view.evictionEvents === 1 ? "" : "s"}`,
|
|
16441
|
+
`${view.recalls} recall${view.recalls === 1 ? "" : "s"}`,
|
|
16442
|
+
`churn ${formatChurn(view)}`
|
|
16443
|
+
].join(" \xB7 ");
|
|
16444
|
+
return [
|
|
16445
|
+
`${theme6.fg("muted", "working set")} ${theme6.fg("dim", "\xB7")} ${theme6.fg("accent", workingSetPolicyLabel(view, config))}`,
|
|
16446
|
+
theme6.fg("dim", summary)
|
|
16447
|
+
];
|
|
16448
|
+
}
|
|
16449
|
+
function renderContextLedgerLines(ledger, contentWidth, workingSet, workingSetConfig) {
|
|
16196
16450
|
const theme6 = clioTheme();
|
|
16197
16451
|
const lines = [];
|
|
16198
16452
|
const provider = ledger.provider ?? "no target";
|
|
@@ -16206,7 +16460,8 @@ function renderContextLedgerLines(ledger, contentWidth) {
|
|
|
16206
16460
|
lines.push("");
|
|
16207
16461
|
if (ledger.contextWindow > 0) {
|
|
16208
16462
|
const source = ledger.measured ? "measured" : "\u2248 estimated";
|
|
16209
|
-
const
|
|
16463
|
+
const window = ledger.contextWindowSlots ? formatContextWindowSlots(ledger.contextWindow, ledger.contextWindowSlots) : formatTokens(ledger.contextWindow);
|
|
16464
|
+
const summary = `${formatTokens(ledger.usedTokens)} / ${window} tokens (${formatContextPercent(ledger.percent)})`;
|
|
16210
16465
|
const provenance = contextWindowProvenanceLabel(ledger.contextWindowSource);
|
|
16211
16466
|
const trailer = provenance ? `${provenance} window \xB7 ${source}` : source;
|
|
16212
16467
|
lines.push(`${theme6.fg("title", summary)} ${theme6.fg("dim", "\xB7")} ${theme6.fg("muted", trailer)}`);
|
|
@@ -16217,7 +16472,12 @@ function renderContextLedgerLines(ledger, contentWidth) {
|
|
|
16217
16472
|
}
|
|
16218
16473
|
lines.push("");
|
|
16219
16474
|
for (const group of ledger.meter) lines.push(legendRow2(group, contentWidth));
|
|
16475
|
+
if (workingSet && workingSet.evicted.size > 0) lines.push(renderEvictedTokensLine(evictedTokens(workingSet), theme6));
|
|
16220
16476
|
lines.push("");
|
|
16477
|
+
if (workingSet) {
|
|
16478
|
+
for (const line of renderWorkingSetLines(workingSet, workingSetConfig)) lines.push(line);
|
|
16479
|
+
lines.push("");
|
|
16480
|
+
}
|
|
16221
16481
|
if (ledger.projectPreload && ledger.groups.some((group) => group.category === "project")) {
|
|
16222
16482
|
lines.push(theme6.fg("dim", `project preload: ${ledger.projectPreload}`));
|
|
16223
16483
|
}
|
|
@@ -16235,8 +16495,13 @@ function renderContextLedgerLines(ledger, contentWidth) {
|
|
|
16235
16495
|
const read = cache2.cacheReadTokens !== null ? `cache read ${formatTokens(cache2.cacheReadTokens)}` : "cache read n/a";
|
|
16236
16496
|
const uncached = cache2.uncachedInputTokens !== null ? `uncached input ${formatTokens(cache2.uncachedInputTokens)}` : null;
|
|
16237
16497
|
const line = ["prompt cache:", shell, "\xB7", backend, "\xB7", read, ...uncached ? ["\xB7", uncached] : []].join(" ");
|
|
16238
|
-
const
|
|
16498
|
+
const coldReasons = cache2.backendVerdict === "cold" ? cache2.expectedColdReasons ?? [] : [];
|
|
16499
|
+
const misleading = cache2.shellReused && cache2.backendVerdict === "cold" && coldReasons.length === 0;
|
|
16239
16500
|
lines.push(theme6.fg(misleading ? "warning" : "dim", line));
|
|
16501
|
+
if (coldReasons.length > 0) {
|
|
16502
|
+
const reasons = coldReasons.map(coldReasonLabel).join(", ");
|
|
16503
|
+
lines.push(theme6.fg("dim", `last cold turn: ${reasons} (expected)`));
|
|
16504
|
+
}
|
|
16240
16505
|
}
|
|
16241
16506
|
if (ledger.lastCompaction) {
|
|
16242
16507
|
const pruneInfo = `last compaction: reclaimed ${formatTokens(ledger.lastCompaction.tokensBefore)} -> ${formatTokens(ledger.lastCompaction.tokensAfter)} tokens (${ledger.lastCompaction.stage})`;
|
|
@@ -16246,7 +16511,13 @@ function renderContextLedgerLines(ledger, contentWidth) {
|
|
|
16246
16511
|
}
|
|
16247
16512
|
var STREAMING_FALLBACK_TICK_MS = 1e3;
|
|
16248
16513
|
function openContextOverlay(tui, getLedger, options) {
|
|
16249
|
-
const
|
|
16514
|
+
const render2 = () => renderContextLedgerLines(
|
|
16515
|
+
getLedger(),
|
|
16516
|
+
DEFAULT_CONTENT_WIDTH,
|
|
16517
|
+
options?.getWorkingSet?.() ?? null,
|
|
16518
|
+
options?.getWorkingSetConfig?.() ?? null
|
|
16519
|
+
).join("\n");
|
|
16520
|
+
const text = new Text(render2(), 0, 0);
|
|
16250
16521
|
const handle = showClioOverlayFrame(tui, text, {
|
|
16251
16522
|
anchor: "center",
|
|
16252
16523
|
width: CONTEXT_OVERLAY_WIDTH,
|
|
@@ -16254,7 +16525,7 @@ function openContextOverlay(tui, getLedger, options) {
|
|
|
16254
16525
|
footerHint: buildHint([])
|
|
16255
16526
|
});
|
|
16256
16527
|
const refresh = () => {
|
|
16257
|
-
text.setText(
|
|
16528
|
+
text.setText(render2());
|
|
16258
16529
|
text.invalidate();
|
|
16259
16530
|
tui.requestRender();
|
|
16260
16531
|
};
|
|
@@ -16312,7 +16583,7 @@ function formatTokens2(n) {
|
|
|
16312
16583
|
function aggregateCostEntries(entries) {
|
|
16313
16584
|
const grouped = /* @__PURE__ */ new Map();
|
|
16314
16585
|
for (const entry of entries) {
|
|
16315
|
-
const key = `${entry.providerId}::${entry.
|
|
16586
|
+
const key = `${entry.providerId}::${entry.attributedModelId}`;
|
|
16316
16587
|
const existing = grouped.get(key);
|
|
16317
16588
|
if (existing) {
|
|
16318
16589
|
existing.row.runs += 1;
|
|
@@ -16323,13 +16594,18 @@ function aggregateCostEntries(entries) {
|
|
|
16323
16594
|
existing.row.cacheWrite += entry.cacheWrite;
|
|
16324
16595
|
existing.row.reasoningTokens += entry.reasoningTokens;
|
|
16325
16596
|
existing.row.apiCalls += entry.apiCalls ?? 1;
|
|
16597
|
+
for (const requestedModelId of entry.requestedModelIds) existing.requestedModelIds.add(requestedModelId);
|
|
16598
|
+
addResponseModelIdObservationCounts(
|
|
16599
|
+
existing.responseModelIdObservationCounts,
|
|
16600
|
+
entry.responseModelIdObservationCounts
|
|
16601
|
+
);
|
|
16326
16602
|
existing.entries.push(entry);
|
|
16327
16603
|
continue;
|
|
16328
16604
|
}
|
|
16329
16605
|
grouped.set(key, {
|
|
16330
16606
|
row: {
|
|
16331
16607
|
providerId: entry.providerId,
|
|
16332
|
-
|
|
16608
|
+
attributedModelId: entry.attributedModelId,
|
|
16333
16609
|
runs: 1,
|
|
16334
16610
|
tokens: entry.tokens,
|
|
16335
16611
|
input: entry.input,
|
|
@@ -16339,16 +16615,20 @@ function aggregateCostEntries(entries) {
|
|
|
16339
16615
|
reasoningTokens: entry.reasoningTokens,
|
|
16340
16616
|
apiCalls: entry.apiCalls ?? 1
|
|
16341
16617
|
},
|
|
16618
|
+
requestedModelIds: new Set(entry.requestedModelIds),
|
|
16619
|
+
responseModelIdObservationCounts: { ...entry.responseModelIdObservationCounts },
|
|
16342
16620
|
entries: [entry]
|
|
16343
16621
|
});
|
|
16344
16622
|
}
|
|
16345
|
-
const rows = Array.from(grouped.values(), ({ row: row2, entries: entries2 }) => ({
|
|
16623
|
+
const rows = Array.from(grouped.values(), ({ row: row2, entries: entries2, requestedModelIds, responseModelIdObservationCounts }) => ({
|
|
16346
16624
|
...row2,
|
|
16625
|
+
requestedModelIds: [...requestedModelIds].sort(),
|
|
16626
|
+
responseModelIdObservationCounts,
|
|
16347
16627
|
cost: aggregateCostAmounts(entries2.map((entry) => ({ usd: entry.usd, provenance: entry.provenance })))
|
|
16348
16628
|
}));
|
|
16349
16629
|
rows.sort((a, b) => {
|
|
16350
16630
|
if (a.providerId !== b.providerId) return a.providerId < b.providerId ? -1 : 1;
|
|
16351
|
-
if (a.
|
|
16631
|
+
if (a.attributedModelId !== b.attributedModelId) return a.attributedModelId < b.attributedModelId ? -1 : 1;
|
|
16352
16632
|
return 0;
|
|
16353
16633
|
});
|
|
16354
16634
|
return rows;
|
|
@@ -16405,6 +16685,8 @@ function summaryBlock(totalCost, totalTokens, rows) {
|
|
|
16405
16685
|
function modelBlock(row2) {
|
|
16406
16686
|
const cost = formatCostAggregate(row2.cost);
|
|
16407
16687
|
return kvBlock([
|
|
16688
|
+
["requested model ids", row2.requestedModelIds.join(", ")],
|
|
16689
|
+
["response model id observation", responseModelIdObservationCountsLabel(row2.responseModelIdObservationCounts)],
|
|
16408
16690
|
["turns", formatTokens2(row2.runs)],
|
|
16409
16691
|
["model calls", formatTokens2(row2.apiCalls)],
|
|
16410
16692
|
...cost === null ? [] : [["cost", cost]],
|
|
@@ -16428,7 +16710,7 @@ function formatCostOverlayBodyLines(totalCost, totalTokens, rows, contentWidth)
|
|
|
16428
16710
|
} else {
|
|
16429
16711
|
for (const [index, row2] of rows.entries()) {
|
|
16430
16712
|
if (index > 0) lines.push("");
|
|
16431
|
-
lines.push(theme6.style("accent", `${row2.providerId} \xB7 ${row2.
|
|
16713
|
+
lines.push(theme6.style("accent", `${row2.providerId} \xB7 attributed model ${row2.attributedModelId}`, { bold: true }));
|
|
16432
16714
|
for (const line of modelBlock(row2)) {
|
|
16433
16715
|
lines.push(line);
|
|
16434
16716
|
}
|
|
@@ -17063,9 +17345,10 @@ function memorySignature(status, records) {
|
|
|
17063
17345
|
return parts.join("|");
|
|
17064
17346
|
}
|
|
17065
17347
|
var MemoryOverlayView = class {
|
|
17066
|
-
constructor(getStatus, getRecords, onClose, onChange) {
|
|
17348
|
+
constructor(getStatus, getRecords, onClose, onChange, promotion) {
|
|
17067
17349
|
this.getStatus = getStatus;
|
|
17068
17350
|
this.getRecords = getRecords;
|
|
17351
|
+
this.promotion = promotion;
|
|
17069
17352
|
this.list = new ListOverlayView(
|
|
17070
17353
|
{
|
|
17071
17354
|
title: "Memory",
|
|
@@ -17073,6 +17356,16 @@ var MemoryOverlayView = class {
|
|
|
17073
17356
|
filterable: true,
|
|
17074
17357
|
layout: "split",
|
|
17075
17358
|
emptyMessage: EMPTY_MESSAGE,
|
|
17359
|
+
...promotion ? {
|
|
17360
|
+
hints: [
|
|
17361
|
+
{ key: "p", verb: "propose repo" },
|
|
17362
|
+
{ key: "g", verb: "propose global" }
|
|
17363
|
+
],
|
|
17364
|
+
actions: {
|
|
17365
|
+
p: (item) => this.promote(item, "repo", onChange),
|
|
17366
|
+
g: (item) => this.promote(item, "global", onChange)
|
|
17367
|
+
}
|
|
17368
|
+
} : {},
|
|
17076
17369
|
onClose
|
|
17077
17370
|
},
|
|
17078
17371
|
onChange
|
|
@@ -17080,9 +17373,13 @@ var MemoryOverlayView = class {
|
|
|
17080
17373
|
}
|
|
17081
17374
|
getStatus;
|
|
17082
17375
|
getRecords;
|
|
17376
|
+
promotion;
|
|
17083
17377
|
list;
|
|
17084
17378
|
signature = null;
|
|
17085
17379
|
renderMemo = null;
|
|
17380
|
+
pendingGlobalEntryId = null;
|
|
17381
|
+
promotionMessage = null;
|
|
17382
|
+
promotionInFlight = false;
|
|
17086
17383
|
getHint() {
|
|
17087
17384
|
this.sync();
|
|
17088
17385
|
return this.list.getHint();
|
|
@@ -17090,11 +17387,19 @@ var MemoryOverlayView = class {
|
|
|
17090
17387
|
render(width) {
|
|
17091
17388
|
const status = this.sync();
|
|
17092
17389
|
const statusLine = formatMemoryStatusLine(status, width);
|
|
17390
|
+
const promotionLine = this.promotionMessage === null ? null : fitUnits(clioTheme(), "", [clioTheme().fg(this.promotionMessage.token, this.promotionMessage.text)], width);
|
|
17391
|
+
const statusKey = promotionLine === null ? statusLine : `${statusLine}
|
|
17392
|
+
${promotionLine}`;
|
|
17093
17393
|
const listLines = this.list.render(width);
|
|
17094
17394
|
const memo = this.renderMemo;
|
|
17095
|
-
if (memo && memo.width === width && memo.status ===
|
|
17096
|
-
const lines = [
|
|
17097
|
-
|
|
17395
|
+
if (memo && memo.width === width && memo.status === statusKey && memo.listLines === listLines) return memo.lines;
|
|
17396
|
+
const lines = [
|
|
17397
|
+
statusLine,
|
|
17398
|
+
...promotionLine === null ? [] : [promotionLine],
|
|
17399
|
+
rule(clioTheme(), width),
|
|
17400
|
+
...listLines
|
|
17401
|
+
];
|
|
17402
|
+
this.renderMemo = { width, status: statusKey, listLines, lines };
|
|
17098
17403
|
return lines;
|
|
17099
17404
|
}
|
|
17100
17405
|
handleInput(data) {
|
|
@@ -17115,13 +17420,62 @@ var MemoryOverlayView = class {
|
|
|
17115
17420
|
}
|
|
17116
17421
|
return status;
|
|
17117
17422
|
}
|
|
17423
|
+
promote(item, scope, onChange) {
|
|
17424
|
+
if (this.promotion === void 0 || this.promotionInFlight) return;
|
|
17425
|
+
const entry = this.selectedBankEntry(item);
|
|
17426
|
+
if (entry === null) {
|
|
17427
|
+
this.pendingGlobalEntryId = null;
|
|
17428
|
+
this.promotionMessage = { token: "warning", text: "select a knowledge or procedural task-bank entry" };
|
|
17429
|
+
this.invalidate();
|
|
17430
|
+
onChange();
|
|
17431
|
+
return;
|
|
17432
|
+
}
|
|
17433
|
+
if (scope === "global" && this.pendingGlobalEntryId !== entry.id) {
|
|
17434
|
+
this.pendingGlobalEntryId = entry.id;
|
|
17435
|
+
this.promotionMessage = {
|
|
17436
|
+
token: "warning",
|
|
17437
|
+
text: `global scope broadens applicability for ${entry.id}; press g again to acknowledge`
|
|
17438
|
+
};
|
|
17439
|
+
this.invalidate();
|
|
17440
|
+
onChange();
|
|
17441
|
+
return;
|
|
17442
|
+
}
|
|
17443
|
+
this.pendingGlobalEntryId = null;
|
|
17444
|
+
this.promotionInFlight = true;
|
|
17445
|
+
this.promotionMessage = { token: "muted", text: `proposing ${entry.id} with ${scope} scope` };
|
|
17446
|
+
this.invalidate();
|
|
17447
|
+
onChange();
|
|
17448
|
+
void this.promotion.onPromote(entry, scope).then((result) => {
|
|
17449
|
+
this.promotionMessage = {
|
|
17450
|
+
token: "success",
|
|
17451
|
+
text: `${result.created ? "proposed" : "found existing"} ${result.record.id}; review, then run clio-coder memory approve ${result.record.id}`
|
|
17452
|
+
};
|
|
17453
|
+
}).catch((error) => {
|
|
17454
|
+
this.promotionMessage = {
|
|
17455
|
+
token: "error",
|
|
17456
|
+
text: `promotion failed: ${error instanceof Error ? error.message : String(error)}`
|
|
17457
|
+
};
|
|
17458
|
+
}).finally(() => {
|
|
17459
|
+
this.promotionInFlight = false;
|
|
17460
|
+
this.invalidate();
|
|
17461
|
+
onChange();
|
|
17462
|
+
});
|
|
17463
|
+
}
|
|
17464
|
+
selectedBankEntry(item) {
|
|
17465
|
+
if (!item.id.startsWith("bank:")) return null;
|
|
17466
|
+
const entryId = item.id.slice("bank:".length);
|
|
17467
|
+
const entry = bankEntries(this.getStatus().bank).find((candidate) => candidate.id === entryId);
|
|
17468
|
+
if (entry === void 0 || entry.kind === "status") return null;
|
|
17469
|
+
return entry;
|
|
17470
|
+
}
|
|
17118
17471
|
};
|
|
17119
17472
|
function openMemoryOverlay(tui, getStatus, getRecords, options = {}) {
|
|
17120
17473
|
const view = new MemoryOverlayView(
|
|
17121
17474
|
getStatus,
|
|
17122
17475
|
getRecords,
|
|
17123
17476
|
() => options.onClose?.(),
|
|
17124
|
-
() => tui.requestRender()
|
|
17477
|
+
() => tui.requestRender(),
|
|
17478
|
+
options.onPromote ? { onPromote: options.onPromote } : void 0
|
|
17125
17479
|
);
|
|
17126
17480
|
const handle = showClioOverlayFrame(tui, view, {
|
|
17127
17481
|
anchor: "center",
|
|
@@ -17250,9 +17604,10 @@ function selectableRows(interviews) {
|
|
|
17250
17604
|
}
|
|
17251
17605
|
function interviewHeader(interview, width, now) {
|
|
17252
17606
|
const theme6 = clioTheme();
|
|
17607
|
+
const presentation = classifyDecisionPresentation(decisionFactsForAnswer(interview.exposure ?? "local"));
|
|
17253
17608
|
const rounds = `${interview.roundCount} round${interview.roundCount === 1 ? "" : "s"}`;
|
|
17254
17609
|
const status = interview.interviewStatus === "complete" ? theme6.fg("success", "complete") : theme6.fg("warning", "cancelled");
|
|
17255
|
-
const heading = `${theme6.fg("accent", relativeTime(interview.endedAt, now))}${theme6.fg("dim", " \xB7 ")}${theme6.fg("muted", rounds)}${theme6.fg("dim", " \xB7 ")}${status}`;
|
|
17610
|
+
const heading = `${theme6.style(presentation.semanticToken, presentation.tierLabel, { bold: true })}${theme6.fg("dim", " \xB7 ")}${theme6.fg("accent", relativeTime(interview.endedAt, now))}${theme6.fg("dim", " \xB7 ")}${theme6.fg("muted", rounds)}${theme6.fg("dim", " \xB7 ")}${status}`;
|
|
17256
17611
|
const lines = [fitLine3(heading, width)];
|
|
17257
17612
|
if (interview.summary) {
|
|
17258
17613
|
lines.push(...wrapTextWithAnsi(theme6.fg("dim", interview.summary), width).map((line) => fitLine3(line, width)));
|
|
@@ -21366,6 +21721,7 @@ function isSettingsSectionId(value) {
|
|
|
21366
21721
|
var COMPACT_POSITIONALS = [
|
|
21367
21722
|
{ name: "instructions", required: false, rest: true }
|
|
21368
21723
|
];
|
|
21724
|
+
var RECALL_POSITIONALS = [{ name: "ref", required: true }];
|
|
21369
21725
|
function fromArgsOrUsage(name, command) {
|
|
21370
21726
|
return (parsed) => parsed.error ? { kind: "usage-error", command: name, reason: parsed.error } : command;
|
|
21371
21727
|
}
|
|
@@ -21711,11 +22067,12 @@ ${usage}` : usage);
|
|
|
21711
22067
|
},
|
|
21712
22068
|
{
|
|
21713
22069
|
name: "context",
|
|
21714
|
-
description: "Context hub: window overlay plus compact, init, refresh, and reset",
|
|
22070
|
+
description: "Context hub: window overlay plus compact, recall, init, refresh, and reset",
|
|
21715
22071
|
group: "Inspect",
|
|
21716
|
-
kinds: ["context-view", "compact", "init", "context-clear", "context-refresh"],
|
|
22072
|
+
kinds: ["context-view", "compact", "context-recall", "init", "context-clear", "context-refresh"],
|
|
21717
22073
|
subcommandDescriptions: {
|
|
21718
22074
|
compact: "Compact session context",
|
|
22075
|
+
recall: "Recall an evicted result",
|
|
21719
22076
|
init: "Initialize project context",
|
|
21720
22077
|
refresh: "Refresh project context",
|
|
21721
22078
|
reset: "Reset project context"
|
|
@@ -21723,6 +22080,7 @@ ${usage}` : usage);
|
|
|
21723
22080
|
args: {
|
|
21724
22081
|
subcommands: {
|
|
21725
22082
|
compact: { positionals: [...COMPACT_POSITIONALS] },
|
|
22083
|
+
recall: { positionals: [...RECALL_POSITIONALS] },
|
|
21726
22084
|
init: {},
|
|
21727
22085
|
refresh: {},
|
|
21728
22086
|
reset: {}
|
|
@@ -21733,6 +22091,8 @@ ${usage}` : usage);
|
|
|
21733
22091
|
switch (parsed.subcommand) {
|
|
21734
22092
|
case "compact":
|
|
21735
22093
|
return { kind: "compact", instructions: parsed.rest };
|
|
22094
|
+
case "recall":
|
|
22095
|
+
return { kind: "context-recall", ref: parsed.positionals[0] ?? "" };
|
|
21736
22096
|
case "init":
|
|
21737
22097
|
return { kind: "init", options: {} };
|
|
21738
22098
|
case "refresh":
|
|
@@ -21751,6 +22111,13 @@ ${usage}` : usage);
|
|
|
21751
22111
|
case "compact":
|
|
21752
22112
|
ctx.runCompact(command.instructions);
|
|
21753
22113
|
return;
|
|
22114
|
+
case "context-recall":
|
|
22115
|
+
if (ctx.runContextRecall) {
|
|
22116
|
+
ctx.runContextRecall(command.ref);
|
|
22117
|
+
} else {
|
|
22118
|
+
ctx.notice("error", "context recall is not wired; no session is bound to this process");
|
|
22119
|
+
}
|
|
22120
|
+
return;
|
|
21754
22121
|
case "init":
|
|
21755
22122
|
ctx.runInit(command.options);
|
|
21756
22123
|
return;
|
|
@@ -21859,7 +22226,7 @@ ${usage}` : usage);
|
|
|
21859
22226
|
},
|
|
21860
22227
|
{
|
|
21861
22228
|
name: "memory",
|
|
21862
|
-
description: "Inspect
|
|
22229
|
+
description: "Inspect, promote, or seed task memory",
|
|
21863
22230
|
group: "Inspect",
|
|
21864
22231
|
kinds: ["memory", "memory-seed"],
|
|
21865
22232
|
subcommandDescriptions: { seed: "Seed the task bank from the newest handoff" },
|
|
@@ -22611,7 +22978,16 @@ function createOverlayGeneralOpeners(deps) {
|
|
|
22611
22978
|
deps.transitions.state = "context-view";
|
|
22612
22979
|
deps.transitions.handle = openContextOverlayFactory(deps.tui, deps.getContextLedger, {
|
|
22613
22980
|
bus: deps.bus,
|
|
22614
|
-
chat: deps.contextChat
|
|
22981
|
+
chat: deps.contextChat,
|
|
22982
|
+
getWorkingSet: () => {
|
|
22983
|
+
const readSessionEntries = deps.readSessionEntries;
|
|
22984
|
+
if (!readSessionEntries) return null;
|
|
22985
|
+
return foldWorkingSet(readSessionEntries(), deps.getSessionMeta()?.pinnedLeafTurnId ?? void 0);
|
|
22986
|
+
},
|
|
22987
|
+
getWorkingSetConfig: () => {
|
|
22988
|
+
const workingSet = deps.getSettings?.().context.workingSet;
|
|
22989
|
+
return workingSet ? { enabled: workingSet.enabled, policy: workingSet.policy } : null;
|
|
22990
|
+
}
|
|
22615
22991
|
});
|
|
22616
22992
|
deps.requestRender();
|
|
22617
22993
|
};
|
|
@@ -22706,7 +23082,30 @@ function createOverlayGeneralOpeners(deps) {
|
|
|
22706
23082
|
}
|
|
22707
23083
|
deps.transitions.state = "memory";
|
|
22708
23084
|
deps.transitions.handle = openMemoryOverlayFactory(deps.tui, deps.getTaskMemoryStatus, () => records, {
|
|
22709
|
-
onClose: deps.closeOverlay
|
|
23085
|
+
onClose: deps.closeOverlay,
|
|
23086
|
+
onPromote: async (entry, scope) => {
|
|
23087
|
+
const meta = deps.getSessionMeta();
|
|
23088
|
+
if (!meta) throw new Error("memory promotion requires an active session");
|
|
23089
|
+
const selection = scope === "global" ? { scope: "global", acknowledgeGlobal: true } : (() => {
|
|
23090
|
+
const repository = canonicalMemoryRepositoryIdentity(meta.cwd);
|
|
23091
|
+
if (repository === null) {
|
|
23092
|
+
throw new Error("repo promotion requires a canonical active repository identity");
|
|
23093
|
+
}
|
|
23094
|
+
return { scope: "repo", repository };
|
|
23095
|
+
})();
|
|
23096
|
+
const result = await proposeMemoryPromotion(
|
|
23097
|
+
deps.dataDir,
|
|
23098
|
+
{
|
|
23099
|
+
kind: "task-bank-entry",
|
|
23100
|
+
sessionId: meta.id,
|
|
23101
|
+
evidenceRefs: [`session-${meta.id}`],
|
|
23102
|
+
entry
|
|
23103
|
+
},
|
|
23104
|
+
selection
|
|
23105
|
+
);
|
|
23106
|
+
records = loadMemoryRecordsSync(deps.dataDir);
|
|
23107
|
+
return result;
|
|
23108
|
+
}
|
|
22710
23109
|
});
|
|
22711
23110
|
deps.requestRender();
|
|
22712
23111
|
};
|
|
@@ -22747,6 +23146,7 @@ function createOverlayGeneralOpeners(deps) {
|
|
|
22747
23146
|
const dispatchBoardHint = () => {
|
|
22748
23147
|
const row2 = deps.dispatchBoard.selectedRow();
|
|
22749
23148
|
const entries = [{ key: "\u2191\u2193", verb: "select" }];
|
|
23149
|
+
if (row2) entries.push({ key: "Enter", verb: deps.dispatchBoard.detailExpanded() ? "hide detail" : "detail" });
|
|
22750
23150
|
if (row2 && isDispatchBoardRowSteerable(row2)) entries.push({ key: "s", verb: "steer" });
|
|
22751
23151
|
if (row2 && isDispatchBoardRowCancellable(row2)) entries.push({ key: "x", verb: "cancel" });
|
|
22752
23152
|
return buildHint(entries);
|
|
@@ -22859,6 +23259,26 @@ init_esm_shims();
|
|
|
22859
23259
|
init_esm_shims();
|
|
22860
23260
|
var PERMISSION_OVERLAY_CONTENT_WIDTH = 78;
|
|
22861
23261
|
var PERMISSION_OVERLAY_WIDTH = PERMISSION_OVERLAY_CONTENT_WIDTH + 4;
|
|
23262
|
+
function permissionOverlayPlacement(tui, editor, footer) {
|
|
23263
|
+
const margin = { bottom: 0 };
|
|
23264
|
+
return {
|
|
23265
|
+
anchor: "bottom-center",
|
|
23266
|
+
margin,
|
|
23267
|
+
visible: (termWidth, termHeight) => {
|
|
23268
|
+
const dockHeight = editor.render(termWidth).length + footer.render(termWidth).length;
|
|
23269
|
+
if (tui.mode === "fullscreen") {
|
|
23270
|
+
margin.bottom = dockHeight;
|
|
23271
|
+
return true;
|
|
23272
|
+
}
|
|
23273
|
+
const baseHeight = tui.render(termWidth).length;
|
|
23274
|
+
const composerTop = Math.max(0, baseHeight - dockHeight);
|
|
23275
|
+
const viewportStart = Math.max(0, baseHeight - termHeight);
|
|
23276
|
+
const composerViewportRow = composerTop - viewportStart;
|
|
23277
|
+
margin.bottom = composerViewportRow >= 0 && composerViewportRow < termHeight ? Math.max(0, termHeight - composerViewportRow) : dockHeight;
|
|
23278
|
+
return true;
|
|
23279
|
+
}
|
|
23280
|
+
};
|
|
23281
|
+
}
|
|
22862
23282
|
var PermissionOverlayBody = class {
|
|
22863
23283
|
constructor(view) {
|
|
22864
23284
|
this.view = view;
|
|
@@ -22909,45 +23329,48 @@ function wrapArtifactLine(value, max) {
|
|
|
22909
23329
|
lines.push(remaining);
|
|
22910
23330
|
return lines;
|
|
22911
23331
|
}
|
|
22912
|
-
function
|
|
22913
|
-
|
|
22914
|
-
|
|
23332
|
+
function permissionDecisionPresentation(view) {
|
|
23333
|
+
return classifyDecisionPresentation(
|
|
23334
|
+
decisionFactsForPermission({
|
|
23335
|
+
tool: view.tool,
|
|
23336
|
+
actionClass: view.actionClass,
|
|
23337
|
+
axis: view.axis.kind === "net" ? { kind: "safety-net", ruleId: view.axis.ruleId } : { kind: "autonomy", level: view.axis.level },
|
|
23338
|
+
origin: view.origin,
|
|
23339
|
+
...view.exposure !== void 0 ? { exposure: view.exposure } : {}
|
|
23340
|
+
})
|
|
23341
|
+
);
|
|
22915
23342
|
}
|
|
22916
|
-
function
|
|
22917
|
-
|
|
22918
|
-
return `worker ${view.origin.agentId} (run ${view.origin.runId}), ${axisLabel(view.axis, "worker")}`;
|
|
22919
|
-
}
|
|
22920
|
-
return axisLabel(view.axis, "main");
|
|
23343
|
+
function permissionOverlayTitle(view) {
|
|
23344
|
+
return permissionDecisionPresentation(view).title;
|
|
22921
23345
|
}
|
|
22922
|
-
function
|
|
22923
|
-
return
|
|
23346
|
+
function permissionOverlayTone(view) {
|
|
23347
|
+
return permissionDecisionPresentation(view).semanticToken;
|
|
23348
|
+
}
|
|
23349
|
+
function permissionOverlayHint(innerWidth, composerHasDraft = false) {
|
|
23350
|
+
return fitHintEntries(permissionHintEntries(composerHasDraft), innerWidth - 3);
|
|
23351
|
+
}
|
|
23352
|
+
function actionConsequence(presentation, id) {
|
|
23353
|
+
return presentation.requiredActions.find((action) => action.id === id)?.consequence ?? "";
|
|
22924
23354
|
}
|
|
22925
|
-
var permissionOverlayHint = buildResponsiveHint(
|
|
22926
|
-
[
|
|
22927
|
-
{ key: "Enter", verb: "allow once", short: "allow", critical: true },
|
|
22928
|
-
{ key: "s", verb: "stop turn", short: "stop", critical: true }
|
|
22929
|
-
],
|
|
22930
|
-
{ key: "Esc", verb: "close", critical: false }
|
|
22931
|
-
);
|
|
22932
|
-
var SAFETY_SENTENCES = [
|
|
22933
|
-
"Parked until you decide; allow or deny applies to this call only.",
|
|
22934
|
-
"Stopping the turn denies it and ends the run, so nothing asks again.",
|
|
22935
|
-
"Hard-blocked actions remain blocked."
|
|
22936
|
-
];
|
|
22937
23355
|
function permissionOverlayLines(view, width) {
|
|
22938
23356
|
const content = Math.max(8, Math.floor(width));
|
|
23357
|
+
const presentation = permissionDecisionPresentation(view);
|
|
22939
23358
|
const lines = [
|
|
22940
|
-
field("Tool: ", view.tool
|
|
23359
|
+
field("Tool: ", `${view.tool} \xB7 Action: ${view.actionClass}`, content),
|
|
22941
23360
|
...view.target !== void 0 && view.target.length > 0 ? [field("Target: ", view.target, content)] : [],
|
|
22942
|
-
|
|
22943
|
-
field("Asked by: ", askedBy(view), content),
|
|
23361
|
+
...wrapSentence(`Requested by: ${presentation.requestedByCopy}`, content),
|
|
22944
23362
|
...view.artifact !== void 0 ? [
|
|
22945
23363
|
"",
|
|
22946
23364
|
"Resolved dispatch plan:",
|
|
22947
23365
|
...view.artifact.text.split(/\r?\n/u).flatMap((line) => wrapArtifactLine(line, content))
|
|
22948
23366
|
] : [],
|
|
22949
23367
|
"",
|
|
22950
|
-
...
|
|
23368
|
+
...wrapSentence(`Approval: ${presentation.authorizationCopy}`, content),
|
|
23369
|
+
...wrapSentence(`Consequence: ${presentation.consequenceCopy}`, content),
|
|
23370
|
+
...wrapSentence(presentation.reversibilityCopy, content),
|
|
23371
|
+
...wrapSentence(`Deny: ${actionConsequence(presentation, "deny")}`, content),
|
|
23372
|
+
...wrapSentence(`Stop: ${actionConsequence(presentation, "stop")}`, content),
|
|
23373
|
+
...wrapSentence("Hard-blocked actions remain blocked.", content)
|
|
22951
23374
|
];
|
|
22952
23375
|
if (view.queueDepth !== void 0 && view.queueDepth > 1) {
|
|
22953
23376
|
lines.splice(lines.indexOf(""), 0, `1 of ${view.queueDepth} parked`);
|
|
@@ -23162,7 +23585,7 @@ function mainApprovalRequestView(call, decision, meta, autonomy, queueDepth) {
|
|
|
23162
23585
|
const axisFromMeta = axisViewFromId(meta?.axis, autonomy);
|
|
23163
23586
|
const axisFromDecision = askAxis(decision);
|
|
23164
23587
|
const axis = axisFromMeta ?? (axisFromDecision.kind === "net" ? { kind: "net", ruleId: axisFromDecision.ruleId } : { kind: "autonomy", level: autonomy });
|
|
23165
|
-
const target = describeCallTarget(call.args);
|
|
23588
|
+
const target = describeCallTarget(call.tool, call.args);
|
|
23166
23589
|
return {
|
|
23167
23590
|
requestId: meta?.requestId ?? "permission-pending",
|
|
23168
23591
|
tool: call.tool,
|
|
@@ -23171,6 +23594,7 @@ function mainApprovalRequestView(call, decision, meta, autonomy, queueDepth) {
|
|
|
23171
23594
|
origin: { kind: "main" },
|
|
23172
23595
|
reason: decision.kind === "ask" ? decision.rejection.short : `${call.tool} requests ${decision.classification.actionClass}`,
|
|
23173
23596
|
...call.tool === ToolNames.Dispatch && decision.kind === "ask" ? { artifact: { kind: "dispatch-plan", text: decision.rejection.detail } } : {},
|
|
23597
|
+
...call.tool === ToolNames.AskUser ? { exposure: askUserExposure(call.args) } : {},
|
|
23174
23598
|
...target.length > 0 ? { target } : {},
|
|
23175
23599
|
...queueDepth !== void 0 && queueDepth > 1 ? { queueDepth } : {}
|
|
23176
23600
|
};
|
|
@@ -23185,7 +23609,7 @@ function workerEscalationEntry(payload, autonomy) {
|
|
|
23185
23609
|
requestId: payload.requestId,
|
|
23186
23610
|
agentId: typeof payload.agentId === "string" ? payload.agentId : "worker",
|
|
23187
23611
|
tool: typeof payload.tool === "string" ? payload.tool : "unknown",
|
|
23188
|
-
actionClass:
|
|
23612
|
+
actionClass: decisionActionClass(payload.actionClass),
|
|
23189
23613
|
axis: axisViewFromId(typeof payload.axis === "string" ? payload.axis : void 0, autonomy) ?? (typeof payload.ruleId === "string" ? { kind: "net", ruleId: payload.ruleId } : { kind: "autonomy", level: autonomy }),
|
|
23190
23614
|
reason: payload.rejection?.short ?? (typeof payload.summary === "string" ? payload.summary : `${payload.tool ?? "worker"} requires approval`),
|
|
23191
23615
|
...typeof payload.target === "string" && payload.target.length > 0 ? { target: sanitizeCallTargetText(payload.target).slice(0, 200) } : {}
|
|
@@ -23221,6 +23645,12 @@ function createOverlayPermissionLifecycle(deps) {
|
|
|
23221
23645
|
const next = workerQueue.shift();
|
|
23222
23646
|
if (next) openWorker(next);
|
|
23223
23647
|
};
|
|
23648
|
+
const retryPending = () => {
|
|
23649
|
+
maybeOpenWorker();
|
|
23650
|
+
if (deps.getOverlayState() === "closed" && deps.toolRegistry?.hasParkedCalls()) {
|
|
23651
|
+
deps.toolRegistry.renotifyHead();
|
|
23652
|
+
}
|
|
23653
|
+
};
|
|
23224
23654
|
const unsubscribePermission = deps.toolRegistry?.onPermissionRequired((call, decision, meta) => {
|
|
23225
23655
|
const autonomy = deps.getAutonomy();
|
|
23226
23656
|
const view = mainApprovalRequestView(call, decision, meta, autonomy, deps.toolRegistry?.parkedCount());
|
|
@@ -23326,10 +23756,7 @@ function createOverlayPermissionLifecycle(deps) {
|
|
|
23326
23756
|
workerQueue.length = 0;
|
|
23327
23757
|
return;
|
|
23328
23758
|
}
|
|
23329
|
-
|
|
23330
|
-
if (deps.getOverlayState() === "closed" && deps.toolRegistry?.hasParkedCalls()) {
|
|
23331
|
-
deps.toolRegistry.renotifyHead();
|
|
23332
|
-
}
|
|
23759
|
+
retryPending();
|
|
23333
23760
|
};
|
|
23334
23761
|
return {
|
|
23335
23762
|
confirm: () => {
|
|
@@ -23346,6 +23773,7 @@ function createOverlayPermissionLifecycle(deps) {
|
|
|
23346
23773
|
);
|
|
23347
23774
|
},
|
|
23348
23775
|
onPermissionOverlayClosed,
|
|
23776
|
+
retryPending,
|
|
23349
23777
|
dispose: () => {
|
|
23350
23778
|
unsubscribePermission();
|
|
23351
23779
|
unsubscribeWorker();
|
|
@@ -24050,9 +24478,9 @@ init_esm_shims();
|
|
|
24050
24478
|
|
|
24051
24479
|
// src/domains/session/cwd-fallback.ts
|
|
24052
24480
|
init_esm_shims();
|
|
24053
|
-
import { existsSync as
|
|
24481
|
+
import { existsSync as existsSync7, statSync as statSync2 } from "node:fs";
|
|
24054
24482
|
var defaultFsProbe = {
|
|
24055
|
-
exists: (p) =>
|
|
24483
|
+
exists: (p) => existsSync7(p),
|
|
24056
24484
|
isDirectory: (p) => {
|
|
24057
24485
|
try {
|
|
24058
24486
|
return statSync2(p).isDirectory();
|
|
@@ -24800,7 +25228,7 @@ function payloadRecord2(value) {
|
|
|
24800
25228
|
function positiveNumber(value) {
|
|
24801
25229
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
|
|
24802
25230
|
}
|
|
24803
|
-
function
|
|
25231
|
+
function nonEmptyString3(source, ...keys) {
|
|
24804
25232
|
for (const key of keys) {
|
|
24805
25233
|
const value = source[key];
|
|
24806
25234
|
if (typeof value === "string" && value.trim().length > 0) return value;
|
|
@@ -24869,6 +25297,10 @@ function lastTurnSummaryFromLedger(entries, defaults = {}, activeLeafTurnId) {
|
|
|
24869
25297
|
let toolErrorCount = 0;
|
|
24870
25298
|
let targetId = turn.targetId;
|
|
24871
25299
|
let modelId = turn.modelId;
|
|
25300
|
+
let responseModelIdObservation = {
|
|
25301
|
+
state: "legacy-difference-only",
|
|
25302
|
+
differingModelId: null
|
|
25303
|
+
};
|
|
24872
25304
|
for (const row2 of turn.rows) {
|
|
24873
25305
|
const record2 = payloadRecord2(row2.payload);
|
|
24874
25306
|
if (row2.role === "tool_result") {
|
|
@@ -24880,8 +25312,9 @@ function lastTurnSummaryFromLedger(entries, defaults = {}, activeLeafTurnId) {
|
|
|
24880
25312
|
sawAssistant = true;
|
|
24881
25313
|
const reason = stopReasonOf(record2.stopReason);
|
|
24882
25314
|
if (reason && reason !== "stop") stopReason = reason;
|
|
24883
|
-
targetId = targetId ??
|
|
24884
|
-
modelId = modelId ??
|
|
25315
|
+
targetId = targetId ?? nonEmptyString3(record2, "provider", "api");
|
|
25316
|
+
modelId = modelId ?? nonEmptyString3(record2, "model");
|
|
25317
|
+
responseModelIdObservation = responseModelIdObservationFromRecord(record2, "legacy-difference-only");
|
|
24885
25318
|
const usage = payloadRecord2(record2.usage);
|
|
24886
25319
|
if (!usage) continue;
|
|
24887
25320
|
inputTokens += positiveNumber(usage.input);
|
|
@@ -24908,7 +25341,8 @@ function lastTurnSummaryFromLedger(entries, defaults = {}, activeLeafTurnId) {
|
|
|
24908
25341
|
toolErrorCount,
|
|
24909
25342
|
stopReason,
|
|
24910
25343
|
watchdogPeak: 0,
|
|
24911
|
-
truncated: false
|
|
25344
|
+
truncated: false,
|
|
25345
|
+
responseModelIdObservation
|
|
24912
25346
|
};
|
|
24913
25347
|
if (sawReasoning) {
|
|
24914
25348
|
summary.reasoningTokens = reasoningTokens;
|
|
@@ -24931,15 +25365,32 @@ function reseedSessionUsageFromLedger(sink, entries, defaults = {}, activeLeafTu
|
|
|
24931
25365
|
sink.resetSession();
|
|
24932
25366
|
const scoped = filterEntriesToActivePath(entries, activeLeafTurnId ?? void 0);
|
|
24933
25367
|
for (const call of ledgerUsageCalls(scoped, defaults)) {
|
|
24934
|
-
|
|
24935
|
-
|
|
24936
|
-
|
|
24937
|
-
|
|
24938
|
-
|
|
24939
|
-
|
|
24940
|
-
|
|
24941
|
-
|
|
24942
|
-
|
|
25368
|
+
const responseModelIdObservationCounts = emptyResponseModelIdObservationCounts();
|
|
25369
|
+
addResponseModelIdObservationCount(
|
|
25370
|
+
responseModelIdObservationCounts,
|
|
25371
|
+
call.responseModelIdObservation,
|
|
25372
|
+
call.apiCalls ?? 1
|
|
25373
|
+
);
|
|
25374
|
+
sink.recordTokens(
|
|
25375
|
+
call.providerId,
|
|
25376
|
+
call.attributedModelId,
|
|
25377
|
+
call.totalTokens,
|
|
25378
|
+
call.costUsd,
|
|
25379
|
+
{
|
|
25380
|
+
input: call.input,
|
|
25381
|
+
output: call.output,
|
|
25382
|
+
cacheRead: call.cacheRead,
|
|
25383
|
+
cacheWrite: call.cacheWrite,
|
|
25384
|
+
reasoningTokens: call.reasoningTokens,
|
|
25385
|
+
totalTokens: call.totalTokens,
|
|
25386
|
+
apiCalls: call.apiCalls ?? 1
|
|
25387
|
+
},
|
|
25388
|
+
void 0,
|
|
25389
|
+
{
|
|
25390
|
+
requestedModelIds: [call.requestedModelId],
|
|
25391
|
+
responseModelIdObservationCounts
|
|
25392
|
+
}
|
|
25393
|
+
);
|
|
24943
25394
|
}
|
|
24944
25395
|
}
|
|
24945
25396
|
|
|
@@ -25005,7 +25456,7 @@ function createOverlaySessionLifecycle(deps) {
|
|
|
25005
25456
|
const replayOptions = leafTurnId ? { activeLeafTurnId: leafTurnId } : {};
|
|
25006
25457
|
deps.resetTranscript();
|
|
25007
25458
|
rehydrateChatPanelFromTurns(deps.chatPanel, turns, replayOptions);
|
|
25008
|
-
const replayMessages =
|
|
25459
|
+
const replayMessages = buildModelReplayAgentMessagesFromTurns(turns, replayOptions);
|
|
25009
25460
|
deps.chat.resetForSession(leafTurnId, replayMessages);
|
|
25010
25461
|
rescopeToBranch(session, turns, leafTurnId);
|
|
25011
25462
|
} catch (error) {
|
|
@@ -25055,7 +25506,7 @@ function createOverlaySessionLifecycle(deps) {
|
|
|
25055
25506
|
const turns = deps.readStructuredEntries(sessionId);
|
|
25056
25507
|
deps.resetTranscript();
|
|
25057
25508
|
rehydrateChatPanelFromTurns(deps.chatPanel, turns, { uptoTurnId: turnId });
|
|
25058
|
-
const replayMessages =
|
|
25509
|
+
const replayMessages = buildModelReplayAgentMessagesFromTurns(turns, { uptoTurnId: turnId });
|
|
25059
25510
|
deps.chat.resetForSession(turnId, replayMessages);
|
|
25060
25511
|
rescopeToBranch(session, turns, turnId);
|
|
25061
25512
|
} catch (error) {
|
|
@@ -25121,8 +25572,11 @@ function createOverlaySessionLifecycle(deps) {
|
|
|
25121
25572
|
try {
|
|
25122
25573
|
const turns = deps.readStructuredEntries(forkedSessionId);
|
|
25123
25574
|
rehydrateChatPanelFromTurns(deps.chatPanel, turns);
|
|
25124
|
-
const replayMessages = buildReplayAgentMessagesFromTurns(turns);
|
|
25125
25575
|
const leafTurnId = session.tree(forkedSessionId).leafId ?? parentTurnId;
|
|
25576
|
+
const replayMessages = buildModelReplayAgentMessagesFromTurns(
|
|
25577
|
+
turns,
|
|
25578
|
+
leafTurnId ? { activeLeafTurnId: leafTurnId } : {}
|
|
25579
|
+
);
|
|
25126
25580
|
deps.chat.resetForSession(leafTurnId, replayMessages);
|
|
25127
25581
|
rescopeToBranch(session, turns, leafTurnId);
|
|
25128
25582
|
} catch (error) {
|
|
@@ -25165,7 +25619,9 @@ function createOverlayTransitions(deps) {
|
|
|
25165
25619
|
return state;
|
|
25166
25620
|
},
|
|
25167
25621
|
set state(next) {
|
|
25622
|
+
const closing = state !== "closed" && next === "closed";
|
|
25168
25623
|
state = next;
|
|
25624
|
+
if (closing) deps.onOverlayClosed?.();
|
|
25169
25625
|
},
|
|
25170
25626
|
get handle() {
|
|
25171
25627
|
return handle;
|
|
@@ -25188,6 +25644,7 @@ function createOverlayTransitions(deps) {
|
|
|
25188
25644
|
handle?.hide();
|
|
25189
25645
|
handle = null;
|
|
25190
25646
|
if (leaving === "permission-confirm") deps.onPermissionOverlayClosed();
|
|
25647
|
+
else deps.onOverlayClosed?.();
|
|
25191
25648
|
deps.renderContextIsland();
|
|
25192
25649
|
deps.renderTaskIsland();
|
|
25193
25650
|
deps.requestRender();
|
|
@@ -25199,9 +25656,17 @@ init_esm_shims();
|
|
|
25199
25656
|
function isEscapeKey(data) {
|
|
25200
25657
|
return matchesKey(data, "escape") && !isKeyRelease(data);
|
|
25201
25658
|
}
|
|
25659
|
+
var DRAFT_EDIT_KEYS = ["backspace", "delete", "ctrl+u", "ctrl+w", "alt+backspace", "ctrl+k"];
|
|
25660
|
+
function isDraftEditKey(data) {
|
|
25661
|
+
return !isKeyRelease(data) && DRAFT_EDIT_KEYS.some((key) => matchesKey(data, key));
|
|
25662
|
+
}
|
|
25202
25663
|
function routePermissionOverlayKey(data, deps) {
|
|
25203
25664
|
if (matchesKey(data, "enter") && !isKeyRelease(data)) {
|
|
25204
|
-
deps.confirmPermission();
|
|
25665
|
+
if (!(deps.composerHasDraft?.() ?? false)) deps.confirmPermission();
|
|
25666
|
+
return true;
|
|
25667
|
+
}
|
|
25668
|
+
if (deps.editDraft && isDraftEditKey(data)) {
|
|
25669
|
+
deps.editDraft(data);
|
|
25205
25670
|
return true;
|
|
25206
25671
|
}
|
|
25207
25672
|
if (isEscapeKey(data)) {
|
|
@@ -25236,6 +25701,10 @@ function routeDispatchBoardOverlayKey(data, deps) {
|
|
|
25236
25701
|
deps.cancelSelectedDispatch();
|
|
25237
25702
|
return true;
|
|
25238
25703
|
}
|
|
25704
|
+
if (matchesKey(data, "enter")) {
|
|
25705
|
+
deps.toggleSelectedDispatchDetail();
|
|
25706
|
+
return true;
|
|
25707
|
+
}
|
|
25239
25708
|
return false;
|
|
25240
25709
|
}
|
|
25241
25710
|
function routeAuthOverlayKey(data, deps) {
|
|
@@ -25375,7 +25844,8 @@ function createOverlayLifecycle(deps) {
|
|
|
25375
25844
|
requestRender: () => tui.requestRender(),
|
|
25376
25845
|
cancelPendingAskUser: () => overlayAskUser?.cancelPending() ?? false,
|
|
25377
25846
|
finishAuth: (dismiss) => overlayAuth.finish(dismiss),
|
|
25378
|
-
onPermissionOverlayClosed: () => overlayPermission?.onPermissionOverlayClosed()
|
|
25847
|
+
onPermissionOverlayClosed: () => overlayPermission?.onPermissionOverlayClosed(),
|
|
25848
|
+
onOverlayClosed: () => overlayPermission?.retryPending()
|
|
25379
25849
|
});
|
|
25380
25850
|
const closeOverlay = overlayTransitions.close;
|
|
25381
25851
|
const overlayAuth = createOverlayAuthLifecycle({
|
|
@@ -25407,10 +25877,13 @@ function createOverlayLifecycle(deps) {
|
|
|
25407
25877
|
if (overlayTransitions.state !== "closed") return false;
|
|
25408
25878
|
overlayTransitions.state = "permission-confirm";
|
|
25409
25879
|
overlayTransitions.handle = showOverlayFrame(tui, createPermissionOverlayBody(view), {
|
|
25410
|
-
|
|
25880
|
+
...permissionOverlayPlacement(tui, editor, footer.view),
|
|
25411
25881
|
width: PERMISSION_OVERLAY_WIDTH,
|
|
25412
|
-
title: permissionOverlayTitle(),
|
|
25413
|
-
|
|
25882
|
+
title: permissionOverlayTitle(view),
|
|
25883
|
+
tone: permissionOverlayTone(view),
|
|
25884
|
+
// Read per frame: the footer names what Enter does right now, and
|
|
25885
|
+
// that depends on whether the composer holds a draft.
|
|
25886
|
+
footerHint: (innerWidth) => permissionOverlayHint(innerWidth, editor.getText().length > 0)
|
|
25414
25887
|
});
|
|
25415
25888
|
tui.requestRender();
|
|
25416
25889
|
return true;
|
|
@@ -25525,6 +25998,7 @@ function createOverlayLifecycle(deps) {
|
|
|
25525
25998
|
stateDir: deps.app.stateDir,
|
|
25526
25999
|
getSessionMeta: () => deps.app.session?.current() ?? null,
|
|
25527
26000
|
...deps.app.readSessionEntries ? { readSessionEntries: deps.app.readSessionEntries } : {},
|
|
26001
|
+
...deps.app.getSettings ? { getSettings: deps.app.getSettings } : {},
|
|
25528
26002
|
terminal,
|
|
25529
26003
|
dispatchBoard,
|
|
25530
26004
|
startDispatchBoardTicker: () => interactiveTickers.startDispatchBoardTicker(),
|
|
@@ -27047,6 +27521,11 @@ function createInteractiveInputRuntime(deps) {
|
|
|
27047
27521
|
cancelPermission: () => deps.overlay.closeOverlay(),
|
|
27048
27522
|
confirmPermission: () => deps.overlay.confirmPermission(),
|
|
27049
27523
|
stopTurnFromPermission: () => deps.overlay.stopTurnFromPermission(),
|
|
27524
|
+
composerHasDraft: () => deps.editor.getText().length > 0,
|
|
27525
|
+
editDraft: (data2) => {
|
|
27526
|
+
deps.editor.handleInput?.(data2);
|
|
27527
|
+
deps.requestRender();
|
|
27528
|
+
},
|
|
27050
27529
|
closeOverlay: () => deps.overlay.closeOverlay(),
|
|
27051
27530
|
selectPreviousDispatch: () => {
|
|
27052
27531
|
deps.dispatchBoard.selectPrevious();
|
|
@@ -27056,6 +27535,10 @@ function createInteractiveInputRuntime(deps) {
|
|
|
27056
27535
|
deps.dispatchBoard.selectNext();
|
|
27057
27536
|
deps.requestRender();
|
|
27058
27537
|
},
|
|
27538
|
+
toggleSelectedDispatchDetail: () => {
|
|
27539
|
+
deps.dispatchBoard.toggleDetail();
|
|
27540
|
+
deps.requestRender();
|
|
27541
|
+
},
|
|
27059
27542
|
steerSelectedDispatch: deps.steerSelectedDispatch,
|
|
27060
27543
|
cancelSelectedDispatch: deps.cancelSelectedDispatch,
|
|
27061
27544
|
cancelAskUser: () => deps.overlay.cancelAskUser()
|
|
@@ -27950,7 +28433,7 @@ function styleStatusVerb(text, toneHint) {
|
|
|
27950
28433
|
function policySegmentFold(seg, detail) {
|
|
27951
28434
|
if (!seg.finished) return policyRunningToolFold(detail);
|
|
27952
28435
|
if (seg.isError && detail.errors === "body") return "expanded";
|
|
27953
|
-
return policyToolFold(detail, toolPresentationPolicy(seg.name, seg.args));
|
|
28436
|
+
return policyToolFold(detail, toolResultPresentationPolicy(seg.result) ?? toolPresentationPolicy(seg.name, seg.args));
|
|
27954
28437
|
}
|
|
27955
28438
|
function toolSegmentExpanded(seg, detail) {
|
|
27956
28439
|
return resolveFold(seg.fold, policySegmentFold(seg, detail)) === "expanded";
|
|
@@ -27978,7 +28461,8 @@ function renderToolSegmentLines(seg, width, expandKey, latestHintToolId, nowMs,
|
|
|
27978
28461
|
durationMs: seg.durationMs,
|
|
27979
28462
|
resultSummary: seg.resultSummary,
|
|
27980
28463
|
outcome: seg.settlement,
|
|
27981
|
-
blockReason: seg.blockReason
|
|
28464
|
+
blockReason: seg.blockReason,
|
|
28465
|
+
evictedReason: seg.evictedReason
|
|
27982
28466
|
} : { toolCallId: seg.id, toolName: seg.name, args: seg.args, elapsedMs, phase },
|
|
27983
28467
|
width,
|
|
27984
28468
|
hintKey,
|
|
@@ -28009,7 +28493,8 @@ function renderToolSegmentLines(seg, width, expandKey, latestHintToolId, nowMs,
|
|
|
28009
28493
|
durationMs: seg.durationMs,
|
|
28010
28494
|
resultSummary: seg.resultSummary,
|
|
28011
28495
|
outcome: seg.settlement,
|
|
28012
|
-
blockReason: seg.blockReason
|
|
28496
|
+
blockReason: seg.blockReason,
|
|
28497
|
+
evictedReason: seg.evictedReason
|
|
28013
28498
|
},
|
|
28014
28499
|
width,
|
|
28015
28500
|
{ unbounded: unboundedToolBodies, diffStyle: seg.replayed === true ? "plain" : "color" }
|
|
@@ -28706,6 +29191,7 @@ function createChatPanel(options = {}) {
|
|
|
28706
29191
|
tool.result = event.result;
|
|
28707
29192
|
tool.isError = event.isError;
|
|
28708
29193
|
const enriched = event;
|
|
29194
|
+
tool.evictedReason = typeof enriched.evictedReason === "string" && enriched.evictedReason.length > 0 ? enriched.evictedReason : void 0;
|
|
28709
29195
|
const settled = toolSettlement(enriched);
|
|
28710
29196
|
tool.settlement = settled?.settlement;
|
|
28711
29197
|
tool.blockReason = settled?.reason;
|
|
@@ -29626,7 +30112,7 @@ function processAutoPacingAllowed(backpressureObserved, env = process.env) {
|
|
|
29626
30112
|
|
|
29627
30113
|
// src/interactive/welcome-dashboard.ts
|
|
29628
30114
|
init_esm_shims();
|
|
29629
|
-
import { existsSync as
|
|
30115
|
+
import { existsSync as existsSync8, readdirSync as readdirSync2, statSync as statSync3 } from "node:fs";
|
|
29630
30116
|
import { basename as basename3, join as join8 } from "node:path";
|
|
29631
30117
|
function activeStatus(status) {
|
|
29632
30118
|
return status.available && status.health.status !== "down";
|
|
@@ -29694,7 +30180,7 @@ function wikiFactsFrom(cwd, staleness) {
|
|
|
29694
30180
|
}
|
|
29695
30181
|
function handoffFacts(cwd) {
|
|
29696
30182
|
const handoffsDir = join8(cwd, ".clio-coder", "handoffs");
|
|
29697
|
-
if (!
|
|
30183
|
+
if (!existsSync8(handoffsDir)) return { handoffCount: 0, handoffFreshness: "none" };
|
|
29698
30184
|
try {
|
|
29699
30185
|
const files = readdirSync2(handoffsDir).filter((f) => f.startsWith("handoff-") && f.endsWith(".md"));
|
|
29700
30186
|
if (files.length === 0) return { handoffCount: 0, handoffFreshness: "none" };
|
|
@@ -29738,7 +30224,7 @@ async function readWelcomeRepositoryFactsAsync(cwd) {
|
|
|
29738
30224
|
function placeholderRepositoryFacts(cwd) {
|
|
29739
30225
|
return {
|
|
29740
30226
|
clioMdStatus: clioMdStatusFor(cwd),
|
|
29741
|
-
hasCodewiki:
|
|
30227
|
+
hasCodewiki: existsSync8(join8(cwd, ".clio-coder", "codewiki.json")),
|
|
29742
30228
|
codewikiCount: 0,
|
|
29743
30229
|
wikiPageCount: 0,
|
|
29744
30230
|
wikiStatus: NO_WIKI_STATUS,
|
|
@@ -30028,7 +30514,11 @@ function createInteractivePresentation(deps) {
|
|
|
30028
30514
|
bus: deps.bus,
|
|
30029
30515
|
...deps.getSettings ? { getSettings: deps.getSettings } : {}
|
|
30030
30516
|
});
|
|
30031
|
-
const dispatchBoardStore = factories.createDispatchBoardStore(
|
|
30517
|
+
const dispatchBoardStore = factories.createDispatchBoardStore(
|
|
30518
|
+
deps.bus,
|
|
30519
|
+
() => deps.dispatch.snapshot(),
|
|
30520
|
+
(runId) => readWorkerReceiptFacts(runId)
|
|
30521
|
+
);
|
|
30032
30522
|
const contextActivityStore = factories.createContextActivityStore(deps.bus);
|
|
30033
30523
|
const footerToolCounts = /* @__PURE__ */ new Map();
|
|
30034
30524
|
const footerActiveTools = /* @__PURE__ */ new Set();
|
|
@@ -30173,6 +30663,7 @@ function createInteractivePresentation(deps) {
|
|
|
30173
30663
|
)?.thinking.display ?? current?.orchestrator?.thinkingLevel ?? "off";
|
|
30174
30664
|
},
|
|
30175
30665
|
isStreaming: () => deps.chat.isStreaming(),
|
|
30666
|
+
...deps.isAwaitingApproval ? { isAwaitingApproval: deps.isAwaitingApproval } : {},
|
|
30176
30667
|
willEnterSteer: (text) => willEnterSteerActiveWork(deps, text),
|
|
30177
30668
|
getSubmitKeyLabel: () => formatKeyLabel(keybindings.getKeys("tui.input.submit")[0], "Enter"),
|
|
30178
30669
|
getNewlineKeyLabel: () => formatKeyLabel(keybindings.getKeys("tui.input.newLine")[0], "Shift+Enter")
|
|
@@ -30304,9 +30795,9 @@ function createInteractivePresentation(deps) {
|
|
|
30304
30795
|
root,
|
|
30305
30796
|
getObservabilitySnapshot: () => observabilitySnapshot,
|
|
30306
30797
|
recordChatEvent,
|
|
30307
|
-
recordToolStart: (toolCallId,
|
|
30798
|
+
recordToolStart: (toolCallId, toolName) => {
|
|
30308
30799
|
footerActiveTools.add(toolCallId);
|
|
30309
|
-
footerToolCounts.set(
|
|
30800
|
+
footerToolCounts.set(toolName, (footerToolCounts.get(toolName) ?? 0) + 1);
|
|
30310
30801
|
},
|
|
30311
30802
|
recordToolEnd: ({ toolCallId, isError, truncated }) => {
|
|
30312
30803
|
footerActiveTools.delete(toolCallId);
|
|
@@ -30342,6 +30833,57 @@ init_esm_shims();
|
|
|
30342
30833
|
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
30343
30834
|
import { join as join9, resolve as resolve4 } from "node:path";
|
|
30344
30835
|
|
|
30836
|
+
// src/interactive/context-recall-command.ts
|
|
30837
|
+
init_esm_shims();
|
|
30838
|
+
function formatTokens3(tokens) {
|
|
30839
|
+
return tokens.toLocaleString("en-US");
|
|
30840
|
+
}
|
|
30841
|
+
function headlineFor(ref, tokens, state, offloadPath) {
|
|
30842
|
+
const parts = [ref];
|
|
30843
|
+
if (state !== void 0) {
|
|
30844
|
+
parts.push(state.by === void 0 ? `evicted: ${state.reason}` : `evicted: ${state.reason} by ${state.by}`);
|
|
30845
|
+
}
|
|
30846
|
+
parts.push(`${formatTokens3(tokens)} tokens`);
|
|
30847
|
+
if (offloadPath !== void 0) parts.push(`offload: ${offloadPath}`);
|
|
30848
|
+
return `[/context recall] ${parts.join(" \xB7 ")}`;
|
|
30849
|
+
}
|
|
30850
|
+
function runOperatorRecall(ref, deps) {
|
|
30851
|
+
if (!deps.hasSession()) {
|
|
30852
|
+
return { ok: false, message: "[/context recall] no active session; start one with /new or /resume first" };
|
|
30853
|
+
}
|
|
30854
|
+
const trimmed = ref.trim();
|
|
30855
|
+
if (trimmed.length === 0) {
|
|
30856
|
+
return { ok: false, message: "[/context recall] needs a ref: the turnId named in an [evicted ...] marker" };
|
|
30857
|
+
}
|
|
30858
|
+
const entries = deps.readEntries();
|
|
30859
|
+
const leaf = deps.activeLeafTurnId();
|
|
30860
|
+
const view = foldWorkingSet(entries, leaf);
|
|
30861
|
+
const resolved = resolveRecall(entries, view, trimmed, leaf);
|
|
30862
|
+
if (!resolved.ok)
|
|
30863
|
+
return { ok: false, message: `[/context recall] ${recallErrorMessage(resolved.error, entries, view)}` };
|
|
30864
|
+
const { result } = resolved;
|
|
30865
|
+
const fields = buildRecallFields(result, { trigger: "operator" });
|
|
30866
|
+
try {
|
|
30867
|
+
deps.appendEntry({ ...fields, parentTurnId: recallParentTurnId(entries, leaf) });
|
|
30868
|
+
} catch (err) {
|
|
30869
|
+
return {
|
|
30870
|
+
ok: false,
|
|
30871
|
+
message: `[/context recall] recall of ${result.ref.entry} could not be recorded: ${err instanceof Error ? err.message : String(err)}`
|
|
30872
|
+
};
|
|
30873
|
+
}
|
|
30874
|
+
deps.onRecalled?.({
|
|
30875
|
+
ref: result.ref.entry,
|
|
30876
|
+
trigger: "operator",
|
|
30877
|
+
tokensReadmitted: result.tokens,
|
|
30878
|
+
at: deps.now?.() ?? Date.now()
|
|
30879
|
+
});
|
|
30880
|
+
return {
|
|
30881
|
+
ok: true,
|
|
30882
|
+
headline: headlineFor(result.ref.entry, result.tokens, view.evicted.get(result.ref.entry), result.offloadPath),
|
|
30883
|
+
body: result.body
|
|
30884
|
+
};
|
|
30885
|
+
}
|
|
30886
|
+
|
|
30345
30887
|
// src/interactive/export-html/index.ts
|
|
30346
30888
|
init_esm_shims();
|
|
30347
30889
|
|
|
@@ -30899,6 +31441,34 @@ function createInteractiveSlashRuntime(deps) {
|
|
|
30899
31441
|
}
|
|
30900
31442
|
deps.openContextReset();
|
|
30901
31443
|
},
|
|
31444
|
+
...deps.session ? {
|
|
31445
|
+
runContextRecall: (ref) => {
|
|
31446
|
+
const session = deps.session;
|
|
31447
|
+
if (!session) return;
|
|
31448
|
+
const outcome = runOperatorRecall(ref, {
|
|
31449
|
+
hasSession: () => session.current() !== null,
|
|
31450
|
+
readEntries: () => {
|
|
31451
|
+
const sessionId = deps.chat.getSessionId();
|
|
31452
|
+
return sessionId ? deps.readStructuredEntries(sessionId) : [];
|
|
31453
|
+
},
|
|
31454
|
+
activeLeafTurnId: () => {
|
|
31455
|
+
const meta = session.current();
|
|
31456
|
+
return meta ? session.tree(meta.id).leafId ?? void 0 : void 0;
|
|
31457
|
+
},
|
|
31458
|
+
appendEntry: (entry) => session.appendEntry(entry),
|
|
31459
|
+
onRecalled: (payload) => deps.bus.emit(BusChannels.ContextRecalled, payload),
|
|
31460
|
+
...deps.now ? { now: () => (deps.now?.() ?? /* @__PURE__ */ new Date()).getTime() } : {}
|
|
31461
|
+
});
|
|
31462
|
+
if (!outcome.ok) {
|
|
31463
|
+
appendCommandNotice("error", outcome.message);
|
|
31464
|
+
return;
|
|
31465
|
+
}
|
|
31466
|
+
appendCommandNotice("success", outcome.headline);
|
|
31467
|
+
deps.io.stdout(`${outcome.body}
|
|
31468
|
+
`);
|
|
31469
|
+
deps.requestRender();
|
|
31470
|
+
}
|
|
31471
|
+
} : {},
|
|
30902
31472
|
runContextRefresh: () => {
|
|
30903
31473
|
if (!deps.onContextRefresh) {
|
|
30904
31474
|
deps.io.stderr("[/context refresh] context refresh not wired; pass onContextRefresh to startInteractive\n");
|
|
@@ -31160,7 +31730,7 @@ function createSessionTranscript(deps) {
|
|
|
31160
31730
|
const turns = deps.readSessionEntries();
|
|
31161
31731
|
deps.chat.resetForSession(
|
|
31162
31732
|
leafTurnId,
|
|
31163
|
-
|
|
31733
|
+
buildModelReplayAgentMessagesFromTurns(turns, {
|
|
31164
31734
|
...leafTurnId ? { activeLeafTurnId: leafTurnId } : {}
|
|
31165
31735
|
})
|
|
31166
31736
|
);
|
|
@@ -31398,10 +31968,12 @@ async function createInteractiveApplication(deps) {
|
|
|
31398
31968
|
const { readStructuredEntries, recordSubmittedTurn } = sessionTranscript;
|
|
31399
31969
|
let leaderArmed = false;
|
|
31400
31970
|
let shutdownArmed = false;
|
|
31971
|
+
let overlayLifecycle;
|
|
31401
31972
|
const presentation = createInteractivePresentation({
|
|
31402
31973
|
bus: deps.bus,
|
|
31403
31974
|
getLeaderArmed: () => leaderArmed,
|
|
31404
31975
|
getShutdownArmed: () => shutdownArmed,
|
|
31976
|
+
isAwaitingApproval: () => overlayLifecycle?.getState() === "permission-confirm",
|
|
31405
31977
|
resolveVisibleEventSequence: (event) => visibleEventIngress.get(event)?.traceSequence ?? null,
|
|
31406
31978
|
resolveStreamIngress: (event) => visibleEventIngress.get(event) ?? null,
|
|
31407
31979
|
commitFrame: (reason) => shell.commitCurrentFrame(reason === "teardown" ? 300 : 3e4),
|
|
@@ -31470,7 +32042,7 @@ async function createInteractiveApplication(deps) {
|
|
|
31470
32042
|
isAskUserWaiting: () => overlayLifecycle.isAskUserWaiting(),
|
|
31471
32043
|
closeAskUserSession: () => overlayLifecycle.closeAskUserSession(),
|
|
31472
32044
|
resetAskUserCancellation: () => overlayLifecycle.resetAskUserCancellation(),
|
|
31473
|
-
recordToolStart: (
|
|
32045
|
+
recordToolStart: (toolName, toolCallId) => presentation.recordToolStart(toolCallId, toolName),
|
|
31474
32046
|
recordToolEnd: (_toolName, toolCallId, isError, truncated) => presentation.recordToolEnd({ toolCallId, isError, truncated }),
|
|
31475
32047
|
setStatusLine: (line) => chatPanel.setStatusLine(line),
|
|
31476
32048
|
setLiveReasoning: (view) => chatPanel.setLiveReasoning(view),
|
|
@@ -31576,7 +32148,6 @@ async function createInteractiveApplication(deps) {
|
|
|
31576
32148
|
notify
|
|
31577
32149
|
});
|
|
31578
32150
|
editor.onSubmit = editorSubmit.submitEditorText;
|
|
31579
|
-
let overlayLifecycle;
|
|
31580
32151
|
const interactiveTickers = createInteractiveTickers({
|
|
31581
32152
|
tui,
|
|
31582
32153
|
dispatchBoardStore,
|
|
@@ -31862,7 +32433,7 @@ import { resolve as resolve5 } from "node:path";
|
|
|
31862
32433
|
|
|
31863
32434
|
// src/tools/dispatch-scout-admission.ts
|
|
31864
32435
|
init_esm_shims();
|
|
31865
|
-
import { existsSync as
|
|
32436
|
+
import { existsSync as existsSync9, readFileSync as readFileSync8 } from "node:fs";
|
|
31866
32437
|
import { join as join10 } from "node:path";
|
|
31867
32438
|
var MAX_SCOUT_PLAN_DEADLINE_MS = 36e5;
|
|
31868
32439
|
function record(value) {
|
|
@@ -31911,7 +32482,7 @@ function loadVerifiedScoutSource(input) {
|
|
|
31911
32482
|
const envelope = input.dispatch.getRun(input.ref.runId);
|
|
31912
32483
|
if (envelope === null) throw new Error(`dispatch: Scout source run '${input.ref.runId}' is unavailable`);
|
|
31913
32484
|
const receiptPath = envelope.receiptPath ?? join10(clioStateDir(), "receipts", `${input.ref.runId}.json`);
|
|
31914
|
-
if (!
|
|
32485
|
+
if (!existsSync9(receiptPath)) throw new Error(`dispatch: Scout source receipt '${input.ref.runId}' is unavailable`);
|
|
31915
32486
|
let receipt;
|
|
31916
32487
|
try {
|
|
31917
32488
|
receipt = JSON.parse(readFileSync8(receiptPath, "utf8"));
|
|
@@ -32504,6 +33075,24 @@ function createDispatchAdmissionController(deps) {
|
|
|
32504
33075
|
|
|
32505
33076
|
// src/tools/dispatch.ts
|
|
32506
33077
|
var THINKING_LEVELS2 = ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
|
|
33078
|
+
var DispatchBudgetPhaseSchema = typebox_exports.Object(
|
|
33079
|
+
{
|
|
33080
|
+
toolCalls: typebox_exports.Integer({ minimum: 1 }),
|
|
33081
|
+
readReserve: typebox_exports.Integer({ minimum: 0 })
|
|
33082
|
+
},
|
|
33083
|
+
{ additionalProperties: false }
|
|
33084
|
+
);
|
|
33085
|
+
var DispatchBudgetSchema = typebox_exports.Object(
|
|
33086
|
+
{
|
|
33087
|
+
toolCalls: typebox_exports.Integer({ minimum: 1, description: "Requested tool-call phase boundary." }),
|
|
33088
|
+
readReserve: typebox_exports.Integer({ minimum: 0, description: "Requested tail reserve for canonical read calls." }),
|
|
33089
|
+
retryRevision: typebox_exports.Optional(DispatchBudgetPhaseSchema)
|
|
33090
|
+
},
|
|
33091
|
+
{
|
|
33092
|
+
additionalProperties: false,
|
|
33093
|
+
description: "Invocation budget inside the recipe policy. retryRevision preauthorizes one ceiling for retry, result-contract revision, or review revision phases."
|
|
33094
|
+
}
|
|
33095
|
+
);
|
|
32507
33096
|
function admissionFailureResult(message) {
|
|
32508
33097
|
return {
|
|
32509
33098
|
kind: "error",
|
|
@@ -32518,12 +33107,12 @@ function createDispatchTool(inputDeps, surfaceOptions = {}) {
|
|
|
32518
33107
|
const admission = createDispatchAdmissionController(deps);
|
|
32519
33108
|
let runnerPromise = null;
|
|
32520
33109
|
const loadRunner = () => {
|
|
32521
|
-
runnerPromise ??= (surfaceOptions.loadRunner ?? (() => import("./dispatch-runner-
|
|
33110
|
+
runnerPromise ??= (surfaceOptions.loadRunner ?? (() => import("./dispatch-runner-GIJBHNFL.js")))();
|
|
32522
33111
|
return runnerPromise;
|
|
32523
33112
|
};
|
|
32524
33113
|
return {
|
|
32525
33114
|
name: ToolNames.Dispatch,
|
|
32526
|
-
description: 'Dispatch one bounded task with task, or a batch with tasks (never both). Singular example: {agent:"debugger", task:"Verify the receipt boundary", briefing:"Prior receipt evidence...", detach:true}. task is the worker assignment; briefing is separate bounded parent context/data and cannot replace task. Ordinary calls auto-wait; detach:true returns ids for monitoring/steering, and collect is the authoritative terminal batch operation before final synthesis. Batch modes are parallel (default), sequential, pipeline, or compete. Task objects may include persona and
|
|
33115
|
+
description: 'Dispatch one bounded task with task, or a batch with tasks (never both). Singular example: {agent:"debugger", task:"Verify the receipt boundary", briefing:"Prior receipt evidence...", detach:true}. task is the worker assignment; briefing is separate bounded parent context/data and cannot replace task. Ordinary calls auto-wait; detach:true returns ids for monitoring/steering, and collect is the authoritative terminal batch operation before final synthesis. Batch modes are parallel (default), sequential, pipeline, or compete. Task objects may include persona, tool_profile, and a recipe-admitted budget envelope. Sealed receipts are durable evidence; report receipt integrity, evidence verification, briefing provenance, and project-context provenance separately. Call with list:true to see agents. Do not repeat an identical successful dispatch in the same user turn. Prefer this tool over inline exploration whenever work is read-only fan-out, parallel investigation, or the operator asked for a worker by name; if you cannot dispatch, say so plainly and name the reason, and never narrate or summarize a worker you did not actually dispatch.',
|
|
32527
33116
|
parameters: typebox_exports.Object({
|
|
32528
33117
|
list: typebox_exports.Optional(typebox_exports.Boolean({ description: "List available agents instead of dispatching." })),
|
|
32529
33118
|
from_scout: typebox_exports.Optional(
|
|
@@ -32563,6 +33152,7 @@ function createDispatchTool(inputDeps, surfaceOptions = {}) {
|
|
|
32563
33152
|
tool_profile: typebox_exports.Optional(
|
|
32564
33153
|
StringEnum(TOOL_PROFILE_NAMES, { description: "Narrow this worker's available tools." })
|
|
32565
33154
|
),
|
|
33155
|
+
budget: typebox_exports.Optional(DispatchBudgetSchema),
|
|
32566
33156
|
target: typebox_exports.Optional(typebox_exports.String()),
|
|
32567
33157
|
model: typebox_exports.Optional(typebox_exports.String()),
|
|
32568
33158
|
node: typebox_exports.Optional(typebox_exports.String({ description: "Fleet node pin: local or a fleet.nodes id." })),
|
|
@@ -32644,6 +33234,7 @@ function createDispatchTool(inputDeps, surfaceOptions = {}) {
|
|
|
32644
33234
|
typebox_exports.String({ description: "Default ad-hoc specialist persona for dispatched tasks, max 8000 chars." })
|
|
32645
33235
|
),
|
|
32646
33236
|
tool_profile: typebox_exports.Optional(StringEnum(TOOL_PROFILE_NAMES, { description: "Default worker tool profile." })),
|
|
33237
|
+
budget: typebox_exports.Optional(DispatchBudgetSchema),
|
|
32647
33238
|
target: typebox_exports.Optional(typebox_exports.String({ description: "Default configured target id (omit for fleet default)." })),
|
|
32648
33239
|
model: typebox_exports.Optional(typebox_exports.String({ description: "Default model override." })),
|
|
32649
33240
|
node: typebox_exports.Optional(
|
|
@@ -32722,7 +33313,7 @@ function registerAllTools(registry, deps = {}) {
|
|
|
32722
33313
|
...builtin(
|
|
32723
33314
|
lazyTool(
|
|
32724
33315
|
monitorToolSurface,
|
|
32725
|
-
async () => (await import("./monitor-
|
|
33316
|
+
async () => (await import("./monitor-US5F5YGZ.js")).createMonitorTool({ dispatch, runEvents: dispatchRunEvents })
|
|
32726
33317
|
),
|
|
32727
33318
|
{
|
|
32728
33319
|
path: "src/tools/monitor.ts",
|
|
@@ -32796,11 +33387,11 @@ function createFileMutationObserver(sink) {
|
|
|
32796
33387
|
hooks: ["after_tool"],
|
|
32797
33388
|
evaluate(input) {
|
|
32798
33389
|
if (input.metadata?.resultKind !== "ok") return NO_EFFECTS;
|
|
32799
|
-
const
|
|
32800
|
-
const paths = toolMutationPaths(
|
|
33390
|
+
const toolName = input.toolName ?? "";
|
|
33391
|
+
const paths = toolMutationPaths(toolName, input.toolArgs !== void 0 ? { ...input.toolArgs } : void 0);
|
|
32801
33392
|
if (paths.length === 0) return NO_EFFECTS;
|
|
32802
33393
|
try {
|
|
32803
|
-
sink({ paths, toolName
|
|
33394
|
+
sink({ paths, toolName });
|
|
32804
33395
|
} catch {
|
|
32805
33396
|
}
|
|
32806
33397
|
return NO_EFFECTS;
|
|
@@ -33149,6 +33740,7 @@ async function bootOrchestrator(options = {}) {
|
|
|
33149
33740
|
installBusTracer();
|
|
33150
33741
|
termination.installSignalHandlers();
|
|
33151
33742
|
ensureClioState();
|
|
33743
|
+
sweepExpiredToolOffloads();
|
|
33152
33744
|
timer.mark("install check");
|
|
33153
33745
|
if (isGitRepository(process.cwd())) {
|
|
33154
33746
|
try {
|
|
@@ -33552,7 +34144,14 @@ async function bootOrchestrator(options = {}) {
|
|
|
33552
34144
|
});
|
|
33553
34145
|
const dispatchBackground = createDispatchBackgroundRegistry();
|
|
33554
34146
|
registerAllTools(toolRegistry, {
|
|
33555
|
-
...session ? {
|
|
34147
|
+
...session ? {
|
|
34148
|
+
session,
|
|
34149
|
+
readSessionEntries: () => {
|
|
34150
|
+
const meta = session.current();
|
|
34151
|
+
return meta ? readSessionEntriesForCompact(meta.id) : [];
|
|
34152
|
+
},
|
|
34153
|
+
onContextRecalled: (payload) => bus.emit(BusChannels.ContextRecalled, payload)
|
|
34154
|
+
} : {},
|
|
33556
34155
|
taskBoard,
|
|
33557
34156
|
userTasks,
|
|
33558
34157
|
dispatch,
|
|
@@ -33765,8 +34364,13 @@ async function bootOrchestrator(options = {}) {
|
|
|
33765
34364
|
getMemorySection: () => {
|
|
33766
34365
|
try {
|
|
33767
34366
|
const records = loadMemoryRecordsSync(clioDataDir());
|
|
34367
|
+
const settings = getCurrentSettings();
|
|
34368
|
+
const targetId = session?.current()?.target ?? settings.orchestrator?.target;
|
|
34369
|
+
const runtimeId = targetId ? providers.getTarget(targetId)?.runtime : void 0;
|
|
33768
34370
|
return buildMemoryPromptSection(records, {
|
|
33769
|
-
|
|
34371
|
+
scopes: ["global", "repo", "runtime"],
|
|
34372
|
+
activeRepository: canonicalMemoryRepositoryIdentity(process.cwd()),
|
|
34373
|
+
activeRuntime: runtimeId === void 0 ? null : { kind: "runtime", key: runtimeId }
|
|
33770
34374
|
}).section;
|
|
33771
34375
|
} catch {
|
|
33772
34376
|
return "";
|
|
@@ -33774,7 +34378,17 @@ async function bootOrchestrator(options = {}) {
|
|
|
33774
34378
|
},
|
|
33775
34379
|
getTaskMemoryHandoffSource: () => {
|
|
33776
34380
|
ensureTaskMemorySession();
|
|
33777
|
-
|
|
34381
|
+
const meta = session?.current();
|
|
34382
|
+
if (!meta) throw new Error("task memory handoff requires an active session");
|
|
34383
|
+
const settings = getCurrentSettings();
|
|
34384
|
+
const targetId = meta.target ?? settings.orchestrator?.target;
|
|
34385
|
+
const runtimeId = targetId ? providers.getTarget(targetId)?.runtime : void 0;
|
|
34386
|
+
return renderTaskMemoryHandoffSource(taskMemoryBank.snapshot(), {
|
|
34387
|
+
sessionId: meta.id,
|
|
34388
|
+
evidenceRefs: [`session-${meta.id}`],
|
|
34389
|
+
runtimeIds: runtimeId === void 0 ? [] : [runtimeId],
|
|
34390
|
+
agentIds: []
|
|
34391
|
+
});
|
|
33778
34392
|
},
|
|
33779
34393
|
registerDeferredReminderSink: (sink) => {
|
|
33780
34394
|
deferredMemoryReminderSink = sink;
|
|
@@ -33808,7 +34422,10 @@ async function bootOrchestrator(options = {}) {
|
|
|
33808
34422
|
try {
|
|
33809
34423
|
chat.resetForSession(
|
|
33810
34424
|
leafTurnId,
|
|
33811
|
-
|
|
34425
|
+
buildModelReplayAgentMessagesFromTurns(
|
|
34426
|
+
readCurrentSessionEntries(),
|
|
34427
|
+
leafTurnId ? { activeLeafTurnId: leafTurnId } : {}
|
|
34428
|
+
)
|
|
33812
34429
|
);
|
|
33813
34430
|
} catch (err) {
|
|
33814
34431
|
chat.resetForSession(leafTurnId);
|
|
@@ -33846,7 +34463,7 @@ async function bootOrchestrator(options = {}) {
|
|
|
33846
34463
|
...session ? { session } : {},
|
|
33847
34464
|
...session ? {
|
|
33848
34465
|
readSessionEntries: readSessionEntriesForCompact,
|
|
33849
|
-
buildReplayMessages: (entries, leafTurnId) =>
|
|
34466
|
+
buildReplayMessages: (entries, leafTurnId) => buildModelReplayAgentMessagesFromTurns(entries, leafTurnId === null ? {} : { activeLeafTurnId: leafTurnId })
|
|
33850
34467
|
} : {},
|
|
33851
34468
|
providers,
|
|
33852
34469
|
settings: {
|
|
@@ -34156,4 +34773,4 @@ export {
|
|
|
34156
34773
|
resolveApiKeyForTarget,
|
|
34157
34774
|
synthesizeOrchestratorModel
|
|
34158
34775
|
};
|
|
34159
|
-
//# sourceMappingURL=orchestrator-
|
|
34776
|
+
//# sourceMappingURL=orchestrator-E2AL4T5N.js.map
|