@iowarp/clio-coder 0.3.8 → 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 +49 -0
- package/README.md +7 -3
- package/dist/{acp-U67UHUK2.js → acp-7LOELQFP.js} +6 -6
- package/dist/{agents-YU6SGALZ.js → agents-FIBG2SHA.js} +27 -25
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-5ZPJOIVG.js → auth-OI4LIH2I.js} +11 -12
- package/dist/{builtins-C6JMZVV6.js → builtins-AD25UL3C.js} +5 -5
- package/dist/{chunk-5FR74PWO.js → chunk-2JDWVJND.js} +2 -2
- package/dist/chunk-3DPEIQKN.js +113 -0
- package/dist/{chunk-4SPRNWDE.js → chunk-3DUR4WUA.js} +15 -15
- package/dist/{chunk-VHN4MY6O.js → chunk-3MRC2YSQ.js} +2 -2
- package/dist/{chunk-5DHKRSMQ.js → chunk-3UUY7R3Z.js} +11 -7
- package/dist/{chunk-IGWKHNIQ.js → chunk-3V5AYSEQ.js} +8 -8
- package/dist/{chunk-FHJEP5SW.js → chunk-465CC7FK.js} +8 -5
- package/dist/{chunk-5WIGXA4T.js → chunk-47CMYGET.js} +111 -4
- package/dist/{chunk-A3WNZD3P.js → chunk-4H6ULJ3H.js} +67 -21
- package/dist/{chunk-TB5666IT.js → chunk-4LJX2PUC.js} +3 -3
- package/dist/{chunk-XWSF374K.js → chunk-56KB5IJP.js} +2 -2
- package/dist/{chunk-SPULKLCF.js → chunk-5DQRIYDZ.js} +2 -2
- package/dist/{chunk-2HEJ2F35.js → chunk-5HFBWUMU.js} +20 -8
- package/dist/{chunk-WNIJTQQK.js → chunk-5PVQ4SRS.js} +78 -6
- package/dist/{chunk-DYIM5TJT.js → chunk-5QKCQQ3E.js} +262 -6
- package/dist/{chunk-TYPGUK6W.js → chunk-5T7RBWN2.js} +111 -5
- package/dist/{chunk-IIZWH4XA.js → chunk-774ILSRL.js} +2 -2
- package/dist/chunk-7C6RYZGQ.js +391 -0
- package/dist/{chunk-TANS5ZJS.js → chunk-AD7Y7STJ.js} +3 -3
- package/dist/{chunk-RWSI4YD7.js → chunk-AEYBF3TB.js} +33 -12
- package/dist/{chunk-DGSYXYMX.js → chunk-AMKHQW3C.js} +2 -2
- package/dist/{chunk-VWZOAB7K.js → chunk-B5XRQOLB.js} +7 -7
- package/dist/{chunk-WXY7KU3G.js → chunk-BVDVID7E.js} +2 -2
- package/dist/{chunk-PMDBGQSJ.js → chunk-CA42X6KT.js} +2 -2
- package/dist/{chunk-HLE42MG7.js → chunk-D73KXYPF.js} +3 -3
- package/dist/{chunk-5Q2VVUKB.js → chunk-DG4M6ZUE.js} +3 -3
- package/dist/{chunk-ME6CCNFO.js → chunk-EBOC7MT3.js} +6 -6
- package/dist/{chunk-MXKJU4JB.js → chunk-ECUO3KDP.js} +48 -7
- package/dist/{chunk-26LEYJZH.js → chunk-FALJGAWU.js} +2 -2
- package/dist/{chunk-GWS3VEIW.js → chunk-FWDFM5ZU.js} +24 -3
- package/dist/{chunk-7RGZWPB6.js → chunk-GAYUJ7LE.js} +67 -13
- package/dist/{chunk-VCBR6CU7.js → chunk-HAY4ZE2P.js} +2 -2
- package/dist/{chunk-FBVTI2TJ.js → chunk-HCBCAYZU.js} +11 -130
- package/dist/{chunk-WSB3FPX7.js → chunk-HJB5IUKP.js} +32 -136
- package/dist/{chunk-J3YUBZWY.js → chunk-HKO36JWF.js} +33 -5
- package/dist/{chunk-E77JEWSD.js → chunk-HPCTNZM2.js} +6 -36
- package/dist/{chunk-FJ3H4MN5.js → chunk-IHKBWSXF.js} +2 -2
- package/dist/{chunk-NMPKI6XL.js → chunk-JEQQR47K.js} +37 -18
- package/dist/{chunk-3BINW3FP.js → chunk-KV2AOLDF.js} +24 -4
- package/dist/{chunk-YS5VLNH5.js → chunk-LXPJXFM5.js} +7 -7
- package/dist/{chunk-7RFXX52T.js → chunk-MIX5N5AC.js} +271 -41
- package/dist/{chunk-K4XHGFR5.js → chunk-MLOK6ZOS.js} +1297 -218
- package/dist/{chunk-ZNLWCMVZ.js → chunk-MV2VUEJC.js} +2 -2
- package/dist/{chunk-MVVUPGPW.js → chunk-MXHC5QYU.js} +6 -6
- package/dist/{chunk-5H3GB5BO.js → chunk-N3PBVRTZ.js} +4 -382
- package/dist/{chunk-2HFZQUHL.js → chunk-N5XKWMDW.js} +17 -7
- package/dist/{chunk-5C3AQNDW.js → chunk-NNNWO6F2.js} +124 -36
- package/dist/{chunk-GU2UIAFZ.js → chunk-NQ6UCCOD.js} +3 -3
- package/dist/{chunk-N22QMJKY.js → chunk-NZU6YDNV.js} +4 -4
- package/dist/{chunk-ZVJ5BLO2.js → chunk-O6I4CIEU.js} +151 -13
- package/dist/{chunk-XN3L4EYL.js → chunk-OEDBCISO.js} +2 -2
- package/dist/{chunk-VAWNZU7Z.js → chunk-P3JGPQFL.js} +2 -2
- package/dist/{chunk-IJ7RPIYJ.js → chunk-PNY46YEY.js} +20 -3
- package/dist/{chunk-U6MBIEMB.js → chunk-PZ4I4JE2.js} +56 -35
- package/dist/{chunk-GPIEI3LY.js → chunk-QQ7EKM72.js} +2 -2
- package/dist/{chunk-WLFILSD5.js → chunk-R7LNVMCS.js} +66 -28
- package/dist/{chunk-GOXNB3AO.js → chunk-RAPCMZL4.js} +75 -4
- package/dist/chunk-RKKLTLYB.js +45 -0
- package/dist/{chunk-TT36MB5S.js → chunk-RKRLDWD3.js} +3 -1
- package/dist/{chunk-TTHACPOM.js → chunk-S4COXYBG.js} +456 -18
- package/dist/{chunk-WWCZ5F23.js → chunk-T3Z6VAAF.js} +69 -10
- package/dist/{chunk-GN57SG4G.js → chunk-TD7UE2L5.js} +9 -7
- package/dist/{chunk-TLQJPP24.js → chunk-TEO2TLVN.js} +523 -322
- package/dist/{chunk-FCSXB6T2.js → chunk-UOSL25KY.js} +14 -2
- package/dist/{chunk-KTYTFRMB.js → chunk-VKBMFOYV.js} +17 -15
- package/dist/{chunk-PT7HYKEM.js → chunk-VO2LKSTM.js} +2 -2
- package/dist/{chunk-P43ETTHK.js → chunk-VPTUJU4P.js} +2 -2
- package/dist/{chunk-WEH5XRJQ.js → chunk-WIE7ZOSW.js} +2 -2
- package/dist/{chunk-EMYUUSFG.js → chunk-WXCJ7VME.js} +5 -5
- package/dist/{chunk-4DGYLA73.js → chunk-XDOQXGFO.js} +22 -7
- package/dist/{chunk-JOZYP4GM.js → chunk-YKOFT37S.js} +5 -5
- package/dist/chunk-YSEHGPCT.js +127 -0
- package/dist/{chunk-HFSBBKSQ.js → chunk-YW7UVM5V.js} +138 -3
- package/dist/cli/index.js +27 -27
- package/dist/{clio-QVTYJ57A.js → clio-LT5V7SSZ.js} +6 -6
- package/dist/{code-nav-FGGFIE7L.js → code-nav-LMW275PA.js} +4 -4
- package/dist/{config-LW5IJFQN.js → config-RXS5T3JT.js} +71 -43
- package/dist/{configure-7XIZCOU4.js → configure-2WYWSCSD.js} +14 -15
- package/dist/{context-Y6Y7QPR6.js → context-I3BTOTCS.js} +12 -12
- package/dist/{context-L3WL3X7K.js → context-MVOORGMF.js} +34 -33
- package/dist/{context-N52ZA626.js → context-PALKKQYL.js} +20 -20
- package/dist/{context-clear-MBQRLSDQ.js → context-clear-N2WOYZ2K.js} +34 -33
- package/dist/{context-index-HVMFQHK3.js → context-index-HNG3MOME.js} +2 -2
- package/dist/{context-working-set-GS6DSO7F.js → context-working-set-MIEVECVZ.js} +10 -11
- package/dist/{dispatch-runner-22ZCNOM3.js → dispatch-runner-VVA4SRRH.js} +34 -33
- package/dist/doctor-TWBWFK5V.js +165 -0
- package/dist/{eval-BEC2WHDA.js → eval-IJ5VEZDJ.js} +2016 -142
- package/dist/{evidence-REJUMSKM.js → evidence-L5APPXNV.js} +29 -28
- package/dist/{evolve-PY5ZBA5K.js → evolve-RGNKFJ52.js} +29 -28
- package/dist/{extensions-HVKU65YU.js → extensions-7WYWUX5A.js} +9 -3
- package/dist/{fleet-7WZEWRFA.js → fleet-6CNVBZZP.js} +87 -55
- package/dist/{fleet-commands-UVHWM76J.js → fleet-commands-L2SXSYEI.js} +6 -6
- package/dist/{fleet-graph-6ULH7PES.js → fleet-graph-2J3OOIPO.js} +14 -12
- package/dist/{fleet-preflight-J53T6CCE.js → fleet-preflight-CZRJ4JP5.js} +3 -4
- package/dist/{fleet-validate-72PC4SLA.js → fleet-validate-C5RI6DP7.js} +16 -15
- package/dist/{init-OG3TPGQG.js → init-VBN2ACVA.js} +50 -48
- package/dist/{library-CNTMPLRF.js → library-JHGUMLY2.js} +13 -11
- package/dist/{memory-6IS7F275.js → memory-K4OQIYWG.js} +31 -30
- package/dist/{models-ENRJDA5W.js → models-2NCZUWDD.js} +23 -22
- package/dist/{monitor-XLDVO7TN.js → monitor-MMVTJABD.js} +35 -34
- package/dist/{orchestrator-6KSPYRHA.js → orchestrator-ZKBPCHW6.js} +1627 -294
- package/dist/{reset-RZ4ER727.js → reset-DD5JGOY3.js} +3 -3
- package/dist/{run-Y2CNK5RU.js → run-QEGNX7FL.js} +56 -55
- package/dist/{share-A55GYP6Z.js → share-JKD3BQMW.js} +13 -11
- package/dist/{skills-ALC5J6AT.js → skills-LMQIKDOZ.js} +14 -12
- package/dist/{skills-eval-JPBEBYQU.js → skills-eval-I7X2774U.js} +34 -32
- package/dist/{steer-GGWFUJUD.js → steer-CF5TDANS.js} +3 -3
- package/dist/{support-MIETYA5E.js → support-I7LOJLIF.js} +4 -4
- package/dist/{targets-VGNXIR3S.js → targets-RUSR6B5Z.js} +58 -32
- package/dist/{terminal-lease-WOBR64YA.js → terminal-lease-QYVORFR4.js} +6 -4
- package/dist/{trace-PNCASAXC.js → trace-ODOQIVIW.js} +61 -6
- package/dist/{upgrade-FUSUAGHR.js → upgrade-XANW3FXB.js} +17 -16
- package/dist/{usage-N4MKVHKD.js → usage-4H7ZRXQT.js} +88 -44
- package/dist/{verifiers-YAWOJ3H2.js → verifiers-UZXNBZEB.js} +6 -6
- package/dist/{verify-LTDHYBGY.js → verify-BVKWTNDL.js} +5 -5
- package/dist/{wiki-generate-6M7GHTBJ.js → wiki-generate-MY7WV2QI.js} +49 -47
- package/dist/worker/entry.js +29 -33
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +1 -1
- package/docs/artifact-versions.md +6 -1
- package/docs/built-in-agents.md +1 -1
- package/docs/capacity-and-scheduling.md +23 -2
- package/docs/commands-and-modes.md +1 -1
- package/docs/configuration-and-targets.md +30 -3
- 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 +11 -10
- package/docs/evolution.md +1 -1
- package/docs/extensions-and-sharing.md +3 -1
- package/docs/fleet-dispatch.md +4 -4
- 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 +53 -2
- package/docs/proactive-memory.md +127 -14
- package/docs/prompt-envelope-and-tools.md +19 -1
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/release-cut-checklist.md +19 -3
- 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 -1
- package/src/cli/agents.ts +1 -1
- package/src/cli/config-inspect.ts +33 -6
- package/src/cli/config.ts +1 -1
- package/src/cli/doctor-state-size.ts +82 -0
- package/src/cli/doctor.ts +3 -1
- package/src/cli/eval.ts +80 -16
- package/src/cli/extensions.ts +5 -1
- package/src/cli/fleet.ts +32 -3
- package/src/cli/targets.ts +44 -13
- package/src/cli/trace.ts +63 -4
- package/src/cli/usage.ts +63 -14
- package/src/core/bus-events.ts +29 -1
- package/src/core/cache-telemetry.ts +42 -0
- 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/residency-target-key.ts +25 -0
- package/src/core/response-schema.ts +36 -2
- package/src/domains/config/classify.ts +3 -0
- package/src/domains/context/codewiki/coordinator.ts +12 -4
- package/src/domains/dispatch/admission.ts +40 -3
- package/src/domains/dispatch/capacity-lease.ts +98 -9
- package/src/domains/dispatch/contract.ts +11 -0
- package/src/domains/dispatch/execution-plan.ts +44 -4
- package/src/domains/dispatch/extension.ts +166 -42
- package/src/domains/dispatch/fleet-run.ts +23 -3
- package/src/domains/dispatch/heartbeat.ts +32 -8
- package/src/domains/dispatch/index.ts +3 -0
- package/src/domains/dispatch/orphan-recovery.ts +5 -0
- package/src/domains/dispatch/reservation-store.ts +116 -8
- package/src/domains/dispatch/state.ts +4 -0
- package/src/domains/dispatch/worker-spawn.ts +25 -11
- package/src/domains/dispatch/write-boundary-enforcer.ts +20 -3
- package/src/domains/dispatch/write-boundary.ts +62 -1
- 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/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 +127 -0
- 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 +2 -13
- package/src/domains/evidence/eval.ts +2 -12
- package/src/domains/evidence/findings-markdown.ts +33 -0
- package/src/domains/evidence/run-trust.ts +7 -113
- package/src/domains/evidence/trust-projection.ts +2 -2
- package/src/domains/extensions/compatibility.ts +285 -0
- package/src/domains/extensions/discovery.ts +38 -3
- package/src/domains/extensions/resources.ts +1 -1
- package/src/domains/extensions/state.ts +12 -3
- package/src/domains/extensions/types.ts +2 -0
- package/src/domains/lifecycle/doctor.ts +69 -1
- 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/providers/endpoint-capacity.ts +96 -0
- 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/prompts/loader.ts +95 -33
- package/src/domains/safety/call-target.ts +52 -0
- package/src/domains/safety/run-effects.ts +35 -4
- 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/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/provider-payload.ts +29 -1
- 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 +84 -12
- 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-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 +35 -1
- 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/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/view-overlay.ts +28 -3
- package/src/tools/ask-user.ts +43 -2
- package/src/tools/dispatch-plan.ts +17 -9
- package/src/tools/dispatch-scout.ts +1 -1
- package/src/tools/registry.ts +16 -0
- package/dist/chunk-AOCYTWAV.js +0 -449
- package/dist/chunk-HWUFFB6L.js +0 -83
- package/dist/chunk-R346GLFC.js +0 -31
- package/dist/doctor-M7YEDGAE.js +0 -91
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { createRequire as __clioCreateRequire } from "node:module"; const require = __clioCreateRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
ShareDomainModule
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-TD7UE2L5.js";
|
|
5
5
|
import {
|
|
6
6
|
bootstrapInputFromInitOptions,
|
|
7
7
|
modelBootstrapGenerate,
|
|
8
8
|
resolveBootstrapRoute
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-3DUR4WUA.js";
|
|
10
10
|
import "./chunk-J5Q24KAG.js";
|
|
11
11
|
import {
|
|
12
12
|
DEFAULT_KEEP_RECENT_TOKENS,
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
projectWorkingSet,
|
|
22
22
|
resolveWorkingSetPolicy,
|
|
23
23
|
selectVisibleEntries
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-3MRC2YSQ.js";
|
|
25
25
|
import {
|
|
26
26
|
assistantSessionPayload,
|
|
27
27
|
backendCacheVerdict,
|
|
@@ -54,42 +54,42 @@ import {
|
|
|
54
54
|
toolNamesFromAgentState,
|
|
55
55
|
toolResultSummary,
|
|
56
56
|
toolSignatureFromState
|
|
57
|
-
} from "./chunk-
|
|
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
63
|
import {
|
|
64
64
|
flushRawStdout,
|
|
65
65
|
writeRawStdout
|
|
66
66
|
} from "./chunk-2VTFPG5O.js";
|
|
67
67
|
import {
|
|
68
68
|
SafetyDomainModule
|
|
69
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-WXCJ7VME.js";
|
|
70
70
|
import {
|
|
71
71
|
LifecycleDomainModule,
|
|
72
72
|
describeUpgradeNotice
|
|
73
|
-
} from "./chunk-
|
|
73
|
+
} from "./chunk-DG4M6ZUE.js";
|
|
74
74
|
import {
|
|
75
75
|
ensureClioState,
|
|
76
76
|
takeUpgradeNotice
|
|
77
|
-
} from "./chunk-
|
|
77
|
+
} from "./chunk-T3Z6VAAF.js";
|
|
78
78
|
import {
|
|
79
79
|
ConfigDomainModule,
|
|
80
80
|
createConfigDomainModule,
|
|
81
81
|
loadDomains
|
|
82
|
-
} from "./chunk-
|
|
82
|
+
} from "./chunk-465CC7FK.js";
|
|
83
83
|
import {
|
|
84
84
|
discoverDeclaredChecks
|
|
85
|
-
} from "./chunk-
|
|
85
|
+
} from "./chunk-P3JGPQFL.js";
|
|
86
86
|
import {
|
|
87
87
|
buildRecallFields,
|
|
88
88
|
recallErrorMessage,
|
|
89
89
|
recallParentTurnId,
|
|
90
90
|
recallableRefListing,
|
|
91
91
|
resolveRecall
|
|
92
|
-
} from "./chunk-
|
|
92
|
+
} from "./chunk-MV2VUEJC.js";
|
|
93
93
|
import {
|
|
94
94
|
foldWorkingSet
|
|
95
95
|
} from "./chunk-TZSKNMZG.js";
|
|
@@ -103,10 +103,11 @@ import {
|
|
|
103
103
|
libraryEntryRef,
|
|
104
104
|
libraryInstallPath,
|
|
105
105
|
planLibraryInstall
|
|
106
|
-
} from "./chunk-
|
|
106
|
+
} from "./chunk-PZ4I4JE2.js";
|
|
107
107
|
import {
|
|
108
108
|
AgentsDomainModule
|
|
109
|
-
} from "./chunk-
|
|
109
|
+
} from "./chunk-YSEHGPCT.js";
|
|
110
|
+
import "./chunk-HCBCAYZU.js";
|
|
110
111
|
import "./chunk-DR52UMZW.js";
|
|
111
112
|
import {
|
|
112
113
|
MARKETPLACE_UNCONFIGURED,
|
|
@@ -115,32 +116,33 @@ import {
|
|
|
115
116
|
installSkill,
|
|
116
117
|
modelVisibleSkills,
|
|
117
118
|
parseSkillCommand
|
|
118
|
-
} from "./chunk-
|
|
119
|
-
import "./chunk-
|
|
119
|
+
} from "./chunk-AD7Y7STJ.js";
|
|
120
|
+
import "./chunk-AMKHQW3C.js";
|
|
120
121
|
import {
|
|
121
122
|
compileScoutTransition,
|
|
122
123
|
createDispatchRunEventRegistry
|
|
123
|
-
} from "./chunk-
|
|
124
|
+
} from "./chunk-YKOFT37S.js";
|
|
124
125
|
import {
|
|
125
126
|
monitorToolSurface
|
|
126
|
-
} from "./chunk-
|
|
127
|
+
} from "./chunk-IHKBWSXF.js";
|
|
127
128
|
import {
|
|
128
129
|
COST_NOT_MEASURED,
|
|
129
130
|
ObservabilityDomainModule,
|
|
130
131
|
aggregateCostAmounts,
|
|
131
132
|
costAggregateForAmount,
|
|
132
133
|
formatCostAggregate,
|
|
133
|
-
readAccountabilitySummary
|
|
134
|
-
|
|
134
|
+
readAccountabilitySummary,
|
|
135
|
+
recordBackgroundMemoryStep
|
|
136
|
+
} from "./chunk-5PVQ4SRS.js";
|
|
135
137
|
import {
|
|
136
138
|
appendOutOfTurnUsageRow
|
|
137
|
-
} from "./chunk-
|
|
138
|
-
import "./chunk-
|
|
139
|
-
import "./chunk-
|
|
139
|
+
} from "./chunk-FWDFM5ZU.js";
|
|
140
|
+
import "./chunk-YW7UVM5V.js";
|
|
141
|
+
import "./chunk-D73KXYPF.js";
|
|
140
142
|
import {
|
|
141
143
|
steerToolSurface
|
|
142
|
-
} from "./chunk-
|
|
143
|
-
import "./chunk-
|
|
144
|
+
} from "./chunk-WIE7ZOSW.js";
|
|
145
|
+
import "./chunk-FALJGAWU.js";
|
|
144
146
|
import {
|
|
145
147
|
ClioEditor,
|
|
146
148
|
CombinedAutocompleteProvider,
|
|
@@ -150,6 +152,7 @@ import {
|
|
|
150
152
|
FocusBox,
|
|
151
153
|
GLYPH,
|
|
152
154
|
Input,
|
|
155
|
+
MUTATION_PREVIEW_KEY,
|
|
153
156
|
Markdown,
|
|
154
157
|
Marked,
|
|
155
158
|
SGR_DIM,
|
|
@@ -207,39 +210,43 @@ import {
|
|
|
207
210
|
truncateToWidth,
|
|
208
211
|
validateKeybindings,
|
|
209
212
|
visibleWidth,
|
|
210
|
-
wrapTextWithAnsi
|
|
211
|
-
|
|
213
|
+
wrapTextWithAnsi,
|
|
214
|
+
writeInputWedgeDump
|
|
215
|
+
} from "./chunk-NNNWO6F2.js";
|
|
212
216
|
import {
|
|
213
217
|
getTerminationCoordinator
|
|
214
|
-
} from "./chunk-
|
|
218
|
+
} from "./chunk-BVDVID7E.js";
|
|
215
219
|
import {
|
|
216
220
|
createContextDomainModule,
|
|
217
221
|
loadProjectClioMd
|
|
218
|
-
} from "./chunk-
|
|
222
|
+
} from "./chunk-HJB5IUKP.js";
|
|
219
223
|
import "./chunk-LCGCVYZ4.js";
|
|
220
224
|
import {
|
|
221
225
|
renderCodewikiDigest
|
|
222
|
-
} from "./chunk-
|
|
226
|
+
} from "./chunk-47CMYGET.js";
|
|
223
227
|
import {
|
|
224
228
|
buildMemoryPromptSection,
|
|
225
229
|
canonicalMemoryRepositoryIdentity,
|
|
226
230
|
createTaskMemoryTrace,
|
|
227
231
|
describeTaskMemoryActivity,
|
|
232
|
+
formatTaskMemorySpend,
|
|
228
233
|
loadMemoryRecordsSync,
|
|
234
|
+
proposeInjectedTaskMemory,
|
|
229
235
|
proposeMemoryPromotion,
|
|
236
|
+
readTaskMemorySpendSummary,
|
|
230
237
|
renderTaskMemoryHandoffSource,
|
|
231
238
|
seedTaskMemoryFromNewestHandoff,
|
|
232
239
|
taskMemoryBankSize,
|
|
233
240
|
taskMemoryHandoffSeedOffer,
|
|
234
241
|
taskMemoryTracePath
|
|
235
|
-
} from "./chunk-
|
|
242
|
+
} from "./chunk-5T7RBWN2.js";
|
|
236
243
|
import {
|
|
237
244
|
listWikiPages,
|
|
238
245
|
wikiCompleteness,
|
|
239
246
|
wikiStaleness,
|
|
240
247
|
wikiStalenessAsync
|
|
241
248
|
} from "./chunk-NDINPTJ4.js";
|
|
242
|
-
import "./chunk-
|
|
249
|
+
import "./chunk-MXHC5QYU.js";
|
|
243
250
|
import {
|
|
244
251
|
ACP_MAX_CHUNK_BYTES,
|
|
245
252
|
ACP_MAX_RAW_RECORD_BYTES,
|
|
@@ -252,6 +259,7 @@ import {
|
|
|
252
259
|
AcpTimeoutError,
|
|
253
260
|
WORKER_OUTPUT_MAX_BYTES,
|
|
254
261
|
acpErrorMessage,
|
|
262
|
+
capacityLeaseUsage,
|
|
255
263
|
createDispatchDomainModule,
|
|
256
264
|
createRunReceiptQuality,
|
|
257
265
|
createStdioServerTransport,
|
|
@@ -265,7 +273,16 @@ import {
|
|
|
265
273
|
readGateDecisionArtifacts,
|
|
266
274
|
readPendingGateDecisions,
|
|
267
275
|
renderDispatchReviewerTask
|
|
268
|
-
} from "./chunk-
|
|
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";
|
|
269
286
|
import {
|
|
270
287
|
SessionDomainModule,
|
|
271
288
|
addResponseModelIdObservationCount,
|
|
@@ -279,30 +296,28 @@ import {
|
|
|
279
296
|
readAuditRows,
|
|
280
297
|
responseModelIdObservationCountsLabel,
|
|
281
298
|
responseModelIdObservationFromRecord
|
|
282
|
-
} from "./chunk-
|
|
283
|
-
import {
|
|
284
|
-
formatTrustSummaryLine,
|
|
285
|
-
inspectRunReceiptTrustStatus,
|
|
286
|
-
isReceiptIntegrity,
|
|
287
|
-
retiredReceiptIntegrity,
|
|
288
|
-
retiredReceiptIntegrityReason,
|
|
289
|
-
summarizeTrustStatus,
|
|
290
|
-
verifyReceiptIntegrity
|
|
291
|
-
} from "./chunk-K4XHGFR5.js";
|
|
299
|
+
} from "./chunk-LXPJXFM5.js";
|
|
292
300
|
import {
|
|
301
|
+
describeWriteBoundaryAttributionDowngrade,
|
|
293
302
|
gitCheckoutRoot,
|
|
294
303
|
isGitRepository,
|
|
295
304
|
preflightWriteBoundaries,
|
|
296
305
|
recoverCleanupReadyCompeteGroups
|
|
297
|
-
} from "./chunk-
|
|
306
|
+
} from "./chunk-ECUO3KDP.js";
|
|
298
307
|
import {
|
|
308
|
+
bindExecutionPlanEndpoints,
|
|
299
309
|
compileFleetExecutionPlan,
|
|
300
310
|
requireAgentSteps
|
|
301
|
-
} from "./chunk-
|
|
311
|
+
} from "./chunk-HKO36JWF.js";
|
|
302
312
|
import {
|
|
303
313
|
parseRigorOverride,
|
|
304
314
|
resolveRigor
|
|
305
315
|
} from "./chunk-RVG5JXAL.js";
|
|
316
|
+
import {
|
|
317
|
+
foldPromptCacheTelemetry,
|
|
318
|
+
hasPromptCacheTelemetry,
|
|
319
|
+
uncachedPrefillTokens
|
|
320
|
+
} from "./chunk-3DPEIQKN.js";
|
|
306
321
|
import {
|
|
307
322
|
filterEntriesToActivePath
|
|
308
323
|
} from "./chunk-W6GROXXM.js";
|
|
@@ -315,12 +330,13 @@ import {
|
|
|
315
330
|
renderFleetPrompt,
|
|
316
331
|
validateFleetCommands,
|
|
317
332
|
validateFleetGraph
|
|
318
|
-
} from "./chunk-
|
|
333
|
+
} from "./chunk-HPCTNZM2.js";
|
|
334
|
+
import "./chunk-RKKLTLYB.js";
|
|
319
335
|
import {
|
|
320
336
|
ExtensionsDomainModule
|
|
321
|
-
} from "./chunk-
|
|
337
|
+
} from "./chunk-5QKCQQ3E.js";
|
|
322
338
|
import "./chunk-JVCV3ICN.js";
|
|
323
|
-
import "./chunk-
|
|
339
|
+
import "./chunk-5HFBWUMU.js";
|
|
324
340
|
import {
|
|
325
341
|
shellQuote
|
|
326
342
|
} from "./chunk-TXOTCRLG.js";
|
|
@@ -336,6 +352,7 @@ import {
|
|
|
336
352
|
import {
|
|
337
353
|
ASK_USER_OTHER_LABEL,
|
|
338
354
|
INTERACTIVE_LOOP_BLOCK_BUDGET,
|
|
355
|
+
applyEditsToNormalizedContent,
|
|
339
356
|
askAxis,
|
|
340
357
|
askUserExposure,
|
|
341
358
|
assertRegisteredBuiltinTools,
|
|
@@ -350,16 +367,20 @@ import {
|
|
|
350
367
|
decisionFactsForPermission,
|
|
351
368
|
diffWords,
|
|
352
369
|
finalizeAskUserInterviewForHost,
|
|
370
|
+
generateDiffString,
|
|
353
371
|
lazyTool,
|
|
372
|
+
normalizeToLF,
|
|
354
373
|
patchProviderThinkingPayload,
|
|
374
|
+
patchResponseSchemaPayloadForDialect,
|
|
355
375
|
patchToolChoiceNamedPayload,
|
|
356
376
|
patchToolChoiceNonePayload,
|
|
357
377
|
readOrchTurnToolCallBudget,
|
|
358
378
|
registerCoreTools,
|
|
359
379
|
resolveFdBinary,
|
|
360
380
|
resolveSessionTools,
|
|
361
|
-
sanitizeLockedSynthesisMessage
|
|
362
|
-
|
|
381
|
+
sanitizeLockedSynthesisMessage,
|
|
382
|
+
stripBom
|
|
383
|
+
} from "./chunk-R7LNVMCS.js";
|
|
363
384
|
import {
|
|
364
385
|
HEADLESS_PERMISSION_DENIED_REASON
|
|
365
386
|
} from "./chunk-K7VKOLQQ.js";
|
|
@@ -367,6 +388,7 @@ import {
|
|
|
367
388
|
MIDDLEWARE_HOOK_TEXT_MAX_CHARS,
|
|
368
389
|
MiddlewareDomainModule,
|
|
369
390
|
WATCHDOG_TASK,
|
|
391
|
+
announceMemoryStepEndpoint,
|
|
370
392
|
createDetachedDispatchNudgeRegistration,
|
|
371
393
|
createHookReceiptLog,
|
|
372
394
|
createMemoryInterventionRegistration,
|
|
@@ -381,12 +403,12 @@ import {
|
|
|
381
403
|
openDetachedBatchViews,
|
|
382
404
|
watchdogBriefing,
|
|
383
405
|
writeMiddlewareDiagnosticToStderr
|
|
384
|
-
} from "./chunk-
|
|
385
|
-
import "./chunk-
|
|
406
|
+
} from "./chunk-GAYUJ7LE.js";
|
|
407
|
+
import "./chunk-HAY4ZE2P.js";
|
|
386
408
|
import "./chunk-UOV2BYIW.js";
|
|
387
|
-
import "./chunk-
|
|
388
|
-
import "./chunk-
|
|
389
|
-
import "./chunk-
|
|
409
|
+
import "./chunk-CA42X6KT.js";
|
|
410
|
+
import "./chunk-OEDBCISO.js";
|
|
411
|
+
import "./chunk-5DQRIYDZ.js";
|
|
390
412
|
import {
|
|
391
413
|
DISPATCH_PLAN_PREPARATION_ERROR_ARGUMENT,
|
|
392
414
|
RESOLVED_DISPATCH_PLAN_ARGUMENT,
|
|
@@ -398,11 +420,11 @@ import {
|
|
|
398
420
|
stringArg,
|
|
399
421
|
timeoutMsArg,
|
|
400
422
|
withResolvedDispatchPlan
|
|
401
|
-
} from "./chunk-
|
|
423
|
+
} from "./chunk-VKBMFOYV.js";
|
|
402
424
|
import {
|
|
403
425
|
TaskMemoryBank,
|
|
404
426
|
createTaskMemoryTelemetrySink
|
|
405
|
-
} from "./chunk-
|
|
427
|
+
} from "./chunk-O6I4CIEU.js";
|
|
406
428
|
import {
|
|
407
429
|
escapeRegExp
|
|
408
430
|
} from "./chunk-VG7TBQIY.js";
|
|
@@ -422,26 +444,29 @@ import {
|
|
|
422
444
|
formatBudgetReasons,
|
|
423
445
|
formatBudgetRequest,
|
|
424
446
|
formatEffectiveBudget,
|
|
447
|
+
isResponseSchemaRejection,
|
|
425
448
|
isToolProfileName,
|
|
426
449
|
normalizeDispatchIntent,
|
|
427
450
|
redactSecretString,
|
|
428
451
|
redactToolArgs,
|
|
429
452
|
renderCouncilVoteMemberTask,
|
|
453
|
+
responseSchemaDialectFor,
|
|
430
454
|
runBashCommand,
|
|
431
455
|
runKindSupportsLiveSteering,
|
|
432
456
|
sanitizeCallTargetText,
|
|
457
|
+
sanitizeMultilineDisplayText,
|
|
433
458
|
toolPresentationPolicy
|
|
434
|
-
} from "./chunk-
|
|
459
|
+
} from "./chunk-4H6ULJ3H.js";
|
|
460
|
+
import {
|
|
461
|
+
defaultRoutingIntent,
|
|
462
|
+
sameRouteIdentity
|
|
463
|
+
} from "./chunk-VPTUJU4P.js";
|
|
435
464
|
import {
|
|
436
465
|
createTaskBoardStore,
|
|
437
466
|
foldSessionTaskHistory,
|
|
438
467
|
foldTaskBoard,
|
|
439
468
|
taskBoardCounts
|
|
440
|
-
} from "./chunk-
|
|
441
|
-
import {
|
|
442
|
-
defaultRoutingIntent,
|
|
443
|
-
sameRouteIdentity
|
|
444
|
-
} from "./chunk-P43ETTHK.js";
|
|
469
|
+
} from "./chunk-2JDWVJND.js";
|
|
445
470
|
import {
|
|
446
471
|
agentRoleFactsResolver,
|
|
447
472
|
gateDeciderAgentId,
|
|
@@ -451,29 +476,29 @@ import {
|
|
|
451
476
|
import {
|
|
452
477
|
DEFAULT_RECENT_ENTRY_LIMIT,
|
|
453
478
|
assessFinishContract
|
|
454
|
-
} from "./chunk-
|
|
479
|
+
} from "./chunk-7C6RYZGQ.js";
|
|
480
|
+
import "./chunk-N3PBVRTZ.js";
|
|
455
481
|
import "./chunk-A2NJGIB3.js";
|
|
456
|
-
import "./chunk-OQE5J4C6.js";
|
|
457
482
|
import {
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
skillActivationFromToolDetails
|
|
461
|
-
} from "./chunk-GOXNB3AO.js";
|
|
462
|
-
import {
|
|
463
|
-
DEFAULT_AUTONOMY_LEVEL
|
|
464
|
-
} from "./chunk-HWUFFB6L.js";
|
|
483
|
+
resolveToCwd
|
|
484
|
+
} from "./chunk-OQE5J4C6.js";
|
|
465
485
|
import {
|
|
466
486
|
parseCouncilReport,
|
|
467
487
|
parseOracleResult,
|
|
468
488
|
parseScoutResult,
|
|
469
489
|
parseVerifierResult,
|
|
470
490
|
resultContractSourceId
|
|
471
|
-
} from "./chunk-
|
|
472
|
-
import "./chunk-AOCYTWAV.js";
|
|
491
|
+
} from "./chunk-S4COXYBG.js";
|
|
473
492
|
import {
|
|
474
493
|
CLIO_PROJECT_DIR,
|
|
475
494
|
toolMutationPaths
|
|
476
495
|
} from "./chunk-MV3K5QF2.js";
|
|
496
|
+
import {
|
|
497
|
+
DEFAULT_AUTONOMY_LEVEL,
|
|
498
|
+
SKILL_SUGGESTION_PREFIX,
|
|
499
|
+
isSkillActivation,
|
|
500
|
+
skillActivationFromToolDetails
|
|
501
|
+
} from "./chunk-RAPCMZL4.js";
|
|
477
502
|
import {
|
|
478
503
|
VERIFICATION_SCRIPT_FAMILY_HINT
|
|
479
504
|
} from "./chunk-UL3WSD3F.js";
|
|
@@ -519,8 +544,8 @@ import {
|
|
|
519
544
|
InteropDomainModule,
|
|
520
545
|
delegationEntryForKind,
|
|
521
546
|
renderProposalEntry
|
|
522
|
-
} from "./chunk-
|
|
523
|
-
import "./chunk-
|
|
547
|
+
} from "./chunk-QQ7EKM72.js";
|
|
548
|
+
import "./chunk-56KB5IJP.js";
|
|
524
549
|
import {
|
|
525
550
|
source_default
|
|
526
551
|
} from "./chunk-5TSRNF4G.js";
|
|
@@ -528,7 +553,11 @@ import {
|
|
|
528
553
|
ProvidersDomainModule,
|
|
529
554
|
VALID_THINKING_LEVELS,
|
|
530
555
|
applyModelCapabilityPatch,
|
|
556
|
+
canonicalEndpointKey,
|
|
557
|
+
endpointCapacitiesForStatuses,
|
|
558
|
+
endpointCapacityForStatus,
|
|
531
559
|
firstRuntimeResolutionError,
|
|
560
|
+
foregroundStreamUsage,
|
|
532
561
|
isDispatchEligibleRuntime,
|
|
533
562
|
isOrchestratorEligibleRuntime,
|
|
534
563
|
modelCandidatesForStatus,
|
|
@@ -536,6 +565,8 @@ import {
|
|
|
536
565
|
modelResidencyForStatus,
|
|
537
566
|
normalizeCostProvenance,
|
|
538
567
|
refineRuntimeTargetWithModelHints,
|
|
568
|
+
registerForegroundStream,
|
|
569
|
+
residencyTargetKey,
|
|
539
570
|
resolveModelCapabilities,
|
|
540
571
|
resolveModelReference,
|
|
541
572
|
resolveModelRuntimeCapabilitiesForProviders,
|
|
@@ -547,7 +578,7 @@ import {
|
|
|
547
578
|
thinkingLevelChoiceLabel,
|
|
548
579
|
thinkingLevelFromChoiceLabel,
|
|
549
580
|
withRunOverrides
|
|
550
|
-
} from "./chunk-
|
|
581
|
+
} from "./chunk-MIX5N5AC.js";
|
|
551
582
|
import "./chunk-CFGTUFWB.js";
|
|
552
583
|
import "./chunk-LU7P4LHA.js";
|
|
553
584
|
import {
|
|
@@ -561,13 +592,15 @@ import {
|
|
|
561
592
|
contextUsageSnapshot,
|
|
562
593
|
estimateAgentContextBreakdown,
|
|
563
594
|
estimateAgentContextTokens,
|
|
595
|
+
estimateAgentMessageTokens,
|
|
564
596
|
estimateReasoningTextTokens,
|
|
565
597
|
extractReasoningTokens,
|
|
566
598
|
getLatestContextSnapshot,
|
|
599
|
+
lastLoadedContextWindow,
|
|
567
600
|
reconcileSnapshot,
|
|
568
601
|
shouldCompact,
|
|
569
602
|
snapshotInputTokens
|
|
570
|
-
} from "./chunk-
|
|
603
|
+
} from "./chunk-AEYBF3TB.js";
|
|
571
604
|
import {
|
|
572
605
|
interopAgentKind
|
|
573
606
|
} from "./chunk-IHXBNWMM.js";
|
|
@@ -582,7 +615,7 @@ import {
|
|
|
582
615
|
setFleetProfileInSettings,
|
|
583
616
|
updateSettings,
|
|
584
617
|
useTargetInSettings
|
|
585
|
-
} from "./chunk-
|
|
618
|
+
} from "./chunk-PNY46YEY.js";
|
|
586
619
|
import {
|
|
587
620
|
MAX_TIMER_DELAY_MS,
|
|
588
621
|
rawDurationMs
|
|
@@ -593,7 +626,7 @@ import {
|
|
|
593
626
|
import {
|
|
594
627
|
BusChannels,
|
|
595
628
|
isRunAbortedPayload
|
|
596
|
-
} from "./chunk-
|
|
629
|
+
} from "./chunk-RKRLDWD3.js";
|
|
597
630
|
import {
|
|
598
631
|
atomicWrite,
|
|
599
632
|
cwdHash,
|
|
@@ -601,8 +634,7 @@ import {
|
|
|
601
634
|
readSessionTailTurns,
|
|
602
635
|
sessionCurrentPath,
|
|
603
636
|
sessionPaths
|
|
604
|
-
} from "./chunk-
|
|
605
|
-
import "./chunk-R346GLFC.js";
|
|
637
|
+
} from "./chunk-KV2AOLDF.js";
|
|
606
638
|
import "./chunk-6EJMN2Y3.js";
|
|
607
639
|
import {
|
|
608
640
|
readClioVersion,
|
|
@@ -611,19 +643,19 @@ import {
|
|
|
611
643
|
import {
|
|
612
644
|
formatContextWindowSlots,
|
|
613
645
|
registerBuiltinRuntimes
|
|
614
|
-
} from "./chunk-
|
|
646
|
+
} from "./chunk-JEQQR47K.js";
|
|
615
647
|
import {
|
|
616
648
|
DEFAULT_DELEGATION_PERMISSION_TIMEOUT_MS,
|
|
617
649
|
DEFAULT_SETTINGS,
|
|
618
650
|
THINKING_LEVELS
|
|
619
|
-
} from "./chunk-
|
|
651
|
+
} from "./chunk-XDOQXGFO.js";
|
|
620
652
|
import "./chunk-LL4KHSZI.js";
|
|
621
653
|
import {
|
|
622
654
|
configureGuardrails
|
|
623
655
|
} from "./chunk-4ZG3XFUR.js";
|
|
624
656
|
import {
|
|
625
657
|
resolveProviderReference
|
|
626
|
-
} from "./chunk-
|
|
658
|
+
} from "./chunk-774ILSRL.js";
|
|
627
659
|
import {
|
|
628
660
|
targetRequiresAuth
|
|
629
661
|
} from "./chunk-EQ63NRB7.js";
|
|
@@ -646,14 +678,15 @@ import {
|
|
|
646
678
|
import {
|
|
647
679
|
AGENT_ROLE_TOOLS_REQUIRED_REASON,
|
|
648
680
|
supportsAgentRoleTools
|
|
649
|
-
} from "./chunk-
|
|
681
|
+
} from "./chunk-VO2LKSTM.js";
|
|
650
682
|
import {
|
|
651
683
|
StringEnum,
|
|
652
684
|
cleanupEngineSessionResources,
|
|
653
685
|
completeEngineText,
|
|
654
686
|
isEngineRetryableAssistantError,
|
|
655
|
-
stream
|
|
656
|
-
|
|
687
|
+
stream,
|
|
688
|
+
streamSimple
|
|
689
|
+
} from "./chunk-UOSL25KY.js";
|
|
657
690
|
import "./chunk-YXLYO42X.js";
|
|
658
691
|
import {
|
|
659
692
|
init_esm_shims
|
|
@@ -4611,10 +4644,29 @@ async function runSideQuestion(input) {
|
|
|
4611
4644
|
const { question, ...rest } = input;
|
|
4612
4645
|
return runOutOfTurnRound({ ...rest, systemPrompt: SIDE_QUESTION_SYSTEM_PROMPT, userText: question });
|
|
4613
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
|
+
}
|
|
4614
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) {
|
|
4615
4664
|
const options = { maxTokens: input.maxTokens ?? SIDE_QUESTION_MAX_TOKENS };
|
|
4616
4665
|
if (input.apiKey !== void 0) options.apiKey = input.apiKey;
|
|
4617
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
|
+
}
|
|
4618
4670
|
const context = {
|
|
4619
4671
|
systemPrompt: input.systemPrompt,
|
|
4620
4672
|
messages: [
|
|
@@ -4664,13 +4716,31 @@ var HANDOFF_SYSTEM_PROMPT = [
|
|
|
4664
4716
|
`The object must match this JSON schema exactly: ${JSON.stringify(HANDOFF_RESPONSE_SCHEMA)}`
|
|
4665
4717
|
].join(" ");
|
|
4666
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
|
+
}
|
|
4667
4736
|
async function runHandoffRound(input) {
|
|
4668
|
-
const { goal, ...rest } = input;
|
|
4737
|
+
const { goal, repair, ...rest } = input;
|
|
4669
4738
|
return runOutOfTurnRound({
|
|
4670
4739
|
...rest,
|
|
4671
4740
|
maxTokens: input.maxTokens ?? HANDOFF_MAX_TOKENS,
|
|
4672
4741
|
systemPrompt: HANDOFF_SYSTEM_PROMPT,
|
|
4673
|
-
|
|
4742
|
+
responseSchema: { name: HANDOFF_SCHEMA_NAME, schema: HANDOFF_RESPONSE_SCHEMA },
|
|
4743
|
+
userText: repair ? repairText(goal, repair) : `The next session's goal is: ${goal}
|
|
4674
4744
|
|
|
4675
4745
|
Extract the handoff record for that goal now.`
|
|
4676
4746
|
});
|
|
@@ -4877,6 +4947,7 @@ function maskStaleObservations(entries, excludeLastTurns) {
|
|
|
4877
4947
|
init_esm_shims();
|
|
4878
4948
|
import { appendFileSync, existsSync as existsSync4, readFileSync as readFileSync4 } from "node:fs";
|
|
4879
4949
|
import { dirname, join as join4 } from "node:path";
|
|
4950
|
+
var PROMPT_MANIFEST_VERSION = 2;
|
|
4880
4951
|
var SHA256_HEX = /^[a-f0-9]{64}$/;
|
|
4881
4952
|
function isCanonicalUtcTimestamp(value) {
|
|
4882
4953
|
if (typeof value !== "string") return false;
|
|
@@ -4902,9 +4973,18 @@ function isProjectPreloadClass(value) {
|
|
|
4902
4973
|
if (!isRecord6(value)) return false;
|
|
4903
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";
|
|
4904
4975
|
}
|
|
4976
|
+
function isOptional(value, guard) {
|
|
4977
|
+
return value === void 0 || guard(value);
|
|
4978
|
+
}
|
|
4905
4979
|
function isSessionPromptCompileRecord(value) {
|
|
4906
4980
|
if (!isRecord6(value)) return false;
|
|
4907
|
-
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);
|
|
4908
4988
|
}
|
|
4909
4989
|
function getPromptManifestFilePath(meta, stateDir) {
|
|
4910
4990
|
const safeMeta = {
|
|
@@ -4952,6 +5032,9 @@ function readPromptCompileManifest(meta, stateDir) {
|
|
|
4952
5032
|
};
|
|
4953
5033
|
}
|
|
4954
5034
|
}
|
|
5035
|
+
function readPromptCompileRecords(meta) {
|
|
5036
|
+
return readPromptCompileManifest(meta).records;
|
|
5037
|
+
}
|
|
4955
5038
|
|
|
4956
5039
|
// src/interactive/model-session-replay.ts
|
|
4957
5040
|
init_esm_shims();
|
|
@@ -5072,6 +5155,160 @@ function formatRetryStatus(status) {
|
|
|
5072
5155
|
// src/interactive/renderers/tool-execution.ts
|
|
5073
5156
|
init_esm_shims();
|
|
5074
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
|
+
|
|
5075
5312
|
// src/interactive/renderers/diff.ts
|
|
5076
5313
|
init_esm_shims();
|
|
5077
5314
|
var ESC = String.fromCharCode(27);
|
|
@@ -5546,7 +5783,10 @@ function renderToolAwaitingApproval(call, width, view) {
|
|
|
5546
5783
|
const facts = [
|
|
5547
5784
|
["action", view.actionClass],
|
|
5548
5785
|
["axis", axis],
|
|
5549
|
-
...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)]] : []
|
|
5550
5790
|
];
|
|
5551
5791
|
for (const [label, value] of facts) {
|
|
5552
5792
|
lines.push(...indentAndWrap(`${dim(`${label} \xB7`)} ${value}`, width, false));
|
|
@@ -6582,12 +6822,12 @@ function toggledFold(effective) {
|
|
|
6582
6822
|
|
|
6583
6823
|
// src/interactive/worker-receipts.ts
|
|
6584
6824
|
init_esm_shims();
|
|
6585
|
-
import { existsSync as existsSync5, readFileSync as
|
|
6825
|
+
import { existsSync as existsSync5, readFileSync as readFileSync7 } from "node:fs";
|
|
6586
6826
|
import { join as join6 } from "node:path";
|
|
6587
6827
|
|
|
6588
6828
|
// src/interactive/view/artifacts.ts
|
|
6589
6829
|
init_esm_shims();
|
|
6590
|
-
import { createReadStream, readFileSync as
|
|
6830
|
+
import { createReadStream, readFileSync as readFileSync6, statSync } from "node:fs";
|
|
6591
6831
|
import { readFile, realpath, stat } from "node:fs/promises";
|
|
6592
6832
|
import { basename, isAbsolute as isAbsolute4, join as join5, relative as relative4, resolve as resolve3, sep } from "node:path";
|
|
6593
6833
|
|
|
@@ -6666,7 +6906,7 @@ var CONTEXT_CATEGORY_TOKEN = {
|
|
|
6666
6906
|
project: "muted",
|
|
6667
6907
|
messages: "accent",
|
|
6668
6908
|
pending: "accentDeep",
|
|
6669
|
-
reserve: "
|
|
6909
|
+
reserve: "frame",
|
|
6670
6910
|
free: "frame",
|
|
6671
6911
|
streaming: "accent"
|
|
6672
6912
|
};
|
|
@@ -7530,6 +7770,18 @@ function progressAnswerLines(theme6, progress, runId, contentWidth) {
|
|
|
7530
7770
|
}
|
|
7531
7771
|
return body.map((row2, index) => `${index === 0 ? cardKvKey(theme6, "answer") : " ".repeat(gutter)}${row2}`);
|
|
7532
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
|
+
}
|
|
7533
7785
|
function renderDispatchCard(row2, width, evidence, options = {}) {
|
|
7534
7786
|
const theme6 = clioTheme();
|
|
7535
7787
|
const contentWidth = Math.max(0, width - 4);
|
|
@@ -7561,16 +7813,13 @@ function renderDispatchCard(row2, width, evidence, options = {}) {
|
|
|
7561
7813
|
const statusUnits = [
|
|
7562
7814
|
statusStr,
|
|
7563
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}`)] : [],
|
|
7564
7817
|
...row2.gate !== void 0 ? [theme6.fg("info", `gate ${row2.gate.role} c${row2.gate.cycle}`)] : [],
|
|
7565
7818
|
...row2.rerouteCount !== void 0 && row2.rerouteCount > 0 ? [theme6.fg("warning", `rerouted x${row2.rerouteCount}`)] : [],
|
|
7566
7819
|
...row2.failoverHops !== void 0 && row2.failoverHops > 0 ? [theme6.fg("warning", `failed over x${row2.failoverHops}`)] : [],
|
|
7567
7820
|
`${theme6.fg("dim", "ttft")} ${theme6.fg("muted", ttft)}`,
|
|
7568
7821
|
`${theme6.fg("dim", "cost")} ${theme6.fg("muted", cost)}`
|
|
7569
7822
|
];
|
|
7570
|
-
const trustUnits = [
|
|
7571
|
-
row2.trust === void 0 ? theme6.fg("dim", isTerminalStatus(row2.status) ? "trust: receipt not read back" : "trust: not sealed yet") : theme6.fg(trustVerdictToken(row2.trust.verdict), `${trustVerdictGlyph(row2.trust.verdict)} ${row2.trust.text}`),
|
|
7572
|
-
...row2.hostVerification !== void 0 ? [theme6.fg("muted", `host checks ${row2.hostVerification}`)] : []
|
|
7573
|
-
];
|
|
7574
7823
|
const contextUnit = formatWorkerContextMeter(row2.lastContextTokens ?? 0, row2.contextWindow, theme6);
|
|
7575
7824
|
const phaseCell = formatDispatchPhaseCell(row2.phase, contentWidth);
|
|
7576
7825
|
const bodyLines2 = [
|
|
@@ -7584,7 +7833,7 @@ function renderDispatchCard(row2, width, evidence, options = {}) {
|
|
|
7584
7833
|
targetLine,
|
|
7585
7834
|
...row2.taskSummary ? [truncateToWidth(`${cardKvKey(theme6, "task")}${theme6.fg("muted", row2.taskSummary)}`, contentWidth, "\u2026", false)] : [],
|
|
7586
7835
|
cardUnitsLine(theme6, "status", statusUnits, contentWidth),
|
|
7587
|
-
|
|
7836
|
+
...trustCardLines(theme6, row2, contentWidth),
|
|
7588
7837
|
...row2.budget !== void 0 ? [
|
|
7589
7838
|
truncateToWidth(
|
|
7590
7839
|
`${cardKvKey(theme6, "policy")}${theme6.fg("muted", `${formatBudgetPolicy(row2.budget)}; requested ${formatBudgetRequest(row2.budget)}`)}`,
|
|
@@ -7639,6 +7888,16 @@ function renderDispatchCard(row2, width, evidence, options = {}) {
|
|
|
7639
7888
|
)
|
|
7640
7889
|
);
|
|
7641
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
|
+
}
|
|
7642
7901
|
if (evidence) {
|
|
7643
7902
|
const proofLine = evidenceCardLine(theme6, evidence, contentWidth);
|
|
7644
7903
|
if (proofLine !== null) bodyLines2.push(proofLine);
|
|
@@ -7777,10 +8036,17 @@ function formatDispatchBoardLines(rows, width = 76, observability, selectedRunId
|
|
|
7777
8036
|
return theme6.fg("dim", " ".repeat(padding) + line);
|
|
7778
8037
|
});
|
|
7779
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
|
+
}
|
|
7780
8045
|
const cards = dispatchBoardItems(rows, selectedRunId).map(
|
|
7781
8046
|
(item) => item.kind === "council" ? renderCouncilCard(item.group, width) : renderDispatchCard(item.row, width, deriveRunEvidenceState(observability, item.row.runId), {
|
|
7782
8047
|
selected: item.row.runId === selectedRunId,
|
|
7783
|
-
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 } : {}
|
|
7784
8050
|
})
|
|
7785
8051
|
);
|
|
7786
8052
|
const body = [];
|
|
@@ -7904,6 +8170,14 @@ function parseGateBadge(value) {
|
|
|
7904
8170
|
const cycle = parsePositiveInt(record2.cycle) ?? 1;
|
|
7905
8171
|
return { role: record2.role, cycle };
|
|
7906
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
|
+
}
|
|
7907
8181
|
function parseCouncilBadge(value) {
|
|
7908
8182
|
if (typeof value !== "object" || value === null) return void 0;
|
|
7909
8183
|
const record2 = value;
|
|
@@ -8055,6 +8329,7 @@ function toRow(entry, now) {
|
|
|
8055
8329
|
runtimeId: entry.runtimeId,
|
|
8056
8330
|
targetId: entry.targetId,
|
|
8057
8331
|
wireModelId: entry.wireModelId,
|
|
8332
|
+
...entry.endpoint !== void 0 ? { endpoint: { ...entry.endpoint } } : {},
|
|
8058
8333
|
...entry.taskSummary !== void 0 ? { taskSummary: entry.taskSummary } : {},
|
|
8059
8334
|
...entry.budget !== void 0 ? { budget: entry.budget } : {},
|
|
8060
8335
|
status: retry ? "retrying" : entry.status,
|
|
@@ -8082,7 +8357,8 @@ function toRow(entry, now) {
|
|
|
8082
8357
|
currentTool: retry ? null : progress.currentAction?.tool ?? null,
|
|
8083
8358
|
recentTools: progress.recentActions.map((action) => action.tool),
|
|
8084
8359
|
...retry ? { retry: { ...retry } } : {},
|
|
8085
|
-
...entry.steerAcknowledgement ? { steerAcknowledgement: { ...entry.steerAcknowledgement } } : {}
|
|
8360
|
+
...entry.steerAcknowledgement ? { steerAcknowledgement: { ...entry.steerAcknowledgement } } : {},
|
|
8361
|
+
...entry.writeRecordDowngrade ? { writeRecordDowngrade: { ...entry.writeRecordDowngrade } } : {}
|
|
8086
8362
|
};
|
|
8087
8363
|
}
|
|
8088
8364
|
function sortEntries(a, b) {
|
|
@@ -8123,6 +8399,7 @@ function createDispatchBoardStore(bus, snapshot, readReceipt) {
|
|
|
8123
8399
|
const agentAudience = parseAgentAudience(raw.agentAudience, previous?.agentAudience);
|
|
8124
8400
|
const requestOrigin = parseRequestOrigin(raw.requestOrigin, previous?.requestOrigin);
|
|
8125
8401
|
const node = parseNonEmptyString(raw.node) ?? previous?.node;
|
|
8402
|
+
const endpoint = parseEndpointCapacity(raw.endpoint) ?? previous?.endpoint;
|
|
8126
8403
|
const gate = parseGateBadge(raw.gate) ?? previous?.gate;
|
|
8127
8404
|
const council = parseCouncilBadge(raw.council) ?? previous?.council;
|
|
8128
8405
|
const rerouteCount = parsePositiveInt(raw.rerouteCount) ?? previous?.rerouteCount;
|
|
@@ -8139,6 +8416,7 @@ function createDispatchBoardStore(bus, snapshot, readReceipt) {
|
|
|
8139
8416
|
runtimeId: parseText(raw.runtimeId, previous?.runtimeId ?? "-"),
|
|
8140
8417
|
targetId: parseText(raw.targetId, previous?.targetId ?? "-"),
|
|
8141
8418
|
wireModelId: parseText(raw.wireModelId, previous?.wireModelId ?? "-"),
|
|
8419
|
+
...endpoint !== void 0 ? { endpoint } : {},
|
|
8142
8420
|
...taskSummary !== void 0 ? { taskSummary } : {},
|
|
8143
8421
|
...budget !== void 0 ? { budget } : {},
|
|
8144
8422
|
status,
|
|
@@ -8166,7 +8444,8 @@ function createDispatchBoardStore(bus, snapshot, readReceipt) {
|
|
|
8166
8444
|
...phase !== void 0 ? { phase } : {},
|
|
8167
8445
|
progress: previous?.progress ?? createWorkerProgressFold(),
|
|
8168
8446
|
...previous?.retry ? { retry: { ...previous.retry } } : {},
|
|
8169
|
-
...previous?.steerAcknowledgement ? { steerAcknowledgement: { ...previous.steerAcknowledgement } } : {}
|
|
8447
|
+
...previous?.steerAcknowledgement ? { steerAcknowledgement: { ...previous.steerAcknowledgement } } : {},
|
|
8448
|
+
...previous?.writeRecordDowngrade ? { writeRecordDowngrade: { ...previous.writeRecordDowngrade } } : {}
|
|
8170
8449
|
};
|
|
8171
8450
|
entries.set(runId, entry);
|
|
8172
8451
|
pruneEntries(entries, (evicted) => fleetPhases.delete(evicted));
|
|
@@ -8293,6 +8572,19 @@ function createDispatchBoardStore(bus, snapshot, readReceipt) {
|
|
|
8293
8572
|
entry.ttftMs = Math.round(performance3.now() - entry.startedAtClockMs);
|
|
8294
8573
|
}
|
|
8295
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
|
+
}
|
|
8296
8588
|
entry.progress.observe(payload.event);
|
|
8297
8589
|
if (type === "clio_steer_received") {
|
|
8298
8590
|
const steerPayload = workerEvent.payload;
|
|
@@ -8736,8 +9028,41 @@ function retryOverlay(status) {
|
|
|
8736
9028
|
}
|
|
8737
9029
|
function reduceStatus(prev, event, ctx) {
|
|
8738
9030
|
switch (event.type) {
|
|
8739
|
-
|
|
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":
|
|
8740
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;
|
|
8741
9066
|
return {
|
|
8742
9067
|
...INITIAL_STATUS,
|
|
8743
9068
|
phase: "preparing",
|
|
@@ -9057,6 +9382,13 @@ function createStatusController(deps) {
|
|
|
9057
9382
|
}
|
|
9058
9383
|
notify(prev, status, force);
|
|
9059
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
|
+
}
|
|
9060
9392
|
unsubscribes.push(
|
|
9061
9393
|
deps.chat.onEvent((event) => {
|
|
9062
9394
|
if (event.type === "agent_status") return;
|
|
@@ -10151,7 +10483,7 @@ function runLedgerPath(stateDir) {
|
|
|
10151
10483
|
}
|
|
10152
10484
|
function readRunLedger(stateDir) {
|
|
10153
10485
|
try {
|
|
10154
|
-
const raw =
|
|
10486
|
+
const raw = readFileSync6(runLedgerPath(stateDir), "utf8").trim();
|
|
10155
10487
|
if (raw.length === 0) return [];
|
|
10156
10488
|
const parsed = JSON.parse(raw);
|
|
10157
10489
|
return Array.isArray(parsed) ? parsed.filter(isRecord9) : [];
|
|
@@ -10195,7 +10527,7 @@ function validateToolStats(value) {
|
|
|
10195
10527
|
}
|
|
10196
10528
|
function receiptTrustDetail(stateDir, runId) {
|
|
10197
10529
|
try {
|
|
10198
|
-
const receipt = JSON.parse(
|
|
10530
|
+
const receipt = JSON.parse(readFileSync6(receiptFilePath(stateDir, runId), "utf8"));
|
|
10199
10531
|
const ledger = readRunEnvelope(stateDir, runId);
|
|
10200
10532
|
return formatTrustSummaryLine(inspectRunReceiptTrustStatus(receipt, ledger.ok ? ledger.envelope : null).status);
|
|
10201
10533
|
} catch {
|
|
@@ -10213,7 +10545,7 @@ function verifyReceiptFile(stateDir, runId) {
|
|
|
10213
10545
|
const target = receiptFilePath(stateDir, runId);
|
|
10214
10546
|
let raw;
|
|
10215
10547
|
try {
|
|
10216
|
-
raw =
|
|
10548
|
+
raw = readFileSync6(target, "utf8");
|
|
10217
10549
|
} catch (err) {
|
|
10218
10550
|
const e = err;
|
|
10219
10551
|
if (e.code === "ENOENT") return { ok: false, reason: "receipt file not found" };
|
|
@@ -11340,7 +11672,7 @@ function workerReceiptFacts(receipt) {
|
|
|
11340
11672
|
function readReceiptFileFacts(runId, stateDir) {
|
|
11341
11673
|
let parsed;
|
|
11342
11674
|
try {
|
|
11343
|
-
parsed = JSON.parse(
|
|
11675
|
+
parsed = JSON.parse(readFileSync7(receiptFilePath(stateDir, runId), "utf8"));
|
|
11344
11676
|
} catch {
|
|
11345
11677
|
return null;
|
|
11346
11678
|
}
|
|
@@ -11359,7 +11691,7 @@ function findRunRow(runId, stateDir) {
|
|
|
11359
11691
|
const path = join6(stateDir, "runs.json");
|
|
11360
11692
|
if (!existsSync5(path)) return null;
|
|
11361
11693
|
try {
|
|
11362
|
-
const parsed = JSON.parse(
|
|
11694
|
+
const parsed = JSON.parse(readFileSync7(path, "utf8"));
|
|
11363
11695
|
if (!Array.isArray(parsed)) return null;
|
|
11364
11696
|
for (const entry of parsed) {
|
|
11365
11697
|
if (isRecord10(entry) && entry.id === runId) return entry;
|
|
@@ -12536,18 +12868,27 @@ function createTurnContext(deps) {
|
|
|
12536
12868
|
const { state, middleware } = deps;
|
|
12537
12869
|
const compactionTrigger = new AutoCompactionTrigger();
|
|
12538
12870
|
let currentContextSnapshot = null;
|
|
12871
|
+
let reconciledAnchor = null;
|
|
12539
12872
|
let lastCompactionEvent = null;
|
|
12540
12873
|
let lastPromptCache = null;
|
|
12541
12874
|
let lastSystemPromptReused = false;
|
|
12875
|
+
let lastPrewarm = null;
|
|
12542
12876
|
let sessionPrompt = null;
|
|
12543
12877
|
let sessionPromptKey = null;
|
|
12878
|
+
let sessionPromptHash = null;
|
|
12879
|
+
let resumedPromptHashRead = false;
|
|
12880
|
+
let resumedPromptHash = null;
|
|
12544
12881
|
const sessionWorkingContextPaths = /* @__PURE__ */ new Set();
|
|
12545
12882
|
let pendingPromptLogEntry = null;
|
|
12546
12883
|
let emptyAutoCompactTurnId = null;
|
|
12547
12884
|
const pendingColdReasons = /* @__PURE__ */ new Set();
|
|
12548
12885
|
let runExpectedColdReasons = [];
|
|
12549
12886
|
let nextAssistantColdReasons = [];
|
|
12550
|
-
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
|
+
]);
|
|
12551
12892
|
const stampsOnTier = (reason, runtimeId) => TIER_INDEPENDENT_COLD_REASONS.has(reason) || runtimeId !== void 0 && deps.providers.getRuntime(runtimeId)?.tier === "local-native";
|
|
12552
12893
|
const noteColdReason = (reason) => {
|
|
12553
12894
|
if (!state.streaming) {
|
|
@@ -12571,6 +12912,21 @@ function createTurnContext(deps) {
|
|
|
12571
12912
|
noteColdReason("compaction");
|
|
12572
12913
|
}) ?? null
|
|
12573
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,
|
|
12574
12930
|
deps.bus?.on(BusChannels.ContextRecalled, (payload) => {
|
|
12575
12931
|
middleware.fireCompactionHook("working_set_recall", payload.trigger);
|
|
12576
12932
|
}) ?? null
|
|
@@ -12625,6 +12981,23 @@ function createTurnContext(deps) {
|
|
|
12625
12981
|
}
|
|
12626
12982
|
return ceilChars(snapshot.pendingUserInput.length);
|
|
12627
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
|
+
};
|
|
12628
13001
|
const resolveWindowWithoutRuntime = () => {
|
|
12629
13002
|
const settings = deps.getSettings();
|
|
12630
13003
|
const targetId = settings.orchestrator?.target?.trim();
|
|
@@ -12636,7 +13009,8 @@ function createTurnContext(deps) {
|
|
|
12636
13009
|
requestedThinkingLevel: settings.orchestrator?.thinkingLevel ?? "off",
|
|
12637
13010
|
use: "orchestrator",
|
|
12638
13011
|
requireTools: false,
|
|
12639
|
-
requireOutputBudget: true
|
|
13012
|
+
requireOutputBudget: true,
|
|
13013
|
+
knownLoadedContextWindow: rememberedLoadedContextWindow(targetId, wireModelId)
|
|
12640
13014
|
});
|
|
12641
13015
|
return resolved.ok ? resolved.target.contextWindowDetails : null;
|
|
12642
13016
|
};
|
|
@@ -12669,6 +13043,19 @@ function createTurnContext(deps) {
|
|
|
12669
13043
|
}
|
|
12670
13044
|
return { contextWindow: 0, contextWindowSource: null, contextWindowSlots: null };
|
|
12671
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
|
+
};
|
|
12672
13059
|
const liveContextEstimate = (agentRuntime, pendingUserText) => {
|
|
12673
13060
|
const contextWindow = agentRuntime.runtimeResolution.contextWindowDetails.effectiveContextWindow;
|
|
12674
13061
|
const estimateInput = {
|
|
@@ -12677,10 +13064,25 @@ function createTurnContext(deps) {
|
|
|
12677
13064
|
tools: agentRuntime.agent.state.tools,
|
|
12678
13065
|
...pendingUserText !== void 0 ? { pendingUserText } : {}
|
|
12679
13066
|
};
|
|
13067
|
+
const breakdown = estimateAgentContextBreakdown(estimateInput);
|
|
13068
|
+
const estimatedTokens = estimateAgentContextTokens(estimateInput);
|
|
13069
|
+
const reconciledTokens = reconciledAnchoredTokens(agentRuntime, breakdown.pendingUserTokens);
|
|
12680
13070
|
return {
|
|
12681
|
-
|
|
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,
|
|
12682
13077
|
contextWindow,
|
|
12683
|
-
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
|
|
12684
13086
|
};
|
|
12685
13087
|
};
|
|
12686
13088
|
const refreshAgentMessagesFromSession = (agentRuntime) => {
|
|
@@ -12694,7 +13096,7 @@ function createTurnContext(deps) {
|
|
|
12694
13096
|
const emitCompactionActivity = (status, message) => {
|
|
12695
13097
|
deps.bus?.emit(BusChannels.ContextActivity, {
|
|
12696
13098
|
kind: "compaction",
|
|
12697
|
-
phase: "done",
|
|
13099
|
+
phase: status === "completed" ? "done" : "compact",
|
|
12698
13100
|
status,
|
|
12699
13101
|
message,
|
|
12700
13102
|
at: Date.now()
|
|
@@ -12761,6 +13163,7 @@ function createTurnContext(deps) {
|
|
|
12761
13163
|
emitCompactionActivity("started", "compacting context (mask stage)");
|
|
12762
13164
|
deps.session.replaceEntries(masked.entries);
|
|
12763
13165
|
refreshAgentMessagesFromSession(agentRuntime);
|
|
13166
|
+
reconciledAnchor = null;
|
|
12764
13167
|
deps.bus?.emit(BusChannels.CompactionEnd, { trigger, at: Date.now() });
|
|
12765
13168
|
const postMaskSnapshot = captureRuntimeContextSnapshot(
|
|
12766
13169
|
agentRuntime,
|
|
@@ -12839,6 +13242,7 @@ function createTurnContext(deps) {
|
|
|
12839
13242
|
});
|
|
12840
13243
|
noteColdReason("working_set_evict");
|
|
12841
13244
|
refreshAgentMessagesFromSession(agentRuntime);
|
|
13245
|
+
carryReconciledAnchorThroughProjection(agentRuntime, planned.tokensBefore - planned.tokensAfter);
|
|
12842
13246
|
const postEvictionSnapshot = captureRuntimeContextSnapshot(
|
|
12843
13247
|
agentRuntime,
|
|
12844
13248
|
state.activeUserTurnId || "compaction",
|
|
@@ -12914,6 +13318,7 @@ function createTurnContext(deps) {
|
|
|
12914
13318
|
deps.bus?.emit(BusChannels.CompactionEnd, { trigger, at: Date.now() });
|
|
12915
13319
|
recordCompactionUsage(agentRuntime, result);
|
|
12916
13320
|
refreshAgentMessagesFromSession(agentRuntime);
|
|
13321
|
+
reconciledAnchor = null;
|
|
12917
13322
|
const postCompactSnapshot = captureRuntimeContextSnapshot(
|
|
12918
13323
|
agentRuntime,
|
|
12919
13324
|
state.activeUserTurnId || "compaction",
|
|
@@ -12966,6 +13371,7 @@ function createTurnContext(deps) {
|
|
|
12966
13371
|
captureRuntimeContextSnapshot,
|
|
12967
13372
|
persistContextSnapshot,
|
|
12968
13373
|
liveContextEstimate,
|
|
13374
|
+
rememberedLoadedContextWindow,
|
|
12969
13375
|
refreshAgentMessagesFromSession,
|
|
12970
13376
|
runAutoCompact,
|
|
12971
13377
|
setCurrentSnapshot(snapshot) {
|
|
@@ -12976,6 +13382,14 @@ function createTurnContext(deps) {
|
|
|
12976
13382
|
persistContextSnapshot(currentContextSnapshot);
|
|
12977
13383
|
},
|
|
12978
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
|
+
}
|
|
12979
13393
|
if (!currentContextSnapshot) return;
|
|
12980
13394
|
currentContextSnapshot = reconcileSnapshot(currentContextSnapshot, usage);
|
|
12981
13395
|
snapshotPersistPending = true;
|
|
@@ -13003,7 +13417,10 @@ function createTurnContext(deps) {
|
|
|
13003
13417
|
return sessionPrompt;
|
|
13004
13418
|
}
|
|
13005
13419
|
const modelState = agentRuntime.agent.state.model;
|
|
13006
|
-
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;
|
|
13007
13424
|
const guidance = modelState?.clio?.quirks?.thinking?.guidance;
|
|
13008
13425
|
const toolNames = toolNamesFromAgentState(agentRuntime.agent.state.tools);
|
|
13009
13426
|
const toolPromptHints = toolNames.flatMap((name) => {
|
|
@@ -13036,16 +13453,19 @@ function createTurnContext(deps) {
|
|
|
13036
13453
|
cwd: process.cwd(),
|
|
13037
13454
|
workingContextPaths: [...sessionWorkingContextPaths]
|
|
13038
13455
|
});
|
|
13039
|
-
const previousHash =
|
|
13456
|
+
const previousHash = sessionPromptHash ?? lastRecordedPromptHash();
|
|
13040
13457
|
const changed = agentRuntime.agent.state.systemPrompt !== result.systemPrompt;
|
|
13041
13458
|
if (changed) {
|
|
13042
13459
|
agentRuntime.agent.state.systemPrompt = result.systemPrompt;
|
|
13043
13460
|
pendingPromptLogEntry = {
|
|
13461
|
+
version: PROMPT_MANIFEST_VERSION,
|
|
13044
13462
|
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
13045
13463
|
previousHash,
|
|
13046
13464
|
systemPromptHash: result.systemPromptHash,
|
|
13047
13465
|
tokenEstimate: result.tokenEstimate,
|
|
13048
13466
|
thinkingLevel: agentRuntime.agent.state.thinkingLevel ?? null,
|
|
13467
|
+
contextWindow,
|
|
13468
|
+
contextWindowSource,
|
|
13049
13469
|
projectPreload: result.projectPreload ?? null,
|
|
13050
13470
|
sections: result.sections.map((s) => ({ id: s.id, tokenEstimate: s.tokenEstimate })),
|
|
13051
13471
|
fragments: result.fragmentManifest.map((f) => ({
|
|
@@ -13058,6 +13478,7 @@ function createTurnContext(deps) {
|
|
|
13058
13478
|
}
|
|
13059
13479
|
lastSystemPromptReused = !changed;
|
|
13060
13480
|
sessionPrompt = result;
|
|
13481
|
+
sessionPromptHash = result.systemPromptHash;
|
|
13061
13482
|
sessionPromptKey = key;
|
|
13062
13483
|
return result;
|
|
13063
13484
|
} catch (err) {
|
|
@@ -13089,6 +13510,9 @@ function createTurnContext(deps) {
|
|
|
13089
13510
|
tokenEstimate: entry.tokenEstimate
|
|
13090
13511
|
}
|
|
13091
13512
|
});
|
|
13513
|
+
if (entry.previousHash !== null && entry.previousHash !== entry.systemPromptHash) {
|
|
13514
|
+
noteColdReason("prompt_recompiled");
|
|
13515
|
+
}
|
|
13092
13516
|
} catch {
|
|
13093
13517
|
}
|
|
13094
13518
|
appendPromptCompileRecord(currentMeta, entry);
|
|
@@ -13159,7 +13583,8 @@ function createTurnContext(deps) {
|
|
|
13159
13583
|
toolCount: liveToolCount,
|
|
13160
13584
|
compactionThreshold,
|
|
13161
13585
|
compactionAuto,
|
|
13162
|
-
promptCache: lastPromptCache
|
|
13586
|
+
promptCache: lastPromptCache,
|
|
13587
|
+
prewarm: lastPrewarm
|
|
13163
13588
|
});
|
|
13164
13589
|
}
|
|
13165
13590
|
const streamingOutput = liveStreamingOutputTokens();
|
|
@@ -13189,7 +13614,8 @@ function createTurnContext(deps) {
|
|
|
13189
13614
|
liveTotalTokens: totalUsed > 0 ? totalUsed : null,
|
|
13190
13615
|
measured,
|
|
13191
13616
|
lastCompaction: lastCompactionEvent,
|
|
13192
|
-
promptCache: lastPromptCache
|
|
13617
|
+
promptCache: lastPromptCache,
|
|
13618
|
+
prewarm: lastPrewarm
|
|
13193
13619
|
});
|
|
13194
13620
|
},
|
|
13195
13621
|
emitContextWindowWarningTransition(warning) {
|
|
@@ -13197,6 +13623,7 @@ function createTurnContext(deps) {
|
|
|
13197
13623
|
lastContextWindowWarning = warning;
|
|
13198
13624
|
deps.bus?.emit(BusChannels.ContextWarning, { warning });
|
|
13199
13625
|
},
|
|
13626
|
+
noteColdReason,
|
|
13200
13627
|
consumeExpectedColdReasons(runtimeId) {
|
|
13201
13628
|
runExpectedColdReasons = [];
|
|
13202
13629
|
nextAssistantColdReasons = [];
|
|
@@ -13210,7 +13637,7 @@ function createTurnContext(deps) {
|
|
|
13210
13637
|
}
|
|
13211
13638
|
}
|
|
13212
13639
|
},
|
|
13213
|
-
promptCachePayloadForAssistant(usage) {
|
|
13640
|
+
promptCachePayloadForAssistant(usage, backend) {
|
|
13214
13641
|
const input = typeof usage.input === "number" ? usage.input : 0;
|
|
13215
13642
|
const cacheRead = typeof usage.cacheRead === "number" ? usage.cacheRead : 0;
|
|
13216
13643
|
const cacheWrite = typeof usage.cacheWrite === "number" ? usage.cacheWrite : 0;
|
|
@@ -13218,34 +13645,54 @@ function createTurnContext(deps) {
|
|
|
13218
13645
|
input,
|
|
13219
13646
|
cacheRead,
|
|
13220
13647
|
cacheWrite,
|
|
13221
|
-
backendVerdict: backendCacheVerdict(input, cacheRead)
|
|
13648
|
+
backendVerdict: backendCacheVerdict(input, cacheRead, backend)
|
|
13222
13649
|
};
|
|
13650
|
+
if (backend !== void 0) promptCache.backend = { ...backend };
|
|
13223
13651
|
if (nextAssistantColdReasons.length > 0) {
|
|
13224
13652
|
promptCache.expectedColdReasons = [...nextAssistantColdReasons];
|
|
13225
13653
|
nextAssistantColdReasons = [];
|
|
13226
13654
|
}
|
|
13227
13655
|
return promptCache;
|
|
13228
13656
|
},
|
|
13657
|
+
notePrewarm(prewarm) {
|
|
13658
|
+
lastPrewarm = prewarm;
|
|
13659
|
+
},
|
|
13229
13660
|
noteRunCacheSummary(messages, runFirstCallVerdict) {
|
|
13661
|
+
lastPrewarm = null;
|
|
13230
13662
|
const cacheSummary = sumRunUsage(messages);
|
|
13231
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
|
+
}
|
|
13232
13671
|
lastPromptCache = {
|
|
13233
13672
|
shellReused: lastSystemPromptReused,
|
|
13234
13673
|
cacheReadTokens: cacheSummary.cacheRead > 0 || cacheSummary.cacheWrite > 0 ? cacheSummary.cacheRead : null,
|
|
13235
13674
|
cacheWriteTokens: cacheSummary.cacheRead > 0 || cacheSummary.cacheWrite > 0 ? cacheSummary.cacheWrite : null,
|
|
13236
13675
|
uncachedInputTokens: cacheSummary.input,
|
|
13676
|
+
backend: lastBackend,
|
|
13677
|
+
uncachedPrefillTokens: uncachedPrefillTokens(lastBackend),
|
|
13237
13678
|
backendVerdict: runFirstCallVerdict,
|
|
13238
13679
|
...runExpectedColdReasons.length > 0 ? { expectedColdReasons: [...runExpectedColdReasons] } : {}
|
|
13239
13680
|
};
|
|
13240
13681
|
}
|
|
13241
13682
|
},
|
|
13242
13683
|
resetForSession() {
|
|
13684
|
+
if (sessionPromptHash !== null) noteColdReason("prompt_recompiled");
|
|
13243
13685
|
lastPromptCache = null;
|
|
13686
|
+
lastPrewarm = null;
|
|
13244
13687
|
lastSystemPromptReused = false;
|
|
13688
|
+
sessionPromptHash = null;
|
|
13245
13689
|
sessionPromptKey = null;
|
|
13690
|
+
resumedPromptHashRead = false;
|
|
13691
|
+
resumedPromptHash = null;
|
|
13246
13692
|
sessionWorkingContextPaths.clear();
|
|
13247
13693
|
pendingPromptLogEntry = null;
|
|
13248
13694
|
emptyAutoCompactTurnId = null;
|
|
13695
|
+
reconciledAnchor = null;
|
|
13249
13696
|
const session = deps.session?.current();
|
|
13250
13697
|
currentContextSnapshot = session ? getLatestContextSnapshot(session) : null;
|
|
13251
13698
|
},
|
|
@@ -13542,7 +13989,8 @@ function createTurnPersistence(deps) {
|
|
|
13542
13989
|
if (timing) payload.timing = timing;
|
|
13543
13990
|
const usage = message.usage;
|
|
13544
13991
|
if (usage && typeof usage === "object") {
|
|
13545
|
-
|
|
13992
|
+
const backendTimings = message.backendTimings;
|
|
13993
|
+
payload.promptCache = deps.promptCachePayloadForAssistant(usage, backendTimings);
|
|
13546
13994
|
}
|
|
13547
13995
|
const interruptedUsage = estimatedUsageForInterruptedTurn(message, deps.promptSideTokens());
|
|
13548
13996
|
if (interruptedUsage !== null) payload.usage = interruptedUsage;
|
|
@@ -13583,8 +14031,8 @@ function createTurnPersistence(deps) {
|
|
|
13583
14031
|
appendAssistantTurn,
|
|
13584
14032
|
appendQueuedUserTurn(message) {
|
|
13585
14033
|
if (message?.role !== "user") return;
|
|
13586
|
-
const text = extractUserText(message)
|
|
13587
|
-
if (text.length === 0) return;
|
|
14034
|
+
const text = extractUserText(message);
|
|
14035
|
+
if (text.trim().length === 0) return;
|
|
13588
14036
|
if (deps.consumePersistedEcho(text)) return;
|
|
13589
14037
|
deps.removeQueuedMirrorEntry(text);
|
|
13590
14038
|
if (!deps.session) return;
|
|
@@ -13745,6 +14193,266 @@ function createTurnPersistence(deps) {
|
|
|
13745
14193
|
};
|
|
13746
14194
|
}
|
|
13747
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
|
+
|
|
13748
14456
|
// src/interactive/turn-queues.ts
|
|
13749
14457
|
init_esm_shims();
|
|
13750
14458
|
var DEFAULT_STEERING_MODE = "next-slot";
|
|
@@ -13756,14 +14464,13 @@ function createTurnQueues(deps) {
|
|
|
13756
14464
|
deps.emitQueueUpdateEvent(queuedMirror.map((entry) => ({ ...entry })));
|
|
13757
14465
|
};
|
|
13758
14466
|
const enqueue = (text, kind) => {
|
|
13759
|
-
|
|
13760
|
-
if (trimmed.length === 0 || !state.streaming || !state.runtime) return false;
|
|
14467
|
+
if (text.trim().length === 0 || !state.streaming || !state.runtime) return false;
|
|
13761
14468
|
const message = {
|
|
13762
14469
|
role: "user",
|
|
13763
|
-
content:
|
|
14470
|
+
content: text,
|
|
13764
14471
|
timestamp: Date.now()
|
|
13765
14472
|
};
|
|
13766
|
-
queuedMirror.push({ text
|
|
14473
|
+
queuedMirror.push({ text, kind });
|
|
13767
14474
|
if (kind === "steer") {
|
|
13768
14475
|
state.runtime.agent.steer(message);
|
|
13769
14476
|
} else {
|
|
@@ -14157,7 +14864,11 @@ function createTurnRuntime(deps) {
|
|
|
14157
14864
|
requestedThinkingLevel: settings.orchestrator.thinkingLevel ?? "off",
|
|
14158
14865
|
use: "orchestrator",
|
|
14159
14866
|
requireTools: false,
|
|
14160
|
-
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)
|
|
14161
14872
|
});
|
|
14162
14873
|
if (!resolved.ok) {
|
|
14163
14874
|
const failure = resolved.diagnostics.find((entry) => entry.severity === "error") ?? resolved.diagnostics[0];
|
|
@@ -14247,7 +14958,8 @@ function createTurnRuntime(deps) {
|
|
|
14247
14958
|
requestedThinkingLevel: deps.getSettings().orchestrator.thinkingLevel ?? "off",
|
|
14248
14959
|
use: "orchestrator",
|
|
14249
14960
|
requireTools: false,
|
|
14250
|
-
requireOutputBudget: true
|
|
14961
|
+
requireOutputBudget: true,
|
|
14962
|
+
knownLoadedContextWindow: context.rememberedLoadedContextWindow(target.target.id, target.wireModelId)
|
|
14251
14963
|
});
|
|
14252
14964
|
if (!refreshed.ok) return;
|
|
14253
14965
|
const liveModel = state.runtime.agent.state.model;
|
|
@@ -14608,7 +15320,8 @@ function createTurnRuntime(deps) {
|
|
|
14608
15320
|
if (isAssistant && usage && typeof usage === "object" && runFirstCallVerdict === null) {
|
|
14609
15321
|
const input = typeof usage.input === "number" ? usage.input : 0;
|
|
14610
15322
|
const cacheRead = typeof usage.cacheRead === "number" ? usage.cacheRead : 0;
|
|
14611
|
-
|
|
15323
|
+
const backendTimings = enrichedEvent.message.backendTimings;
|
|
15324
|
+
runFirstCallVerdict = backendCacheVerdict(input, cacheRead, backendTimings);
|
|
14612
15325
|
}
|
|
14613
15326
|
if (usage) {
|
|
14614
15327
|
context.reconcileUsage(usage);
|
|
@@ -14652,6 +15365,8 @@ function createTurnState(initialThinkingLevel) {
|
|
|
14652
15365
|
runtime: null,
|
|
14653
15366
|
lastTurnId: null,
|
|
14654
15367
|
streaming: false,
|
|
15368
|
+
turnPreparation: "idle",
|
|
15369
|
+
turnPreparationSince: 0,
|
|
14655
15370
|
currentThinkingLevel: initialThinkingLevel,
|
|
14656
15371
|
replayedContextMessages: [],
|
|
14657
15372
|
activeUserTurnId: null,
|
|
@@ -14769,6 +15484,31 @@ function createChatLoop(deps) {
|
|
|
14769
15484
|
const middlewareToolChoice = deps.middlewareToolChoice ?? createMiddlewareToolChoiceControl();
|
|
14770
15485
|
const state = createTurnState(deps.getSettings().orchestrator.thinkingLevel ?? "off");
|
|
14771
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
|
+
};
|
|
14772
15512
|
const emit = (event) => {
|
|
14773
15513
|
for (const listener of listeners) {
|
|
14774
15514
|
listener(event);
|
|
@@ -14845,7 +15585,7 @@ function createChatLoop(deps) {
|
|
|
14845
15585
|
middlewareToolChoice,
|
|
14846
15586
|
consumePersistedEcho: (text) => queues.consumePersistedEcho(text),
|
|
14847
15587
|
removeQueuedMirrorEntry: (text) => queues.removeQueuedMirrorEntry(text),
|
|
14848
|
-
promptCachePayloadForAssistant: (usage) => context.promptCachePayloadForAssistant(usage),
|
|
15588
|
+
promptCachePayloadForAssistant: (usage, backend) => context.promptCachePayloadForAssistant(usage, backend),
|
|
14849
15589
|
promptSideTokens: () => context.promptSideTokens(),
|
|
14850
15590
|
observability: deps.observability
|
|
14851
15591
|
});
|
|
@@ -14916,6 +15656,16 @@ function createChatLoop(deps) {
|
|
|
14916
15656
|
return { ok: false, reason: err instanceof Error ? err.message : String(err) };
|
|
14917
15657
|
}
|
|
14918
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
|
+
};
|
|
14919
15669
|
const writeOutOfTurnUsageRow = deps.recordOutOfTurnUsageRow ?? ((row2) => appendOutOfTurnUsageRow(clioStateDir(), row2));
|
|
14920
15670
|
const recordOutOfTurnUsage = (runtime, usage, label) => {
|
|
14921
15671
|
if (!usage) return;
|
|
@@ -14960,6 +15710,39 @@ function createChatLoop(deps) {
|
|
|
14960
15710
|
}
|
|
14961
15711
|
});
|
|
14962
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");
|
|
14963
15746
|
const api = {
|
|
14964
15747
|
steer: (text) => queues.steer(text),
|
|
14965
15748
|
queueFollowUp: (text) => queues.queueFollowUp(text),
|
|
@@ -14972,9 +15755,9 @@ function createChatLoop(deps) {
|
|
|
14972
15755
|
let mode = options.steering ?? DEFAULT_STEERING_MODE;
|
|
14973
15756
|
const trimmed = text.trim();
|
|
14974
15757
|
if (mode === "interrupt" && trimmed.length > 0) {
|
|
14975
|
-
const
|
|
14976
|
-
if (
|
|
14977
|
-
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");
|
|
14978
15761
|
mode = "next-slot";
|
|
14979
15762
|
} else {
|
|
14980
15763
|
const prior = priorSubmit;
|
|
@@ -14998,15 +15781,15 @@ function createChatLoop(deps) {
|
|
|
14998
15781
|
const hasImages = options.images !== void 0 && options.images.length > 0;
|
|
14999
15782
|
if (!hasImages && trimmed.length > 0 && state.runtime) {
|
|
15000
15783
|
if (isWorkerShareNote(trimmed)) state.turnSharedWorkerNote = true;
|
|
15001
|
-
if (mode === "end-of-turn") queues.queueFollowUp(
|
|
15002
|
-
else queues.steer(
|
|
15784
|
+
if (mode === "end-of-turn") queues.queueFollowUp(text);
|
|
15785
|
+
else queues.steer(text);
|
|
15003
15786
|
return;
|
|
15004
15787
|
}
|
|
15005
15788
|
emitNotice("[Clio Coder] response already in progress. Press Esc to cancel the active run.");
|
|
15006
15789
|
return;
|
|
15007
15790
|
}
|
|
15008
15791
|
}
|
|
15009
|
-
state.lastRunSnapshot
|
|
15792
|
+
const previousRunSnapshot = state.lastRunSnapshot;
|
|
15010
15793
|
let agentRuntime;
|
|
15011
15794
|
try {
|
|
15012
15795
|
await turnRuntime.ensureLiveCapabilitiesForSelectedModel();
|
|
@@ -15037,6 +15820,7 @@ function createChatLoop(deps) {
|
|
|
15037
15820
|
currentToolInvokeOptions,
|
|
15038
15821
|
turnRuntime.toolTelemetry
|
|
15039
15822
|
);
|
|
15823
|
+
const toolSignature = toolSignatureFromState(agentRuntime.agent.state.tools);
|
|
15040
15824
|
const askUserPolicy = createAskUserToolPolicy(agentRuntime.agent.state.tools);
|
|
15041
15825
|
middleware.fireTurnStart(agentRuntime, text, pendingSkillRequests.length, options.requestContinuation === true);
|
|
15042
15826
|
const reminderBlock = middleware.flushPendingReminders();
|
|
@@ -15051,9 +15835,12 @@ function createChatLoop(deps) {
|
|
|
15051
15835
|
const submittedText = [reminderBlock, skillPreamble, taskMemoryHandoffSource, text].filter((part) => part.length > 0).join("\n\n");
|
|
15052
15836
|
const forceNow = process.env.CLIO_CODER_FORCE_COMPACT === "1";
|
|
15053
15837
|
try {
|
|
15838
|
+
setTurnPreparation("compacting");
|
|
15054
15839
|
await context.runAutoCompact(agentRuntime, forceNow, void 0, void 0, submittedText);
|
|
15055
15840
|
} catch (err) {
|
|
15056
15841
|
emitNotice(`[Clio Coder] auto-compaction failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
15842
|
+
} finally {
|
|
15843
|
+
endPreparationCompaction();
|
|
15057
15844
|
}
|
|
15058
15845
|
const compiledPrompt = await context.ensureSessionPrompt(agentRuntime);
|
|
15059
15846
|
const compactionThreshold = deps.getSettings().compaction?.threshold ?? null;
|
|
@@ -15062,18 +15849,23 @@ function createChatLoop(deps) {
|
|
|
15062
15849
|
pendingUserInput: submittedText,
|
|
15063
15850
|
images,
|
|
15064
15851
|
promptHash: compiledPrompt?.systemPromptHash,
|
|
15065
|
-
toolSignature
|
|
15852
|
+
toolSignature
|
|
15066
15853
|
});
|
|
15067
15854
|
const reservedOutput = resolveReservedOutputTokens(agentRuntime.runtimeResolution.capabilityDecisions.maxTokens);
|
|
15068
15855
|
const effectiveWindow = agentRuntime.runtimeResolution.contextWindowDetails.effectiveContextWindow;
|
|
15069
15856
|
const pendingInputTokens = ceilChars(submittedText.length);
|
|
15070
15857
|
let turnSnapshot = captureTurnSnapshot("pending");
|
|
15071
|
-
const
|
|
15858
|
+
const budgetedPromptTokens = (snapshot) => Math.max(
|
|
15859
|
+
snapshotInputTokens(snapshot) + pendingInputTokens,
|
|
15860
|
+
context.liveContextEstimate(agentRuntime, submittedText).tokens
|
|
15861
|
+
);
|
|
15862
|
+
const totalEstimate = budgetedPromptTokens(turnSnapshot) + reservedOutput;
|
|
15072
15863
|
if (effectiveWindow > 0 && totalEstimate > effectiveWindow) {
|
|
15073
15864
|
emitNotice(
|
|
15074
|
-
`[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...`
|
|
15075
15866
|
);
|
|
15076
|
-
|
|
15867
|
+
setTurnPreparation("compacting");
|
|
15868
|
+
const compacted = await context.runAutoCompact(agentRuntime, true, void 0, void 0, submittedText).finally(endPreparationCompaction);
|
|
15077
15869
|
if (!compacted) {
|
|
15078
15870
|
emitNotice(
|
|
15079
15871
|
"[Clio Coder] Compaction could not reclaim enough space. Request blocked; trim the prompt, reduce active tools, or start a fresh session."
|
|
@@ -15082,7 +15874,7 @@ function createChatLoop(deps) {
|
|
|
15082
15874
|
}
|
|
15083
15875
|
context.refreshAgentMessagesFromSession(agentRuntime);
|
|
15084
15876
|
turnSnapshot = captureTurnSnapshot("pending");
|
|
15085
|
-
const postTotalEstimate =
|
|
15877
|
+
const postTotalEstimate = budgetedPromptTokens(turnSnapshot) + reservedOutput;
|
|
15086
15878
|
if (postTotalEstimate > effectiveWindow) {
|
|
15087
15879
|
emitNotice(
|
|
15088
15880
|
`[Clio Coder] Request still exceeds the effective window after compaction (${postTotalEstimate} > ${effectiveWindow}). Request blocked.`
|
|
@@ -15102,6 +15894,13 @@ function createChatLoop(deps) {
|
|
|
15102
15894
|
);
|
|
15103
15895
|
if (interrupted) emit({ type: "queued_user_turn", text, kind: "interrupt" });
|
|
15104
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
|
+
}
|
|
15105
15904
|
turnSnapshot = { ...turnSnapshot, turnId: userTurnId ?? "unknown" };
|
|
15106
15905
|
context.setCurrentSnapshot(turnSnapshot);
|
|
15107
15906
|
context.persistContextSnapshot(turnSnapshot);
|
|
@@ -15116,7 +15915,7 @@ function createChatLoop(deps) {
|
|
|
15116
15915
|
compiledPromptHash: promptHash,
|
|
15117
15916
|
staticCompositionHash: promptHash,
|
|
15118
15917
|
promptSignature: promptHash,
|
|
15119
|
-
toolSignature
|
|
15918
|
+
toolSignature,
|
|
15120
15919
|
runtimeResolution: runtimeTargetSnapshot(agentRuntime.runtimeResolution),
|
|
15121
15920
|
sessionId: deps.session?.current()?.id ?? null,
|
|
15122
15921
|
cwd: process.cwd()
|
|
@@ -15129,6 +15928,9 @@ function createChatLoop(deps) {
|
|
|
15129
15928
|
state.interruptedUsage = null;
|
|
15130
15929
|
context.consumeExpectedColdReasons(agentRuntime.runtimeId);
|
|
15131
15930
|
state.streaming = true;
|
|
15931
|
+
const endpointKey = canonicalEndpointKey(agentRuntime.runtimeResolution.target);
|
|
15932
|
+
const releaseForeground = endpointKey === null ? () => {
|
|
15933
|
+
} : registerForegroundStream(endpointKey);
|
|
15132
15934
|
try {
|
|
15133
15935
|
options.onAdmitted?.();
|
|
15134
15936
|
} catch {
|
|
@@ -15178,6 +15980,7 @@ function createChatLoop(deps) {
|
|
|
15178
15980
|
}
|
|
15179
15981
|
await recovery.runCompactAndRetry(agentRuntime, runtimePromptText, overflow, images);
|
|
15180
15982
|
} finally {
|
|
15983
|
+
releaseForeground();
|
|
15181
15984
|
if (askUserPolicy) {
|
|
15182
15985
|
try {
|
|
15183
15986
|
await finalizeAskUserInterviewForHost(
|
|
@@ -15247,9 +16050,19 @@ function createChatLoop(deps) {
|
|
|
15247
16050
|
isStreaming() {
|
|
15248
16051
|
return state.streaming;
|
|
15249
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
|
+
},
|
|
15250
16062
|
contextUsage: () => context.contextUsage(),
|
|
15251
16063
|
contextLedger: () => context.contextLedger(),
|
|
15252
16064
|
whenSettled: () => activeSubmit,
|
|
16065
|
+
whenPrewarmSettled: () => prewarm.settled(),
|
|
15253
16066
|
resetForSession(leafTurnId, replayMessages) {
|
|
15254
16067
|
if (state.runtime) {
|
|
15255
16068
|
state.runtime.agent.abort();
|
|
@@ -15261,6 +16074,7 @@ function createChatLoop(deps) {
|
|
|
15261
16074
|
middleware.clearPendingReminders();
|
|
15262
16075
|
middlewareToolChoice.reset();
|
|
15263
16076
|
state.lastTurnId = leafTurnId;
|
|
16077
|
+
state.lastRunSnapshot = null;
|
|
15264
16078
|
context.resetForSession();
|
|
15265
16079
|
void turnRuntime.ensureLiveCapabilitiesForSelectedModel().catch(() => {
|
|
15266
16080
|
});
|
|
@@ -15271,10 +16085,13 @@ function createChatLoop(deps) {
|
|
|
15271
16085
|
if (deps.protectedArtifacts) {
|
|
15272
16086
|
reloadProtectedArtifactsForSession(deps.protectedArtifacts, deps.readSessionEntries);
|
|
15273
16087
|
}
|
|
16088
|
+
prewarm.schedule(replayMessages && replayMessages.length > 0 ? "resume" : "session-start");
|
|
15274
16089
|
},
|
|
15275
16090
|
dispose() {
|
|
15276
16091
|
unsubscribeConfigReload?.();
|
|
15277
16092
|
unsubscribeSynthesisLock?.();
|
|
16093
|
+
unsubscribePrewarmCompaction();
|
|
16094
|
+
prewarm.dispose();
|
|
15278
16095
|
context.dispose();
|
|
15279
16096
|
if (state.runtime) {
|
|
15280
16097
|
state.runtime.agent.abort();
|
|
@@ -15297,16 +16114,19 @@ function createChatLoop(deps) {
|
|
|
15297
16114
|
if (!prepared.ok) return { status: "refused", reason: prepared.reason };
|
|
15298
16115
|
let result;
|
|
15299
16116
|
try {
|
|
15300
|
-
result = await
|
|
15301
|
-
|
|
15302
|
-
|
|
15303
|
-
|
|
15304
|
-
|
|
15305
|
-
|
|
15306
|
-
|
|
15307
|
-
|
|
15308
|
-
|
|
15309
|
-
|
|
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
|
+
);
|
|
15310
16130
|
} catch (err) {
|
|
15311
16131
|
return { status: "failed", reason: err instanceof Error ? err.message : String(err) };
|
|
15312
16132
|
}
|
|
@@ -15325,14 +16145,21 @@ function createChatLoop(deps) {
|
|
|
15325
16145
|
if (!prepared.ok) return { status: "refused", reason: prepared.reason };
|
|
15326
16146
|
let result;
|
|
15327
16147
|
try {
|
|
15328
|
-
result = await
|
|
15329
|
-
|
|
15330
|
-
|
|
15331
|
-
|
|
15332
|
-
|
|
15333
|
-
|
|
15334
|
-
|
|
15335
|
-
|
|
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
|
+
);
|
|
15336
16163
|
} catch (err) {
|
|
15337
16164
|
return { status: "failed", reason: err instanceof Error ? err.message : String(err) };
|
|
15338
16165
|
}
|
|
@@ -15371,13 +16198,17 @@ function createChatLoop(deps) {
|
|
|
15371
16198
|
const submitInner = api.submit.bind(api);
|
|
15372
16199
|
const submitTracked = (text, options) => {
|
|
15373
16200
|
priorSubmit = activeSubmit;
|
|
15374
|
-
|
|
16201
|
+
turnActive = true;
|
|
16202
|
+
const run = submitInner(text, options).finally(() => {
|
|
16203
|
+
turnActive = false;
|
|
16204
|
+
});
|
|
15375
16205
|
activeSubmit = run.catch(() => {
|
|
15376
16206
|
});
|
|
15377
16207
|
return run;
|
|
15378
16208
|
};
|
|
15379
16209
|
let admissionTail = null;
|
|
15380
16210
|
api.submit = (text, options = {}) => {
|
|
16211
|
+
prewarm.cancel();
|
|
15381
16212
|
const previous = admissionTail;
|
|
15382
16213
|
let release = () => {
|
|
15383
16214
|
};
|
|
@@ -15389,14 +16220,30 @@ function createChatLoop(deps) {
|
|
|
15389
16220
|
release();
|
|
15390
16221
|
if (admissionTail === ticket) admissionTail = null;
|
|
15391
16222
|
};
|
|
15392
|
-
|
|
15393
|
-
|
|
15394
|
-
|
|
15395
|
-
|
|
15396
|
-
|
|
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 {
|
|
15397
16235
|
}
|
|
15398
|
-
|
|
15399
|
-
|
|
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);
|
|
15400
16247
|
};
|
|
15401
16248
|
return api;
|
|
15402
16249
|
}
|
|
@@ -15716,6 +16563,17 @@ function buildArtifactHeader(artifact, verification, width) {
|
|
|
15716
16563
|
}
|
|
15717
16564
|
return padAnsi(parts.join(" "), width, ELLIPSIS);
|
|
15718
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
|
+
}
|
|
15719
16577
|
function viewFooterHint(focus, canVerify, innerWidth) {
|
|
15720
16578
|
if (innerWidth !== void 0 && viewUsesSinglePane(innerWidth - 2)) {
|
|
15721
16579
|
const budget = innerWidth - 3;
|
|
@@ -15905,14 +16763,14 @@ var ViewOverlayView = class {
|
|
|
15905
16763
|
this.ensureContentLoaded(artifact);
|
|
15906
16764
|
this.lastContentWidth = width;
|
|
15907
16765
|
const verification = artifact ? this.verifications.get(artifactKey(artifact)) : void 0;
|
|
15908
|
-
const header =
|
|
15909
|
-
const bodyHeight = Math.max(0, height -
|
|
16766
|
+
const header = buildArtifactHeaderLines(artifact, verification, width);
|
|
16767
|
+
const bodyHeight = Math.max(0, height - header.length);
|
|
15910
16768
|
this.lastContentBodyHeight = Math.max(1, bodyHeight);
|
|
15911
16769
|
const body = this.renderedContentLines(width);
|
|
15912
16770
|
const maxOffset = Math.max(0, body.length - Math.max(1, bodyHeight));
|
|
15913
16771
|
if (this.contentScrollOffset > maxOffset) this.contentScrollOffset = maxOffset;
|
|
15914
16772
|
const visible = body.slice(this.contentScrollOffset, this.contentScrollOffset + bodyHeight).map((line) => padAnsi(line, width, ELLIPSIS));
|
|
15915
|
-
const lines = [header, ...visible];
|
|
16773
|
+
const lines = [...header, ...visible];
|
|
15916
16774
|
return this.fixedLines(lines, width, height);
|
|
15917
16775
|
}
|
|
15918
16776
|
fixedLines(lines, width, height) {
|
|
@@ -16102,7 +16960,8 @@ function createQuestionState(question) {
|
|
|
16102
16960
|
selected: /* @__PURE__ */ new Set(),
|
|
16103
16961
|
customAnswer: "",
|
|
16104
16962
|
inputValue: "",
|
|
16105
|
-
answer: ""
|
|
16963
|
+
answer: "",
|
|
16964
|
+
rawValue: ""
|
|
16106
16965
|
};
|
|
16107
16966
|
}
|
|
16108
16967
|
function isOtherOption(label) {
|
|
@@ -16139,12 +16998,16 @@ function optionIndexFromValue(value) {
|
|
|
16139
16998
|
const index = Number(value.slice("option:".length));
|
|
16140
16999
|
return Number.isInteger(index) && index >= 0 ? index : null;
|
|
16141
17000
|
}
|
|
16142
|
-
function
|
|
16143
|
-
const
|
|
17001
|
+
function selectedOptionLabels(question, selected) {
|
|
17002
|
+
const labels = [];
|
|
16144
17003
|
for (const index of [...selected].sort((a, b) => a - b)) {
|
|
16145
17004
|
const label = question.options?.[index]?.label;
|
|
16146
|
-
if (label)
|
|
17005
|
+
if (label) labels.push(label);
|
|
16147
17006
|
}
|
|
17007
|
+
return labels;
|
|
17008
|
+
}
|
|
17009
|
+
function answerText(question, selected, customAnswer) {
|
|
17010
|
+
const parts = selectedOptionLabels(question, selected);
|
|
16148
17011
|
const custom = customAnswer.trim();
|
|
16149
17012
|
if (custom.length > 0) parts.push(custom);
|
|
16150
17013
|
return parts.join("; ");
|
|
@@ -16261,6 +17124,10 @@ var AskUserOverlayView = class {
|
|
|
16261
17124
|
this.commitMultiSelectOrOpenOther(state);
|
|
16262
17125
|
return;
|
|
16263
17126
|
}
|
|
17127
|
+
if (this.isAddTextKey(data)) {
|
|
17128
|
+
this.chooseFocusedAndOpenText(question, state);
|
|
17129
|
+
return;
|
|
17130
|
+
}
|
|
16264
17131
|
this.list?.handleInput(data);
|
|
16265
17132
|
}
|
|
16266
17133
|
/**
|
|
@@ -16387,20 +17254,16 @@ var AskUserOverlayView = class {
|
|
|
16387
17254
|
{ key: "Alt+Left/Right", verb: "question" }
|
|
16388
17255
|
]) : this.withScrollHint([{ key: "Enter", verb: recordAnswer }]);
|
|
16389
17256
|
}
|
|
17257
|
+
const addText = { key: "t", verb: "add text", short: "text" };
|
|
16390
17258
|
if (question.multi_select === true) {
|
|
16391
17259
|
return this.questions.length > 1 ? this.withScrollHint([
|
|
16392
17260
|
{ key: "Left/Right", verb: "question" },
|
|
16393
17261
|
{ key: "Space", verb: "toggle" },
|
|
17262
|
+
addText,
|
|
16394
17263
|
{ key: "Enter", verb: recordAnswer }
|
|
16395
|
-
]) : this.withScrollHint([
|
|
16396
|
-
{ key: "Space", verb: "toggle" },
|
|
16397
|
-
{ key: "Enter", verb: recordAnswer }
|
|
16398
|
-
]);
|
|
17264
|
+
]) : this.withScrollHint([{ key: "Space", verb: "toggle" }, addText, { key: "Enter", verb: recordAnswer }]);
|
|
16399
17265
|
}
|
|
16400
|
-
return this.questions.length > 1 ? this.withScrollHint([
|
|
16401
|
-
{ key: "Left/Right", verb: "question" },
|
|
16402
|
-
{ key: "Enter", verb: recordAnswer }
|
|
16403
|
-
]) : 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 }]);
|
|
16404
17267
|
}
|
|
16405
17268
|
renderDecisionContext(width) {
|
|
16406
17269
|
const theme6 = clioTheme();
|
|
@@ -16501,6 +17364,32 @@ var AskUserOverlayView = class {
|
|
|
16501
17364
|
isTextModeNextKey(data) {
|
|
16502
17365
|
return this.questions.length > 1 && (matchesKey(data, "alt+right") || matchesKey(data, "ctrl+right"));
|
|
16503
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
|
+
}
|
|
16504
17393
|
/**
|
|
16505
17394
|
* The row above the question, or nothing.
|
|
16506
17395
|
*
|
|
@@ -16654,14 +17543,15 @@ var AskUserOverlayView = class {
|
|
|
16654
17543
|
return;
|
|
16655
17544
|
}
|
|
16656
17545
|
state.inputValue = answer;
|
|
17546
|
+
state.rawValue = value;
|
|
16657
17547
|
if (questionHasOptions(question) && question.multi_select === true) {
|
|
16658
17548
|
state.customAnswer = answer;
|
|
16659
17549
|
this.commitCurrentAnswer();
|
|
16660
|
-
|
|
16661
|
-
state.customAnswer = questionHasOptions(question) ? answer : "";
|
|
16662
|
-
state.answer = answer;
|
|
16663
|
-
this.finishIfCompleteOrAdvance();
|
|
17550
|
+
return;
|
|
16664
17551
|
}
|
|
17552
|
+
state.customAnswer = questionHasOptions(question) ? answer : "";
|
|
17553
|
+
state.answer = questionHasOptions(question) ? answerText(question, state.selected, state.customAnswer) : answer;
|
|
17554
|
+
this.finishIfCompleteOrAdvance();
|
|
16665
17555
|
};
|
|
16666
17556
|
activeInput.onEscape = () => this.cancel();
|
|
16667
17557
|
this.input = activeInput;
|
|
@@ -16690,7 +17580,10 @@ var AskUserOverlayView = class {
|
|
|
16690
17580
|
return;
|
|
16691
17581
|
}
|
|
16692
17582
|
state.selected = /* @__PURE__ */ new Set([optionIndex]);
|
|
16693
|
-
state.
|
|
17583
|
+
state.customAnswer = "";
|
|
17584
|
+
state.rawValue = "";
|
|
17585
|
+
state.inputValue = "";
|
|
17586
|
+
state.answer = answerText(question, state.selected, state.customAnswer) || item.label;
|
|
16694
17587
|
state.focusedValue = item.value;
|
|
16695
17588
|
this.status = "";
|
|
16696
17589
|
this.finishIfCompleteOrAdvance();
|
|
@@ -16802,12 +17695,26 @@ var AskUserOverlayView = class {
|
|
|
16802
17695
|
allAnswered() {
|
|
16803
17696
|
return this.states.length > 0 && this.states.every((state) => state.answer.trim().length > 0);
|
|
16804
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
|
+
*/
|
|
16805
17704
|
answers() {
|
|
16806
17705
|
const answers = [];
|
|
16807
17706
|
for (let index = 0; index < this.questions.length; index += 1) {
|
|
16808
17707
|
const question = this.questions[index];
|
|
16809
|
-
const
|
|
16810
|
-
|
|
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
|
+
});
|
|
16811
17718
|
}
|
|
16812
17719
|
return answers;
|
|
16813
17720
|
}
|
|
@@ -17416,7 +18323,7 @@ function legendRow2(group, contentWidth) {
|
|
|
17416
18323
|
const tokens = formatTokens(group.tokens);
|
|
17417
18324
|
const percent = formatContextPercent(group.percent);
|
|
17418
18325
|
const right = `${tokens.padStart(9)} ${percent.padStart(6)}`;
|
|
17419
|
-
const labelToken = group.category === "
|
|
18326
|
+
const labelToken = group.category === "reserve" ? "frame" : group.category === "free" ? "dim" : "muted";
|
|
17420
18327
|
const leftWidth = Math.max(0, contentWidth - visibleWidth(right) - 2);
|
|
17421
18328
|
const labelText = group.label.length > leftWidth ? group.label.slice(0, leftWidth) : group.label.padEnd(leftWidth);
|
|
17422
18329
|
return `${swatch} ${theme6.fg(labelToken, labelText)} ${theme6.fg("muted", right)}`;
|
|
@@ -17438,6 +18345,16 @@ function coldReasonLabel(reason) {
|
|
|
17438
18345
|
return "compaction";
|
|
17439
18346
|
case "dispatch":
|
|
17440
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";
|
|
17441
18358
|
default:
|
|
17442
18359
|
return reason;
|
|
17443
18360
|
}
|
|
@@ -17509,18 +18426,28 @@ function renderContextLedgerLines(ledger, contentWidth, workingSet, workingSetCo
|
|
|
17509
18426
|
if (ledger.promptCache) {
|
|
17510
18427
|
const cache2 = ledger.promptCache;
|
|
17511
18428
|
const shell = cache2.shellReused ? "shell reused" : "shell recompiled";
|
|
17512
|
-
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";
|
|
17513
18431
|
const read = cache2.cacheReadTokens !== null ? `cache read ${formatTokens(cache2.cacheReadTokens)}` : "cache read n/a";
|
|
17514
18432
|
const uncached = cache2.uncachedInputTokens !== null ? `uncached input ${formatTokens(cache2.uncachedInputTokens)}` : null;
|
|
17515
|
-
const line = ["prompt cache:", shell, "\xB7", backend, "\xB7", read, ...uncached ? ["\xB7", uncached] : []].join(" ");
|
|
17516
|
-
const coldReasons = cache2.backendVerdict === "cold" ? cache2.expectedColdReasons ?? [] : [];
|
|
17517
|
-
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;
|
|
17518
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
|
+
}
|
|
17519
18441
|
if (coldReasons.length > 0) {
|
|
17520
18442
|
const reasons = coldReasons.map(coldReasonLabel).join(", ");
|
|
17521
18443
|
lines.push(theme6.fg("dim", `last cold turn: ${reasons} (expected)`));
|
|
17522
18444
|
}
|
|
17523
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
|
+
}
|
|
17524
18451
|
if (ledger.lastCompaction) {
|
|
17525
18452
|
const pruneInfo = `last compaction: reclaimed ${formatTokens(ledger.lastCompaction.tokensBefore)} -> ${formatTokens(ledger.lastCompaction.tokensAfter)} tokens (${ledger.lastCompaction.stage})`;
|
|
17526
18453
|
lines.push(theme6.fg("dim", pruneInfo));
|
|
@@ -17614,6 +18541,8 @@ function aggregateCostEntries(entries) {
|
|
|
17614
18541
|
existing.row.apiCalls += entry.apiCalls ?? 1;
|
|
17615
18542
|
if (entry.label === "side-question") existing.row.sideQuestions += 1;
|
|
17616
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;
|
|
17617
18546
|
for (const requestedModelId of entry.requestedModelIds) existing.requestedModelIds.add(requestedModelId);
|
|
17618
18547
|
addResponseModelIdObservationCounts(
|
|
17619
18548
|
existing.responseModelIdObservationCounts,
|
|
@@ -17635,7 +18564,9 @@ function aggregateCostEntries(entries) {
|
|
|
17635
18564
|
reasoningTokens: entry.reasoningTokens,
|
|
17636
18565
|
apiCalls: entry.apiCalls ?? 1,
|
|
17637
18566
|
sideQuestions: entry.label === "side-question" ? 1 : 0,
|
|
17638
|
-
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
|
|
17639
18570
|
},
|
|
17640
18571
|
requestedModelIds: new Set(entry.requestedModelIds),
|
|
17641
18572
|
responseModelIdObservationCounts: { ...entry.responseModelIdObservationCounts },
|
|
@@ -17667,7 +18598,9 @@ function sumRows(rows) {
|
|
|
17667
18598
|
reasoningTokens: acc.reasoningTokens + row2.reasoningTokens,
|
|
17668
18599
|
apiCalls: acc.apiCalls + row2.apiCalls,
|
|
17669
18600
|
sideQuestions: acc.sideQuestions + row2.sideQuestions,
|
|
17670
|
-
handoffs: acc.handoffs + row2.handoffs
|
|
18601
|
+
handoffs: acc.handoffs + row2.handoffs,
|
|
18602
|
+
prewarms: acc.prewarms + row2.prewarms,
|
|
18603
|
+
backgroundMemory: acc.backgroundMemory + row2.backgroundMemory
|
|
17671
18604
|
}),
|
|
17672
18605
|
{
|
|
17673
18606
|
runs: 0,
|
|
@@ -17679,7 +18612,9 @@ function sumRows(rows) {
|
|
|
17679
18612
|
reasoningTokens: 0,
|
|
17680
18613
|
apiCalls: 0,
|
|
17681
18614
|
sideQuestions: 0,
|
|
17682
|
-
handoffs: 0
|
|
18615
|
+
handoffs: 0,
|
|
18616
|
+
prewarms: 0,
|
|
18617
|
+
backgroundMemory: 0
|
|
17683
18618
|
}
|
|
17684
18619
|
);
|
|
17685
18620
|
}
|
|
@@ -17701,21 +18636,37 @@ function kvBlock(entries) {
|
|
|
17701
18636
|
return annotation ? `${row2} ${theme6.fg("dim", annotation)}` : row2;
|
|
17702
18637
|
});
|
|
17703
18638
|
}
|
|
17704
|
-
function summaryBlock(totalCost, totalTokens, rows) {
|
|
18639
|
+
function summaryBlock(totalCost, totalTokens, rows, promptCache) {
|
|
17705
18640
|
const totals = sumRows(rows);
|
|
17706
18641
|
const resolvedTotal = totalTokens > 0 ? totalTokens : totals.tokens;
|
|
17707
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
|
+
] : [];
|
|
17708
18653
|
return kvBlock([
|
|
17709
|
-
[
|
|
18654
|
+
[
|
|
18655
|
+
"turns",
|
|
18656
|
+
formatTokens2(totals.runs - totals.sideQuestions - totals.handoffs - totals.prewarms - totals.backgroundMemory)
|
|
18657
|
+
],
|
|
17710
18658
|
["model calls", formatTokens2(totals.apiCalls)],
|
|
17711
18659
|
...totals.sideQuestions > 0 ? [["side questions", formatTokens2(totals.sideQuestions)]] : [],
|
|
17712
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)]] : [],
|
|
17713
18663
|
...cost === null ? [] : [["cost", cost]],
|
|
17714
18664
|
["input", formatTokens2(totals.input)],
|
|
17715
18665
|
["output", formatTokens2(totals.output)],
|
|
17716
18666
|
["reasoning", ...reasoningValue(totals.reasoningTokens)],
|
|
17717
18667
|
["cache read", ...cacheReadValue(totals.cacheRead, totals.apiCalls)],
|
|
17718
18668
|
["cache write", formatTokens2(totals.cacheWrite)],
|
|
18669
|
+
...cacheRows,
|
|
17719
18670
|
["processed", `${formatTokens2(resolvedTotal)} tokens`]
|
|
17720
18671
|
]);
|
|
17721
18672
|
}
|
|
@@ -17724,10 +18675,12 @@ function modelBlock(row2) {
|
|
|
17724
18675
|
return kvBlock([
|
|
17725
18676
|
["requested model ids", row2.requestedModelIds.join(", ")],
|
|
17726
18677
|
["response model id observation", responseModelIdObservationCountsLabel(row2.responseModelIdObservationCounts)],
|
|
17727
|
-
["turns", formatTokens2(row2.runs - row2.sideQuestions - row2.handoffs)],
|
|
18678
|
+
["turns", formatTokens2(row2.runs - row2.sideQuestions - row2.handoffs - row2.prewarms - row2.backgroundMemory)],
|
|
17728
18679
|
["model calls", formatTokens2(row2.apiCalls)],
|
|
17729
18680
|
...row2.sideQuestions > 0 ? [["side questions", formatTokens2(row2.sideQuestions)]] : [],
|
|
17730
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)]] : [],
|
|
17731
18684
|
...cost === null ? [] : [["cost", cost]],
|
|
17732
18685
|
["input", formatTokens2(row2.input)],
|
|
17733
18686
|
["output", formatTokens2(row2.output)],
|
|
@@ -17737,10 +18690,10 @@ function modelBlock(row2) {
|
|
|
17737
18690
|
["processed", `${formatTokens2(row2.tokens)} tokens`]
|
|
17738
18691
|
]);
|
|
17739
18692
|
}
|
|
17740
|
-
function formatCostOverlayBodyLines(totalCost, totalTokens, rows, contentWidth) {
|
|
18693
|
+
function formatCostOverlayBodyLines(totalCost, totalTokens, rows, contentWidth, promptCache = null) {
|
|
17741
18694
|
const theme6 = clioTheme();
|
|
17742
18695
|
const lines = [];
|
|
17743
|
-
for (const line of summaryBlock(totalCost, totalTokens, rows)) {
|
|
18696
|
+
for (const line of summaryBlock(totalCost, totalTokens, rows, promptCache)) {
|
|
17744
18697
|
lines.push(line);
|
|
17745
18698
|
}
|
|
17746
18699
|
lines.push(rule(theme6, contentWidth));
|
|
@@ -17757,7 +18710,7 @@ function formatCostOverlayBodyLines(totalCost, totalTokens, rows, contentWidth)
|
|
|
17757
18710
|
}
|
|
17758
18711
|
return lines;
|
|
17759
18712
|
}
|
|
17760
|
-
function buildCostSnapshot(observability, sessionId, snapshot) {
|
|
18713
|
+
function buildCostSnapshot(observability, sessionId, snapshot, getSessionEntries) {
|
|
17761
18714
|
const entries = observability.costEntries();
|
|
17762
18715
|
const rows = aggregateCostEntries(entries);
|
|
17763
18716
|
const totalTokens = rows.reduce((sum, r) => sum + r.tokens, 0);
|
|
@@ -17765,7 +18718,8 @@ function buildCostSnapshot(observability, sessionId, snapshot) {
|
|
|
17765
18718
|
sessionId,
|
|
17766
18719
|
totalCost: snapshot?.session.cost ?? observability.sessionCostSummary(),
|
|
17767
18720
|
totalTokens,
|
|
17768
|
-
rows
|
|
18721
|
+
rows,
|
|
18722
|
+
promptCache: getSessionEntries ? foldPromptCacheTelemetry(getSessionEntries()) : null
|
|
17769
18723
|
};
|
|
17770
18724
|
}
|
|
17771
18725
|
var CostOverlayBody = class {
|
|
@@ -17776,7 +18730,13 @@ var CostOverlayBody = class {
|
|
|
17776
18730
|
render(width) {
|
|
17777
18731
|
const contentWidth = Math.max(1, Math.floor(width));
|
|
17778
18732
|
const snapshot = this.getSnapshot();
|
|
17779
|
-
return formatCostOverlayBodyLines(
|
|
18733
|
+
return formatCostOverlayBodyLines(
|
|
18734
|
+
snapshot.totalCost,
|
|
18735
|
+
snapshot.totalTokens,
|
|
18736
|
+
snapshot.rows,
|
|
18737
|
+
contentWidth,
|
|
18738
|
+
snapshot.promptCache
|
|
18739
|
+
);
|
|
17780
18740
|
}
|
|
17781
18741
|
invalidate() {
|
|
17782
18742
|
}
|
|
@@ -17784,7 +18744,9 @@ var CostOverlayBody = class {
|
|
|
17784
18744
|
function openCostOverlay(tui, observability, options) {
|
|
17785
18745
|
const sessionId = options?.sessionId ?? null;
|
|
17786
18746
|
let latest = observability.snapshot();
|
|
17787
|
-
const body = new CostOverlayBody(
|
|
18747
|
+
const body = new CostOverlayBody(
|
|
18748
|
+
() => buildCostSnapshot(observability, sessionId, latest, options?.getSessionEntries)
|
|
18749
|
+
);
|
|
17788
18750
|
const handle = showClioOverlayFrame(tui, body, {
|
|
17789
18751
|
anchor: "center",
|
|
17790
18752
|
width: COST_OVERLAY_WIDTH,
|
|
@@ -17871,6 +18833,38 @@ function compileFleetRunPreview(input) {
|
|
|
17871
18833
|
diagnostics.push(describeError(error));
|
|
17872
18834
|
return fail();
|
|
17873
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
|
+
}
|
|
17874
18868
|
try {
|
|
17875
18869
|
preflightWriteBoundaries(plan, input.workspaceRoot);
|
|
17876
18870
|
} catch (error) {
|
|
@@ -17919,19 +18913,7 @@ function compileFleetRunPreview(input) {
|
|
|
17919
18913
|
}
|
|
17920
18914
|
];
|
|
17921
18915
|
}
|
|
17922
|
-
|
|
17923
|
-
try {
|
|
17924
|
-
route = input.resolveRoute?.({
|
|
17925
|
-
stepId: step.id,
|
|
17926
|
-
agentId: step.agentId,
|
|
17927
|
-
task: step.task,
|
|
17928
|
-
scope: step.scope,
|
|
17929
|
-
...step.target !== void 0 ? { target: step.target } : {},
|
|
17930
|
-
...step.profile !== void 0 ? { profile: step.profile } : {}
|
|
17931
|
-
}) ?? null;
|
|
17932
|
-
} catch (error) {
|
|
17933
|
-
diagnostics.push(`step '${step.id}' route preflight failed: ${describeError(error)}`);
|
|
17934
|
-
}
|
|
18916
|
+
const route = routes.get(step.id) ?? null;
|
|
17935
18917
|
return [
|
|
17936
18918
|
{
|
|
17937
18919
|
...base,
|
|
@@ -18549,6 +19531,8 @@ function formatMemoryStatusLine(status, contentWidth) {
|
|
|
18549
19531
|
theme6.fg("muted", `last ${status.lastDecision ?? "none"}`)
|
|
18550
19532
|
];
|
|
18551
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));
|
|
18552
19536
|
return fitUnits(theme6, "", units, width);
|
|
18553
19537
|
}
|
|
18554
19538
|
function bankEntries(snapshot) {
|
|
@@ -18645,7 +19629,8 @@ function memorySignature(status, records) {
|
|
|
18645
19629
|
status.tier,
|
|
18646
19630
|
String(status.size),
|
|
18647
19631
|
status.lastDecision ?? "none",
|
|
18648
|
-
status.stepInFlight ? "running" : "idle"
|
|
19632
|
+
status.stepInFlight ? "running" : "idle",
|
|
19633
|
+
`${status.spend?.llmSteps ?? 0}:${status.spend?.injections ?? 0}:${status.spend?.totalTokens ?? 0}`
|
|
18649
19634
|
];
|
|
18650
19635
|
for (const record2 of records) parts.push(`r:${record2.id}:${record2.approved}:${record2.rejectedAt ?? ""}`);
|
|
18651
19636
|
for (const entry of bankEntries(status.bank)) {
|
|
@@ -21303,6 +22288,7 @@ function buildSettingItems(settings, options) {
|
|
|
21303
22288
|
}),
|
|
21304
22289
|
fleetGroupHeader("fleet.group.placement", "Placement"),
|
|
21305
22290
|
...fleetNodeRows(options?.getFleetNodes?.() ?? []),
|
|
22291
|
+
...fleetEndpointRows(options?.providers),
|
|
21306
22292
|
settingItem("targets", "", {
|
|
21307
22293
|
description: "Live inference target inventory and routing roles.",
|
|
21308
22294
|
affordance: "column heading",
|
|
@@ -21641,6 +22627,32 @@ function fleetNodeRows(nodes) {
|
|
|
21641
22627
|
});
|
|
21642
22628
|
});
|
|
21643
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
|
+
}
|
|
21644
22656
|
function buildSettingsSections(items) {
|
|
21645
22657
|
return SETTINGS_SECTIONS.map((section2) => ({
|
|
21646
22658
|
id: section2.id,
|
|
@@ -25080,8 +26092,8 @@ function dispatchSlashCommand(command, ctx) {
|
|
|
25080
26092
|
ctx.submitChat(command.text);
|
|
25081
26093
|
return "accepted";
|
|
25082
26094
|
}
|
|
25083
|
-
const
|
|
25084
|
-
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.`);
|
|
25085
26097
|
ctx.render();
|
|
25086
26098
|
return "rejected";
|
|
25087
26099
|
}
|
|
@@ -25532,7 +26544,10 @@ function createOverlayGeneralOpeners(deps) {
|
|
|
25532
26544
|
if (deps.transitions.state !== "closed") return;
|
|
25533
26545
|
deps.transitions.state = "cost";
|
|
25534
26546
|
deps.transitions.handle = openCostOverlayFactory(deps.tui, deps.observability, {
|
|
25535
|
-
sessionId: deps.getSessionId?.() ?? null
|
|
26547
|
+
sessionId: deps.getSessionId?.() ?? null,
|
|
26548
|
+
...deps.readSessionEntries ? {
|
|
26549
|
+
getSessionEntries: () => deps.readSessionEntries?.() ?? []
|
|
26550
|
+
} : {}
|
|
25536
26551
|
});
|
|
25537
26552
|
deps.requestRender();
|
|
25538
26553
|
};
|
|
@@ -25777,10 +26792,17 @@ function createOverlayGeneralOpeners(deps) {
|
|
|
25777
26792
|
};
|
|
25778
26793
|
const resolution = deps.dispatch.preview?.(request);
|
|
25779
26794
|
if (!resolution) return null;
|
|
26795
|
+
const foregroundHeld = resolution.endpoint === void 0 ? 0 : foregroundStreamUsage()[resolution.endpoint.key] ?? 0;
|
|
25780
26796
|
return {
|
|
25781
26797
|
targetId: resolution.targetId,
|
|
25782
26798
|
wireModelId: resolution.wireModelId,
|
|
25783
|
-
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
|
+
} : {}
|
|
25784
26806
|
};
|
|
25785
26807
|
}
|
|
25786
26808
|
});
|
|
@@ -25967,12 +26989,41 @@ function permissionOverlayPlacement(tui, editor, footer) {
|
|
|
25967
26989
|
};
|
|
25968
26990
|
}
|
|
25969
26991
|
var PermissionOverlayBody = class {
|
|
25970
|
-
constructor(view) {
|
|
26992
|
+
constructor(view, inspect) {
|
|
25971
26993
|
this.view = view;
|
|
26994
|
+
this.inspect = inspect;
|
|
25972
26995
|
}
|
|
25973
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
|
+
}
|
|
25974
27022
|
render(width) {
|
|
25975
|
-
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;
|
|
25976
27027
|
}
|
|
25977
27028
|
invalidate() {
|
|
25978
27029
|
}
|
|
@@ -26033,18 +27084,66 @@ function permissionOverlayTitle(view) {
|
|
|
26033
27084
|
function permissionOverlayTone(view) {
|
|
26034
27085
|
return permissionDecisionPresentation(view).semanticToken;
|
|
26035
27086
|
}
|
|
26036
|
-
function permissionOverlayHint(innerWidth, composerHasDraft = false) {
|
|
26037
|
-
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";
|
|
26038
27092
|
}
|
|
26039
27093
|
function actionConsequence(presentation, id) {
|
|
26040
27094
|
return presentation.requiredActions.find((action) => action.id === id)?.consequence ?? "";
|
|
26041
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
|
+
}
|
|
26042
27127
|
function permissionOverlayLines(view, width) {
|
|
26043
27128
|
const content = Math.max(8, Math.floor(width));
|
|
26044
27129
|
const presentation = permissionDecisionPresentation(view);
|
|
26045
27130
|
const lines = [
|
|
26046
27131
|
field("Tool: ", `${view.tool} \xB7 Action: ${view.actionClass}`, content),
|
|
26047
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
|
+
) : [],
|
|
26048
27147
|
...wrapSentence(`Requested by: ${presentation.requestedByCopy}`, content),
|
|
26049
27148
|
...view.artifact !== void 0 ? [
|
|
26050
27149
|
"",
|
|
@@ -26064,8 +27163,8 @@ function permissionOverlayLines(view, width) {
|
|
|
26064
27163
|
}
|
|
26065
27164
|
return lines;
|
|
26066
27165
|
}
|
|
26067
|
-
function createPermissionOverlayBody(view) {
|
|
26068
|
-
return new PermissionOverlayBody(view);
|
|
27166
|
+
function createPermissionOverlayBody(view, inspect) {
|
|
27167
|
+
return new PermissionOverlayBody(view, inspect);
|
|
26069
27168
|
}
|
|
26070
27169
|
|
|
26071
27170
|
// src/interactive/bus-notices.ts
|
|
@@ -26286,6 +27385,7 @@ function mainApprovalRequestView(call, decision, meta, autonomy, queueDepth) {
|
|
|
26286
27385
|
const axisFromDecision = askAxis(decision);
|
|
26287
27386
|
const axis = axisFromMeta ?? (axisFromDecision.kind === "net" ? { kind: "net", ruleId: axisFromDecision.ruleId } : { kind: "autonomy", level: autonomy });
|
|
26288
27387
|
const target = describeCallTarget(call.tool, call.args);
|
|
27388
|
+
const mutation = mutationFacts(call.tool, call.args);
|
|
26289
27389
|
return {
|
|
26290
27390
|
requestId: meta?.requestId ?? "permission-pending",
|
|
26291
27391
|
tool: call.tool,
|
|
@@ -26296,9 +27396,14 @@ function mainApprovalRequestView(call, decision, meta, autonomy, queueDepth) {
|
|
|
26296
27396
|
...call.tool === ToolNames.Dispatch && decision.kind === "ask" ? { artifact: { kind: "dispatch-plan", text: decision.rejection.detail } } : {},
|
|
26297
27397
|
...call.tool === ToolNames.AskUser ? { exposure: askUserExposure(call.args) } : {},
|
|
26298
27398
|
...target.length > 0 ? { target } : {},
|
|
27399
|
+
...mutation !== null ? { mutation } : {},
|
|
26299
27400
|
...queueDepth !== void 0 && queueDepth > 1 ? { queueDepth } : {}
|
|
26300
27401
|
};
|
|
26301
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
|
+
}
|
|
26302
27407
|
function workerEscalationEntry(payload, autonomy) {
|
|
26303
27408
|
if (!isLiveWorkerEscalationRequest(payload) || typeof payload.requestId !== "string") return null;
|
|
26304
27409
|
const origin = typeof payload.origin === "string" ? payload.origin : void 0;
|
|
@@ -26372,7 +27477,7 @@ function createOverlayPermissionLifecycle(deps) {
|
|
|
26372
27477
|
announceParked();
|
|
26373
27478
|
return;
|
|
26374
27479
|
}
|
|
26375
|
-
if (!deps.openPermissionOverlay(view)) {
|
|
27480
|
+
if (!deps.openPermissionOverlay(view, mainMutationInspector(call, view))) {
|
|
26376
27481
|
announceParked();
|
|
26377
27482
|
return;
|
|
26378
27483
|
}
|
|
@@ -26760,7 +27865,8 @@ function openHelpOverlay(tui, manager, onClose, initialFilter) {
|
|
|
26760
27865
|
"**Tool surface**: which tools exist at all through registration, tool profiles, skill narrowing, and dispatch admission. Violations are terminal denials, never approvable.",
|
|
26761
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.",
|
|
26762
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.",
|
|
26763
|
-
"**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."
|
|
26764
27870
|
]
|
|
26765
27871
|
}
|
|
26766
27872
|
];
|
|
@@ -26893,13 +27999,16 @@ function openPromptsOverlay(tui, ctx, onClose) {
|
|
|
26893
27999
|
lines.push(`**Argument Hint:** \`${template.argumentHint}\``);
|
|
26894
28000
|
}
|
|
26895
28001
|
lines.push(`**Source:** ${template.sourceInfo.source ?? template.sourceInfo.scope}`);
|
|
28002
|
+
if (template.unavailable !== void 0) {
|
|
28003
|
+
lines.push(`**Unavailable:** ${template.unavailable}`);
|
|
28004
|
+
}
|
|
26896
28005
|
if (!template.trusted) {
|
|
26897
28006
|
lines.push("**Untrusted:** set `skills.trustProjectCompatRoots` before this template will expand.");
|
|
26898
28007
|
}
|
|
26899
28008
|
return lines;
|
|
26900
28009
|
}
|
|
26901
28010
|
};
|
|
26902
|
-
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");
|
|
26903
28012
|
if (marker) item.meta = template.argumentHint ? `${template.argumentHint} \xB7 ${marker}` : marker;
|
|
26904
28013
|
else if (template.argumentHint) item.meta = template.argumentHint;
|
|
26905
28014
|
return item;
|
|
@@ -27059,7 +28168,7 @@ function runCompactWithNotice(onCompact, notice, instructions) {
|
|
|
27059
28168
|
init_esm_shims();
|
|
27060
28169
|
import { spawnSync } from "node:child_process";
|
|
27061
28170
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
27062
|
-
import { readFileSync as
|
|
28171
|
+
import { readFileSync as readFileSync8, unlinkSync, writeFileSync } from "node:fs";
|
|
27063
28172
|
import { tmpdir } from "node:os";
|
|
27064
28173
|
import { join as join7 } from "node:path";
|
|
27065
28174
|
function defaultProbe(candidates) {
|
|
@@ -27099,7 +28208,7 @@ function editTextExternally(initialText, command) {
|
|
|
27099
28208
|
const result = runEditor(command, tmpFile);
|
|
27100
28209
|
if (result.error) return { ok: false, error: result.error.message };
|
|
27101
28210
|
if (result.status !== 0) return { ok: false, error: `external editor exited with code ${result.status ?? "?"}` };
|
|
27102
|
-
return { ok: true, text:
|
|
28211
|
+
return { ok: true, text: readFileSync8(tmpFile, "utf8").replace(/\n$/, "") };
|
|
27103
28212
|
} finally {
|
|
27104
28213
|
try {
|
|
27105
28214
|
unlinkSync(tmpFile);
|
|
@@ -28356,19 +29465,54 @@ function createOverlaySessionLifecycle(deps) {
|
|
|
28356
29465
|
}
|
|
28357
29466
|
void runHandoffExtraction(session, fromSessionId, verdict.goal);
|
|
28358
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
|
+
}
|
|
28359
29508
|
async function runHandoffExtraction(session, fromSessionId, goal) {
|
|
28360
29509
|
const notice = deps.getSlashNotice();
|
|
28361
|
-
const
|
|
28362
|
-
if (
|
|
28363
|
-
|
|
28364
|
-
emitCommandNotice(notice, outcome.status === "failed" ? "error" : "warn", "handoff", reason);
|
|
28365
|
-
return;
|
|
28366
|
-
}
|
|
28367
|
-
const parsed = parseHandoffExtraction(outcome.text);
|
|
28368
|
-
if (!parsed.ok) {
|
|
28369
|
-
emitCommandNotice(notice, "error", "handoff", parsed.reason);
|
|
29510
|
+
const extraction = await extractWithOneRepair(goal);
|
|
29511
|
+
if (!extraction.ok) {
|
|
29512
|
+
emitCommandNotice(notice, extraction.level, "handoff", extraction.reason);
|
|
28370
29513
|
return;
|
|
28371
29514
|
}
|
|
29515
|
+
const parsed = extraction.parsed;
|
|
28372
29516
|
const meta = session.current();
|
|
28373
29517
|
const cwd = typeof meta?.cwd === "string" && meta.cwd.length > 0 ? meta.cwd : null;
|
|
28374
29518
|
const entries = deps.readStructuredEntries(fromSessionId);
|
|
@@ -28547,6 +29691,14 @@ var DRAFT_EDIT_KEYS = ["backspace", "delete", "ctrl+u", "ctrl+w", "alt+backspace
|
|
|
28547
29691
|
function isDraftEditKey(data) {
|
|
28548
29692
|
return !isKeyRelease(data) && DRAFT_EDIT_KEYS.some((key) => matchesKey(data, key));
|
|
28549
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
|
+
}
|
|
28550
29702
|
function routePermissionOverlayKey(data, deps) {
|
|
28551
29703
|
if (matchesKey(data, "enter") && !isKeyRelease(data)) {
|
|
28552
29704
|
if (!(deps.composerHasDraft?.() ?? false)) deps.confirmPermission();
|
|
@@ -28556,6 +29708,17 @@ function routePermissionOverlayKey(data, deps) {
|
|
|
28556
29708
|
deps.editDraft(data);
|
|
28557
29709
|
return true;
|
|
28558
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
|
+
}
|
|
28559
29722
|
if (isEscapeKey(data)) {
|
|
28560
29723
|
deps.cancelPermission();
|
|
28561
29724
|
return true;
|
|
@@ -28730,6 +29893,11 @@ function createOverlayLifecycle(deps) {
|
|
|
28730
29893
|
} = deps;
|
|
28731
29894
|
let overlayPermission = null;
|
|
28732
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
|
+
};
|
|
28733
29901
|
const overlayTransitions = createOverlayTransitions({
|
|
28734
29902
|
stopDispatchBoardTicker: () => interactiveTickers.stopDispatchBoardTicker(),
|
|
28735
29903
|
renderContextIsland: () => interactiveTickers.renderContextIsland(),
|
|
@@ -28737,7 +29905,10 @@ function createOverlayLifecycle(deps) {
|
|
|
28737
29905
|
requestRender: () => tui.requestRender(),
|
|
28738
29906
|
cancelPendingAskUser: () => overlayAskUser?.cancelPending() ?? false,
|
|
28739
29907
|
finishAuth: (dismiss) => overlayAuth.finish(dismiss),
|
|
28740
|
-
onPermissionOverlayClosed: () =>
|
|
29908
|
+
onPermissionOverlayClosed: () => {
|
|
29909
|
+
permissionBody = null;
|
|
29910
|
+
overlayPermission?.onPermissionOverlayClosed();
|
|
29911
|
+
},
|
|
28741
29912
|
onOverlayClosed: () => overlayPermission?.retryPending()
|
|
28742
29913
|
});
|
|
28743
29914
|
const closeOverlay = overlayTransitions.close;
|
|
@@ -28766,17 +29937,20 @@ function createOverlayLifecycle(deps) {
|
|
|
28766
29937
|
dispatch: deps.app.dispatch,
|
|
28767
29938
|
getAutonomy: () => deps.app.getSettings?.().autonomy ?? "auto-edit",
|
|
28768
29939
|
getOverlayState: () => overlayTransitions.state,
|
|
28769
|
-
openPermissionOverlay: (view) => {
|
|
29940
|
+
openPermissionOverlay: (view, inspect) => {
|
|
28770
29941
|
if (overlayTransitions.state !== "closed") return false;
|
|
28771
29942
|
overlayTransitions.state = "permission-confirm";
|
|
28772
|
-
|
|
29943
|
+
const body = createPermissionOverlayBody(view, inspect);
|
|
29944
|
+
permissionBody = body;
|
|
29945
|
+
overlayTransitions.handle = showOverlayFrame(tui, body, {
|
|
28773
29946
|
...permissionOverlayPlacement(tui, editor, footer.view),
|
|
28774
29947
|
width: PERMISSION_OVERLAY_WIDTH,
|
|
28775
29948
|
title: permissionOverlayTitle(view),
|
|
28776
29949
|
tone: permissionOverlayTone(view),
|
|
28777
29950
|
// Read per frame: the footer names what Enter does right now, and
|
|
28778
|
-
// that depends on whether the composer holds a draft
|
|
28779
|
-
|
|
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())
|
|
28780
29954
|
});
|
|
28781
29955
|
tui.requestRender();
|
|
28782
29956
|
return true;
|
|
@@ -28974,6 +30148,16 @@ function createOverlayLifecycle(deps) {
|
|
|
28974
30148
|
footer.refresh();
|
|
28975
30149
|
tui.requestRender();
|
|
28976
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
|
+
},
|
|
28977
30161
|
cancelAskUser: overlayAskUser.cancel,
|
|
28978
30162
|
dispose: () => {
|
|
28979
30163
|
overlayPermission?.dispose();
|
|
@@ -30496,6 +31680,10 @@ function createInteractiveInputRuntime(deps) {
|
|
|
30496
31680
|
confirmPermission: () => deps.overlay.confirmPermission(),
|
|
30497
31681
|
stopTurnFromPermission: () => deps.overlay.stopTurnFromPermission(),
|
|
30498
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),
|
|
30499
31687
|
editDraft: (data2) => {
|
|
30500
31688
|
deps.editor.handleInput?.(data2);
|
|
30501
31689
|
deps.requestRender();
|
|
@@ -31327,11 +32515,23 @@ function renderErrorSegmentLines(seg, width) {
|
|
|
31327
32515
|
var CLIO_PREFIX = `${TEAL}${AGENT_GLYPH}${RESET} `;
|
|
31328
32516
|
var CLIO_PREFIX_ERROR = `${RED_CRIT}${AGENT_GLYPH}${RESET} `;
|
|
31329
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";
|
|
31330
32521
|
var PROSE_GUTTER = " ";
|
|
31331
32522
|
var PROSE_GUTTER_WIDTH = 2;
|
|
31332
32523
|
function hangProseLines(lines, firstPrefix) {
|
|
31333
32524
|
return lines.map((line, index) => `${index === 0 && firstPrefix !== void 0 ? firstPrefix : PROSE_GUTTER}${line}`);
|
|
31334
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
|
+
}
|
|
31335
32535
|
var THINKING_HIDDEN_LABEL = `Thinking${GLYPH.ellipsis}`;
|
|
31336
32536
|
var THINKING_LINE_LIMIT = 12;
|
|
31337
32537
|
function dimLine(text, width) {
|
|
@@ -31488,8 +32688,11 @@ function renderEntryLines(entry, width, expandKey, latestHintToolId, latestFolde
|
|
|
31488
32688
|
const contentWidth = Math.max(1, width - PROSE_GUTTER_WIDTH);
|
|
31489
32689
|
const lines2 = [];
|
|
31490
32690
|
for (const sourceLine of entry.text.split("\n")) lines2.push(...wrapTextWithAnsi(sourceLine, contentWidth));
|
|
31491
|
-
const
|
|
32691
|
+
const status = entry.status?.() ?? "committed";
|
|
32692
|
+
const rendered = hangProseLines(lines2, status === "committed" ? USER_PREFIX : USER_PREFIX_PENDING);
|
|
31492
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);
|
|
31493
32696
|
return rendered;
|
|
31494
32697
|
}
|
|
31495
32698
|
if (entry.role === "retryStatus") {
|
|
@@ -31789,8 +32992,8 @@ function createChatPanel(options = {}) {
|
|
|
31789
32992
|
(segment) => segment.kind === "tool" && !segment.finished && segment.startedAtMs !== void 0
|
|
31790
32993
|
// The live reasoning line counts its own elapsed, so a turn that is
|
|
31791
32994
|
// only thinking still needs the time-keyed render key.
|
|
31792
|
-
) || entry.pending && openThinkingSegment(entry)?.startedAtMs !== void 0) || entry.role === "replayBlock" && entry.isLive?.() === true;
|
|
31793
|
-
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);
|
|
31794
32997
|
const render2 = (width) => {
|
|
31795
32998
|
const startedAt = performance5.now();
|
|
31796
32999
|
const expandKey = resolveExpandKey();
|
|
@@ -31872,8 +33075,8 @@ function createChatPanel(options = {}) {
|
|
|
31872
33075
|
return out;
|
|
31873
33076
|
};
|
|
31874
33077
|
return {
|
|
31875
|
-
appendUser(text) {
|
|
31876
|
-
transcript.push({ role: "user", text });
|
|
33078
|
+
appendUser(text, status) {
|
|
33079
|
+
transcript.push({ role: "user", text, ...status ? { status } : {} });
|
|
31877
33080
|
markDirty();
|
|
31878
33081
|
},
|
|
31879
33082
|
appendReplayBlock(renderBlock, isLive2, fold) {
|
|
@@ -32310,6 +33513,7 @@ init_esm_shims();
|
|
|
32310
33513
|
var CONTEXT_ISLAND_WIDTH = 52;
|
|
32311
33514
|
var PHASES = ["scan", "codewiki", "generate", "clio-md", "state", "done"];
|
|
32312
33515
|
var WIKI_PHASES = ["codewiki", "generate", "state", "done"];
|
|
33516
|
+
var COMPACTION_PHASES = ["compact", "done"];
|
|
32313
33517
|
var PHASE_LABELS = {
|
|
32314
33518
|
scan: "scan",
|
|
32315
33519
|
// "index" rather than "wiki": this phase is the codewiki index build, and
|
|
@@ -32318,6 +33522,7 @@ var PHASE_LABELS = {
|
|
|
32318
33522
|
generate: "draft",
|
|
32319
33523
|
"clio-md": "CLIO-CODER.md",
|
|
32320
33524
|
state: "state",
|
|
33525
|
+
compact: "compact",
|
|
32321
33526
|
done: "done"
|
|
32322
33527
|
};
|
|
32323
33528
|
var WIKI_PHASE_LABELS = {
|
|
@@ -32332,8 +33537,9 @@ var KINDS = /* @__PURE__ */ new Set([
|
|
|
32332
33537
|
"context-wiki",
|
|
32333
33538
|
"compaction"
|
|
32334
33539
|
]);
|
|
32335
|
-
var PHASE_SET = new Set(PHASES);
|
|
33540
|
+
var PHASE_SET = /* @__PURE__ */ new Set([...PHASES, ...COMPACTION_PHASES]);
|
|
32336
33541
|
function phasesFor(kind) {
|
|
33542
|
+
if (kind === "compaction") return COMPACTION_PHASES;
|
|
32337
33543
|
return kind === "context-wiki" ? WIKI_PHASES : PHASES;
|
|
32338
33544
|
}
|
|
32339
33545
|
function phaseLabel(kind, phase) {
|
|
@@ -33638,6 +34844,8 @@ function createInteractivePresentation(deps) {
|
|
|
33638
34844
|
},
|
|
33639
34845
|
isStreaming: () => deps.chat.isStreaming(),
|
|
33640
34846
|
...deps.isAwaitingApproval ? { isAwaitingApproval: deps.isAwaitingApproval } : {},
|
|
34847
|
+
...deps.getPermissionInspection ? { getPermissionInspection: deps.getPermissionInspection } : {},
|
|
34848
|
+
getTurnPreparation: () => deps.chat.turnPreparation().phase,
|
|
33641
34849
|
willEnterSteer: (text) => willEnterSteerActiveWork(deps, text),
|
|
33642
34850
|
getSubmitKeyLabel: () => formatKeyLabel(keybindings.getKeys("tui.input.submit")[0], "Enter"),
|
|
33643
34851
|
getNewlineKeyLabel: () => formatKeyLabel(keybindings.getKeys("tui.input.newLine")[0], "Shift+Enter")
|
|
@@ -34150,9 +35358,9 @@ function createInteractiveSlashRuntime(deps) {
|
|
|
34150
35358
|
const willQueue = deps.chat.isStreaming();
|
|
34151
35359
|
deps.recordSubmittedTurn();
|
|
34152
35360
|
deps.refreshFooter();
|
|
34153
|
-
|
|
35361
|
+
let rowStatus = "pending";
|
|
35362
|
+
if (!willQueue) deps.chatPanel.appendUser(sub.text, () => rowStatus);
|
|
34154
35363
|
deps.requestRender();
|
|
34155
|
-
deps.beforeSemanticSubmit?.();
|
|
34156
35364
|
let acknowledgeAdmission = () => {
|
|
34157
35365
|
};
|
|
34158
35366
|
const admitted = new Promise((resolve7) => {
|
|
@@ -34163,13 +35371,26 @@ function createInteractiveSlashRuntime(deps) {
|
|
|
34163
35371
|
...sub.workingContextPaths.length > 0 ? { workingContextPaths: sub.workingContextPaths } : {},
|
|
34164
35372
|
...sub.pendingSkillRequests.length > 0 ? { pendingSkillRequests: sub.pendingSkillRequests } : {},
|
|
34165
35373
|
...awaitAdmission && willQueue ? { steering: "end-of-turn" } : {},
|
|
34166
|
-
|
|
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
|
+
}
|
|
34167
35385
|
});
|
|
34168
35386
|
const settlement = turn.then(() => deps.settleVisibleFrame?.("submit-return")).catch((err) => {
|
|
34169
35387
|
const msg = err instanceof Error ? err.message : String(err);
|
|
34170
35388
|
deps.io.stderr(`[interactive] chat failed: ${msg}
|
|
34171
35389
|
`);
|
|
34172
|
-
}).finally(
|
|
35390
|
+
}).finally(() => {
|
|
35391
|
+
if (rowStatus === "pending") rowStatus = willQueue ? "committed" : "refused";
|
|
35392
|
+
deps.requestRender();
|
|
35393
|
+
});
|
|
34173
35394
|
return awaitAdmission ? Promise.race([admitted, settlement]) : settlement;
|
|
34174
35395
|
} catch (err) {
|
|
34175
35396
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -34923,6 +36144,13 @@ async function createInteractiveApplication(deps) {
|
|
|
34923
36144
|
});
|
|
34924
36145
|
const { terminal, tui } = shell;
|
|
34925
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);
|
|
34926
36154
|
const visibleEventIngress = /* @__PURE__ */ new WeakMap();
|
|
34927
36155
|
let visibleEventSequence = 0;
|
|
34928
36156
|
let visibleEventGeneration = 0;
|
|
@@ -34978,6 +36206,11 @@ async function createInteractiveApplication(deps) {
|
|
|
34978
36206
|
getLeaderArmed: () => leaderArmed,
|
|
34979
36207
|
getShutdownArmed: () => shutdownArmed,
|
|
34980
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
|
+
},
|
|
34981
36214
|
resolveVisibleEventSequence: (event) => visibleEventIngress.get(event)?.traceSequence ?? null,
|
|
34982
36215
|
resolveStreamIngress: (event) => visibleEventIngress.get(event) ?? null,
|
|
34983
36216
|
commitFrame: (reason) => shell.commitCurrentFrame(reason === "teardown" ? 300 : 3e4),
|
|
@@ -35086,7 +36319,7 @@ async function createInteractiveApplication(deps) {
|
|
|
35086
36319
|
chat: deps.chat,
|
|
35087
36320
|
chatPanel: {
|
|
35088
36321
|
appendReplayBlock: (...args) => chatRenderer.mutate(() => chatPanel.appendReplayBlock(...args), "slash-output"),
|
|
35089
|
-
appendUser: (text) => chatRenderer.mutate(() => chatPanel.appendUser(text), "user-submit"),
|
|
36322
|
+
appendUser: (text, status) => chatRenderer.mutate(() => chatPanel.appendUser(text, status), "user-submit"),
|
|
35090
36323
|
clearFoldOverrides: () => chatRenderer.mutate(() => chatPanel.clearFoldOverrides(), "output-detail")
|
|
35091
36324
|
},
|
|
35092
36325
|
beforeSemanticSubmit: () => chatRenderer.flush(),
|
|
@@ -35385,6 +36618,7 @@ async function createInteractiveApplication(deps) {
|
|
|
35385
36618
|
cancelParkedCalls: (reason) => deps.toolRegistry?.cancelParkedCalls(reason),
|
|
35386
36619
|
onShutdown: async () => {
|
|
35387
36620
|
try {
|
|
36621
|
+
if (dumpInputWedgeOnTerminate) process.off("SIGTERM", dumpInputWedgeOnTerminate);
|
|
35388
36622
|
await deps.onShutdown();
|
|
35389
36623
|
} finally {
|
|
35390
36624
|
if (lease) await lease.close();
|
|
@@ -35503,7 +36737,7 @@ import { isAbsolute as isAbsolute6, relative as relative7, resolve as resolve6 }
|
|
|
35503
36737
|
|
|
35504
36738
|
// src/tools/dispatch-scout-admission.ts
|
|
35505
36739
|
init_esm_shims();
|
|
35506
|
-
import { existsSync as existsSync9, readFileSync as
|
|
36740
|
+
import { existsSync as existsSync9, readFileSync as readFileSync9 } from "node:fs";
|
|
35507
36741
|
import { join as join10 } from "node:path";
|
|
35508
36742
|
var MAX_SCOUT_PLAN_DEADLINE_MS = 36e5;
|
|
35509
36743
|
function record(value) {
|
|
@@ -35555,7 +36789,7 @@ function loadVerifiedScoutSource(input) {
|
|
|
35555
36789
|
if (!existsSync9(receiptPath)) throw new Error(`dispatch: Scout source receipt '${input.ref.runId}' is unavailable`);
|
|
35556
36790
|
let receipt;
|
|
35557
36791
|
try {
|
|
35558
|
-
receipt = JSON.parse(
|
|
36792
|
+
receipt = JSON.parse(readFileSync9(receiptPath, "utf8"));
|
|
35559
36793
|
} catch (error) {
|
|
35560
36794
|
throw new Error(
|
|
35561
36795
|
`dispatch: Scout source receipt is unreadable: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -36411,7 +37645,7 @@ function createDispatchTool(inputDeps, surfaceOptions = {}) {
|
|
|
36411
37645
|
const admission = createDispatchAdmissionController(deps);
|
|
36412
37646
|
let runnerPromise = null;
|
|
36413
37647
|
const loadRunner = () => {
|
|
36414
|
-
runnerPromise ??= (surfaceOptions.loadRunner ?? (() => import("./dispatch-runner-
|
|
37648
|
+
runnerPromise ??= (surfaceOptions.loadRunner ?? (() => import("./dispatch-runner-VVA4SRRH.js")))();
|
|
36415
37649
|
return runnerPromise;
|
|
36416
37650
|
};
|
|
36417
37651
|
return {
|
|
@@ -36649,7 +37883,7 @@ function registerAllTools(registry, deps = {}) {
|
|
|
36649
37883
|
...builtin(
|
|
36650
37884
|
lazyTool(
|
|
36651
37885
|
monitorToolSurface,
|
|
36652
|
-
async () => (await import("./monitor-
|
|
37886
|
+
async () => (await import("./monitor-MMVTJABD.js")).createMonitorTool({ dispatch, runEvents: dispatchRunEvents })
|
|
36653
37887
|
),
|
|
36654
37888
|
{
|
|
36655
37889
|
path: "src/tools/monitor.ts",
|
|
@@ -36659,7 +37893,7 @@ function registerAllTools(registry, deps = {}) {
|
|
|
36659
37893
|
});
|
|
36660
37894
|
registry.register({
|
|
36661
37895
|
...builtin(
|
|
36662
|
-
lazyTool(steerToolSurface, async () => (await import("./steer-
|
|
37896
|
+
lazyTool(steerToolSurface, async () => (await import("./steer-CF5TDANS.js")).createSteerTool({ dispatch })),
|
|
36663
37897
|
{
|
|
36664
37898
|
path: "src/tools/steer.ts",
|
|
36665
37899
|
scope: "core"
|
|
@@ -36806,7 +38040,7 @@ async function resolveApiKeyForTarget(target, providers, signal) {
|
|
|
36806
38040
|
const resolved = await providers.auth.resolveForTarget(target, runtime, signal ? { signal } : void 0);
|
|
36807
38041
|
return resolved.apiKey;
|
|
36808
38042
|
}
|
|
36809
|
-
function createBackgroundMemoryModelClient(providers, settings, timeoutMs) {
|
|
38043
|
+
function createBackgroundMemoryModelClient(providers, settings, timeoutMs, bus) {
|
|
36810
38044
|
const targetId = settings.background.target?.trim();
|
|
36811
38045
|
const wireModelId = settings.background.model?.trim();
|
|
36812
38046
|
if (!targetId || !wireModelId) return null;
|
|
@@ -36830,22 +38064,52 @@ function createBackgroundMemoryModelClient(providers, settings, timeoutMs) {
|
|
|
36830
38064
|
const model = resolved.target.runtime.synthesizeModel(resolved.target.target, resolved.target.wireModelId, kbHit);
|
|
36831
38065
|
const refined = refineRuntimeTargetWithModelHints(resolved.target, model, providers.knowledgeBase);
|
|
36832
38066
|
applyModelCapabilityPatch(model, refined.capabilities);
|
|
38067
|
+
const costProvenance = normalizeCostProvenance(refined.costProvenance);
|
|
38068
|
+
const endpointKey = canonicalEndpointKey(refined.target);
|
|
36833
38069
|
return {
|
|
36834
|
-
|
|
36835
|
-
|
|
36836
|
-
|
|
36837
|
-
|
|
36838
|
-
|
|
36839
|
-
|
|
36840
|
-
|
|
36841
|
-
|
|
36842
|
-
|
|
36843
|
-
|
|
36844
|
-
|
|
36845
|
-
|
|
36846
|
-
|
|
36847
|
-
|
|
36848
|
-
|
|
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
|
+
})
|
|
36849
38113
|
}
|
|
36850
38114
|
};
|
|
36851
38115
|
}
|
|
@@ -36916,7 +38180,7 @@ async function resolveCompactionModel(settings, providers) {
|
|
|
36916
38180
|
const model = synthesizeOrchestratorModel(providers, target, wireModelId);
|
|
36917
38181
|
if (!model) return null;
|
|
36918
38182
|
const apiKey = await resolveApiKeyForTarget(target, providers);
|
|
36919
|
-
const resolution = { model, targetId };
|
|
38183
|
+
const resolution = { model, targetId, endpointKey: canonicalEndpointKey(target) };
|
|
36920
38184
|
if (apiKey !== void 0) resolution.apiKey = apiKey;
|
|
36921
38185
|
return resolution;
|
|
36922
38186
|
}
|
|
@@ -36988,12 +38252,19 @@ async function runCompactionFlow(session, settings, providers, instructions, tri
|
|
|
36988
38252
|
const activeLeafTurnId = session.tree(meta.id).leafId ?? void 0;
|
|
36989
38253
|
const entries = filterEntriesToActivePath(readSessionEntriesForCompact(meta.id), activeLeafTurnId);
|
|
36990
38254
|
if (entries.length === 0) return null;
|
|
36991
|
-
const
|
|
36992
|
-
|
|
36993
|
-
|
|
36994
|
-
|
|
36995
|
-
|
|
36996
|
-
|
|
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
|
+
}
|
|
36997
38268
|
if (result.messagesSummarized === 0 || result.summary.length === 0) return null;
|
|
36998
38269
|
const entry = {
|
|
36999
38270
|
kind: "compactionSummary",
|
|
@@ -37362,6 +38633,40 @@ async function bootOrchestrator(options = {}) {
|
|
|
37362
38633
|
let deferredWatchdogNoticeSink = null;
|
|
37363
38634
|
const memoryTracePath = taskMemoryTracePath();
|
|
37364
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
|
+
};
|
|
37365
38670
|
const memoryIntervention = createMemoryInterventionRegistration({
|
|
37366
38671
|
bank: taskMemoryBank,
|
|
37367
38672
|
telemetry: createTaskMemoryTelemetrySink(),
|
|
@@ -37376,8 +38681,21 @@ async function bootOrchestrator(options = {}) {
|
|
|
37376
38681
|
},
|
|
37377
38682
|
getModelClient: () => {
|
|
37378
38683
|
const settings = effectiveSettingsForDispatch?.();
|
|
37379
|
-
|
|
37380
|
-
|
|
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)
|
|
37381
38699
|
});
|
|
37382
38700
|
middleware.registerHook(memoryIntervention);
|
|
37383
38701
|
const unsubscribeMemoryLoop = bus.on(BusChannels.LoopBlocked, () => memoryIntervention.signalLoop());
|
|
@@ -37705,6 +39023,12 @@ async function bootOrchestrator(options = {}) {
|
|
|
37705
39023
|
);
|
|
37706
39024
|
}
|
|
37707
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
|
+
},
|
|
37708
39032
|
getSettings: getCurrentSettings,
|
|
37709
39033
|
providers,
|
|
37710
39034
|
middleware,
|
|
@@ -37761,7 +39085,12 @@ async function bootOrchestrator(options = {}) {
|
|
|
37761
39085
|
autoCompact: createProductionAutoCompact(session, getCurrentSettings, providers)
|
|
37762
39086
|
} : {},
|
|
37763
39087
|
toolRegistry,
|
|
37764
|
-
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
|
|
37765
39094
|
});
|
|
37766
39095
|
termination.onDrain(async () => {
|
|
37767
39096
|
chat.dispose();
|
|
@@ -37964,7 +39293,11 @@ async function bootOrchestrator(options = {}) {
|
|
|
37964
39293
|
lastDecision: memoryIntervention.lastDecision(),
|
|
37965
39294
|
bank,
|
|
37966
39295
|
activity: memoryIntervention.recentActivity(),
|
|
37967
|
-
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())
|
|
37968
39301
|
};
|
|
37969
39302
|
},
|
|
37970
39303
|
getTaskMemorySeedOffer,
|
|
@@ -38137,4 +39470,4 @@ export {
|
|
|
38137
39470
|
resolveApiKeyForTarget,
|
|
38138
39471
|
synthesizeOrchestratorModel
|
|
38139
39472
|
};
|
|
38140
|
-
//# sourceMappingURL=orchestrator-
|
|
39473
|
+
//# sourceMappingURL=orchestrator-ZKBPCHW6.js.map
|