@iowarp/clio-coder 0.3.4 → 0.3.7
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 +65 -2
- package/CONTRIBUTING.md +6 -6
- package/README.md +16 -5
- package/dist/{acp-S5R4RR5B.js → acp-SK4MD6MM.js} +11 -11
- package/dist/{agents-P6DMMVZY.js → agents-2FN2K6ME.js} +33 -26
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-2XCZLPKS.js → auth-QIYZWM5I.js} +15 -15
- package/dist/{chunk-EKMEHE4H.js → chunk-33YXPOE3.js} +2 -3
- package/dist/{chunk-VAWWTKDP.js → chunk-3HAPLH5M.js} +11 -11
- package/dist/{chunk-YCWGATWI.js → chunk-465YSENW.js} +3 -3
- package/dist/{chunk-4OC57DA6.js → chunk-4DGYLA73.js} +53 -2
- package/dist/{chunk-UZHIZC5S.js → chunk-4DWFMQDR.js} +61 -76
- package/dist/{chunk-ZWMF7253.js → chunk-5C3AQNDW.js} +328 -9
- package/dist/{chunk-22NAGB7X.js → chunk-5C77SEEY.js} +5 -94
- package/dist/{chunk-WPQLXFOZ.js → chunk-5FR74PWO.js} +3 -2
- package/dist/{chunk-35MKKU5R.js → chunk-5UJ6ECTS.js} +18 -10
- package/dist/{chunk-BRXQQJFP.js → chunk-6M7VS3J3.js} +571 -50
- package/dist/{chunk-QQK64KLB.js → chunk-6TUKSZVF.js} +141 -23
- package/dist/{chunk-N4CZJQRK.js → chunk-AB4XIIVB.js} +8 -6
- package/dist/{chunk-KRPY7NTG.js → chunk-BMWK7ZIZ.js} +14 -20
- package/dist/{chunk-4BPJXDWC.js → chunk-C4JBQ5SR.js} +30 -14
- package/dist/{chunk-ZYKPLLNQ.js → chunk-CEYBNUGC.js} +821 -83
- package/dist/{chunk-VEZEGCGW.js → chunk-D4MDIG46.js} +20 -18
- package/dist/chunk-DJNLUABN.js +843 -0
- package/dist/{chunk-BP4OYD6A.js → chunk-DMD2AGVS.js} +21 -2
- package/dist/{chunk-KOHPCX4K.js → chunk-DOOEX22V.js} +2 -2
- package/dist/chunk-DQA7QLMD.js +123 -0
- package/dist/chunk-DR52UMZW.js +21 -0
- package/dist/{chunk-3HZ5RWN2.js → chunk-EBEFWSGL.js} +9 -7
- package/dist/{chunk-EDRHSCIE.js → chunk-EELBMBT6.js} +128 -13
- package/dist/{chunk-HV5X7OR2.js → chunk-EOOQZZDE.js} +16 -14
- package/dist/{chunk-WR67VIZY.js → chunk-FOT2FX5J.js} +63 -5
- package/dist/{chunk-BPGS2WCQ.js → chunk-GEYXPTRF.js} +2 -1
- package/dist/{chunk-FYYLNIL5.js → chunk-GH5622CP.js} +2 -2
- package/dist/{chunk-BEY543CS.js → chunk-GOXNB3AO.js} +5 -2
- package/dist/chunk-GWS3VEIW.js +195 -0
- package/dist/{chunk-G4BMMOKF.js → chunk-HVDIIIQW.js} +2 -2
- package/dist/chunk-HWUFFB6L.js +83 -0
- package/dist/{chunk-X6COSD2O.js → chunk-J7PIKKWC.js} +8 -436
- package/dist/{chunk-NILBFAPG.js → chunk-JNXPYBB4.js} +2 -2
- package/dist/{chunk-4VP4KH3K.js → chunk-JRIO5UD2.js} +4 -4
- package/dist/{chunk-K6WL7QZT.js → chunk-JTSEDYVQ.js} +7 -7
- package/dist/{chunk-QKMUKYO7.js → chunk-KCMKRQX4.js} +236 -84
- package/dist/chunk-KZ2H5X4G.js +1026 -0
- package/dist/{chunk-A2GZF7DC.js → chunk-LADCF22A.js} +13 -13
- package/dist/chunk-LCGCVYZ4.js +57 -0
- package/dist/chunk-M4AKACEO.js +382 -0
- package/dist/{chunk-POHLU5DW.js → chunk-M6L6IDJG.js} +3 -3
- package/dist/{chunk-4JUF2NNX.js → chunk-MXI6J5JF.js} +7 -7
- package/dist/{chunk-X4RCMKVQ.js → chunk-NDINPTJ4.js} +2 -2
- package/dist/{chunk-TTNYS3EA.js → chunk-OB5HIGJY.js} +1 -1
- package/dist/{chunk-7RXG6QRZ.js → chunk-OBMAI2DP.js} +61 -840
- package/dist/{chunk-5M54SPOL.js → chunk-ODFEOB4F.js} +161 -5
- package/dist/chunk-PD3MESLB.js +242 -0
- package/dist/{chunk-ED4KHGC3.js → chunk-PPAMZ32Z.js} +9 -2
- package/dist/{chunk-VMNQ6OZA.js → chunk-QCTRSGHQ.js} +963 -786
- package/dist/chunk-RVG5JXAL.js +41 -0
- package/dist/{chunk-RD5U66HV.js → chunk-SROCI7ZU.js} +7 -7
- package/dist/{chunk-MFFY33HR.js → chunk-THKY7CD7.js} +466 -205
- package/dist/{chunk-34475P3I.js → chunk-TSHXZTOQ.js} +5 -4
- package/dist/{chunk-PCZJO5TI.js → chunk-UFQ3F4FW.js} +13 -178
- package/dist/{chunk-AD2SYQYC.js → chunk-UHXRNZ2J.js} +121 -3
- package/dist/chunk-UND3GU2L.js +103 -0
- package/dist/{chunk-QQL5RT5M.js → chunk-UUANF5CR.js} +2323 -2114
- package/dist/{chunk-VJWL6YS5.js → chunk-UUVG37B4.js} +2 -2
- package/dist/chunk-UVDSQ6LW.js +472 -0
- package/dist/{chunk-QWU7ZBO7.js → chunk-VQNODYQ4.js} +215 -56
- package/dist/chunk-VREKEFLL.js +37 -0
- package/dist/{chunk-2TZWSW76.js → chunk-WHGPSPT5.js} +2 -2
- package/dist/{chunk-TW3WDMVS.js → chunk-WHJYKASB.js} +2 -2
- package/dist/{chunk-MEQ45TQ4.js → chunk-WJHBC77E.js} +21 -7
- package/dist/{chunk-HXG4IURW.js → chunk-X2KV5FXT.js} +2 -2
- package/dist/{chunk-YHZX5GEU.js → chunk-XAKHZX5N.js} +2 -2
- package/dist/{chunk-2LZI5CAG.js → chunk-XEGB6BCN.js} +228 -36
- package/dist/{chunk-E25LMLRW.js → chunk-YD734TPH.js} +2 -2
- package/dist/{verifiers-4UUM6TEE.js → chunk-YTYFXUI3.js} +121 -372
- package/dist/{chunk-3JLKSKD7.js → chunk-ZGH7FGS5.js} +17 -7
- package/dist/{chunk-VSNATDE6.js → chunk-ZZMN5OM4.js} +2 -2
- package/dist/cli/index.js +34 -32
- package/dist/{clio-J5JIOIDS.js → clio-WBVQEBKO.js} +7 -7
- package/dist/{code-nav-AXCXSBHX.js → code-nav-FGGFIE7L.js} +7 -7
- package/dist/codewiki/build-worker.js +4 -4
- package/dist/{components-KELWS457.js → components-F7OEATSO.js} +5 -5
- package/dist/{config-OEBMIN2U.js → config-TRBL3RCF.js} +48 -41
- package/dist/{configure-PUQOSIXQ.js → configure-OLCVPHNM.js} +17 -17
- package/dist/{context-URSXPBCK.js → context-MJIJ6GOX.js} +12 -12
- package/dist/{context-EKDCKUUZ.js → context-WFPKQSM6.js} +26 -9
- package/dist/{context-MGSE4Z2T.js → context-XEWE3MOJ.js} +44 -37
- package/dist/{context-clear-KDAJRNUK.js → context-clear-KNOS2JPB.js} +44 -37
- package/dist/{context-index-BZ4UYMTC.js → context-index-SSR5ECNE.js} +3 -3
- package/dist/{context-working-set-SBKMPPI2.js → context-working-set-EUXAZI6N.js} +14 -13
- package/dist/{dispatch-runner-MSWN72NK.js → dispatch-runner-B7MTOVKL.js} +321 -60
- package/dist/{docs-2C2LTVT2.js → docs-FLJTIDSE.js} +5 -5
- package/dist/{doctor-7BSE27PJ.js → doctor-RN4YKO2X.js} +15 -15
- package/dist/{eval-IZGDOO4H.js → eval-RUBJVSNQ.js} +52 -236
- package/dist/{evidence-SR7WXB5B.js → evidence-JZNBUOQZ.js} +39 -33
- package/dist/{evolve-K7VE2CBX.js → evolve-FJVC4KKI.js} +39 -33
- package/dist/{extensions-QVDOHDGJ.js → extensions-IQL36S7K.js} +5 -5
- package/dist/{fleet-7XMJNQNF.js → fleet-BDKYJFCP.js} +243 -370
- package/dist/fleet-commands-ZFIWZSB3.js +70 -0
- package/dist/fleet-graph-Y6HPXIVF.js +125 -0
- package/dist/fleet-new-RDVJLHHH.js +48 -0
- package/dist/{fleet-preflight-AQNAH644.js → fleet-preflight-BHSNPBMH.js} +2 -2
- package/dist/fleet-validate-BIYREGIK.js +79 -0
- package/dist/{init-JGNPAYXT.js → init-LQUB5COQ.js} +57 -48
- package/dist/library-NJAHIGG4.js +217 -0
- package/dist/memory-OG6HOYKM.js +472 -0
- package/dist/{models-ZMMLFJNN.js → models-5ZG5XY7J.js} +23 -22
- package/dist/{monitor-2F3T5KHP.js → monitor-TJ7AMTGB.js} +69 -35
- package/dist/{orchestrator-ORHT43JB.js → orchestrator-WZYB54DM.js} +4868 -1189
- package/dist/{paths-UXLN5YYZ.js → paths-XUC7GS6E.js} +5 -5
- package/dist/{reset-NXGTYNUO.js → reset-PXQT45IY.js} +8 -8
- package/dist/{run-RF4WJGMT.js → run-FQ74YF62.js} +82 -62
- package/dist/{share-UT3W6E4M.js → share-FW7SVCL3.js} +34 -10
- package/dist/{skills-PSACKC5Q.js → skills-7E7IRB3R.js} +25 -9
- package/dist/{skills-eval-WJSI55RZ.js → skills-eval-LI75W6OK.js} +43 -35
- package/dist/{targets-PIIRAOYS.js → targets-4CIFKCTW.js} +27 -24
- package/dist/{terminal-lease-ULWXWNVY.js → terminal-lease-WUZY7ZV5.js} +5 -4
- package/dist/{uninstall-FZCQCDKC.js → uninstall-7FV7IP4E.js} +5 -5
- package/dist/{upgrade-346TZ6AV.js → upgrade-K2HVIVMQ.js} +21 -20
- package/dist/{usage-6KKXR32N.js → usage-GTZELZQX.js} +159 -59
- package/dist/verifiers-RLAHT27O.js +336 -0
- package/dist/{verify-X5HDROLA.js → verify-BX3BRKH5.js} +7 -6
- package/dist/{wiki-generate-7STOCIFZ.js → wiki-generate-ASIFASCN.js} +58 -48
- package/dist/worker/entry.js +98 -84
- package/dist/{workspace-G4ZWUIPR.js → workspace-ZJ6BFM3Q.js} +4 -4
- package/docs/README.md +4 -3
- package/docs/acp.md +1 -1
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +2 -2
- package/docs/artifact-placement.md +1 -2
- package/docs/artifact-versions.md +10 -6
- package/docs/built-in-agents.md +26 -2
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +90 -8
- package/docs/configuration-and-targets.md +90 -2
- package/docs/context-engine.md +4 -2
- package/docs/context-working-set.md +4 -4
- package/docs/development-pipeline.md +1 -1
- package/docs/dispatch-architecture-rationale.md +1 -1
- package/docs/documentation-coverage.md +4 -4
- package/docs/documentation-guide.md +4 -4
- package/docs/eval-runner.md +1 -1
- package/docs/evals-internal.md +4 -45
- package/docs/evidence-and-memory.md +70 -10
- package/docs/evolution.md +1 -1
- package/docs/exit-codes-and-output.md +4 -1
- package/docs/extensions-and-sharing.md +6 -2
- package/docs/fleet-demo-runbook.md +2 -2
- package/docs/fleet-dispatch.md +224 -11
- package/docs/git-commit-provenance.md +2 -2
- package/docs/glossary.md +1 -1
- package/docs/installation-and-lifecycle.md +2 -2
- package/docs/middleware-and-components.md +20 -2
- package/docs/model-catalog.md +1 -1
- package/docs/observability.md +55 -8
- package/docs/proactive-memory.md +26 -16
- package/docs/prompt-envelope-and-tools.md +4 -2
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/release-cut-checklist.md +83 -65
- package/docs/resource-library.md +59 -0
- package/docs/safety-model.md +29 -7
- package/docs/scientific-validation.md +3 -3
- package/docs/session-lifecycle.md +37 -1
- package/docs/skills-marketplace.md +16 -3
- package/docs/tool-usage.md +14 -7
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +1 -1
- package/docs/tui-design.md +38 -4
- package/docs/worker-dispatch-mechanics.md +3 -3
- package/package.json +7 -4
- package/src/cli/agents.ts +2 -3
- package/src/cli/argv.ts +14 -1
- package/src/cli/fleet-commands.ts +37 -0
- package/src/cli/fleet-graph.ts +102 -0
- package/src/cli/fleet-new.ts +36 -0
- package/src/cli/fleet-preflight.ts +121 -0
- package/src/cli/fleet-validate.ts +30 -0
- package/src/cli/fleet.ts +188 -335
- package/src/cli/index.ts +4 -2
- package/src/cli/library.ts +190 -0
- package/src/cli/memory.ts +272 -10
- package/src/cli/modes/json-stream.ts +2 -2
- package/src/cli/modes/print.ts +12 -1
- package/src/cli/run.ts +22 -2
- package/src/cli/share.ts +13 -1
- package/src/cli/targets.ts +12 -3
- package/src/cli/usage.ts +160 -20
- package/src/core/bus-events.ts +7 -0
- package/src/core/commit-attribution.ts +4 -4
- package/src/core/config.ts +130 -0
- package/src/core/defaults.ts +81 -0
- package/src/core/response-model-id.ts +134 -0
- package/src/core/toml.ts +62 -0
- package/src/core/workspace-files.ts +0 -1
- package/src/domains/agents/builtins/architect.md +2 -1
- package/src/domains/agents/builtins/oracle.md +33 -0
- package/src/domains/agents/catalog.ts +18 -5
- package/src/domains/agents/fleet-contract.ts +278 -16
- package/src/domains/agents/index.ts +14 -0
- package/src/domains/agents/recipe.ts +54 -14
- package/src/domains/agents/result-contract.ts +242 -5
- package/src/domains/config/classify.ts +4 -0
- package/src/domains/context/bootstrap.ts +36 -27
- package/src/domains/context/project-metadata.ts +19 -63
- package/src/domains/context/prompt-context.ts +8 -0
- package/src/domains/context/working-set/policies/index.ts +3 -4
- package/src/domains/dispatch/active-route-planner.ts +14 -0
- package/src/domains/dispatch/backoff.ts +2 -1
- package/src/domains/dispatch/budget-envelope.ts +396 -0
- package/src/domains/dispatch/capability-match.ts +1 -0
- package/src/domains/dispatch/checkout-writer-lease.ts +175 -0
- package/src/domains/dispatch/contract.ts +36 -0
- package/src/domains/dispatch/delegation-plan.ts +167 -0
- package/src/domains/dispatch/execution-plan.ts +76 -5
- package/src/domains/dispatch/execution-role.ts +3 -1
- package/src/domains/dispatch/execution-scheduler.ts +183 -67
- package/src/domains/dispatch/extension.ts +339 -36
- package/src/domains/dispatch/fleet-gate.ts +14 -0
- package/src/domains/dispatch/fleet-plan.ts +63 -3
- package/src/domains/dispatch/fleet-run.ts +737 -0
- package/src/domains/dispatch/gate-role-prompts.ts +9 -0
- package/src/domains/dispatch/host-verification.ts +178 -0
- package/src/domains/dispatch/index.ts +38 -0
- package/src/domains/dispatch/intent.ts +159 -0
- package/src/domains/dispatch/orphan-recovery.ts +1 -0
- package/src/domains/dispatch/receipt-integrity.ts +12 -4
- package/src/domains/dispatch/state.ts +37 -3
- package/src/domains/dispatch/types.ts +61 -9
- package/src/domains/dispatch/validation.ts +80 -6
- package/src/domains/dispatch/worker-spawn.ts +14 -3
- package/src/domains/eval/metrics/evidence.ts +0 -116
- package/src/domains/eval/metrics/invariants.ts +1 -1
- package/src/domains/eval/runners/clio-run.ts +1 -10
- package/src/domains/eval/runners/external-command.ts +2 -29
- package/src/domains/eval/schema/suite.ts +0 -7
- package/src/domains/eval/suites/run.ts +1 -7
- package/src/domains/evidence/trust-status.ts +10 -1
- package/src/domains/memory/index.ts +22 -0
- package/src/domains/memory/operations.ts +58 -1
- package/src/domains/memory/promotion.ts +281 -0
- package/src/domains/memory/prompt-section.ts +25 -5
- package/src/domains/memory/proposal.ts +51 -7
- package/src/domains/memory/task-bank.ts +3 -2
- package/src/domains/memory/task-memory-handoff.ts +181 -24
- package/src/domains/memory/task-memory-policy.ts +3 -1
- package/src/domains/memory/types.ts +37 -0
- package/src/domains/memory/validate.ts +178 -0
- package/src/domains/middleware/index.ts +15 -0
- package/src/domains/middleware/memory-intervention.ts +35 -25
- package/src/domains/middleware/runtime.ts +6 -0
- package/src/domains/middleware/skills-reminder.ts +19 -4
- package/src/domains/middleware/stalled-turn.ts +43 -1
- package/src/domains/middleware/types.ts +10 -0
- package/src/domains/middleware/watchdog.ts +281 -0
- package/src/domains/observability/contract.ts +9 -2
- package/src/domains/observability/cost.ts +31 -4
- package/src/domains/observability/extension.ts +2 -2
- package/src/domains/observability/index.ts +10 -0
- package/src/domains/observability/out-of-turn-usage.ts +223 -0
- package/src/domains/providers/index.ts +3 -0
- package/src/domains/providers/model-discovery.ts +9 -0
- package/src/domains/providers/runtime-resolution.ts +38 -1
- package/src/domains/providers/runtimes/common/probe-helpers.ts +97 -16
- package/src/domains/providers/types/context-window-slots.ts +18 -0
- package/src/domains/providers/types/runtime-descriptor.ts +3 -1
- package/src/domains/resources/index.ts +20 -0
- package/src/domains/resources/library.ts +326 -0
- package/src/domains/resources/skills/marketplace.ts +37 -12
- package/src/domains/safety/call-target.ts +211 -14
- package/src/domains/safety/decision-presentation.ts +268 -0
- package/src/domains/safety/redaction.ts +73 -0
- package/src/domains/session/context-ledger.ts +10 -1
- package/src/domains/session/decision-board.ts +4 -0
- package/src/domains/session/entries.ts +3 -0
- package/src/domains/session/handoff.ts +629 -0
- package/src/domains/session/history.ts +68 -19
- package/src/domains/session/usage.ts +24 -7
- package/src/domains/share/archive.ts +67 -2
- package/src/engine/acp/event-mapper.ts +7 -0
- package/src/engine/acp/server.ts +29 -2
- package/src/engine/apis/lmstudio.ts +25 -4
- package/src/engine/apis/openai-completions.ts +147 -22
- package/src/engine/claude/sdk-runtime.ts +8 -2
- package/src/engine/claude/tool-safety.ts +13 -0
- package/src/engine/loop-guard.ts +27 -3
- package/src/engine/worker-events.ts +4 -3
- package/src/engine/worker-runtime.ts +59 -54
- package/src/entry/orchestrator.ts +55 -1
- package/src/interactive/bus-notices.ts +26 -0
- package/src/interactive/chat-loop-messages.ts +22 -0
- package/src/interactive/chat-loop.ts +248 -1
- package/src/interactive/chat-renderer.ts +41 -3
- package/src/interactive/clio-editor.ts +44 -7
- package/src/interactive/context-overlay.ts +43 -5
- package/src/interactive/cost-overlay.ts +70 -11
- package/src/interactive/council-dispatch.ts +30 -0
- package/src/interactive/council-grid.ts +213 -0
- package/src/interactive/council.ts +99 -0
- package/src/interactive/dispatch-board.ts +471 -50
- package/src/interactive/fleet-run-preview.ts +307 -0
- package/src/interactive/footer/notifications.ts +219 -0
- package/src/interactive/footer/widgets.ts +13 -0
- package/src/interactive/handoff-round.ts +56 -0
- package/src/interactive/interactive-application.ts +49 -2
- package/src/interactive/interactive-event-projection.ts +9 -1
- package/src/interactive/interactive-input-runtime.ts +11 -1
- package/src/interactive/interactive-presentation.ts +11 -1
- package/src/interactive/interactive-slash-runtime.ts +52 -2
- package/src/interactive/interactive-subscriptions.ts +14 -2
- package/src/interactive/memory-overlay.ts +89 -4
- package/src/interactive/oracle.ts +179 -0
- package/src/interactive/overlay-ask-user-lifecycle.ts +7 -1
- package/src/interactive/overlay-frame.ts +5 -2
- package/src/interactive/overlay-general-openers.ts +230 -2
- package/src/interactive/overlay-key-routing.ts +58 -2
- package/src/interactive/overlay-lifecycle.ts +52 -5
- package/src/interactive/overlay-permission-lifecycle.ts +33 -8
- package/src/interactive/overlay-resource-openers.ts +11 -3
- package/src/interactive/overlay-session-lifecycle.ts +234 -2
- package/src/interactive/overlay-transitions.ts +11 -0
- package/src/interactive/overlays/ask-user.ts +74 -30
- package/src/interactive/overlays/decisions.ts +3 -1
- package/src/interactive/overlays/fleet-run-approval.ts +208 -0
- package/src/interactive/overlays/handoff-review.ts +185 -0
- package/src/interactive/overlays/library-install-confirm.ts +151 -0
- package/src/interactive/overlays/list-overlay.ts +168 -2
- package/src/interactive/overlays/settings.ts +101 -4
- package/src/interactive/overlays/side-question.ts +139 -0
- package/src/interactive/overlays/skills-hub.ts +401 -15
- package/src/interactive/permission-hint.ts +35 -0
- package/src/interactive/permission-overlay.ts +95 -45
- package/src/interactive/renderers/tool-execution.ts +19 -49
- package/src/interactive/session-last-turn.ts +8 -1
- package/src/interactive/session-usage-reseed.ts +36 -10
- package/src/interactive/side-question.ts +171 -0
- package/src/interactive/slash-commands.ts +434 -7
- package/src/interactive/slash-spec.ts +19 -6
- package/src/interactive/status/summary.ts +5 -0
- package/src/interactive/status/types.ts +5 -0
- package/src/interactive/terminal-lease.ts +1 -0
- package/src/interactive/theme/tokens.ts +30 -0
- package/src/interactive/turn-context.ts +96 -23
- package/src/interactive/turn-middleware.ts +16 -1
- package/src/interactive/turn-runtime.ts +37 -8
- package/src/interactive/turn-state.ts +3 -0
- package/src/interactive/watchdog-run.ts +75 -0
- package/src/interactive/worker-progress.ts +440 -0
- package/src/interactive/worker-share.ts +56 -1
- package/src/interactive/worker-stream.ts +58 -110
- package/src/tools/agent-tools.ts +28 -3
- package/src/tools/ask-user.ts +21 -1
- package/src/tools/bootstrap.ts +3 -0
- package/src/tools/compete-worktrees.ts +13 -79
- package/src/tools/context/index.ts +2 -2
- package/src/tools/dispatch-admission.ts +242 -8
- package/src/tools/dispatch-arguments.ts +65 -1
- package/src/tools/dispatch-event-text.ts +19 -0
- package/src/tools/dispatch-plan.ts +136 -6
- package/src/tools/dispatch-runner.ts +319 -13
- package/src/tools/dispatch-types.ts +20 -1
- package/src/tools/dispatch.ts +96 -3
- package/src/tools/monitor.ts +31 -0
- package/src/tools/profiles.ts +18 -4
- package/src/tools/registry.ts +15 -5
- package/src/tools/result-disposition.ts +156 -0
- package/src/tools/result-shaping.ts +59 -1
- package/src/tools/task-worktree.ts +238 -0
- package/src/tools/verify/authoring.ts +116 -55
- package/src/tools/verify/scripts.ts +62 -0
- package/src/tools/worker-evidence.ts +21 -1
- package/src/worker/spec-contract.ts +44 -3
- package/dist/chunk-EFADSJET.js +0 -18
- package/dist/chunk-HC4CLZ2Y.js +0 -68
- package/dist/memory-4ALKDJ4Q.js +0 -246
- package/src/domains/eval/metrics/chaos-stream.ts +0 -93
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { BusChannels } from "../core/bus-events.js";
|
|
2
2
|
import { THINKING_LEVELS } from "../core/defaults.js";
|
|
3
3
|
import type { SafeEventBus } from "../core/event-bus.js";
|
|
4
|
+
import { parseCouncilReport, parseOracleResult } from "../domains/agents/index.js";
|
|
4
5
|
import type { AgentSpec } from "../domains/agents/spec.js";
|
|
5
6
|
import type { ContextInitOptions } from "../domains/context/init-options.js";
|
|
6
7
|
import type { DispatchContract, DispatchRequest } from "../domains/dispatch/contract.js";
|
|
@@ -12,16 +13,46 @@ import type { InstalledExtension } from "../domains/extensions/index.js";
|
|
|
12
13
|
import type { InteropAgentId, InteropProposal, InteropReport } from "../domains/interop/index.js";
|
|
13
14
|
import type { ProvidersContract, ResolvedModelRef } from "../domains/providers/index.js";
|
|
14
15
|
import { resolveModelReference } from "../domains/providers/index.js";
|
|
15
|
-
import type {
|
|
16
|
+
import type {
|
|
17
|
+
LibraryEntryKind,
|
|
18
|
+
PromptTemplate,
|
|
19
|
+
PromptTemplateExpansion,
|
|
20
|
+
ResourceList,
|
|
21
|
+
} from "../domains/resources/index.js";
|
|
16
22
|
import { parseSkillCommand } from "../domains/resources/index.js";
|
|
17
23
|
import type { ShareImportPlan } from "../domains/share/index.js";
|
|
18
24
|
import type { UserTask } from "../domains/user-tasks/store.js";
|
|
19
25
|
import { isToolProfileName, TOOL_PROFILE_NAMES, type ToolProfileName } from "../tools/profiles.js";
|
|
20
26
|
import type { NoticeLevel } from "./command-output.js";
|
|
27
|
+
import {
|
|
28
|
+
buildCouncilDispatchArgs,
|
|
29
|
+
COUNCIL_MAX_ROUNDS,
|
|
30
|
+
COUNCIL_SYNTHESIS_MODES,
|
|
31
|
+
type CouncilCommandOptions,
|
|
32
|
+
type CouncilRosters,
|
|
33
|
+
isCouncilSynthesisMode,
|
|
34
|
+
resolveCouncilRoster,
|
|
35
|
+
} from "./council.js";
|
|
36
|
+
import { COUNCIL_SYNTHESIS_LABEL } from "./council-grid.js";
|
|
37
|
+
import {
|
|
38
|
+
formatOracleAnswer,
|
|
39
|
+
ORACLE_AGENT_ID,
|
|
40
|
+
ORACLE_TASK,
|
|
41
|
+
type OracleDigestSources,
|
|
42
|
+
packOracleDigest,
|
|
43
|
+
} from "./oracle.js";
|
|
21
44
|
import { SETTINGS_SECTIONS, type SettingsCenterRowId, type SettingsSectionId } from "./overlays/settings.js";
|
|
45
|
+
import { isLibraryTab, LIBRARY_TABS } from "./overlays/skills-hub.js";
|
|
22
46
|
import type { CommandArgsSpec, CommandPositionalSpec, ParsedArgs } from "./slash-spec.js";
|
|
23
47
|
import { matchFromSpec, usageLine } from "./slash-spec.js";
|
|
24
|
-
import {
|
|
48
|
+
import {
|
|
49
|
+
formatCouncilMemberShareNote,
|
|
50
|
+
formatCouncilShareNote,
|
|
51
|
+
formatWorkerShareNote,
|
|
52
|
+
selectWorkerRunToShare,
|
|
53
|
+
type WorkerShareFacts,
|
|
54
|
+
workerShareFactsFromEntry,
|
|
55
|
+
} from "./worker-share.js";
|
|
25
56
|
import type { WorkerEntryState } from "./worker-stream.js";
|
|
26
57
|
|
|
27
58
|
/**
|
|
@@ -47,6 +78,7 @@ type SlashCommandVariant =
|
|
|
47
78
|
/** `ref` is the turnId an `[evicted ...]` marker names. */
|
|
48
79
|
| { kind: "context-recall"; ref: string }
|
|
49
80
|
| { kind: "skill-selector" }
|
|
81
|
+
| { kind: "library"; tab?: LibraryEntryKind }
|
|
50
82
|
| { kind: "skill-invocation"; text: string }
|
|
51
83
|
| { kind: "prompts" }
|
|
52
84
|
| { kind: "extensions" }
|
|
@@ -57,6 +89,19 @@ type SlashCommandVariant =
|
|
|
57
89
|
| { kind: "run-usage" }
|
|
58
90
|
| { kind: "delegate"; agentId: string; task: string; source: string; share?: boolean }
|
|
59
91
|
| { kind: "delegate-usage" }
|
|
92
|
+
| { kind: "btw"; question: string }
|
|
93
|
+
| { kind: "btw-usage" }
|
|
94
|
+
/** `/oracle <question>`: one read-only advisory run briefed on the record, never on the transcript. */
|
|
95
|
+
| { kind: "oracle"; question: string }
|
|
96
|
+
| { kind: "oracle-usage" }
|
|
97
|
+
/** `/council <task>`: one read-only council of roster members, dispatched through the dispatch tool. */
|
|
98
|
+
| { kind: "council"; task: string; options: CouncilCommandOptions }
|
|
99
|
+
| { kind: "council-usage"; reason?: string }
|
|
100
|
+
| { kind: "handoff"; goal: string }
|
|
101
|
+
| { kind: "handoff-usage" }
|
|
102
|
+
/** `/fleet run <name>`: compile the plan, show it for approval, dispatch on accept. */
|
|
103
|
+
| { kind: "fleet-run"; name: string; vars: Record<string, string> }
|
|
104
|
+
| { kind: "fleet-run-usage"; reason?: string }
|
|
60
105
|
| { kind: "agents" }
|
|
61
106
|
| { kind: "cost" }
|
|
62
107
|
| { kind: "context-view" }
|
|
@@ -109,6 +154,16 @@ export type SetOutputVerbosityResult =
|
|
|
109
154
|
| { status: "unsupported"; verbosity: string; supported: ReadonlyArray<string> }
|
|
110
155
|
| { status: "unavailable" };
|
|
111
156
|
|
|
157
|
+
/**
|
|
158
|
+
* What one admitted dispatch-tool call reports back to `/council`. The council
|
|
159
|
+
* itself is watched on the board and in the transcript, so success is silent;
|
|
160
|
+
* only a refusal or a failure is worth a notice.
|
|
161
|
+
*/
|
|
162
|
+
export type CouncilDispatchOutcome =
|
|
163
|
+
| { status: "ok" }
|
|
164
|
+
| { status: "blocked"; reason: string }
|
|
165
|
+
| { status: "error"; message: string };
|
|
166
|
+
|
|
112
167
|
export type TaskMemorySeedCommandResult =
|
|
113
168
|
| { status: "seeded"; seeded: number; skipped: number; source: string }
|
|
114
169
|
| { status: "disabled" }
|
|
@@ -276,6 +331,136 @@ async function handleDelegate(
|
|
|
276
331
|
);
|
|
277
332
|
}
|
|
278
333
|
|
|
334
|
+
/**
|
|
335
|
+
* `/oracle <question>`: one advisory run, dispatched like any other.
|
|
336
|
+
*
|
|
337
|
+
* Nothing here is a side channel. The run goes through the ordinary dispatch
|
|
338
|
+
* path, so admission, the receipt, and the Fleet Runs island treat it exactly
|
|
339
|
+
* as they treat a `/run`; `requestOrigin: "internal"` is what lets a shadow
|
|
340
|
+
* recipe be reached at all, and `autonomy: "read-only"` narrows the worker
|
|
341
|
+
* below whatever the session holds. The answer reaches the main agent the way
|
|
342
|
+
* `/share` puts one there: an operator-authored note on the ordinary user-turn
|
|
343
|
+
* path, never a fabricated tool result.
|
|
344
|
+
*/
|
|
345
|
+
async function handleOracle(question: string, ctx: SlashCommandContext): Promise<void> {
|
|
346
|
+
if (!ctx.submitOperatorNote) {
|
|
347
|
+
ctx.notice("error", "/oracle is not wired in this session; there is nowhere to put the answer");
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
// Refused, never queued. The digest describes the record as it stands and a
|
|
351
|
+
// turn still in flight is about to change it, so an answer written against
|
|
352
|
+
// the old record would be advice about a session that no longer exists.
|
|
353
|
+
if (ctx.isTurnInFlight?.() === true) {
|
|
354
|
+
ctx.notice("warn", "a turn is in flight; /oracle is refused rather than queued");
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
const sources = ctx.oracleBriefing?.();
|
|
358
|
+
if (!sources) {
|
|
359
|
+
ctx.notice("error", "/oracle needs the session record, which is not wired in this session");
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
const digest = packOracleDigest({ ...sources, question });
|
|
363
|
+
const request: DispatchRequest = {
|
|
364
|
+
agentId: ORACLE_AGENT_ID,
|
|
365
|
+
task: ORACLE_TASK,
|
|
366
|
+
briefing: digest.text,
|
|
367
|
+
executionRole: requestExecutionRole({
|
|
368
|
+
agentId: ORACLE_AGENT_ID,
|
|
369
|
+
...(ctx.getAgentRoleFacts ? { resolveFacts: ctx.getAgentRoleFacts } : {}),
|
|
370
|
+
}),
|
|
371
|
+
requestOrigin: "internal",
|
|
372
|
+
autonomy: "read-only",
|
|
373
|
+
};
|
|
374
|
+
const progressBus = ctx.dispatch.ownsProgressBus?.(ctx.bus) === true ? undefined : ctx.bus;
|
|
375
|
+
try {
|
|
376
|
+
const handle = await ctx.dispatch.dispatch(request);
|
|
377
|
+
for await (const event of handle.events) {
|
|
378
|
+
const typed = event as { type?: string };
|
|
379
|
+
if (!typed.type || typed.type === "heartbeat") continue;
|
|
380
|
+
progressBus?.emit(BusChannels.DispatchProgress, { runId: handle.runId, agentId: ORACLE_AGENT_ID, event });
|
|
381
|
+
}
|
|
382
|
+
const receipt = await handle.finalPromise;
|
|
383
|
+
const parsed = parseOracleResult(receipt.output?.text ?? null);
|
|
384
|
+
if (parsed === null) {
|
|
385
|
+
ctx.notice("error", `/oracle run ${receipt.runId} returned no usable answer (${receipt.outcome})`);
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
const note = formatWorkerShareNote({
|
|
389
|
+
agentId: ORACLE_AGENT_ID,
|
|
390
|
+
runId: receipt.runId,
|
|
391
|
+
outcome: receipt.outcome,
|
|
392
|
+
text: formatOracleAnswer(parsed),
|
|
393
|
+
});
|
|
394
|
+
if (note === null) {
|
|
395
|
+
ctx.notice("error", `/oracle run ${receipt.runId} produced no text to share`);
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
ctx.submitOperatorNote(note);
|
|
399
|
+
} catch (err) {
|
|
400
|
+
ctx.notice("error", `/oracle failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* `/council <task>`: one council, dispatched exactly as the model dispatches one.
|
|
406
|
+
*
|
|
407
|
+
* The command builds dispatch-tool arguments and hands them to the tool
|
|
408
|
+
* registry. That is the whole of it, and it is deliberate: a council is a
|
|
409
|
+
* plan-scale dispatch, so supervised autonomy parks the call and the approval
|
|
410
|
+
* overlay shows the same artifact it shows for a model-asked council, naming
|
|
411
|
+
* every member's label, target, model, node, round count, and synthesis mode.
|
|
412
|
+
* A private path would have had to reproduce that, and would eventually have
|
|
413
|
+
* reproduced it wrongly.
|
|
414
|
+
*/
|
|
415
|
+
async function handleCouncil(task: string, options: CouncilCommandOptions, ctx: SlashCommandContext): Promise<void> {
|
|
416
|
+
// Refused, never queued, exactly as `/oracle` and `/fleet run` are. An
|
|
417
|
+
// approved council describes the workspace as it stands, and a turn in
|
|
418
|
+
// flight is about to change it.
|
|
419
|
+
if (ctx.isTurnInFlight?.() === true) {
|
|
420
|
+
ctx.notice("warn", "a turn is in flight; /council is refused rather than queued");
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
if (!ctx.runCouncilDispatch) {
|
|
424
|
+
ctx.notice("error", "/council is not wired in this session");
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
const rosters = ctx.getWorkerRosters?.();
|
|
428
|
+
if (rosters === undefined) {
|
|
429
|
+
ctx.notice("error", "/council needs workers.rosters, which is not wired in this session");
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
const resolved = resolveCouncilRoster(options.roster, rosters);
|
|
433
|
+
if (!resolved.ok) {
|
|
434
|
+
ctx.notice("error", resolved.reason);
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
try {
|
|
438
|
+
const outcome = await ctx.runCouncilDispatch(buildCouncilDispatchArgs(task, resolved.roster, options));
|
|
439
|
+
if (outcome.status === "blocked") ctx.notice("warn", `/council was not admitted: ${outcome.reason}`);
|
|
440
|
+
else if (outcome.status === "error") ctx.notice("error", `/council failed: ${outcome.message}`);
|
|
441
|
+
} catch (err) {
|
|
442
|
+
ctx.notice("error", `/council failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* The note a run becomes, with a council run treated as what it is.
|
|
448
|
+
*
|
|
449
|
+
* A council synthesis run seals the whole `council-report`, so sharing its id
|
|
450
|
+
* shares the council: every final member's labelled answer and the synthesis,
|
|
451
|
+
* as one bounded block. A member run seals one voice, so it travels under the
|
|
452
|
+
* roster label the operator watched it under. Every other run keeps the note it
|
|
453
|
+
* has always had. A synthesis whose sealed text does not parse as a report is
|
|
454
|
+
* shared verbatim rather than dropped: the operator asked for that run.
|
|
455
|
+
*/
|
|
456
|
+
function councilAwareShareNote(facts: WorkerShareFacts, entry: WorkerEntryState): string | null {
|
|
457
|
+
const council = entry.council;
|
|
458
|
+
if (council === undefined) return formatWorkerShareNote(facts);
|
|
459
|
+
if (council.label !== COUNCIL_SYNTHESIS_LABEL) return formatCouncilMemberShareNote(facts, council.label);
|
|
460
|
+
const report = parseCouncilReport(facts.text);
|
|
461
|
+
return report === null ? formatWorkerShareNote(facts) : formatCouncilShareNote(facts, report);
|
|
462
|
+
}
|
|
463
|
+
|
|
279
464
|
/**
|
|
280
465
|
* `/share [runId]`: hand a finished worker run's answer to the main agent.
|
|
281
466
|
*
|
|
@@ -299,7 +484,7 @@ function shareWorkerRun(runId: string | undefined, ctx: SlashCommandContext): vo
|
|
|
299
484
|
return;
|
|
300
485
|
}
|
|
301
486
|
const facts = workerShareFactsFromEntry(entry);
|
|
302
|
-
const note = facts === null ? null :
|
|
487
|
+
const note = facts === null ? null : councilAwareShareNote(facts, entry);
|
|
303
488
|
if (note === null) {
|
|
304
489
|
ctx.notice("error", `run ${entry.runId} produced no text to share`);
|
|
305
490
|
return;
|
|
@@ -352,7 +537,7 @@ export interface SlashCommandContext {
|
|
|
352
537
|
* until the host wires a session.
|
|
353
538
|
*/
|
|
354
539
|
runContextRecall?: (ref: string) => void;
|
|
355
|
-
openSkillsHub?: () => void;
|
|
540
|
+
openSkillsHub?: (tab?: LibraryEntryKind) => void;
|
|
356
541
|
listPrompts: () => ResourceList<PromptTemplate>;
|
|
357
542
|
/**
|
|
358
543
|
* Resolve a `/name` against the loaded prompt templates. Absent when the host
|
|
@@ -380,6 +565,51 @@ export interface SlashCommandContext {
|
|
|
380
565
|
exportShareArchive?: (outPath: string) => { fileCount: number; path: string };
|
|
381
566
|
importShareArchive?: (path: string, options: { dryRun?: boolean; force?: boolean }) => ShareImportPlan;
|
|
382
567
|
openCost: () => void;
|
|
568
|
+
/**
|
|
569
|
+
* `/btw <question>`: one model round beside the session, answered in an
|
|
570
|
+
* overlay. Nothing about it enters the transcript, the ledger, or the task
|
|
571
|
+
* board, so the workers a fleet run briefs never see the question or its
|
|
572
|
+
* answer.
|
|
573
|
+
*/
|
|
574
|
+
openSideQuestion: (question: string) => void;
|
|
575
|
+
/**
|
|
576
|
+
* The record `/oracle` briefs its advisor on: settled decisions, the task
|
|
577
|
+
* board, and the last compaction summary. Absent on a host with no session,
|
|
578
|
+
* in which case `/oracle` says so instead of briefing on nothing.
|
|
579
|
+
*/
|
|
580
|
+
oracleBriefing?: () => Omit<OracleDigestSources, "question">;
|
|
581
|
+
/**
|
|
582
|
+
* Configured `workers.rosters`, which is what `/council` seats a council
|
|
583
|
+
* from. Absent on a host with no settings, in which case the command says so
|
|
584
|
+
* rather than dispatching a roster name it could not check.
|
|
585
|
+
*/
|
|
586
|
+
getWorkerRosters?: () => CouncilRosters;
|
|
587
|
+
/**
|
|
588
|
+
* Run one dispatch-tool call with prepared council arguments through the
|
|
589
|
+
* ordinary tool-admission path. The council command owns no dispatch path of
|
|
590
|
+
* its own, so admission, the approval overlay, receipts, and the board treat
|
|
591
|
+
* an operator council exactly as they treat a model-asked one.
|
|
592
|
+
*/
|
|
593
|
+
runCouncilDispatch?: (args: Readonly<Record<string, unknown>>) => Promise<CouncilDispatchOutcome>;
|
|
594
|
+
/**
|
|
595
|
+
* True while a turn is streaming. `/oracle` is refused then, never queued:
|
|
596
|
+
* the digest describes the record as it stands and an in-flight turn is
|
|
597
|
+
* about to change it.
|
|
598
|
+
*/
|
|
599
|
+
isTurnInFlight?: () => boolean;
|
|
600
|
+
/**
|
|
601
|
+
* `/handoff <goal>`: extract this session's working state for a stated goal,
|
|
602
|
+
* review the document, and seed a successor session with it. A session
|
|
603
|
+
* operation only. It writes no memory promotion candidate and never calls
|
|
604
|
+
* the task-memory bank.
|
|
605
|
+
*/
|
|
606
|
+
startHandoff: (goal: string) => void;
|
|
607
|
+
/**
|
|
608
|
+
* `/fleet run <name>`: compile the contract's plan, show every wave, agent,
|
|
609
|
+
* target, boundary, budget, and code-step argv for approval, and dispatch
|
|
610
|
+
* only what the operator accepted. Absent on a host with no fleet wiring.
|
|
611
|
+
*/
|
|
612
|
+
startFleetRun?: (name: string, vars: Readonly<Record<string, string>>) => void;
|
|
383
613
|
/** Open the read-only `/context` overlay: categorized context-window ledger. */
|
|
384
614
|
openContextView: () => void;
|
|
385
615
|
/** Open the read-only `/tasks` overlay: the session task board with receipts. */
|
|
@@ -393,7 +623,7 @@ export interface SlashCommandContext {
|
|
|
393
623
|
done(id: string): UserTask;
|
|
394
624
|
drop(id: string): UserTask;
|
|
395
625
|
};
|
|
396
|
-
/** Open
|
|
626
|
+
/** Open `/memory` for approved lessons, the live task bank, and reviewed promotion. */
|
|
397
627
|
openMemory: () => void;
|
|
398
628
|
/** Opt-in import from the newest structured handoff; absent when the host has no task bank. */
|
|
399
629
|
seedTaskMemory?: () => TaskMemorySeedCommandResult;
|
|
@@ -591,6 +821,26 @@ export const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [
|
|
|
591
821
|
}
|
|
592
822
|
},
|
|
593
823
|
},
|
|
824
|
+
{
|
|
825
|
+
name: "library",
|
|
826
|
+
description: "Open the Skills Hub on a resource library tab",
|
|
827
|
+
group: "Run",
|
|
828
|
+
kinds: ["library"],
|
|
829
|
+
args: { positionals: [{ name: "kind", required: false }] },
|
|
830
|
+
fromArgs(parsed) {
|
|
831
|
+
if (parsed.error) return { kind: "usage-error", command: "library", reason: parsed.error };
|
|
832
|
+
const tab = parsed.positionals[0];
|
|
833
|
+
if (tab === undefined) return { kind: "library" };
|
|
834
|
+
if (!isLibraryTab(tab)) {
|
|
835
|
+
const known = LIBRARY_TABS.map((entry) => entry.id).join(", ");
|
|
836
|
+
return { kind: "usage-error", command: "library", reason: `Unknown kind: ${tab} (one of ${known})` };
|
|
837
|
+
}
|
|
838
|
+
return { kind: "library", tab };
|
|
839
|
+
},
|
|
840
|
+
handle(command, ctx) {
|
|
841
|
+
if (command.kind === "library") ctx.openSkillsHub?.(command.tab);
|
|
842
|
+
},
|
|
843
|
+
},
|
|
594
844
|
{
|
|
595
845
|
name: "prompts",
|
|
596
846
|
description: "List prompt templates",
|
|
@@ -850,6 +1100,108 @@ export const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [
|
|
|
850
1100
|
})();
|
|
851
1101
|
},
|
|
852
1102
|
},
|
|
1103
|
+
{
|
|
1104
|
+
name: "btw",
|
|
1105
|
+
description: "Ask a side question that never enters the session transcript",
|
|
1106
|
+
group: "Run",
|
|
1107
|
+
kinds: ["btw", "btw-usage"],
|
|
1108
|
+
args: {
|
|
1109
|
+
positionals: [{ name: "question", required: true, rest: true }],
|
|
1110
|
+
},
|
|
1111
|
+
fromArgs(parsed) {
|
|
1112
|
+
const question = parsed.rest?.trim() ?? "";
|
|
1113
|
+
if (parsed.error || question.length === 0) return { kind: "btw-usage" };
|
|
1114
|
+
return { kind: "btw", question };
|
|
1115
|
+
},
|
|
1116
|
+
handle(command, ctx) {
|
|
1117
|
+
if (command.kind === "btw-usage") {
|
|
1118
|
+
const entry = BUILTIN_SLASH_COMMANDS.find((candidate) => candidate.name === "btw");
|
|
1119
|
+
if (entry) ctx.notice("info", usageNotice(entry));
|
|
1120
|
+
return;
|
|
1121
|
+
}
|
|
1122
|
+
if (command.kind !== "btw") return;
|
|
1123
|
+
ctx.openSideQuestion(command.question);
|
|
1124
|
+
},
|
|
1125
|
+
},
|
|
1126
|
+
{
|
|
1127
|
+
name: "oracle",
|
|
1128
|
+
description: "Ask a read-only advisor to challenge a question against this session's settled decisions",
|
|
1129
|
+
group: "Run",
|
|
1130
|
+
kinds: ["oracle", "oracle-usage"],
|
|
1131
|
+
args: {
|
|
1132
|
+
positionals: [{ name: "question", required: true, rest: true }],
|
|
1133
|
+
},
|
|
1134
|
+
fromArgs(parsed) {
|
|
1135
|
+
const question = parsed.rest?.trim() ?? "";
|
|
1136
|
+
if (parsed.error || question.length === 0) return { kind: "oracle-usage" };
|
|
1137
|
+
return { kind: "oracle", question };
|
|
1138
|
+
},
|
|
1139
|
+
handle(command, ctx) {
|
|
1140
|
+
if (command.kind === "oracle-usage") {
|
|
1141
|
+
const entry = BUILTIN_SLASH_COMMANDS.find((candidate) => candidate.name === "oracle");
|
|
1142
|
+
if (entry) ctx.notice("info", usageNotice(entry));
|
|
1143
|
+
return;
|
|
1144
|
+
}
|
|
1145
|
+
if (command.kind !== "oracle") return;
|
|
1146
|
+
void (async () => {
|
|
1147
|
+
await handleOracle(command.question, ctx);
|
|
1148
|
+
ctx.render();
|
|
1149
|
+
})();
|
|
1150
|
+
},
|
|
1151
|
+
},
|
|
1152
|
+
{
|
|
1153
|
+
name: "council",
|
|
1154
|
+
description: "Ask a roster of read-only members the same task, with an optional vote or judge synthesis",
|
|
1155
|
+
group: "Run",
|
|
1156
|
+
kinds: ["council", "council-usage"],
|
|
1157
|
+
args: {
|
|
1158
|
+
parseFlagsBeforeRest: true,
|
|
1159
|
+
flags: [
|
|
1160
|
+
{ name: "--roster", takesValue: true, valueName: "name" },
|
|
1161
|
+
{ name: "--rounds", takesValue: true, valueName: "n" },
|
|
1162
|
+
{ name: "--synthesis", takesValue: true, values: COUNCIL_SYNTHESIS_MODES },
|
|
1163
|
+
],
|
|
1164
|
+
positionals: [{ name: "task", required: true, rest: true }],
|
|
1165
|
+
},
|
|
1166
|
+
fromArgs(parsed) {
|
|
1167
|
+
const task = parsed.rest?.trim() ?? "";
|
|
1168
|
+
if (parsed.error) return { kind: "council-usage", reason: parsed.error };
|
|
1169
|
+
if (task.length === 0) return { kind: "council-usage" };
|
|
1170
|
+
const options: CouncilCommandOptions = {};
|
|
1171
|
+
const roster = parsed.flags.get("--roster");
|
|
1172
|
+
if (typeof roster === "string") options.roster = roster;
|
|
1173
|
+
const rounds = parsed.flags.get("--rounds");
|
|
1174
|
+
if (typeof rounds === "string") {
|
|
1175
|
+
const parsedRounds = Number(rounds);
|
|
1176
|
+
// The tool bounds rounds at one to three, and a council that is
|
|
1177
|
+
// refused after admission has already shown the operator a plan it
|
|
1178
|
+
// cannot run, so the same bound is enforced where it was typed.
|
|
1179
|
+
if (!Number.isInteger(parsedRounds) || parsedRounds < 1 || parsedRounds > COUNCIL_MAX_ROUNDS) {
|
|
1180
|
+
return { kind: "council-usage", reason: `--rounds must be an integer 1..${COUNCIL_MAX_ROUNDS}` };
|
|
1181
|
+
}
|
|
1182
|
+
options.rounds = parsedRounds;
|
|
1183
|
+
}
|
|
1184
|
+
const synthesis = parsed.flags.get("--synthesis");
|
|
1185
|
+
if (typeof synthesis === "string") {
|
|
1186
|
+
if (!isCouncilSynthesisMode(synthesis)) return { kind: "council-usage" };
|
|
1187
|
+
options.synthesis = synthesis;
|
|
1188
|
+
}
|
|
1189
|
+
return { kind: "council", task, options };
|
|
1190
|
+
},
|
|
1191
|
+
handle(command, ctx) {
|
|
1192
|
+
if (command.kind === "council-usage") {
|
|
1193
|
+
const entry = BUILTIN_SLASH_COMMANDS.find((candidate) => candidate.name === "council");
|
|
1194
|
+
const usage = entry ? usageNotice(entry) : "usage: /council <task>";
|
|
1195
|
+
ctx.notice("info", command.reason ? `${command.reason}\n${usage}` : usage);
|
|
1196
|
+
return;
|
|
1197
|
+
}
|
|
1198
|
+
if (command.kind !== "council") return;
|
|
1199
|
+
void (async () => {
|
|
1200
|
+
await handleCouncil(command.task, command.options, ctx);
|
|
1201
|
+
ctx.render();
|
|
1202
|
+
})();
|
|
1203
|
+
},
|
|
1204
|
+
},
|
|
853
1205
|
{
|
|
854
1206
|
name: "agents",
|
|
855
1207
|
description: "List Clio agents and ACP delegation agents",
|
|
@@ -944,7 +1296,59 @@ export const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [
|
|
|
944
1296
|
}
|
|
945
1297
|
},
|
|
946
1298
|
},
|
|
947
|
-
|
|
1299
|
+
{
|
|
1300
|
+
name: "fleet",
|
|
1301
|
+
description: "Open Settings → Fleet, or run a fleet contract with an approval preview",
|
|
1302
|
+
group: "Configure",
|
|
1303
|
+
kinds: ["fleet-run", "fleet-run-usage"],
|
|
1304
|
+
subcommandDescriptions: { run: "Preview and run a repo-owned fleet contract" },
|
|
1305
|
+
args: {
|
|
1306
|
+
subcommands: {
|
|
1307
|
+
run: {
|
|
1308
|
+
flags: [{ name: "--var", takesValue: true, repeatable: true, valueName: "key=value" }],
|
|
1309
|
+
positionals: [{ name: "name", required: true }],
|
|
1310
|
+
},
|
|
1311
|
+
},
|
|
1312
|
+
},
|
|
1313
|
+
/**
|
|
1314
|
+
* `/fleet` alone keeps the settings deep link it has always been, and
|
|
1315
|
+
* only `run` parses as a command of its own, so an operator who types
|
|
1316
|
+
* `/fleet` out of habit still lands in Settings → Fleet. Anything else
|
|
1317
|
+
* on the line stays the usage error every other deep link reports.
|
|
1318
|
+
*/
|
|
1319
|
+
fromArgs(parsed) {
|
|
1320
|
+
if (parsed.subcommand !== "run") {
|
|
1321
|
+
return parsed.error
|
|
1322
|
+
? { kind: "usage-error", command: "fleet", reason: parsed.error }
|
|
1323
|
+
: { kind: "settings", section: "fleet" };
|
|
1324
|
+
}
|
|
1325
|
+
if (parsed.error) return { kind: "fleet-run-usage", reason: parsed.error };
|
|
1326
|
+
const name = parsed.positionals[0] ?? "";
|
|
1327
|
+
if (name.length === 0) return { kind: "fleet-run-usage" };
|
|
1328
|
+
const vars: Record<string, string> = {};
|
|
1329
|
+
for (const pair of parsed.flagValues.get("--var") ?? []) {
|
|
1330
|
+
const eq = pair.indexOf("=");
|
|
1331
|
+
const key = eq < 0 ? "" : pair.slice(0, eq).trim();
|
|
1332
|
+
if (key.length === 0) return { kind: "fleet-run-usage", reason: "--var requires key=value" };
|
|
1333
|
+
vars[key] = pair.slice(eq + 1);
|
|
1334
|
+
}
|
|
1335
|
+
return { kind: "fleet-run", name, vars };
|
|
1336
|
+
},
|
|
1337
|
+
handle(command, ctx) {
|
|
1338
|
+
if (command.kind === "fleet-run-usage") {
|
|
1339
|
+
const entry = BUILTIN_SLASH_COMMANDS.find((candidate) => candidate.name === "fleet");
|
|
1340
|
+
const usage = entry ? usageNotice(entry, "run") : "usage: /fleet run <name> [--var key=value ...]";
|
|
1341
|
+
ctx.notice("info", command.reason ? `${command.reason}\n${usage}` : usage);
|
|
1342
|
+
return;
|
|
1343
|
+
}
|
|
1344
|
+
if (command.kind !== "fleet-run") return;
|
|
1345
|
+
if (!ctx.startFleetRun) {
|
|
1346
|
+
ctx.notice("error", "/fleet run is not wired in this session");
|
|
1347
|
+
return;
|
|
1348
|
+
}
|
|
1349
|
+
ctx.startFleetRun(command.name, command.vars);
|
|
1350
|
+
},
|
|
1351
|
+
},
|
|
948
1352
|
{
|
|
949
1353
|
name: "decisions",
|
|
950
1354
|
description: "Show settled interview decisions and operator revisions",
|
|
@@ -1036,7 +1440,7 @@ export const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [
|
|
|
1036
1440
|
},
|
|
1037
1441
|
{
|
|
1038
1442
|
name: "memory",
|
|
1039
|
-
description: "Inspect
|
|
1443
|
+
description: "Inspect, promote, or seed task memory",
|
|
1040
1444
|
group: "Inspect",
|
|
1041
1445
|
kinds: ["memory", "memory-seed"],
|
|
1042
1446
|
subcommandDescriptions: { seed: "Seed the task bank from the newest handoff" },
|
|
@@ -1250,6 +1654,29 @@ export const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [
|
|
|
1250
1654
|
ctx.startNewSession();
|
|
1251
1655
|
},
|
|
1252
1656
|
},
|
|
1657
|
+
{
|
|
1658
|
+
name: "handoff",
|
|
1659
|
+
description: "Hand this session's working state to a fresh session for a stated goal",
|
|
1660
|
+
group: "Sessions",
|
|
1661
|
+
kinds: ["handoff", "handoff-usage"],
|
|
1662
|
+
args: {
|
|
1663
|
+
positionals: [{ name: "goal", required: true, rest: true }],
|
|
1664
|
+
},
|
|
1665
|
+
fromArgs(parsed) {
|
|
1666
|
+
const goal = parsed.rest?.trim() ?? "";
|
|
1667
|
+
if (parsed.error || goal.length === 0) return { kind: "handoff-usage" };
|
|
1668
|
+
return { kind: "handoff", goal };
|
|
1669
|
+
},
|
|
1670
|
+
handle(command, ctx) {
|
|
1671
|
+
if (command.kind === "handoff-usage") {
|
|
1672
|
+
const entry = BUILTIN_SLASH_COMMANDS.find((candidate) => candidate.name === "handoff");
|
|
1673
|
+
if (entry) ctx.notice("info", usageNotice(entry));
|
|
1674
|
+
return;
|
|
1675
|
+
}
|
|
1676
|
+
if (command.kind !== "handoff") return;
|
|
1677
|
+
ctx.startHandoff(command.goal);
|
|
1678
|
+
},
|
|
1679
|
+
},
|
|
1253
1680
|
{
|
|
1254
1681
|
name: "tree",
|
|
1255
1682
|
description: "Open session tree navigator",
|
|
@@ -154,18 +154,31 @@ export function parseArgs(spec: CommandArgsSpec, argsLine: string): ParsedArgs {
|
|
|
154
154
|
const positionalSpecs = currentSpec.positionals ?? [];
|
|
155
155
|
let positionalIndex = 0;
|
|
156
156
|
|
|
157
|
+
// A token ends at whitespace unless a quote is open: `--var task="do it"`
|
|
158
|
+
// and `--var "task=do it"` both carry the spaces through, and the quotes
|
|
159
|
+
// themselves are dropped. An unterminated quote runs to the end of the line.
|
|
157
160
|
const readToken = (): { token: string } | null => {
|
|
158
161
|
const tokenStart = index;
|
|
162
|
+
let token = "";
|
|
163
|
+
let quote: string | null = null;
|
|
159
164
|
while (index < argsLine.length) {
|
|
160
|
-
const char = argsLine[index];
|
|
161
|
-
if (
|
|
165
|
+
const char = argsLine[index] ?? "";
|
|
166
|
+
if (quote !== null) {
|
|
167
|
+
if (char === quote) quote = null;
|
|
168
|
+
else token += char;
|
|
162
169
|
index++;
|
|
163
|
-
|
|
164
|
-
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
if (char === '"' || char === "'") {
|
|
173
|
+
quote = char;
|
|
174
|
+
index++;
|
|
175
|
+
continue;
|
|
165
176
|
}
|
|
177
|
+
if (/\s/.test(char)) break;
|
|
178
|
+
token += char;
|
|
179
|
+
index++;
|
|
166
180
|
}
|
|
167
|
-
|
|
168
|
-
if (token.length === 0) return null;
|
|
181
|
+
if (index === tokenStart) return null;
|
|
169
182
|
return { token };
|
|
170
183
|
};
|
|
171
184
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { responseModelIdObservationFromRecord } from "../../core/response-model-id.js";
|
|
1
2
|
import { estimateReasoningTextTokens, extractReasoningTokens } from "../../domains/session/context-accounting.js";
|
|
2
3
|
import type { AgentMessage } from "../../engine/types.js";
|
|
3
4
|
import type { ReasoningTokenProvenance, RunTally, TurnStopReason, TurnSummary, WatchdogTier } from "./types.js";
|
|
@@ -65,6 +66,7 @@ export function emptyRunTally(): RunTally {
|
|
|
65
66
|
hadEstimatedReasoning: false,
|
|
66
67
|
toolCount: 0,
|
|
67
68
|
toolErrorCount: 0,
|
|
69
|
+
responseModelIdObservation: { state: "not-observed" },
|
|
68
70
|
};
|
|
69
71
|
}
|
|
70
72
|
|
|
@@ -85,8 +87,10 @@ export function foldMessageIntoRunTally(tally: RunTally, message: AgentMessage):
|
|
|
85
87
|
}
|
|
86
88
|
if (message.role !== "assistant") return tally;
|
|
87
89
|
const usage = (message as { usage?: UsageLike }).usage;
|
|
90
|
+
const record = message as unknown as Record<string, unknown>;
|
|
88
91
|
const next: RunTally = {
|
|
89
92
|
...tally,
|
|
93
|
+
responseModelIdObservation: responseModelIdObservationFromRecord(record, "not-observed"),
|
|
90
94
|
inputTokens: tally.inputTokens + (usage ? finite(usage.input) : 0),
|
|
91
95
|
outputTokens: tally.outputTokens + (usage ? finite(usage.output) : 0),
|
|
92
96
|
cacheReadTokens: tally.cacheReadTokens + (usage ? finite(usage.cacheRead) : 0),
|
|
@@ -145,6 +149,7 @@ export function summaryFromRunTally(tally: RunTally, input: SummaryFromTallyInpu
|
|
|
145
149
|
...(input.stopDetail !== undefined ? { stopDetail: input.stopDetail } : {}),
|
|
146
150
|
watchdogPeak: input.watchdogPeak,
|
|
147
151
|
truncated: input.truncated === true,
|
|
152
|
+
responseModelIdObservation: tally.responseModelIdObservation,
|
|
148
153
|
};
|
|
149
154
|
if (tally.hadProviderReasoning || tally.hadEstimatedReasoning) {
|
|
150
155
|
summary.reasoningTokens = tally.reasoningTokens;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { StatusPhase, WatchdogTier } from "../../core/bus-events.js";
|
|
2
|
+
import type { ResponseModelIdObservation } from "../../core/response-model-id.js";
|
|
2
3
|
|
|
3
4
|
// StatusPhase, WatchdogTier, and AgentStatusChangedPayload moved to
|
|
4
5
|
// src/core/bus-events.ts (the phase taxonomy rides the agent.status.changed
|
|
@@ -29,6 +30,8 @@ export interface DispatchOverlay {
|
|
|
29
30
|
export interface TurnSummary {
|
|
30
31
|
elapsedMs: number;
|
|
31
32
|
modelId: string;
|
|
33
|
+
/** Direct response model-id observation for the last API call in the turn. */
|
|
34
|
+
responseModelIdObservation: ResponseModelIdObservation;
|
|
32
35
|
targetId: string;
|
|
33
36
|
inputTokens: number;
|
|
34
37
|
outputTokens: number;
|
|
@@ -70,6 +73,8 @@ export interface RunTally {
|
|
|
70
73
|
hadEstimatedReasoning: boolean;
|
|
71
74
|
toolCount: number;
|
|
72
75
|
toolErrorCount: number;
|
|
76
|
+
/** Direct response model-id observation for the last assistant call folded. */
|
|
77
|
+
responseModelIdObservation: ResponseModelIdObservation;
|
|
73
78
|
}
|
|
74
79
|
|
|
75
80
|
export interface OverlayFrame {
|
|
@@ -189,6 +189,7 @@ export function createProcessTerminalLease(options: CreateProcessTerminalLeaseOp
|
|
|
189
189
|
getModelLabel: () => editorChrome.getModelLabel(),
|
|
190
190
|
getThinkingLabel: () => editorChrome.getThinkingLabel(),
|
|
191
191
|
isStreaming: () => editorChrome.isStreaming?.() ?? false,
|
|
192
|
+
isAwaitingApproval: () => editorChrome.isAwaitingApproval?.() ?? false,
|
|
192
193
|
willEnterSteer: (text) => editorChrome.willEnterSteer?.(text) ?? false,
|
|
193
194
|
getSubmitKeyLabel: () => editorChrome.getSubmitKeyLabel?.() ?? "Enter",
|
|
194
195
|
getNewlineKeyLabel: () => editorChrome.getNewlineKeyLabel?.() ?? "Shift+Enter",
|