@iowarp/clio-coder 0.4.2 → 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 +35 -0
- package/CONTRIBUTING.md +86 -19
- package/README.md +35 -6
- package/dist/{acp-TMDQZDIG.js → acp-H2NGRPWO.js} +11 -11
- package/dist/{agents-5N5NG3XG.js → agents-TL5LLUQP.js} +54 -53
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-Z5CCBXKQ.js → auth-E5SW4HMS.js} +19 -16
- package/dist/{builtins-K6TNDT24.js → builtins-IA7V7FUC.js} +9 -4
- package/dist/{chunk-ZW4HH5JJ.js → chunk-2APPQIER.js} +6 -6
- package/dist/{chunk-72GZI5EV.js → chunk-2JH2WHGE.js} +2 -2
- package/dist/{chunk-UBRFI4HS.js → chunk-2UG5F4C5.js} +127 -47
- package/dist/{chunk-UH632ZYL.js → chunk-2UH2KFUP.js} +2 -2
- package/dist/{chunk-3F7VUY77.js → chunk-2VIKGWFZ.js} +2 -2
- package/dist/{chunk-I66EAJFY.js → chunk-2WZ546HR.js} +267 -232
- package/dist/{chunk-RKSR6VSF.js → chunk-4IUZQIJ3.js} +29 -1
- package/dist/{chunk-2X4RYJTJ.js → chunk-4UVU7BJ5.js} +2 -2
- package/dist/{chunk-M2DAX4F6.js → chunk-4WR7VSYB.js} +2 -2
- package/dist/{chunk-5KW52TEP.js → chunk-54CBCGIR.js} +5 -5
- package/dist/{chunk-3KIPBMUA.js → chunk-5ICU3EUH.js} +2 -2
- package/dist/{chunk-77QIVUZB.js → chunk-5MEZN6CB.js} +4 -4
- package/dist/{chunk-O42A54GG.js → chunk-5OIVVPHF.js} +2 -2
- package/dist/{chunk-LJID3DYZ.js → chunk-64I3JVYM.js} +2 -2
- package/dist/{chunk-4JDLP6ZS.js → chunk-6PTFB5VS.js} +7 -7
- package/dist/{chunk-VN3SHNBN.js → chunk-7DICMOS6.js} +2 -2
- package/dist/{chunk-HLAFFSEK.js → chunk-7DRAWPTZ.js} +2 -2
- package/dist/chunk-7E7I3WLS.js +3762 -0
- package/dist/{chunk-YJISEZKC.js → chunk-7ZYNNDKC.js} +6 -6
- package/dist/{chunk-I66ZTYNP.js → chunk-AF4YM7Z4.js} +236 -101
- package/dist/{chunk-2HFQNRV3.js → chunk-AX2THNSA.js} +12 -12
- package/dist/{chunk-PGF63K6I.js → chunk-B4OAX3SI.js} +65 -3
- package/dist/{chunk-W6NIE6OW.js → chunk-B4VEBZKF.js} +3 -3
- package/dist/{chunk-JBCS7CRR.js → chunk-BEPZRGGU.js} +10 -10
- package/dist/{chunk-XGDPUNND.js → chunk-CE5AX47J.js} +2 -2
- package/dist/{chunk-I64IFBLB.js → chunk-DWUOQKRU.js} +17 -10
- package/dist/{chunk-DZAW46HP.js → chunk-E3TPLWFX.js} +3 -3
- package/dist/{chunk-HIICAHCJ.js → chunk-EKCHAPYA.js} +2 -2
- package/dist/{chunk-XE3PCIXH.js → chunk-F5JHEYZM.js} +7 -7
- package/dist/{chunk-5PFYMY2V.js → chunk-FTMGRKEF.js} +2 -2
- package/dist/{chunk-ZNT2M6TG.js → chunk-G76U63X4.js} +17 -17
- package/dist/{chunk-34BHNEE3.js → chunk-GHS5EBTQ.js} +58 -7
- package/dist/{chunk-2NHR3NAY.js → chunk-GI7YYQ3F.js} +40 -34
- package/dist/{chunk-DYHAXKHD.js → chunk-GWZNEVM2.js} +12 -8
- package/dist/chunk-GYV6VZOC.js +26 -0
- package/dist/{chunk-MQXIVJ35.js → chunk-HAXOFFRH.js} +5 -5
- package/dist/{chunk-W4YEMFBX.js → chunk-HEQY7ZFI.js} +2 -2
- package/dist/{chunk-IKOZFYBN.js → chunk-I7ZPNEJM.js} +145 -102
- package/dist/{chunk-WNP7O5WZ.js → chunk-ID64D7PE.js} +4 -4
- package/dist/{chunk-XQRY4DTA.js → chunk-IGLP3ODT.js} +10 -10
- package/dist/chunk-IJNZMHLA.js +101 -0
- package/dist/{chunk-JWJGP5DQ.js → chunk-INY6HTFL.js} +7 -7
- package/dist/{chunk-PBP4B7XR.js → chunk-IUE3Y34X.js} +2 -2
- package/dist/{chunk-B74PXLU7.js → chunk-IWT4SF4R.js} +3 -3
- package/dist/{chunk-B7HM5Z7T.js → chunk-JDAY6FIL.js} +5 -5
- package/dist/{chunk-PJX3WQUQ.js → chunk-JEQ3XTHC.js} +2 -2
- package/dist/{chunk-FSP7CMNU.js → chunk-JGRC33J2.js} +50 -4
- package/dist/{chunk-X7IARSHT.js → chunk-JKKCYP3C.js} +9 -9
- package/dist/{chunk-HJWWJ6IL.js → chunk-JSC3U7TI.js} +16 -4
- package/dist/{chunk-SSEYRH53.js → chunk-KK4JZPBQ.js} +19 -140
- package/dist/{chunk-IHXBNWMM.js → chunk-KXDSS5WJ.js} +7 -3
- package/dist/{chunk-Q4XWMHX6.js → chunk-L47TF46W.js} +2 -2
- package/dist/{chunk-O3YUNJZ2.js → chunk-LDJG7DW3.js} +81 -24
- package/dist/{chunk-CDNVLKUX.js → chunk-LLDJM5XK.js} +13 -7
- package/dist/{chunk-F2I26BDK.js → chunk-MUW2BDDH.js} +4 -4
- package/dist/{chunk-HKMD33FO.js → chunk-MWUZBSAQ.js} +79 -76
- package/dist/{chunk-QQLGQY2A.js → chunk-N2Z7HLVY.js} +20 -20
- package/dist/{chunk-DZEK6CJN.js → chunk-NIQJ66N4.js} +19 -19
- package/dist/{chunk-CWVRRIEI.js → chunk-NZMNUPZZ.js} +2 -2
- package/dist/{chunk-462T4EGZ.js → chunk-O5CVSAG5.js} +2 -2
- package/dist/{chunk-TPEQIQIE.js → chunk-OML5D5V5.js} +8 -8
- package/dist/{chunk-IKSLQ4XV.js → chunk-PAJQJ7BS.js} +558 -216
- package/dist/{chunk-ZW55JB7N.js → chunk-PUVDKJ2Y.js} +2 -2
- package/dist/{chunk-UH347SHR.js → chunk-QWGDJJYJ.js} +11 -11
- package/dist/chunk-R6Q67RJH.js +134 -0
- package/dist/{chunk-CRFOIAX3.js → chunk-RRNP2ANY.js} +6 -6
- package/dist/{chunk-IDNA72AH.js → chunk-RSJ25QSL.js} +2 -2
- package/dist/chunk-SKHCAU7K.js +385 -0
- package/dist/{chunk-RLYRBIYQ.js → chunk-TM6LQDI3.js} +20 -12
- package/dist/chunk-UOIZ7DA4.js +41 -0
- package/dist/{chunk-P75RZCJW.js → chunk-UPZU6GE4.js} +3 -3
- package/dist/{chunk-MCMZMDAC.js → chunk-V2ANDPVT.js} +4 -4
- package/dist/{chunk-AK5XEFVZ.js → chunk-VA5FNYMT.js} +26 -13
- package/dist/{chunk-IMXMHHMQ.js → chunk-VW6DOEDG.js} +332 -57
- package/dist/{chunk-XOXV5GKE.js → chunk-W6RRQCPQ.js} +16 -7
- package/dist/{chunk-CYZW7JHJ.js → chunk-WBKFA554.js} +8 -8
- package/dist/{chunk-BO7Y52RY.js → chunk-WCXUNS7U.js} +7 -7
- package/dist/{chunk-ZGNYYXQ6.js → chunk-WRBAGUNF.js} +3 -3
- package/dist/{chunk-FVDGR2ZL.js → chunk-XIVNBFZS.js} +85 -30
- package/dist/{chunk-BYMNWQ7O.js → chunk-XPWWI35G.js} +299 -58
- package/dist/{chunk-KPXDY6QF.js → chunk-XRZT5WY5.js} +2 -2
- package/dist/{chunk-AZ4WMN4W.js → chunk-Y3CBHOR6.js} +2 -2
- package/dist/{chunk-VXMFAE2W.js → chunk-YPC6ZR5L.js} +19 -6
- package/dist/{chunk-54ODD65L.js → chunk-YQWYVTMC.js} +4 -4
- package/dist/{chunk-M2WXEHER.js → chunk-ZA4VCIGV.js} +2 -2
- package/dist/{chunk-7BHIY2MW.js → chunk-ZDN3Y73Y.js} +6 -6
- package/dist/{chunk-E7GT7O5N.js → chunk-ZWPRK62N.js} +7 -4
- package/dist/cli/index.js +38 -37
- package/dist/{clio-7VB377CC.js → clio-CMMK4KRR.js} +7 -7
- package/dist/{code-nav-YVLCYA7V.js → code-nav-MDZNQS33.js} +7 -7
- package/dist/{components-UBWCQSRW.js → components-UCUQ4QXW.js} +4 -4
- package/dist/{config-4HVOS65E.js → config-SVM5P5YI.js} +76 -74
- package/dist/{configure-PIWO7B24.js → configure-LE3IK2TJ.js} +26 -24
- package/dist/{context-IYEHL3WQ.js → context-2OHRKS42.js} +66 -63
- package/dist/{context-N6ZE3LGJ.js → context-E3VC7RX5.js} +15 -11
- package/dist/{context-KQYIWPWT.js → context-VNCR7KAG.js} +60 -45
- package/dist/{context-clear-G4OGZJDS.js → context-clear-BW4O37TG.js} +61 -59
- package/dist/context-map-COB37XXN.js +505 -0
- package/dist/{context-working-set-BWLF6LJP.js → context-working-set-VDS25HXZ.js} +17 -16
- package/dist/{dispatch-runner-2QQAITS3.js → dispatch-runner-5AHT53RF.js} +85 -74
- package/dist/{doctor-LHBD36VU.js → doctor-WNNVO6FY.js} +37 -37
- package/dist/{eval-C45FYRJ6.js → eval-7G7SGAYO.js} +285 -114
- package/dist/{eval-inventory-6DEJPLBF.js → eval-inventory-Y6QRFOH5.js} +4 -4
- package/dist/{evidence-6SHONYAF.js → evidence-VD6736FQ.js} +63 -62
- package/dist/{evolve-KRKMV72X.js → evolve-AL3NGVRL.js} +62 -61
- package/dist/{extensions-KPZ2UHBB.js → extensions-MOVJ32NM.js} +7 -7
- package/dist/{fleet-IVTCKDHT.js → fleet-QZHUMAGI.js} +110 -108
- package/dist/{fleet-commands-EDWL3IT7.js → fleet-commands-BAYT5FJZ.js} +10 -10
- package/dist/{fleet-decisions-YP3YEFGK.js → fleet-decisions-IREVMRU4.js} +7 -6
- package/dist/{fleet-graph-ZFWKHY2M.js → fleet-graph-YCTT3HTI.js} +19 -18
- package/dist/{fleet-inspect-FVUNCBML.js → fleet-inspect-QVJTDAVB.js} +55 -54
- package/dist/{fleet-preflight-UN5XED4R.js → fleet-preflight-25QAFPK4.js} +4 -4
- package/dist/{fleet-validate-XOWC4HSX.js → fleet-validate-5O57AAJ7.js} +23 -22
- package/dist/{fleet-verify-UN3SODEL.js → fleet-verify-CPH2W2T6.js} +56 -55
- package/dist/{fleet-view-TWHJKCN6.js → fleet-view-SWBR3VGQ.js} +55 -54
- package/dist/{init-T2QORQ3Y.js → init-J477LKZH.js} +78 -76
- package/dist/{interop-IN5I2A66.js → interop-3FCM6XLG.js} +11 -11
- package/dist/{library-LSCATDLZ.js → library-QUQEIUG6.js} +28 -27
- package/dist/{memory-HYOKAGGJ.js → memory-SGGSEP65.js} +64 -63
- package/dist/{models-2GPMFYCM.js → models-HEKUAXXK.js} +49 -43
- package/dist/{monitor-E4ASVUJH.js → monitor-HKU57TYQ.js} +61 -60
- package/dist/{orchestrator-DDMPR3PY.js → orchestrator-VDFAEFAI.js} +919 -546
- package/dist/{panes-E3RUXOW5.js → panes-DN2SSFOH.js} +3 -3
- package/dist/{panes-IXKLOKA2.js → panes-TALGNPZT.js} +8 -8
- package/dist/{paths-L7LGY6RN.js → paths-NBMFAIEZ.js} +5 -5
- package/dist/reset-EAJFFJVB.js +344 -0
- package/dist/{resources-OTRSN34L.js → resources-OVKSEFVE.js} +27 -20
- package/dist/{run-5DEYH5QK.js → run-7DP7ZF2J.js} +113 -109
- package/dist/{share-IHWTLO3M.js → share-WML67FT3.js} +26 -25
- package/dist/{skills-IYMXMKW4.js → skills-SG662R2K.js} +39 -31
- package/dist/{skills-eval-DROHSJAR.js → skills-eval-VVZEUU46.js} +74 -73
- package/dist/{skills-inventory-D7X4L4ZX.js → skills-inventory-I2E23GET.js} +21 -20
- package/dist/{slash-commands-QBM7UZ3B.js → slash-commands-S7MBJDQK.js} +35 -34
- package/dist/{steer-Z5DO23FJ.js → steer-2LQOMCPB.js} +3 -3
- package/dist/{support-U7QOWY26.js → support-CC2UJBJ6.js} +6 -6
- package/dist/{targets-P2FUC4IL.js → targets-4QC3HIEW.js} +48 -45
- package/dist/{terminal-lease-YREJ3JX2.js → terminal-lease-TUHIJ6Y2.js} +2 -2
- package/dist/{tools-5B7RO6MV.js → tools-TFGJICCU.js} +8 -8
- package/dist/{trace-YMGMUM6A.js → trace-FXMXUZUF.js} +7 -7
- package/dist/uninstall-5PEVOE5B.js +408 -0
- package/dist/upgrade-M4WXY6KN.js +303 -0
- package/dist/{usage-ME5MPXGX.js → usage-N7ZNVLEM.js} +147 -102
- package/dist/{verifiers-BVZ7IWOO.js → verifiers-DJTP4XX6.js} +15 -15
- package/dist/{verify-5K7ZKQFC.js → verify-RWE4PPEK.js} +9 -9
- package/dist/{wiki-generate-F5W5QTYY.js → wiki-generate-C7IQOXSP.js} +84 -82
- package/dist/{with-panes-BYOJCLAM.js → with-panes-4GCGSL7J.js} +9 -9
- package/dist/worker/entry.js +61 -60
- package/docs/architecture/artifact-placement.md +1 -0
- package/docs/architecture/artifact-versions.md +1 -1
- package/docs/architecture/context-engine.md +4 -0
- package/docs/architecture/middleware-and-components.md +1 -1
- package/docs/architecture/model-catalog.md +21 -10
- package/docs/architecture/observability.md +12 -1
- package/docs/architecture/prompt-envelope-and-tools.md +2 -0
- package/docs/architecture/provider-adapter-cookbook.md +63 -0
- package/docs/architecture/safety-model.md +15 -5
- package/docs/guide/built-in-agents.md +17 -3
- package/docs/guide/commands-and-modes.md +1 -1
- package/docs/guide/configuration-and-targets.md +97 -9
- package/docs/guide/configuration-reference.md +7 -2
- package/docs/guide/environment-variables.md +2 -0
- package/docs/guide/installation-and-lifecycle.md +37 -4
- package/docs/guide/proactive-memory.md +66 -55
- package/docs/guide/skills-marketplace.md +18 -0
- package/docs/process/development-pipeline.md +34 -1
- package/docs/process/eval-runner.md +67 -3
- package/evals/behavioral-model.yaml +3 -2
- package/package.json +2 -2
- package/skills/README.md +7 -5
- package/skills/coding/ast-grep/SKILL.md +101 -30
- package/skills/coding/ast-grep/evals.md +26 -0
- package/skills/coding/coding-standards/SKILL.md +40 -5
- package/skills/coding/coding-standards/evals.md +23 -0
- package/skills/coding/prototype/SKILL.md +87 -28
- package/skills/coding/prototype/evals.md +19 -0
- package/skills/coding/tdd/SKILL.md +80 -53
- package/skills/coding/tdd/evals.md +20 -0
- package/skills/context/context-handoff/SKILL.md +43 -2
- package/skills/context/context-handoff/evals.md +44 -0
- package/skills/context/context-prime/SKILL.md +45 -15
- 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 +77 -63
- 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 +87 -64
- 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 +100 -51
- 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/planning/archify/SKILL.md +196 -0
- package/skills/planning/archify/evals.md +65 -0
- package/skills/planning/architecture/SKILL.md +61 -12
- package/skills/planning/architecture/evals.md +65 -0
- package/skills/planning/backlog/SKILL.md +130 -14
- package/skills/planning/backlog/evals.md +142 -0
- package/skills/planning/prd/SKILL.md +46 -6
- package/skills/planning/prd/evals.md +54 -0
- package/skills/planning/product-intent/SKILL.md +57 -2
- package/skills/planning/product-intent/evals.md +70 -0
- package/skills/planning/tech-spec/SKILL.md +53 -2
- package/skills/planning/tech-spec/evals.md +73 -0
- package/skills/registry.yaml +58 -50
- package/skills/remote.yaml +13 -0
- package/skills/research/arxiv-literature/SKILL.md +76 -18
- package/skills/research/arxiv-literature/evals.md +50 -0
- package/skills/research/experiment-protocol/SKILL.md +20 -1
- package/skills/research/experiment-protocol/evals.md +23 -0
- package/skills/research/scientific-debugging/SKILL.md +23 -1
- package/skills/research/scientific-debugging/evals.md +18 -0
- package/skills/research/scientific-modernization/SKILL.md +26 -1
- package/skills/research/scientific-modernization/evals.md +27 -0
- package/skills/skill-marketplace.json +63 -28
- package/skills/workflow/cut-it/SKILL.md +65 -5
- package/skills/workflow/cut-it/evals.md +101 -0
- package/skills/workflow/design-council/SKILL.md +117 -27
- package/skills/workflow/design-council/evals.md +161 -0
- package/skills/workflow/grill-me/SKILL.md +86 -10
- package/skills/workflow/grill-me/evals.md +153 -0
- package/skills/workflow/workflow-distiller/SKILL.md +76 -17
- package/skills/workflow/workflow-distiller/evals.md +118 -0
- 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 -528
- package/src/cli/context-map.ts +114 -0
- package/src/cli/context.ts +4 -0
- package/src/cli/index.ts +1 -0
- 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/reset.ts +228 -106
- package/src/cli/run.ts +7 -2
- package/src/cli/select.ts +664 -0
- package/src/cli/skills.ts +9 -2
- package/src/cli/targets.ts +3 -0
- 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/core/config.ts +56 -0
- package/src/core/external-diagnostic.ts +44 -0
- package/src/core/gateway-routing.ts +157 -0
- package/src/core/safe-exec.ts +17 -2
- package/src/core/skill-activation.ts +89 -2
- package/src/domains/agents/builtins/world-knowledge.md +31 -0
- package/src/domains/agents/catalog.ts +1 -1
- package/src/domains/agents/result-contract.ts +70 -0
- package/src/domains/context/wiki/map-seed.ts +589 -0
- package/src/domains/context/wiki/plan.ts +2 -2
- 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 +1 -0
- package/src/domains/dispatch/capacity-lease.ts +17 -0
- package/src/domains/dispatch/contract.ts +11 -1
- package/src/domains/dispatch/extension.ts +134 -29
- package/src/domains/dispatch/types.ts +3 -0
- package/src/domains/dispatch/worker-model-metadata.ts +38 -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/suites/resolve.ts +13 -1
- package/src/domains/eval/suites/run.ts +24 -3
- package/src/domains/interop/registry.ts +6 -2
- package/src/domains/interop/types.ts +4 -0
- package/src/domains/lifecycle/migrations/index.ts +4 -0
- package/src/domains/memory/task-memory-policy.ts +70 -26
- package/src/domains/memory/task-memory-telemetry.ts +1 -0
- package/src/domains/middleware/index.ts +0 -1
- 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/skills-reminder.ts +31 -2
- package/src/domains/observability/compaction-usage.ts +118 -0
- package/src/domains/observability/cost.ts +1 -1
- package/src/domains/observability/extension.ts +6 -1
- package/src/domains/observability/out-of-turn-usage.ts +52 -21
- package/src/domains/providers/contract.ts +4 -1
- package/src/domains/providers/extension.ts +40 -9
- 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 +15 -5
- package/src/domains/providers/models/local-models/clio-coder-local-coding-targets.yaml +32 -12
- 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/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/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 +7 -0
- package/src/domains/resources/skills/marketplace.ts +63 -11
- package/src/domains/safety/autonomy.ts +15 -0
- package/src/domains/safety/index.ts +1 -0
- 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/usage.ts +3 -3
- 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/openai-completions.ts +117 -14
- package/src/engine/external-subprocess.ts +114 -6
- package/src/entry/background-model-metadata.ts +18 -0
- package/src/entry/compaction-prompt.ts +57 -0
- package/src/entry/orchestrator.ts +405 -216
- package/src/entry/task-memory-lifecycle.ts +35 -0
- package/src/interactive/chat-loop-messages.ts +13 -4
- package/src/interactive/chat-loop.ts +65 -2
- package/src/interactive/chat-renderer.ts +1 -0
- package/src/interactive/cost-overlay.ts +26 -2
- package/src/interactive/interactive-slash-runtime.ts +2 -1
- package/src/interactive/renderers/worker-entry.ts +32 -0
- package/src/interactive/slash-commands.ts +24 -6
- package/src/interactive/theme/labels.ts +19 -13
- package/src/interactive/turn-context.ts +9 -5
- 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/tools/context/index.ts +30 -9
- package/src/tools/dispatch-arguments.ts +1 -0
- package/src/tools/dispatch-event-text.ts +10 -0
- package/src/tools/dispatch-plan.ts +1 -0
- package/src/tools/dispatch-runner.ts +12 -0
- package/src/tools/registry.ts +11 -5
- package/src/tools/worker-evidence.ts +3 -1
- package/src/worker/spec-contract.ts +4 -0
- package/dist/chunk-2Z2IKEXI.js +0 -1554
- package/dist/reset-OAQP3W4O.js +0 -230
- package/dist/uninstall-N34PCTGJ.js +0 -331
- package/dist/upgrade-PXK3S2YM.js +0 -325
|
@@ -28,6 +28,17 @@ export interface BudgetEnvelopeReason {
|
|
|
28
28
|
|
|
29
29
|
export interface RunToolBudgetEnvelope {
|
|
30
30
|
version: 1;
|
|
31
|
+
enforcement:
|
|
32
|
+
| {
|
|
33
|
+
classification: "native-per-tool";
|
|
34
|
+
perTool: "enforced";
|
|
35
|
+
clioControls: ReadonlyArray<"tool-calls" | "read-reserve" | "synthesis" | "attempt-cap">;
|
|
36
|
+
}
|
|
37
|
+
| {
|
|
38
|
+
classification: "external-one-shot";
|
|
39
|
+
perTool: "unobserved-not-enforced";
|
|
40
|
+
clioControls: ReadonlyArray<"single-launch" | "wall-clock" | "output-cap" | "cancellation" | "result-contract">;
|
|
41
|
+
};
|
|
31
42
|
policy: {
|
|
32
43
|
recipeId: string;
|
|
33
44
|
default: AgentBudgetPhase & { synthesis: boolean };
|
|
@@ -39,6 +50,15 @@ export interface RunToolBudgetEnvelope {
|
|
|
39
50
|
reasons: ReadonlyArray<BudgetEnvelopeReason>;
|
|
40
51
|
}
|
|
41
52
|
|
|
53
|
+
const NATIVE_CLIO_CONTROLS = ["tool-calls", "read-reserve", "synthesis", "attempt-cap"] as const;
|
|
54
|
+
const EXTERNAL_CLIO_CONTROLS = [
|
|
55
|
+
"single-launch",
|
|
56
|
+
"wall-clock",
|
|
57
|
+
"output-cap",
|
|
58
|
+
"cancellation",
|
|
59
|
+
"result-contract",
|
|
60
|
+
] as const;
|
|
61
|
+
|
|
42
62
|
export type BudgetAdmissionDenialCode =
|
|
43
63
|
| "exact-recipe-policy"
|
|
44
64
|
| "recipe-maximum"
|
|
@@ -94,6 +114,8 @@ export function cloneDispatchBudgetRequest(value: unknown, prefix = "budget"): D
|
|
|
94
114
|
}
|
|
95
115
|
|
|
96
116
|
function freezeEnvelope(envelope: RunToolBudgetEnvelope): RunToolBudgetEnvelope {
|
|
117
|
+
Object.freeze(envelope.enforcement.clioControls);
|
|
118
|
+
Object.freeze(envelope.enforcement);
|
|
97
119
|
Object.freeze(envelope.policy.default);
|
|
98
120
|
Object.freeze(envelope.policy.maximum);
|
|
99
121
|
Object.freeze(envelope.policy);
|
|
@@ -172,6 +194,7 @@ export interface ResolveToolBudgetEnvelopeInput {
|
|
|
172
194
|
hasReadTool: boolean;
|
|
173
195
|
retry: boolean;
|
|
174
196
|
revision: boolean;
|
|
197
|
+
enforcement?: "native-per-tool" | "external-one-shot";
|
|
175
198
|
}
|
|
176
199
|
|
|
177
200
|
/** Resolve the one immutable envelope used by admission, enforcement, and evidence. */
|
|
@@ -253,6 +276,18 @@ export function resolveToolBudgetEnvelope(input: ResolveToolBudgetEnvelopeInput)
|
|
|
253
276
|
const authoredMaximum = input.policy.maximum ?? input.policy;
|
|
254
277
|
return freezeEnvelope({
|
|
255
278
|
version: 1,
|
|
279
|
+
enforcement:
|
|
280
|
+
input.enforcement === "external-one-shot"
|
|
281
|
+
? {
|
|
282
|
+
classification: "external-one-shot",
|
|
283
|
+
perTool: "unobserved-not-enforced",
|
|
284
|
+
clioControls: [...EXTERNAL_CLIO_CONTROLS],
|
|
285
|
+
}
|
|
286
|
+
: {
|
|
287
|
+
classification: "native-per-tool",
|
|
288
|
+
perTool: "enforced",
|
|
289
|
+
clioControls: [...NATIVE_CLIO_CONTROLS],
|
|
290
|
+
},
|
|
256
291
|
policy: {
|
|
257
292
|
recipeId: input.recipeId,
|
|
258
293
|
default: {
|
|
@@ -297,7 +332,11 @@ export function formatEffectiveBudget(envelope: RunToolBudgetEnvelope): string {
|
|
|
297
332
|
const revision = budget.revision
|
|
298
333
|
? `, result revision ${budget.revision.toolCalls}/${budget.revision.readReserve}`
|
|
299
334
|
: "";
|
|
300
|
-
|
|
335
|
+
const enforcement =
|
|
336
|
+
envelope.enforcement.classification === "external-one-shot"
|
|
337
|
+
? "external one-shot; per-tool unobserved/not enforced"
|
|
338
|
+
: "native per-tool enforced";
|
|
339
|
+
return `${budget.toolCalls}/${budget.readReserve}${revision}, lifetime cap ${budget.hardCap}, synthesis=${budget.synthesis ? "on" : "off"}; ${enforcement}`;
|
|
301
340
|
}
|
|
302
341
|
|
|
303
342
|
export function formatBudgetReasons(envelope: RunToolBudgetEnvelope): string {
|
|
@@ -314,6 +353,10 @@ const BUDGET_REASON_CODES: ReadonlySet<string> = new Set<BudgetEnvelopeReasonCod
|
|
|
314
353
|
"revision-growth-denied",
|
|
315
354
|
]);
|
|
316
355
|
|
|
356
|
+
function isExactStringArray(value: unknown[], expected: readonly string[]): boolean {
|
|
357
|
+
return value.length === expected.length && value.every((item, index) => item === expected[index]);
|
|
358
|
+
}
|
|
359
|
+
|
|
317
360
|
/** Safely project an envelope that crossed a persistence or event boundary. */
|
|
318
361
|
export function cloneRunToolBudgetEnvelope(value: unknown): RunToolBudgetEnvelope | undefined {
|
|
319
362
|
try {
|
|
@@ -373,8 +416,50 @@ export function cloneRunToolBudgetEnvelope(value: unknown): RunToolBudgetEnvelop
|
|
|
373
416
|
}
|
|
374
417
|
reasons.push({ code: reason.code as BudgetEnvelopeReasonCode, detail: reason.detail });
|
|
375
418
|
}
|
|
419
|
+
const enforcement = (() => {
|
|
420
|
+
if (value.enforcement === undefined) {
|
|
421
|
+
return {
|
|
422
|
+
classification: "native-per-tool" as const,
|
|
423
|
+
perTool: "enforced" as const,
|
|
424
|
+
clioControls: [...NATIVE_CLIO_CONTROLS],
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
if (!isRecord(value.enforcement) || !Array.isArray(value.enforcement.clioControls)) return null;
|
|
428
|
+
if (
|
|
429
|
+
Object.keys(value.enforcement).some(
|
|
430
|
+
(key) => key !== "classification" && key !== "perTool" && key !== "clioControls",
|
|
431
|
+
)
|
|
432
|
+
) {
|
|
433
|
+
return null;
|
|
434
|
+
}
|
|
435
|
+
if (
|
|
436
|
+
value.enforcement.classification === "external-one-shot" &&
|
|
437
|
+
value.enforcement.perTool === "unobserved-not-enforced" &&
|
|
438
|
+
isExactStringArray(value.enforcement.clioControls, EXTERNAL_CLIO_CONTROLS)
|
|
439
|
+
) {
|
|
440
|
+
return {
|
|
441
|
+
classification: "external-one-shot" as const,
|
|
442
|
+
perTool: "unobserved-not-enforced" as const,
|
|
443
|
+
clioControls: [...EXTERNAL_CLIO_CONTROLS],
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
if (
|
|
447
|
+
value.enforcement.classification === "native-per-tool" &&
|
|
448
|
+
value.enforcement.perTool === "enforced" &&
|
|
449
|
+
isExactStringArray(value.enforcement.clioControls, NATIVE_CLIO_CONTROLS)
|
|
450
|
+
) {
|
|
451
|
+
return {
|
|
452
|
+
classification: "native-per-tool" as const,
|
|
453
|
+
perTool: "enforced" as const,
|
|
454
|
+
clioControls: [...NATIVE_CLIO_CONTROLS],
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
return null;
|
|
458
|
+
})();
|
|
459
|
+
if (enforcement === null) return undefined;
|
|
376
460
|
return freezeEnvelope({
|
|
377
461
|
version: 1,
|
|
462
|
+
enforcement,
|
|
378
463
|
policy: {
|
|
379
464
|
recipeId,
|
|
380
465
|
default: { ...defaultPhase, synthesis: value.policy.default.synthesis },
|
|
@@ -481,6 +481,23 @@ export function capacityLeaseUsage(options?: { nowMs?: number; probe?: LeaseOwne
|
|
|
481
481
|
return { global: leases.length, nodes, endpoints, endpointHolders };
|
|
482
482
|
}
|
|
483
483
|
|
|
484
|
+
/** Coherent current endpoint occupancy, including held reservation waves.
|
|
485
|
+
* The caller still owns admission; process-local streams are not global leases.
|
|
486
|
+
*/
|
|
487
|
+
export function endpointCapacityUsage(): Readonly<Record<string, number>> {
|
|
488
|
+
return withStateFileLockSync(capacityStateLockPath(), () => {
|
|
489
|
+
const file = readCapacityStateUnsafe();
|
|
490
|
+
reclaim(file, Date.now(), defaultProbe);
|
|
491
|
+
const held = heldReservationUsage(file.reservations);
|
|
492
|
+
const usage: Record<string, number> = { ...foregroundStreamUsage() };
|
|
493
|
+
for (const [key, count] of Object.entries(held.endpoints)) usage[key] = (usage[key] ?? 0) + count;
|
|
494
|
+
for (const lease of file.leases) {
|
|
495
|
+
if (lease.endpointKey !== undefined) usage[lease.endpointKey] = (usage[lease.endpointKey] ?? 0) + 1;
|
|
496
|
+
}
|
|
497
|
+
return usage;
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
|
|
484
501
|
/**
|
|
485
502
|
* Per-node lease counts for display and for advisory placement spreading. Every
|
|
486
503
|
* read takes the admission state lock, so a render loop or a multi-node
|
|
@@ -86,6 +86,12 @@ export interface DispatchAdmissionObserver {
|
|
|
86
86
|
onAdmitted(run: { runId: string; pid: number | null; runtimeKind: RunEnvelope["runtimeKind"] }): void;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
/** Invocation-owned admission bounds; never serialized into model-authored requests. */
|
|
90
|
+
export interface DispatchPreparationOptions {
|
|
91
|
+
signal?: AbortSignal;
|
|
92
|
+
deadlineAt?: number;
|
|
93
|
+
}
|
|
94
|
+
|
|
89
95
|
/** Side-effect-free effective routing used to construct a dispatch approval artifact. */
|
|
90
96
|
export interface DispatchPlanTaskResolution {
|
|
91
97
|
agentId: string;
|
|
@@ -225,6 +231,7 @@ export interface DispatchContract {
|
|
|
225
231
|
dispatch(
|
|
226
232
|
req: DispatchRequest,
|
|
227
233
|
observer?: DispatchAdmissionObserver,
|
|
234
|
+
preparation?: DispatchPreparationOptions,
|
|
228
235
|
): Promise<{
|
|
229
236
|
runId: string;
|
|
230
237
|
events: AsyncIterableIterator<unknown>;
|
|
@@ -232,7 +239,10 @@ export interface DispatchContract {
|
|
|
232
239
|
}>;
|
|
233
240
|
|
|
234
241
|
/** Spawn a group of dispatches and expose one merged batch event stream. */
|
|
235
|
-
dispatchBatch(
|
|
242
|
+
dispatchBatch(
|
|
243
|
+
reqs: ReadonlyArray<DispatchRequest>,
|
|
244
|
+
preparation?: DispatchPreparationOptions,
|
|
245
|
+
): Promise<{
|
|
236
246
|
batchId: string;
|
|
237
247
|
/** Logical work ids, one per request in admission order. */
|
|
238
248
|
assignmentIds: ReadonlyArray<string>;
|
|
@@ -16,6 +16,7 @@ import { performance } from "node:perf_hooks";
|
|
|
16
16
|
import { BusChannels, type DispatchCompletedPayload, type DispatchRunIdentity } from "../../core/bus-events.js";
|
|
17
17
|
import { DEFAULT_SETTINGS, type DelegationToolGovernance } from "../../core/defaults.js";
|
|
18
18
|
import type { DomainBundle, DomainContext, DomainExtension } from "../../core/domain-loader.js";
|
|
19
|
+
import { gatewayRoutingObservationFromRecord } from "../../core/gateway-routing.js";
|
|
19
20
|
import { GUARDRAIL_DEFAULTS } from "../../core/guardrails.js";
|
|
20
21
|
import { readClioVersion, readPiMonoVersion } from "../../core/package-root.js";
|
|
21
22
|
import { canonicalizeExistingPath } from "../../core/path-canonical.js";
|
|
@@ -158,6 +159,7 @@ import type {
|
|
|
158
159
|
DispatchAdmissionObserver,
|
|
159
160
|
DispatchContract,
|
|
160
161
|
DispatchPlanTaskResolution,
|
|
162
|
+
DispatchPreparationOptions,
|
|
161
163
|
DispatchRequest,
|
|
162
164
|
DispatchSnapshot,
|
|
163
165
|
} from "./contract.js";
|
|
@@ -297,6 +299,7 @@ import {
|
|
|
297
299
|
validateJobSpec,
|
|
298
300
|
} from "./validation.js";
|
|
299
301
|
import { describeUngroundedValidations, groundClaimedValidations, invalidatesQuality } from "./validation-grounding.js";
|
|
302
|
+
import { prepareWorkerModelMetadata } from "./worker-model-metadata.js";
|
|
300
303
|
import {
|
|
301
304
|
type AgentLedgerBody,
|
|
302
305
|
computeSettingsFingerprint,
|
|
@@ -1439,6 +1442,13 @@ function runtimeLimitations(runtimeKind: RunKind, runtimeId: string): string[] {
|
|
|
1439
1442
|
"Claude CLI subprocess executes Claude Code tools; Clio constrains permission mode and forbids dangerous bypass unless explicitly gated",
|
|
1440
1443
|
];
|
|
1441
1444
|
}
|
|
1445
|
+
if (runtimeKind === "subprocess" && runtimeId === "antigravity-code") {
|
|
1446
|
+
return [
|
|
1447
|
+
"Antigravity CLI owns its internal tools, network activity, prompts, and approvals; Clio observes only structured stream output and does not provide per-tool mediation or complete tool telemetry",
|
|
1448
|
+
"Antigravity conversation ids are recorded only as opaque provider observations; Clio does not resume them",
|
|
1449
|
+
"Antigravity runs are one-shot and never retried automatically",
|
|
1450
|
+
];
|
|
1451
|
+
}
|
|
1442
1452
|
// HTTP/native runtimes run through pi-agent-core, which Clio observes and
|
|
1443
1453
|
// controls directly, so there are no runtime-imposed dispatch limitations.
|
|
1444
1454
|
return [];
|
|
@@ -1479,13 +1489,6 @@ function assertWriteRootsEnforceable(runtime: RuntimeDescriptor, writeRoots: Rea
|
|
|
1479
1489
|
);
|
|
1480
1490
|
}
|
|
1481
1491
|
|
|
1482
|
-
function assertWorkerBudgetEnforceable(runtime: RuntimeDescriptor, hasDeclaredBudget: boolean): void {
|
|
1483
|
-
if (!hasDeclaredBudget || runtime.kind !== "subprocess") return;
|
|
1484
|
-
throw new Error(
|
|
1485
|
-
`dispatch: runtime '${runtime.id}' cannot enforce an explicit dispatch budget because subprocess workers do not expose per-tool mediation; choose a native or claude-sdk worker`,
|
|
1486
|
-
);
|
|
1487
|
-
}
|
|
1488
|
-
|
|
1489
1492
|
/**
|
|
1490
1493
|
* API families whose wire protocol carries tool calls. Membership is a property
|
|
1491
1494
|
* of the protocol, not of any one model: every server speaking one of these can
|
|
@@ -1614,13 +1617,38 @@ function workerToolCallHardCap(settings: EffectiveSettings): number {
|
|
|
1614
1617
|
return settings?.fleet.limits.toolCallsPerRun ?? GUARDRAIL_DEFAULTS.workerToolCallCap;
|
|
1615
1618
|
}
|
|
1616
1619
|
|
|
1620
|
+
/**
|
|
1621
|
+
* Only a runtime that declares its external agent loop may accept a declared
|
|
1622
|
+
* per-tool budget: Clio records that budget as unobserved rather than enforced.
|
|
1623
|
+
* Any other subprocess runtime cannot mediate tool calls, so a declared budget
|
|
1624
|
+
* would be a claim nobody enforces.
|
|
1625
|
+
*/
|
|
1626
|
+
export function assertWorkerBudgetEnforceable(
|
|
1627
|
+
runtime: Pick<RuntimeDescriptor, "id" | "kind" | "externalAgentLoop">,
|
|
1628
|
+
hasDeclaredBudget: boolean,
|
|
1629
|
+
): void {
|
|
1630
|
+
if (!hasDeclaredBudget || runtime.kind !== "subprocess" || runtime.externalAgentLoop !== undefined) return;
|
|
1631
|
+
throw new Error(
|
|
1632
|
+
`dispatch: runtime '${runtime.id}' cannot enforce an explicit dispatch budget because subprocess workers do not expose per-tool mediation; choose a native or claude-sdk worker`,
|
|
1633
|
+
);
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1636
|
+
/** Per-tool budget enforcement is real only where Clio observes each tool call. */
|
|
1637
|
+
export function budgetEnforcementForRuntime(
|
|
1638
|
+
runtime: Pick<RuntimeDescriptor, "kind">,
|
|
1639
|
+
): "native-per-tool" | "external-one-shot" {
|
|
1640
|
+
return runtime.kind === "subprocess" ? "external-one-shot" : "native-per-tool";
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1617
1643
|
function resolveEffectiveWorkerBudget(input: {
|
|
1618
1644
|
req: DispatchRequest;
|
|
1619
1645
|
recipeId: string;
|
|
1620
1646
|
declared: ReturnType<typeof normalizeAgentSpec>["budget"];
|
|
1621
1647
|
allowedTools: ReadonlyArray<ToolName>;
|
|
1622
1648
|
settings: EffectiveSettings;
|
|
1649
|
+
runtime: RuntimeDescriptor;
|
|
1623
1650
|
}): RunToolBudgetEnvelope {
|
|
1651
|
+
assertWorkerBudgetEnforceable(input.runtime, input.declared !== null || input.req.budget !== undefined);
|
|
1624
1652
|
const hardCap = workerToolCallHardCap(input.settings);
|
|
1625
1653
|
const declared = input.declared ?? {
|
|
1626
1654
|
toolCalls: hardCap,
|
|
@@ -1635,6 +1663,7 @@ function resolveEffectiveWorkerBudget(input: {
|
|
|
1635
1663
|
hasReadTool: input.allowedTools.includes(ToolNames.Read),
|
|
1636
1664
|
retry: (input.req.lineage?.attempt ?? 0) > 0,
|
|
1637
1665
|
revision: input.req.gate?.role === "builder" && input.req.gate.cycle > 1 && input.req.gate.verdict === "revise",
|
|
1666
|
+
enforcement: budgetEnforcementForRuntime(input.runtime),
|
|
1638
1667
|
});
|
|
1639
1668
|
}
|
|
1640
1669
|
|
|
@@ -1975,6 +2004,15 @@ function clampWorkerAutonomy(session: AutonomyLevel, requested: AutonomyLevel |
|
|
|
1975
2004
|
return AUTONOMY_ORDER[requested] < AUTONOMY_ORDER[session] ? requested : session;
|
|
1976
2005
|
}
|
|
1977
2006
|
|
|
2007
|
+
/** Read-only recipes are an authority boundary, including on opaque external loops. */
|
|
2008
|
+
export function effectiveWorkerAutonomy(
|
|
2009
|
+
session: AutonomyLevel,
|
|
2010
|
+
requested: AutonomyLevel | undefined,
|
|
2011
|
+
capabilityClass: AgentCapabilityClass,
|
|
2012
|
+
): AutonomyLevel {
|
|
2013
|
+
return clampWorkerAutonomy(session, capabilityClass === "read-only" ? "read-only" : requested);
|
|
2014
|
+
}
|
|
2015
|
+
|
|
1978
2016
|
function requestedAutonomyEvidence(
|
|
1979
2017
|
sessionAutonomy: AutonomyLevel,
|
|
1980
2018
|
requestedAutonomy: AutonomyLevel | undefined,
|
|
@@ -2662,6 +2700,7 @@ export function createDispatchBundle(
|
|
|
2662
2700
|
nodeId: string,
|
|
2663
2701
|
timing: RunPhaseMarks,
|
|
2664
2702
|
endpoint?: EndpointCapacity | null,
|
|
2703
|
+
signal?: AbortSignal,
|
|
2665
2704
|
) {
|
|
2666
2705
|
const queuedAt = now();
|
|
2667
2706
|
timing.queuedAt = new Date(queuedAt).toISOString();
|
|
@@ -2677,7 +2716,12 @@ export function createDispatchBundle(
|
|
|
2677
2716
|
: planQueueSlot(req.reservation.ownerId, req.reservation.memberId, (error) =>
|
|
2678
2717
|
reportDispatchDiagnostic("read plan queue identity", error),
|
|
2679
2718
|
);
|
|
2719
|
+
const cancel = (): void => {
|
|
2720
|
+
capacityAdmission.cancel(assignmentId);
|
|
2721
|
+
};
|
|
2722
|
+
signal?.addEventListener("abort", cancel, { once: true });
|
|
2680
2723
|
try {
|
|
2724
|
+
signal?.throwIfAborted();
|
|
2681
2725
|
const admitted = await capacityAdmission.admit({
|
|
2682
2726
|
assignmentId,
|
|
2683
2727
|
nodeId,
|
|
@@ -2700,6 +2744,8 @@ export function createDispatchBundle(
|
|
|
2700
2744
|
else await failQueuedAssignment(assignmentId);
|
|
2701
2745
|
}
|
|
2702
2746
|
throw error;
|
|
2747
|
+
} finally {
|
|
2748
|
+
signal?.removeEventListener("abort", cancel);
|
|
2703
2749
|
}
|
|
2704
2750
|
}
|
|
2705
2751
|
|
|
@@ -2849,6 +2895,14 @@ export function createDispatchBundle(
|
|
|
2849
2895
|
if (draining) return { scheduled: false };
|
|
2850
2896
|
const rootRunId = run.lineage.rootRunId;
|
|
2851
2897
|
if (!retryChainIsLive(run)) return { scheduled: false };
|
|
2898
|
+
if (providers.getRuntime(run.runtimeId)?.externalAgentLoop?.generatingRetry === "forbidden") {
|
|
2899
|
+
retryBackoff.delete(rootRunId);
|
|
2900
|
+
return {
|
|
2901
|
+
scheduled: false,
|
|
2902
|
+
settlementDetail:
|
|
2903
|
+
"automatic retry suppressed because this external agent loop is one-shot and Clio cannot prove replay is side-effect-free",
|
|
2904
|
+
};
|
|
2905
|
+
}
|
|
2852
2906
|
if (!RETRYABLE_OUTCOMES.has(outcome)) {
|
|
2853
2907
|
retryBackoff.delete(rootRunId);
|
|
2854
2908
|
return { scheduled: false };
|
|
@@ -3224,6 +3278,9 @@ export function createDispatchBundle(
|
|
|
3224
3278
|
const tickMonotonic = monotonicNow();
|
|
3225
3279
|
for (const run of active.values()) {
|
|
3226
3280
|
if (run.aborted || run.stallKilled || !run.heartbeatAt) continue;
|
|
3281
|
+
// Finalizers retain active entries while awaiting ledger persistence.
|
|
3282
|
+
// Their terminal status is already sealed into the receipt digest.
|
|
3283
|
+
if (ledger.get(run.runId)?.endedAt !== null) continue;
|
|
3227
3284
|
const heartbeatMonotonic = heartbeatMonotonicAt(run.heartbeatAt);
|
|
3228
3285
|
if (!Number.isFinite(heartbeatMonotonic) || !Number.isFinite(run.heartbeatAt.current)) continue;
|
|
3229
3286
|
if (run.runtimeKind === "acp-delegation") {
|
|
@@ -3415,7 +3472,12 @@ export function createDispatchBundle(
|
|
|
3415
3472
|
}
|
|
3416
3473
|
}
|
|
3417
3474
|
|
|
3418
|
-
async function resolveLifecycle(
|
|
3475
|
+
async function resolveLifecycle(
|
|
3476
|
+
req: DispatchRequest,
|
|
3477
|
+
settings: EffectiveSettings,
|
|
3478
|
+
metadataDeadlineAt: number,
|
|
3479
|
+
signal?: AbortSignal,
|
|
3480
|
+
): Promise<DispatchLifecycleStage> {
|
|
3419
3481
|
const recipe = agents.get(req.agentId);
|
|
3420
3482
|
if (!recipe) {
|
|
3421
3483
|
throw new Error(`dispatch: unknown agent recipe: ${req.agentId}`);
|
|
@@ -3453,22 +3515,35 @@ export function createDispatchBundle(
|
|
|
3453
3515
|
publishDispatchPathScope(req, pathScope);
|
|
3454
3516
|
const admission = resolveDispatchAdmissionStage(req, recipe, safety, pathScope);
|
|
3455
3517
|
const targets = readWorkerTargets(settings);
|
|
3456
|
-
const
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3518
|
+
const resolveTarget = () =>
|
|
3519
|
+
resolveDispatchTarget(
|
|
3520
|
+
req,
|
|
3521
|
+
recipe,
|
|
3522
|
+
targets.workerDefault,
|
|
3523
|
+
targets.workerProfiles,
|
|
3524
|
+
targets.agentBindings,
|
|
3525
|
+
targets.targetOrder,
|
|
3526
|
+
providers,
|
|
3527
|
+
);
|
|
3528
|
+
let target = resolveTarget();
|
|
3529
|
+
const identity = (resolved: ResolvedTarget): string =>
|
|
3530
|
+
JSON.stringify([
|
|
3531
|
+
resolved.target.id,
|
|
3532
|
+
resolved.runtime.id,
|
|
3533
|
+
resolved.wireModelId,
|
|
3534
|
+
endpointIdentityHash(resolved.target.url),
|
|
3535
|
+
]);
|
|
3536
|
+
const selectedIdentity = identity(target);
|
|
3537
|
+
await prepareWorkerModelMetadata(providers, target.target.id, metadataDeadlineAt, signal, now);
|
|
3538
|
+
target = resolveTarget();
|
|
3539
|
+
if (identity(target) !== selectedIdentity) {
|
|
3540
|
+
throw new Error("dispatch: worker route changed during model metadata preparation; request a fresh admission");
|
|
3541
|
+
}
|
|
3465
3542
|
enforceCapabilityGate(target.target.id, target.modelCapabilities, req.requiredCapabilities);
|
|
3466
3543
|
assertRuntimeCanHonorWorkerPermissionMode(target.runtime, settings?.fleet.permissions.mode ?? "deny");
|
|
3467
|
-
assertWorkerBudgetEnforceable(target.runtime, spec.budget !== null || req.budget !== undefined);
|
|
3468
|
-
|
|
3469
3544
|
const cwd = req.cwd ?? process.cwd();
|
|
3470
3545
|
const sessionAutonomy = settings?.safety.autonomy ?? "auto-edit";
|
|
3471
|
-
const effectiveAutonomy =
|
|
3546
|
+
const effectiveAutonomy = effectiveWorkerAutonomy(sessionAutonomy, req.autonomy, spec.capabilityClass);
|
|
3472
3547
|
const effectiveTools = withLedgerToolNarrowing(
|
|
3473
3548
|
effectiveToolNames(admission.allowedTools, target, pathScope.writeBoundaries.length > 0, deniedToolNames(req)),
|
|
3474
3549
|
req,
|
|
@@ -3507,6 +3582,7 @@ export function createDispatchBundle(
|
|
|
3507
3582
|
declared: spec.budget,
|
|
3508
3583
|
allowedTools: effectiveTools,
|
|
3509
3584
|
settings,
|
|
3585
|
+
runtime: target.runtime,
|
|
3510
3586
|
});
|
|
3511
3587
|
// Fetch structured project context only for tiers that receive it, so
|
|
3512
3588
|
// read-only scouts never pay the CLIO-CODER.md read. The tier is spec policy
|
|
@@ -3827,11 +3903,13 @@ export function createDispatchBundle(
|
|
|
3827
3903
|
const responseModelIdObservation = responseModelIdObservationFromRecord(event.message, "not-observed");
|
|
3828
3904
|
const differingResponseModelId = readStringOrNull(event.message.responseModel);
|
|
3829
3905
|
const providerResponseId = readStringOrNull(event.message.responseId);
|
|
3906
|
+
const gatewayRouting = gatewayRoutingObservationFromRecord(event.message);
|
|
3830
3907
|
upstreamResponses.push({
|
|
3831
3908
|
requestedModelId,
|
|
3832
3909
|
responseModelIdObservation,
|
|
3833
3910
|
differingResponseModelId,
|
|
3834
3911
|
providerResponseId,
|
|
3912
|
+
...(gatewayRouting !== null ? { gatewayRouting } : {}),
|
|
3835
3913
|
});
|
|
3836
3914
|
if (event.message.stopReason === "error") {
|
|
3837
3915
|
const message = readStringOrNull(event.message.errorMessage);
|
|
@@ -4389,6 +4467,7 @@ export function createDispatchBundle(
|
|
|
4389
4467
|
async function dispatchAttempt(
|
|
4390
4468
|
req: DispatchRequest,
|
|
4391
4469
|
observer?: DispatchAdmissionObserver,
|
|
4470
|
+
preparation?: DispatchPreparationOptions,
|
|
4392
4471
|
settlement?: BatchVerificationGate,
|
|
4393
4472
|
): Promise<{
|
|
4394
4473
|
runId: string;
|
|
@@ -4494,7 +4573,10 @@ export function createDispatchBundle(
|
|
|
4494
4573
|
}
|
|
4495
4574
|
|
|
4496
4575
|
req = routeAroundCoolingTarget(req, settings) ?? req;
|
|
4497
|
-
const
|
|
4576
|
+
const metadataDeadlineAt =
|
|
4577
|
+
req.assignmentDeadlineAt ?? Date.parse(requestedAt) + (req.routingIntent?.deadlineMs ?? 60_000);
|
|
4578
|
+
const lifecycle = await resolveLifecycle(req, settings, metadataDeadlineAt, preparation?.signal);
|
|
4579
|
+
preparation?.signal?.throwIfAborted();
|
|
4498
4580
|
timing.decisionCompletedAt = new Date(now()).toISOString();
|
|
4499
4581
|
assertResponseSchemaEnforceable(
|
|
4500
4582
|
lifecycle.target.runtime,
|
|
@@ -4571,7 +4653,13 @@ export function createDispatchBundle(
|
|
|
4571
4653
|
if (queuedIdentity !== null) publishCapacityQueued(queuedIdentity, timing, placement?.node ?? null);
|
|
4572
4654
|
let capacityLease: Awaited<ReturnType<typeof admitAssignmentCapacity>>;
|
|
4573
4655
|
try {
|
|
4574
|
-
capacityLease = await admitAssignmentCapacity(
|
|
4656
|
+
capacityLease = await admitAssignmentCapacity(
|
|
4657
|
+
req,
|
|
4658
|
+
placement?.node.id ?? "local",
|
|
4659
|
+
timing,
|
|
4660
|
+
endpoint,
|
|
4661
|
+
preparation?.signal,
|
|
4662
|
+
);
|
|
4575
4663
|
} catch (error) {
|
|
4576
4664
|
if (queuedIdentity !== null) publishCapacityAdmissionFailure(queuedIdentity, error);
|
|
4577
4665
|
throw error;
|
|
@@ -4582,6 +4670,7 @@ export function createDispatchBundle(
|
|
|
4582
4670
|
|
|
4583
4671
|
const ledgerRef = (() => {
|
|
4584
4672
|
try {
|
|
4673
|
+
preparation?.signal?.throwIfAborted();
|
|
4585
4674
|
return requireLedger();
|
|
4586
4675
|
} catch (error) {
|
|
4587
4676
|
leaseSlot.release();
|
|
@@ -4644,6 +4733,7 @@ export function createDispatchBundle(
|
|
|
4644
4733
|
};
|
|
4645
4734
|
let worker: SpawnedWorker;
|
|
4646
4735
|
try {
|
|
4736
|
+
preparation?.signal?.throwIfAborted();
|
|
4647
4737
|
worker = (placement?.spawn ?? spawnWorker)(spec, {
|
|
4648
4738
|
cwd: lifecycle.cwd,
|
|
4649
4739
|
now,
|
|
@@ -4865,11 +4955,13 @@ export function createDispatchBundle(
|
|
|
4865
4955
|
const responseModelIdObservation = responseModelIdObservationFromRecord(event.message, "not-observed");
|
|
4866
4956
|
const differingResponseModelId = readStringOrNull(event.message.responseModel);
|
|
4867
4957
|
const providerResponseId = readStringOrNull(event.message.responseId);
|
|
4958
|
+
const gatewayRouting = gatewayRoutingObservationFromRecord(event.message);
|
|
4868
4959
|
upstreamResponses.push({
|
|
4869
4960
|
requestedModelId,
|
|
4870
4961
|
responseModelIdObservation,
|
|
4871
4962
|
differingResponseModelId,
|
|
4872
4963
|
providerResponseId,
|
|
4964
|
+
...(gatewayRouting !== null ? { gatewayRouting } : {}),
|
|
4873
4965
|
});
|
|
4874
4966
|
if (event.message.stopReason === "error") {
|
|
4875
4967
|
const message = readStringOrNull(event.message.errorMessage);
|
|
@@ -5493,7 +5585,9 @@ export function createDispatchBundle(
|
|
|
5493
5585
|
reachedTerminalResult: resultContractWasDue(finalOutcome, outcomeCode),
|
|
5494
5586
|
output: capturedOutput?.state === "final" ? capturedOutput.text : null,
|
|
5495
5587
|
cwd: lifecycle.cwd,
|
|
5496
|
-
networkAllowed:
|
|
5588
|
+
networkAllowed:
|
|
5589
|
+
lifecycle.admission.allowedTools.includes(ToolNames.WebFetch) ||
|
|
5590
|
+
lifecycle.target.runtime.externalAgentLoop?.network === "externally-governed-unobserved",
|
|
5497
5591
|
observedRunEffects,
|
|
5498
5592
|
filesystem: nodeResultContractFilesystem(),
|
|
5499
5593
|
});
|
|
@@ -5754,13 +5848,20 @@ export function createDispatchBundle(
|
|
|
5754
5848
|
async function dispatch(
|
|
5755
5849
|
req: DispatchRequest,
|
|
5756
5850
|
observer?: DispatchAdmissionObserver,
|
|
5851
|
+
preparation?: DispatchPreparationOptions,
|
|
5757
5852
|
settlement?: BatchVerificationGate,
|
|
5758
5853
|
): Promise<{
|
|
5759
5854
|
runId: string;
|
|
5760
5855
|
events: AsyncIterableIterator<unknown>;
|
|
5761
5856
|
finalPromise: Promise<RunReceipt>;
|
|
5762
5857
|
}> {
|
|
5763
|
-
let prepared =
|
|
5858
|
+
let prepared =
|
|
5859
|
+
preparation?.deadlineAt === undefined
|
|
5860
|
+
? req
|
|
5861
|
+
: {
|
|
5862
|
+
...req,
|
|
5863
|
+
assignmentDeadlineAt: Math.min(req.assignmentDeadlineAt ?? Number.POSITIVE_INFINITY, preparation.deadlineAt),
|
|
5864
|
+
};
|
|
5764
5865
|
let createdWorktree: DispatchRequest["taskWorktree"];
|
|
5765
5866
|
let writerLease: CheckoutWriterLease | undefined;
|
|
5766
5867
|
const writerRecipe = agents.get(req.agentId);
|
|
@@ -5792,7 +5893,7 @@ export function createDispatchBundle(
|
|
|
5792
5893
|
return rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute(rel) ? entry : resolvePath(taskWorktree.path, rel);
|
|
5793
5894
|
});
|
|
5794
5895
|
prepared = {
|
|
5795
|
-
...
|
|
5896
|
+
...prepared,
|
|
5796
5897
|
runIdHint: runId,
|
|
5797
5898
|
taskWorktree,
|
|
5798
5899
|
cwd: workerCwd,
|
|
@@ -5802,7 +5903,8 @@ export function createDispatchBundle(
|
|
|
5802
5903
|
}
|
|
5803
5904
|
let handle: Awaited<ReturnType<typeof dispatchAttempt>>;
|
|
5804
5905
|
try {
|
|
5805
|
-
|
|
5906
|
+
preparation?.signal?.throwIfAborted();
|
|
5907
|
+
handle = await dispatchAttempt(prepared, observer, preparation, settlement);
|
|
5806
5908
|
} catch (error) {
|
|
5807
5909
|
writerLease?.release();
|
|
5808
5910
|
if (createdWorktree !== undefined) {
|
|
@@ -5929,7 +6031,6 @@ export function createDispatchBundle(
|
|
|
5929
6031
|
);
|
|
5930
6032
|
assertPostRuntimeToolCompatibility(req.agentId, agentSpec, effectiveTools, target);
|
|
5931
6033
|
assertRuntimeCanHonorWorkerPermissionMode(target.runtime, settings?.fleet.permissions.mode ?? "deny");
|
|
5932
|
-
assertWorkerBudgetEnforceable(target.runtime, agentSpec.budget !== null || req.budget !== undefined);
|
|
5933
6034
|
assertResponseSchemaEnforceable(target.runtime, target.modelCapabilities, req.responseSchema, effectiveTools.length);
|
|
5934
6035
|
assertWriteRootsEnforceable(target.runtime, pathScope.writeBoundaries);
|
|
5935
6036
|
assertProtectedArtifactsEnforceable(
|
|
@@ -5943,6 +6044,7 @@ export function createDispatchBundle(
|
|
|
5943
6044
|
declared: agentSpec.budget,
|
|
5944
6045
|
allowedTools: effectiveTools,
|
|
5945
6046
|
settings,
|
|
6047
|
+
runtime: target.runtime,
|
|
5946
6048
|
});
|
|
5947
6049
|
const endpoint = endpointCapacityForTarget(target.target.id);
|
|
5948
6050
|
return {
|
|
@@ -6191,7 +6293,10 @@ export function createDispatchBundle(
|
|
|
6191
6293
|
})();
|
|
6192
6294
|
}
|
|
6193
6295
|
|
|
6194
|
-
async function dispatchBatch(
|
|
6296
|
+
async function dispatchBatch(
|
|
6297
|
+
reqs: ReadonlyArray<DispatchRequest>,
|
|
6298
|
+
preparation?: DispatchPreparationOptions,
|
|
6299
|
+
): Promise<{
|
|
6195
6300
|
batchId: string;
|
|
6196
6301
|
assignmentIds: ReadonlyArray<string>;
|
|
6197
6302
|
events: AsyncIterableIterator<unknown>;
|
|
@@ -6210,7 +6315,7 @@ export function createDispatchBundle(
|
|
|
6210
6315
|
const handles: Array<Awaited<ReturnType<typeof dispatch>> & { agentId: string }> = [];
|
|
6211
6316
|
try {
|
|
6212
6317
|
for (const req of reqs) {
|
|
6213
|
-
const handle = await dispatch(req, undefined, settlement);
|
|
6318
|
+
const handle = await dispatch(req, undefined, preparation, settlement);
|
|
6214
6319
|
handles.push({ ...handle, agentId: req.agentId });
|
|
6215
6320
|
}
|
|
6216
6321
|
} catch (err) {
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* are pure data: no class methods, no engine refs.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import type { GatewayRoutingObservation } from "../../core/gateway-routing.js";
|
|
9
10
|
import type { ResponseModelIdObservation } from "../../core/response-model-id.js";
|
|
10
11
|
import type { SkillActivation } from "../../core/skill-activation.js";
|
|
11
12
|
import type { ToolProfileName } from "../../tools/profiles.js";
|
|
@@ -652,6 +653,8 @@ export interface RunReceiptUpstreamResponse {
|
|
|
652
653
|
responseModelIdObservation: ResponseModelIdObservation;
|
|
653
654
|
differingResponseModelId: string | null;
|
|
654
655
|
providerResponseId: string | null;
|
|
656
|
+
/** Physical route and proxy attempts reported by LiteLLM, when this call used that gateway. */
|
|
657
|
+
gatewayRouting?: GatewayRoutingObservation;
|
|
655
658
|
}
|
|
656
659
|
|
|
657
660
|
/**
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ProvidersContract } from "../providers/contract.js";
|
|
2
|
+
|
|
3
|
+
/** Preparation owns its wait; a late HTTP body cannot start an expired worker. */
|
|
4
|
+
export async function prepareWorkerModelMetadata(
|
|
5
|
+
providers: ProvidersContract,
|
|
6
|
+
targetId: string,
|
|
7
|
+
deadlineAt: number,
|
|
8
|
+
signal?: AbortSignal,
|
|
9
|
+
now: () => number = Date.now,
|
|
10
|
+
): Promise<void> {
|
|
11
|
+
signal?.throwIfAborted();
|
|
12
|
+
const status = providers.list().find((entry) => entry.target.id === targetId);
|
|
13
|
+
if (status?.target.runtime !== "litellm" || status.health.lastCheckAt !== null) return;
|
|
14
|
+
const remainingMs = deadlineAt - now();
|
|
15
|
+
const deadlineError = new Error("dispatch: admission deadline expired during worker model metadata preparation");
|
|
16
|
+
if (remainingMs <= 0) throw deadlineError;
|
|
17
|
+
const controller = new AbortController();
|
|
18
|
+
const abort = (): void => controller.abort(signal?.reason);
|
|
19
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
20
|
+
const timer = setTimeout(() => controller.abort(deadlineError), Math.min(remainingMs, 2_147_483_647));
|
|
21
|
+
let rejectAborted!: (reason: unknown) => void;
|
|
22
|
+
const aborted = new Promise<never>((_resolve, reject) => {
|
|
23
|
+
rejectAborted = reject;
|
|
24
|
+
});
|
|
25
|
+
const onAbort = (): void => rejectAborted(controller.signal.reason);
|
|
26
|
+
controller.signal.addEventListener("abort", onAbort, { once: true });
|
|
27
|
+
try {
|
|
28
|
+
// The provider also fences publication after each await. Promise.race
|
|
29
|
+
// observes the probe's eventual rejection if an HTTP body settles late.
|
|
30
|
+
await Promise.race([providers.probeTarget(targetId, { reasoning: false, signal: controller.signal }), aborted]);
|
|
31
|
+
controller.signal.throwIfAborted();
|
|
32
|
+
if (now() >= deadlineAt) throw deadlineError;
|
|
33
|
+
} finally {
|
|
34
|
+
clearTimeout(timer);
|
|
35
|
+
signal?.removeEventListener("abort", abort);
|
|
36
|
+
controller.signal.removeEventListener("abort", onAbort);
|
|
37
|
+
}
|
|
38
|
+
}
|