@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
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
*
|
|
27
27
|
* The reconciler is best-effort and non-blocking. A slow or unreachable
|
|
28
28
|
* server, or a malformed resident listing, degrades to observe-only and never
|
|
29
|
-
* crashes a turn.
|
|
30
|
-
*
|
|
29
|
+
* crashes a turn. An explicit target `lifecycle: user-managed` forces
|
|
30
|
+
* observe-only on every runtime path.
|
|
31
31
|
* Every collision or stress case emits a notice over the event bus instead of
|
|
32
32
|
* a thrown error. One reconcile decision holds per (target, model) within a
|
|
33
33
|
* TTL, and mutations for a target are serialized across processes through a
|
|
@@ -280,7 +280,7 @@ function evictionNotice(facts: ResidencyFacts, entry: ResidentClassified): Resid
|
|
|
280
280
|
facts,
|
|
281
281
|
"swap",
|
|
282
282
|
"warning",
|
|
283
|
-
`swapping resident '${entry.modelId}' for requested '${facts.keepModelId}' on '${facts.targetId}' (Clio did not load it; recorded transition instead of a silent unload; set
|
|
283
|
+
`swapping resident '${entry.modelId}' for requested '${facts.keepModelId}' on '${facts.targetId}' (Clio did not load it; recorded transition instead of a silent unload; set lifecycle: user-managed to forbid swaps).`,
|
|
284
284
|
{
|
|
285
285
|
...(entry.sizeVramBytes !== undefined ? { freedVramBytes: entry.sizeVramBytes } : {}),
|
|
286
286
|
swappedOut: entry.modelId,
|
|
@@ -775,29 +775,10 @@ export async function reconcileResidency(adapter: ResidencyAdapter): Promise<Rec
|
|
|
775
775
|
}
|
|
776
776
|
|
|
777
777
|
/**
|
|
778
|
-
*
|
|
779
|
-
*
|
|
780
|
-
*
|
|
781
|
-
* through {@link residencyManagedFor}.
|
|
778
|
+
* Residency policy for one target. An absent lifecycle means the operator made
|
|
779
|
+
* no choice and Clio manages by default; runtime synthesis only sets the
|
|
780
|
+
* metadata field when settings carry an explicit value.
|
|
782
781
|
*/
|
|
783
|
-
export function
|
|
784
|
-
|
|
785
|
-
if (opt === "observe" || opt === "off" || opt === "0" || opt === "false" || opt === "user" || opt === "user-managed") {
|
|
786
|
-
return false;
|
|
787
|
-
}
|
|
788
|
-
return true;
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
/**
|
|
792
|
-
* Combined residency opt-out for one target: the process-wide env switch plus
|
|
793
|
-
* the target's explicit `lifecycle: user-managed`. An absent lifecycle means
|
|
794
|
-
* the operator made no choice, and Clio manages by default; runtime synthesis
|
|
795
|
-
* only sets the metadata field when settings carry an explicit value.
|
|
796
|
-
*/
|
|
797
|
-
export function residencyManagedFor(
|
|
798
|
-
lifecycle: "user-managed" | "clio-coder-managed" | undefined,
|
|
799
|
-
env: NodeJS.ProcessEnv = process.env,
|
|
800
|
-
): boolean {
|
|
801
|
-
if (lifecycle === "user-managed") return false;
|
|
802
|
-
return residencyManaged(env);
|
|
782
|
+
export function residencyManagedFor(lifecycle: "user-managed" | "clio-coder-managed" | undefined): boolean {
|
|
783
|
+
return lifecycle !== "user-managed";
|
|
803
784
|
}
|
|
@@ -6,6 +6,25 @@ import type {
|
|
|
6
6
|
ThinkingContent,
|
|
7
7
|
} from "@earendil-works/pi-ai";
|
|
8
8
|
import { createAssistantMessageEventStream } from "@earendil-works/pi-ai";
|
|
9
|
+
import { inferLocalModelFamily } from "../domains/providers/model-family.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Whether a model id names a Gemma 4 checkpoint, whose chat template writes its
|
|
13
|
+
* private channel with the markers below when llama-server leaves the thought
|
|
14
|
+
* inline in `content` instead of extracting it to `reasoning_content`.
|
|
15
|
+
*
|
|
16
|
+
* Keyed on the wire model id rather than on the resolved family, because
|
|
17
|
+
* `capabilityFamily` returns the knowledge-base family whenever the catalog
|
|
18
|
+
* matches an id and every Gemma entry there names a build (`gemma4-26b-a4b`,
|
|
19
|
+
* `gemma-4-31b-it-qat-mtp`, `gemopus-4-31b-it`), never the literal `gemma-4`
|
|
20
|
+
* that `inferLocalModelFamily` produces for an id the catalog does not match.
|
|
21
|
+
* Gating on the family therefore ran the filter only for Gemma ids the catalog
|
|
22
|
+
* did not know, so naming `gemma4-26b-moe` and `gemma4-31b-dense` in it (issue
|
|
23
|
+
* #263) turned the filter off for the two ids the router actually serves.
|
|
24
|
+
*/
|
|
25
|
+
export function usesGemmaChannelMarkers(modelId: string): boolean {
|
|
26
|
+
return inferLocalModelFamily(modelId) === "gemma-4";
|
|
27
|
+
}
|
|
9
28
|
|
|
10
29
|
const THOUGHT_START = /<\|channel>[^\n]*\n/;
|
|
11
30
|
const BARE_THOUGHT_START = /^\s*(?:thought|own[- ]?(?:thought|think))\s*\n/i;
|
package/src/engine/loop-guard.ts
CHANGED
|
@@ -87,9 +87,9 @@ export const LOOP_SYNTHESIS_BACKSTOP_DENIALS = 2;
|
|
|
87
87
|
export const WIDE_BATCH_DENIAL_FLOOR = 32;
|
|
88
88
|
|
|
89
89
|
/**
|
|
90
|
-
* Default lifetime tool-call cap for a worker run.
|
|
91
|
-
*
|
|
92
|
-
*
|
|
90
|
+
* Default lifetime tool-call cap for a worker run. The configurable value lives
|
|
91
|
+
* at `fleet.limits.toolCallsPerRun`; this default is re-exported for tests and
|
|
92
|
+
* callers that reason about the guard's tuning in one place.
|
|
93
93
|
*/
|
|
94
94
|
export const DEFAULT_WORKER_TOOL_CALL_CAP = GUARDRAIL_DEFAULTS.workerToolCallCap;
|
|
95
95
|
|
|
@@ -105,7 +105,7 @@ export const DEFAULT_WORKER_TOOL_CALL_CAP = GUARDRAIL_DEFAULTS.workerToolCallCap
|
|
|
105
105
|
* DISTINCT unproductive calls. Legitimate deep work (a repo-wide audit runs
|
|
106
106
|
* 25+ productive calls in one turn) must not be decapitated by it; mainstream
|
|
107
107
|
* harnesses run 100+ calls per turn with no ceiling at all. Value and env
|
|
108
|
-
*
|
|
108
|
+
* live at `safety.limits.chatToolCallsPerTurn`.
|
|
109
109
|
*/
|
|
110
110
|
export const DEFAULT_ORCH_TURN_TOOL_CALL_BUDGET = GUARDRAIL_DEFAULTS.turnToolCallBudget;
|
|
111
111
|
/**
|
|
@@ -185,6 +185,70 @@ function loopBlockBaseReason(tool: string, repeatCount: number, priorSuccesses:
|
|
|
185
185
|
);
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
+
/** True when a sanitized locked reply holds nothing but the fallback notice. */
|
|
189
|
+
export function isLockedSynthesisFallbackOnly(message: AgentMessage | undefined): boolean {
|
|
190
|
+
if (!message || typeof message !== "object" || (message as { role?: unknown }).role !== "assistant") return false;
|
|
191
|
+
const content = (message as { content?: unknown }).content;
|
|
192
|
+
if (!Array.isArray(content)) return false;
|
|
193
|
+
const text = content
|
|
194
|
+
.filter((block): block is { type: "text"; text: string } => block?.type === "text" && typeof block.text === "string")
|
|
195
|
+
.map((block) => block.text)
|
|
196
|
+
.join("")
|
|
197
|
+
.trim();
|
|
198
|
+
return text === lockedSynthesisFallbackText();
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export const LOCKED_SYNTHESIS_REPROMPT_TOOL = "clio_synthesis_reprompt";
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* One bounded re-prompt after a locked round came back as tool-call markup
|
|
205
|
+
* only. Delivered as a paired synthetic tool exchange, never a user turn, for
|
|
206
|
+
* the same reason the result-contract repair is (#55: a late user message
|
|
207
|
+
* re-renders every earlier assistant turn on templates keyed off the last
|
|
208
|
+
* user message and invalidates the whole prompt cache).
|
|
209
|
+
*/
|
|
210
|
+
export function lockedSynthesisRepromptMessages(
|
|
211
|
+
attempt: number,
|
|
212
|
+
origin: { provider: string; api: string; model: string },
|
|
213
|
+
): ReadonlyArray<AgentMessage> {
|
|
214
|
+
const id = `clio-synthesis-reprompt-${attempt}`;
|
|
215
|
+
const timestamp = Date.now();
|
|
216
|
+
return [
|
|
217
|
+
{
|
|
218
|
+
role: "assistant",
|
|
219
|
+
content: [{ type: "toolCall", id, name: LOCKED_SYNTHESIS_REPROMPT_TOOL, arguments: {} }],
|
|
220
|
+
stopReason: "toolUse",
|
|
221
|
+
usage: {
|
|
222
|
+
input: 0,
|
|
223
|
+
output: 0,
|
|
224
|
+
cacheRead: 0,
|
|
225
|
+
cacheWrite: 0,
|
|
226
|
+
totalTokens: 0,
|
|
227
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
228
|
+
},
|
|
229
|
+
...origin,
|
|
230
|
+
timestamp,
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
role: "toolResult",
|
|
234
|
+
toolCallId: id,
|
|
235
|
+
toolName: LOCKED_SYNTHESIS_REPROMPT_TOOL,
|
|
236
|
+
content: [
|
|
237
|
+
{
|
|
238
|
+
type: "text",
|
|
239
|
+
text:
|
|
240
|
+
"Your previous reply contained only tool-call markup, which cannot run: tool calls are disabled for " +
|
|
241
|
+
"the rest of this run. Everything you gathered is already in the conversation above. Write the " +
|
|
242
|
+
"final answer now as plain prose (or the exact result format the task asked for), with no tool-call " +
|
|
243
|
+
"markup of any kind.",
|
|
244
|
+
},
|
|
245
|
+
],
|
|
246
|
+
isError: true,
|
|
247
|
+
timestamp,
|
|
248
|
+
},
|
|
249
|
+
] as unknown as ReadonlyArray<AgentMessage>;
|
|
250
|
+
}
|
|
251
|
+
|
|
188
252
|
/**
|
|
189
253
|
* Directive returned when a turn is locked to synthesis: tool use is over, so
|
|
190
254
|
* the model must answer from what it already gathered. Fed back to the model as
|
|
@@ -360,8 +424,8 @@ export interface OrchTurnToolCallBudget {
|
|
|
360
424
|
hard: number;
|
|
361
425
|
}
|
|
362
426
|
|
|
363
|
-
export function readOrchTurnToolCallBudget(
|
|
364
|
-
const soft = resolveGuardrail("turnToolCallBudget"
|
|
427
|
+
export function readOrchTurnToolCallBudget(): OrchTurnToolCallBudget {
|
|
428
|
+
const soft = resolveGuardrail("turnToolCallBudget");
|
|
365
429
|
return { soft, hard: soft + ORCH_TURN_TOOL_CALL_HARD_MARGIN };
|
|
366
430
|
}
|
|
367
431
|
|
|
@@ -416,7 +480,7 @@ export interface CreateLoopGuardRegistrationOptions {
|
|
|
416
480
|
* the turn over the bus. Absent for workers, which rely on the lifetime
|
|
417
481
|
* {@link toolCallCap} instead.
|
|
418
482
|
*/
|
|
419
|
-
turnToolCallBudget?: OrchTurnToolCallBudget;
|
|
483
|
+
turnToolCallBudget?: OrchTurnToolCallBudget | (() => OrchTurnToolCallBudget);
|
|
420
484
|
/**
|
|
421
485
|
* When the per-turn loop-block budget is exhausted, lock tool use for the
|
|
422
486
|
* rest of the turn instead of cancelling it outright. Every further call is
|
|
@@ -467,7 +531,6 @@ export function createLoopGuardRegistration(options: CreateLoopGuardRegistration
|
|
|
467
531
|
(cap === undefined || options.toolCallSoftLimit <= cap)
|
|
468
532
|
? options.toolCallSoftLimit
|
|
469
533
|
: undefined;
|
|
470
|
-
const turnBudget = options.turnToolCallBudget;
|
|
471
534
|
const synthesisLockout = options.turnSynthesisLockout === true;
|
|
472
535
|
let softReadReserve = options.toolCallSoftReadReserve ?? 0;
|
|
473
536
|
let softReadReserveThreshold =
|
|
@@ -516,6 +579,12 @@ export function createLoopGuardRegistration(options: CreateLoopGuardRegistration
|
|
|
516
579
|
let reserveDirectiveEmitted = false;
|
|
517
580
|
const blocksByTurn = new Map<string, number>();
|
|
518
581
|
const callsByTurn = new Map<string, number>();
|
|
582
|
+
/**
|
|
583
|
+
* Per-turn count of successful write or edit calls. The identical-call key
|
|
584
|
+
* carries it, so a check rerun after a change (fix-verify) is a fresh call
|
|
585
|
+
* while a verbatim repeat with nothing changed in between still counts.
|
|
586
|
+
*/
|
|
587
|
+
const mutationEpochByTurn = new Map<string, number>();
|
|
519
588
|
/**
|
|
520
589
|
* Turns whose tool use is locked to synthesis after reaching the block
|
|
521
590
|
* budget. Key present means locked; the value carries the block that tripped
|
|
@@ -594,6 +663,9 @@ export function createLoopGuardRegistration(options: CreateLoopGuardRegistration
|
|
|
594
663
|
// (admission returns before execution), so only real results anchor.
|
|
595
664
|
const recordSuccessfulResult = (input: MiddlewareHookInput): void => {
|
|
596
665
|
if (input.metadata?.resultKind !== "ok") return;
|
|
666
|
+
if (input.toolName === ToolNames.Write || input.toolName === ToolNames.Edit) {
|
|
667
|
+
bumpBoundedCounter(mutationEpochByTurn, input.turnId ?? NO_TURN_BUCKET);
|
|
668
|
+
}
|
|
597
669
|
if (!resultCarriesEvidence(input.toolResultDetails)) return;
|
|
598
670
|
const tool = input.toolName;
|
|
599
671
|
if (typeof tool !== "string" || tool.length === 0) return;
|
|
@@ -748,11 +820,11 @@ export function createLoopGuardRegistration(options: CreateLoopGuardRegistration
|
|
|
748
820
|
|
|
749
821
|
const emitBudgetEvent = (
|
|
750
822
|
input: MiddlewareHookInput,
|
|
823
|
+
turnBudget: OrchTurnToolCallBudget,
|
|
751
824
|
callsThisTurn: number,
|
|
752
825
|
interrupted: boolean,
|
|
753
826
|
at: number,
|
|
754
827
|
): void => {
|
|
755
|
-
if (turnBudget === undefined) return;
|
|
756
828
|
const payload: ToolBudgetExceededPayload = {
|
|
757
829
|
tool: input.toolName ?? "unknown",
|
|
758
830
|
callsThisTurn,
|
|
@@ -766,6 +838,8 @@ export function createLoopGuardRegistration(options: CreateLoopGuardRegistration
|
|
|
766
838
|
};
|
|
767
839
|
|
|
768
840
|
const evaluateTurnBudget = (input: MiddlewareHookInput, now: number): ReadonlyArray<MiddlewareEffect> | null => {
|
|
841
|
+
const budgetSource = options.turnToolCallBudget;
|
|
842
|
+
const turnBudget = typeof budgetSource === "function" ? budgetSource() : budgetSource;
|
|
769
843
|
if (turnBudget === undefined) return null;
|
|
770
844
|
const turnKey = input.turnId ?? NO_TURN_BUCKET;
|
|
771
845
|
const callsThisTurn = bumpBoundedCounter(callsByTurn, turnKey);
|
|
@@ -773,7 +847,7 @@ export function createLoopGuardRegistration(options: CreateLoopGuardRegistration
|
|
|
773
847
|
// Hard ceiling: interrupt the turn the same way the block budget does.
|
|
774
848
|
// The bus event drives chat.cancel() in the interactive layer; the
|
|
775
849
|
// block effect makes the in-flight attempt fail with the same reason.
|
|
776
|
-
if (callsThisTurn === turnBudget.hard) emitBudgetEvent(input, callsThisTurn, true, now);
|
|
850
|
+
if (callsThisTurn === turnBudget.hard) emitBudgetEvent(input, turnBudget, callsThisTurn, true, now);
|
|
777
851
|
return [
|
|
778
852
|
{
|
|
779
853
|
kind: "block_tool",
|
|
@@ -792,7 +866,7 @@ export function createLoopGuardRegistration(options: CreateLoopGuardRegistration
|
|
|
792
866
|
// ever run. The operator sees one warn notice per turn (the first
|
|
793
867
|
// crossing); the model keeps getting the directive on every further
|
|
794
868
|
// over-budget attempt so it cannot quietly resume spraying calls.
|
|
795
|
-
if (callsThisTurn === turnBudget.soft) emitBudgetEvent(input, callsThisTurn, false, now);
|
|
869
|
+
if (callsThisTurn === turnBudget.soft) emitBudgetEvent(input, turnBudget, callsThisTurn, false, now);
|
|
796
870
|
return [
|
|
797
871
|
{
|
|
798
872
|
kind: "block_tool",
|
|
@@ -1084,7 +1158,13 @@ export function createLoopGuardRegistration(options: CreateLoopGuardRegistration
|
|
|
1084
1158
|
// regardless of age, so an unscoped key would let one identical call
|
|
1085
1159
|
// per user turn (rerunning a build across turns) accumulate into a
|
|
1086
1160
|
// false loop.
|
|
1087
|
-
|
|
1161
|
+
// The epoch scopes repeats to "since the last successful write or
|
|
1162
|
+
// edit": a live session repeated a batch of eleven read-only bash
|
|
1163
|
+
// calls five times, every one admitted, because the detector kept
|
|
1164
|
+
// only a 30 s window or the last four attempts and no batch ever
|
|
1165
|
+
// showed a third repeat inside either.
|
|
1166
|
+
const epoch = mutationEpochByTurn.get(turnKey) ?? 0;
|
|
1167
|
+
const verdict = options.safety.observeLoop(`${turnKey}|${epoch}|${fingerprint}`, now);
|
|
1088
1168
|
if (verdict.looping) {
|
|
1089
1169
|
const tool = input.toolName ?? "unknown";
|
|
1090
1170
|
const priorSuccesses = succeededFingerprints.get(fingerprint) ?? 0;
|
|
@@ -73,8 +73,10 @@ import { startClaudeSdkWorkerRun } from "./claude/sdk-runtime.js";
|
|
|
73
73
|
import { startClaudeCodeWorkerRun } from "./claude/subprocess-runtime.js";
|
|
74
74
|
import {
|
|
75
75
|
createLoopGuardRegistration,
|
|
76
|
+
isLockedSynthesisFallbackOnly,
|
|
76
77
|
isLoopGuardSynthesisBackstopReason,
|
|
77
78
|
lockedSynthesisFallbackText,
|
|
79
|
+
lockedSynthesisRepromptMessages,
|
|
78
80
|
resolveDeliveryTools,
|
|
79
81
|
sanitizeLockedSynthesisMessage,
|
|
80
82
|
workerLoopBlockBudget,
|
|
@@ -378,9 +380,8 @@ export function startWorkerRun(input: WorkerRunInput, emit: WorkerEventEmit): Wo
|
|
|
378
380
|
// already surfaced.
|
|
379
381
|
const workerSettings = validateSettingsFile().settings;
|
|
380
382
|
setGlobalDefaultMaxOutputTokens(workerSettings.chat.maxOutputTokens);
|
|
381
|
-
// Same mirroring for guardrail policy: the
|
|
382
|
-
//
|
|
383
|
-
// installed before any registry or tool construction reads it.
|
|
383
|
+
// Same mirroring for guardrail policy: the fresh process needs its settings
|
|
384
|
+
// projection installed before any registry or tool construction reads it.
|
|
384
385
|
configureGuardrails(guardrailValuesFromSettings(workerSettings));
|
|
385
386
|
const fauxModel = registerFauxFromEnv();
|
|
386
387
|
// Workers are bounded runs against an admission-verified recipe surface.
|
|
@@ -412,8 +413,10 @@ export function startWorkerRun(input: WorkerRunInput, emit: WorkerEventEmit): Wo
|
|
|
412
413
|
: {}),
|
|
413
414
|
});
|
|
414
415
|
// Flipped by the loop guard's lockout callback; read by onPayload below to
|
|
415
|
-
// force the remaining model rounds text-only
|
|
416
|
+
// force the remaining model rounds text-only by removing the tool surface
|
|
417
|
+
// (tool_choice none on Anthropic; see patchToolSurfaceLockedPayload).
|
|
416
418
|
let synthesisToolLock = false;
|
|
419
|
+
let lockedSynthesisReprompts = 0;
|
|
417
420
|
let workerBoundFailure: string | null = null;
|
|
418
421
|
let workerBoundAborted = false;
|
|
419
422
|
let abortWorkerForBound: (() => void) | null = null;
|
|
@@ -596,6 +599,7 @@ export function startWorkerRun(input: WorkerRunInput, emit: WorkerEventEmit): Wo
|
|
|
596
599
|
includeInteractiveTools: false,
|
|
597
600
|
invokeOptions: () => ({
|
|
598
601
|
correlationId: `worker-model-round-${workerModelRound}`,
|
|
602
|
+
toolResultMaxBytes: workerSettings.context.toolResultMaxBytes,
|
|
599
603
|
...(agentSkillPolicy ? { pendingSkillPolicy: agentSkillPolicy } : {}),
|
|
600
604
|
}),
|
|
601
605
|
});
|
|
@@ -661,13 +665,38 @@ export function startWorkerRun(input: WorkerRunInput, emit: WorkerEventEmit): Wo
|
|
|
661
665
|
pendingReadCitations.delete(event.toolCallId);
|
|
662
666
|
if (request !== undefined && event.isError !== true) recordObservedRead(request, event.result);
|
|
663
667
|
}
|
|
664
|
-
// Synthesis-locked run:
|
|
665
|
-
// chat template's tool-call syntax
|
|
666
|
-
//
|
|
667
|
-
// agent state, so the NDJSON
|
|
668
|
-
//
|
|
668
|
+
// Synthesis-locked run: the round ships no tool surface, so a model that
|
|
669
|
+
// calls a tool anyway lands its chat template's tool-call syntax in the
|
|
670
|
+
// reply as plain text. Sanitize the finished message in place before it
|
|
671
|
+
// hits stdout; pi stores this same object in agent state, so the NDJSON
|
|
672
|
+
// event, the dispatch consumer's answer reconstruction, and any later
|
|
673
|
+
// provider round all see the same text.
|
|
674
|
+
// A markup-only locked reply re-prompted this round; the result-contract
|
|
675
|
+
// check below stands aside so the round costs the one re-prompt, not one
|
|
676
|
+
// of the contract's bounded repair slots (on ornith both were queued for
|
|
677
|
+
// the same message and the run then ran out of repairs on a later
|
|
678
|
+
// grounding violation).
|
|
679
|
+
let repromptedThisMessage = false;
|
|
669
680
|
if (synthesisToolLock && event.type === "message_end") {
|
|
670
|
-
sanitizeLockedSynthesisMessage(event.message);
|
|
681
|
+
const stripped = sanitizeLockedSynthesisMessage(event.message);
|
|
682
|
+
// A model that calls a tool anyway hands its markup back as text and
|
|
683
|
+
// the sanitizer leaves only the fallback notice: the training habit
|
|
684
|
+
// survives the strip (Qwen3.8 did it in 1 of 5 stripped runs). One
|
|
685
|
+
// re-prompt, delivered as a tool exchange like the result-contract
|
|
686
|
+
// repair, asks for the answer in prose; a second markup-only reply
|
|
687
|
+
// keeps the notice.
|
|
688
|
+
if (stripped && lockedSynthesisReprompts < 1 && isLockedSynthesisFallbackOnly(event.message)) {
|
|
689
|
+
lockedSynthesisReprompts += 1;
|
|
690
|
+
repromptedThisMessage = true;
|
|
691
|
+
process.stderr.write("[worker] synthesis lock: reply was tool-call markup only; re-prompting once for prose\n");
|
|
692
|
+
for (const message of lockedSynthesisRepromptMessages(lockedSynthesisReprompts, {
|
|
693
|
+
provider: model.provider,
|
|
694
|
+
api: model.api,
|
|
695
|
+
model: model.id,
|
|
696
|
+
})) {
|
|
697
|
+
agent.followUp(message as unknown as AgentMessage);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
671
700
|
}
|
|
672
701
|
// Bounded terminal-contract repair, on whichever message ends the run.
|
|
673
702
|
// A worker that finishes inside its budget never trips the synthesis
|
|
@@ -676,7 +705,7 @@ export function startWorkerRun(input: WorkerRunInput, emit: WorkerEventEmit): Wo
|
|
|
676
705
|
// same contract against the sealed receipt; this is the only point at
|
|
677
706
|
// which the model can still act on the validator's reason.
|
|
678
707
|
const contract = input.resultContract;
|
|
679
|
-
if (contract && event.type === "message_end" && isTerminalAssistantMessage(event.message)) {
|
|
708
|
+
if (contract && !repromptedThisMessage && event.type === "message_end" && isTerminalAssistantMessage(event.message)) {
|
|
680
709
|
const violation = terminalContractViolation(
|
|
681
710
|
contract,
|
|
682
711
|
event.message,
|
|
@@ -155,8 +155,10 @@ export function createWorkerToolRegistry(
|
|
|
155
155
|
// The ledger tool registers unconditionally. attestedToolSignature signs the
|
|
156
156
|
// names a bare registry produces, so a conditional registration would drift
|
|
157
157
|
// the signature and fail admission; only the injected port varies, and a run
|
|
158
|
-
// without one answers that it has no coordination ledger.
|
|
158
|
+
// without one answers that it has no coordination ledger. The explicit flag
|
|
159
|
+
// is what keeps that true now that the session registry omits the tool.
|
|
159
160
|
const registration = registerCoreTools(registry, {
|
|
161
|
+
includeLedgerTools: true,
|
|
160
162
|
...(agentLedger ? { agentLedger } : {}),
|
|
161
163
|
// A worker cannot install a skill or reach the operator who could, so
|
|
162
164
|
// its skill listing carries installed (or bound) skills only; the
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ExtensionSnapshot } from "../domains/extensions/index.js";
|
|
2
|
+
import type { CapturedHookSourceSet } from "../domains/middleware/index.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Adapt an extension snapshot's captured hook declarations to the
|
|
6
|
+
* middleware-native captured source set. This is the only place the two
|
|
7
|
+
* domains' shapes meet; middleware never imports extension types.
|
|
8
|
+
*/
|
|
9
|
+
export function capturedHookSourcesFor(
|
|
10
|
+
snapshot: Pick<ExtensionSnapshot, "generation" | "hookSources">,
|
|
11
|
+
): CapturedHookSourceSet {
|
|
12
|
+
return {
|
|
13
|
+
generation: snapshot.generation,
|
|
14
|
+
sources: snapshot.hookSources.map((source) => ({
|
|
15
|
+
provenance: {
|
|
16
|
+
id: source.provenance.id,
|
|
17
|
+
scope: source.provenance.scope,
|
|
18
|
+
...(source.provenance.sourcePath !== undefined ? { sourcePath: source.provenance.sourcePath } : {}),
|
|
19
|
+
canonicalRoot: source.provenance.canonicalRoot,
|
|
20
|
+
manifestDigest: source.provenance.manifestDigest,
|
|
21
|
+
contentDigest: source.provenance.contentDigest,
|
|
22
|
+
},
|
|
23
|
+
declarationsDigest: source.declarationsDigest,
|
|
24
|
+
declarations: source.declarations,
|
|
25
|
+
...(source.parseError !== undefined ? { parseError: source.parseError } : {}),
|
|
26
|
+
})),
|
|
27
|
+
};
|
|
28
|
+
}
|