@iowarp/clio-coder 0.3.9 → 0.4.1
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 +92 -0
- package/NOTICE +33 -0
- package/README.md +121 -16
- package/dist/{acp-7LOELQFP.js → acp-ZILU3AUO.js} +19 -18
- package/dist/{agents-FIBG2SHA.js → agents-HYWGBGQR.js} +53 -39
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-OI4LIH2I.js → auth-N3QT7CBO.js} +24 -21
- package/dist/{builtins-AD25UL3C.js → builtins-UJLMOVOV.js} +6 -6
- package/dist/{chunk-I4HZDVNP.js → chunk-2LEAKD4C.js} +2 -3
- package/dist/{chunk-465CC7FK.js → chunk-2NM363SV.js} +60 -64
- package/dist/{chunk-4H6ULJ3H.js → chunk-2VG7KLYV.js} +1046 -1370
- package/dist/{chunk-SST6Z5JA.js → chunk-336NSSKI.js} +1 -1
- package/dist/{chunk-NZU6YDNV.js → chunk-3I5NY75V.js} +5 -5
- package/dist/{chunk-47CMYGET.js → chunk-3QSOM6PA.js} +2 -2
- package/dist/chunk-42FMPA75.js +101 -0
- package/dist/{chunk-HAY4ZE2P.js → chunk-5PSMVOLM.js} +2 -2
- package/dist/{chunk-IHKBWSXF.js → chunk-5QIAJV2D.js} +3 -3
- package/dist/chunk-5YHDIDBP.js +97 -0
- package/dist/chunk-6CCS4G3W.js +1529 -0
- package/dist/{chunk-2JDWVJND.js → chunk-6DWBAZ5U.js} +2 -2
- package/dist/{chunk-BVDVID7E.js → chunk-6FN3E6KX.js} +6 -6
- package/dist/{chunk-DG4M6ZUE.js → chunk-6HMJX2VU.js} +59 -59
- package/dist/{chunk-3MRC2YSQ.js → chunk-6I5ILFOF.js} +3 -2
- package/dist/chunk-6NJQITNH.js +1412 -0
- package/dist/chunk-6VC4OV3Z.js +365 -0
- package/dist/{chunk-LU7P4LHA.js → chunk-72GZI5EV.js} +2 -2
- package/dist/{chunk-5T7RBWN2.js → chunk-74YWRRU5.js} +9 -8
- package/dist/{chunk-VPTUJU4P.js → chunk-7EPLI7VL.js} +2 -2
- package/dist/{chunk-CA42X6KT.js → chunk-7OBGU7UB.js} +7 -7
- package/dist/{chunk-56KB5IJP.js → chunk-7PWAODYW.js} +3 -3
- package/dist/chunk-7RY5VZPH.js +573 -0
- package/dist/{chunk-OEDBCISO.js → chunk-ABLSQ6JX.js} +3 -3
- package/dist/{chunk-5HFBWUMU.js → chunk-AFKWHWXF.js} +13 -23
- package/dist/{chunk-FWDFM5ZU.js → chunk-AK5XEFVZ.js} +3 -3
- package/dist/{chunk-WXCJ7VME.js → chunk-AKB4GYDL.js} +7 -7
- package/dist/chunk-AP73CFDC.js +308 -0
- package/dist/{chunk-4LJX2PUC.js → chunk-BBTJOK6Y.js} +5 -5
- package/dist/{chunk-QQ7EKM72.js → chunk-BDPT6GTK.js} +13 -61
- package/dist/chunk-BJGUKIG4.js +302 -0
- package/dist/chunk-BMS5RKQY.js +27 -0
- package/dist/{chunk-TD7UE2L5.js → chunk-BTGG6BG2.js} +81 -40
- package/dist/chunk-BTK3SSSK.js +67 -0
- package/dist/{chunk-M6L6IDJG.js → chunk-BWH6N36D.js} +1 -1
- package/dist/chunk-BWW4HLO4.js +301 -0
- package/dist/{chunk-BNAZZHFG.js → chunk-BYP5D4HI.js} +1 -1
- package/dist/{chunk-HJB5IUKP.js → chunk-C537JADH.js} +18 -18
- package/dist/{chunk-774ILSRL.js → chunk-CDNVLKUX.js} +5 -4
- package/dist/{chunk-HPCTNZM2.js → chunk-CTJ4RNAA.js} +4 -4
- package/dist/{chunk-AEYBF3TB.js → chunk-CWVRRIEI.js} +2 -2
- package/dist/chunk-D4CJV46V.js +462 -0
- package/dist/chunk-D7E7WCDF.js +27 -0
- package/dist/{chunk-5PVQ4SRS.js → chunk-E67WX76H.js} +10 -126
- package/dist/{chunk-FQ4SKYE4.js → chunk-EBY63B7G.js} +2 -5
- package/dist/chunk-EIMVLWB3.js +1842 -0
- package/dist/{chunk-AMKHQW3C.js → chunk-FEFIFZTL.js} +3 -3
- package/dist/{chunk-RAPCMZL4.js → chunk-FSP7CMNU.js} +9 -1
- package/dist/{chunk-3DUR4WUA.js → chunk-FYUN5KZ3.js} +25 -25
- package/dist/{chunk-MV3K5QF2.js → chunk-GCSMB2KY.js} +2 -2
- package/dist/chunk-GIZNH63R.js +40 -0
- package/dist/chunk-GPPB3JBE.js +688 -0
- package/dist/{chunk-B5XRQOLB.js → chunk-GVQJ5CCZ.js} +17 -11
- package/dist/chunk-HHV2GANA.js +88 -0
- package/dist/chunk-HJWWJ6IL.js +184 -0
- package/dist/{chunk-RKRLDWD3.js → chunk-HLW2MRKE.js} +1 -1
- package/dist/chunk-HRQMFLJP.js +75 -0
- package/dist/{chunk-AD7Y7STJ.js → chunk-HUAS7ITX.js} +107 -97
- package/dist/{chunk-O6I4CIEU.js → chunk-I66EAJFY.js} +6 -6
- package/dist/{chunk-S4COXYBG.js → chunk-IG7BCQBA.js} +129 -106
- package/dist/{chunk-N3PBVRTZ.js → chunk-IXJT6DCX.js} +9 -7
- package/dist/chunk-J4HBWF6Y.js +2635 -0
- package/dist/chunk-J5LZHVIT.js +284 -0
- package/dist/{chunk-GAYUJ7LE.js → chunk-JA5QWE4Z.js} +544 -227
- package/dist/{chunk-B5CSFE7B.js → chunk-JIEGK6UF.js} +6 -174
- package/dist/{chunk-VKBMFOYV.js → chunk-JZWT5J3Y.js} +23 -27
- package/dist/chunk-K6BF4U2H.js +1785 -0
- package/dist/{chunk-CGKSTWHD.js → chunk-K6BSR66V.js} +2 -1
- package/dist/{chunk-YSEHGPCT.js → chunk-MA3H6DM5.js} +6 -6
- package/dist/{chunk-EBOC7MT3.js → chunk-MOPSG2X7.js} +9 -9
- package/dist/{chunk-KV2AOLDF.js → chunk-MQXIVJ35.js} +18 -29
- package/dist/{chunk-P3JGPQFL.js → chunk-N5UK64DP.js} +4 -4
- package/dist/chunk-NDDGJUXD.js +81 -0
- package/dist/chunk-NEKRRTYW.js +56 -0
- package/dist/{chunk-4ZG3XFUR.js → chunk-NLFAQR7Z.js} +12 -1
- package/dist/{chunk-VO2LKSTM.js → chunk-O42A54GG.js} +2 -2
- package/dist/{chunk-T3Z6VAAF.js → chunk-OJTRZGR3.js} +53 -92
- package/dist/{chunk-5DQRIYDZ.js → chunk-PBP4B7XR.js} +3 -3
- package/dist/{chunk-NQ6UCCOD.js → chunk-PJJ6MY27.js} +8 -8
- package/dist/chunk-PMZCIOCJ.js +25 -0
- package/dist/{chunk-ZGVHUX3M.js → chunk-PMZVFWSR.js} +2 -2
- package/dist/{chunk-7C6RYZGQ.js → chunk-PVAMAVBB.js} +5 -4
- package/dist/chunk-QDC3K2U3.js +262 -0
- package/dist/{chunk-JEQQR47K.js → chunk-QKIFBZKT.js} +173 -14
- package/dist/{chunk-R7LNVMCS.js → chunk-QMXC4JB7.js} +70 -78
- package/dist/chunk-QSNYB6ZV.js +195 -0
- package/dist/chunk-QTFGO774.js +644 -0
- package/dist/{chunk-ODFEOB4F.js → chunk-R23Z6K6I.js} +27 -9
- package/dist/{chunk-3UUY7R3Z.js → chunk-R32CLGZ6.js} +14 -14
- package/dist/chunk-R346GLFC.js +31 -0
- package/dist/chunk-RKSR6VSF.js +132 -0
- package/dist/{chunk-N5XKWMDW.js → chunk-SCYB3HA4.js} +73 -27
- package/dist/{chunk-PZ4I4JE2.js → chunk-SINK3QR6.js} +135 -125
- package/dist/{chunk-5QKCQQ3E.js → chunk-SUW5DORT.js} +2 -2
- package/dist/chunk-T56WDKA5.js +183 -0
- package/dist/{chunk-ECUO3KDP.js → chunk-TD3PGPQA.js} +87 -26
- package/dist/{chunk-HKO36JWF.js → chunk-THYWACCR.js} +31 -3
- package/dist/{chunk-LXPJXFM5.js → chunk-TVH4ONAM.js} +18 -12
- package/dist/chunk-TVHHYFHE.js +255 -0
- package/dist/chunk-U2WB7TZS.js +271 -0
- package/dist/{chunk-NNNWO6F2.js → chunk-UAPGZHYC.js} +237 -33
- package/dist/{chunk-MIX5N5AC.js → chunk-UEDMSP56.js} +415 -160
- package/dist/{chunk-WIE7ZOSW.js → chunk-UXN6JT4W.js} +3 -3
- package/dist/{chunk-CMZWFGD2.js → chunk-VAVR4IJY.js} +19 -15
- package/dist/{chunk-MV2VUEJC.js → chunk-VEGN6WIQ.js} +2 -2
- package/dist/chunk-VKFQTNDV.js +66 -0
- package/dist/{chunk-FALJGAWU.js → chunk-VKRH2TCS.js} +2 -2
- package/dist/{chunk-A2NJGIB3.js → chunk-VN3SHNBN.js} +2 -2
- package/dist/{chunk-XK56QHLX.js → chunk-VPKWYKEY.js} +19 -5
- package/dist/{chunk-UOSL25KY.js → chunk-VXMFAE2W.js} +1 -1
- package/dist/{chunk-EQ63NRB7.js → chunk-WNP7O5WZ.js} +3 -3
- package/dist/chunk-WR6U3OVP.js +45 -0
- package/dist/{chunk-TEO2TLVN.js → chunk-XKA2ICR3.js} +1051 -1196
- package/dist/{chunk-3V5AYSEQ.js → chunk-Y45G3AXC.js} +72 -65
- package/dist/{chunk-J5Q24KAG.js → chunk-Y4CAGMM6.js} +2 -2
- package/dist/chunk-YAKGTXEV.js +17 -0
- package/dist/{chunk-ZI647VB5.js → chunk-YPI3QQCF.js} +2 -2
- package/dist/{chunk-YW7UVM5V.js → chunk-ZAZB4JMW.js} +55 -11
- package/dist/{chunk-HCBCAYZU.js → chunk-ZJLUDYFY.js} +11 -11
- package/dist/{chunk-HKIYEGME.js → chunk-ZTJUVLTU.js} +2 -2
- package/dist/{chunk-IFBNV6H6.js → chunk-ZW55JB7N.js} +3 -3
- package/dist/cli/index.js +48 -37
- package/dist/clio-IT3G3VQH.js +25 -0
- package/dist/{code-nav-LMW275PA.js → code-nav-RK6S7F6E.js} +8 -8
- package/dist/codewiki/build-worker.js +1 -1
- package/dist/{compile-cache-CVJMMODC.js → compile-cache-OQAVB7Y5.js} +3 -5
- package/dist/{components-ZFA3SAER.js → components-UBWCQSRW.js} +6 -6
- package/dist/{config-RXS5T3JT.js → config-3QZRWZJF.js} +73 -61
- package/dist/configure-FL7Y3KJF.js +54 -0
- package/dist/{context-MVOORGMF.js → context-5HE7ODYK.js} +61 -49
- package/dist/{context-I3BTOTCS.js → context-KYQFRVDC.js} +11 -11
- package/dist/{context-PALKKQYL.js → context-XNHL75JV.js} +43 -28
- package/dist/{context-clear-N2WOYZ2K.js → context-clear-N545L53A.js} +60 -48
- package/dist/{context-working-set-MIEVECVZ.js → context-working-set-QHKXSV2F.js} +15 -13
- package/dist/{dispatch-runner-VVA4SRRH.js → dispatch-runner-RGIE5PCT.js} +109 -72
- package/dist/{docs-7LQ23DLM.js → docs-5NAF6AU7.js} +7 -13
- package/dist/doctor-ZGPEGHIP.js +772 -0
- package/dist/{eval-IJ5VEZDJ.js → eval-GXLL44RD.js} +106 -86
- package/dist/eval-inventory-HBWSWQOK.js +315 -0
- package/dist/{evidence-L5APPXNV.js → evidence-HWLBRH3Q.js} +209 -51
- package/dist/{evolve-RGNKFJ52.js → evolve-FTZBMNVW.js} +57 -45
- package/dist/{extensions-7WYWUX5A.js → extensions-VHRBEID7.js} +7 -7
- package/dist/{fleet-6CNVBZZP.js → fleet-CKZHJWZJ.js} +215 -114
- package/dist/{fleet-commands-L2SXSYEI.js → fleet-commands-EXDXBMV6.js} +13 -12
- package/dist/fleet-decisions-OTHB6KRL.js +157 -0
- package/dist/{fleet-graph-2J3OOIPO.js → fleet-graph-YTEZUCUT.js} +20 -17
- package/dist/fleet-inspect-SS6YMDCK.js +445 -0
- package/dist/{fleet-preflight-CZRJ4JP5.js → fleet-preflight-PBY4VYOM.js} +6 -9
- package/dist/{fleet-validate-C5RI6DP7.js → fleet-validate-KMEM5L3S.js} +25 -20
- package/dist/fleet-verify-QD5M7E7Q.js +178 -0
- package/dist/fleet-view-WAMJYNDT.js +94 -0
- package/dist/{init-VBN2ACVA.js → init-5XQRBOFV.js} +79 -66
- package/dist/install-NKNG7KD4.js +13 -0
- package/dist/interop-34TVO25M.js +116 -0
- package/dist/{library-JHGUMLY2.js → library-3QY6KF57.js} +25 -21
- package/dist/{memory-K4OQIYWG.js → memory-L4UTIIIW.js} +59 -47
- package/dist/{models-2NCZUWDD.js → models-ZVX3QOWE.js} +47 -37
- package/dist/{monitor-MMVTJABD.js → monitor-CEKVSYTS.js} +67 -57
- package/dist/{orchestrator-ZKBPCHW6.js → orchestrator-77BAP6BC.js} +7633 -7699
- package/dist/panes-7STHOAUJ.js +103 -0
- package/dist/panes-SHAUIRXY.js +60 -0
- package/dist/{paths-DBXMZMDU.js → paths-L7LGY6RN.js} +6 -6
- package/dist/{reset-DD5JGOY3.js → reset-EOLM7GVE.js} +15 -14
- package/dist/resources-74GKTLSF.js +115 -0
- package/dist/{run-QEGNX7FL.js → run-HBAUJNNZ.js} +139 -98
- package/dist/{share-JKD3BQMW.js → share-G3APVLVP.js} +25 -21
- package/dist/{skills-LMQIKDOZ.js → skills-35HHUKCR.js} +37 -27
- package/dist/{skills-eval-I7X2774U.js → skills-eval-QN4HSHDC.js} +80 -73
- package/dist/skills-inventory-J357J34F.js +129 -0
- package/dist/slash-commands-JZZCQA32.js +79 -0
- package/dist/{steer-CF5TDANS.js → steer-XAVHJM22.js} +4 -4
- package/dist/{support-I7LOJLIF.js → support-U7QOWY26.js} +7 -7
- package/dist/{targets-RUSR6B5Z.js → targets-DSM6CY3M.js} +67 -59
- package/dist/{terminal-lease-QYVORFR4.js → terminal-lease-JOPFUVEM.js} +15 -10
- package/dist/tools-MKNWVPBH.js +29 -0
- package/dist/{trace-ODOQIVIW.js → trace-ECQ7TIYZ.js} +194 -7
- package/dist/tui-primitives-K5PASC3O.js +17 -0
- package/dist/{uninstall-ZJF5H5ZN.js → uninstall-N34PCTGJ.js} +6 -8
- package/dist/{upgrade-XANW3FXB.js → upgrade-H7TOM7YL.js} +37 -62
- package/dist/{usage-4H7ZRXQT.js → usage-X52N3IDJ.js} +70 -59
- package/dist/{verifiers-UZXNBZEB.js → verifiers-EJTVVSMA.js} +174 -14
- package/dist/{verify-BVKWTNDL.js → verify-YJL6XET2.js} +12 -11
- package/dist/{web-fetch-2YHJ3KTG.js → web-fetch-MPIFL3LL.js} +3 -4
- package/dist/{wiki-generate-MY7WV2QI.js → wiki-generate-4NDZTQ4B.js} +86 -75
- package/dist/with-panes-OBOBFIIR.js +818 -0
- package/dist/worker/entry.js +131 -91
- package/docs/README.md +3 -2
- package/docs/acp.md +25 -4
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +2 -2
- package/docs/artifact-versions.md +4 -1
- package/docs/built-in-agents.md +40 -32
- package/docs/capacity-and-scheduling.md +43 -5
- package/docs/commands-and-modes.md +39 -4
- package/docs/config-knobs-audit.md +3 -0
- package/docs/configuration-and-targets.md +138 -167
- package/docs/context-engine.md +1 -1
- package/docs/development-pipeline.md +19 -0
- package/docs/dispatch-typed-intent.md +385 -0
- package/docs/documentation-coverage.md +2 -2
- package/docs/documentation-guide.md +1 -1
- package/docs/environment-variables.md +3 -1
- package/docs/eval-runner.md +1 -1
- package/docs/evals-internal.md +1 -1
- package/docs/evidence-and-memory.md +2 -2
- package/docs/evolution.md +1 -1
- package/docs/exit-codes-and-output.md +3 -1
- package/docs/extensions-and-sharing.md +25 -1
- package/docs/fleet-demo-runbook.md +6 -3
- package/docs/fleet-dispatch.md +30 -7
- package/docs/installation-and-lifecycle.md +16 -3
- package/docs/middleware-and-components.md +1 -1
- package/docs/model-catalog.md +10 -1
- package/docs/observability.md +3 -3
- package/docs/proactive-memory.md +1 -1
- package/docs/prompt-envelope-and-tools.md +1 -1
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/release-cut-checklist.md +164 -177
- package/docs/safety-model.md +2 -2
- package/docs/scientific-validation.md +3 -3
- package/docs/session-lifecycle.md +1 -1
- package/docs/skills-marketplace.md +1 -1
- package/docs/tool-usage.md +18 -8
- package/docs/trace-store.md +16 -11
- package/docs/troubleshooting.md +2 -2
- package/docs/tui-design.md +1 -1
- package/docs/worker-dispatch-mechanics.md +1 -1
- package/evals/README.md +5 -0
- package/evals/behavioral-corpus-grader.mjs +103 -0
- package/evals/behavioral-machinery-baseline.json +2276 -0
- package/evals/behavioral-machinery-driver.ts +250 -0
- package/evals/behavioral-machinery-support.ts +253 -0
- package/evals/behavioral-machinery.yaml +614 -0
- package/evals/behavioral-model-negative-control.yaml +68 -0
- package/evals/behavioral-model.yaml +216 -0
- package/evals/fixtures/behavioral-facts.txt +3 -0
- package/evals/fixtures/behavioral-main.ts +7 -0
- package/evals/fixtures/decoy/note.txt +2 -0
- package/evals/fixtures/private/credentials.txt +1 -0
- package/evals/tracked-metrics-baseline.yaml +229 -0
- package/evals/tracked-metrics-grader.mjs +129 -0
- package/package.json +8 -16
- package/skills/README.md +6 -6
- package/skills/coding/ast-grep/SKILL.md +8 -2
- package/skills/coding/coding-standards/SKILL.md +8 -2
- package/skills/coding/prototype/SKILL.md +8 -2
- package/skills/coding/tdd/SKILL.md +8 -2
- package/skills/context/context-handoff/SKILL.md +12 -3
- package/skills/context/context-handoff/evals.md +3 -3
- package/skills/context/context-prime/SKILL.md +8 -2
- package/skills/context/context-prime/evals.md +2 -2
- package/skills/git/file-ticket/SKILL.md +9 -4
- package/skills/git/file-ticket/evals.md +2 -2
- package/skills/git/fix-issue/SKILL.md +12 -5
- package/skills/git/fix-issue/evals.md +4 -4
- package/skills/git/resolve-merge-conflicts/SKILL.md +8 -2
- package/skills/git/resolve-merge-conflicts/evals.md +2 -2
- package/skills/git/ship/SKILL.md +9 -3
- package/skills/git/ship/evals.md +4 -4
- package/skills/git/worktree-create/SKILL.md +7 -2
- package/skills/git/worktree-create/evals.md +6 -6
- package/skills/git/worktree-merge/SKILL.md +7 -2
- package/skills/git/worktree-merge/evals.md +6 -6
- package/skills/meta/{clio-dev → clio-coder-dev}/SKILL.md +14 -8
- package/skills/meta/{clio-dev → clio-coder-dev}/evals.md +3 -3
- package/skills/meta/{clio-test → clio-coder-test}/SKILL.md +11 -5
- package/skills/meta/{clio-test → clio-coder-test}/evals.md +1 -1
- package/skills/meta/credentials/SKILL.md +9 -2
- package/skills/meta/find-skills/SKILL.md +8 -2
- package/skills/meta/herdr/SKILL.md +8 -2
- package/skills/meta/skill-craft/SKILL.md +21 -4
- package/skills/planning/architecture/SKILL.md +9 -3
- package/skills/planning/backlog/SKILL.md +8 -2
- package/skills/planning/prd/SKILL.md +8 -2
- package/skills/planning/product-intent/SKILL.md +8 -2
- package/skills/planning/tech-spec/SKILL.md +9 -3
- package/skills/registry.yaml +66 -66
- package/skills/research/arxiv-literature/SKILL.md +8 -2
- package/skills/research/experiment-protocol/SKILL.md +9 -2
- package/skills/research/scientific-debugging/SKILL.md +9 -2
- package/skills/research/scientific-debugging/evals.md +2 -2
- package/skills/research/scientific-modernization/SKILL.md +9 -2
- package/skills/skill-marketplace.json +257 -38
- package/skills/workflow/cut-it/SKILL.md +10 -2
- package/skills/workflow/design-council/SKILL.md +11 -2
- package/skills/workflow/grill-me/SKILL.md +8 -2
- package/skills/workflow/workflow-distiller/SKILL.md +8 -2
- package/src/cli/acp.ts +8 -4
- package/src/cli/argv.ts +25 -0
- package/src/cli/auth.ts +2 -2
- package/src/cli/bootstrap-generate.ts +5 -5
- package/src/cli/clio.ts +6 -1
- package/src/cli/config-inspect.ts +3 -3
- package/src/cli/configure-interop.ts +1 -1
- package/src/cli/configure.ts +50 -48
- package/src/cli/default-target.ts +1 -1
- package/src/cli/docs.ts +6 -6
- package/src/cli/doctor-naming.ts +323 -0
- package/src/cli/doctor-panes.ts +156 -0
- package/src/cli/doctor-toolchain.ts +78 -0
- package/src/cli/doctor.ts +34 -1
- package/src/cli/eval-inventory.ts +436 -0
- package/src/cli/eval.ts +13 -0
- package/src/cli/evidence-detail.ts +88 -0
- package/src/cli/evidence-inventory.ts +183 -0
- package/src/cli/evidence.ts +30 -5
- package/src/cli/fleet-decisions.ts +69 -0
- package/src/cli/fleet-inspect.ts +334 -0
- package/src/cli/fleet-preflight.ts +1 -1
- package/src/cli/fleet-verify.ts +133 -0
- package/src/cli/fleet-view.ts +827 -0
- package/src/cli/fleet.ts +154 -40
- package/src/cli/index.ts +14 -2
- package/src/cli/interop-inspect.ts +128 -0
- package/src/cli/interop.ts +34 -0
- package/src/cli/models.ts +3 -3
- package/src/cli/modes/print.ts +1 -1
- package/src/cli/panes.ts +35 -0
- package/src/cli/reset.ts +6 -3
- package/src/cli/run.ts +67 -13
- package/src/cli/share.ts +1 -1
- package/src/cli/skills-eval.ts +11 -11
- package/src/cli/skills-inventory.ts +185 -0
- package/src/cli/skills.ts +16 -13
- package/src/cli/targets.ts +23 -24
- package/src/cli/tools.ts +321 -0
- package/src/cli/trace-inspect.ts +252 -0
- package/src/cli/trace.ts +64 -2
- package/src/cli/uninstall.ts +2 -2
- package/src/cli/upgrade.ts +29 -34
- package/src/cli/usage.ts +2 -2
- package/src/cli/validate-model.ts +1 -1
- package/src/cli/verifiers-inspect.ts +347 -0
- package/src/cli/verifiers.ts +9 -0
- package/src/cli/wiki-generate.ts +5 -5
- package/src/core/bash-exec.ts +1 -1
- package/src/core/boot-trace.ts +3 -3
- package/src/core/bus-events.ts +4 -0
- package/src/core/bus-trace.ts +2 -2
- package/src/core/compile-cache.ts +1 -1
- package/src/core/config.ts +1070 -845
- package/src/core/defaults.ts +342 -463
- package/src/core/domain-loader.ts +6 -4
- package/src/core/event-bus.ts +1 -1
- package/src/core/file-references.ts +78 -88
- package/src/core/git-commit-attribution.ts +3 -9
- package/src/core/guardrails.ts +24 -4
- package/src/core/naming-compat.ts +45 -0
- package/src/core/naming-events.ts +62 -0
- package/src/core/recent-models.ts +1 -7
- package/src/core/residency-protection.ts +4 -8
- package/src/core/resolve-config-value.ts +1 -1
- package/src/core/response-model-id.ts +0 -14
- package/src/core/response-schema.ts +44 -4
- package/src/core/session-routing.ts +84 -74
- package/src/core/skill-activation.ts +18 -0
- package/src/core/termination.ts +4 -4
- package/src/core/theme-token-hex.ts +43 -0
- package/src/core/timers.ts +2 -12
- package/src/core/tool-names.ts +2 -1
- package/src/core/xdg.ts +1 -1
- package/src/domains/agents/catalog.ts +2 -12
- package/src/domains/agents/extension.ts +3 -3
- package/src/domains/agents/fleets/build-review.md +0 -3
- package/src/domains/agents/fleets/build-test.md +0 -3
- package/src/domains/agents/registry.ts +7 -7
- package/src/domains/agents/result-contract-filesystem.ts +32 -0
- package/src/domains/agents/result-contract.ts +165 -36
- package/src/domains/agents/spec.ts +0 -11
- package/src/domains/config/classify.ts +37 -46
- package/src/domains/config/extension.ts +5 -5
- package/src/domains/config/keybindings.ts +48 -47
- package/src/domains/config/watcher.ts +1 -1
- package/src/domains/context/codewiki/indexer.ts +1 -1
- package/src/domains/context/extension.ts +3 -3
- package/src/domains/context/prompt-context.ts +1 -1
- package/src/domains/context/wiki/assemble.ts +2 -2
- package/src/domains/context/working-set/replay/metrics.ts +0 -4
- package/src/domains/context/working-set/replay/report.ts +1 -1
- package/src/domains/context/working-set/replay/synthetic.ts +2 -2
- package/src/domains/dispatch/active-route-planner.ts +2 -2
- package/src/domains/dispatch/admission-error.ts +9 -0
- package/src/domains/dispatch/admission.ts +22 -21
- package/src/domains/dispatch/agent-candidates.ts +1 -1
- package/src/domains/dispatch/agent-ledger-store.ts +1 -1
- package/src/domains/dispatch/agent-ledger.ts +1 -1
- package/src/domains/dispatch/assignment.ts +5 -5
- package/src/domains/dispatch/capacity-lease.ts +23 -6
- package/src/domains/dispatch/code-step.ts +1 -1
- package/src/domains/dispatch/contract.ts +2 -2
- package/src/domains/dispatch/council-topology.ts +398 -0
- package/src/domains/dispatch/extension.ts +287 -111
- package/src/domains/dispatch/fleet-node-prompt.ts +62 -0
- package/src/domains/dispatch/fleet-plan.ts +7 -2
- package/src/domains/dispatch/fleet-preflight.ts +8 -17
- package/src/domains/dispatch/fleet-run.ts +59 -3
- package/src/domains/dispatch/gate-decisions.ts +36 -15
- package/src/domains/dispatch/gate-role-prompts.ts +9 -0
- package/src/domains/dispatch/gate-topology.ts +289 -0
- package/src/domains/dispatch/index.ts +19 -0
- package/src/domains/dispatch/intent-compatibility.ts +330 -0
- package/src/domains/dispatch/intent.ts +85 -1
- package/src/domains/dispatch/joint-route-resolver.ts +1 -1
- package/src/domains/dispatch/path-scope.ts +0 -61
- package/src/domains/dispatch/placement.ts +2 -2
- package/src/domains/dispatch/receipt-findings.ts +1 -1
- package/src/domains/dispatch/receipt-integrity.ts +20 -8
- package/src/domains/dispatch/reservation-store.ts +24 -27
- package/src/domains/dispatch/route-decision.ts +1 -1
- package/src/domains/dispatch/route-history.ts +1 -1
- package/src/domains/dispatch/route-policy.ts +1 -1
- package/src/domains/dispatch/route-readiness.ts +0 -28
- package/src/domains/dispatch/run-event-journal-bridge.ts +149 -0
- package/src/domains/dispatch/run-event-journal.ts +599 -0
- package/src/domains/dispatch/state.ts +45 -1
- package/src/domains/dispatch/tool-stats.ts +1 -1
- package/src/domains/dispatch/transport.ts +2 -19
- package/src/domains/dispatch/types.ts +16 -3
- package/src/domains/dispatch/validation.ts +33 -8
- package/src/domains/dispatch/worker-protocol.ts +2 -2
- package/src/domains/eval/artifacts/store.ts +5 -4
- package/src/domains/eval/compare/compare.ts +3 -16
- package/src/domains/eval/compare/thresholds.ts +0 -8
- package/src/domains/eval/execution-provenance.ts +1 -1
- package/src/domains/eval/inventory.ts +113 -0
- package/src/domains/eval/metrics/token-stream.ts +0 -7
- package/src/domains/eval/report.ts +1 -1
- package/src/domains/eval/runner.ts +1 -1
- package/src/domains/eval/runners/clio-run.ts +7 -6
- package/src/domains/eval/runners/external-command.ts +4 -3
- package/src/domains/eval/schema/artifact.ts +1 -1
- package/src/domains/eval/schema/behavioral-metrics.ts +3 -2
- package/src/domains/eval/schema/behavioral.ts +7 -6
- package/src/domains/eval/schema/execution-envelope.ts +4 -2
- package/src/domains/eval/schema/naming.ts +10 -0
- package/src/domains/eval/schema/serving.ts +31 -0
- package/src/domains/eval/schema/suite.ts +2 -2
- package/src/domains/eval/schema/validate.ts +9 -5
- package/src/domains/eval/schema/verdict.ts +4 -2
- package/src/domains/eval/store.ts +12 -2
- package/src/domains/eval/suites/run.ts +12 -6
- package/src/domains/eval/types.ts +1 -1
- package/src/domains/eval/workspaces/git.ts +1 -1
- package/src/domains/eval/workspaces/temp-copy.ts +1 -1
- package/src/domains/evidence/build.ts +13 -5
- package/src/domains/evidence/store.ts +6 -0
- package/src/domains/interop/consent.ts +7 -7
- package/src/domains/interop/extension.ts +1 -1
- package/src/domains/lifecycle/doctor.ts +27 -21
- package/src/domains/lifecycle/migrations/2026-09-01-clio-coder-naming.ts +155 -0
- package/src/domains/lifecycle/migrations/2026-09-01-retire-panes-knobs.ts +59 -0
- package/src/domains/lifecycle/migrations/2026-09-01-settings-v2.ts +338 -0
- package/src/domains/lifecycle/migrations/index.ts +20 -1
- package/src/domains/lifecycle/naming-history.ts +153 -0
- package/src/domains/lifecycle/naming-mutable-state.ts +104 -0
- package/src/domains/lifecycle/naming-resources.ts +261 -0
- package/src/domains/lifecycle/naming-tool-markers.ts +139 -0
- package/src/domains/lifecycle/naming-yazi.ts +81 -0
- package/src/domains/lifecycle/upgrade-notice.ts +1 -1
- package/src/domains/memory/index.ts +0 -1
- package/src/domains/memory/task-memory-handoff.ts +6 -3
- package/src/domains/memory/task-memory-policy.ts +6 -10
- package/src/domains/memory/task-memory-telemetry.ts +1 -0
- package/src/domains/middleware/index.ts +7 -0
- package/src/domains/middleware/marketplace-offer.ts +339 -0
- package/src/domains/middleware/memory-intervention.ts +33 -21
- package/src/domains/middleware/runtime.ts +2 -2
- package/src/domains/mux/contract.ts +566 -0
- package/src/domains/mux/detect.ts +182 -0
- package/src/domains/mux/dock-controller.ts +365 -0
- package/src/domains/mux/extension.ts +53 -0
- package/src/domains/mux/index.ts +116 -0
- package/src/domains/mux/manifest.ts +6 -0
- package/src/domains/mux/operations.ts +192 -0
- package/src/domains/mux/pane-registry.ts +90 -0
- package/src/domains/mux/protocol.ts +62 -0
- package/src/domains/mux/socket-client.ts +964 -0
- package/src/domains/mux/types.ts +265 -0
- package/src/domains/mux/viewer-command.ts +59 -0
- package/src/domains/mux/yazi/assets/init.lua +2 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/LICENSE +21 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/README.md +78 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/main.lua +255 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/types.lua +12 -0
- package/src/domains/mux/yazi/assets/yazi.toml +17 -0
- package/src/domains/mux/yazi/event-stream.ts +182 -0
- package/src/domains/mux/yazi/profile.ts +299 -0
- package/src/domains/mux/yazi/session.ts +251 -0
- package/src/domains/mux/yazi/theme.ts +30 -0
- package/src/domains/observability/cost.ts +21 -0
- package/src/domains/observability/extension.ts +1 -1
- package/src/domains/observability/index.ts +2 -0
- package/src/domains/observability/out-of-turn-usage.ts +2 -2
- package/src/domains/observability/projection.ts +1 -1
- package/src/domains/observability/trace-store.ts +63 -11
- package/src/domains/prompts/compiler.ts +2 -2
- package/src/domains/prompts/extension.ts +3 -3
- package/src/domains/prompts/fragments/identity/clio-worker.md +1 -1
- package/src/domains/prompts/fragments/operating/skills.md +25 -18
- package/src/domains/providers/endpoint-capacity.ts +154 -22
- package/src/domains/providers/endpoint-slots-store.ts +189 -0
- package/src/domains/providers/extension.ts +25 -8
- package/src/domains/providers/index.ts +22 -0
- package/src/domains/providers/knowledge-base-path.ts +1 -1
- package/src/domains/providers/model-runtime-capabilities.ts +46 -2
- package/src/domains/providers/models/cloud-models/alcf.yaml +1 -1
- package/src/domains/providers/models/local-models/{clio-local-coding-targets.yaml → clio-coder-local-coding-targets.yaml} +4 -4
- package/src/domains/providers/plugins.ts +1 -1
- package/src/domains/providers/resolver.ts +1 -1
- package/src/domains/providers/runtimes/boot-manifest.ts +1 -0
- package/src/domains/providers/runtimes/builtins.ts +2 -0
- package/src/domains/providers/runtimes/cloud/alcf.ts +4 -4
- package/src/domains/providers/runtimes/common/lmstudio-http.ts +1 -5
- package/src/domains/providers/runtimes/common/local-synth.ts +3 -3
- package/src/domains/providers/runtimes/common/probe-helpers.ts +2 -2
- package/src/domains/providers/runtimes/local-native/llamacpp-completion.ts +1 -1
- package/src/domains/providers/runtimes/local-native/lmstudio.ts +2 -9
- package/src/domains/providers/runtimes/protocol/litellm.ts +285 -0
- package/src/domains/providers/support.ts +1 -0
- package/src/domains/providers/target-model-cache.ts +124 -0
- package/src/domains/providers/types/knowledge-base.ts +13 -0
- package/src/domains/providers/types/local-model-quirks.ts +2 -2
- package/src/domains/providers/types/target-descriptor.ts +3 -3
- package/src/domains/resources/extension.ts +1 -1
- package/src/domains/resources/index.ts +3 -0
- package/src/domains/resources/library.ts +6 -6
- package/src/domains/resources/prompts/loader.ts +1 -1
- package/src/domains/resources/skills/content-hash.ts +7 -6
- package/src/domains/resources/skills/evals.ts +1 -1
- package/src/domains/resources/skills/install.ts +36 -12
- package/src/domains/resources/skills/loader.ts +72 -13
- package/src/domains/resources/skills/marketplace.ts +21 -2
- package/src/domains/resources/skills/promotion.ts +214 -0
- package/src/domains/safety/action-classifier.ts +6 -0
- package/src/domains/safety/audit.ts +2 -2
- package/src/domains/safety/finish-contract.ts +2 -1
- package/src/domains/safety/run-effects.ts +1 -1
- package/src/domains/scheduling/extension.ts +4 -4
- package/src/domains/session/archive-readers.ts +9 -1
- package/src/domains/session/compaction/branch-summary.ts +4 -0
- package/src/domains/session/compaction/compact.ts +1 -1
- package/src/domains/session/compaction/tokens.ts +4 -0
- package/src/domains/session/context-accounting.ts +1 -1
- package/src/domains/session/decision-board.ts +1 -1
- package/src/domains/session/extension.ts +1 -1
- package/src/domains/session/handoff.ts +2 -2
- package/src/domains/session/prompt-manifest.ts +0 -5
- package/src/domains/session/protected-artifact-journal.ts +12 -6
- package/src/domains/session/retry.ts +1 -1
- package/src/domains/share/archive.ts +85 -36
- package/src/domains/toolchain/archive.ts +175 -0
- package/src/domains/toolchain/contract.ts +28 -0
- package/src/domains/toolchain/extension.ts +47 -0
- package/src/domains/toolchain/index.ts +39 -0
- package/src/domains/toolchain/install.ts +327 -0
- package/src/domains/toolchain/manifest.ts +8 -0
- package/src/domains/toolchain/paths.ts +34 -0
- package/src/domains/toolchain/registry.ts +265 -0
- package/src/domains/toolchain/remove.ts +218 -0
- package/src/domains/toolchain/resolve.ts +182 -0
- package/src/domains/toolchain/types.ts +113 -0
- package/src/domains/toolchain/version.ts +88 -0
- package/src/engine/acp/adapter.ts +3 -3
- package/src/engine/acp/event-mapper.ts +3 -3
- package/src/engine/acp/server.ts +440 -96
- package/src/engine/acp/tool-mediator.ts +2 -2
- package/src/engine/acp/types.ts +20 -2
- package/src/engine/alcf-oauth.ts +5 -5
- package/src/engine/antigravity/subprocess-runtime.ts +2 -2
- package/src/engine/api-registry.ts +1 -1
- package/src/engine/apis/llamacpp-residency.ts +1 -19
- package/src/engine/apis/lmstudio.ts +1 -6
- package/src/engine/apis/ollama-native.ts +3 -3
- package/src/engine/apis/openai-completions.ts +2 -2
- package/src/engine/apis/residency.ts +3 -9
- package/src/engine/claude/sdk-module.ts +87 -0
- package/src/engine/claude/sdk-runtime.ts +25 -17
- package/src/engine/claude/subprocess-runtime.ts +1 -1
- package/src/engine/claude/tool-safety.ts +4 -4
- package/src/engine/loop-guard.ts +0 -5
- package/src/engine/session.ts +14 -7
- package/src/engine/tui-primitives.ts +21 -0
- package/src/engine/tui.ts +1 -0
- package/src/engine/worker-events.ts +6 -6
- package/src/engine/worker-runtime.ts +16 -26
- package/src/entry/boot-options.ts +2 -0
- package/src/entry/orchestrator.ts +207 -90
- package/src/entry/panes-activation.ts +31 -0
- package/src/entry/with-panes.ts +20 -0
- package/src/interactive/application-controller.ts +21 -21
- package/src/interactive/bus-notices.ts +2 -2
- package/src/interactive/chat-loop.ts +8 -8
- package/src/interactive/chat-panel.ts +1 -1
- package/src/interactive/clio-editor.ts +105 -1
- package/src/interactive/context-activity.ts +8 -6
- package/src/interactive/context-meter.ts +3 -6
- package/src/interactive/context-overlay.ts +2 -1
- package/src/interactive/cost-overlay.ts +3 -1
- package/src/interactive/council-grid.ts +3 -5
- package/src/interactive/council.ts +11 -0
- package/src/interactive/dispatch-board.ts +56 -49
- package/src/interactive/editor-bash.ts +21 -0
- package/src/interactive/editor-steer.ts +9 -4
- package/src/interactive/editor-submit.ts +24 -18
- package/src/interactive/external-editor.ts +1 -1
- package/src/interactive/file-reference-completion.ts +360 -0
- package/src/interactive/footer/dashboard.ts +15 -17
- package/src/interactive/footer/notifications.ts +14 -8
- package/src/interactive/footer/widgets.ts +2 -44
- package/src/interactive/interactive-application.ts +229 -62
- package/src/interactive/interactive-event-projection.ts +1 -1
- package/src/interactive/interactive-input-runtime.ts +9 -2
- package/src/interactive/interactive-presentation.ts +21 -16
- package/src/interactive/interactive-shell.ts +2 -2
- package/src/interactive/interactive-slash-runtime.ts +99 -23
- package/src/interactive/interactive-subscriptions.ts +1 -1
- package/src/interactive/interactive-tickers.ts +1 -1
- package/src/interactive/keybinding-manager.ts +4 -4
- package/src/interactive/layout.ts +1 -1
- package/src/interactive/memory-overlay.ts +3 -2
- package/src/interactive/modal-marker.ts +151 -0
- package/src/interactive/mutation-preview.ts +1 -1
- package/src/interactive/mux-bridge.ts +214 -0
- package/src/interactive/overlay-frame.ts +62 -14
- package/src/interactive/overlay-general-openers.ts +7 -2
- package/src/interactive/overlay-key-routing.ts +21 -10
- package/src/interactive/overlay-lifecycle.ts +20 -4
- package/src/interactive/overlay-model-selectors.ts +43 -6
- package/src/interactive/overlay-permission-lifecycle.ts +90 -22
- package/src/interactive/overlay-transitions.ts +18 -4
- package/src/interactive/overlays/agents.ts +3 -2
- package/src/interactive/overlays/ask-user.ts +161 -41
- package/src/interactive/overlays/auth-dialog.ts +1 -0
- package/src/interactive/overlays/context-reset.ts +29 -4
- package/src/interactive/overlays/cwd-fallback.ts +29 -4
- package/src/interactive/overlays/decisions.ts +15 -13
- package/src/interactive/overlays/extensions.ts +1 -0
- package/src/interactive/overlays/fleet-run-approval.ts +4 -3
- package/src/interactive/overlays/handoff-review.ts +3 -2
- package/src/interactive/overlays/help-reference.ts +2 -0
- package/src/interactive/overlays/interop.ts +2 -1
- package/src/interactive/overlays/library-install-confirm.ts +2 -1
- package/src/interactive/overlays/library-tabs.ts +28 -0
- package/src/interactive/overlays/list-overlay.ts +10 -1
- package/src/interactive/overlays/message-picker.ts +2 -1
- package/src/interactive/overlays/model-scope.ts +86 -0
- package/src/interactive/overlays/model-selector.ts +40 -31
- package/src/interactive/overlays/prompts.ts +11 -4
- package/src/interactive/overlays/session-selector.ts +3 -2
- package/src/interactive/overlays/settings-sections.ts +30 -0
- package/src/interactive/overlays/settings.ts +849 -268
- package/src/interactive/overlays/side-question.ts +3 -2
- package/src/interactive/overlays/skills-hub.ts +11 -19
- package/src/interactive/overlays/tree-selector.ts +3 -2
- package/src/interactive/pane-policy.ts +46 -0
- package/src/interactive/panes-runtime.ts +318 -0
- package/src/interactive/permission-overlay.ts +2 -2
- package/src/interactive/renderers/compaction-summary.ts +29 -0
- package/src/interactive/renderers/retry-status.ts +12 -4
- package/src/interactive/renderers/tool-execution.ts +4 -4
- package/src/interactive/renderers/worker-entry.ts +122 -14
- package/src/interactive/session-transcript.ts +3 -3
- package/src/interactive/slash-autocomplete.ts +454 -165
- package/src/interactive/slash-commands.ts +521 -189
- package/src/interactive/slash-spec.ts +160 -17
- package/src/interactive/status/controller.ts +2 -2
- package/src/interactive/stream-pacing-policy.ts +1 -1
- package/src/interactive/tasks-overlay.ts +21 -13
- package/src/interactive/terminal-lease.ts +6 -7
- package/src/interactive/theme/tokens.ts +3 -14
- package/src/interactive/turn-context.ts +58 -13
- package/src/interactive/turn-persistence.ts +2 -2
- package/src/interactive/turn-prewarm.ts +2 -2
- package/src/interactive/turn-runtime.ts +8 -8
- package/src/interactive/turn-state.ts +1 -1
- package/src/interactive/view/artifacts.ts +120 -9
- package/src/interactive/view/view-overlay.ts +14 -10
- package/src/interactive/watch-pane.ts +180 -0
- package/src/interactive/welcome-dashboard.ts +15 -15
- package/src/interactive/worker-progress.ts +11 -5
- package/src/interactive/worker-receipts.ts +20 -2
- package/src/interactive/worker-stream.ts +6 -4
- package/src/interactive/yazi-bridge.ts +451 -0
- package/src/tools/ask-user.ts +3 -3
- package/src/tools/bash.ts +1 -1
- package/src/tools/bootstrap.ts +26 -2
- package/src/tools/builtin-tool-catalog.ts +16 -1
- package/src/tools/compete-worktrees.ts +108 -17
- package/src/tools/context/index.ts +15 -1
- package/src/tools/core-bootstrap.ts +2 -1
- package/src/tools/dispatch-admission.ts +18 -5
- package/src/tools/dispatch-arguments.ts +21 -21
- package/src/tools/dispatch-plan.ts +0 -11
- package/src/tools/dispatch-run-events.ts +145 -28
- package/src/tools/dispatch-runner.ts +40 -13
- package/src/tools/dispatch-types.ts +15 -3
- package/src/tools/dispatch.ts +2 -2
- package/src/tools/executables.ts +17 -14
- package/src/tools/find.ts +1 -6
- package/src/tools/monitor.ts +4 -4
- package/src/tools/observation.ts +54 -4
- package/src/tools/observers.ts +0 -33
- package/src/tools/panes-surface.ts +38 -0
- package/src/tools/panes.ts +112 -0
- package/src/tools/policy.ts +10 -1
- package/src/tools/presentation.ts +1 -0
- package/src/tools/task-worktree.ts +28 -7
- package/src/tools/verify/authoring.ts +3 -6
- package/src/tools/verify/frontend.ts +1 -1
- package/src/tools/web-fetch.ts +1 -1
- package/src/worker/entry.ts +4 -3
- package/src/worker/protocol.ts +16 -14
- package/src/worker/spec-contract.ts +2 -2
- package/src/worker/stdin-demux.ts +2 -2
- package/dist/chunk-D73KXYPF.js +0 -37
- package/dist/chunk-MLOK6ZOS.js +0 -2888
- package/dist/chunk-PNY46YEY.js +0 -1581
- package/dist/chunk-XDOQXGFO.js +0 -515
- package/dist/chunk-YKOFT37S.js +0 -279
- package/dist/clio-LT5V7SSZ.js +0 -26
- package/dist/configure-2WYWSCSD.js +0 -49
- package/dist/doctor-TWBWFK5V.js +0 -165
- package/src/engine/apis/degraded-inference.ts +0 -95
- /package/skills/meta/{clio-test → clio-coder-test}/references/harness.md +0 -0
- /package/skills/meta/{clio-test → clio-coder-test}/references/test-map.md +0 -0
|
@@ -308,7 +308,7 @@
|
|
|
308
308
|
measuredUnder:
|
|
309
309
|
hardware: unknown
|
|
310
310
|
runtime: lmstudio
|
|
311
|
-
build: "unknown; the host was
|
|
311
|
+
build: "unknown; the host was a Windows LM Studio machine whose bundled build string was not recorded on this date"
|
|
312
312
|
llamaCpp: "unknown; the measurement went through LM Studio's OpenAI-compatible port, which does not expose the underlying server argv"
|
|
313
313
|
date: "2026-08-08"
|
|
314
314
|
source: "commit b3db3b82 (fix(providers): thinking off reaches the wire for models that reason by default)"
|
|
@@ -884,12 +884,12 @@
|
|
|
884
884
|
measuredUnder:
|
|
885
885
|
hardware: unknown
|
|
886
886
|
runtime: "lmstudio and its OpenAI-compatible port for the reasoning findings; an unrecorded llama.cpp host for the presence-penalty finding"
|
|
887
|
-
build: "unknown for both dates; the
|
|
887
|
+
build: "unknown for both dates; the Windows LM Studio measurement host's bundled build string was first recorded on 2026-08-29 as llama.cpp-win-x86_64-nvidia-cuda12-avx2, which is three weeks after the reasoning measurement and cannot be backdated to it"
|
|
888
888
|
llamaCpp: "unknown; the reasoning measurement went through LM Studio's HTTP port, which does not expose the underlying server argv, and no argv survives for the dispatch that produced the presence-penalty value"
|
|
889
889
|
date: "2026-08-08 (reasoning_effort and enable_thinking), 2026-07-06 (presence penalty)"
|
|
890
890
|
source: "commits b3db3b82 and f7d76bf4"
|
|
891
891
|
note: |
|
|
892
|
-
Three numbers here are measurements. On 2026-08-08 on
|
|
892
|
+
Three numbers here are measurements. On 2026-08-08 on that host this
|
|
893
893
|
model spent 98 of 103 completion tokens reasoning on "what is 17+25"
|
|
894
894
|
with no thinking field set; chat_template_kwargs enable_thinking was
|
|
895
895
|
inert, re-checked with unique prompts to rule out prompt-cache hits;
|
|
@@ -1268,7 +1268,7 @@
|
|
|
1268
1268
|
maxTokens: 32768
|
|
1269
1269
|
quirks:
|
|
1270
1270
|
measuredUnder:
|
|
1271
|
-
hardware: "unknown; the host was
|
|
1271
|
+
hardware: "unknown; the host was a Windows LM Studio machine"
|
|
1272
1272
|
runtime: "lmstudio, SDK 1.5.0 and its OpenAI-compatible port"
|
|
1273
1273
|
build: "unknown; LM Studio's bundled llama.cpp build string was not recorded on this date"
|
|
1274
1274
|
llamaCpp: "unknown; the measurement went through LM Studio, which does not expose the underlying server argv"
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* 1. `~/.config/clio-coder/runtimes/`: any `.js` file whose default export is a valid
|
|
5
5
|
* RuntimeDescriptor. Resolved from `clioConfigDir()` so CLIO_CODER_HOME /
|
|
6
6
|
* CLIO_CODER_CONFIG_DIR overrides flow through.
|
|
7
|
-
* 2. npm packages listed under `settings.runtimePlugins
|
|
7
|
+
* 2. npm packages listed under `settings.integrations.runtimePlugins`.
|
|
8
8
|
* Each package must export a `clioRuntimes: RuntimeDescriptor[]` array.
|
|
9
9
|
*
|
|
10
10
|
* Missing directories, import failures, and descriptor conflicts are logged
|
|
@@ -117,7 +117,7 @@ function buildResult(
|
|
|
117
117
|
*
|
|
118
118
|
* Trailing `:low`/`:medium`/`:high`/`:xhigh`/`:minimal`/`:off` is parsed off
|
|
119
119
|
* before matching and surfaced on the returned ref so callers can apply it
|
|
120
|
-
* to settings.
|
|
120
|
+
* to settings.chat.thinkingLevel.
|
|
121
121
|
*/
|
|
122
122
|
export function resolveModelReference(rawPattern: string, providers: ProvidersContract): ResolveModelResult {
|
|
123
123
|
const trimmed = rawPattern.trim();
|
|
@@ -42,6 +42,7 @@ export const BUILTIN_RUNTIME_BOOT_MANIFEST: ReadonlyArray<RuntimeBootMetadata> =
|
|
|
42
42
|
{ id: "lmstudio", aliases: ["lmstudio-native"], kind: "http", tier: "local-native", auth: "api-key" },
|
|
43
43
|
{ id: "ollama-native", kind: "http", tier: "local-native", auth: "none" },
|
|
44
44
|
{ id: "anthropic-compat", kind: "http", tier: "protocol", auth: "api-key" },
|
|
45
|
+
{ id: "litellm", kind: "http", tier: "protocol", auth: "api-key" },
|
|
45
46
|
{ id: "openai-compat", kind: "http", tier: "protocol", auth: "api-key" },
|
|
46
47
|
{ id: "sglang", kind: "http", tier: "local-native", auth: "api-key" },
|
|
47
48
|
{ id: "vllm", kind: "http", tier: "local-native", auth: "api-key" },
|
|
@@ -36,6 +36,7 @@ import ollamaNative from "./local-native/ollama-native.js";
|
|
|
36
36
|
import sglang from "./local-native/sglang.js";
|
|
37
37
|
import vllm from "./local-native/vllm.js";
|
|
38
38
|
import anthropicCompat from "./protocol/anthropic-compat.js";
|
|
39
|
+
import litellm from "./protocol/litellm.js";
|
|
39
40
|
import openaiCompat from "./protocol/openai-compat.js";
|
|
40
41
|
|
|
41
42
|
const BUILTIN_RUNTIMES: ReadonlyArray<RuntimeDescriptor> = [
|
|
@@ -60,6 +61,7 @@ const BUILTIN_RUNTIMES: ReadonlyArray<RuntimeDescriptor> = [
|
|
|
60
61
|
lmstudio,
|
|
61
62
|
ollamaNative,
|
|
62
63
|
anthropicCompat,
|
|
64
|
+
litellm,
|
|
63
65
|
openaiCompat,
|
|
64
66
|
sglang,
|
|
65
67
|
vllm,
|
|
@@ -35,13 +35,13 @@ const KNOWN_MODELS: string[] = [
|
|
|
35
35
|
|
|
36
36
|
type AlcfCluster = string;
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
function clusterFromUrl(url: string | undefined): AlcfCluster | null {
|
|
39
39
|
if (!url) return null;
|
|
40
40
|
const match = /\/resource_server\/([^/]+)\//.exec(url);
|
|
41
41
|
return match ? (match[1] ?? null) : null;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
function frameworkForCluster(cluster: AlcfCluster): string {
|
|
45
45
|
return cluster === "metis" ? "api" : "vllm";
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -59,7 +59,7 @@ export function catalogModels(payload: CatalogPayload, cluster: string, framewor
|
|
|
59
59
|
return models.map((model) => String(model).trim()).filter((model) => model.length > 0);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
function runningModels(payload: JobsPayload): string[] {
|
|
63
63
|
const out: string[] = [];
|
|
64
64
|
for (const job of payload.running ?? []) {
|
|
65
65
|
for (const raw of String(job.Models ?? "").split(",")) {
|
|
@@ -162,7 +162,7 @@ const alcfRuntime: RuntimeDescriptor = {
|
|
|
162
162
|
provider: "alcf",
|
|
163
163
|
baseUrlForTarget: withAsIs,
|
|
164
164
|
});
|
|
165
|
-
const meta = (model as Model<Api> & {
|
|
165
|
+
const meta = (model as Model<Api> & { clioCoder?: { chatTemplateKwargsUnsupported?: boolean } }).clioCoder;
|
|
166
166
|
if (meta) meta.chatTemplateKwargsUnsupported = true;
|
|
167
167
|
return model;
|
|
168
168
|
},
|
|
@@ -169,7 +169,7 @@ function reasoningOptions(capabilities: unknown): string[] | undefined {
|
|
|
169
169
|
return options.length > 0 ? options : undefined;
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
-
|
|
172
|
+
function parseLmStudioV1Models(data: unknown): LmStudioModelInfo[] | null {
|
|
173
173
|
if (!isRecord(data) || !Array.isArray(data.models)) return null;
|
|
174
174
|
const models: LmStudioModelInfo[] = [];
|
|
175
175
|
for (const raw of data.models) {
|
|
@@ -285,10 +285,6 @@ export function resolveLmStudioInstance(
|
|
|
285
285
|
return { requestedId, wireModelId: requestedId, peerTargets: [], state: "unknown" };
|
|
286
286
|
}
|
|
287
287
|
|
|
288
|
-
export function resetLmStudioHostCatalogs(): void {
|
|
289
|
-
catalogsByHost.clear();
|
|
290
|
-
}
|
|
291
|
-
|
|
292
288
|
export function lmStudioReasoningLevels(options: ReadonlyArray<string> | undefined): ThinkingLevel[] {
|
|
293
289
|
if (!options || options.length === 0) return [...THINKING_LEVELS];
|
|
294
290
|
if (options.includes("on") && !options.includes("low") && !options.includes("medium") && !options.includes("high")) {
|
|
@@ -7,10 +7,10 @@ import { extractLocalModelQuirks, type LocalModelQuirks } from "../../types/loca
|
|
|
7
7
|
import type { RuntimeApiFamily } from "../../types/runtime-descriptor.js";
|
|
8
8
|
import type { TargetDescriptor } from "../../types/target-descriptor.js";
|
|
9
9
|
|
|
10
|
-
export type LocalModelLifecycle = "user-managed" | "clio-managed";
|
|
10
|
+
export type LocalModelLifecycle = "user-managed" | "clio-coder-managed";
|
|
11
11
|
|
|
12
12
|
export interface ClioLocalModelMetadata {
|
|
13
|
-
|
|
13
|
+
clioCoder?: {
|
|
14
14
|
targetId: string;
|
|
15
15
|
runtimeId: string;
|
|
16
16
|
/**
|
|
@@ -101,7 +101,7 @@ export function synthLocalModel(input: LocalSynthesisInput): Model<Api> {
|
|
|
101
101
|
},
|
|
102
102
|
contextWindow: caps.contextWindow,
|
|
103
103
|
maxTokens: caps.maxTokens,
|
|
104
|
-
|
|
104
|
+
clioCoder: {
|
|
105
105
|
targetId: target.id,
|
|
106
106
|
runtimeId: target.runtime,
|
|
107
107
|
...(target.lifecycle ? { lifecycle: target.lifecycle } : {}),
|
|
@@ -357,7 +357,7 @@ export interface LlamaCppRequestContextWindow {
|
|
|
357
357
|
* 25% (issue #187). With `--kv-unified` every slot shares one sequence and
|
|
358
358
|
* the total is the window.
|
|
359
359
|
*/
|
|
360
|
-
|
|
360
|
+
function llamaCppRequestContextWindow(flags: LlamaCppServerFlags): LlamaCppRequestContextWindow | undefined {
|
|
361
361
|
const total = positiveNumber(flags.contextSize);
|
|
362
362
|
if (total === undefined) return undefined;
|
|
363
363
|
const parallel = positiveNumber(flags.parallel);
|
|
@@ -423,7 +423,7 @@ function booleanFlag(args: ReadonlyArray<string>, ...flags: ReadonlyArray<string
|
|
|
423
423
|
return undefined;
|
|
424
424
|
}
|
|
425
425
|
|
|
426
|
-
|
|
426
|
+
function parseLlamaCppServerFlags(args: ReadonlyArray<string>): LlamaCppServerFlags {
|
|
427
427
|
const flags: LlamaCppServerFlags = {};
|
|
428
428
|
const ctxSize = numberFlag(args, "--ctx-size", "-c");
|
|
429
429
|
if (ctxSize !== undefined) flags.contextSize = ctxSize;
|
|
@@ -100,7 +100,7 @@ async function* streamSse(body: ReadableStream<Uint8Array>): AsyncGenerator<Comp
|
|
|
100
100
|
}
|
|
101
101
|
} finally {
|
|
102
102
|
if (droppedFrames > 0) {
|
|
103
|
-
process.stderr.write(`[clio:llamacpp] dropped ${droppedFrames} malformed stream frame(s)\n`);
|
|
103
|
+
process.stderr.write(`[clio-coder:llamacpp] dropped ${droppedFrames} malformed stream frame(s)\n`);
|
|
104
104
|
}
|
|
105
105
|
reader.releaseLock();
|
|
106
106
|
}
|
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
listLmStudioModels,
|
|
14
14
|
lmStudioReasoningLevels,
|
|
15
15
|
loadedContextLength,
|
|
16
|
-
parseLmStudioV1Models,
|
|
17
16
|
resolveLmStudioInstance,
|
|
18
17
|
} from "../common/lmstudio-http.js";
|
|
19
18
|
import { synthLocalModel, withV1 } from "../common/local-synth.js";
|
|
@@ -181,12 +180,6 @@ function probeFromCatalog(catalog: LmStudioCatalog, target: TargetDescriptor): P
|
|
|
181
180
|
return result;
|
|
182
181
|
}
|
|
183
182
|
|
|
184
|
-
export function probeResultFromV1Models(data: unknown, target: TargetDescriptor, latencyMs?: number): ProbeResult {
|
|
185
|
-
const models = parseLmStudioV1Models(data);
|
|
186
|
-
if (!models) return { ok: false, error: "LM Studio /api/v1/models response has no models array" };
|
|
187
|
-
return probeFromCatalog({ ok: true, models, tier: "0.4+", ...(latencyMs !== undefined ? { latencyMs } : {}) }, target);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
183
|
const lmstudioRuntime: RuntimeDescriptor = {
|
|
191
184
|
id: "lmstudio",
|
|
192
185
|
aliases: ["lmstudio-native"],
|
|
@@ -224,13 +217,13 @@ const lmstudioRuntime: RuntimeDescriptor = {
|
|
|
224
217
|
});
|
|
225
218
|
const metadata = (
|
|
226
219
|
model as Model<Api> & {
|
|
227
|
-
|
|
220
|
+
clioCoder?: {
|
|
228
221
|
chatTemplateKwargsUnsupported?: boolean;
|
|
229
222
|
lmstudioReasoningOptions?: ReadonlyArray<string>;
|
|
230
223
|
lmstudioDefaultModel?: string;
|
|
231
224
|
};
|
|
232
225
|
}
|
|
233
|
-
).
|
|
226
|
+
).clioCoder;
|
|
234
227
|
if (metadata) {
|
|
235
228
|
metadata.chatTemplateKwargsUnsupported = true;
|
|
236
229
|
if (target.defaultModel) metadata.lmstudioDefaultModel = target.defaultModel;
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LiteLLM proxy: an OpenAI-compatible gateway that fronts a fleet.
|
|
3
|
+
*
|
|
4
|
+
* This is a separate runtime from `openai-compat` rather than a target flag on
|
|
5
|
+
* it, because a gateway answers two questions the generic protocol cannot.
|
|
6
|
+
*
|
|
7
|
+
* First, capability discovery. A gateway publishes semantic aliases: the client
|
|
8
|
+
* asks for `code` and the proxy decides that means `katcoder2.5-35b-moe` on one
|
|
9
|
+
* particular host. LiteLLM's `/v1/models` is the plain OpenAI listing, so every
|
|
10
|
+
* row flattens to a bare id and the context window, tool support, and modality
|
|
11
|
+
* of the model actually behind the alias are all erased. Reached over
|
|
12
|
+
* `openai-compat`, a 262k tool-calling coder is indistinguishable from a 4k
|
|
13
|
+
* chat toy, and Clio plans the session against its own assumed floor. LiteLLM
|
|
14
|
+
* publishes the real numbers on `/v1/model/info` instead, which is what this
|
|
15
|
+
* probe reads.
|
|
16
|
+
*
|
|
17
|
+
* Structured output is the one property worth stating explicitly, because
|
|
18
|
+
* getting it wrong is silent. `src/core/response-schema.ts` deliberately keys
|
|
19
|
+
* the schema dialect on runtime id and not on api family, since a generic
|
|
20
|
+
* OpenAI-compatible gateway answers HTTP 200 to a `response_format` spelling it
|
|
21
|
+
* does not implement and returns unconstrained JSON. LiteLLM earns its entry in
|
|
22
|
+
* that table by measurement rather than by assumption: against the homelab
|
|
23
|
+
* gateway on 2026-08-30, `{"type":"json_schema", json_schema:{...}}` was
|
|
24
|
+
* grammar-enforced end to end on both a llama.cpp upstream and an LM Studio
|
|
25
|
+
* upstream, `{"type":"json_object", schema:{...}}` was enforced on llama.cpp
|
|
26
|
+
* and rejected HTTP 400 by LM Studio, and the same prompt with no
|
|
27
|
+
* `response_format` returned plain prose. `drop_params: true` did not strip
|
|
28
|
+
* either spelling. The standard `json_schema` dialect is therefore the one that
|
|
29
|
+
* holds across every upstream, and it is what this runtime declares.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
import { CLIO_MIN_CONTEXT_WINDOW, CLIO_MIN_MAX_OUTPUT_TOKENS } from "../../../../core/context-floor.js";
|
|
33
|
+
import type { Api, Model } from "../../../../engine/types.js";
|
|
34
|
+
import { probeJson } from "../../probe/http.js";
|
|
35
|
+
import type { CapabilityFlags } from "../../types/capability-flags.js";
|
|
36
|
+
import type { KnowledgeBaseHit } from "../../types/knowledge-base.js";
|
|
37
|
+
import type { ProbeContext, ProbeModelStatus, ProbeResult, RuntimeDescriptor } from "../../types/runtime-descriptor.js";
|
|
38
|
+
import type { TargetDescriptor } from "../../types/target-descriptor.js";
|
|
39
|
+
import { stripTrailingSlash, synthLocalModel, withV1 } from "../common/local-synth.js";
|
|
40
|
+
|
|
41
|
+
const LITELLM_PROVIDER = "litellm";
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Conservative until the probe answers. A gateway that does not publish
|
|
45
|
+
* `model_info` has told Clio nothing, and claiming tools on a target whose tool
|
|
46
|
+
* surface is unknown produces a worker that fails on its first tool call rather
|
|
47
|
+
* than one that is never admitted.
|
|
48
|
+
*/
|
|
49
|
+
const defaultCapabilities: CapabilityFlags = {
|
|
50
|
+
chat: true,
|
|
51
|
+
tools: false,
|
|
52
|
+
reasoning: false,
|
|
53
|
+
vision: false,
|
|
54
|
+
audio: false,
|
|
55
|
+
embeddings: false,
|
|
56
|
+
rerank: false,
|
|
57
|
+
fim: false,
|
|
58
|
+
structuredOutputs: "json-schema",
|
|
59
|
+
contextWindow: CLIO_MIN_CONTEXT_WINDOW,
|
|
60
|
+
maxTokens: CLIO_MIN_MAX_OUTPUT_TOKENS,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/** The server root. This runtime's own paths carry `/v1` where they need it. */
|
|
64
|
+
function rootUrl(target: TargetDescriptor): string | null {
|
|
65
|
+
if (!target.url) return null;
|
|
66
|
+
const trimmed = stripTrailingSlash(target.url);
|
|
67
|
+
return trimmed.endsWith("/v1") ? trimmed.slice(0, -"/v1".length) : trimmed;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function bearerHeaders(target: TargetDescriptor, ctx: ProbeContext): Record<string, string> {
|
|
71
|
+
const headers: Record<string, string> = { ...(target.auth?.headers ?? {}) };
|
|
72
|
+
const envName = target.auth?.apiKeyEnvVar;
|
|
73
|
+
const fromEnv = envName && ctx.credentialsPresent.has(envName) ? process.env[envName]?.trim() : undefined;
|
|
74
|
+
const token = ctx.authToken?.trim() || fromEnv;
|
|
75
|
+
if (token) headers.authorization = `Bearer ${token}`;
|
|
76
|
+
return headers;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
interface LiteLLMModelInfoRow {
|
|
80
|
+
model_name?: unknown;
|
|
81
|
+
litellm_params?: { model?: unknown; api_base?: unknown };
|
|
82
|
+
model_info?: Record<string, unknown>;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
interface LiteLLMModelInfoResponse {
|
|
86
|
+
data?: ReadonlyArray<LiteLLMModelInfoRow>;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
interface LiteLLMModelsResponse {
|
|
90
|
+
data?: ReadonlyArray<{ id?: unknown }>;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function positiveInteger(value: unknown): number | undefined {
|
|
94
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.floor(value) : undefined;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function boolean(value: unknown): boolean | undefined {
|
|
98
|
+
return typeof value === "boolean" ? value : undefined;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Project one LiteLLM `model_info` block onto Clio's capability flags.
|
|
103
|
+
*
|
|
104
|
+
* Only fields the gateway actually filled in are returned. A `model_info` that
|
|
105
|
+
* declares nothing leaves the whole record empty rather than reporting zeros,
|
|
106
|
+
* so the caller can tell "the gateway says this model has no vision" apart from
|
|
107
|
+
* "the gateway did not say", and merge accordingly.
|
|
108
|
+
*/
|
|
109
|
+
function capabilitiesFromLiteLLMModelInfo(info: Record<string, unknown>): Partial<CapabilityFlags> {
|
|
110
|
+
const caps: Partial<CapabilityFlags> = {};
|
|
111
|
+
const contextWindow = positiveInteger(info.max_input_tokens) ?? positiveInteger(info.max_tokens);
|
|
112
|
+
if (contextWindow !== undefined) caps.contextWindow = contextWindow;
|
|
113
|
+
const maxTokens = positiveInteger(info.max_output_tokens);
|
|
114
|
+
if (maxTokens !== undefined) caps.maxTokens = maxTokens;
|
|
115
|
+
const tools = boolean(info.supports_function_calling);
|
|
116
|
+
if (tools !== undefined) caps.tools = tools;
|
|
117
|
+
const vision = boolean(info.supports_vision);
|
|
118
|
+
if (vision !== undefined) caps.vision = vision;
|
|
119
|
+
const reasoning = boolean(info.supports_reasoning);
|
|
120
|
+
if (reasoning !== undefined) caps.reasoning = reasoning;
|
|
121
|
+
const audio = boolean(info.supports_audio_input);
|
|
122
|
+
if (audio !== undefined) caps.audio = audio;
|
|
123
|
+
// `mode` is LiteLLM's own surface discriminator. An embedding deployment is
|
|
124
|
+
// not a chat deployment, and admitting it as one produces a run that fails
|
|
125
|
+
// at the first completion rather than at selection.
|
|
126
|
+
if (info.mode === "embedding") {
|
|
127
|
+
caps.chat = false;
|
|
128
|
+
caps.embeddings = true;
|
|
129
|
+
}
|
|
130
|
+
if (info.mode === "rerank") {
|
|
131
|
+
caps.chat = false;
|
|
132
|
+
caps.rerank = true;
|
|
133
|
+
}
|
|
134
|
+
if (info.mode === "chat") caps.chat = true;
|
|
135
|
+
// Measured, not inferred: see the module header.
|
|
136
|
+
if (boolean(info.supports_response_schema) === true) caps.structuredOutputs = "json-schema";
|
|
137
|
+
return caps;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
interface LiteLLMCatalog {
|
|
141
|
+
models: string[];
|
|
142
|
+
modelCapabilities: Record<string, Partial<CapabilityFlags>>;
|
|
143
|
+
modelStates: Record<string, ProbeModelStatus>;
|
|
144
|
+
/** Physical deployment behind each alias, for display. */
|
|
145
|
+
deployments: Record<string, { model: string; apiBase?: string }>;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const EMPTY_CATALOG: LiteLLMCatalog = { models: [], modelCapabilities: {}, modelStates: {}, deployments: {} };
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Read the catalog from `/v1/model/info`, falling back to `/v1/models`.
|
|
152
|
+
*
|
|
153
|
+
* The detail endpoint is the only one that carries capabilities, but it can be
|
|
154
|
+
* refused for a virtual key with narrower permissions than the master key. A
|
|
155
|
+
* gateway that answers the plain listing and refuses the detail is still usable;
|
|
156
|
+
* it just cannot tell Clio anything beyond which aliases exist, so the target
|
|
157
|
+
* falls back to its declared capabilities exactly as `openai-compat` would.
|
|
158
|
+
*/
|
|
159
|
+
async function fetchCatalog(base: string, ctx: ProbeContext, headers: Record<string, string>): Promise<LiteLLMCatalog> {
|
|
160
|
+
const detailOpts = { url: `${base}/v1/model/info`, timeoutMs: ctx.httpTimeoutMs, headers } as const;
|
|
161
|
+
const detail = await (ctx.signal
|
|
162
|
+
? probeJson<LiteLLMModelInfoResponse>({ ...detailOpts, signal: ctx.signal })
|
|
163
|
+
: probeJson<LiteLLMModelInfoResponse>(detailOpts));
|
|
164
|
+
|
|
165
|
+
if (detail.ok && Array.isArray(detail.data?.data)) {
|
|
166
|
+
const catalog: LiteLLMCatalog = { models: [], modelCapabilities: {}, modelStates: {}, deployments: {} };
|
|
167
|
+
for (const row of detail.data.data) {
|
|
168
|
+
if (typeof row?.model_name !== "string" || row.model_name.length === 0) continue;
|
|
169
|
+
const alias = row.model_name;
|
|
170
|
+
// One alias can carry several deployments. They share a name and Clio
|
|
171
|
+
// addresses them as one model, so the first row establishes the entry
|
|
172
|
+
// and later rows for the same alias are the load-balancing pool behind
|
|
173
|
+
// it rather than separate models.
|
|
174
|
+
if (catalog.deployments[alias] !== undefined) continue;
|
|
175
|
+
catalog.models.push(alias);
|
|
176
|
+
const caps = row.model_info ? capabilitiesFromLiteLLMModelInfo(row.model_info) : {};
|
|
177
|
+
if (Object.keys(caps).length > 0) catalog.modelCapabilities[alias] = caps;
|
|
178
|
+
const upstream = row.litellm_params?.model;
|
|
179
|
+
const apiBase = row.litellm_params?.api_base;
|
|
180
|
+
catalog.deployments[alias] = {
|
|
181
|
+
model: typeof upstream === "string" ? upstream : alias,
|
|
182
|
+
...(typeof apiBase === "string" ? { apiBase } : {}),
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
if (catalog.models.length > 0) return catalog;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const listOpts = { url: `${base}/v1/models`, timeoutMs: ctx.httpTimeoutMs, headers } as const;
|
|
189
|
+
const list = await (ctx.signal
|
|
190
|
+
? probeJson<LiteLLMModelsResponse>({ ...listOpts, signal: ctx.signal })
|
|
191
|
+
: probeJson<LiteLLMModelsResponse>(listOpts));
|
|
192
|
+
if (!list.ok || !Array.isArray(list.data?.data)) return EMPTY_CATALOG;
|
|
193
|
+
const models = list.data.data
|
|
194
|
+
.map((row) => (typeof row?.id === "string" ? row.id : null))
|
|
195
|
+
.filter((id): id is string => id !== null && id.length > 0);
|
|
196
|
+
return { models, modelCapabilities: {}, modelStates: {}, deployments: {} };
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const litellmRuntime: RuntimeDescriptor = {
|
|
200
|
+
id: "litellm",
|
|
201
|
+
displayName: "LiteLLM gateway",
|
|
202
|
+
kind: "http",
|
|
203
|
+
tier: "protocol",
|
|
204
|
+
apiFamily: "openai-completions",
|
|
205
|
+
auth: "api-key",
|
|
206
|
+
defaultCapabilities,
|
|
207
|
+
|
|
208
|
+
async probe(target: TargetDescriptor, ctx: ProbeContext): Promise<ProbeResult> {
|
|
209
|
+
const base = rootUrl(target);
|
|
210
|
+
if (!base) return { ok: false, error: "target has no url" };
|
|
211
|
+
const headers = bearerHeaders(target, ctx);
|
|
212
|
+
|
|
213
|
+
// Liveness first, and deliberately on the unauthenticated endpoint. A
|
|
214
|
+
// gateway with authentication enforced answers 401 to `/v1/models` when
|
|
215
|
+
// credentials are missing or wrong, which is indistinguishable from an
|
|
216
|
+
// unreachable host if that is the only thing probed. `/health/liveliness`
|
|
217
|
+
// separates "the gateway is down" from "this key is not valid", and the
|
|
218
|
+
// two have completely different remedies.
|
|
219
|
+
const liveOpts = { url: `${base}/health/liveliness`, timeoutMs: ctx.httpTimeoutMs } as const;
|
|
220
|
+
const live = await (ctx.signal
|
|
221
|
+
? probeJson<unknown>({ ...liveOpts, signal: ctx.signal })
|
|
222
|
+
: probeJson<unknown>(liveOpts));
|
|
223
|
+
if (!live.ok) return { ok: false, error: live.error ?? "gateway is not reachable" };
|
|
224
|
+
|
|
225
|
+
const catalog = await fetchCatalog(base, ctx, headers);
|
|
226
|
+
if (catalog.models.length === 0) {
|
|
227
|
+
const result: ProbeResult = {
|
|
228
|
+
ok: false,
|
|
229
|
+
error: "gateway is live but served no model catalog; check the target's API key",
|
|
230
|
+
};
|
|
231
|
+
if (live.latencyMs !== undefined) result.latencyMs = live.latencyMs;
|
|
232
|
+
return result;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const result: ProbeResult = { ok: true, models: catalog.models };
|
|
236
|
+
if (live.latencyMs !== undefined) result.latencyMs = live.latencyMs;
|
|
237
|
+
if (Object.keys(catalog.modelCapabilities).length > 0) {
|
|
238
|
+
result.modelCapabilities = catalog.modelCapabilities;
|
|
239
|
+
const selected = target.defaultModel?.trim();
|
|
240
|
+
const selectedCaps = selected ? catalog.modelCapabilities[selected] : undefined;
|
|
241
|
+
if (selected && selectedCaps) {
|
|
242
|
+
result.discoveredCapabilities = selectedCaps;
|
|
243
|
+
result.capabilityModelId = selected;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
const notes: string[] = [];
|
|
247
|
+
const configured = target.defaultModel?.trim();
|
|
248
|
+
if (configured && !catalog.models.includes(configured)) {
|
|
249
|
+
notes.push(`configured model '${configured}' is not in the gateway catalog`);
|
|
250
|
+
}
|
|
251
|
+
// Naming the physical model behind each alias is the difference between a
|
|
252
|
+
// catalog an operator can audit and a list of words.
|
|
253
|
+
const routed = Object.entries(catalog.deployments)
|
|
254
|
+
.map(([alias, deployment]) => `${alias}=${deployment.model}`)
|
|
255
|
+
.sort();
|
|
256
|
+
if (routed.length > 0) notes.push(`routes: ${routed.join(", ")}`);
|
|
257
|
+
if (notes.length > 0) result.notes = notes;
|
|
258
|
+
return result;
|
|
259
|
+
},
|
|
260
|
+
|
|
261
|
+
async probeModels(target: TargetDescriptor, ctx: ProbeContext): Promise<string[]> {
|
|
262
|
+
const base = rootUrl(target);
|
|
263
|
+
if (!base) return [];
|
|
264
|
+
return (await fetchCatalog(base, ctx, bearerHeaders(target, ctx))).models;
|
|
265
|
+
},
|
|
266
|
+
|
|
267
|
+
synthesizeModel(target: TargetDescriptor, wireModelId: string, kb: KnowledgeBaseHit | null): Model<Api> {
|
|
268
|
+
return synthLocalModel({
|
|
269
|
+
// A LiteLLM target is a gateway whether or not settings said so. The
|
|
270
|
+
// residency layer reads this to stay observe-only: the models behind an
|
|
271
|
+
// alias are the proxy's to load and evict, and a Clio stream that tried
|
|
272
|
+
// to manage them would be issuing load commands to a host that does not
|
|
273
|
+
// take them.
|
|
274
|
+
target: { ...target, gateway: true },
|
|
275
|
+
wireModelId,
|
|
276
|
+
kb,
|
|
277
|
+
defaultCapabilities,
|
|
278
|
+
apiFamily: "openai-completions",
|
|
279
|
+
provider: LITELLM_PROVIDER,
|
|
280
|
+
baseUrlForTarget: withV1,
|
|
281
|
+
});
|
|
282
|
+
},
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
export default litellmRuntime;
|
|
@@ -59,6 +59,7 @@ const SUMMARY_BY_RUNTIME_ID: Readonly<Record<string, string>> = {
|
|
|
59
59
|
llamacpp: "llama.cpp server (auto-detect surface)",
|
|
60
60
|
"anthropic-compat": "Generic Anthropic-compatible REST",
|
|
61
61
|
"openai-compat": "Generic OpenAI-compatible REST",
|
|
62
|
+
litellm: "LiteLLM gateway with per-alias capability discovery and routed-model attribution",
|
|
62
63
|
};
|
|
63
64
|
|
|
64
65
|
function groupPriority(group: ProviderSupportGroup): number {
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Disposable per-target model catalogs discovered by provider probes.
|
|
3
|
+
*
|
|
4
|
+
* A live endpoint catalog is machine state, not operator policy. Persisting it
|
|
5
|
+
* in settings.yaml made a three-target config carry hundreds of volatile model
|
|
6
|
+
* ids. Cache files keep that snapshot available to a new process without
|
|
7
|
+
* turning the hand-edited settings file into a probe transcript.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { createHash } from "node:crypto";
|
|
11
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
12
|
+
import { join } from "node:path";
|
|
13
|
+
import { safeResourceWrite } from "../../core/safe-resource-write.js";
|
|
14
|
+
import { clioCacheDir } from "../../core/xdg.js";
|
|
15
|
+
import type { TargetDescriptor } from "./types/target-descriptor.js";
|
|
16
|
+
|
|
17
|
+
export const TARGET_MODEL_CACHE_TTL_MS = 24 * 60 * 60 * 1_000;
|
|
18
|
+
const TARGET_MODEL_CACHE_VERSION = 1;
|
|
19
|
+
const TARGET_MODEL_CACHE_MAX_MODELS = 4_096;
|
|
20
|
+
const TARGET_MODEL_CACHE_MAX_MODEL_ID_CHARS = 1_024;
|
|
21
|
+
|
|
22
|
+
export interface TargetModelSnapshot {
|
|
23
|
+
version: 1;
|
|
24
|
+
targetId: string;
|
|
25
|
+
runtimeId: string;
|
|
26
|
+
url: string | null;
|
|
27
|
+
models: string[];
|
|
28
|
+
observedAt: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface TargetModelCacheOptions {
|
|
32
|
+
cacheDir?: string;
|
|
33
|
+
nowMs?: number;
|
|
34
|
+
ttlMs?: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function targetCacheKey(targetId: string): string {
|
|
38
|
+
return createHash("sha256").update(targetId).digest("hex").slice(0, 24);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function targetModelSnapshotPath(targetId: string, cacheDir = clioCacheDir()): string {
|
|
42
|
+
return join(cacheDir, "provider-target-models", `${targetCacheKey(targetId)}.json`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function normalizedModels(models: ReadonlyArray<string>): string[] {
|
|
46
|
+
const seen = new Set<string>();
|
|
47
|
+
const out: string[] = [];
|
|
48
|
+
for (const raw of models) {
|
|
49
|
+
const model = raw.trim();
|
|
50
|
+
if (model.length === 0 || model.length > TARGET_MODEL_CACHE_MAX_MODEL_ID_CHARS || seen.has(model)) continue;
|
|
51
|
+
seen.add(model);
|
|
52
|
+
out.push(model);
|
|
53
|
+
if (out.length >= TARGET_MODEL_CACHE_MAX_MODELS) break;
|
|
54
|
+
}
|
|
55
|
+
return out;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function parseSnapshot(value: unknown): TargetModelSnapshot | null {
|
|
59
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return null;
|
|
60
|
+
const row = value as Partial<TargetModelSnapshot>;
|
|
61
|
+
if (row.version !== TARGET_MODEL_CACHE_VERSION) return null;
|
|
62
|
+
if (typeof row.targetId !== "string" || row.targetId.length === 0) return null;
|
|
63
|
+
if (typeof row.runtimeId !== "string" || row.runtimeId.length === 0) return null;
|
|
64
|
+
if (row.url !== null && typeof row.url !== "string") return null;
|
|
65
|
+
if (!Array.isArray(row.models) || row.models.some((model) => typeof model !== "string")) return null;
|
|
66
|
+
if (typeof row.observedAt !== "string" || !Number.isFinite(Date.parse(row.observedAt))) return null;
|
|
67
|
+
const models = normalizedModels(row.models);
|
|
68
|
+
if (models.length !== row.models.length) return null;
|
|
69
|
+
return {
|
|
70
|
+
version: TARGET_MODEL_CACHE_VERSION,
|
|
71
|
+
targetId: row.targetId,
|
|
72
|
+
runtimeId: row.runtimeId,
|
|
73
|
+
url: row.url,
|
|
74
|
+
models,
|
|
75
|
+
observedAt: row.observedAt,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Read a fresh snapshot only when it still describes this target identity. */
|
|
80
|
+
export function readTargetModelSnapshot(
|
|
81
|
+
target: Pick<TargetDescriptor, "id" | "runtime" | "url">,
|
|
82
|
+
options: TargetModelCacheOptions = {},
|
|
83
|
+
): TargetModelSnapshot | null {
|
|
84
|
+
const path = targetModelSnapshotPath(target.id, options.cacheDir);
|
|
85
|
+
if (!existsSync(path)) return null;
|
|
86
|
+
try {
|
|
87
|
+
const snapshot = parseSnapshot(JSON.parse(readFileSync(path, "utf8")) as unknown);
|
|
88
|
+
if (snapshot === null) return null;
|
|
89
|
+
if (snapshot.targetId !== target.id || snapshot.runtimeId !== target.runtime) return null;
|
|
90
|
+
if (snapshot.url !== (target.url ?? null)) return null;
|
|
91
|
+
const observedMs = Date.parse(snapshot.observedAt);
|
|
92
|
+
const nowMs = options.nowMs ?? Date.now();
|
|
93
|
+
const ttlMs = options.ttlMs ?? TARGET_MODEL_CACHE_TTL_MS;
|
|
94
|
+
if (observedMs > nowMs || nowMs - observedMs >= ttlMs) return null;
|
|
95
|
+
return snapshot;
|
|
96
|
+
} catch {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Best-effort atomic replacement of one target's disposable probe snapshot. */
|
|
102
|
+
export function recordTargetModelSnapshot(
|
|
103
|
+
target: Pick<TargetDescriptor, "id" | "runtime" | "url">,
|
|
104
|
+
models: ReadonlyArray<string>,
|
|
105
|
+
options: Pick<TargetModelCacheOptions, "cacheDir" | "nowMs"> = {},
|
|
106
|
+
): boolean {
|
|
107
|
+
if (target.id.length === 0 || target.runtime.length === 0) return false;
|
|
108
|
+
const snapshot: TargetModelSnapshot = {
|
|
109
|
+
version: TARGET_MODEL_CACHE_VERSION,
|
|
110
|
+
targetId: target.id,
|
|
111
|
+
runtimeId: target.runtime,
|
|
112
|
+
url: target.url ?? null,
|
|
113
|
+
models: normalizedModels(models),
|
|
114
|
+
observedAt: new Date(options.nowMs ?? Date.now()).toISOString(),
|
|
115
|
+
};
|
|
116
|
+
try {
|
|
117
|
+
safeResourceWrite(targetModelSnapshotPath(target.id, options.cacheDir), `${JSON.stringify(snapshot, null, 2)}\n`, {
|
|
118
|
+
encoding: "utf8",
|
|
119
|
+
});
|
|
120
|
+
return true;
|
|
121
|
+
} catch {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
}
|