@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
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { BusChannels } from "../core/bus-events.js";
|
|
2
|
+
import type { SafeEventBus } from "../core/event-bus.js";
|
|
3
|
+
import type { TaskMemoryStepUsage } from "../domains/memory/task-memory-policy.js";
|
|
4
|
+
import type { MemoryInterventionRegistration } from "../domains/middleware/memory-intervention.js";
|
|
5
|
+
import {
|
|
6
|
+
type RecordBackgroundMemoryStepInput,
|
|
7
|
+
recordBackgroundMemoryStep,
|
|
8
|
+
} from "../domains/observability/background-memory-usage.js";
|
|
9
|
+
|
|
10
|
+
/** Explicit navigation owns memory lifetime; ordinary leaf advances and tree reads do not. */
|
|
11
|
+
export function bindTaskMemoryLifecycle(
|
|
12
|
+
bus: SafeEventBus,
|
|
13
|
+
memory: Pick<MemoryInterventionRegistration, "reset" | "dispose">,
|
|
14
|
+
): () => void {
|
|
15
|
+
const unsubscribe = [
|
|
16
|
+
bus.on(BusChannels.SessionParked, () => memory.reset()),
|
|
17
|
+
bus.on(BusChannels.SessionResumed, () => memory.reset()),
|
|
18
|
+
bus.on(BusChannels.SessionTurnSwitched, () => memory.reset()),
|
|
19
|
+
bus.on(BusChannels.SessionEnd, () => memory.dispose()),
|
|
20
|
+
];
|
|
21
|
+
return () => {
|
|
22
|
+
memory.dispose();
|
|
23
|
+
for (const off of unsubscribe) off();
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** The durable row keeps launch identity even when the live cost tracker has moved on. */
|
|
28
|
+
export function captureTaskMemoryUsage(
|
|
29
|
+
input: Omit<RecordBackgroundMemoryStepInput, "usage">,
|
|
30
|
+
): (usage: TaskMemoryStepUsage, isCurrent: boolean) => void {
|
|
31
|
+
const { observability, ...origin } = input;
|
|
32
|
+
return (usage, isCurrent) => {
|
|
33
|
+
recordBackgroundMemoryStep({ ...origin, usage, observability: isCurrent ? observability : undefined });
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -471,11 +471,11 @@ export function backendCacheVerdict(
|
|
|
471
471
|
return classifyCacheUsage(input, cacheRead);
|
|
472
472
|
}
|
|
473
473
|
|
|
474
|
-
/**
|
|
474
|
+
/** Native stream-invocation latency, measured on one monotonic clock. */
|
|
475
475
|
export interface AssistantCallTiming {
|
|
476
|
-
/**
|
|
476
|
+
/** Invocation to first assistant output; null when no output arrived. */
|
|
477
477
|
ttftMs: number | null;
|
|
478
|
-
/**
|
|
478
|
+
/** Invocation to message_end for the same assistant API call. */
|
|
479
479
|
apiMs: number;
|
|
480
480
|
}
|
|
481
481
|
|
|
@@ -490,7 +490,16 @@ export function assistantSessionPayload(
|
|
|
490
490
|
if (Array.isArray(raw.content)) payload.content = raw.content;
|
|
491
491
|
if (thinking.length > 0) payload.thinking = thinking;
|
|
492
492
|
payload.responseModelIdObservation = responseModelIdObservationFromRecord(raw, "not-observed");
|
|
493
|
-
for (const key of [
|
|
493
|
+
for (const key of [
|
|
494
|
+
"usage",
|
|
495
|
+
"api",
|
|
496
|
+
"provider",
|
|
497
|
+
"model",
|
|
498
|
+
"responseModel",
|
|
499
|
+
"responseId",
|
|
500
|
+
"gatewayRouting",
|
|
501
|
+
"diagnostics",
|
|
502
|
+
]) {
|
|
494
503
|
if (raw[key] !== undefined) payload[key] = raw[key];
|
|
495
504
|
}
|
|
496
505
|
if (failure && !isSelfExplainingAbort({ stopReason: raw.stopReason, errorMessage: raw.errorMessage, text })) {
|
|
@@ -16,7 +16,14 @@
|
|
|
16
16
|
import { BusChannels, type RunAbortSource } from "../core/bus-events.js";
|
|
17
17
|
import type { ClioSettings } from "../core/config.js";
|
|
18
18
|
import type { SafeEventBus } from "../core/event-bus.js";
|
|
19
|
-
import
|
|
19
|
+
import {
|
|
20
|
+
armedSkillSurface,
|
|
21
|
+
type PendingSkillRequest,
|
|
22
|
+
type PendingSkillToolPolicy,
|
|
23
|
+
skillSurfaceLabels,
|
|
24
|
+
skillSurfaceNames,
|
|
25
|
+
withModelSkillActivation,
|
|
26
|
+
} from "../core/skill-activation.js";
|
|
20
27
|
import { clioStateDir } from "../core/xdg.js";
|
|
21
28
|
import {
|
|
22
29
|
createMiddlewareToolChoiceControl,
|
|
@@ -36,6 +43,7 @@ import {
|
|
|
36
43
|
runtimeTargetSnapshot,
|
|
37
44
|
targetRequiresAuth,
|
|
38
45
|
} from "../domains/providers/index.js";
|
|
46
|
+
import { type AutonomyLevel, modelMayActivateSkills } from "../domains/safety/autonomy.js";
|
|
39
47
|
import type { ProtectedArtifactState } from "../domains/safety/protected-artifacts.js";
|
|
40
48
|
import type { CompactResult } from "../domains/session/compaction/compact.js";
|
|
41
49
|
import type { ContextSnapshot, ContextUsageSnapshot } from "../domains/session/context-accounting.js";
|
|
@@ -285,6 +293,12 @@ export interface ChatLoop {
|
|
|
285
293
|
* queues the text for the next slot instead.
|
|
286
294
|
*/
|
|
287
295
|
interruptRefusal(): string | null;
|
|
296
|
+
/**
|
|
297
|
+
* `/skill off`: drop the tool surface an activated skill armed, so the next
|
|
298
|
+
* turn runs with the full surface again. Returns the skill names that were
|
|
299
|
+
* armed, or an empty list when nothing was.
|
|
300
|
+
*/
|
|
301
|
+
clearSkillSurface(): ReadonlyArray<string>;
|
|
288
302
|
clearQueuedFollowUps(): string[];
|
|
289
303
|
queuedMessages(): QueuedMessagesSnapshot;
|
|
290
304
|
cancel(options?: ChatCancelOptions): void;
|
|
@@ -368,6 +382,12 @@ export interface ChatLoop {
|
|
|
368
382
|
|
|
369
383
|
export interface CreateChatLoopDeps {
|
|
370
384
|
getSettings: () => Readonly<ClioSettings>;
|
|
385
|
+
/**
|
|
386
|
+
* The same effective autonomy level registry admission resolves, so the
|
|
387
|
+
* skill-activation gate and the tool gate can never disagree. Absent falls
|
|
388
|
+
* back to the settings value.
|
|
389
|
+
*/
|
|
390
|
+
getAutonomy?: () => AutonomyLevel;
|
|
371
391
|
providers: ProvidersContract;
|
|
372
392
|
/**
|
|
373
393
|
* Whitelist of target ids that the chat-loop is allowed to drive. The
|
|
@@ -622,6 +642,31 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
|
|
|
622
642
|
emit({ type: "notice", level, surface: "transcript", text, ...(key === undefined ? {} : { key }) });
|
|
623
643
|
};
|
|
624
644
|
|
|
645
|
+
/**
|
|
646
|
+
* Carry (or drop) the tool surface a skill declared once the turn that
|
|
647
|
+
* loaded it settles, and say so once on the transcript. The operator needs
|
|
648
|
+
* to know a narrowing is armed across their next messages, and needs one
|
|
649
|
+
* line back when it lifts; the skill-activation ledger entry already
|
|
650
|
+
* records provenance, so this is the notice, not a second UI.
|
|
651
|
+
*/
|
|
652
|
+
const armSkillSurface = (policy: PendingSkillToolPolicy | undefined, loadedBefore?: ReadonlySet<string>): void => {
|
|
653
|
+
const previous = skillSurfaceNames(state.activeSkillSurface).join(", ");
|
|
654
|
+
const next = armedSkillSurface(policy);
|
|
655
|
+
const current = skillSurfaceNames(next).join(", ");
|
|
656
|
+
state.activeSkillSurface = next;
|
|
657
|
+
const activated = skillSurfaceLabels(policy).filter((label) => !loadedBefore?.has(label.split(" ")[0] ?? label));
|
|
658
|
+
if (activated.length > 0) {
|
|
659
|
+
emitNotice(
|
|
660
|
+
current.length > 0
|
|
661
|
+
? `[Clio Coder] Skill activated: ${activated.join(", ")}. Its tool surface stays armed across your next turns until another skill replaces it or you run /skill off.`
|
|
662
|
+
: `[Clio Coder] Skill activated: ${activated.join(", ")}. It declares no tool narrowing.`,
|
|
663
|
+
);
|
|
664
|
+
}
|
|
665
|
+
if (current !== previous && current.length === 0 && previous.length > 0) {
|
|
666
|
+
emitNotice(`[Clio Coder] Skill tool surface cleared: ${previous}. The full tool surface is back.`);
|
|
667
|
+
}
|
|
668
|
+
};
|
|
669
|
+
|
|
625
670
|
/**
|
|
626
671
|
* The same transcript notice every admission exit already emitted, carrying
|
|
627
672
|
* the reason the turn never started. Text, level, and surface are unchanged,
|
|
@@ -745,6 +790,7 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
|
|
|
745
790
|
context,
|
|
746
791
|
middleware,
|
|
747
792
|
retrySettings,
|
|
793
|
+
sessionId: () => deps.session?.current()?.id,
|
|
748
794
|
emit: emitRuntimeEvent,
|
|
749
795
|
emitNotice,
|
|
750
796
|
toolStartTimes,
|
|
@@ -959,6 +1005,11 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
|
|
|
959
1005
|
steer: (text) => queues.steer(text),
|
|
960
1006
|
queueFollowUp: (text) => queues.queueFollowUp(text),
|
|
961
1007
|
interruptRefusal: () => (state.streaming ? interruptRefusalReason() : null),
|
|
1008
|
+
clearSkillSurface: () => {
|
|
1009
|
+
const cleared = skillSurfaceNames(state.activeSkillSurface);
|
|
1010
|
+
armSkillSurface(undefined);
|
|
1011
|
+
return cleared;
|
|
1012
|
+
},
|
|
962
1013
|
clearQueuedFollowUps: () => queues.clearQueuedMirror().map((entry) => entry.text),
|
|
963
1014
|
queuedMessages: () => queues.queuedMessages(),
|
|
964
1015
|
|
|
@@ -1043,7 +1094,18 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
|
|
|
1043
1094
|
const images = options.images && options.images.length > 0 ? [...options.images] : undefined;
|
|
1044
1095
|
const pendingSkillRequests = options.pendingSkillRequests ?? [];
|
|
1045
1096
|
context.addWorkingContextPaths(options.workingContextPaths ?? []);
|
|
1046
|
-
|
|
1097
|
+
// A skill the operator activated narrows the tools for the workflow
|
|
1098
|
+
// it started, and that workflow outlives the turn it began in. A
|
|
1099
|
+
// fresh /skill this turn replaces the armed surface; otherwise the
|
|
1100
|
+
// armed surface is what this turn runs under.
|
|
1101
|
+
const pendingSkillPolicy = withModelSkillActivation(
|
|
1102
|
+
createPendingSkillToolPolicy(pendingSkillRequests) ?? state.activeSkillSurface,
|
|
1103
|
+
modelMayActivateSkills(deps.getAutonomy?.() ?? deps.getSettings().safety.autonomy),
|
|
1104
|
+
);
|
|
1105
|
+
// What was already loaded when this turn started, so the settle-time
|
|
1106
|
+
// notice names the skills this turn activated and not the ones a
|
|
1107
|
+
// carried surface has been holding since an earlier message.
|
|
1108
|
+
const skillsLoadedBeforeTurn = new Set(pendingSkillPolicy?.loadedSkillNames ?? []);
|
|
1047
1109
|
// Resolve the frozen session tool surface before turn_start so intent
|
|
1048
1110
|
// middleware sees the exact tools this request can actually call.
|
|
1049
1111
|
agentRuntime.agent.state.tools = resolveSessionTools(
|
|
@@ -1310,6 +1372,7 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
|
|
|
1310
1372
|
}
|
|
1311
1373
|
state.currentPendingSkillPolicy = priorPendingSkillPolicy;
|
|
1312
1374
|
state.currentAskUserPolicy = priorAskUserPolicy;
|
|
1375
|
+
armSkillSurface(pendingSkillPolicy, skillsLoadedBeforeTurn);
|
|
1313
1376
|
state.activeUserTurnId = null;
|
|
1314
1377
|
// Safety net for thrown paths where agent_end never delivered;
|
|
1315
1378
|
// no-op when the agent_end flush already ran.
|
|
@@ -46,6 +46,7 @@ export interface CostRow {
|
|
|
46
46
|
prewarms: number;
|
|
47
47
|
/** Calls in this row that were proactive-memory steps on the background target. */
|
|
48
48
|
backgroundMemory: number;
|
|
49
|
+
failedCompaction: number;
|
|
49
50
|
cost: CostAggregate;
|
|
50
51
|
}
|
|
51
52
|
|
|
@@ -79,6 +80,7 @@ export function aggregateCostEntries(entries: ReadonlyArray<CostEntry>): CostRow
|
|
|
79
80
|
if (entry.label === "handoff") existing.row.handoffs += 1;
|
|
80
81
|
if (entry.label === "prewarm") existing.row.prewarms += 1;
|
|
81
82
|
if (entry.label === "background-memory") existing.row.backgroundMemory += 1;
|
|
83
|
+
if (entry.label === "failed-compaction") existing.row.failedCompaction += 1;
|
|
82
84
|
for (const requestedModelId of entry.requestedModelIds) existing.requestedModelIds.add(requestedModelId);
|
|
83
85
|
addResponseModelIdObservationCounts(
|
|
84
86
|
existing.responseModelIdObservationCounts,
|
|
@@ -103,6 +105,7 @@ export function aggregateCostEntries(entries: ReadonlyArray<CostEntry>): CostRow
|
|
|
103
105
|
handoffs: entry.label === "handoff" ? 1 : 0,
|
|
104
106
|
prewarms: entry.label === "prewarm" ? 1 : 0,
|
|
105
107
|
backgroundMemory: entry.label === "background-memory" ? 1 : 0,
|
|
108
|
+
failedCompaction: entry.label === "failed-compaction" ? 1 : 0,
|
|
106
109
|
},
|
|
107
110
|
requestedModelIds: new Set(entry.requestedModelIds),
|
|
108
111
|
responseModelIdObservationCounts: { ...entry.responseModelIdObservationCounts },
|
|
@@ -143,6 +146,7 @@ function sumRows(
|
|
|
143
146
|
handoffs: acc.handoffs + row.handoffs,
|
|
144
147
|
prewarms: acc.prewarms + row.prewarms,
|
|
145
148
|
backgroundMemory: acc.backgroundMemory + row.backgroundMemory,
|
|
149
|
+
failedCompaction: acc.failedCompaction + row.failedCompaction,
|
|
146
150
|
}),
|
|
147
151
|
{
|
|
148
152
|
runs: 0,
|
|
@@ -157,6 +161,7 @@ function sumRows(
|
|
|
157
161
|
handoffs: 0,
|
|
158
162
|
prewarms: 0,
|
|
159
163
|
backgroundMemory: 0,
|
|
164
|
+
failedCompaction: 0,
|
|
160
165
|
},
|
|
161
166
|
);
|
|
162
167
|
}
|
|
@@ -229,13 +234,26 @@ function summaryBlock(
|
|
|
229
234
|
return kvBlock([
|
|
230
235
|
[
|
|
231
236
|
"turns",
|
|
232
|
-
formatTokens(
|
|
237
|
+
formatTokens(
|
|
238
|
+
totals.runs -
|
|
239
|
+
totals.sideQuestions -
|
|
240
|
+
totals.handoffs -
|
|
241
|
+
totals.prewarms -
|
|
242
|
+
totals.backgroundMemory -
|
|
243
|
+
totals.failedCompaction,
|
|
244
|
+
),
|
|
233
245
|
],
|
|
234
246
|
["model calls", formatTokens(totals.apiCalls)],
|
|
235
247
|
...(totals.sideQuestions > 0 ? [["side questions", formatTokens(totals.sideQuestions)] as const] : []),
|
|
236
248
|
...(totals.handoffs > 0 ? [["handoffs", formatTokens(totals.handoffs)] as const] : []),
|
|
237
249
|
...(totals.prewarms > 0 ? [["pre-warms", formatTokens(totals.prewarms)] as const] : []),
|
|
238
250
|
...(totals.backgroundMemory > 0 ? [["memory steps", formatTokens(totals.backgroundMemory)] as const] : []),
|
|
251
|
+
...(totals.failedCompaction > 0
|
|
252
|
+
? [
|
|
253
|
+
["failed compaction calls", formatTokens(totals.failedCompaction)] as const,
|
|
254
|
+
["compaction usage", "known subtotals; missing usage is unknown"] as const,
|
|
255
|
+
]
|
|
256
|
+
: []),
|
|
239
257
|
...(cost === null ? [] : [["cost", cost] as const]),
|
|
240
258
|
["input", formatTokens(totals.input)],
|
|
241
259
|
["output", formatTokens(totals.output)],
|
|
@@ -255,12 +273,18 @@ function modelBlock(row: CostRow): string[] {
|
|
|
255
273
|
return kvBlock([
|
|
256
274
|
["requested model ids", row.requestedModelIds.join(", ")],
|
|
257
275
|
["response model id observation", responseModelIdObservationCountsLabel(row.responseModelIdObservationCounts)],
|
|
258
|
-
[
|
|
276
|
+
[
|
|
277
|
+
"turns",
|
|
278
|
+
formatTokens(
|
|
279
|
+
row.runs - row.sideQuestions - row.handoffs - row.prewarms - row.backgroundMemory - row.failedCompaction,
|
|
280
|
+
),
|
|
281
|
+
],
|
|
259
282
|
["model calls", formatTokens(row.apiCalls)],
|
|
260
283
|
...(row.sideQuestions > 0 ? [["side questions", formatTokens(row.sideQuestions)] as const] : []),
|
|
261
284
|
...(row.handoffs > 0 ? [["handoffs", formatTokens(row.handoffs)] as const] : []),
|
|
262
285
|
...(row.prewarms > 0 ? [["pre-warms", formatTokens(row.prewarms)] as const] : []),
|
|
263
286
|
...(row.backgroundMemory > 0 ? [["memory steps", formatTokens(row.backgroundMemory)] as const] : []),
|
|
287
|
+
...(row.failedCompaction > 0 ? [["failed compaction calls", formatTokens(row.failedCompaction)] as const] : []),
|
|
264
288
|
...(cost === null ? [] : [["cost", cost] as const]),
|
|
265
289
|
["input", formatTokens(row.input)],
|
|
266
290
|
["output", formatTokens(row.output)],
|
|
@@ -62,7 +62,7 @@ export interface InteractiveSlashSubmitExpansion {
|
|
|
62
62
|
pendingSkillRequests: PendingSkillRequest[];
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
type SlashChat = Pick<ChatLoop, "getSessionId" | "isStreaming" | "submit">;
|
|
65
|
+
type SlashChat = Pick<ChatLoop, "clearSkillSurface" | "getSessionId" | "isStreaming" | "submit">;
|
|
66
66
|
type SlashChatPanel = Pick<ChatPanel, "appendReplayBlock" | "appendUser" | "clearFoldOverrides">;
|
|
67
67
|
type UserTurnStatus = import("./chat-panel.js").UserTurnStatus;
|
|
68
68
|
type SlashResources = Pick<ResourcesContract, "prompts" | "expandPromptTemplate" | "reload">;
|
|
@@ -389,6 +389,7 @@ export function createInteractiveSlashRuntime(deps: InteractiveSlashRuntimeDeps)
|
|
|
389
389
|
listPrompts: () => deps.resources?.prompts(cwd()) ?? { items: [], diagnostics: [] },
|
|
390
390
|
...(resources ? { expandPromptTemplate: (text: string) => resources.expandPromptTemplate(text, cwd()) } : {}),
|
|
391
391
|
openSkillsHub: deps.openSkillsHub,
|
|
392
|
+
clearSkillSurface: () => deps.chat.clearSkillSurface(),
|
|
392
393
|
listExtensions: () => deps.extensions?.list(cwd(), { all: true }) ?? [],
|
|
393
394
|
listAgents: () => deps.agents?.listSpecs().filter((spec) => spec.audience !== "internal") ?? [],
|
|
394
395
|
listDelegationAgents: () => deps.getSettings?.().integrations.externalAgents.entries ?? [],
|
|
@@ -206,6 +206,36 @@ function researchReport(value: Record<string, unknown>): PresentedContractAnswer
|
|
|
206
206
|
return { lines: lines.length === 0 ? ["No findings reported."] : lines, footer: `source ${value.source}` };
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
+
function worldKnowledgeReport(value: Record<string, unknown>): PresentedContractAnswer | null {
|
|
210
|
+
if (
|
|
211
|
+
(value.discovery !== "performed" &&
|
|
212
|
+
value.discovery !== "caller-supplied-only" &&
|
|
213
|
+
value.discovery !== "unavailable") ||
|
|
214
|
+
!Array.isArray(value.facts) ||
|
|
215
|
+
!isStringArray(value.synthesis) ||
|
|
216
|
+
!isStringArray(value.uncertainties) ||
|
|
217
|
+
!isStringArray(value.followUpVerification)
|
|
218
|
+
) {
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
const lines: string[] = [];
|
|
222
|
+
for (const raw of value.facts) {
|
|
223
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) return null;
|
|
224
|
+
const fact = raw as Record<string, unknown>;
|
|
225
|
+
const claim = reportString(fact.claim);
|
|
226
|
+
const evidence = reportString(fact.evidence);
|
|
227
|
+
if (claim === null || evidence === null || !isStringArray(fact.sources)) return null;
|
|
228
|
+
lines.push(`- ${claim}`, ` support: ${evidence}`);
|
|
229
|
+
if (fact.sources.length > 0) lines.push(` sources: ${fact.sources.join(", ")}`);
|
|
230
|
+
}
|
|
231
|
+
if (value.synthesis.length > 0) lines.push("Synthesis:", ...value.synthesis.map((item) => `- ${item}`));
|
|
232
|
+
if (value.uncertainties.length > 0) lines.push("Uncertainties:", ...value.uncertainties.map((item) => `- ${item}`));
|
|
233
|
+
if (value.followUpVerification.length > 0) {
|
|
234
|
+
lines.push("Verify next:", ...value.followUpVerification.map((item) => `- ${item}`));
|
|
235
|
+
}
|
|
236
|
+
return { lines: lines.length === 0 ? ["No findings reported."] : lines, footer: `discovery ${value.discovery}` };
|
|
237
|
+
}
|
|
238
|
+
|
|
209
239
|
function scoutReport(value: Record<string, unknown>): PresentedContractAnswer | null {
|
|
210
240
|
if (!Array.isArray(value.findings) || typeof value.needsSplit !== "boolean") return null;
|
|
211
241
|
const lines: string[] = [];
|
|
@@ -250,6 +280,8 @@ function presentedContractAnswer(entry: WorkerEntryState): PresentedContractAnsw
|
|
|
250
280
|
return verifierReport(value);
|
|
251
281
|
case "research-report":
|
|
252
282
|
return researchReport(value);
|
|
283
|
+
case "world-knowledge-report":
|
|
284
|
+
return worldKnowledgeReport(value);
|
|
253
285
|
case "scout-report":
|
|
254
286
|
return scoutReport(value);
|
|
255
287
|
}
|
|
@@ -28,7 +28,7 @@ import type {
|
|
|
28
28
|
PromptTemplateExpansion,
|
|
29
29
|
ResourceList,
|
|
30
30
|
} from "../domains/resources/index.js";
|
|
31
|
-
import { parseSkillCommand } from "../domains/resources/index.js";
|
|
31
|
+
import { parseSkillCommand, SKILL_SURFACE_CLEAR_ARG } from "../domains/resources/index.js";
|
|
32
32
|
import type { ShareImportPlan } from "../domains/share/index.js";
|
|
33
33
|
import type { UserTask } from "../domains/user-tasks/store.js";
|
|
34
34
|
import type { ExtensionReloadOutcome } from "../entry/extension-reload.js";
|
|
@@ -118,6 +118,8 @@ type SlashCommandVariant =
|
|
|
118
118
|
| { kind: "skill-selector" }
|
|
119
119
|
| { kind: "resources"; family?: "skills" | "prompts" | "extensions"; tab?: LibraryEntryKind; action?: "reload" }
|
|
120
120
|
| { kind: "skill-invocation"; text: string }
|
|
121
|
+
/** `/skill off`: drop the tool surface an activated skill armed for the session. */
|
|
122
|
+
| { kind: "skill-surface-clear" }
|
|
121
123
|
| ShareCommandVariant
|
|
122
124
|
| ArchiveCommandVariant
|
|
123
125
|
/** `source` is the line the operator typed, echoed above the run's transcript block. */
|
|
@@ -595,6 +597,12 @@ export interface SlashCommandContext {
|
|
|
595
597
|
*/
|
|
596
598
|
runContextRecall?: (ref: string) => void;
|
|
597
599
|
openSkillsHub?: (tab?: LibraryEntryKind) => void;
|
|
600
|
+
/**
|
|
601
|
+
* `/skill off`: drop the tool surface an activated skill armed for the
|
|
602
|
+
* session. Returns the names that were armed. Absent on a host with no
|
|
603
|
+
* chat loop, where nothing can be armed in the first place.
|
|
604
|
+
*/
|
|
605
|
+
clearSkillSurface?: () => ReadonlyArray<string>;
|
|
598
606
|
listPrompts: () => ResourceList<PromptTemplate>;
|
|
599
607
|
/**
|
|
600
608
|
* Resolve a `/name` against the loaded prompt templates. Absent when the host
|
|
@@ -912,9 +920,9 @@ export const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [
|
|
|
912
920
|
},
|
|
913
921
|
{
|
|
914
922
|
name: "skill",
|
|
915
|
-
description: "Open the Skills Hub
|
|
923
|
+
description: "Open the Skills Hub, invoke a skill, or `off` to drop an active skill's tool surface",
|
|
916
924
|
group: "Work",
|
|
917
|
-
kinds: ["skill-selector", "skill-invocation"],
|
|
925
|
+
kinds: ["skill-selector", "skill-invocation", "skill-surface-clear"],
|
|
918
926
|
args: {
|
|
919
927
|
positionals: [
|
|
920
928
|
{ name: "name", required: false },
|
|
@@ -926,16 +934,26 @@ export const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [
|
|
|
926
934
|
return { kind: "skill-selector" };
|
|
927
935
|
}
|
|
928
936
|
const command = parseSkillCommand(trimmed);
|
|
929
|
-
if (command)
|
|
930
|
-
|
|
937
|
+
if (!command) return null;
|
|
938
|
+
// `off` is the one reserved name: an installed skill called `off`
|
|
939
|
+
// would still be reachable from the hub, and clearing the armed
|
|
940
|
+
// surface has to stay typeable without a second command.
|
|
941
|
+
if (command.name === SKILL_SURFACE_CLEAR_ARG && command.args.length === 0) {
|
|
942
|
+
return { kind: "skill-surface-clear" };
|
|
931
943
|
}
|
|
932
|
-
return
|
|
944
|
+
return { kind: "skill-invocation", text: trimmed };
|
|
933
945
|
},
|
|
934
946
|
handle(command, ctx) {
|
|
935
947
|
if (command.kind === "skill-selector") {
|
|
936
948
|
ctx.openSkillsHub?.();
|
|
937
949
|
} else if (command.kind === "skill-invocation") {
|
|
938
950
|
ctx.submitChat(command.text);
|
|
951
|
+
} else if (command.kind === "skill-surface-clear") {
|
|
952
|
+
const cleared = ctx.clearSkillSurface?.() ?? [];
|
|
953
|
+
ctx.notice(
|
|
954
|
+
"info",
|
|
955
|
+
cleared.length > 0 ? `Skill tool surface cleared: ${cleared.join(", ")}.` : "No skill tool surface is active.",
|
|
956
|
+
);
|
|
939
957
|
}
|
|
940
958
|
},
|
|
941
959
|
},
|
|
@@ -1,23 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Abbreviate a wire model id for chips and dashboards without amputating a
|
|
3
|
-
* version suffix.
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* `qwen3-coder-30b`. A single part longer than 18 characters is hard-clipped.
|
|
3
|
+
* meaningful placement prefix or version suffix. `dynamo/qwen3.8-27b` remains
|
|
4
|
+
* visible as selected; only the leaf is shortened when the complete route is
|
|
5
|
+
* wider than 24 characters.
|
|
7
6
|
*/
|
|
8
7
|
export function abbreviateModelId(modelId: string | null | undefined): string {
|
|
9
|
-
const
|
|
8
|
+
const segments = (modelId ?? "").trim().split("/").filter(Boolean);
|
|
9
|
+
const base = segments.pop() ?? "";
|
|
10
10
|
if (base.length === 0) return "model";
|
|
11
|
+
const prefix = segments[0];
|
|
12
|
+
const maxLeaf = prefix ? Math.max(8, 24 - prefix.length - 1) : 18;
|
|
11
13
|
const parts = base.split("-").filter((part) => part.length > 0);
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
let leaf: string;
|
|
15
|
+
if (parts.length <= 1) leaf = base.length > maxLeaf ? base.slice(0, maxLeaf) : base;
|
|
16
|
+
else {
|
|
17
|
+
const kept: string[] = [];
|
|
18
|
+
for (const part of parts) {
|
|
19
|
+
const next = [...kept, part].join("-");
|
|
20
|
+
if (kept.length > 0 && next.length > maxLeaf) break;
|
|
21
|
+
kept.push(part);
|
|
22
|
+
}
|
|
23
|
+
const joined = kept.join("-");
|
|
24
|
+
leaf = joined.length > maxLeaf ? joined.slice(0, maxLeaf) : joined;
|
|
18
25
|
}
|
|
19
|
-
|
|
20
|
-
return joined.length > 18 ? joined.slice(0, 18) : joined;
|
|
26
|
+
return prefix ? `${prefix}/${leaf}` : leaf;
|
|
21
27
|
}
|
|
22
28
|
|
|
23
29
|
export interface TargetLabelOptions {
|
|
@@ -641,8 +641,8 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
641
641
|
if (!usage || !deps.observability) return;
|
|
642
642
|
if (usage.totalTokens <= 0 && usage.cost.total <= 0) return;
|
|
643
643
|
deps.observability.recordTokens(
|
|
644
|
-
agentRuntime.targetId,
|
|
645
|
-
agentRuntime.wireModelId,
|
|
644
|
+
usage.targetId ?? agentRuntime.targetId,
|
|
645
|
+
usage.modelId ?? agentRuntime.wireModelId,
|
|
646
646
|
usage.totalTokens,
|
|
647
647
|
usage.cost.total,
|
|
648
648
|
{
|
|
@@ -654,7 +654,11 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
654
654
|
totalTokens: usage.totalTokens,
|
|
655
655
|
apiCalls: Math.max(1, Math.round(usage.apiCalls)),
|
|
656
656
|
},
|
|
657
|
-
|
|
657
|
+
usage.targetId === undefined && usage.modelId === undefined
|
|
658
|
+
? agentRuntime.runtimeResolution.costProvenance
|
|
659
|
+
: usage.cost.total > 0
|
|
660
|
+
? "estimated"
|
|
661
|
+
: "unknown",
|
|
658
662
|
);
|
|
659
663
|
};
|
|
660
664
|
|
|
@@ -915,8 +919,8 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
915
919
|
if (!summaryLifecycleStarted) startSummaryLifecycle();
|
|
916
920
|
deps.bus?.emit(BusChannels.CompactionEnd, { trigger, at: Date.now() });
|
|
917
921
|
|
|
918
|
-
// The
|
|
919
|
-
//
|
|
922
|
+
// The checkpoint identifies the selected summary route; older results
|
|
923
|
+
// fall back to the active chat route. The ledger carries usage for reseed; this is the
|
|
920
924
|
// live sink, so `/cost` and the footer move the moment /context compact
|
|
921
925
|
// returns instead of staying byte-identical to before it ran.
|
|
922
926
|
recordCompactionUsage(agentRuntime, result);
|
|
@@ -217,6 +217,14 @@ export function createTurnRecovery(deps: TurnRecoveryDeps): TurnRecovery {
|
|
|
217
217
|
text: string,
|
|
218
218
|
initialFailure: TerminalAssistantFailure,
|
|
219
219
|
): Promise<boolean> => {
|
|
220
|
+
// A LiteLLM model id can be a deliberate physical route. Retrying it in
|
|
221
|
+
// Clio obscures the failure, delays operator recovery, and can multiply
|
|
222
|
+
// attempts beneath a gateway. Preserve and emit the one terminal failure;
|
|
223
|
+
// the operator can choose another advertised route with /model.
|
|
224
|
+
if (agentRuntime.runtimeId === "litellm") {
|
|
225
|
+
ensureFailureVisibleAndPersisted(initialFailure);
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
220
228
|
const settings = deps.retrySettings();
|
|
221
229
|
if (!settings.enabled || settings.maxRetries <= 0) return false;
|
|
222
230
|
if (initialFailure.stopReason === "aborted" || !isRetryableErrorMessage(initialFailure.errorMessage)) return false;
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { performance } from "node:perf_hooks";
|
|
9
9
|
import type { BackendCompletionTimings } from "../core/cache-telemetry.js";
|
|
10
10
|
import type { ClioSettings } from "../core/config.js";
|
|
11
|
+
import { gatewayRoutingObservationFromRecord, gatewayRoutingObservationLabel } from "../core/gateway-routing.js";
|
|
11
12
|
import { attributedModelId } from "../core/response-model-id.js";
|
|
12
13
|
import type { MiddlewareToolChoiceControl } from "../domains/middleware/index.js";
|
|
13
14
|
import type { ObservabilityContract } from "../domains/observability/contract.js";
|
|
@@ -130,6 +131,8 @@ export interface TurnRuntimeDeps {
|
|
|
130
131
|
context: TurnContext;
|
|
131
132
|
middleware: TurnMiddleware;
|
|
132
133
|
retrySettings: () => RetrySettings;
|
|
134
|
+
/** Stable Clio session id forwarded only to gateway runtimes that understand it. */
|
|
135
|
+
sessionId?: () => string | undefined;
|
|
133
136
|
emit: (event: AgentEvent | AssistantDeltaEvent) => void;
|
|
134
137
|
emitNotice: (text: string) => void;
|
|
135
138
|
/** Tool-call id to its `performance.now()` start mark; spans only, never an instant. */
|
|
@@ -447,6 +450,11 @@ export function createTurnRuntime(deps: TurnRuntimeDeps): TurnRuntime {
|
|
|
447
450
|
cleanupSessionResources(state.runtime.agent.sessionId);
|
|
448
451
|
}
|
|
449
452
|
let getCurrentAgentSignal: () => AbortSignal | undefined = () => undefined;
|
|
453
|
+
const gatewaySessionId = target.runtime.id === "litellm" ? deps.sessionId?.() : undefined;
|
|
454
|
+
// message_start can follow response headers. Keep each invocation's
|
|
455
|
+
// monotonic anchor before that wait, including custom stream delegates.
|
|
456
|
+
let apiCallStartedAt: number | null = null;
|
|
457
|
+
let apiCallFirstDeltaAt: number | null = null;
|
|
450
458
|
const handle = deps.createAgent({
|
|
451
459
|
initialState: {
|
|
452
460
|
systemPrompt: fallbackIdentityPrompt(),
|
|
@@ -456,6 +464,11 @@ export function createTurnRuntime(deps: TurnRuntimeDeps): TurnRuntime {
|
|
|
456
464
|
messages: priorMessages,
|
|
457
465
|
},
|
|
458
466
|
maxRetryDelayMs: deps.retrySettings().maxDelayMs,
|
|
467
|
+
...(gatewaySessionId ? { sessionId: gatewaySessionId } : {}),
|
|
468
|
+
onStreamInvocation: () => {
|
|
469
|
+
apiCallStartedAt = performance.now();
|
|
470
|
+
apiCallFirstDeltaAt = null;
|
|
471
|
+
},
|
|
459
472
|
onPayload: async (payload, currentModel) => {
|
|
460
473
|
const thinkingPatched = patchProviderThinkingPayload(payload, currentModel, state.currentThinkingLevel);
|
|
461
474
|
const basePayload = thinkingPatched ?? payload;
|
|
@@ -575,10 +588,6 @@ export function createTurnRuntime(deps: TurnRuntimeDeps): TurnRuntime {
|
|
|
575
588
|
|
|
576
589
|
let streamStartedAt: number | null = null;
|
|
577
590
|
let firstAssistantDeltaAt: number | null = null;
|
|
578
|
-
// Per-API-call timing (T3.2): one assistant message per provider call,
|
|
579
|
-
// bounded by message_start/message_end; the first delta marks TTFT.
|
|
580
|
-
let apiCallStartedAt: number | null = null;
|
|
581
|
-
let apiCallFirstDeltaAt: number | null = null;
|
|
582
591
|
// First call of the run is the one whose verdict says whether the
|
|
583
592
|
// backend reused the session prefix; later calls in a tool loop are
|
|
584
593
|
// trivially warm.
|
|
@@ -669,6 +678,15 @@ export function createTurnRuntime(deps: TurnRuntimeDeps): TurnRuntime {
|
|
|
669
678
|
}
|
|
670
679
|
let publicEvent = enrichedEvent;
|
|
671
680
|
if (enrichedEvent.type === "message_end" && enrichedEvent.message?.role === "assistant") {
|
|
681
|
+
const gatewayRouting = gatewayRoutingObservationFromRecord(
|
|
682
|
+
enrichedEvent.message as unknown as Record<string, unknown>,
|
|
683
|
+
);
|
|
684
|
+
if (
|
|
685
|
+
gatewayRouting !== null &&
|
|
686
|
+
((gatewayRouting.attemptedFallbacks ?? 0) > 0 || (gatewayRouting.attemptedRetries ?? 0) > 0)
|
|
687
|
+
) {
|
|
688
|
+
deps.emitNotice(`[Clio Coder] ${gatewayRoutingObservationLabel(gatewayRouting)}`);
|
|
689
|
+
}
|
|
672
690
|
const interruptedUsage = estimatedUsageForInterruptedTurn(enrichedEvent.message, context.promptSideTokens());
|
|
673
691
|
if (interruptedUsage !== null) {
|
|
674
692
|
// Persistence records the same estimate, but it does so after the
|
|
@@ -718,17 +736,15 @@ export function createTurnRuntime(deps: TurnRuntimeDeps): TurnRuntime {
|
|
|
718
736
|
// mediator, a dropped frame) therefore stops suspending the watchdog
|
|
719
737
|
// at the turn that issued it instead of for the rest of the run.
|
|
720
738
|
if (publicEvent?.type === "turn_end") toolsInFlight = 0;
|
|
721
|
-
if (publicEvent?.type === "message_start" && publicEvent.message?.role === "assistant") {
|
|
722
|
-
apiCallStartedAt = eventClock;
|
|
723
|
-
apiCallFirstDeltaAt = null;
|
|
724
|
-
}
|
|
725
739
|
if (publicEvent?.type === "message_update") {
|
|
726
740
|
const assistantEvent = publicEvent.assistantMessageEvent as { type?: string; delta?: unknown };
|
|
727
741
|
const hasDelta =
|
|
728
|
-
assistantEvent.type === "text_delta" ||
|
|
729
|
-
assistantEvent.type === "thinking_delta" ||
|
|
730
742
|
assistantEvent.type === "toolcall_start" ||
|
|
731
|
-
assistantEvent.type === "
|
|
743
|
+
((assistantEvent.type === "text_delta" ||
|
|
744
|
+
assistantEvent.type === "thinking_delta" ||
|
|
745
|
+
assistantEvent.type === "toolcall_delta") &&
|
|
746
|
+
typeof assistantEvent.delta === "string" &&
|
|
747
|
+
assistantEvent.delta.length > 0);
|
|
732
748
|
if (hasDelta && firstAssistantDeltaAt === null) firstAssistantDeltaAt = eventClock;
|
|
733
749
|
if (hasDelta && apiCallFirstDeltaAt === null) apiCallFirstDeltaAt = eventClock;
|
|
734
750
|
}
|
|
@@ -127,6 +127,12 @@ export interface ChatTurnState {
|
|
|
127
127
|
/** A middleware request_continuation is waiting to resubmit after settle. */
|
|
128
128
|
pendingRequestContinuation: boolean;
|
|
129
129
|
currentPendingSkillPolicy: PendingSkillToolPolicy | undefined;
|
|
130
|
+
/**
|
|
131
|
+
* Tool surface an activated skill narrowed, held across the operator's
|
|
132
|
+
* later turns. Replaced when the operator activates a different skill,
|
|
133
|
+
* cleared by `/skill off`, gone with the session.
|
|
134
|
+
*/
|
|
135
|
+
activeSkillSurface: PendingSkillToolPolicy | undefined;
|
|
130
136
|
currentAskUserPolicy: AskUserToolPolicy | undefined;
|
|
131
137
|
lastRunSnapshot: ChatLoopRunSnapshot | null;
|
|
132
138
|
}
|
|
@@ -153,6 +159,7 @@ export function createTurnState(initialThinkingLevel: ThinkingLevel): ChatTurnSt
|
|
|
153
159
|
stalledTurnNudgeSpent: false,
|
|
154
160
|
pendingRequestContinuation: false,
|
|
155
161
|
currentPendingSkillPolicy: undefined,
|
|
162
|
+
activeSkillSurface: undefined,
|
|
156
163
|
currentAskUserPolicy: undefined,
|
|
157
164
|
lastRunSnapshot: null,
|
|
158
165
|
};
|