@iowarp/clio-coder 0.3.7 → 0.3.9
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 +80 -0
- package/README.md +13 -4
- package/dist/{acp-SK4MD6MM.js → acp-7LOELQFP.js} +13 -13
- package/dist/{agents-2FN2K6ME.js → agents-FIBG2SHA.js} +41 -37
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-QIYZWM5I.js → auth-OI4LIH2I.js} +31 -24
- package/dist/builtins-AD25UL3C.js +17 -0
- package/dist/{chunk-5FR74PWO.js → chunk-2JDWVJND.js} +2 -2
- package/dist/chunk-3DPEIQKN.js +113 -0
- package/dist/{chunk-EOOQZZDE.js → chunk-3DUR4WUA.js} +19 -19
- package/dist/{chunk-WHJYKASB.js → chunk-3MRC2YSQ.js} +2 -2
- package/dist/{chunk-EBEFWSGL.js → chunk-3UUY7R3Z.js} +14 -10
- package/dist/{chunk-LADCF22A.js → chunk-3V5AYSEQ.js} +113 -54
- package/dist/{chunk-BMWK7ZIZ.js → chunk-465CC7FK.js} +16 -13
- package/dist/{chunk-5WIGXA4T.js → chunk-47CMYGET.js} +111 -4
- package/dist/{chunk-CEYBNUGC.js → chunk-4H6ULJ3H.js} +378 -36
- package/dist/{chunk-YTYFXUI3.js → chunk-4LJX2PUC.js} +9 -9
- package/dist/{chunk-DOOEX22V.js → chunk-56KB5IJP.js} +5 -5
- package/dist/{chunk-SPULKLCF.js → chunk-5DQRIYDZ.js} +2 -2
- package/dist/{chunk-TSHXZTOQ.js → chunk-5HFBWUMU.js} +23 -11
- package/dist/{chunk-5UJ6ECTS.js → chunk-5PVQ4SRS.js} +80 -8
- package/dist/{chunk-ZWLZP4ZT.js → chunk-5QKCQQ3E.js} +359 -17
- package/dist/{chunk-6M7VS3J3.js → chunk-5T7RBWN2.js} +111 -5
- package/dist/chunk-774ILSRL.js +172 -0
- package/dist/chunk-7C6RYZGQ.js +391 -0
- package/dist/{chunk-GH5622CP.js → chunk-A2NJGIB3.js} +2 -2
- package/dist/{chunk-C4JBQ5SR.js → chunk-AD7Y7STJ.js} +6 -6
- package/dist/{chunk-GEYXPTRF.js → chunk-AEYBF3TB.js} +33 -12
- package/dist/{chunk-2SFS6XQE.js → chunk-AMKHQW3C.js} +3 -2
- package/dist/{chunk-D4MDIG46.js → chunk-B5CSFE7B.js} +7 -7
- package/dist/{chunk-MXI6J5JF.js → chunk-B5XRQOLB.js} +10 -10
- package/dist/{chunk-X2KV5FXT.js → chunk-BVDVID7E.js} +2 -2
- package/dist/{chunk-JNXPYBB4.js → chunk-CA42X6KT.js} +3 -3
- package/dist/{chunk-VREKEFLL.js → chunk-D73KXYPF.js} +3 -3
- package/dist/{chunk-JTSEDYVQ.js → chunk-DG4M6ZUE.js} +7 -7
- package/dist/{chunk-DQA7QLMD.js → chunk-EBOC7MT3.js} +10 -25
- package/dist/{chunk-KZ2H5X4G.js → chunk-ECUO3KDP.js} +129 -14
- package/dist/{chunk-JRIO5UD2.js → chunk-EQ63NRB7.js} +5 -5
- package/dist/{chunk-YD734TPH.js → chunk-FALJGAWU.js} +2 -2
- package/dist/{chunk-GWS3VEIW.js → chunk-FWDFM5ZU.js} +24 -3
- package/dist/{chunk-XEGB6BCN.js → chunk-GAYUJ7LE.js} +68 -14
- package/dist/{chunk-UND3GU2L.js → chunk-H7IXIC72.js} +2 -2
- package/dist/{chunk-IR4CFBFN.js → chunk-HAY4ZE2P.js} +12 -12
- package/dist/{chunk-UVDSQ6LW.js → chunk-HCBCAYZU.js} +74 -147
- package/dist/{chunk-4DWFMQDR.js → chunk-HJB5IUKP.js} +89 -145
- package/dist/{chunk-M4AKACEO.js → chunk-HKO36JWF.js} +33 -5
- package/dist/{chunk-KCMKRQX4.js → chunk-HPCTNZM2.js} +45 -82
- package/dist/{chunk-465YSENW.js → chunk-IFBNV6H6.js} +3 -3
- package/dist/{chunk-FJ3H4MN5.js → chunk-IHKBWSXF.js} +2 -2
- package/dist/chunk-JEQQR47K.js +3025 -0
- package/dist/{chunk-FO5ZOVUY.js → chunk-KV2AOLDF.js} +27 -7
- package/dist/chunk-LU7P4LHA.js +33 -0
- package/dist/{chunk-6TUKSZVF.js → chunk-LXPJXFM5.js} +11 -11
- package/dist/{chunk-VQNODYQ4.js → chunk-MIX5N5AC.js} +488 -3668
- package/dist/chunk-MLOK6ZOS.js +2888 -0
- package/dist/{chunk-ZZMN5OM4.js → chunk-MV2VUEJC.js} +2 -2
- package/dist/{chunk-MVVUPGPW.js → chunk-MXHC5QYU.js} +6 -6
- package/dist/{chunk-OBMAI2DP.js → chunk-N3PBVRTZ.js} +12 -388
- package/dist/{chunk-WJHBC77E.js → chunk-N5XKWMDW.js} +17 -7
- package/dist/{chunk-5C3AQNDW.js → chunk-NNNWO6F2.js} +124 -36
- package/dist/{chunk-UFQ3F4FW.js → chunk-NQ6UCCOD.js} +4 -4
- package/dist/chunk-NUGM5KR6.js +165 -0
- package/dist/{chunk-DMD2AGVS.js → chunk-NZU6YDNV.js} +20 -18
- package/dist/{chunk-WHGPSPT5.js → chunk-O6I4CIEU.js} +151 -13
- package/dist/{chunk-XN3L4EYL.js → chunk-OEDBCISO.js} +2 -2
- package/dist/{chunk-PD3MESLB.js → chunk-P3JGPQFL.js} +4 -4
- package/dist/{chunk-UHXRNZ2J.js → chunk-PNY46YEY.js} +23 -6
- package/dist/{chunk-THKY7CD7.js → chunk-PZ4I4JE2.js} +134 -29
- package/dist/{chunk-SROCI7ZU.js → chunk-QQ7EKM72.js} +5 -5
- package/dist/{chunk-QCTRSGHQ.js → chunk-R7LNVMCS.js} +91 -53
- package/dist/{chunk-GOXNB3AO.js → chunk-RAPCMZL4.js} +75 -4
- package/dist/chunk-RKKLTLYB.js +45 -0
- package/dist/{chunk-OB5HIGJY.js → chunk-RKRLDWD3.js} +4 -1
- package/dist/{chunk-DJNLUABN.js → chunk-S4COXYBG.js} +588 -32
- package/dist/{chunk-3HAPLH5M.js → chunk-T3Z6VAAF.js} +172 -11
- package/dist/{chunk-FOT2FX5J.js → chunk-TD7UE2L5.js} +12 -10
- package/dist/{chunk-UUANF5CR.js → chunk-TEO2TLVN.js} +856 -967
- package/dist/{chunk-FCSXB6T2.js → chunk-UOSL25KY.js} +14 -2
- package/dist/{chunk-EELBMBT6.js → chunk-VKBMFOYV.js} +74 -15
- package/dist/chunk-VO2LKSTM.js +165 -0
- package/dist/{chunk-5C77SEEY.js → chunk-VPTUJU4P.js} +3 -3
- package/dist/{chunk-WEH5XRJQ.js → chunk-WIE7ZOSW.js} +2 -2
- package/dist/{chunk-J7PIKKWC.js → chunk-WXCJ7VME.js} +8 -8
- package/dist/{chunk-4DGYLA73.js → chunk-XDOQXGFO.js} +22 -7
- package/dist/{chunk-PPAMZ32Z.js → chunk-XK56QHLX.js} +6 -1
- package/dist/{chunk-AB4XIIVB.js → chunk-YKOFT37S.js} +6 -6
- package/dist/chunk-YSEHGPCT.js +127 -0
- package/dist/{chunk-HFSBBKSQ.js → chunk-YW7UVM5V.js} +138 -3
- package/dist/cli/index.js +32 -32
- package/dist/{clio-WBVQEBKO.js → clio-LT5V7SSZ.js} +9 -9
- package/dist/{code-nav-FGGFIE7L.js → code-nav-LMW275PA.js} +5 -5
- package/dist/codewiki/build-worker.js +4 -4
- package/dist/{components-F7OEATSO.js → components-ZFA3SAER.js} +8 -8
- package/dist/{config-TRBL3RCF.js → config-RXS5T3JT.js} +98 -65
- package/dist/{configure-OLCVPHNM.js → configure-2WYWSCSD.js} +26 -22
- package/dist/{context-MJIJ6GOX.js → context-I3BTOTCS.js} +12 -12
- package/dist/{context-XEWE3MOJ.js → context-MVOORGMF.js} +54 -47
- package/dist/{context-WFPKQSM6.js → context-PALKKQYL.js} +28 -28
- package/dist/{context-clear-KNOS2JPB.js → context-clear-N2WOYZ2K.js} +53 -46
- package/dist/{context-index-SSR5ECNE.js → context-index-HNG3MOME.js} +6 -6
- package/dist/{context-working-set-EUXAZI6N.js → context-working-set-MIEVECVZ.js} +17 -18
- package/dist/{dispatch-runner-B7MTOVKL.js → dispatch-runner-VVA4SRRH.js} +90 -61
- package/dist/{docs-FLJTIDSE.js → docs-7LQ23DLM.js} +8 -8
- package/dist/doctor-TWBWFK5V.js +165 -0
- package/dist/eval-IJ5VEZDJ.js +4483 -0
- package/dist/{evidence-JZNBUOQZ.js → evidence-L5APPXNV.js} +68 -61
- package/dist/{evolve-FJVC4KKI.js → evolve-RGNKFJ52.js} +47 -40
- package/dist/{extensions-IQL36S7K.js → extensions-7WYWUX5A.js} +13 -7
- package/dist/{fleet-BDKYJFCP.js → fleet-6CNVBZZP.js} +113 -76
- package/dist/{fleet-commands-ZFIWZSB3.js → fleet-commands-L2SXSYEI.js} +10 -10
- package/dist/{fleet-graph-Y6HPXIVF.js → fleet-graph-2J3OOIPO.js} +17 -15
- package/dist/{fleet-preflight-BHSNPBMH.js → fleet-preflight-CZRJ4JP5.js} +5 -6
- package/dist/{fleet-validate-BIYREGIK.js → fleet-validate-C5RI6DP7.js} +20 -19
- package/dist/{init-LQUB5COQ.js → init-VBN2ACVA.js} +70 -63
- package/dist/{library-NJAHIGG4.js → library-JHGUMLY2.js} +22 -20
- package/dist/{memory-OG6HOYKM.js → memory-K4OQIYWG.js} +49 -42
- package/dist/{models-5ZG5XY7J.js → models-2NCZUWDD.js} +35 -29
- package/dist/{monitor-TJ7AMTGB.js → monitor-MMVTJABD.js} +64 -45
- package/dist/{orchestrator-WZYB54DM.js → orchestrator-ZKBPCHW6.js} +1971 -520
- package/dist/{paths-XUC7GS6E.js → paths-DBXMZMDU.js} +5 -5
- package/dist/registry-LG64LTF4.js +11 -0
- package/dist/{reset-PXQT45IY.js → reset-DD5JGOY3.js} +11 -11
- package/dist/{run-FQ74YF62.js → run-QEGNX7FL.js} +89 -83
- package/dist/{share-FW7SVCL3.js → share-JKD3BQMW.js} +20 -18
- package/dist/{skills-7E7IRB3R.js → skills-LMQIKDOZ.js} +23 -21
- package/dist/{skills-eval-LI75W6OK.js → skills-eval-I7X2774U.js} +59 -52
- package/dist/{steer-GGWFUJUD.js → steer-CF5TDANS.js} +3 -3
- package/dist/support-I7LOJLIF.js +38 -0
- package/dist/{targets-4CIFKCTW.js → targets-RUSR6B5Z.js} +77 -42
- package/dist/{terminal-lease-WUZY7ZV5.js → terminal-lease-QYVORFR4.js} +6 -4
- package/dist/{trace-PNCASAXC.js → trace-ODOQIVIW.js} +61 -6
- package/dist/{uninstall-7FV7IP4E.js → uninstall-ZJF5H5ZN.js} +8 -8
- package/dist/{upgrade-K2HVIVMQ.js → upgrade-XANW3FXB.js} +29 -26
- package/dist/{usage-GTZELZQX.js → usage-4H7ZRXQT.js} +110 -61
- package/dist/{verifiers-RLAHT27O.js → verifiers-UZXNBZEB.js} +13 -13
- package/dist/{verify-BX3BRKH5.js → verify-BVKWTNDL.js} +9 -9
- package/dist/{wiki-generate-ASIFASCN.js → wiki-generate-MY7WV2QI.js} +76 -69
- package/dist/worker/entry.js +69 -66
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +1 -1
- package/docs/artifact-versions.md +11 -5
- package/docs/built-in-agents.md +1 -1
- package/docs/capacity-and-scheduling.md +23 -2
- package/docs/commands-and-modes.md +2 -2
- package/docs/configuration-and-targets.md +37 -5
- package/docs/context-engine.md +63 -4
- package/docs/documentation-coverage.md +3 -3
- package/docs/documentation-guide.md +1 -1
- package/docs/environment-variables.md +2 -0
- package/docs/eval-runner.md +262 -11
- package/docs/evals-internal.md +72 -2
- package/docs/evidence-and-memory.md +77 -12
- package/docs/evolution.md +1 -1
- package/docs/extensions-and-sharing.md +3 -1
- package/docs/fleet-dispatch.md +34 -9
- package/docs/glossary.md +21 -1
- package/docs/installation-and-lifecycle.md +1 -1
- package/docs/middleware-and-components.md +1 -1
- package/docs/model-catalog.md +1 -1
- package/docs/observability.md +54 -3
- package/docs/proactive-memory.md +127 -14
- package/docs/prompt-envelope-and-tools.md +22 -2
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/release-cut-checklist.md +60 -41
- package/docs/safety-model.md +1 -1
- package/docs/scientific-validation.md +1 -1
- package/docs/skills-marketplace.md +1 -1
- package/docs/tool-usage.md +1 -1
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +87 -0
- package/docs/tui-design.md +1 -1
- package/docs/worker-dispatch-mechanics.md +1 -1
- package/package.json +2 -2
- package/src/cli/agents.ts +1 -1
- package/src/cli/argv.ts +5 -0
- package/src/cli/config-inspect.ts +33 -6
- package/src/cli/config.ts +1 -1
- package/src/cli/configure.ts +107 -23
- package/src/cli/doctor-state-size.ts +82 -0
- package/src/cli/doctor.ts +7 -1
- package/src/cli/eval.ts +80 -16
- package/src/cli/evidence.ts +30 -25
- package/src/cli/extensions.ts +5 -1
- package/src/cli/fleet-preflight.ts +2 -12
- package/src/cli/fleet.ts +32 -3
- package/src/cli/shared.ts +1 -0
- package/src/cli/targets.ts +45 -11
- package/src/cli/trace.ts +63 -4
- package/src/cli/usage.ts +63 -14
- package/src/cli/validate-model.ts +60 -5
- package/src/core/bus-events.ts +54 -1
- package/src/core/cache-telemetry.ts +42 -0
- package/src/core/commit-attribution.ts +4 -4
- package/src/core/config.ts +18 -0
- package/src/core/defaults.ts +36 -6
- package/src/core/endpoint-key.ts +27 -0
- package/src/core/path-boundary.ts +100 -0
- package/src/core/residency-target-key.ts +25 -0
- package/src/core/response-schema.ts +36 -2
- package/src/domains/agents/extension.ts +2 -11
- package/src/domains/agents/fleet-contract.ts +30 -12
- package/src/domains/agents/recipe.ts +7 -1
- package/src/domains/agents/registry.ts +73 -5
- package/src/domains/agents/result-contract.ts +128 -17
- package/src/domains/agents/write-boundary.ts +15 -50
- package/src/domains/config/classify.ts +3 -0
- package/src/domains/context/codewiki/coordinator.ts +12 -4
- package/src/domains/context/project-rules.ts +51 -1
- package/src/domains/dispatch/admission.ts +40 -3
- package/src/domains/dispatch/assignment-reconcile.ts +22 -5
- package/src/domains/dispatch/assignment-store.ts +151 -14
- package/src/domains/dispatch/capacity-lease.ts +98 -9
- package/src/domains/dispatch/contract.ts +26 -1
- package/src/domains/dispatch/delegation-plan.ts +2 -5
- package/src/domains/dispatch/execution-plan.ts +44 -4
- package/src/domains/dispatch/execution-role.ts +9 -1
- package/src/domains/dispatch/extension.ts +309 -96
- package/src/domains/dispatch/fleet-run.ts +78 -4
- package/src/domains/dispatch/gate-role-prompts.ts +38 -0
- package/src/domains/dispatch/heartbeat.ts +32 -8
- package/src/domains/dispatch/index.ts +6 -1
- package/src/domains/dispatch/intent-requirements.ts +40 -0
- package/src/domains/dispatch/intent.ts +84 -8
- package/src/domains/dispatch/orphan-recovery.ts +5 -0
- package/src/domains/dispatch/path-scope.ts +370 -0
- package/src/domains/dispatch/receipt-integrity.ts +2 -1
- package/src/domains/dispatch/reservation-store.ts +116 -8
- package/src/domains/dispatch/state.ts +4 -0
- package/src/domains/dispatch/types.ts +14 -7
- package/src/domains/dispatch/validation.ts +6 -3
- package/src/domains/dispatch/worker-spawn.ts +25 -11
- package/src/domains/dispatch/write-boundary-enforcer.ts +62 -0
- package/src/domains/dispatch/write-boundary.ts +262 -22
- package/src/domains/eval/artifacts/store.ts +62 -0
- package/src/domains/eval/compare/behavioral.ts +224 -0
- package/src/domains/eval/compare/compare.ts +355 -2
- package/src/domains/eval/compare/envelope.ts +128 -0
- package/src/domains/eval/compare/gates.ts +24 -6
- package/src/domains/eval/compare/thresholds.ts +30 -3
- package/src/domains/eval/execution-provenance.ts +240 -0
- package/src/domains/eval/metrics/aggregate.ts +136 -0
- package/src/domains/eval/metrics/call-ledger-stream.ts +112 -0
- package/src/domains/eval/metrics/evidence.ts +79 -2
- package/src/domains/eval/metrics/tracked.ts +413 -0
- package/src/domains/eval/provenance.ts +117 -0
- package/src/domains/eval/reports/comparison.ts +128 -0
- package/src/domains/eval/reports/junit.ts +17 -3
- package/src/domains/eval/reports/markdown.ts +3 -3
- package/src/domains/eval/reports/text.ts +14 -0
- package/src/domains/eval/run-compare.ts +20 -0
- package/src/domains/eval/runners/clio-run.ts +139 -2
- package/src/domains/eval/runners/external-command.ts +28 -3
- package/src/domains/eval/schema/adapter.ts +111 -0
- package/src/domains/eval/schema/artifact.ts +20 -0
- package/src/domains/eval/schema/behavioral-metrics.ts +204 -0
- package/src/domains/eval/schema/behavioral.ts +520 -0
- package/src/domains/eval/schema/execution-envelope.ts +194 -0
- package/src/domains/eval/schema/serving.ts +74 -0
- package/src/domains/eval/schema/suite.ts +38 -8
- package/src/domains/eval/schema/validate.ts +58 -3
- package/src/domains/eval/schema/verdict.ts +237 -0
- package/src/domains/eval/suites/resolve.ts +2 -0
- package/src/domains/eval/suites/run.ts +264 -33
- package/src/domains/eval/verifiers/command.ts +2 -1
- package/src/domains/eval/workspaces/temp-copy.ts +145 -13
- package/src/domains/evidence/build.ts +68 -21
- package/src/domains/evidence/eval.ts +2 -12
- package/src/domains/evidence/findings-markdown.ts +33 -0
- package/src/domains/evidence/index.ts +21 -0
- package/src/domains/evidence/provenance.ts +46 -11
- package/src/domains/evidence/run-trust.ts +7 -113
- package/src/domains/evidence/trust-projection.ts +274 -0
- package/src/domains/evidence/trust-status.ts +145 -17
- package/src/domains/evidence/types.ts +4 -0
- package/src/domains/extensions/compatibility.ts +285 -0
- package/src/domains/extensions/discovery.ts +126 -4
- package/src/domains/extensions/resources.ts +21 -9
- package/src/domains/extensions/state.ts +18 -5
- package/src/domains/extensions/types.ts +6 -1
- package/src/domains/lifecycle/doctor.ts +209 -2
- package/src/domains/memory/index.ts +14 -0
- package/src/domains/memory/task-bank-promotion.ts +64 -0
- package/src/domains/memory/task-memory-policy.ts +77 -8
- package/src/domains/memory/task-memory-spend.ts +131 -0
- package/src/domains/memory/task-memory-status.ts +7 -0
- package/src/domains/memory/task-memory-telemetry.ts +2 -0
- package/src/domains/middleware/index.ts +1 -0
- package/src/domains/middleware/memory-intervention.ts +69 -5
- package/src/domains/middleware/memory-step-endpoint.ts +71 -0
- package/src/domains/observability/background-memory-usage.ts +140 -0
- package/src/domains/observability/cost.ts +1 -1
- package/src/domains/observability/index.ts +7 -0
- package/src/domains/observability/out-of-turn-usage.ts +51 -2
- package/src/domains/observability/trace-store.ts +192 -2
- package/src/domains/prompts/compiler.ts +100 -13
- package/src/domains/prompts/contract.ts +3 -5
- package/src/domains/providers/endpoint-capacity.ts +96 -0
- package/src/domains/providers/extension.ts +30 -2
- package/src/domains/providers/index.ts +10 -0
- package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +243 -1
- package/src/domains/providers/runtime-resolution.ts +8 -1
- package/src/domains/providers/runtimes/common/probe-helpers.ts +31 -9
- package/src/domains/providers/runtimes/local-native/llamacpp-anthropic.ts +1 -1
- package/src/domains/providers/runtimes/local-native/llamacpp-completion.ts +1 -1
- package/src/domains/providers/runtimes/local-native/llamacpp-embed.ts +1 -1
- package/src/domains/providers/runtimes/local-native/llamacpp-rerank.ts +1 -1
- package/src/domains/providers/runtimes/local-native/llamacpp.ts +4 -1
- package/src/domains/providers/runtimes/local-native/lmstudio.ts +4 -1
- package/src/domains/providers/runtimes/local-native/ollama-native.ts +6 -1
- package/src/domains/providers/types/capability-flags.ts +2 -0
- package/src/domains/providers/types/target-descriptor.ts +2 -0
- package/src/domains/resources/common-loader.ts +3 -0
- package/src/domains/resources/prompts/loader.ts +184 -17
- package/src/domains/safety/call-target.ts +52 -0
- package/src/domains/safety/policy-engine.ts +5 -5
- package/src/domains/safety/run-effects.ts +96 -2
- package/src/domains/safety/scope.ts +7 -12
- package/src/domains/session/context-accounting.ts +52 -1
- package/src/domains/session/context-ledger.ts +37 -13
- package/src/domains/session/index.ts +6 -0
- package/src/domains/session/prompt-cache.ts +140 -0
- package/src/domains/session/prompt-manifest.ts +42 -0
- package/src/engine/acp/adapter.ts +18 -3
- package/src/engine/acp/server.ts +4 -1
- package/src/engine/ai.ts +35 -0
- package/src/engine/apis/llamacpp-residency.ts +55 -3
- package/src/engine/apis/lmstudio.ts +25 -5
- package/src/engine/apis/ollama-native.ts +2 -1
- package/src/engine/apis/openai-completions.ts +80 -17
- package/src/engine/apis/residency-lock.ts +3 -1
- package/src/engine/apis/residency.ts +34 -1
- package/src/engine/prompt-templates.ts +18 -1
- package/src/engine/provider-payload.ts +29 -1
- package/src/engine/worker-runtime.ts +6 -3
- package/src/entry/orchestrator.ts +176 -30
- package/src/interactive/chat-loop-messages.ts +26 -7
- package/src/interactive/chat-loop.ts +318 -41
- package/src/interactive/chat-panel.ts +62 -8
- package/src/interactive/clio-editor.ts +45 -8
- package/src/interactive/context-activity.ts +5 -1
- package/src/interactive/context-meter.ts +1 -1
- package/src/interactive/context-overlay.ts +40 -10
- package/src/interactive/cost-overlay.ts +64 -6
- package/src/interactive/dispatch-board.ts +127 -5
- package/src/interactive/fleet-run-preview.ts +41 -15
- package/src/interactive/handoff-round.ts +41 -2
- package/src/interactive/interactive-application.ts +24 -1
- package/src/interactive/interactive-event-projection.ts +14 -0
- package/src/interactive/interactive-input-runtime.ts +8 -0
- package/src/interactive/interactive-presentation.ts +4 -0
- package/src/interactive/interactive-shell.ts +20 -17
- package/src/interactive/interactive-slash-runtime.ts +27 -4
- package/src/interactive/memory-overlay.ts +8 -0
- package/src/interactive/mutation-preview.ts +295 -0
- package/src/interactive/overlay-general-openers.ts +16 -0
- package/src/interactive/overlay-key-routing.ts +38 -0
- package/src/interactive/overlay-lifecycle.ts +38 -5
- package/src/interactive/overlay-permission-lifecycle.ts +22 -2
- package/src/interactive/overlay-session-lifecycle.ts +73 -9
- package/src/interactive/overlays/ask-user.ts +91 -19
- package/src/interactive/overlays/help-reference.ts +4 -0
- package/src/interactive/overlays/prompts.ts +11 -1
- package/src/interactive/overlays/settings.ts +176 -48
- package/src/interactive/permission-hint.ts +34 -2
- package/src/interactive/permission-overlay.ts +159 -9
- package/src/interactive/prewarm.ts +197 -0
- package/src/interactive/render-trace.ts +162 -15
- package/src/interactive/renderers/tool-execution.ts +4 -0
- package/src/interactive/side-question.ts +58 -1
- package/src/interactive/slash-commands.ts +7 -2
- package/src/interactive/status/controller.ts +11 -0
- package/src/interactive/status/state-machine.ts +54 -2
- package/src/interactive/status/types.ts +7 -0
- package/src/interactive/terminal-lease.ts +2 -0
- package/src/interactive/turn-context.ts +299 -31
- package/src/interactive/turn-persistence.ts +14 -4
- package/src/interactive/turn-prewarm.ts +364 -0
- package/src/interactive/turn-queues.ts +7 -4
- package/src/interactive/turn-runtime.ts +8 -1
- package/src/interactive/turn-state.ts +23 -0
- package/src/interactive/view/artifacts.ts +42 -9
- package/src/interactive/view/view-overlay.ts +43 -6
- package/src/interactive/worker-receipts.ts +14 -2
- package/src/interactive/worker-stream.ts +8 -0
- package/src/tools/ask-user.ts +43 -2
- package/src/tools/dispatch-admission.ts +12 -13
- package/src/tools/dispatch-arguments.ts +27 -0
- package/src/tools/dispatch-plan.ts +46 -9
- package/src/tools/dispatch-runner.ts +48 -13
- package/src/tools/dispatch-scout.ts +1 -1
- package/src/tools/monitor.ts +13 -0
- package/src/tools/registry.ts +16 -0
- package/src/tools/worker-evidence.ts +19 -13
- package/src/worker/spec-contract.ts +2 -1
- package/dist/chunk-AOCYTWAV.js +0 -449
- package/dist/chunk-HWUFFB6L.js +0 -83
- package/dist/chunk-R346GLFC.js +0 -31
- package/dist/chunk-ZGH7FGS5.js +0 -1079
- package/dist/doctor-RN4YKO2X.js +0 -87
- package/dist/eval-RUBJVSNQ.js +0 -2557
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import { createRequire as __clioCreateRequire } from "node:module"; const require = __clioCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
ShareDomainModule
|
|
4
|
+
} from "./chunk-TD7UE2L5.js";
|
|
5
|
+
import {
|
|
6
|
+
bootstrapInputFromInitOptions,
|
|
7
|
+
modelBootstrapGenerate,
|
|
8
|
+
resolveBootstrapRoute
|
|
9
|
+
} from "./chunk-3DUR4WUA.js";
|
|
10
|
+
import "./chunk-J5Q24KAG.js";
|
|
2
11
|
import {
|
|
3
12
|
DEFAULT_KEEP_RECENT_TOKENS,
|
|
4
13
|
DEFAULT_RESERVE_TOKENS,
|
|
@@ -12,7 +21,7 @@ import {
|
|
|
12
21
|
projectWorkingSet,
|
|
13
22
|
resolveWorkingSetPolicy,
|
|
14
23
|
selectVisibleEntries
|
|
15
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-3MRC2YSQ.js";
|
|
16
25
|
import {
|
|
17
26
|
assistantSessionPayload,
|
|
18
27
|
backendCacheVerdict,
|
|
@@ -45,86 +54,199 @@ import {
|
|
|
45
54
|
toolNamesFromAgentState,
|
|
46
55
|
toolResultSummary,
|
|
47
56
|
toolSignatureFromState
|
|
48
|
-
} from "./chunk-
|
|
49
|
-
import {
|
|
50
|
-
ShareDomainModule
|
|
51
|
-
} from "./chunk-FOT2FX5J.js";
|
|
52
|
-
import {
|
|
53
|
-
bootstrapInputFromInitOptions,
|
|
54
|
-
modelBootstrapGenerate,
|
|
55
|
-
resolveBootstrapRoute
|
|
56
|
-
} from "./chunk-EOOQZZDE.js";
|
|
57
|
-
import "./chunk-J5Q24KAG.js";
|
|
57
|
+
} from "./chunk-N5XKWMDW.js";
|
|
58
58
|
import {
|
|
59
59
|
SchedulingDomainModule,
|
|
60
60
|
createPromptsDomainModule,
|
|
61
61
|
renderAgentCatalogSectionsFromSpecs
|
|
62
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-3UUY7R3Z.js";
|
|
63
|
+
import {
|
|
64
|
+
flushRawStdout,
|
|
65
|
+
writeRawStdout
|
|
66
|
+
} from "./chunk-2VTFPG5O.js";
|
|
63
67
|
import {
|
|
64
68
|
SafetyDomainModule
|
|
65
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-WXCJ7VME.js";
|
|
66
70
|
import {
|
|
67
71
|
LifecycleDomainModule,
|
|
68
72
|
describeUpgradeNotice
|
|
69
|
-
} from "./chunk-
|
|
73
|
+
} from "./chunk-DG4M6ZUE.js";
|
|
70
74
|
import {
|
|
71
75
|
ensureClioState,
|
|
72
76
|
takeUpgradeNotice
|
|
73
|
-
} from "./chunk-
|
|
77
|
+
} from "./chunk-T3Z6VAAF.js";
|
|
74
78
|
import {
|
|
75
79
|
ConfigDomainModule,
|
|
76
80
|
createConfigDomainModule,
|
|
77
81
|
loadDomains
|
|
78
|
-
} from "./chunk-
|
|
82
|
+
} from "./chunk-465CC7FK.js";
|
|
83
|
+
import {
|
|
84
|
+
discoverDeclaredChecks
|
|
85
|
+
} from "./chunk-P3JGPQFL.js";
|
|
86
|
+
import {
|
|
87
|
+
buildRecallFields,
|
|
88
|
+
recallErrorMessage,
|
|
89
|
+
recallParentTurnId,
|
|
90
|
+
recallableRefListing,
|
|
91
|
+
resolveRecall
|
|
92
|
+
} from "./chunk-MV2VUEJC.js";
|
|
93
|
+
import {
|
|
94
|
+
foldWorkingSet
|
|
95
|
+
} from "./chunk-TZSKNMZG.js";
|
|
96
|
+
import {
|
|
97
|
+
classifyLibraryRequirements,
|
|
98
|
+
createResourcesDomainModule,
|
|
99
|
+
discoverLibrary,
|
|
100
|
+
installLibraryPlan,
|
|
101
|
+
libraryEntryInstalled,
|
|
102
|
+
libraryEntryPin,
|
|
103
|
+
libraryEntryRef,
|
|
104
|
+
libraryInstallPath,
|
|
105
|
+
planLibraryInstall
|
|
106
|
+
} from "./chunk-PZ4I4JE2.js";
|
|
107
|
+
import {
|
|
108
|
+
AgentsDomainModule
|
|
109
|
+
} from "./chunk-YSEHGPCT.js";
|
|
110
|
+
import "./chunk-HCBCAYZU.js";
|
|
111
|
+
import "./chunk-DR52UMZW.js";
|
|
112
|
+
import {
|
|
113
|
+
MARKETPLACE_UNCONFIGURED,
|
|
114
|
+
discoverMarketplaceSkills,
|
|
115
|
+
getMarketplaceSkills,
|
|
116
|
+
installSkill,
|
|
117
|
+
modelVisibleSkills,
|
|
118
|
+
parseSkillCommand
|
|
119
|
+
} from "./chunk-AD7Y7STJ.js";
|
|
120
|
+
import "./chunk-AMKHQW3C.js";
|
|
79
121
|
import {
|
|
80
122
|
compileScoutTransition,
|
|
81
123
|
createDispatchRunEventRegistry
|
|
82
|
-
} from "./chunk-
|
|
124
|
+
} from "./chunk-YKOFT37S.js";
|
|
83
125
|
import {
|
|
84
126
|
monitorToolSurface
|
|
85
|
-
} from "./chunk-
|
|
127
|
+
} from "./chunk-IHKBWSXF.js";
|
|
86
128
|
import {
|
|
87
129
|
COST_NOT_MEASURED,
|
|
88
130
|
ObservabilityDomainModule,
|
|
89
131
|
aggregateCostAmounts,
|
|
90
132
|
costAggregateForAmount,
|
|
91
133
|
formatCostAggregate,
|
|
92
|
-
readAccountabilitySummary
|
|
93
|
-
|
|
134
|
+
readAccountabilitySummary,
|
|
135
|
+
recordBackgroundMemoryStep
|
|
136
|
+
} from "./chunk-5PVQ4SRS.js";
|
|
94
137
|
import {
|
|
95
138
|
appendOutOfTurnUsageRow
|
|
96
|
-
} from "./chunk-
|
|
97
|
-
import "./chunk-
|
|
98
|
-
import "./chunk-
|
|
139
|
+
} from "./chunk-FWDFM5ZU.js";
|
|
140
|
+
import "./chunk-YW7UVM5V.js";
|
|
141
|
+
import "./chunk-D73KXYPF.js";
|
|
99
142
|
import {
|
|
100
143
|
steerToolSurface
|
|
101
|
-
} from "./chunk-
|
|
144
|
+
} from "./chunk-WIE7ZOSW.js";
|
|
145
|
+
import "./chunk-FALJGAWU.js";
|
|
102
146
|
import {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
147
|
+
ClioEditor,
|
|
148
|
+
CombinedAutocompleteProvider,
|
|
149
|
+
Container,
|
|
150
|
+
DEFAULT_SELECT_THEME,
|
|
151
|
+
FILTER_HINT,
|
|
152
|
+
FocusBox,
|
|
153
|
+
GLYPH,
|
|
154
|
+
Input,
|
|
155
|
+
MUTATION_PREVIEW_KEY,
|
|
156
|
+
Markdown,
|
|
157
|
+
Marked,
|
|
158
|
+
SGR_DIM,
|
|
159
|
+
SGR_RESET,
|
|
160
|
+
ScrollView,
|
|
161
|
+
SelectList,
|
|
162
|
+
Text,
|
|
163
|
+
VStack,
|
|
164
|
+
abbreviateModelId,
|
|
165
|
+
barSep,
|
|
166
|
+
brandMark,
|
|
167
|
+
buildHint,
|
|
168
|
+
buildResponsiveHint,
|
|
169
|
+
clioError,
|
|
170
|
+
clioTheme,
|
|
171
|
+
collapseHomePath,
|
|
172
|
+
createAgentProgress,
|
|
173
|
+
createKeybindingManager,
|
|
174
|
+
createProcessInteractiveShell,
|
|
175
|
+
detectPlatformKeybindingWarnings,
|
|
176
|
+
detectTerminalKeySupport,
|
|
177
|
+
dotSep,
|
|
178
|
+
fgSequence,
|
|
179
|
+
fitHintEntries,
|
|
180
|
+
fitUnits,
|
|
181
|
+
formatCompactMs,
|
|
182
|
+
formatContextPercent,
|
|
183
|
+
formatInvalidKeybindingNotice,
|
|
184
|
+
formatPlatformKeybindingNotice,
|
|
185
|
+
formatRuntimeResolutionDiagnostic,
|
|
186
|
+
formatTargetLabel,
|
|
187
|
+
frame,
|
|
188
|
+
fuzzyFilter,
|
|
189
|
+
getActiveRenderTrace,
|
|
190
|
+
getKeybindings,
|
|
191
|
+
innerDivider,
|
|
192
|
+
isClioToken,
|
|
193
|
+
isKeyRelease,
|
|
194
|
+
joinChips,
|
|
195
|
+
joinSections,
|
|
196
|
+
listGroupHeader,
|
|
197
|
+
markdownTheme,
|
|
198
|
+
matchesKey,
|
|
199
|
+
padAnsi,
|
|
200
|
+
paintHex,
|
|
201
|
+
permissionHintEntries,
|
|
202
|
+
rule,
|
|
203
|
+
runtimeResolutionDiagnosticLine,
|
|
204
|
+
screenTitle,
|
|
205
|
+
sectionTag,
|
|
206
|
+
selectListTheme,
|
|
207
|
+
showClioOverlayFrame,
|
|
208
|
+
spinnerFrame,
|
|
209
|
+
stripTerminalSequences,
|
|
210
|
+
truncateToWidth,
|
|
211
|
+
validateKeybindings,
|
|
212
|
+
visibleWidth,
|
|
213
|
+
wrapTextWithAnsi,
|
|
214
|
+
writeInputWedgeDump
|
|
215
|
+
} from "./chunk-NNNWO6F2.js";
|
|
216
|
+
import {
|
|
217
|
+
getTerminationCoordinator
|
|
218
|
+
} from "./chunk-BVDVID7E.js";
|
|
107
219
|
import {
|
|
108
220
|
createContextDomainModule,
|
|
109
221
|
loadProjectClioMd
|
|
110
|
-
} from "./chunk-
|
|
222
|
+
} from "./chunk-HJB5IUKP.js";
|
|
111
223
|
import "./chunk-LCGCVYZ4.js";
|
|
112
224
|
import {
|
|
113
225
|
renderCodewikiDigest
|
|
114
|
-
} from "./chunk-
|
|
226
|
+
} from "./chunk-47CMYGET.js";
|
|
115
227
|
import {
|
|
116
228
|
buildMemoryPromptSection,
|
|
117
229
|
canonicalMemoryRepositoryIdentity,
|
|
118
230
|
createTaskMemoryTrace,
|
|
119
231
|
describeTaskMemoryActivity,
|
|
232
|
+
formatTaskMemorySpend,
|
|
120
233
|
loadMemoryRecordsSync,
|
|
234
|
+
proposeInjectedTaskMemory,
|
|
121
235
|
proposeMemoryPromotion,
|
|
236
|
+
readTaskMemorySpendSummary,
|
|
122
237
|
renderTaskMemoryHandoffSource,
|
|
123
238
|
seedTaskMemoryFromNewestHandoff,
|
|
124
239
|
taskMemoryBankSize,
|
|
125
240
|
taskMemoryHandoffSeedOffer,
|
|
126
241
|
taskMemoryTracePath
|
|
127
|
-
} from "./chunk-
|
|
242
|
+
} from "./chunk-5T7RBWN2.js";
|
|
243
|
+
import {
|
|
244
|
+
listWikiPages,
|
|
245
|
+
wikiCompleteness,
|
|
246
|
+
wikiStaleness,
|
|
247
|
+
wikiStalenessAsync
|
|
248
|
+
} from "./chunk-NDINPTJ4.js";
|
|
249
|
+
import "./chunk-MXHC5QYU.js";
|
|
128
250
|
import {
|
|
129
251
|
ACP_MAX_CHUNK_BYTES,
|
|
130
252
|
ACP_MAX_RAW_RECORD_BYTES,
|
|
@@ -137,6 +259,7 @@ import {
|
|
|
137
259
|
AcpTimeoutError,
|
|
138
260
|
WORKER_OUTPUT_MAX_BYTES,
|
|
139
261
|
acpErrorMessage,
|
|
262
|
+
capacityLeaseUsage,
|
|
140
263
|
createDispatchDomainModule,
|
|
141
264
|
createRunReceiptQuality,
|
|
142
265
|
createStdioServerTransport,
|
|
@@ -148,8 +271,18 @@ import {
|
|
|
148
271
|
openLedger,
|
|
149
272
|
protectedResidencyModels,
|
|
150
273
|
readGateDecisionArtifacts,
|
|
151
|
-
readPendingGateDecisions
|
|
152
|
-
|
|
274
|
+
readPendingGateDecisions,
|
|
275
|
+
renderDispatchReviewerTask
|
|
276
|
+
} from "./chunk-TEO2TLVN.js";
|
|
277
|
+
import {
|
|
278
|
+
formatTrustSummaryLine,
|
|
279
|
+
inspectRunReceiptTrustStatus,
|
|
280
|
+
isReceiptIntegrity,
|
|
281
|
+
retiredReceiptIntegrity,
|
|
282
|
+
retiredReceiptIntegrityReason,
|
|
283
|
+
summarizeTrustStatus,
|
|
284
|
+
verifyReceiptIntegrity
|
|
285
|
+
} from "./chunk-MLOK6ZOS.js";
|
|
153
286
|
import {
|
|
154
287
|
SessionDomainModule,
|
|
155
288
|
addResponseModelIdObservationCount,
|
|
@@ -163,81 +296,28 @@ import {
|
|
|
163
296
|
readAuditRows,
|
|
164
297
|
responseModelIdObservationCountsLabel,
|
|
165
298
|
responseModelIdObservationFromRecord
|
|
166
|
-
} from "./chunk-
|
|
299
|
+
} from "./chunk-LXPJXFM5.js";
|
|
167
300
|
import {
|
|
301
|
+
describeWriteBoundaryAttributionDowngrade,
|
|
168
302
|
gitCheckoutRoot,
|
|
169
303
|
isGitRepository,
|
|
170
304
|
preflightWriteBoundaries,
|
|
171
305
|
recoverCleanupReadyCompeteGroups
|
|
172
|
-
} from "./chunk-
|
|
306
|
+
} from "./chunk-ECUO3KDP.js";
|
|
173
307
|
import {
|
|
308
|
+
bindExecutionPlanEndpoints,
|
|
174
309
|
compileFleetExecutionPlan,
|
|
175
310
|
requireAgentSteps
|
|
176
|
-
} from "./chunk-
|
|
311
|
+
} from "./chunk-HKO36JWF.js";
|
|
177
312
|
import {
|
|
178
313
|
parseRigorOverride,
|
|
179
314
|
resolveRigor
|
|
180
315
|
} from "./chunk-RVG5JXAL.js";
|
|
181
316
|
import {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
import {
|
|
187
|
-
shellQuote
|
|
188
|
-
} from "./chunk-TXOTCRLG.js";
|
|
189
|
-
import {
|
|
190
|
-
emptyWorkspaceSnapshot,
|
|
191
|
-
probeGitStatusAsync,
|
|
192
|
-
probeWorkspaceAsync
|
|
193
|
-
} from "./chunk-HVDIIIQW.js";
|
|
194
|
-
import {
|
|
195
|
-
discoverDeclaredChecks
|
|
196
|
-
} from "./chunk-PD3MESLB.js";
|
|
197
|
-
import {
|
|
198
|
-
listWikiPages,
|
|
199
|
-
wikiCompleteness,
|
|
200
|
-
wikiStaleness,
|
|
201
|
-
wikiStalenessAsync
|
|
202
|
-
} from "./chunk-NDINPTJ4.js";
|
|
203
|
-
import "./chunk-MVVUPGPW.js";
|
|
204
|
-
import {
|
|
205
|
-
buildRecallFields,
|
|
206
|
-
recallErrorMessage,
|
|
207
|
-
recallParentTurnId,
|
|
208
|
-
recallableRefListing,
|
|
209
|
-
resolveRecall
|
|
210
|
-
} from "./chunk-ZZMN5OM4.js";
|
|
211
|
-
import {
|
|
212
|
-
foldWorkingSet
|
|
213
|
-
} from "./chunk-TZSKNMZG.js";
|
|
214
|
-
import {
|
|
215
|
-
classifyLibraryRequirements,
|
|
216
|
-
createResourcesDomainModule,
|
|
217
|
-
discoverLibrary,
|
|
218
|
-
installLibraryPlan,
|
|
219
|
-
libraryEntryInstalled,
|
|
220
|
-
libraryEntryPin,
|
|
221
|
-
libraryEntryRef,
|
|
222
|
-
libraryInstallPath,
|
|
223
|
-
planLibraryInstall
|
|
224
|
-
} from "./chunk-THKY7CD7.js";
|
|
225
|
-
import {
|
|
226
|
-
AgentsDomainModule
|
|
227
|
-
} from "./chunk-UVDSQ6LW.js";
|
|
228
|
-
import "./chunk-DR52UMZW.js";
|
|
229
|
-
import {
|
|
230
|
-
MARKETPLACE_UNCONFIGURED,
|
|
231
|
-
discoverMarketplaceSkills,
|
|
232
|
-
getMarketplaceSkills,
|
|
233
|
-
installSkill,
|
|
234
|
-
modelVisibleSkills,
|
|
235
|
-
parseSkillCommand
|
|
236
|
-
} from "./chunk-C4JBQ5SR.js";
|
|
237
|
-
import "./chunk-2SFS6XQE.js";
|
|
238
|
-
import {
|
|
239
|
-
ExtensionsDomainModule
|
|
240
|
-
} from "./chunk-ZWLZP4ZT.js";
|
|
317
|
+
foldPromptCacheTelemetry,
|
|
318
|
+
hasPromptCacheTelemetry,
|
|
319
|
+
uncachedPrefillTokens
|
|
320
|
+
} from "./chunk-3DPEIQKN.js";
|
|
241
321
|
import {
|
|
242
322
|
filterEntriesToActivePath
|
|
243
323
|
} from "./chunk-W6GROXXM.js";
|
|
@@ -250,7 +330,21 @@ import {
|
|
|
250
330
|
renderFleetPrompt,
|
|
251
331
|
validateFleetCommands,
|
|
252
332
|
validateFleetGraph
|
|
253
|
-
} from "./chunk-
|
|
333
|
+
} from "./chunk-HPCTNZM2.js";
|
|
334
|
+
import "./chunk-RKKLTLYB.js";
|
|
335
|
+
import {
|
|
336
|
+
ExtensionsDomainModule
|
|
337
|
+
} from "./chunk-5QKCQQ3E.js";
|
|
338
|
+
import "./chunk-JVCV3ICN.js";
|
|
339
|
+
import "./chunk-5HFBWUMU.js";
|
|
340
|
+
import {
|
|
341
|
+
shellQuote
|
|
342
|
+
} from "./chunk-TXOTCRLG.js";
|
|
343
|
+
import {
|
|
344
|
+
emptyWorkspaceSnapshot,
|
|
345
|
+
probeGitStatusAsync,
|
|
346
|
+
probeWorkspaceAsync
|
|
347
|
+
} from "./chunk-HVDIIIQW.js";
|
|
254
348
|
import {
|
|
255
349
|
formatBootTrace,
|
|
256
350
|
traceBoot
|
|
@@ -258,6 +352,7 @@ import {
|
|
|
258
352
|
import {
|
|
259
353
|
ASK_USER_OTHER_LABEL,
|
|
260
354
|
INTERACTIVE_LOOP_BLOCK_BUDGET,
|
|
355
|
+
applyEditsToNormalizedContent,
|
|
261
356
|
askAxis,
|
|
262
357
|
askUserExposure,
|
|
263
358
|
assertRegisteredBuiltinTools,
|
|
@@ -272,16 +367,20 @@ import {
|
|
|
272
367
|
decisionFactsForPermission,
|
|
273
368
|
diffWords,
|
|
274
369
|
finalizeAskUserInterviewForHost,
|
|
370
|
+
generateDiffString,
|
|
275
371
|
lazyTool,
|
|
372
|
+
normalizeToLF,
|
|
276
373
|
patchProviderThinkingPayload,
|
|
374
|
+
patchResponseSchemaPayloadForDialect,
|
|
277
375
|
patchToolChoiceNamedPayload,
|
|
278
376
|
patchToolChoiceNonePayload,
|
|
279
377
|
readOrchTurnToolCallBudget,
|
|
280
378
|
registerCoreTools,
|
|
281
379
|
resolveFdBinary,
|
|
282
380
|
resolveSessionTools,
|
|
283
|
-
sanitizeLockedSynthesisMessage
|
|
284
|
-
|
|
381
|
+
sanitizeLockedSynthesisMessage,
|
|
382
|
+
stripBom
|
|
383
|
+
} from "./chunk-R7LNVMCS.js";
|
|
285
384
|
import {
|
|
286
385
|
HEADLESS_PERMISSION_DENIED_REASON
|
|
287
386
|
} from "./chunk-K7VKOLQQ.js";
|
|
@@ -289,6 +388,7 @@ import {
|
|
|
289
388
|
MIDDLEWARE_HOOK_TEXT_MAX_CHARS,
|
|
290
389
|
MiddlewareDomainModule,
|
|
291
390
|
WATCHDOG_TASK,
|
|
391
|
+
announceMemoryStepEndpoint,
|
|
292
392
|
createDetachedDispatchNudgeRegistration,
|
|
293
393
|
createHookReceiptLog,
|
|
294
394
|
createMemoryInterventionRegistration,
|
|
@@ -303,9 +403,12 @@ import {
|
|
|
303
403
|
openDetachedBatchViews,
|
|
304
404
|
watchdogBriefing,
|
|
305
405
|
writeMiddlewareDiagnosticToStderr
|
|
306
|
-
} from "./chunk-
|
|
307
|
-
import "./chunk-
|
|
406
|
+
} from "./chunk-GAYUJ7LE.js";
|
|
407
|
+
import "./chunk-HAY4ZE2P.js";
|
|
308
408
|
import "./chunk-UOV2BYIW.js";
|
|
409
|
+
import "./chunk-CA42X6KT.js";
|
|
410
|
+
import "./chunk-OEDBCISO.js";
|
|
411
|
+
import "./chunk-5DQRIYDZ.js";
|
|
309
412
|
import {
|
|
310
413
|
DISPATCH_PLAN_PREPARATION_ERROR_ARGUMENT,
|
|
311
414
|
RESOLVED_DISPATCH_PLAN_ARGUMENT,
|
|
@@ -317,11 +420,14 @@ import {
|
|
|
317
420
|
stringArg,
|
|
318
421
|
timeoutMsArg,
|
|
319
422
|
withResolvedDispatchPlan
|
|
320
|
-
} from "./chunk-
|
|
423
|
+
} from "./chunk-VKBMFOYV.js";
|
|
321
424
|
import {
|
|
322
425
|
TaskMemoryBank,
|
|
323
426
|
createTaskMemoryTelemetrySink
|
|
324
|
-
} from "./chunk-
|
|
427
|
+
} from "./chunk-O6I4CIEU.js";
|
|
428
|
+
import {
|
|
429
|
+
escapeRegExp
|
|
430
|
+
} from "./chunk-VG7TBQIY.js";
|
|
325
431
|
import {
|
|
326
432
|
COUNCIL_JUDGE_PROMPT,
|
|
327
433
|
DISPATCH_BRIEFING_MAX_BYTES,
|
|
@@ -338,66 +444,61 @@ import {
|
|
|
338
444
|
formatBudgetReasons,
|
|
339
445
|
formatBudgetRequest,
|
|
340
446
|
formatEffectiveBudget,
|
|
447
|
+
isResponseSchemaRejection,
|
|
341
448
|
isToolProfileName,
|
|
342
449
|
normalizeDispatchIntent,
|
|
343
450
|
redactSecretString,
|
|
344
451
|
redactToolArgs,
|
|
452
|
+
renderCouncilVoteMemberTask,
|
|
453
|
+
responseSchemaDialectFor,
|
|
345
454
|
runBashCommand,
|
|
346
455
|
runKindSupportsLiveSteering,
|
|
347
456
|
sanitizeCallTargetText,
|
|
457
|
+
sanitizeMultilineDisplayText,
|
|
348
458
|
toolPresentationPolicy
|
|
349
|
-
} from "./chunk-
|
|
459
|
+
} from "./chunk-4H6ULJ3H.js";
|
|
460
|
+
import {
|
|
461
|
+
defaultRoutingIntent,
|
|
462
|
+
sameRouteIdentity
|
|
463
|
+
} from "./chunk-VPTUJU4P.js";
|
|
350
464
|
import {
|
|
351
465
|
createTaskBoardStore,
|
|
352
466
|
foldSessionTaskHistory,
|
|
353
467
|
foldTaskBoard,
|
|
354
468
|
taskBoardCounts
|
|
355
|
-
} from "./chunk-
|
|
356
|
-
import {
|
|
357
|
-
DEFAULT_RECENT_ENTRY_LIMIT,
|
|
358
|
-
assessFinishContract
|
|
359
|
-
} from "./chunk-OBMAI2DP.js";
|
|
360
|
-
import {
|
|
361
|
-
defaultRoutingIntent,
|
|
362
|
-
sameRouteIdentity
|
|
363
|
-
} from "./chunk-5C77SEEY.js";
|
|
469
|
+
} from "./chunk-2JDWVJND.js";
|
|
364
470
|
import {
|
|
365
471
|
agentRoleFactsResolver,
|
|
366
472
|
gateDeciderAgentId,
|
|
367
473
|
requestExecutionRole,
|
|
368
474
|
withAttemptRole
|
|
369
|
-
} from "./chunk-
|
|
370
|
-
import "./chunk-CMZWFGD2.js";
|
|
371
|
-
import "./chunk-I4HZDVNP.js";
|
|
372
|
-
import "./chunk-ZI647VB5.js";
|
|
373
|
-
import "./chunk-JNXPYBB4.js";
|
|
374
|
-
import "./chunk-GH5622CP.js";
|
|
375
|
-
import "./chunk-XN3L4EYL.js";
|
|
475
|
+
} from "./chunk-H7IXIC72.js";
|
|
376
476
|
import {
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
import "./chunk-
|
|
381
|
-
import
|
|
382
|
-
SKILL_SUGGESTION_PREFIX,
|
|
383
|
-
isSkillActivation,
|
|
384
|
-
skillActivationFromToolDetails
|
|
385
|
-
} from "./chunk-GOXNB3AO.js";
|
|
477
|
+
DEFAULT_RECENT_ENTRY_LIMIT,
|
|
478
|
+
assessFinishContract
|
|
479
|
+
} from "./chunk-7C6RYZGQ.js";
|
|
480
|
+
import "./chunk-N3PBVRTZ.js";
|
|
481
|
+
import "./chunk-A2NJGIB3.js";
|
|
386
482
|
import {
|
|
387
|
-
|
|
388
|
-
} from "./chunk-
|
|
483
|
+
resolveToCwd
|
|
484
|
+
} from "./chunk-OQE5J4C6.js";
|
|
389
485
|
import {
|
|
390
486
|
parseCouncilReport,
|
|
391
487
|
parseOracleResult,
|
|
392
488
|
parseScoutResult,
|
|
393
489
|
parseVerifierResult,
|
|
394
490
|
resultContractSourceId
|
|
395
|
-
} from "./chunk-
|
|
396
|
-
import "./chunk-AOCYTWAV.js";
|
|
491
|
+
} from "./chunk-S4COXYBG.js";
|
|
397
492
|
import {
|
|
398
493
|
CLIO_PROJECT_DIR,
|
|
399
494
|
toolMutationPaths
|
|
400
495
|
} from "./chunk-MV3K5QF2.js";
|
|
496
|
+
import {
|
|
497
|
+
DEFAULT_AUTONOMY_LEVEL,
|
|
498
|
+
SKILL_SUGGESTION_PREFIX,
|
|
499
|
+
isSkillActivation,
|
|
500
|
+
skillActivationFromToolDetails
|
|
501
|
+
} from "./chunk-RAPCMZL4.js";
|
|
401
502
|
import {
|
|
402
503
|
VERIFICATION_SCRIPT_FAMILY_HINT
|
|
403
504
|
} from "./chunk-UL3WSD3F.js";
|
|
@@ -411,6 +512,9 @@ import {
|
|
|
411
512
|
} from "./chunk-OZNBF4L3.js";
|
|
412
513
|
import "./chunk-4BJ5BYCE.js";
|
|
413
514
|
import "./chunk-ECH6PKUQ.js";
|
|
515
|
+
import "./chunk-CMZWFGD2.js";
|
|
516
|
+
import "./chunk-I4HZDVNP.js";
|
|
517
|
+
import "./chunk-ZI647VB5.js";
|
|
414
518
|
import {
|
|
415
519
|
truncateUtf8
|
|
416
520
|
} from "./chunk-6XLNIQDB.js";
|
|
@@ -424,13 +528,14 @@ import {
|
|
|
424
528
|
incompleteInstallationAdvice
|
|
425
529
|
} from "./chunk-65DEGPJ6.js";
|
|
426
530
|
import "./chunk-M6L6IDJG.js";
|
|
427
|
-
import "./chunk-XAKHZX5N.js";
|
|
428
531
|
import "./chunk-UUVG37B4.js";
|
|
429
532
|
import {
|
|
430
533
|
readCodewiki,
|
|
431
534
|
readCodewikiAsync
|
|
432
535
|
} from "./chunk-LBMZMYH2.js";
|
|
536
|
+
import "./chunk-XAKHZX5N.js";
|
|
433
537
|
import "./chunk-33YXPOE3.js";
|
|
538
|
+
import "./chunk-7CR24IG7.js";
|
|
434
539
|
import {
|
|
435
540
|
getVersionInfo
|
|
436
541
|
} from "./chunk-XPLRXC72.js";
|
|
@@ -439,19 +544,20 @@ import {
|
|
|
439
544
|
InteropDomainModule,
|
|
440
545
|
delegationEntryForKind,
|
|
441
546
|
renderProposalEntry
|
|
442
|
-
} from "./chunk-
|
|
443
|
-
import "./chunk-
|
|
547
|
+
} from "./chunk-QQ7EKM72.js";
|
|
548
|
+
import "./chunk-56KB5IJP.js";
|
|
444
549
|
import {
|
|
445
550
|
source_default
|
|
446
551
|
} from "./chunk-5TSRNF4G.js";
|
|
447
552
|
import {
|
|
448
|
-
AGENT_ROLE_TOOLS_REQUIRED_REASON,
|
|
449
553
|
ProvidersDomainModule,
|
|
450
554
|
VALID_THINKING_LEVELS,
|
|
451
555
|
applyModelCapabilityPatch,
|
|
556
|
+
canonicalEndpointKey,
|
|
557
|
+
endpointCapacitiesForStatuses,
|
|
558
|
+
endpointCapacityForStatus,
|
|
452
559
|
firstRuntimeResolutionError,
|
|
453
|
-
|
|
454
|
-
getRuntimeRegistry,
|
|
560
|
+
foregroundStreamUsage,
|
|
455
561
|
isDispatchEligibleRuntime,
|
|
456
562
|
isOrchestratorEligibleRuntime,
|
|
457
563
|
modelCandidatesForStatus,
|
|
@@ -459,28 +565,22 @@ import {
|
|
|
459
565
|
modelResidencyForStatus,
|
|
460
566
|
normalizeCostProvenance,
|
|
461
567
|
refineRuntimeTargetWithModelHints,
|
|
462
|
-
|
|
568
|
+
registerForegroundStream,
|
|
569
|
+
residencyTargetKey,
|
|
463
570
|
resolveModelCapabilities,
|
|
464
571
|
resolveModelReference,
|
|
465
572
|
resolveModelRuntimeCapabilitiesForProviders,
|
|
466
|
-
resolveProviderReference,
|
|
467
573
|
resolveReservedOutputTokens,
|
|
468
574
|
resolveRuntimeTarget,
|
|
469
575
|
runtimeResolutionWarningsBesideThinkingNotice,
|
|
470
576
|
runtimeTargetSnapshot,
|
|
471
577
|
setProtectedModelsProvider,
|
|
472
|
-
supportsAgentRoleTools,
|
|
473
578
|
thinkingLevelChoiceLabel,
|
|
474
579
|
thinkingLevelFromChoiceLabel,
|
|
475
580
|
withRunOverrides
|
|
476
|
-
} from "./chunk-
|
|
581
|
+
} from "./chunk-MIX5N5AC.js";
|
|
477
582
|
import "./chunk-CFGTUFWB.js";
|
|
478
|
-
import
|
|
479
|
-
targetRequiresAuth
|
|
480
|
-
} from "./chunk-JRIO5UD2.js";
|
|
481
|
-
import {
|
|
482
|
-
interopAgentKind
|
|
483
|
-
} from "./chunk-IHXBNWMM.js";
|
|
583
|
+
import "./chunk-LU7P4LHA.js";
|
|
484
584
|
import {
|
|
485
585
|
AutoCompactionTrigger,
|
|
486
586
|
DEFAULT_COMPACTION_THRESHOLD,
|
|
@@ -492,13 +592,21 @@ import {
|
|
|
492
592
|
contextUsageSnapshot,
|
|
493
593
|
estimateAgentContextBreakdown,
|
|
494
594
|
estimateAgentContextTokens,
|
|
595
|
+
estimateAgentMessageTokens,
|
|
495
596
|
estimateReasoningTextTokens,
|
|
496
597
|
extractReasoningTokens,
|
|
497
598
|
getLatestContextSnapshot,
|
|
599
|
+
lastLoadedContextWindow,
|
|
498
600
|
reconcileSnapshot,
|
|
499
601
|
shouldCompact,
|
|
500
602
|
snapshotInputTokens
|
|
501
|
-
} from "./chunk-
|
|
603
|
+
} from "./chunk-AEYBF3TB.js";
|
|
604
|
+
import {
|
|
605
|
+
interopAgentKind
|
|
606
|
+
} from "./chunk-IHXBNWMM.js";
|
|
607
|
+
import {
|
|
608
|
+
setGitCommitAttributionEnabled
|
|
609
|
+
} from "./chunk-B5CSFE7B.js";
|
|
502
610
|
import {
|
|
503
611
|
bindAgentProfileInSettings,
|
|
504
612
|
readSettings,
|
|
@@ -507,14 +615,18 @@ import {
|
|
|
507
615
|
setFleetProfileInSettings,
|
|
508
616
|
updateSettings,
|
|
509
617
|
useTargetInSettings
|
|
510
|
-
} from "./chunk-
|
|
618
|
+
} from "./chunk-PNY46YEY.js";
|
|
511
619
|
import {
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
620
|
+
MAX_TIMER_DELAY_MS,
|
|
621
|
+
rawDurationMs
|
|
622
|
+
} from "./chunk-FQ4SKYE4.js";
|
|
623
|
+
import {
|
|
624
|
+
getSharedBus
|
|
625
|
+
} from "./chunk-ZGVHUX3M.js";
|
|
626
|
+
import {
|
|
627
|
+
BusChannels,
|
|
628
|
+
isRunAbortedPayload
|
|
629
|
+
} from "./chunk-RKRLDWD3.js";
|
|
518
630
|
import {
|
|
519
631
|
atomicWrite,
|
|
520
632
|
cwdHash,
|
|
@@ -522,123 +634,60 @@ import {
|
|
|
522
634
|
readSessionTailTurns,
|
|
523
635
|
sessionCurrentPath,
|
|
524
636
|
sessionPaths
|
|
525
|
-
} from "./chunk-
|
|
526
|
-
import "./chunk-
|
|
637
|
+
} from "./chunk-KV2AOLDF.js";
|
|
638
|
+
import "./chunk-6EJMN2Y3.js";
|
|
527
639
|
import {
|
|
528
|
-
|
|
529
|
-
|
|
640
|
+
readClioVersion,
|
|
641
|
+
readPiMonoVersion
|
|
642
|
+
} from "./chunk-IWHMRKLL.js";
|
|
530
643
|
import {
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
} from "./chunk-
|
|
644
|
+
formatContextWindowSlots,
|
|
645
|
+
registerBuiltinRuntimes
|
|
646
|
+
} from "./chunk-JEQQR47K.js";
|
|
647
|
+
import {
|
|
648
|
+
DEFAULT_DELEGATION_PERMISSION_TIMEOUT_MS,
|
|
649
|
+
DEFAULT_SETTINGS,
|
|
650
|
+
THINKING_LEVELS
|
|
651
|
+
} from "./chunk-XDOQXGFO.js";
|
|
652
|
+
import "./chunk-LL4KHSZI.js";
|
|
534
653
|
import {
|
|
535
654
|
configureGuardrails
|
|
536
655
|
} from "./chunk-4ZG3XFUR.js";
|
|
656
|
+
import {
|
|
657
|
+
resolveProviderReference
|
|
658
|
+
} from "./chunk-774ILSRL.js";
|
|
659
|
+
import {
|
|
660
|
+
targetRequiresAuth
|
|
661
|
+
} from "./chunk-EQ63NRB7.js";
|
|
662
|
+
import "./chunk-SST6Z5JA.js";
|
|
537
663
|
import "./chunk-IKCO5N3L.js";
|
|
538
664
|
import "./chunk-3I7MS7N2.js";
|
|
539
|
-
import {
|
|
540
|
-
StringEnum,
|
|
541
|
-
cleanupEngineSessionResources,
|
|
542
|
-
completeEngineText,
|
|
543
|
-
isEngineRetryableAssistantError,
|
|
544
|
-
stream
|
|
545
|
-
} from "./chunk-FCSXB6T2.js";
|
|
546
665
|
import "./chunk-APJ265NV.js";
|
|
547
|
-
import "./chunk-YXLYO42X.js";
|
|
548
666
|
import {
|
|
549
667
|
clioConfigDir,
|
|
550
668
|
clioDataDir,
|
|
551
669
|
clioStateDir,
|
|
552
670
|
stateRootRemoved
|
|
553
671
|
} from "./chunk-BNAZZHFG.js";
|
|
554
|
-
import "./chunk-6EJMN2Y3.js";
|
|
555
672
|
import {
|
|
556
673
|
safeResourceWrite
|
|
557
674
|
} from "./chunk-WEPFGWHJ.js";
|
|
558
675
|
import {
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
Container,
|
|
562
|
-
DEFAULT_SELECT_THEME,
|
|
563
|
-
FILTER_HINT,
|
|
564
|
-
FocusBox,
|
|
565
|
-
GLYPH,
|
|
566
|
-
Input,
|
|
567
|
-
Markdown,
|
|
568
|
-
Marked,
|
|
569
|
-
SGR_DIM,
|
|
570
|
-
SGR_RESET,
|
|
571
|
-
ScrollView,
|
|
572
|
-
SelectList,
|
|
573
|
-
Text,
|
|
574
|
-
VStack,
|
|
575
|
-
abbreviateModelId,
|
|
576
|
-
barSep,
|
|
577
|
-
brandMark,
|
|
578
|
-
buildHint,
|
|
579
|
-
buildResponsiveHint,
|
|
580
|
-
clioError,
|
|
581
|
-
clioTheme,
|
|
582
|
-
collapseHomePath,
|
|
583
|
-
createAgentProgress,
|
|
584
|
-
createKeybindingManager,
|
|
585
|
-
createProcessInteractiveShell,
|
|
586
|
-
detectPlatformKeybindingWarnings,
|
|
587
|
-
detectTerminalKeySupport,
|
|
588
|
-
dotSep,
|
|
589
|
-
fgSequence,
|
|
590
|
-
fitHintEntries,
|
|
591
|
-
fitUnits,
|
|
592
|
-
formatCompactMs,
|
|
593
|
-
formatContextPercent,
|
|
594
|
-
formatInvalidKeybindingNotice,
|
|
595
|
-
formatPlatformKeybindingNotice,
|
|
596
|
-
formatRuntimeResolutionDiagnostic,
|
|
597
|
-
formatTargetLabel,
|
|
598
|
-
frame,
|
|
599
|
-
fuzzyFilter,
|
|
600
|
-
getActiveRenderTrace,
|
|
601
|
-
getKeybindings,
|
|
602
|
-
innerDivider,
|
|
603
|
-
isClioToken,
|
|
604
|
-
isKeyRelease,
|
|
605
|
-
joinChips,
|
|
606
|
-
joinSections,
|
|
607
|
-
listGroupHeader,
|
|
608
|
-
markdownTheme,
|
|
609
|
-
matchesKey,
|
|
610
|
-
padAnsi,
|
|
611
|
-
paintHex,
|
|
612
|
-
permissionHintEntries,
|
|
613
|
-
rule,
|
|
614
|
-
runtimeResolutionDiagnosticLine,
|
|
615
|
-
screenTitle,
|
|
616
|
-
sectionTag,
|
|
617
|
-
selectListTheme,
|
|
618
|
-
showClioOverlayFrame,
|
|
619
|
-
spinnerFrame,
|
|
620
|
-
stripTerminalSequences,
|
|
621
|
-
truncateToWidth,
|
|
622
|
-
validateKeybindings,
|
|
623
|
-
visibleWidth,
|
|
624
|
-
wrapTextWithAnsi
|
|
625
|
-
} from "./chunk-5C3AQNDW.js";
|
|
626
|
-
import {
|
|
627
|
-
getTerminationCoordinator
|
|
628
|
-
} from "./chunk-X2KV5FXT.js";
|
|
676
|
+
getRuntimeRegistry
|
|
677
|
+
} from "./chunk-NUGM5KR6.js";
|
|
629
678
|
import {
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
BusChannels,
|
|
634
|
-
isRunAbortedPayload
|
|
635
|
-
} from "./chunk-OB5HIGJY.js";
|
|
636
|
-
import "./chunk-JVCV3ICN.js";
|
|
637
|
-
import "./chunk-7CR24IG7.js";
|
|
679
|
+
AGENT_ROLE_TOOLS_REQUIRED_REASON,
|
|
680
|
+
supportsAgentRoleTools
|
|
681
|
+
} from "./chunk-VO2LKSTM.js";
|
|
638
682
|
import {
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
683
|
+
StringEnum,
|
|
684
|
+
cleanupEngineSessionResources,
|
|
685
|
+
completeEngineText,
|
|
686
|
+
isEngineRetryableAssistantError,
|
|
687
|
+
stream,
|
|
688
|
+
streamSimple
|
|
689
|
+
} from "./chunk-UOSL25KY.js";
|
|
690
|
+
import "./chunk-YXLYO42X.js";
|
|
642
691
|
import {
|
|
643
692
|
init_esm_shims
|
|
644
693
|
} from "./chunk-3R73A4XB.js";
|
|
@@ -3242,7 +3291,8 @@ function safeProbeReason(providers, status) {
|
|
|
3242
3291
|
} catch {
|
|
3243
3292
|
return "not-configured";
|
|
3244
3293
|
}
|
|
3245
|
-
|
|
3294
|
+
const reachable = status.health.status === "healthy" || status.health.status === "degraded";
|
|
3295
|
+
return status.available && reachable ? null : "unreachable";
|
|
3246
3296
|
}
|
|
3247
3297
|
function installPermissionBridge(input) {
|
|
3248
3298
|
if (!input.toolRegistry) return { unregister: () => {
|
|
@@ -4594,10 +4644,29 @@ async function runSideQuestion(input) {
|
|
|
4594
4644
|
const { question, ...rest } = input;
|
|
4595
4645
|
return runOutOfTurnRound({ ...rest, systemPrompt: SIDE_QUESTION_SYSTEM_PROMPT, userText: question });
|
|
4596
4646
|
}
|
|
4647
|
+
function schemaBindingFor(input) {
|
|
4648
|
+
if (input.responseSchema === void 0 || input.runtimeId === void 0) return null;
|
|
4649
|
+
const dialect = responseSchemaDialectFor(input.runtimeId);
|
|
4650
|
+
return dialect === null ? null : { dialect, ...input.responseSchema };
|
|
4651
|
+
}
|
|
4597
4652
|
async function runOutOfTurnRound(input) {
|
|
4653
|
+
const binding = schemaBindingFor(input);
|
|
4654
|
+
if (binding === null) return runRound(input, null);
|
|
4655
|
+
try {
|
|
4656
|
+
return await runRound(input, binding);
|
|
4657
|
+
} catch (error) {
|
|
4658
|
+
if (input.signal?.aborted === true) throw error;
|
|
4659
|
+
if (!isResponseSchemaRejection(error instanceof Error ? error.message : String(error))) throw error;
|
|
4660
|
+
return runRound(input, null);
|
|
4661
|
+
}
|
|
4662
|
+
}
|
|
4663
|
+
async function runRound(input, binding) {
|
|
4598
4664
|
const options = { maxTokens: input.maxTokens ?? SIDE_QUESTION_MAX_TOKENS };
|
|
4599
4665
|
if (input.apiKey !== void 0) options.apiKey = input.apiKey;
|
|
4600
4666
|
if (input.signal !== void 0) options.signal = input.signal;
|
|
4667
|
+
if (binding !== null) {
|
|
4668
|
+
options.onPayload = (payload) => patchResponseSchemaPayloadForDialect(payload, binding.dialect, binding.schema, binding.name);
|
|
4669
|
+
}
|
|
4601
4670
|
const context = {
|
|
4602
4671
|
systemPrompt: input.systemPrompt,
|
|
4603
4672
|
messages: [
|
|
@@ -4647,13 +4716,31 @@ var HANDOFF_SYSTEM_PROMPT = [
|
|
|
4647
4716
|
`The object must match this JSON schema exactly: ${JSON.stringify(HANDOFF_RESPONSE_SCHEMA)}`
|
|
4648
4717
|
].join(" ");
|
|
4649
4718
|
var HANDOFF_MAX_TOKENS = 4096;
|
|
4719
|
+
var HANDOFF_SCHEMA_NAME = "handoff_record";
|
|
4720
|
+
var HANDOFF_REPAIR_QUOTE_CHARS = 600;
|
|
4721
|
+
function repairText(goal, repair) {
|
|
4722
|
+
const quoted = repair.previous.slice(0, HANDOFF_REPAIR_QUOTE_CHARS);
|
|
4723
|
+
return [
|
|
4724
|
+
`The next session's goal is: ${goal}`,
|
|
4725
|
+
"",
|
|
4726
|
+
"Your previous answer could not be read as a handoff record.",
|
|
4727
|
+
`The parser said: ${repair.complaint}`,
|
|
4728
|
+
"This is what you returned, verbatim:",
|
|
4729
|
+
"---",
|
|
4730
|
+
quoted.length > 0 ? quoted : "(nothing)",
|
|
4731
|
+
"---",
|
|
4732
|
+
"Answer again with one JSON object matching the schema and nothing else.",
|
|
4733
|
+
"No prose before it, no prose after it, no code fence."
|
|
4734
|
+
].join("\n");
|
|
4735
|
+
}
|
|
4650
4736
|
async function runHandoffRound(input) {
|
|
4651
|
-
const { goal, ...rest } = input;
|
|
4737
|
+
const { goal, repair, ...rest } = input;
|
|
4652
4738
|
return runOutOfTurnRound({
|
|
4653
4739
|
...rest,
|
|
4654
4740
|
maxTokens: input.maxTokens ?? HANDOFF_MAX_TOKENS,
|
|
4655
4741
|
systemPrompt: HANDOFF_SYSTEM_PROMPT,
|
|
4656
|
-
|
|
4742
|
+
responseSchema: { name: HANDOFF_SCHEMA_NAME, schema: HANDOFF_RESPONSE_SCHEMA },
|
|
4743
|
+
userText: repair ? repairText(goal, repair) : `The next session's goal is: ${goal}
|
|
4657
4744
|
|
|
4658
4745
|
Extract the handoff record for that goal now.`
|
|
4659
4746
|
});
|
|
@@ -4860,6 +4947,7 @@ function maskStaleObservations(entries, excludeLastTurns) {
|
|
|
4860
4947
|
init_esm_shims();
|
|
4861
4948
|
import { appendFileSync, existsSync as existsSync4, readFileSync as readFileSync4 } from "node:fs";
|
|
4862
4949
|
import { dirname, join as join4 } from "node:path";
|
|
4950
|
+
var PROMPT_MANIFEST_VERSION = 2;
|
|
4863
4951
|
var SHA256_HEX = /^[a-f0-9]{64}$/;
|
|
4864
4952
|
function isCanonicalUtcTimestamp(value) {
|
|
4865
4953
|
if (typeof value !== "string") return false;
|
|
@@ -4885,9 +4973,18 @@ function isProjectPreloadClass(value) {
|
|
|
4885
4973
|
if (!isRecord6(value)) return false;
|
|
4886
4974
|
return (value.mode === "full" || value.mode === "synopsis" || value.mode === "none") && isNonNegativeInteger(value.chars) && isNonNegativeInteger(value.lines) && (value.reason === null || value.reason === "size" || value.reason === "lines" || value.reason === "no-clio-md") && typeof value.nearLimit === "boolean" && typeof value.label === "string";
|
|
4887
4975
|
}
|
|
4976
|
+
function isOptional(value, guard) {
|
|
4977
|
+
return value === void 0 || guard(value);
|
|
4978
|
+
}
|
|
4888
4979
|
function isSessionPromptCompileRecord(value) {
|
|
4889
4980
|
if (!isRecord6(value)) return false;
|
|
4890
|
-
return
|
|
4981
|
+
return isOptional(value.version, isNonNegativeInteger) && isOptional(
|
|
4982
|
+
value.contextWindow,
|
|
4983
|
+
(candidate) => candidate === null ? true : isNonNegativeInteger(candidate)
|
|
4984
|
+
) && isOptional(
|
|
4985
|
+
value.contextWindowSource,
|
|
4986
|
+
(candidate) => candidate === null ? true : typeof candidate === "string"
|
|
4987
|
+
) && isCanonicalUtcTimestamp(value.at) && (value.previousHash === null || isSha256(value.previousHash)) && isSha256(value.systemPromptHash) && isNonNegativeInteger(value.tokenEstimate) && (value.thinkingLevel === null || typeof value.thinkingLevel === "string") && (value.projectPreload === null || isProjectPreloadClass(value.projectPreload)) && Array.isArray(value.sections) && value.sections.every(isPromptManifestSection) && Array.isArray(value.fragments) && value.fragments.every(isPromptManifestFragment);
|
|
4891
4988
|
}
|
|
4892
4989
|
function getPromptManifestFilePath(meta, stateDir) {
|
|
4893
4990
|
const safeMeta = {
|
|
@@ -4935,6 +5032,9 @@ function readPromptCompileManifest(meta, stateDir) {
|
|
|
4935
5032
|
};
|
|
4936
5033
|
}
|
|
4937
5034
|
}
|
|
5035
|
+
function readPromptCompileRecords(meta) {
|
|
5036
|
+
return readPromptCompileManifest(meta).records;
|
|
5037
|
+
}
|
|
4938
5038
|
|
|
4939
5039
|
// src/interactive/model-session-replay.ts
|
|
4940
5040
|
init_esm_shims();
|
|
@@ -5055,6 +5155,160 @@ function formatRetryStatus(status) {
|
|
|
5055
5155
|
// src/interactive/renderers/tool-execution.ts
|
|
5056
5156
|
init_esm_shims();
|
|
5057
5157
|
|
|
5158
|
+
// src/interactive/mutation-preview.ts
|
|
5159
|
+
init_esm_shims();
|
|
5160
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
5161
|
+
import { readFileSync as readFileSync5 } from "node:fs";
|
|
5162
|
+
var MUTATION_PREVIEW_VISIBLE_ROWS = 16;
|
|
5163
|
+
var MUTATION_PREVIEW_MAX_CHARS = 262144;
|
|
5164
|
+
function canonicalJson(value) {
|
|
5165
|
+
if (value === null || value === void 0) return "null";
|
|
5166
|
+
if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
|
|
5167
|
+
if (typeof value === "object") {
|
|
5168
|
+
const entries = Object.entries(value).filter(([, entry]) => entry !== void 0).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
|
|
5169
|
+
return `{${entries.map(([key, entry]) => `${JSON.stringify(key)}:${canonicalJson(entry)}`).join(",")}}`;
|
|
5170
|
+
}
|
|
5171
|
+
if (typeof value === "string") return JSON.stringify(value);
|
|
5172
|
+
if (typeof value === "number") return Number.isFinite(value) ? JSON.stringify(value) : "null";
|
|
5173
|
+
if (typeof value === "boolean") return value ? "true" : "false";
|
|
5174
|
+
return "null";
|
|
5175
|
+
}
|
|
5176
|
+
function callArgumentsDigest(args) {
|
|
5177
|
+
return createHash2("sha256").update(canonicalJson(args ?? {}), "utf8").digest("hex").slice(0, 16);
|
|
5178
|
+
}
|
|
5179
|
+
function readEdits(value) {
|
|
5180
|
+
if (!Array.isArray(value)) return null;
|
|
5181
|
+
const edits = [];
|
|
5182
|
+
for (const entry of value) {
|
|
5183
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) return null;
|
|
5184
|
+
const record2 = entry;
|
|
5185
|
+
if (typeof record2.oldText !== "string" || typeof record2.newText !== "string") return null;
|
|
5186
|
+
edits.push({ oldText: record2.oldText, newText: record2.newText });
|
|
5187
|
+
}
|
|
5188
|
+
return edits;
|
|
5189
|
+
}
|
|
5190
|
+
function mutationFacts(tool, args) {
|
|
5191
|
+
if (!args || typeof args.path !== "string" || args.path.length === 0) return null;
|
|
5192
|
+
if (tool === ToolNames.Write) {
|
|
5193
|
+
if (typeof args.content !== "string") return null;
|
|
5194
|
+
return {
|
|
5195
|
+
kind: "write",
|
|
5196
|
+
bytes: Buffer.byteLength(args.content, "utf8"),
|
|
5197
|
+
replacements: 1,
|
|
5198
|
+
digest: callArgumentsDigest(args)
|
|
5199
|
+
};
|
|
5200
|
+
}
|
|
5201
|
+
if (tool === ToolNames.Edit) {
|
|
5202
|
+
const edits = readEdits(args.edits);
|
|
5203
|
+
if (edits === null || edits.length === 0) return null;
|
|
5204
|
+
const bytes = edits.reduce((total, edit) => total + Buffer.byteLength(edit.newText, "utf8"), 0);
|
|
5205
|
+
return { kind: "edit", bytes, replacements: edits.length, digest: callArgumentsDigest(args) };
|
|
5206
|
+
}
|
|
5207
|
+
return null;
|
|
5208
|
+
}
|
|
5209
|
+
function mutationFactsLine(facts) {
|
|
5210
|
+
const shape = facts.kind === "write" ? `write ${facts.bytes} B` : `edit ${facts.replacements} replacement${facts.replacements === 1 ? "" : "s"} \xB7 ${facts.bytes} B`;
|
|
5211
|
+
return `${shape} \xB7 sha256 ${facts.digest}`;
|
|
5212
|
+
}
|
|
5213
|
+
function numberedLines(text) {
|
|
5214
|
+
const raw = text.split("\n");
|
|
5215
|
+
const width = String(raw.length).length;
|
|
5216
|
+
return raw.map((line, index) => `${String(index + 1).padStart(width, " ")} ${line}`);
|
|
5217
|
+
}
|
|
5218
|
+
function boundedContent(content) {
|
|
5219
|
+
if (content.length <= MUTATION_PREVIEW_MAX_CHARS) return { text: content, withheld: 0 };
|
|
5220
|
+
return {
|
|
5221
|
+
text: content.slice(0, MUTATION_PREVIEW_MAX_CHARS),
|
|
5222
|
+
withheld: content.length - MUTATION_PREVIEW_MAX_CHARS
|
|
5223
|
+
};
|
|
5224
|
+
}
|
|
5225
|
+
function previewFrom(facts, heading, text, options = {}) {
|
|
5226
|
+
const clean = sanitizeMultilineDisplayText(text);
|
|
5227
|
+
const body = options.numbered ? numberedLines(clean.text) : clean.text.split("\n");
|
|
5228
|
+
if (options.trailer !== void 0) body.push(options.trailer);
|
|
5229
|
+
return {
|
|
5230
|
+
facts,
|
|
5231
|
+
heading,
|
|
5232
|
+
body,
|
|
5233
|
+
neutralized: clean.neutralized,
|
|
5234
|
+
tabsExpanded: clean.tabsExpanded
|
|
5235
|
+
};
|
|
5236
|
+
}
|
|
5237
|
+
function refusal(facts, heading, reason) {
|
|
5238
|
+
return { facts, heading, body: [reason], neutralized: false, tabsExpanded: false };
|
|
5239
|
+
}
|
|
5240
|
+
function replacementListing(edits) {
|
|
5241
|
+
const blocks = [];
|
|
5242
|
+
for (const [index, edit] of edits.entries()) {
|
|
5243
|
+
blocks.push(`@@ replacement ${index + 1} of ${edits.length}`);
|
|
5244
|
+
for (const line of normalizeToLF(edit.oldText).split("\n")) blocks.push(`- ${line}`);
|
|
5245
|
+
for (const line of normalizeToLF(edit.newText).split("\n")) blocks.push(`+ ${line}`);
|
|
5246
|
+
}
|
|
5247
|
+
return blocks.join("\n");
|
|
5248
|
+
}
|
|
5249
|
+
function editPreview(facts, path, edits, read) {
|
|
5250
|
+
let current;
|
|
5251
|
+
try {
|
|
5252
|
+
current = read(resolveToCwd(path));
|
|
5253
|
+
} catch (error) {
|
|
5254
|
+
const message = sanitizeCallTargetText(error instanceof Error ? error.message : String(error));
|
|
5255
|
+
return previewFrom(
|
|
5256
|
+
facts,
|
|
5257
|
+
`Requested replacements for ${sanitizeCallTargetText(path)} (the file could not be read: ${message})`,
|
|
5258
|
+
replacementListing(edits)
|
|
5259
|
+
);
|
|
5260
|
+
}
|
|
5261
|
+
try {
|
|
5262
|
+
const { text } = stripBom(current);
|
|
5263
|
+
const applied = applyEditsToNormalizedContent(normalizeToLF(text), edits, path);
|
|
5264
|
+
const diff = generateDiffString(applied.baseContent, applied.newContent);
|
|
5265
|
+
return previewFrom(facts, `Effective diff for ${sanitizeCallTargetText(path)}`, diff.diff);
|
|
5266
|
+
} catch (error) {
|
|
5267
|
+
const message = sanitizeCallTargetText(error instanceof Error ? error.message : String(error));
|
|
5268
|
+
return previewFrom(
|
|
5269
|
+
facts,
|
|
5270
|
+
`Requested replacements for ${sanitizeCallTargetText(path)} (they do not apply: ${message})`,
|
|
5271
|
+
replacementListing(edits)
|
|
5272
|
+
);
|
|
5273
|
+
}
|
|
5274
|
+
}
|
|
5275
|
+
function createMutationInspector(tool, args, facts, options = {}) {
|
|
5276
|
+
const read = options.readFile ?? ((path) => readFileSync5(path, "utf8"));
|
|
5277
|
+
return () => {
|
|
5278
|
+
const current = mutationFacts(tool, args);
|
|
5279
|
+
if (current === null || current.digest !== facts.digest) {
|
|
5280
|
+
return refusal(
|
|
5281
|
+
facts,
|
|
5282
|
+
"Preview unavailable",
|
|
5283
|
+
`These arguments no longer digest to sha256 ${facts.digest}. Deny this call rather than approving bytes that cannot be shown.`
|
|
5284
|
+
);
|
|
5285
|
+
}
|
|
5286
|
+
const path = typeof args?.path === "string" ? args.path : "";
|
|
5287
|
+
if (facts.kind === "write") {
|
|
5288
|
+
const content = typeof args?.content === "string" ? args.content : "";
|
|
5289
|
+
const bounded = boundedContent(content);
|
|
5290
|
+
return previewFrom(facts, `Proposed content for ${sanitizeCallTargetText(path)}`, bounded.text, {
|
|
5291
|
+
numbered: true,
|
|
5292
|
+
...bounded.withheld > 0 ? { trailer: `\u2026 ${bounded.withheld} more characters not shown (preview capped at ${MUTATION_PREVIEW_MAX_CHARS})` } : {}
|
|
5293
|
+
});
|
|
5294
|
+
}
|
|
5295
|
+
const edits = readEdits(args?.edits) ?? [];
|
|
5296
|
+
return editPreview(facts, path, edits, read);
|
|
5297
|
+
};
|
|
5298
|
+
}
|
|
5299
|
+
function mutationPreviewWindow(lines, scroll, rows = MUTATION_PREVIEW_VISIBLE_ROWS) {
|
|
5300
|
+
const visible = Math.max(1, rows);
|
|
5301
|
+
const maxScroll = Math.max(0, lines.length - visible);
|
|
5302
|
+
const start = Math.max(0, Math.min(scroll, maxScroll));
|
|
5303
|
+
const window = lines.slice(start, start + visible);
|
|
5304
|
+
if (lines.length <= visible) return { window, position: null, maxScroll };
|
|
5305
|
+
return {
|
|
5306
|
+
window,
|
|
5307
|
+
position: `(${start + 1}-${start + window.length} of ${lines.length} lines)`,
|
|
5308
|
+
maxScroll
|
|
5309
|
+
};
|
|
5310
|
+
}
|
|
5311
|
+
|
|
5058
5312
|
// src/interactive/renderers/diff.ts
|
|
5059
5313
|
init_esm_shims();
|
|
5060
5314
|
var ESC = String.fromCharCode(27);
|
|
@@ -5529,7 +5783,10 @@ function renderToolAwaitingApproval(call, width, view) {
|
|
|
5529
5783
|
const facts = [
|
|
5530
5784
|
["action", view.actionClass],
|
|
5531
5785
|
["axis", axis],
|
|
5532
|
-
...view.target !== void 0 && view.target.length > 0 ? [["target", view.target]] : []
|
|
5786
|
+
...view.target !== void 0 && view.target.length > 0 ? [["target", view.target]] : [],
|
|
5787
|
+
// Size and digest, never the mutation text: this row is the transcript,
|
|
5788
|
+
// which is written, replayed, and shared (issue #254).
|
|
5789
|
+
...view.mutation !== void 0 ? [["mutation", mutationFactsLine(view.mutation)]] : []
|
|
5533
5790
|
];
|
|
5534
5791
|
for (const [label, value] of facts) {
|
|
5535
5792
|
lines.push(...indentAndWrap(`${dim(`${label} \xB7`)} ${value}`, width, false));
|
|
@@ -6565,12 +6822,12 @@ function toggledFold(effective) {
|
|
|
6565
6822
|
|
|
6566
6823
|
// src/interactive/worker-receipts.ts
|
|
6567
6824
|
init_esm_shims();
|
|
6568
|
-
import { existsSync as existsSync5, readFileSync as
|
|
6825
|
+
import { existsSync as existsSync5, readFileSync as readFileSync7 } from "node:fs";
|
|
6569
6826
|
import { join as join6 } from "node:path";
|
|
6570
6827
|
|
|
6571
6828
|
// src/interactive/view/artifacts.ts
|
|
6572
6829
|
init_esm_shims();
|
|
6573
|
-
import { createReadStream, readFileSync as
|
|
6830
|
+
import { createReadStream, readFileSync as readFileSync6, statSync } from "node:fs";
|
|
6574
6831
|
import { readFile, realpath, stat } from "node:fs/promises";
|
|
6575
6832
|
import { basename, isAbsolute as isAbsolute4, join as join5, relative as relative4, resolve as resolve3, sep } from "node:path";
|
|
6576
6833
|
|
|
@@ -6649,7 +6906,7 @@ var CONTEXT_CATEGORY_TOKEN = {
|
|
|
6649
6906
|
project: "muted",
|
|
6650
6907
|
messages: "accent",
|
|
6651
6908
|
pending: "accentDeep",
|
|
6652
|
-
reserve: "
|
|
6909
|
+
reserve: "frame",
|
|
6653
6910
|
free: "frame",
|
|
6654
6911
|
streaming: "accent"
|
|
6655
6912
|
};
|
|
@@ -7513,6 +7770,18 @@ function progressAnswerLines(theme6, progress, runId, contentWidth) {
|
|
|
7513
7770
|
}
|
|
7514
7771
|
return body.map((row2, index) => `${index === 0 ? cardKvKey(theme6, "answer") : " ".repeat(gutter)}${row2}`);
|
|
7515
7772
|
}
|
|
7773
|
+
function trustCardLines(theme6, row2, contentWidth) {
|
|
7774
|
+
const gutter = CARD_KV_KEY_WIDTH + 1;
|
|
7775
|
+
const valueWidth = Math.max(1, contentWidth - gutter);
|
|
7776
|
+
const trust = row2.trust === void 0 ? theme6.fg("dim", isTerminalStatus(row2.status) ? "receipt not read back" : "not sealed yet") : theme6.fg(
|
|
7777
|
+
trustVerdictToken(row2.trust.verdict),
|
|
7778
|
+
`${trustVerdictGlyph(row2.trust.verdict)} ${row2.trust.verdict}; ${row2.trust.text}`
|
|
7779
|
+
);
|
|
7780
|
+
const host = row2.hostVerification === void 0 ? "" : ` \xB7 ${theme6.fg("muted", `host checks ${row2.hostVerification}`)}`;
|
|
7781
|
+
return wrapTextWithAnsi(`${trust}${host}`, valueWidth).map(
|
|
7782
|
+
(line, index) => `${index === 0 ? cardKvKey(theme6, "trust") : " ".repeat(gutter)}${line}`
|
|
7783
|
+
);
|
|
7784
|
+
}
|
|
7516
7785
|
function renderDispatchCard(row2, width, evidence, options = {}) {
|
|
7517
7786
|
const theme6 = clioTheme();
|
|
7518
7787
|
const contentWidth = Math.max(0, width - 4);
|
|
@@ -7544,13 +7813,13 @@ function renderDispatchCard(row2, width, evidence, options = {}) {
|
|
|
7544
7813
|
const statusUnits = [
|
|
7545
7814
|
statusStr,
|
|
7546
7815
|
theme6.fg("muted", `node ${row2.node ?? "local"}`),
|
|
7816
|
+
...row2.endpoint !== void 0 ? [theme6.fg("info", `slots ${options.endpointActive ?? 0}/${row2.endpoint.limit} ${row2.endpoint.label}`)] : [],
|
|
7547
7817
|
...row2.gate !== void 0 ? [theme6.fg("info", `gate ${row2.gate.role} c${row2.gate.cycle}`)] : [],
|
|
7548
7818
|
...row2.rerouteCount !== void 0 && row2.rerouteCount > 0 ? [theme6.fg("warning", `rerouted x${row2.rerouteCount}`)] : [],
|
|
7549
7819
|
...row2.failoverHops !== void 0 && row2.failoverHops > 0 ? [theme6.fg("warning", `failed over x${row2.failoverHops}`)] : [],
|
|
7550
7820
|
`${theme6.fg("dim", "ttft")} ${theme6.fg("muted", ttft)}`,
|
|
7551
7821
|
`${theme6.fg("dim", "cost")} ${theme6.fg("muted", cost)}`
|
|
7552
7822
|
];
|
|
7553
|
-
const hostVerification = theme6.fg("info", `host_verification=${row2.hostVerification ?? "not_requested"}`);
|
|
7554
7823
|
const contextUnit = formatWorkerContextMeter(row2.lastContextTokens ?? 0, row2.contextWindow, theme6);
|
|
7555
7824
|
const phaseCell = formatDispatchPhaseCell(row2.phase, contentWidth);
|
|
7556
7825
|
const bodyLines2 = [
|
|
@@ -7564,7 +7833,7 @@ function renderDispatchCard(row2, width, evidence, options = {}) {
|
|
|
7564
7833
|
targetLine,
|
|
7565
7834
|
...row2.taskSummary ? [truncateToWidth(`${cardKvKey(theme6, "task")}${theme6.fg("muted", row2.taskSummary)}`, contentWidth, "\u2026", false)] : [],
|
|
7566
7835
|
cardUnitsLine(theme6, "status", statusUnits, contentWidth),
|
|
7567
|
-
|
|
7836
|
+
...trustCardLines(theme6, row2, contentWidth),
|
|
7568
7837
|
...row2.budget !== void 0 ? [
|
|
7569
7838
|
truncateToWidth(
|
|
7570
7839
|
`${cardKvKey(theme6, "policy")}${theme6.fg("muted", `${formatBudgetPolicy(row2.budget)}; requested ${formatBudgetRequest(row2.budget)}`)}`,
|
|
@@ -7619,6 +7888,16 @@ function renderDispatchCard(row2, width, evidence, options = {}) {
|
|
|
7619
7888
|
)
|
|
7620
7889
|
);
|
|
7621
7890
|
}
|
|
7891
|
+
if (row2.writeRecordDowngrade) {
|
|
7892
|
+
const warning = describeWriteBoundaryAttributionDowngrade({
|
|
7893
|
+
...row2.writeRecordDowngrade,
|
|
7894
|
+
runId: row2.runId,
|
|
7895
|
+
stepId: row2.phase?.stepId ?? null
|
|
7896
|
+
});
|
|
7897
|
+
bodyLines2.push(
|
|
7898
|
+
...wrapTextWithAnsi(`${cardKvKey(theme6, "record")}${theme6.fg("warning", `open: ${warning}`)}`, contentWidth)
|
|
7899
|
+
);
|
|
7900
|
+
}
|
|
7622
7901
|
if (evidence) {
|
|
7623
7902
|
const proofLine = evidenceCardLine(theme6, evidence, contentWidth);
|
|
7624
7903
|
if (proofLine !== null) bodyLines2.push(proofLine);
|
|
@@ -7757,10 +8036,17 @@ function formatDispatchBoardLines(rows, width = 76, observability, selectedRunId
|
|
|
7757
8036
|
return theme6.fg("dim", " ".repeat(padding) + line);
|
|
7758
8037
|
});
|
|
7759
8038
|
}
|
|
8039
|
+
const endpointActive = { ...foregroundStreamUsage() };
|
|
8040
|
+
for (const row2 of rows) {
|
|
8041
|
+
if (row2.endpoint !== void 0 && (row2.status === "running" || row2.status === "stale" || row2.status === "enqueued" || row2.status === "cancelling")) {
|
|
8042
|
+
endpointActive[row2.endpoint.key] = (endpointActive[row2.endpoint.key] ?? 0) + 1;
|
|
8043
|
+
}
|
|
8044
|
+
}
|
|
7760
8045
|
const cards = dispatchBoardItems(rows, selectedRunId).map(
|
|
7761
8046
|
(item) => item.kind === "council" ? renderCouncilCard(item.group, width) : renderDispatchCard(item.row, width, deriveRunEvidenceState(observability, item.row.runId), {
|
|
7762
8047
|
selected: item.row.runId === selectedRunId,
|
|
7763
|
-
expanded: detailExpanded && item.row.runId === selectedRunId
|
|
8048
|
+
expanded: detailExpanded && item.row.runId === selectedRunId,
|
|
8049
|
+
...item.row.endpoint !== void 0 ? { endpointActive: endpointActive[item.row.endpoint.key] ?? 0 } : {}
|
|
7764
8050
|
})
|
|
7765
8051
|
);
|
|
7766
8052
|
const body = [];
|
|
@@ -7884,6 +8170,14 @@ function parseGateBadge(value) {
|
|
|
7884
8170
|
const cycle = parsePositiveInt(record2.cycle) ?? 1;
|
|
7885
8171
|
return { role: record2.role, cycle };
|
|
7886
8172
|
}
|
|
8173
|
+
function parseEndpointCapacity(value) {
|
|
8174
|
+
if (typeof value !== "object" || value === null) return void 0;
|
|
8175
|
+
const record2 = value;
|
|
8176
|
+
const key = parseNonEmptyString(record2.key);
|
|
8177
|
+
const label = parseNonEmptyString(record2.label);
|
|
8178
|
+
const limit = parsePositiveInt(record2.limit);
|
|
8179
|
+
return key === void 0 || label === void 0 || limit === void 0 ? void 0 : { key, label, limit };
|
|
8180
|
+
}
|
|
7887
8181
|
function parseCouncilBadge(value) {
|
|
7888
8182
|
if (typeof value !== "object" || value === null) return void 0;
|
|
7889
8183
|
const record2 = value;
|
|
@@ -7906,6 +8200,30 @@ function parseOptionalDetail(value) {
|
|
|
7906
8200
|
const detail = value.replace(/\s+/g, " ").trim();
|
|
7907
8201
|
return detail.length > 0 ? detail : null;
|
|
7908
8202
|
}
|
|
8203
|
+
function trustVerdictToken(verdict) {
|
|
8204
|
+
switch (verdict) {
|
|
8205
|
+
case "reviewed":
|
|
8206
|
+
return "success";
|
|
8207
|
+
case "grounded":
|
|
8208
|
+
return "info";
|
|
8209
|
+
case "unverified":
|
|
8210
|
+
return "muted";
|
|
8211
|
+
case "compromised":
|
|
8212
|
+
return "error";
|
|
8213
|
+
default:
|
|
8214
|
+
return "dim";
|
|
8215
|
+
}
|
|
8216
|
+
}
|
|
8217
|
+
function trustVerdictGlyph(verdict) {
|
|
8218
|
+
switch (verdict) {
|
|
8219
|
+
case "reviewed":
|
|
8220
|
+
return GLYPH.ok;
|
|
8221
|
+
case "compromised":
|
|
8222
|
+
return GLYPH.error;
|
|
8223
|
+
default:
|
|
8224
|
+
return "\u25C7";
|
|
8225
|
+
}
|
|
8226
|
+
}
|
|
7909
8227
|
function terminalDetail(row2) {
|
|
7910
8228
|
if (row2.status !== "failed" && row2.status !== "dead" && row2.status !== "aborted") return null;
|
|
7911
8229
|
return parseOptionalDetail(row2.outcomeDetail);
|
|
@@ -8011,6 +8329,7 @@ function toRow(entry, now) {
|
|
|
8011
8329
|
runtimeId: entry.runtimeId,
|
|
8012
8330
|
targetId: entry.targetId,
|
|
8013
8331
|
wireModelId: entry.wireModelId,
|
|
8332
|
+
...entry.endpoint !== void 0 ? { endpoint: { ...entry.endpoint } } : {},
|
|
8014
8333
|
...entry.taskSummary !== void 0 ? { taskSummary: entry.taskSummary } : {},
|
|
8015
8334
|
...entry.budget !== void 0 ? { budget: entry.budget } : {},
|
|
8016
8335
|
status: retry ? "retrying" : entry.status,
|
|
@@ -8026,6 +8345,7 @@ function toRow(entry, now) {
|
|
|
8026
8345
|
...entry.gate !== void 0 ? { gate: { ...entry.gate } } : {},
|
|
8027
8346
|
...entry.council !== void 0 ? { council: { ...entry.council } } : {},
|
|
8028
8347
|
...entry.hostVerification !== void 0 ? { hostVerification: entry.hostVerification } : {},
|
|
8348
|
+
...entry.trust !== void 0 ? { trust: entry.trust } : {},
|
|
8029
8349
|
...entry.rerouteCount !== void 0 ? { rerouteCount: entry.rerouteCount } : {},
|
|
8030
8350
|
...entry.failoverHops !== void 0 ? { failoverHops: entry.failoverHops } : {},
|
|
8031
8351
|
...entry.contextWindow !== void 0 ? { contextWindow: entry.contextWindow } : {},
|
|
@@ -8037,7 +8357,8 @@ function toRow(entry, now) {
|
|
|
8037
8357
|
currentTool: retry ? null : progress.currentAction?.tool ?? null,
|
|
8038
8358
|
recentTools: progress.recentActions.map((action) => action.tool),
|
|
8039
8359
|
...retry ? { retry: { ...retry } } : {},
|
|
8040
|
-
...entry.steerAcknowledgement ? { steerAcknowledgement: { ...entry.steerAcknowledgement } } : {}
|
|
8360
|
+
...entry.steerAcknowledgement ? { steerAcknowledgement: { ...entry.steerAcknowledgement } } : {},
|
|
8361
|
+
...entry.writeRecordDowngrade ? { writeRecordDowngrade: { ...entry.writeRecordDowngrade } } : {}
|
|
8041
8362
|
};
|
|
8042
8363
|
}
|
|
8043
8364
|
function sortEntries(a, b) {
|
|
@@ -8066,8 +8387,10 @@ function createDispatchBoardStore(bus, snapshot, readReceipt) {
|
|
|
8066
8387
|
let nextSequence = 0;
|
|
8067
8388
|
let reconciledAtMs = Date.now();
|
|
8068
8389
|
const settleFromReceipt = (entry) => {
|
|
8069
|
-
const
|
|
8390
|
+
const facts = readReceipt?.(entry.runId);
|
|
8391
|
+
const text = facts?.text;
|
|
8070
8392
|
entry.progress.settle(typeof text === "string" && text.trim().length > 0 ? text : void 0);
|
|
8393
|
+
if (facts?.trust !== void 0) entry.trust = summarizeTrustStatus(facts.trust);
|
|
8071
8394
|
};
|
|
8072
8395
|
const upsertBase = (raw, status, now) => {
|
|
8073
8396
|
const runId = parseRunId(raw.runId);
|
|
@@ -8076,6 +8399,7 @@ function createDispatchBoardStore(bus, snapshot, readReceipt) {
|
|
|
8076
8399
|
const agentAudience = parseAgentAudience(raw.agentAudience, previous?.agentAudience);
|
|
8077
8400
|
const requestOrigin = parseRequestOrigin(raw.requestOrigin, previous?.requestOrigin);
|
|
8078
8401
|
const node = parseNonEmptyString(raw.node) ?? previous?.node;
|
|
8402
|
+
const endpoint = parseEndpointCapacity(raw.endpoint) ?? previous?.endpoint;
|
|
8079
8403
|
const gate = parseGateBadge(raw.gate) ?? previous?.gate;
|
|
8080
8404
|
const council = parseCouncilBadge(raw.council) ?? previous?.council;
|
|
8081
8405
|
const rerouteCount = parsePositiveInt(raw.rerouteCount) ?? previous?.rerouteCount;
|
|
@@ -8092,6 +8416,7 @@ function createDispatchBoardStore(bus, snapshot, readReceipt) {
|
|
|
8092
8416
|
runtimeId: parseText(raw.runtimeId, previous?.runtimeId ?? "-"),
|
|
8093
8417
|
targetId: parseText(raw.targetId, previous?.targetId ?? "-"),
|
|
8094
8418
|
wireModelId: parseText(raw.wireModelId, previous?.wireModelId ?? "-"),
|
|
8419
|
+
...endpoint !== void 0 ? { endpoint } : {},
|
|
8095
8420
|
...taskSummary !== void 0 ? { taskSummary } : {},
|
|
8096
8421
|
...budget !== void 0 ? { budget } : {},
|
|
8097
8422
|
status,
|
|
@@ -8119,7 +8444,8 @@ function createDispatchBoardStore(bus, snapshot, readReceipt) {
|
|
|
8119
8444
|
...phase !== void 0 ? { phase } : {},
|
|
8120
8445
|
progress: previous?.progress ?? createWorkerProgressFold(),
|
|
8121
8446
|
...previous?.retry ? { retry: { ...previous.retry } } : {},
|
|
8122
|
-
...previous?.steerAcknowledgement ? { steerAcknowledgement: { ...previous.steerAcknowledgement } } : {}
|
|
8447
|
+
...previous?.steerAcknowledgement ? { steerAcknowledgement: { ...previous.steerAcknowledgement } } : {},
|
|
8448
|
+
...previous?.writeRecordDowngrade ? { writeRecordDowngrade: { ...previous.writeRecordDowngrade } } : {}
|
|
8123
8449
|
};
|
|
8124
8450
|
entries.set(runId, entry);
|
|
8125
8451
|
pruneEntries(entries, (evicted) => fleetPhases.delete(evicted));
|
|
@@ -8246,6 +8572,19 @@ function createDispatchBoardStore(bus, snapshot, readReceipt) {
|
|
|
8246
8572
|
entry.ttftMs = Math.round(performance3.now() - entry.startedAtClockMs);
|
|
8247
8573
|
}
|
|
8248
8574
|
}
|
|
8575
|
+
if (type === "clio_write_record_downgraded") {
|
|
8576
|
+
const rawPayload = workerEvent.payload;
|
|
8577
|
+
const payload2 = typeof rawPayload === "object" && rawPayload !== null ? rawPayload : null;
|
|
8578
|
+
const tool = payload2 === null ? void 0 : parseNonEmptyString(payload2.tool);
|
|
8579
|
+
const toolCallId = payload2 === null ? void 0 : parseNonEmptyString(payload2.toolCallId);
|
|
8580
|
+
if (payload2?.reason === "opaque_tool_succeeded" && tool !== void 0 && toolCallId !== void 0) {
|
|
8581
|
+
entry.writeRecordDowngrade = {
|
|
8582
|
+
reason: "opaque_tool_succeeded",
|
|
8583
|
+
tool: sanitizeCallTargetText(tool),
|
|
8584
|
+
toolCallId: sanitizeCallTargetText(toolCallId)
|
|
8585
|
+
};
|
|
8586
|
+
}
|
|
8587
|
+
}
|
|
8249
8588
|
entry.progress.observe(payload.event);
|
|
8250
8589
|
if (type === "clio_steer_received") {
|
|
8251
8590
|
const steerPayload = workerEvent.payload;
|
|
@@ -8689,8 +9028,41 @@ function retryOverlay(status) {
|
|
|
8689
9028
|
}
|
|
8690
9029
|
function reduceStatus(prev, event, ctx) {
|
|
8691
9030
|
switch (event.type) {
|
|
8692
|
-
|
|
9031
|
+
// A consumed prompt occupies `preparing` before any engine event exists,
|
|
9032
|
+
// and the previous turn's summary rides along untouched: a refused
|
|
9033
|
+
// admission puts the footer back on the last turn that actually ran,
|
|
9034
|
+
// which is still the truth about what happened.
|
|
9035
|
+
case "submit_accepted":
|
|
8693
9036
|
if (isActive(prev.phase)) return prev;
|
|
9037
|
+
return {
|
|
9038
|
+
...prev,
|
|
9039
|
+
phase: "preparing",
|
|
9040
|
+
since: ctx.now,
|
|
9041
|
+
lastMeaningfulAt: ctx.now,
|
|
9042
|
+
localRuntime: ctx.localRuntime,
|
|
9043
|
+
preparingSubmission: true,
|
|
9044
|
+
watchdogTier: 0,
|
|
9045
|
+
resumePhase: void 0,
|
|
9046
|
+
activePhases: void 0,
|
|
9047
|
+
overlayStack: [],
|
|
9048
|
+
tool: void 0,
|
|
9049
|
+
toolStartedAt: void 0,
|
|
9050
|
+
retry: void 0,
|
|
9051
|
+
dispatch: void 0
|
|
9052
|
+
};
|
|
9053
|
+
case "submit_settled":
|
|
9054
|
+
if (prev.preparingSubmission !== true) return prev;
|
|
9055
|
+
return {
|
|
9056
|
+
...prev,
|
|
9057
|
+
phase: prev.summary ? "ended" : "idle",
|
|
9058
|
+
since: ctx.now,
|
|
9059
|
+
preparingSubmission: void 0,
|
|
9060
|
+
resumePhase: void 0,
|
|
9061
|
+
activePhases: void 0,
|
|
9062
|
+
overlayStack: []
|
|
9063
|
+
};
|
|
9064
|
+
case "agent_start":
|
|
9065
|
+
if (isActive(prev.phase) && prev.preparingSubmission !== true) return prev;
|
|
8694
9066
|
return {
|
|
8695
9067
|
...INITIAL_STATUS,
|
|
8696
9068
|
phase: "preparing",
|
|
@@ -9010,6 +9382,13 @@ function createStatusController(deps) {
|
|
|
9010
9382
|
}
|
|
9011
9383
|
notify(prev, status, force);
|
|
9012
9384
|
};
|
|
9385
|
+
if (deps.chat.onTurnPreparation) {
|
|
9386
|
+
unsubscribes.push(
|
|
9387
|
+
deps.chat.onTurnPreparation((phase) => {
|
|
9388
|
+
apply({ type: phase === "idle" ? "submit_settled" : "submit_accepted" }, true);
|
|
9389
|
+
})
|
|
9390
|
+
);
|
|
9391
|
+
}
|
|
9013
9392
|
unsubscribes.push(
|
|
9014
9393
|
deps.chat.onEvent((event) => {
|
|
9015
9394
|
if (event.type === "agent_status") return;
|
|
@@ -10104,7 +10483,7 @@ function runLedgerPath(stateDir) {
|
|
|
10104
10483
|
}
|
|
10105
10484
|
function readRunLedger(stateDir) {
|
|
10106
10485
|
try {
|
|
10107
|
-
const raw =
|
|
10486
|
+
const raw = readFileSync6(runLedgerPath(stateDir), "utf8").trim();
|
|
10108
10487
|
if (raw.length === 0) return [];
|
|
10109
10488
|
const parsed = JSON.parse(raw);
|
|
10110
10489
|
return Array.isArray(parsed) ? parsed.filter(isRecord9) : [];
|
|
@@ -10146,6 +10525,15 @@ function validateToolStats(value) {
|
|
|
10146
10525
|
}
|
|
10147
10526
|
return { ok: true };
|
|
10148
10527
|
}
|
|
10528
|
+
function receiptTrustDetail(stateDir, runId) {
|
|
10529
|
+
try {
|
|
10530
|
+
const receipt = JSON.parse(readFileSync6(receiptFilePath(stateDir, runId), "utf8"));
|
|
10531
|
+
const ledger = readRunEnvelope(stateDir, runId);
|
|
10532
|
+
return formatTrustSummaryLine(inspectRunReceiptTrustStatus(receipt, ledger.ok ? ledger.envelope : null).status);
|
|
10533
|
+
} catch {
|
|
10534
|
+
return "integrity verified; trust status unreadable";
|
|
10535
|
+
}
|
|
10536
|
+
}
|
|
10149
10537
|
function readRunEnvelope(stateDir, runId) {
|
|
10150
10538
|
const runs = readRunLedger(stateDir);
|
|
10151
10539
|
for (const entry of runs) {
|
|
@@ -10157,7 +10545,7 @@ function verifyReceiptFile(stateDir, runId) {
|
|
|
10157
10545
|
const target = receiptFilePath(stateDir, runId);
|
|
10158
10546
|
let raw;
|
|
10159
10547
|
try {
|
|
10160
|
-
raw =
|
|
10548
|
+
raw = readFileSync6(target, "utf8");
|
|
10161
10549
|
} catch (err) {
|
|
10162
10550
|
const e = err;
|
|
10163
10551
|
if (e.code === "ENOENT") return { ok: false, reason: "receipt file not found" };
|
|
@@ -10252,6 +10640,8 @@ function verifyReceiptFile(stateDir, runId) {
|
|
|
10252
10640
|
if (!isNullableString(r.sessionId)) {
|
|
10253
10641
|
return { ok: false, reason: `sessionId invalid: ${String(r.sessionId)}` };
|
|
10254
10642
|
}
|
|
10643
|
+
const retired = retiredReceiptIntegrity(r.integrity);
|
|
10644
|
+
if (retired !== null) return { ok: false, reason: retiredReceiptIntegrityReason(retired), retired };
|
|
10255
10645
|
if (!isReceiptIntegrity(r.integrity)) {
|
|
10256
10646
|
return { ok: false, reason: "integrity invalid" };
|
|
10257
10647
|
}
|
|
@@ -10507,8 +10897,10 @@ var ReceiptArtifactProvider = class {
|
|
|
10507
10897
|
load: () => loadJsonFileLines(path),
|
|
10508
10898
|
verify: async () => {
|
|
10509
10899
|
const result = verifyReceiptFile(this.deps.stateDir, env.id);
|
|
10510
|
-
if (!result.ok)
|
|
10511
|
-
|
|
10900
|
+
if (!result.ok) {
|
|
10901
|
+
return { ok: false, detail: result.reason, ...result.retired !== void 0 ? { retired: true } : {} };
|
|
10902
|
+
}
|
|
10903
|
+
return { ok: true, detail: receiptTrustDetail(this.deps.stateDir, env.id) };
|
|
10512
10904
|
}
|
|
10513
10905
|
};
|
|
10514
10906
|
});
|
|
@@ -11278,12 +11670,19 @@ function workerReceiptFacts(receipt) {
|
|
|
11278
11670
|
};
|
|
11279
11671
|
}
|
|
11280
11672
|
function readReceiptFileFacts(runId, stateDir) {
|
|
11673
|
+
let parsed;
|
|
11281
11674
|
try {
|
|
11282
|
-
|
|
11283
|
-
return isRecord10(parsed) ? workerReceiptFacts(parsed) : null;
|
|
11675
|
+
parsed = JSON.parse(readFileSync7(receiptFilePath(stateDir, runId), "utf8"));
|
|
11284
11676
|
} catch {
|
|
11285
11677
|
return null;
|
|
11286
11678
|
}
|
|
11679
|
+
if (!isRecord10(parsed)) return null;
|
|
11680
|
+
const facts = workerReceiptFacts(parsed);
|
|
11681
|
+
if (facts === null) return null;
|
|
11682
|
+
const row2 = findRunRow(runId, stateDir);
|
|
11683
|
+
if (row2 === null) return facts;
|
|
11684
|
+
const trust = inspectRunReceiptTrustStatus(parsed, row2).status;
|
|
11685
|
+
return { ...facts, trust };
|
|
11287
11686
|
}
|
|
11288
11687
|
function readWorkerReceiptFacts(runId, stateDir = clioStateDir()) {
|
|
11289
11688
|
return readReceiptFileFacts(runId, stateDir);
|
|
@@ -11292,7 +11691,7 @@ function findRunRow(runId, stateDir) {
|
|
|
11292
11691
|
const path = join6(stateDir, "runs.json");
|
|
11293
11692
|
if (!existsSync5(path)) return null;
|
|
11294
11693
|
try {
|
|
11295
|
-
const parsed = JSON.parse(
|
|
11694
|
+
const parsed = JSON.parse(readFileSync7(path, "utf8"));
|
|
11296
11695
|
if (!Array.isArray(parsed)) return null;
|
|
11297
11696
|
for (const entry of parsed) {
|
|
11298
11697
|
if (isRecord10(entry) && entry.id === runId) return entry;
|
|
@@ -12469,18 +12868,27 @@ function createTurnContext(deps) {
|
|
|
12469
12868
|
const { state, middleware } = deps;
|
|
12470
12869
|
const compactionTrigger = new AutoCompactionTrigger();
|
|
12471
12870
|
let currentContextSnapshot = null;
|
|
12871
|
+
let reconciledAnchor = null;
|
|
12472
12872
|
let lastCompactionEvent = null;
|
|
12473
12873
|
let lastPromptCache = null;
|
|
12474
12874
|
let lastSystemPromptReused = false;
|
|
12875
|
+
let lastPrewarm = null;
|
|
12475
12876
|
let sessionPrompt = null;
|
|
12476
12877
|
let sessionPromptKey = null;
|
|
12878
|
+
let sessionPromptHash = null;
|
|
12879
|
+
let resumedPromptHashRead = false;
|
|
12880
|
+
let resumedPromptHash = null;
|
|
12477
12881
|
const sessionWorkingContextPaths = /* @__PURE__ */ new Set();
|
|
12478
12882
|
let pendingPromptLogEntry = null;
|
|
12479
12883
|
let emptyAutoCompactTurnId = null;
|
|
12480
12884
|
const pendingColdReasons = /* @__PURE__ */ new Set();
|
|
12481
12885
|
let runExpectedColdReasons = [];
|
|
12482
12886
|
let nextAssistantColdReasons = [];
|
|
12483
|
-
const TIER_INDEPENDENT_COLD_REASONS = /* @__PURE__ */ new Set([
|
|
12887
|
+
const TIER_INDEPENDENT_COLD_REASONS = /* @__PURE__ */ new Set([
|
|
12888
|
+
"working_set_evict",
|
|
12889
|
+
"tool_surface_change",
|
|
12890
|
+
"prompt_recompiled"
|
|
12891
|
+
]);
|
|
12484
12892
|
const stampsOnTier = (reason, runtimeId) => TIER_INDEPENDENT_COLD_REASONS.has(reason) || runtimeId !== void 0 && deps.providers.getRuntime(runtimeId)?.tier === "local-native";
|
|
12485
12893
|
const noteColdReason = (reason) => {
|
|
12486
12894
|
if (!state.streaming) {
|
|
@@ -12504,6 +12912,21 @@ function createTurnContext(deps) {
|
|
|
12504
12912
|
noteColdReason("compaction");
|
|
12505
12913
|
}) ?? null
|
|
12506
12914
|
),
|
|
12915
|
+
deps.bus?.on(BusChannels.ResidencyMutation, (payload) => {
|
|
12916
|
+
const runtime = state.runtime;
|
|
12917
|
+
const model = runtime?.agent.state.model;
|
|
12918
|
+
const baseUrl = typeof model?.baseUrl === "string" ? model.baseUrl : null;
|
|
12919
|
+
if (payload.targetKey !== residencyTargetKey(runtime?.runtimeId ?? "", baseUrl)) return;
|
|
12920
|
+
noteColdReason("residency");
|
|
12921
|
+
}) ?? null,
|
|
12922
|
+
// A memory step on another endpoint disturbs nothing here, so the stamp is
|
|
12923
|
+
// gated on the step having called the very server this session streams to.
|
|
12924
|
+
deps.bus?.on(BusChannels.MemoryStepCompleted, (payload) => {
|
|
12925
|
+
const target = state.runtime?.runtimeResolution.target;
|
|
12926
|
+
if (target === void 0) return;
|
|
12927
|
+
if (canonicalEndpointKey(target) !== payload.endpointKey) return;
|
|
12928
|
+
noteColdReason("background_memory");
|
|
12929
|
+
}) ?? null,
|
|
12507
12930
|
deps.bus?.on(BusChannels.ContextRecalled, (payload) => {
|
|
12508
12931
|
middleware.fireCompactionHook("working_set_recall", payload.trigger);
|
|
12509
12932
|
}) ?? null
|
|
@@ -12558,6 +12981,23 @@ function createTurnContext(deps) {
|
|
|
12558
12981
|
}
|
|
12559
12982
|
return ceilChars(snapshot.pendingUserInput.length);
|
|
12560
12983
|
};
|
|
12984
|
+
const rememberedLoadedContextWindow = (targetId, modelId) => {
|
|
12985
|
+
const session = deps.session?.current();
|
|
12986
|
+
if (!session) return null;
|
|
12987
|
+
return lastLoadedContextWindow(session, targetId, modelId);
|
|
12988
|
+
};
|
|
12989
|
+
const lastRecordedPromptHash = () => {
|
|
12990
|
+
if (resumedPromptHashRead) return resumedPromptHash;
|
|
12991
|
+
resumedPromptHashRead = true;
|
|
12992
|
+
const currentSession = deps.session?.current();
|
|
12993
|
+
if (!currentSession) {
|
|
12994
|
+
resumedPromptHashRead = false;
|
|
12995
|
+
return null;
|
|
12996
|
+
}
|
|
12997
|
+
const records = readPromptCompileRecords(currentSession);
|
|
12998
|
+
resumedPromptHash = records[records.length - 1]?.systemPromptHash ?? null;
|
|
12999
|
+
return resumedPromptHash;
|
|
13000
|
+
};
|
|
12561
13001
|
const resolveWindowWithoutRuntime = () => {
|
|
12562
13002
|
const settings = deps.getSettings();
|
|
12563
13003
|
const targetId = settings.orchestrator?.target?.trim();
|
|
@@ -12569,7 +13009,8 @@ function createTurnContext(deps) {
|
|
|
12569
13009
|
requestedThinkingLevel: settings.orchestrator?.thinkingLevel ?? "off",
|
|
12570
13010
|
use: "orchestrator",
|
|
12571
13011
|
requireTools: false,
|
|
12572
|
-
requireOutputBudget: true
|
|
13012
|
+
requireOutputBudget: true,
|
|
13013
|
+
knownLoadedContextWindow: rememberedLoadedContextWindow(targetId, wireModelId)
|
|
12573
13014
|
});
|
|
12574
13015
|
return resolved.ok ? resolved.target.contextWindowDetails : null;
|
|
12575
13016
|
};
|
|
@@ -12602,6 +13043,19 @@ function createTurnContext(deps) {
|
|
|
12602
13043
|
}
|
|
12603
13044
|
return { contextWindow: 0, contextWindowSource: null, contextWindowSlots: null };
|
|
12604
13045
|
};
|
|
13046
|
+
const reconciledAnchoredTokens = (agentRuntime, pendingUserTokens) => {
|
|
13047
|
+
const anchor = reconciledAnchor;
|
|
13048
|
+
if (!anchor) return null;
|
|
13049
|
+
const messages = agentRuntime.agent.state.messages;
|
|
13050
|
+
if (anchor.anchoredMessageCount > messages.length) return null;
|
|
13051
|
+
let tail = 0;
|
|
13052
|
+
for (let i = anchor.anchoredMessageCount; i < messages.length; i += 1) {
|
|
13053
|
+
const message = messages[i];
|
|
13054
|
+
if (message === void 0) continue;
|
|
13055
|
+
tail += estimateAgentMessageTokens(message);
|
|
13056
|
+
}
|
|
13057
|
+
return anchor.tokens + tail + pendingUserTokens;
|
|
13058
|
+
};
|
|
12605
13059
|
const liveContextEstimate = (agentRuntime, pendingUserText) => {
|
|
12606
13060
|
const contextWindow = agentRuntime.runtimeResolution.contextWindowDetails.effectiveContextWindow;
|
|
12607
13061
|
const estimateInput = {
|
|
@@ -12610,10 +13064,25 @@ function createTurnContext(deps) {
|
|
|
12610
13064
|
tools: agentRuntime.agent.state.tools,
|
|
12611
13065
|
...pendingUserText !== void 0 ? { pendingUserText } : {}
|
|
12612
13066
|
};
|
|
13067
|
+
const breakdown = estimateAgentContextBreakdown(estimateInput);
|
|
13068
|
+
const estimatedTokens = estimateAgentContextTokens(estimateInput);
|
|
13069
|
+
const reconciledTokens = reconciledAnchoredTokens(agentRuntime, breakdown.pendingUserTokens);
|
|
12613
13070
|
return {
|
|
12614
|
-
|
|
13071
|
+
// The estimate is a floor, not a competing verdict: it prices material
|
|
13072
|
+
// the attested call never saw, so a provider count below it would be
|
|
13073
|
+
// answering about a smaller conversation.
|
|
13074
|
+
tokens: Math.max(estimatedTokens, reconciledTokens ?? 0),
|
|
13075
|
+
estimatedTokens,
|
|
13076
|
+
reconciledTokens,
|
|
12615
13077
|
contextWindow,
|
|
12616
|
-
breakdown
|
|
13078
|
+
breakdown
|
|
13079
|
+
};
|
|
13080
|
+
};
|
|
13081
|
+
const carryReconciledAnchorThroughProjection = (agentRuntime, tokensRemoved) => {
|
|
13082
|
+
if (!reconciledAnchor) return;
|
|
13083
|
+
reconciledAnchor = {
|
|
13084
|
+
tokens: Math.max(0, reconciledAnchor.tokens - Math.max(0, tokensRemoved)),
|
|
13085
|
+
anchoredMessageCount: agentRuntime.agent.state.messages.length
|
|
12617
13086
|
};
|
|
12618
13087
|
};
|
|
12619
13088
|
const refreshAgentMessagesFromSession = (agentRuntime) => {
|
|
@@ -12627,7 +13096,7 @@ function createTurnContext(deps) {
|
|
|
12627
13096
|
const emitCompactionActivity = (status, message) => {
|
|
12628
13097
|
deps.bus?.emit(BusChannels.ContextActivity, {
|
|
12629
13098
|
kind: "compaction",
|
|
12630
|
-
phase: "done",
|
|
13099
|
+
phase: status === "completed" ? "done" : "compact",
|
|
12631
13100
|
status,
|
|
12632
13101
|
message,
|
|
12633
13102
|
at: Date.now()
|
|
@@ -12694,6 +13163,7 @@ function createTurnContext(deps) {
|
|
|
12694
13163
|
emitCompactionActivity("started", "compacting context (mask stage)");
|
|
12695
13164
|
deps.session.replaceEntries(masked.entries);
|
|
12696
13165
|
refreshAgentMessagesFromSession(agentRuntime);
|
|
13166
|
+
reconciledAnchor = null;
|
|
12697
13167
|
deps.bus?.emit(BusChannels.CompactionEnd, { trigger, at: Date.now() });
|
|
12698
13168
|
const postMaskSnapshot = captureRuntimeContextSnapshot(
|
|
12699
13169
|
agentRuntime,
|
|
@@ -12772,6 +13242,7 @@ function createTurnContext(deps) {
|
|
|
12772
13242
|
});
|
|
12773
13243
|
noteColdReason("working_set_evict");
|
|
12774
13244
|
refreshAgentMessagesFromSession(agentRuntime);
|
|
13245
|
+
carryReconciledAnchorThroughProjection(agentRuntime, planned.tokensBefore - planned.tokensAfter);
|
|
12775
13246
|
const postEvictionSnapshot = captureRuntimeContextSnapshot(
|
|
12776
13247
|
agentRuntime,
|
|
12777
13248
|
state.activeUserTurnId || "compaction",
|
|
@@ -12847,6 +13318,7 @@ function createTurnContext(deps) {
|
|
|
12847
13318
|
deps.bus?.emit(BusChannels.CompactionEnd, { trigger, at: Date.now() });
|
|
12848
13319
|
recordCompactionUsage(agentRuntime, result);
|
|
12849
13320
|
refreshAgentMessagesFromSession(agentRuntime);
|
|
13321
|
+
reconciledAnchor = null;
|
|
12850
13322
|
const postCompactSnapshot = captureRuntimeContextSnapshot(
|
|
12851
13323
|
agentRuntime,
|
|
12852
13324
|
state.activeUserTurnId || "compaction",
|
|
@@ -12899,6 +13371,7 @@ function createTurnContext(deps) {
|
|
|
12899
13371
|
captureRuntimeContextSnapshot,
|
|
12900
13372
|
persistContextSnapshot,
|
|
12901
13373
|
liveContextEstimate,
|
|
13374
|
+
rememberedLoadedContextWindow,
|
|
12902
13375
|
refreshAgentMessagesFromSession,
|
|
12903
13376
|
runAutoCompact,
|
|
12904
13377
|
setCurrentSnapshot(snapshot) {
|
|
@@ -12909,6 +13382,14 @@ function createTurnContext(deps) {
|
|
|
12909
13382
|
persistContextSnapshot(currentContextSnapshot);
|
|
12910
13383
|
},
|
|
12911
13384
|
reconcileUsage(usage) {
|
|
13385
|
+
const promptTokens = (usage.input || 0) + (usage.cacheRead || 0) + (usage.cacheWrite || 0);
|
|
13386
|
+
const messages = state.runtime?.agent.state.messages;
|
|
13387
|
+
if (promptTokens > 0 && messages) {
|
|
13388
|
+
reconciledAnchor = {
|
|
13389
|
+
tokens: promptTokens + (usage.output || 0),
|
|
13390
|
+
anchoredMessageCount: messages.length
|
|
13391
|
+
};
|
|
13392
|
+
}
|
|
12912
13393
|
if (!currentContextSnapshot) return;
|
|
12913
13394
|
currentContextSnapshot = reconcileSnapshot(currentContextSnapshot, usage);
|
|
12914
13395
|
snapshotPersistPending = true;
|
|
@@ -12936,7 +13417,10 @@ function createTurnContext(deps) {
|
|
|
12936
13417
|
return sessionPrompt;
|
|
12937
13418
|
}
|
|
12938
13419
|
const modelState = agentRuntime.agent.state.model;
|
|
12939
|
-
const
|
|
13420
|
+
const windowDetails = agentRuntime.runtimeResolution.contextWindowDetails;
|
|
13421
|
+
const resolvedWindow = windowDetails.effectiveContextWindow;
|
|
13422
|
+
const contextWindow = typeof resolvedWindow === "number" && resolvedWindow > 0 ? resolvedWindow : null;
|
|
13423
|
+
const contextWindowSource = contextWindow === null ? null : windowDetails.contextWindowSource;
|
|
12940
13424
|
const guidance = modelState?.clio?.quirks?.thinking?.guidance;
|
|
12941
13425
|
const toolNames = toolNamesFromAgentState(agentRuntime.agent.state.tools);
|
|
12942
13426
|
const toolPromptHints = toolNames.flatMap((name) => {
|
|
@@ -12969,16 +13453,19 @@ function createTurnContext(deps) {
|
|
|
12969
13453
|
cwd: process.cwd(),
|
|
12970
13454
|
workingContextPaths: [...sessionWorkingContextPaths]
|
|
12971
13455
|
});
|
|
12972
|
-
const previousHash =
|
|
13456
|
+
const previousHash = sessionPromptHash ?? lastRecordedPromptHash();
|
|
12973
13457
|
const changed = agentRuntime.agent.state.systemPrompt !== result.systemPrompt;
|
|
12974
13458
|
if (changed) {
|
|
12975
13459
|
agentRuntime.agent.state.systemPrompt = result.systemPrompt;
|
|
12976
13460
|
pendingPromptLogEntry = {
|
|
13461
|
+
version: PROMPT_MANIFEST_VERSION,
|
|
12977
13462
|
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12978
13463
|
previousHash,
|
|
12979
13464
|
systemPromptHash: result.systemPromptHash,
|
|
12980
13465
|
tokenEstimate: result.tokenEstimate,
|
|
12981
13466
|
thinkingLevel: agentRuntime.agent.state.thinkingLevel ?? null,
|
|
13467
|
+
contextWindow,
|
|
13468
|
+
contextWindowSource,
|
|
12982
13469
|
projectPreload: result.projectPreload ?? null,
|
|
12983
13470
|
sections: result.sections.map((s) => ({ id: s.id, tokenEstimate: s.tokenEstimate })),
|
|
12984
13471
|
fragments: result.fragmentManifest.map((f) => ({
|
|
@@ -12991,6 +13478,7 @@ function createTurnContext(deps) {
|
|
|
12991
13478
|
}
|
|
12992
13479
|
lastSystemPromptReused = !changed;
|
|
12993
13480
|
sessionPrompt = result;
|
|
13481
|
+
sessionPromptHash = result.systemPromptHash;
|
|
12994
13482
|
sessionPromptKey = key;
|
|
12995
13483
|
return result;
|
|
12996
13484
|
} catch (err) {
|
|
@@ -13022,6 +13510,9 @@ function createTurnContext(deps) {
|
|
|
13022
13510
|
tokenEstimate: entry.tokenEstimate
|
|
13023
13511
|
}
|
|
13024
13512
|
});
|
|
13513
|
+
if (entry.previousHash !== null && entry.previousHash !== entry.systemPromptHash) {
|
|
13514
|
+
noteColdReason("prompt_recompiled");
|
|
13515
|
+
}
|
|
13025
13516
|
} catch {
|
|
13026
13517
|
}
|
|
13027
13518
|
appendPromptCompileRecord(currentMeta, entry);
|
|
@@ -13092,7 +13583,8 @@ function createTurnContext(deps) {
|
|
|
13092
13583
|
toolCount: liveToolCount,
|
|
13093
13584
|
compactionThreshold,
|
|
13094
13585
|
compactionAuto,
|
|
13095
|
-
promptCache: lastPromptCache
|
|
13586
|
+
promptCache: lastPromptCache,
|
|
13587
|
+
prewarm: lastPrewarm
|
|
13096
13588
|
});
|
|
13097
13589
|
}
|
|
13098
13590
|
const streamingOutput = liveStreamingOutputTokens();
|
|
@@ -13122,7 +13614,8 @@ function createTurnContext(deps) {
|
|
|
13122
13614
|
liveTotalTokens: totalUsed > 0 ? totalUsed : null,
|
|
13123
13615
|
measured,
|
|
13124
13616
|
lastCompaction: lastCompactionEvent,
|
|
13125
|
-
promptCache: lastPromptCache
|
|
13617
|
+
promptCache: lastPromptCache,
|
|
13618
|
+
prewarm: lastPrewarm
|
|
13126
13619
|
});
|
|
13127
13620
|
},
|
|
13128
13621
|
emitContextWindowWarningTransition(warning) {
|
|
@@ -13130,6 +13623,7 @@ function createTurnContext(deps) {
|
|
|
13130
13623
|
lastContextWindowWarning = warning;
|
|
13131
13624
|
deps.bus?.emit(BusChannels.ContextWarning, { warning });
|
|
13132
13625
|
},
|
|
13626
|
+
noteColdReason,
|
|
13133
13627
|
consumeExpectedColdReasons(runtimeId) {
|
|
13134
13628
|
runExpectedColdReasons = [];
|
|
13135
13629
|
nextAssistantColdReasons = [];
|
|
@@ -13143,7 +13637,7 @@ function createTurnContext(deps) {
|
|
|
13143
13637
|
}
|
|
13144
13638
|
}
|
|
13145
13639
|
},
|
|
13146
|
-
promptCachePayloadForAssistant(usage) {
|
|
13640
|
+
promptCachePayloadForAssistant(usage, backend) {
|
|
13147
13641
|
const input = typeof usage.input === "number" ? usage.input : 0;
|
|
13148
13642
|
const cacheRead = typeof usage.cacheRead === "number" ? usage.cacheRead : 0;
|
|
13149
13643
|
const cacheWrite = typeof usage.cacheWrite === "number" ? usage.cacheWrite : 0;
|
|
@@ -13151,34 +13645,54 @@ function createTurnContext(deps) {
|
|
|
13151
13645
|
input,
|
|
13152
13646
|
cacheRead,
|
|
13153
13647
|
cacheWrite,
|
|
13154
|
-
backendVerdict: backendCacheVerdict(input, cacheRead)
|
|
13648
|
+
backendVerdict: backendCacheVerdict(input, cacheRead, backend)
|
|
13155
13649
|
};
|
|
13650
|
+
if (backend !== void 0) promptCache.backend = { ...backend };
|
|
13156
13651
|
if (nextAssistantColdReasons.length > 0) {
|
|
13157
13652
|
promptCache.expectedColdReasons = [...nextAssistantColdReasons];
|
|
13158
13653
|
nextAssistantColdReasons = [];
|
|
13159
13654
|
}
|
|
13160
13655
|
return promptCache;
|
|
13161
13656
|
},
|
|
13657
|
+
notePrewarm(prewarm) {
|
|
13658
|
+
lastPrewarm = prewarm;
|
|
13659
|
+
},
|
|
13162
13660
|
noteRunCacheSummary(messages, runFirstCallVerdict) {
|
|
13661
|
+
lastPrewarm = null;
|
|
13163
13662
|
const cacheSummary = sumRunUsage(messages);
|
|
13164
13663
|
if (cacheSummary.hadUsage) {
|
|
13664
|
+
let lastBackend = null;
|
|
13665
|
+
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
13666
|
+
const message = messages[index];
|
|
13667
|
+
if (message?.role !== "assistant") continue;
|
|
13668
|
+
lastBackend = message.backendTimings ?? null;
|
|
13669
|
+
break;
|
|
13670
|
+
}
|
|
13165
13671
|
lastPromptCache = {
|
|
13166
13672
|
shellReused: lastSystemPromptReused,
|
|
13167
13673
|
cacheReadTokens: cacheSummary.cacheRead > 0 || cacheSummary.cacheWrite > 0 ? cacheSummary.cacheRead : null,
|
|
13168
13674
|
cacheWriteTokens: cacheSummary.cacheRead > 0 || cacheSummary.cacheWrite > 0 ? cacheSummary.cacheWrite : null,
|
|
13169
13675
|
uncachedInputTokens: cacheSummary.input,
|
|
13676
|
+
backend: lastBackend,
|
|
13677
|
+
uncachedPrefillTokens: uncachedPrefillTokens(lastBackend),
|
|
13170
13678
|
backendVerdict: runFirstCallVerdict,
|
|
13171
13679
|
...runExpectedColdReasons.length > 0 ? { expectedColdReasons: [...runExpectedColdReasons] } : {}
|
|
13172
13680
|
};
|
|
13173
13681
|
}
|
|
13174
13682
|
},
|
|
13175
13683
|
resetForSession() {
|
|
13684
|
+
if (sessionPromptHash !== null) noteColdReason("prompt_recompiled");
|
|
13176
13685
|
lastPromptCache = null;
|
|
13686
|
+
lastPrewarm = null;
|
|
13177
13687
|
lastSystemPromptReused = false;
|
|
13688
|
+
sessionPromptHash = null;
|
|
13178
13689
|
sessionPromptKey = null;
|
|
13690
|
+
resumedPromptHashRead = false;
|
|
13691
|
+
resumedPromptHash = null;
|
|
13179
13692
|
sessionWorkingContextPaths.clear();
|
|
13180
13693
|
pendingPromptLogEntry = null;
|
|
13181
13694
|
emptyAutoCompactTurnId = null;
|
|
13695
|
+
reconciledAnchor = null;
|
|
13182
13696
|
const session = deps.session?.current();
|
|
13183
13697
|
currentContextSnapshot = session ? getLatestContextSnapshot(session) : null;
|
|
13184
13698
|
},
|
|
@@ -13475,7 +13989,8 @@ function createTurnPersistence(deps) {
|
|
|
13475
13989
|
if (timing) payload.timing = timing;
|
|
13476
13990
|
const usage = message.usage;
|
|
13477
13991
|
if (usage && typeof usage === "object") {
|
|
13478
|
-
|
|
13992
|
+
const backendTimings = message.backendTimings;
|
|
13993
|
+
payload.promptCache = deps.promptCachePayloadForAssistant(usage, backendTimings);
|
|
13479
13994
|
}
|
|
13480
13995
|
const interruptedUsage = estimatedUsageForInterruptedTurn(message, deps.promptSideTokens());
|
|
13481
13996
|
if (interruptedUsage !== null) payload.usage = interruptedUsage;
|
|
@@ -13516,8 +14031,8 @@ function createTurnPersistence(deps) {
|
|
|
13516
14031
|
appendAssistantTurn,
|
|
13517
14032
|
appendQueuedUserTurn(message) {
|
|
13518
14033
|
if (message?.role !== "user") return;
|
|
13519
|
-
const text = extractUserText(message)
|
|
13520
|
-
if (text.length === 0) return;
|
|
14034
|
+
const text = extractUserText(message);
|
|
14035
|
+
if (text.trim().length === 0) return;
|
|
13521
14036
|
if (deps.consumePersistedEcho(text)) return;
|
|
13522
14037
|
deps.removeQueuedMirrorEntry(text);
|
|
13523
14038
|
if (!deps.session) return;
|
|
@@ -13678,6 +14193,266 @@ function createTurnPersistence(deps) {
|
|
|
13678
14193
|
};
|
|
13679
14194
|
}
|
|
13680
14195
|
|
|
14196
|
+
// src/interactive/turn-prewarm.ts
|
|
14197
|
+
init_esm_shims();
|
|
14198
|
+
|
|
14199
|
+
// src/interactive/prewarm.ts
|
|
14200
|
+
init_esm_shims();
|
|
14201
|
+
var PREWARM_USER_TEXT = ".";
|
|
14202
|
+
var PREWARM_MAX_TOKENS = 1;
|
|
14203
|
+
var LLM_MESSAGE_ROLES = /* @__PURE__ */ new Set(["user", "assistant", "toolResult"]);
|
|
14204
|
+
function prewarmPrefix(state) {
|
|
14205
|
+
return {
|
|
14206
|
+
systemPrompt: state.systemPrompt,
|
|
14207
|
+
messages: state.messages.filter((message) => LLM_MESSAGE_ROLES.has(message.role ?? "")),
|
|
14208
|
+
tools: [...state.tools]
|
|
14209
|
+
};
|
|
14210
|
+
}
|
|
14211
|
+
function usageOf(message) {
|
|
14212
|
+
if (message === null || typeof message !== "object") return null;
|
|
14213
|
+
const usage = message.usage;
|
|
14214
|
+
return usage !== null && typeof usage === "object" ? usage : null;
|
|
14215
|
+
}
|
|
14216
|
+
function backendOf(message) {
|
|
14217
|
+
if (message === null || typeof message !== "object") return null;
|
|
14218
|
+
const backend = message.backendTimings;
|
|
14219
|
+
return backend !== null && typeof backend === "object" ? backend : null;
|
|
14220
|
+
}
|
|
14221
|
+
function prewarmPromptTokens(result) {
|
|
14222
|
+
if (result.backend) return result.backend.promptTokens;
|
|
14223
|
+
const usage = result.usage;
|
|
14224
|
+
if (!usage) return null;
|
|
14225
|
+
const total = (usage.input || 0) + (usage.cacheRead || 0) + (usage.cacheWrite || 0);
|
|
14226
|
+
return total > 0 ? total : null;
|
|
14227
|
+
}
|
|
14228
|
+
async function runPrewarmRound(input) {
|
|
14229
|
+
const prefix = prewarmPrefix(input.state);
|
|
14230
|
+
const context = {
|
|
14231
|
+
systemPrompt: prefix.systemPrompt,
|
|
14232
|
+
messages: [
|
|
14233
|
+
...prefix.messages,
|
|
14234
|
+
{ role: "user", content: [{ type: "text", text: PREWARM_USER_TEXT }], timestamp: Date.now() }
|
|
14235
|
+
],
|
|
14236
|
+
tools: prefix.tools
|
|
14237
|
+
};
|
|
14238
|
+
const options = { maxTokens: PREWARM_MAX_TOKENS };
|
|
14239
|
+
if (input.state.thinkingLevel !== "off") options.reasoning = input.state.thinkingLevel;
|
|
14240
|
+
if (input.apiKey !== void 0) options.apiKey = input.apiKey;
|
|
14241
|
+
if (input.signal !== void 0) options.signal = input.signal;
|
|
14242
|
+
const send = input.streamFn ?? streamSimple;
|
|
14243
|
+
const startedAt = performance.now();
|
|
14244
|
+
let firstDeltaAt = null;
|
|
14245
|
+
const elapsed = () => Math.round(Math.max(0, performance.now() - startedAt));
|
|
14246
|
+
const ttft = () => firstDeltaAt === null ? null : Math.round(Math.max(0, firstDeltaAt - startedAt));
|
|
14247
|
+
try {
|
|
14248
|
+
const events = send(
|
|
14249
|
+
input.model,
|
|
14250
|
+
context,
|
|
14251
|
+
options
|
|
14252
|
+
);
|
|
14253
|
+
for await (const event of events) {
|
|
14254
|
+
if (firstDeltaAt === null && event.type !== "start") firstDeltaAt = performance.now();
|
|
14255
|
+
if (event.type === "done") {
|
|
14256
|
+
return {
|
|
14257
|
+
aborted: false,
|
|
14258
|
+
usage: usageOf(event.message),
|
|
14259
|
+
backend: backendOf(event.message),
|
|
14260
|
+
timing: { ttftMs: ttft(), apiMs: elapsed() },
|
|
14261
|
+
errorMessage: null
|
|
14262
|
+
};
|
|
14263
|
+
}
|
|
14264
|
+
if (event.type === "error") {
|
|
14265
|
+
const failed = event.error;
|
|
14266
|
+
const aborted = event.reason === "aborted" || failed.stopReason === "aborted" || input.signal?.aborted === true;
|
|
14267
|
+
return {
|
|
14268
|
+
aborted,
|
|
14269
|
+
usage: usageOf(event.error),
|
|
14270
|
+
backend: backendOf(event.error),
|
|
14271
|
+
timing: { ttftMs: ttft(), apiMs: elapsed() },
|
|
14272
|
+
errorMessage: aborted ? null : typeof failed.errorMessage === "string" ? failed.errorMessage : "pre-warm failed"
|
|
14273
|
+
};
|
|
14274
|
+
}
|
|
14275
|
+
}
|
|
14276
|
+
} catch (error) {
|
|
14277
|
+
return {
|
|
14278
|
+
aborted: input.signal?.aborted === true,
|
|
14279
|
+
usage: null,
|
|
14280
|
+
backend: null,
|
|
14281
|
+
timing: { ttftMs: ttft(), apiMs: elapsed() },
|
|
14282
|
+
errorMessage: input.signal?.aborted === true ? null : error instanceof Error ? error.message : String(error)
|
|
14283
|
+
};
|
|
14284
|
+
}
|
|
14285
|
+
return {
|
|
14286
|
+
aborted: input.signal?.aborted === true,
|
|
14287
|
+
usage: null,
|
|
14288
|
+
backend: null,
|
|
14289
|
+
timing: { ttftMs: ttft(), apiMs: elapsed() },
|
|
14290
|
+
errorMessage: null
|
|
14291
|
+
};
|
|
14292
|
+
}
|
|
14293
|
+
|
|
14294
|
+
// src/interactive/turn-prewarm.ts
|
|
14295
|
+
var ABORT_ROUND_ON_SUBMIT = false;
|
|
14296
|
+
function createTurnPrewarm(deps) {
|
|
14297
|
+
const round = deps.runPrewarm ?? runPrewarmRound;
|
|
14298
|
+
const abortOnSubmit = deps.abortRoundOnSubmit ?? ABORT_ROUND_ON_SUBMIT;
|
|
14299
|
+
let pendingTrigger = null;
|
|
14300
|
+
let timer = null;
|
|
14301
|
+
let active = null;
|
|
14302
|
+
const detached = /* @__PURE__ */ new WeakSet();
|
|
14303
|
+
let inFlight = Promise.resolve(null);
|
|
14304
|
+
let dispatchesInFlight = 0;
|
|
14305
|
+
const unsubscribeDispatch = [
|
|
14306
|
+
deps.bus?.on(BusChannels.DispatchStarted, () => {
|
|
14307
|
+
dispatchesInFlight += 1;
|
|
14308
|
+
}) ?? null,
|
|
14309
|
+
...[BusChannels.DispatchCompleted, BusChannels.DispatchFailed].map(
|
|
14310
|
+
(channel) => deps.bus?.on(channel, () => {
|
|
14311
|
+
dispatchesInFlight = Math.max(0, dispatchesInFlight - 1);
|
|
14312
|
+
}) ?? null
|
|
14313
|
+
)
|
|
14314
|
+
];
|
|
14315
|
+
const dispatchActive = () => dispatchesInFlight > 0 || deps.hasActiveDispatch();
|
|
14316
|
+
const admissionRefusal = () => {
|
|
14317
|
+
if (deps.getSettings().prewarm?.enabled === false) return "disabled";
|
|
14318
|
+
if (!deps.isLatencySurface()) return "surface";
|
|
14319
|
+
if (deps.state.streaming || deps.isTurnActive()) return "turn-active";
|
|
14320
|
+
if (dispatchActive()) return "dispatch-active";
|
|
14321
|
+
const targetId = deps.getSettings().orchestrator?.target?.trim();
|
|
14322
|
+
const runtimeId = targetId ? deps.providers.getTarget(targetId)?.runtime : void 0;
|
|
14323
|
+
if (runtimeId === void 0 || deps.providers.getRuntime(runtimeId)?.tier !== "local-native") return "tier";
|
|
14324
|
+
return null;
|
|
14325
|
+
};
|
|
14326
|
+
const runOnce = async (trigger, controller) => {
|
|
14327
|
+
const refusal2 = admissionRefusal();
|
|
14328
|
+
if (refusal2) return { ran: false, reason: refusal2 };
|
|
14329
|
+
const prepared = await deps.prepareRuntime(controller.signal);
|
|
14330
|
+
if (!prepared.ok) return { ran: false, reason: "unresolved" };
|
|
14331
|
+
const runtime = prepared.runtime;
|
|
14332
|
+
if (deps.providers.getRuntime(runtime.runtimeId)?.tier !== "local-native") {
|
|
14333
|
+
return { ran: false, reason: "tier" };
|
|
14334
|
+
}
|
|
14335
|
+
deps.applySessionTools(runtime);
|
|
14336
|
+
await deps.context.ensureSessionPrompt(runtime);
|
|
14337
|
+
const lateRefusal = admissionRefusal();
|
|
14338
|
+
if (lateRefusal) return { ran: false, reason: lateRefusal };
|
|
14339
|
+
if (detached.has(controller) || controller.signal.aborted) return { ran: false, reason: "superseded" };
|
|
14340
|
+
const releaseEndpointSlot = deps.registerEndpointSlot?.(runtime) ?? null;
|
|
14341
|
+
let result;
|
|
14342
|
+
try {
|
|
14343
|
+
result = await round({
|
|
14344
|
+
model: runtime.agent.state.model,
|
|
14345
|
+
state: {
|
|
14346
|
+
systemPrompt: runtime.agent.state.systemPrompt,
|
|
14347
|
+
messages: runtime.agent.state.messages,
|
|
14348
|
+
tools: runtime.agent.state.tools,
|
|
14349
|
+
thinkingLevel: runtime.agent.state.thinkingLevel ?? "off"
|
|
14350
|
+
},
|
|
14351
|
+
...prepared.apiKey !== void 0 ? { apiKey: prepared.apiKey } : {},
|
|
14352
|
+
signal: controller.signal
|
|
14353
|
+
});
|
|
14354
|
+
} finally {
|
|
14355
|
+
releaseEndpointSlot?.();
|
|
14356
|
+
}
|
|
14357
|
+
const wasDetached = detached.has(controller) || controller.signal.aborted;
|
|
14358
|
+
const promptTokens = prewarmPromptTokens(result);
|
|
14359
|
+
if (!wasDetached) {
|
|
14360
|
+
deps.context.notePrewarm({
|
|
14361
|
+
tokens: promptTokens,
|
|
14362
|
+
ms: result.timing.apiMs,
|
|
14363
|
+
aborted: result.aborted
|
|
14364
|
+
});
|
|
14365
|
+
}
|
|
14366
|
+
deps.recordUsage(runtime, result.usage);
|
|
14367
|
+
try {
|
|
14368
|
+
deps.session?.appendEntry({
|
|
14369
|
+
kind: "custom",
|
|
14370
|
+
customType: "prewarm",
|
|
14371
|
+
// Never a model message and never a rendered transcript block: a
|
|
14372
|
+
// pre-warm is a fact about the backend, not something the session said.
|
|
14373
|
+
display: false,
|
|
14374
|
+
parentTurnId: deps.state.lastTurnId,
|
|
14375
|
+
data: {
|
|
14376
|
+
trigger,
|
|
14377
|
+
target: runtime.targetId,
|
|
14378
|
+
model: runtime.wireModelId,
|
|
14379
|
+
promptTokens,
|
|
14380
|
+
aborted: result.aborted,
|
|
14381
|
+
detached: wasDetached,
|
|
14382
|
+
timing: result.timing,
|
|
14383
|
+
promptCache: {
|
|
14384
|
+
input: result.usage?.input ?? 0,
|
|
14385
|
+
cacheRead: result.usage?.cacheRead ?? 0,
|
|
14386
|
+
cacheWrite: result.usage?.cacheWrite ?? 0,
|
|
14387
|
+
...result.backend ? { backend: { ...result.backend } } : {}
|
|
14388
|
+
},
|
|
14389
|
+
...result.errorMessage ? { error: result.errorMessage } : {}
|
|
14390
|
+
}
|
|
14391
|
+
});
|
|
14392
|
+
} catch {
|
|
14393
|
+
}
|
|
14394
|
+
return { ran: true, trigger };
|
|
14395
|
+
};
|
|
14396
|
+
const releaseActiveRound = () => {
|
|
14397
|
+
const controller = active;
|
|
14398
|
+
if (controller === null) return;
|
|
14399
|
+
detached.add(controller);
|
|
14400
|
+
if (abortOnSubmit) controller.abort();
|
|
14401
|
+
active = null;
|
|
14402
|
+
};
|
|
14403
|
+
const fire = () => {
|
|
14404
|
+
timer = null;
|
|
14405
|
+
const trigger = pendingTrigger;
|
|
14406
|
+
pendingTrigger = null;
|
|
14407
|
+
if (trigger === null) return;
|
|
14408
|
+
const controller = new AbortController();
|
|
14409
|
+
active = controller;
|
|
14410
|
+
const previous = inFlight;
|
|
14411
|
+
inFlight = previous.catch(() => null).then(() => runOnce(trigger, controller)).catch(() => null).finally(() => {
|
|
14412
|
+
if (active === controller) active = null;
|
|
14413
|
+
});
|
|
14414
|
+
};
|
|
14415
|
+
return {
|
|
14416
|
+
schedule(trigger) {
|
|
14417
|
+
releaseActiveRound();
|
|
14418
|
+
pendingTrigger = trigger;
|
|
14419
|
+
if (timer !== null) return;
|
|
14420
|
+
timer = setTimeout(fire, 0);
|
|
14421
|
+
},
|
|
14422
|
+
cancel() {
|
|
14423
|
+
pendingTrigger = null;
|
|
14424
|
+
if (timer !== null) {
|
|
14425
|
+
clearTimeout(timer);
|
|
14426
|
+
timer = null;
|
|
14427
|
+
}
|
|
14428
|
+
releaseActiveRound();
|
|
14429
|
+
},
|
|
14430
|
+
settled() {
|
|
14431
|
+
return new Promise((resolve7) => {
|
|
14432
|
+
setTimeout(() => {
|
|
14433
|
+
resolve7(inFlight.catch(() => null));
|
|
14434
|
+
}, 0);
|
|
14435
|
+
});
|
|
14436
|
+
},
|
|
14437
|
+
dispose() {
|
|
14438
|
+
for (const unsubscribe of unsubscribeDispatch) unsubscribe?.();
|
|
14439
|
+
pendingTrigger = null;
|
|
14440
|
+
if (timer !== null) {
|
|
14441
|
+
clearTimeout(timer);
|
|
14442
|
+
timer = null;
|
|
14443
|
+
}
|
|
14444
|
+
active?.abort();
|
|
14445
|
+
active = null;
|
|
14446
|
+
}
|
|
14447
|
+
};
|
|
14448
|
+
}
|
|
14449
|
+
function subscribePrewarmToCompaction(bus, prewarm) {
|
|
14450
|
+
const unsubscribe = bus?.on(BusChannels.CompactionEnd, () => {
|
|
14451
|
+
prewarm.schedule("compaction");
|
|
14452
|
+
});
|
|
14453
|
+
return () => unsubscribe?.();
|
|
14454
|
+
}
|
|
14455
|
+
|
|
13681
14456
|
// src/interactive/turn-queues.ts
|
|
13682
14457
|
init_esm_shims();
|
|
13683
14458
|
var DEFAULT_STEERING_MODE = "next-slot";
|
|
@@ -13689,14 +14464,13 @@ function createTurnQueues(deps) {
|
|
|
13689
14464
|
deps.emitQueueUpdateEvent(queuedMirror.map((entry) => ({ ...entry })));
|
|
13690
14465
|
};
|
|
13691
14466
|
const enqueue = (text, kind) => {
|
|
13692
|
-
|
|
13693
|
-
if (trimmed.length === 0 || !state.streaming || !state.runtime) return false;
|
|
14467
|
+
if (text.trim().length === 0 || !state.streaming || !state.runtime) return false;
|
|
13694
14468
|
const message = {
|
|
13695
14469
|
role: "user",
|
|
13696
|
-
content:
|
|
14470
|
+
content: text,
|
|
13697
14471
|
timestamp: Date.now()
|
|
13698
14472
|
};
|
|
13699
|
-
queuedMirror.push({ text
|
|
14473
|
+
queuedMirror.push({ text, kind });
|
|
13700
14474
|
if (kind === "steer") {
|
|
13701
14475
|
state.runtime.agent.steer(message);
|
|
13702
14476
|
} else {
|
|
@@ -14090,7 +14864,11 @@ function createTurnRuntime(deps) {
|
|
|
14090
14864
|
requestedThinkingLevel: settings.orchestrator.thinkingLevel ?? "off",
|
|
14091
14865
|
use: "orchestrator",
|
|
14092
14866
|
requireTools: false,
|
|
14093
|
-
requireOutputBudget: true
|
|
14867
|
+
requireOutputBudget: true,
|
|
14868
|
+
// A resumed session already knows what this backend had open; without
|
|
14869
|
+
// it the first turn budgets against the probed server-wide figure and
|
|
14870
|
+
// corrects only once discovery reports a loaded window (issue #227).
|
|
14871
|
+
knownLoadedContextWindow: context.rememberedLoadedContextWindow(targetId, wireModelId)
|
|
14094
14872
|
});
|
|
14095
14873
|
if (!resolved.ok) {
|
|
14096
14874
|
const failure = resolved.diagnostics.find((entry) => entry.severity === "error") ?? resolved.diagnostics[0];
|
|
@@ -14180,7 +14958,8 @@ function createTurnRuntime(deps) {
|
|
|
14180
14958
|
requestedThinkingLevel: deps.getSettings().orchestrator.thinkingLevel ?? "off",
|
|
14181
14959
|
use: "orchestrator",
|
|
14182
14960
|
requireTools: false,
|
|
14183
|
-
requireOutputBudget: true
|
|
14961
|
+
requireOutputBudget: true,
|
|
14962
|
+
knownLoadedContextWindow: context.rememberedLoadedContextWindow(target.target.id, target.wireModelId)
|
|
14184
14963
|
});
|
|
14185
14964
|
if (!refreshed.ok) return;
|
|
14186
14965
|
const liveModel = state.runtime.agent.state.model;
|
|
@@ -14541,7 +15320,8 @@ function createTurnRuntime(deps) {
|
|
|
14541
15320
|
if (isAssistant && usage && typeof usage === "object" && runFirstCallVerdict === null) {
|
|
14542
15321
|
const input = typeof usage.input === "number" ? usage.input : 0;
|
|
14543
15322
|
const cacheRead = typeof usage.cacheRead === "number" ? usage.cacheRead : 0;
|
|
14544
|
-
|
|
15323
|
+
const backendTimings = enrichedEvent.message.backendTimings;
|
|
15324
|
+
runFirstCallVerdict = backendCacheVerdict(input, cacheRead, backendTimings);
|
|
14545
15325
|
}
|
|
14546
15326
|
if (usage) {
|
|
14547
15327
|
context.reconcileUsage(usage);
|
|
@@ -14585,6 +15365,8 @@ function createTurnState(initialThinkingLevel) {
|
|
|
14585
15365
|
runtime: null,
|
|
14586
15366
|
lastTurnId: null,
|
|
14587
15367
|
streaming: false,
|
|
15368
|
+
turnPreparation: "idle",
|
|
15369
|
+
turnPreparationSince: 0,
|
|
14588
15370
|
currentThinkingLevel: initialThinkingLevel,
|
|
14589
15371
|
replayedContextMessages: [],
|
|
14590
15372
|
activeUserTurnId: null,
|
|
@@ -14702,6 +15484,31 @@ function createChatLoop(deps) {
|
|
|
14702
15484
|
const middlewareToolChoice = deps.middlewareToolChoice ?? createMiddlewareToolChoiceControl();
|
|
14703
15485
|
const state = createTurnState(deps.getSettings().orchestrator.thinkingLevel ?? "off");
|
|
14704
15486
|
const toolStartTimes = /* @__PURE__ */ new Map();
|
|
15487
|
+
const preparationListeners = /* @__PURE__ */ new Set();
|
|
15488
|
+
const setTurnPreparation = (phase) => {
|
|
15489
|
+
if (state.turnPreparation === phase) return;
|
|
15490
|
+
if (state.turnPreparation === "idle") state.turnPreparationSince = Date.now();
|
|
15491
|
+
if (phase === "idle") state.turnPreparationSince = 0;
|
|
15492
|
+
state.turnPreparation = phase;
|
|
15493
|
+
for (const listener of preparationListeners) {
|
|
15494
|
+
try {
|
|
15495
|
+
listener(phase);
|
|
15496
|
+
} catch {
|
|
15497
|
+
}
|
|
15498
|
+
}
|
|
15499
|
+
};
|
|
15500
|
+
let preparingSubmits = 0;
|
|
15501
|
+
const enterPreparation = () => {
|
|
15502
|
+
preparingSubmits += 1;
|
|
15503
|
+
if (state.turnPreparation === "idle") setTurnPreparation("preparing");
|
|
15504
|
+
};
|
|
15505
|
+
const leavePreparation = () => {
|
|
15506
|
+
preparingSubmits = Math.max(0, preparingSubmits - 1);
|
|
15507
|
+
if (preparingSubmits === 0) setTurnPreparation("idle");
|
|
15508
|
+
};
|
|
15509
|
+
const endPreparationCompaction = () => {
|
|
15510
|
+
setTurnPreparation(preparingSubmits > 0 ? "preparing" : "idle");
|
|
15511
|
+
};
|
|
14705
15512
|
const emit = (event) => {
|
|
14706
15513
|
for (const listener of listeners) {
|
|
14707
15514
|
listener(event);
|
|
@@ -14778,7 +15585,7 @@ function createChatLoop(deps) {
|
|
|
14778
15585
|
middlewareToolChoice,
|
|
14779
15586
|
consumePersistedEcho: (text) => queues.consumePersistedEcho(text),
|
|
14780
15587
|
removeQueuedMirrorEntry: (text) => queues.removeQueuedMirrorEntry(text),
|
|
14781
|
-
promptCachePayloadForAssistant: (usage) => context.promptCachePayloadForAssistant(usage),
|
|
15588
|
+
promptCachePayloadForAssistant: (usage, backend) => context.promptCachePayloadForAssistant(usage, backend),
|
|
14782
15589
|
promptSideTokens: () => context.promptSideTokens(),
|
|
14783
15590
|
observability: deps.observability
|
|
14784
15591
|
});
|
|
@@ -14849,6 +15656,16 @@ function createChatLoop(deps) {
|
|
|
14849
15656
|
return { ok: false, reason: err instanceof Error ? err.message : String(err) };
|
|
14850
15657
|
}
|
|
14851
15658
|
};
|
|
15659
|
+
const withEndpointSlot = async (runtime, round) => {
|
|
15660
|
+
const endpointKey = canonicalEndpointKey(runtime.runtimeResolution.target);
|
|
15661
|
+
const release = endpointKey === null ? () => {
|
|
15662
|
+
} : registerForegroundStream(endpointKey);
|
|
15663
|
+
try {
|
|
15664
|
+
return await round();
|
|
15665
|
+
} finally {
|
|
15666
|
+
release();
|
|
15667
|
+
}
|
|
15668
|
+
};
|
|
14852
15669
|
const writeOutOfTurnUsageRow = deps.recordOutOfTurnUsageRow ?? ((row2) => appendOutOfTurnUsageRow(clioStateDir(), row2));
|
|
14853
15670
|
const recordOutOfTurnUsage = (runtime, usage, label) => {
|
|
14854
15671
|
if (!usage) return;
|
|
@@ -14893,6 +15710,39 @@ function createChatLoop(deps) {
|
|
|
14893
15710
|
}
|
|
14894
15711
|
});
|
|
14895
15712
|
};
|
|
15713
|
+
let turnActive = false;
|
|
15714
|
+
const prewarm = createTurnPrewarm({
|
|
15715
|
+
state,
|
|
15716
|
+
getSettings: deps.getSettings,
|
|
15717
|
+
providers: deps.providers,
|
|
15718
|
+
context,
|
|
15719
|
+
bus: deps.bus,
|
|
15720
|
+
...deps.session ? { session: deps.session } : {},
|
|
15721
|
+
isLatencySurface: () => deps.isLatencySurface?.() !== false,
|
|
15722
|
+
isTurnActive: () => turnActive,
|
|
15723
|
+
hasActiveDispatch: () => (deps.hasActiveDispatch ?? deps.hasAttachedDispatch)?.() === true,
|
|
15724
|
+
prepareRuntime: async (signal) => {
|
|
15725
|
+
await turnRuntime.ensureLiveCapabilitiesForSelectedModel().catch(() => {
|
|
15726
|
+
});
|
|
15727
|
+
return prepareOutOfTurnRound("a turn is in flight", signal);
|
|
15728
|
+
},
|
|
15729
|
+
applySessionTools: (runtime) => {
|
|
15730
|
+
runtime.agent.state.tools = resolveSessionTools(
|
|
15731
|
+
runtime,
|
|
15732
|
+
deps.toolRegistry,
|
|
15733
|
+
currentToolInvokeOptions,
|
|
15734
|
+
turnRuntime.toolTelemetry
|
|
15735
|
+
);
|
|
15736
|
+
},
|
|
15737
|
+
recordUsage: (runtime, usage) => {
|
|
15738
|
+
recordOutOfTurnUsage(runtime, sideQuestionUsage(usage), "prewarm");
|
|
15739
|
+
},
|
|
15740
|
+
...deps.runPrewarm ? { runPrewarm: deps.runPrewarm } : {},
|
|
15741
|
+
...deps.abortPrewarmOnSubmit === void 0 ? {} : { abortRoundOnSubmit: deps.abortPrewarmOnSubmit },
|
|
15742
|
+
...deps.registerPrewarmEndpointSlot ? { registerEndpointSlot: deps.registerPrewarmEndpointSlot } : {}
|
|
15743
|
+
});
|
|
15744
|
+
const unsubscribePrewarmCompaction = subscribePrewarmToCompaction(deps.bus, prewarm);
|
|
15745
|
+
prewarm.schedule("session-start");
|
|
14896
15746
|
const api = {
|
|
14897
15747
|
steer: (text) => queues.steer(text),
|
|
14898
15748
|
queueFollowUp: (text) => queues.queueFollowUp(text),
|
|
@@ -14905,9 +15755,9 @@ function createChatLoop(deps) {
|
|
|
14905
15755
|
let mode = options.steering ?? DEFAULT_STEERING_MODE;
|
|
14906
15756
|
const trimmed = text.trim();
|
|
14907
15757
|
if (mode === "interrupt" && trimmed.length > 0) {
|
|
14908
|
-
const
|
|
14909
|
-
if (
|
|
14910
|
-
emitNotice(`[Clio Coder] interrupt refused: ${
|
|
15758
|
+
const refusal2 = interruptRefusalReason();
|
|
15759
|
+
if (refusal2 !== null) {
|
|
15760
|
+
emitNotice(`[Clio Coder] interrupt refused: ${refusal2}. Queued for the next slot instead.`, "warning");
|
|
14911
15761
|
mode = "next-slot";
|
|
14912
15762
|
} else {
|
|
14913
15763
|
const prior = priorSubmit;
|
|
@@ -14931,15 +15781,15 @@ function createChatLoop(deps) {
|
|
|
14931
15781
|
const hasImages = options.images !== void 0 && options.images.length > 0;
|
|
14932
15782
|
if (!hasImages && trimmed.length > 0 && state.runtime) {
|
|
14933
15783
|
if (isWorkerShareNote(trimmed)) state.turnSharedWorkerNote = true;
|
|
14934
|
-
if (mode === "end-of-turn") queues.queueFollowUp(
|
|
14935
|
-
else queues.steer(
|
|
15784
|
+
if (mode === "end-of-turn") queues.queueFollowUp(text);
|
|
15785
|
+
else queues.steer(text);
|
|
14936
15786
|
return;
|
|
14937
15787
|
}
|
|
14938
15788
|
emitNotice("[Clio Coder] response already in progress. Press Esc to cancel the active run.");
|
|
14939
15789
|
return;
|
|
14940
15790
|
}
|
|
14941
15791
|
}
|
|
14942
|
-
state.lastRunSnapshot
|
|
15792
|
+
const previousRunSnapshot = state.lastRunSnapshot;
|
|
14943
15793
|
let agentRuntime;
|
|
14944
15794
|
try {
|
|
14945
15795
|
await turnRuntime.ensureLiveCapabilitiesForSelectedModel();
|
|
@@ -14970,6 +15820,7 @@ function createChatLoop(deps) {
|
|
|
14970
15820
|
currentToolInvokeOptions,
|
|
14971
15821
|
turnRuntime.toolTelemetry
|
|
14972
15822
|
);
|
|
15823
|
+
const toolSignature = toolSignatureFromState(agentRuntime.agent.state.tools);
|
|
14973
15824
|
const askUserPolicy = createAskUserToolPolicy(agentRuntime.agent.state.tools);
|
|
14974
15825
|
middleware.fireTurnStart(agentRuntime, text, pendingSkillRequests.length, options.requestContinuation === true);
|
|
14975
15826
|
const reminderBlock = middleware.flushPendingReminders();
|
|
@@ -14984,9 +15835,12 @@ function createChatLoop(deps) {
|
|
|
14984
15835
|
const submittedText = [reminderBlock, skillPreamble, taskMemoryHandoffSource, text].filter((part) => part.length > 0).join("\n\n");
|
|
14985
15836
|
const forceNow = process.env.CLIO_CODER_FORCE_COMPACT === "1";
|
|
14986
15837
|
try {
|
|
15838
|
+
setTurnPreparation("compacting");
|
|
14987
15839
|
await context.runAutoCompact(agentRuntime, forceNow, void 0, void 0, submittedText);
|
|
14988
15840
|
} catch (err) {
|
|
14989
15841
|
emitNotice(`[Clio Coder] auto-compaction failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
15842
|
+
} finally {
|
|
15843
|
+
endPreparationCompaction();
|
|
14990
15844
|
}
|
|
14991
15845
|
const compiledPrompt = await context.ensureSessionPrompt(agentRuntime);
|
|
14992
15846
|
const compactionThreshold = deps.getSettings().compaction?.threshold ?? null;
|
|
@@ -14995,18 +15849,23 @@ function createChatLoop(deps) {
|
|
|
14995
15849
|
pendingUserInput: submittedText,
|
|
14996
15850
|
images,
|
|
14997
15851
|
promptHash: compiledPrompt?.systemPromptHash,
|
|
14998
|
-
toolSignature
|
|
15852
|
+
toolSignature
|
|
14999
15853
|
});
|
|
15000
15854
|
const reservedOutput = resolveReservedOutputTokens(agentRuntime.runtimeResolution.capabilityDecisions.maxTokens);
|
|
15001
15855
|
const effectiveWindow = agentRuntime.runtimeResolution.contextWindowDetails.effectiveContextWindow;
|
|
15002
15856
|
const pendingInputTokens = ceilChars(submittedText.length);
|
|
15003
15857
|
let turnSnapshot = captureTurnSnapshot("pending");
|
|
15004
|
-
const
|
|
15858
|
+
const budgetedPromptTokens = (snapshot) => Math.max(
|
|
15859
|
+
snapshotInputTokens(snapshot) + pendingInputTokens,
|
|
15860
|
+
context.liveContextEstimate(agentRuntime, submittedText).tokens
|
|
15861
|
+
);
|
|
15862
|
+
const totalEstimate = budgetedPromptTokens(turnSnapshot) + reservedOutput;
|
|
15005
15863
|
if (effectiveWindow > 0 && totalEstimate > effectiveWindow) {
|
|
15006
15864
|
emitNotice(
|
|
15007
|
-
`[Clio Coder] Estimated request size ${totalEstimate} tokens (input ${
|
|
15865
|
+
`[Clio Coder] Estimated request size ${totalEstimate} tokens (input ${totalEstimate - reservedOutput} + output budget ${reservedOutput}) exceeds the effective context window of ${effectiveWindow} tokens. Running compaction before sending...`
|
|
15008
15866
|
);
|
|
15009
|
-
|
|
15867
|
+
setTurnPreparation("compacting");
|
|
15868
|
+
const compacted = await context.runAutoCompact(agentRuntime, true, void 0, void 0, submittedText).finally(endPreparationCompaction);
|
|
15010
15869
|
if (!compacted) {
|
|
15011
15870
|
emitNotice(
|
|
15012
15871
|
"[Clio Coder] Compaction could not reclaim enough space. Request blocked; trim the prompt, reduce active tools, or start a fresh session."
|
|
@@ -15015,7 +15874,7 @@ function createChatLoop(deps) {
|
|
|
15015
15874
|
}
|
|
15016
15875
|
context.refreshAgentMessagesFromSession(agentRuntime);
|
|
15017
15876
|
turnSnapshot = captureTurnSnapshot("pending");
|
|
15018
|
-
const postTotalEstimate =
|
|
15877
|
+
const postTotalEstimate = budgetedPromptTokens(turnSnapshot) + reservedOutput;
|
|
15019
15878
|
if (postTotalEstimate > effectiveWindow) {
|
|
15020
15879
|
emitNotice(
|
|
15021
15880
|
`[Clio Coder] Request still exceeds the effective window after compaction (${postTotalEstimate} > ${effectiveWindow}). Request blocked.`
|
|
@@ -15035,6 +15894,13 @@ function createChatLoop(deps) {
|
|
|
15035
15894
|
);
|
|
15036
15895
|
if (interrupted) emit({ type: "queued_user_turn", text, kind: "interrupt" });
|
|
15037
15896
|
context.logPromptCompileIfPending();
|
|
15897
|
+
const previousThinkingLevel = previousRunSnapshot?.runtimeResolution?.effectiveThinkingLevel;
|
|
15898
|
+
if (previousThinkingLevel !== void 0 && previousThinkingLevel !== agentRuntime.runtimeResolution.effectiveThinkingLevel) {
|
|
15899
|
+
context.noteColdReason("thinking_change");
|
|
15900
|
+
}
|
|
15901
|
+
if (typeof previousRunSnapshot?.toolSignature === "string" && previousRunSnapshot.toolSignature !== toolSignature) {
|
|
15902
|
+
context.noteColdReason("tool_surface_change");
|
|
15903
|
+
}
|
|
15038
15904
|
turnSnapshot = { ...turnSnapshot, turnId: userTurnId ?? "unknown" };
|
|
15039
15905
|
context.setCurrentSnapshot(turnSnapshot);
|
|
15040
15906
|
context.persistContextSnapshot(turnSnapshot);
|
|
@@ -15049,7 +15915,7 @@ function createChatLoop(deps) {
|
|
|
15049
15915
|
compiledPromptHash: promptHash,
|
|
15050
15916
|
staticCompositionHash: promptHash,
|
|
15051
15917
|
promptSignature: promptHash,
|
|
15052
|
-
toolSignature
|
|
15918
|
+
toolSignature,
|
|
15053
15919
|
runtimeResolution: runtimeTargetSnapshot(agentRuntime.runtimeResolution),
|
|
15054
15920
|
sessionId: deps.session?.current()?.id ?? null,
|
|
15055
15921
|
cwd: process.cwd()
|
|
@@ -15062,6 +15928,9 @@ function createChatLoop(deps) {
|
|
|
15062
15928
|
state.interruptedUsage = null;
|
|
15063
15929
|
context.consumeExpectedColdReasons(agentRuntime.runtimeId);
|
|
15064
15930
|
state.streaming = true;
|
|
15931
|
+
const endpointKey = canonicalEndpointKey(agentRuntime.runtimeResolution.target);
|
|
15932
|
+
const releaseForeground = endpointKey === null ? () => {
|
|
15933
|
+
} : registerForegroundStream(endpointKey);
|
|
15065
15934
|
try {
|
|
15066
15935
|
options.onAdmitted?.();
|
|
15067
15936
|
} catch {
|
|
@@ -15111,6 +15980,7 @@ function createChatLoop(deps) {
|
|
|
15111
15980
|
}
|
|
15112
15981
|
await recovery.runCompactAndRetry(agentRuntime, runtimePromptText, overflow, images);
|
|
15113
15982
|
} finally {
|
|
15983
|
+
releaseForeground();
|
|
15114
15984
|
if (askUserPolicy) {
|
|
15115
15985
|
try {
|
|
15116
15986
|
await finalizeAskUserInterviewForHost(
|
|
@@ -15180,9 +16050,19 @@ function createChatLoop(deps) {
|
|
|
15180
16050
|
isStreaming() {
|
|
15181
16051
|
return state.streaming;
|
|
15182
16052
|
},
|
|
16053
|
+
turnPreparation() {
|
|
16054
|
+
return { phase: state.turnPreparation, since: state.turnPreparationSince };
|
|
16055
|
+
},
|
|
16056
|
+
onTurnPreparation(handler) {
|
|
16057
|
+
preparationListeners.add(handler);
|
|
16058
|
+
return () => {
|
|
16059
|
+
preparationListeners.delete(handler);
|
|
16060
|
+
};
|
|
16061
|
+
},
|
|
15183
16062
|
contextUsage: () => context.contextUsage(),
|
|
15184
16063
|
contextLedger: () => context.contextLedger(),
|
|
15185
16064
|
whenSettled: () => activeSubmit,
|
|
16065
|
+
whenPrewarmSettled: () => prewarm.settled(),
|
|
15186
16066
|
resetForSession(leafTurnId, replayMessages) {
|
|
15187
16067
|
if (state.runtime) {
|
|
15188
16068
|
state.runtime.agent.abort();
|
|
@@ -15194,6 +16074,7 @@ function createChatLoop(deps) {
|
|
|
15194
16074
|
middleware.clearPendingReminders();
|
|
15195
16075
|
middlewareToolChoice.reset();
|
|
15196
16076
|
state.lastTurnId = leafTurnId;
|
|
16077
|
+
state.lastRunSnapshot = null;
|
|
15197
16078
|
context.resetForSession();
|
|
15198
16079
|
void turnRuntime.ensureLiveCapabilitiesForSelectedModel().catch(() => {
|
|
15199
16080
|
});
|
|
@@ -15204,10 +16085,13 @@ function createChatLoop(deps) {
|
|
|
15204
16085
|
if (deps.protectedArtifacts) {
|
|
15205
16086
|
reloadProtectedArtifactsForSession(deps.protectedArtifacts, deps.readSessionEntries);
|
|
15206
16087
|
}
|
|
16088
|
+
prewarm.schedule(replayMessages && replayMessages.length > 0 ? "resume" : "session-start");
|
|
15207
16089
|
},
|
|
15208
16090
|
dispose() {
|
|
15209
16091
|
unsubscribeConfigReload?.();
|
|
15210
16092
|
unsubscribeSynthesisLock?.();
|
|
16093
|
+
unsubscribePrewarmCompaction();
|
|
16094
|
+
prewarm.dispose();
|
|
15211
16095
|
context.dispose();
|
|
15212
16096
|
if (state.runtime) {
|
|
15213
16097
|
state.runtime.agent.abort();
|
|
@@ -15230,16 +16114,19 @@ function createChatLoop(deps) {
|
|
|
15230
16114
|
if (!prepared.ok) return { status: "refused", reason: prepared.reason };
|
|
15231
16115
|
let result;
|
|
15232
16116
|
try {
|
|
15233
|
-
result = await
|
|
15234
|
-
|
|
15235
|
-
|
|
15236
|
-
|
|
15237
|
-
|
|
15238
|
-
|
|
15239
|
-
|
|
15240
|
-
|
|
15241
|
-
|
|
15242
|
-
|
|
16117
|
+
result = await withEndpointSlot(
|
|
16118
|
+
prepared.runtime,
|
|
16119
|
+
() => sideQuestionRound({
|
|
16120
|
+
model: prepared.runtime.agent.state.model,
|
|
16121
|
+
// Read-only: runSideQuestion copies before appending its own
|
|
16122
|
+
// message, so the live agent's history is untouched.
|
|
16123
|
+
messages: prepared.runtime.agent.state.messages,
|
|
16124
|
+
question: text,
|
|
16125
|
+
...prepared.apiKey !== void 0 ? { apiKey: prepared.apiKey } : {},
|
|
16126
|
+
...options.signal ? { signal: options.signal } : {},
|
|
16127
|
+
...options.onDelta ? { onDelta: options.onDelta } : {}
|
|
16128
|
+
})
|
|
16129
|
+
);
|
|
15243
16130
|
} catch (err) {
|
|
15244
16131
|
return { status: "failed", reason: err instanceof Error ? err.message : String(err) };
|
|
15245
16132
|
}
|
|
@@ -15258,14 +16145,21 @@ function createChatLoop(deps) {
|
|
|
15258
16145
|
if (!prepared.ok) return { status: "refused", reason: prepared.reason };
|
|
15259
16146
|
let result;
|
|
15260
16147
|
try {
|
|
15261
|
-
result = await
|
|
15262
|
-
|
|
15263
|
-
|
|
15264
|
-
|
|
15265
|
-
|
|
15266
|
-
|
|
15267
|
-
|
|
15268
|
-
|
|
16148
|
+
result = await withEndpointSlot(
|
|
16149
|
+
prepared.runtime,
|
|
16150
|
+
() => handoffRound({
|
|
16151
|
+
model: prepared.runtime.agent.state.model,
|
|
16152
|
+
// Read-only, exactly as the side-question round treats it.
|
|
16153
|
+
messages: prepared.runtime.agent.state.messages,
|
|
16154
|
+
goal: text,
|
|
16155
|
+
// The runtime id is what decides whether the schema can be bound
|
|
16156
|
+
// on the wire rather than only stated in the prompt.
|
|
16157
|
+
runtimeId: prepared.runtime.runtimeResolution.runtime.id,
|
|
16158
|
+
...prepared.apiKey !== void 0 ? { apiKey: prepared.apiKey } : {},
|
|
16159
|
+
...options.signal ? { signal: options.signal } : {},
|
|
16160
|
+
...options.repair ? { repair: options.repair } : {}
|
|
16161
|
+
})
|
|
16162
|
+
);
|
|
15269
16163
|
} catch (err) {
|
|
15270
16164
|
return { status: "failed", reason: err instanceof Error ? err.message : String(err) };
|
|
15271
16165
|
}
|
|
@@ -15304,13 +16198,17 @@ function createChatLoop(deps) {
|
|
|
15304
16198
|
const submitInner = api.submit.bind(api);
|
|
15305
16199
|
const submitTracked = (text, options) => {
|
|
15306
16200
|
priorSubmit = activeSubmit;
|
|
15307
|
-
|
|
16201
|
+
turnActive = true;
|
|
16202
|
+
const run = submitInner(text, options).finally(() => {
|
|
16203
|
+
turnActive = false;
|
|
16204
|
+
});
|
|
15308
16205
|
activeSubmit = run.catch(() => {
|
|
15309
16206
|
});
|
|
15310
16207
|
return run;
|
|
15311
16208
|
};
|
|
15312
16209
|
let admissionTail = null;
|
|
15313
16210
|
api.submit = (text, options = {}) => {
|
|
16211
|
+
prewarm.cancel();
|
|
15314
16212
|
const previous = admissionTail;
|
|
15315
16213
|
let release = () => {
|
|
15316
16214
|
};
|
|
@@ -15322,14 +16220,30 @@ function createChatLoop(deps) {
|
|
|
15322
16220
|
release();
|
|
15323
16221
|
if (admissionTail === ticket) admissionTail = null;
|
|
15324
16222
|
};
|
|
15325
|
-
|
|
15326
|
-
|
|
15327
|
-
|
|
15328
|
-
|
|
15329
|
-
|
|
16223
|
+
enterPreparation();
|
|
16224
|
+
let leftPreparation = false;
|
|
16225
|
+
const leaveOnce = () => {
|
|
16226
|
+
if (leftPreparation) return;
|
|
16227
|
+
leftPreparation = true;
|
|
16228
|
+
leavePreparation();
|
|
16229
|
+
};
|
|
16230
|
+
const start = async () => {
|
|
16231
|
+
const { onPreparationVisible, ...submitOptions } = options;
|
|
16232
|
+
try {
|
|
16233
|
+
await onPreparationVisible?.();
|
|
16234
|
+
} catch {
|
|
15330
16235
|
}
|
|
15331
|
-
|
|
15332
|
-
|
|
16236
|
+
return submitTracked(text, {
|
|
16237
|
+
...submitOptions,
|
|
16238
|
+
onAdmitted: () => {
|
|
16239
|
+
releaseTicket();
|
|
16240
|
+
leaveOnce();
|
|
16241
|
+
options.onAdmitted?.();
|
|
16242
|
+
}
|
|
16243
|
+
}).finally(releaseTicket);
|
|
16244
|
+
};
|
|
16245
|
+
const run = previous ? previous.then(start) : start();
|
|
16246
|
+
return run.finally(leaveOnce);
|
|
15333
16247
|
};
|
|
15334
16248
|
return api;
|
|
15335
16249
|
}
|
|
@@ -15632,6 +16546,7 @@ function verificationText(state) {
|
|
|
15632
16546
|
if (!state || state.status === "idle") return "";
|
|
15633
16547
|
if (state.status === "running") return `${GLYPH.running} verify running`;
|
|
15634
16548
|
if (state.status === "ok") return `${GLYPH.ok} verify ok ${state.detail}`;
|
|
16549
|
+
if (state.status === "retired") return `${GLYPH.warn} verify retired ${state.detail}`;
|
|
15635
16550
|
return `${GLYPH.error} verify fail ${state.detail}`;
|
|
15636
16551
|
}
|
|
15637
16552
|
function buildArtifactHeader(artifact, verification, width) {
|
|
@@ -15643,11 +16558,22 @@ function buildArtifactHeader(artifact, verification, width) {
|
|
|
15643
16558
|
if (size.length > 0) parts.push(theme6.fg("dim", size));
|
|
15644
16559
|
const verify = verificationText(verification);
|
|
15645
16560
|
if (verify.length > 0) {
|
|
15646
|
-
const token = verification?.status === "ok" ? "success" : verification?.status === "fail" ? "error" : "info";
|
|
16561
|
+
const token = verification?.status === "ok" ? "success" : verification?.status === "fail" ? "error" : verification?.status === "retired" ? "warning" : "info";
|
|
15647
16562
|
parts.push(theme6.fg(token, verify));
|
|
15648
16563
|
}
|
|
15649
16564
|
return padAnsi(parts.join(" "), width, ELLIPSIS);
|
|
15650
16565
|
}
|
|
16566
|
+
function buildArtifactHeaderLines(artifact, verification, width) {
|
|
16567
|
+
const metadata = buildArtifactHeader(artifact, void 0, width);
|
|
16568
|
+
const verify = verificationText(verification);
|
|
16569
|
+
if (artifact === void 0 || verify.length === 0) return [metadata];
|
|
16570
|
+
const theme6 = clioTheme();
|
|
16571
|
+
const token = verification?.status === "ok" ? "success" : verification?.status === "fail" ? "error" : verification?.status === "retired" ? "warning" : "info";
|
|
16572
|
+
return [
|
|
16573
|
+
metadata,
|
|
16574
|
+
...wrapTextWithAnsi(theme6.fg(token, verify), Math.max(1, width)).map((line) => padAnsi(line, width, ELLIPSIS))
|
|
16575
|
+
];
|
|
16576
|
+
}
|
|
15651
16577
|
function viewFooterHint(focus, canVerify, innerWidth) {
|
|
15652
16578
|
if (innerWidth !== void 0 && viewUsesSinglePane(innerWidth - 2)) {
|
|
15653
16579
|
const budget = innerWidth - 3;
|
|
@@ -15837,14 +16763,14 @@ var ViewOverlayView = class {
|
|
|
15837
16763
|
this.ensureContentLoaded(artifact);
|
|
15838
16764
|
this.lastContentWidth = width;
|
|
15839
16765
|
const verification = artifact ? this.verifications.get(artifactKey(artifact)) : void 0;
|
|
15840
|
-
const header =
|
|
15841
|
-
const bodyHeight = Math.max(0, height -
|
|
16766
|
+
const header = buildArtifactHeaderLines(artifact, verification, width);
|
|
16767
|
+
const bodyHeight = Math.max(0, height - header.length);
|
|
15842
16768
|
this.lastContentBodyHeight = Math.max(1, bodyHeight);
|
|
15843
16769
|
const body = this.renderedContentLines(width);
|
|
15844
16770
|
const maxOffset = Math.max(0, body.length - Math.max(1, bodyHeight));
|
|
15845
16771
|
if (this.contentScrollOffset > maxOffset) this.contentScrollOffset = maxOffset;
|
|
15846
16772
|
const visible = body.slice(this.contentScrollOffset, this.contentScrollOffset + bodyHeight).map((line) => padAnsi(line, width, ELLIPSIS));
|
|
15847
|
-
const lines = [header, ...visible];
|
|
16773
|
+
const lines = [...header, ...visible];
|
|
15848
16774
|
return this.fixedLines(lines, width, height);
|
|
15849
16775
|
}
|
|
15850
16776
|
fixedLines(lines, width, height) {
|
|
@@ -15957,7 +16883,7 @@ var ViewOverlayView = class {
|
|
|
15957
16883
|
void artifact.verify().then((result) => {
|
|
15958
16884
|
this.verifications.set(
|
|
15959
16885
|
key,
|
|
15960
|
-
result.ok ? { status: "ok", detail: result.detail } : { status: "fail", detail: result.detail }
|
|
16886
|
+
result.ok ? { status: "ok", detail: result.detail } : { status: result.retired === true ? "retired" : "fail", detail: result.detail }
|
|
15961
16887
|
);
|
|
15962
16888
|
}).catch((err) => {
|
|
15963
16889
|
const detail = err instanceof Error ? err.message : String(err);
|
|
@@ -16034,7 +16960,8 @@ function createQuestionState(question) {
|
|
|
16034
16960
|
selected: /* @__PURE__ */ new Set(),
|
|
16035
16961
|
customAnswer: "",
|
|
16036
16962
|
inputValue: "",
|
|
16037
|
-
answer: ""
|
|
16963
|
+
answer: "",
|
|
16964
|
+
rawValue: ""
|
|
16038
16965
|
};
|
|
16039
16966
|
}
|
|
16040
16967
|
function isOtherOption(label) {
|
|
@@ -16071,12 +16998,16 @@ function optionIndexFromValue(value) {
|
|
|
16071
16998
|
const index = Number(value.slice("option:".length));
|
|
16072
16999
|
return Number.isInteger(index) && index >= 0 ? index : null;
|
|
16073
17000
|
}
|
|
16074
|
-
function
|
|
16075
|
-
const
|
|
17001
|
+
function selectedOptionLabels(question, selected) {
|
|
17002
|
+
const labels = [];
|
|
16076
17003
|
for (const index of [...selected].sort((a, b) => a - b)) {
|
|
16077
17004
|
const label = question.options?.[index]?.label;
|
|
16078
|
-
if (label)
|
|
17005
|
+
if (label) labels.push(label);
|
|
16079
17006
|
}
|
|
17007
|
+
return labels;
|
|
17008
|
+
}
|
|
17009
|
+
function answerText(question, selected, customAnswer) {
|
|
17010
|
+
const parts = selectedOptionLabels(question, selected);
|
|
16080
17011
|
const custom = customAnswer.trim();
|
|
16081
17012
|
if (custom.length > 0) parts.push(custom);
|
|
16082
17013
|
return parts.join("; ");
|
|
@@ -16193,6 +17124,10 @@ var AskUserOverlayView = class {
|
|
|
16193
17124
|
this.commitMultiSelectOrOpenOther(state);
|
|
16194
17125
|
return;
|
|
16195
17126
|
}
|
|
17127
|
+
if (this.isAddTextKey(data)) {
|
|
17128
|
+
this.chooseFocusedAndOpenText(question, state);
|
|
17129
|
+
return;
|
|
17130
|
+
}
|
|
16196
17131
|
this.list?.handleInput(data);
|
|
16197
17132
|
}
|
|
16198
17133
|
/**
|
|
@@ -16319,20 +17254,16 @@ var AskUserOverlayView = class {
|
|
|
16319
17254
|
{ key: "Alt+Left/Right", verb: "question" }
|
|
16320
17255
|
]) : this.withScrollHint([{ key: "Enter", verb: recordAnswer }]);
|
|
16321
17256
|
}
|
|
17257
|
+
const addText = { key: "t", verb: "add text", short: "text" };
|
|
16322
17258
|
if (question.multi_select === true) {
|
|
16323
17259
|
return this.questions.length > 1 ? this.withScrollHint([
|
|
16324
17260
|
{ key: "Left/Right", verb: "question" },
|
|
16325
17261
|
{ key: "Space", verb: "toggle" },
|
|
17262
|
+
addText,
|
|
16326
17263
|
{ key: "Enter", verb: recordAnswer }
|
|
16327
|
-
]) : this.withScrollHint([
|
|
16328
|
-
{ key: "Space", verb: "toggle" },
|
|
16329
|
-
{ key: "Enter", verb: recordAnswer }
|
|
16330
|
-
]);
|
|
17264
|
+
]) : this.withScrollHint([{ key: "Space", verb: "toggle" }, addText, { key: "Enter", verb: recordAnswer }]);
|
|
16331
17265
|
}
|
|
16332
|
-
return this.questions.length > 1 ? this.withScrollHint([
|
|
16333
|
-
{ key: "Left/Right", verb: "question" },
|
|
16334
|
-
{ key: "Enter", verb: recordAnswer }
|
|
16335
|
-
]) : this.withScrollHint([{ key: "Enter", verb: recordAnswer }]);
|
|
17266
|
+
return this.questions.length > 1 ? this.withScrollHint([{ key: "Left/Right", verb: "question" }, addText, { key: "Enter", verb: recordAnswer }]) : this.withScrollHint([addText, { key: "Enter", verb: recordAnswer }]);
|
|
16336
17267
|
}
|
|
16337
17268
|
renderDecisionContext(width) {
|
|
16338
17269
|
const theme6 = clioTheme();
|
|
@@ -16433,6 +17364,32 @@ var AskUserOverlayView = class {
|
|
|
16433
17364
|
isTextModeNextKey(data) {
|
|
16434
17365
|
return this.questions.length > 1 && (matchesKey(data, "alt+right") || matchesKey(data, "ctrl+right"));
|
|
16435
17366
|
}
|
|
17367
|
+
/**
|
|
17368
|
+
* The key that adds typed text to the option under the cursor.
|
|
17369
|
+
*
|
|
17370
|
+
* Choosing an option used to be the whole answer, so a model that offered
|
|
17371
|
+
* "Exact number - I'll type it" gave the operator a label and nowhere to put
|
|
17372
|
+
* the number; the interview then spent two of its four rounds asking for the
|
|
17373
|
+
* figures again (issue #228). The list itself only reads the arrows, Enter,
|
|
17374
|
+
* and Esc, so a letter is free here.
|
|
17375
|
+
*/
|
|
17376
|
+
isAddTextKey(data) {
|
|
17377
|
+
return matchesKey(data, "t");
|
|
17378
|
+
}
|
|
17379
|
+
/**
|
|
17380
|
+
* Take the focused option and open the text field for it, without committing.
|
|
17381
|
+
* Submitting the text records the label and the text together.
|
|
17382
|
+
*/
|
|
17383
|
+
chooseFocusedAndOpenText(question, state) {
|
|
17384
|
+
const current = this.list?.getSelectedItem();
|
|
17385
|
+
const optionIndex = current && current.value !== "other" ? optionIndexFromValue(current.value) : null;
|
|
17386
|
+
if (optionIndex !== null) {
|
|
17387
|
+
if (question.multi_select === true) state.selected.add(optionIndex);
|
|
17388
|
+
else state.selected = /* @__PURE__ */ new Set([optionIndex]);
|
|
17389
|
+
state.focusedValue = `option:${optionIndex}`;
|
|
17390
|
+
}
|
|
17391
|
+
this.openTextInput(state.selected.size > 0 ? "Add your answer to the chosen option" : "Other answer");
|
|
17392
|
+
}
|
|
16436
17393
|
/**
|
|
16437
17394
|
* The row above the question, or nothing.
|
|
16438
17395
|
*
|
|
@@ -16586,14 +17543,15 @@ var AskUserOverlayView = class {
|
|
|
16586
17543
|
return;
|
|
16587
17544
|
}
|
|
16588
17545
|
state.inputValue = answer;
|
|
17546
|
+
state.rawValue = value;
|
|
16589
17547
|
if (questionHasOptions(question) && question.multi_select === true) {
|
|
16590
17548
|
state.customAnswer = answer;
|
|
16591
17549
|
this.commitCurrentAnswer();
|
|
16592
|
-
|
|
16593
|
-
state.customAnswer = questionHasOptions(question) ? answer : "";
|
|
16594
|
-
state.answer = answer;
|
|
16595
|
-
this.finishIfCompleteOrAdvance();
|
|
17550
|
+
return;
|
|
16596
17551
|
}
|
|
17552
|
+
state.customAnswer = questionHasOptions(question) ? answer : "";
|
|
17553
|
+
state.answer = questionHasOptions(question) ? answerText(question, state.selected, state.customAnswer) : answer;
|
|
17554
|
+
this.finishIfCompleteOrAdvance();
|
|
16597
17555
|
};
|
|
16598
17556
|
activeInput.onEscape = () => this.cancel();
|
|
16599
17557
|
this.input = activeInput;
|
|
@@ -16622,7 +17580,10 @@ var AskUserOverlayView = class {
|
|
|
16622
17580
|
return;
|
|
16623
17581
|
}
|
|
16624
17582
|
state.selected = /* @__PURE__ */ new Set([optionIndex]);
|
|
16625
|
-
state.
|
|
17583
|
+
state.customAnswer = "";
|
|
17584
|
+
state.rawValue = "";
|
|
17585
|
+
state.inputValue = "";
|
|
17586
|
+
state.answer = answerText(question, state.selected, state.customAnswer) || item.label;
|
|
16626
17587
|
state.focusedValue = item.value;
|
|
16627
17588
|
this.status = "";
|
|
16628
17589
|
this.finishIfCompleteOrAdvance();
|
|
@@ -16734,12 +17695,26 @@ var AskUserOverlayView = class {
|
|
|
16734
17695
|
allAnswered() {
|
|
16735
17696
|
return this.states.length > 0 && this.states.every((state) => state.answer.trim().length > 0);
|
|
16736
17697
|
}
|
|
17698
|
+
/**
|
|
17699
|
+
* What the round captured, as three separable facts per question: the one-line
|
|
17700
|
+
* answer, the labels chosen, and the text typed. A reader tells a label-only
|
|
17701
|
+
* answer from a label-plus-value one by whether `value` is there, which the
|
|
17702
|
+
* joined string alone could never say.
|
|
17703
|
+
*/
|
|
16737
17704
|
answers() {
|
|
16738
17705
|
const answers = [];
|
|
16739
17706
|
for (let index = 0; index < this.questions.length; index += 1) {
|
|
16740
17707
|
const question = this.questions[index];
|
|
16741
|
-
const
|
|
16742
|
-
|
|
17708
|
+
const state = this.states[index];
|
|
17709
|
+
const answer = state?.answer.trim();
|
|
17710
|
+
if (!question || !state || !answer || answer.length === 0) continue;
|
|
17711
|
+
const options = selectedOptionLabels(question, state.selected);
|
|
17712
|
+
answers.push({
|
|
17713
|
+
question: question.question,
|
|
17714
|
+
answer,
|
|
17715
|
+
...options.length > 0 ? { options } : {},
|
|
17716
|
+
...state.rawValue.length > 0 ? { value: state.rawValue } : {}
|
|
17717
|
+
});
|
|
16743
17718
|
}
|
|
16744
17719
|
return answers;
|
|
16745
17720
|
}
|
|
@@ -17348,7 +18323,7 @@ function legendRow2(group, contentWidth) {
|
|
|
17348
18323
|
const tokens = formatTokens(group.tokens);
|
|
17349
18324
|
const percent = formatContextPercent(group.percent);
|
|
17350
18325
|
const right = `${tokens.padStart(9)} ${percent.padStart(6)}`;
|
|
17351
|
-
const labelToken = group.category === "
|
|
18326
|
+
const labelToken = group.category === "reserve" ? "frame" : group.category === "free" ? "dim" : "muted";
|
|
17352
18327
|
const leftWidth = Math.max(0, contentWidth - visibleWidth(right) - 2);
|
|
17353
18328
|
const labelText = group.label.length > leftWidth ? group.label.slice(0, leftWidth) : group.label.padEnd(leftWidth);
|
|
17354
18329
|
return `${swatch} ${theme6.fg(labelToken, labelText)} ${theme6.fg("muted", right)}`;
|
|
@@ -17370,6 +18345,16 @@ function coldReasonLabel(reason) {
|
|
|
17370
18345
|
return "compaction";
|
|
17371
18346
|
case "dispatch":
|
|
17372
18347
|
return "dispatch traffic";
|
|
18348
|
+
case "residency":
|
|
18349
|
+
return "residency change";
|
|
18350
|
+
case "thinking_change":
|
|
18351
|
+
return "thinking-level change";
|
|
18352
|
+
case "tool_surface_change":
|
|
18353
|
+
return "tool-surface change";
|
|
18354
|
+
case "prompt_recompiled":
|
|
18355
|
+
return "prompt recompile";
|
|
18356
|
+
case "background_memory":
|
|
18357
|
+
return "background memory step";
|
|
17373
18358
|
default:
|
|
17374
18359
|
return reason;
|
|
17375
18360
|
}
|
|
@@ -17441,18 +18426,28 @@ function renderContextLedgerLines(ledger, contentWidth, workingSet, workingSetCo
|
|
|
17441
18426
|
if (ledger.promptCache) {
|
|
17442
18427
|
const cache2 = ledger.promptCache;
|
|
17443
18428
|
const shell = cache2.shellReused ? "shell reused" : "shell recompiled";
|
|
17444
|
-
const
|
|
18429
|
+
const backendCacheReadsUnknown = cache2.backend?.cachedTokens === null;
|
|
18430
|
+
const backend = backendCacheReadsUnknown ? "server does not report cache reads" : cache2.backendVerdict === "hot" || cache2.backendVerdict === "partial" ? "backend reused" : cache2.backendVerdict === "cold" ? "backend cold" : cache2.backendVerdict === "small" ? "backend small" : "backend n/a";
|
|
17445
18431
|
const read = cache2.cacheReadTokens !== null ? `cache read ${formatTokens(cache2.cacheReadTokens)}` : "cache read n/a";
|
|
17446
18432
|
const uncached = cache2.uncachedInputTokens !== null ? `uncached input ${formatTokens(cache2.uncachedInputTokens)}` : null;
|
|
17447
|
-
const line = ["prompt cache:", shell, "\xB7", backend, "\xB7", read, ...uncached ? ["\xB7", uncached] : []].join(" ");
|
|
17448
|
-
const coldReasons = cache2.backendVerdict === "cold" ? cache2.expectedColdReasons ?? [] : [];
|
|
17449
|
-
const misleading = cache2.shellReused && cache2.backendVerdict === "cold" && coldReasons.length === 0;
|
|
18433
|
+
const line = backendCacheReadsUnknown ? ["prompt cache:", shell, "\xB7", backend].join(" ") : ["prompt cache:", shell, "\xB7", backend, "\xB7", read, ...uncached ? ["\xB7", uncached] : []].join(" ");
|
|
18434
|
+
const coldReasons = cache2.backendVerdict === "cold" && !backendCacheReadsUnknown ? cache2.expectedColdReasons ?? [] : [];
|
|
18435
|
+
const misleading = cache2.shellReused && cache2.backendVerdict === "cold" && !backendCacheReadsUnknown && coldReasons.length === 0;
|
|
17450
18436
|
lines.push(theme6.fg(misleading ? "warning" : "dim", line));
|
|
18437
|
+
if (cache2.backend) {
|
|
18438
|
+
const prefill = cache2.backend.cachedTokens !== null && cache2.uncachedPrefillTokens !== null ? `prefill: ${formatTokens(cache2.uncachedPrefillTokens)} uncached \xB7 ${formatTokens(cache2.backend.cachedTokens)} cached \xB7 ${formatTokens(cache2.backend.promptMs)} ms` : `prefill: ${formatTokens(cache2.backend.promptTokens)} prompt \xB7 ${formatTokens(cache2.backend.promptMs)} ms`;
|
|
18439
|
+
lines.push(theme6.fg("dim", prefill));
|
|
18440
|
+
}
|
|
17451
18441
|
if (coldReasons.length > 0) {
|
|
17452
18442
|
const reasons = coldReasons.map(coldReasonLabel).join(", ");
|
|
17453
18443
|
lines.push(theme6.fg("dim", `last cold turn: ${reasons} (expected)`));
|
|
17454
18444
|
}
|
|
17455
18445
|
}
|
|
18446
|
+
if (ledger.prewarm) {
|
|
18447
|
+
const tokens = ledger.prewarm.tokens !== null ? `${formatTokens(ledger.prewarm.tokens)} tokens` : "prefix";
|
|
18448
|
+
const aborted = ledger.prewarm.aborted ? " (aborted on submit; prefix stays in the slot)" : "";
|
|
18449
|
+
lines.push(theme6.fg("dim", `prewarmed: ${tokens} in ${formatTokens(ledger.prewarm.ms)} ms${aborted}`));
|
|
18450
|
+
}
|
|
17456
18451
|
if (ledger.lastCompaction) {
|
|
17457
18452
|
const pruneInfo = `last compaction: reclaimed ${formatTokens(ledger.lastCompaction.tokensBefore)} -> ${formatTokens(ledger.lastCompaction.tokensAfter)} tokens (${ledger.lastCompaction.stage})`;
|
|
17458
18453
|
lines.push(theme6.fg("dim", pruneInfo));
|
|
@@ -17546,6 +18541,8 @@ function aggregateCostEntries(entries) {
|
|
|
17546
18541
|
existing.row.apiCalls += entry.apiCalls ?? 1;
|
|
17547
18542
|
if (entry.label === "side-question") existing.row.sideQuestions += 1;
|
|
17548
18543
|
if (entry.label === "handoff") existing.row.handoffs += 1;
|
|
18544
|
+
if (entry.label === "prewarm") existing.row.prewarms += 1;
|
|
18545
|
+
if (entry.label === "background-memory") existing.row.backgroundMemory += 1;
|
|
17549
18546
|
for (const requestedModelId of entry.requestedModelIds) existing.requestedModelIds.add(requestedModelId);
|
|
17550
18547
|
addResponseModelIdObservationCounts(
|
|
17551
18548
|
existing.responseModelIdObservationCounts,
|
|
@@ -17567,7 +18564,9 @@ function aggregateCostEntries(entries) {
|
|
|
17567
18564
|
reasoningTokens: entry.reasoningTokens,
|
|
17568
18565
|
apiCalls: entry.apiCalls ?? 1,
|
|
17569
18566
|
sideQuestions: entry.label === "side-question" ? 1 : 0,
|
|
17570
|
-
handoffs: entry.label === "handoff" ? 1 : 0
|
|
18567
|
+
handoffs: entry.label === "handoff" ? 1 : 0,
|
|
18568
|
+
prewarms: entry.label === "prewarm" ? 1 : 0,
|
|
18569
|
+
backgroundMemory: entry.label === "background-memory" ? 1 : 0
|
|
17571
18570
|
},
|
|
17572
18571
|
requestedModelIds: new Set(entry.requestedModelIds),
|
|
17573
18572
|
responseModelIdObservationCounts: { ...entry.responseModelIdObservationCounts },
|
|
@@ -17599,7 +18598,9 @@ function sumRows(rows) {
|
|
|
17599
18598
|
reasoningTokens: acc.reasoningTokens + row2.reasoningTokens,
|
|
17600
18599
|
apiCalls: acc.apiCalls + row2.apiCalls,
|
|
17601
18600
|
sideQuestions: acc.sideQuestions + row2.sideQuestions,
|
|
17602
|
-
handoffs: acc.handoffs + row2.handoffs
|
|
18601
|
+
handoffs: acc.handoffs + row2.handoffs,
|
|
18602
|
+
prewarms: acc.prewarms + row2.prewarms,
|
|
18603
|
+
backgroundMemory: acc.backgroundMemory + row2.backgroundMemory
|
|
17603
18604
|
}),
|
|
17604
18605
|
{
|
|
17605
18606
|
runs: 0,
|
|
@@ -17611,7 +18612,9 @@ function sumRows(rows) {
|
|
|
17611
18612
|
reasoningTokens: 0,
|
|
17612
18613
|
apiCalls: 0,
|
|
17613
18614
|
sideQuestions: 0,
|
|
17614
|
-
handoffs: 0
|
|
18615
|
+
handoffs: 0,
|
|
18616
|
+
prewarms: 0,
|
|
18617
|
+
backgroundMemory: 0
|
|
17615
18618
|
}
|
|
17616
18619
|
);
|
|
17617
18620
|
}
|
|
@@ -17633,21 +18636,37 @@ function kvBlock(entries) {
|
|
|
17633
18636
|
return annotation ? `${row2} ${theme6.fg("dim", annotation)}` : row2;
|
|
17634
18637
|
});
|
|
17635
18638
|
}
|
|
17636
|
-
function summaryBlock(totalCost, totalTokens, rows) {
|
|
18639
|
+
function summaryBlock(totalCost, totalTokens, rows, promptCache) {
|
|
17637
18640
|
const totals = sumRows(rows);
|
|
17638
18641
|
const resolvedTotal = totalTokens > 0 ? totalTokens : totals.tokens;
|
|
17639
18642
|
const cost = formatCostAggregate(totalCost);
|
|
18643
|
+
const cacheRows = promptCache !== null && hasPromptCacheTelemetry(promptCache) ? [
|
|
18644
|
+
[
|
|
18645
|
+
"uncached prefill",
|
|
18646
|
+
promptCache.uncachedPrefillTokens === null ? "not reported" : formatTokens2(promptCache.uncachedPrefillTokens)
|
|
18647
|
+
],
|
|
18648
|
+
[
|
|
18649
|
+
"cache verdicts",
|
|
18650
|
+
`hot ${promptCache.verdictCounts.hot} \xB7 partial ${promptCache.verdictCounts.partial} \xB7 cold ${promptCache.verdictCounts.cold} \xB7 small ${promptCache.verdictCounts.small}`
|
|
18651
|
+
]
|
|
18652
|
+
] : [];
|
|
17640
18653
|
return kvBlock([
|
|
17641
|
-
[
|
|
18654
|
+
[
|
|
18655
|
+
"turns",
|
|
18656
|
+
formatTokens2(totals.runs - totals.sideQuestions - totals.handoffs - totals.prewarms - totals.backgroundMemory)
|
|
18657
|
+
],
|
|
17642
18658
|
["model calls", formatTokens2(totals.apiCalls)],
|
|
17643
18659
|
...totals.sideQuestions > 0 ? [["side questions", formatTokens2(totals.sideQuestions)]] : [],
|
|
17644
18660
|
...totals.handoffs > 0 ? [["handoffs", formatTokens2(totals.handoffs)]] : [],
|
|
18661
|
+
...totals.prewarms > 0 ? [["pre-warms", formatTokens2(totals.prewarms)]] : [],
|
|
18662
|
+
...totals.backgroundMemory > 0 ? [["memory steps", formatTokens2(totals.backgroundMemory)]] : [],
|
|
17645
18663
|
...cost === null ? [] : [["cost", cost]],
|
|
17646
18664
|
["input", formatTokens2(totals.input)],
|
|
17647
18665
|
["output", formatTokens2(totals.output)],
|
|
17648
18666
|
["reasoning", ...reasoningValue(totals.reasoningTokens)],
|
|
17649
18667
|
["cache read", ...cacheReadValue(totals.cacheRead, totals.apiCalls)],
|
|
17650
18668
|
["cache write", formatTokens2(totals.cacheWrite)],
|
|
18669
|
+
...cacheRows,
|
|
17651
18670
|
["processed", `${formatTokens2(resolvedTotal)} tokens`]
|
|
17652
18671
|
]);
|
|
17653
18672
|
}
|
|
@@ -17656,10 +18675,12 @@ function modelBlock(row2) {
|
|
|
17656
18675
|
return kvBlock([
|
|
17657
18676
|
["requested model ids", row2.requestedModelIds.join(", ")],
|
|
17658
18677
|
["response model id observation", responseModelIdObservationCountsLabel(row2.responseModelIdObservationCounts)],
|
|
17659
|
-
["turns", formatTokens2(row2.runs - row2.sideQuestions - row2.handoffs)],
|
|
18678
|
+
["turns", formatTokens2(row2.runs - row2.sideQuestions - row2.handoffs - row2.prewarms - row2.backgroundMemory)],
|
|
17660
18679
|
["model calls", formatTokens2(row2.apiCalls)],
|
|
17661
18680
|
...row2.sideQuestions > 0 ? [["side questions", formatTokens2(row2.sideQuestions)]] : [],
|
|
17662
18681
|
...row2.handoffs > 0 ? [["handoffs", formatTokens2(row2.handoffs)]] : [],
|
|
18682
|
+
...row2.prewarms > 0 ? [["pre-warms", formatTokens2(row2.prewarms)]] : [],
|
|
18683
|
+
...row2.backgroundMemory > 0 ? [["memory steps", formatTokens2(row2.backgroundMemory)]] : [],
|
|
17663
18684
|
...cost === null ? [] : [["cost", cost]],
|
|
17664
18685
|
["input", formatTokens2(row2.input)],
|
|
17665
18686
|
["output", formatTokens2(row2.output)],
|
|
@@ -17669,10 +18690,10 @@ function modelBlock(row2) {
|
|
|
17669
18690
|
["processed", `${formatTokens2(row2.tokens)} tokens`]
|
|
17670
18691
|
]);
|
|
17671
18692
|
}
|
|
17672
|
-
function formatCostOverlayBodyLines(totalCost, totalTokens, rows, contentWidth) {
|
|
18693
|
+
function formatCostOverlayBodyLines(totalCost, totalTokens, rows, contentWidth, promptCache = null) {
|
|
17673
18694
|
const theme6 = clioTheme();
|
|
17674
18695
|
const lines = [];
|
|
17675
|
-
for (const line of summaryBlock(totalCost, totalTokens, rows)) {
|
|
18696
|
+
for (const line of summaryBlock(totalCost, totalTokens, rows, promptCache)) {
|
|
17676
18697
|
lines.push(line);
|
|
17677
18698
|
}
|
|
17678
18699
|
lines.push(rule(theme6, contentWidth));
|
|
@@ -17689,7 +18710,7 @@ function formatCostOverlayBodyLines(totalCost, totalTokens, rows, contentWidth)
|
|
|
17689
18710
|
}
|
|
17690
18711
|
return lines;
|
|
17691
18712
|
}
|
|
17692
|
-
function buildCostSnapshot(observability, sessionId, snapshot) {
|
|
18713
|
+
function buildCostSnapshot(observability, sessionId, snapshot, getSessionEntries) {
|
|
17693
18714
|
const entries = observability.costEntries();
|
|
17694
18715
|
const rows = aggregateCostEntries(entries);
|
|
17695
18716
|
const totalTokens = rows.reduce((sum, r) => sum + r.tokens, 0);
|
|
@@ -17697,7 +18718,8 @@ function buildCostSnapshot(observability, sessionId, snapshot) {
|
|
|
17697
18718
|
sessionId,
|
|
17698
18719
|
totalCost: snapshot?.session.cost ?? observability.sessionCostSummary(),
|
|
17699
18720
|
totalTokens,
|
|
17700
|
-
rows
|
|
18721
|
+
rows,
|
|
18722
|
+
promptCache: getSessionEntries ? foldPromptCacheTelemetry(getSessionEntries()) : null
|
|
17701
18723
|
};
|
|
17702
18724
|
}
|
|
17703
18725
|
var CostOverlayBody = class {
|
|
@@ -17708,7 +18730,13 @@ var CostOverlayBody = class {
|
|
|
17708
18730
|
render(width) {
|
|
17709
18731
|
const contentWidth = Math.max(1, Math.floor(width));
|
|
17710
18732
|
const snapshot = this.getSnapshot();
|
|
17711
|
-
return formatCostOverlayBodyLines(
|
|
18733
|
+
return formatCostOverlayBodyLines(
|
|
18734
|
+
snapshot.totalCost,
|
|
18735
|
+
snapshot.totalTokens,
|
|
18736
|
+
snapshot.rows,
|
|
18737
|
+
contentWidth,
|
|
18738
|
+
snapshot.promptCache
|
|
18739
|
+
);
|
|
17712
18740
|
}
|
|
17713
18741
|
invalidate() {
|
|
17714
18742
|
}
|
|
@@ -17716,7 +18744,9 @@ var CostOverlayBody = class {
|
|
|
17716
18744
|
function openCostOverlay(tui, observability, options) {
|
|
17717
18745
|
const sessionId = options?.sessionId ?? null;
|
|
17718
18746
|
let latest = observability.snapshot();
|
|
17719
|
-
const body = new CostOverlayBody(
|
|
18747
|
+
const body = new CostOverlayBody(
|
|
18748
|
+
() => buildCostSnapshot(observability, sessionId, latest, options?.getSessionEntries)
|
|
18749
|
+
);
|
|
17720
18750
|
const handle = showClioOverlayFrame(tui, body, {
|
|
17721
18751
|
anchor: "center",
|
|
17722
18752
|
width: COST_OVERLAY_WIDTH,
|
|
@@ -17803,6 +18833,38 @@ function compileFleetRunPreview(input) {
|
|
|
17803
18833
|
diagnostics.push(describeError(error));
|
|
17804
18834
|
return fail();
|
|
17805
18835
|
}
|
|
18836
|
+
const routes = /* @__PURE__ */ new Map();
|
|
18837
|
+
if (input.resolveRoute !== void 0) {
|
|
18838
|
+
for (const step of plan.steps) {
|
|
18839
|
+
if (step.kind === "code") continue;
|
|
18840
|
+
try {
|
|
18841
|
+
const route = input.resolveRoute({
|
|
18842
|
+
stepId: step.id,
|
|
18843
|
+
agentId: step.agentId,
|
|
18844
|
+
task: step.task,
|
|
18845
|
+
scope: step.scope,
|
|
18846
|
+
...step.target !== void 0 ? { target: step.target } : {},
|
|
18847
|
+
...step.profile !== void 0 ? { profile: step.profile } : {}
|
|
18848
|
+
});
|
|
18849
|
+
if (route !== null) routes.set(step.id, route);
|
|
18850
|
+
} catch (error) {
|
|
18851
|
+
diagnostics.push(`step '${step.id}' route preflight failed: ${describeError(error)}`);
|
|
18852
|
+
}
|
|
18853
|
+
}
|
|
18854
|
+
plan = bindExecutionPlanEndpoints(
|
|
18855
|
+
plan,
|
|
18856
|
+
Object.fromEntries(
|
|
18857
|
+
[...routes].map(([stepId, route]) => [
|
|
18858
|
+
stepId,
|
|
18859
|
+
route.endpoint === void 0 ? void 0 : {
|
|
18860
|
+
key: route.endpoint.key,
|
|
18861
|
+
limit: route.endpoint.limit,
|
|
18862
|
+
...route.endpoint.foregroundHeld !== void 0 ? { foregroundHeld: route.endpoint.foregroundHeld } : {}
|
|
18863
|
+
}
|
|
18864
|
+
])
|
|
18865
|
+
)
|
|
18866
|
+
);
|
|
18867
|
+
}
|
|
17806
18868
|
try {
|
|
17807
18869
|
preflightWriteBoundaries(plan, input.workspaceRoot);
|
|
17808
18870
|
} catch (error) {
|
|
@@ -17851,19 +18913,7 @@ function compileFleetRunPreview(input) {
|
|
|
17851
18913
|
}
|
|
17852
18914
|
];
|
|
17853
18915
|
}
|
|
17854
|
-
|
|
17855
|
-
try {
|
|
17856
|
-
route = input.resolveRoute?.({
|
|
17857
|
-
stepId: step.id,
|
|
17858
|
-
agentId: step.agentId,
|
|
17859
|
-
task: step.task,
|
|
17860
|
-
scope: step.scope,
|
|
17861
|
-
...step.target !== void 0 ? { target: step.target } : {},
|
|
17862
|
-
...step.profile !== void 0 ? { profile: step.profile } : {}
|
|
17863
|
-
}) ?? null;
|
|
17864
|
-
} catch (error) {
|
|
17865
|
-
diagnostics.push(`step '${step.id}' route preflight failed: ${describeError(error)}`);
|
|
17866
|
-
}
|
|
18916
|
+
const route = routes.get(step.id) ?? null;
|
|
17867
18917
|
return [
|
|
17868
18918
|
{
|
|
17869
18919
|
...base,
|
|
@@ -18481,6 +19531,8 @@ function formatMemoryStatusLine(status, contentWidth) {
|
|
|
18481
19531
|
theme6.fg("muted", `last ${status.lastDecision ?? "none"}`)
|
|
18482
19532
|
];
|
|
18483
19533
|
if (status.stepInFlight) units.push(theme6.fg("reason", "step running"));
|
|
19534
|
+
const spend = status.spend === null || status.spend === void 0 ? "" : formatTaskMemorySpend(status.spend);
|
|
19535
|
+
if (spend.length > 0) units.push(theme6.fg("dim", spend));
|
|
18484
19536
|
return fitUnits(theme6, "", units, width);
|
|
18485
19537
|
}
|
|
18486
19538
|
function bankEntries(snapshot) {
|
|
@@ -18577,7 +19629,8 @@ function memorySignature(status, records) {
|
|
|
18577
19629
|
status.tier,
|
|
18578
19630
|
String(status.size),
|
|
18579
19631
|
status.lastDecision ?? "none",
|
|
18580
|
-
status.stepInFlight ? "running" : "idle"
|
|
19632
|
+
status.stepInFlight ? "running" : "idle",
|
|
19633
|
+
`${status.spend?.llmSteps ?? 0}:${status.spend?.injections ?? 0}:${status.spend?.totalTokens ?? 0}`
|
|
18581
19634
|
];
|
|
18582
19635
|
for (const record2 of records) parts.push(`r:${record2.id}:${record2.approved}:${record2.rejectedAt ?? ""}`);
|
|
18583
19636
|
for (const entry of bankEntries(status.bank)) {
|
|
@@ -20552,6 +21605,15 @@ var SubmenuWrapper = class {
|
|
|
20552
21605
|
child;
|
|
20553
21606
|
hint;
|
|
20554
21607
|
note;
|
|
21608
|
+
/**
|
|
21609
|
+
* Why the last submission was refused, or null while nothing is wrong. The
|
|
21610
|
+
* editor sets it instead of closing, so the operator corrects the value with
|
|
21611
|
+
* the reason on screen rather than back at the row list with no reason.
|
|
21612
|
+
*/
|
|
21613
|
+
problem = null;
|
|
21614
|
+
setProblem(problem) {
|
|
21615
|
+
this.problem = problem;
|
|
21616
|
+
}
|
|
20555
21617
|
render(width) {
|
|
20556
21618
|
const theme6 = clioTheme();
|
|
20557
21619
|
const lines = [];
|
|
@@ -20565,6 +21627,11 @@ var SubmenuWrapper = class {
|
|
|
20565
21627
|
}
|
|
20566
21628
|
lines.push("");
|
|
20567
21629
|
lines.push(...this.child.render(Math.max(1, width - 2)).map((line) => ` ${line}`));
|
|
21630
|
+
if (this.problem !== null) {
|
|
21631
|
+
for (const line of wrapTextWithAnsi(this.problem, Math.max(1, width - 2))) {
|
|
21632
|
+
lines.push(theme6.fg("error", ` ${line}`));
|
|
21633
|
+
}
|
|
21634
|
+
}
|
|
20568
21635
|
lines.push("");
|
|
20569
21636
|
lines.push(theme6.fg("dim", ` ${this.hint}`));
|
|
20570
21637
|
return lines;
|
|
@@ -20628,31 +21695,63 @@ function selectModelSubmenu(providers, getActiveTarget) {
|
|
|
20628
21695
|
function editTextSubmenu(title, note) {
|
|
20629
21696
|
return textInputSubmenu(title, note);
|
|
20630
21697
|
}
|
|
20631
|
-
|
|
20632
|
-
|
|
21698
|
+
var NUMBER_SETTING_RULES = {
|
|
21699
|
+
"budget.sessionCeilingUsd": { min: 0, integer: false },
|
|
21700
|
+
"watchdog.cadenceToolCalls": { min: 1, integer: true, allowBlank: true },
|
|
21701
|
+
"delegation.defaults.connectTimeoutMs": { min: 1, max: MAX_TIMER_DELAY_MS, integer: true },
|
|
21702
|
+
"delegation.defaults.turnTimeoutMs": { min: 1, max: MAX_TIMER_DELAY_MS, integer: true },
|
|
21703
|
+
"delegation.defaults.permissionTimeoutMs": { min: 1, max: MAX_TIMER_DELAY_MS, integer: true }
|
|
21704
|
+
};
|
|
21705
|
+
var NUMBER_SETTING_IDS = Object.keys(NUMBER_SETTING_RULES);
|
|
21706
|
+
function describeSubmittedText(value) {
|
|
21707
|
+
const trimmed = value.trim();
|
|
21708
|
+
return trimmed.length === 0 ? "an empty string" : JSON.stringify(trimmed);
|
|
21709
|
+
}
|
|
21710
|
+
function parseNumberSetting(value, rule2) {
|
|
21711
|
+
const trimmed = value.trim();
|
|
21712
|
+
const noun = rule2.integer ? "an integer" : "a number";
|
|
21713
|
+
if (trimmed.length === 0 && rule2.allowBlank === true) return { value: null };
|
|
21714
|
+
const parsed = trimmed.length === 0 ? Number.NaN : Number(trimmed);
|
|
21715
|
+
if (!Number.isFinite(parsed) || rule2.integer && !Number.isInteger(parsed)) {
|
|
21716
|
+
const shown = Number.isFinite(parsed) ? String(parsed) : describeSubmittedText(value);
|
|
21717
|
+
return { refusal: `Not applied: expected ${noun}, got ${shown}.` };
|
|
21718
|
+
}
|
|
21719
|
+
if (parsed < rule2.min) return { refusal: `Not applied: expected ${noun} >= ${rule2.min}, got ${parsed}.` };
|
|
21720
|
+
if (rule2.max !== void 0 && parsed > rule2.max) {
|
|
21721
|
+
return { refusal: `Not applied: expected ${noun} <= ${rule2.max}, got ${parsed}.` };
|
|
21722
|
+
}
|
|
21723
|
+
return { value: parsed };
|
|
21724
|
+
}
|
|
21725
|
+
function numberSettingNote(rule2) {
|
|
21726
|
+
const noun = rule2.integer ? "a whole number" : "a number";
|
|
21727
|
+
const clears = rule2.allowBlank === true ? "; blank clears it" : "";
|
|
21728
|
+
if (rule2.min > 0 && rule2.max !== void 0) return `Use ${noun} from ${rule2.min} to ${rule2.max}${clears}.`;
|
|
21729
|
+
if (rule2.min > 0) return `Use ${noun} of at least ${rule2.min}${clears}.`;
|
|
21730
|
+
return `Use a non-negative ${rule2.integer ? "whole number" : "number"}${clears}.`;
|
|
21731
|
+
}
|
|
21732
|
+
function editNumberSubmenu(title, id) {
|
|
21733
|
+
const rule2 = NUMBER_SETTING_RULES[id];
|
|
20633
21734
|
return (currentValue, done) => {
|
|
20634
21735
|
const input = new Input();
|
|
20635
21736
|
input.setValue(currentValue);
|
|
20636
21737
|
input.focused = true;
|
|
21738
|
+
const wrapper = new SubmenuWrapper(
|
|
21739
|
+
title,
|
|
21740
|
+
input,
|
|
21741
|
+
buildHint([{ key: "Enter", verb: "confirm" }], "back"),
|
|
21742
|
+
numberSettingNote(rule2)
|
|
21743
|
+
);
|
|
20637
21744
|
input.onSubmit = (val) => {
|
|
20638
|
-
|
|
20639
|
-
|
|
21745
|
+
const outcome = parseNumberSetting(val, rule2);
|
|
21746
|
+
if ("refusal" in outcome) {
|
|
21747
|
+
wrapper.setProblem(outcome.refusal);
|
|
20640
21748
|
return;
|
|
20641
21749
|
}
|
|
20642
|
-
|
|
20643
|
-
|
|
20644
|
-
done(val);
|
|
20645
|
-
} else {
|
|
20646
|
-
done();
|
|
20647
|
-
}
|
|
21750
|
+
wrapper.setProblem(null);
|
|
21751
|
+
done(outcome.value === null ? "" : val.trim());
|
|
20648
21752
|
};
|
|
20649
21753
|
input.onEscape = () => done();
|
|
20650
|
-
return
|
|
20651
|
-
title,
|
|
20652
|
-
input,
|
|
20653
|
-
buildHint([{ key: "Enter", verb: "confirm" }], "back"),
|
|
20654
|
-
min > 0 ? `Use a whole number of at least ${min}${options.allowBlank === true ? "; blank clears it" : ""}.` : "Use a non-negative number."
|
|
20655
|
-
);
|
|
21754
|
+
return wrapper;
|
|
20656
21755
|
};
|
|
20657
21756
|
}
|
|
20658
21757
|
function selectListSubmenu(title, items, note) {
|
|
@@ -21189,6 +22288,7 @@ function buildSettingItems(settings, options) {
|
|
|
21189
22288
|
}),
|
|
21190
22289
|
fleetGroupHeader("fleet.group.placement", "Placement"),
|
|
21191
22290
|
...fleetNodeRows(options?.getFleetNodes?.() ?? []),
|
|
22291
|
+
...fleetEndpointRows(options?.providers),
|
|
21192
22292
|
settingItem("targets", "", {
|
|
21193
22293
|
description: "Live inference target inventory and routing roles.",
|
|
21194
22294
|
affordance: "column heading",
|
|
@@ -21210,7 +22310,7 @@ function buildSettingItems(settings, options) {
|
|
|
21210
22310
|
readOnly: true
|
|
21211
22311
|
}),
|
|
21212
22312
|
settingItem("budget.sessionCeilingUsd", String(settings.budget.sessionCeilingUsd), {
|
|
21213
|
-
submenu: editNumberSubmenu("Edit session cost ceiling USD"),
|
|
22313
|
+
submenu: editNumberSubmenu("Edit session cost ceiling USD", "budget.sessionCeilingUsd"),
|
|
21214
22314
|
affordance: "free text"
|
|
21215
22315
|
}),
|
|
21216
22316
|
settingItem("defaults.maxTokens", String(settings.defaults.maxTokens), {
|
|
@@ -21277,10 +22377,10 @@ function buildSettingItems(settings, options) {
|
|
|
21277
22377
|
"watchdog.cadenceToolCalls",
|
|
21278
22378
|
watchdog.cadenceToolCalls === void 0 ? "(turn end only)" : String(watchdog.cadenceToolCalls),
|
|
21279
22379
|
{
|
|
21280
|
-
submenu: editNumberSubmenu(
|
|
21281
|
-
|
|
21282
|
-
|
|
21283
|
-
|
|
22380
|
+
submenu: editNumberSubmenu(
|
|
22381
|
+
"Edit watchdog cadence in tool calls; blank fires at turn end only",
|
|
22382
|
+
"watchdog.cadenceToolCalls"
|
|
22383
|
+
),
|
|
21284
22384
|
affordance: "free text",
|
|
21285
22385
|
editValue: watchdog.cadenceToolCalls === void 0 ? "" : String(watchdog.cadenceToolCalls)
|
|
21286
22386
|
}
|
|
@@ -21301,15 +22401,15 @@ function buildSettingItems(settings, options) {
|
|
|
21301
22401
|
affordance: "free text"
|
|
21302
22402
|
}),
|
|
21303
22403
|
settingItem("delegation.defaults.connectTimeoutMs", String(settings.delegation.defaults.connectTimeoutMs), {
|
|
21304
|
-
submenu: editNumberSubmenu("Edit delegate connect timeout (ms)"),
|
|
22404
|
+
submenu: editNumberSubmenu("Edit delegate connect timeout (ms)", "delegation.defaults.connectTimeoutMs"),
|
|
21305
22405
|
affordance: "free text"
|
|
21306
22406
|
}),
|
|
21307
22407
|
settingItem("delegation.defaults.turnTimeoutMs", String(settings.delegation.defaults.turnTimeoutMs), {
|
|
21308
|
-
submenu: editNumberSubmenu("Edit delegate turn timeout (ms)"),
|
|
22408
|
+
submenu: editNumberSubmenu("Edit delegate turn timeout (ms)", "delegation.defaults.turnTimeoutMs"),
|
|
21309
22409
|
affordance: "free text"
|
|
21310
22410
|
}),
|
|
21311
22411
|
settingItem("delegation.defaults.permissionTimeoutMs", String(settings.delegation.defaults.permissionTimeoutMs), {
|
|
21312
|
-
submenu: editNumberSubmenu("Edit delegate permission timeout (ms)"),
|
|
22412
|
+
submenu: editNumberSubmenu("Edit delegate permission timeout (ms)", "delegation.defaults.permissionTimeoutMs"),
|
|
21313
22413
|
affordance: "free text"
|
|
21314
22414
|
}),
|
|
21315
22415
|
settingItem("keybindings", keybindingCount > 0 ? `${keybindingCount} override(s)` : "(defaults)", {
|
|
@@ -21527,6 +22627,32 @@ function fleetNodeRows(nodes) {
|
|
|
21527
22627
|
});
|
|
21528
22628
|
});
|
|
21529
22629
|
}
|
|
22630
|
+
function fleetEndpointRows(providers) {
|
|
22631
|
+
if (providers === void 0) return [];
|
|
22632
|
+
let usage = {};
|
|
22633
|
+
try {
|
|
22634
|
+
usage = capacityLeaseUsage().endpoints;
|
|
22635
|
+
} catch {
|
|
22636
|
+
}
|
|
22637
|
+
const capacities = endpointCapacitiesForStatuses(providers.list());
|
|
22638
|
+
const targetsByEndpoint = /* @__PURE__ */ new Map();
|
|
22639
|
+
for (const status of providers.list()) {
|
|
22640
|
+
const endpoint = endpointCapacityForStatus(status);
|
|
22641
|
+
if (endpoint === null) continue;
|
|
22642
|
+
targetsByEndpoint.set(endpoint.key, [...targetsByEndpoint.get(endpoint.key) ?? [], status.target.id]);
|
|
22643
|
+
}
|
|
22644
|
+
return Object.entries(capacities).map(([key, endpoint]) => {
|
|
22645
|
+
const slots = `slots ${usage[key] ?? 0}/${endpoint.limit}`;
|
|
22646
|
+
return settingItem(`fleet.endpoints.${key}`, slots, {
|
|
22647
|
+
label: `endpoint ${endpoint.label}`,
|
|
22648
|
+
description: `Targets: ${(targetsByEndpoint.get(key) ?? []).join(", ")} \xB7 Limit source: ${endpoint.source}`,
|
|
22649
|
+
affordance: "read-only inference endpoint capacity",
|
|
22650
|
+
readOnly: true,
|
|
22651
|
+
presentationKind: "status",
|
|
22652
|
+
valueSegments: [{ text: slots, tone: "neutral" }]
|
|
22653
|
+
});
|
|
22654
|
+
});
|
|
22655
|
+
}
|
|
21530
22656
|
function buildSettingsSections(items) {
|
|
21531
22657
|
return SETTINGS_SECTIONS.map((section2) => ({
|
|
21532
22658
|
id: section2.id,
|
|
@@ -21572,9 +22698,10 @@ function applyNonNegativeInteger(value, set) {
|
|
|
21572
22698
|
const parsed = Number(value);
|
|
21573
22699
|
if (Number.isFinite(parsed) && parsed >= 0) set(Math.floor(parsed));
|
|
21574
22700
|
}
|
|
21575
|
-
function
|
|
21576
|
-
const
|
|
21577
|
-
if (
|
|
22701
|
+
function applyNumberSetting(id, value, set) {
|
|
22702
|
+
const outcome = parseNumberSetting(value, NUMBER_SETTING_RULES[id]);
|
|
22703
|
+
if ("refusal" in outcome) return;
|
|
22704
|
+
set(outcome.value);
|
|
21578
22705
|
}
|
|
21579
22706
|
function applyDelegationAgentChange(settings, value) {
|
|
21580
22707
|
if (value.startsWith(DELEGATION_REMOVE_PREFIX)) {
|
|
@@ -21733,15 +22860,12 @@ function applySettingChange(settings, id, value) {
|
|
|
21733
22860
|
else delete settings.watchdog.target;
|
|
21734
22861
|
return;
|
|
21735
22862
|
}
|
|
21736
|
-
case "watchdog.cadenceToolCalls":
|
|
21737
|
-
|
|
21738
|
-
delete settings.watchdog.cadenceToolCalls;
|
|
21739
|
-
|
|
21740
|
-
}
|
|
21741
|
-
const parsed = Number(value);
|
|
21742
|
-
if (Number.isFinite(parsed) && Math.floor(parsed) >= 1) settings.watchdog.cadenceToolCalls = Math.floor(parsed);
|
|
22863
|
+
case "watchdog.cadenceToolCalls":
|
|
22864
|
+
applyNumberSetting("watchdog.cadenceToolCalls", value, (next) => {
|
|
22865
|
+
if (next === null) delete settings.watchdog.cadenceToolCalls;
|
|
22866
|
+
else settings.watchdog.cadenceToolCalls = next;
|
|
22867
|
+
});
|
|
21743
22868
|
return;
|
|
21744
|
-
}
|
|
21745
22869
|
case "terminal.smoothStreaming":
|
|
21746
22870
|
if (value === "off" || value === "auto" || value === "on") settings.terminal.smoothStreaming = value;
|
|
21747
22871
|
return;
|
|
@@ -21749,18 +22873,18 @@ function applySettingChange(settings, id, value) {
|
|
|
21749
22873
|
settings.runtimePlugins = value.split(",").map((entry) => entry.trim()).filter(Boolean);
|
|
21750
22874
|
return;
|
|
21751
22875
|
case "delegation.defaults.connectTimeoutMs":
|
|
21752
|
-
|
|
21753
|
-
settings.delegation.defaults.connectTimeoutMs = next;
|
|
22876
|
+
applyNumberSetting("delegation.defaults.connectTimeoutMs", value, (next) => {
|
|
22877
|
+
if (next !== null) settings.delegation.defaults.connectTimeoutMs = next;
|
|
21754
22878
|
});
|
|
21755
22879
|
return;
|
|
21756
22880
|
case "delegation.defaults.turnTimeoutMs":
|
|
21757
|
-
|
|
21758
|
-
settings.delegation.defaults.turnTimeoutMs = next;
|
|
22881
|
+
applyNumberSetting("delegation.defaults.turnTimeoutMs", value, (next) => {
|
|
22882
|
+
if (next !== null) settings.delegation.defaults.turnTimeoutMs = next;
|
|
21759
22883
|
});
|
|
21760
22884
|
return;
|
|
21761
22885
|
case "delegation.defaults.permissionTimeoutMs":
|
|
21762
|
-
|
|
21763
|
-
settings.delegation.defaults.permissionTimeoutMs = next;
|
|
22886
|
+
applyNumberSetting("delegation.defaults.permissionTimeoutMs", value, (next) => {
|
|
22887
|
+
if (next !== null) settings.delegation.defaults.permissionTimeoutMs = next;
|
|
21764
22888
|
});
|
|
21765
22889
|
return;
|
|
21766
22890
|
case "orchestrator.target": {
|
|
@@ -21799,11 +22923,11 @@ function applySettingChange(settings, id, value) {
|
|
|
21799
22923
|
case "scope":
|
|
21800
22924
|
settings.scope = parseScopedModelSelection(value) ?? value.split(",").map((v) => v.trim()).filter(Boolean);
|
|
21801
22925
|
return;
|
|
21802
|
-
case "budget.sessionCeilingUsd":
|
|
21803
|
-
|
|
21804
|
-
|
|
22926
|
+
case "budget.sessionCeilingUsd":
|
|
22927
|
+
applyNumberSetting("budget.sessionCeilingUsd", value, (next) => {
|
|
22928
|
+
if (next !== null) settings.budget.sessionCeilingUsd = next;
|
|
22929
|
+
});
|
|
21805
22930
|
return;
|
|
21806
|
-
}
|
|
21807
22931
|
}
|
|
21808
22932
|
}
|
|
21809
22933
|
function applyEntrySettingChange(settings, id, value) {
|
|
@@ -24718,6 +25842,8 @@ ${usage}` : usage);
|
|
|
24718
25842
|
const result = ctx.verifyReceipt(command.runId);
|
|
24719
25843
|
if (result.ok) {
|
|
24720
25844
|
ctx.notice("success", `verify ok ${command.runId}`);
|
|
25845
|
+
} else if (result.retired !== void 0) {
|
|
25846
|
+
ctx.notice("warn", `verify retired ${command.runId} ${result.reason}`);
|
|
24721
25847
|
} else {
|
|
24722
25848
|
ctx.notice("error", `verify fail ${command.runId} ${result.reason}`);
|
|
24723
25849
|
}
|
|
@@ -24966,8 +26092,8 @@ function dispatchSlashCommand(command, ctx) {
|
|
|
24966
26092
|
ctx.submitChat(command.text);
|
|
24967
26093
|
return "accepted";
|
|
24968
26094
|
}
|
|
24969
|
-
const
|
|
24970
|
-
ctx.notice("error",
|
|
26095
|
+
const refusal2 = expansion?.expanded === false ? expansion.refusal : void 0;
|
|
26096
|
+
ctx.notice("error", refusal2 ? refusal2.message : `/${command.token} is not a command. Type /help for the list.`);
|
|
24971
26097
|
ctx.render();
|
|
24972
26098
|
return "rejected";
|
|
24973
26099
|
}
|
|
@@ -25418,7 +26544,10 @@ function createOverlayGeneralOpeners(deps) {
|
|
|
25418
26544
|
if (deps.transitions.state !== "closed") return;
|
|
25419
26545
|
deps.transitions.state = "cost";
|
|
25420
26546
|
deps.transitions.handle = openCostOverlayFactory(deps.tui, deps.observability, {
|
|
25421
|
-
sessionId: deps.getSessionId?.() ?? null
|
|
26547
|
+
sessionId: deps.getSessionId?.() ?? null,
|
|
26548
|
+
...deps.readSessionEntries ? {
|
|
26549
|
+
getSessionEntries: () => deps.readSessionEntries?.() ?? []
|
|
26550
|
+
} : {}
|
|
25422
26551
|
});
|
|
25423
26552
|
deps.requestRender();
|
|
25424
26553
|
};
|
|
@@ -25663,10 +26792,17 @@ function createOverlayGeneralOpeners(deps) {
|
|
|
25663
26792
|
};
|
|
25664
26793
|
const resolution = deps.dispatch.preview?.(request);
|
|
25665
26794
|
if (!resolution) return null;
|
|
26795
|
+
const foregroundHeld = resolution.endpoint === void 0 ? 0 : foregroundStreamUsage()[resolution.endpoint.key] ?? 0;
|
|
25666
26796
|
return {
|
|
25667
26797
|
targetId: resolution.targetId,
|
|
25668
26798
|
wireModelId: resolution.wireModelId,
|
|
25669
|
-
nodeId: resolution.node.id
|
|
26799
|
+
nodeId: resolution.node.id,
|
|
26800
|
+
...resolution.endpoint !== void 0 ? {
|
|
26801
|
+
endpoint: {
|
|
26802
|
+
...resolution.endpoint,
|
|
26803
|
+
...foregroundHeld > 0 ? { foregroundHeld } : {}
|
|
26804
|
+
}
|
|
26805
|
+
} : {}
|
|
25670
26806
|
};
|
|
25671
26807
|
}
|
|
25672
26808
|
});
|
|
@@ -25853,12 +26989,41 @@ function permissionOverlayPlacement(tui, editor, footer) {
|
|
|
25853
26989
|
};
|
|
25854
26990
|
}
|
|
25855
26991
|
var PermissionOverlayBody = class {
|
|
25856
|
-
constructor(view) {
|
|
26992
|
+
constructor(view, inspect) {
|
|
25857
26993
|
this.view = view;
|
|
26994
|
+
this.inspect = inspect;
|
|
25858
26995
|
}
|
|
25859
26996
|
view;
|
|
26997
|
+
inspect;
|
|
26998
|
+
preview = null;
|
|
26999
|
+
scroll = 0;
|
|
27000
|
+
lastLineCount = 0;
|
|
27001
|
+
canInspect() {
|
|
27002
|
+
return this.inspect !== void 0;
|
|
27003
|
+
}
|
|
27004
|
+
isInspecting() {
|
|
27005
|
+
return this.preview !== null;
|
|
27006
|
+
}
|
|
27007
|
+
toggleInspect() {
|
|
27008
|
+
if (this.inspect === void 0) return;
|
|
27009
|
+
if (this.preview !== null) {
|
|
27010
|
+
this.preview = null;
|
|
27011
|
+
this.scroll = 0;
|
|
27012
|
+
return;
|
|
27013
|
+
}
|
|
27014
|
+
this.preview = this.inspect();
|
|
27015
|
+
this.scroll = 0;
|
|
27016
|
+
}
|
|
27017
|
+
scrollInspect(delta) {
|
|
27018
|
+
if (this.preview === null) return;
|
|
27019
|
+
const maxScroll = Math.max(0, this.lastLineCount - MUTATION_PREVIEW_VISIBLE_ROWS);
|
|
27020
|
+
this.scroll = Math.max(0, Math.min(this.scroll + delta, maxScroll));
|
|
27021
|
+
}
|
|
25860
27022
|
render(width) {
|
|
25861
|
-
return permissionOverlayLines(this.view, width);
|
|
27023
|
+
if (this.preview === null) return permissionOverlayLines(this.view, width);
|
|
27024
|
+
const rendered = permissionInspectionLines(this.view, this.preview, width, this.scroll);
|
|
27025
|
+
this.lastLineCount = rendered.wrappedLineCount;
|
|
27026
|
+
return rendered.lines;
|
|
25862
27027
|
}
|
|
25863
27028
|
invalidate() {
|
|
25864
27029
|
}
|
|
@@ -25919,18 +27084,66 @@ function permissionOverlayTitle(view) {
|
|
|
25919
27084
|
function permissionOverlayTone(view) {
|
|
25920
27085
|
return permissionDecisionPresentation(view).semanticToken;
|
|
25921
27086
|
}
|
|
25922
|
-
function permissionOverlayHint(innerWidth, composerHasDraft = false) {
|
|
25923
|
-
return fitHintEntries(permissionHintEntries(composerHasDraft), innerWidth - 3);
|
|
27087
|
+
function permissionOverlayHint(innerWidth, composerHasDraft = false, inspection = "none") {
|
|
27088
|
+
return fitHintEntries(permissionHintEntries(composerHasDraft, inspection), innerWidth - 3);
|
|
27089
|
+
}
|
|
27090
|
+
function isFileMutationTool(tool) {
|
|
27091
|
+
return tool === "write" || tool === "edit";
|
|
25924
27092
|
}
|
|
25925
27093
|
function actionConsequence(presentation, id) {
|
|
25926
27094
|
return presentation.requiredActions.find((action) => action.id === id)?.consequence ?? "";
|
|
25927
27095
|
}
|
|
27096
|
+
function wrapMutationLine(value, max) {
|
|
27097
|
+
if (max <= 1) return [value];
|
|
27098
|
+
if (value.length <= max) return [value];
|
|
27099
|
+
const lines = [];
|
|
27100
|
+
let remaining = value;
|
|
27101
|
+
while (remaining.length > max) {
|
|
27102
|
+
lines.push(`${remaining.slice(0, max - 1)}\u21A9`);
|
|
27103
|
+
remaining = remaining.slice(max - 1);
|
|
27104
|
+
}
|
|
27105
|
+
lines.push(remaining);
|
|
27106
|
+
return lines;
|
|
27107
|
+
}
|
|
27108
|
+
function permissionInspectionLines(view, preview, width, scroll) {
|
|
27109
|
+
const content = Math.max(8, Math.floor(width));
|
|
27110
|
+
const wrapped = preview.body.flatMap((line) => wrapMutationLine(line, content));
|
|
27111
|
+
const pane = mutationPreviewWindow(wrapped, scroll);
|
|
27112
|
+
const notes = [];
|
|
27113
|
+
if (preview.neutralized) notes.push("control characters shown as \xB7");
|
|
27114
|
+
if (preview.tabsExpanded) notes.push("tabs shown as spaces");
|
|
27115
|
+
const lines = [
|
|
27116
|
+
field("Tool: ", `${view.tool} \xB7 Action: ${view.actionClass}`, content),
|
|
27117
|
+
...view.target !== void 0 && view.target.length > 0 ? [field("Target: ", view.target, content)] : [],
|
|
27118
|
+
...wrapSentence(`Mutation: ${mutationFactsLine(preview.facts)}`, content),
|
|
27119
|
+
"",
|
|
27120
|
+
...wrapSentence(preview.heading, content),
|
|
27121
|
+
...pane.window,
|
|
27122
|
+
...pane.position === null ? [] : [pane.position],
|
|
27123
|
+
...notes.length > 0 ? [`Rendered safely: ${notes.join(", ")}.`] : []
|
|
27124
|
+
];
|
|
27125
|
+
return { lines, wrappedLineCount: wrapped.length };
|
|
27126
|
+
}
|
|
25928
27127
|
function permissionOverlayLines(view, width) {
|
|
25929
27128
|
const content = Math.max(8, Math.floor(width));
|
|
25930
27129
|
const presentation = permissionDecisionPresentation(view);
|
|
25931
27130
|
const lines = [
|
|
25932
27131
|
field("Tool: ", `${view.tool} \xB7 Action: ${view.actionClass}`, content),
|
|
25933
27132
|
...view.target !== void 0 && view.target.length > 0 ? [field("Target: ", view.target, content)] : [],
|
|
27133
|
+
// Size and digest stay on the collapsed card whether or not the operator
|
|
27134
|
+
// opens the mutation, so the decision always carries the identity of the
|
|
27135
|
+
// bytes it applies to.
|
|
27136
|
+
// Wrapped, never ellipsized: at 40 columns the digest is the tail of the
|
|
27137
|
+
// line, and ellipsizing it would drop the one fact that ties the decision
|
|
27138
|
+
// to the bytes it applies to.
|
|
27139
|
+
...view.mutation !== void 0 ? [
|
|
27140
|
+
...wrapSentence(`Mutation: ${mutationFactsLine(view.mutation)}`, content),
|
|
27141
|
+
...wrapSentence(`Press ${MUTATION_PREVIEW_KEY} to read it before deciding.`, content)
|
|
27142
|
+
] : [],
|
|
27143
|
+
...view.mutation === void 0 && view.origin.kind === "worker" && isFileMutationTool(view.tool) ? wrapSentence(
|
|
27144
|
+
"No local preview: this call's arguments stay inside the worker, so you are approving the target above without inspecting the mutation.",
|
|
27145
|
+
content
|
|
27146
|
+
) : [],
|
|
25934
27147
|
...wrapSentence(`Requested by: ${presentation.requestedByCopy}`, content),
|
|
25935
27148
|
...view.artifact !== void 0 ? [
|
|
25936
27149
|
"",
|
|
@@ -25950,8 +27163,8 @@ function permissionOverlayLines(view, width) {
|
|
|
25950
27163
|
}
|
|
25951
27164
|
return lines;
|
|
25952
27165
|
}
|
|
25953
|
-
function createPermissionOverlayBody(view) {
|
|
25954
|
-
return new PermissionOverlayBody(view);
|
|
27166
|
+
function createPermissionOverlayBody(view, inspect) {
|
|
27167
|
+
return new PermissionOverlayBody(view, inspect);
|
|
25955
27168
|
}
|
|
25956
27169
|
|
|
25957
27170
|
// src/interactive/bus-notices.ts
|
|
@@ -26172,6 +27385,7 @@ function mainApprovalRequestView(call, decision, meta, autonomy, queueDepth) {
|
|
|
26172
27385
|
const axisFromDecision = askAxis(decision);
|
|
26173
27386
|
const axis = axisFromMeta ?? (axisFromDecision.kind === "net" ? { kind: "net", ruleId: axisFromDecision.ruleId } : { kind: "autonomy", level: autonomy });
|
|
26174
27387
|
const target = describeCallTarget(call.tool, call.args);
|
|
27388
|
+
const mutation = mutationFacts(call.tool, call.args);
|
|
26175
27389
|
return {
|
|
26176
27390
|
requestId: meta?.requestId ?? "permission-pending",
|
|
26177
27391
|
tool: call.tool,
|
|
@@ -26182,9 +27396,14 @@ function mainApprovalRequestView(call, decision, meta, autonomy, queueDepth) {
|
|
|
26182
27396
|
...call.tool === ToolNames.Dispatch && decision.kind === "ask" ? { artifact: { kind: "dispatch-plan", text: decision.rejection.detail } } : {},
|
|
26183
27397
|
...call.tool === ToolNames.AskUser ? { exposure: askUserExposure(call.args) } : {},
|
|
26184
27398
|
...target.length > 0 ? { target } : {},
|
|
27399
|
+
...mutation !== null ? { mutation } : {},
|
|
26185
27400
|
...queueDepth !== void 0 && queueDepth > 1 ? { queueDepth } : {}
|
|
26186
27401
|
};
|
|
26187
27402
|
}
|
|
27403
|
+
function mainMutationInspector(call, view) {
|
|
27404
|
+
if (view.mutation === void 0) return void 0;
|
|
27405
|
+
return createMutationInspector(call.tool, call.args, view.mutation);
|
|
27406
|
+
}
|
|
26188
27407
|
function workerEscalationEntry(payload, autonomy) {
|
|
26189
27408
|
if (!isLiveWorkerEscalationRequest(payload) || typeof payload.requestId !== "string") return null;
|
|
26190
27409
|
const origin = typeof payload.origin === "string" ? payload.origin : void 0;
|
|
@@ -26258,7 +27477,7 @@ function createOverlayPermissionLifecycle(deps) {
|
|
|
26258
27477
|
announceParked();
|
|
26259
27478
|
return;
|
|
26260
27479
|
}
|
|
26261
|
-
if (!deps.openPermissionOverlay(view)) {
|
|
27480
|
+
if (!deps.openPermissionOverlay(view, mainMutationInspector(call, view))) {
|
|
26262
27481
|
announceParked();
|
|
26263
27482
|
return;
|
|
26264
27483
|
}
|
|
@@ -26646,7 +27865,8 @@ function openHelpOverlay(tui, manager, onClose, initialFilter) {
|
|
|
26646
27865
|
"**Tool surface**: which tools exist at all through registration, tool profiles, skill narrowing, and dispatch admission. Violations are terminal denials, never approvable.",
|
|
26647
27866
|
"**Safety net** (always on, level-independent): damage-control rules, path policy for secrets and system paths, command-substitution confirmation, and `git_destructive` blocks. Blocks are final at every level; confirm rails ask at every level.",
|
|
26648
27867
|
"**Autonomy level** (`/settings`, persisted as `autonomy`): the operator's standing grant per action class for actions the net passed, enforced by the harness at tool admission. read-only denies non-read, suggest parks every non-read call, auto-edit parks unrecognized commands, and full-auto runs them.",
|
|
26649
|
-
"**Approvals**: a parked call waits for a one-shot operator decision; approving resumes only that call. Workers resolve asks per `workers.onPermission` (Approvals Routing); headless runs auto-deny."
|
|
27868
|
+
"**Approvals**: a parked call waits for a one-shot operator decision; approving resumes only that call. Workers resolve asks per `workers.onPermission` (Approvals Routing); headless runs auto-deny.",
|
|
27869
|
+
"**Inspecting a mutation**: a parked `write` or `edit` card carries the target, the byte count, and a `sha256` digest of the exact call arguments. Press `v` to read the complete proposed content, or the complete effective diff against the file on disk, and `v` again to put it away; \u2191/\u2193 and PageUp/PageDown scroll it. Enter still allows, `s` still stops, and Esc still denies while it is open. The mutation text is shown locally and never enters the transcript, a notice, a desktop notification, or the render trace. A worker escalation has no preview because the call's arguments never leave the worker, and its card says so."
|
|
26650
27870
|
]
|
|
26651
27871
|
}
|
|
26652
27872
|
];
|
|
@@ -26779,13 +27999,16 @@ function openPromptsOverlay(tui, ctx, onClose) {
|
|
|
26779
27999
|
lines.push(`**Argument Hint:** \`${template.argumentHint}\``);
|
|
26780
28000
|
}
|
|
26781
28001
|
lines.push(`**Source:** ${template.sourceInfo.source ?? template.sourceInfo.scope}`);
|
|
28002
|
+
if (template.unavailable !== void 0) {
|
|
28003
|
+
lines.push(`**Unavailable:** ${template.unavailable}`);
|
|
28004
|
+
}
|
|
26782
28005
|
if (!template.trusted) {
|
|
26783
28006
|
lines.push("**Untrusted:** set `skills.trustProjectCompatRoots` before this template will expand.");
|
|
26784
28007
|
}
|
|
26785
28008
|
return lines;
|
|
26786
28009
|
}
|
|
26787
28010
|
};
|
|
26788
|
-
const marker = template.trusted ? void 0 : clioTheme().fg("warning", "untrusted");
|
|
28011
|
+
const marker = template.unavailable !== void 0 ? clioTheme().fg("error", "unavailable") : template.trusted ? void 0 : clioTheme().fg("warning", "untrusted");
|
|
26789
28012
|
if (marker) item.meta = template.argumentHint ? `${template.argumentHint} \xB7 ${marker}` : marker;
|
|
26790
28013
|
else if (template.argumentHint) item.meta = template.argumentHint;
|
|
26791
28014
|
return item;
|
|
@@ -26945,7 +28168,7 @@ function runCompactWithNotice(onCompact, notice, instructions) {
|
|
|
26945
28168
|
init_esm_shims();
|
|
26946
28169
|
import { spawnSync } from "node:child_process";
|
|
26947
28170
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
26948
|
-
import { readFileSync as
|
|
28171
|
+
import { readFileSync as readFileSync8, unlinkSync, writeFileSync } from "node:fs";
|
|
26949
28172
|
import { tmpdir } from "node:os";
|
|
26950
28173
|
import { join as join7 } from "node:path";
|
|
26951
28174
|
function defaultProbe(candidates) {
|
|
@@ -26985,7 +28208,7 @@ function editTextExternally(initialText, command) {
|
|
|
26985
28208
|
const result = runEditor(command, tmpFile);
|
|
26986
28209
|
if (result.error) return { ok: false, error: result.error.message };
|
|
26987
28210
|
if (result.status !== 0) return { ok: false, error: `external editor exited with code ${result.status ?? "?"}` };
|
|
26988
|
-
return { ok: true, text:
|
|
28211
|
+
return { ok: true, text: readFileSync8(tmpFile, "utf8").replace(/\n$/, "") };
|
|
26989
28212
|
} finally {
|
|
26990
28213
|
try {
|
|
26991
28214
|
unlinkSync(tmpFile);
|
|
@@ -28242,19 +29465,54 @@ function createOverlaySessionLifecycle(deps) {
|
|
|
28242
29465
|
}
|
|
28243
29466
|
void runHandoffExtraction(session, fromSessionId, verdict.goal);
|
|
28244
29467
|
}
|
|
29468
|
+
const HANDOFF_REFUSAL_QUOTE_CHARS = 200;
|
|
29469
|
+
function terminalHandoffRefusal(firstReason, secondReason, secondText) {
|
|
29470
|
+
const answered = secondText.replace(/\s+/g, " ").trim().slice(0, HANDOFF_REFUSAL_QUOTE_CHARS);
|
|
29471
|
+
return [
|
|
29472
|
+
"the extraction round could not produce a handoff record after one repair attempt.",
|
|
29473
|
+
`Asked for: one JSON object with decisions, facts, files, commands, and openQuestions.`,
|
|
29474
|
+
`Round 1: ${firstReason}.`,
|
|
29475
|
+
`Round 2: ${secondReason}.`,
|
|
29476
|
+
`Round 2 returned: ${answered.length > 0 ? answered : "(nothing)"}`
|
|
29477
|
+
].join(" ");
|
|
29478
|
+
}
|
|
29479
|
+
async function extractWithOneRepair(goal) {
|
|
29480
|
+
const first = await deps.chat.extractHandoff(goal);
|
|
29481
|
+
if (first.status !== "answered") {
|
|
29482
|
+
return {
|
|
29483
|
+
ok: false,
|
|
29484
|
+
level: first.status === "failed" ? "error" : "warn",
|
|
29485
|
+
reason: first.status === "aborted" ? "the extraction round was cancelled" : first.reason
|
|
29486
|
+
};
|
|
29487
|
+
}
|
|
29488
|
+
const parsedFirst = parseHandoffExtraction(first.text);
|
|
29489
|
+
if (parsedFirst.ok) return { ok: true, parsed: parsedFirst };
|
|
29490
|
+
const second = await deps.chat.extractHandoff(goal, {
|
|
29491
|
+
repair: { complaint: parsedFirst.reason, previous: first.text }
|
|
29492
|
+
});
|
|
29493
|
+
if (second.status !== "answered") {
|
|
29494
|
+
return {
|
|
29495
|
+
ok: false,
|
|
29496
|
+
level: second.status === "failed" ? "error" : "warn",
|
|
29497
|
+
reason: second.status === "aborted" ? "the repair round was cancelled" : `round 1 could not be read (${parsedFirst.reason}); the repair round then failed: ${second.reason}`
|
|
29498
|
+
};
|
|
29499
|
+
}
|
|
29500
|
+
const parsedSecond = parseHandoffExtraction(second.text);
|
|
29501
|
+
if (parsedSecond.ok) return { ok: true, parsed: parsedSecond };
|
|
29502
|
+
return {
|
|
29503
|
+
ok: false,
|
|
29504
|
+
level: "error",
|
|
29505
|
+
reason: terminalHandoffRefusal(parsedFirst.reason, parsedSecond.reason, second.text)
|
|
29506
|
+
};
|
|
29507
|
+
}
|
|
28245
29508
|
async function runHandoffExtraction(session, fromSessionId, goal) {
|
|
28246
29509
|
const notice = deps.getSlashNotice();
|
|
28247
|
-
const
|
|
28248
|
-
if (
|
|
28249
|
-
|
|
28250
|
-
emitCommandNotice(notice, outcome.status === "failed" ? "error" : "warn", "handoff", reason);
|
|
28251
|
-
return;
|
|
28252
|
-
}
|
|
28253
|
-
const parsed = parseHandoffExtraction(outcome.text);
|
|
28254
|
-
if (!parsed.ok) {
|
|
28255
|
-
emitCommandNotice(notice, "error", "handoff", parsed.reason);
|
|
29510
|
+
const extraction = await extractWithOneRepair(goal);
|
|
29511
|
+
if (!extraction.ok) {
|
|
29512
|
+
emitCommandNotice(notice, extraction.level, "handoff", extraction.reason);
|
|
28256
29513
|
return;
|
|
28257
29514
|
}
|
|
29515
|
+
const parsed = extraction.parsed;
|
|
28258
29516
|
const meta = session.current();
|
|
28259
29517
|
const cwd = typeof meta?.cwd === "string" && meta.cwd.length > 0 ? meta.cwd : null;
|
|
28260
29518
|
const entries = deps.readStructuredEntries(fromSessionId);
|
|
@@ -28433,6 +29691,14 @@ var DRAFT_EDIT_KEYS = ["backspace", "delete", "ctrl+u", "ctrl+w", "alt+backspace
|
|
|
28433
29691
|
function isDraftEditKey(data) {
|
|
28434
29692
|
return !isKeyRelease(data) && DRAFT_EDIT_KEYS.some((key) => matchesKey(data, key));
|
|
28435
29693
|
}
|
|
29694
|
+
var MUTATION_PAGE_ROWS = 16;
|
|
29695
|
+
function mutationScrollDelta(data) {
|
|
29696
|
+
if (matchesKey(data, "up")) return -1;
|
|
29697
|
+
if (matchesKey(data, "down")) return 1;
|
|
29698
|
+
if (matchesKey(data, "pageUp")) return -MUTATION_PAGE_ROWS;
|
|
29699
|
+
if (matchesKey(data, "pageDown")) return MUTATION_PAGE_ROWS;
|
|
29700
|
+
return 0;
|
|
29701
|
+
}
|
|
28436
29702
|
function routePermissionOverlayKey(data, deps) {
|
|
28437
29703
|
if (matchesKey(data, "enter") && !isKeyRelease(data)) {
|
|
28438
29704
|
if (!(deps.composerHasDraft?.() ?? false)) deps.confirmPermission();
|
|
@@ -28442,6 +29708,17 @@ function routePermissionOverlayKey(data, deps) {
|
|
|
28442
29708
|
deps.editDraft(data);
|
|
28443
29709
|
return true;
|
|
28444
29710
|
}
|
|
29711
|
+
if (matchesKey(data, MUTATION_PREVIEW_KEY) && !isKeyRelease(data) && (deps.canInspectMutation?.() ?? false) && deps.toggleMutationInspection) {
|
|
29712
|
+
deps.toggleMutationInspection();
|
|
29713
|
+
return true;
|
|
29714
|
+
}
|
|
29715
|
+
if ((deps.isInspectingMutation?.() ?? false) && deps.scrollMutationInspection && !isKeyRelease(data)) {
|
|
29716
|
+
const delta = mutationScrollDelta(data);
|
|
29717
|
+
if (delta !== 0) {
|
|
29718
|
+
deps.scrollMutationInspection(delta);
|
|
29719
|
+
return true;
|
|
29720
|
+
}
|
|
29721
|
+
}
|
|
28445
29722
|
if (isEscapeKey(data)) {
|
|
28446
29723
|
deps.cancelPermission();
|
|
28447
29724
|
return true;
|
|
@@ -28616,6 +29893,11 @@ function createOverlayLifecycle(deps) {
|
|
|
28616
29893
|
} = deps;
|
|
28617
29894
|
let overlayPermission = null;
|
|
28618
29895
|
let overlayAskUser = null;
|
|
29896
|
+
let permissionBody = null;
|
|
29897
|
+
const inspectionHint = () => {
|
|
29898
|
+
if (permissionBody === null || !permissionBody.canInspect()) return "none";
|
|
29899
|
+
return permissionBody.isInspecting() ? "open" : "closed";
|
|
29900
|
+
};
|
|
28619
29901
|
const overlayTransitions = createOverlayTransitions({
|
|
28620
29902
|
stopDispatchBoardTicker: () => interactiveTickers.stopDispatchBoardTicker(),
|
|
28621
29903
|
renderContextIsland: () => interactiveTickers.renderContextIsland(),
|
|
@@ -28623,7 +29905,10 @@ function createOverlayLifecycle(deps) {
|
|
|
28623
29905
|
requestRender: () => tui.requestRender(),
|
|
28624
29906
|
cancelPendingAskUser: () => overlayAskUser?.cancelPending() ?? false,
|
|
28625
29907
|
finishAuth: (dismiss) => overlayAuth.finish(dismiss),
|
|
28626
|
-
onPermissionOverlayClosed: () =>
|
|
29908
|
+
onPermissionOverlayClosed: () => {
|
|
29909
|
+
permissionBody = null;
|
|
29910
|
+
overlayPermission?.onPermissionOverlayClosed();
|
|
29911
|
+
},
|
|
28627
29912
|
onOverlayClosed: () => overlayPermission?.retryPending()
|
|
28628
29913
|
});
|
|
28629
29914
|
const closeOverlay = overlayTransitions.close;
|
|
@@ -28652,17 +29937,20 @@ function createOverlayLifecycle(deps) {
|
|
|
28652
29937
|
dispatch: deps.app.dispatch,
|
|
28653
29938
|
getAutonomy: () => deps.app.getSettings?.().autonomy ?? "auto-edit",
|
|
28654
29939
|
getOverlayState: () => overlayTransitions.state,
|
|
28655
|
-
openPermissionOverlay: (view) => {
|
|
29940
|
+
openPermissionOverlay: (view, inspect) => {
|
|
28656
29941
|
if (overlayTransitions.state !== "closed") return false;
|
|
28657
29942
|
overlayTransitions.state = "permission-confirm";
|
|
28658
|
-
|
|
29943
|
+
const body = createPermissionOverlayBody(view, inspect);
|
|
29944
|
+
permissionBody = body;
|
|
29945
|
+
overlayTransitions.handle = showOverlayFrame(tui, body, {
|
|
28659
29946
|
...permissionOverlayPlacement(tui, editor, footer.view),
|
|
28660
29947
|
width: PERMISSION_OVERLAY_WIDTH,
|
|
28661
29948
|
title: permissionOverlayTitle(view),
|
|
28662
29949
|
tone: permissionOverlayTone(view),
|
|
28663
29950
|
// Read per frame: the footer names what Enter does right now, and
|
|
28664
|
-
// that depends on whether the composer holds a draft
|
|
28665
|
-
|
|
29951
|
+
// that depends on whether the composer holds a draft and on whether
|
|
29952
|
+
// the mutation is open.
|
|
29953
|
+
footerHint: (innerWidth) => permissionOverlayHint(innerWidth, editor.getText().length > 0, inspectionHint())
|
|
28666
29954
|
});
|
|
28667
29955
|
tui.requestRender();
|
|
28668
29956
|
return true;
|
|
@@ -28860,6 +30148,16 @@ function createOverlayLifecycle(deps) {
|
|
|
28860
30148
|
footer.refresh();
|
|
28861
30149
|
tui.requestRender();
|
|
28862
30150
|
},
|
|
30151
|
+
canInspectMutation: () => permissionBody?.canInspect() ?? false,
|
|
30152
|
+
isInspectingMutation: () => permissionBody?.isInspecting() ?? false,
|
|
30153
|
+
toggleMutationInspection: () => {
|
|
30154
|
+
permissionBody?.toggleInspect();
|
|
30155
|
+
tui.requestRender();
|
|
30156
|
+
},
|
|
30157
|
+
scrollMutationInspection: (delta) => {
|
|
30158
|
+
permissionBody?.scrollInspect(delta);
|
|
30159
|
+
tui.requestRender();
|
|
30160
|
+
},
|
|
28863
30161
|
cancelAskUser: overlayAskUser.cancel,
|
|
28864
30162
|
dispose: () => {
|
|
28865
30163
|
overlayPermission?.dispose();
|
|
@@ -30083,6 +31381,14 @@ function createInteractiveEventProjection(deps) {
|
|
|
30083
31381
|
})
|
|
30084
31382
|
);
|
|
30085
31383
|
remainingUnsubscribers.push(
|
|
31384
|
+
deps.bus.on(BusChannels.DispatchScopeNotice, (payload) => {
|
|
31385
|
+
const event = payload;
|
|
31386
|
+
if (!event || typeof event !== "object" || !["typed_scope_replaced_inferred_paths", "legacy_scope_inferred", "legacy_scope_empty"].includes(event.code) || typeof event.message !== "string") {
|
|
31387
|
+
return;
|
|
31388
|
+
}
|
|
31389
|
+
deps.appendTranscriptNotice("warn", event.message);
|
|
31390
|
+
deps.requestRender();
|
|
31391
|
+
}),
|
|
30086
31392
|
deps.bus.on(BusChannels.LoopBlocked, (payload) => {
|
|
30087
31393
|
const event = payload;
|
|
30088
31394
|
if (!event || typeof event !== "object" || typeof event.tool !== "string" || typeof event.repeatCount !== "number") {
|
|
@@ -30374,6 +31680,10 @@ function createInteractiveInputRuntime(deps) {
|
|
|
30374
31680
|
confirmPermission: () => deps.overlay.confirmPermission(),
|
|
30375
31681
|
stopTurnFromPermission: () => deps.overlay.stopTurnFromPermission(),
|
|
30376
31682
|
composerHasDraft: () => deps.editor.getText().length > 0,
|
|
31683
|
+
canInspectMutation: () => deps.overlay.canInspectMutation(),
|
|
31684
|
+
isInspectingMutation: () => deps.overlay.isInspectingMutation(),
|
|
31685
|
+
toggleMutationInspection: () => deps.overlay.toggleMutationInspection(),
|
|
31686
|
+
scrollMutationInspection: (delta) => deps.overlay.scrollMutationInspection(delta),
|
|
30377
31687
|
editDraft: (data2) => {
|
|
30378
31688
|
deps.editor.handleInput?.(data2);
|
|
30379
31689
|
deps.requestRender();
|
|
@@ -31205,11 +32515,23 @@ function renderErrorSegmentLines(seg, width) {
|
|
|
31205
32515
|
var CLIO_PREFIX = `${TEAL}${AGENT_GLYPH}${RESET} `;
|
|
31206
32516
|
var CLIO_PREFIX_ERROR = `${RED_CRIT}${AGENT_GLYPH}${RESET} `;
|
|
31207
32517
|
var USER_PREFIX = `${TEAL}${USER_GLYPH}${RESET} `;
|
|
32518
|
+
var USER_PREFIX_PENDING = `${DIM}${USER_GLYPH}${RESET} `;
|
|
32519
|
+
var USER_PENDING_TAIL = " \xB7 preparing";
|
|
32520
|
+
var USER_REFUSED_TAIL = " \xB7 not sent";
|
|
31208
32521
|
var PROSE_GUTTER = " ";
|
|
31209
32522
|
var PROSE_GUTTER_WIDTH = 2;
|
|
31210
32523
|
function hangProseLines(lines, firstPrefix) {
|
|
31211
32524
|
return lines.map((line, index) => `${index === 0 && firstPrefix !== void 0 ? firstPrefix : PROSE_GUTTER}${line}`);
|
|
31212
32525
|
}
|
|
32526
|
+
function appendUserRowTail(rendered, tail, width) {
|
|
32527
|
+
const last = rendered.length - 1;
|
|
32528
|
+
const lastLine = rendered[last];
|
|
32529
|
+
if (lastLine !== void 0 && visibleWidth(lastLine) + tail.length <= width) {
|
|
32530
|
+
rendered[last] = `${lastLine}${DIM}${tail}${RESET}`;
|
|
32531
|
+
return;
|
|
32532
|
+
}
|
|
32533
|
+
rendered.push(`${PROSE_GUTTER}${dimLine(tail.trimStart(), Math.max(1, width - PROSE_GUTTER_WIDTH))}`);
|
|
32534
|
+
}
|
|
31213
32535
|
var THINKING_HIDDEN_LABEL = `Thinking${GLYPH.ellipsis}`;
|
|
31214
32536
|
var THINKING_LINE_LIMIT = 12;
|
|
31215
32537
|
function dimLine(text, width) {
|
|
@@ -31366,8 +32688,11 @@ function renderEntryLines(entry, width, expandKey, latestHintToolId, latestFolde
|
|
|
31366
32688
|
const contentWidth = Math.max(1, width - PROSE_GUTTER_WIDTH);
|
|
31367
32689
|
const lines2 = [];
|
|
31368
32690
|
for (const sourceLine of entry.text.split("\n")) lines2.push(...wrapTextWithAnsi(sourceLine, contentWidth));
|
|
31369
|
-
const
|
|
32691
|
+
const status = entry.status?.() ?? "committed";
|
|
32692
|
+
const rendered = hangProseLines(lines2, status === "committed" ? USER_PREFIX : USER_PREFIX_PENDING);
|
|
31370
32693
|
if (rendered[0] !== void 0) rendered[0] = `${OSC133_PROMPT_START}${rendered[0]}`;
|
|
32694
|
+
if (status !== "committed")
|
|
32695
|
+
appendUserRowTail(rendered, status === "pending" ? USER_PENDING_TAIL : USER_REFUSED_TAIL, width);
|
|
31371
32696
|
return rendered;
|
|
31372
32697
|
}
|
|
31373
32698
|
if (entry.role === "retryStatus") {
|
|
@@ -31667,8 +32992,8 @@ function createChatPanel(options = {}) {
|
|
|
31667
32992
|
(segment) => segment.kind === "tool" && !segment.finished && segment.startedAtMs !== void 0
|
|
31668
32993
|
// The live reasoning line counts its own elapsed, so a turn that is
|
|
31669
32994
|
// only thinking still needs the time-keyed render key.
|
|
31670
|
-
) || entry.pending && openThinkingSegment(entry)?.startedAtMs !== void 0) || entry.role === "replayBlock" && entry.isLive?.() === true;
|
|
31671
|
-
const entryIsStable = (entry) => entry.role === "user" || entry.role === "replayBlock" && entry.isLive?.() !== true || entry.role === "worker" && !entry.state.pending || entry.role === "assistant" && !entry.pending && !entry.segments.some((segment) => segment.kind === "tool" && !segment.finished);
|
|
32995
|
+
) || entry.pending && openThinkingSegment(entry)?.startedAtMs !== void 0) || entry.role === "replayBlock" && entry.isLive?.() === true || entry.role === "user" && (entry.status?.() ?? "committed") !== "committed";
|
|
32996
|
+
const entryIsStable = (entry) => entry.role === "user" && (entry.status?.() ?? "committed") === "committed" || entry.role === "replayBlock" && entry.isLive?.() !== true || entry.role === "worker" && !entry.state.pending || entry.role === "assistant" && !entry.pending && !entry.segments.some((segment) => segment.kind === "tool" && !segment.finished);
|
|
31672
32997
|
const render2 = (width) => {
|
|
31673
32998
|
const startedAt = performance5.now();
|
|
31674
32999
|
const expandKey = resolveExpandKey();
|
|
@@ -31750,8 +33075,8 @@ function createChatPanel(options = {}) {
|
|
|
31750
33075
|
return out;
|
|
31751
33076
|
};
|
|
31752
33077
|
return {
|
|
31753
|
-
appendUser(text) {
|
|
31754
|
-
transcript.push({ role: "user", text });
|
|
33078
|
+
appendUser(text, status) {
|
|
33079
|
+
transcript.push({ role: "user", text, ...status ? { status } : {} });
|
|
31755
33080
|
markDirty();
|
|
31756
33081
|
},
|
|
31757
33082
|
appendReplayBlock(renderBlock, isLive2, fold) {
|
|
@@ -32188,6 +33513,7 @@ init_esm_shims();
|
|
|
32188
33513
|
var CONTEXT_ISLAND_WIDTH = 52;
|
|
32189
33514
|
var PHASES = ["scan", "codewiki", "generate", "clio-md", "state", "done"];
|
|
32190
33515
|
var WIKI_PHASES = ["codewiki", "generate", "state", "done"];
|
|
33516
|
+
var COMPACTION_PHASES = ["compact", "done"];
|
|
32191
33517
|
var PHASE_LABELS = {
|
|
32192
33518
|
scan: "scan",
|
|
32193
33519
|
// "index" rather than "wiki": this phase is the codewiki index build, and
|
|
@@ -32196,6 +33522,7 @@ var PHASE_LABELS = {
|
|
|
32196
33522
|
generate: "draft",
|
|
32197
33523
|
"clio-md": "CLIO-CODER.md",
|
|
32198
33524
|
state: "state",
|
|
33525
|
+
compact: "compact",
|
|
32199
33526
|
done: "done"
|
|
32200
33527
|
};
|
|
32201
33528
|
var WIKI_PHASE_LABELS = {
|
|
@@ -32210,8 +33537,9 @@ var KINDS = /* @__PURE__ */ new Set([
|
|
|
32210
33537
|
"context-wiki",
|
|
32211
33538
|
"compaction"
|
|
32212
33539
|
]);
|
|
32213
|
-
var PHASE_SET = new Set(PHASES);
|
|
33540
|
+
var PHASE_SET = /* @__PURE__ */ new Set([...PHASES, ...COMPACTION_PHASES]);
|
|
32214
33541
|
function phasesFor(kind) {
|
|
33542
|
+
if (kind === "compaction") return COMPACTION_PHASES;
|
|
32215
33543
|
return kind === "context-wiki" ? WIKI_PHASES : PHASES;
|
|
32216
33544
|
}
|
|
32217
33545
|
function phaseLabel(kind, phase) {
|
|
@@ -33516,6 +34844,8 @@ function createInteractivePresentation(deps) {
|
|
|
33516
34844
|
},
|
|
33517
34845
|
isStreaming: () => deps.chat.isStreaming(),
|
|
33518
34846
|
...deps.isAwaitingApproval ? { isAwaitingApproval: deps.isAwaitingApproval } : {},
|
|
34847
|
+
...deps.getPermissionInspection ? { getPermissionInspection: deps.getPermissionInspection } : {},
|
|
34848
|
+
getTurnPreparation: () => deps.chat.turnPreparation().phase,
|
|
33519
34849
|
willEnterSteer: (text) => willEnterSteerActiveWork(deps, text),
|
|
33520
34850
|
getSubmitKeyLabel: () => formatKeyLabel(keybindings.getKeys("tui.input.submit")[0], "Enter"),
|
|
33521
34851
|
getNewlineKeyLabel: () => formatKeyLabel(keybindings.getKeys("tui.input.newLine")[0], "Shift+Enter")
|
|
@@ -34028,9 +35358,9 @@ function createInteractiveSlashRuntime(deps) {
|
|
|
34028
35358
|
const willQueue = deps.chat.isStreaming();
|
|
34029
35359
|
deps.recordSubmittedTurn();
|
|
34030
35360
|
deps.refreshFooter();
|
|
34031
|
-
|
|
35361
|
+
let rowStatus = "pending";
|
|
35362
|
+
if (!willQueue) deps.chatPanel.appendUser(sub.text, () => rowStatus);
|
|
34032
35363
|
deps.requestRender();
|
|
34033
|
-
deps.beforeSemanticSubmit?.();
|
|
34034
35364
|
let acknowledgeAdmission = () => {
|
|
34035
35365
|
};
|
|
34036
35366
|
const admitted = new Promise((resolve7) => {
|
|
@@ -34041,13 +35371,26 @@ function createInteractiveSlashRuntime(deps) {
|
|
|
34041
35371
|
...sub.workingContextPaths.length > 0 ? { workingContextPaths: sub.workingContextPaths } : {},
|
|
34042
35372
|
...sub.pendingSkillRequests.length > 0 ? { pendingSkillRequests: sub.pendingSkillRequests } : {},
|
|
34043
35373
|
...awaitAdmission && willQueue ? { steering: "end-of-turn" } : {},
|
|
34044
|
-
|
|
35374
|
+
...!willQueue ? {
|
|
35375
|
+
onPreparationVisible: async () => {
|
|
35376
|
+
deps.beforeSemanticSubmit?.();
|
|
35377
|
+
await deps.settleVisibleFrame?.("submit-preparing");
|
|
35378
|
+
}
|
|
35379
|
+
} : {},
|
|
35380
|
+
onAdmitted: () => {
|
|
35381
|
+
rowStatus = "committed";
|
|
35382
|
+
deps.requestRender();
|
|
35383
|
+
if (awaitAdmission) acknowledgeAdmission();
|
|
35384
|
+
}
|
|
34045
35385
|
});
|
|
34046
35386
|
const settlement = turn.then(() => deps.settleVisibleFrame?.("submit-return")).catch((err) => {
|
|
34047
35387
|
const msg = err instanceof Error ? err.message : String(err);
|
|
34048
35388
|
deps.io.stderr(`[interactive] chat failed: ${msg}
|
|
34049
35389
|
`);
|
|
34050
|
-
}).finally(
|
|
35390
|
+
}).finally(() => {
|
|
35391
|
+
if (rowStatus === "pending") rowStatus = willQueue ? "committed" : "refused";
|
|
35392
|
+
deps.requestRender();
|
|
35393
|
+
});
|
|
34051
35394
|
return awaitAdmission ? Promise.race([admitted, settlement]) : settlement;
|
|
34052
35395
|
} catch (err) {
|
|
34053
35396
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -34801,6 +36144,13 @@ async function createInteractiveApplication(deps) {
|
|
|
34801
36144
|
});
|
|
34802
36145
|
const { terminal, tui } = shell;
|
|
34803
36146
|
const renderTrace = getActiveRenderTrace();
|
|
36147
|
+
const dumpInputWedgeOnTerminate = renderTrace ? () => {
|
|
36148
|
+
try {
|
|
36149
|
+
writeInputWedgeDump(clioStateDir(), renderTrace.snapshotInputWedge());
|
|
36150
|
+
} catch {
|
|
36151
|
+
}
|
|
36152
|
+
} : null;
|
|
36153
|
+
if (dumpInputWedgeOnTerminate) process.on("SIGTERM", dumpInputWedgeOnTerminate);
|
|
34804
36154
|
const visibleEventIngress = /* @__PURE__ */ new WeakMap();
|
|
34805
36155
|
let visibleEventSequence = 0;
|
|
34806
36156
|
let visibleEventGeneration = 0;
|
|
@@ -34856,6 +36206,11 @@ async function createInteractiveApplication(deps) {
|
|
|
34856
36206
|
getLeaderArmed: () => leaderArmed,
|
|
34857
36207
|
getShutdownArmed: () => shutdownArmed,
|
|
34858
36208
|
isAwaitingApproval: () => overlayLifecycle?.getState() === "permission-confirm",
|
|
36209
|
+
getPermissionInspection: () => {
|
|
36210
|
+
if (overlayLifecycle === void 0 || overlayLifecycle === null) return "none";
|
|
36211
|
+
if (!overlayLifecycle.canInspectMutation()) return "none";
|
|
36212
|
+
return overlayLifecycle.isInspectingMutation() ? "open" : "closed";
|
|
36213
|
+
},
|
|
34859
36214
|
resolveVisibleEventSequence: (event) => visibleEventIngress.get(event)?.traceSequence ?? null,
|
|
34860
36215
|
resolveStreamIngress: (event) => visibleEventIngress.get(event) ?? null,
|
|
34861
36216
|
commitFrame: (reason) => shell.commitCurrentFrame(reason === "teardown" ? 300 : 3e4),
|
|
@@ -34964,7 +36319,7 @@ async function createInteractiveApplication(deps) {
|
|
|
34964
36319
|
chat: deps.chat,
|
|
34965
36320
|
chatPanel: {
|
|
34966
36321
|
appendReplayBlock: (...args) => chatRenderer.mutate(() => chatPanel.appendReplayBlock(...args), "slash-output"),
|
|
34967
|
-
appendUser: (text) => chatRenderer.mutate(() => chatPanel.appendUser(text), "user-submit"),
|
|
36322
|
+
appendUser: (text, status) => chatRenderer.mutate(() => chatPanel.appendUser(text, status), "user-submit"),
|
|
34968
36323
|
clearFoldOverrides: () => chatRenderer.mutate(() => chatPanel.clearFoldOverrides(), "output-detail")
|
|
34969
36324
|
},
|
|
34970
36325
|
beforeSemanticSubmit: () => chatRenderer.flush(),
|
|
@@ -35263,6 +36618,7 @@ async function createInteractiveApplication(deps) {
|
|
|
35263
36618
|
cancelParkedCalls: (reason) => deps.toolRegistry?.cancelParkedCalls(reason),
|
|
35264
36619
|
onShutdown: async () => {
|
|
35265
36620
|
try {
|
|
36621
|
+
if (dumpInputWedgeOnTerminate) process.off("SIGTERM", dumpInputWedgeOnTerminate);
|
|
35266
36622
|
await deps.onShutdown();
|
|
35267
36623
|
} finally {
|
|
35268
36624
|
if (lease) await lease.close();
|
|
@@ -35381,7 +36737,7 @@ import { isAbsolute as isAbsolute6, relative as relative7, resolve as resolve6 }
|
|
|
35381
36737
|
|
|
35382
36738
|
// src/tools/dispatch-scout-admission.ts
|
|
35383
36739
|
init_esm_shims();
|
|
35384
|
-
import { existsSync as existsSync9, readFileSync as
|
|
36740
|
+
import { existsSync as existsSync9, readFileSync as readFileSync9 } from "node:fs";
|
|
35385
36741
|
import { join as join10 } from "node:path";
|
|
35386
36742
|
var MAX_SCOUT_PLAN_DEADLINE_MS = 36e5;
|
|
35387
36743
|
function record(value) {
|
|
@@ -35433,7 +36789,7 @@ function loadVerifiedScoutSource(input) {
|
|
|
35433
36789
|
if (!existsSync9(receiptPath)) throw new Error(`dispatch: Scout source receipt '${input.ref.runId}' is unavailable`);
|
|
35434
36790
|
let receipt;
|
|
35435
36791
|
try {
|
|
35436
|
-
receipt = JSON.parse(
|
|
36792
|
+
receipt = JSON.parse(readFileSync9(receiptPath, "utf8"));
|
|
35437
36793
|
} catch (error) {
|
|
35438
36794
|
throw new Error(
|
|
35439
36795
|
`dispatch: Scout source receipt is unreadable: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -35670,14 +37026,6 @@ function councilSettingsFromArgs(args, deps) {
|
|
|
35670
37026
|
function isRecord11(value) {
|
|
35671
37027
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
35672
37028
|
}
|
|
35673
|
-
function reviewerTask(originalTask, builderRunId, cycle) {
|
|
35674
|
-
return [
|
|
35675
|
-
`Review the work of builder run ${builderRunId} (review cycle ${cycle}).`,
|
|
35676
|
-
"The builder's final answer is provided as input data; verify it against the workspace, do not trust it blindly.",
|
|
35677
|
-
"Original task the builder was given:",
|
|
35678
|
-
originalTask
|
|
35679
|
-
].join("\n\n");
|
|
35680
|
-
}
|
|
35681
37029
|
function reviewSettingsFromArgs(args) {
|
|
35682
37030
|
const raw = args.review;
|
|
35683
37031
|
if (raw === void 0 || raw === false) return { ok: true, review: void 0 };
|
|
@@ -36007,9 +37355,6 @@ function createDispatchAdmissionController(deps) {
|
|
|
36007
37355
|
if (parsed.requests.length !== 1 || parsed.requests[0] === void 0) {
|
|
36008
37356
|
return shapeRejection(args, REVIEW_SINGLE_TASK_MESSAGE);
|
|
36009
37357
|
}
|
|
36010
|
-
if (parsed.requests.some((request) => (request.resolvedVerification?.length ?? 0) > 0)) {
|
|
36011
|
-
return shapeRejection(args, "verification_unsupported_for_mode: review requests cannot run host verification");
|
|
36012
|
-
}
|
|
36013
37358
|
}
|
|
36014
37359
|
if (mode === "compete" && (parsed.requests.length !== 1 || parsed.requests[0] === void 0)) {
|
|
36015
37360
|
return shapeRejection(args, COMPETE_SINGLE_TASK_MESSAGE);
|
|
@@ -36060,7 +37405,7 @@ function createDispatchAdmissionController(deps) {
|
|
|
36060
37405
|
{
|
|
36061
37406
|
agentId: gateDeciderAgentId(reviewResult.review.reviewer),
|
|
36062
37407
|
executionRole: "reviewer",
|
|
36063
|
-
task:
|
|
37408
|
+
task: renderDispatchReviewerTask(base.task, subject.runId, cycle, base.intent),
|
|
36064
37409
|
systemPrompt: REVIEWER_GATE_PROMPT,
|
|
36065
37410
|
autonomy: "read-only",
|
|
36066
37411
|
gate: { role: "reviewer", group: "plan-preview", cycle, subjects: [subject] },
|
|
@@ -36121,6 +37466,13 @@ function createDispatchAdmissionController(deps) {
|
|
|
36121
37466
|
executionRole: "researcher",
|
|
36122
37467
|
autonomy: "read-only",
|
|
36123
37468
|
toolProfile: "council-read-only",
|
|
37469
|
+
// The runner reuses this composed task from the resolved plan, so
|
|
37470
|
+
// the approval artifact the plan hash binds shows the operator the
|
|
37471
|
+
// exact ballot the member is asked to cast.
|
|
37472
|
+
...council.synthesis === "vote" ? {
|
|
37473
|
+
task: renderCouncilVoteMemberTask(base.task),
|
|
37474
|
+
resultContractOverride: { kind: "council-ballot" }
|
|
37475
|
+
} : {},
|
|
36124
37476
|
target: member.target,
|
|
36125
37477
|
...member.model ? { model: member.model } : {},
|
|
36126
37478
|
...member.thinking ? { thinkingLevel: member.thinking } : {},
|
|
@@ -36293,7 +37645,7 @@ function createDispatchTool(inputDeps, surfaceOptions = {}) {
|
|
|
36293
37645
|
const admission = createDispatchAdmissionController(deps);
|
|
36294
37646
|
let runnerPromise = null;
|
|
36295
37647
|
const loadRunner = () => {
|
|
36296
|
-
runnerPromise ??= (surfaceOptions.loadRunner ?? (() => import("./dispatch-runner-
|
|
37648
|
+
runnerPromise ??= (surfaceOptions.loadRunner ?? (() => import("./dispatch-runner-VVA4SRRH.js")))();
|
|
36297
37649
|
return runnerPromise;
|
|
36298
37650
|
};
|
|
36299
37651
|
return {
|
|
@@ -36531,7 +37883,7 @@ function registerAllTools(registry, deps = {}) {
|
|
|
36531
37883
|
...builtin(
|
|
36532
37884
|
lazyTool(
|
|
36533
37885
|
monitorToolSurface,
|
|
36534
|
-
async () => (await import("./monitor-
|
|
37886
|
+
async () => (await import("./monitor-MMVTJABD.js")).createMonitorTool({ dispatch, runEvents: dispatchRunEvents })
|
|
36535
37887
|
),
|
|
36536
37888
|
{
|
|
36537
37889
|
path: "src/tools/monitor.ts",
|
|
@@ -36541,7 +37893,7 @@ function registerAllTools(registry, deps = {}) {
|
|
|
36541
37893
|
});
|
|
36542
37894
|
registry.register({
|
|
36543
37895
|
...builtin(
|
|
36544
|
-
lazyTool(steerToolSurface, async () => (await import("./steer-
|
|
37896
|
+
lazyTool(steerToolSurface, async () => (await import("./steer-CF5TDANS.js")).createSteerTool({ dispatch })),
|
|
36545
37897
|
{
|
|
36546
37898
|
path: "src/tools/steer.ts",
|
|
36547
37899
|
scope: "core"
|
|
@@ -36688,7 +38040,7 @@ async function resolveApiKeyForTarget(target, providers, signal) {
|
|
|
36688
38040
|
const resolved = await providers.auth.resolveForTarget(target, runtime, signal ? { signal } : void 0);
|
|
36689
38041
|
return resolved.apiKey;
|
|
36690
38042
|
}
|
|
36691
|
-
function createBackgroundMemoryModelClient(providers, settings, timeoutMs) {
|
|
38043
|
+
function createBackgroundMemoryModelClient(providers, settings, timeoutMs, bus) {
|
|
36692
38044
|
const targetId = settings.background.target?.trim();
|
|
36693
38045
|
const wireModelId = settings.background.model?.trim();
|
|
36694
38046
|
if (!targetId || !wireModelId) return null;
|
|
@@ -36712,22 +38064,52 @@ function createBackgroundMemoryModelClient(providers, settings, timeoutMs) {
|
|
|
36712
38064
|
const model = resolved.target.runtime.synthesizeModel(resolved.target.target, resolved.target.wireModelId, kbHit);
|
|
36713
38065
|
const refined = refineRuntimeTargetWithModelHints(resolved.target, model, providers.knowledgeBase);
|
|
36714
38066
|
applyModelCapabilityPatch(model, refined.capabilities);
|
|
38067
|
+
const costProvenance = normalizeCostProvenance(refined.costProvenance);
|
|
38068
|
+
const endpointKey = canonicalEndpointKey(refined.target);
|
|
36715
38069
|
return {
|
|
36716
|
-
|
|
36717
|
-
|
|
36718
|
-
|
|
36719
|
-
|
|
36720
|
-
|
|
36721
|
-
|
|
36722
|
-
|
|
36723
|
-
|
|
36724
|
-
|
|
36725
|
-
|
|
36726
|
-
|
|
36727
|
-
|
|
36728
|
-
|
|
36729
|
-
|
|
36730
|
-
|
|
38070
|
+
targetId,
|
|
38071
|
+
wireModelId: refined.wireModelId,
|
|
38072
|
+
endpointKey,
|
|
38073
|
+
client: {
|
|
38074
|
+
// Wrapped at the layer that knows a request left the process: the step
|
|
38075
|
+
// holds endpoint capacity while it is out and publishes the cache
|
|
38076
|
+
// disturbance even when a timeout means the usage sink never sees it.
|
|
38077
|
+
complete: announceMemoryStepEndpoint({ bus, endpointKey, targetId }, async (request) => {
|
|
38078
|
+
const apiKey = targetRequiresAuth(refined.target, refined.runtime) ? (await providers.auth.resolveForTarget(refined.target, refined.runtime, { signal: request.signal })).apiKey : LOCAL_API_KEY_FALLBACK2;
|
|
38079
|
+
const startedAt = Date.now();
|
|
38080
|
+
const completion = await completeEngineText({
|
|
38081
|
+
model,
|
|
38082
|
+
systemPrompt: request.systemPrompt,
|
|
38083
|
+
userPrompt: request.userPrompt,
|
|
38084
|
+
maxTokens: request.maxTokens,
|
|
38085
|
+
// Always off, never the operator's chat thinking level. A model that
|
|
38086
|
+
// reasons anyway still works: `completeEngineText` keeps only text
|
|
38087
|
+
// blocks, and the memory output budget leaves room for the preamble.
|
|
38088
|
+
thinkingLevel: "off",
|
|
38089
|
+
signal: request.signal,
|
|
38090
|
+
timeoutMs,
|
|
38091
|
+
...apiKey === void 0 ? {} : { apiKey }
|
|
38092
|
+
});
|
|
38093
|
+
return {
|
|
38094
|
+
text: completion.text,
|
|
38095
|
+
inputTokens: completion.inputTokens,
|
|
38096
|
+
outputTokens: completion.outputTokens,
|
|
38097
|
+
usage: {
|
|
38098
|
+
targetId,
|
|
38099
|
+
attributedModelId: refined.wireModelId,
|
|
38100
|
+
input: completion.usage.input,
|
|
38101
|
+
output: completion.usage.output,
|
|
38102
|
+
cacheRead: completion.usage.cacheRead,
|
|
38103
|
+
cacheWrite: completion.usage.cacheWrite,
|
|
38104
|
+
reasoning: completion.usage.reasoning,
|
|
38105
|
+
totalTokens: completion.usage.totalTokens,
|
|
38106
|
+
costUsd: completion.usage.costUsd,
|
|
38107
|
+
costProvenance,
|
|
38108
|
+
durationMs: Date.now() - startedAt,
|
|
38109
|
+
backend: completion.backend
|
|
38110
|
+
}
|
|
38111
|
+
};
|
|
38112
|
+
})
|
|
36731
38113
|
}
|
|
36732
38114
|
};
|
|
36733
38115
|
}
|
|
@@ -36798,7 +38180,7 @@ async function resolveCompactionModel(settings, providers) {
|
|
|
36798
38180
|
const model = synthesizeOrchestratorModel(providers, target, wireModelId);
|
|
36799
38181
|
if (!model) return null;
|
|
36800
38182
|
const apiKey = await resolveApiKeyForTarget(target, providers);
|
|
36801
|
-
const resolution = { model, targetId };
|
|
38183
|
+
const resolution = { model, targetId, endpointKey: canonicalEndpointKey(target) };
|
|
36802
38184
|
if (apiKey !== void 0) resolution.apiKey = apiKey;
|
|
36803
38185
|
return resolution;
|
|
36804
38186
|
}
|
|
@@ -36870,12 +38252,19 @@ async function runCompactionFlow(session, settings, providers, instructions, tri
|
|
|
36870
38252
|
const activeLeafTurnId = session.tree(meta.id).leafId ?? void 0;
|
|
36871
38253
|
const entries = filterEntriesToActivePath(readSessionEntriesForCompact(meta.id), activeLeafTurnId);
|
|
36872
38254
|
if (entries.length === 0) return null;
|
|
36873
|
-
const
|
|
36874
|
-
|
|
36875
|
-
|
|
36876
|
-
|
|
36877
|
-
|
|
36878
|
-
|
|
38255
|
+
const releaseEndpointSlot = resolved.endpointKey === null ? () => {
|
|
38256
|
+
} : registerForegroundStream(resolved.endpointKey);
|
|
38257
|
+
let result;
|
|
38258
|
+
try {
|
|
38259
|
+
result = await compact({
|
|
38260
|
+
entries,
|
|
38261
|
+
model: resolved.model,
|
|
38262
|
+
...resolved.apiKey !== void 0 ? { apiKey: resolved.apiKey } : {},
|
|
38263
|
+
...instructions !== void 0 ? { instructions } : {}
|
|
38264
|
+
});
|
|
38265
|
+
} finally {
|
|
38266
|
+
releaseEndpointSlot();
|
|
38267
|
+
}
|
|
36879
38268
|
if (result.messagesSummarized === 0 || result.summary.length === 0) return null;
|
|
36880
38269
|
const entry = {
|
|
36881
38270
|
kind: "compactionSummary",
|
|
@@ -37244,6 +38633,40 @@ async function bootOrchestrator(options = {}) {
|
|
|
37244
38633
|
let deferredWatchdogNoticeSink = null;
|
|
37245
38634
|
const memoryTracePath = taskMemoryTracePath();
|
|
37246
38635
|
const memoryTrace = memoryTracePath === null ? null : createTaskMemoryTrace(memoryTracePath);
|
|
38636
|
+
let backgroundMemoryRoute = null;
|
|
38637
|
+
const recordBackgroundMemoryUsage = (usage) => {
|
|
38638
|
+
const meta = session?.current() ?? null;
|
|
38639
|
+
try {
|
|
38640
|
+
recordBackgroundMemoryStep({
|
|
38641
|
+
usage,
|
|
38642
|
+
stateDir: clioStateDir(),
|
|
38643
|
+
sessionId: meta?.id ?? null,
|
|
38644
|
+
// The identity the session ledger is filed under, so `usage report
|
|
38645
|
+
// --repo` selects these rows with the same hash it selects ledgers with.
|
|
38646
|
+
repoIdentity: meta ? meta.cwdHash || cwdHash(meta.cwd || process.cwd()) : null,
|
|
38647
|
+
...observability === void 0 ? {} : { observability }
|
|
38648
|
+
});
|
|
38649
|
+
} catch {
|
|
38650
|
+
}
|
|
38651
|
+
};
|
|
38652
|
+
const proposeInjectedMemoryEntries = (entries) => {
|
|
38653
|
+
const meta = session?.current() ?? null;
|
|
38654
|
+
void proposeInjectedTaskMemory(clioDataDir(), {
|
|
38655
|
+
sessionId: meta?.id ?? null,
|
|
38656
|
+
cwd: meta?.cwd || process.cwd(),
|
|
38657
|
+
entries
|
|
38658
|
+
}).then((result2) => {
|
|
38659
|
+
for (const error of result2.errors) {
|
|
38660
|
+
process.stderr.write(`[clio:memory] proposed record not written for ${error}
|
|
38661
|
+
`);
|
|
38662
|
+
}
|
|
38663
|
+
}).catch((error) => {
|
|
38664
|
+
process.stderr.write(
|
|
38665
|
+
`[clio:memory] proposed records not written: ${error instanceof Error ? error.message : String(error)}
|
|
38666
|
+
`
|
|
38667
|
+
);
|
|
38668
|
+
});
|
|
38669
|
+
};
|
|
37247
38670
|
const memoryIntervention = createMemoryInterventionRegistration({
|
|
37248
38671
|
bank: taskMemoryBank,
|
|
37249
38672
|
telemetry: createTaskMemoryTelemetrySink(),
|
|
@@ -37258,8 +38681,21 @@ async function bootOrchestrator(options = {}) {
|
|
|
37258
38681
|
},
|
|
37259
38682
|
getModelClient: () => {
|
|
37260
38683
|
const settings = effectiveSettingsForDispatch?.();
|
|
37261
|
-
|
|
37262
|
-
|
|
38684
|
+
backgroundMemoryRoute = settings === void 0 ? null : createBackgroundMemoryModelClient(providers, settings, settings.memory.intervention.timeoutMs, bus);
|
|
38685
|
+
return backgroundMemoryRoute?.client ?? null;
|
|
38686
|
+
},
|
|
38687
|
+
// A single-slot local server serves one request at a time, so a memory step
|
|
38688
|
+
// started while the operator's turn is streaming either waits behind it or
|
|
38689
|
+
// makes the server swap the resident model out to answer. The chat loop
|
|
38690
|
+
// registers its stream on the endpoint it streams against, so the two are
|
|
38691
|
+
// compared by the same canonical key dispatch admission counts slots on.
|
|
38692
|
+
backgroundEndpointBusy: () => {
|
|
38693
|
+
const endpointKey = backgroundMemoryRoute?.endpointKey ?? null;
|
|
38694
|
+
if (endpointKey === null) return false;
|
|
38695
|
+
return (foregroundStreamUsage()[endpointKey] ?? 0) > 0;
|
|
38696
|
+
},
|
|
38697
|
+
onStepUsage: (usage) => recordBackgroundMemoryUsage(usage),
|
|
38698
|
+
onInjectedEntries: (entries) => proposeInjectedMemoryEntries(entries)
|
|
37263
38699
|
});
|
|
37264
38700
|
middleware.registerHook(memoryIntervention);
|
|
37265
38701
|
const unsubscribeMemoryLoop = bus.on(BusChannels.LoopBlocked, () => memoryIntervention.signalLoop());
|
|
@@ -37587,6 +39023,12 @@ async function bootOrchestrator(options = {}) {
|
|
|
37587
39023
|
);
|
|
37588
39024
|
}
|
|
37589
39025
|
const chat = createChatLoop({
|
|
39026
|
+
// The pre-warm holds one slot on its endpoint while it runs, so dispatch
|
|
39027
|
+
// admission (#250) sees it exactly as it sees the orchestrator's own turn.
|
|
39028
|
+
registerPrewarmEndpointSlot: (runtime) => {
|
|
39029
|
+
const key = canonicalEndpointKey(runtime.runtimeResolution.target);
|
|
39030
|
+
return key === null ? null : registerForegroundStream(key);
|
|
39031
|
+
},
|
|
37590
39032
|
getSettings: getCurrentSettings,
|
|
37591
39033
|
providers,
|
|
37592
39034
|
middleware,
|
|
@@ -37643,7 +39085,12 @@ async function bootOrchestrator(options = {}) {
|
|
|
37643
39085
|
autoCompact: createProductionAutoCompact(session, getCurrentSettings, providers)
|
|
37644
39086
|
} : {},
|
|
37645
39087
|
toolRegistry,
|
|
37646
|
-
hasAttachedDispatch: () => dispatchBackground.size() > 0
|
|
39088
|
+
hasAttachedDispatch: () => dispatchBackground.size() > 0,
|
|
39089
|
+
// The pre-warm buys latency for a person about to type the next turn. A
|
|
39090
|
+
// headless `run` submits its one prompt immediately and an unattended boot
|
|
39091
|
+
// never submits at all, so neither has latency to buy; the ACP surface has
|
|
39092
|
+
// an operator on the other end of the client and keeps it.
|
|
39093
|
+
isLatencySurface: () => interactive || acpMode
|
|
37647
39094
|
});
|
|
37648
39095
|
termination.onDrain(async () => {
|
|
37649
39096
|
chat.dispose();
|
|
@@ -37846,7 +39293,11 @@ async function bootOrchestrator(options = {}) {
|
|
|
37846
39293
|
lastDecision: memoryIntervention.lastDecision(),
|
|
37847
39294
|
bank,
|
|
37848
39295
|
activity: memoryIntervention.recentActivity(),
|
|
37849
|
-
stepInFlight: memoryIntervention.stepInFlight()
|
|
39296
|
+
stepInFlight: memoryIntervention.stepInFlight(),
|
|
39297
|
+
// Folded from the telemetry ledger, which is durable across sessions,
|
|
39298
|
+
// so `/memory` answers what the tier has cost since it was turned on
|
|
39299
|
+
// rather than what it cost since this process started.
|
|
39300
|
+
spend: readTaskMemorySpendSummary(clioStateDir())
|
|
37850
39301
|
};
|
|
37851
39302
|
},
|
|
37852
39303
|
getTaskMemorySeedOffer,
|
|
@@ -38019,4 +39470,4 @@ export {
|
|
|
38019
39470
|
resolveApiKeyForTarget,
|
|
38020
39471
|
synthesizeOrchestratorModel
|
|
38021
39472
|
};
|
|
38022
|
-
//# sourceMappingURL=orchestrator-
|
|
39473
|
+
//# sourceMappingURL=orchestrator-ZKBPCHW6.js.map
|