@relayflows/sdk 2.0.9 → 2.0.11
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/dist/adapters/base.d.ts +46 -0
- package/dist/adapters/base.d.ts.map +1 -0
- package/dist/adapters/base.js +15 -0
- package/dist/adapters/base.js.map +1 -0
- package/dist/adapters/claude.d.ts +5 -0
- package/dist/adapters/claude.d.ts.map +1 -0
- package/dist/adapters/claude.js +44 -0
- package/dist/adapters/claude.js.map +1 -0
- package/dist/adapters/codex.d.ts +5 -0
- package/dist/adapters/codex.d.ts.map +1 -0
- package/dist/adapters/codex.js +45 -0
- package/dist/adapters/codex.js.map +1 -0
- package/dist/adapters/index.d.ts +14 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +29 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/wrapper.d.ts +12 -0
- package/dist/adapters/wrapper.d.ts.map +1 -0
- package/dist/adapters/wrapper.js +31 -0
- package/dist/adapters/wrapper.js.map +1 -0
- package/dist/agent-relay-receipt.d.ts +24 -0
- package/dist/agent-relay-receipt.d.ts.map +1 -0
- package/dist/agent-relay-receipt.js +66 -0
- package/dist/agent-relay-receipt.js.map +1 -0
- package/dist/agent-relay-state.d.ts +18 -0
- package/dist/agent-relay-state.d.ts.map +1 -0
- package/dist/agent-relay-state.js +58 -0
- package/dist/agent-relay-state.js.map +1 -0
- package/dist/agent-relay-transport.d.ts +31 -0
- package/dist/agent-relay-transport.d.ts.map +1 -0
- package/dist/agent-relay-transport.js +199 -0
- package/dist/agent-relay-transport.js.map +1 -0
- package/dist/authored-budget.d.ts +13 -0
- package/dist/authored-budget.d.ts.map +1 -0
- package/dist/authored-budget.js +78 -0
- package/dist/authored-budget.js.map +1 -0
- package/dist/authored-flow-error.d.ts +2 -21
- package/dist/authored-flow-error.d.ts.map +1 -1
- package/dist/authored-flow-error.js +1 -12
- package/dist/authored-flow-error.js.map +1 -1
- package/dist/authored-flow-executor.d.ts +13 -7
- package/dist/authored-flow-executor.d.ts.map +1 -1
- package/dist/authored-flow-executor.js +116 -235
- package/dist/authored-flow-executor.js.map +1 -1
- package/dist/authored-flow-loader.d.ts +10 -1
- package/dist/authored-flow-loader.d.ts.map +1 -1
- package/dist/authored-flow-loader.js +56 -3
- package/dist/authored-flow-loader.js.map +1 -1
- package/dist/authored-flow-operation.d.ts +9 -1
- package/dist/authored-flow-operation.d.ts.map +1 -1
- package/dist/authored-flow-operation.js +35 -4
- package/dist/authored-flow-operation.js.map +1 -1
- package/dist/authored-helper-effect.d.ts +12 -0
- package/dist/authored-helper-effect.d.ts.map +1 -0
- package/dist/authored-helper-effect.js +144 -0
- package/dist/authored-helper-effect.js.map +1 -0
- package/dist/authored-mcp.d.ts +17 -0
- package/dist/authored-mcp.d.ts.map +1 -0
- package/dist/authored-mcp.js +171 -0
- package/dist/authored-mcp.js.map +1 -0
- package/dist/authored-memory.d.ts +7 -0
- package/dist/authored-memory.d.ts.map +1 -0
- package/dist/authored-memory.js +60 -0
- package/dist/authored-memory.js.map +1 -0
- package/dist/authored-plugin-effect.d.ts +16 -0
- package/dist/authored-plugin-effect.d.ts.map +1 -0
- package/dist/authored-plugin-effect.js +163 -0
- package/dist/authored-plugin-effect.js.map +1 -0
- package/dist/authored-step-output.d.ts +23 -0
- package/dist/authored-step-output.d.ts.map +1 -0
- package/dist/authored-step-output.js +67 -0
- package/dist/authored-step-output.js.map +1 -0
- package/dist/authored-worker-step.d.ts +15 -0
- package/dist/authored-worker-step.d.ts.map +1 -0
- package/dist/authored-worker-step.js +136 -0
- package/dist/authored-worker-step.js.map +1 -0
- package/dist/budget-preflight.d.ts +5 -0
- package/dist/budget-preflight.d.ts.map +1 -0
- package/dist/budget-preflight.js +33 -0
- package/dist/budget-preflight.js.map +1 -0
- package/dist/budget.d.ts +14 -0
- package/dist/budget.d.ts.map +1 -0
- package/dist/budget.js +52 -0
- package/dist/budget.js.map +1 -0
- package/dist/bundle-transport.d.ts +18 -0
- package/dist/bundle-transport.d.ts.map +1 -0
- package/dist/bundle-transport.js +111 -0
- package/dist/bundle-transport.js.map +1 -0
- package/dist/bundle-typescript.d.ts +8 -0
- package/dist/bundle-typescript.d.ts.map +1 -0
- package/dist/bundle-typescript.js +108 -0
- package/dist/bundle-typescript.js.map +1 -0
- package/dist/bundle.d.ts +25 -0
- package/dist/bundle.d.ts.map +1 -0
- package/dist/bundle.js +199 -0
- package/dist/bundle.js.map +1 -0
- package/dist/child-stop.d.ts +59 -0
- package/dist/child-stop.d.ts.map +1 -0
- package/dist/child-stop.js +94 -0
- package/dist/child-stop.js.map +1 -0
- package/dist/cli/add.d.ts +6 -0
- package/dist/cli/add.d.ts.map +1 -0
- package/dist/cli/add.js +47 -0
- package/dist/cli/add.js.map +1 -0
- package/dist/cli/build.d.ts +13 -0
- package/dist/cli/build.d.ts.map +1 -0
- package/dist/cli/build.js +224 -0
- package/dist/cli/build.js.map +1 -0
- package/dist/cli/bundle-preflight.d.ts +5 -0
- package/dist/cli/bundle-preflight.d.ts.map +1 -0
- package/dist/cli/bundle-preflight.js +28 -0
- package/dist/cli/bundle-preflight.js.map +1 -0
- package/dist/cli/check-helper-body.d.ts +4 -0
- package/dist/cli/check-helper-body.d.ts.map +1 -0
- package/dist/cli/check-helper-body.js +15 -0
- package/dist/cli/check-helper-body.js.map +1 -0
- package/dist/cli/check-triggers.d.ts +14 -0
- package/dist/cli/check-triggers.d.ts.map +1 -0
- package/dist/cli/check-triggers.js +37 -0
- package/dist/cli/check-triggers.js.map +1 -0
- package/dist/cli/check-typescript.d.ts +20 -0
- package/dist/cli/check-typescript.d.ts.map +1 -0
- package/dist/cli/check-typescript.js +54 -0
- package/dist/cli/check-typescript.js.map +1 -0
- package/dist/cli/check.d.ts +36 -3
- package/dist/cli/check.d.ts.map +1 -1
- package/dist/cli/check.js +122 -11
- package/dist/cli/check.js.map +1 -1
- package/dist/cli/cloud-run.d.ts +8 -0
- package/dist/cli/cloud-run.d.ts.map +1 -0
- package/dist/cli/cloud-run.js +50 -0
- package/dist/cli/cloud-run.js.map +1 -0
- package/dist/cli/deploy.d.ts +9 -0
- package/dist/cli/deploy.d.ts.map +1 -0
- package/dist/cli/deploy.js +58 -0
- package/dist/cli/deploy.js.map +1 -0
- package/dist/cli/deterministic-failure.d.ts +5 -0
- package/dist/cli/deterministic-failure.d.ts.map +1 -0
- package/dist/cli/deterministic-failure.js +66 -0
- package/dist/cli/deterministic-failure.js.map +1 -0
- package/dist/cli/direct-run.d.ts.map +1 -1
- package/dist/cli/direct-run.js +83 -18
- package/dist/cli/direct-run.js.map +1 -1
- package/dist/cli/hn-monitor.d.ts.map +1 -1
- package/dist/cli/hn-monitor.js +2 -1
- package/dist/cli/hn-monitor.js.map +1 -1
- package/dist/cli/replay.d.ts +12 -0
- package/dist/cli/replay.d.ts.map +1 -0
- package/dist/cli/replay.js +82 -0
- package/dist/cli/replay.js.map +1 -0
- package/dist/cli/reuse.d.ts +8 -0
- package/dist/cli/reuse.d.ts.map +1 -0
- package/dist/cli/reuse.js +25 -0
- package/dist/cli/reuse.js.map +1 -0
- package/dist/cli/run-digest.d.ts +4 -0
- package/dist/cli/run-digest.d.ts.map +1 -0
- package/dist/cli/run-digest.js +24 -0
- package/dist/cli/run-digest.js.map +1 -0
- package/dist/cli/run.d.ts +16 -5
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +99 -17
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/serve-webhook.d.ts +40 -0
- package/dist/cli/serve-webhook.d.ts.map +1 -0
- package/dist/cli/serve-webhook.js +233 -0
- package/dist/cli/serve-webhook.js.map +1 -0
- package/dist/cli/tick-runner.d.ts.map +1 -1
- package/dist/cli/tick-runner.js +2 -1
- package/dist/cli/tick-runner.js.map +1 -1
- package/dist/cli-adapter.d.ts +8 -14
- package/dist/cli-adapter.d.ts.map +1 -1
- package/dist/cli-adapter.js +19 -64
- package/dist/cli-adapter.js.map +1 -1
- package/dist/cli-watch.d.ts +13 -0
- package/dist/cli-watch.d.ts.map +1 -0
- package/dist/cli-watch.js +185 -0
- package/dist/cli-watch.js.map +1 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +387 -14
- package/dist/cli.js.map +1 -1
- package/dist/cloud-http.d.ts +22 -0
- package/dist/cloud-http.d.ts.map +1 -0
- package/dist/cloud-http.js +84 -0
- package/dist/cloud-http.js.map +1 -0
- package/dist/cloud-run.d.ts +38 -0
- package/dist/cloud-run.d.ts.map +1 -0
- package/dist/cloud-run.js +112 -0
- package/dist/cloud-run.js.map +1 -0
- package/dist/compile.d.ts +21 -3
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +97 -23
- package/dist/compile.js.map +1 -1
- package/dist/create-flow.d.ts +17 -0
- package/dist/create-flow.d.ts.map +1 -0
- package/dist/create-flow.js +72 -0
- package/dist/create-flow.js.map +1 -0
- package/dist/daemon-connection.d.ts +14 -0
- package/dist/daemon-connection.d.ts.map +1 -1
- package/dist/daemon-connection.js +33 -1
- package/dist/daemon-connection.js.map +1 -1
- package/dist/demo-hn-monitor.js +2 -1
- package/dist/demo-hn-monitor.js.map +1 -1
- package/dist/effect-channel.d.ts +30 -0
- package/dist/effect-channel.d.ts.map +1 -0
- package/dist/effect-channel.js +71 -0
- package/dist/effect-channel.js.map +1 -0
- package/dist/failure-kinds.d.ts +14 -3
- package/dist/failure-kinds.d.ts.map +1 -1
- package/dist/failure-kinds.js +27 -0
- package/dist/failure-kinds.js.map +1 -1
- package/dist/gate-contract.d.ts.map +1 -1
- package/dist/gate-contract.js +9 -0
- package/dist/gate-contract.js.map +1 -1
- package/dist/helper-preflight.d.ts +18 -0
- package/dist/helper-preflight.d.ts.map +1 -0
- package/dist/helper-preflight.js +32 -0
- package/dist/helper-preflight.js.map +1 -0
- package/dist/helper-storage.d.ts +5 -0
- package/dist/helper-storage.d.ts.map +1 -0
- package/dist/helper-storage.js +31 -0
- package/dist/helper-storage.js.map +1 -0
- package/dist/helper-writeback.d.ts +12 -0
- package/dist/helper-writeback.d.ts.map +1 -0
- package/dist/helper-writeback.js +95 -0
- package/dist/helper-writeback.js.map +1 -0
- package/dist/index.d.ts +10 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/input-binding.d.ts +4 -0
- package/dist/input-binding.d.ts.map +1 -0
- package/dist/input-binding.js +78 -0
- package/dist/input-binding.js.map +1 -0
- package/dist/journal-client.d.ts +12 -4
- package/dist/journal-client.d.ts.map +1 -1
- package/dist/journal-client.js +17 -6
- package/dist/journal-client.js.map +1 -1
- package/dist/journal-offset.d.ts +3 -0
- package/dist/journal-offset.d.ts.map +1 -0
- package/dist/journal-offset.js +69 -0
- package/dist/journal-offset.js.map +1 -0
- package/dist/journal-reader.d.ts +30 -0
- package/dist/journal-reader.d.ts.map +1 -0
- package/dist/journal-reader.js +156 -0
- package/dist/journal-reader.js.map +1 -0
- package/dist/json-schema.d.ts +2 -0
- package/dist/json-schema.d.ts.map +1 -1
- package/dist/json-schema.js +38 -22
- package/dist/json-schema.js.map +1 -1
- package/dist/llm-worker.d.ts +16 -0
- package/dist/llm-worker.d.ts.map +1 -0
- package/dist/llm-worker.js +79 -0
- package/dist/llm-worker.js.map +1 -0
- package/dist/local-agent.d.ts +8 -0
- package/dist/local-agent.d.ts.map +1 -0
- package/dist/local-agent.js +25 -0
- package/dist/local-agent.js.map +1 -0
- package/dist/mcp-client.d.ts +15 -0
- package/dist/mcp-client.d.ts.map +1 -0
- package/dist/mcp-client.js +104 -0
- package/dist/mcp-client.js.map +1 -0
- package/dist/mcp-config.d.ts +4 -0
- package/dist/mcp-config.d.ts.map +1 -0
- package/dist/mcp-config.js +61 -0
- package/dist/mcp-config.js.map +1 -0
- package/dist/mcp-stdio.d.ts +24 -0
- package/dist/mcp-stdio.d.ts.map +1 -0
- package/dist/mcp-stdio.js +89 -0
- package/dist/mcp-stdio.js.map +1 -0
- package/dist/model-pricing.d.ts +22 -0
- package/dist/model-pricing.d.ts.map +1 -0
- package/dist/model-pricing.js +30 -0
- package/dist/model-pricing.js.map +1 -0
- package/dist/mount-registry.d.ts +9 -0
- package/dist/mount-registry.d.ts.map +1 -0
- package/dist/mount-registry.js +47 -0
- package/dist/mount-registry.js.map +1 -0
- package/dist/named-gate-lowering.d.ts +9 -0
- package/dist/named-gate-lowering.d.ts.map +1 -0
- package/dist/named-gate-lowering.js +152 -0
- package/dist/named-gate-lowering.js.map +1 -0
- package/dist/named-gates.d.ts +10 -0
- package/dist/named-gates.d.ts.map +1 -0
- package/dist/named-gates.js +69 -0
- package/dist/named-gates.js.map +1 -0
- package/dist/observer-link.d.ts +129 -0
- package/dist/observer-link.d.ts.map +1 -0
- package/dist/observer-link.js +274 -0
- package/dist/observer-link.js.map +1 -0
- package/dist/plugin-loader.d.ts +13 -0
- package/dist/plugin-loader.d.ts.map +1 -0
- package/dist/plugin-loader.js +110 -0
- package/dist/plugin-loader.js.map +1 -0
- package/dist/plugin-manifest.d.ts +27 -0
- package/dist/plugin-manifest.d.ts.map +1 -0
- package/dist/plugin-manifest.js +89 -0
- package/dist/plugin-manifest.js.map +1 -0
- package/dist/preflight.d.ts +26 -2
- package/dist/preflight.d.ts.map +1 -1
- package/dist/preflight.js +175 -1
- package/dist/preflight.js.map +1 -1
- package/dist/progress.d.ts +14 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/progress.js +39 -0
- package/dist/progress.js.map +1 -0
- package/dist/protocol.d.ts +11 -0
- package/dist/protocol.d.ts.map +1 -1
- package/dist/pty-sidechannel.d.ts +14 -0
- package/dist/pty-sidechannel.d.ts.map +1 -0
- package/dist/pty-sidechannel.js +103 -0
- package/dist/pty-sidechannel.js.map +1 -0
- package/dist/scope-compiler.d.ts +52 -0
- package/dist/scope-compiler.d.ts.map +1 -0
- package/dist/scope-compiler.js +62 -0
- package/dist/scope-compiler.js.map +1 -0
- package/dist/slack-preflight.d.ts +6 -0
- package/dist/slack-preflight.d.ts.map +1 -0
- package/dist/slack-preflight.js +28 -0
- package/dist/slack-preflight.js.map +1 -0
- package/dist/slack-writeback.d.ts +40 -0
- package/dist/slack-writeback.d.ts.map +1 -0
- package/dist/slack-writeback.js +60 -0
- package/dist/slack-writeback.js.map +1 -0
- package/dist/spec.d.ts +134 -4
- package/dist/spec.d.ts.map +1 -1
- package/dist/spec.js.map +1 -1
- package/dist/step-dependencies.d.ts.map +1 -1
- package/dist/step-dependencies.js +2 -1
- package/dist/step-dependencies.js.map +1 -1
- package/dist/step-fields.d.ts +4 -4
- package/dist/step-fields.d.ts.map +1 -1
- package/dist/step-fields.js +5 -2
- package/dist/step-fields.js.map +1 -1
- package/dist/trigger-executor.d.ts +7 -0
- package/dist/trigger-executor.d.ts.map +1 -0
- package/dist/trigger-executor.js +35 -0
- package/dist/trigger-executor.js.map +1 -0
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +53 -6
- package/dist/validate.js.map +1 -1
- package/dist/webhook-rate-limit.d.ts +29 -0
- package/dist/webhook-rate-limit.d.ts.map +1 -0
- package/dist/webhook-rate-limit.js +38 -0
- package/dist/webhook-rate-limit.js.map +1 -0
- package/dist/webhook-signature.d.ts +22 -0
- package/dist/webhook-signature.d.ts.map +1 -0
- package/dist/webhook-signature.js +53 -0
- package/dist/webhook-signature.js.map +1 -0
- package/dist/worker-cli.d.ts +16 -1
- package/dist/worker-cli.d.ts.map +1 -1
- package/dist/worker-cli.js +129 -12
- package/dist/worker-cli.js.map +1 -1
- package/dist/worker-input.d.ts +4 -0
- package/dist/worker-input.d.ts.map +1 -0
- package/dist/worker-input.js +14 -0
- package/dist/worker-input.js.map +1 -0
- package/dist/worker-lease.d.ts +5 -0
- package/dist/worker-lease.d.ts.map +1 -0
- package/dist/worker-lease.js +80 -0
- package/dist/worker-lease.js.map +1 -0
- package/dist/worker-spend.d.ts +19 -0
- package/dist/worker-spend.d.ts.map +1 -0
- package/dist/worker-spend.js +22 -0
- package/dist/worker-spend.js.map +1 -0
- package/dist/worker-usage.d.ts +7 -0
- package/dist/worker-usage.d.ts.map +1 -0
- package/dist/worker-usage.js +54 -0
- package/dist/worker-usage.js.map +1 -0
- package/dist/worker.d.ts +2 -0
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +29 -9
- package/dist/worker.js.map +1 -1
- package/dist/wrapper-session.d.ts +1 -1
- package/dist/wrapper-session.d.ts.map +1 -1
- package/dist/wrapper-session.js +56 -19
- package/dist/wrapper-session.js.map +1 -1
- package/dist/yaml-helper-effect.d.ts +8 -0
- package/dist/yaml-helper-effect.d.ts.map +1 -0
- package/dist/yaml-helper-effect.js +79 -0
- package/dist/yaml-helper-effect.js.map +1 -0
- package/dist/yaml-helpers.d.ts +18 -0
- package/dist/yaml-helpers.d.ts.map +1 -0
- package/dist/yaml-helpers.js +116 -0
- package/dist/yaml-helpers.js.map +1 -0
- package/package.json +19 -2
- package/src/adapters/base.ts +53 -0
- package/src/adapters/claude.ts +55 -0
- package/src/adapters/codex.ts +56 -0
- package/src/adapters/index.ts +36 -0
- package/src/adapters/wrapper.ts +42 -0
- package/src/agent-relay-receipt.ts +120 -0
- package/src/agent-relay-state.ts +73 -0
- package/src/agent-relay-transport.ts +273 -0
- package/src/authored-budget.ts +69 -0
- package/src/authored-flow-error.ts +10 -10
- package/src/authored-flow-executor.ts +171 -347
- package/src/authored-flow-loader.ts +60 -3
- package/src/authored-flow-operation.ts +38 -5
- package/src/authored-helper-effect.ts +143 -0
- package/src/authored-mcp.ts +166 -0
- package/src/authored-memory.ts +55 -0
- package/src/authored-plugin-effect.ts +152 -0
- package/src/authored-step-output.ts +107 -0
- package/src/authored-worker-step.ts +181 -0
- package/src/budget-preflight.ts +31 -0
- package/src/budget.ts +49 -0
- package/src/bundle-transport.ts +79 -0
- package/src/bundle-typescript.ts +98 -0
- package/src/bundle.ts +182 -0
- package/src/child-stop.ts +138 -0
- package/src/cli/add.ts +45 -0
- package/src/cli/build.ts +214 -0
- package/src/cli/bundle-preflight.ts +28 -0
- package/src/cli/check-helper-body.ts +14 -0
- package/src/cli/check-triggers.ts +41 -0
- package/src/cli/check-typescript.ts +63 -0
- package/src/cli/check.ts +132 -14
- package/src/cli/cloud-run.ts +47 -0
- package/src/cli/deploy.ts +52 -0
- package/src/cli/deterministic-failure.ts +69 -0
- package/src/cli/direct-run.ts +79 -18
- package/src/cli/hn-monitor.ts +2 -1
- package/src/cli/replay.ts +81 -0
- package/src/cli/reuse.ts +23 -0
- package/src/cli/run-digest.ts +24 -0
- package/src/cli/run.ts +104 -21
- package/src/cli/serve-webhook.ts +246 -0
- package/src/cli/tick-runner.ts +2 -1
- package/src/cli-adapter.ts +31 -74
- package/src/cli-watch.ts +174 -0
- package/src/cli.ts +396 -17
- package/src/cloud-http.ts +100 -0
- package/src/cloud-run.ts +137 -0
- package/src/compile.ts +102 -23
- package/src/create-flow.ts +82 -0
- package/src/daemon-connection.ts +32 -1
- package/src/demo-hn-monitor.ts +2 -1
- package/src/effect-channel.ts +97 -0
- package/src/failure-kinds.ts +38 -0
- package/src/gate-contract.ts +7 -0
- package/src/helper-preflight.ts +34 -0
- package/src/helper-storage.ts +23 -0
- package/src/helper-writeback.ts +83 -0
- package/src/index.ts +26 -0
- package/src/input-binding.ts +76 -0
- package/src/journal-client.ts +20 -7
- package/src/journal-offset.ts +60 -0
- package/src/journal-reader.ts +165 -0
- package/src/json-schema.ts +34 -18
- package/src/llm-worker.ts +82 -0
- package/src/local-agent.ts +30 -0
- package/src/mcp-client.ts +97 -0
- package/src/mcp-config.ts +42 -0
- package/src/mcp-stdio.ts +84 -0
- package/src/model-pricing.ts +32 -0
- package/src/mount-registry.ts +44 -0
- package/src/named-gate-lowering.ts +147 -0
- package/src/named-gates.ts +76 -0
- package/src/observer-link.ts +368 -0
- package/src/plugin-loader.ts +88 -0
- package/src/plugin-manifest.ts +76 -0
- package/src/preflight.ts +178 -4
- package/src/progress.ts +51 -0
- package/src/protocol.ts +12 -0
- package/src/pty-sidechannel.ts +92 -0
- package/src/scope-compiler.ts +105 -0
- package/src/slack-preflight.ts +25 -0
- package/src/slack-writeback.ts +63 -0
- package/src/spec.ts +112 -4
- package/src/step-dependencies.ts +3 -1
- package/src/step-fields.ts +5 -2
- package/src/trigger-executor.ts +34 -0
- package/src/validate.ts +47 -6
- package/src/webhook-rate-limit.ts +69 -0
- package/src/webhook-signature.ts +74 -0
- package/src/worker-cli.ts +150 -11
- package/src/worker-input.ts +15 -0
- package/src/worker-lease.ts +85 -0
- package/src/worker-spend.ts +23 -0
- package/src/worker-usage.ts +48 -0
- package/src/worker.ts +34 -10
- package/src/wrapper-session.ts +50 -15
- package/src/yaml-helper-effect.ts +78 -0
- package/src/yaml-helpers.ts +131 -0
|
@@ -1,22 +1,34 @@
|
|
|
1
|
+
import { pluginHelpers } from './plugin-loader.js';
|
|
2
|
+
import { runPluginEffect } from './authored-plugin-effect.js';
|
|
3
|
+
import { randomUUID } from 'node:crypto';
|
|
4
|
+
import { dirname } from 'node:path';
|
|
5
|
+
import { runHelperEffect } from './authored-helper-effect.js';
|
|
6
|
+
import { checkSlackHelpers } from './slack-preflight.js';
|
|
7
|
+
import { snapshotJsonValue } from './json-value.js';
|
|
8
|
+
import type { SlackCall } from './slack-writeback.js';
|
|
9
|
+
import { checkMcpHeader, McpPreflightError } from './cli/check-typescript.js';
|
|
10
|
+
import { buildMcpProxy, runMcpEffect } from './authored-mcp.js';
|
|
11
|
+
import { AuthoredBudget } from './authored-budget.js';
|
|
12
|
+
import { assertMemoryReachable, authoredMemory, scriptMemoryScope } from './authored-memory.js';
|
|
13
|
+
import { authoredDeterministicRunner, authoredWorkerRunner } from './authored-worker-step.js';
|
|
14
|
+
import { isSurfaceRunCompletionReason } from './authored-step-output.js';
|
|
1
15
|
import {
|
|
2
|
-
COMPLETION_REASONS,
|
|
3
|
-
RUN_COMPLETION_REASONS,
|
|
4
|
-
type AgentOptions,
|
|
5
16
|
type AgentResult,
|
|
17
|
+
type LlmOptions,
|
|
6
18
|
type CloudHelper,
|
|
7
19
|
type CompletionReason as SurfaceCompletionReason,
|
|
8
20
|
type Ctx,
|
|
21
|
+
type FlowCompletionReason,
|
|
9
22
|
type RunCompletionReason as SurfaceRunCompletionReason,
|
|
10
23
|
type Step,
|
|
11
24
|
} from '@relayflows/surface';
|
|
12
|
-
import type
|
|
25
|
+
import { createHelpers, helperProviders, type HelperCall, type FlowHandle } from '@relayflows/surface/runtime';
|
|
13
26
|
import { join } from 'node:path';
|
|
14
|
-
import {
|
|
27
|
+
import { observeStep, type ProgressEvent } from './progress.js';
|
|
28
|
+
import { parseStepTimeout } from './compile.js';
|
|
15
29
|
import { getAuthoredFlowDefinition } from './authored-flow.js';
|
|
16
30
|
import type { GetFlowDefinition } from './authored-flow-loader.js';
|
|
17
|
-
import {
|
|
18
|
-
import { classifyOutcome, type RunLifecycleOptions } from './cli/run.js';
|
|
19
|
-
import type { PreflightDiagnostic } from './preflight.js';
|
|
31
|
+
import type { RunLifecycleOptions } from './cli/run.js';
|
|
20
32
|
import {
|
|
21
33
|
AuthoredFlowExecutionError,
|
|
22
34
|
type AuthoredFlowExecutionErrorCode,
|
|
@@ -31,9 +43,7 @@ import { JournalClient } from './journal-client.js';
|
|
|
31
43
|
import type {
|
|
32
44
|
CompletionReason as ProtocolCompletionReason,
|
|
33
45
|
RunCompletionReason as ProtocolRunCompletionReason,
|
|
34
|
-
RunOutcome,
|
|
35
46
|
} from './protocol.js';
|
|
36
|
-
import { SPEC_SCHEMA_VERSION, type FlowSpec } from './spec.js';
|
|
37
47
|
|
|
38
48
|
type Assert<T extends true> = T;
|
|
39
49
|
type Equal<A, B> = [A] extends [B]
|
|
@@ -46,8 +56,8 @@ type RunCompletionVocabularyMatchesProtocol = Assert<
|
|
|
46
56
|
Equal<SurfaceRunCompletionReason, ProtocolRunCompletionReason>
|
|
47
57
|
>;
|
|
48
58
|
type DoneCompletionReason = Parameters<Ctx['done']>[0];
|
|
49
|
-
type
|
|
50
|
-
DoneCompletionReason
|
|
59
|
+
type DoneAcceptsOnlyFlowCompletionReasons = Assert<
|
|
60
|
+
Equal<DoneCompletionReason, FlowCompletionReason>
|
|
51
61
|
>;
|
|
52
62
|
type EveryRunCompletionReasonIsAcceptedByDone = Assert<
|
|
53
63
|
SurfaceRunCompletionReason extends DoneCompletionReason ? true : false
|
|
@@ -55,15 +65,6 @@ type EveryRunCompletionReasonIsAcceptedByDone = Assert<
|
|
|
55
65
|
|
|
56
66
|
export { AuthoredFlowExecutionError, type AuthoredFlowExecutionErrorCode };
|
|
57
67
|
|
|
58
|
-
/**
|
|
59
|
-
* Matches the `"path/glob: readonly"` / `"path/glob: readwrite"` shorthand
|
|
60
|
-
* shown in docs/SURFACE.md and the examples — the only shape a workspace
|
|
61
|
-
* string could plausibly declare a permission in. No parser anywhere in this
|
|
62
|
-
* package turns that annotation into a real restriction, so `lowerAgent`
|
|
63
|
-
* refuses rather than silently accepting and ignoring it.
|
|
64
|
-
*/
|
|
65
|
-
const WORKSPACE_PERMISSION_ANNOTATION = /:\s*(readonly|readwrite)\s*$/i;
|
|
66
|
-
|
|
67
68
|
export interface AuthoredFlowJournalStep {
|
|
68
69
|
readonly id: string;
|
|
69
70
|
readonly runId: string;
|
|
@@ -72,12 +73,12 @@ export interface AuthoredFlowJournalStep {
|
|
|
72
73
|
|
|
73
74
|
export interface AuthoredFlowExecutionResult {
|
|
74
75
|
readonly name: string;
|
|
75
|
-
readonly completionReason:
|
|
76
|
+
readonly completionReason: FlowCompletionReason;
|
|
76
77
|
readonly journalSteps: readonly AuthoredFlowJournalStep[];
|
|
77
78
|
}
|
|
78
79
|
|
|
79
|
-
type
|
|
80
|
-
Equal<AuthoredFlowExecutionResult['completionReason'],
|
|
80
|
+
type ExecutionResultUsesFlowCompletionReason = Assert<
|
|
81
|
+
Equal<AuthoredFlowExecutionResult['completionReason'], FlowCompletionReason>
|
|
81
82
|
>;
|
|
82
83
|
type JournalStepUsesStepCompletionReason = Assert<
|
|
83
84
|
Equal<AuthoredFlowJournalStep['completionReason'], ProtocolCompletionReason>
|
|
@@ -88,9 +89,9 @@ type JournalStepUsesStepCompletionReason = Assert<
|
|
|
88
89
|
*
|
|
89
90
|
* This is deliberately not exported by the SDK package: without a durable
|
|
90
91
|
* authored root, it is not a resumable public runner. The seam is narrow: an
|
|
91
|
-
*
|
|
92
|
-
* `f.done("success")`.
|
|
93
|
-
*
|
|
92
|
+
* flow with an optional budget may await `f.run`, `f.llm`, and `f.agent` steps and must
|
|
93
|
+
* finish with `f.done("success")` or `f.done("needs_human")`. Each step and the terminal marker is
|
|
94
|
+
* a compiled spec submitted through
|
|
94
95
|
* `JournalClient`; values are read back from `step.completed` journal entries.
|
|
95
96
|
* Unsupported headers, verbs, gates, or completion lowering fail closed.
|
|
96
97
|
*/
|
|
@@ -102,6 +103,8 @@ export interface ExecuteAuthoredFlowOptions {
|
|
|
102
103
|
* `getDefinition` instead; see authored-flow-loader.ts's comment on why.
|
|
103
104
|
*/
|
|
104
105
|
readonly getDefinition?: GetFlowDefinition;
|
|
106
|
+
/** Helper receipt and mock-writeback storage; CLI passes its daemon data directory. */
|
|
107
|
+
readonly dataDir?: string;
|
|
105
108
|
/**
|
|
106
109
|
* The flow file's own path — passed straight to `checkAuthoredFlow`
|
|
107
110
|
* (cli/check.ts) so `f.agent` resolves a CLI the same way a declarative
|
|
@@ -117,6 +120,8 @@ export interface ExecuteAuthoredFlowOptions {
|
|
|
117
120
|
/** Passed straight through to classifyOutcome (cli/run.ts) for f.agent's wait. */
|
|
118
121
|
readonly signal?: RunLifecycleOptions['signal'];
|
|
119
122
|
readonly onWait?: RunLifecycleOptions['onWait'];
|
|
123
|
+
readonly onProgress?: (event: ProgressEvent) => void;
|
|
124
|
+
readonly localAgentStream?: string;
|
|
120
125
|
}
|
|
121
126
|
|
|
122
127
|
export async function executeAuthoredFlow<Input = undefined>(
|
|
@@ -126,218 +131,159 @@ export async function executeAuthoredFlow<Input = undefined>(
|
|
|
126
131
|
options: ExecuteAuthoredFlowOptions = {},
|
|
127
132
|
): Promise<AuthoredFlowExecutionResult> {
|
|
128
133
|
const getDefinition = options.getDefinition ?? getAuthoredFlowDefinition;
|
|
134
|
+
const localAgentStream = options.localAgentStream;
|
|
135
|
+
const onProgress = options.onProgress;
|
|
129
136
|
const flowPath = options.flowPath ?? join(process.cwd(), 'flow.ts');
|
|
130
|
-
// Named separately from `options` because `lowerAgent` below has its own,
|
|
131
|
-
// differently-typed `options: AgentOptions` parameter that shadows this one.
|
|
132
137
|
const waitOptions: RunLifecycleOptions = {
|
|
133
138
|
...(options.signal !== undefined ? { signal: options.signal } : {}),
|
|
134
139
|
...(options.onWait !== undefined ? { onWait: options.onWait } : {}),
|
|
135
140
|
};
|
|
136
141
|
const definition = getDefinition<Input>(handle);
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
142
|
+
const headerFields = Object.keys(definition.header).filter(key => key !== 'tools' && key !== 'budget' && key !== 'memory');
|
|
143
|
+
if (definition.header.tools && Object.keys(definition.header.tools).some(key => !['mcp', ...helperProviders.map(p => p.namespace)].includes(key))) headerFields.push('tools');
|
|
144
|
+
if (definition.header.tools?.relayfile !== undefined) headerFields.push('tools.relayfile');
|
|
145
|
+
const helperPreflight = checkSlackHelpers(definition);
|
|
146
|
+
if (!helperPreflight.ok) {
|
|
147
|
+
const diagnostic = helperPreflight.diagnostics[0]!;
|
|
148
|
+
throw new AuthoredFlowExecutionError(diagnostic.kind as AuthoredFlowExecutionErrorCode, diagnostic.message);
|
|
149
|
+
}
|
|
150
|
+
if (headerFields.length > 0) {
|
|
144
151
|
throw new AuthoredFlowExecutionError(
|
|
145
152
|
'unsupported_header',
|
|
146
|
-
`flow "${definition.name}" uses unsupported header fields: ${
|
|
153
|
+
`flow "${definition.name}" uses unsupported header fields: ${headerFields.join(', ')}`,
|
|
147
154
|
);
|
|
148
155
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
//
|
|
158
|
-
//
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const { report } = checkAuthoredFlow({
|
|
162
|
-
version: SPEC_SCHEMA_VERSION,
|
|
163
|
-
name: `${definition.name}/declared-agents`,
|
|
164
|
-
agents: { ...definition.header.agents },
|
|
165
|
-
steps: [{ id: 'declared-agents', type: 'deterministic', command: ':' }],
|
|
166
|
-
}, flowPath);
|
|
167
|
-
if (!report.ok) {
|
|
168
|
-
const refusal = report.diagnostics.find(
|
|
169
|
-
(diagnostic): diagnostic is PreflightDiagnostic & { severity: 'refusal' } =>
|
|
170
|
-
diagnostic.severity === 'refusal',
|
|
171
|
-
);
|
|
172
|
-
throw new AuthoredFlowExecutionError(
|
|
173
|
-
'agent_cli_unresolved',
|
|
174
|
-
refusal?.message
|
|
175
|
-
?? `flow "${definition.name}" declares an invalid named agent`,
|
|
176
|
-
undefined,
|
|
177
|
-
undefined,
|
|
178
|
-
refusal?.kind ?? 'invalid_spec',
|
|
179
|
-
);
|
|
180
|
-
}
|
|
156
|
+
|
|
157
|
+
const checkedMcp = await checkMcpHeader(definition, flowPath);
|
|
158
|
+
if (!checkedMcp.report.ok) throw new McpPreflightError(checkedMcp.report);
|
|
159
|
+
|
|
160
|
+
const budget = new AuthoredBudget(definition.header.budget);
|
|
161
|
+
if (definition.header.memory?.agent === true) {
|
|
162
|
+
throw new AuthoredFlowExecutionError('unsupported_header', 'memory.agent requires the follow-up identity-scoped agent memory adapter');
|
|
163
|
+
}
|
|
164
|
+
// Direct member use is checked before any body effects; aliases are checked
|
|
165
|
+
// by the helper itself, without executing the body during discovery.
|
|
166
|
+
if (definition.header.memory !== undefined || /\.memory\b/.test(String(definition.body))) {
|
|
167
|
+
await assertMemoryReachable();
|
|
181
168
|
}
|
|
182
169
|
|
|
183
170
|
const journalSteps: AuthoredFlowJournalStep[] = [];
|
|
184
171
|
const authoredSteps: AuthoredFlowOperation<unknown>[] = [];
|
|
185
172
|
const lifecycle = new AuthoredFlowLifecycle();
|
|
186
173
|
let nextStep = 1;
|
|
187
|
-
let requestedCompletion:
|
|
174
|
+
let requestedCompletion: FlowCompletionReason | undefined;
|
|
188
175
|
|
|
189
|
-
const lowerDeterministic =
|
|
190
|
-
id: string,
|
|
191
|
-
command: string,
|
|
192
|
-
): Promise<string> => {
|
|
193
|
-
const spec = toKernelSpec(compileSpec({
|
|
194
|
-
version: SPEC_SCHEMA_VERSION,
|
|
195
|
-
name: `${definition.name}/${id}`,
|
|
196
|
-
steps: [{ id, type: 'deterministic', command }],
|
|
197
|
-
}));
|
|
198
|
-
const outcome = await journal.runStart(spec);
|
|
199
|
-
return readSuccessfulOutput(journal, outcome, id, journalSteps);
|
|
200
|
-
};
|
|
176
|
+
const lowerDeterministic = authoredDeterministicRunner(definition.name, journal, journalSteps, budget);
|
|
201
177
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
+
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}],
|
|
249
|
-
};
|
|
250
|
-
// The kernel never resolves a `cli` on its own — every declarative
|
|
251
|
-
// `flows run`/`flows check` binds it first via this exact function
|
|
252
|
-
// (cli/check.ts), searching for the nearest flows.json from `flowPath`
|
|
253
|
-
// and real-probing auth/model readiness. An authored agent step gets
|
|
254
|
-
// nothing for free just because it was declared in TS instead of YAML.
|
|
255
|
-
const { report, flow: resolved } = checkAuthoredFlow(authoring, flowPath);
|
|
256
|
-
if (!report.ok || resolved === undefined) {
|
|
257
|
-
const refusal = report.diagnostics.find(
|
|
258
|
-
(diagnostic): diagnostic is PreflightDiagnostic & { severity: 'refusal' } =>
|
|
259
|
-
diagnostic.severity === 'refusal',
|
|
260
|
-
);
|
|
261
|
-
throw new AuthoredFlowExecutionError(
|
|
262
|
-
'agent_cli_unresolved',
|
|
263
|
-
refusal?.message
|
|
264
|
-
?? `flow "${definition.name}" step "${id}": no CLI could be resolved for f.agent `
|
|
265
|
-
+ `(searched for flows.json from "${flowPath}")`,
|
|
266
|
-
undefined,
|
|
267
|
-
undefined,
|
|
268
|
-
refusal?.kind ?? 'invalid_spec',
|
|
269
|
-
);
|
|
270
|
-
}
|
|
271
|
-
const spec = toKernelSpec(resolved);
|
|
272
|
-
const outcome = await journal.runStart(spec);
|
|
273
|
-
// Reuse the declarative CLI's own wait/classification (cli/run.ts) rather
|
|
274
|
-
// than a hand-rolled poll: `step.completed` and the run's own terminal
|
|
275
|
-
// state are appended as two SEPARATE actions (kernel/relayflowd-core/src/machine.rs
|
|
276
|
-
// completion_actions vs complete_run_actions), so a naive read right
|
|
277
|
-
// after runStart can race a real, valid completion — and a genuinely
|
|
278
|
-
// long-running agent has no reason to be bounded by anything other than
|
|
279
|
-
// its own worker's lease, which classifyOutcome already follows
|
|
280
|
-
// (renewing as the lease renews, per docs/SURFACE.md §5's WAITING
|
|
281
|
-
// [worker_lease] contract), never an unrelated fixed deadline.
|
|
282
|
-
const execution = await classifyOutcome(journal, 'run', outcome, report, '', waitOptions);
|
|
283
|
-
if (execution.exitCode === 3) {
|
|
284
|
-
const parked = execution.report.parkedStep;
|
|
285
|
-
throw new AuthoredFlowExecutionError(
|
|
286
|
-
'agent_parked',
|
|
287
|
-
execution.report.diagnostics.at(-1)?.message
|
|
288
|
-
?? `flow "${definition.name}" step "${id}" parked`
|
|
289
|
-
+ (parked !== undefined ? ` (${parked.type})` : '')
|
|
290
|
-
+ ': no worker is attached to run it.',
|
|
291
|
-
undefined,
|
|
292
|
-
outcome.run_id,
|
|
293
|
-
);
|
|
294
|
-
}
|
|
295
|
-
if (execution.exitCode !== 0) {
|
|
296
|
-
const reason = execution.report.completionReason;
|
|
297
|
-
throw new AuthoredFlowExecutionError(
|
|
298
|
-
'step_failed',
|
|
299
|
-
execution.report.diagnostics.at(-1)?.message
|
|
300
|
-
?? `flow "${definition.name}" step "${id}" did not complete successfully `
|
|
301
|
-
+ `(status: ${execution.report.status ?? 'unknown'})`,
|
|
302
|
-
isSurfaceCompletionReason(reason) ? reason : undefined,
|
|
303
|
-
outcome.run_id,
|
|
304
|
-
);
|
|
305
|
-
}
|
|
306
|
-
return readSuccessfulAgentOutput(journal, outcome.run_id, id, journalSteps);
|
|
307
|
-
};
|
|
178
|
+
const worker = authoredWorkerRunner(definition, journal, flowPath, journalSteps, waitOptions, localAgentStream, budget, definition.header.budget);
|
|
179
|
+
|
|
180
|
+
function llmOperation(strings: TemplateStringsArray, ...values: unknown[]): Step<string>;
|
|
181
|
+
function llmOperation(prompt: string, options: LlmOptions): Step<unknown>;
|
|
182
|
+
function llmOperation(prompt: string | TemplateStringsArray, ...values: unknown[]): Step<unknown> {
|
|
183
|
+
assertOperationAllowed('llm', definition.name, requestedCompletion);
|
|
184
|
+
const id = `llm-${nextStep++}`;
|
|
185
|
+
// Hoist the operation reference so the start closure can read the
|
|
186
|
+
// caller's `.gate(config)` at spec-build time. AuthoredFlowOperation
|
|
187
|
+
// begins after construction returns, so `llmOp` is defined by then.
|
|
188
|
+
let llmOp!: AuthoredFlowOperation<unknown>;
|
|
189
|
+
llmOp = new AuthoredFlowOperation(
|
|
190
|
+
id, 'llm',
|
|
191
|
+
() => assertOperationAllowed('llm', definition.name, requestedCompletion),
|
|
192
|
+
() => observeStep(id, 'llm', () => {
|
|
193
|
+
if (typeof prompt === 'string') {
|
|
194
|
+
if (values.length !== 1 || values[0] === undefined) {
|
|
195
|
+
throw new AuthoredFlowExecutionError('llm_cli_unresolved', 'f.llm(prompt, options) requires an output JSON Schema.');
|
|
196
|
+
}
|
|
197
|
+
return worker.llm(id, prompt, values[0] as LlmOptions, llmOp.namedGate);
|
|
198
|
+
}
|
|
199
|
+
const text = prompt.reduce((result, part, index) => result + part
|
|
200
|
+
+ (index < values.length ? String(values[index]) : ''), '');
|
|
201
|
+
return worker.llm(id, text, undefined, llmOp.namedGate);
|
|
202
|
+
}, onProgress),
|
|
203
|
+
lifecycle,
|
|
204
|
+
);
|
|
205
|
+
return trackStep(authoredSteps, llmOp);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const slackRun = randomUUID();
|
|
209
|
+
function slackOperation<T>(call: SlackCall): Step<T> {
|
|
210
|
+
assertOperationAllowed(`slack.${call.verb}`, definition.name, requestedCompletion);
|
|
211
|
+
const snapshot = snapshotJsonValue(call, 'f.slack call') as unknown as SlackCall;
|
|
212
|
+
const id = `slack-${slackRun}-${nextStep++}`;
|
|
213
|
+
return trackStep(authoredSteps, new AuthoredFlowOperation<T>(
|
|
214
|
+
id, `slack.${call.verb}`,
|
|
215
|
+
() => assertOperationAllowed(`slack.${call.verb}`, definition.name, requestedCompletion),
|
|
216
|
+
async () => {
|
|
217
|
+
const receipt = await runHelperEffect(journal, definition.name, id, snapshot,
|
|
218
|
+
options.dataDir ?? dirname(journal.socketPath), journalSteps);
|
|
219
|
+
return (call.verb === 'react' ? undefined : receipt) as T;
|
|
220
|
+
},
|
|
221
|
+
lifecycle,
|
|
222
|
+
));
|
|
223
|
+
}
|
|
308
224
|
|
|
309
225
|
const context: Ctx = {
|
|
310
|
-
|
|
226
|
+
...createHelpers(<T>(call: HelperCall): Step<T> => {
|
|
227
|
+
const verb = `${call.provider}.${call.verb}`;
|
|
228
|
+
assertOperationAllowed(verb, definition.name, requestedCompletion);
|
|
229
|
+
const snapshot = snapshotJsonValue(call, `f.${verb} call`) as unknown as HelperCall;
|
|
230
|
+
const id = `${call.provider}-${slackRun}-${nextStep++}`;
|
|
231
|
+
return trackStep(authoredSteps, new AuthoredFlowOperation<T>(id, verb,
|
|
232
|
+
() => assertOperationAllowed(verb, definition.name, requestedCompletion),
|
|
233
|
+
async () => await runHelperEffect(journal, definition.name, id, snapshot,
|
|
234
|
+
options.dataDir ?? dirname(journal.socketPath), journalSteps) as T,
|
|
235
|
+
lifecycle));
|
|
236
|
+
}),
|
|
237
|
+
slack: {
|
|
238
|
+
post: (channel, text, opts) => slackOperation({ type: 'effect', provider: 'slack', verb: 'post', params: { channel, text, ...(opts === undefined ? {} : { opts }) } }),
|
|
239
|
+
dm: (user, text) => slackOperation({ type: 'effect', provider: 'slack', verb: 'dm', params: { user, text } }),
|
|
240
|
+
reply: (channel, threadTs, text) => slackOperation({ type: 'effect', provider: 'slack', verb: 'reply', params: { channel, threadTs, text } }),
|
|
241
|
+
react: (channel, messageTs, emoji) => slackOperation({ type: 'effect', provider: 'slack', verb: 'react', params: { channel, messageTs, emoji } }),
|
|
242
|
+
},
|
|
243
|
+
mcp: buildMcpProxy(checkedMcp.inventory, (server, tool, args, known) => {
|
|
244
|
+
assertOperationAllowed('mcp', definition.name, requestedCompletion);
|
|
245
|
+
const id = `mcp-${nextStep++}`;
|
|
246
|
+
return trackStep(authoredSteps, new AuthoredFlowOperation(
|
|
247
|
+
id, 'mcp',
|
|
248
|
+
() => assertOperationAllowed('mcp', definition.name, requestedCompletion),
|
|
249
|
+
() => runMcpEffect(journal, definition.name, id, server, tool, args,
|
|
250
|
+
known, checkedMcp.servers[server]!, journalSteps),
|
|
251
|
+
lifecycle,
|
|
252
|
+
));
|
|
253
|
+
}),
|
|
254
|
+
memory: authoredMemory(
|
|
255
|
+
scriptMemoryScope(flowPath, definition.name),
|
|
256
|
+
() => assertOperationAllowed('memory', definition.name, requestedCompletion),
|
|
257
|
+
definition.header.memory?.script !== false,
|
|
258
|
+
),
|
|
259
|
+
run(command, runOptions) {
|
|
311
260
|
assertOperationAllowed('run', definition.name, requestedCompletion);
|
|
261
|
+
const leaseMs = runOptions?.timeout === undefined ? undefined : parseStepTimeout(runOptions.timeout);
|
|
312
262
|
const id = `run-${nextStep++}`;
|
|
313
|
-
|
|
263
|
+
let runOp!: AuthoredFlowOperation<string>;
|
|
264
|
+
runOp = new AuthoredFlowOperation<string>(
|
|
314
265
|
id,
|
|
315
266
|
'run',
|
|
316
267
|
() => assertOperationAllowed('run', definition.name, requestedCompletion),
|
|
317
|
-
() => lowerDeterministic(id, command),
|
|
318
|
-
lifecycle,
|
|
319
|
-
));
|
|
320
|
-
},
|
|
321
|
-
llm() {
|
|
322
|
-
assertOperationAllowed('llm', definition.name, requestedCompletion);
|
|
323
|
-
const id = `llm-${nextStep++}`;
|
|
324
|
-
return trackStep(authoredSteps, unsupportedStep(
|
|
325
|
-
id,
|
|
326
|
-
'llm',
|
|
327
|
-
() => assertOperationAllowed('llm', definition.name, requestedCompletion),
|
|
268
|
+
() => observeStep(id, 'deterministic', () => lowerDeterministic(id, command, false, leaseMs, runOp.namedGate), options.onProgress),
|
|
328
269
|
lifecycle,
|
|
329
|
-
)
|
|
270
|
+
);
|
|
271
|
+
return trackStep(authoredSteps, runOp);
|
|
330
272
|
},
|
|
273
|
+
llm: llmOperation,
|
|
331
274
|
agent(name, options) {
|
|
332
275
|
assertOperationAllowed('agent', definition.name, requestedCompletion);
|
|
276
|
+
void name; // Authored headers do not yet declare reusable named agents.
|
|
333
277
|
const id = `agent-${nextStep++}`;
|
|
334
|
-
|
|
278
|
+
let agentOp!: AuthoredFlowOperation<AgentResult>;
|
|
279
|
+
agentOp = new AuthoredFlowOperation<AgentResult>(
|
|
335
280
|
id,
|
|
336
281
|
'agent',
|
|
337
282
|
() => assertOperationAllowed('agent', definition.name, requestedCompletion),
|
|
338
|
-
() =>
|
|
283
|
+
() => observeStep(id, 'agent', () => worker.agent(id, options, agentOp.namedGate), onProgress),
|
|
339
284
|
lifecycle,
|
|
340
|
-
)
|
|
285
|
+
);
|
|
286
|
+
return trackStep(authoredSteps, agentOp);
|
|
341
287
|
},
|
|
342
288
|
human() {
|
|
343
289
|
assertOperationAllowed('human', definition.name, requestedCompletion);
|
|
@@ -348,7 +294,7 @@ export async function executeAuthoredFlow<Input = undefined>(
|
|
|
348
294
|
throw unsupportedVerb('dispatch');
|
|
349
295
|
},
|
|
350
296
|
done(reason) {
|
|
351
|
-
if (!isSurfaceRunCompletionReason(reason)) {
|
|
297
|
+
if (reason !== 'needs_human' && !isSurfaceRunCompletionReason(reason)) {
|
|
352
298
|
throw new AuthoredFlowExecutionError(
|
|
353
299
|
'unsupported_completion',
|
|
354
300
|
`unknown completion reason: ${String(reason)}`,
|
|
@@ -360,7 +306,7 @@ export async function executeAuthoredFlow<Input = undefined>(
|
|
|
360
306
|
`flow "${definition.name}" called done() more than once`,
|
|
361
307
|
);
|
|
362
308
|
}
|
|
363
|
-
if (reason !== 'success') {
|
|
309
|
+
if (reason !== 'success' && reason !== 'needs_human') {
|
|
364
310
|
throw new AuthoredFlowExecutionError(
|
|
365
311
|
'unsupported_completion',
|
|
366
312
|
`the initial authored executor cannot lower done("${reason}")`,
|
|
@@ -375,6 +321,17 @@ export async function executeAuthoredFlow<Input = undefined>(
|
|
|
375
321
|
),
|
|
376
322
|
};
|
|
377
323
|
|
|
324
|
+
Object.assign(context, pluginHelpers(checkedMcp.plugins ?? [], (plugin, verb, args) => {
|
|
325
|
+
const label = `${verb.namespace}.${verb.method}`;
|
|
326
|
+
assertOperationAllowed(label, definition.name, requestedCompletion);
|
|
327
|
+
const id = `plugin-${nextStep++}`;
|
|
328
|
+
return trackStep(authoredSteps, new AuthoredFlowOperation(
|
|
329
|
+
id, label, () => assertOperationAllowed(label, definition.name, requestedCompletion),
|
|
330
|
+
() => runPluginEffect(journal, definition.name, id, plugin, verb, args, journalSteps, budget),
|
|
331
|
+
lifecycle,
|
|
332
|
+
));
|
|
333
|
+
}));
|
|
334
|
+
|
|
378
335
|
let bodyFailed = false;
|
|
379
336
|
let bodyFailure: unknown;
|
|
380
337
|
try {
|
|
@@ -424,7 +381,11 @@ export async function executeAuthoredFlow<Input = undefined>(
|
|
|
424
381
|
lifecycle.close();
|
|
425
382
|
}
|
|
426
383
|
|
|
427
|
-
|
|
384
|
+
// The authored runner has no durable root yet. Record the handoff as a
|
|
385
|
+
// successful effect containing the authored outcome, not a fabricated kernel
|
|
386
|
+
// run.completed reason. The CLI reports this outcome as parked (exit 3).
|
|
387
|
+
await lowerDeterministic(`complete-${nextStep}`, requestedCompletion === 'needs_human'
|
|
388
|
+
? `printf '%s' '{"completionReason":"needs_human"}'` : ':', true);
|
|
428
389
|
return Object.freeze({
|
|
429
390
|
name: definition.name,
|
|
430
391
|
completionReason: requestedCompletion,
|
|
@@ -440,17 +401,6 @@ function trackStep<T>(
|
|
|
440
401
|
return operation.step;
|
|
441
402
|
}
|
|
442
403
|
|
|
443
|
-
function unsupportedStep<T>(
|
|
444
|
-
id: string,
|
|
445
|
-
verb: string,
|
|
446
|
-
assertCanStart: () => void,
|
|
447
|
-
lifecycle: AuthoredFlowLifecycle,
|
|
448
|
-
): AuthoredFlowOperation<T> {
|
|
449
|
-
return new AuthoredFlowOperation<T>(id, verb, assertCanStart, async () => {
|
|
450
|
-
throw unsupportedVerb(verb);
|
|
451
|
-
}, lifecycle);
|
|
452
|
-
}
|
|
453
|
-
|
|
454
404
|
function unsupportedVerb(verb: string): AuthoredFlowExecutionError {
|
|
455
405
|
return new AuthoredFlowExecutionError(
|
|
456
406
|
'unsupported_verb',
|
|
@@ -461,13 +411,13 @@ function unsupportedVerb(verb: string): AuthoredFlowExecutionError {
|
|
|
461
411
|
function assertOperationAllowed(
|
|
462
412
|
verb: string,
|
|
463
413
|
flowName: string,
|
|
464
|
-
completion:
|
|
414
|
+
completion: FlowCompletionReason | undefined,
|
|
465
415
|
): void {
|
|
466
416
|
if (completion !== undefined) {
|
|
467
417
|
throw new AuthoredFlowExecutionError(
|
|
468
418
|
'operation_after_completion',
|
|
469
419
|
`flow "${flowName}" called f.${verb} after done()`,
|
|
470
|
-
completion,
|
|
420
|
+
completion === 'needs_human' ? undefined : completion,
|
|
471
421
|
);
|
|
472
422
|
}
|
|
473
423
|
}
|
|
@@ -480,129 +430,3 @@ function unsupportedCloud(assertOpen: () => void): CloudHelper {
|
|
|
480
430
|
},
|
|
481
431
|
}) as CloudHelper;
|
|
482
432
|
}
|
|
483
|
-
|
|
484
|
-
/**
|
|
485
|
-
* Shared by every `f.*` verb that lowers to one kernel step run in isolation:
|
|
486
|
-
* find its `step.completed` entry, record it, and refuse anything but a
|
|
487
|
-
* clean success before handing the raw `output` back for verb-specific
|
|
488
|
-
* extraction (a plain string for `f.run`, an `AgentResult` for `f.agent`).
|
|
489
|
-
*
|
|
490
|
-
* Callers are responsible for having already established that the RUN
|
|
491
|
-
* reached a terminal, successful state before calling this — `f.run`'s
|
|
492
|
-
* caller relies on `runStart`'s own immediate response (the kernel drives a
|
|
493
|
-
* deterministic step to completion inline, no race); `f.agent`'s caller
|
|
494
|
-
* relies on `classifyOutcome` (cli/run.ts) having already polled to a true
|
|
495
|
-
* terminal state. Given that, a single read from the start of this run's
|
|
496
|
-
* (small, single-step) journal is enough — no polling here, and no run
|
|
497
|
-
* outcome ever needs re-checking.
|
|
498
|
-
*/
|
|
499
|
-
async function readCompletedStepOutput(
|
|
500
|
-
journal: JournalClient,
|
|
501
|
-
runId: string,
|
|
502
|
-
stepId: string,
|
|
503
|
-
journalSteps: AuthoredFlowJournalStep[],
|
|
504
|
-
): Promise<unknown> {
|
|
505
|
-
const entries = (await journal.journalRead(runId, 1)).entries;
|
|
506
|
-
const completed = entries.find((entry) => isStepCompleted(entry, stepId));
|
|
507
|
-
if (!isStepCompleted(completed, stepId)) {
|
|
508
|
-
throw protocolViolation(runId, `journal has no step.completed for "${stepId}"`);
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
const reason = completed.payload.completionReason;
|
|
512
|
-
journalSteps.push(Object.freeze({ id: stepId, runId, completionReason: reason }));
|
|
513
|
-
if (reason !== 'success') {
|
|
514
|
-
throw new AuthoredFlowExecutionError(
|
|
515
|
-
'step_failed',
|
|
516
|
-
`journal step "${stepId}" completed with ${reason}`,
|
|
517
|
-
reason,
|
|
518
|
-
runId,
|
|
519
|
-
);
|
|
520
|
-
}
|
|
521
|
-
return completed.payload.output;
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
async function readSuccessfulOutput(
|
|
525
|
-
journal: JournalClient,
|
|
526
|
-
outcome: RunOutcome,
|
|
527
|
-
stepId: string,
|
|
528
|
-
journalSteps: AuthoredFlowJournalStep[],
|
|
529
|
-
): Promise<string> {
|
|
530
|
-
const output = await readCompletedStepOutput(journal, outcome.run_id, stepId, journalSteps);
|
|
531
|
-
if (!isRecord(output) || typeof output['stdout_tail'] !== 'string') {
|
|
532
|
-
throw protocolViolation(outcome.run_id, `step "${stepId}" has no string stdout_tail`);
|
|
533
|
-
}
|
|
534
|
-
return output['stdout_tail'];
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
/**
|
|
538
|
-
* The kernel journals an agent step's raw `CliResult` shape
|
|
539
|
-
* (`exit_code`/`stdout_tail`/`stderr_tail`) — same as a deterministic step —
|
|
540
|
-
* UNLESS the CLI's stdout parsed as JSON, in which case `output` is that
|
|
541
|
-
* parsed object directly (worker.ts: `parseJsonOutput(result.stdout_tail) ??
|
|
542
|
-
* result`). Neither shape carries a real `artifacts` list today: nothing in
|
|
543
|
-
* the kernel or worker enumerates files an agent wrote, and `f.agent`'s
|
|
544
|
-
* `AgentOptions` has no `output` schema parameter for a CLI to target either
|
|
545
|
-
* (unlike the declarative `AgentStepSpec.output` field). `artifacts` is
|
|
546
|
-
* therefore always empty here — honest about what data exists, not a
|
|
547
|
-
* placeholder for something not yet wired.
|
|
548
|
-
*/
|
|
549
|
-
async function readSuccessfulAgentOutput(
|
|
550
|
-
journal: JournalClient,
|
|
551
|
-
runId: string,
|
|
552
|
-
stepId: string,
|
|
553
|
-
journalSteps: AuthoredFlowJournalStep[],
|
|
554
|
-
): Promise<AgentResult> {
|
|
555
|
-
const output = await readCompletedStepOutput(journal, runId, stepId, journalSteps);
|
|
556
|
-
if (!isRecord(output)) {
|
|
557
|
-
throw protocolViolation(runId, `step "${stepId}" produced a non-object output`);
|
|
558
|
-
}
|
|
559
|
-
if (typeof output['stdout_tail'] === 'string') {
|
|
560
|
-
return { summary: output['stdout_tail'], artifacts: [] };
|
|
561
|
-
}
|
|
562
|
-
// The CLI's stdout parsed as JSON, so `output` is that value, not a
|
|
563
|
-
// CliResult. Fall back to a stable, inspectable summary rather than
|
|
564
|
-
// refusing a run whose agent step genuinely succeeded.
|
|
565
|
-
return { summary: JSON.stringify(output), artifacts: [] };
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
interface StepCompletedEntry {
|
|
569
|
-
entry_type: 'step.completed';
|
|
570
|
-
step_id: string;
|
|
571
|
-
payload: {
|
|
572
|
-
completionReason: ProtocolCompletionReason;
|
|
573
|
-
output: unknown;
|
|
574
|
-
};
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
function isStepCompleted(value: unknown, stepId: string): value is StepCompletedEntry {
|
|
578
|
-
if (!isRecord(value) || value['entry_type'] !== 'step.completed' || value['step_id'] !== stepId) {
|
|
579
|
-
return false;
|
|
580
|
-
}
|
|
581
|
-
const payload = value['payload'];
|
|
582
|
-
return isRecord(payload)
|
|
583
|
-
&& isSurfaceCompletionReason(payload['completionReason'])
|
|
584
|
-
&& 'output' in payload;
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
function isSurfaceCompletionReason(value: unknown): value is ProtocolCompletionReason {
|
|
588
|
-
return typeof value === 'string'
|
|
589
|
-
&& (COMPLETION_REASONS as readonly string[]).includes(value);
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
function isSurfaceRunCompletionReason(value: unknown): value is ProtocolRunCompletionReason {
|
|
593
|
-
return typeof value === 'string'
|
|
594
|
-
&& (RUN_COMPLETION_REASONS as readonly string[]).includes(value);
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
598
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
function protocolViolation(runId: string, detail: string): AuthoredFlowExecutionError {
|
|
602
|
-
return new AuthoredFlowExecutionError(
|
|
603
|
-
'journal_protocol_violation',
|
|
604
|
-
detail,
|
|
605
|
-
undefined,
|
|
606
|
-
runId,
|
|
607
|
-
);
|
|
608
|
-
}
|