@iowarp/clio-coder 0.3.8 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +102 -0
- package/NOTICE +33 -0
- package/README.md +12 -3
- package/dist/{acp-U67UHUK2.js → acp-G5WJBNCT.js} +13 -12
- package/dist/{agents-YU6SGALZ.js → agents-FMV2Q5G4.js} +41 -36
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-5ZPJOIVG.js → auth-3IDSJEIK.js} +18 -18
- package/dist/{builtins-C6JMZVV6.js → builtins-XCZWXSC7.js} +5 -5
- package/dist/{chunk-IFBNV6H6.js → chunk-2ANTL7MR.js} +3 -3
- package/dist/{chunk-5FR74PWO.js → chunk-2JDWVJND.js} +2 -2
- package/dist/{chunk-XWSF374K.js → chunk-2OQE55CK.js} +3 -3
- package/dist/{chunk-5H3GB5BO.js → chunk-32KWKNSF.js} +8 -384
- package/dist/{chunk-KTYTFRMB.js → chunk-36EJLSQQ.js} +34 -36
- package/dist/{chunk-FHJEP5SW.js → chunk-3BT2XMV4.js} +19 -13
- package/dist/chunk-3DPEIQKN.js +113 -0
- package/dist/{chunk-GU2UIAFZ.js → chunk-3URVFKWK.js} +7 -7
- package/dist/{chunk-WEH5XRJQ.js → chunk-3XML7CDN.js} +3 -3
- package/dist/chunk-42FMPA75.js +101 -0
- package/dist/{chunk-A2NJGIB3.js → chunk-5LXZXPKX.js} +2 -2
- package/dist/{chunk-VCBR6CU7.js → chunk-5PSMVOLM.js} +2 -2
- package/dist/{chunk-NMPKI6XL.js → chunk-6DB53AJS.js} +203 -25
- package/dist/{chunk-3BINW3FP.js → chunk-76ONBSIA.js} +2 -2
- package/dist/{chunk-26LEYJZH.js → chunk-7MCTRUCE.js} +2 -2
- package/dist/{chunk-TYPGUK6W.js → chunk-AB44T6BB.js} +111 -5
- package/dist/{chunk-K4XHGFR5.js → chunk-B7OBL7PK.js} +317 -721
- package/dist/{chunk-B5CSFE7B.js → chunk-BBVJUZHB.js} +2 -2
- package/dist/{chunk-EQ63NRB7.js → chunk-BBVYXMFO.js} +2 -2
- package/dist/{chunk-ZVJ5BLO2.js → chunk-BKFJHQCA.js} +154 -16
- package/dist/chunk-BKFM6EJV.js +462 -0
- package/dist/chunk-BMS5RKQY.js +27 -0
- package/dist/{chunk-ZNLWCMVZ.js → chunk-BPKCPIL7.js} +2 -2
- package/dist/{chunk-TLQJPP24.js → chunk-BUMFYQFY.js} +1394 -1349
- package/dist/{chunk-BNAZZHFG.js → chunk-BYP5D4HI.js} +1 -1
- package/dist/chunk-C2LTL2W6.js +2447 -0
- package/dist/{chunk-ME6CCNFO.js → chunk-CODPRO7Q.js} +8 -8
- package/dist/{chunk-E77JEWSD.js → chunk-CTJ4RNAA.js} +7 -37
- package/dist/{chunk-ODFEOB4F.js → chunk-CY6FY24N.js} +26 -8
- package/dist/{chunk-7RFXX52T.js → chunk-DQITNCXG.js} +642 -172
- package/dist/{chunk-TTHACPOM.js → chunk-DYJP44XW.js} +578 -117
- package/dist/{chunk-2HFZQUHL.js → chunk-F4CKPOEQ.js} +18 -8
- package/dist/{chunk-DGSYXYMX.js → chunk-FEFIFZTL.js} +3 -3
- package/dist/{chunk-GWS3VEIW.js → chunk-FWDFM5ZU.js} +24 -3
- package/dist/{chunk-MV3K5QF2.js → chunk-GCSMB2KY.js} +2 -2
- package/dist/chunk-GKF55TAZ.js +391 -0
- package/dist/{chunk-VWZOAB7K.js → chunk-GR5G2PVF.js} +9 -8
- package/dist/{chunk-4DGYLA73.js → chunk-GXNLGKAB.js} +80 -9
- package/dist/chunk-HHV2GANA.js +88 -0
- package/dist/{chunk-IIZWH4XA.js → chunk-HI63TFOG.js} +5 -4
- package/dist/{chunk-WLFILSD5.js → chunk-HJJTYUHX.js} +113 -83
- package/dist/{chunk-TT36MB5S.js → chunk-HLW2MRKE.js} +3 -1
- package/dist/{chunk-PMDBGQSJ.js → chunk-HWHKMHUA.js} +7 -7
- package/dist/chunk-HZHHCK24.js +1631 -0
- package/dist/{chunk-WSB3FPX7.js → chunk-I5VEOC6I.js} +39 -143
- package/dist/chunk-IBEBSCYA.js +564 -0
- package/dist/chunk-IQ7KR472.js +362 -0
- package/dist/{chunk-A3WNZD3P.js → chunk-J4W7KFM7.js} +949 -972
- package/dist/{chunk-TB5666IT.js → chunk-JDG2WCRO.js} +5 -5
- package/dist/{chunk-N22QMJKY.js → chunk-K5C3NCBD.js} +4 -4
- package/dist/{chunk-CGKSTWHD.js → chunk-K6BSR66V.js} +2 -1
- package/dist/{chunk-5C3AQNDW.js → chunk-KFZI4NIL.js} +216 -38
- package/dist/chunk-KMVISBZR.js +132 -0
- package/dist/{chunk-WXY7KU3G.js → chunk-LDQ2ZF2M.js} +2 -2
- package/dist/{chunk-XN3L4EYL.js → chunk-LQ3DZAMX.js} +3 -3
- package/dist/{chunk-U6MBIEMB.js → chunk-LY4S7GJC.js} +173 -144
- package/dist/{chunk-4SPRNWDE.js → chunk-MLKNTWH2.js} +19 -19
- package/dist/{chunk-MVVUPGPW.js → chunk-MXHC5QYU.js} +6 -6
- package/dist/chunk-NEKRRTYW.js +56 -0
- package/dist/{chunk-SPULKLCF.js → chunk-NHCZP4K7.js} +3 -3
- package/dist/chunk-NHLBIGRH.js +1506 -0
- package/dist/chunk-NQQH3YT7.js +302 -0
- package/dist/chunk-NYS75XW5.js +15 -0
- package/dist/{chunk-GN57SG4G.js → chunk-O4XIVISU.js} +10 -8
- package/dist/{chunk-EMYUUSFG.js → chunk-O6TL7WWY.js} +6 -6
- package/dist/chunk-OQBA45DZ.js +97 -0
- package/dist/{chunk-LU7P4LHA.js → chunk-P3FOHJT4.js} +2 -2
- package/dist/chunk-PMZCIOCJ.js +25 -0
- package/dist/{chunk-I4HZDVNP.js → chunk-PQEFIJ36.js} +2 -2
- package/dist/{chunk-J3YUBZWY.js → chunk-QBJA7R7N.js} +62 -6
- package/dist/chunk-QDC3K2U3.js +262 -0
- package/dist/{chunk-2HEJ2F35.js → chunk-QLFS5GO2.js} +22 -10
- package/dist/{chunk-7RGZWPB6.js → chunk-QLL7ILRG.js} +95 -32
- package/dist/{chunk-YS5VLNH5.js → chunk-QREDIESB.js} +6 -6
- package/dist/chunk-QSNYB6ZV.js +195 -0
- package/dist/{chunk-GOXNB3AO.js → chunk-RAPCMZL4.js} +75 -4
- package/dist/chunk-RKKLTLYB.js +45 -0
- package/dist/{chunk-P43ETTHK.js → chunk-SJ5ZKQ4S.js} +2 -2
- package/dist/{chunk-GPIEI3LY.js → chunk-SP2RXXYO.js} +6 -54
- package/dist/chunk-SUCTJL45.js +45 -0
- package/dist/{chunk-DYIM5TJT.js → chunk-SUW5DORT.js} +263 -7
- package/dist/chunk-T56WDKA5.js +183 -0
- package/dist/chunk-TVHHYFHE.js +255 -0
- package/dist/{chunk-FJ3H4MN5.js → chunk-TZ3SGWZZ.js} +3 -3
- package/dist/{chunk-MXKJU4JB.js → chunk-U77AMWDL.js} +91 -10
- package/dist/{chunk-5DHKRSMQ.js → chunk-ULC6OTWO.js} +11 -7
- package/dist/{chunk-RWSI4YD7.js → chunk-UM7N4G5A.js} +33 -12
- package/dist/{chunk-FCSXB6T2.js → chunk-UOSL25KY.js} +14 -2
- package/dist/{chunk-IGWKHNIQ.js → chunk-UXMFQ54G.js} +44 -37
- package/dist/{chunk-HFSBBKSQ.js → chunk-V5DHCITQ.js} +171 -3
- package/dist/{chunk-5WIGXA4T.js → chunk-VAZSBTKF.js} +111 -4
- package/dist/{chunk-VHN4MY6O.js → chunk-VEO4AP2K.js} +2 -2
- package/dist/{chunk-IJ7RPIYJ.js → chunk-VFA6GDY5.js} +65 -4
- package/dist/{chunk-PT7HYKEM.js → chunk-VO2LKSTM.js} +2 -2
- package/dist/chunk-VO67MWHC.js +75 -0
- package/dist/{chunk-XK56QHLX.js → chunk-VPKWYKEY.js} +19 -5
- package/dist/{chunk-TANS5ZJS.js → chunk-VYMXRQI6.js} +36 -22
- package/dist/{chunk-WWCZ5F23.js → chunk-W5VSYASO.js} +77 -16
- package/dist/{chunk-WNIJTQQK.js → chunk-WZR7K7ZX.js} +72 -116
- package/dist/{chunk-5Q2VVUKB.js → chunk-X3YGUTOB.js} +4 -4
- package/dist/chunk-X75E3D2N.js +686 -0
- package/dist/{chunk-VAWNZU7Z.js → chunk-YDFRH54B.js} +4 -4
- package/dist/chunk-YJX4SHTD.js +40 -0
- package/dist/{chunk-ZI647VB5.js → chunk-YPI3QQCF.js} +2 -2
- package/dist/chunk-Z2RR6MAK.js +127 -0
- package/dist/{chunk-FBVTI2TJ.js → chunk-Z4TXYIEG.js} +12 -131
- package/dist/cli/index.js +47 -36
- package/dist/{clio-QVTYJ57A.js → clio-2JXHBBY5.js} +7 -7
- package/dist/{code-nav-FGGFIE7L.js → code-nav-3YYRMYNF.js} +8 -8
- package/dist/{compile-cache-CVJMMODC.js → compile-cache-7FPE6PS3.js} +3 -3
- package/dist/{components-ZFA3SAER.js → components-RYZV4JGP.js} +5 -5
- package/dist/{config-LW5IJFQN.js → config-QZPCMYSO.js} +99 -63
- package/dist/{configure-7XIZCOU4.js → configure-TEGEBYCA.js} +23 -22
- package/dist/{context-Y6Y7QPR6.js → context-AV7OEZ4D.js} +12 -12
- package/dist/{context-L3WL3X7K.js → context-E6H5RNMC.js} +56 -47
- package/dist/{context-N52ZA626.js → context-GSXUE4CT.js} +29 -27
- package/dist/{context-clear-MBQRLSDQ.js → context-clear-SHIBYK6T.js} +55 -46
- package/dist/{context-index-HVMFQHK3.js → context-index-HNG3MOME.js} +2 -2
- package/dist/{context-working-set-GS6DSO7F.js → context-working-set-5ZGKPGZQ.js} +13 -13
- package/dist/{dispatch-runner-22ZCNOM3.js → dispatch-runner-EFMJT4LD.js} +93 -64
- package/dist/{docs-7LQ23DLM.js → docs-23KQS3XK.js} +5 -5
- package/dist/doctor-QOA5FNY5.js +313 -0
- package/dist/{eval-BEC2WHDA.js → eval-TFBYQH4H.js} +2032 -156
- package/dist/eval-inventory-SXH7PDKX.js +316 -0
- package/dist/{evidence-REJUMSKM.js → evidence-ERGESKGN.js} +203 -48
- package/dist/{evolve-PY5ZBA5K.js → evolve-VDXTSYCJ.js} +52 -43
- package/dist/{extensions-HVKU65YU.js → extensions-7BGBHN57.js} +13 -7
- package/dist/{fleet-7WZEWRFA.js → fleet-2RRVDF2V.js} +228 -108
- package/dist/{fleet-commands-UVHWM76J.js → fleet-commands-VJ726XIA.js} +11 -11
- package/dist/fleet-decisions-EPAPM3XJ.js +157 -0
- package/dist/{fleet-graph-6ULH7PES.js → fleet-graph-JF5QOATM.js} +18 -15
- package/dist/fleet-inspect-VLY4S7QM.js +442 -0
- package/dist/{fleet-preflight-J53T6CCE.js → fleet-preflight-AIZUEJOY.js} +5 -5
- package/dist/{fleet-validate-72PC4SLA.js → fleet-validate-AJRPDMDV.js} +22 -19
- package/dist/fleet-verify-JFEL2L3H.js +175 -0
- package/dist/fleet-view-ZCON35AG.js +102 -0
- package/dist/{init-OG3TPGQG.js → init-DN2WWLFE.js} +72 -62
- package/dist/install-XGLBQY5E.js +13 -0
- package/dist/interop-OZBKXAYL.js +114 -0
- package/dist/{library-CNTMPLRF.js → library-YWZG7IMW.js} +21 -18
- package/dist/{memory-6IS7F275.js → memory-I4C4HMLW.js} +54 -45
- package/dist/{models-ENRJDA5W.js → models-CEYXJBO6.js} +33 -30
- package/dist/{monitor-XLDVO7TN.js → monitor-NZ6GCI3P.js} +59 -52
- package/dist/{orchestrator-6KSPYRHA.js → orchestrator-GCGQ4N5I.js} +7827 -7328
- package/dist/panes-HMABYVO4.js +58 -0
- package/dist/panes-KY6W3V2E.js +103 -0
- package/dist/{paths-DBXMZMDU.js → paths-II4K7DNR.js} +5 -5
- package/dist/{reset-RZ4ER727.js → reset-DQ6FGCSH.js} +13 -11
- package/dist/resources-BB3MVJMD.js +111 -0
- package/dist/{run-Y2CNK5RU.js → run-H2GQDUER.js} +119 -87
- package/dist/{share-A55GYP6Z.js → share-GTJN6A5O.js} +20 -17
- package/dist/{skills-ALC5J6AT.js → skills-L55TEW6R.js} +33 -24
- package/dist/{skills-eval-JPBEBYQU.js → skills-eval-XVXPH2JI.js} +67 -56
- package/dist/skills-inventory-S4MXPJFV.js +126 -0
- package/dist/slash-commands-ZSGASKJC.js +77 -0
- package/dist/{steer-GGWFUJUD.js → steer-RZGSCY4R.js} +4 -4
- package/dist/{support-MIETYA5E.js → support-PKEUNNQL.js} +6 -6
- package/dist/{targets-VGNXIR3S.js → targets-NCPZ644J.js} +68 -40
- package/dist/{terminal-lease-WOBR64YA.js → terminal-lease-44SV3YCN.js} +6 -4
- package/dist/tools-DAF3DI3C.js +27 -0
- package/dist/{trace-PNCASAXC.js → trace-FYVW2MQA.js} +207 -10
- package/dist/tui-primitives-2AKXQNZK.js +13 -0
- package/dist/{uninstall-ZJF5H5ZN.js → uninstall-DW2PNOIC.js} +5 -5
- package/dist/{upgrade-FUSUAGHR.js → upgrade-3XPP6OQL.js} +27 -24
- package/dist/{usage-N4MKVHKD.js → usage-3NLHGTU2.js} +114 -62
- package/dist/{verifiers-YAWOJ3H2.js → verifiers-SSQONKRT.js} +172 -13
- package/dist/{verify-LTDHYBGY.js → verify-3U6J7FZI.js} +10 -10
- package/dist/{web-fetch-2YHJ3KTG.js → web-fetch-S7RR6GZ7.js} +3 -3
- package/dist/{wiki-generate-6M7GHTBJ.js → wiki-generate-CEHYGPGQ.js} +75 -65
- package/dist/with-panes-MKB46MPQ.js +782 -0
- package/dist/worker/entry.js +106 -75
- package/docs/README.md +3 -2
- package/docs/acp.md +24 -3
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +2 -2
- package/docs/artifact-versions.md +9 -1
- package/docs/built-in-agents.md +1 -1
- package/docs/capacity-and-scheduling.md +62 -3
- package/docs/commands-and-modes.md +31 -2
- package/docs/configuration-and-targets.md +69 -12
- package/docs/context-engine.md +63 -4
- package/docs/development-pipeline.md +19 -0
- package/docs/dispatch-typed-intent.md +385 -0
- package/docs/documentation-coverage.md +5 -5
- package/docs/documentation-guide.md +1 -1
- package/docs/environment-variables.md +3 -0
- package/docs/eval-runner.md +262 -11
- package/docs/evals-internal.md +72 -2
- package/docs/evidence-and-memory.md +12 -11
- package/docs/evolution.md +1 -1
- package/docs/exit-codes-and-output.md +1 -1
- package/docs/extensions-and-sharing.md +27 -1
- package/docs/fleet-dispatch.md +25 -4
- package/docs/installation-and-lifecycle.md +15 -2
- package/docs/middleware-and-components.md +1 -1
- package/docs/model-catalog.md +10 -1
- package/docs/observability.md +55 -4
- 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 +2 -2
- package/docs/scientific-validation.md +3 -3
- package/docs/session-lifecycle.md +1 -1
- package/docs/skills-marketplace.md +1 -1
- package/docs/tool-usage.md +18 -8
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +88 -1
- package/docs/tui-design.md +1 -1
- package/docs/worker-dispatch-mechanics.md +1 -1
- package/package.json +5 -2
- package/src/cli/acp.ts +6 -2
- package/src/cli/agents.ts +1 -1
- package/src/cli/argv.ts +25 -0
- package/src/cli/config-inspect.ts +33 -6
- package/src/cli/config.ts +1 -1
- package/src/cli/configure.ts +23 -21
- package/src/cli/doctor-panes.ts +124 -0
- package/src/cli/doctor-state-size.ts +82 -0
- package/src/cli/doctor-toolchain.ts +57 -0
- package/src/cli/doctor.ts +22 -1
- package/src/cli/eval-inventory.ts +436 -0
- package/src/cli/eval.ts +93 -16
- package/src/cli/evidence-detail.ts +88 -0
- package/src/cli/evidence-inventory.ts +183 -0
- package/src/cli/evidence.ts +30 -5
- package/src/cli/extensions.ts +5 -1
- package/src/cli/fleet-decisions.ts +69 -0
- package/src/cli/fleet-inspect.ts +334 -0
- package/src/cli/fleet-verify.ts +133 -0
- package/src/cli/fleet-view.ts +810 -0
- package/src/cli/fleet.ts +179 -39
- package/src/cli/index.ts +14 -2
- package/src/cli/interop-inspect.ts +128 -0
- package/src/cli/interop.ts +34 -0
- package/src/cli/panes.ts +35 -0
- package/src/cli/reset.ts +5 -2
- package/src/cli/run.ts +58 -0
- package/src/cli/skills-inventory.ts +185 -0
- package/src/cli/skills.ts +16 -13
- package/src/cli/targets.ts +44 -13
- package/src/cli/tools.ts +321 -0
- package/src/cli/trace-inspect.ts +252 -0
- package/src/cli/trace.ts +85 -5
- package/src/cli/usage.ts +63 -14
- package/src/cli/verifiers-inspect.ts +347 -0
- package/src/cli/verifiers.ts +9 -0
- package/src/core/bus-events.ts +33 -1
- package/src/core/cache-telemetry.ts +42 -0
- package/src/core/config.ts +67 -0
- package/src/core/defaults.ts +124 -8
- package/src/core/endpoint-key.ts +27 -0
- package/src/core/residency-target-key.ts +25 -0
- package/src/core/response-schema.ts +80 -6
- package/src/core/theme-token-hex.ts +43 -0
- package/src/core/tool-names.ts +2 -1
- package/src/core/xdg.ts +1 -1
- package/src/domains/agents/fleets/build-review.md +0 -3
- package/src/domains/agents/fleets/build-test.md +0 -3
- package/src/domains/agents/result-contract-filesystem.ts +32 -0
- package/src/domains/agents/result-contract.ts +164 -35
- package/src/domains/config/classify.ts +6 -0
- package/src/domains/context/codewiki/coordinator.ts +12 -4
- package/src/domains/dispatch/admission-error.ts +9 -0
- package/src/domains/dispatch/admission.ts +52 -14
- package/src/domains/dispatch/capacity-lease.ts +118 -9
- package/src/domains/dispatch/contract.ts +11 -0
- package/src/domains/dispatch/council-topology.ts +398 -0
- package/src/domains/dispatch/execution-plan.ts +44 -4
- package/src/domains/dispatch/extension.ts +378 -82
- package/src/domains/dispatch/fleet-node-prompt.ts +62 -0
- package/src/domains/dispatch/fleet-plan.ts +7 -2
- package/src/domains/dispatch/fleet-run.ts +87 -4
- package/src/domains/dispatch/gate-decisions.ts +11 -1
- package/src/domains/dispatch/gate-role-prompts.ts +9 -0
- package/src/domains/dispatch/gate-topology.ts +289 -0
- package/src/domains/dispatch/heartbeat.ts +32 -8
- package/src/domains/dispatch/index.ts +22 -0
- package/src/domains/dispatch/intent-compatibility.ts +330 -0
- package/src/domains/dispatch/intent.ts +85 -1
- package/src/domains/dispatch/orphan-recovery.ts +5 -0
- package/src/domains/dispatch/reservation-store.ts +139 -11
- package/src/domains/dispatch/run-event-journal-bridge.ts +149 -0
- package/src/domains/dispatch/run-event-journal.ts +598 -0
- package/src/domains/dispatch/state.ts +49 -1
- package/src/domains/dispatch/types.ts +13 -0
- package/src/domains/dispatch/validation.ts +33 -8
- 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 +342 -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/inventory.ts +113 -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 +105 -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/store.ts +6 -0
- 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 -1
- package/src/domains/memory/task-bank-promotion.ts +64 -0
- package/src/domains/memory/task-memory-policy.ts +82 -17
- 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 +3 -0
- package/src/domains/middleware/index.ts +1 -0
- package/src/domains/middleware/memory-intervention.ts +97 -21
- package/src/domains/middleware/memory-step-endpoint.ts +71 -0
- package/src/domains/mux/contract.ts +434 -0
- package/src/domains/mux/detect.ts +158 -0
- package/src/domains/mux/extension.ts +47 -0
- package/src/domains/mux/index.ts +96 -0
- package/src/domains/mux/manifest.ts +6 -0
- package/src/domains/mux/operations.ts +164 -0
- package/src/domains/mux/pane-registry.ts +90 -0
- package/src/domains/mux/protocol.ts +49 -0
- package/src/domains/mux/socket-client.ts +816 -0
- package/src/domains/mux/types.ts +222 -0
- package/src/domains/mux/viewer-command.ts +59 -0
- package/src/domains/mux/yazi/assets/init.lua +2 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/LICENSE +21 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/README.md +78 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/main.lua +255 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/types.lua +12 -0
- package/src/domains/mux/yazi/assets/yazi.toml +17 -0
- package/src/domains/mux/yazi/event-stream.ts +180 -0
- package/src/domains/mux/yazi/profile.ts +299 -0
- package/src/domains/mux/yazi/session.ts +228 -0
- package/src/domains/mux/yazi/theme.ts +30 -0
- package/src/domains/observability/background-memory-usage.ts +140 -0
- package/src/domains/observability/cost.ts +22 -1
- package/src/domains/observability/index.ts +9 -0
- package/src/domains/observability/out-of-turn-usage.ts +51 -2
- package/src/domains/observability/trace-store.ts +234 -2
- package/src/domains/prompts/compiler.ts +100 -13
- package/src/domains/providers/endpoint-capacity.ts +228 -0
- package/src/domains/providers/endpoint-slots-store.ts +189 -0
- package/src/domains/providers/extension.ts +20 -3
- package/src/domains/providers/index.ts +32 -0
- package/src/domains/providers/model-runtime-capabilities.ts +32 -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/boot-manifest.ts +1 -0
- package/src/domains/providers/runtimes/builtins.ts +2 -0
- 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/runtimes/protocol/litellm.ts +375 -0
- package/src/domains/providers/support.ts +1 -0
- package/src/domains/providers/target-model-cache.ts +124 -0
- package/src/domains/providers/types/capability-flags.ts +2 -0
- package/src/domains/providers/types/target-descriptor.ts +2 -0
- package/src/domains/resources/index.ts +3 -0
- package/src/domains/resources/prompts/loader.ts +95 -33
- package/src/domains/resources/skills/loader.ts +33 -0
- package/src/domains/safety/action-classifier.ts +6 -0
- 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/domains/toolchain/archive.ts +175 -0
- package/src/domains/toolchain/contract.ts +28 -0
- package/src/domains/toolchain/extension.ts +47 -0
- package/src/domains/toolchain/index.ts +39 -0
- package/src/domains/toolchain/install.ts +327 -0
- package/src/domains/toolchain/manifest.ts +8 -0
- package/src/domains/toolchain/paths.ts +34 -0
- package/src/domains/toolchain/registry.ts +265 -0
- package/src/domains/toolchain/remove.ts +218 -0
- package/src/domains/toolchain/resolve.ts +182 -0
- package/src/domains/toolchain/types.ts +113 -0
- package/src/domains/toolchain/version.ts +88 -0
- package/src/engine/acp/adapter.ts +18 -3
- package/src/engine/acp/server.ts +413 -70
- package/src/engine/acp/types.ts +19 -1
- package/src/engine/ai.ts +35 -0
- package/src/engine/apis/llamacpp-residency.ts +55 -3
- package/src/engine/apis/lmstudio.ts +25 -5
- package/src/engine/apis/ollama-native.ts +2 -1
- package/src/engine/apis/openai-completions.ts +80 -17
- package/src/engine/apis/residency-lock.ts +3 -1
- package/src/engine/apis/residency.ts +34 -1
- package/src/engine/claude/sdk-module.ts +98 -0
- package/src/engine/claude/sdk-runtime.ts +19 -11
- package/src/engine/provider-payload.ts +29 -1
- package/src/engine/tui-primitives.ts +21 -0
- package/src/engine/tui.ts +1 -0
- package/src/engine/worker-runtime.ts +2 -13
- package/src/entry/boot-options.ts +2 -0
- package/src/entry/orchestrator.ts +279 -35
- package/src/entry/panes-activation.ts +31 -0
- package/src/entry/with-panes.ts +20 -0
- 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 +41 -10
- package/src/interactive/cost-overlay.ts +66 -6
- package/src/interactive/council-grid.ts +1 -3
- package/src/interactive/council.ts +11 -0
- package/src/interactive/dispatch-board.ts +102 -20
- package/src/interactive/fleet-run-preview.ts +41 -15
- package/src/interactive/handoff-round.ts +41 -2
- package/src/interactive/interactive-application.ts +177 -7
- package/src/interactive/interactive-input-runtime.ts +15 -0
- package/src/interactive/interactive-presentation.ts +4 -0
- package/src/interactive/interactive-shell.ts +20 -17
- package/src/interactive/interactive-slash-runtime.ts +63 -10
- package/src/interactive/memory-overlay.ts +9 -0
- package/src/interactive/modal-marker.ts +170 -0
- package/src/interactive/mutation-preview.ts +295 -0
- package/src/interactive/mux-bridge.ts +214 -0
- package/src/interactive/overlay-frame.ts +58 -2
- package/src/interactive/overlay-general-openers.ts +17 -0
- package/src/interactive/overlay-key-routing.ts +52 -3
- package/src/interactive/overlay-lifecycle.ts +56 -7
- package/src/interactive/overlay-model-selectors.ts +40 -3
- package/src/interactive/overlay-permission-lifecycle.ts +112 -24
- package/src/interactive/overlay-session-lifecycle.ts +73 -9
- package/src/interactive/overlay-transitions.ts +18 -4
- package/src/interactive/overlays/agents.ts +1 -0
- package/src/interactive/overlays/ask-user.ts +227 -49
- package/src/interactive/overlays/auth-dialog.ts +1 -0
- package/src/interactive/overlays/context-reset.ts +1 -0
- package/src/interactive/overlays/cwd-fallback.ts +1 -0
- package/src/interactive/overlays/decisions.ts +11 -11
- package/src/interactive/overlays/extensions.ts +1 -0
- package/src/interactive/overlays/fleet-run-approval.ts +1 -0
- package/src/interactive/overlays/handoff-review.ts +1 -0
- package/src/interactive/overlays/help-reference.ts +6 -0
- package/src/interactive/overlays/interop.ts +1 -0
- package/src/interactive/overlays/library-install-confirm.ts +1 -0
- package/src/interactive/overlays/library-tabs.ts +28 -0
- package/src/interactive/overlays/list-overlay.ts +10 -1
- package/src/interactive/overlays/message-picker.ts +1 -0
- package/src/interactive/overlays/model-scope.ts +86 -0
- package/src/interactive/overlays/model-selector.ts +1 -0
- package/src/interactive/overlays/prompts.ts +12 -1
- package/src/interactive/overlays/session-selector.ts +1 -0
- package/src/interactive/overlays/settings-sections.ts +30 -0
- package/src/interactive/overlays/settings.ts +614 -45
- package/src/interactive/overlays/side-question.ts +1 -0
- package/src/interactive/overlays/skills-hub.ts +3 -11
- package/src/interactive/overlays/tree-selector.ts +1 -0
- package/src/interactive/pane-policy.ts +46 -0
- package/src/interactive/panes-runtime.ts +292 -0
- 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/compaction-summary.ts +29 -0
- package/src/interactive/renderers/tool-execution.ts +4 -0
- package/src/interactive/renderers/worker-entry.ts +122 -14
- package/src/interactive/side-question.ts +58 -1
- package/src/interactive/slash-commands.ts +251 -15
- 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/tasks-overlay.ts +1 -0
- package/src/interactive/terminal-lease.ts +2 -0
- package/src/interactive/theme/tokens.ts +3 -14
- package/src/interactive/turn-context.ts +346 -33
- package/src/interactive/turn-persistence.ts +14 -4
- package/src/interactive/turn-prewarm.ts +364 -0
- package/src/interactive/turn-queues.ts +7 -4
- package/src/interactive/turn-runtime.ts +8 -1
- package/src/interactive/turn-state.ts +23 -0
- package/src/interactive/view/artifacts.ts +109 -1
- package/src/interactive/view/view-overlay.ts +29 -3
- package/src/interactive/watch-pane.ts +152 -0
- package/src/interactive/worker-progress.ts +7 -1
- package/src/interactive/worker-receipts.ts +19 -1
- package/src/interactive/worker-stream.ts +5 -0
- package/src/interactive/yazi-bridge.ts +444 -0
- package/src/tools/ask-user.ts +43 -2
- package/src/tools/bootstrap.ts +26 -2
- package/src/tools/builtin-tool-catalog.ts +15 -0
- package/src/tools/compete-worktrees.ts +83 -2
- package/src/tools/core-bootstrap.ts +2 -1
- package/src/tools/dispatch-admission.ts +14 -3
- package/src/tools/dispatch-arguments.ts +20 -20
- package/src/tools/dispatch-plan.ts +17 -9
- package/src/tools/dispatch-run-events.ts +134 -19
- package/src/tools/dispatch-runner.ts +29 -7
- package/src/tools/dispatch-scout.ts +1 -1
- package/src/tools/dispatch-types.ts +15 -3
- package/src/tools/dispatch.ts +1 -1
- package/src/tools/executables.ts +17 -14
- package/src/tools/observation.ts +54 -4
- package/src/tools/panes-surface.ts +38 -0
- package/src/tools/panes.ts +112 -0
- package/src/tools/policy.ts +10 -1
- package/src/tools/presentation.ts +1 -0
- package/src/tools/registry.ts +16 -0
- package/dist/chunk-AOCYTWAV.js +0 -449
- package/dist/chunk-HLE42MG7.js +0 -37
- package/dist/chunk-HWUFFB6L.js +0 -83
- package/dist/chunk-JOZYP4GM.js +0 -279
- package/dist/doctor-M7YEDGAE.js +0 -91
|
@@ -12,12 +12,21 @@ import {
|
|
|
12
12
|
type ContextPrunedPayload,
|
|
13
13
|
type ContextRecalledPayload,
|
|
14
14
|
type ContextWarningPayload,
|
|
15
|
+
type MemoryStepCompletedPayload,
|
|
16
|
+
type ResidencyMutationPayload,
|
|
15
17
|
} from "../core/bus-events.js";
|
|
18
|
+
import {
|
|
19
|
+
type BackendCacheVerdict,
|
|
20
|
+
type BackendCompletionTimings,
|
|
21
|
+
uncachedPrefillTokens,
|
|
22
|
+
} from "../core/cache-telemetry.js";
|
|
16
23
|
import type { ClioSettings } from "../core/config.js";
|
|
17
24
|
import type { SafeEventBus } from "../core/event-bus.js";
|
|
25
|
+
import { residencyTargetKey } from "../core/residency-target-key.js";
|
|
18
26
|
import type { ToolName } from "../core/tool-names.js";
|
|
19
27
|
import { buildEvictionFields, planEviction } from "../domains/context/working-set/engine.js";
|
|
20
28
|
import { foldWorkingSet } from "../domains/context/working-set/fold.js";
|
|
29
|
+
import { isTurnStart } from "../domains/context/working-set/horizon.js";
|
|
21
30
|
import { resolveWorkingSetPolicy } from "../domains/context/working-set/policies/index.js";
|
|
22
31
|
import { selectVisibleEntries } from "../domains/context/working-set/visible.js";
|
|
23
32
|
import type { ObservabilityContract } from "../domains/observability/contract.js";
|
|
@@ -26,6 +35,7 @@ import type { PromptsContract } from "../domains/prompts/contract.js";
|
|
|
26
35
|
import {
|
|
27
36
|
type ContextWindowDetails,
|
|
28
37
|
type ContextWindowSource,
|
|
38
|
+
canonicalEndpointKey,
|
|
29
39
|
type ProvidersContract,
|
|
30
40
|
resolveRuntimeTarget,
|
|
31
41
|
} from "../domains/providers/index.js";
|
|
@@ -50,18 +60,29 @@ import {
|
|
|
50
60
|
contextUsageSnapshot,
|
|
51
61
|
estimateAgentContextBreakdown,
|
|
52
62
|
estimateAgentContextTokens,
|
|
63
|
+
estimateAgentMessageTokens,
|
|
53
64
|
getLatestContextSnapshot,
|
|
65
|
+
lastLoadedContextWindow,
|
|
54
66
|
reconcileSnapshot,
|
|
55
67
|
snapshotInputTokens,
|
|
56
68
|
} from "../domains/session/context-accounting.js";
|
|
57
|
-
import {
|
|
69
|
+
import {
|
|
70
|
+
buildContextLedger,
|
|
71
|
+
type ContextLedger,
|
|
72
|
+
type PrewarmStats,
|
|
73
|
+
type PromptCacheStats,
|
|
74
|
+
} from "../domains/session/context-ledger.js";
|
|
58
75
|
import type { SessionContract } from "../domains/session/contract.js";
|
|
59
76
|
import type { CompactionTrigger, SessionEntry } from "../domains/session/entries.js";
|
|
60
|
-
import {
|
|
77
|
+
import {
|
|
78
|
+
appendPromptCompileRecord,
|
|
79
|
+
PROMPT_MANIFEST_VERSION,
|
|
80
|
+
readPromptCompileRecords,
|
|
81
|
+
type SessionPromptCompileRecord,
|
|
82
|
+
} from "../domains/session/prompt-manifest.js";
|
|
61
83
|
import type { AgentMessage, Usage } from "../engine/types.js";
|
|
62
84
|
import type { ToolRegistry } from "../tools/registry.js";
|
|
63
85
|
import {
|
|
64
|
-
type BackendCacheVerdict,
|
|
65
86
|
backendCacheVerdict,
|
|
66
87
|
extractUserText,
|
|
67
88
|
runtimeSupportsTools,
|
|
@@ -69,7 +90,7 @@ import {
|
|
|
69
90
|
toolNamesFromAgentState,
|
|
70
91
|
} from "./chat-loop-messages.js";
|
|
71
92
|
import { buildModelReplayAgentMessagesFromTurns } from "./model-session-replay.js";
|
|
72
|
-
import { renderCompactionSummaryLine } from "./renderers/compaction-summary.js";
|
|
93
|
+
import { renderCompactionSummaryLine, renderEvictionSkipLine } from "./renderers/compaction-summary.js";
|
|
73
94
|
import type { TurnMiddleware } from "./turn-middleware.js";
|
|
74
95
|
import type { AgentRuntime, ChatTurnState } from "./turn-state.js";
|
|
75
96
|
|
|
@@ -92,11 +113,43 @@ export interface TurnContextDeps {
|
|
|
92
113
|
}
|
|
93
114
|
|
|
94
115
|
export interface LiveContextEstimate {
|
|
116
|
+
/**
|
|
117
|
+
* The figure to budget against: the reconciled total when the provider has
|
|
118
|
+
* attested one for this conversation, otherwise the estimate. Never below
|
|
119
|
+
* the estimate, because the estimate covers material the last provider call
|
|
120
|
+
* did not see.
|
|
121
|
+
*/
|
|
95
122
|
tokens: number;
|
|
123
|
+
/** Pure chars/4 projection, with the pre-existing provider-usage anchor. */
|
|
124
|
+
estimatedTokens: number;
|
|
125
|
+
/**
|
|
126
|
+
* Provider-attested prompt tokens for the messages up to the last reconciled
|
|
127
|
+
* call, plus a chars/4 estimate of everything appended since. Null before the
|
|
128
|
+
* first reconcile of a session and after a summary compaction rewrites the
|
|
129
|
+
* history the attestation described.
|
|
130
|
+
*/
|
|
131
|
+
reconciledTokens: number | null;
|
|
96
132
|
contextWindow: number;
|
|
97
133
|
breakdown: ReturnType<typeof estimateAgentContextBreakdown>;
|
|
98
134
|
}
|
|
99
135
|
|
|
136
|
+
/** Known causes that make the next provider prefix cache miss expected. */
|
|
137
|
+
export type ExpectedColdReason =
|
|
138
|
+
| "dispatch"
|
|
139
|
+
| "compaction"
|
|
140
|
+
| "working_set_evict"
|
|
141
|
+
| "residency"
|
|
142
|
+
| "thinking_change"
|
|
143
|
+
| "tool_surface_change"
|
|
144
|
+
| "prompt_recompiled"
|
|
145
|
+
/**
|
|
146
|
+
* A proactive-memory step ran between turns on the endpoint this session
|
|
147
|
+
* streams against. Its prompt is a trajectory rather than the chat prefix, so
|
|
148
|
+
* on a local server that keeps one prefix cache the next turn re-prefills
|
|
149
|
+
* (#229).
|
|
150
|
+
*/
|
|
151
|
+
| "background_memory";
|
|
152
|
+
|
|
100
153
|
export interface TurnContext {
|
|
101
154
|
ensureSessionPrompt(agentRuntime: AgentRuntime): Promise<CompiledSessionPrompt | null>;
|
|
102
155
|
logPromptCompileIfPending(): void;
|
|
@@ -120,6 +173,12 @@ export interface TurnContext {
|
|
|
120
173
|
*/
|
|
121
174
|
promptSideTokens(): number;
|
|
122
175
|
liveContextEstimate(agentRuntime: AgentRuntime, pendingUserText?: string): LiveContextEstimate;
|
|
176
|
+
/**
|
|
177
|
+
* The loaded context window this session already recorded for a target and
|
|
178
|
+
* model, so a resume budgets against it instead of re-probing. Null when the
|
|
179
|
+
* ledger has no such measurement.
|
|
180
|
+
*/
|
|
181
|
+
rememberedLoadedContextWindow(targetId: string, modelId: string): number | null;
|
|
123
182
|
refreshAgentMessagesFromSession(agentRuntime: AgentRuntime): ReadonlyArray<SessionEntry>;
|
|
124
183
|
runAutoCompact(
|
|
125
184
|
agentRuntime: AgentRuntime,
|
|
@@ -142,27 +201,74 @@ export interface TurnContext {
|
|
|
142
201
|
contextUsage(): ContextUsageSnapshot;
|
|
143
202
|
contextLedger(): ContextLedger;
|
|
144
203
|
emitContextWindowWarningTransition(warning: string | null): void;
|
|
204
|
+
/** Record one known cache disturbance for the current or next call. */
|
|
205
|
+
noteColdReason(reason: ExpectedColdReason): void;
|
|
145
206
|
/** Consume disturbances since the last settled run (T3.3 honesty). */
|
|
146
207
|
consumeExpectedColdReasons(runtimeId: string): void;
|
|
147
208
|
/** Prompt-cache record for one persisted assistant call, with cold-reason stamp. */
|
|
148
|
-
promptCachePayloadForAssistant(usage: Usage): Record<string, unknown>;
|
|
209
|
+
promptCachePayloadForAssistant(usage: Usage, backend?: BackendCompletionTimings): Record<string, unknown>;
|
|
149
210
|
/** Record the settled run's cache summary for /context. */
|
|
150
211
|
noteRunCacheSummary(messages: ReadonlyArray<AgentMessage>, runFirstCallVerdict: BackendCacheVerdict | null): void;
|
|
212
|
+
/**
|
|
213
|
+
* Record one pre-warm for `/context`. It contributes no tokens to the context
|
|
214
|
+
* estimate and is never an expected-cold reason: a pre-warm is the opposite
|
|
215
|
+
* of a disturbance, it is the prefix the next turn wants already resident.
|
|
216
|
+
*/
|
|
217
|
+
notePrewarm(prewarm: PrewarmStats): void;
|
|
151
218
|
resetForSession(): void;
|
|
152
219
|
dispose(): void;
|
|
153
220
|
}
|
|
154
221
|
|
|
222
|
+
/**
|
|
223
|
+
* Why the working-set stage declined, said in the terms the operator can act
|
|
224
|
+
* on. The two cases are worth separating: a session whose every turn is inside
|
|
225
|
+
* `protectLastTurns` was never offered a candidate, while a longer one was
|
|
226
|
+
* offered candidates the policy refused. The first is the shape smoke pass 2
|
|
227
|
+
* found (G1), and the setting it names is the one that changes it.
|
|
228
|
+
*/
|
|
229
|
+
function evictionSkipMessage(
|
|
230
|
+
visibleEntries: ReadonlyArray<SessionEntry>,
|
|
231
|
+
workingSet: Readonly<{ protectLastTurns: number; policy: string }>,
|
|
232
|
+
policyId: string,
|
|
233
|
+
): string {
|
|
234
|
+
const turns = visibleEntries.filter(isTurnStart).length;
|
|
235
|
+
return renderEvictionSkipLine({
|
|
236
|
+
reason: turns <= workingSet.protectLastTurns ? "all-protected" : "nothing-evictable",
|
|
237
|
+
turns,
|
|
238
|
+
protectLastTurns: workingSet.protectLastTurns,
|
|
239
|
+
policyId,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
|
|
155
243
|
export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
156
244
|
const { state, middleware } = deps;
|
|
157
245
|
const compactionTrigger = new AutoCompactionTrigger<CompactResult | null>();
|
|
158
246
|
|
|
159
247
|
let currentContextSnapshot: ContextSnapshot | null = null;
|
|
248
|
+
/**
|
|
249
|
+
* The last provider-attested prompt size, and how many agent messages it
|
|
250
|
+
* covered (issue #227).
|
|
251
|
+
*
|
|
252
|
+
* `tokens` is the provider's own prompt count for that call plus the output
|
|
253
|
+
* it produced, which together are what the next call's prompt carries for
|
|
254
|
+
* the same messages. `anchoredMessageCount` is the length of the live
|
|
255
|
+
* message list at that moment, so anything appended since is priced by
|
|
256
|
+
* estimate and added on top. Unlike the per-message usage anchor inside
|
|
257
|
+
* `estimateAgentContextTokens`, this survives `contextUsageInvalidated`:
|
|
258
|
+
* a working-set projection subtracts the tokens it removed rather than
|
|
259
|
+
* throwing the attestation away.
|
|
260
|
+
*/
|
|
261
|
+
let reconciledAnchor: { tokens: number; anchoredMessageCount: number } | null = null;
|
|
160
262
|
let lastCompactionEvent: { stage: string; tokensBefore: number; tokensAfter: number; trigger: string } | null = null;
|
|
161
263
|
// Last settled run's provider cache usage plus whether the compiled system
|
|
162
264
|
// prompt was reused. Shown together in /context so "prompt reused" can
|
|
163
265
|
// never imply provider cache reuse the backend did not report.
|
|
164
266
|
let lastPromptCache: PromptCacheStats | null = null;
|
|
165
267
|
let lastSystemPromptReused = false;
|
|
268
|
+
// The last pre-warm, shown by /context until the next settled run answers the
|
|
269
|
+
// question it was asked about: did the prefix the next turn needs get there
|
|
270
|
+
// before the operator did.
|
|
271
|
+
let lastPrewarm: PrewarmStats | null = null;
|
|
166
272
|
// The session system prompt, compiled once per session. Recompiles happen
|
|
167
273
|
// only on explicit events: the compile key (target, model, safety level,
|
|
168
274
|
// session id) changes, or a config hot-reload invalidates the cache. A
|
|
@@ -170,6 +276,19 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
170
276
|
// ledger entry so a cold provider cache is always explainable.
|
|
171
277
|
let sessionPrompt: CompiledSessionPrompt | null = null;
|
|
172
278
|
let sessionPromptKey: string | null = null;
|
|
279
|
+
// The hash this process compiled *for the session that is current now*, and
|
|
280
|
+
// the manifest's `previousHash` whenever it is set. It is not read off
|
|
281
|
+
// `sessionPrompt`: an in-process `/resume` leaves that compile in place so
|
|
282
|
+
// the ledger keeps its project-preload labels until the next compile, but
|
|
283
|
+
// manifest provenance follows the session, so a switch drops the hash here
|
|
284
|
+
// and the next compile falls through to the incoming session's own manifest
|
|
285
|
+
// exactly as a cold-start resume does (#249).
|
|
286
|
+
let sessionPromptHash: string | null = null;
|
|
287
|
+
// Whether this process has already looked up the resumed session's last
|
|
288
|
+
// recorded prompt hash. The lookup reads the manifest file, so it happens
|
|
289
|
+
// once, on the first compile, and never on the reuse path.
|
|
290
|
+
let resumedPromptHashRead = false;
|
|
291
|
+
let resumedPromptHash: string | null = null;
|
|
173
292
|
const sessionWorkingContextPaths = new Set<string>();
|
|
174
293
|
let pendingPromptLogEntry: SessionPromptCompileRecord | null = null;
|
|
175
294
|
// A post-tool guard can run after every tool result in one model turn. Once
|
|
@@ -178,22 +297,25 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
178
297
|
// and summary probes. A new submitted user turn gets a new id naturally.
|
|
179
298
|
let emptyAutoCompactTurnId: string | null = null;
|
|
180
299
|
|
|
181
|
-
// Cache-disturbance honesty (T3.3).
|
|
182
|
-
//
|
|
183
|
-
//
|
|
184
|
-
//
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
let
|
|
188
|
-
|
|
189
|
-
//
|
|
190
|
-
//
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
300
|
+
// Cache-disturbance honesty (T3.3). Accumulate every known local-runtime
|
|
301
|
+
// disturbance and prefix-byte change since the last settled run. The next
|
|
302
|
+
// submit consumes the set, stamps `promptCache.expectedColdReasons` on its
|
|
303
|
+
// first assistant entry, and shows one dim notice.
|
|
304
|
+
const pendingColdReasons = new Set<ExpectedColdReason>();
|
|
305
|
+
let runExpectedColdReasons: ExpectedColdReason[] = [];
|
|
306
|
+
let nextAssistantColdReasons: ExpectedColdReason[] = [];
|
|
307
|
+
// Prefix-byte changes cool every tier. Residency, thinking changes, dispatch
|
|
308
|
+
// traffic, and compaction keep the local-native gate because they disturb a
|
|
309
|
+
// local server or its rendered template.
|
|
310
|
+
const TIER_INDEPENDENT_COLD_REASONS: ReadonlySet<ExpectedColdReason> = new Set([
|
|
311
|
+
"working_set_evict",
|
|
312
|
+
"tool_surface_change",
|
|
313
|
+
"prompt_recompiled",
|
|
314
|
+
]);
|
|
315
|
+
const stampsOnTier = (reason: ExpectedColdReason, runtimeId: string | undefined): boolean =>
|
|
194
316
|
TIER_INDEPENDENT_COLD_REASONS.has(reason) ||
|
|
195
317
|
(runtimeId !== undefined && deps.providers.getRuntime(runtimeId)?.tier === "local-native");
|
|
196
|
-
const noteColdReason = (reason:
|
|
318
|
+
const noteColdReason = (reason: ExpectedColdReason): void => {
|
|
197
319
|
if (!state.streaming) {
|
|
198
320
|
pendingColdReasons.add(reason);
|
|
199
321
|
return;
|
|
@@ -217,6 +339,21 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
217
339
|
noteColdReason("compaction");
|
|
218
340
|
}) ?? null,
|
|
219
341
|
),
|
|
342
|
+
deps.bus?.on(BusChannels.ResidencyMutation, (payload: ResidencyMutationPayload) => {
|
|
343
|
+
const runtime = state.runtime;
|
|
344
|
+
const model = runtime?.agent.state.model as { baseUrl?: unknown } | undefined;
|
|
345
|
+
const baseUrl = typeof model?.baseUrl === "string" ? model.baseUrl : null;
|
|
346
|
+
if (payload.targetKey !== residencyTargetKey(runtime?.runtimeId ?? "", baseUrl)) return;
|
|
347
|
+
noteColdReason("residency");
|
|
348
|
+
}) ?? null,
|
|
349
|
+
// A memory step on another endpoint disturbs nothing here, so the stamp is
|
|
350
|
+
// gated on the step having called the very server this session streams to.
|
|
351
|
+
deps.bus?.on(BusChannels.MemoryStepCompleted, (payload: MemoryStepCompletedPayload) => {
|
|
352
|
+
const target = state.runtime?.runtimeResolution.target;
|
|
353
|
+
if (target === undefined) return;
|
|
354
|
+
if (canonicalEndpointKey(target) !== payload.endpointKey) return;
|
|
355
|
+
noteColdReason("background_memory");
|
|
356
|
+
}) ?? null,
|
|
220
357
|
deps.bus?.on(BusChannels.ContextRecalled, (payload: ContextRecalledPayload) => {
|
|
221
358
|
middleware.fireCompactionHook("working_set_recall", payload.trigger);
|
|
222
359
|
}) ?? null,
|
|
@@ -322,6 +459,33 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
322
459
|
* (issue #189). Null when no target is configured or it does not resolve,
|
|
323
460
|
* and the overlay's "unknown" is then true.
|
|
324
461
|
*/
|
|
462
|
+
const rememberedLoadedContextWindow = (targetId: string, modelId: string): number | null => {
|
|
463
|
+
const session = deps.session?.current();
|
|
464
|
+
if (!session) return null;
|
|
465
|
+
return lastLoadedContextWindow(session, targetId, modelId);
|
|
466
|
+
};
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* The prompt hash this session last recorded, for the first compile of a
|
|
470
|
+
* resumed process. Without it a resume reports `previousHash: null`, which
|
|
471
|
+
* reads as "there was no prompt before" when in fact there was one and it
|
|
472
|
+
* is exactly what a reader needs to attribute the cold cache to: a layout
|
|
473
|
+
* bump, a fragment edit, or a moved context window (issue #249).
|
|
474
|
+
*/
|
|
475
|
+
const lastRecordedPromptHash = (): string | null => {
|
|
476
|
+
if (resumedPromptHashRead) return resumedPromptHash;
|
|
477
|
+
resumedPromptHashRead = true;
|
|
478
|
+
const currentSession = deps.session?.current();
|
|
479
|
+
if (!currentSession) {
|
|
480
|
+
// No session to read; leave the lookup open for the next compile.
|
|
481
|
+
resumedPromptHashRead = false;
|
|
482
|
+
return null;
|
|
483
|
+
}
|
|
484
|
+
const records = readPromptCompileRecords(currentSession);
|
|
485
|
+
resumedPromptHash = records[records.length - 1]?.systemPromptHash ?? null;
|
|
486
|
+
return resumedPromptHash;
|
|
487
|
+
};
|
|
488
|
+
|
|
325
489
|
const resolveWindowWithoutRuntime = (): ContextWindowDetails | null => {
|
|
326
490
|
const settings = deps.getSettings();
|
|
327
491
|
const targetId = settings.orchestrator?.target?.trim();
|
|
@@ -334,6 +498,7 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
334
498
|
use: "orchestrator",
|
|
335
499
|
requireTools: false,
|
|
336
500
|
requireOutputBudget: true,
|
|
501
|
+
knownLoadedContextWindow: rememberedLoadedContextWindow(targetId, wireModelId),
|
|
337
502
|
});
|
|
338
503
|
return resolved.ok ? resolved.target.contextWindowDetails : null;
|
|
339
504
|
};
|
|
@@ -383,6 +548,29 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
383
548
|
return { contextWindow: 0, contextWindowSource: null, contextWindowSlots: null };
|
|
384
549
|
};
|
|
385
550
|
|
|
551
|
+
/**
|
|
552
|
+
* Carry the reconciled anchor onto the current message list: the attested
|
|
553
|
+
* prompt for the messages it covered, plus a chars/4 estimate of everything
|
|
554
|
+
* appended since, plus text that has not been submitted yet. The tool
|
|
555
|
+
* schemas and the system prompt are inside the attested figure already, so
|
|
556
|
+
* they are not added again. Null when there is no attestation, or when the
|
|
557
|
+
* list is shorter than the anchor covered, which means the history it
|
|
558
|
+
* described was rewritten beneath it.
|
|
559
|
+
*/
|
|
560
|
+
const reconciledAnchoredTokens = (agentRuntime: AgentRuntime, pendingUserTokens: number): number | null => {
|
|
561
|
+
const anchor = reconciledAnchor;
|
|
562
|
+
if (!anchor) return null;
|
|
563
|
+
const messages = agentRuntime.agent.state.messages;
|
|
564
|
+
if (anchor.anchoredMessageCount > messages.length) return null;
|
|
565
|
+
let tail = 0;
|
|
566
|
+
for (let i = anchor.anchoredMessageCount; i < messages.length; i += 1) {
|
|
567
|
+
const message = messages[i];
|
|
568
|
+
if (message === undefined) continue;
|
|
569
|
+
tail += estimateAgentMessageTokens(message);
|
|
570
|
+
}
|
|
571
|
+
return anchor.tokens + tail + pendingUserTokens;
|
|
572
|
+
};
|
|
573
|
+
|
|
386
574
|
const liveContextEstimate = (agentRuntime: AgentRuntime, pendingUserText?: string): LiveContextEstimate => {
|
|
387
575
|
const contextWindow = agentRuntime.runtimeResolution.contextWindowDetails.effectiveContextWindow;
|
|
388
576
|
const estimateInput = {
|
|
@@ -391,10 +579,34 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
391
579
|
tools: agentRuntime.agent.state.tools,
|
|
392
580
|
...(pendingUserText !== undefined ? { pendingUserText } : {}),
|
|
393
581
|
};
|
|
582
|
+
const breakdown = estimateAgentContextBreakdown(estimateInput);
|
|
583
|
+
const estimatedTokens = estimateAgentContextTokens(estimateInput);
|
|
584
|
+
const reconciledTokens = reconciledAnchoredTokens(agentRuntime, breakdown.pendingUserTokens);
|
|
394
585
|
return {
|
|
395
|
-
|
|
586
|
+
// The estimate is a floor, not a competing verdict: it prices material
|
|
587
|
+
// the attested call never saw, so a provider count below it would be
|
|
588
|
+
// answering about a smaller conversation.
|
|
589
|
+
tokens: Math.max(estimatedTokens, reconciledTokens ?? 0),
|
|
590
|
+
estimatedTokens,
|
|
591
|
+
reconciledTokens,
|
|
396
592
|
contextWindow,
|
|
397
|
-
breakdown
|
|
593
|
+
breakdown,
|
|
594
|
+
};
|
|
595
|
+
};
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* A working-set projection removes tokens from messages the attestation
|
|
599
|
+
* covered; it does not make the attestation wrong about the rest. Subtract
|
|
600
|
+
* what the planner priced out against the same projection and re-anchor on
|
|
601
|
+
* the refreshed list, instead of discarding the figure and falling back to
|
|
602
|
+
* pure chars/4 exactly when the accounting matters most (issue #227).
|
|
603
|
+
* Call after the message list has been rebuilt.
|
|
604
|
+
*/
|
|
605
|
+
const carryReconciledAnchorThroughProjection = (agentRuntime: AgentRuntime, tokensRemoved: number): void => {
|
|
606
|
+
if (!reconciledAnchor) return;
|
|
607
|
+
reconciledAnchor = {
|
|
608
|
+
tokens: Math.max(0, reconciledAnchor.tokens - Math.max(0, tokensRemoved)),
|
|
609
|
+
anchoredMessageCount: agentRuntime.agent.state.messages.length,
|
|
398
610
|
};
|
|
399
611
|
};
|
|
400
612
|
|
|
@@ -414,7 +626,7 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
414
626
|
const emitCompactionActivity = (status: ContextActivityStatus, message: string): void => {
|
|
415
627
|
deps.bus?.emit(BusChannels.ContextActivity, {
|
|
416
628
|
kind: "compaction",
|
|
417
|
-
phase: "done",
|
|
629
|
+
phase: status === "completed" ? "done" : "compact",
|
|
418
630
|
status,
|
|
419
631
|
message,
|
|
420
632
|
at: Date.now(),
|
|
@@ -471,6 +683,12 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
471
683
|
const autoEnabled = cfg?.auto !== false;
|
|
472
684
|
if (!force && !autoEnabled) return false;
|
|
473
685
|
let preSummaryStageActed = false;
|
|
686
|
+
// G1 from smoke pass 2: a short session generates all its pressure inside
|
|
687
|
+
// the protection window, the non-destructive layer finds nothing, and the
|
|
688
|
+
// destructive summary ran with nothing in the transcript saying eviction
|
|
689
|
+
// was considered and declined. Held here and emitted only if a summary
|
|
690
|
+
// actually follows.
|
|
691
|
+
let evictionSkipNotice: string | null = null;
|
|
474
692
|
const rememberEmptyAutomaticAttempt = (): void => {
|
|
475
693
|
if (!force && !preSummaryStageActed && activeAutoTurnId) emptyAutoCompactTurnId = activeAutoTurnId;
|
|
476
694
|
};
|
|
@@ -507,6 +725,8 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
507
725
|
emitCompactionActivity("started", "compacting context (mask stage)");
|
|
508
726
|
deps.session.replaceEntries(masked.entries);
|
|
509
727
|
refreshAgentMessagesFromSession(agentRuntime);
|
|
728
|
+
// The masked history is not the one the provider counted.
|
|
729
|
+
reconciledAnchor = null;
|
|
510
730
|
deps.bus?.emit(BusChannels.CompactionEnd, { trigger, at: Date.now() });
|
|
511
731
|
|
|
512
732
|
const postMaskSnapshot = captureRuntimeContextSnapshot(
|
|
@@ -551,12 +771,16 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
551
771
|
}
|
|
552
772
|
} else if (settings.context.workingSet.enabled) {
|
|
553
773
|
let planned: ReturnType<typeof planEviction>;
|
|
774
|
+
let visibleEntries: ReadonlyArray<SessionEntry> = [];
|
|
775
|
+
let policyId = settings.context.workingSet.policy;
|
|
554
776
|
try {
|
|
555
777
|
const entries = deps.readSessionEntries() ?? [];
|
|
556
778
|
const view = foldWorkingSet(entries, state.lastTurnId ?? undefined);
|
|
557
779
|
const policy = resolveWorkingSetPolicy(settings.context.workingSet.policy);
|
|
780
|
+
policyId = policy.id;
|
|
781
|
+
visibleEntries = selectVisibleEntries(entries, state.lastTurnId ?? undefined);
|
|
558
782
|
planned = (deps.planEviction ?? planEviction)(policy, {
|
|
559
|
-
entries:
|
|
783
|
+
entries: visibleEntries,
|
|
560
784
|
view,
|
|
561
785
|
cwd: deps.session.current()?.cwd ?? null,
|
|
562
786
|
settings: settings.context.workingSet,
|
|
@@ -591,6 +815,7 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
591
815
|
});
|
|
592
816
|
noteColdReason("working_set_evict");
|
|
593
817
|
refreshAgentMessagesFromSession(agentRuntime);
|
|
818
|
+
carryReconciledAnchorThroughProjection(agentRuntime, planned.tokensBefore - planned.tokensAfter);
|
|
594
819
|
|
|
595
820
|
const postEvictionSnapshot = captureRuntimeContextSnapshot(
|
|
596
821
|
agentRuntime,
|
|
@@ -637,7 +862,16 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
637
862
|
emitCompactionActivity("failed", compactionFailureMessage(error));
|
|
638
863
|
throw error;
|
|
639
864
|
}
|
|
865
|
+
} else {
|
|
866
|
+
evictionSkipNotice = evictionSkipMessage(visibleEntries, settings.context.workingSet, policyId);
|
|
640
867
|
}
|
|
868
|
+
} else {
|
|
869
|
+
evictionSkipNotice = renderEvictionSkipLine({
|
|
870
|
+
reason: "disabled",
|
|
871
|
+
turns: 0,
|
|
872
|
+
protectLastTurns: settings.context.workingSet.protectLastTurns,
|
|
873
|
+
policyId: settings.context.workingSet.policy,
|
|
874
|
+
});
|
|
641
875
|
}
|
|
642
876
|
}
|
|
643
877
|
}
|
|
@@ -654,6 +888,10 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
654
888
|
summaryLifecycleStarted = true;
|
|
655
889
|
};
|
|
656
890
|
if (force) startSummaryLifecycle();
|
|
891
|
+
// Said before the summary call, not after it: the operator is about to wait
|
|
892
|
+
// on a destructive stage, and the reason the cheap one was skipped is only
|
|
893
|
+
// useful ahead of it.
|
|
894
|
+
if (evictionSkipNotice) deps.emitNotice(evictionSkipNotice);
|
|
657
895
|
let result: CompactResult | null = null;
|
|
658
896
|
const beforeSnapshotId = currentContextSnapshot?.snapshotId ?? null;
|
|
659
897
|
try {
|
|
@@ -683,6 +921,9 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
683
921
|
recordCompactionUsage(agentRuntime, result);
|
|
684
922
|
|
|
685
923
|
refreshAgentMessagesFromSession(agentRuntime);
|
|
924
|
+
// A summary replaces the conversation the attestation described, so no
|
|
925
|
+
// arithmetic carries it forward; the next call re-anchors it.
|
|
926
|
+
reconciledAnchor = null;
|
|
686
927
|
|
|
687
928
|
const postCompactSnapshot = captureRuntimeContextSnapshot(
|
|
688
929
|
agentRuntime,
|
|
@@ -741,6 +982,7 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
741
982
|
captureRuntimeContextSnapshot,
|
|
742
983
|
persistContextSnapshot,
|
|
743
984
|
liveContextEstimate,
|
|
985
|
+
rememberedLoadedContextWindow,
|
|
744
986
|
refreshAgentMessagesFromSession,
|
|
745
987
|
runAutoCompact,
|
|
746
988
|
|
|
@@ -754,6 +996,18 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
754
996
|
},
|
|
755
997
|
|
|
756
998
|
reconcileUsage(usage: Usage): void {
|
|
999
|
+
// Cached prompt tokens still occupy the window; providers report them
|
|
1000
|
+
// outside `input`, so the attested prompt is the three summed.
|
|
1001
|
+
const promptTokens = (usage.input || 0) + (usage.cacheRead || 0) + (usage.cacheWrite || 0);
|
|
1002
|
+
const messages = state.runtime?.agent.state.messages;
|
|
1003
|
+
if (promptTokens > 0 && messages) {
|
|
1004
|
+
// The output of this call is part of the next call's prompt for the
|
|
1005
|
+
// same messages, which is why it is folded in here.
|
|
1006
|
+
reconciledAnchor = {
|
|
1007
|
+
tokens: promptTokens + (usage.output || 0),
|
|
1008
|
+
anchoredMessageCount: messages.length,
|
|
1009
|
+
};
|
|
1010
|
+
}
|
|
757
1011
|
if (!currentContextSnapshot) return;
|
|
758
1012
|
// Reconcile in memory on every API call so the live meters
|
|
759
1013
|
// track usage; persistence waits for the run to settle.
|
|
@@ -787,7 +1041,22 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
787
1041
|
const modelState = agentRuntime.agent.state.model as
|
|
788
1042
|
| (typeof agentRuntime.agent.state.model & { clio?: { quirks?: LocalModelQuirks } })
|
|
789
1043
|
| undefined;
|
|
790
|
-
|
|
1044
|
+
// `Context window: N` is the window the backend will actually serve
|
|
1045
|
+
// this session, taken from the resolution the turn already ran rather
|
|
1046
|
+
// than from the model descriptor's copy of it (issue #249). The
|
|
1047
|
+
// ranking that puts a loaded figure ahead of a probed one lives in
|
|
1048
|
+
// `resolveContextWindowDetails`, which tests `loadedContextWindow`
|
|
1049
|
+
// first and only then `probedContextWindow`, so `effectiveContextWindow`
|
|
1050
|
+
// already is the loaded window whenever one is known and the source
|
|
1051
|
+
// already reads "loaded"; brief #227's carry-forward is what puts that
|
|
1052
|
+
// figure in reach on a resume. The source rides into the prompt
|
|
1053
|
+
// manifest, so a recompile after the loaded window is first observed
|
|
1054
|
+
// is explained by the record.
|
|
1055
|
+
const windowDetails = agentRuntime.runtimeResolution.contextWindowDetails;
|
|
1056
|
+
const resolvedWindow = windowDetails.effectiveContextWindow;
|
|
1057
|
+
const contextWindow = typeof resolvedWindow === "number" && resolvedWindow > 0 ? resolvedWindow : null;
|
|
1058
|
+
const contextWindowSource: ContextWindowSource | null =
|
|
1059
|
+
contextWindow === null ? null : windowDetails.contextWindowSource;
|
|
791
1060
|
const guidance = modelState?.clio?.quirks?.thinking?.guidance;
|
|
792
1061
|
// Per-tool prompt hints come from registry metadata, derived once from
|
|
793
1062
|
// the frozen surface per compile. The compiler renders them sorted by
|
|
@@ -823,16 +1092,19 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
823
1092
|
cwd: process.cwd(),
|
|
824
1093
|
workingContextPaths: [...sessionWorkingContextPaths],
|
|
825
1094
|
});
|
|
826
|
-
const previousHash =
|
|
1095
|
+
const previousHash = sessionPromptHash ?? lastRecordedPromptHash();
|
|
827
1096
|
const changed = agentRuntime.agent.state.systemPrompt !== result.systemPrompt;
|
|
828
1097
|
if (changed) {
|
|
829
1098
|
agentRuntime.agent.state.systemPrompt = result.systemPrompt;
|
|
830
1099
|
pendingPromptLogEntry = {
|
|
1100
|
+
version: PROMPT_MANIFEST_VERSION,
|
|
831
1101
|
at: new Date().toISOString(),
|
|
832
1102
|
previousHash,
|
|
833
1103
|
systemPromptHash: result.systemPromptHash,
|
|
834
1104
|
tokenEstimate: result.tokenEstimate,
|
|
835
1105
|
thinkingLevel: agentRuntime.agent.state.thinkingLevel ?? null,
|
|
1106
|
+
contextWindow,
|
|
1107
|
+
contextWindowSource,
|
|
836
1108
|
projectPreload: result.projectPreload ?? null,
|
|
837
1109
|
sections: result.sections.map((s) => ({ id: s.id, tokenEstimate: s.tokenEstimate })),
|
|
838
1110
|
fragments: result.fragmentManifest.map((f) => ({
|
|
@@ -845,6 +1117,7 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
845
1117
|
}
|
|
846
1118
|
lastSystemPromptReused = !changed;
|
|
847
1119
|
sessionPrompt = result;
|
|
1120
|
+
sessionPromptHash = result.systemPromptHash;
|
|
848
1121
|
sessionPromptKey = key;
|
|
849
1122
|
return result;
|
|
850
1123
|
} catch (err) {
|
|
@@ -877,6 +1150,11 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
877
1150
|
tokenEstimate: entry.tokenEstimate,
|
|
878
1151
|
},
|
|
879
1152
|
});
|
|
1153
|
+
// A resumed process names the session's last recorded hash as previousHash (#249), so
|
|
1154
|
+
// the stamp requires the hash to have moved, not merely to have a predecessor.
|
|
1155
|
+
if (entry.previousHash !== null && entry.previousHash !== entry.systemPromptHash) {
|
|
1156
|
+
noteColdReason("prompt_recompiled");
|
|
1157
|
+
}
|
|
880
1158
|
} catch {
|
|
881
1159
|
// Ledger logging is diagnostics, not control flow; never abort a turn.
|
|
882
1160
|
}
|
|
@@ -966,6 +1244,7 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
966
1244
|
compactionThreshold,
|
|
967
1245
|
compactionAuto,
|
|
968
1246
|
promptCache: lastPromptCache,
|
|
1247
|
+
prewarm: lastPrewarm,
|
|
969
1248
|
});
|
|
970
1249
|
}
|
|
971
1250
|
|
|
@@ -998,6 +1277,7 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
998
1277
|
measured,
|
|
999
1278
|
lastCompaction: lastCompactionEvent,
|
|
1000
1279
|
promptCache: lastPromptCache,
|
|
1280
|
+
prewarm: lastPrewarm,
|
|
1001
1281
|
});
|
|
1002
1282
|
},
|
|
1003
1283
|
|
|
@@ -1007,12 +1287,14 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
1007
1287
|
deps.bus?.emit(BusChannels.ContextWarning, { warning } satisfies ContextWarningPayload);
|
|
1008
1288
|
},
|
|
1009
1289
|
|
|
1290
|
+
noteColdReason,
|
|
1291
|
+
|
|
1010
1292
|
consumeExpectedColdReasons(runtimeId: string): void {
|
|
1011
1293
|
// Cache-disturbance honesty (T3.3): consume disturbances since
|
|
1012
1294
|
// the last settled run. Only single-slot local backends lose their
|
|
1013
|
-
// prefix cache to interleaved work, so
|
|
1014
|
-
// stamp only on local-native targets
|
|
1015
|
-
// the prefix
|
|
1295
|
+
// prefix cache to interleaved work, so residency, thinking changes,
|
|
1296
|
+
// dispatch, and compaction stamp only on local-native targets. Reasons
|
|
1297
|
+
// that change the prefix bytes stamp every tier (see stampsOnTier).
|
|
1016
1298
|
runExpectedColdReasons = [];
|
|
1017
1299
|
nextAssistantColdReasons = [];
|
|
1018
1300
|
if (pendingColdReasons.size > 0) {
|
|
@@ -1026,10 +1308,10 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
1026
1308
|
}
|
|
1027
1309
|
},
|
|
1028
1310
|
|
|
1029
|
-
promptCachePayloadForAssistant(usage: Usage): Record<string, unknown> {
|
|
1030
|
-
// Per-call prompt-cache record (T3.2)
|
|
1031
|
-
//
|
|
1032
|
-
//
|
|
1311
|
+
promptCachePayloadForAssistant(usage: Usage, backend?: BackendCompletionTimings): Record<string, unknown> {
|
|
1312
|
+
// Per-call prompt-cache record (T3.2) keeps normalized provider usage
|
|
1313
|
+
// beside any timings captured from the server response. The run's first
|
|
1314
|
+
// persisted call also carries any expected-cold reasons.
|
|
1033
1315
|
const input = typeof usage.input === "number" ? usage.input : 0;
|
|
1034
1316
|
const cacheRead = typeof usage.cacheRead === "number" ? usage.cacheRead : 0;
|
|
1035
1317
|
const cacheWrite = typeof usage.cacheWrite === "number" ? usage.cacheWrite : 0;
|
|
@@ -1037,8 +1319,9 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
1037
1319
|
input,
|
|
1038
1320
|
cacheRead,
|
|
1039
1321
|
cacheWrite,
|
|
1040
|
-
backendVerdict: backendCacheVerdict(input, cacheRead),
|
|
1322
|
+
backendVerdict: backendCacheVerdict(input, cacheRead, backend),
|
|
1041
1323
|
};
|
|
1324
|
+
if (backend !== undefined) promptCache.backend = { ...backend };
|
|
1042
1325
|
if (nextAssistantColdReasons.length > 0) {
|
|
1043
1326
|
promptCache.expectedColdReasons = [...nextAssistantColdReasons];
|
|
1044
1327
|
nextAssistantColdReasons = [];
|
|
@@ -1046,14 +1329,30 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
1046
1329
|
return promptCache;
|
|
1047
1330
|
},
|
|
1048
1331
|
|
|
1332
|
+
notePrewarm(prewarm: PrewarmStats): void {
|
|
1333
|
+
lastPrewarm = prewarm;
|
|
1334
|
+
},
|
|
1335
|
+
|
|
1049
1336
|
noteRunCacheSummary(messages, runFirstCallVerdict): void {
|
|
1337
|
+
// The settled run is the answer to the pre-warm's question, so the
|
|
1338
|
+
// pre-warm line stops being the newest fact about the prefix here.
|
|
1339
|
+
lastPrewarm = null;
|
|
1050
1340
|
const cacheSummary = sumRunUsage(messages);
|
|
1051
1341
|
if (cacheSummary.hadUsage) {
|
|
1342
|
+
let lastBackend: BackendCompletionTimings | null = null;
|
|
1343
|
+
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
1344
|
+
const message = messages[index];
|
|
1345
|
+
if (message?.role !== "assistant") continue;
|
|
1346
|
+
lastBackend = (message as { backendTimings?: BackendCompletionTimings }).backendTimings ?? null;
|
|
1347
|
+
break;
|
|
1348
|
+
}
|
|
1052
1349
|
lastPromptCache = {
|
|
1053
1350
|
shellReused: lastSystemPromptReused,
|
|
1054
1351
|
cacheReadTokens: cacheSummary.cacheRead > 0 || cacheSummary.cacheWrite > 0 ? cacheSummary.cacheRead : null,
|
|
1055
1352
|
cacheWriteTokens: cacheSummary.cacheRead > 0 || cacheSummary.cacheWrite > 0 ? cacheSummary.cacheWrite : null,
|
|
1056
1353
|
uncachedInputTokens: cacheSummary.input,
|
|
1354
|
+
backend: lastBackend,
|
|
1355
|
+
uncachedPrefillTokens: uncachedPrefillTokens(lastBackend),
|
|
1057
1356
|
backendVerdict: runFirstCallVerdict,
|
|
1058
1357
|
...(runExpectedColdReasons.length > 0 ? { expectedColdReasons: [...runExpectedColdReasons] } : {}),
|
|
1059
1358
|
};
|
|
@@ -1061,12 +1360,26 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
1061
1360
|
},
|
|
1062
1361
|
|
|
1063
1362
|
resetForSession(): void {
|
|
1363
|
+
// An in-process switch replaces the whole prefix: the backend's slot
|
|
1364
|
+
// still holds the outgoing session's prompt and history, so the first
|
|
1365
|
+
// turn on the incoming one is expected-cold on every tier, exactly as
|
|
1366
|
+
// a recompile is. The manifest can no longer say so on its own once
|
|
1367
|
+
// provenance follows the session, because the incoming session's last
|
|
1368
|
+
// recorded hash usually equals its fresh compile, so the stamp comes
|
|
1369
|
+
// from here. Only when this process had actually applied a prompt:
|
|
1370
|
+
// before the first compile there is nothing in the slot to have lost.
|
|
1371
|
+
if (sessionPromptHash !== null) noteColdReason("prompt_recompiled");
|
|
1064
1372
|
lastPromptCache = null;
|
|
1373
|
+
lastPrewarm = null;
|
|
1065
1374
|
lastSystemPromptReused = false;
|
|
1375
|
+
sessionPromptHash = null;
|
|
1066
1376
|
sessionPromptKey = null;
|
|
1377
|
+
resumedPromptHashRead = false;
|
|
1378
|
+
resumedPromptHash = null;
|
|
1067
1379
|
sessionWorkingContextPaths.clear();
|
|
1068
1380
|
pendingPromptLogEntry = null;
|
|
1069
1381
|
emptyAutoCompactTurnId = null;
|
|
1382
|
+
reconciledAnchor = null;
|
|
1070
1383
|
const session = deps.session?.current();
|
|
1071
1384
|
currentContextSnapshot = session ? getLatestContextSnapshot(session) : null;
|
|
1072
1385
|
},
|