@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
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { randomBytes } from "node:crypto";
|
|
2
2
|
import { withStateFileLockSync } from "../../core/state-file-lock.js";
|
|
3
|
+
import { endpointLabel } from "../providers/endpoint-capacity.js";
|
|
3
4
|
import {
|
|
4
5
|
acquireCapacityLease,
|
|
5
6
|
activeCapacityDrainUnsafe,
|
|
@@ -7,21 +8,38 @@ import {
|
|
|
7
8
|
type CapacityLimits,
|
|
8
9
|
type CapacityStateFile,
|
|
9
10
|
capacityStateLockPath,
|
|
11
|
+
describeEndpointCapacityHolders,
|
|
12
|
+
endpointCapacityRemedy,
|
|
10
13
|
readCapacityStateUnsafe,
|
|
11
14
|
writeCapacityStateUnsafe,
|
|
12
15
|
} from "./capacity-lease.js";
|
|
16
|
+
import { COUNCIL_MIN_MEMBERS } from "./gate-role-prompts.js";
|
|
13
17
|
|
|
14
18
|
const MAX_RESERVATION_RECORDS = 500;
|
|
15
19
|
export const DEFAULT_RESERVATION_TTL_MS = 15 * 60_000;
|
|
16
20
|
|
|
17
|
-
|
|
21
|
+
/**
|
|
22
|
+
* `council` is carried rather than flattened into `parallel` because it is the
|
|
23
|
+
* one topology with a floor on its own width. Every other plan can answer a
|
|
24
|
+
* capacity denial by dispatching fewer at once; a council of two cannot, and a
|
|
25
|
+
* denial that tells it to is advice it cannot take.
|
|
26
|
+
*/
|
|
27
|
+
export type ReservationTopology =
|
|
28
|
+
| "parallel"
|
|
29
|
+
| "detached"
|
|
30
|
+
| "sequential"
|
|
31
|
+
| "pipeline"
|
|
32
|
+
| "review"
|
|
33
|
+
| "compete"
|
|
34
|
+
| "council";
|
|
18
35
|
export type ReservationMemberStatus = "held" | "consumed" | "released";
|
|
19
36
|
export type ReservationStatus = "active" | "released" | "rolled_back" | "expired";
|
|
20
37
|
|
|
21
38
|
/**
|
|
22
|
-
* A reservation holds
|
|
23
|
-
* concurrency slot, a per-node slot, and a budget
|
|
24
|
-
*
|
|
39
|
+
* A reservation holds four scarce things and nothing else: a global
|
|
40
|
+
* concurrency slot, a per-node slot, an inference-endpoint slot, and a budget
|
|
41
|
+
* upper bound. Node and endpoint identity matter only because slots bind on
|
|
42
|
+
* those dimensions. Agent, target, model, and runtime
|
|
25
43
|
* identity are route identity, which the failover envelope owns
|
|
26
44
|
* (`assertRouteWithinApprovedEnvelope`); pinning them here made a
|
|
27
45
|
* plan-approved dispatch unable to fail over at all.
|
|
@@ -30,6 +48,7 @@ export interface ReservationPlanTask {
|
|
|
30
48
|
memberId: string;
|
|
31
49
|
wave: number;
|
|
32
50
|
nodeId: string;
|
|
51
|
+
endpointKey?: string;
|
|
33
52
|
costUpperBoundUsd: number;
|
|
34
53
|
}
|
|
35
54
|
|
|
@@ -54,17 +73,33 @@ export interface DispatchReservationRecord {
|
|
|
54
73
|
export interface ReservationCapacitySnapshot {
|
|
55
74
|
global: { active: number; limit: number };
|
|
56
75
|
nodes: Readonly<Record<string, { active: number; limit: number }>>;
|
|
76
|
+
endpoints: Readonly<Record<string, { active: number; limit: number; leases?: number; foregroundStreams?: number }>>;
|
|
57
77
|
budget: { currentUsd: number; ceilingUsd: number };
|
|
58
78
|
}
|
|
59
79
|
|
|
60
80
|
export interface ReservationAllocation {
|
|
61
81
|
globalSlots: number;
|
|
62
82
|
nodeSlots: Readonly<Record<string, number>>;
|
|
83
|
+
endpointSlots: Readonly<Record<string, number>>;
|
|
63
84
|
budgetUsd: number;
|
|
64
85
|
}
|
|
65
86
|
|
|
66
87
|
export type ReservationPlanResult = { ok: true; allocation: ReservationAllocation } | { ok: false; reason: string };
|
|
67
88
|
|
|
89
|
+
function endpointCapacityDenial(input: {
|
|
90
|
+
endpointKey: string;
|
|
91
|
+
limit: number;
|
|
92
|
+
used: number;
|
|
93
|
+
requested: number;
|
|
94
|
+
leases: number;
|
|
95
|
+
reservations: number;
|
|
96
|
+
foregroundStreams: number;
|
|
97
|
+
topology?: ReservationTopology;
|
|
98
|
+
}): string {
|
|
99
|
+
const remedy = endpointCapacityRemedy(input.topology === "council" ? { rosterFloor: COUNCIL_MIN_MEMBERS } : undefined);
|
|
100
|
+
return `dispatch: admission denied: endpoint '${endpointLabel(input.endpointKey)}' capacity exceeded (${input.used + input.requested}/${input.limit} slots): ${describeEndpointCapacityHolders(input)}; ${remedy}`;
|
|
101
|
+
}
|
|
102
|
+
|
|
68
103
|
function copyRecord(record: DispatchReservationRecord): DispatchReservationRecord {
|
|
69
104
|
return { ...record, members: record.members.map((member) => ({ ...member })) };
|
|
70
105
|
}
|
|
@@ -82,7 +117,8 @@ function validRecord(value: unknown): value is DispatchReservationRecord {
|
|
|
82
117
|
record.topology === "sequential" ||
|
|
83
118
|
record.topology === "pipeline" ||
|
|
84
119
|
record.topology === "review" ||
|
|
85
|
-
record.topology === "compete"
|
|
120
|
+
record.topology === "compete" ||
|
|
121
|
+
record.topology === "council") &&
|
|
86
122
|
(record.status === "active" ||
|
|
87
123
|
record.status === "released" ||
|
|
88
124
|
record.status === "rolled_back" ||
|
|
@@ -96,6 +132,7 @@ function validRecord(value: unknown): value is DispatchReservationRecord {
|
|
|
96
132
|
typeof member.memberId === "string" &&
|
|
97
133
|
Number.isInteger(member.wave) &&
|
|
98
134
|
typeof member.nodeId === "string" &&
|
|
135
|
+
(member.endpointKey === undefined || typeof member.endpointKey === "string") &&
|
|
99
136
|
typeof member.costUpperBoundUsd === "number" &&
|
|
100
137
|
Number.isFinite(member.costUpperBoundUsd) &&
|
|
101
138
|
member.costUpperBoundUsd >= 0 &&
|
|
@@ -145,9 +182,13 @@ function reservationAllocation(tasks: ReadonlyArray<ReservationPlanTask>): Reser
|
|
|
145
182
|
),
|
|
146
183
|
);
|
|
147
184
|
const nodeSlots = peakBy(tasks.map((task) => ({ wave: task.wave, key: task.nodeId })));
|
|
185
|
+
const endpointSlots = peakBy(
|
|
186
|
+
tasks.flatMap((task) => (task.endpointKey === undefined ? [] : [{ wave: task.wave, key: task.endpointKey }])),
|
|
187
|
+
);
|
|
148
188
|
return {
|
|
149
189
|
globalSlots,
|
|
150
190
|
nodeSlots,
|
|
191
|
+
endpointSlots,
|
|
151
192
|
budgetUsd: tasks.reduce((sum, task) => sum + task.costUpperBoundUsd, 0),
|
|
152
193
|
};
|
|
153
194
|
}
|
|
@@ -168,6 +209,7 @@ function allocateReservation(
|
|
|
168
209
|
tasks: ReadonlyArray<ReservationPlanTask>,
|
|
169
210
|
existing: ReadonlyArray<DispatchReservationRecord>,
|
|
170
211
|
capacity: ReservationCapacitySnapshot,
|
|
212
|
+
topology?: ReservationTopology,
|
|
171
213
|
): ReservationPlanResult {
|
|
172
214
|
if (tasks.length === 0) return { ok: false, reason: "reservation requires at least one task" };
|
|
173
215
|
const duplicate = tasks.find((task, index) => tasks.slice(0, index).some((entry) => entry.memberId === task.memberId));
|
|
@@ -191,6 +233,27 @@ function allocateReservation(
|
|
|
191
233
|
return { ok: false, reason: `node '${nodeId}' capacity exceeded (${used + slots}/${node.limit})` };
|
|
192
234
|
}
|
|
193
235
|
}
|
|
236
|
+
for (const [endpointKey, slots] of Object.entries(requested.endpointSlots)) {
|
|
237
|
+
const endpoint = capacity.endpoints[endpointKey];
|
|
238
|
+
if (!endpoint || !Number.isFinite(endpoint.limit)) continue;
|
|
239
|
+
const heldSlots = held.reduce((sum, allocation) => sum + (allocation.endpointSlots[endpointKey] ?? 0), 0);
|
|
240
|
+
const used = endpoint.active + heldSlots;
|
|
241
|
+
if (used + slots > endpoint.limit) {
|
|
242
|
+
return {
|
|
243
|
+
ok: false,
|
|
244
|
+
reason: endpointCapacityDenial({
|
|
245
|
+
endpointKey,
|
|
246
|
+
limit: endpoint.limit,
|
|
247
|
+
used,
|
|
248
|
+
requested: slots,
|
|
249
|
+
leases: endpoint.leases ?? endpoint.active - (endpoint.foregroundStreams ?? 0),
|
|
250
|
+
reservations: heldSlots,
|
|
251
|
+
foregroundStreams: endpoint.foregroundStreams ?? 0,
|
|
252
|
+
...(topology === undefined ? {} : { topology }),
|
|
253
|
+
}),
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
}
|
|
194
257
|
const existingBudget = activeRecords.reduce((sum, record) => sum + outstandingBudget(record), 0);
|
|
195
258
|
const projected = capacity.budget.currentUsd + existingBudget + requested.budgetUsd;
|
|
196
259
|
if (projected >= capacity.budget.ceilingUsd) {
|
|
@@ -221,11 +284,13 @@ export function createDispatchReservation(input: {
|
|
|
221
284
|
`dispatch: reservation denied: capacity is draining (requested by pid ${drain.requestedByPid} at ${drain.requestedAt})`,
|
|
222
285
|
);
|
|
223
286
|
}
|
|
224
|
-
const planned = allocateReservation(input.tasks, records, input.capacity);
|
|
287
|
+
const planned = allocateReservation(input.tasks, records, input.capacity, input.topology);
|
|
225
288
|
if (!planned.ok) {
|
|
226
289
|
replaceReservations(state, records);
|
|
227
290
|
writeCapacityStateUnsafe(state);
|
|
228
|
-
throw new Error(
|
|
291
|
+
throw new Error(
|
|
292
|
+
planned.reason.startsWith("dispatch:") ? planned.reason : `dispatch: reservation denied: ${planned.reason}`,
|
|
293
|
+
);
|
|
229
294
|
}
|
|
230
295
|
const createdAt = new Date(nowMs).toISOString();
|
|
231
296
|
const record: DispatchReservationRecord = {
|
|
@@ -250,6 +315,7 @@ export function transferDispatchReservationToLease(input: {
|
|
|
250
315
|
memberId: string;
|
|
251
316
|
assignmentId: string;
|
|
252
317
|
nodeId: string;
|
|
318
|
+
endpointKey?: string;
|
|
253
319
|
limits: CapacityLimits;
|
|
254
320
|
nowMs?: number;
|
|
255
321
|
ttlMs?: number;
|
|
@@ -258,6 +324,7 @@ export function transferDispatchReservationToLease(input: {
|
|
|
258
324
|
return acquireCapacityLease({
|
|
259
325
|
assignmentId: input.assignmentId,
|
|
260
326
|
nodeId: input.nodeId,
|
|
327
|
+
...(input.endpointKey !== undefined ? { endpointKey: input.endpointKey } : {}),
|
|
261
328
|
limits: input.limits,
|
|
262
329
|
nowMs,
|
|
263
330
|
...(input.ttlMs !== undefined ? { ttlMs: input.ttlMs } : {}),
|
|
@@ -290,6 +357,7 @@ export function rebindDispatchReservationMember(input: {
|
|
|
290
357
|
ownerId: string;
|
|
291
358
|
memberId: string;
|
|
292
359
|
nodeId: string;
|
|
360
|
+
endpointKey?: string;
|
|
293
361
|
costUpperBoundUsd: number;
|
|
294
362
|
capacity: ReservationCapacitySnapshot;
|
|
295
363
|
nowMs?: number;
|
|
@@ -304,11 +372,42 @@ export function rebindDispatchReservationMember(input: {
|
|
|
304
372
|
if (member.status === "released") {
|
|
305
373
|
throw new Error(`dispatch: reservation member '${input.memberId}' was already released`);
|
|
306
374
|
}
|
|
307
|
-
if (
|
|
375
|
+
if (
|
|
376
|
+
member.nodeId === input.nodeId &&
|
|
377
|
+
member.endpointKey === input.endpointKey &&
|
|
378
|
+
member.costUpperBoundUsd === input.costUpperBoundUsd
|
|
379
|
+
) {
|
|
308
380
|
return copyRecord(record);
|
|
309
381
|
}
|
|
310
|
-
|
|
311
382
|
const others = records.filter((entry) => entry.status === "active" && entry.ownerId !== input.ownerId);
|
|
383
|
+
if (member.endpointKey !== input.endpointKey && input.endpointKey !== undefined) {
|
|
384
|
+
const endpointKey = input.endpointKey;
|
|
385
|
+
const endpoint = input.capacity.endpoints[endpointKey];
|
|
386
|
+
if (endpoint !== undefined && Number.isFinite(endpoint.limit)) {
|
|
387
|
+
const siblingSlots = record.members.filter(
|
|
388
|
+
(entry) => entry !== member && entry.status !== "released" && entry.endpointKey === endpointKey,
|
|
389
|
+
).length;
|
|
390
|
+
const otherHeld = others.reduce(
|
|
391
|
+
(sum, entry) => sum + (reservationAllocation(outstandingTasks(entry)).endpointSlots[endpointKey] ?? 0),
|
|
392
|
+
0,
|
|
393
|
+
);
|
|
394
|
+
const used = endpoint.active + otherHeld + siblingSlots;
|
|
395
|
+
if (used + 1 > endpoint.limit) {
|
|
396
|
+
throw new Error(
|
|
397
|
+
endpointCapacityDenial({
|
|
398
|
+
endpointKey,
|
|
399
|
+
limit: endpoint.limit,
|
|
400
|
+
used,
|
|
401
|
+
requested: 1,
|
|
402
|
+
leases: endpoint.leases ?? endpoint.active - (endpoint.foregroundStreams ?? 0),
|
|
403
|
+
reservations: otherHeld + siblingSlots,
|
|
404
|
+
foregroundStreams: endpoint.foregroundStreams ?? 0,
|
|
405
|
+
}),
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
312
411
|
if (member.nodeId !== input.nodeId) {
|
|
313
412
|
const node = input.capacity.nodes[input.nodeId];
|
|
314
413
|
if (node !== undefined && Number.isFinite(node.limit)) {
|
|
@@ -342,6 +441,8 @@ export function rebindDispatchReservationMember(input: {
|
|
|
342
441
|
}
|
|
343
442
|
|
|
344
443
|
member.nodeId = input.nodeId;
|
|
444
|
+
if (input.endpointKey === undefined) delete member.endpointKey;
|
|
445
|
+
else member.endpointKey = input.endpointKey;
|
|
345
446
|
member.costUpperBoundUsd = Math.max(0, input.costUpperBoundUsd);
|
|
346
447
|
writeStore(records);
|
|
347
448
|
return copyRecord(record);
|
|
@@ -370,6 +471,26 @@ export function releaseDispatchReservationMember(
|
|
|
370
471
|
});
|
|
371
472
|
}
|
|
372
473
|
|
|
474
|
+
/** Settle every member after the scheduler has finished the reserved plan. */
|
|
475
|
+
export function releaseDispatchReservation(ownerId: string, nowMs = Date.now()): DispatchReservationRecord | null {
|
|
476
|
+
return withStateFileLockSync(capacityStateLockPath(), () => {
|
|
477
|
+
const records = readStore();
|
|
478
|
+
const record = records.find((entry) => entry.ownerId === ownerId);
|
|
479
|
+
if (!record) return null;
|
|
480
|
+
if (record.status !== "active") return copyRecord(record);
|
|
481
|
+
const settledAt = new Date(nowMs).toISOString();
|
|
482
|
+
for (const member of record.members) {
|
|
483
|
+
if (member.status === "released") continue;
|
|
484
|
+
member.status = "released";
|
|
485
|
+
member.releasedAt = settledAt;
|
|
486
|
+
}
|
|
487
|
+
record.status = "released";
|
|
488
|
+
record.settledAt = settledAt;
|
|
489
|
+
writeStore(records);
|
|
490
|
+
return copyRecord(record);
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
|
|
373
494
|
export function rollbackDispatchReservation(ownerId: string, nowMs = Date.now()): DispatchReservationRecord | null {
|
|
374
495
|
return withStateFileLockSync(capacityStateLockPath(), () => {
|
|
375
496
|
const records = readStore();
|
|
@@ -488,14 +609,21 @@ export function reservedBudgetUsd(): number {
|
|
|
488
609
|
.reduce((sum, record) => sum + outstandingBudget(record), 0);
|
|
489
610
|
}
|
|
490
611
|
|
|
491
|
-
export function reservedCapacity(): {
|
|
612
|
+
export function reservedCapacity(): {
|
|
613
|
+
globalSlots: number;
|
|
614
|
+
nodeSlots: Readonly<Record<string, number>>;
|
|
615
|
+
endpointSlots: Readonly<Record<string, number>>;
|
|
616
|
+
} {
|
|
492
617
|
let globalSlots = 0;
|
|
493
618
|
const nodeSlots: Record<string, number> = {};
|
|
619
|
+
const endpointSlots: Record<string, number> = {};
|
|
494
620
|
for (const record of readStore().filter((entry) => entry.status === "active")) {
|
|
495
621
|
const allocation = reservationAllocation(outstandingTasks(record));
|
|
496
622
|
globalSlots += allocation.globalSlots;
|
|
497
623
|
for (const [nodeId, count] of Object.entries(allocation.nodeSlots))
|
|
498
624
|
nodeSlots[nodeId] = (nodeSlots[nodeId] ?? 0) + count;
|
|
625
|
+
for (const [endpointKey, count] of Object.entries(allocation.endpointSlots))
|
|
626
|
+
endpointSlots[endpointKey] = (endpointSlots[endpointKey] ?? 0) + count;
|
|
499
627
|
}
|
|
500
|
-
return { globalSlots, nodeSlots };
|
|
628
|
+
return { globalSlots, nodeSlots, endpointSlots };
|
|
501
629
|
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Domain-owned writer for the run event journal.
|
|
3
|
+
*
|
|
4
|
+
* The journal was originally teed from `createDispatchRunEventRegistry`
|
|
5
|
+
* (src/tools/dispatch-run-events.ts), the display-tail helper behind the
|
|
6
|
+
* model-facing `dispatch` tool. That helper is not on the operator paths:
|
|
7
|
+
* `clio-coder run --agent` (src/cli/run.ts), `clio-coder fleet run`
|
|
8
|
+
* (src/cli/fleet.ts), and the TUI `/run` slash command each take a handle
|
|
9
|
+
* straight off `DispatchContract.dispatch` and iterate `handle.events`
|
|
10
|
+
* themselves, so no registry is ever built and the sink never fired. The
|
|
11
|
+
* writer had to move to something every dispatch reaches.
|
|
12
|
+
*
|
|
13
|
+
* `BusChannels.DispatchProgress` is that thing. The dispatch domain publishes
|
|
14
|
+
* it from inside the event pump for every consumer-visible event of every run,
|
|
15
|
+
* "attached, detached, batched, and retry runs, exactly once" (see
|
|
16
|
+
* src/core/bus-events.ts), whether or not anyone iterates the handle. The
|
|
17
|
+
* terminal pair `DispatchCompleted`/`DispatchFailed` closes every run the same
|
|
18
|
+
* way. Subscribing here makes the journal a property of dispatching, not of
|
|
19
|
+
* which caller happened to build a registry.
|
|
20
|
+
*
|
|
21
|
+
* Ownership is explicit rather than ambient: the bridge attaches only when a
|
|
22
|
+
* composition root asks for it (`DispatchBundleOptions.journalRunEvents`), and
|
|
23
|
+
* `registerAllTools` hands its registry `journal: null` in that same process.
|
|
24
|
+
* One writer per file, decided at one place, so a tool-path run in the TUI is
|
|
25
|
+
* not transcribed twice.
|
|
26
|
+
*
|
|
27
|
+
* Every write is best-effort. The sink degrades itself on I/O failure and a
|
|
28
|
+
* listener that throws is contained by the safe bus, so nothing here can fail a
|
|
29
|
+
* dispatch.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
import type {
|
|
33
|
+
DispatchCompletedPayload,
|
|
34
|
+
DispatchFailedPayload,
|
|
35
|
+
DispatchProgressPayload,
|
|
36
|
+
} from "../../core/bus-events.js";
|
|
37
|
+
import { BusChannels } from "../../core/bus-events.js";
|
|
38
|
+
import type { SafeEventBus } from "../../core/event-bus.js";
|
|
39
|
+
import { runTailEntryFromEvent } from "../../tools/dispatch-run-events.js";
|
|
40
|
+
import { defaultRunEventJournal, type RunEventJournalSink } from "./run-event-journal.js";
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Runs whose `open` line this bridge has already written. Bounded so a
|
|
44
|
+
* long-lived orchestrator cannot grow it without limit; the journal writer
|
|
45
|
+
* keeps its own bound for the same reason. Evicting a run only forgets that it
|
|
46
|
+
* was opened, and a later event for it writes a second `open` line, which the
|
|
47
|
+
* reader and the writer both tolerate.
|
|
48
|
+
*/
|
|
49
|
+
const OPENED_RUN_LIMIT = 512;
|
|
50
|
+
|
|
51
|
+
export interface RunEventJournalBridge {
|
|
52
|
+
/** Unsubscribe from the bus. Idempotent. */
|
|
53
|
+
stop(): void;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface AttachRunEventJournalBridgeOptions {
|
|
57
|
+
/** Sink override; defaults to the process-wide journal. */
|
|
58
|
+
journal?: RunEventJournalSink;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
62
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function runIdentity(payload: unknown): { runId: string; agentId: string } | null {
|
|
66
|
+
if (!isRecord(payload)) return null;
|
|
67
|
+
if (typeof payload.runId !== "string" || payload.runId.length === 0) return null;
|
|
68
|
+
return { runId: payload.runId, agentId: typeof payload.agentId === "string" ? payload.agentId : "unknown" };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Subscribe the journal to a dispatch bus. Returns a handle whose `stop()` the
|
|
73
|
+
* owning bundle calls on shutdown so a second bundle in the same process (tests
|
|
74
|
+
* do this) never inherits the first one's listeners.
|
|
75
|
+
*/
|
|
76
|
+
export function attachRunEventJournalBridge(
|
|
77
|
+
bus: SafeEventBus,
|
|
78
|
+
options: AttachRunEventJournalBridgeOptions = {},
|
|
79
|
+
): RunEventJournalBridge {
|
|
80
|
+
const journal = options.journal ?? defaultRunEventJournal();
|
|
81
|
+
const opened = new Set<string>();
|
|
82
|
+
|
|
83
|
+
const ensureOpen = (runId: string, agentId: string): void => {
|
|
84
|
+
if (opened.has(runId)) return;
|
|
85
|
+
opened.add(runId);
|
|
86
|
+
while (opened.size > OPENED_RUN_LIMIT) {
|
|
87
|
+
const oldest = opened.values().next();
|
|
88
|
+
if (oldest.done === true) break;
|
|
89
|
+
opened.delete(oldest.value);
|
|
90
|
+
}
|
|
91
|
+
journal.open(runId, agentId);
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Write the receipt facts and close the run. Read defensively for the same
|
|
96
|
+
* reason the registry's seal is: a terminal payload that is missing a field
|
|
97
|
+
* it is typed to have must degrade the transcript, never throw back into the
|
|
98
|
+
* finalizer that emitted it.
|
|
99
|
+
*/
|
|
100
|
+
const seal = (outcome: string, detail: string | null | undefined, payload: unknown): void => {
|
|
101
|
+
const identity = runIdentity(payload);
|
|
102
|
+
if (identity === null) return;
|
|
103
|
+
ensureOpen(identity.runId, identity.agentId);
|
|
104
|
+
const exitCode = isRecord(payload) && typeof payload.exitCode === "number" ? payload.exitCode : null;
|
|
105
|
+
journal.receipt(identity.runId, { outcome, exitCode });
|
|
106
|
+
journal.terminal(identity.runId, outcome, detail ?? undefined);
|
|
107
|
+
opened.delete(identity.runId);
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const unsubscribes = [
|
|
111
|
+
bus.on(BusChannels.DispatchProgress, (payload: DispatchProgressPayload) => {
|
|
112
|
+
const identity = runIdentity(payload);
|
|
113
|
+
if (identity === null) return;
|
|
114
|
+
// The display projection decides what a transcript line is; a
|
|
115
|
+
// heartbeat or a streaming delta is not one. Opening the run only
|
|
116
|
+
// once an event survives that filter keeps a heartbeat-only run from
|
|
117
|
+
// creating an empty journal directory.
|
|
118
|
+
const entry = runTailEntryFromEvent(payload.event);
|
|
119
|
+
if (entry === null) return;
|
|
120
|
+
ensureOpen(identity.runId, identity.agentId);
|
|
121
|
+
// Route resolution warnings use `message`, while worker transcript
|
|
122
|
+
// events generally project their text through `detail`. Preserve the
|
|
123
|
+
// warning at this dispatch-owned durability seam so fleet view does not
|
|
124
|
+
// render a content-free `route_warning` line.
|
|
125
|
+
const message =
|
|
126
|
+
isRecord(payload.event) && typeof payload.event.message === "string" ? payload.event.message : undefined;
|
|
127
|
+
journal.append(
|
|
128
|
+
identity.runId,
|
|
129
|
+
entry.detail === undefined && message !== undefined ? { ...entry, detail: message } : entry,
|
|
130
|
+
);
|
|
131
|
+
}),
|
|
132
|
+
bus.on(BusChannels.DispatchCompleted, (payload: DispatchCompletedPayload) => {
|
|
133
|
+
seal(payload.outcome, payload.outcomeDetail, payload);
|
|
134
|
+
}),
|
|
135
|
+
bus.on(BusChannels.DispatchFailed, (payload: DispatchFailedPayload) => {
|
|
136
|
+
seal(payload.outcome, payload.outcomeDetail, payload);
|
|
137
|
+
}),
|
|
138
|
+
];
|
|
139
|
+
|
|
140
|
+
let stopped = false;
|
|
141
|
+
return {
|
|
142
|
+
stop(): void {
|
|
143
|
+
if (stopped) return;
|
|
144
|
+
stopped = true;
|
|
145
|
+
for (const unsubscribe of unsubscribes) unsubscribe();
|
|
146
|
+
opened.clear();
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
}
|