@iowarp/clio-coder 0.4.1 → 0.4.3
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 +127 -0
- package/CONTRIBUTING.md +142 -52
- package/README.md +434 -473
- package/SECURITY.md +2 -1
- package/dist/{acp-ZILU3AUO.js → acp-H2NGRPWO.js} +12 -12
- package/dist/{agents-HYWGBGQR.js → agents-TL5LLUQP.js} +56 -55
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-N3QT7CBO.js → auth-E5SW4HMS.js} +23 -21
- package/dist/builtins-IA7V7FUC.js +22 -0
- package/dist/{chunk-7RY5VZPH.js → chunk-2APPQIER.js} +8 -8
- package/dist/{chunk-72GZI5EV.js → chunk-2JH2WHGE.js} +2 -2
- package/dist/{chunk-JA5QWE4Z.js → chunk-2UG5F4C5.js} +1973 -1664
- package/dist/{chunk-5YHDIDBP.js → chunk-2UH2KFUP.js} +2 -2
- package/dist/{chunk-CTJ4RNAA.js → chunk-2VIKGWFZ.js} +2 -2
- package/dist/{chunk-I66EAJFY.js → chunk-2WZ546HR.js} +267 -232
- package/dist/{chunk-GIZNH63R.js → chunk-35MSIRKH.js} +9 -4
- package/dist/chunk-3EBYEESD.js +314 -0
- package/dist/{chunk-J5LZHVIT.js → chunk-3M6DQK6S.js} +113 -35
- package/dist/{chunk-RKSR6VSF.js → chunk-4IUZQIJ3.js} +29 -1
- package/dist/{chunk-6FN3E6KX.js → chunk-4O6MANBS.js} +2 -2
- package/dist/chunk-4UVU7BJ5.js +39 -0
- package/dist/{chunk-VKRH2TCS.js → chunk-4WR7VSYB.js} +2 -2
- package/dist/{chunk-BBTJOK6Y.js → chunk-54CBCGIR.js} +5 -5
- package/dist/{chunk-AP73CFDC.js → chunk-5ICU3EUH.js} +2 -2
- package/dist/chunk-5MEZN6CB.js +1334 -0
- package/dist/{chunk-O42A54GG.js → chunk-5OIVVPHF.js} +2 -2
- package/dist/{chunk-ABLSQ6JX.js → chunk-64I3JVYM.js} +8 -2
- package/dist/{chunk-AFKWHWXF.js → chunk-6PTFB5VS.js} +39 -22
- package/dist/{chunk-VN3SHNBN.js → chunk-7DICMOS6.js} +2 -2
- package/dist/chunk-7DRAWPTZ.js +360 -0
- package/dist/chunk-7E7I3WLS.js +3762 -0
- package/dist/{chunk-BJGUKIG4.js → chunk-7ZYNNDKC.js} +7 -7
- package/dist/{chunk-XKA2ICR3.js → chunk-AF4YM7Z4.js} +652 -252
- package/dist/{chunk-GVQJ5CCZ.js → chunk-AX2THNSA.js} +12 -12
- package/dist/{chunk-IG7BCQBA.js → chunk-B4OAX3SI.js} +65 -3
- package/dist/{chunk-TD3PGPQA.js → chunk-B4VEBZKF.js} +3 -3
- package/dist/{chunk-74YWRRU5.js → chunk-BEPZRGGU.js} +10 -10
- package/dist/{chunk-FEFIFZTL.js → chunk-CE5AX47J.js} +2 -2
- package/dist/{chunk-UAPGZHYC.js → chunk-DWUOQKRU.js} +25 -11
- package/dist/{chunk-THYWACCR.js → chunk-E3TPLWFX.js} +3 -3
- package/dist/{chunk-7EPLI7VL.js → chunk-EKCHAPYA.js} +2 -2
- package/dist/{chunk-HLW2MRKE.js → chunk-F4EKGO4N.js} +3 -1
- package/dist/{chunk-PJJ6MY27.js → chunk-F5JHEYZM.js} +7 -7
- package/dist/{chunk-6CCS4G3W.js → chunk-FTMGRKEF.js} +3 -3
- package/dist/{chunk-SINK3QR6.js → chunk-G76U63X4.js} +17 -17
- package/dist/{chunk-EIMVLWB3.js → chunk-GHS5EBTQ.js} +64 -9
- package/dist/{chunk-QMXC4JB7.js → chunk-GI7YYQ3F.js} +187 -1419
- package/dist/{chunk-TZSKNMZG.js → chunk-GTUD2WMY.js} +2 -1
- package/dist/{chunk-6HMJX2VU.js → chunk-GWZNEVM2.js} +44 -12
- package/dist/chunk-GYV6VZOC.js +26 -0
- package/dist/{chunk-MQXIVJ35.js → chunk-HAXOFFRH.js} +5 -5
- package/dist/{chunk-UXN6JT4W.js → chunk-HEQY7ZFI.js} +3 -3
- package/dist/{chunk-7PWAODYW.js → chunk-I7XBWTYH.js} +2 -2
- package/dist/{chunk-GCSMB2KY.js → chunk-I7ZPNEJM.js} +145 -102
- package/dist/{chunk-WNP7O5WZ.js → chunk-ID64D7PE.js} +4 -4
- package/dist/{chunk-QTFGO774.js → chunk-IGLP3ODT.js} +29 -16
- package/dist/chunk-IJNZMHLA.js +101 -0
- package/dist/{chunk-BDPT6GTK.js → chunk-INY6HTFL.js} +7 -7
- package/dist/{chunk-PBP4B7XR.js → chunk-IUE3Y34X.js} +2 -2
- package/dist/{chunk-6NJQITNH.js → chunk-IWT4SF4R.js} +6 -3
- package/dist/{chunk-R23Z6K6I.js → chunk-JDAY6FIL.js} +19 -19
- package/dist/chunk-JEQ3XTHC.js +42 -0
- package/dist/{chunk-FSP7CMNU.js → chunk-JGRC33J2.js} +50 -4
- package/dist/{chunk-TVH4ONAM.js → chunk-JKKCYP3C.js} +10 -10
- package/dist/{chunk-HJWWJ6IL.js → chunk-JSC3U7TI.js} +16 -4
- package/dist/{chunk-C537JADH.js → chunk-KK4JZPBQ.js} +19 -141
- package/dist/{chunk-K6BF4U2H.js → chunk-KKOJXO6R.js} +62 -14
- package/dist/{chunk-IHXBNWMM.js → chunk-KXDSS5WJ.js} +7 -3
- package/dist/{chunk-6DWBAZ5U.js → chunk-L47TF46W.js} +5 -7
- package/dist/{chunk-HUAS7ITX.js → chunk-LDJG7DW3.js} +91 -42
- package/dist/{chunk-CDNVLKUX.js → chunk-LLDJM5XK.js} +13 -7
- package/dist/{chunk-YPI3QQCF.js → chunk-MCEPRMZW.js} +2 -4
- package/dist/{chunk-Y4CAGMM6.js → chunk-MNJGS2IN.js} +5 -6
- package/dist/{chunk-VKFQTNDV.js → chunk-MUW2BDDH.js} +4 -4
- package/dist/{chunk-E67WX76H.js → chunk-MWUZBSAQ.js} +104 -152
- package/dist/{chunk-OJTRZGR3.js → chunk-N2Z7HLVY.js} +21 -21
- package/dist/{chunk-TVHHYFHE.js → chunk-NEDJ26B5.js} +2 -2
- package/dist/{chunk-FYUN5KZ3.js → chunk-NIQJ66N4.js} +21 -21
- package/dist/{chunk-U2WB7TZS.js → chunk-NMJXSHBJ.js} +97 -85
- package/dist/{chunk-CWVRRIEI.js → chunk-NZMNUPZZ.js} +2 -2
- package/dist/{chunk-VEGN6WIQ.js → chunk-O5CVSAG5.js} +3 -3
- package/dist/{chunk-MOPSG2X7.js → chunk-OML5D5V5.js} +8 -8
- package/dist/{chunk-2VG7KLYV.js → chunk-PAJQJ7BS.js} +5816 -3255
- package/dist/{chunk-ZW55JB7N.js → chunk-PUVDKJ2Y.js} +2 -2
- package/dist/{chunk-BTGG6BG2.js → chunk-QWGDJJYJ.js} +158 -19
- package/dist/chunk-R6Q67RJH.js +134 -0
- package/dist/{chunk-ZJLUDYFY.js → chunk-RRNP2ANY.js} +6 -6
- package/dist/{chunk-PVAMAVBB.js → chunk-RSJ25QSL.js} +102 -2
- package/dist/{chunk-NLFAQR7Z.js → chunk-S66XZJOF.js} +3 -23
- package/dist/chunk-SKHCAU7K.js +385 -0
- package/dist/chunk-SZAA6XDG.js +30 -0
- package/dist/{chunk-J4HBWF6Y.js → chunk-TM6LQDI3.js} +131 -28
- package/dist/chunk-UOIZ7DA4.js +41 -0
- package/dist/{chunk-MA3H6DM5.js → chunk-UPZU6GE4.js} +25 -3
- package/dist/{chunk-BWW4HLO4.js → chunk-UXCU4E3T.js} +8 -6
- package/dist/{chunk-N5UK64DP.js → chunk-V2ANDPVT.js} +4 -4
- package/dist/{chunk-AK5XEFVZ.js → chunk-VA5FNYMT.js} +26 -13
- package/dist/{chunk-6VC4OV3Z.js → chunk-VIA6RFQZ.js} +3 -11
- package/dist/{chunk-ZAZB4JMW.js → chunk-VKPAQYEB.js} +27 -8
- package/dist/{chunk-QKIFBZKT.js → chunk-VW6DOEDG.js} +497 -81
- package/dist/{chunk-SCYB3HA4.js → chunk-W6RRQCPQ.js} +63 -19
- package/dist/{chunk-2NM363SV.js → chunk-WBKFA554.js} +10 -10
- package/dist/{chunk-R32CLGZ6.js → chunk-WCXUNS7U.js} +82 -21
- package/dist/{chunk-GPPB3JBE.js → chunk-WRBAGUNF.js} +3 -3
- package/dist/{chunk-IXJT6DCX.js → chunk-XIVNBFZS.js} +85 -30
- package/dist/{chunk-UEDMSP56.js → chunk-XPWWI35G.js} +417 -201
- package/dist/chunk-XRZT5WY5.js +47 -0
- package/dist/{chunk-3QSOM6PA.js → chunk-Y3CBHOR6.js} +2 -2
- package/dist/{chunk-VXMFAE2W.js → chunk-YPC6ZR5L.js} +19 -6
- package/dist/{chunk-AKB4GYDL.js → chunk-YQWYVTMC.js} +5 -5
- package/dist/{chunk-6I5ILFOF.js → chunk-ZA4VCIGV.js} +3 -3
- package/dist/{chunk-7OBGU7UB.js → chunk-ZDN3Y73Y.js} +12 -18
- package/dist/{chunk-3I5NY75V.js → chunk-ZWPRK62N.js} +8 -5
- package/dist/cli/index.js +41 -39
- package/dist/{clio-IT3G3VQH.js → clio-CMMK4KRR.js} +9 -9
- package/dist/{code-nav-RK6S7F6E.js → code-nav-MDZNQS33.js} +89 -21
- package/dist/{components-UBWCQSRW.js → components-UCUQ4QXW.js} +4 -4
- package/dist/{config-3QZRWZJF.js → config-SVM5P5YI.js} +131 -84
- package/dist/{configure-FL7Y3KJF.js → configure-LE3IK2TJ.js} +28 -26
- package/dist/{context-5HE7ODYK.js → context-2OHRKS42.js} +69 -64
- package/dist/{context-KYQFRVDC.js → context-E3VC7RX5.js} +15 -11
- package/dist/{context-XNHL75JV.js → context-VNCR7KAG.js} +93 -65
- package/dist/{context-clear-N545L53A.js → context-clear-BW4O37TG.js} +64 -60
- package/dist/context-map-COB37XXN.js +505 -0
- package/dist/{context-working-set-QHKXSV2F.js → context-working-set-VDS25HXZ.js} +19 -18
- package/dist/{dispatch-runner-RGIE5PCT.js → dispatch-runner-5AHT53RF.js} +93 -82
- package/dist/{docs-5NAF6AU7.js → docs-PD3EXDKU.js} +21 -20
- package/dist/{doctor-ZGPEGHIP.js → doctor-WNNVO6FY.js} +48 -47
- package/dist/{eval-GXLL44RD.js → eval-7G7SGAYO.js} +287 -115
- package/dist/{eval-inventory-HBWSWQOK.js → eval-inventory-Y6QRFOH5.js} +4 -4
- package/dist/{evidence-HWLBRH3Q.js → evidence-VD6736FQ.js} +67 -64
- package/dist/{evolve-FTZBMNVW.js → evolve-AL3NGVRL.js} +65 -62
- package/dist/{extensions-VHRBEID7.js → extensions-MOVJ32NM.js} +9 -7
- package/dist/{fleet-CKZHJWZJ.js → fleet-QZHUMAGI.js} +114 -111
- package/dist/{fleet-commands-EXDXBMV6.js → fleet-commands-BAYT5FJZ.js} +10 -10
- package/dist/{fleet-decisions-OTHB6KRL.js → fleet-decisions-IREVMRU4.js} +7 -6
- package/dist/{fleet-graph-YTEZUCUT.js → fleet-graph-YCTT3HTI.js} +22 -19
- package/dist/{fleet-inspect-SS6YMDCK.js → fleet-inspect-QVJTDAVB.js} +58 -55
- package/dist/{fleet-preflight-PBY4VYOM.js → fleet-preflight-25QAFPK4.js} +4 -4
- package/dist/{fleet-validate-KMEM5L3S.js → fleet-validate-5O57AAJ7.js} +26 -23
- package/dist/{fleet-verify-QD5M7E7Q.js → fleet-verify-CPH2W2T6.js} +59 -56
- package/dist/{fleet-view-WAMJYNDT.js → fleet-view-SWBR3VGQ.js} +58 -55
- package/dist/{init-5XQRBOFV.js → init-J477LKZH.js} +82 -79
- package/dist/{interop-34TVO25M.js → interop-3FCM6XLG.js} +11 -11
- package/dist/{library-3QY6KF57.js → library-QUQEIUG6.js} +30 -27
- package/dist/{memory-L4UTIIIW.js → memory-SGGSEP65.js} +67 -64
- package/dist/{models-ZVX3QOWE.js → models-HEKUAXXK.js} +53 -46
- package/dist/{monitor-CEKVSYTS.js → monitor-HKU57TYQ.js} +63 -60
- package/dist/{orchestrator-77BAP6BC.js → orchestrator-VDFAEFAI.js} +1831 -1057
- package/dist/{panes-7STHOAUJ.js → panes-DN2SSFOH.js} +5 -5
- package/dist/{panes-SHAUIRXY.js → panes-TALGNPZT.js} +29 -14
- package/dist/{paths-L7LGY6RN.js → paths-NBMFAIEZ.js} +5 -5
- package/dist/reset-EAJFFJVB.js +344 -0
- package/dist/{resources-74GKTLSF.js → resources-OVKSEFVE.js} +29 -20
- package/dist/{run-HBAUJNNZ.js → run-7DP7ZF2J.js} +120 -115
- package/dist/{share-G3APVLVP.js → share-WML67FT3.js} +32 -27
- package/dist/{skills-35HHUKCR.js → skills-SG662R2K.js} +41 -31
- package/dist/{skills-eval-QN4HSHDC.js → skills-eval-VVZEUU46.js} +78 -77
- package/dist/{skills-inventory-J357J34F.js → skills-inventory-I2E23GET.js} +23 -20
- package/dist/{slash-commands-JZZCQA32.js → slash-commands-S7MBJDQK.js} +40 -36
- package/dist/{steer-XAVHJM22.js → steer-2LQOMCPB.js} +3 -3
- package/dist/{support-U7QOWY26.js → support-CC2UJBJ6.js} +6 -6
- package/dist/{targets-DSM6CY3M.js → targets-4QC3HIEW.js} +54 -54
- package/dist/{terminal-lease-JOPFUVEM.js → terminal-lease-TUHIJ6Y2.js} +5 -5
- package/dist/{tools-MKNWVPBH.js → tools-TFGJICCU.js} +10 -10
- package/dist/{trace-ECQ7TIYZ.js → trace-FXMXUZUF.js} +55 -7
- package/dist/uninstall-5PEVOE5B.js +408 -0
- package/dist/upgrade-M4WXY6KN.js +303 -0
- package/dist/{usage-X52N3IDJ.js → usage-N7ZNVLEM.js} +151 -104
- package/dist/{verifiers-EJTVVSMA.js → verifiers-DJTP4XX6.js} +15 -15
- package/dist/{verify-YJL6XET2.js → verify-RWE4PPEK.js} +9 -9
- package/dist/{web-fetch-MPIFL3LL.js → web-fetch-MPARV2K7.js} +2 -2
- package/dist/{wiki-generate-4NDZTQ4B.js → wiki-generate-C7IQOXSP.js} +89 -86
- package/dist/{with-panes-OBOBFIIR.js → with-panes-4GCGSL7J.js} +53 -257
- package/dist/worker/entry.js +90 -74
- package/docs/README.md +176 -81
- package/docs/{acp.md → architecture/acp.md} +36 -20
- package/docs/{alcf-provider.md → architecture/alcf-provider.md} +8 -5
- package/docs/{architecture.md → architecture/architecture.md} +43 -22
- package/docs/{artifact-placement.md → architecture/artifact-placement.md} +27 -23
- package/docs/architecture/artifact-versions.md +90 -0
- package/docs/{capacity-and-scheduling.md → architecture/capacity-and-scheduling.md} +26 -13
- package/docs/{context-engine.md → architecture/context-engine.md} +29 -25
- package/docs/{context-working-set.md → architecture/context-working-set.md} +13 -10
- package/docs/{dispatch-architecture-rationale.md → architecture/dispatch-architecture-rationale.md} +12 -9
- package/docs/{dispatch-typed-intent.md → architecture/dispatch-typed-intent.md} +68 -46
- package/docs/{evidence-and-memory.md → architecture/evidence-and-memory.md} +23 -16
- package/docs/{middleware-and-components.md → architecture/middleware-and-components.md} +11 -5
- package/docs/{model-catalog.md → architecture/model-catalog.md} +61 -27
- package/docs/{observability.md → architecture/observability.md} +38 -14
- package/docs/{pi-boundary.md → architecture/pi-boundary.md} +24 -11
- package/docs/{prompt-envelope-and-tools.md → architecture/prompt-envelope-and-tools.md} +57 -20
- package/docs/{provider-adapter-cookbook.md → architecture/provider-adapter-cookbook.md} +99 -25
- package/docs/{safety-model.md → architecture/safety-model.md} +35 -20
- package/docs/{session-lifecycle.md → architecture/session-lifecycle.md} +8 -5
- package/docs/architecture/time-conventions.md +125 -0
- package/docs/{trace-store.md → architecture/trace-store.md} +13 -5
- package/docs/{tui-design.md → architecture/tui-design.md} +13 -13
- package/docs/{worker-dispatch-mechanics.md → architecture/worker-dispatch-mechanics.md} +27 -30
- package/docs/{built-in-agents.md → guide/built-in-agents.md} +65 -35
- package/docs/{commands-and-modes.md → guide/commands-and-modes.md} +66 -61
- package/docs/{configuration-and-targets.md → guide/configuration-and-targets.md} +323 -297
- package/docs/guide/configuration-reference.md +1163 -0
- package/docs/{environment-variables.md → guide/environment-variables.md} +33 -28
- package/docs/{exit-codes-and-output.md → guide/exit-codes-and-output.md} +6 -3
- package/docs/{extensions-and-sharing.md → guide/extensions-and-sharing.md} +41 -14
- package/docs/{fleet-dispatch.md → guide/fleet-dispatch.md} +39 -43
- package/docs/{glossary.md → guide/glossary.md} +14 -11
- package/docs/{installation-and-lifecycle.md → guide/installation-and-lifecycle.md} +81 -17
- package/docs/guide/panes-and-files.md +290 -0
- package/docs/{proactive-memory.md → guide/proactive-memory.md} +131 -107
- package/docs/{resource-library.md → guide/resource-library.md} +13 -4
- package/docs/{skills-marketplace.md → guide/skills-marketplace.md} +25 -3
- package/docs/{tool-usage.md → guide/tool-usage.md} +87 -23
- package/docs/{troubleshooting.md → guide/troubleshooting.md} +9 -4
- package/docs/{config-knobs-audit.md → history/config-knobs-audit.md} +11 -11
- package/docs/{release-cut-checklist.md → history/release-cut-checklist.md} +29 -2
- package/docs/process/development-pipeline.md +152 -0
- package/docs/process/documentation-coverage.md +100 -0
- package/docs/process/documentation-guide.md +187 -0
- package/docs/{eval-runner.md → process/eval-runner.md} +108 -53
- package/docs/{evals-internal.md → process/evals-internal.md} +10 -10
- package/docs/{evolution.md → process/evolution.md} +2 -2
- package/docs/{fleet-demo-runbook.md → process/fleet-demo-runbook.md} +11 -7
- package/docs/{git-commit-provenance.md → process/git-commit-provenance.md} +11 -4
- package/docs/{performance-methodology.md → process/performance-methodology.md} +87 -69
- package/docs/{scientific-validation.md → process/scientific-validation.md} +4 -4
- package/evals/README.md +2 -2
- package/evals/behavioral-model.yaml +3 -2
- package/package.json +10 -8
- package/skills/README.md +52 -41
- package/skills/coding/ast-grep/SKILL.md +102 -31
- package/skills/coding/ast-grep/evals.md +26 -0
- package/skills/coding/coding-standards/SKILL.md +41 -6
- package/skills/coding/coding-standards/evals.md +23 -0
- package/skills/coding/prototype/SKILL.md +88 -29
- package/skills/coding/prototype/evals.md +19 -0
- package/skills/coding/tdd/SKILL.md +81 -54
- package/skills/coding/tdd/evals.md +20 -0
- package/skills/context/context-handoff/SKILL.md +44 -3
- package/skills/context/context-handoff/evals.md +44 -0
- package/skills/context/context-prime/SKILL.md +46 -16
- package/skills/context/context-prime/evals.md +45 -0
- package/skills/git/branch-closeout/SKILL.md +132 -0
- package/skills/git/branch-closeout/evals.md +133 -0
- package/skills/git/branch-closeout/references/closeout-checklist.md +81 -0
- package/skills/git/file-ticket/SKILL.md +78 -64
- package/skills/git/file-ticket/assets/issue-template.md +22 -0
- package/skills/git/file-ticket/evals.md +31 -26
- package/skills/git/file-ticket/references/issue-discovery.md +49 -0
- package/skills/git/fix-issue/SKILL.md +88 -65
- package/skills/git/fix-issue/evals.md +35 -31
- package/skills/git/fix-issue/references/diagnosis-and-rca.md +46 -0
- package/skills/git/resolve-merge-conflicts/SKILL.md +101 -52
- package/skills/git/resolve-merge-conflicts/evals.md +52 -25
- package/skills/git/resolve-merge-conflicts/references/conflict-matrix.md +126 -0
- package/skills/git/ship/SKILL.md +103 -67
- package/skills/git/ship/assets/pr-template.md +21 -0
- package/skills/git/ship/evals.md +44 -28
- package/skills/git/ship/references/remote-and-branch-policy.md +62 -0
- package/skills/git/worktree-create/SKILL.md +80 -50
- package/skills/git/worktree-create/evals.md +40 -33
- package/skills/git/worktree-create/references/worktree-setup.md +62 -66
- package/skills/git/worktree-merge/SKILL.md +112 -65
- package/skills/git/worktree-merge/evals.md +42 -34
- package/skills/git/worktree-merge/references/merge-strategies.md +52 -0
- package/skills/meta/clio-coder-dev/SKILL.md +9 -5
- package/skills/meta/clio-coder-dev/evals.md +3 -2
- package/skills/meta/clio-coder-test/SKILL.md +102 -95
- package/skills/meta/clio-coder-test/evals.md +9 -4
- package/skills/meta/clio-coder-test/references/harness.md +100 -124
- package/skills/meta/clio-coder-test/references/test-map.md +77 -50
- package/skills/meta/credentials/SKILL.md +2 -2
- package/skills/meta/find-skills/SKILL.md +2 -2
- package/skills/meta/herdr/SKILL.md +2 -2
- package/skills/meta/skill-craft/SKILL.md +22 -16
- package/skills/planning/archify/SKILL.md +196 -0
- package/skills/planning/archify/evals.md +65 -0
- package/skills/planning/architecture/SKILL.md +62 -13
- package/skills/planning/architecture/evals.md +65 -0
- package/skills/planning/backlog/SKILL.md +131 -15
- package/skills/planning/backlog/evals.md +142 -0
- package/skills/planning/prd/SKILL.md +47 -7
- package/skills/planning/prd/evals.md +54 -0
- package/skills/planning/product-intent/SKILL.md +58 -3
- package/skills/planning/product-intent/evals.md +70 -0
- package/skills/planning/tech-spec/SKILL.md +54 -3
- package/skills/planning/tech-spec/evals.md +73 -0
- package/skills/registry.yaml +70 -62
- package/skills/remote.yaml +13 -0
- package/skills/research/arxiv-literature/SKILL.md +77 -19
- package/skills/research/arxiv-literature/evals.md +50 -0
- package/skills/research/experiment-protocol/SKILL.md +21 -2
- package/skills/research/experiment-protocol/evals.md +23 -0
- package/skills/research/scientific-debugging/SKILL.md +24 -2
- package/skills/research/scientific-debugging/evals.md +18 -0
- package/skills/research/scientific-modernization/SKILL.md +27 -2
- package/skills/research/scientific-modernization/evals.md +27 -0
- package/skills/skill-marketplace.json +97 -62
- package/skills/workflow/cut-it/SKILL.md +66 -6
- package/skills/workflow/cut-it/evals.md +101 -0
- package/skills/workflow/design-council/SKILL.md +118 -28
- package/skills/workflow/design-council/evals.md +161 -0
- package/skills/workflow/grill-me/SKILL.md +87 -11
- package/skills/workflow/grill-me/evals.md +153 -0
- package/skills/workflow/workflow-distiller/SKILL.md +77 -18
- package/skills/workflow/workflow-distiller/evals.md +118 -0
- package/src/cli/args.ts +2 -2
- package/src/cli/bootstrap-generate.ts +1 -1
- package/src/cli/config-inspect.ts +65 -12
- package/src/cli/configure-interop.ts +105 -13
- package/src/cli/configure-oauth.ts +57 -0
- package/src/cli/configure-onboarding.ts +980 -0
- package/src/cli/configure-target.ts +594 -0
- package/src/cli/configure.ts +1082 -532
- package/src/cli/context-map.ts +114 -0
- package/src/cli/context.ts +4 -0
- package/src/cli/docs.ts +22 -14
- package/src/cli/doctor-naming.ts +5 -5
- package/src/cli/doctor-toolchain.ts +3 -3
- package/src/cli/eval.ts +1 -2
- package/src/cli/extensions.ts +2 -1
- package/src/cli/fleet.ts +1 -1
- package/src/cli/index.ts +3 -1
- package/src/cli/internal-dispatch.ts +3 -4
- package/src/cli/lifecycle-presenter.ts +436 -0
- package/src/cli/models.ts +10 -2
- package/src/cli/modes/print.ts +5 -1
- package/src/cli/panes.ts +19 -5
- package/src/cli/reset.ts +228 -106
- package/src/cli/run.ts +9 -4
- package/src/cli/select.ts +664 -0
- package/src/cli/share.ts +5 -1
- package/src/cli/skills-eval.ts +3 -3
- package/src/cli/skills.ts +9 -2
- package/src/cli/targets.ts +5 -6
- package/src/cli/trace.ts +55 -4
- package/src/cli/uninstall.ts +233 -165
- package/src/cli/upgrade.ts +204 -149
- package/src/cli/usage.ts +86 -27
- package/src/cli/validate-model.ts +3 -3
- package/src/cli/wiki-generate.ts +1 -1
- package/src/core/artifact-paths.ts +1 -1
- package/src/core/bash-exec.ts +131 -86
- package/src/core/bus-events.ts +51 -6
- package/src/core/config.ts +61 -1
- package/src/core/defaults.ts +7 -4
- package/src/core/dispatch-outcome.ts +16 -0
- package/src/core/external-diagnostic.ts +44 -0
- package/src/core/gateway-routing.ts +157 -0
- package/src/core/guardrails.ts +10 -49
- package/src/core/prompt-hint.ts +9 -0
- package/src/core/safe-exec.ts +17 -2
- package/src/core/skill-activation.ts +89 -2
- package/src/domains/agents/builtins/architect.md +2 -3
- package/src/domains/agents/builtins/coder.md +3 -2
- package/src/domains/agents/builtins/debugger.md +2 -2
- package/src/domains/agents/builtins/documenter.md +2 -2
- package/src/domains/agents/builtins/git-master.md +1 -1
- package/src/domains/agents/builtins/oracle.md +1 -1
- 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 +2 -2
- package/src/domains/agents/builtins/verifier.md +2 -2
- package/src/domains/agents/builtins/wiki-writer.md +1 -1
- package/src/domains/agents/builtins/world-knowledge.md +31 -0
- package/src/domains/agents/catalog.ts +13 -15
- package/src/domains/agents/contract.ts +2 -0
- package/src/domains/agents/extension.ts +23 -1
- package/src/domains/agents/result-contract.ts +70 -0
- package/src/domains/config/keybindings.ts +8 -0
- package/src/domains/context/extension.ts +0 -3
- package/src/domains/context/wiki/map-seed.ts +589 -0
- package/src/domains/context/wiki/plan.ts +2 -2
- package/src/domains/context/working-set/path-index.ts +1 -0
- package/src/domains/dispatch/admission.ts +29 -0
- package/src/domains/dispatch/agent-candidates.ts +10 -0
- package/src/domains/dispatch/budget-envelope.ts +86 -1
- package/src/domains/dispatch/capability-match.ts +11 -0
- package/src/domains/dispatch/capacity-lease.ts +17 -0
- package/src/domains/dispatch/contract.ts +11 -1
- package/src/domains/dispatch/extension.ts +237 -49
- package/src/domains/dispatch/host-verification.ts +435 -39
- package/src/domains/dispatch/intent-requirements.ts +10 -0
- package/src/domains/dispatch/intent.ts +18 -1
- package/src/domains/dispatch/path-scope.ts +235 -24
- package/src/domains/dispatch/run-event-journal.ts +4 -15
- package/src/domains/dispatch/state.ts +2 -3
- package/src/domains/dispatch/transport.ts +45 -21
- package/src/domains/dispatch/types.ts +58 -3
- package/src/domains/dispatch/worker-model-metadata.ts +38 -0
- package/src/domains/eval/artifacts/store.ts +5 -0
- package/src/domains/eval/metrics/call-ledger-stream.ts +34 -11
- package/src/domains/eval/metrics/token-stream.ts +201 -31
- package/src/domains/eval/metrics/tracked.ts +40 -4
- package/src/domains/eval/runners/clio-run.ts +5 -2
- package/src/domains/eval/schema/suite.ts +28 -0
- package/src/domains/eval/schema/verdict.ts +2 -2
- package/src/domains/eval/store.ts +8 -1
- package/src/domains/eval/suites/resolve.ts +13 -1
- package/src/domains/eval/suites/run.ts +24 -3
- package/src/domains/evidence/trust-status.ts +10 -1
- package/src/domains/extensions/contract.ts +15 -1
- package/src/domains/extensions/discovery.ts +238 -41
- package/src/domains/extensions/extension.ts +105 -6
- package/src/domains/extensions/index.ts +24 -0
- package/src/domains/extensions/integrity.ts +189 -0
- package/src/domains/extensions/manager.ts +17 -1
- package/src/domains/extensions/resource-path.ts +27 -0
- package/src/domains/extensions/resources.ts +18 -38
- package/src/domains/extensions/snapshot-store.ts +39 -0
- package/src/domains/extensions/snapshot.ts +180 -0
- package/src/domains/extensions/state.ts +385 -57
- package/src/domains/extensions/types.ts +118 -1
- package/src/domains/interop/registry.ts +6 -2
- package/src/domains/interop/types.ts +4 -0
- package/src/domains/lifecycle/migrations/2026-09-01-extension-install-digests.ts +27 -0
- package/src/domains/lifecycle/migrations/index.ts +6 -0
- package/src/domains/lifecycle/naming-resources.ts +19 -4
- package/src/domains/lifecycle/naming-yazi.ts +10 -5
- package/src/domains/memory/task-memory-policy.ts +70 -26
- package/src/domains/memory/task-memory-telemetry.ts +1 -0
- package/src/domains/middleware/contract.ts +26 -0
- package/src/domains/middleware/extension.ts +24 -24
- package/src/domains/middleware/hook-receipts.ts +27 -4
- package/src/domains/middleware/hooks-io.ts +65 -32
- package/src/domains/middleware/hooks.ts +64 -0
- package/src/domains/middleware/index.ts +28 -5
- package/src/domains/middleware/marketplace-offer.ts +3 -35
- package/src/domains/middleware/memory-intervention.ts +127 -32
- package/src/domains/middleware/memory-step-endpoint.ts +3 -2
- package/src/domains/middleware/registrations.ts +326 -0
- package/src/domains/middleware/runtime.ts +28 -0
- package/src/domains/middleware/skills-reminder.ts +31 -2
- package/src/domains/middleware/snapshot.ts +20 -7
- package/src/domains/mux/contract.ts +38 -0
- package/src/domains/mux/detect.ts +6 -13
- package/src/domains/mux/index.ts +1 -1
- package/src/domains/mux/operations.ts +44 -5
- package/src/domains/mux/yazi/assets/yazi.toml +2 -2
- package/src/domains/mux/yazi/session.ts +53 -4
- package/src/domains/mux/yazi/theme.ts +117 -17
- package/src/domains/observability/compaction-usage.ts +118 -0
- package/src/domains/observability/contract.ts +10 -11
- package/src/domains/observability/cost.ts +1 -1
- package/src/domains/observability/extension.ts +17 -4
- package/src/domains/observability/out-of-turn-usage.ts +52 -21
- package/src/domains/observability/projection.ts +14 -90
- package/src/domains/observability/trace-store.ts +43 -7
- package/src/domains/prompts/compiler.ts +73 -53
- package/src/domains/prompts/contract.ts +15 -3
- package/src/domains/prompts/extension.ts +97 -9
- package/src/domains/prompts/fragments/identity/clio-worker.md +1 -3
- package/src/domains/prompts/fragments/identity/clio.md +6 -12
- package/src/domains/prompts/fragments/identity/docs-routing.md +1 -2
- package/src/domains/prompts/fragments/identity/self-awareness.md +3 -11
- package/src/domains/prompts/fragments/operating/contract.md +7 -15
- package/src/domains/prompts/fragments/operating/delegation.md +32 -34
- package/src/domains/prompts/fragments/operating/skills.md +10 -24
- package/src/domains/prompts/fragments/operating/worker.md +1 -8
- package/src/domains/providers/contract.ts +4 -1
- package/src/domains/providers/extension.ts +40 -9
- package/src/domains/providers/index.ts +1 -1
- package/src/domains/providers/model-capabilities.ts +9 -0
- package/src/domains/providers/model-discovery.ts +2 -0
- package/src/domains/providers/model-runtime-capabilities.ts +99 -25
- package/src/domains/providers/models/local-models/clio-coder-local-coding-targets.yaml +699 -114
- package/src/domains/providers/runtime-resolution.ts +31 -0
- package/src/domains/providers/runtimes/antigravity/antigravity-code.ts +225 -45
- package/src/domains/providers/runtimes/common/lmstudio-http.ts +6 -2
- package/src/domains/providers/runtimes/common/local-synth.ts +2 -0
- package/src/domains/providers/runtimes/common/probe-helpers.ts +7 -2
- package/src/domains/providers/runtimes/local-native/llamacpp.ts +9 -1
- package/src/domains/providers/runtimes/protocol/litellm.ts +119 -29
- package/src/domains/providers/support.ts +11 -5
- package/src/domains/providers/target-model-cache.ts +25 -2
- package/src/domains/providers/types/capability-flags.ts +2 -0
- package/src/domains/providers/types/cost-provenance.ts +19 -0
- package/src/domains/providers/types/local-model-quirks.ts +85 -37
- package/src/domains/providers/types/runtime-descriptor.ts +20 -1
- package/src/domains/providers/types/target-descriptor.ts +19 -0
- package/src/domains/resources/index.ts +3 -0
- package/src/domains/resources/skills/install.ts +72 -7
- package/src/domains/resources/skills/loader.ts +23 -19
- package/src/domains/resources/skills/marketplace.ts +63 -11
- package/src/domains/safety/autonomy.ts +15 -0
- package/src/domains/safety/call-target.ts +1 -1
- package/src/domains/safety/index.ts +1 -0
- package/src/domains/safety/loop-detector.ts +7 -4
- package/src/domains/safety/path-policy.ts +1 -1
- package/src/domains/safety/policy-engine.ts +34 -11
- package/src/domains/safety/protected-artifacts.ts +191 -88
- package/src/domains/safety/run-effects.ts +2 -22
- package/src/domains/safety/skill-authority.ts +55 -0
- package/src/domains/session/compaction/compact.ts +72 -22
- package/src/domains/session/entries.ts +6 -0
- package/src/domains/session/task-board.ts +10 -9
- package/src/domains/session/usage.ts +3 -3
- package/src/domains/share/archive.ts +164 -7
- package/src/engine/acp/server.ts +62 -9
- package/src/engine/agent.ts +13 -3
- package/src/engine/ai.ts +26 -8
- package/src/engine/antigravity/subprocess-runtime.ts +386 -120
- package/src/engine/api-registry.ts +3 -0
- package/src/engine/apis/llamacpp-residency.ts +3 -4
- package/src/engine/apis/lmstudio.ts +3 -3
- package/src/engine/apis/ollama-native.ts +6 -6
- package/src/engine/apis/openai-completions.ts +145 -39
- package/src/engine/apis/output-budget.ts +8 -18
- package/src/engine/apis/residency.ts +8 -27
- package/src/engine/external-subprocess.ts +114 -6
- package/src/engine/gemma-channel-filter.ts +19 -0
- package/src/engine/loop-guard.ts +92 -12
- package/src/engine/worker-runtime.ts +40 -11
- package/src/engine/worker-tools.ts +3 -1
- package/src/entry/background-model-metadata.ts +18 -0
- package/src/entry/compaction-prompt.ts +57 -0
- package/src/entry/extension-hook-sources.ts +28 -0
- package/src/entry/extension-reload.ts +309 -0
- package/src/entry/orchestrator.ts +464 -251
- package/src/entry/task-memory-lifecycle.ts +35 -0
- package/src/interactive/application-controller.ts +2 -1
- package/src/interactive/bus-notices.ts +8 -1
- package/src/interactive/chat-loop-messages.ts +16 -17
- package/src/interactive/chat-loop.ts +75 -3
- package/src/interactive/chat-panel.ts +36 -13
- package/src/interactive/chat-renderer.ts +72 -7
- package/src/interactive/cost-overlay.ts +26 -2
- package/src/interactive/dispatch-board.ts +6 -11
- package/src/interactive/footer/widgets.ts +13 -0
- package/src/interactive/interactive-application.ts +39 -4
- package/src/interactive/interactive-input-runtime.ts +4 -0
- package/src/interactive/interactive-presentation.ts +2 -2
- package/src/interactive/interactive-slash-runtime.ts +4 -1
- package/src/interactive/overlays/extensions.ts +9 -1
- package/src/interactive/overlays/help-reference.ts +13 -0
- package/src/interactive/overlays/settings.ts +27 -16
- package/src/interactive/panes-runtime.ts +111 -35
- package/src/interactive/prompt-cache-identity.ts +88 -0
- package/src/interactive/renderers/worker-entry.ts +32 -0
- package/src/interactive/slash-commands.ts +153 -20
- package/src/interactive/stream-pacing-policy.ts +0 -23
- package/src/interactive/theme/labels.ts +19 -13
- package/src/interactive/turn-context.ts +39 -20
- package/src/interactive/turn-recovery.ts +8 -0
- package/src/interactive/turn-runtime.ts +27 -11
- package/src/interactive/turn-state.ts +7 -0
- package/src/interactive/worker-receipts.ts +1 -0
- package/src/interactive/worker-stream.ts +6 -1
- package/src/interactive/yazi-bridge.ts +60 -6
- package/src/tools/agent-tools.ts +30 -1
- package/src/tools/artifact.ts +2 -2
- package/src/tools/ask-user.ts +3 -3
- package/src/tools/bash.ts +1 -1
- package/src/tools/bootstrap.ts +4 -0
- package/src/tools/builtin-tool-catalog.ts +52 -22
- package/src/tools/codewiki/code-nav-surface.ts +6 -0
- package/src/tools/codewiki/code-nav.ts +99 -13
- package/src/tools/context/docs-engine.ts +20 -7
- package/src/tools/context/index.ts +59 -21
- package/src/tools/core-bootstrap.ts +28 -6
- package/src/tools/credential-present.ts +1 -2
- package/src/tools/dispatch-arguments.ts +6 -1
- package/src/tools/dispatch-event-text.ts +10 -0
- package/src/tools/dispatch-plan.ts +49 -4
- package/src/tools/dispatch-run-events.ts +1 -1
- package/src/tools/dispatch-runner.ts +12 -0
- package/src/tools/dispatch-schema.ts +338 -0
- package/src/tools/dispatch-types.ts +3 -0
- package/src/tools/dispatch.ts +9 -254
- package/src/tools/ledger.ts +3 -5
- package/src/tools/monitor-surface.ts +5 -13
- package/src/tools/observation.ts +4 -5
- package/src/tools/panes-surface.ts +4 -11
- package/src/tools/panes.ts +4 -2
- package/src/tools/policy.ts +15 -2
- package/src/tools/read.ts +5 -6
- package/src/tools/registry.ts +41 -12
- package/src/tools/result-shaping.ts +18 -14
- package/src/tools/steer-surface.ts +1 -1
- package/src/tools/tasks.ts +1 -1
- package/src/tools/truncate.ts +6 -5
- package/src/tools/verify/surface.ts +6 -12
- package/src/tools/web-fetch-surface.ts +1 -3
- package/src/tools/worker-evidence.ts +3 -1
- package/src/worker/spec-contract.ts +4 -0
- package/dist/builtins-UJLMOVOV.js +0 -17
- package/dist/chunk-5QIAJV2D.js +0 -48
- package/dist/chunk-JZWT5J3Y.js +0 -814
- package/dist/chunk-K7VKOLQQ.js +0 -15
- package/dist/chunk-PMZCIOCJ.js +0 -25
- package/dist/chunk-SUW5DORT.js +0 -819
- package/dist/chunk-UOV2BYIW.js +0 -107
- package/dist/chunk-WR6U3OVP.js +0 -45
- package/dist/chunk-Y45G3AXC.js +0 -1558
- package/dist/reset-EOLM7GVE.js +0 -230
- package/dist/uninstall-N34PCTGJ.js +0 -331
- package/dist/upgrade-H7TOM7YL.js +0 -323
- package/docs/artifact-versions.md +0 -67
- package/docs/development-pipeline.md +0 -121
- package/docs/documentation-coverage.md +0 -46
- package/docs/documentation-guide.md +0 -167
- package/docs/time-conventions.md +0 -101
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
1
3
|
import { join } from "node:path";
|
|
2
4
|
import chalk from "chalk";
|
|
3
5
|
import { modelBootstrapGenerate, resolveBootstrapRoute } from "../cli/bootstrap-generate.js";
|
|
@@ -44,6 +46,7 @@ import { ConfigDomainModule, createConfigDomainModule } from "../domains/config/
|
|
|
44
46
|
import type { ContextContract } from "../domains/context/contract.js";
|
|
45
47
|
import { bootstrapInputFromInitOptions } from "../domains/context/init-options.js";
|
|
46
48
|
import { createContextDomainModule } from "../domains/context/runtime.js";
|
|
49
|
+
import { endpointCapacityUsage } from "../domains/dispatch/capacity-lease.js";
|
|
47
50
|
import type { DispatchContract } from "../domains/dispatch/contract.js";
|
|
48
51
|
import { createDispatchDedupRegistration } from "../domains/dispatch/dedup.js";
|
|
49
52
|
import { agentRoleFactsResolver } from "../domains/dispatch/execution-role.js";
|
|
@@ -77,6 +80,7 @@ import {
|
|
|
77
80
|
taskMemoryTracePath,
|
|
78
81
|
} from "../domains/memory/index.js";
|
|
79
82
|
import { TaskMemoryBank } from "../domains/memory/task-bank.js";
|
|
83
|
+
import { TaskMemoryEndpointBusyError } from "../domains/memory/task-memory-policy.js";
|
|
80
84
|
import {
|
|
81
85
|
createDetachedDispatchNudgeRegistration,
|
|
82
86
|
createReadOnlyExplorationNudgeRegistration,
|
|
@@ -88,8 +92,7 @@ import {
|
|
|
88
92
|
createMarketplaceOfferRegistration,
|
|
89
93
|
createMiddlewareToolChoiceControl,
|
|
90
94
|
createSkillsReminderRegistration,
|
|
91
|
-
|
|
92
|
-
installUserHooks,
|
|
95
|
+
formatRegistrationConflict,
|
|
93
96
|
type MiddlewareContract,
|
|
94
97
|
MiddlewareDomainModule,
|
|
95
98
|
writeMiddlewareDiagnosticToStderr,
|
|
@@ -100,8 +103,10 @@ import { createTaskBoardReminderRegistration } from "../domains/middleware/task-
|
|
|
100
103
|
import { createTaskNudgeRegistration } from "../domains/middleware/task-nudge.js";
|
|
101
104
|
import { createWatchdogRegistration } from "../domains/middleware/watchdog.js";
|
|
102
105
|
import type { MuxContract } from "../domains/mux/index.js";
|
|
106
|
+
import type { BackgroundMemoryUsageSink } from "../domains/observability/background-memory-usage.js";
|
|
107
|
+
import { recordFailedCompactionCalls } from "../domains/observability/compaction-usage.js";
|
|
103
108
|
import type { ObservabilityContract } from "../domains/observability/index.js";
|
|
104
|
-
import { ObservabilityDomainModule
|
|
109
|
+
import { ObservabilityDomainModule } from "../domains/observability/index.js";
|
|
105
110
|
import type { PromptsContract } from "../domains/prompts/contract.js";
|
|
106
111
|
import { createPromptsDomainModule } from "../domains/prompts/index.js";
|
|
107
112
|
import type { ProvidersContract, TargetDescriptor, ThinkingLevel } from "../domains/providers/index.js";
|
|
@@ -110,12 +115,12 @@ import {
|
|
|
110
115
|
applyModelCapabilityPatch,
|
|
111
116
|
canonicalEndpointKey,
|
|
112
117
|
firstRuntimeResolutionError,
|
|
113
|
-
foregroundStreamUsage,
|
|
114
118
|
isOrchestratorEligibleRuntime,
|
|
115
119
|
normalizeCostProvenance,
|
|
116
120
|
ProvidersDomainModule,
|
|
117
121
|
refineRuntimeTargetWithModelHints,
|
|
118
122
|
registerForegroundStream,
|
|
123
|
+
resolveEndpointCapacities,
|
|
119
124
|
resolveModelCapabilities,
|
|
120
125
|
resolveModelRuntimeCapabilitiesForProviders,
|
|
121
126
|
resolveRuntimeTarget,
|
|
@@ -123,8 +128,10 @@ import {
|
|
|
123
128
|
targetRequiresAuth,
|
|
124
129
|
VALID_THINKING_LEVELS,
|
|
125
130
|
} from "../domains/providers/index.js";
|
|
131
|
+
import { hasLiveModelCatalog, modelResidencyForStatus } from "../domains/providers/model-discovery.js";
|
|
126
132
|
import { memoryInterventionModelMaxTokens } from "../domains/providers/model-runtime-capabilities.js";
|
|
127
133
|
import { getRuntimeRegistry } from "../domains/providers/registry.js";
|
|
134
|
+
import { resolveModelReference } from "../domains/providers/resolver.js";
|
|
128
135
|
import { registerBuiltinRuntimes } from "../domains/providers/runtimes/builtins.js";
|
|
129
136
|
import {
|
|
130
137
|
createResourcesDomainModule,
|
|
@@ -136,7 +143,12 @@ import {
|
|
|
136
143
|
import { DEFAULT_RECENT_ENTRY_LIMIT } from "../domains/safety/finish-contract.js";
|
|
137
144
|
import { createFinishContractRegistration } from "../domains/safety/finish-contract-registration.js";
|
|
138
145
|
import type { AutonomyLevel, SafetyContract } from "../domains/safety/index.js";
|
|
139
|
-
import {
|
|
146
|
+
import {
|
|
147
|
+
modelMayActivateSkills,
|
|
148
|
+
parseRigorOverride,
|
|
149
|
+
resolveRigor,
|
|
150
|
+
SafetyDomainModule,
|
|
151
|
+
} from "../domains/safety/index.js";
|
|
140
152
|
import type { ProtectedArtifactState } from "../domains/safety/protected-artifacts.js";
|
|
141
153
|
import {
|
|
142
154
|
createProtectedArtifactsRegistration,
|
|
@@ -144,6 +156,7 @@ import {
|
|
|
144
156
|
} from "../domains/safety/protected-artifacts-registration.js";
|
|
145
157
|
import type { SchedulingContract } from "../domains/scheduling/contract.js";
|
|
146
158
|
import { SchedulingDomainModule } from "../domains/scheduling/index.js";
|
|
159
|
+
import type { CompactionCallObservation } from "../domains/session/compaction/compact.js";
|
|
147
160
|
import { type CompactResult, compact } from "../domains/session/compaction/compact.js";
|
|
148
161
|
import { collectSessionEntries } from "../domains/session/compaction/session-entries.js";
|
|
149
162
|
import { estimateTokens } from "../domains/session/compaction/tokens.js";
|
|
@@ -168,7 +181,7 @@ import { ToolchainDomainModule } from "../domains/toolchain/index.js";
|
|
|
168
181
|
import { createUserTasksStore } from "../domains/user-tasks/store.js";
|
|
169
182
|
import { type AcpSafeSettingsPatch, type AcpSafeSettingsSnapshot, serveClioAcpAgent } from "../engine/acp/server.js";
|
|
170
183
|
import { createStdioServerTransport } from "../engine/acp/transport.js";
|
|
171
|
-
import { completeEngineText } from "../engine/ai.js";
|
|
184
|
+
import { completeEngineText, type EngineTextCompletionResult } from "../engine/ai.js";
|
|
172
185
|
import { setProtectedModelsProvider } from "../engine/apis/residency.js";
|
|
173
186
|
import {
|
|
174
187
|
createLoopGuardRegistration,
|
|
@@ -180,8 +193,12 @@ import type { EngineModel } from "../engine/types.js";
|
|
|
180
193
|
import { createChatLoop } from "../interactive/chat-loop.js";
|
|
181
194
|
import { type RunIo, startInteractive } from "../interactive/index.js";
|
|
182
195
|
import { buildModelReplayAgentMessagesFromTurns } from "../interactive/model-session-replay.js";
|
|
196
|
+
import { prepareBackgroundModelMetadata } from "./background-model-metadata.js";
|
|
183
197
|
import type { BootOptions } from "./boot-options.js";
|
|
198
|
+
import { readCompactionSystemPrompt } from "./compaction-prompt.js";
|
|
199
|
+
import { createExtensionReloadCoordinator } from "./extension-reload.js";
|
|
184
200
|
import { resolvePanesEnablement } from "./panes-activation.js";
|
|
201
|
+
import { bindTaskMemoryLifecycle, captureTaskMemoryUsage } from "./task-memory-lifecycle.js";
|
|
185
202
|
|
|
186
203
|
export type { BootOptions, HeadlessSamplingOverrides } from "./boot-options.js";
|
|
187
204
|
|
|
@@ -200,6 +217,7 @@ import { type AskUserHandler, cancelledAskUserResult } from "../tools/ask-user.j
|
|
|
200
217
|
import { registerAllTools } from "../tools/bootstrap.js";
|
|
201
218
|
import { isGitRepository, recoverCleanupReadyCompeteGroups } from "../tools/compete-worktrees.js";
|
|
202
219
|
import { createDispatchBackgroundRegistry } from "../tools/dispatch-background.js";
|
|
220
|
+
import { dispatchSchemaCompositionFor } from "../tools/dispatch-schema.js";
|
|
203
221
|
import { createFileMutationObserver, createSkillActivationObserver } from "../tools/observers.js";
|
|
204
222
|
import { createRegistry } from "../tools/registry.js";
|
|
205
223
|
import { sweepExpiredToolOffloads } from "../tools/result-shaping.js";
|
|
@@ -286,6 +304,8 @@ interface CompactionResolution {
|
|
|
286
304
|
model: EngineModel;
|
|
287
305
|
targetId: string;
|
|
288
306
|
endpointKey: string | null;
|
|
307
|
+
wireModelId: string;
|
|
308
|
+
headers?: Record<string, string>;
|
|
289
309
|
apiKey?: string;
|
|
290
310
|
}
|
|
291
311
|
|
|
@@ -311,53 +331,71 @@ function advanceThinkingLevel(current: ThinkingLevel, available: ReadonlyArray<T
|
|
|
311
331
|
*/
|
|
312
332
|
const LOCAL_API_KEY_FALLBACK = "clio-coder-local-target";
|
|
313
333
|
|
|
314
|
-
async function resolveApiKeyForTarget(
|
|
315
|
-
target: TargetDescriptor,
|
|
316
|
-
providers: ProvidersContract,
|
|
317
|
-
signal?: AbortSignal,
|
|
318
|
-
): Promise<string | undefined> {
|
|
319
|
-
const runtime = providers.getRuntime(target.runtime);
|
|
320
|
-
if (!runtime) return undefined;
|
|
321
|
-
// A target that needs no credential still needs the placeholder. Returning
|
|
322
|
-
// nothing here left compaction as the one path that did not send it, so
|
|
323
|
-
// `/context compact` and every automatic compaction at the window threshold
|
|
324
|
-
// failed on exactly the local runtimes Clio is built for, while ordinary
|
|
325
|
-
// turns against the same target succeeded.
|
|
326
|
-
if (!targetRequiresAuth(target, runtime)) return LOCAL_API_KEY_FALLBACK;
|
|
327
|
-
const resolved = await providers.auth.resolveForTarget(target, runtime, signal ? { signal } : undefined);
|
|
328
|
-
return resolved.apiKey;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
334
|
/**
|
|
332
335
|
* The background memory role, resolved to the endpoint it would call.
|
|
333
336
|
*
|
|
334
|
-
* The endpoint key
|
|
335
|
-
*
|
|
336
|
-
*
|
|
337
|
+
* The endpoint key joins the existing dispatch capacity evidence and local
|
|
338
|
+
* request holds. A gateway key does not identify one physical model server or
|
|
339
|
+
* imply a one-slot limit; the configured protocol owns downstream routing.
|
|
337
340
|
*/
|
|
338
341
|
interface BackgroundMemoryRoute {
|
|
339
342
|
client: TaskMemoryModelClient;
|
|
343
|
+
selection: "dedicated" | "chat-fallback";
|
|
344
|
+
fallbackReason?: string;
|
|
340
345
|
targetId: string;
|
|
341
346
|
wireModelId: string;
|
|
342
347
|
endpointKey: string | null;
|
|
343
348
|
modelMaxTokens(configuredMaxTokens: number): number;
|
|
344
349
|
}
|
|
345
350
|
|
|
346
|
-
function createBackgroundMemoryModelClient(
|
|
351
|
+
export function createBackgroundMemoryModelClient(
|
|
347
352
|
providers: ProvidersContract,
|
|
348
353
|
settings: Readonly<ClioSettings>,
|
|
349
354
|
timeoutMs: number,
|
|
350
355
|
bus: Pick<SafeEventBus, "emit"> | null,
|
|
356
|
+
fallbackOnly = false,
|
|
351
357
|
): BackgroundMemoryRoute | null {
|
|
352
|
-
const
|
|
353
|
-
const
|
|
354
|
-
if (!
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
if (
|
|
358
|
+
const configuredTarget = settings.context.memory.target?.trim();
|
|
359
|
+
const configuredModel = settings.context.memory.model?.trim();
|
|
360
|
+
if (!configuredTarget || !configuredModel) return null;
|
|
361
|
+
const chatTarget = settings.chat.target?.trim();
|
|
362
|
+
const chatModel = settings.chat.model?.trim();
|
|
363
|
+
const sameRoute = configuredTarget === chatTarget && configuredModel === chatModel;
|
|
364
|
+
if (fallbackOnly && sameRoute) return null;
|
|
365
|
+
let fallbackReason: string | undefined;
|
|
366
|
+
if (!fallbackOnly) {
|
|
367
|
+
try {
|
|
368
|
+
return prepareBackgroundMemoryRoute(providers, configuredTarget, configuredModel, timeoutMs, bus, "dedicated");
|
|
369
|
+
} catch {
|
|
370
|
+
fallbackReason = "configured route unavailable";
|
|
371
|
+
}
|
|
372
|
+
} else fallbackReason = "configured route client error";
|
|
373
|
+
if (!chatTarget || !chatModel || sameRoute) {
|
|
374
|
+
if (fallbackOnly) return null;
|
|
375
|
+
throw new Error("configured memory route is unavailable and no distinct chat fallback can run");
|
|
376
|
+
}
|
|
377
|
+
try {
|
|
378
|
+
return {
|
|
379
|
+
...prepareBackgroundMemoryRoute(providers, chatTarget, chatModel, timeoutMs, bus, "chat-fallback"),
|
|
380
|
+
fallbackReason,
|
|
381
|
+
};
|
|
382
|
+
} catch {
|
|
383
|
+
if (fallbackOnly) return null;
|
|
384
|
+
throw new Error("neither the configured memory route nor the active chat fallback is available");
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
function prepareBackgroundMemoryModel(providers: ProvidersContract, targetId: string, wireModelId: string) {
|
|
389
|
+
const status = providers.list().find((entry) => entry.target.id === targetId);
|
|
390
|
+
if (
|
|
391
|
+
status &&
|
|
392
|
+
(!status.available ||
|
|
393
|
+
status.health.status === "down" ||
|
|
394
|
+
(hasLiveModelCatalog(status) && !status.discoveredModels.includes(wireModelId)) ||
|
|
395
|
+
modelResidencyForStatus(status, wireModelId) === "absent" ||
|
|
396
|
+
modelResidencyForStatus(status, wireModelId) === "loading")
|
|
397
|
+
)
|
|
398
|
+
throw new Error("background memory route is unavailable");
|
|
361
399
|
const resolved = resolveRuntimeTarget(providers, {
|
|
362
400
|
targetId,
|
|
363
401
|
wireModelId,
|
|
@@ -377,9 +415,37 @@ function createBackgroundMemoryModelClient(
|
|
|
377
415
|
const model = resolved.target.runtime.synthesizeModel(resolved.target.target, resolved.target.wireModelId, kbHit);
|
|
378
416
|
const refined = refineRuntimeTargetWithModelHints(resolved.target, model, providers.knowledgeBase);
|
|
379
417
|
applyModelCapabilityPatch(model, refined.capabilities);
|
|
380
|
-
|
|
418
|
+
return { model, refined };
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
function backgroundMemoryEndpointBusy(
|
|
422
|
+
providers: ProvidersContract,
|
|
423
|
+
endpointKey: string | null,
|
|
424
|
+
targets: ReadonlyArray<TargetDescriptor>,
|
|
425
|
+
): boolean {
|
|
426
|
+
if (endpointKey === null) return false;
|
|
427
|
+
const capacity = resolveEndpointCapacities({
|
|
428
|
+
statuses: providers.list(),
|
|
429
|
+
targets,
|
|
430
|
+
runtimeFor: (id) => providers.getRuntime(id),
|
|
431
|
+
})[endpointKey];
|
|
432
|
+
// Gateways and non-fixed schedulers have no invented local one-slot cap.
|
|
433
|
+
return capacity !== undefined && (endpointCapacityUsage()[endpointKey] ?? 0) >= capacity.limit;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
function prepareBackgroundMemoryRoute(
|
|
437
|
+
providers: ProvidersContract,
|
|
438
|
+
targetId: string,
|
|
439
|
+
wireModelId: string,
|
|
440
|
+
timeoutMs: number,
|
|
441
|
+
bus: Pick<SafeEventBus, "emit"> | null,
|
|
442
|
+
selection: BackgroundMemoryRoute["selection"],
|
|
443
|
+
): BackgroundMemoryRoute {
|
|
444
|
+
const initial = prepareBackgroundMemoryModel(providers, targetId, wireModelId);
|
|
445
|
+
const { refined } = initial;
|
|
381
446
|
const endpointKey = canonicalEndpointKey(refined.target);
|
|
382
447
|
return {
|
|
448
|
+
selection,
|
|
383
449
|
targetId,
|
|
384
450
|
wireModelId: refined.wireModelId,
|
|
385
451
|
endpointKey,
|
|
@@ -393,47 +459,121 @@ function createBackgroundMemoryModelClient(
|
|
|
393
459
|
// Wrapped at the layer that knows a request left the process: the step
|
|
394
460
|
// holds endpoint capacity while it is out and publishes the cache
|
|
395
461
|
// disturbance even when a timeout means the usage sink never sees it.
|
|
396
|
-
complete:
|
|
462
|
+
complete: async (request) => {
|
|
463
|
+
await prepareBackgroundModelMetadata(providers, targetId, request.signal);
|
|
464
|
+
const { model, refined } = prepareBackgroundMemoryModel(providers, targetId, wireModelId);
|
|
465
|
+
if (refined.runtimeId !== initial.refined.runtimeId || canonicalEndpointKey(refined.target) !== endpointKey) {
|
|
466
|
+
throw new Error("background memory target changed during preparation");
|
|
467
|
+
}
|
|
468
|
+
const costProvenance = normalizeCostProvenance(refined.costProvenance);
|
|
397
469
|
const apiKey = targetRequiresAuth(refined.target, refined.runtime)
|
|
398
470
|
? (await providers.auth.resolveForTarget(refined.target, refined.runtime, { signal: request.signal })).apiKey
|
|
399
471
|
: LOCAL_API_KEY_FALLBACK;
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
...(apiKey === undefined ? {} : { apiKey }),
|
|
413
|
-
});
|
|
414
|
-
// The step is billed here whatever the policy later decides about the
|
|
415
|
-
// answer. A model that read a trajectory and chose silence spent the
|
|
416
|
-
// same prefill as one that produced a reminder.
|
|
417
|
-
return {
|
|
418
|
-
text: completion.text,
|
|
419
|
-
inputTokens: completion.inputTokens,
|
|
420
|
-
outputTokens: completion.outputTokens,
|
|
421
|
-
usage: {
|
|
472
|
+
request.signal.throwIfAborted();
|
|
473
|
+
// Preparation yielded after the middleware's first check. Recheck current
|
|
474
|
+
// occupancy immediately before the synchronous foreground-slot registration;
|
|
475
|
+
// no await may separate this admission from announceMemoryStepEndpoint.
|
|
476
|
+
if (backgroundMemoryEndpointBusy(providers, endpointKey, [refined.target])) {
|
|
477
|
+
throw new TaskMemoryEndpointBusyError("background memory endpoint is busy");
|
|
478
|
+
}
|
|
479
|
+
return announceMemoryStepEndpoint({ bus, endpointKey, targetId }, async () => {
|
|
480
|
+
const startedAt = Date.now();
|
|
481
|
+
let observedUsage: TaskMemoryStepUsage | undefined;
|
|
482
|
+
const mapUsage = (completion: Pick<EngineTextCompletionResult, "usage" | "backend">): TaskMemoryStepUsage => ({
|
|
483
|
+
...completion.usage,
|
|
422
484
|
targetId,
|
|
423
485
|
attributedModelId: refined.wireModelId,
|
|
424
|
-
input: completion.usage.input,
|
|
425
|
-
output: completion.usage.output,
|
|
426
|
-
cacheRead: completion.usage.cacheRead,
|
|
427
|
-
cacheWrite: completion.usage.cacheWrite,
|
|
428
|
-
reasoning: completion.usage.reasoning,
|
|
429
|
-
totalTokens: completion.usage.totalTokens,
|
|
430
|
-
costUsd: completion.usage.costUsd,
|
|
431
486
|
costProvenance,
|
|
432
487
|
durationMs: Date.now() - startedAt,
|
|
433
488
|
backend: completion.backend,
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
|
|
489
|
+
});
|
|
490
|
+
const completion = await completeEngineText({
|
|
491
|
+
model,
|
|
492
|
+
systemPrompt: request.systemPrompt,
|
|
493
|
+
userPrompt: request.userPrompt,
|
|
494
|
+
maxTokens:
|
|
495
|
+
refined.capabilityDecisions.maxTokens > 0
|
|
496
|
+
? Math.min(request.maxTokens, refined.capabilityDecisions.maxTokens)
|
|
497
|
+
: request.maxTokens,
|
|
498
|
+
// Always off, never the operator's chat thinking level. A model that
|
|
499
|
+
// reasons anyway still works: `completeEngineText` keeps only text
|
|
500
|
+
// blocks, and the memory output budget leaves room for the preamble.
|
|
501
|
+
thinkingLevel: "off",
|
|
502
|
+
signal: request.signal,
|
|
503
|
+
timeoutMs,
|
|
504
|
+
onUsage: (observation) => {
|
|
505
|
+
observedUsage = mapUsage(observation);
|
|
506
|
+
request.onUsage?.(observedUsage);
|
|
507
|
+
},
|
|
508
|
+
...(apiKey === undefined ? {} : { apiKey }),
|
|
509
|
+
...(refined.target.auth?.headers ? { headers: refined.target.auth.headers } : {}),
|
|
510
|
+
});
|
|
511
|
+
// The step is billed here whatever the policy later decides about the
|
|
512
|
+
// answer. A model that read a trajectory and chose silence spent the
|
|
513
|
+
// same prefill as one that produced a reminder.
|
|
514
|
+
return {
|
|
515
|
+
text: completion.text,
|
|
516
|
+
inputTokens: completion.inputTokens,
|
|
517
|
+
outputTokens: completion.outputTokens,
|
|
518
|
+
usage: observedUsage ?? mapUsage(completion),
|
|
519
|
+
};
|
|
520
|
+
})(request);
|
|
521
|
+
},
|
|
522
|
+
},
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/** Production callback composition shared with routing/capacity contracts. */
|
|
527
|
+
export function createBackgroundMemoryRouting(
|
|
528
|
+
providers: ProvidersContract,
|
|
529
|
+
getSettings: () => Readonly<ClioSettings> | undefined,
|
|
530
|
+
bus: Pick<SafeEventBus, "emit"> | null,
|
|
531
|
+
) {
|
|
532
|
+
let route: BackgroundMemoryRoute | null = null;
|
|
533
|
+
let snapshot: Readonly<ClioSettings> | undefined;
|
|
534
|
+
let lastNotice: string | null = null;
|
|
535
|
+
const noteFallback = (): void => {
|
|
536
|
+
if (route?.selection !== "chat-fallback") {
|
|
537
|
+
lastNotice = null;
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
540
|
+
const message = `Memory: ${route.fallbackReason}; selected chat fallback ${route.targetId}/${route.wireModelId} for this step, subject to available endpoint capacity.`;
|
|
541
|
+
if (message === lastNotice) return;
|
|
542
|
+
lastNotice = message;
|
|
543
|
+
try {
|
|
544
|
+
bus?.emit(BusChannels.RuntimeNotice, {
|
|
545
|
+
kind: "degraded",
|
|
546
|
+
level: "info",
|
|
547
|
+
message,
|
|
548
|
+
targetId: route.targetId,
|
|
549
|
+
runtimeId: providers.getTarget(route.targetId)?.runtime ?? "unknown",
|
|
550
|
+
model: route.wireModelId,
|
|
551
|
+
});
|
|
552
|
+
} catch {
|
|
553
|
+
/* Advisory only. */
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
return {
|
|
557
|
+
getModelClient: (): TaskMemoryModelClient | null => {
|
|
558
|
+
const current = getSettings();
|
|
559
|
+
snapshot = current === undefined ? undefined : structuredClone(current);
|
|
560
|
+
route =
|
|
561
|
+
snapshot === undefined
|
|
562
|
+
? null
|
|
563
|
+
: createBackgroundMemoryModelClient(providers, snapshot, snapshot.context.memory.timeoutMs, bus);
|
|
564
|
+
noteFallback();
|
|
565
|
+
return route?.client ?? null;
|
|
566
|
+
},
|
|
567
|
+
getFallbackModelClient: (): TaskMemoryModelClient | null => {
|
|
568
|
+
if (route?.selection !== "dedicated" || snapshot === undefined) return null;
|
|
569
|
+
route = createBackgroundMemoryModelClient(providers, snapshot, snapshot.context.memory.timeoutMs, bus, true);
|
|
570
|
+
noteFallback();
|
|
571
|
+
return route?.client ?? null;
|
|
572
|
+
},
|
|
573
|
+
getModelMaxTokens: (configured: number): number => route?.modelMaxTokens(configured) ?? configured,
|
|
574
|
+
backgroundEndpointBusy: (): boolean => {
|
|
575
|
+
if (route?.endpointKey == null || snapshot === undefined) return false;
|
|
576
|
+
return backgroundMemoryEndpointBusy(providers, route.endpointKey, snapshot.targets);
|
|
437
577
|
},
|
|
438
578
|
};
|
|
439
579
|
}
|
|
@@ -471,74 +611,84 @@ function agentRoleToolWarnings(providers: ProvidersContract, settings: Readonly<
|
|
|
471
611
|
return warnings;
|
|
472
612
|
}
|
|
473
613
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
* that model reasons. Distinct models, or a non-reasoning shared model, are both
|
|
477
|
-
* fine; this only catches the one-model-does-everything configuration.
|
|
478
|
-
*/
|
|
479
|
-
function backgroundSharesReasoningModelWithOrchestrator(
|
|
614
|
+
async function resolveCompactionModel(
|
|
615
|
+
settings: ClioSettings,
|
|
480
616
|
providers: ProvidersContract,
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
if (
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
617
|
+
): Promise<CompactionResolution | null> {
|
|
618
|
+
const override = settings.context.compaction.model;
|
|
619
|
+
let targetId = settings.chat.target;
|
|
620
|
+
let wireModelId = settings.chat.model;
|
|
621
|
+
if (override !== undefined && override !== null) {
|
|
622
|
+
let selected: ReturnType<typeof resolveModelReference>;
|
|
623
|
+
try {
|
|
624
|
+
selected = resolveModelReference(override, providers);
|
|
625
|
+
} catch {
|
|
626
|
+
throw new Error("context.compaction.model is an invalid pattern; set a unique target/model reference");
|
|
627
|
+
}
|
|
628
|
+
if (!selected.ref || selected.warning) {
|
|
629
|
+
throw new Error(
|
|
630
|
+
"context.compaction.model must match exactly one configured model; set a unique target/model reference",
|
|
631
|
+
);
|
|
632
|
+
}
|
|
633
|
+
targetId = selected.ref.target;
|
|
634
|
+
wireModelId = selected.ref.model;
|
|
495
635
|
}
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
636
|
+
if (!targetId || !wireModelId) return null;
|
|
637
|
+
await prepareBackgroundModelMetadata(providers, targetId);
|
|
638
|
+
const status = providers.list().find((entry) => entry.target.id === targetId);
|
|
639
|
+
if (!status?.available) {
|
|
640
|
+
throw new Error("context.compaction.model target is unavailable; check the selected target with clio-coder targets");
|
|
641
|
+
}
|
|
642
|
+
const resolved = resolveRuntimeTarget(providers, {
|
|
643
|
+
targetId,
|
|
644
|
+
wireModelId,
|
|
645
|
+
use: "orchestrator",
|
|
646
|
+
requestedThinkingLevel: "off",
|
|
647
|
+
requireTools: false,
|
|
648
|
+
requireStreaming: true,
|
|
649
|
+
requireOutputBudget: true,
|
|
650
|
+
});
|
|
651
|
+
if (!resolved.ok) {
|
|
652
|
+
// Configured identifiers and provider diagnostics can contain terminal controls.
|
|
653
|
+
// Keep the failure actionable without echoing arbitrary provider/config text.
|
|
654
|
+
throw new Error(
|
|
655
|
+
"context.compaction.model cannot run as a summarizer; select an available HTTP chat model with an output budget",
|
|
656
|
+
);
|
|
657
|
+
}
|
|
658
|
+
const route = resolved.target;
|
|
505
659
|
let model: EngineModel;
|
|
506
660
|
try {
|
|
507
|
-
|
|
508
|
-
|
|
661
|
+
model = route.runtime.synthesizeModel(
|
|
662
|
+
route.target,
|
|
663
|
+
route.wireModelId,
|
|
664
|
+
providers.knowledgeBase?.lookup(route.wireModelId) ?? null,
|
|
665
|
+
);
|
|
509
666
|
} catch {
|
|
510
|
-
|
|
667
|
+
throw new Error("context.compaction.model could not be prepared; check the selected target/model configuration");
|
|
511
668
|
}
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
669
|
+
const refined = refineRuntimeTargetWithModelHints(route, model, providers.knowledgeBase);
|
|
670
|
+
if (refined.capabilityDecisions.maxTokens <= 0) {
|
|
671
|
+
throw new Error("context.compaction.model has no output budget; select a model with a known positive output limit");
|
|
672
|
+
}
|
|
673
|
+
applyModelCapabilityPatch(model, refined.capabilities);
|
|
674
|
+
let apiKey: string | undefined = LOCAL_API_KEY_FALLBACK;
|
|
675
|
+
if (targetRequiresAuth(route.target, route.runtime)) {
|
|
676
|
+
const auth = await providers.auth.resolveForTarget(route.target, route.runtime);
|
|
677
|
+
if (!auth.available || !auth.apiKey) {
|
|
678
|
+
throw new Error(
|
|
679
|
+
"context.compaction.model authentication is unavailable; authenticate the selected target with clio-coder auth",
|
|
680
|
+
);
|
|
519
681
|
}
|
|
520
|
-
|
|
521
|
-
// Older test doubles and degraded provider bundles may not expose live
|
|
522
|
-
// status. The synthesized model still carries runtime and catalog caps.
|
|
682
|
+
apiKey = auth.apiKey;
|
|
523
683
|
}
|
|
524
|
-
return
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
const wireModelId = settings.chat?.model ?? null;
|
|
533
|
-
if (!targetId || !wireModelId) return null;
|
|
534
|
-
const target = resolveTarget(providers, targetId);
|
|
535
|
-
if (!target) return null;
|
|
536
|
-
const model = synthesizeOrchestratorModel(providers, target, wireModelId);
|
|
537
|
-
if (!model) return null;
|
|
538
|
-
const apiKey = await resolveApiKeyForTarget(target, providers);
|
|
539
|
-
const resolution: CompactionResolution = { model, targetId, endpointKey: canonicalEndpointKey(target) };
|
|
540
|
-
if (apiKey !== undefined) resolution.apiKey = apiKey;
|
|
541
|
-
return resolution;
|
|
684
|
+
return {
|
|
685
|
+
model,
|
|
686
|
+
targetId: route.targetId,
|
|
687
|
+
wireModelId: route.wireModelId,
|
|
688
|
+
endpointKey: canonicalEndpointKey(route.target),
|
|
689
|
+
apiKey,
|
|
690
|
+
...(route.target.auth?.headers ? { headers: route.target.auth.headers } : {}),
|
|
691
|
+
};
|
|
542
692
|
}
|
|
543
693
|
|
|
544
694
|
function readSessionEntriesForCompact(sessionId: string): SessionEntry[] {
|
|
@@ -643,11 +793,19 @@ async function runCompactionFlow(
|
|
|
643
793
|
providers: ProvidersContract,
|
|
644
794
|
instructions?: string,
|
|
645
795
|
trigger?: CompactionTrigger,
|
|
796
|
+
observability?: BackgroundMemoryUsageSink,
|
|
646
797
|
): Promise<CompactResult | null> {
|
|
647
798
|
const meta = session.current();
|
|
648
799
|
if (!meta) {
|
|
649
800
|
throw new Error("no current session to compact; start one with /new or /resume first");
|
|
650
801
|
}
|
|
802
|
+
const stateDir = clioStateDir();
|
|
803
|
+
const activeLeafTurnId = session.tree(meta.id).leafId ?? undefined;
|
|
804
|
+
const isOriginCurrent = () =>
|
|
805
|
+
session.current()?.id === meta.id && (session.tree(meta.id).leafId ?? undefined) === activeLeafTurnId;
|
|
806
|
+
const entries = filterEntriesToActivePath(readSessionEntriesForCompact(meta.id), activeLeafTurnId);
|
|
807
|
+
if (entries.length === 0) return null;
|
|
808
|
+
const systemPrompt = await readCompactionSystemPrompt(settings.context.compaction.systemPrompt, meta.cwd);
|
|
651
809
|
const resolved = await resolveCompactionModel(settings, providers);
|
|
652
810
|
if (!resolved) {
|
|
653
811
|
throw new Error("no model configured; set chat.target + chat.model");
|
|
@@ -660,11 +818,22 @@ async function runCompactionFlow(
|
|
|
660
818
|
// read the full file too (last taskLedger entry in file order, with no
|
|
661
819
|
// branch filter at all), which was a second, independent instance of this
|
|
662
820
|
// same bug. See the taskBoard wiring below for the fix.
|
|
663
|
-
|
|
664
|
-
const
|
|
665
|
-
|
|
821
|
+
if (!isOriginCurrent()) throw new Error("compaction session or branch changed before summarization");
|
|
822
|
+
const calls: CompactionCallObservation[] = [];
|
|
823
|
+
const preserveCalls = () =>
|
|
824
|
+
recordFailedCompactionCalls(
|
|
825
|
+
{
|
|
826
|
+
stateDir,
|
|
827
|
+
sessionId: meta.id,
|
|
828
|
+
repoIdentity: meta.cwdHash || cwdHash(meta.cwd),
|
|
829
|
+
target: resolved.targetId,
|
|
830
|
+
model: resolved.wireModelId,
|
|
831
|
+
},
|
|
832
|
+
calls,
|
|
833
|
+
isOriginCurrent() ? observability : undefined,
|
|
834
|
+
);
|
|
666
835
|
|
|
667
|
-
// A compaction summary is a full streamed request against
|
|
836
|
+
// A compaction summary is a full streamed request against its resolved target.
|
|
668
837
|
// Hold the same canonical endpoint slot as an ordinary turn, /btw round, or
|
|
669
838
|
// pre-warm so dispatch admission and background memory see its real usage.
|
|
670
839
|
const releaseEndpointSlot = resolved.endpointKey === null ? () => {} : registerForegroundStream(resolved.endpointKey);
|
|
@@ -672,17 +841,39 @@ async function runCompactionFlow(
|
|
|
672
841
|
try {
|
|
673
842
|
result = await compact({
|
|
674
843
|
entries,
|
|
844
|
+
onCall: (call) => calls.push(call),
|
|
675
845
|
model: resolved.model,
|
|
846
|
+
...(systemPrompt !== undefined ? { systemPrompt } : {}),
|
|
847
|
+
...(resolved.headers !== undefined ? { headers: resolved.headers } : {}),
|
|
676
848
|
...(resolved.apiKey !== undefined ? { apiKey: resolved.apiKey } : {}),
|
|
677
849
|
...(instructions !== undefined ? { instructions } : {}),
|
|
678
850
|
});
|
|
851
|
+
} catch (error) {
|
|
852
|
+
try {
|
|
853
|
+
preserveCalls();
|
|
854
|
+
} catch (recordingError) {
|
|
855
|
+
throw new AggregateError([error, recordingError], "compaction failed and its usage could not be fully recorded");
|
|
856
|
+
}
|
|
857
|
+
throw error;
|
|
679
858
|
} finally {
|
|
680
859
|
releaseEndpointSlot();
|
|
681
860
|
}
|
|
682
|
-
if (
|
|
861
|
+
if (!isOriginCurrent()) {
|
|
862
|
+
preserveCalls();
|
|
863
|
+
throw new Error("compaction session or branch changed; summary discarded and originating usage retained");
|
|
864
|
+
}
|
|
865
|
+
if (result.messagesSummarized === 0 || result.summary.length === 0) {
|
|
866
|
+
preserveCalls();
|
|
867
|
+
if (calls.length > 0) throw new Error("compaction returned no summary; reported usage retained without a checkpoint");
|
|
868
|
+
return null;
|
|
869
|
+
}
|
|
870
|
+
if (result.usage) {
|
|
871
|
+
result.usage = { ...result.usage, targetId: resolved.targetId, modelId: resolved.wireModelId };
|
|
872
|
+
}
|
|
683
873
|
|
|
684
|
-
const entry: Omit<CompactionSummaryEntry, "
|
|
874
|
+
const entry: Omit<CompactionSummaryEntry, "timestamp"> = {
|
|
685
875
|
kind: "compactionSummary",
|
|
876
|
+
turnId: randomUUID(),
|
|
686
877
|
parentTurnId: result.firstKeptTurnId ?? null,
|
|
687
878
|
summary: result.summary,
|
|
688
879
|
tokensBefore: result.tokensBefore,
|
|
@@ -696,22 +887,61 @@ async function runCompactionFlow(
|
|
|
696
887
|
...(result.usage !== undefined ? { usage: result.usage } : {}),
|
|
697
888
|
};
|
|
698
889
|
if (trigger !== undefined) entry.trigger = trigger;
|
|
699
|
-
|
|
890
|
+
try {
|
|
891
|
+
session.appendEntry(entry);
|
|
892
|
+
} catch (error) {
|
|
893
|
+
// A write may have reached the ledger before its caller threw. Reconcile
|
|
894
|
+
// this exact checkpoint identity before choosing a second accounting store.
|
|
895
|
+
try {
|
|
896
|
+
if (!compactionCheckpointWasWritten(sessionPaths(meta).current, entry.turnId)) preserveCalls();
|
|
897
|
+
} catch (recordingError) {
|
|
898
|
+
throw new AggregateError(
|
|
899
|
+
[error, recordingError],
|
|
900
|
+
"compaction checkpoint persistence is unresolved; usage was not duplicated",
|
|
901
|
+
);
|
|
902
|
+
}
|
|
903
|
+
throw error;
|
|
904
|
+
}
|
|
700
905
|
return result;
|
|
701
906
|
}
|
|
702
907
|
|
|
908
|
+
function compactionCheckpointWasWritten(path: string, turnId: string): boolean {
|
|
909
|
+
let malformed = false;
|
|
910
|
+
for (const line of readFileSync(path, "utf8").split("\n")) {
|
|
911
|
+
if (line.trim().length === 0) continue;
|
|
912
|
+
try {
|
|
913
|
+
const entry: unknown = JSON.parse(line);
|
|
914
|
+
if (
|
|
915
|
+
entry &&
|
|
916
|
+
typeof entry === "object" &&
|
|
917
|
+
"turnId" in entry &&
|
|
918
|
+
entry.turnId === turnId &&
|
|
919
|
+
"kind" in entry &&
|
|
920
|
+
entry.kind === "compactionSummary"
|
|
921
|
+
)
|
|
922
|
+
return true;
|
|
923
|
+
} catch {
|
|
924
|
+
malformed = true;
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
if (malformed) throw new Error("cannot prove checkpoint absence in a malformed session ledger");
|
|
928
|
+
return false;
|
|
929
|
+
}
|
|
930
|
+
|
|
703
931
|
/**
|
|
704
932
|
* Compose the production chat-loop compaction callback. Errors intentionally
|
|
705
933
|
* propagate: the chat loop owns activity failure reporting and distinguishes
|
|
706
934
|
* a thrown read/model/persistence failure from the legitimate null no-op that
|
|
707
935
|
* `runCompactionFlow` returns for an empty session or an unavailable cut.
|
|
708
936
|
*/
|
|
709
|
-
function createProductionAutoCompact(
|
|
937
|
+
export function createProductionAutoCompact(
|
|
710
938
|
session: SessionContract,
|
|
711
939
|
getSettings: () => ClioSettings,
|
|
712
940
|
providers: ProvidersContract,
|
|
941
|
+
observability?: BackgroundMemoryUsageSink,
|
|
713
942
|
): (instructions?: string, trigger?: CompactionTrigger) => Promise<CompactResult | null> {
|
|
714
|
-
return (instructions, trigger) =>
|
|
943
|
+
return (instructions, trigger) =>
|
|
944
|
+
runCompactionFlow(session, getSettings(), providers, instructions, trigger, observability);
|
|
715
945
|
}
|
|
716
946
|
|
|
717
947
|
function estimateTokensFromSummary(summary: string): number {
|
|
@@ -1026,7 +1256,7 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1026
1256
|
else resolvedResumeId = latest.id;
|
|
1027
1257
|
}
|
|
1028
1258
|
}
|
|
1029
|
-
const resumeId = resolvedResumeId
|
|
1259
|
+
const resumeId = resolvedResumeId;
|
|
1030
1260
|
let resumedSessionAtBoot = false;
|
|
1031
1261
|
if (resumeId && session && headlessResumeFailure === null) {
|
|
1032
1262
|
try {
|
|
@@ -1038,7 +1268,6 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1038
1268
|
else bootStderr(`Clio Coder: failed to resume session ${resumeId}: ${detail}\n`);
|
|
1039
1269
|
}
|
|
1040
1270
|
}
|
|
1041
|
-
Reflect.deleteProperty(process.env, "CLIO_CODER_RESUME_SESSION_ID");
|
|
1042
1271
|
if (headlessResumeFailure !== null) {
|
|
1043
1272
|
bootStderr(`clio-coder run: ${headlessResumeFailure}\n`);
|
|
1044
1273
|
await termination.shutdown(2);
|
|
@@ -1050,6 +1279,20 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1050
1279
|
// middleware.hookFailed (the interactive warn notice consumes it) and keep
|
|
1051
1280
|
// stderr for non-interactive runs, which have no notice subscriber.
|
|
1052
1281
|
middleware.setDiagnosticSink((diagnostic) => {
|
|
1282
|
+
if (diagnostic.kind === "registration_conflict") {
|
|
1283
|
+
// Registration bookkeeping has no hook occurrence; the affected owner
|
|
1284
|
+
// today declares user hooks, which never run on on_compaction, so the
|
|
1285
|
+
// payload's hook slot carries that as the "no evaluation" marker.
|
|
1286
|
+
bus.emit(BusChannels.MiddlewareHookFailed, {
|
|
1287
|
+
kind: "registration_conflict",
|
|
1288
|
+
registrationId: diagnostic.registrationId,
|
|
1289
|
+
hook: "on_compaction",
|
|
1290
|
+
at: Date.now(),
|
|
1291
|
+
message: formatRegistrationConflict(diagnostic),
|
|
1292
|
+
});
|
|
1293
|
+
if (!interactive) writeMiddlewareDiagnosticToStderr(diagnostic);
|
|
1294
|
+
return;
|
|
1295
|
+
}
|
|
1053
1296
|
bus.emit(BusChannels.MiddlewareHookFailed, {
|
|
1054
1297
|
kind: diagnostic.kind,
|
|
1055
1298
|
registrationId: diagnostic.registrationId,
|
|
@@ -1082,15 +1325,14 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1082
1325
|
});
|
|
1083
1326
|
}
|
|
1084
1327
|
|
|
1085
|
-
//
|
|
1086
|
-
//
|
|
1087
|
-
// settings section before any guard registration or tool reads it.
|
|
1328
|
+
// Install guardrail policy before any guard registration or tool reads it.
|
|
1329
|
+
// The effective session view replaces this boot projection below.
|
|
1088
1330
|
const resolvedSettings = config?.get() ?? readSettings();
|
|
1089
1331
|
configureGuardrails(guardrailValuesFromSettings(resolvedSettings));
|
|
1090
1332
|
|
|
1091
|
-
// The
|
|
1092
|
-
//
|
|
1093
|
-
//
|
|
1333
|
+
// The journal sink sits on the dispatch event path, where reading settings
|
|
1334
|
+
// would be both a cost and a throw site. The effective session view replaces
|
|
1335
|
+
// this boot projection below.
|
|
1094
1336
|
configureRunEventJournal(resolvedSettings.fleet.history.journal);
|
|
1095
1337
|
|
|
1096
1338
|
// Guard registrations on the middleware contract, in order: loop guard,
|
|
@@ -1104,7 +1346,7 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1104
1346
|
safety,
|
|
1105
1347
|
bus,
|
|
1106
1348
|
turnBlockBudget: INTERACTIVE_LOOP_BLOCK_BUDGET,
|
|
1107
|
-
turnToolCallBudget: readOrchTurnToolCallBudget(),
|
|
1349
|
+
turnToolCallBudget: () => readOrchTurnToolCallBudget(),
|
|
1108
1350
|
// Interactive/headless/ACP all share this orchestrator guard: at the
|
|
1109
1351
|
// block budget, lock tools for the rest of the turn so the model
|
|
1110
1352
|
// answers from what it gathered instead of hard-cancelling a turn that
|
|
@@ -1154,37 +1396,12 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1154
1396
|
middleware.registerHook(
|
|
1155
1397
|
createSkillActivationObserver((activation) => appendSkillActivationRegistryEvent(session, activation)),
|
|
1156
1398
|
);
|
|
1157
|
-
// First-turn skills reminder: user-message-visible text is the one channel
|
|
1158
|
-
// the battery-tested local models act on; suggestion protocol only, the
|
|
1159
|
-
// operator load gate is untouched.
|
|
1160
|
-
if (resources) {
|
|
1161
|
-
middleware.registerHook(
|
|
1162
|
-
createSkillsReminderRegistration({
|
|
1163
|
-
countModelVisibleSkills: () => modelVisibleSkills(resources.skills(process.cwd()).items).length,
|
|
1164
|
-
// Same lookup context(scope="skills") lists under its Marketplace
|
|
1165
|
-
// heading, minus what is already installed, so the count the
|
|
1166
|
-
// reminder quotes is the count the listing will show.
|
|
1167
|
-
countInstallableSkills: () => {
|
|
1168
|
-
const installed = new Set(resources.skills(process.cwd()).items.map((skill) => skill.name));
|
|
1169
|
-
return discoverMarketplaceSkills({ cwd: process.cwd() }).skills.filter((skill) => !installed.has(skill.name))
|
|
1170
|
-
.length;
|
|
1171
|
-
},
|
|
1172
|
-
}),
|
|
1173
|
-
);
|
|
1174
|
-
}
|
|
1175
1399
|
// Task-board reminder: same user-message-visible channel, fired once per
|
|
1176
1400
|
// session when a request literally enumerates three or more steps. The
|
|
1177
1401
|
// static routing line and tasks hint ask for the same board; battery-tested
|
|
1178
1402
|
// local models only comply when the instruction rides the user message.
|
|
1179
1403
|
middleware.registerHook(createTaskBoardReminderRegistration());
|
|
1180
1404
|
const taskMemoryBank = new TaskMemoryBank();
|
|
1181
|
-
let taskMemorySessionId = session?.current()?.id ?? null;
|
|
1182
|
-
const ensureTaskMemorySession = (): void => {
|
|
1183
|
-
const currentSessionId = session?.current()?.id ?? null;
|
|
1184
|
-
if (currentSessionId === taskMemorySessionId) return;
|
|
1185
|
-
taskMemoryBank.clear();
|
|
1186
|
-
taskMemorySessionId = currentSessionId;
|
|
1187
|
-
};
|
|
1188
1405
|
const memorySettings = (config?.get() ?? readSettings()).context.memory;
|
|
1189
1406
|
// Bound late: the registration is built here, but the buffer a deferred
|
|
1190
1407
|
// reminder lands in belongs to the chat loop that has not been composed yet.
|
|
@@ -1199,7 +1416,6 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1199
1416
|
const memoryTrace = memoryTracePath === null ? null : createTaskMemoryTrace(memoryTracePath);
|
|
1200
1417
|
// The route the last resolved memory client would call, kept so the endpoint
|
|
1201
1418
|
// check and the cost row read the same resolution the step itself used.
|
|
1202
|
-
let backgroundMemoryRoute: BackgroundMemoryRoute | null = null;
|
|
1203
1419
|
/**
|
|
1204
1420
|
* Account for one background memory step exactly as a `/btw` side question is
|
|
1205
1421
|
* accounted for: the in-process cost tracker under its own label so `/cost`
|
|
@@ -1208,23 +1424,16 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1208
1424
|
*
|
|
1209
1425
|
* Accounting only. The client wrapper (`announceMemoryStepEndpoint`) holds the
|
|
1210
1426
|
* endpoint slot and publishes the disturbance; it sees the timed-out and
|
|
1211
|
-
* thrown steps
|
|
1427
|
+
* thrown steps that report no usage. Late reported usage still reaches this sink.
|
|
1212
1428
|
*/
|
|
1213
|
-
const
|
|
1429
|
+
const captureBackgroundMemoryUsage = () => {
|
|
1214
1430
|
const meta = session?.current() ?? null;
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
// --repo` selects these rows with the same hash it selects ledgers with.
|
|
1222
|
-
repoIdentity: meta ? meta.cwdHash || cwdHash(meta.cwd || process.cwd()) : null,
|
|
1223
|
-
...(observability === undefined ? {} : { observability }),
|
|
1224
|
-
});
|
|
1225
|
-
} catch {
|
|
1226
|
-
// Accounting is bookkeeping. Its failure never reaches the memory step.
|
|
1227
|
-
}
|
|
1431
|
+
return captureTaskMemoryUsage({
|
|
1432
|
+
stateDir: clioStateDir(),
|
|
1433
|
+
sessionId: meta?.id ?? null,
|
|
1434
|
+
repoIdentity: meta ? meta.cwdHash || cwdHash(meta.cwd || process.cwd()) : null,
|
|
1435
|
+
...(observability === undefined ? {} : { observability }),
|
|
1436
|
+
});
|
|
1228
1437
|
};
|
|
1229
1438
|
const proposeInjectedMemoryEntries = (entries: ReadonlyArray<TaskMemoryEntry>): void => {
|
|
1230
1439
|
const meta = session?.current() ?? null;
|
|
@@ -1253,7 +1462,6 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1253
1462
|
deliversDeferredReminders: options.headless === undefined,
|
|
1254
1463
|
onDeferredReminder: (message) => deferredMemoryReminderSink?.(message),
|
|
1255
1464
|
getSettings: () => {
|
|
1256
|
-
ensureTaskMemorySession();
|
|
1257
1465
|
const memory = effectiveSettingsForDispatch?.().context.memory ?? memorySettings;
|
|
1258
1466
|
return {
|
|
1259
1467
|
enabled: memory.enabled,
|
|
@@ -1263,34 +1471,17 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1263
1471
|
timeoutMs: memory.timeoutMs,
|
|
1264
1472
|
};
|
|
1265
1473
|
},
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
backgroundMemoryRoute =
|
|
1269
|
-
settings === undefined
|
|
1270
|
-
? null
|
|
1271
|
-
: createBackgroundMemoryModelClient(providers, settings, settings.context.memory.timeoutMs, bus);
|
|
1272
|
-
return backgroundMemoryRoute?.client ?? null;
|
|
1273
|
-
},
|
|
1274
|
-
getModelMaxTokens: (configuredMaxTokens) =>
|
|
1275
|
-
backgroundMemoryRoute?.modelMaxTokens(configuredMaxTokens) ?? configuredMaxTokens,
|
|
1276
|
-
// A single-slot local server serves one request at a time, so a memory step
|
|
1277
|
-
// started while the operator's turn is streaming either waits behind it or
|
|
1278
|
-
// makes the server swap the resident model out to answer. The chat loop
|
|
1279
|
-
// registers its stream on the endpoint it streams against, so the two are
|
|
1280
|
-
// compared by the same canonical key dispatch admission counts slots on.
|
|
1281
|
-
backgroundEndpointBusy: () => {
|
|
1282
|
-
const endpointKey = backgroundMemoryRoute?.endpointKey ?? null;
|
|
1283
|
-
if (endpointKey === null) return false;
|
|
1284
|
-
// This runs before the client wrapper registers the admitted step, so the
|
|
1285
|
-
// count contains other requests only and the step cannot refuse itself.
|
|
1286
|
-
return (foregroundStreamUsage()[endpointKey] ?? 0) > 0;
|
|
1287
|
-
},
|
|
1288
|
-
onStepUsage: (usage) => recordBackgroundMemoryUsage(usage),
|
|
1474
|
+
...createBackgroundMemoryRouting(providers, () => effectiveSettingsForDispatch?.(), bus),
|
|
1475
|
+
captureStepUsage: captureBackgroundMemoryUsage,
|
|
1289
1476
|
onInjectedEntries: (entries) => proposeInjectedMemoryEntries(entries),
|
|
1290
1477
|
});
|
|
1291
1478
|
middleware.registerHook(memoryIntervention);
|
|
1292
1479
|
const unsubscribeMemoryLoop = bus.on(BusChannels.LoopBlocked, () => memoryIntervention.signalLoop());
|
|
1293
|
-
|
|
1480
|
+
const disposeMemoryLifecycle = bindTaskMemoryLifecycle(bus, memoryIntervention);
|
|
1481
|
+
termination.onDrain(() => {
|
|
1482
|
+
unsubscribeMemoryLoop();
|
|
1483
|
+
disposeMemoryLifecycle();
|
|
1484
|
+
});
|
|
1294
1485
|
if (contextDomain) {
|
|
1295
1486
|
middleware.registerHook(createFileMutationObserver(({ paths }) => contextDomain.noteFileChanges(paths)));
|
|
1296
1487
|
}
|
|
@@ -1299,24 +1490,26 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1299
1490
|
// same effect machinery. They register after the guards, so safety stays
|
|
1300
1491
|
// authoritative: a hook may add effects (including request block_tool) but
|
|
1301
1492
|
// cannot grant a permission safety would deny. Loading is best-effort.
|
|
1493
|
+
// The coordinator is the only writer of the "user-hooks" owner and the only
|
|
1494
|
+
// caller of the extensions reload; it publishes the extension generation
|
|
1495
|
+
// and the hook registrations with two adjacent assignments on one stack
|
|
1496
|
+
// and emits extensions.reloaded only after both. The boot generation is
|
|
1497
|
+
// published here too (the extensions bundle publishes nothing at start),
|
|
1498
|
+
// so no consumer ever sees extension resources paired with hooks from a
|
|
1499
|
+
// different generation. The owner slot is anchored here, so user hooks
|
|
1500
|
+
// keep evaluating after the guards and before the assessors below.
|
|
1302
1501
|
const hookReceiptLog = createHookReceiptLog({ persistPath: join(clioStateDir(), "hook-receipts.json") });
|
|
1303
|
-
const
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
cwd: process.cwd(),
|
|
1308
|
-
extensions: extensionHookRoots,
|
|
1309
|
-
registerHook: (registration) => middleware.registerHook(registration),
|
|
1502
|
+
const extensionReload = createExtensionReloadCoordinator({
|
|
1503
|
+
extensions,
|
|
1504
|
+
middleware,
|
|
1505
|
+
cwd: () => process.cwd(),
|
|
1310
1506
|
recordReceipt: (receipt) => hookReceiptLog.record(receipt),
|
|
1507
|
+
report: (line) => {
|
|
1508
|
+
if (!interactive) process.stderr.write(`${line}\n`);
|
|
1509
|
+
},
|
|
1510
|
+
onCommitted: (event) => bus.emit(BusChannels.ExtensionsReloaded, event),
|
|
1311
1511
|
});
|
|
1312
|
-
|
|
1313
|
-
for (const issue of userHooks.fileIssues) {
|
|
1314
|
-
process.stderr.write(`[clio-coder:hooks] ${issue.message}\n`);
|
|
1315
|
-
}
|
|
1316
|
-
for (const issue of userHooks.issues) {
|
|
1317
|
-
process.stderr.write(`[clio-coder:hooks] ${issue.source.sourcePath}#${issue.index}: ${issue.issues.join("; ")}\n`);
|
|
1318
|
-
}
|
|
1319
|
-
}
|
|
1512
|
+
extensionReload.applyBoot();
|
|
1320
1513
|
termination.onDrain(() => hookReceiptLog.flush());
|
|
1321
1514
|
// Autonomy is hot-reloaded for interactive and headless admissions. ACP
|
|
1322
1515
|
// server prompts use the snapshot captured at session/new.
|
|
@@ -1331,17 +1524,34 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1331
1524
|
(config?.get() ?? readSettings()).safety.autonomy ??
|
|
1332
1525
|
"auto-edit";
|
|
1333
1526
|
const resolveEffectiveAutonomy = (): AutonomyLevel => activeAcpSessionAutonomy ?? resolveBaselineAutonomy();
|
|
1527
|
+
// First-turn skills reminder: user-message-visible text is the one channel
|
|
1528
|
+
// the battery-tested local models act on. Which protocol it teaches follows
|
|
1529
|
+
// the effective autonomy level, resolved one line up: suggest-and-wait at
|
|
1530
|
+
// read-only and suggest, load-it-yourself at auto-edit and full-auto.
|
|
1531
|
+
if (resources) {
|
|
1532
|
+
middleware.registerHook(
|
|
1533
|
+
createSkillsReminderRegistration({
|
|
1534
|
+
countModelVisibleSkills: () => modelVisibleSkills(resources.skills(process.cwd()).items).length,
|
|
1535
|
+
// Same lookup context(scope="skills") lists under its Marketplace
|
|
1536
|
+
// heading, minus what is already installed, so the count the
|
|
1537
|
+
// reminder quotes is the count the listing will show.
|
|
1538
|
+
countInstallableSkills: () => {
|
|
1539
|
+
const installed = new Set(resources.skills(process.cwd()).items.map((skill) => skill.name));
|
|
1540
|
+
return discoverMarketplaceSkills({ cwd: process.cwd() }).skills.filter((skill) => !installed.has(skill.name))
|
|
1541
|
+
.length;
|
|
1542
|
+
},
|
|
1543
|
+
modelMayActivateSkills: () => modelMayActivateSkills(resolveEffectiveAutonomy()),
|
|
1544
|
+
}),
|
|
1545
|
+
);
|
|
1546
|
+
}
|
|
1334
1547
|
// Marketplace self-promotion: coordinator-only by this wiring (never a
|
|
1335
|
-
// dispatch worker), local matcher
|
|
1336
|
-
//
|
|
1337
|
-
// registration. Registered here because it needs the effective-autonomy
|
|
1338
|
-
// resolution defined one line up.
|
|
1548
|
+
// dispatch worker), local matcher and operator-consented installs at every autonomy level. The
|
|
1549
|
+
// registration also checks the own-marketplace source gate before installing.
|
|
1339
1550
|
if (resources) {
|
|
1340
1551
|
middleware.registerHook(
|
|
1341
1552
|
createMarketplaceOfferRegistration({
|
|
1342
1553
|
listInstalledSkillNames: () => resources.skills(process.cwd()).items.map((skill) => skill.name),
|
|
1343
1554
|
listMarketplaceEntries: () => discoverMarketplaceSkills({ cwd: process.cwd() }).skills,
|
|
1344
|
-
getAutonomy: resolveEffectiveAutonomy,
|
|
1345
1555
|
installEntry: (entry, scope) => {
|
|
1346
1556
|
const installed = installSkill({ source: entry.sourceUrl, scope, name: entry.name, cwd: process.cwd() });
|
|
1347
1557
|
return { path: installed.path, sourceUrl: installed.sourceUrl, installedHash: installed.installedHash };
|
|
@@ -1494,6 +1704,7 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1494
1704
|
...(panes && mux?.mode !== "none" ? { panes } : {}),
|
|
1495
1705
|
getCostCeilingUsd: () => result.getContract<SchedulingContract>("scheduling")?.ceilingUsd() ?? 0,
|
|
1496
1706
|
...(config ? { getWorkerRosters: () => config.get().fleet.rosters } : {}),
|
|
1707
|
+
...(config ? { getDispatchSchemaComposition: () => dispatchSchemaCompositionFor(config.get().fleet) } : {}),
|
|
1497
1708
|
getSkillLoaderOptions: () => ({
|
|
1498
1709
|
trustProjectCompatRoots: config?.get().integrations.projectResources.trustProjectImports === true,
|
|
1499
1710
|
disableDiscovery: options.noSkills === true || options.headless?.noSkills === true,
|
|
@@ -1518,8 +1729,13 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1518
1729
|
// view, so the live session reflects them immediately while settings.yaml
|
|
1519
1730
|
// (the global default for new sessions) stays untouched until the operator
|
|
1520
1731
|
// chooses to save globally.
|
|
1732
|
+
// Overrides are keyed by settings path, the same ids the /settings overlay
|
|
1733
|
+
// commits (`setAtPath` walks the dotted path). The headless `--autonomy`
|
|
1734
|
+
// flag was keyed by the bare word, which wrote a top-level `autonomy` key
|
|
1735
|
+
// nothing reads, so `run --autonomy full-auto` compiled and admitted at
|
|
1736
|
+
// whatever settings.yaml said.
|
|
1521
1737
|
const sessionOverrides: SessionOverrides = new Map(
|
|
1522
|
-
options.headless?.autonomy === undefined ? [] : [["autonomy", options.headless.autonomy]],
|
|
1738
|
+
options.headless?.autonomy === undefined ? [] : [["safety.autonomy", options.headless.autonomy]],
|
|
1523
1739
|
);
|
|
1524
1740
|
// The effective view is derived by deep-cloning the saved snapshot, and it
|
|
1525
1741
|
// is read on the tool-admission hot path (every call resolves autonomy
|
|
@@ -1534,9 +1750,10 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1534
1750
|
let cachedSettingsView: ClioSettings | null = null;
|
|
1535
1751
|
const bumpSessionState = (): void => {
|
|
1536
1752
|
sessionStateGeneration += 1;
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1753
|
+
const settings = getCurrentSettings();
|
|
1754
|
+
configureGuardrails(guardrailValuesFromSettings(settings));
|
|
1755
|
+
configureRunEventJournal(settings.fleet.history.journal);
|
|
1756
|
+
setGitCommitAttributionEnabled(settings.integrations.git.commitAttribution);
|
|
1540
1757
|
};
|
|
1541
1758
|
const getCurrentSettings = (): ClioSettings => {
|
|
1542
1759
|
// Recents live in the data dir (core/recent-models.ts), never in
|
|
@@ -1562,15 +1779,15 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1562
1779
|
};
|
|
1563
1780
|
effectiveSettingsForDispatch = getCurrentSettings;
|
|
1564
1781
|
bumpSessionState();
|
|
1565
|
-
// The config bundle publishes
|
|
1566
|
-
//
|
|
1567
|
-
|
|
1568
|
-
|
|
1782
|
+
// The config bundle publishes saved values on reload; session-scoped
|
|
1783
|
+
// overrides must win, so re-derive every process-local projection from the
|
|
1784
|
+
// effective session view after it.
|
|
1785
|
+
const unsubscribeSettingsProjectionSync = bus.on(BusChannels.ConfigHotReload, () => bumpSessionState());
|
|
1786
|
+
termination.onDrain(() => unsubscribeSettingsProjectionSync());
|
|
1569
1787
|
const getTaskMemorySeedOffer = (): { source: string; count: number } | null => {
|
|
1570
1788
|
return taskMemoryHandoffSeedOffer(process.cwd(), getCurrentSettings().context.memory.enabled);
|
|
1571
1789
|
};
|
|
1572
1790
|
const seedCurrentTaskMemoryFromHandoff = () => {
|
|
1573
|
-
ensureTaskMemorySession();
|
|
1574
1791
|
return seedTaskMemoryFromNewestHandoff(taskMemoryBank, process.cwd(), getCurrentSettings().context.memory.enabled);
|
|
1575
1792
|
};
|
|
1576
1793
|
if (resumedSessionAtBoot) {
|
|
@@ -1812,6 +2029,7 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1812
2029
|
return key === null ? null : registerForegroundStream(key);
|
|
1813
2030
|
},
|
|
1814
2031
|
getSettings: getCurrentSettings,
|
|
2032
|
+
getAutonomy: resolveEffectiveAutonomy,
|
|
1815
2033
|
providers,
|
|
1816
2034
|
middleware,
|
|
1817
2035
|
middlewareToolChoice,
|
|
@@ -1840,7 +2058,6 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1840
2058
|
}
|
|
1841
2059
|
},
|
|
1842
2060
|
getTaskMemoryHandoffSource: () => {
|
|
1843
|
-
ensureTaskMemorySession();
|
|
1844
2061
|
const meta = session?.current();
|
|
1845
2062
|
if (!meta) throw new Error("task memory handoff requires an active session");
|
|
1846
2063
|
const settings = getCurrentSettings();
|
|
@@ -1865,7 +2082,7 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1865
2082
|
...(session
|
|
1866
2083
|
? {
|
|
1867
2084
|
readSessionEntries: readCurrentSessionEntries,
|
|
1868
|
-
autoCompact: createProductionAutoCompact(session, getCurrentSettings, providers),
|
|
2085
|
+
autoCompact: createProductionAutoCompact(session, getCurrentSettings, providers, observability),
|
|
1869
2086
|
}
|
|
1870
2087
|
: {}),
|
|
1871
2088
|
toolRegistry,
|
|
@@ -1892,7 +2109,7 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
1892
2109
|
await chat.whenSettled();
|
|
1893
2110
|
});
|
|
1894
2111
|
|
|
1895
|
-
// A boot-time resume (
|
|
2112
|
+
// A boot-time resume (headless --session or --continue) must replay the resumed
|
|
1896
2113
|
// session into the chat loop the same way the interactive /resume overlay
|
|
1897
2114
|
// does. Without this, the first submit runs with an empty provider context
|
|
1898
2115
|
// and parents its user turn at null, appending a second root that silently
|
|
@@ -2117,6 +2334,7 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
2117
2334
|
...(initialNotices.length > 0 ? { initialNotices } : {}),
|
|
2118
2335
|
...(resources ? { resources } : {}),
|
|
2119
2336
|
...(extensions ? { extensions } : {}),
|
|
2337
|
+
reloadExtensions: () => extensionReload.reload(),
|
|
2120
2338
|
...(interop ? { interop } : {}),
|
|
2121
2339
|
...(share ? { share } : {}),
|
|
2122
2340
|
...(mux ? { mux } : {}),
|
|
@@ -2141,7 +2359,6 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
2141
2359
|
supersedeDecision: (interviewId, key, correction) => decisionBoard.supersede(interviewId, key, correction),
|
|
2142
2360
|
userTasks,
|
|
2143
2361
|
getTaskMemoryStatus: () => {
|
|
2144
|
-
ensureTaskMemorySession();
|
|
2145
2362
|
const settings = getCurrentSettings();
|
|
2146
2363
|
const bank = taskMemoryBank.snapshot();
|
|
2147
2364
|
return {
|
|
@@ -2295,10 +2512,8 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
2295
2512
|
? {
|
|
2296
2513
|
onResumeSession: (sessionId) => {
|
|
2297
2514
|
try {
|
|
2298
|
-
const previousSessionId = session.current()?.id ?? null;
|
|
2299
2515
|
session.resume(sessionId);
|
|
2300
2516
|
taskBoard.snapshot();
|
|
2301
|
-
if (previousSessionId !== sessionId) ensureTaskMemorySession();
|
|
2302
2517
|
} catch (err) {
|
|
2303
2518
|
process.stderr.write(
|
|
2304
2519
|
`[/resume] failed to resume ${sessionId}: ${err instanceof Error ? err.message : String(err)}\n`,
|
|
@@ -2312,13 +2527,11 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
|
|
|
2312
2527
|
if (settings.chat.model) input.model = settings.chat.model;
|
|
2313
2528
|
session.create(input);
|
|
2314
2529
|
taskBoard.snapshot();
|
|
2315
|
-
ensureTaskMemorySession();
|
|
2316
2530
|
},
|
|
2317
2531
|
onForkSession: (parentTurnId) => {
|
|
2318
2532
|
try {
|
|
2319
2533
|
session.fork(parentTurnId);
|
|
2320
2534
|
taskBoard.snapshot();
|
|
2321
|
-
ensureTaskMemorySession();
|
|
2322
2535
|
} catch (err) {
|
|
2323
2536
|
process.stderr.write(
|
|
2324
2537
|
`[/fork] failed at turn ${parentTurnId}: ${err instanceof Error ? err.message : String(err)}\n`,
|