@iowarp/clio-coder 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +92 -0
- package/CONTRIBUTING.md +59 -36
- package/README.md +404 -472
- package/SECURITY.md +2 -1
- package/dist/{acp-ZILU3AUO.js → acp-TMDQZDIG.js} +7 -7
- package/dist/{agents-HYWGBGQR.js → agents-5N5NG3XG.js} +28 -28
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-N3QT7CBO.js → auth-Z5CCBXKQ.js} +8 -9
- package/dist/{builtins-UJLMOVOV.js → builtins-K6TNDT24.js} +4 -4
- package/dist/{chunk-GVQJ5CCZ.js → chunk-2HFQNRV3.js} +7 -7
- package/dist/{chunk-QMXC4JB7.js → chunk-2NHR3NAY.js} +163 -1401
- package/dist/chunk-2X4RYJTJ.js +39 -0
- package/dist/{chunk-Y45G3AXC.js → chunk-2Z2IKEXI.js} +6 -10
- package/dist/{chunk-EIMVLWB3.js → chunk-34BHNEE3.js} +7 -3
- package/dist/{chunk-GIZNH63R.js → chunk-35MSIRKH.js} +9 -4
- package/dist/chunk-3EBYEESD.js +314 -0
- package/dist/{chunk-CTJ4RNAA.js → chunk-3F7VUY77.js} +2 -2
- package/dist/{chunk-AP73CFDC.js → chunk-3KIPBMUA.js} +2 -2
- package/dist/{chunk-J5LZHVIT.js → chunk-3M6DQK6S.js} +113 -35
- package/dist/{chunk-VEGN6WIQ.js → chunk-462T4EGZ.js} +2 -2
- package/dist/{chunk-AFKWHWXF.js → chunk-4JDLP6ZS.js} +33 -16
- package/dist/{chunk-6FN3E6KX.js → chunk-4O6MANBS.js} +2 -2
- package/dist/{chunk-AKB4GYDL.js → chunk-54ODD65L.js} +5 -5
- package/dist/{chunk-BBTJOK6Y.js → chunk-5KW52TEP.js} +3 -3
- package/dist/{chunk-6CCS4G3W.js → chunk-5PFYMY2V.js} +2 -2
- package/dist/chunk-77QIVUZB.js +1334 -0
- package/dist/{chunk-7OBGU7UB.js → chunk-7BHIY2MW.js} +7 -13
- package/dist/{chunk-3QSOM6PA.js → chunk-AZ4WMN4W.js} +2 -2
- package/dist/{chunk-6NJQITNH.js → chunk-B74PXLU7.js} +6 -3
- package/dist/{chunk-R23Z6K6I.js → chunk-B7HM5Z7T.js} +15 -15
- package/dist/{chunk-R32CLGZ6.js → chunk-BO7Y52RY.js} +81 -20
- package/dist/{chunk-UEDMSP56.js → chunk-BYMNWQ7O.js} +123 -148
- package/dist/{chunk-ZJLUDYFY.js → chunk-CRFOIAX3.js} +4 -4
- package/dist/{chunk-2NM363SV.js → chunk-CYZW7JHJ.js} +7 -7
- package/dist/{chunk-6HMJX2VU.js → chunk-DYHAXKHD.js} +38 -10
- package/dist/{chunk-THYWACCR.js → chunk-DZAW46HP.js} +3 -3
- package/dist/{chunk-FYUN5KZ3.js → chunk-DZEK6CJN.js} +17 -17
- package/dist/{chunk-3I5NY75V.js → chunk-E7GT7O5N.js} +5 -5
- package/dist/{chunk-VKFQTNDV.js → chunk-F2I26BDK.js} +4 -4
- package/dist/{chunk-HLW2MRKE.js → chunk-F4EKGO4N.js} +3 -1
- package/dist/{chunk-IXJT6DCX.js → chunk-FVDGR2ZL.js} +3 -3
- package/dist/{chunk-TZSKNMZG.js → chunk-GTUD2WMY.js} +2 -1
- package/dist/{chunk-7EPLI7VL.js → chunk-HIICAHCJ.js} +2 -2
- package/dist/{chunk-E67WX76H.js → chunk-HKMD33FO.js} +29 -80
- package/dist/chunk-HLAFFSEK.js +360 -0
- package/dist/{chunk-UAPGZHYC.js → chunk-I64IFBLB.js} +9 -2
- package/dist/{chunk-XKA2ICR3.js → chunk-I66ZTYNP.js} +440 -175
- package/dist/{chunk-7PWAODYW.js → chunk-I7XBWTYH.js} +2 -2
- package/dist/{chunk-PVAMAVBB.js → chunk-IDNA72AH.js} +102 -2
- package/dist/{chunk-GCSMB2KY.js → chunk-IKOZFYBN.js} +1 -1
- package/dist/{chunk-2VG7KLYV.js → chunk-IKSLQ4XV.js} +5460 -3241
- package/dist/{chunk-QKIFBZKT.js → chunk-IMXMHHMQ.js} +166 -25
- package/dist/{chunk-74YWRRU5.js → chunk-JBCS7CRR.js} +2 -2
- package/dist/{chunk-BDPT6GTK.js → chunk-JWJGP5DQ.js} +2 -2
- package/dist/{chunk-K6BF4U2H.js → chunk-KKOJXO6R.js} +62 -14
- package/dist/chunk-KPXDY6QF.js +47 -0
- package/dist/{chunk-ABLSQ6JX.js → chunk-LJID3DYZ.js} +7 -1
- package/dist/{chunk-VKRH2TCS.js → chunk-M2DAX4F6.js} +2 -2
- package/dist/{chunk-6I5ILFOF.js → chunk-M2WXEHER.js} +2 -2
- package/dist/{chunk-YPI3QQCF.js → chunk-MCEPRMZW.js} +2 -4
- package/dist/{chunk-N5UK64DP.js → chunk-MCMZMDAC.js} +2 -2
- package/dist/{chunk-Y4CAGMM6.js → chunk-MNJGS2IN.js} +5 -6
- package/dist/{chunk-TVHHYFHE.js → chunk-NEDJ26B5.js} +2 -2
- package/dist/{chunk-U2WB7TZS.js → chunk-NMJXSHBJ.js} +97 -85
- package/dist/{chunk-HUAS7ITX.js → chunk-O3YUNJZ2.js} +13 -21
- package/dist/{chunk-MA3H6DM5.js → chunk-P75RZCJW.js} +25 -3
- package/dist/{chunk-IG7BCQBA.js → chunk-PGF63K6I.js} +2 -2
- package/dist/chunk-PJX3WQUQ.js +42 -0
- package/dist/{chunk-6DWBAZ5U.js → chunk-Q4XWMHX6.js} +4 -6
- package/dist/{chunk-OJTRZGR3.js → chunk-QQLGQY2A.js} +8 -8
- package/dist/{chunk-J4HBWF6Y.js → chunk-RLYRBIYQ.js} +115 -20
- package/dist/{chunk-NLFAQR7Z.js → chunk-S66XZJOF.js} +3 -23
- package/dist/{chunk-C537JADH.js → chunk-SSEYRH53.js} +6 -7
- package/dist/chunk-SZAA6XDG.js +30 -0
- package/dist/{chunk-MOPSG2X7.js → chunk-TPEQIQIE.js} +6 -6
- package/dist/{chunk-JA5QWE4Z.js → chunk-UBRFI4HS.js} +1879 -1650
- package/dist/{chunk-BTGG6BG2.js → chunk-UH347SHR.js} +154 -15
- package/dist/{chunk-5YHDIDBP.js → chunk-UH632ZYL.js} +2 -2
- package/dist/{chunk-BWW4HLO4.js → chunk-UXCU4E3T.js} +8 -6
- package/dist/{chunk-6VC4OV3Z.js → chunk-VIA6RFQZ.js} +3 -11
- package/dist/{chunk-ZAZB4JMW.js → chunk-VKPAQYEB.js} +27 -8
- package/dist/{chunk-UXN6JT4W.js → chunk-W4YEMFBX.js} +2 -2
- package/dist/{chunk-TD3PGPQA.js → chunk-W6NIE6OW.js} +2 -2
- package/dist/{chunk-TVH4ONAM.js → chunk-X7IARSHT.js} +3 -3
- package/dist/{chunk-PJJ6MY27.js → chunk-XE3PCIXH.js} +3 -3
- package/dist/{chunk-FEFIFZTL.js → chunk-XGDPUNND.js} +2 -2
- package/dist/{chunk-SCYB3HA4.js → chunk-XOXV5GKE.js} +51 -16
- package/dist/{chunk-QTFGO774.js → chunk-XQRY4DTA.js} +24 -11
- package/dist/{chunk-BJGUKIG4.js → chunk-YJISEZKC.js} +2 -2
- package/dist/{chunk-GPPB3JBE.js → chunk-ZGNYYXQ6.js} +2 -2
- package/dist/{chunk-SINK3QR6.js → chunk-ZNT2M6TG.js} +7 -7
- package/dist/{chunk-7RY5VZPH.js → chunk-ZW4HH5JJ.js} +6 -6
- package/dist/cli/index.js +33 -32
- package/dist/{clio-IT3G3VQH.js → clio-7VB377CC.js} +7 -7
- package/dist/{code-nav-RK6S7F6E.js → code-nav-YVLCYA7V.js} +85 -17
- package/dist/{config-3QZRWZJF.js → config-4HVOS65E.js} +88 -43
- package/dist/{configure-FL7Y3KJF.js → configure-PIWO7B24.js} +10 -10
- package/dist/{context-5HE7ODYK.js → context-IYEHL3WQ.js} +33 -31
- package/dist/{context-XNHL75JV.js → context-KQYIWPWT.js} +47 -34
- package/dist/{context-KYQFRVDC.js → context-N6ZE3LGJ.js} +11 -11
- package/dist/{context-clear-N545L53A.js → context-clear-G4OGZJDS.js} +33 -31
- package/dist/{context-working-set-QHKXSV2F.js → context-working-set-BWLF6LJP.js} +7 -7
- package/dist/{dispatch-runner-RGIE5PCT.js → dispatch-runner-2QQAITS3.js} +38 -38
- package/dist/{docs-5NAF6AU7.js → docs-PD3EXDKU.js} +21 -20
- package/dist/{doctor-ZGPEGHIP.js → doctor-LHBD36VU.js} +23 -22
- package/dist/{eval-GXLL44RD.js → eval-C45FYRJ6.js} +21 -20
- package/dist/{eval-inventory-HBWSWQOK.js → eval-inventory-6DEJPLBF.js} +2 -2
- package/dist/{evidence-HWLBRH3Q.js → evidence-6SHONYAF.js} +30 -28
- package/dist/{evolve-FTZBMNVW.js → evolve-KRKMV72X.js} +30 -28
- package/dist/{extensions-VHRBEID7.js → extensions-KPZ2UHBB.js} +5 -3
- package/dist/{fleet-CKZHJWZJ.js → fleet-IVTCKDHT.js} +62 -61
- package/dist/{fleet-commands-EXDXBMV6.js → fleet-commands-EDWL3IT7.js} +5 -5
- package/dist/{fleet-decisions-OTHB6KRL.js → fleet-decisions-YP3YEFGK.js} +4 -4
- package/dist/{fleet-graph-YTEZUCUT.js → fleet-graph-ZFWKHY2M.js} +16 -14
- package/dist/{fleet-inspect-SS6YMDCK.js → fleet-inspect-FVUNCBML.js} +31 -29
- package/dist/{fleet-preflight-PBY4VYOM.js → fleet-preflight-UN5XED4R.js} +2 -2
- package/dist/{fleet-validate-KMEM5L3S.js → fleet-validate-XOWC4HSX.js} +17 -15
- package/dist/{fleet-verify-QD5M7E7Q.js → fleet-verify-UN3SODEL.js} +30 -28
- package/dist/{fleet-view-WAMJYNDT.js → fleet-view-TWHJKCN6.js} +31 -29
- package/dist/{init-5XQRBOFV.js → init-T2QORQ3Y.js} +50 -49
- package/dist/{interop-34TVO25M.js → interop-IN5I2A66.js} +5 -5
- package/dist/{library-3QY6KF57.js → library-LSCATDLZ.js} +15 -13
- package/dist/{memory-L4UTIIIW.js → memory-HYOKAGGJ.js} +31 -29
- package/dist/{models-ZVX3QOWE.js → models-2GPMFYCM.js} +22 -21
- package/dist/{monitor-CEKVSYTS.js → monitor-E4ASVUJH.js} +34 -32
- package/dist/{orchestrator-77BAP6BC.js → orchestrator-DDMPR3PY.js} +984 -583
- package/dist/{panes-7STHOAUJ.js → panes-E3RUXOW5.js} +4 -4
- package/dist/{panes-SHAUIRXY.js → panes-IXKLOKA2.js} +23 -8
- package/dist/{reset-EOLM7GVE.js → reset-OAQP3W4O.js} +4 -4
- package/dist/{resources-74GKTLSF.js → resources-OTRSN34L.js} +15 -13
- package/dist/{run-HBAUJNNZ.js → run-5DEYH5QK.js} +60 -59
- package/dist/{share-G3APVLVP.js → share-IHWTLO3M.js} +19 -15
- package/dist/{skills-35HHUKCR.js → skills-IYMXMKW4.js} +17 -15
- package/dist/{skills-eval-QN4HSHDC.js → skills-eval-DROHSJAR.js} +36 -36
- package/dist/{skills-inventory-J357J34F.js → skills-inventory-D7X4L4ZX.js} +15 -13
- package/dist/{slash-commands-JZZCQA32.js → slash-commands-QBM7UZ3B.js} +21 -18
- package/dist/{steer-XAVHJM22.js → steer-Z5DO23FJ.js} +2 -2
- package/dist/{targets-DSM6CY3M.js → targets-P2FUC4IL.js} +25 -28
- package/dist/{terminal-lease-JOPFUVEM.js → terminal-lease-YREJ3JX2.js} +5 -5
- package/dist/{tools-MKNWVPBH.js → tools-5B7RO6MV.js} +4 -4
- package/dist/{trace-ECQ7TIYZ.js → trace-YMGMUM6A.js} +55 -7
- package/dist/{upgrade-H7TOM7YL.js → upgrade-PXK3S2YM.js} +11 -9
- package/dist/{usage-X52N3IDJ.js → usage-ME5MPXGX.js} +36 -34
- package/dist/{verifiers-EJTVVSMA.js → verifiers-BVZ7IWOO.js} +5 -5
- package/dist/{verify-YJL6XET2.js → verify-5K7ZKQFC.js} +4 -4
- package/dist/{web-fetch-MPIFL3LL.js → web-fetch-MPARV2K7.js} +2 -2
- package/dist/{wiki-generate-4NDZTQ4B.js → wiki-generate-F5W5QTYY.js} +48 -47
- package/dist/{with-panes-OBOBFIIR.js → with-panes-BYOJCLAM.js} +51 -255
- package/dist/worker/entry.js +45 -30
- package/docs/README.md +176 -81
- package/docs/{acp.md → architecture/acp.md} +36 -20
- package/docs/{alcf-provider.md → architecture/alcf-provider.md} +8 -5
- package/docs/{architecture.md → architecture/architecture.md} +43 -22
- package/docs/{artifact-placement.md → architecture/artifact-placement.md} +26 -23
- package/docs/architecture/artifact-versions.md +90 -0
- package/docs/{capacity-and-scheduling.md → architecture/capacity-and-scheduling.md} +26 -13
- package/docs/{context-engine.md → architecture/context-engine.md} +25 -25
- package/docs/{context-working-set.md → architecture/context-working-set.md} +13 -10
- package/docs/{dispatch-architecture-rationale.md → architecture/dispatch-architecture-rationale.md} +12 -9
- package/docs/{dispatch-typed-intent.md → architecture/dispatch-typed-intent.md} +68 -46
- package/docs/{evidence-and-memory.md → architecture/evidence-and-memory.md} +23 -16
- package/docs/{middleware-and-components.md → architecture/middleware-and-components.md} +11 -5
- package/docs/{model-catalog.md → architecture/model-catalog.md} +40 -17
- package/docs/{observability.md → architecture/observability.md} +26 -13
- package/docs/{pi-boundary.md → architecture/pi-boundary.md} +24 -11
- package/docs/{prompt-envelope-and-tools.md → architecture/prompt-envelope-and-tools.md} +55 -20
- package/docs/{provider-adapter-cookbook.md → architecture/provider-adapter-cookbook.md} +35 -24
- package/docs/{safety-model.md → architecture/safety-model.md} +20 -15
- package/docs/{session-lifecycle.md → architecture/session-lifecycle.md} +8 -5
- package/docs/architecture/time-conventions.md +125 -0
- package/docs/{trace-store.md → architecture/trace-store.md} +13 -5
- package/docs/{tui-design.md → architecture/tui-design.md} +13 -13
- package/docs/{worker-dispatch-mechanics.md → architecture/worker-dispatch-mechanics.md} +27 -30
- package/docs/{built-in-agents.md → guide/built-in-agents.md} +50 -34
- package/docs/{commands-and-modes.md → guide/commands-and-modes.md} +65 -60
- package/docs/{configuration-and-targets.md → guide/configuration-and-targets.md} +227 -289
- package/docs/guide/configuration-reference.md +1158 -0
- package/docs/{environment-variables.md → guide/environment-variables.md} +31 -28
- package/docs/{exit-codes-and-output.md → guide/exit-codes-and-output.md} +6 -3
- package/docs/{extensions-and-sharing.md → guide/extensions-and-sharing.md} +41 -14
- package/docs/{fleet-dispatch.md → guide/fleet-dispatch.md} +39 -43
- package/docs/{glossary.md → guide/glossary.md} +14 -11
- package/docs/{installation-and-lifecycle.md → guide/installation-and-lifecycle.md} +44 -13
- package/docs/guide/panes-and-files.md +290 -0
- package/docs/{proactive-memory.md → guide/proactive-memory.md} +79 -66
- package/docs/{resource-library.md → guide/resource-library.md} +13 -4
- package/docs/{skills-marketplace.md → guide/skills-marketplace.md} +7 -3
- package/docs/{tool-usage.md → guide/tool-usage.md} +87 -23
- package/docs/{troubleshooting.md → guide/troubleshooting.md} +9 -4
- package/docs/{config-knobs-audit.md → history/config-knobs-audit.md} +11 -11
- package/docs/{release-cut-checklist.md → history/release-cut-checklist.md} +29 -2
- package/docs/{development-pipeline.md → process/development-pipeline.md} +24 -26
- package/docs/process/documentation-coverage.md +100 -0
- package/docs/process/documentation-guide.md +187 -0
- package/docs/{eval-runner.md → process/eval-runner.md} +41 -50
- package/docs/{evals-internal.md → process/evals-internal.md} +10 -10
- package/docs/{evolution.md → process/evolution.md} +2 -2
- package/docs/{fleet-demo-runbook.md → process/fleet-demo-runbook.md} +11 -7
- package/docs/{git-commit-provenance.md → process/git-commit-provenance.md} +11 -4
- package/docs/{performance-methodology.md → process/performance-methodology.md} +87 -69
- package/docs/{scientific-validation.md → process/scientific-validation.md} +4 -4
- package/evals/README.md +2 -2
- package/package.json +9 -7
- package/skills/README.md +46 -37
- package/skills/coding/ast-grep/SKILL.md +2 -2
- package/skills/coding/coding-standards/SKILL.md +2 -2
- package/skills/coding/prototype/SKILL.md +2 -2
- package/skills/coding/tdd/SKILL.md +2 -2
- package/skills/context/context-handoff/SKILL.md +2 -2
- package/skills/context/context-prime/SKILL.md +2 -2
- package/skills/git/file-ticket/SKILL.md +2 -2
- package/skills/git/fix-issue/SKILL.md +3 -3
- package/skills/git/resolve-merge-conflicts/SKILL.md +2 -2
- package/skills/git/ship/SKILL.md +2 -2
- package/skills/git/worktree-create/SKILL.md +2 -2
- package/skills/git/worktree-merge/SKILL.md +2 -2
- package/skills/meta/clio-coder-dev/SKILL.md +9 -5
- package/skills/meta/clio-coder-dev/evals.md +3 -2
- package/skills/meta/clio-coder-test/SKILL.md +102 -95
- package/skills/meta/clio-coder-test/evals.md +9 -4
- package/skills/meta/clio-coder-test/references/harness.md +100 -124
- package/skills/meta/clio-coder-test/references/test-map.md +77 -50
- package/skills/meta/credentials/SKILL.md +2 -2
- package/skills/meta/find-skills/SKILL.md +2 -2
- package/skills/meta/herdr/SKILL.md +2 -2
- package/skills/meta/skill-craft/SKILL.md +22 -16
- package/skills/planning/architecture/SKILL.md +2 -2
- package/skills/planning/backlog/SKILL.md +2 -2
- package/skills/planning/prd/SKILL.md +2 -2
- package/skills/planning/product-intent/SKILL.md +2 -2
- package/skills/planning/tech-spec/SKILL.md +2 -2
- package/skills/registry.yaml +62 -62
- package/skills/research/arxiv-literature/SKILL.md +2 -2
- package/skills/research/experiment-protocol/SKILL.md +2 -2
- package/skills/research/scientific-debugging/SKILL.md +2 -2
- package/skills/research/scientific-modernization/SKILL.md +2 -2
- package/skills/skill-marketplace.json +62 -62
- package/skills/workflow/cut-it/SKILL.md +2 -2
- package/skills/workflow/design-council/SKILL.md +2 -2
- package/skills/workflow/grill-me/SKILL.md +2 -2
- package/skills/workflow/workflow-distiller/SKILL.md +2 -2
- package/src/cli/args.ts +2 -2
- package/src/cli/bootstrap-generate.ts +1 -1
- package/src/cli/config-inspect.ts +65 -12
- package/src/cli/configure.ts +0 -4
- package/src/cli/docs.ts +22 -14
- package/src/cli/doctor-naming.ts +5 -5
- package/src/cli/doctor-toolchain.ts +3 -3
- package/src/cli/eval.ts +1 -2
- package/src/cli/extensions.ts +2 -1
- package/src/cli/fleet.ts +1 -1
- package/src/cli/index.ts +2 -1
- package/src/cli/internal-dispatch.ts +3 -4
- package/src/cli/panes.ts +19 -5
- package/src/cli/run.ts +2 -2
- package/src/cli/share.ts +5 -1
- package/src/cli/skills-eval.ts +3 -3
- package/src/cli/targets.ts +2 -6
- package/src/cli/trace.ts +55 -4
- package/src/cli/wiki-generate.ts +1 -1
- package/src/core/artifact-paths.ts +1 -1
- package/src/core/bash-exec.ts +131 -86
- package/src/core/bus-events.ts +51 -6
- package/src/core/config.ts +5 -1
- package/src/core/defaults.ts +7 -4
- package/src/core/dispatch-outcome.ts +16 -0
- package/src/core/guardrails.ts +10 -49
- package/src/core/prompt-hint.ts +9 -0
- package/src/domains/agents/builtins/architect.md +2 -3
- package/src/domains/agents/builtins/coder.md +3 -2
- package/src/domains/agents/builtins/debugger.md +2 -2
- package/src/domains/agents/builtins/documenter.md +2 -2
- package/src/domains/agents/builtins/git-master.md +1 -1
- package/src/domains/agents/builtins/oracle.md +1 -1
- package/src/domains/agents/builtins/provenance.md +1 -1
- package/src/domains/agents/builtins/researcher.md +1 -1
- package/src/domains/agents/builtins/scout.md +1 -1
- package/src/domains/agents/builtins/tester.md +2 -2
- package/src/domains/agents/builtins/verifier.md +2 -2
- package/src/domains/agents/builtins/wiki-writer.md +1 -1
- package/src/domains/agents/catalog.ts +12 -14
- package/src/domains/agents/contract.ts +2 -0
- package/src/domains/agents/extension.ts +23 -1
- package/src/domains/config/keybindings.ts +8 -0
- package/src/domains/context/extension.ts +0 -3
- package/src/domains/context/working-set/path-index.ts +1 -0
- package/src/domains/dispatch/capability-match.ts +10 -0
- package/src/domains/dispatch/extension.ts +105 -22
- package/src/domains/dispatch/host-verification.ts +435 -39
- package/src/domains/dispatch/intent-requirements.ts +10 -0
- package/src/domains/dispatch/intent.ts +18 -1
- package/src/domains/dispatch/path-scope.ts +235 -24
- package/src/domains/dispatch/run-event-journal.ts +4 -15
- package/src/domains/dispatch/state.ts +2 -3
- package/src/domains/dispatch/transport.ts +45 -21
- package/src/domains/dispatch/types.ts +55 -3
- package/src/domains/eval/artifacts/store.ts +5 -0
- package/src/domains/eval/store.ts +8 -1
- package/src/domains/evidence/trust-status.ts +10 -1
- package/src/domains/extensions/contract.ts +15 -1
- package/src/domains/extensions/discovery.ts +238 -41
- package/src/domains/extensions/extension.ts +105 -6
- package/src/domains/extensions/index.ts +24 -0
- package/src/domains/extensions/integrity.ts +189 -0
- package/src/domains/extensions/manager.ts +17 -1
- package/src/domains/extensions/resource-path.ts +27 -0
- package/src/domains/extensions/resources.ts +18 -38
- package/src/domains/extensions/snapshot-store.ts +39 -0
- package/src/domains/extensions/snapshot.ts +180 -0
- package/src/domains/extensions/state.ts +385 -57
- package/src/domains/extensions/types.ts +118 -1
- package/src/domains/lifecycle/migrations/2026-09-01-extension-install-digests.ts +27 -0
- package/src/domains/lifecycle/migrations/index.ts +2 -0
- package/src/domains/lifecycle/naming-resources.ts +19 -4
- package/src/domains/lifecycle/naming-yazi.ts +10 -5
- package/src/domains/middleware/contract.ts +26 -0
- package/src/domains/middleware/extension.ts +24 -24
- package/src/domains/middleware/hook-receipts.ts +27 -4
- package/src/domains/middleware/hooks-io.ts +65 -32
- package/src/domains/middleware/hooks.ts +64 -0
- package/src/domains/middleware/index.ts +28 -4
- package/src/domains/middleware/registrations.ts +326 -0
- package/src/domains/middleware/runtime.ts +28 -0
- package/src/domains/middleware/snapshot.ts +20 -7
- package/src/domains/mux/contract.ts +38 -0
- package/src/domains/mux/detect.ts +6 -13
- package/src/domains/mux/index.ts +1 -1
- package/src/domains/mux/operations.ts +44 -5
- package/src/domains/mux/yazi/assets/yazi.toml +2 -2
- package/src/domains/mux/yazi/session.ts +53 -4
- package/src/domains/mux/yazi/theme.ts +117 -17
- package/src/domains/observability/contract.ts +10 -11
- package/src/domains/observability/extension.ts +11 -3
- package/src/domains/observability/projection.ts +14 -90
- package/src/domains/observability/trace-store.ts +43 -7
- package/src/domains/prompts/compiler.ts +73 -53
- package/src/domains/prompts/contract.ts +15 -3
- package/src/domains/prompts/extension.ts +97 -9
- package/src/domains/prompts/fragments/identity/clio-worker.md +1 -3
- package/src/domains/prompts/fragments/identity/clio.md +6 -12
- package/src/domains/prompts/fragments/identity/docs-routing.md +1 -2
- package/src/domains/prompts/fragments/identity/self-awareness.md +3 -11
- package/src/domains/prompts/fragments/operating/contract.md +7 -15
- package/src/domains/prompts/fragments/operating/delegation.md +32 -34
- package/src/domains/prompts/fragments/operating/skills.md +10 -24
- package/src/domains/prompts/fragments/operating/worker.md +1 -8
- package/src/domains/providers/index.ts +1 -1
- package/src/domains/providers/model-runtime-capabilities.ts +85 -21
- package/src/domains/providers/models/local-models/clio-coder-local-coding-targets.yaml +669 -104
- package/src/domains/providers/runtime-resolution.ts +31 -0
- package/src/domains/providers/runtimes/common/probe-helpers.ts +7 -2
- package/src/domains/providers/runtimes/local-native/llamacpp.ts +9 -1
- package/src/domains/providers/types/cost-provenance.ts +19 -0
- package/src/domains/providers/types/local-model-quirks.ts +85 -37
- package/src/domains/resources/skills/loader.ts +16 -19
- package/src/domains/safety/call-target.ts +1 -1
- package/src/domains/safety/loop-detector.ts +7 -4
- package/src/domains/session/task-board.ts +10 -9
- package/src/domains/share/archive.ts +164 -7
- package/src/engine/acp/server.ts +62 -9
- package/src/engine/apis/llamacpp-residency.ts +3 -4
- package/src/engine/apis/lmstudio.ts +3 -3
- package/src/engine/apis/ollama-native.ts +6 -6
- package/src/engine/apis/openai-completions.ts +28 -25
- package/src/engine/apis/output-budget.ts +8 -18
- package/src/engine/apis/residency.ts +8 -27
- package/src/engine/gemma-channel-filter.ts +19 -0
- package/src/engine/loop-guard.ts +92 -12
- package/src/engine/worker-runtime.ts +40 -11
- package/src/engine/worker-tools.ts +3 -1
- package/src/entry/extension-hook-sources.ts +28 -0
- package/src/entry/extension-reload.ts +309 -0
- package/src/entry/orchestrator.ts +59 -35
- package/src/interactive/application-controller.ts +2 -1
- package/src/interactive/bus-notices.ts +8 -1
- package/src/interactive/chat-loop-messages.ts +3 -13
- package/src/interactive/chat-loop.ts +10 -1
- package/src/interactive/chat-panel.ts +36 -13
- package/src/interactive/chat-renderer.ts +71 -7
- package/src/interactive/dispatch-board.ts +6 -11
- package/src/interactive/footer/widgets.ts +13 -0
- package/src/interactive/interactive-application.ts +39 -4
- package/src/interactive/interactive-input-runtime.ts +4 -0
- package/src/interactive/interactive-presentation.ts +2 -2
- package/src/interactive/interactive-slash-runtime.ts +2 -0
- package/src/interactive/overlays/extensions.ts +9 -1
- package/src/interactive/overlays/help-reference.ts +13 -0
- package/src/interactive/overlays/settings.ts +27 -16
- package/src/interactive/panes-runtime.ts +111 -35
- package/src/interactive/prompt-cache-identity.ts +88 -0
- package/src/interactive/slash-commands.ts +129 -14
- package/src/interactive/stream-pacing-policy.ts +0 -23
- package/src/interactive/turn-context.ts +30 -15
- package/src/interactive/yazi-bridge.ts +60 -6
- package/src/tools/agent-tools.ts +30 -1
- package/src/tools/artifact.ts +2 -2
- package/src/tools/ask-user.ts +3 -3
- package/src/tools/bash.ts +1 -1
- package/src/tools/bootstrap.ts +4 -0
- package/src/tools/builtin-tool-catalog.ts +52 -22
- package/src/tools/codewiki/code-nav-surface.ts +6 -0
- package/src/tools/codewiki/code-nav.ts +99 -13
- package/src/tools/context/docs-engine.ts +20 -7
- package/src/tools/context/index.ts +29 -12
- package/src/tools/core-bootstrap.ts +28 -6
- package/src/tools/credential-present.ts +1 -2
- package/src/tools/dispatch-arguments.ts +5 -1
- package/src/tools/dispatch-plan.ts +48 -4
- package/src/tools/dispatch-run-events.ts +1 -1
- package/src/tools/dispatch-schema.ts +338 -0
- package/src/tools/dispatch-types.ts +3 -0
- package/src/tools/dispatch.ts +9 -254
- package/src/tools/ledger.ts +3 -5
- package/src/tools/monitor-surface.ts +5 -13
- package/src/tools/observation.ts +4 -5
- package/src/tools/panes-surface.ts +4 -11
- package/src/tools/panes.ts +4 -2
- package/src/tools/policy.ts +15 -2
- package/src/tools/read.ts +5 -6
- package/src/tools/registry.ts +30 -7
- package/src/tools/result-shaping.ts +18 -14
- package/src/tools/steer-surface.ts +1 -1
- package/src/tools/tasks.ts +1 -1
- package/src/tools/truncate.ts +6 -5
- package/src/tools/verify/surface.ts +6 -12
- package/src/tools/web-fetch-surface.ts +1 -3
- package/dist/chunk-5QIAJV2D.js +0 -48
- package/dist/chunk-JZWT5J3Y.js +0 -814
- package/dist/chunk-K7VKOLQQ.js +0 -15
- package/dist/chunk-PMZCIOCJ.js +0 -25
- package/dist/chunk-SUW5DORT.js +0 -819
- package/dist/chunk-UOV2BYIW.js +0 -107
- package/dist/chunk-WR6U3OVP.js +0 -45
- package/docs/artifact-versions.md +0 -67
- package/docs/documentation-coverage.md +0 -46
- package/docs/documentation-guide.md +0 -167
- package/docs/time-conventions.md +0 -101
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
existsSync,
|
|
4
|
+
lstatSync,
|
|
5
|
+
mkdirSync,
|
|
6
|
+
mkdtempSync,
|
|
7
|
+
readdirSync,
|
|
8
|
+
readFileSync,
|
|
9
|
+
realpathSync,
|
|
10
|
+
rmSync,
|
|
11
|
+
type Stats,
|
|
12
|
+
statSync,
|
|
13
|
+
} from "node:fs";
|
|
14
|
+
import { tmpdir } from "node:os";
|
|
3
15
|
import path from "node:path";
|
|
4
16
|
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
|
5
17
|
import { type ClioSettings, readSettings, settingsPath, updateSettings, validateSettings } from "../../core/config.js";
|
|
@@ -18,6 +30,10 @@ import {
|
|
|
18
30
|
parseAgentRecipeSchema,
|
|
19
31
|
parseFleetContract,
|
|
20
32
|
} from "../agents/index.js";
|
|
33
|
+
import { loadManifestFromRoot } from "../extensions/discovery.js";
|
|
34
|
+
import { extensionContentDigest } from "../extensions/integrity.js";
|
|
35
|
+
import { extensionBaseDir, installExtension, listInstalledExtensions } from "../extensions/state.js";
|
|
36
|
+
import type { ExtensionScope } from "../extensions/types.js";
|
|
21
37
|
import { migrateSettingsV1Document } from "../lifecycle/migrations/2026-09-01-settings-v2.js";
|
|
22
38
|
|
|
23
39
|
export type ShareScope = "project" | "user";
|
|
@@ -331,7 +347,14 @@ export function createShareArchive(options: ShareExportOptions = {}): ClioShareA
|
|
|
331
347
|
for (const scope of scopes) {
|
|
332
348
|
const root =
|
|
333
349
|
scope === "user" ? path.join(clioConfigDir(), "extensions") : path.join(cwd, ".clio-coder", "extensions");
|
|
334
|
-
addTree(
|
|
350
|
+
addTree(
|
|
351
|
+
files,
|
|
352
|
+
"extension",
|
|
353
|
+
scope,
|
|
354
|
+
root,
|
|
355
|
+
`${scope}/extensions`,
|
|
356
|
+
(relativePath) => !relativePath.split("/")[0]?.startsWith(".") && path.basename(relativePath) !== "state.json",
|
|
357
|
+
);
|
|
335
358
|
}
|
|
336
359
|
}
|
|
337
360
|
if (includes.includeSettings) {
|
|
@@ -453,6 +476,15 @@ interface ShareImportPreparedPlan {
|
|
|
453
476
|
actions: ShareImportAction[];
|
|
454
477
|
diagnostics: ShareDiagnostic[];
|
|
455
478
|
targets: ShareImportPreparedTarget[];
|
|
479
|
+
extensionPackages: ShareImportPreparedExtensionPackage[];
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
interface ShareImportPreparedExtensionPackage {
|
|
483
|
+
id: string;
|
|
484
|
+
scope: ExtensionScope;
|
|
485
|
+
files: Array<{ relativePath: string; buffer: Buffer }>;
|
|
486
|
+
contentDigest: string;
|
|
487
|
+
install: boolean;
|
|
456
488
|
}
|
|
457
489
|
|
|
458
490
|
function configDirPath(): string {
|
|
@@ -608,6 +640,91 @@ function preflightImportTargets(
|
|
|
608
640
|
return { targets, diagnostics };
|
|
609
641
|
}
|
|
610
642
|
|
|
643
|
+
function withStagedExtensionPackage<T>(
|
|
644
|
+
input: { id: string; files: ReadonlyArray<{ relativePath: string; buffer: Buffer }> },
|
|
645
|
+
fn: (root: string) => T,
|
|
646
|
+
): T {
|
|
647
|
+
const stagingParent = mkdtempSync(path.join(tmpdir(), "clio-share-extension-"));
|
|
648
|
+
const root = path.join(stagingParent, input.id);
|
|
649
|
+
try {
|
|
650
|
+
mkdirSync(root, { recursive: true });
|
|
651
|
+
for (const file of input.files) safeResourceWrite(path.join(root, file.relativePath), file.buffer);
|
|
652
|
+
return fn(root);
|
|
653
|
+
} finally {
|
|
654
|
+
rmSync(stagingParent, { recursive: true, force: true });
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
function prepareExtensionPackages(
|
|
659
|
+
targets: ReadonlyArray<ShareImportPreparedTarget>,
|
|
660
|
+
options: ShareImportOptions,
|
|
661
|
+
): { packages: ShareImportPreparedExtensionPackage[]; diagnostics: ShareDiagnostic[] } {
|
|
662
|
+
const diagnostics: ShareDiagnostic[] = [];
|
|
663
|
+
const grouped = new Map<string, Omit<ShareImportPreparedExtensionPackage, "contentDigest" | "install">>();
|
|
664
|
+
for (const target of targets) {
|
|
665
|
+
if (target.entry.type !== "extension") continue;
|
|
666
|
+
const segments = relativePathSegments(target.entry.relativePath);
|
|
667
|
+
const id = segments?.[0];
|
|
668
|
+
const packagePath = segments?.slice(1).join("/");
|
|
669
|
+
if (!id || !packagePath) {
|
|
670
|
+
diagnostics.push({
|
|
671
|
+
type: "error",
|
|
672
|
+
message: `extension archive path must be <id>/<package-path>: ${pathDiagnostic(target.entry)}`,
|
|
673
|
+
path: target.entry.relativePath,
|
|
674
|
+
});
|
|
675
|
+
continue;
|
|
676
|
+
}
|
|
677
|
+
const scope = target.scope as ExtensionScope;
|
|
678
|
+
const key = `${scope}\0${id}`;
|
|
679
|
+
const group = grouped.get(key) ?? { id, scope, files: [] };
|
|
680
|
+
if (group.files.some((file) => file.relativePath === packagePath)) {
|
|
681
|
+
diagnostics.push({ type: "error", message: `duplicate extension archive path ${target.entry.relativePath}` });
|
|
682
|
+
continue;
|
|
683
|
+
}
|
|
684
|
+
group.files.push({ relativePath: packagePath, buffer: target.buffer });
|
|
685
|
+
grouped.set(key, group);
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
const packages: ShareImportPreparedExtensionPackage[] = [];
|
|
689
|
+
for (const group of [...grouped.values()].sort((a, b) => `${a.scope}/${a.id}`.localeCompare(`${b.scope}/${b.id}`))) {
|
|
690
|
+
try {
|
|
691
|
+
const contentDigest = withStagedExtensionPackage(group, (root) => {
|
|
692
|
+
const candidate = loadManifestFromRoot(root);
|
|
693
|
+
if (!candidate.valid || !candidate.manifest) {
|
|
694
|
+
throw new Error(candidate.diagnostics.map((diagnostic) => diagnostic.message).join("; ") || "manifest is invalid");
|
|
695
|
+
}
|
|
696
|
+
if (candidate.manifest.id !== group.id) {
|
|
697
|
+
throw new Error(`manifest id ${candidate.manifest.id} does not match archive package ${group.id}`);
|
|
698
|
+
}
|
|
699
|
+
return extensionContentDigest(root);
|
|
700
|
+
});
|
|
701
|
+
const cwd = path.resolve(options.cwd ?? process.cwd());
|
|
702
|
+
const targetRoot = path.join(extensionBaseDir(group.scope, cwd), group.id);
|
|
703
|
+
const existing = listInstalledExtensions(cwd, { scope: group.scope, all: true }).find(
|
|
704
|
+
(extension) => extension.id === group.id && extension.rootPath === targetRoot,
|
|
705
|
+
);
|
|
706
|
+
const alreadyVerified =
|
|
707
|
+
existing?.valid === true &&
|
|
708
|
+
existing.provenance?.contentDigest === contentDigest &&
|
|
709
|
+
existing.observedContentDigest === contentDigest;
|
|
710
|
+
if (existsSync(targetRoot) && !alreadyVerified && !options.force) {
|
|
711
|
+
diagnostics.push({
|
|
712
|
+
type: "conflict",
|
|
713
|
+
message: `extension ${group.id} is not already installed with the archive's verified digest; re-run with --force to use the canonical installer`,
|
|
714
|
+
path: targetRoot,
|
|
715
|
+
});
|
|
716
|
+
}
|
|
717
|
+
packages.push({ ...group, contentDigest, install: !alreadyVerified });
|
|
718
|
+
} catch (error) {
|
|
719
|
+
diagnostics.push({
|
|
720
|
+
type: "error",
|
|
721
|
+
message: `extension ${group.id} in share archive is invalid: ${error instanceof Error ? error.message : String(error)}`,
|
|
722
|
+
});
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
return { packages, diagnostics };
|
|
726
|
+
}
|
|
727
|
+
|
|
611
728
|
function versionDiagnostics(archive: ClioShareArchive): ShareDiagnostic[] {
|
|
612
729
|
const current = readClioVersion();
|
|
613
730
|
const [curMajor, curMinor] = current.split(".");
|
|
@@ -657,13 +774,20 @@ function prepareShareImport(filePath: string, options: ShareImportOptions = {}):
|
|
|
657
774
|
actions: [],
|
|
658
775
|
diagnostics: [{ type: "error", message: err instanceof Error ? err.message : String(err), path: filePath }],
|
|
659
776
|
targets: [],
|
|
777
|
+
extensionPackages: [],
|
|
660
778
|
};
|
|
661
779
|
}
|
|
662
780
|
const diagnostics: ShareDiagnostic[] = [...versionDiagnostics(archive)];
|
|
663
781
|
const actions: ShareImportAction[] = [];
|
|
664
782
|
const preflight = preflightImportTargets(archive, options);
|
|
665
783
|
if (preflight.diagnostics.length > 0) {
|
|
666
|
-
return {
|
|
784
|
+
return {
|
|
785
|
+
archive,
|
|
786
|
+
actions: [],
|
|
787
|
+
diagnostics: [...diagnostics, ...preflight.diagnostics],
|
|
788
|
+
targets: [],
|
|
789
|
+
extensionPackages: [],
|
|
790
|
+
};
|
|
667
791
|
}
|
|
668
792
|
for (const targetInfo of preflight.targets) {
|
|
669
793
|
const { entry, target, scope, buffer } = targetInfo;
|
|
@@ -706,7 +830,9 @@ function prepareShareImport(filePath: string, options: ShareImportOptions = {}):
|
|
|
706
830
|
}
|
|
707
831
|
actions.push({ action: "write", type: entry.type, scope, path: target });
|
|
708
832
|
}
|
|
709
|
-
|
|
833
|
+
const extensions = prepareExtensionPackages(preflight.targets, options);
|
|
834
|
+
diagnostics.push(...extensions.diagnostics);
|
|
835
|
+
return { archive, actions, diagnostics, targets: preflight.targets, extensionPackages: extensions.packages };
|
|
710
836
|
}
|
|
711
837
|
|
|
712
838
|
function publicImportPlan(prepared: ShareImportPreparedPlan, recovery?: ShareImportRecovery): ShareImportPlan {
|
|
@@ -750,10 +876,41 @@ export function importShareArchive(filePath: string, options: ShareImportOptions
|
|
|
750
876
|
};
|
|
751
877
|
let failed: string | undefined;
|
|
752
878
|
try {
|
|
879
|
+
for (const extensionPackage of prepared.extensionPackages) {
|
|
880
|
+
if (!extensionPackage.install) continue;
|
|
881
|
+
const cwd = path.resolve(options.cwd ?? process.cwd());
|
|
882
|
+
failed = path.join(extensionBaseDir(extensionPackage.scope, cwd), extensionPackage.id);
|
|
883
|
+
const result = withStagedExtensionPackage(extensionPackage, (root) =>
|
|
884
|
+
installExtension(root, {
|
|
885
|
+
cwd,
|
|
886
|
+
scope: extensionPackage.scope,
|
|
887
|
+
...(options.force !== undefined ? { force: options.force } : {}),
|
|
888
|
+
}),
|
|
889
|
+
);
|
|
890
|
+
for (const backup of [result.recovery?.stateBackup, result.recovery?.packageBackup]) {
|
|
891
|
+
if (backup && !backups.includes(backup)) backups.push(backup);
|
|
892
|
+
}
|
|
893
|
+
const errors = result.diagnostics.filter((diagnostic) => diagnostic.type === "error");
|
|
894
|
+
if (!result.extension || errors.length > 0) {
|
|
895
|
+
throw new Error(errors.map((diagnostic) => diagnostic.message).join("; ") || "canonical install failed");
|
|
896
|
+
}
|
|
897
|
+
if (result.extension.provenance?.contentDigest !== extensionPackage.contentDigest) {
|
|
898
|
+
throw new Error(`canonical install digest mismatch for extension ${extensionPackage.id}`);
|
|
899
|
+
}
|
|
900
|
+
for (const diagnostic of result.diagnostics) {
|
|
901
|
+
prepared.diagnostics.push({
|
|
902
|
+
type: "warning",
|
|
903
|
+
message: diagnostic.message,
|
|
904
|
+
...(diagnostic.path ? { path: diagnostic.path } : {}),
|
|
905
|
+
});
|
|
906
|
+
}
|
|
907
|
+
if (!written.includes(result.extension.rootPath)) written.push(result.extension.rootPath);
|
|
908
|
+
failed = undefined;
|
|
909
|
+
}
|
|
753
910
|
for (let index = 0; index < prepared.targets.length; index += 1) {
|
|
754
911
|
const targetInfo = prepared.targets[index];
|
|
755
912
|
const action = prepared.actions[index];
|
|
756
|
-
if (!targetInfo || !action || action.action === "skip") continue;
|
|
913
|
+
if (!targetInfo || !action || action.action === "skip" || targetInfo.entry.type === "extension") continue;
|
|
757
914
|
failed = targetInfo.target;
|
|
758
915
|
if (targetInfo.entry.type === "settings") {
|
|
759
916
|
const path = mergeSettingsFragment(targetInfo.buffer);
|
|
@@ -768,7 +925,7 @@ export function importShareArchive(filePath: string, options: ShareImportOptions
|
|
|
768
925
|
);
|
|
769
926
|
failed = undefined;
|
|
770
927
|
}
|
|
771
|
-
return
|
|
928
|
+
return publicImportPlan(prepared, backups.length > 0 ? { written, backups } : undefined);
|
|
772
929
|
} catch (err) {
|
|
773
930
|
if (failed) {
|
|
774
931
|
const expectedBackup = safeResourceBackupPath(failed);
|
|
@@ -787,7 +944,7 @@ export function importShareArchive(filePath: string, options: ShareImportOptions
|
|
|
787
944
|
...prepared.diagnostics,
|
|
788
945
|
{
|
|
789
946
|
type: "error",
|
|
790
|
-
message: `share import failed
|
|
947
|
+
message: `share import failed${failed ? ` while importing ${failed}` : ""}: ${reason}`,
|
|
791
948
|
...(failed ? { path: failed } : {}),
|
|
792
949
|
},
|
|
793
950
|
],
|
package/src/engine/acp/server.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import { realpathSync } from "node:fs";
|
|
3
3
|
import { isAbsolute, resolve as resolvePath } from "node:path";
|
|
4
4
|
import {
|
|
5
|
+
type AccountabilityEvidenceReadyPayload,
|
|
5
6
|
BusChannels,
|
|
6
7
|
type DispatchCompletedPayload,
|
|
7
8
|
type DispatchEnqueuedPayload,
|
|
@@ -209,6 +210,8 @@ interface AcpServerUsage {
|
|
|
209
210
|
cacheRead: number;
|
|
210
211
|
cacheWrite: number;
|
|
211
212
|
reasoning: number;
|
|
213
|
+
totalTokens: number;
|
|
214
|
+
costUsd: number;
|
|
212
215
|
}
|
|
213
216
|
|
|
214
217
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
@@ -333,7 +336,10 @@ const ACP_MAX_REPLAY_TOOL_CALLS = 8192;
|
|
|
333
336
|
* the list is the allowlist, and a client's requested kinds are intersected
|
|
334
337
|
* with it rather than trusted. `safety.loopBlocked` was the first member; the
|
|
335
338
|
* dispatch lifecycle joined it so a client can draw a live fleet board from
|
|
336
|
-
* reported facts instead of inferring one from tool titles or timing
|
|
339
|
+
* reported facts instead of inferring one from tool titles or timing;
|
|
340
|
+
* `accountability.evidenceReady` follows a run's terminal event once its
|
|
341
|
+
* evidence bundle has landed, so the board can show first-pass success and a
|
|
342
|
+
* finding count without reading Clio's state tree.
|
|
337
343
|
*/
|
|
338
344
|
const ACP_FORWARDABLE_EVENT_KINDS = [
|
|
339
345
|
"safety.loopBlocked",
|
|
@@ -342,6 +348,7 @@ const ACP_FORWARDABLE_EVENT_KINDS = [
|
|
|
342
348
|
"dispatch.progress",
|
|
343
349
|
"dispatch.completed",
|
|
344
350
|
"dispatch.failed",
|
|
351
|
+
"accountability.evidenceReady",
|
|
345
352
|
] as const;
|
|
346
353
|
|
|
347
354
|
type AcpForwardableEventKind = (typeof ACP_FORWARDABLE_EVENT_KINDS)[number];
|
|
@@ -359,6 +366,9 @@ const ACP_MAX_DISPATCH_TASK_PREVIEW_BYTES = 160;
|
|
|
359
366
|
|
|
360
367
|
/** Wire bound for the short identifiers a dispatch event carries. */
|
|
361
368
|
const ACP_MAX_DISPATCH_ID_BYTES = 128;
|
|
369
|
+
/** Evidence tags are a closed vocabulary of short identifiers; anything wider is not a tag. */
|
|
370
|
+
const ACP_MAX_EVIDENCE_TAGS = 32;
|
|
371
|
+
const ACP_MAX_EVIDENCE_TAG_BYTES = 64;
|
|
362
372
|
|
|
363
373
|
/**
|
|
364
374
|
* Progress events forwarded per run before the stream is capped. One run
|
|
@@ -521,8 +531,8 @@ function utf8Bytes(value: string): number {
|
|
|
521
531
|
return Buffer.byteLength(value, "utf8");
|
|
522
532
|
}
|
|
523
533
|
|
|
524
|
-
function emptyUsage(): AcpServerUsage {
|
|
525
|
-
return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, reasoning: 0 };
|
|
534
|
+
export function emptyUsage(): AcpServerUsage {
|
|
535
|
+
return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, reasoning: 0, totalTokens: 0, costUsd: 0 };
|
|
526
536
|
}
|
|
527
537
|
|
|
528
538
|
function createActivePromptState(): ActivePrompt {
|
|
@@ -552,15 +562,33 @@ function finite(value: unknown): number {
|
|
|
552
562
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
|
|
553
563
|
}
|
|
554
564
|
|
|
555
|
-
|
|
565
|
+
/** Only field `sumRunUsage` (chat-loop-messages.ts) reads for a dollar figure; matched here so ACP never re-derives cost through a separate path. */
|
|
566
|
+
function costTotal(usage: Record<string, unknown>): number {
|
|
567
|
+
const cost = usage.cost;
|
|
568
|
+
return isRecord(cost) ? finite(cost.total) : 0;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
export function mergeUsage(into: AcpServerUsage, usage: unknown): void {
|
|
556
572
|
if (!isRecord(usage)) return;
|
|
557
|
-
|
|
573
|
+
const input =
|
|
558
574
|
finite(usage.input) + finite(usage.inputTokens) + finite(usage.input_tokens) + finite(usage.prompt_tokens);
|
|
559
|
-
|
|
575
|
+
const output =
|
|
560
576
|
finite(usage.output) + finite(usage.outputTokens) + finite(usage.output_tokens) + finite(usage.completion_tokens);
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
577
|
+
const cacheRead = finite(usage.cacheRead) + finite(usage.cacheReadTokens) + finite(usage.cache_read_tokens);
|
|
578
|
+
const cacheWrite = finite(usage.cacheWrite) + finite(usage.cacheWriteTokens) + finite(usage.cache_write_tokens);
|
|
579
|
+
const reasoning = finite(usage.reasoning) + finite(usage.reasoningTokens) + finite(usage.reasoning_tokens);
|
|
580
|
+
into.input += input;
|
|
581
|
+
into.output += output;
|
|
582
|
+
into.cacheRead += cacheRead;
|
|
583
|
+
into.cacheWrite += cacheWrite;
|
|
584
|
+
into.reasoning += reasoning;
|
|
585
|
+
// Same fallback sumRunUsage uses: prefer the provider's own total, otherwise
|
|
586
|
+
// sum the four merged categories for this message (reasoning excluded,
|
|
587
|
+
// matching sumRunUsage, since a provider that reports reasoning separately
|
|
588
|
+
// still counts it inside output for billing).
|
|
589
|
+
const explicitTotal = finite(usage.totalTokens) + finite(usage.total_tokens);
|
|
590
|
+
into.totalTokens += explicitTotal > 0 ? explicitTotal : input + output + cacheRead + cacheWrite;
|
|
591
|
+
into.costUsd += costTotal(usage);
|
|
564
592
|
}
|
|
565
593
|
|
|
566
594
|
function mergeMessageUsage(into: AcpServerUsage, message: unknown, seen?: WeakSet<object>): void {
|
|
@@ -1857,6 +1885,29 @@ export async function serveClioAcpAgent(options: ClioAcpServerOptions): Promise<
|
|
|
1857
1885
|
});
|
|
1858
1886
|
}),
|
|
1859
1887
|
);
|
|
1888
|
+
unsubscribeEvents.push(
|
|
1889
|
+
bus.on(BusChannels.AccountabilityEvidenceReady, (payload: AccountabilityEvidenceReadyPayload) => {
|
|
1890
|
+
// Arrives after dispatch.completed or dispatch.failed for the same run,
|
|
1891
|
+
// so it is terminal too: nothing about that run follows it. The
|
|
1892
|
+
// bundle's prose (findings, overview) stays behind; only the summary
|
|
1893
|
+
// counters the projection itself carries cross, and the tags are
|
|
1894
|
+
// filtered to bounded identifiers rather than truncated into new ones.
|
|
1895
|
+
const runId = safeStoredIdentifier(payload.runId, ACP_MAX_DISPATCH_ID_BYTES);
|
|
1896
|
+
const evidenceId = safeStoredIdentifier(payload.evidenceId, ACP_MAX_DISPATCH_ID_BYTES);
|
|
1897
|
+
if (runId === null || evidenceId === null) return;
|
|
1898
|
+
const tags = (Array.isArray(payload.tags) ? payload.tags : [])
|
|
1899
|
+
.map((tag) => safeStoredIdentifier(tag, ACP_MAX_EVIDENCE_TAG_BYTES))
|
|
1900
|
+
.filter((tag): tag is string => tag !== null)
|
|
1901
|
+
.slice(0, ACP_MAX_EVIDENCE_TAGS);
|
|
1902
|
+
forwardEvent("accountability.evidenceReady", null, true, {
|
|
1903
|
+
runId,
|
|
1904
|
+
evidenceId,
|
|
1905
|
+
firstPassSuccess: payload.firstPassSuccess === true,
|
|
1906
|
+
findingCount: safeCount(payload.findingCount),
|
|
1907
|
+
tags,
|
|
1908
|
+
});
|
|
1909
|
+
}),
|
|
1910
|
+
);
|
|
1860
1911
|
}
|
|
1861
1912
|
const unsubscribeEventStream = (): void => {
|
|
1862
1913
|
for (const unsubscribe of unsubscribeEvents) unsubscribe();
|
|
@@ -2607,6 +2658,8 @@ function promptResponse(stopReason: string, active: ActivePrompt): AcpPromptResp
|
|
|
2607
2658
|
cacheRead: active.usage.cacheRead,
|
|
2608
2659
|
cacheWrite: active.usage.cacheWrite,
|
|
2609
2660
|
reasoning: active.usage.reasoning,
|
|
2661
|
+
totalTokens: active.usage.totalTokens,
|
|
2662
|
+
costUsd: active.usage.costUsd,
|
|
2610
2663
|
},
|
|
2611
2664
|
},
|
|
2612
2665
|
};
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
type ResidencyAdapter,
|
|
6
6
|
ResidencyPreconditionError,
|
|
7
7
|
reconcileResidency,
|
|
8
|
-
residencyManaged,
|
|
9
8
|
residentTagProtected,
|
|
10
9
|
} from "./residency.js";
|
|
11
10
|
|
|
@@ -27,8 +26,8 @@ export interface LlamaCppResidencyInput {
|
|
|
27
26
|
runtimeId: string;
|
|
28
27
|
keepModelId: string;
|
|
29
28
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
29
|
+
* Target lifecycle verdict from the caller (residencyManagedFor). Defaults
|
|
30
|
+
* to managed for direct adapter callers.
|
|
32
31
|
*/
|
|
33
32
|
managed?: boolean;
|
|
34
33
|
fetchImpl?: typeof fetch;
|
|
@@ -284,7 +283,7 @@ export async function ensureLlamaCppResidency(input: LlamaCppResidencyInput): Pr
|
|
|
284
283
|
targetId: input.targetId,
|
|
285
284
|
runtimeId: input.runtimeId,
|
|
286
285
|
keepModelId: input.keepModelId,
|
|
287
|
-
managed: input.managed ??
|
|
286
|
+
managed: input.managed ?? true,
|
|
288
287
|
strategy: "router",
|
|
289
288
|
listResident: async () => {
|
|
290
289
|
const models = await fetchRouterModels(input, fetchImpl);
|
|
@@ -16,7 +16,7 @@ import { emitResidencyMutation, emitResidencyNotice, reconcileResidency, residen
|
|
|
16
16
|
import { withResidencyLock } from "./residency-lock.js";
|
|
17
17
|
|
|
18
18
|
interface LmStudioModelMetadata {
|
|
19
|
-
|
|
19
|
+
clioCoder?: {
|
|
20
20
|
targetId: string;
|
|
21
21
|
runtimeId: string;
|
|
22
22
|
lifecycle?: "user-managed" | "clio-coder-managed";
|
|
@@ -42,8 +42,8 @@ function responseInstanceId(data: unknown): string | undefined {
|
|
|
42
42
|
return typeof id === "string" && id.trim().length > 0 ? id.trim() : undefined;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
function metadata(model: Model<Api>): NonNullable<LmStudioModelMetadata["
|
|
46
|
-
return (model as Model<Api> & LmStudioModelMetadata).
|
|
45
|
+
function metadata(model: Model<Api>): NonNullable<LmStudioModelMetadata["clioCoder"]> | undefined {
|
|
46
|
+
return (model as Model<Api> & LmStudioModelMetadata).clioCoder;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
function targetForModel(model: Model<"openai-completions">): TargetDescriptor | null {
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
} from "../../domains/providers/index.js";
|
|
33
33
|
import type { LocalModelQuirks, SamplingProfile } from "../../domains/providers/types/local-model-quirks.js";
|
|
34
34
|
import { calculateEngineCost } from "../ai.js";
|
|
35
|
-
import { createGemmaChannelFilter } from "../gemma-channel-filter.js";
|
|
35
|
+
import { createGemmaChannelFilter, usesGemmaChannelMarkers } from "../gemma-channel-filter.js";
|
|
36
36
|
import { createSentinelStripper } from "../strip-tokenizer-sentinels.js";
|
|
37
37
|
import { remainingContextMaxTokens } from "./output-budget.js";
|
|
38
38
|
import { type ResidencyAdapter, reconcileResidency, residencyManagedFor } from "./residency.js";
|
|
@@ -43,7 +43,7 @@ import type { EngineApiProvider } from "./types.js";
|
|
|
43
43
|
const REASONING_CHARS_PER_TOKEN = 4;
|
|
44
44
|
|
|
45
45
|
interface ClioRuntimeMetadata {
|
|
46
|
-
|
|
46
|
+
clioCoder?: {
|
|
47
47
|
targetId: string;
|
|
48
48
|
runtimeId: string;
|
|
49
49
|
/** Present only when settings set the target lifecycle explicitly. */
|
|
@@ -55,11 +55,11 @@ interface ClioRuntimeMetadata {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
function clioQuirks(model: Model<"ollama-native">): LocalModelQuirks | undefined {
|
|
58
|
-
return (model as Model<"ollama-native"> & ClioRuntimeMetadata).
|
|
58
|
+
return (model as Model<"ollama-native"> & ClioRuntimeMetadata).clioCoder?.quirks;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
function ollamaTargetId(model: Model<"ollama-native">): string {
|
|
62
|
-
return (model as Model<"ollama-native"> & ClioRuntimeMetadata).
|
|
62
|
+
return (model as Model<"ollama-native"> & ClioRuntimeMetadata).clioCoder?.targetId ?? model.provider;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
/**
|
|
@@ -74,7 +74,7 @@ function ollamaTargetId(model: Model<"ollama-native">): string {
|
|
|
74
74
|
async function reconcileOllamaResidency(model: Model<"ollama-native">, headers: Record<string, string>): Promise<void> {
|
|
75
75
|
const baseUrl = model.baseUrl;
|
|
76
76
|
if (!baseUrl) return;
|
|
77
|
-
const metadata = (model as Model<"ollama-native"> & ClioRuntimeMetadata).
|
|
77
|
+
const metadata = (model as Model<"ollama-native"> & ClioRuntimeMetadata).clioCoder;
|
|
78
78
|
const adapter: ResidencyAdapter = {
|
|
79
79
|
targetKey: residencyTargetKey("ollama-native", baseUrl),
|
|
80
80
|
targetId: ollamaTargetId(model),
|
|
@@ -384,7 +384,7 @@ function runStream(
|
|
|
384
384
|
let doneReason: string | undefined;
|
|
385
385
|
const sentinelStripper = createSentinelStripper();
|
|
386
386
|
const resolved = resolveModelRuntimeCapabilitiesForModel(model, thinkingLevel);
|
|
387
|
-
const channelFilter = resolved.
|
|
387
|
+
const channelFilter = usesGemmaChannelMarkers(resolved.modelId) ? createGemmaChannelFilter() : null;
|
|
388
388
|
const closeActiveThinking = () => {
|
|
389
389
|
if (!activeThinking) return;
|
|
390
390
|
stream.push({
|
|
@@ -28,12 +28,12 @@ import { lmStudioReasoningEffort } from "../../domains/providers/runtimes/common
|
|
|
28
28
|
import type { ThinkingLevel } from "../../domains/providers/types/capability-flags.js";
|
|
29
29
|
import type { LocalModelQuirks, SamplingProfile } from "../../domains/providers/types/local-model-quirks.js";
|
|
30
30
|
import type { LmStudioTargetSettings } from "../../domains/providers/types/target-descriptor.js";
|
|
31
|
-
import { filterGemmaChannelStream } from "../gemma-channel-filter.js";
|
|
31
|
+
import { filterGemmaChannelStream, usesGemmaChannelMarkers } from "../gemma-channel-filter.js";
|
|
32
32
|
import { HarmonyResponseParser } from "../harmony-response.js";
|
|
33
33
|
import { createSentinelStripper, stripTokenizerSentinels } from "../strip-tokenizer-sentinels.js";
|
|
34
34
|
import { ensureLlamaCppResidency } from "./llamacpp-residency.js";
|
|
35
35
|
import { ensureLmStudioResidency } from "./lmstudio.js";
|
|
36
|
-
import {
|
|
36
|
+
import { remainingContextMaxTokens } from "./output-budget.js";
|
|
37
37
|
import { residencyManagedFor } from "./residency.js";
|
|
38
38
|
import { mergeSamplingOverride } from "./sampling-overrides.js";
|
|
39
39
|
import type { EngineApiProvider } from "./types.js";
|
|
@@ -60,7 +60,7 @@ const REASONING_CHARS_PER_TOKEN = 4;
|
|
|
60
60
|
export { estimateInputTokensFromContext, remainingContextMaxTokens } from "./output-budget.js";
|
|
61
61
|
|
|
62
62
|
interface ClioRuntimeMetadata {
|
|
63
|
-
|
|
63
|
+
clioCoder?: {
|
|
64
64
|
targetId: string;
|
|
65
65
|
runtimeId: string;
|
|
66
66
|
/** Present only when settings set the target lifecycle explicitly. */
|
|
@@ -75,11 +75,11 @@ interface ClioRuntimeMetadata {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
function chatTemplateKwargsUnsupported(model: Model<Api>): boolean {
|
|
78
|
-
return (model as Model<Api> & ClioRuntimeMetadata).
|
|
78
|
+
return (model as Model<Api> & ClioRuntimeMetadata).clioCoder?.chatTemplateKwargsUnsupported === true;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
function clioQuirks(model: Model<"openai-completions">): LocalModelQuirks | undefined {
|
|
82
|
-
return (model as Model<"openai-completions"> & ClioRuntimeMetadata).
|
|
82
|
+
return (model as Model<"openai-completions"> & ClioRuntimeMetadata).clioCoder?.quirks;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
function pickSamplingProfile(
|
|
@@ -138,7 +138,7 @@ function backendCompletionTimings(value: unknown, source: BackendTimingsSource):
|
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
function backendTimingsSourceForModel(model: Model<Api>): BackendTimingsSource | null {
|
|
141
|
-
const metadata = (model as Model<Api> & ClioRuntimeMetadata).
|
|
141
|
+
const metadata = (model as Model<Api> & ClioRuntimeMetadata).clioCoder;
|
|
142
142
|
if (model.provider === "llamacpp" && metadata?.runtimeId === "llamacpp") return "llamacpp-timings";
|
|
143
143
|
if (model.provider === "lmstudio" && metadata?.runtimeId === "lmstudio") return "lmstudio-timings";
|
|
144
144
|
return null;
|
|
@@ -371,8 +371,23 @@ function applyThinkingPayload(
|
|
|
371
371
|
resolved: ResolvedModelRuntimeCapabilities,
|
|
372
372
|
model: Model<Api>,
|
|
373
373
|
): Record<string, unknown> {
|
|
374
|
-
if (applied.mechanism === "none")
|
|
375
|
-
|
|
374
|
+
if (applied.mechanism === "none") {
|
|
375
|
+
const next = stripThinkingRequestFields(payload);
|
|
376
|
+
if (resolved.request.chatTemplateKwargs && !chatTemplateKwargsUnsupported(model)) {
|
|
377
|
+
const existing = isPlainRecord(next.chat_template_kwargs) ? next.chat_template_kwargs : {};
|
|
378
|
+
next.chat_template_kwargs = { ...existing, ...resolved.request.chatTemplateKwargs };
|
|
379
|
+
}
|
|
380
|
+
return next;
|
|
381
|
+
}
|
|
382
|
+
if (applied.mechanism === "always-on") {
|
|
383
|
+
if (resolved.request.chatTemplateKwargs && !chatTemplateKwargsUnsupported(model)) {
|
|
384
|
+
const next: Record<string, unknown> = { ...payload };
|
|
385
|
+
const existing = isPlainRecord(next.chat_template_kwargs) ? next.chat_template_kwargs : {};
|
|
386
|
+
next.chat_template_kwargs = { ...existing, ...resolved.request.chatTemplateKwargs };
|
|
387
|
+
return next;
|
|
388
|
+
}
|
|
389
|
+
return payload;
|
|
390
|
+
}
|
|
376
391
|
const next: Record<string, unknown> = { ...payload };
|
|
377
392
|
if (
|
|
378
393
|
resolved.request.reasoningEffort &&
|
|
@@ -563,21 +578,9 @@ function withRemainingContextBudget<TOptions extends StreamOptions>(
|
|
|
563
578
|
context: Context,
|
|
564
579
|
options: TOptions | undefined,
|
|
565
580
|
): TOptions {
|
|
566
|
-
const metadata = runtimeMetadata(model);
|
|
567
|
-
const localToolOutputLimit =
|
|
568
|
-
options?.maxTokens === undefined &&
|
|
569
|
-
(context.tools?.length ?? 0) > 0 &&
|
|
570
|
-
(model.provider === "llamacpp" || metadata?.runtimeId === "llamacpp")
|
|
571
|
-
? LOCAL_TOOL_TURN_MAX_OUTPUT_TOKENS
|
|
572
|
-
: undefined;
|
|
573
581
|
return {
|
|
574
582
|
...(options ?? {}),
|
|
575
|
-
maxTokens: remainingContextMaxTokens(
|
|
576
|
-
model,
|
|
577
|
-
context,
|
|
578
|
-
options,
|
|
579
|
-
localToolOutputLimit === undefined ? undefined : { maxOutputTokens: localToolOutputLimit },
|
|
580
|
-
),
|
|
583
|
+
maxTokens: remainingContextMaxTokens(model, context, options),
|
|
581
584
|
} as TOptions;
|
|
582
585
|
}
|
|
583
586
|
|
|
@@ -593,8 +596,8 @@ function hasEmptyArguments(args: Record<string, unknown>): boolean {
|
|
|
593
596
|
return Object.keys(args).length === 0;
|
|
594
597
|
}
|
|
595
598
|
|
|
596
|
-
function runtimeMetadata(model: Model<Api>): NonNullable<ClioRuntimeMetadata["
|
|
597
|
-
return (model as Model<Api> & ClioRuntimeMetadata).
|
|
599
|
+
function runtimeMetadata(model: Model<Api>): NonNullable<ClioRuntimeMetadata["clioCoder"]> | undefined {
|
|
600
|
+
return (model as Model<Api> & ClioRuntimeMetadata).clioCoder;
|
|
598
601
|
}
|
|
599
602
|
|
|
600
603
|
function emptyErrorMessage(model: Model<"openai-completions">, message: string): AssistantMessage {
|
|
@@ -936,7 +939,7 @@ export const openAICompletionsApiProvider: EngineApiProvider<"openai-completions
|
|
|
936
939
|
(requestModel) => piOpenAICompletions.stream(requestModel, effectiveContext, capturedOptions),
|
|
937
940
|
),
|
|
938
941
|
),
|
|
939
|
-
resolved.
|
|
942
|
+
usesGemmaChannelMarkers(resolved.modelId),
|
|
940
943
|
),
|
|
941
944
|
resolved,
|
|
942
945
|
),
|
|
@@ -969,7 +972,7 @@ export const openAICompletionsApiProvider: EngineApiProvider<"openai-completions
|
|
|
969
972
|
(requestModel) => piOpenAICompletions.streamSimple(requestModel, effectiveContext, capturedOptions),
|
|
970
973
|
),
|
|
971
974
|
),
|
|
972
|
-
resolved.
|
|
975
|
+
usesGemmaChannelMarkers(resolved.modelId),
|
|
973
976
|
),
|
|
974
977
|
resolved,
|
|
975
978
|
),
|
|
@@ -13,7 +13,7 @@ const DEFAULT_MAX_OUTPUT_TOKENS = CLIO_MIN_MAX_OUTPUT_TOKENS;
|
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Process-wide default output budget requested per turn, sourced from
|
|
16
|
-
*
|
|
16
|
+
* chat.maxOutputTokens at session start (see
|
|
17
17
|
* {@link setGlobalDefaultMaxOutputTokens}). 0 means unset: callers fall back to
|
|
18
18
|
* the model's advertised cap as before.
|
|
19
19
|
*/
|
|
@@ -30,19 +30,6 @@ export function setGlobalDefaultMaxOutputTokens(value: number): void {
|
|
|
30
30
|
globalDefaultMaxOutputTokens = Number.isFinite(value) && value > 0 ? Math.floor(value) : 0;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
/**
|
|
34
|
-
* Output ceiling applied to a llama.cpp tool-bearing turn when the caller did
|
|
35
|
-
* not request an explicit limit. It bounds a genuinely runaway local
|
|
36
|
-
* generation without muzzling real work: a single tool call that writes a
|
|
37
|
-
* sizable file (a full HTML page, a multi-function source module) needs far
|
|
38
|
-
* more than a few thousand tokens of argument, and the tool-call argument
|
|
39
|
-
* counts against this same response budget. Narration loops where a local
|
|
40
|
-
* model keeps saying it will call a tool without emitting one are caught
|
|
41
|
-
* separately by assessToolProseLoop, so this number only has to be large
|
|
42
|
-
* enough to let legitimate large outputs through.
|
|
43
|
-
*/
|
|
44
|
-
export const LOCAL_TOOL_TURN_MAX_OUTPUT_TOKENS = CLIO_MIN_MAX_OUTPUT_TOKENS;
|
|
45
|
-
|
|
46
33
|
/**
|
|
47
34
|
* Tokens a preflight context check should hold back for the response: the
|
|
48
35
|
* smaller of the model's advertised output limit and the default output
|
|
@@ -84,15 +71,18 @@ export function remainingContextMaxTokens(
|
|
|
84
71
|
const modelLimit = model.maxTokens > 0 ? model.maxTokens : Number.POSITIVE_INFINITY;
|
|
85
72
|
// Precedence for the requested ceiling when the caller gave no explicit
|
|
86
73
|
// maxTokens: a more-specific tool-turn limit, then the global default, then
|
|
87
|
-
// the model's advertised cap.
|
|
88
|
-
//
|
|
89
|
-
//
|
|
74
|
+
// the model's advertised cap. A model that advertises no cap uses the product
|
|
75
|
+
// floor instead of requesting its entire remaining context window. Math.min
|
|
76
|
+
// below clamps the result down to every known boundary, so frontier providers
|
|
77
|
+
// with a known cap never receive a larger max_tokens value.
|
|
90
78
|
const defaultLimit =
|
|
91
79
|
limits?.maxOutputTokens !== undefined && limits.maxOutputTokens > 0
|
|
92
80
|
? limits.maxOutputTokens
|
|
93
81
|
: globalDefaultMaxOutputTokens > 0
|
|
94
82
|
? globalDefaultMaxOutputTokens
|
|
95
|
-
:
|
|
83
|
+
: model.maxTokens > 0
|
|
84
|
+
? modelLimit
|
|
85
|
+
: DEFAULT_MAX_OUTPUT_TOKENS;
|
|
96
86
|
const requested = options?.maxTokens ?? defaultLimit;
|
|
97
87
|
const resolved = Math.min(requested, modelLimit, budget);
|
|
98
88
|
return Number.isFinite(resolved) ? resolved : DEFAULT_MAX_OUTPUT_TOKENS;
|