@iowarp/clio-coder 0.3.3 → 0.3.6
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 +74 -0
- package/CONTRIBUTING.md +7 -7
- package/README.md +3 -3
- package/dist/{acp-P2AQILE2.js → acp-2BEHC4DL.js} +9 -8
- package/dist/{agents-72W3BI7I.js → agents-LNNFTM53.js} +29 -24
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-5TWEIYDN.js → auth-KXXFI2VS.js} +14 -10
- package/dist/{chunk-GGXXDWE4.js → chunk-22NAGB7X.js} +2 -2
- package/dist/{chunk-YCWGATWI.js → chunk-24I7BN55.js} +2 -2
- package/dist/{chunk-EKMEHE4H.js → chunk-33YXPOE3.js} +2 -3
- package/dist/chunk-3BPUFZDL.js +37 -0
- package/dist/chunk-43AOLP7E.js +375 -0
- package/dist/{chunk-ZDOOVTXZ.js → chunk-4OC57DA6.js} +27 -4
- package/dist/{chunk-6SGHMWE3.js → chunk-5JGRAMKL.js} +5 -5
- package/dist/{chunk-V6RTAOC2.js → chunk-6US73PDB.js} +572 -51
- package/dist/{chunk-5UFT4SUX.js → chunk-6XXKFVSN.js} +3 -3
- package/dist/{chunk-A3CYT5EX.js → chunk-AD2SYQYC.js} +55 -2
- package/dist/chunk-AOCYTWAV.js +449 -0
- package/dist/chunk-CFGTUFWB.js +67 -0
- package/dist/chunk-CJUB2JJ2.js +1478 -0
- package/dist/{chunk-FNTMWMX5.js → chunk-CKXWIANG.js} +14 -12
- package/dist/{chunk-PIWWS5BL.js → chunk-CYQKWTG3.js} +63 -78
- package/dist/{chunk-LZSJBIVT.js → chunk-DJVECN66.js} +271 -762
- package/dist/{chunk-CBCAPZAA.js → chunk-E25LMLRW.js} +2 -2
- package/dist/{chunk-ZWMF7253.js → chunk-E2ER4LJF.js} +304 -9
- package/dist/{chunk-STBPMHSX.js → chunk-EKY57CSP.js} +51 -84
- package/dist/{chunk-DUYJ5IO6.js → chunk-EYPA3EGJ.js} +12 -4
- package/dist/{chunk-M6SHUN7Q.js → chunk-FO5ZOVUY.js} +2 -2
- package/dist/chunk-FYYLNIL5.js +313 -0
- package/dist/{chunk-OQ33BKR3.js → chunk-G7MUEIGA.js} +3 -60
- package/dist/chunk-GEYXPTRF.js +613 -0
- package/dist/chunk-GOXNB3AO.js +261 -0
- package/dist/{chunk-G4BMMOKF.js → chunk-HVDIIIQW.js} +2 -2
- package/dist/chunk-HWUFFB6L.js +83 -0
- package/dist/{chunk-4XUGQOHA.js → chunk-K7T3E2SR.js} +15 -8
- package/dist/chunk-K7VKOLQQ.js +15 -0
- package/dist/{chunk-UFIIWP2H.js → chunk-KHSFENX2.js} +8 -8
- package/dist/{chunk-BMEMKKIT.js → chunk-KOHPCX4K.js} +2 -2
- package/dist/chunk-LCGCVYZ4.js +57 -0
- package/dist/chunk-LL4KHSZI.js +22 -0
- package/dist/{chunk-PAJK6MAQ.js → chunk-LYF7OHWH.js} +42 -15
- package/dist/{chunk-POHLU5DW.js → chunk-M6L6IDJG.js} +3 -3
- package/dist/{chunk-5UUP6MWO.js → chunk-MV3K5QF2.js} +5 -436
- package/dist/{chunk-X4RCMKVQ.js → chunk-NDINPTJ4.js} +2 -2
- package/dist/{chunk-TZK7PACC.js → chunk-NILBFAPG.js} +14 -8
- package/dist/chunk-ODFEOB4F.js +1082 -0
- package/dist/{chunk-AGYYIBLL.js → chunk-OH3TOQTB.js} +6 -2
- package/dist/chunk-OZNBF4L3.js +23 -0
- package/dist/{chunk-DSELYM6W.js → chunk-PBTHKCPN.js} +30 -10
- package/dist/{verify-375KUB3Y.js → chunk-PCZJO5TI.js} +127 -42
- package/dist/{chunk-ED4KHGC3.js → chunk-PPAMZ32Z.js} +9 -2
- package/dist/{chunk-SRDMMSEP.js → chunk-QM3F2GKX.js} +1063 -1645
- package/dist/{chunk-X6IAEBZR.js → chunk-QNQHSOLF.js} +7 -7
- package/dist/{chunk-OC7FIQPC.js → chunk-R46L2BIR.js} +10 -7
- package/dist/{chunk-2TLUCQVG.js → chunk-RD5U66HV.js} +3 -3
- package/dist/{chunk-6N5PTWMY.js → chunk-RY3LY4J5.js} +50 -13
- package/dist/{chunk-OKGUZO2U.js → chunk-SPULKLCF.js} +4 -3
- package/dist/{chunk-OOJYHWRB.js → chunk-TSHXZTOQ.js} +6 -5
- package/dist/chunk-TZSKNMZG.js +434 -0
- package/dist/{chunk-7MNJORFF.js → chunk-UL3WSD3F.js} +6 -1
- package/dist/{chunk-VJWL6YS5.js → chunk-UUVG37B4.js} +2 -2
- package/dist/{chunk-COU2UHX6.js → chunk-VEZEGCGW.js} +170 -2
- package/dist/chunk-W6GROXXM.js +69 -0
- package/dist/{chunk-OAO4GE4M.js → chunk-WHGPSPT5.js} +2 -2
- package/dist/chunk-WHJYKASB.js +677 -0
- package/dist/{chunk-ORBHGJC5.js → chunk-WR67VIZY.js} +3 -3
- package/dist/{chunk-YHZX5GEU.js → chunk-XAKHZX5N.js} +2 -2
- package/dist/{chunk-TZTZS7QK.js → chunk-XE2VEJHX.js} +5 -3
- package/dist/{chunk-LM5TQCJZ.js → chunk-XF5N4U5A.js} +8 -7
- package/dist/{chunk-LWLEKMDQ.js → chunk-XXQNGV4M.js} +1073 -552
- package/dist/{chunk-KZWTDYJF.js → chunk-XYDYPRZI.js} +7 -7
- package/dist/chunk-ZGVHUX3M.js +66 -0
- package/dist/{chunk-LW6DSM3M.js → chunk-ZRGEBJ4T.js} +1192 -1119
- package/dist/{chunk-2DJ2KNFG.js → chunk-ZXF4XRKW.js} +202 -40
- package/dist/chunk-ZZMN5OM4.js +122 -0
- package/dist/cli/index.js +34 -30
- package/dist/{clio-JOU4FXVA.js → clio-M2KGYUFZ.js} +7 -6
- package/dist/{code-nav-7AX6FYE6.js → code-nav-GQNL7XA6.js} +8 -6
- package/dist/codewiki/build-worker.js +4 -4
- package/dist/{components-KELWS457.js → components-5TTYYX6G.js} +3 -3
- package/dist/{config-XCDVKR23.js → config-XUUYQIWO.js} +47 -35
- package/dist/{configure-4GAP54ZW.js → configure-IHJ7YOMV.js} +18 -15
- package/dist/{context-77FM5DV5.js → context-74JLXAWD.js} +18 -10
- package/dist/{context-4UOGGLQ5.js → context-75MIWW3U.js} +41 -29
- package/dist/{context-5VKGUVJJ.js → context-ZQ7SIFJV.js} +85 -9
- package/dist/{context-clear-XXJRLCJJ.js → context-clear-GYKWNUML.js} +41 -29
- package/dist/{context-index-BZ4UYMTC.js → context-index-SSR5ECNE.js} +3 -3
- package/dist/context-working-set-UX5KEP4J.js +1553 -0
- package/dist/{dispatch-runner-QPRDDBDX.js → dispatch-runner-GIJBHNFL.js} +47 -32
- package/dist/{docs-2C2LTVT2.js → docs-6FZSCG5B.js} +3 -3
- package/dist/{doctor-HR46URBJ.js → doctor-SVJ5BZCW.js} +12 -12
- package/dist/{eval-XSSNATB4.js → eval-CG6LLBLD.js} +54 -238
- package/dist/{evidence-6HG2PY2B.js → evidence-ZYFIEN42.js} +57 -28
- package/dist/{evolve-K7YU3NCY.js → evolve-QGEXEMDW.js} +36 -25
- package/dist/{extensions-QVDOHDGJ.js → extensions-ADGNCJJD.js} +3 -3
- package/dist/{fleet-VY3HHKN6.js → fleet-S5R4ZOQY.js} +73 -44
- package/dist/{fleet-preflight-DDN536IT.js → fleet-preflight-BHSNPBMH.js} +3 -3
- package/dist/{init-JYGXI3FK.js → init-5DRU55YR.js} +49 -37
- package/dist/memory-7YKKR6UC.js +467 -0
- package/dist/{models-I5QWSEOM.js → models-ZPOLRU2C.js} +24 -21
- package/dist/{monitor-GE4ID3IA.js → monitor-US5F5YGZ.js} +73 -46
- package/dist/{orchestrator-EM5MC3HM.js → orchestrator-E2AL4T5N.js} +1624 -1007
- package/dist/{paths-UXLN5YYZ.js → paths-E7KYAQWE.js} +3 -3
- package/dist/{reset-L2FQEE3E.js → reset-KZ652EK6.js} +6 -5
- package/dist/{run-ZU3QMZPZ.js → run-SRNBKDWD.js} +76 -54
- package/dist/{share-S5BZQC5I.js → share-CGZE33UP.js} +7 -6
- package/dist/{skills-X5VXCRNQ.js → skills-S2X4DLY5.js} +4 -4
- package/dist/{skills-eval-WKIHWTHR.js → skills-eval-W2GGIC4R.js} +40 -29
- package/dist/{targets-SNCPI2NR.js → targets-54SWINWB.js} +28 -23
- package/dist/{terminal-lease-BNAHVHBS.js → terminal-lease-SAIF2OGY.js} +6 -4
- package/dist/{uninstall-FZCQCDKC.js → uninstall-BVLWXKBT.js} +3 -3
- package/dist/{upgrade-JQHHPQ4K.js → upgrade-JKAR27XC.js} +20 -19
- package/dist/{usage-OR4O5SMZ.js → usage-MSAWCLX4.js} +79 -36
- package/dist/verifiers-NCBTHHN2.js +1220 -0
- package/dist/verify-X5HDROLA.js +25 -0
- package/dist/{wiki-generate-UEXP2ARI.js → wiki-generate-GUSOQ6ZP.js} +50 -37
- package/dist/worker/entry.js +90 -70
- package/dist/{workspace-G4ZWUIPR.js → workspace-ZJ6BFM3Q.js} +4 -4
- package/docs/README.md +8 -7
- 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 +1 -1
- package/docs/built-in-agents.md +1 -1
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +60 -26
- package/docs/config-knobs-audit.md +1 -2
- package/docs/configuration-and-targets.md +26 -1
- package/docs/context-engine.md +67 -13
- package/docs/context-working-set.md +194 -0
- package/docs/development-pipeline.md +1 -1
- package/docs/documentation-coverage.md +6 -6
- package/docs/documentation-guide.md +7 -6
- package/docs/environment-variables.md +2 -1
- package/docs/eval-runner.md +1 -1
- package/docs/evals-internal.md +4 -32
- package/docs/evidence-and-memory.md +139 -7
- package/docs/evolution.md +1 -1
- package/docs/exit-codes-and-output.md +1 -1
- package/docs/extensions-and-sharing.md +2 -2
- package/docs/fleet-dispatch.md +49 -8
- package/docs/glossary.md +21 -1
- package/docs/installation-and-lifecycle.md +2 -2
- package/docs/middleware-and-components.md +19 -2
- package/docs/model-catalog.md +7 -9
- package/docs/observability.md +4 -4
- package/docs/proactive-memory.md +26 -16
- package/docs/prompt-envelope-and-tools.md +7 -5
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/release-cut-checklist.md +43 -40
- package/docs/safety-model.md +49 -8
- package/docs/scientific-validation.md +21 -3
- package/docs/session-lifecycle.md +3 -3
- package/docs/skills-marketplace.md +1 -1
- package/docs/tool-usage.md +79 -12
- 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 +11 -1
- package/package.json +13 -13
- package/skills/meta/clio-test/SKILL.md +20 -17
- package/skills/meta/clio-test/evals.md +3 -3
- package/skills/meta/clio-test/references/harness.md +35 -6
- package/skills/meta/clio-test/references/test-map.md +20 -10
- package/skills/registry.yaml +2 -2
- package/skills/skill-marketplace.json +1 -1
- package/src/cli/agents.ts +2 -3
- package/src/cli/argv.ts +14 -1
- package/src/cli/context-working-set.ts +513 -0
- package/src/cli/context.ts +8 -0
- package/src/cli/evidence.ts +20 -2
- package/src/cli/fleet.ts +15 -0
- package/src/cli/index.ts +5 -1
- 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/targets.ts +12 -3
- package/src/cli/usage.ts +55 -7
- package/src/cli/verifiers.ts +325 -0
- package/src/core/bash-exec.ts +39 -14
- package/src/core/bus-events.ts +22 -4
- package/src/core/config.ts +54 -0
- package/src/core/defaults.ts +50 -3
- package/src/core/response-model-id.ts +134 -0
- package/src/core/toml.ts +62 -0
- package/src/core/verification-scripts.ts +6 -0
- package/src/core/workspace-files.ts +0 -1
- package/src/domains/agents/builtins/architect.md +1 -1
- package/src/domains/agents/builtins/verifier.md +3 -0
- package/src/domains/agents/catalog.ts +5 -4
- package/src/domains/agents/recipe.ts +54 -14
- package/src/domains/agents/result-contract.ts +7 -4
- package/src/domains/config/classify.ts +1 -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/contract.ts +161 -0
- package/src/domains/context/working-set/defaults.ts +28 -0
- package/src/domains/context/working-set/engine.ts +203 -0
- package/src/domains/context/working-set/fold.ts +62 -0
- package/src/domains/context/working-set/horizon.ts +38 -0
- package/src/domains/context/working-set/marker.ts +103 -0
- package/src/domains/context/working-set/path-index.ts +436 -0
- package/src/domains/context/working-set/payload.ts +152 -0
- package/src/domains/context/working-set/policies/age-horizon.ts +55 -0
- package/src/domains/context/working-set/policies/index.ts +20 -0
- package/src/domains/context/working-set/policies/structural.ts +160 -0
- package/src/domains/context/working-set/project.ts +132 -0
- package/src/domains/context/working-set/protect.ts +109 -0
- package/src/domains/context/working-set/recall.ts +177 -0
- package/src/domains/context/working-set/replay/controls.ts +112 -0
- package/src/domains/context/working-set/replay/load-clio.ts +199 -0
- package/src/domains/context/working-set/replay/metrics.ts +185 -0
- package/src/domains/context/working-set/replay/reference-graph.ts +79 -0
- package/src/domains/context/working-set/replay/report.ts +139 -0
- package/src/domains/context/working-set/replay/runner.ts +325 -0
- package/src/domains/context/working-set/replay/synthetic.ts +422 -0
- package/src/domains/context/working-set/replay/trace.ts +21 -0
- package/src/domains/context/working-set/visible.ts +54 -0
- package/src/domains/dispatch/budget-envelope.ts +396 -0
- package/src/domains/dispatch/contract.ts +2 -0
- package/src/domains/dispatch/extension.ts +81 -27
- package/src/domains/dispatch/orphan-recovery.ts +1 -0
- package/src/domains/dispatch/receipt-integrity.ts +4 -0
- package/src/domains/dispatch/state.ts +1 -0
- package/src/domains/dispatch/types.ts +10 -3
- package/src/domains/dispatch/validation.ts +14 -0
- 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/build.ts +112 -45
- package/src/domains/evidence/eval.ts +24 -7
- package/src/domains/evidence/index.ts +53 -0
- package/src/domains/evidence/ordering.ts +12 -0
- package/src/domains/evidence/run-trust.ts +221 -0
- package/src/domains/evidence/store.ts +46 -6
- package/src/domains/evidence/trust-status.ts +854 -0
- package/src/domains/evidence/types.ts +26 -0
- 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/memory-intervention.ts +38 -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 +208 -5
- package/src/domains/middleware/types.ts +10 -0
- package/src/domains/observability/contract.ts +6 -1
- package/src/domains/observability/cost.ts +20 -4
- package/src/domains/observability/extension.ts +2 -2
- 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/safety/autonomy.ts +1 -1
- package/src/domains/safety/call-target.ts +211 -14
- package/src/domains/safety/decision-presentation.ts +268 -0
- package/src/domains/safety/default-path-policy.ts +8 -0
- package/src/domains/safety/finish-contract.ts +4 -3
- package/src/domains/safety/policy-engine.ts +48 -6
- package/src/domains/safety/redaction.ts +73 -0
- package/src/domains/session/compaction/compact.ts +23 -1
- package/src/domains/session/compaction/cut-point.ts +2 -0
- package/src/domains/session/compaction/tokens.ts +16 -1
- package/src/domains/session/context-ledger.ts +12 -1
- package/src/domains/session/decision-board.ts +4 -0
- package/src/domains/session/entries.ts +110 -1
- package/src/domains/session/history.ts +68 -19
- package/src/domains/session/manager.ts +9 -2
- package/src/domains/session/migrations/index.ts +22 -3
- package/src/domains/session/usage.ts +24 -7
- package/src/engine/acp/event-mapper.ts +7 -0
- package/src/engine/acp/server.ts +32 -2
- package/src/engine/agent.ts +18 -1
- 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/session.ts +9 -3
- package/src/engine/worker-events.ts +4 -3
- package/src/engine/worker-runtime.ts +59 -54
- package/src/entry/orchestrator.ts +34 -5
- package/src/interactive/chat-loop-messages.ts +40 -6
- package/src/interactive/chat-loop.ts +13 -0
- package/src/interactive/chat-panel.ts +17 -1
- package/src/interactive/chat-renderer.ts +49 -24
- package/src/interactive/clio-editor.ts +44 -7
- package/src/interactive/context-meter.ts +10 -0
- package/src/interactive/context-overlay.ts +120 -7
- package/src/interactive/context-recall-command.ts +110 -0
- package/src/interactive/cost-overlay.ts +39 -8
- package/src/interactive/dispatch-board.ts +212 -35
- package/src/interactive/footer/widgets.ts +13 -0
- package/src/interactive/interactive-application.ts +6 -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 +37 -1
- package/src/interactive/memory-overlay.ts +89 -4
- package/src/interactive/model-session-replay.ts +21 -0
- package/src/interactive/overlay-ask-user-lifecycle.ts +1 -1
- package/src/interactive/overlay-frame.ts +5 -2
- package/src/interactive/overlay-general-openers.ts +46 -1
- package/src/interactive/overlay-key-routing.ts +41 -1
- package/src/interactive/overlay-lifecycle.ts +11 -4
- package/src/interactive/overlay-permission-lifecycle.ts +23 -8
- package/src/interactive/overlay-session-lifecycle.ts +8 -4
- 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/permission-hint.ts +35 -0
- package/src/interactive/permission-overlay.ts +95 -45
- package/src/interactive/renderers/tool-execution.ts +37 -51
- package/src/interactive/session-last-turn.ts +8 -1
- package/src/interactive/session-transcript.ts +2 -2
- package/src/interactive/session-usage-reseed.ts +36 -10
- package/src/interactive/slash-commands.ts +31 -4
- 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/turn-context.ts +333 -110
- package/src/interactive/turn-middleware.ts +7 -6
- package/src/interactive/turn-runtime.ts +37 -8
- package/src/interactive/turn-state.ts +3 -0
- package/src/interactive/worker-progress.ts +440 -0
- package/src/interactive/worker-stream.ts +51 -110
- package/src/tools/agent-tools.ts +39 -7
- package/src/tools/ask-user.ts +21 -1
- package/src/tools/bash.ts +144 -82
- package/src/tools/builtin-tool-catalog.ts +11 -5
- package/src/tools/context/index.ts +107 -5
- package/src/tools/context/surface.ts +3 -2
- package/src/tools/core-bootstrap.ts +21 -0
- package/src/tools/dispatch-arguments.ts +8 -0
- package/src/tools/dispatch-event-text.ts +19 -0
- package/src/tools/dispatch-runner.ts +9 -7
- package/src/tools/dispatch.ts +24 -1
- package/src/tools/monitor.ts +43 -20
- package/src/tools/registry.ts +72 -10
- package/src/tools/result-disposition.ts +706 -0
- package/src/tools/result-shaping.ts +321 -20
- package/src/tools/safe-exec.ts +2 -0
- package/src/tools/verify/authoring.ts +1120 -0
- package/src/tools/verify/catalog.ts +346 -0
- package/src/tools/verify/index.ts +13 -3
- package/src/tools/verify/scripts.ts +135 -37
- package/src/tools/verify/surface.ts +9 -5
- package/src/tools/worker-evidence.ts +54 -12
- package/src/worker/spec-contract.ts +43 -3
- package/dist/chunk-J7CWMCQD.js +0 -255
- package/dist/chunk-T6YILFSB.js +0 -80
- package/dist/chunk-VAKQQHWR.js +0 -434
- package/dist/chunk-VPAYEGVX.js +0 -184
- package/dist/chunk-XBXAASKX.js +0 -18
- package/dist/memory-WFZMGYHX.js +0 -236
- package/src/domains/eval/metrics/chaos-stream.ts +0 -93
|
@@ -8,6 +8,13 @@
|
|
|
8
8
|
* to a bus, or renders; the chat panel owns presentation and the wiring owns
|
|
9
9
|
* I/O, so every sequence below is testable as a pure fold.
|
|
10
10
|
*
|
|
11
|
+
* What a worker is saying and doing is not decided here. That is the canonical
|
|
12
|
+
* {@link WorkerProgressSnapshot} projection in `worker-progress.ts`, which the
|
|
13
|
+
* Fleet Runs board reads from the same events, so the two surfaces cannot drift
|
|
14
|
+
* on the answer tail, the tool names, or what a call is touching. This module
|
|
15
|
+
* owns the half the board has no use for: which assignment an event belongs to,
|
|
16
|
+
* which attempt is current, and what the receipt sealed.
|
|
17
|
+
*
|
|
11
18
|
* Three rules the fold enforces rather than documents:
|
|
12
19
|
*
|
|
13
20
|
* - Tool *names* only. Names come exclusively from the `clio_*` telemetry
|
|
@@ -34,10 +41,16 @@ import type {
|
|
|
34
41
|
DispatchStartedPayload,
|
|
35
42
|
RunAbortedPayload,
|
|
36
43
|
} from "../core/bus-events.js";
|
|
37
|
-
import { durableAssistantTextFromEvent, WORKER_OUTPUT_MAX_BYTES } from "../domains/dispatch/event-pump.js";
|
|
38
44
|
import type { RunKind } from "../domains/dispatch/types.js";
|
|
39
45
|
import type { WorkerRunOrigin, WorkerRunRuntime, WorkerRunRuntimeKind } from "../domains/session/index.js";
|
|
40
|
-
import {
|
|
46
|
+
import { createWorkerProgressFold, type WorkerProgressFold, type WorkerProgressSnapshot } from "./worker-progress.js";
|
|
47
|
+
|
|
48
|
+
export {
|
|
49
|
+
boundSettledText,
|
|
50
|
+
WORKER_LIVE_TAIL_LINES,
|
|
51
|
+
WORKER_TOOL_NAME_LIMIT,
|
|
52
|
+
} from "./worker-progress.js";
|
|
53
|
+
export type { WorkerProgressSnapshot };
|
|
41
54
|
|
|
42
55
|
export interface WorkerAttempt {
|
|
43
56
|
runId: string;
|
|
@@ -95,6 +108,8 @@ export interface WorkerEntryState {
|
|
|
95
108
|
droppedLines: number;
|
|
96
109
|
/** Distinct tool names in first-use order, bounded. */
|
|
97
110
|
tools: string[];
|
|
111
|
+
/** Canonical live projection. Absent only on receipt-based session replay. */
|
|
112
|
+
progress?: WorkerProgressSnapshot;
|
|
98
113
|
/** Every attempt of this assignment, oldest first. */
|
|
99
114
|
attempts: WorkerAttempt[];
|
|
100
115
|
pending: boolean;
|
|
@@ -143,23 +158,6 @@ export interface WorkerStream {
|
|
|
143
158
|
reset(): void;
|
|
144
159
|
}
|
|
145
160
|
|
|
146
|
-
/**
|
|
147
|
-
* Lines of worker prose kept while a run is live. The tail is what a streaming
|
|
148
|
-
* answer is about, so the head is what gets dropped; once the run settles the
|
|
149
|
-
* body is replaced by the receipt-sealed answer and anchors at the head, which
|
|
150
|
-
* is the same rule the thinking block already follows.
|
|
151
|
-
*/
|
|
152
|
-
export const WORKER_LIVE_TAIL_LINES = 40;
|
|
153
|
-
|
|
154
|
-
/** Distinct tool names carried on an entry. The receipt's call count carries the total. */
|
|
155
|
-
export const WORKER_TOOL_NAME_LIMIT = 8;
|
|
156
|
-
|
|
157
|
-
const WORKER_TEXT_TRUNCATION_MARKER = "";
|
|
158
|
-
|
|
159
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
160
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
161
|
function nonEmptyString(value: unknown): string | undefined {
|
|
164
162
|
return typeof value === "string" && value.trim().length > 0 ? value : undefined;
|
|
165
163
|
}
|
|
@@ -202,58 +200,6 @@ export function workerTargetLabel(runtime: WorkerRunRuntime): string {
|
|
|
202
200
|
return runtime.targetId ?? runtime.wireModelId ?? "unknown";
|
|
203
201
|
}
|
|
204
202
|
|
|
205
|
-
/**
|
|
206
|
-
* Incremental assistant prose carried by one worker event.
|
|
207
|
-
*
|
|
208
|
-
* Native workers slim `message_update` down to `assistantMessageEvent.delta`
|
|
209
|
-
* before it crosses the NDJSON seam (src/worker/event-projection.ts); the ACP
|
|
210
|
-
* mapper emits a top-level `text_delta` carrying `text`. Both spellings are
|
|
211
|
-
* read here so ACP peers need no separate UI path.
|
|
212
|
-
*/
|
|
213
|
-
function textDelta(event: unknown): string {
|
|
214
|
-
if (!isRecord(event)) return "";
|
|
215
|
-
if (event.type === "message_update") {
|
|
216
|
-
const assistantEvent = isRecord(event.assistantMessageEvent) ? event.assistantMessageEvent : null;
|
|
217
|
-
if (assistantEvent?.type !== "text_delta") return "";
|
|
218
|
-
return typeof assistantEvent.delta === "string" ? assistantEvent.delta : "";
|
|
219
|
-
}
|
|
220
|
-
if (event.type !== "text_delta") return "";
|
|
221
|
-
if (typeof event.delta === "string") return event.delta;
|
|
222
|
-
return typeof event.text === "string" ? event.text : "";
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/** Tool name from Clio's own telemetry. Never from `tool_execution_*`, whose args are the call's arguments. */
|
|
226
|
-
function toolName(event: unknown): string | undefined {
|
|
227
|
-
if (!isRecord(event)) return undefined;
|
|
228
|
-
if (event.type !== "clio_tool_start" && event.type !== "clio_tool_finish") return undefined;
|
|
229
|
-
const payload = isRecord(event.payload) ? event.payload : null;
|
|
230
|
-
return nonEmptyString(payload?.tool);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
function lineCount(text: string): number {
|
|
234
|
-
if (text.length === 0) return 0;
|
|
235
|
-
let lines = 1;
|
|
236
|
-
for (let index = 0; index < text.length; index += 1) {
|
|
237
|
-
if (text[index] === "\n") lines += 1;
|
|
238
|
-
}
|
|
239
|
-
return lines;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/** Keep the newest `WORKER_LIVE_TAIL_LINES` lines; report what that cost. */
|
|
243
|
-
function boundLiveText(text: string): { text: string; dropped: number } {
|
|
244
|
-
const lines = text.split("\n");
|
|
245
|
-
if (lines.length <= WORKER_LIVE_TAIL_LINES) return { text, dropped: 0 };
|
|
246
|
-
const dropped = lines.length - WORKER_LIVE_TAIL_LINES;
|
|
247
|
-
return { text: lines.slice(dropped).join("\n"), dropped };
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/** Head-anchored byte bound for a settled answer, matching the receipt's own bound. */
|
|
251
|
-
export function boundSettledText(text: string): { text: string; dropped: number } {
|
|
252
|
-
const bounded = truncateUtf8(text, WORKER_OUTPUT_MAX_BYTES, WORKER_TEXT_TRUNCATION_MARKER);
|
|
253
|
-
if (bounded === text) return { text, dropped: 0 };
|
|
254
|
-
return { text: bounded, dropped: Math.max(0, lineCount(text) - lineCount(bounded)) };
|
|
255
|
-
}
|
|
256
|
-
|
|
257
203
|
/**
|
|
258
204
|
* Terminal facts a lifecycle payload can supply on its own. Used only when the
|
|
259
205
|
* sealed receipt is unreadable, so the block still reports an honest outcome
|
|
@@ -294,8 +240,21 @@ export function createWorkerStream(options: WorkerStreamOptions = {}): WorkerStr
|
|
|
294
240
|
const attemptByAssignment = new Map<string, number>();
|
|
295
241
|
/** Every attempt run id to its assignment, so progress and terminal events find their entry. */
|
|
296
242
|
const assignmentByRun = new Map<string, string>();
|
|
297
|
-
/**
|
|
298
|
-
|
|
243
|
+
/**
|
|
244
|
+
* The canonical progress projection per assignment. One fold spans every
|
|
245
|
+
* attempt of an assignment, because a failover keeps streaming into the block
|
|
246
|
+
* the operator is already reading.
|
|
247
|
+
*/
|
|
248
|
+
const progressByAssignment = new Map<string, WorkerProgressFold>();
|
|
249
|
+
|
|
250
|
+
/** Copy the canonical projection onto the entry fields the block renders. */
|
|
251
|
+
const applyProgress = (entry: WorkerEntryState, fold: WorkerProgressFold): void => {
|
|
252
|
+
const snapshot = fold.snapshot();
|
|
253
|
+
entry.text = snapshot.tailText;
|
|
254
|
+
entry.droppedLines = snapshot.droppedLines;
|
|
255
|
+
entry.tools = [...snapshot.toolNames];
|
|
256
|
+
entry.progress = snapshot;
|
|
257
|
+
};
|
|
299
258
|
|
|
300
259
|
/** The entry a run id addresses, and only while that run is the entry's current attempt. */
|
|
301
260
|
const currentEntryForRun = (runId: unknown): WorkerEntryState | undefined => {
|
|
@@ -315,11 +274,10 @@ export function createWorkerStream(options: WorkerStreamOptions = {}): WorkerStr
|
|
|
315
274
|
// Terminal truth is the sealed answer. A run whose receipt could not be
|
|
316
275
|
// read keeps whatever durable text its own stream produced, and a run that
|
|
317
276
|
// produced none keeps the live tail rather than blanking the block.
|
|
318
|
-
const
|
|
319
|
-
if (
|
|
320
|
-
|
|
321
|
-
entry
|
|
322
|
-
entry.droppedLines = bounded.dropped;
|
|
277
|
+
const fold = progressByAssignment.get(entry.assignmentId);
|
|
278
|
+
if (fold !== undefined) {
|
|
279
|
+
fold.settle(nonEmptyString(facts.text));
|
|
280
|
+
applyProgress(entry, fold);
|
|
323
281
|
}
|
|
324
282
|
return { kind: "updated", entry };
|
|
325
283
|
};
|
|
@@ -343,10 +301,16 @@ export function createWorkerStream(options: WorkerStreamOptions = {}): WorkerStr
|
|
|
343
301
|
delete existing.receipt;
|
|
344
302
|
existing.attempts.push({ runId, targetLabel: workerTargetLabel(runtime) });
|
|
345
303
|
assignmentByRun.set(runId, assignmentId);
|
|
304
|
+
const progress = progressByAssignment.get(assignmentId);
|
|
305
|
+
if (progress !== undefined) {
|
|
306
|
+
progress.restart();
|
|
307
|
+
applyProgress(existing, progress);
|
|
308
|
+
}
|
|
346
309
|
return { kind: "updated", entry: existing };
|
|
347
310
|
}
|
|
348
311
|
if (payload.requestOrigin !== "user" && payload.requestOrigin !== "agent") return null;
|
|
349
312
|
attemptByAssignment.set(assignmentId, payload.attempt);
|
|
313
|
+
const progress = createWorkerProgressFold();
|
|
350
314
|
const entry: WorkerEntryState = {
|
|
351
315
|
assignmentId,
|
|
352
316
|
runId,
|
|
@@ -356,49 +320,26 @@ export function createWorkerStream(options: WorkerStreamOptions = {}): WorkerStr
|
|
|
356
320
|
text: "",
|
|
357
321
|
droppedLines: 0,
|
|
358
322
|
tools: [],
|
|
323
|
+
progress: progress.snapshot(),
|
|
359
324
|
attempts: [{ runId, targetLabel: workerTargetLabel(runtime) }],
|
|
360
325
|
pending: true,
|
|
361
326
|
...(payload.parentToolCallId !== undefined ? { parentToolCallId: payload.parentToolCallId } : {}),
|
|
362
327
|
};
|
|
363
328
|
byAssignment.set(assignmentId, entry);
|
|
364
329
|
assignmentByRun.set(runId, assignmentId);
|
|
330
|
+
progressByAssignment.set(assignmentId, progress);
|
|
365
331
|
return { kind: "created", entry };
|
|
366
332
|
},
|
|
367
333
|
|
|
368
334
|
progress(payload): WorkerStreamChange | null {
|
|
369
335
|
const entry = currentEntryForRun(payload.runId);
|
|
370
336
|
if (entry === undefined || !entry.pending) return null;
|
|
371
|
-
const
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
entry.text = bounded.text;
|
|
378
|
-
entry.droppedLines += bounded.dropped;
|
|
379
|
-
changed = true;
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
// A durable message_end is the answer as the receipt will seal it. An
|
|
383
|
-
// ACP peer that streamed no deltas reaches the transcript only here.
|
|
384
|
-
const durable = durableAssistantTextFromEvent(event);
|
|
385
|
-
if (durable.trim().length > 0) {
|
|
386
|
-
durableTextByRun.set(entry.runId, durable);
|
|
387
|
-
if (delta.length === 0 && entry.text.trim().length === 0) {
|
|
388
|
-
const bounded = boundLiveText(durable);
|
|
389
|
-
entry.text = bounded.text;
|
|
390
|
-
entry.droppedLines += bounded.dropped;
|
|
391
|
-
}
|
|
392
|
-
changed = true;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
const tool = toolName(event);
|
|
396
|
-
if (tool !== undefined && !entry.tools.includes(tool) && entry.tools.length < WORKER_TOOL_NAME_LIMIT) {
|
|
397
|
-
entry.tools.push(tool);
|
|
398
|
-
changed = true;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
return changed ? { kind: "updated", entry } : null;
|
|
337
|
+
const fold = progressByAssignment.get(entry.assignmentId);
|
|
338
|
+
// Everything the block shows about the stream comes from the canonical
|
|
339
|
+
// projection, so an event that moved nothing visible repaints nothing.
|
|
340
|
+
if (fold === undefined || !fold.observe(payload.event)) return null;
|
|
341
|
+
applyProgress(entry, fold);
|
|
342
|
+
return { kind: "updated", entry };
|
|
402
343
|
},
|
|
403
344
|
|
|
404
345
|
completed(payload): WorkerStreamChange | null {
|
|
@@ -440,7 +381,7 @@ export function createWorkerStream(options: WorkerStreamOptions = {}): WorkerStr
|
|
|
440
381
|
byAssignment.clear();
|
|
441
382
|
attemptByAssignment.clear();
|
|
442
383
|
assignmentByRun.clear();
|
|
443
|
-
|
|
384
|
+
progressByAssignment.clear();
|
|
444
385
|
},
|
|
445
386
|
};
|
|
446
387
|
}
|
package/src/tools/agent-tools.ts
CHANGED
|
@@ -22,12 +22,14 @@ import { type SkillActivation, skillActivationFromToolDetails } from "../core/sk
|
|
|
22
22
|
import type { ToolName } from "../core/tool-names.js";
|
|
23
23
|
import { ToolNames } from "../core/tool-names.js";
|
|
24
24
|
import type { ResolvedRuntimeTarget } from "../domains/providers/index.js";
|
|
25
|
+
import { type CallActionDescriptor, describeCallAction } from "../domains/safety/call-target.js";
|
|
25
26
|
import type { SafetyDecision } from "../domains/safety/contract.js";
|
|
26
27
|
import { formatModelRejection } from "../domains/safety/rejection-feedback.js";
|
|
27
28
|
import { validateEngineToolArguments } from "../engine/ai.js";
|
|
28
29
|
import type { AgentTool, AgentToolResult, AgentToolUpdateCallback } from "../engine/types.js";
|
|
29
30
|
import { applyToolProfile, type ToolProfileName } from "./profiles.js";
|
|
30
31
|
import type { ToolInvokeOptions, ToolRegistry, ToolResult, ToolSpec } from "./registry.js";
|
|
32
|
+
import { isDispositionedToolResultError, toolResultContextText } from "./result-disposition.js";
|
|
31
33
|
|
|
32
34
|
/**
|
|
33
35
|
* Lightweight per-call observability hook. Default no-op so unused
|
|
@@ -44,6 +46,12 @@ export type ToolOutcome = "ok" | "error" | "blocked";
|
|
|
44
46
|
|
|
45
47
|
export interface ToolStartEvent {
|
|
46
48
|
tool: string;
|
|
49
|
+
/**
|
|
50
|
+
* The engine's id for this call, when the producer has one. New producers
|
|
51
|
+
* put the same id on start and finish so concurrent calls of one tool remain
|
|
52
|
+
* independently attributable. Optional for direct callers and old streams.
|
|
53
|
+
*/
|
|
54
|
+
toolCallId?: string;
|
|
47
55
|
posture: "operating";
|
|
48
56
|
/**
|
|
49
57
|
* Wall-clock anchor for the instant the call began, for a human correlating
|
|
@@ -52,6 +60,14 @@ export interface ToolStartEvent {
|
|
|
52
60
|
* event is measured on that process's monotonic clock instead.
|
|
53
61
|
*/
|
|
54
62
|
startedAt: number;
|
|
63
|
+
/**
|
|
64
|
+
* What this call is doing, as a bounded redacted descriptor composed here
|
|
65
|
+
* where the arguments are trusted. This is the only account of a worker's
|
|
66
|
+
* arguments that may cross the NDJSON stdout seam; the arguments themselves
|
|
67
|
+
* never do, so an operator surface reads a verb and an object it can show,
|
|
68
|
+
* never an argument object it would have to sanitize itself.
|
|
69
|
+
*/
|
|
70
|
+
action?: CallActionDescriptor;
|
|
55
71
|
}
|
|
56
72
|
|
|
57
73
|
export interface ToolFinishEvent {
|
|
@@ -99,10 +115,10 @@ type WorkerToolOkDetails = { kind: "ok" } & Record<string, unknown>;
|
|
|
99
115
|
function projectToolResult(result: ToolResult): WorkerAgentToolResult {
|
|
100
116
|
const details = { ...(result.details ?? {}), kind: result.kind } as { kind: "ok" } | { kind: "error" };
|
|
101
117
|
if (result.kind === "error") {
|
|
102
|
-
return { content: [{ type: "text", text: result
|
|
118
|
+
return { content: [{ type: "text", text: toolResultContextText(result) }], details };
|
|
103
119
|
}
|
|
104
120
|
return {
|
|
105
|
-
content: [{ type: "text", text: result
|
|
121
|
+
content: [{ type: "text", text: toolResultContextText(result) }],
|
|
106
122
|
details,
|
|
107
123
|
...(result.terminate === true ? { terminate: true } : {}),
|
|
108
124
|
};
|
|
@@ -119,6 +135,8 @@ interface RunValidatedToolCallInput {
|
|
|
119
135
|
signal?: AbortSignal;
|
|
120
136
|
telemetry?: ToolTelemetry;
|
|
121
137
|
invokeOptions?: Partial<ToolInvokeOptions>;
|
|
138
|
+
/** Agent loops can preserve canonical failure envelopes and classify them after execution. */
|
|
139
|
+
returnDispositionedErrors?: boolean;
|
|
122
140
|
}
|
|
123
141
|
|
|
124
142
|
async function runValidatedToolCall(input: RunValidatedToolCallInput): Promise<WorkerAgentToolResult> {
|
|
@@ -127,11 +145,21 @@ async function runValidatedToolCall(input: RunValidatedToolCallInput): Promise<W
|
|
|
127
145
|
// spans the call, so `durationMs` survives a clock correction mid-tool.
|
|
128
146
|
const startedAt = Date.now();
|
|
129
147
|
const startedAtClock = performance.now();
|
|
130
|
-
|
|
131
|
-
//
|
|
132
|
-
// outcome to the engine's `tool_execution_end` for the same call.
|
|
148
|
+
// Stamped onto both lifecycle events so a concurrent finish resolves only
|
|
149
|
+
// the start for its own engine call. Direct callers may legitimately omit it.
|
|
133
150
|
const callId = input.invokeOptions?.toolCallId;
|
|
134
151
|
const withCallId = callId === undefined ? {} : { toolCallId: callId };
|
|
152
|
+
// The one seam that holds validated arguments and publishes telemetry, so it
|
|
153
|
+
// is where the redacted descriptor is composed. Everything downstream of here
|
|
154
|
+
// sees the descriptor and never the arguments.
|
|
155
|
+
const action = describeCallAction(spec.name, args);
|
|
156
|
+
telemetry?.onStart?.({
|
|
157
|
+
tool: spec.name,
|
|
158
|
+
...withCallId,
|
|
159
|
+
posture: "operating",
|
|
160
|
+
startedAt,
|
|
161
|
+
...(action !== null ? { action } : {}),
|
|
162
|
+
});
|
|
135
163
|
const invokeOpts: ToolInvokeOptions = {};
|
|
136
164
|
if (input.invokeOptions) Object.assign(invokeOpts, input.invokeOptions);
|
|
137
165
|
if (signal) invokeOpts.signal = signal;
|
|
@@ -183,13 +211,16 @@ async function runValidatedToolCall(input: RunValidatedToolCallInput): Promise<W
|
|
|
183
211
|
reason: verdict.result.message,
|
|
184
212
|
decision: verdict.decision,
|
|
185
213
|
});
|
|
186
|
-
|
|
214
|
+
if (input.returnDispositionedErrors === true && isDispositionedToolResultError(verdict.result)) {
|
|
215
|
+
return projectToolResult(verdict.result);
|
|
216
|
+
}
|
|
217
|
+
throw new Error(toolResultContextText(verdict.result));
|
|
187
218
|
}
|
|
188
219
|
const toolDetails = isRecord(verdict.result.details) ? verdict.result.details : {};
|
|
189
220
|
const skillActivation =
|
|
190
221
|
spec.name === ToolNames.Context ? skillActivationFromToolDetails(toolDetails, input.invokeOptions?.turnId) : null;
|
|
191
222
|
const result: AgentToolResult<WorkerToolOkDetails> = {
|
|
192
|
-
content: [{ type: "text", text: verdict.result
|
|
223
|
+
content: [{ type: "text", text: toolResultContextText(verdict.result) }],
|
|
193
224
|
details: { ...toolDetails, kind: "ok" },
|
|
194
225
|
};
|
|
195
226
|
if (verdict.result.terminate === true) {
|
|
@@ -291,6 +322,7 @@ function toAgentTool(
|
|
|
291
322
|
spec,
|
|
292
323
|
args: params as Record<string, unknown>,
|
|
293
324
|
registry,
|
|
325
|
+
returnDispositionedErrors: true,
|
|
294
326
|
};
|
|
295
327
|
if (signal) callInput.signal = signal;
|
|
296
328
|
if (telemetry) callInput.telemetry = telemetry;
|
package/src/tools/ask-user.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { Type } from "typebox";
|
|
|
5
5
|
import { ToolNames } from "../core/tool-names.js";
|
|
6
6
|
import { clioStateDir } from "../core/xdg.js";
|
|
7
7
|
import { type AutonomyExposure, DEFAULT_AUTONOMY_EXPOSURE } from "../domains/safety/autonomy.js";
|
|
8
|
+
import { classifyDecisionPresentation, decisionFactsForAnswer } from "../domains/safety/decision-presentation.js";
|
|
8
9
|
import { StringEnum } from "../engine/ai.js";
|
|
9
10
|
import type {
|
|
10
11
|
AskUserToolPolicy,
|
|
@@ -57,6 +58,7 @@ export interface AskUserResult {
|
|
|
57
58
|
|
|
58
59
|
export interface AskUserCall {
|
|
59
60
|
action: AskUserAction;
|
|
61
|
+
exposure?: AutonomyExposure;
|
|
60
62
|
mode?: AskUserMode;
|
|
61
63
|
questions?: AskUserQuestion[];
|
|
62
64
|
decisions?: AskUserDecision[];
|
|
@@ -284,6 +286,7 @@ export function normalizeAskUserCall(args: Record<string, unknown>): { call?: As
|
|
|
284
286
|
return {
|
|
285
287
|
call: {
|
|
286
288
|
action: "ask",
|
|
289
|
+
exposure: exposure.exposure ?? DEFAULT_AUTONOMY_EXPOSURE,
|
|
287
290
|
...(mode.mode ? { mode: mode.mode } : {}),
|
|
288
291
|
questions: questions.questions,
|
|
289
292
|
...(summary ? { summary } : {}),
|
|
@@ -319,6 +322,7 @@ function createStandalonePolicy(options?: ToolInvokeOptions): AskUserToolPolicy
|
|
|
319
322
|
updatedAt: now,
|
|
320
323
|
...(options?.sessionId ? { sessionId: options.sessionId } : {}),
|
|
321
324
|
...(options?.turnId ? { turnId: options.turnId } : {}),
|
|
325
|
+
exposure: DEFAULT_AUTONOMY_EXPOSURE,
|
|
322
326
|
rounds: [],
|
|
323
327
|
decisions: [],
|
|
324
328
|
inFlight: false,
|
|
@@ -335,6 +339,13 @@ function hydratePolicy(policy: AskUserToolPolicy, options?: ToolInvokeOptions):
|
|
|
335
339
|
if (options?.turnId && !policy.turnId) policy.turnId = options.turnId;
|
|
336
340
|
}
|
|
337
341
|
|
|
342
|
+
/** Once an interview is outward, a later local round cannot lower its replay tier. */
|
|
343
|
+
function mergePolicyExposure(policy: AskUserToolPolicy, exposure: AutonomyExposure): AutonomyExposure {
|
|
344
|
+
const merged = policy.exposure === "outward" || exposure === "outward" ? "outward" : "local";
|
|
345
|
+
policy.exposure = merged;
|
|
346
|
+
return merged;
|
|
347
|
+
}
|
|
348
|
+
|
|
338
349
|
function transcriptQuestions(questions: ReadonlyArray<AskUserQuestion>): AskUserTranscriptQuestion[] {
|
|
339
350
|
return questions.map((question) => ({
|
|
340
351
|
question: question.question,
|
|
@@ -455,6 +466,7 @@ async function persistAskUserTranscript(
|
|
|
455
466
|
...(policy.endedAt ? { endedAt: policy.endedAt } : {}),
|
|
456
467
|
...(policy.sessionId ? { sessionId: policy.sessionId } : {}),
|
|
457
468
|
...(policy.turnId ? { turnId: policy.turnId } : {}),
|
|
469
|
+
exposure: policy.exposure ?? DEFAULT_AUTONOMY_EXPOSURE,
|
|
458
470
|
...(policy.summary ? { summary: policy.summary } : {}),
|
|
459
471
|
decisions: policy.decisions,
|
|
460
472
|
rounds: policy.rounds,
|
|
@@ -478,6 +490,7 @@ function compactInterview(
|
|
|
478
490
|
rounds: policy.rounds.length,
|
|
479
491
|
max_rounds: policy.maxCalls,
|
|
480
492
|
transcript_path: policy.transcriptPath ?? null,
|
|
493
|
+
exposure: policy.exposure ?? DEFAULT_AUTONOMY_EXPOSURE,
|
|
481
494
|
latest_answers: latestAnswers,
|
|
482
495
|
decisions: policy.decisions,
|
|
483
496
|
...(policy.summary ? { summary: policy.summary } : {}),
|
|
@@ -591,6 +604,7 @@ export function createAskUserTool(deps: AskUserToolDeps = {}): ToolSpec {
|
|
|
591
604
|
return completeInterview(policy, "complete", options, call.summary, call.decisions ?? []);
|
|
592
605
|
}
|
|
593
606
|
const questions = call.questions ?? [];
|
|
607
|
+
const exposure = mergePolicyExposure(policy, call.exposure ?? DEFAULT_AUTONOMY_EXPOSURE);
|
|
594
608
|
if (call.max_rounds !== undefined) {
|
|
595
609
|
const nextLimit = policy.callCount === 0 ? call.max_rounds : Math.max(policy.maxCalls, call.max_rounds);
|
|
596
610
|
policy.maxCalls = Math.max(nextLimit, policy.callCount + 1);
|
|
@@ -632,7 +646,13 @@ export function createAskUserTool(deps: AskUserToolDeps = {}): ToolSpec {
|
|
|
632
646
|
if (call.summary) policy.summary = call.summary;
|
|
633
647
|
const handler = deps.askUser ?? defaultAskUserHandler;
|
|
634
648
|
try {
|
|
635
|
-
const result = normalizeAskUserResult(
|
|
649
|
+
const result = normalizeAskUserResult(
|
|
650
|
+
questions,
|
|
651
|
+
await handler(questions, {
|
|
652
|
+
...options,
|
|
653
|
+
decisionPresentation: classifyDecisionPresentation(decisionFactsForAnswer(exposure)),
|
|
654
|
+
}),
|
|
655
|
+
);
|
|
636
656
|
const answeredAt = new Date().toISOString();
|
|
637
657
|
policy.callCount += 1;
|
|
638
658
|
policy.askedQuestionKeys.add(key);
|