@iowarp/clio-coder 0.3.0 → 0.3.2
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 +123 -2
- package/CONTRIBUTING.md +23 -23
- package/README.md +295 -627
- package/dist/acp-BIYHVZIM.js +128 -0
- package/dist/{agents-Q4MYPMUW.js → agents-YT6SSRIT.js} +52 -27
- package/dist/assets/codewiki.json +1 -0
- package/dist/assets/grammars/notices/@vscode__tree-sitter-wasm/LICENSE +21 -0
- package/dist/assets/grammars/notices/@vscode__tree-sitter-wasm/cgmanifest.json +16 -0
- package/dist/assets/grammars/notices/tree-sitter-wasms/LICENSE +24 -0
- package/dist/assets/grammars/tree-sitter-c-sharp.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-c.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-cpp.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-go.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-java.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-javascript.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-python.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-ruby.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-rust.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-tsx.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-typescript.wasm +0 -0
- package/dist/assets/grammars/tree-sitter.wasm +0 -0
- package/dist/{auth-O6HYIJ6J.js → auth-5TWEIYDN.js} +30 -15
- package/dist/chunk-2EHAIA3X.js +481 -0
- package/dist/{chunk-ME6DNWIU.js → chunk-2IR2NMPA.js} +12 -4
- package/dist/chunk-2SFS6XQE.js +122 -0
- package/dist/{chunk-KKKPTZLM.js → chunk-2STGEDFV.js} +8 -1
- package/dist/chunk-2VTFPG5O.js +48 -0
- package/dist/chunk-3I7MS7N2.js +40 -0
- package/dist/chunk-3R73A4XB.js +69 -0
- package/dist/{chunk-JPOWPFCU.js → chunk-3ZXDFGR5.js} +52 -23
- package/dist/chunk-4BJ5BYCE.js +61 -0
- package/dist/{chunk-26BZQOAD.js → chunk-4BPJXDWC.js} +161 -260
- package/dist/chunk-4KLWL3UC.js +18 -0
- package/dist/{chunk-5LDRNKX2.js → chunk-4VP4KH3K.js} +161 -262
- package/dist/chunk-4ZG3XFUR.js +77 -0
- package/dist/chunk-5B2AEOW5.js +5407 -0
- package/dist/chunk-5TSRNF4G.js +510 -0
- package/dist/{chunk-WD6AJM35.js → chunk-5UUP6MWO.js} +48 -69
- package/dist/{chunk-X3BR7HWV.js → chunk-5WIGXA4T.js} +7 -1
- package/dist/chunk-65DEGPJ6.js +52 -0
- package/dist/chunk-6EJMN2Y3.js +17 -0
- package/dist/chunk-6EJV5X2W.js +16405 -0
- package/dist/chunk-6N5PTWMY.js +136 -0
- package/dist/chunk-6XLNIQDB.js +27 -0
- package/dist/{chunk-XNISANGE.js → chunk-77VKQEHF.js} +171 -74
- package/dist/chunk-7CR24IG7.js +242 -0
- package/dist/{chunk-UWIJNAOB.js → chunk-7EYHLWU7.js} +907 -638
- package/dist/chunk-7MNJORFF.js +22 -0
- package/dist/{chunk-JWHCJDCI.js → chunk-A3CYT5EX.js} +257 -79
- package/dist/chunk-AGYYIBLL.js +1069 -0
- package/dist/chunk-AO4RKG4M.js +277 -0
- package/dist/chunk-APJ265NV.js +7410 -0
- package/dist/chunk-ARBGF5F7.js +174 -0
- package/dist/{chunk-TFSSEXL6.js → chunk-BMEMKKIT.js} +14 -4
- package/dist/{chunk-X3NE4WVW.js → chunk-BNAZZHFG.js} +7 -1
- package/dist/chunk-CBCAPZAA.js +229 -0
- package/dist/{chunk-QV47YRF4.js → chunk-CGKSTWHD.js} +7 -1
- package/dist/chunk-CMZWFGD2.js +352 -0
- package/dist/chunk-ECH6PKUQ.js +39 -0
- package/dist/{chunk-67MTHP2E.js → chunk-ED4KHGC3.js} +13 -5
- package/dist/chunk-EKMEHE4H.js +340 -0
- package/dist/{chunk-O4EJEDHO.js → chunk-EPVUXGXG.js} +50 -35
- package/dist/chunk-FCSXB6T2.js +338 -0
- package/dist/chunk-FJ3H4MN5.js +48 -0
- package/dist/chunk-FQ4SKYE4.js +29 -0
- package/dist/chunk-G2DE3C7R.js +644 -0
- package/dist/chunk-G4BMMOKF.js +182 -0
- package/dist/{chunk-7BHLZB3A.js → chunk-GGXXDWE4.js} +190 -1218
- package/dist/chunk-HC4CLZ2Y.js +68 -0
- package/dist/{chunk-E3NYWENM.js → chunk-HFSBBKSQ.js} +55 -61
- package/dist/chunk-HKIYEGME.js +30 -0
- package/dist/chunk-I4HZDVNP.js +73 -0
- package/dist/chunk-IGLFWIYI.js +161 -0
- package/dist/chunk-IHXBNWMM.js +137 -0
- package/dist/chunk-IKCO5N3L.js +162 -0
- package/dist/chunk-IR4CFBFN.js +56 -0
- package/dist/{chunk-DXQNI4PC.js → chunk-IWHMRKLL.js} +8 -1
- package/dist/{chunk-VOO7NYPP.js → chunk-J5HN4RYU.js} +27 -9
- package/dist/{chunk-4UQA7NCT.js → chunk-J5Q24KAG.js} +7 -2
- package/dist/{chunk-KBR4MZZR.js → chunk-JVCV3ICN.js} +7 -1
- package/dist/chunk-KJ5LWLOE.js +1077 -0
- package/dist/chunk-LBMZMYH2.js +285 -0
- package/dist/{chunk-3DANZDGR.js → chunk-LBNRH5WM.js} +100 -161
- package/dist/{chunk-TKHQ4DGZ.js → chunk-LZSJBIVT.js} +7358 -7414
- package/dist/{chunk-UGYAX5YI.js → chunk-M6SHUN7Q.js} +13 -8
- package/dist/chunk-MAW544W2.js +1882 -0
- package/dist/chunk-MBS4V7ZP.js +217 -0
- package/dist/{chunk-2J63S4SF.js → chunk-MFFY33HR.js} +167 -140
- package/dist/chunk-MNA4JGU4.js +255 -0
- package/dist/chunk-MQSRRFWA.js +3428 -0
- package/dist/{chunk-RQDWMVRB.js → chunk-MVVUPGPW.js} +138 -137
- package/dist/chunk-OAO4GE4M.js +619 -0
- package/dist/chunk-OHHN2SO4.js +5135 -0
- package/dist/chunk-OKGUZO2U.js +34 -0
- package/dist/{chunk-BBUH4VAA.js → chunk-OOJYHWRB.js} +60 -361
- package/dist/{chunk-D5YD55AR.js → chunk-OQ33BKR3.js} +12 -1
- package/dist/chunk-OQE5J4C6.js +73 -0
- package/dist/{chunk-AMFR5YA3.js → chunk-ORBHGJC5.js} +26 -12
- package/dist/chunk-POHLU5DW.js +1186 -0
- package/dist/chunk-QKMUKYO7.js +4961 -0
- package/dist/{chunk-7RBKDI66.js → chunk-QTYWRVRA.js} +104 -12
- package/dist/{chunk-5N2FG33Q.js → chunk-R346GLFC.js} +7 -1
- package/dist/chunk-SRF2PJNW.js +184 -0
- package/dist/chunk-SST6Z5JA.js +80 -0
- package/dist/{chunk-XV4ZJ6ZM.js → chunk-STBPMHSX.js} +473 -1194
- package/dist/{chunk-HBU5MTAM.js → chunk-SVNXH4L2.js} +7 -1
- package/dist/chunk-T6YILFSB.js +80 -0
- package/dist/chunk-TXOTCRLG.js +15 -0
- package/dist/chunk-TZTZS7QK.js +227 -0
- package/dist/chunk-UOV2BYIW.js +107 -0
- package/dist/{chunk-527KG6XR.js → chunk-V4RXGQ5Q.js} +72 -185
- package/dist/chunk-VAKQQHWR.js +434 -0
- package/dist/chunk-VG7TBQIY.js +128 -0
- package/dist/chunk-VJWL6YS5.js +244 -0
- package/dist/chunk-WEH5XRJQ.js +32 -0
- package/dist/{chunk-VPAWTYLY.js → chunk-WEPFGWHJ.js} +7 -1
- package/dist/chunk-WMSVI4G2.js +2095 -0
- package/dist/chunk-WVO7V2QY.js +797 -0
- package/dist/chunk-X4RCMKVQ.js +641 -0
- package/dist/chunk-X75S7HFS.js +374 -0
- package/dist/chunk-XN3L4EYL.js +46 -0
- package/dist/{chunk-HMYNFFY4.js → chunk-XPLRXC72.js} +7 -2
- package/dist/{chunk-PIDUD6M2.js → chunk-YCWGATWI.js} +12 -5
- package/dist/chunk-YHZX5GEU.js +193 -0
- package/dist/chunk-YXLYO42X.js +91 -0
- package/dist/{chunk-UHTSULZS.js → chunk-ZDOOVTXZ.js} +38 -73
- package/dist/chunk-ZI647VB5.js +37 -0
- package/dist/{chunk-CLJ5HLUD.js → chunk-ZWLZP4ZT.js} +25 -6
- package/dist/cli/index.js +70 -56
- package/dist/clio-4LY5K2AC.js +25 -0
- package/dist/code-nav-7AX6FYE6.js +600 -0
- package/dist/codewiki/build-worker.js +66 -0
- package/dist/compile-cache-CVJMMODC.js +18 -0
- package/dist/{components-JVHMUBEB.js → components-KELWS457.js} +31 -9
- package/dist/{config-ZFCDBMDC.js → config-GTLUW2PR.js} +104 -56
- package/dist/configure-R6A64DHX.js +42 -0
- package/dist/context-5VKGUVJJ.js +866 -0
- package/dist/{context-CDXTP2MP.js → context-JFZEJ7W5.js} +21 -13
- package/dist/{context-E3KIFVXI.js → context-RW5HC47S.js} +77 -36
- package/dist/{context-clear-3F4PLXOS.js → context-clear-6ZHBAZZT.js} +64 -30
- package/dist/{context-index-Q7YSYTR3.js → context-index-BZ4UYMTC.js} +36 -24
- package/dist/dispatch-runner-VKBRCWQC.js +1997 -0
- package/dist/{docs-YIETIWZI.js → docs-2C2LTVT2.js} +32 -13
- package/dist/doctor-KI767GSN.js +87 -0
- package/dist/{eval-B3KZZESM.js → eval-XSSNATB4.js} +93 -27
- package/dist/{evidence-V67CHM35.js → evidence-UA6AWDQQ.js} +55 -27
- package/dist/{evolve-YDZSUQYA.js → evolve-QNTFGV6Z.js} +59 -26
- package/dist/{extensions-SRG7XCAH.js → extensions-QVDOHDGJ.js} +23 -8
- package/dist/{fleet-CA2CRTVG.js → fleet-Q7UOMUSG.js} +173 -56
- package/dist/fleet-preflight-DDN536IT.js +26 -0
- package/dist/{init-2OZDJE2D.js → init-WBB65ZHQ.js} +79 -34
- package/dist/{memory-3PIQQAKX.js → memory-MD3O64RI.js} +57 -28
- package/dist/{models-DY35XI7Y.js → models-BZU34YWD.js} +49 -24
- package/dist/monitor-MEQA5C3I.js +661 -0
- package/dist/{chunk-PS4PFJQP.js → orchestrator-CGFKEP27.js} +22837 -18564
- package/dist/{paths-5OMXW7Z4.js → paths-UXLN5YYZ.js} +17 -6
- package/dist/preload-P6DGH2PZ.js +13 -0
- package/dist/{reset-PIFYNOS3.js → reset-L2FQEE3E.js} +25 -13
- package/dist/{run-3VSPP24F.js → run-IV4Q6RLN.js} +115 -63
- package/dist/{share-D36RQCXM.js → share-S5BZQC5I.js} +23 -10
- package/dist/{skills-F2MRLELY.js → skills-LQEKRDTN.js} +42 -15
- package/dist/{skills-eval-E2ZTW4PL.js → skills-eval-3DC4HEWS.js} +90 -45
- package/dist/steer-GGWFUJUD.js +77 -0
- package/dist/{targets-DZMEZAH4.js → targets-C4SSGQOB.js} +78 -60
- package/dist/terminal-lease-IT5JW2NR.js +395 -0
- package/dist/{trace-7NYCUI2J.js → trace-PNCASAXC.js} +48 -17
- package/dist/tree-sitter-HGKH6LG4.js +4673 -0
- package/dist/{uninstall-AD3JWHBB.js → uninstall-FZCQCDKC.js} +19 -8
- package/dist/{upgrade-WYYBKGDY.js → upgrade-7TT7SQ3G.js} +66 -24
- package/dist/{usage-ULIDAGFF.js → usage-GV4PKT3M.js} +71 -32
- package/dist/verify-G6V4D2G7.js +716 -0
- package/dist/version-KGEG7EPO.js +21 -0
- package/dist/web-fetch-2YHJ3KTG.js +638 -0
- package/dist/{wiki-generate-PKFIX6OB.js → wiki-generate-DQF6Z66B.js} +98 -48
- package/dist/worker/entry.js +297 -54
- package/dist/workspace-G4ZWUIPR.js +22 -0
- package/docs/README.md +29 -21
- package/docs/acp.md +191 -16
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +157 -7
- package/docs/artifact-placement.md +101 -0
- package/docs/artifact-versions.md +1 -1
- package/docs/built-in-agents.md +4 -2
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +224 -97
- package/docs/config-knobs-audit.md +1 -3
- package/docs/configuration-and-targets.md +236 -38
- package/docs/context-engine.md +34 -7
- package/docs/development-pipeline.md +102 -0
- package/docs/dispatch-architecture-rationale.md +1 -1
- package/docs/documentation-coverage.md +4 -4
- package/docs/documentation-guide.md +3 -3
- package/docs/environment-variables.md +15 -6
- package/docs/eval-runner.md +3 -3
- package/docs/evals-internal.md +2 -2
- package/docs/evidence-and-memory.md +10 -2
- package/docs/evolution.md +2 -2
- package/docs/exit-codes-and-output.md +15 -9
- package/docs/extensions-and-sharing.md +25 -18
- package/docs/fleet-demo-runbook.md +22 -23
- package/docs/fleet-dispatch.md +117 -16
- package/docs/git-commit-provenance.md +120 -0
- package/docs/glossary.md +107 -15
- package/docs/installation-and-lifecycle.md +75 -17
- package/docs/middleware-and-components.md +1 -1
- package/docs/model-catalog.md +46 -15
- package/docs/observability.md +8 -5
- package/docs/performance-methodology.md +491 -0
- package/docs/pi-boundary.md +72 -0
- package/docs/proactive-memory.md +14 -14
- package/docs/prompt-envelope-and-tools.md +25 -4
- package/docs/provider-adapter-cookbook.md +57 -4
- package/docs/release-cut-checklist.md +129 -111
- package/docs/safety-model.md +28 -8
- package/docs/scientific-validation.md +3 -3
- package/docs/session-lifecycle.md +55 -12
- package/docs/skills-marketplace.md +12 -8
- package/docs/time-conventions.md +101 -0
- package/docs/tool-usage.md +6 -5
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +10 -7
- package/docs/tui-design.md +121 -28
- package/docs/worker-dispatch-mechanics.md +3 -3
- package/package.json +33 -36
- package/skills/README.md +5 -6
- package/skills/coding/ast-grep/SKILL.md +136 -0
- package/skills/coding/ast-grep/evals.md +56 -0
- package/skills/coding/ast-grep/references/rule_reference.md +297 -0
- package/skills/coding/coding-standards/SKILL.md +113 -0
- package/skills/coding/coding-standards/evals.md +34 -0
- package/skills/coding/prototype/SKILL.md +86 -0
- package/skills/coding/prototype/evals.md +42 -0
- package/skills/coding/prototype/references/LOGIC.md +67 -0
- package/skills/coding/prototype/references/UI.md +112 -0
- package/skills/coding/tdd/SKILL.md +101 -0
- package/skills/coding/tdd/evals.md +41 -0
- package/skills/coding/tdd/references/mocking.md +59 -0
- package/skills/coding/tdd/references/tests.md +77 -0
- package/skills/context/context-handoff/SKILL.md +126 -0
- package/skills/context/context-handoff/evals.md +57 -0
- package/skills/context/context-handoff/scripts/new-handoff.sh +26 -0
- package/skills/context/context-prime/SKILL.md +95 -0
- package/skills/context/context-prime/evals.md +54 -0
- package/skills/git/file-ticket/SKILL.md +107 -0
- package/skills/git/file-ticket/evals.md +54 -0
- package/skills/git/fix-issue/SKILL.md +106 -0
- package/skills/git/fix-issue/evals.md +71 -0
- package/skills/git/ship/SKILL.md +92 -0
- package/skills/git/ship/evals.md +72 -0
- package/skills/meta/clio-dev/SKILL.md +91 -0
- package/skills/meta/clio-dev/evals.md +45 -0
- package/skills/meta/clio-test/SKILL.md +130 -0
- package/skills/meta/clio-test/evals.md +43 -0
- package/skills/meta/clio-test/references/harness.md +97 -0
- package/skills/meta/clio-test/references/test-map.md +59 -0
- package/skills/meta/credentials/SKILL.md +125 -0
- package/skills/meta/credentials/evals.md +104 -0
- package/skills/meta/find-skills/SKILL.md +72 -0
- package/skills/meta/find-skills/evals.md +47 -0
- package/skills/meta/herdr/SKILL.md +127 -0
- package/skills/meta/herdr/evals.md +38 -0
- package/skills/meta/skill-craft/SKILL.md +102 -0
- package/skills/meta/skill-craft/evals.md +41 -0
- package/skills/planning/architecture/SKILL.md +129 -0
- package/skills/planning/architecture/evals.md +36 -0
- package/skills/planning/backlog/SKILL.md +90 -0
- package/skills/planning/backlog/evals.md +43 -0
- package/skills/planning/prd/SKILL.md +82 -0
- package/skills/planning/prd/evals.md +49 -0
- package/skills/planning/product-intent/SKILL.md +112 -0
- package/skills/planning/product-intent/evals.md +36 -0
- package/skills/planning/tech-spec/SKILL.md +115 -0
- package/skills/planning/tech-spec/evals.md +47 -0
- package/skills/registry.yaml +136 -0
- package/skills/research/arxiv-literature/SKILL.md +104 -0
- package/skills/research/arxiv-literature/evals.md +58 -0
- package/skills/research/experiment-protocol/SKILL.md +122 -0
- package/skills/research/experiment-protocol/evals.md +91 -0
- package/skills/research/scientific-debugging/SKILL.md +119 -0
- package/skills/research/scientific-debugging/evals.md +138 -0
- package/skills/research/scientific-modernization/SKILL.md +138 -0
- package/skills/research/scientific-modernization/evals.md +84 -0
- package/skills/skill-marketplace.json +12 -20
- package/skills/workflow/design-council/SKILL.md +139 -0
- package/skills/workflow/design-council/evals.md +97 -0
- package/skills/workflow/grill-me/SKILL.md +186 -0
- package/skills/workflow/grill-me/evals.md +78 -0
- package/skills/workflow/workflow-distiller/SKILL.md +136 -0
- package/skills/workflow/workflow-distiller/evals.md +107 -0
- package/src/cli/acp.ts +115 -0
- package/src/cli/agents.ts +60 -0
- package/src/cli/args.ts +280 -0
- package/src/cli/argv.ts +170 -0
- package/src/cli/ask.ts +34 -0
- package/src/cli/auth.ts +468 -0
- package/src/cli/bootstrap-generate.ts +498 -0
- package/src/cli/clio.ts +96 -0
- package/src/cli/components.ts +195 -0
- package/src/cli/config-inspect.ts +336 -0
- package/src/cli/config.ts +72 -0
- package/src/cli/configure-interop.ts +67 -0
- package/src/cli/configure-layout.ts +172 -0
- package/src/cli/configure.ts +1525 -0
- package/src/cli/context-clear.ts +76 -0
- package/src/cli/context-index.ts +100 -0
- package/src/cli/context.ts +321 -0
- package/src/cli/default-target.ts +55 -0
- package/src/cli/docs.ts +346 -0
- package/src/cli/doctor.ts +54 -0
- package/src/cli/eval.ts +315 -0
- package/src/cli/evidence.ts +225 -0
- package/src/cli/evolve.ts +219 -0
- package/src/cli/extensions.ts +214 -0
- package/src/cli/fleet.ts +868 -0
- package/src/cli/index.ts +338 -0
- package/src/cli/init.ts +219 -0
- package/src/cli/initial-message.ts +47 -0
- package/src/cli/internal-dispatch.ts +55 -0
- package/src/cli/memory.ts +182 -0
- package/src/cli/models.ts +257 -0
- package/src/cli/modes/json-stream.ts +121 -0
- package/src/cli/modes/jsonl.ts +9 -0
- package/src/cli/modes/print.ts +604 -0
- package/src/cli/oauth-manual-input.ts +72 -0
- package/src/cli/oauth-select.ts +36 -0
- package/src/cli/output-guard.ts +48 -0
- package/src/cli/paths.ts +44 -0
- package/src/cli/provider-target.ts +113 -0
- package/src/cli/removal.ts +72 -0
- package/src/cli/reset.ts +253 -0
- package/src/cli/run.ts +497 -0
- package/src/cli/share.ts +243 -0
- package/src/cli/shared.ts +60 -0
- package/src/cli/skills-eval.ts +1240 -0
- package/src/cli/skills.ts +485 -0
- package/src/cli/steer-channel.ts +86 -0
- package/src/cli/targets.ts +1154 -0
- package/src/cli/text-layout.ts +112 -0
- package/src/cli/trace.ts +322 -0
- package/src/cli/uninstall.ts +405 -0
- package/src/cli/upgrade.ts +286 -0
- package/src/cli/usage.ts +876 -0
- package/src/cli/validate-model.ts +28 -0
- package/src/cli/version.ts +7 -0
- package/src/cli/wiki-generate.ts +510 -0
- package/src/core/agent-environment.ts +7 -0
- package/src/core/artifact-paths.ts +43 -0
- package/src/core/bash-exec.ts +313 -0
- package/src/core/boot-trace.ts +42 -0
- package/src/core/bus-events.ts +744 -0
- package/src/core/bus-trace.ts +53 -0
- package/src/core/c-header-language.ts +265 -0
- package/src/core/clio-repo.ts +78 -0
- package/src/core/commit-attribution.ts +157 -0
- package/src/core/compile-cache.ts +159 -0
- package/src/core/config.ts +1722 -0
- package/src/core/context-floor.ts +33 -0
- package/src/core/defaults.ts +659 -0
- package/src/core/domain-loader.ts +177 -0
- package/src/core/event-bus.ts +94 -0
- package/src/core/file-references.ts +282 -0
- package/src/core/git-commit-attribution.ts +362 -0
- package/src/core/guardrails.ts +185 -0
- package/src/core/headless-permission.ts +21 -0
- package/src/core/incomplete-installation.ts +45 -0
- package/src/core/init.ts +223 -0
- package/src/core/json-payload.ts +58 -0
- package/src/core/package-root.ts +54 -0
- package/src/core/path-canonical.ts +37 -0
- package/src/core/process-identity.ts +41 -0
- package/src/core/recent-models.ts +91 -0
- package/src/core/residency-protection.ts +56 -0
- package/src/core/resolve-config-value.ts +88 -0
- package/src/core/response-schema.ts +279 -0
- package/src/core/run-overrides.ts +77 -0
- package/src/core/safe-exec.ts +205 -0
- package/src/core/safe-id.ts +37 -0
- package/src/core/safe-resource-write.ts +162 -0
- package/src/core/session-routing.ts +339 -0
- package/src/core/settings-layers.ts +354 -0
- package/src/core/shared-bus.ts +8 -0
- package/src/core/shell-quote.ts +26 -0
- package/src/core/skill-activation.ts +190 -0
- package/src/core/startup-timer.ts +37 -0
- package/src/core/state-file-lock.ts +219 -0
- package/src/core/termination.ts +275 -0
- package/src/core/timers.ts +38 -0
- package/src/core/tool-names.ts +65 -0
- package/src/core/verification-scripts.ts +13 -0
- package/src/core/workspace-files.ts +492 -0
- package/src/core/xdg.ts +177 -0
- package/src/domains/agents/builtins/architect.md +4 -4
- package/src/domains/agents/builtins/coder.md +3 -2
- package/src/domains/agents/builtins/debugger.md +1 -1
- package/src/domains/agents/builtins/documenter.md +1 -1
- package/src/domains/agents/builtins/git-master.md +3 -3
- package/src/domains/agents/builtins/provenance.md +1 -1
- package/src/domains/agents/builtins/researcher.md +1 -1
- package/src/domains/agents/builtins/scout.md +1 -1
- package/src/domains/agents/builtins/tester.md +1 -1
- package/src/domains/agents/builtins/verifier.md +1 -1
- package/src/domains/agents/builtins/wiki-writer.md +1 -1
- package/src/domains/agents/catalog.ts +172 -0
- package/src/domains/agents/contract.ts +16 -0
- package/src/domains/agents/extension.ts +110 -0
- package/src/domains/agents/fleet-commands.ts +154 -0
- package/src/domains/agents/fleet-contract.ts +797 -0
- package/src/domains/agents/frontmatter.ts +40 -0
- package/src/domains/agents/index.ts +102 -0
- package/src/domains/agents/manifest.ts +6 -0
- package/src/domains/agents/recipe-schema.ts +202 -0
- package/src/domains/agents/recipe.ts +125 -0
- package/src/domains/agents/registry.ts +111 -0
- package/src/domains/agents/result-contract.ts +1265 -0
- package/src/domains/agents/spec.ts +371 -0
- package/src/domains/agents/write-boundary.ts +109 -0
- package/src/domains/components/diff.ts +99 -0
- package/src/domains/components/hash.ts +21 -0
- package/src/domains/components/index.ts +3 -0
- package/src/domains/components/scan.ts +304 -0
- package/src/domains/components/snapshot.ts +108 -0
- package/src/domains/components/types.ts +82 -0
- package/src/domains/config/agent-namespace.ts +13 -0
- package/src/domains/config/classify.ts +106 -0
- package/src/domains/config/contract.ts +22 -0
- package/src/domains/config/extension.ts +142 -0
- package/src/domains/config/index.ts +23 -0
- package/src/domains/config/keybindings.ts +200 -0
- package/src/domains/config/manifest.ts +6 -0
- package/src/domains/config/watcher.ts +41 -0
- package/src/domains/context/adoption.ts +880 -0
- package/src/domains/context/bootstrap-prompt.ts +273 -0
- package/src/domains/context/bootstrap.ts +1502 -0
- package/src/domains/context/clear.ts +91 -0
- package/src/domains/context/clio-md.ts +429 -0
- package/src/domains/context/codewiki/artifact.ts +400 -0
- package/src/domains/context/codewiki/build-worker-protocol.ts +24 -0
- package/src/domains/context/codewiki/build-worker.ts +54 -0
- package/src/domains/context/codewiki/cmake.ts +356 -0
- package/src/domains/context/codewiki/cooperative.ts +46 -0
- package/src/domains/context/codewiki/coordinator.ts +182 -0
- package/src/domains/context/codewiki/digest.ts +135 -0
- package/src/domains/context/codewiki/grammar-assets.ts +33 -0
- package/src/domains/context/codewiki/indexer.ts +1529 -0
- package/src/domains/context/codewiki/paths.ts +67 -0
- package/src/domains/context/codewiki/schema.ts +80 -0
- package/src/domains/context/codewiki/tree-sitter.ts +771 -0
- package/src/domains/context/contract.ts +68 -0
- package/src/domains/context/excluded-dirs.ts +1 -0
- package/src/domains/context/extension.ts +358 -0
- package/src/domains/context/fingerprint.ts +198 -0
- package/src/domains/context/index.ts +154 -0
- package/src/domains/context/init-options.ts +69 -0
- package/src/domains/context/manifest.ts +6 -0
- package/src/domains/context/operator-profile.ts +157 -0
- package/src/domains/context/project-metadata.ts +529 -0
- package/src/domains/context/project-rules.ts +227 -0
- package/src/domains/context/prompt-context.ts +61 -0
- package/src/domains/context/refresh.ts +178 -0
- package/src/domains/context/runtime.ts +17 -0
- package/src/domains/context/sibling-files.ts +10 -0
- package/src/domains/context/state.ts +237 -0
- package/src/domains/context/wiki/assemble.ts +303 -0
- package/src/domains/context/wiki/frontmatter.ts +210 -0
- package/src/domains/context/wiki/generate.ts +595 -0
- package/src/domains/context/wiki/layout.ts +111 -0
- package/src/domains/context/wiki/meta.ts +221 -0
- package/src/domains/context/wiki/plan-store.ts +217 -0
- package/src/domains/context/wiki/plan.ts +250 -0
- package/src/domains/context/wiki/prompts.ts +283 -0
- package/src/domains/context/wiki/staleness.ts +198 -0
- package/src/domains/dispatch/active-route-planner.ts +168 -0
- package/src/domains/dispatch/admission-queue.ts +150 -0
- package/src/domains/dispatch/admission.ts +334 -0
- package/src/domains/dispatch/agent-candidates.ts +307 -0
- package/src/domains/dispatch/agent-ledger-hub.ts +71 -0
- package/src/domains/dispatch/agent-ledger-store.ts +257 -0
- package/src/domains/dispatch/agent-ledger.ts +212 -0
- package/src/domains/dispatch/agent-plan-adapter.ts +85 -0
- package/src/domains/dispatch/assignment-events.ts +132 -0
- package/src/domains/dispatch/assignment-reconcile.ts +76 -0
- package/src/domains/dispatch/assignment-store.ts +162 -0
- package/src/domains/dispatch/assignment.ts +278 -0
- package/src/domains/dispatch/backoff.ts +59 -0
- package/src/domains/dispatch/batch-store.ts +134 -0
- package/src/domains/dispatch/batch-tracker.ts +66 -0
- package/src/domains/dispatch/capability-match.ts +155 -0
- package/src/domains/dispatch/capacity-lease.ts +413 -0
- package/src/domains/dispatch/code-step-store.ts +52 -0
- package/src/domains/dispatch/code-step.ts +387 -0
- package/src/domains/dispatch/contract.ts +278 -0
- package/src/domains/dispatch/dedup.ts +133 -0
- package/src/domains/dispatch/event-pump.ts +251 -0
- package/src/domains/dispatch/execution-handoff.ts +29 -0
- package/src/domains/dispatch/execution-plan.ts +328 -0
- package/src/domains/dispatch/execution-role.ts +277 -0
- package/src/domains/dispatch/execution-scheduler.ts +583 -0
- package/src/domains/dispatch/extension.ts +6006 -0
- package/src/domains/dispatch/failure-classification.ts +147 -0
- package/src/domains/dispatch/fleet-commit-attribution.ts +56 -0
- package/src/domains/dispatch/fleet-plan.ts +225 -0
- package/src/domains/dispatch/fleet-preflight.ts +394 -0
- package/src/domains/dispatch/gate-decisions.ts +1040 -0
- package/src/domains/dispatch/gate-role-prompts.ts +58 -0
- package/src/domains/dispatch/heartbeat.ts +27 -0
- package/src/domains/dispatch/index.ts +137 -0
- package/src/domains/dispatch/joint-route-adapter.ts +114 -0
- package/src/domains/dispatch/joint-route-resolver.ts +283 -0
- package/src/domains/dispatch/manifest.ts +6 -0
- package/src/domains/dispatch/orphan-recovery.ts +266 -0
- package/src/domains/dispatch/outcome.ts +109 -0
- package/src/domains/dispatch/phase-timing.ts +47 -0
- package/src/domains/dispatch/placement.ts +202 -0
- package/src/domains/dispatch/receipt-findings.ts +255 -0
- package/src/domains/dispatch/receipt-integrity.ts +383 -0
- package/src/domains/dispatch/recovery-candidates.ts +74 -0
- package/src/domains/dispatch/reproducibility.ts +48 -0
- package/src/domains/dispatch/reservation-store.ts +501 -0
- package/src/domains/dispatch/route-approval.ts +177 -0
- package/src/domains/dispatch/route-candidates.ts +57 -0
- package/src/domains/dispatch/route-decision.ts +1079 -0
- package/src/domains/dispatch/route-facts.ts +187 -0
- package/src/domains/dispatch/route-history.ts +238 -0
- package/src/domains/dispatch/route-observer.ts +488 -0
- package/src/domains/dispatch/route-policy.ts +327 -0
- package/src/domains/dispatch/route-quality.ts +256 -0
- package/src/domains/dispatch/route-readiness.ts +120 -0
- package/src/domains/dispatch/routing-intent.ts +287 -0
- package/src/domains/dispatch/run-identity.ts +56 -0
- package/src/domains/dispatch/scout-transition.ts +130 -0
- package/src/domains/dispatch/state.ts +302 -0
- package/src/domains/dispatch/tool-stats.ts +132 -0
- package/src/domains/dispatch/transport.ts +210 -0
- package/src/domains/dispatch/types.ts +799 -0
- package/src/domains/dispatch/validation-grounding.ts +154 -0
- package/src/domains/dispatch/validation.ts +721 -0
- package/src/domains/dispatch/worker-protocol.ts +275 -0
- package/src/domains/dispatch/worker-spawn.ts +585 -0
- package/src/domains/dispatch/write-boundary-enforcer.ts +97 -0
- package/src/domains/dispatch/write-boundary.ts +426 -0
- package/src/domains/eval/artifacts/redact.ts +42 -0
- package/src/domains/eval/artifacts/store.ts +173 -0
- package/src/domains/eval/compare/compare.ts +33 -0
- package/src/domains/eval/compare/gates.ts +66 -0
- package/src/domains/eval/compare/thresholds.ts +92 -0
- package/src/domains/eval/harness-metrics.ts +62 -0
- package/src/domains/eval/index.ts +66 -0
- package/src/domains/eval/metrics/chaos-stream.ts +93 -0
- package/src/domains/eval/metrics/context.ts +34 -0
- package/src/domains/eval/metrics/coverage.ts +21 -0
- package/src/domains/eval/metrics/evidence.ts +182 -0
- package/src/domains/eval/metrics/fleet-loop-stream.ts +196 -0
- package/src/domains/eval/metrics/invariants.ts +736 -0
- package/src/domains/eval/metrics/latency.ts +4 -0
- package/src/domains/eval/metrics/token-stream.ts +139 -0
- package/src/domains/eval/metrics/tokens.ts +51 -0
- package/src/domains/eval/metrics/tool-calls.ts +7 -0
- package/src/domains/eval/proactive-memory.ts +279 -0
- package/src/domains/eval/provenance.ts +35 -0
- package/src/domains/eval/report.ts +234 -0
- package/src/domains/eval/reports/json.ts +5 -0
- package/src/domains/eval/reports/junit.ts +23 -0
- package/src/domains/eval/reports/markdown.ts +20 -0
- package/src/domains/eval/reports/swe-jsonl.ts +16 -0
- package/src/domains/eval/reports/text.ts +25 -0
- package/src/domains/eval/run-compare.ts +274 -0
- package/src/domains/eval/runner.ts +244 -0
- package/src/domains/eval/runners/clio-run.ts +148 -0
- package/src/domains/eval/runners/context-index.ts +56 -0
- package/src/domains/eval/runners/context-init.ts +203 -0
- package/src/domains/eval/runners/external-command.ts +350 -0
- package/src/domains/eval/runtime-paths.ts +171 -0
- package/src/domains/eval/schema/artifact.ts +75 -0
- package/src/domains/eval/schema/suite.ts +235 -0
- package/src/domains/eval/schema/validate.ts +339 -0
- package/src/domains/eval/store.ts +392 -0
- package/src/domains/eval/suites/load.ts +74 -0
- package/src/domains/eval/suites/matrix.ts +19 -0
- package/src/domains/eval/suites/resolve.ts +44 -0
- package/src/domains/eval/suites/run.ts +325 -0
- package/src/domains/eval/task-file.ts +186 -0
- package/src/domains/eval/types.ts +140 -0
- package/src/domains/eval/verifiers/command.ts +27 -0
- package/src/domains/eval/verifiers/file-exists.ts +6 -0
- package/src/domains/eval/verifiers/patch.ts +22 -0
- package/src/domains/eval/workspaces/git.ts +41 -0
- package/src/domains/eval/workspaces/local.ts +17 -0
- package/src/domains/eval/workspaces/temp-copy.ts +29 -0
- package/src/domains/evidence/build.ts +1754 -0
- package/src/domains/evidence/eval.ts +605 -0
- package/src/domains/evidence/failure-attribution.ts +54 -0
- package/src/domains/evidence/finish-contract-map.ts +42 -0
- package/src/domains/evidence/index.ts +55 -0
- package/src/domains/evidence/provenance.ts +200 -0
- package/src/domains/evidence/redact.ts +81 -0
- package/src/domains/evidence/store.ts +291 -0
- package/src/domains/evidence/types.ts +325 -0
- package/src/domains/evolution/SELF_EDIT_GATE.md +91 -0
- package/src/domains/evolution/index.ts +26 -0
- package/src/domains/evolution/manifest.ts +154 -0
- package/src/domains/evolution/validate.ts +304 -0
- package/src/domains/extensions/contract.ts +22 -0
- package/src/domains/extensions/discovery.ts +193 -0
- package/src/domains/extensions/extension.ts +46 -0
- package/src/domains/extensions/index.ts +34 -0
- package/src/domains/extensions/manager.ts +30 -0
- package/src/domains/extensions/manifest.ts +6 -0
- package/src/domains/extensions/resources.ts +38 -0
- package/src/domains/extensions/state.ts +224 -0
- package/src/domains/extensions/types.ts +83 -0
- package/src/domains/interop/consent.ts +185 -0
- package/src/domains/interop/contract.ts +29 -0
- package/src/domains/interop/detect.ts +173 -0
- package/src/domains/interop/extension.ts +59 -0
- package/src/domains/interop/index.ts +34 -0
- package/src/domains/interop/manifest.ts +6 -0
- package/src/domains/interop/registry.ts +139 -0
- package/src/domains/interop/state.ts +92 -0
- package/src/domains/interop/types.ts +109 -0
- package/src/domains/lifecycle/contract.ts +11 -0
- package/src/domains/lifecycle/doctor.ts +536 -0
- package/src/domains/lifecycle/extension.ts +23 -0
- package/src/domains/lifecycle/index.ts +21 -0
- package/src/domains/lifecycle/install-method.ts +51 -0
- package/src/domains/lifecycle/manifest.ts +6 -0
- package/src/domains/lifecycle/migrations/2026-08-18-lmstudio-runtime-id.ts +52 -0
- package/src/domains/lifecycle/migrations/index.ts +114 -0
- package/src/domains/lifecycle/state.ts +93 -0
- package/src/domains/lifecycle/upgrade-notice.ts +35 -0
- package/src/domains/lifecycle/version.ts +35 -0
- package/src/domains/memory/index.ts +128 -0
- package/src/domains/memory/operations.ts +143 -0
- package/src/domains/memory/prompt-section.ts +86 -0
- package/src/domains/memory/proposal.ts +180 -0
- package/src/domains/memory/store.ts +163 -0
- package/src/domains/memory/task-bank.ts +229 -0
- package/src/domains/memory/task-memory-handoff.ts +222 -0
- package/src/domains/memory/task-memory-policy.ts +602 -0
- package/src/domains/memory/task-memory-status.ts +58 -0
- package/src/domains/memory/task-memory-telemetry.ts +346 -0
- package/src/domains/memory/task-memory-trace.ts +89 -0
- package/src/domains/memory/types.ts +74 -0
- package/src/domains/memory/validate.ts +297 -0
- package/src/domains/middleware/budget.ts +216 -0
- package/src/domains/middleware/contract.ts +35 -0
- package/src/domains/middleware/dispatch-nudge.ts +469 -0
- package/src/domains/middleware/extension.ts +129 -0
- package/src/domains/middleware/hook-receipts.ts +70 -0
- package/src/domains/middleware/hooks-io.ts +186 -0
- package/src/domains/middleware/hooks.ts +432 -0
- package/src/domains/middleware/index.ts +154 -0
- package/src/domains/middleware/manifest.ts +6 -0
- package/src/domains/middleware/memory-intervention.ts +701 -0
- package/src/domains/middleware/rules.ts +42 -0
- package/src/domains/middleware/runtime.ts +333 -0
- package/src/domains/middleware/skills-reminder.ts +202 -0
- package/src/domains/middleware/snapshot.ts +71 -0
- package/src/domains/middleware/stalled-turn.ts +71 -0
- package/src/domains/middleware/task-board-reminder.ts +87 -0
- package/src/domains/middleware/task-nudge.ts +77 -0
- package/src/domains/middleware/tool-choice-control.ts +42 -0
- package/src/domains/middleware/types.ts +131 -0
- package/src/domains/middleware/validate.ts +329 -0
- package/src/domains/observability/accountability.ts +67 -0
- package/src/domains/observability/contract.ts +168 -0
- package/src/domains/observability/cost.ts +206 -0
- package/src/domains/observability/evidence-index.ts +123 -0
- package/src/domains/observability/extension.ts +281 -0
- package/src/domains/observability/index.ts +78 -0
- package/src/domains/observability/manifest.ts +10 -0
- package/src/domains/observability/metrics.ts +37 -0
- package/src/domains/observability/projection.ts +477 -0
- package/src/domains/observability/telemetry.ts +89 -0
- package/src/domains/observability/trace-store.ts +1454 -0
- package/src/domains/prompts/compiler.ts +614 -0
- package/src/domains/prompts/contract.ts +46 -0
- package/src/domains/prompts/extension.ts +336 -0
- package/src/domains/prompts/fragment-loader.ts +138 -0
- package/src/domains/prompts/fragments/identity/clio.md +5 -6
- package/src/domains/prompts/fragments/identity/docs-routing.md +10 -0
- package/src/domains/prompts/fragments/identity/self-awareness.md +19 -0
- package/src/domains/prompts/fragments/operating/contract.md +4 -41
- package/src/domains/prompts/fragments/operating/delegation.md +42 -0
- package/src/domains/prompts/fragments/operating/skills.md +26 -0
- package/src/domains/prompts/fragments/operating/worker.md +16 -0
- package/src/domains/prompts/fragments/safety/auto-edit.md +5 -5
- package/src/domains/prompts/fragments/safety/full-auto.md +3 -3
- package/src/domains/prompts/fragments/safety/read-only.md +4 -4
- package/src/domains/prompts/fragments/safety/suggest.md +2 -2
- package/src/domains/prompts/fragments/wiki/page.md +10 -0
- package/src/domains/prompts/fragments/wiki/plan.md +10 -0
- package/src/domains/prompts/hash.ts +73 -0
- package/src/domains/prompts/index.ts +32 -0
- package/src/domains/prompts/manifest.ts +8 -0
- package/src/domains/prompts/memory-intervention.ts +57 -0
- package/src/domains/prompts/preload.ts +82 -0
- package/src/domains/providers/auth/api-key.ts +47 -0
- package/src/domains/providers/auth/backend-file.ts +79 -0
- package/src/domains/providers/auth/backend-memory.ts +72 -0
- package/src/domains/providers/auth/boot-status.ts +65 -0
- package/src/domains/providers/auth/index.ts +37 -0
- package/src/domains/providers/auth/oauth.ts +37 -0
- package/src/domains/providers/auth/storage.ts +726 -0
- package/src/domains/providers/capabilities.ts +58 -0
- package/src/domains/providers/catalog.ts +162 -0
- package/src/domains/providers/contract.ts +162 -0
- package/src/domains/providers/credentials.ts +20 -0
- package/src/domains/providers/eligibility.ts +24 -0
- package/src/domains/providers/errors.ts +64 -0
- package/src/domains/providers/extension.ts +548 -0
- package/src/domains/providers/index.ts +142 -0
- package/src/domains/providers/knowledge-base-path.ts +102 -0
- package/src/domains/providers/manifest.ts +6 -0
- package/src/domains/providers/model-capabilities.ts +136 -0
- package/src/domains/providers/model-discovery.ts +144 -0
- package/src/domains/providers/model-family.ts +32 -0
- package/src/domains/providers/model-runtime-capabilities.ts +723 -0
- package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +120 -37
- package/src/domains/providers/plugins.ts +61 -0
- package/src/domains/providers/probe/fingerprint.ts +64 -0
- package/src/domains/providers/probe/http.ts +114 -0
- package/src/domains/providers/probe/reasoning.ts +111 -0
- package/src/domains/providers/registry.ts +187 -0
- package/src/domains/providers/resolver.ts +156 -0
- package/src/domains/providers/runtime-resolution.ts +720 -0
- package/src/domains/providers/runtimes/antigravity/antigravity-code.ts +90 -0
- package/src/domains/providers/runtimes/boot-manifest.ts +55 -0
- package/src/domains/providers/runtimes/builtins.ts +78 -0
- package/src/domains/providers/runtimes/claude/claude-code.ts +38 -0
- package/src/domains/providers/runtimes/claude/claude-sdk.ts +38 -0
- package/src/domains/providers/runtimes/claude/common.ts +55 -0
- package/src/domains/providers/runtimes/cloud/alcf.ts +171 -0
- package/src/domains/providers/runtimes/cloud/anthropic-max.ts +71 -0
- package/src/domains/providers/runtimes/cloud/anthropic.ts +43 -0
- package/src/domains/providers/runtimes/cloud/bedrock.ts +35 -0
- package/src/domains/providers/runtimes/cloud/deepseek.ts +50 -0
- package/src/domains/providers/runtimes/cloud/google.ts +41 -0
- package/src/domains/providers/runtimes/cloud/groq.ts +46 -0
- package/src/domains/providers/runtimes/cloud/mistral.ts +46 -0
- package/src/domains/providers/runtimes/cloud/openai-codex.ts +49 -0
- package/src/domains/providers/runtimes/cloud/openai.ts +46 -0
- package/src/domains/providers/runtimes/cloud/openrouter.ts +111 -0
- package/src/domains/providers/runtimes/common/lmstudio-http.ts +423 -0
- package/src/domains/providers/runtimes/common/local-synth.ts +164 -0
- package/src/domains/providers/runtimes/common/probe-helpers.ts +474 -0
- package/src/domains/providers/runtimes/local-native/lemonade-anthropic.ts +27 -0
- package/src/domains/providers/runtimes/local-native/lemonade-openai.ts +26 -0
- package/src/domains/providers/runtimes/local-native/llamacpp-anthropic.ts +88 -0
- package/src/domains/providers/runtimes/local-native/llamacpp-completion.ts +207 -0
- package/src/domains/providers/runtimes/local-native/llamacpp-embed.ts +180 -0
- package/src/domains/providers/runtimes/local-native/llamacpp-rerank.ts +126 -0
- package/src/domains/providers/runtimes/local-native/llamacpp.ts +98 -0
- package/src/domains/providers/runtimes/local-native/lmstudio.ts +241 -0
- package/src/domains/providers/runtimes/local-native/ollama-native.ts +117 -0
- package/src/domains/providers/runtimes/local-native/sglang.ts +26 -0
- package/src/domains/providers/runtimes/local-native/vllm.ts +27 -0
- package/src/domains/providers/runtimes/protocol/anthropic-compat.ts +104 -0
- package/src/domains/providers/runtimes/protocol/anthropic-messages.ts +28 -0
- package/src/domains/providers/runtimes/protocol/bedrock.ts +26 -0
- package/src/domains/providers/runtimes/protocol/google.ts +27 -0
- package/src/domains/providers/runtimes/protocol/openai-compat.ts +145 -0
- package/src/domains/providers/support.ts +241 -0
- package/src/domains/providers/thinking-control-policy.ts +85 -0
- package/src/domains/providers/types/capability-flags.ts +114 -0
- package/src/domains/providers/types/cost-provenance.ts +7 -0
- package/src/domains/providers/types/inference.ts +41 -0
- package/src/domains/providers/types/knowledge-base.ts +156 -0
- package/src/domains/providers/types/local-model-quirks.ts +216 -0
- package/src/domains/providers/types/runtime-descriptor.ts +181 -0
- package/src/domains/providers/types/target-descriptor.ts +60 -0
- package/src/domains/resources/collision.ts +92 -0
- package/src/domains/resources/common-loader.ts +140 -0
- package/src/domains/resources/contract.ts +24 -0
- package/src/domains/resources/extension.ts +59 -0
- package/src/domains/resources/index.ts +74 -0
- package/src/domains/resources/loader.ts +85 -0
- package/src/domains/resources/manifest.ts +6 -0
- package/src/domains/resources/prompts/loader.ts +246 -0
- package/src/domains/resources/prompts/substitute.ts +1 -0
- package/src/domains/resources/skills/content-hash.ts +107 -0
- package/src/domains/resources/skills/evals.ts +175 -0
- package/src/domains/resources/skills/install.ts +427 -0
- package/src/domains/resources/skills/loader.ts +985 -0
- package/src/domains/resources/skills/marketplace.ts +301 -0
- package/src/domains/resources/skills/provenance-pin.ts +115 -0
- package/src/domains/safety/action-classifier.ts +270 -0
- package/src/domains/safety/approval-axis.ts +23 -0
- package/src/domains/safety/audit.ts +493 -0
- package/src/domains/safety/autonomy.ts +174 -0
- package/src/domains/safety/call-target.ts +59 -0
- package/src/domains/safety/contract.ts +65 -0
- package/src/domains/safety/damage-control.ts +44 -0
- package/src/domains/safety/default-path-policy.ts +117 -0
- package/src/domains/safety/extension.ts +383 -0
- package/src/domains/safety/finish-contract-registration.ts +128 -0
- package/src/domains/safety/finish-contract.ts +554 -0
- package/src/domains/safety/index.ts +44 -0
- package/src/domains/safety/loop-detector.ts +143 -0
- package/src/domains/safety/manifest.ts +6 -0
- package/src/domains/safety/path-policy.ts +164 -0
- package/src/domains/safety/policy-engine.ts +994 -0
- package/src/domains/safety/project-policy.ts +391 -0
- package/src/domains/safety/protected-artifacts-registration.ts +189 -0
- package/src/domains/safety/protected-artifacts.ts +993 -0
- package/src/domains/safety/rejection-feedback.ts +102 -0
- package/src/domains/safety/rigor.ts +72 -0
- package/src/domains/safety/rule-compiler.ts +48 -0
- package/src/domains/safety/rule-pack-loader.ts +92 -0
- package/src/domains/safety/run-effects.ts +197 -0
- package/src/domains/safety/scope.ts +61 -0
- package/src/domains/scheduling/budget.ts +35 -0
- package/src/domains/scheduling/cluster.ts +175 -0
- package/src/domains/scheduling/contract.ts +30 -0
- package/src/domains/scheduling/extension.ts +91 -0
- package/src/domains/scheduling/index.ts +12 -0
- package/src/domains/scheduling/manifest.ts +6 -0
- package/src/domains/session/archive-readers.ts +208 -0
- package/src/domains/session/checkpoint.ts +38 -0
- package/src/domains/session/compaction/auto.ts +89 -0
- package/src/domains/session/compaction/branch-summary.ts +187 -0
- package/src/domains/session/compaction/compact.ts +493 -0
- package/src/domains/session/compaction/cut-point.ts +172 -0
- package/src/domains/session/compaction/defaults.ts +34 -0
- package/src/domains/session/compaction/mask-observations.ts +265 -0
- package/src/domains/session/compaction/session-entries.ts +18 -0
- package/src/domains/session/compaction/tokens.ts +148 -0
- package/src/domains/session/context-accounting.ts +583 -0
- package/src/domains/session/context-ledger.ts +362 -0
- package/src/domains/session/contract.ts +159 -0
- package/src/domains/session/cwd-fallback.ts +65 -0
- package/src/domains/session/decision-board.ts +190 -0
- package/src/domains/session/entries.ts +572 -0
- package/src/domains/session/extension.ts +403 -0
- package/src/domains/session/history.ts +172 -0
- package/src/domains/session/index.ts +84 -0
- package/src/domains/session/manager.ts +128 -0
- package/src/domains/session/manifest.ts +6 -0
- package/src/domains/session/migrations/index.ts +27 -0
- package/src/domains/session/prompt-manifest.ts +173 -0
- package/src/domains/session/protected-artifact-journal.ts +241 -0
- package/src/domains/session/protected-artifacts.ts +90 -0
- package/src/domains/session/retry.ts +230 -0
- package/src/domains/session/session-artifacts.ts +107 -0
- package/src/domains/session/task-board.ts +569 -0
- package/src/domains/session/tree/active-path.ts +137 -0
- package/src/domains/session/tree/fork.ts +159 -0
- package/src/domains/session/tree/manager.ts +128 -0
- package/src/domains/session/tree/navigator.ts +177 -0
- package/src/domains/session/tree/preview.ts +259 -0
- package/src/domains/session/usage.ts +148 -0
- package/src/domains/session/workspace/git-probe.ts +167 -0
- package/src/domains/session/workspace/index.ts +4 -0
- package/src/domains/session/workspace/project-type.ts +217 -0
- package/src/domains/session/workspace/snapshot.ts +74 -0
- package/src/domains/share/archive.ts +684 -0
- package/src/domains/share/contract.ts +9 -0
- package/src/domains/share/extension.ts +26 -0
- package/src/domains/share/index.ts +28 -0
- package/src/domains/share/manifest.ts +6 -0
- package/src/domains/user-tasks/store.ts +297 -0
- package/src/engine/acp/adapter.ts +397 -0
- package/src/engine/acp/errors.ts +128 -0
- package/src/engine/acp/event-mapper.ts +154 -0
- package/src/engine/acp/server.ts +2238 -0
- package/src/engine/acp/tool-mediator.ts +686 -0
- package/src/engine/acp/transport.ts +775 -0
- package/src/engine/acp/types.ts +196 -0
- package/src/engine/agent.ts +29 -0
- package/src/engine/ai.ts +207 -0
- package/src/engine/alcf-oauth.ts +205 -0
- package/src/engine/antigravity/subprocess-runtime.ts +205 -0
- package/src/engine/api-registry.ts +223 -0
- package/src/engine/apis/degraded-inference.ts +95 -0
- package/src/engine/apis/index.ts +16 -0
- package/src/engine/apis/llamacpp-residency.ts +292 -0
- package/src/engine/apis/lmstudio-residency.ts +76 -0
- package/src/engine/apis/lmstudio.ts +243 -0
- package/src/engine/apis/ollama-native.ts +528 -0
- package/src/engine/apis/openai-completions.ts +795 -0
- package/src/engine/apis/output-budget.ts +99 -0
- package/src/engine/apis/residency-lock.ts +29 -0
- package/src/engine/apis/residency.ts +776 -0
- package/src/engine/apis/resident-models.ts +42 -0
- package/src/engine/apis/sampling-overrides.ts +38 -0
- package/src/engine/apis/types.ts +16 -0
- package/src/engine/claude/sdk-runtime.ts +685 -0
- package/src/engine/claude/session-id.ts +5 -0
- package/src/engine/claude/subprocess-runtime.ts +316 -0
- package/src/engine/claude/tool-safety.ts +400 -0
- package/src/engine/env-api-keys.ts +98 -0
- package/src/engine/external-subprocess.ts +23 -0
- package/src/engine/gemma-channel-filter.ts +223 -0
- package/src/engine/harmony-response.ts +165 -0
- package/src/engine/instrumented-tui.ts +192 -0
- package/src/engine/loop-guard.ts +1127 -0
- package/src/engine/messages.ts +14 -0
- package/src/engine/models.ts +42 -0
- package/src/engine/oauth.ts +196 -0
- package/src/engine/pi-mono-names.ts +13 -0
- package/src/engine/prompt-templates.ts +1 -0
- package/src/engine/provider-payload.ts +272 -0
- package/src/engine/select-list.ts +53 -0
- package/src/engine/session.ts +834 -0
- package/src/engine/strip-tokenizer-sentinels.ts +125 -0
- package/src/engine/truncate.ts +9 -0
- package/src/engine/tui.ts +111 -0
- package/src/engine/types.ts +63 -0
- package/src/engine/worker-events.ts +100 -0
- package/src/engine/worker-runtime-capabilities.ts +5 -0
- package/src/engine/worker-runtime.ts +1022 -0
- package/src/engine/worker-tools.ts +208 -0
- package/src/entry/boot-options.ts +50 -0
- package/src/entry/orchestrator.ts +2011 -0
- package/src/interactive/application-controller.ts +433 -0
- package/src/interactive/bus-notices.ts +265 -0
- package/src/interactive/chat-loop-messages.ts +626 -0
- package/src/interactive/chat-loop-policy.ts +18 -0
- package/src/interactive/chat-loop.ts +1090 -0
- package/src/interactive/chat-panel.ts +1820 -0
- package/src/interactive/chat-renderer.ts +1228 -0
- package/src/interactive/clio-editor.ts +161 -0
- package/src/interactive/command-fallbacks.ts +23 -0
- package/src/interactive/command-output.ts +85 -0
- package/src/interactive/context-activity.ts +203 -0
- package/src/interactive/context-meter.ts +223 -0
- package/src/interactive/context-overlay.ts +246 -0
- package/src/interactive/cost-overlay.ts +279 -0
- package/src/interactive/dispatch-board.ts +1319 -0
- package/src/interactive/dispatch-steering.ts +86 -0
- package/src/interactive/editor-bash.ts +46 -0
- package/src/interactive/editor-steer.ts +51 -0
- package/src/interactive/editor-submit.ts +507 -0
- package/src/interactive/export-html/ansi-to-html.ts +161 -0
- package/src/interactive/export-html/index.ts +51 -0
- package/src/interactive/export-html/template.ts +45 -0
- package/src/interactive/export-html/tool-renderer.ts +54 -0
- package/src/interactive/external-editor.ts +67 -0
- package/src/interactive/follow-up-queue-panel.ts +75 -0
- package/src/interactive/footer/dashboard.ts +538 -0
- package/src/interactive/footer/notifications.ts +275 -0
- package/src/interactive/footer/widgets.ts +1264 -0
- package/src/interactive/footer-panel.ts +187 -0
- package/src/interactive/format-time.ts +97 -0
- package/src/interactive/index.ts +11 -0
- package/src/interactive/interactive-application.ts +939 -0
- package/src/interactive/interactive-event-projection.ts +385 -0
- package/src/interactive/interactive-input-runtime.ts +307 -0
- package/src/interactive/interactive-presentation.ts +584 -0
- package/src/interactive/interactive-shell.ts +388 -0
- package/src/interactive/interactive-slash-runtime.ts +554 -0
- package/src/interactive/interactive-subscriptions.ts +111 -0
- package/src/interactive/interactive-tickers.ts +183 -0
- package/src/interactive/keybinding-manager.ts +496 -0
- package/src/interactive/layout.ts +57 -0
- package/src/interactive/leader-key.ts +143 -0
- package/src/interactive/loop-guard-interrupt.ts +101 -0
- package/src/interactive/memory-overlay.ts +280 -0
- package/src/interactive/overlay-ask-user-lifecycle.ts +110 -0
- package/src/interactive/overlay-auth-lifecycle.ts +308 -0
- package/src/interactive/overlay-frame.ts +502 -0
- package/src/interactive/overlay-general-openers.ts +274 -0
- package/src/interactive/overlay-key-routing.ts +216 -0
- package/src/interactive/overlay-lifecycle.ts +426 -0
- package/src/interactive/overlay-model-selectors.ts +127 -0
- package/src/interactive/overlay-permission-lifecycle.ts +345 -0
- package/src/interactive/overlay-resource-openers.ts +112 -0
- package/src/interactive/overlay-session-lifecycle.ts +327 -0
- package/src/interactive/overlay-transitions.ts +57 -0
- package/src/interactive/overlays/agents.ts +69 -0
- package/src/interactive/overlays/ask-user.ts +921 -0
- package/src/interactive/overlays/auth-dialog.ts +221 -0
- package/src/interactive/overlays/context-reset.ts +108 -0
- package/src/interactive/overlays/cwd-fallback.ts +141 -0
- package/src/interactive/overlays/decisions.ts +300 -0
- package/src/interactive/overlays/extensions.ts +54 -0
- package/src/interactive/overlays/help-reference.ts +145 -0
- package/src/interactive/overlays/interop.ts +139 -0
- package/src/interactive/overlays/keybinding-detail.ts +90 -0
- package/src/interactive/overlays/list-overlay.ts +606 -0
- package/src/interactive/overlays/message-picker.ts +155 -0
- package/src/interactive/overlays/model-selector.ts +1109 -0
- package/src/interactive/overlays/prompts.ts +72 -0
- package/src/interactive/overlays/session-selector-search.ts +31 -0
- package/src/interactive/overlays/session-selector.ts +284 -0
- package/src/interactive/overlays/settings.ts +3451 -0
- package/src/interactive/overlays/skills-hub.ts +237 -0
- package/src/interactive/overlays/tree-selector.ts +422 -0
- package/src/interactive/permission-overlay.ts +170 -0
- package/src/interactive/render-trace.ts +534 -0
- package/src/interactive/renderers/branch-summary.ts +86 -0
- package/src/interactive/renderers/code-ink.ts +420 -0
- package/src/interactive/renderers/compaction-summary.ts +112 -0
- package/src/interactive/renderers/diff.ts +137 -0
- package/src/interactive/renderers/mermaid.ts +53 -0
- package/src/interactive/renderers/notice.ts +28 -0
- package/src/interactive/renderers/retry-status.ts +31 -0
- package/src/interactive/renderers/structured.ts +89 -0
- package/src/interactive/renderers/tool-execution.ts +1357 -0
- package/src/interactive/renderers/worker-entry.ts +280 -0
- package/src/interactive/session-last-turn.ts +186 -0
- package/src/interactive/session-switch-settlement.ts +10 -0
- package/src/interactive/session-transcript.ts +105 -0
- package/src/interactive/session-usage-reseed.ts +74 -0
- package/src/interactive/slash-autocomplete.ts +256 -0
- package/src/interactive/slash-commands.ts +1407 -0
- package/src/interactive/slash-spec.ts +424 -0
- package/src/interactive/status/controller.ts +260 -0
- package/src/interactive/status/index.ts +23 -0
- package/src/interactive/status/state-machine.ts +530 -0
- package/src/interactive/status/summary.ts +170 -0
- package/src/interactive/status/types.ts +121 -0
- package/src/interactive/status/verbs.ts +163 -0
- package/src/interactive/status/watchdog.ts +24 -0
- package/src/interactive/stdout-backpressure.ts +99 -0
- package/src/interactive/stream-pacer.ts +530 -0
- package/src/interactive/stream-pacing-policy.ts +66 -0
- package/src/interactive/tasks-overlay.ts +540 -0
- package/src/interactive/terminal-lease.ts +485 -0
- package/src/interactive/theme/components.ts +55 -0
- package/src/interactive/theme/glyphs.ts +70 -0
- package/src/interactive/theme/index.ts +15 -0
- package/src/interactive/theme/labels.ts +88 -0
- package/src/interactive/theme/rules.ts +138 -0
- package/src/interactive/theme/segments.ts +88 -0
- package/src/interactive/theme/tokens.ts +121 -0
- package/src/interactive/thinking-level-policy.ts +6 -0
- package/src/interactive/tool-prose-loop.ts +122 -0
- package/src/interactive/tool-prose-registration.ts +48 -0
- package/src/interactive/turn-context.ts +855 -0
- package/src/interactive/turn-middleware.ts +283 -0
- package/src/interactive/turn-persistence.ts +458 -0
- package/src/interactive/turn-queues.ts +181 -0
- package/src/interactive/turn-recovery.ts +323 -0
- package/src/interactive/turn-runtime.ts +869 -0
- package/src/interactive/turn-state.ts +133 -0
- package/src/interactive/view/artifacts.ts +1452 -0
- package/src/interactive/view/view-overlay.ts +735 -0
- package/src/interactive/welcome-dashboard.ts +537 -0
- package/src/interactive/worker-receipts.ts +143 -0
- package/src/interactive/worker-replay.ts +111 -0
- package/src/interactive/worker-share.ts +100 -0
- package/src/interactive/worker-stream.ts +446 -0
- package/src/interactive/workspace-facts.ts +141 -0
- package/src/tools/agent-tools.ts +402 -0
- package/src/tools/artifact.ts +103 -0
- package/src/tools/ask-user.ts +666 -0
- package/src/tools/bash.ts +204 -0
- package/src/tools/bootstrap.ts +77 -0
- package/src/tools/builtin-tool-catalog.ts +265 -0
- package/src/tools/codewiki/code-nav-surface.ts +29 -0
- package/src/tools/codewiki/code-nav.ts +549 -0
- package/src/tools/codewiki/shared.ts +118 -0
- package/src/tools/compete-worktrees.ts +898 -0
- package/src/tools/context/docs-engine.ts +630 -0
- package/src/tools/context/index.ts +514 -0
- package/src/tools/context/surface.ts +19 -0
- package/src/tools/core-bootstrap.ts +168 -0
- package/src/tools/credential-present.ts +151 -0
- package/src/tools/dispatch-admission.ts +533 -0
- package/src/tools/dispatch-arguments.ts +228 -0
- package/src/tools/dispatch-background.ts +54 -0
- package/src/tools/dispatch-event-text.ts +6 -0
- package/src/tools/dispatch-plan.ts +746 -0
- package/src/tools/dispatch-run-events.ts +238 -0
- package/src/tools/dispatch-runner.ts +2370 -0
- package/src/tools/dispatch-scout-admission.ts +295 -0
- package/src/tools/dispatch-scout.ts +461 -0
- package/src/tools/dispatch-types.ts +77 -0
- package/src/tools/dispatch.ts +244 -0
- package/src/tools/edit-diff.ts +534 -0
- package/src/tools/edit.ts +128 -0
- package/src/tools/executables.ts +22 -0
- package/src/tools/file-mutation-queue.ts +35 -0
- package/src/tools/find.ts +294 -0
- package/src/tools/grep.ts +495 -0
- package/src/tools/ignore-policy.ts +169 -0
- package/src/tools/lazy-tool.ts +60 -0
- package/src/tools/ledger.ts +206 -0
- package/src/tools/ls.ts +110 -0
- package/src/tools/monitor-surface.ts +36 -0
- package/src/tools/monitor.ts +767 -0
- package/src/tools/network-policy.ts +29 -0
- package/src/tools/observation.ts +421 -0
- package/src/tools/observers.ts +99 -0
- package/src/tools/path-utils.ts +79 -0
- package/src/tools/policy.ts +154 -0
- package/src/tools/profiles.ts +108 -0
- package/src/tools/read.ts +173 -0
- package/src/tools/registry.ts +1169 -0
- package/src/tools/result-shaping.ts +204 -0
- package/src/tools/safe-exec.ts +128 -0
- package/src/tools/spawn-hygiene.ts +182 -0
- package/src/tools/steer-surface.ts +17 -0
- package/src/tools/steer.ts +77 -0
- package/src/tools/tasks.ts +265 -0
- package/src/tools/truncate-utf8.ts +17 -0
- package/src/tools/truncate.ts +43 -0
- package/src/tools/verify/frontend.ts +687 -0
- package/src/tools/verify/index.ts +31 -0
- package/src/tools/verify/scripts.ts +108 -0
- package/src/tools/verify/surface.ts +46 -0
- package/src/tools/web-fetch-surface.ts +23 -0
- package/src/tools/web-fetch.ts +759 -0
- package/src/tools/worker-evidence.ts +215 -0
- package/src/tools/write.ts +57 -0
- package/src/utils/exif-orientation.ts +192 -0
- package/src/utils/git.ts +24 -0
- package/src/utils/image-resize.ts +148 -0
- package/src/utils/photon.ts +103 -0
- package/src/worker/control-lane.ts +22 -0
- package/src/worker/entry.ts +294 -0
- package/src/worker/event-projection.ts +56 -0
- package/src/worker/heartbeat.ts +24 -0
- package/src/worker/ledger-mirror.ts +95 -0
- package/src/worker/ndjson.ts +40 -0
- package/src/worker/protocol.ts +529 -0
- package/src/worker/resource-facts.ts +79 -0
- package/src/worker/runtime-registry.ts +12 -0
- package/src/worker/spec-contract.ts +675 -0
- package/src/worker/stdin-demux.ts +316 -0
- package/dist/acp-UMLFVA3F.js +0 -92
- package/dist/chunk-262G75JS.js +0 -35
- package/dist/chunk-6CWDTGUC.js +0 -20
- package/dist/chunk-BYEU76JP.js +0 -899
- package/dist/chunk-GNGDQYDU.js +0 -34688
- package/dist/chunk-GOTUR54M.js +0 -9
- package/dist/chunk-NI4DEJMC.js +0 -88
- package/dist/chunk-TPOCL34A.js +0 -2876
- package/dist/chunk-UU3R62TT.js +0 -128
- package/dist/clio-KIQ5SNDS.js +0 -53
- package/dist/configure-G4E3A2PG.js +0 -27
- package/dist/doctor-M5HJJZOL.js +0 -61
- package/dist/domains/agents/builtins/architect.md +0 -33
- package/dist/domains/agents/builtins/coder.md +0 -31
- package/dist/domains/agents/builtins/context-bootstrap.md +0 -38
- package/dist/domains/agents/builtins/debugger.md +0 -30
- package/dist/domains/agents/builtins/documenter.md +0 -31
- package/dist/domains/agents/builtins/git-master.md +0 -30
- package/dist/domains/agents/builtins/provenance.md +0 -30
- package/dist/domains/agents/builtins/researcher.md +0 -71
- package/dist/domains/agents/builtins/scout.md +0 -42
- package/dist/domains/agents/builtins/tester.md +0 -31
- package/dist/domains/agents/builtins/verifier.md +0 -30
- package/dist/domains/agents/builtins/wiki-writer.md +0 -41
- package/dist/fleet-preflight-CLIAX7YR.js +0 -21
- package/dist/preload-KZVHET2B.js +0 -11
- package/dist/version-ROZ6CZKH.js +0 -16
- package/docs/html/agents_blueprint.html +0 -936
- package/docs/html/alcf_blueprint.html +0 -324
- package/docs/html/architecture_blueprint.html +0 -850
- package/docs/html/commands_blueprint.html +0 -794
- package/docs/html/config_knobs_audit_blueprint.html +0 -178
- package/docs/html/configuration_blueprint.html +0 -1080
- package/docs/html/context_blueprint.html +0 -603
- package/docs/html/documentation_blueprint.html +0 -832
- package/docs/html/environment_blueprint.html +0 -404
- package/docs/html/eval_blueprint.html +0 -743
- package/docs/html/evals_internal_blueprint.html +0 -190
- package/docs/html/evolution_blueprint.html +0 -674
- package/docs/html/extensions_blueprint.html +0 -2065
- package/docs/html/fleet_dispatch_blueprint.html +0 -286
- package/docs/html/index.html +0 -919
- package/docs/html/lifecycle_blueprint.html +0 -723
- package/docs/html/memory_blueprint.html +0 -699
- package/docs/html/middleware_blueprint.html +0 -664
- package/docs/html/models_blueprint.html +0 -2366
- package/docs/html/observability_blueprint.html +0 -683
- package/docs/html/provider_adapter_blueprint.html +0 -245
- package/docs/html/safety_blueprint.html +0 -1386
- package/docs/html/shared.css +0 -571
- package/docs/html/shared.js +0 -143
- package/docs/html/skills_blueprint.html +0 -671
- package/docs/html/soak_blueprint.html +0 -182
- package/docs/html/tool_usage_blueprint.html +0 -350
- package/docs/html/tools_blueprint.html +0 -2249
- package/docs/html/trace_blueprint.html +0 -235
- package/docs/html/tui_design_blueprint.html +0 -314
- package/docs/html/validation_blueprint.html +0 -961
- package/docs/html/worker_dispatch_blueprint.html +0 -231
- package/skills/git/commit-crafting/SKILL.md +0 -79
- package/skills/git/commit-crafting/evals.md +0 -92
- package/skills/git/create-pr/SKILL.md +0 -116
- package/skills/git/create-pr/evals.md +0 -114
- package/skills/git/investigate-issue/SKILL.md +0 -139
- package/skills/git/investigate-issue/evals.md +0 -94
- package/skills/git/review-changes/SKILL.md +0 -103
- package/skills/git/review-changes/evals.md +0 -85
|
@@ -0,0 +1,776 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One capacity-aware model-residency reconciler, shared by every local runtime
|
|
3
|
+
* that pins weights in VRAM. Both the interactive chat loop and the headless
|
|
4
|
+
* worker drive the provider stream path, so calling the reconciler at the top
|
|
5
|
+
* of each manageable runtime's stream gives exactly one place that decides
|
|
6
|
+
* load and evict for both paths.
|
|
7
|
+
*
|
|
8
|
+
* Co-residency is the default. Local servers are multi-model hosts with finite
|
|
9
|
+
* VRAM, not single-model slots: when the runtime advertises capacity (the
|
|
10
|
+
* llama.cpp router's `max_instances`) and a slot is free, Clio loads without
|
|
11
|
+
* evicting anything; when the runtime loads just-in-time and fails an
|
|
12
|
+
* oversized load cleanly (LM Studio), Clio attempts the co-resident load first
|
|
13
|
+
* and swaps only after that failure; when the server schedules fits itself
|
|
14
|
+
* (Ollama), Clio releases only its own unprotected stragglers. Eviction is the
|
|
15
|
+
* exception, taken only when a slot must be freed, and it never selects a
|
|
16
|
+
* protected resident while an unprotected one is available.
|
|
17
|
+
*
|
|
18
|
+
* Protection is symmetric and role-aware. Residents tagged `pinned:true` or
|
|
19
|
+
* `role:scout` by the server operator are never evicted. Residents referenced
|
|
20
|
+
* by the operator's own Clio configuration (see
|
|
21
|
+
* {@link setProtectedModelsProvider}) carry the role they serve (chat, memory,
|
|
22
|
+
* worker, target default) and are never evicted by another Clio stream while an
|
|
23
|
+
* unprotected candidate exists, and only with a loud warning naming the role
|
|
24
|
+
* when capacity is exhausted. No Clio profile silently evicts another profile's
|
|
25
|
+
* model, and no chat switch silently unloads the memory plane.
|
|
26
|
+
*
|
|
27
|
+
* The reconciler is best-effort and non-blocking. A slow or unreachable
|
|
28
|
+
* server, or a malformed resident listing, degrades to observe-only and never
|
|
29
|
+
* crashes a turn. `CLIO_CODER_RESIDENCY=observe` and an explicit target
|
|
30
|
+
* `lifecycle: user-managed` both force observe-only on every runtime path.
|
|
31
|
+
* Every collision or stress case emits a notice over the event bus instead of
|
|
32
|
+
* a thrown error. One reconcile decision holds per (target, model) within a
|
|
33
|
+
* TTL, and mutations for a target are serialized across processes through a
|
|
34
|
+
* state-dir lock file so a worker and the orchestrator cannot interleave
|
|
35
|
+
* unload/load against the same server.
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
import { BusChannels, type RuntimeNoticeKind, type RuntimeNoticePayload } from "../../core/bus-events.js";
|
|
39
|
+
import type { ProtectedModelRef, ResidencyRole } from "../../core/residency-protection.js";
|
|
40
|
+
import { getSharedBus } from "../../core/shared-bus.js";
|
|
41
|
+
import { withResidencyLock } from "./residency-lock.js";
|
|
42
|
+
import { type ResidentModelInfo, residentMatchesKeep } from "./resident-models.js";
|
|
43
|
+
|
|
44
|
+
export type ResidencyNotice = RuntimeNoticePayload;
|
|
45
|
+
export type { RuntimeNoticeKind };
|
|
46
|
+
|
|
47
|
+
// --- notice sink -----------------------------------------------------------
|
|
48
|
+
|
|
49
|
+
export type ResidencyNoticeSink = (notice: ResidencyNotice) => void;
|
|
50
|
+
|
|
51
|
+
function busNoticeSink(notice: ResidencyNotice): void {
|
|
52
|
+
getSharedBus().emit(BusChannels.RuntimeNotice, notice);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let noticeSink: ResidencyNoticeSink = busNoticeSink;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Override where residency notices go. The main process keeps the default,
|
|
59
|
+
* which emits on the shared bus that the interactive layer renders. The worker
|
|
60
|
+
* subprocess installs a stderr sink so headless runs still surface the reason.
|
|
61
|
+
* Passing null restores the bus sink.
|
|
62
|
+
*/
|
|
63
|
+
export function setResidencyNoticeSink(sink: ResidencyNoticeSink | null): void {
|
|
64
|
+
noticeSink = sink ?? busNoticeSink;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Emit one notice through the active sink. Never throws into a turn. */
|
|
68
|
+
export function emitResidencyNotice(notice: ResidencyNotice): void {
|
|
69
|
+
try {
|
|
70
|
+
noticeSink(notice);
|
|
71
|
+
} catch {
|
|
72
|
+
// A notice is informational; a sink failure must never escape into a turn.
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// --- configured-model protection ---------------------------------------------
|
|
77
|
+
|
|
78
|
+
// Wire model ids the operator's own configuration references, with the role
|
|
79
|
+
// each one serves (chat, memory, worker, target default). The provider is
|
|
80
|
+
// installed by the composition root: the orchestrator entry derives it from the
|
|
81
|
+
// live effective settings, and the worker entry from the protectedModels list
|
|
82
|
+
// carried on its WorkerSpec, so every process protects the same set. A bare
|
|
83
|
+
// string is accepted for an id whose role the caller does not know.
|
|
84
|
+
export type ProtectedModelEntry = string | ProtectedModelRef;
|
|
85
|
+
|
|
86
|
+
let protectedModelsProvider: (() => ReadonlyArray<ProtectedModelEntry>) | null = null;
|
|
87
|
+
|
|
88
|
+
export function setProtectedModelsProvider(provider: (() => ReadonlyArray<ProtectedModelEntry>) | null): void {
|
|
89
|
+
protectedModelsProvider = provider;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Configured model ids mapped to the role that references them, when known. */
|
|
93
|
+
function configProtectedRoles(): ReadonlyMap<string, ResidencyRole | undefined> {
|
|
94
|
+
const roles = new Map<string, ResidencyRole | undefined>();
|
|
95
|
+
try {
|
|
96
|
+
for (const entry of protectedModelsProvider?.() ?? []) {
|
|
97
|
+
const modelId = (typeof entry === "string" ? entry : entry.modelId).trim();
|
|
98
|
+
if (modelId.length === 0) continue;
|
|
99
|
+
const role = typeof entry === "string" ? undefined : entry.role;
|
|
100
|
+
if (!roles.has(modelId) || roles.get(modelId) === undefined) roles.set(modelId, role);
|
|
101
|
+
}
|
|
102
|
+
} catch {
|
|
103
|
+
return new Map();
|
|
104
|
+
}
|
|
105
|
+
return roles;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** True when the runtime tagged this resident as operator-pinned (llama.cpp router tags). */
|
|
109
|
+
export function residentTagProtected(tags: ReadonlyArray<string> | undefined): boolean {
|
|
110
|
+
if (!tags) return false;
|
|
111
|
+
return tags.includes("pinned:true") || tags.includes("role:scout");
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// --- Clio-loaded registry --------------------------------------------------
|
|
115
|
+
|
|
116
|
+
// Models Clio itself loaded, keyed by a stable per-server target key. The
|
|
117
|
+
// registry is per-process; a resident model absent from it may still be
|
|
118
|
+
// another Clio process's model, which is why eviction relies on the symmetric
|
|
119
|
+
// protection above rather than on attribution alone.
|
|
120
|
+
const clioLoaded = new Map<string, Set<string>>();
|
|
121
|
+
|
|
122
|
+
/** Record that Clio loaded `modelId` on the target identified by `targetKey`. */
|
|
123
|
+
export function markClioLoaded(targetKey: string, modelId: string): void {
|
|
124
|
+
let set = clioLoaded.get(targetKey);
|
|
125
|
+
if (!set) {
|
|
126
|
+
set = new Set();
|
|
127
|
+
clioLoaded.set(targetKey, set);
|
|
128
|
+
}
|
|
129
|
+
set.add(modelId);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function forgetClioLoaded(targetKey: string, modelId: string): void {
|
|
133
|
+
clioLoaded.get(targetKey)?.delete(modelId);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function isClioLoaded(targetKey: string, entry: ResidentModelInfo): boolean {
|
|
137
|
+
const set = clioLoaded.get(targetKey);
|
|
138
|
+
if (!set) return false;
|
|
139
|
+
if (set.has(entry.modelId)) return true;
|
|
140
|
+
return (entry.aliasIds ?? []).some((id) => set.has(id));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// --- TTL fast path ---------------------------------------------------------
|
|
144
|
+
|
|
145
|
+
/** Skip the listResident round-trip for this long after a clean reconcile. */
|
|
146
|
+
export const RECONCILE_TTL_MS = 60_000;
|
|
147
|
+
const reconcileCache = new Map<string, { modelId: string; decision: "reconcile" | "observe"; at: number }>();
|
|
148
|
+
|
|
149
|
+
/** Test-only: clear the cross-call Clio-loaded registry and TTL cache. */
|
|
150
|
+
export function resetResidencyState(): void {
|
|
151
|
+
clioLoaded.clear();
|
|
152
|
+
reconcileCache.clear();
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// --- residency decision (pure) ----------------------------------------------
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* How the runtime makes a requested model resident, which decides when an
|
|
159
|
+
* eviction is even on the table:
|
|
160
|
+
* - "router": Clio must POST an explicit load (llama.cpp router) and the
|
|
161
|
+
* server advertises a slot capacity. A free slot loads without eviction;
|
|
162
|
+
* a full server frees exactly the slots needed; unknown capacity falls
|
|
163
|
+
* back to a conservative swap of unprotected residents.
|
|
164
|
+
* - "jit": the runtime loads on open and fails an oversized load cleanly
|
|
165
|
+
* (LM Studio with gpuStrictVramCap). Nothing is evicted up front; the
|
|
166
|
+
* plan carries ranked `fallbackEvict` candidates for a retry after a
|
|
167
|
+
* will-not-fit failure.
|
|
168
|
+
* - "scheduler": the server places and fits models itself (Ollama). Only
|
|
169
|
+
* Clio's own unprotected stragglers are released, because Clio pins them
|
|
170
|
+
* with keep_alive -1 and nothing else ever reclaims them.
|
|
171
|
+
*/
|
|
172
|
+
export type ResidencyStrategy = "router" | "jit" | "scheduler";
|
|
173
|
+
|
|
174
|
+
/** Why a resident model may not be evicted, when it may not. */
|
|
175
|
+
export type ResidencyProtection = "tag" | "config";
|
|
176
|
+
|
|
177
|
+
export interface ResidentClassified extends ResidentModelInfo {
|
|
178
|
+
/** True when this process's Clio-loaded registry attributes the model to Clio. */
|
|
179
|
+
loadedByClio: boolean;
|
|
180
|
+
/** Set when the resident is protected from eviction (server tag or operator config). */
|
|
181
|
+
protection?: ResidencyProtection;
|
|
182
|
+
/** Which configured plane references this resident, when the protection came from config. */
|
|
183
|
+
role?: ResidencyRole;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export interface ResidencyFacts {
|
|
187
|
+
targetId: string;
|
|
188
|
+
runtimeId: string;
|
|
189
|
+
keepModelId: string;
|
|
190
|
+
resident: ReadonlyArray<ResidentClassified>;
|
|
191
|
+
/** False when the env or explicit target lifecycle opt-out asks Clio to only observe. */
|
|
192
|
+
managed: boolean;
|
|
193
|
+
strategy: ResidencyStrategy;
|
|
194
|
+
/** Max co-resident models when the runtime advertises it (llama.cpp router max_instances). */
|
|
195
|
+
capacity?: number;
|
|
196
|
+
/**
|
|
197
|
+
* True when the runtime tags the keep model itself as operator-pinned, so it
|
|
198
|
+
* will be excluded from every eviction tier once it is resident. Such a model
|
|
199
|
+
* may only take an unprotected slot: evicting a config-protected resident for
|
|
200
|
+
* it would be a one-way swap the configured role could never undo (#72).
|
|
201
|
+
*/
|
|
202
|
+
keepTagProtected?: boolean;
|
|
203
|
+
contextLength?: number;
|
|
204
|
+
modelMaxContext?: number;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export type ResidencyDecision = "reconcile" | "observe" | "decline";
|
|
208
|
+
|
|
209
|
+
export interface ResidencyPlan {
|
|
210
|
+
decision: ResidencyDecision;
|
|
211
|
+
/** Residents the plan releases before making the keep model resident. */
|
|
212
|
+
evict: ResidentModelInfo[];
|
|
213
|
+
/** Ranked swap candidates for after a failed co-resident JIT load ("jit" strategy only). */
|
|
214
|
+
fallbackEvict: ResidentModelInfo[];
|
|
215
|
+
/** True when the keep model is already resident on the target. */
|
|
216
|
+
keepResident: boolean;
|
|
217
|
+
notices: ResidencyNotice[];
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function gib(bytes: number): string {
|
|
221
|
+
return `${(bytes / 1024 ** 3).toFixed(1)} GiB`;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function makeNotice(
|
|
225
|
+
facts: ResidencyFacts,
|
|
226
|
+
kind: RuntimeNoticeKind,
|
|
227
|
+
level: ResidencyNotice["level"],
|
|
228
|
+
message: string,
|
|
229
|
+
detail?: ResidencyNotice["detail"],
|
|
230
|
+
): ResidencyNotice {
|
|
231
|
+
const notice: ResidencyNotice = {
|
|
232
|
+
kind,
|
|
233
|
+
level,
|
|
234
|
+
targetId: facts.targetId,
|
|
235
|
+
runtimeId: facts.runtimeId,
|
|
236
|
+
model: facts.keepModelId,
|
|
237
|
+
message,
|
|
238
|
+
};
|
|
239
|
+
if (detail) notice.detail = detail;
|
|
240
|
+
return notice;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function clioLoadedFirst(entries: ReadonlyArray<ResidentClassified>): ResidentClassified[] {
|
|
244
|
+
return [...entries.filter((entry) => entry.loadedByClio), ...entries.filter((entry) => !entry.loadedByClio)];
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/** `the memory model` / `the chat model` for a notice, or the bare id's article. */
|
|
248
|
+
function describeRole(role: ResidencyRole | undefined): string {
|
|
249
|
+
if (role === "chat") return "the chat model";
|
|
250
|
+
if (role === "memory") return "the memory model";
|
|
251
|
+
if (role === "worker") return "a worker model";
|
|
252
|
+
if (role === "target-default") return "a target default model";
|
|
253
|
+
return "a configured model";
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function evictionNotice(facts: ResidencyFacts, entry: ResidentClassified): ResidencyNotice {
|
|
257
|
+
if (entry.protection === "config") {
|
|
258
|
+
return makeNotice(
|
|
259
|
+
facts,
|
|
260
|
+
"swap",
|
|
261
|
+
"warning",
|
|
262
|
+
`evicting '${entry.modelId}' from '${facts.targetId}' to make room for '${facts.keepModelId}' even though settings still reference it as ${describeRole(entry.role)}: every slot is taken and no unprotected resident is left. Another profile pointed at it will reload it.`,
|
|
263
|
+
{ swappedOut: entry.modelId, configProtected: true, ...(entry.role ? { role: entry.role } : {}) },
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
if (entry.loadedByClio) {
|
|
267
|
+
return makeNotice(
|
|
268
|
+
facts,
|
|
269
|
+
"about-to-evict",
|
|
270
|
+
"info",
|
|
271
|
+
`evicting Clio-loaded model '${entry.modelId}' from '${facts.targetId}' to free a slot for '${facts.keepModelId}'.`,
|
|
272
|
+
entry.sizeVramBytes !== undefined ? { freedVramBytes: entry.sizeVramBytes } : undefined,
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
return makeNotice(
|
|
276
|
+
facts,
|
|
277
|
+
"swap",
|
|
278
|
+
"warning",
|
|
279
|
+
`swapping resident '${entry.modelId}' for requested '${facts.keepModelId}' on '${facts.targetId}' (Clio did not load it; recorded transition instead of a silent unload; set CLIO_CODER_RESIDENCY=observe or lifecycle: user-managed to forbid swaps).`,
|
|
280
|
+
{
|
|
281
|
+
...(entry.sizeVramBytes !== undefined ? { freedVramBytes: entry.sizeVramBytes } : {}),
|
|
282
|
+
swappedOut: entry.modelId,
|
|
283
|
+
},
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Decide what to do with the target's resident set, purely from already
|
|
289
|
+
* gathered facts. The async {@link reconcileResidency} wraps this with the
|
|
290
|
+
* round-trips; keeping the decision pure makes the capacity math, protection
|
|
291
|
+
* tiers, eviction order, and every notice case directly testable without a
|
|
292
|
+
* server.
|
|
293
|
+
*/
|
|
294
|
+
export function decideResidency(facts: ResidencyFacts): ResidencyPlan {
|
|
295
|
+
const notices: ResidencyNotice[] = [];
|
|
296
|
+
const keepResident = facts.resident.some((entry) => residentMatchesKeep(entry, facts.keepModelId));
|
|
297
|
+
const others = facts.resident.filter((entry) => !residentMatchesKeep(entry, facts.keepModelId));
|
|
298
|
+
|
|
299
|
+
// Stress: requested context window above the model's advertised maximum.
|
|
300
|
+
if (
|
|
301
|
+
facts.contextLength !== undefined &&
|
|
302
|
+
facts.modelMaxContext !== undefined &&
|
|
303
|
+
facts.modelMaxContext > 0 &&
|
|
304
|
+
facts.contextLength > facts.modelMaxContext
|
|
305
|
+
) {
|
|
306
|
+
notices.push(
|
|
307
|
+
makeNotice(
|
|
308
|
+
facts,
|
|
309
|
+
"stress",
|
|
310
|
+
"warning",
|
|
311
|
+
`context length ${facts.contextLength} exceeds ${facts.keepModelId}'s ${facts.modelMaxContext}-token limit on '${facts.targetId}'; lower the context window to avoid a truncated or split load.`,
|
|
312
|
+
{ requestedContext: facts.contextLength, modelMaxContext: facts.modelMaxContext },
|
|
313
|
+
),
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// Stress: a resident model is partly on CPU (its total weight footprint is
|
|
318
|
+
// larger than its GPU-resident bytes), so the GPU is already oversubscribed.
|
|
319
|
+
for (const entry of facts.resident) {
|
|
320
|
+
if (entry.sizeBytes !== undefined && entry.sizeVramBytes !== undefined && entry.sizeBytes > entry.sizeVramBytes) {
|
|
321
|
+
notices.push(
|
|
322
|
+
makeNotice(
|
|
323
|
+
facts,
|
|
324
|
+
"stress",
|
|
325
|
+
"warning",
|
|
326
|
+
`model '${entry.modelId}' on '${facts.targetId}' is split across CPU and GPU (${gib(entry.sizeVramBytes)} of ${gib(entry.sizeBytes)} on GPU); expect slow generation.`,
|
|
327
|
+
{ residentVramBytes: entry.sizeVramBytes, residentTotalBytes: entry.sizeBytes },
|
|
328
|
+
),
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Observe-only: an explicit opt-out. Never evict; only report.
|
|
334
|
+
if (!facts.managed) {
|
|
335
|
+
return { decision: "observe", evict: [], fallbackEvict: [], keepResident, notices };
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// The keep model is already served: co-residents stay, whoever loaded them.
|
|
339
|
+
// Report the sharing once per TTL so a genuinely oversubscribed box is
|
|
340
|
+
// never silent, but a fitting co-residency is normal, not a defect.
|
|
341
|
+
if (keepResident) {
|
|
342
|
+
if (others.length > 0) {
|
|
343
|
+
const names = others.map((entry) => (entry.role ? `${entry.modelId} (${entry.role})` : entry.modelId)).join(", ");
|
|
344
|
+
if (facts.capacity !== undefined && facts.resident.length > facts.capacity) {
|
|
345
|
+
notices.push(
|
|
346
|
+
makeNotice(
|
|
347
|
+
facts,
|
|
348
|
+
"stress",
|
|
349
|
+
"warning",
|
|
350
|
+
`'${facts.targetId}' holds ${facts.resident.length} models (${names} alongside '${facts.keepModelId}') above its ${facts.capacity}-instance capacity; unload one or raise the server's limit.`,
|
|
351
|
+
{ residentCount: facts.resident.length, maxInstances: facts.capacity },
|
|
352
|
+
),
|
|
353
|
+
);
|
|
354
|
+
} else {
|
|
355
|
+
notices.push(
|
|
356
|
+
makeNotice(
|
|
357
|
+
facts,
|
|
358
|
+
"co-resident",
|
|
359
|
+
"info",
|
|
360
|
+
`'${facts.targetId}' serves '${facts.keepModelId}' alongside ${names}. Clio leaves co-resident models loaded; keep the setup only while weights and KV caches fit in GPU memory.`,
|
|
361
|
+
facts.capacity !== undefined
|
|
362
|
+
? { residentCount: facts.resident.length, maxInstances: facts.capacity }
|
|
363
|
+
: { residentCount: facts.resident.length },
|
|
364
|
+
),
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
return { decision: "reconcile", evict: [], fallbackEvict: [], keepResident, notices };
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// The keep model is not resident. Rank potential evictions by protection
|
|
372
|
+
// tier: unprotected residents first (Clio-attributed before foreign), then
|
|
373
|
+
// config-protected ones as a loud last resort. Tag-pinned residents are
|
|
374
|
+
// never candidates. A keep model that will itself come back tag-pinned may
|
|
375
|
+
// not displace the config tier: once resident it is never a candidate, so
|
|
376
|
+
// the configured role could not reclaim its slot.
|
|
377
|
+
const tierUnprotected = clioLoadedFirst(others.filter((entry) => entry.protection === undefined));
|
|
378
|
+
const tierConfig = clioLoadedFirst(others.filter((entry) => entry.protection === "config"));
|
|
379
|
+
const configEvictable = facts.keepTagProtected !== true;
|
|
380
|
+
|
|
381
|
+
let evict: ResidentClassified[] = [];
|
|
382
|
+
let fallbackEvict: ResidentClassified[] = [];
|
|
383
|
+
|
|
384
|
+
if (facts.strategy === "jit") {
|
|
385
|
+
// Attempt the co-resident load first; the runtime turns an oversized
|
|
386
|
+
// load into a clean failure, and only that failure justifies a swap.
|
|
387
|
+
fallbackEvict = configEvictable ? [...tierUnprotected, ...tierConfig] : tierUnprotected;
|
|
388
|
+
} else if (facts.strategy === "scheduler") {
|
|
389
|
+
// The server fits and places models itself. Release only Clio's own
|
|
390
|
+
// unprotected stragglers; foreign and protected residents stay.
|
|
391
|
+
evict = tierUnprotected.filter((entry) => entry.loadedByClio);
|
|
392
|
+
} else if (facts.capacity === undefined) {
|
|
393
|
+
// Router without readable capacity: no way to prove a free slot, so
|
|
394
|
+
// fall back to swapping the unprotected residents before the load.
|
|
395
|
+
evict = tierUnprotected;
|
|
396
|
+
} else {
|
|
397
|
+
const slotsNeeded = facts.resident.length + 1 - facts.capacity;
|
|
398
|
+
if (slotsNeeded > 0) {
|
|
399
|
+
const candidates = configEvictable ? [...tierUnprotected, ...tierConfig] : tierUnprotected;
|
|
400
|
+
if (
|
|
401
|
+
candidates.length < slotsNeeded &&
|
|
402
|
+
!configEvictable &&
|
|
403
|
+
tierUnprotected.length + tierConfig.length >= slotsNeeded
|
|
404
|
+
) {
|
|
405
|
+
// The load would only fit by evicting a configured model in favour of
|
|
406
|
+
// a pinned one. Decline up front instead of stranding the config role.
|
|
407
|
+
const blocked = tierConfig.slice(0, slotsNeeded - tierUnprotected.length);
|
|
408
|
+
const names = blocked.map((entry) => `'${entry.modelId}' (${describeRole(entry.role)})`).join(", ");
|
|
409
|
+
notices.push(
|
|
410
|
+
makeNotice(
|
|
411
|
+
facts,
|
|
412
|
+
"will-not-fit",
|
|
413
|
+
"error",
|
|
414
|
+
`cannot load pinned '${facts.keepModelId}' on '${facts.targetId}': it would evict ${names} that settings still reference, and a pinned model is never evicted, so the configured model could not return. Unload one manually, unpin '${facts.keepModelId}' on the server, or raise the server's max instances.`,
|
|
415
|
+
{
|
|
416
|
+
residentCount: facts.resident.length,
|
|
417
|
+
maxInstances: facts.capacity,
|
|
418
|
+
configProtected: true,
|
|
419
|
+
...(blocked[0]?.role ? { role: blocked[0].role } : {}),
|
|
420
|
+
},
|
|
421
|
+
),
|
|
422
|
+
);
|
|
423
|
+
return { decision: "decline", evict: [], fallbackEvict: [], keepResident, notices };
|
|
424
|
+
}
|
|
425
|
+
if (candidates.length < slotsNeeded) {
|
|
426
|
+
notices.push(
|
|
427
|
+
makeNotice(
|
|
428
|
+
facts,
|
|
429
|
+
"will-not-fit",
|
|
430
|
+
"error",
|
|
431
|
+
`cannot load '${facts.keepModelId}' on '${facts.targetId}': all ${facts.capacity} instance slots hold pinned models (${others.map((entry) => entry.modelId).join(", ")}). Unload one manually or raise the server's max instances.`,
|
|
432
|
+
{ residentCount: facts.resident.length, maxInstances: facts.capacity },
|
|
433
|
+
),
|
|
434
|
+
);
|
|
435
|
+
return { decision: "decline", evict: [], fallbackEvict: [], keepResident, notices };
|
|
436
|
+
}
|
|
437
|
+
evict = candidates.slice(0, slotsNeeded);
|
|
438
|
+
} else if (others.length > 0) {
|
|
439
|
+
notices.push(
|
|
440
|
+
makeNotice(
|
|
441
|
+
facts,
|
|
442
|
+
"co-resident",
|
|
443
|
+
"info",
|
|
444
|
+
`loading '${facts.keepModelId}' alongside ${others.map((entry) => entry.modelId).join(", ")} on '${facts.targetId}' (${facts.resident.length + 1}/${facts.capacity} instances).`,
|
|
445
|
+
{ residentCount: facts.resident.length + 1, maxInstances: facts.capacity },
|
|
446
|
+
),
|
|
447
|
+
);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
for (const entry of evict) notices.push(evictionNotice(facts, entry));
|
|
452
|
+
return { decision: "reconcile", evict, fallbackEvict, keepResident, notices };
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// --- async reconciler ------------------------------------------------------
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Per-runtime hooks the reconciler drives. Each manageable runtime builds an
|
|
459
|
+
* adapter that closes over its own transport (LM Studio REST, the Ollama HTTP
|
|
460
|
+
* client, the llama.cpp router's HTTP surface) so the reconciler
|
|
461
|
+
* itself stays runtime-agnostic.
|
|
462
|
+
*/
|
|
463
|
+
export interface ResidencyAdapter {
|
|
464
|
+
/** Stable per-server key for the Clio-loaded registry, TTL cache, and lock file. */
|
|
465
|
+
targetKey: string;
|
|
466
|
+
targetId: string;
|
|
467
|
+
runtimeId: string;
|
|
468
|
+
keepModelId: string;
|
|
469
|
+
/** False when the env or explicit target lifecycle opt-out asks Clio to only observe. */
|
|
470
|
+
managed: boolean;
|
|
471
|
+
strategy: ResidencyStrategy;
|
|
472
|
+
contextLength?: number;
|
|
473
|
+
modelMaxContext?: number;
|
|
474
|
+
listResident(): Promise<ResidentModelInfo[]>;
|
|
475
|
+
/**
|
|
476
|
+
* Runtime tags of the keep model itself, when the runtime lists them before
|
|
477
|
+
* the load (the llama.cpp router lists tags for unloaded models too). Called
|
|
478
|
+
* after {@link listResident}, so an adapter may serve it from that snapshot.
|
|
479
|
+
*/
|
|
480
|
+
keepModelTags?(): Promise<ReadonlyArray<string> | undefined>;
|
|
481
|
+
unload(modelId: string): Promise<void>;
|
|
482
|
+
/**
|
|
483
|
+
* Reject with a {@link ResidencyPreconditionError} when the server cannot
|
|
484
|
+
* make the keep model resident at all, most often because the model is not
|
|
485
|
+
* in its catalog. Consulted only when the plan would evict, and only from
|
|
486
|
+
* facts the adapter already holds, so it costs no extra round trip.
|
|
487
|
+
*
|
|
488
|
+
* Adapters that cannot know this ahead of the load omit the hook, which
|
|
489
|
+
* keeps the previous behaviour of letting the load itself report the failure.
|
|
490
|
+
*/
|
|
491
|
+
assertLoadable?(): Promise<void>;
|
|
492
|
+
/** Router-style servers: read the max co-resident instance count. */
|
|
493
|
+
capacity?(): Promise<number | undefined>;
|
|
494
|
+
/**
|
|
495
|
+
* Router-style servers: make the keep model resident. Must be idempotent
|
|
496
|
+
* (a loaded model returns immediately) and bounded by the runtime's load
|
|
497
|
+
* wait. A thrown error propagates to the caller and fails the turn with
|
|
498
|
+
* its message.
|
|
499
|
+
*/
|
|
500
|
+
load?(modelId: string): Promise<void>;
|
|
501
|
+
/**
|
|
502
|
+
* Make a model the reconciler just evicted resident again, after the load
|
|
503
|
+
* that eviction made room for was rejected. Distinct from
|
|
504
|
+
* {@link ResidencyAdapter.load}, which serves the keep model and may consult
|
|
505
|
+
* a listing snapshot taken before the eviction: that snapshot still shows
|
|
506
|
+
* the evicted model as resident, so reusing it here would restore nothing.
|
|
507
|
+
* Implementations must therefore force the load rather than short-circuit on
|
|
508
|
+
* cached state.
|
|
509
|
+
*
|
|
510
|
+
* Adapters that omit the hook keep the previous behaviour, where a failed
|
|
511
|
+
* load leaves the evicted model unloaded.
|
|
512
|
+
*/
|
|
513
|
+
reloadEvicted?(modelId: string): Promise<void>;
|
|
514
|
+
/** Cross-process mutation serializer; defaults to the state-dir lock file. */
|
|
515
|
+
withLock?<T>(targetKey: string, fn: () => Promise<T>): Promise<T>;
|
|
516
|
+
now?: () => number;
|
|
517
|
+
ttlMs?: number;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
export type ReconcileResult = ResidencyPlan;
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* Put back the models an eviction removed once the load it made room for has
|
|
524
|
+
* failed. Best-effort by construction: the load failure is the error the caller
|
|
525
|
+
* must see, so a restore that also fails is reported as a notice and never
|
|
526
|
+
* replaces it. Restores run in eviction order, and the freed slots are known to
|
|
527
|
+
* be available because the keep model did not take them.
|
|
528
|
+
*/
|
|
529
|
+
async function restoreEvictedModels(
|
|
530
|
+
adapter: ResidencyAdapter,
|
|
531
|
+
evicted: ReadonlyArray<ResidentModelInfo>,
|
|
532
|
+
loadError: unknown,
|
|
533
|
+
): Promise<void> {
|
|
534
|
+
if (evicted.length === 0) return;
|
|
535
|
+
const reason = loadError instanceof Error ? loadError.message : String(loadError);
|
|
536
|
+
const restored: string[] = [];
|
|
537
|
+
const failed: string[] = [];
|
|
538
|
+
for (const entry of evicted) {
|
|
539
|
+
if (!adapter.reloadEvicted) {
|
|
540
|
+
failed.push(entry.modelId);
|
|
541
|
+
continue;
|
|
542
|
+
}
|
|
543
|
+
try {
|
|
544
|
+
await adapter.reloadEvicted(entry.modelId);
|
|
545
|
+
restored.push(entry.modelId);
|
|
546
|
+
} catch {
|
|
547
|
+
failed.push(entry.modelId);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
if (restored.length > 0) {
|
|
551
|
+
emitResidencyNotice({
|
|
552
|
+
kind: "swap",
|
|
553
|
+
level: "warning",
|
|
554
|
+
targetId: adapter.targetId,
|
|
555
|
+
runtimeId: adapter.runtimeId,
|
|
556
|
+
model: adapter.keepModelId,
|
|
557
|
+
message: `loading '${adapter.keepModelId}' on '${adapter.targetId}' failed (${reason}); restored ${restored.map((id) => `'${id}'`).join(", ")} so the target keeps serving.`,
|
|
558
|
+
detail: { restored: restored.join(", ") },
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
if (failed.length > 0) {
|
|
562
|
+
emitResidencyNotice({
|
|
563
|
+
kind: "will-not-fit",
|
|
564
|
+
level: "error",
|
|
565
|
+
targetId: adapter.targetId,
|
|
566
|
+
runtimeId: adapter.runtimeId,
|
|
567
|
+
model: adapter.keepModelId,
|
|
568
|
+
message: `loading '${adapter.keepModelId}' on '${adapter.targetId}' failed (${reason}) and ${failed.map((id) => `'${id}'`).join(", ")} could not be restored; the target may now serve nothing. Reload it on the server.`,
|
|
569
|
+
detail: { unrestored: failed.join(", ") },
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* Thrown by an adapter's {@link ResidencyAdapter.assertLoadable} when the
|
|
576
|
+
* server cannot make the keep model resident at all, most often because the
|
|
577
|
+
* model is not in the server's catalog. It is a precondition failure, not a
|
|
578
|
+
* transport failure: the reconciler must not evict anything for a load that is
|
|
579
|
+
* already known to be impossible, because the eviction would succeed, the load
|
|
580
|
+
* would fail, and the target would be left holding nothing (#127).
|
|
581
|
+
*
|
|
582
|
+
* The reconciler answers it by declining the reconcile and emitting a
|
|
583
|
+
* `will-not-fit` notice, so the turn continues to the provider call and fails
|
|
584
|
+
* with the server's own error for the unknown model instead of with a silent
|
|
585
|
+
* outage on the node. It is the fast path in front of the restore that
|
|
586
|
+
* {@link reconcileResidency} performs when a load fails for any other reason.
|
|
587
|
+
*/
|
|
588
|
+
export class ResidencyPreconditionError extends Error {
|
|
589
|
+
override readonly name = "ResidencyPreconditionError";
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Gather the resident set and capacity facts, decide, emit notices, and
|
|
594
|
+
* perform the mutations under the cross-process lock. List and unload probes
|
|
595
|
+
* are best-effort and degrade to observe-only; an explicit `load` failure
|
|
596
|
+
* propagates so the turn fails with the router's reason instead of a bare
|
|
597
|
+
* connection error.
|
|
598
|
+
*/
|
|
599
|
+
export async function reconcileResidency(adapter: ResidencyAdapter): Promise<ReconcileResult> {
|
|
600
|
+
const now = adapter.now ?? Date.now;
|
|
601
|
+
const ttl = adapter.ttlMs ?? RECONCILE_TTL_MS;
|
|
602
|
+
|
|
603
|
+
const cached = reconcileCache.get(adapter.targetKey);
|
|
604
|
+
if (cached && cached.modelId === adapter.keepModelId && now() - cached.at < ttl) {
|
|
605
|
+
return {
|
|
606
|
+
decision: cached.decision,
|
|
607
|
+
evict: [],
|
|
608
|
+
fallbackEvict: [],
|
|
609
|
+
keepResident: cached.decision === "reconcile",
|
|
610
|
+
notices: [],
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
let resident: ResidentModelInfo[];
|
|
615
|
+
try {
|
|
616
|
+
resident = await adapter.listResident();
|
|
617
|
+
} catch {
|
|
618
|
+
// Unreachable or slow server: never block the turn, just observe.
|
|
619
|
+
return { decision: "observe", evict: [], fallbackEvict: [], keepResident: false, notices: [] };
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
let capacity: number | undefined;
|
|
623
|
+
if (adapter.capacity) {
|
|
624
|
+
try {
|
|
625
|
+
capacity = await adapter.capacity();
|
|
626
|
+
} catch {
|
|
627
|
+
capacity = undefined;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
let keepTagProtected = false;
|
|
632
|
+
if (adapter.keepModelTags) {
|
|
633
|
+
try {
|
|
634
|
+
keepTagProtected = residentTagProtected(await adapter.keepModelTags());
|
|
635
|
+
} catch {
|
|
636
|
+
keepTagProtected = false;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
const protectedRoles = configProtectedRoles();
|
|
641
|
+
const classified: ResidentClassified[] = resident.map((entry) => {
|
|
642
|
+
const configId = [entry.modelId, ...(entry.aliasIds ?? [])].find((id) => protectedRoles.has(id));
|
|
643
|
+
const protection: ResidencyProtection | undefined = residentTagProtected(entry.tags)
|
|
644
|
+
? "tag"
|
|
645
|
+
: configId !== undefined
|
|
646
|
+
? "config"
|
|
647
|
+
: undefined;
|
|
648
|
+
const role = configId === undefined ? undefined : protectedRoles.get(configId);
|
|
649
|
+
return {
|
|
650
|
+
...entry,
|
|
651
|
+
loadedByClio: isClioLoaded(adapter.targetKey, entry),
|
|
652
|
+
...(protection ? { protection } : {}),
|
|
653
|
+
...(role ? { role } : {}),
|
|
654
|
+
};
|
|
655
|
+
});
|
|
656
|
+
|
|
657
|
+
const facts: ResidencyFacts = {
|
|
658
|
+
targetId: adapter.targetId,
|
|
659
|
+
runtimeId: adapter.runtimeId,
|
|
660
|
+
keepModelId: adapter.keepModelId,
|
|
661
|
+
resident: classified,
|
|
662
|
+
managed: adapter.managed,
|
|
663
|
+
strategy: adapter.strategy,
|
|
664
|
+
...(capacity !== undefined ? { capacity } : {}),
|
|
665
|
+
...(keepTagProtected ? { keepTagProtected } : {}),
|
|
666
|
+
...(adapter.contextLength !== undefined ? { contextLength: adapter.contextLength } : {}),
|
|
667
|
+
...(adapter.modelMaxContext !== undefined ? { modelMaxContext: adapter.modelMaxContext } : {}),
|
|
668
|
+
};
|
|
669
|
+
|
|
670
|
+
const plan = decideResidency(facts);
|
|
671
|
+
|
|
672
|
+
// An eviction is only justified if the load it makes room for can succeed.
|
|
673
|
+
// Unloading first and discovering afterwards that the keep model does not
|
|
674
|
+
// exist leaves the target serving nothing, which took a shared node out of
|
|
675
|
+
// service on the live fleet (#127). Nothing has mutated yet at this point,
|
|
676
|
+
// so refusing here is a clean no-op: the turn continues to the provider call
|
|
677
|
+
// and fails with the server's own error for the unknown model.
|
|
678
|
+
if (plan.decision === "reconcile" && plan.evict.length > 0 && adapter.assertLoadable) {
|
|
679
|
+
try {
|
|
680
|
+
await adapter.assertLoadable();
|
|
681
|
+
} catch (error) {
|
|
682
|
+
if (!(error instanceof ResidencyPreconditionError)) throw error;
|
|
683
|
+
const notice: ResidencyNotice = {
|
|
684
|
+
kind: "will-not-fit",
|
|
685
|
+
level: "error",
|
|
686
|
+
targetId: adapter.targetId,
|
|
687
|
+
runtimeId: adapter.runtimeId,
|
|
688
|
+
model: adapter.keepModelId,
|
|
689
|
+
message: error.message,
|
|
690
|
+
};
|
|
691
|
+
emitResidencyNotice(notice);
|
|
692
|
+
return { decision: "decline", evict: [], fallbackEvict: [], keepResident: false, notices: [notice] };
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
// Emitted after the loadability gate so the operator never reads an eviction
|
|
697
|
+
// notice for a swap that the gate then refuses.
|
|
698
|
+
for (const notice of plan.notices) emitResidencyNotice(notice);
|
|
699
|
+
|
|
700
|
+
if (plan.decision === "reconcile") {
|
|
701
|
+
const mutate = async (): Promise<void> => {
|
|
702
|
+
const evicted: ResidentModelInfo[] = [];
|
|
703
|
+
for (const entry of plan.evict) {
|
|
704
|
+
try {
|
|
705
|
+
await adapter.unload(entry.modelId);
|
|
706
|
+
forgetClioLoaded(adapter.targetKey, entry.modelId);
|
|
707
|
+
evicted.push(entry);
|
|
708
|
+
} catch {
|
|
709
|
+
// Best-effort: a failed unload self-heals on the next reconcile.
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
if (!adapter.load) return;
|
|
713
|
+
try {
|
|
714
|
+
await adapter.load(adapter.keepModelId);
|
|
715
|
+
} catch (error) {
|
|
716
|
+
// The eviction bought nothing: the slot it freed is still empty and
|
|
717
|
+
// the target is now serving less than before the reconcile. Put back
|
|
718
|
+
// what was taken before surfacing the load's own failure, so a
|
|
719
|
+
// rejected load costs the node a request rather than its resident
|
|
720
|
+
// model (#127). The gate above catches the knowable case ahead of any
|
|
721
|
+
// mutation; this covers the rest, including an out-of-memory load, a
|
|
722
|
+
// 5xx, a load wait that times out, and a preset removed between the
|
|
723
|
+
// listing and the load.
|
|
724
|
+
await restoreEvictedModels(adapter, evicted, error);
|
|
725
|
+
throw error;
|
|
726
|
+
}
|
|
727
|
+
};
|
|
728
|
+
// Serialize actual mutations across processes; a keep model that is
|
|
729
|
+
// already fully resident needs no lock (the load hook is a no-op) and
|
|
730
|
+
// waiting on a still-loading model is read-only polling.
|
|
731
|
+
if (plan.evict.length > 0 || (adapter.load && !plan.keepResident)) {
|
|
732
|
+
const lock = adapter.withLock ?? withResidencyLock;
|
|
733
|
+
await lock(adapter.targetKey, mutate);
|
|
734
|
+
} else {
|
|
735
|
+
await mutate();
|
|
736
|
+
}
|
|
737
|
+
// Attribute the keep model to Clio only when Clio is the one loading it.
|
|
738
|
+
if (!plan.keepResident) markClioLoaded(adapter.targetKey, adapter.keepModelId);
|
|
739
|
+
reconcileCache.set(adapter.targetKey, { modelId: adapter.keepModelId, decision: "reconcile", at: now() });
|
|
740
|
+
} else if (plan.decision === "observe" && !adapter.managed) {
|
|
741
|
+
// Cache the opt-out observation so its notices dedupe per TTL; a
|
|
742
|
+
// degraded observe (listResident failure) is never cached, so the next
|
|
743
|
+
// stream re-probes.
|
|
744
|
+
reconcileCache.set(adapter.targetKey, { modelId: adapter.keepModelId, decision: "observe", at: now() });
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
return plan;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
/**
|
|
751
|
+
* The env-level residency opt-out. Clio manages residency for every
|
|
752
|
+
* manageable runtime by default; `CLIO_CODER_RESIDENCY=observe` (or off/0/false/
|
|
753
|
+
* user) flips the whole process to observe-only. Per-target opt-out goes
|
|
754
|
+
* through {@link residencyManagedFor}.
|
|
755
|
+
*/
|
|
756
|
+
export function residencyManaged(env: NodeJS.ProcessEnv = process.env): boolean {
|
|
757
|
+
const opt = (env.CLIO_CODER_RESIDENCY ?? "").trim().toLowerCase();
|
|
758
|
+
if (opt === "observe" || opt === "off" || opt === "0" || opt === "false" || opt === "user" || opt === "user-managed") {
|
|
759
|
+
return false;
|
|
760
|
+
}
|
|
761
|
+
return true;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
/**
|
|
765
|
+
* Combined residency opt-out for one target: the process-wide env switch plus
|
|
766
|
+
* the target's explicit `lifecycle: user-managed`. An absent lifecycle means
|
|
767
|
+
* the operator made no choice, and Clio manages by default; runtime synthesis
|
|
768
|
+
* only sets the metadata field when settings carry an explicit value.
|
|
769
|
+
*/
|
|
770
|
+
export function residencyManagedFor(
|
|
771
|
+
lifecycle: "user-managed" | "clio-managed" | undefined,
|
|
772
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
773
|
+
): boolean {
|
|
774
|
+
if (lifecycle === "user-managed") return false;
|
|
775
|
+
return residencyManaged(env);
|
|
776
|
+
}
|