@relayflows/sdk 2.0.8 → 2.0.10
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-transport.d.ts +84 -0
- package/dist/agent-relay-transport.d.ts.map +1 -0
- package/dist/agent-relay-transport.js +134 -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 +1 -1
- package/dist/authored-flow-error.d.ts.map +1 -1
- 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 +115 -194
- 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 -7
- 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 +13 -1
- package/dist/worker-cli.d.ts.map +1 -1
- package/dist/worker-cli.js +133 -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 +22 -8
- 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-transport.ts +187 -0
- package/src/authored-budget.ts +69 -0
- package/src/authored-flow-error.ts +10 -0
- package/src/authored-flow-executor.ts +170 -293
- 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 -7
- 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 +156 -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 +27 -9
- package/src/wrapper-session.ts +50 -15
- package/src/yaml-helper-effect.ts +78 -0
- package/src/yaml-helpers.ts +131 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type RelayTransport } from '@relayfile/relay-helpers';
|
|
2
|
+
import type { AgentStepSpec, KernelAgentStep, YamlHelperParams } from './spec.js';
|
|
3
|
+
export type HelperCall = {
|
|
4
|
+
[P in keyof YamlHelperParams]: {
|
|
5
|
+
[V in keyof YamlHelperParams[P]]: {
|
|
6
|
+
type: 'effect';
|
|
7
|
+
provider: P;
|
|
8
|
+
verb: V;
|
|
9
|
+
params: YamlHelperParams[P][V];
|
|
10
|
+
};
|
|
11
|
+
}[keyof YamlHelperParams[P]];
|
|
12
|
+
}[keyof YamlHelperParams];
|
|
13
|
+
/** Runs on the inert JSON snapshot, before ordinary step validation. */
|
|
14
|
+
export declare function expandYamlHelpers(spec: unknown): unknown;
|
|
15
|
+
/** The versioned instruction envelope survives canonical specs and journal resume. */
|
|
16
|
+
export declare function helperCall(step: Partial<AgentStepSpec | KernelAgentStep>): HelperCall | undefined;
|
|
17
|
+
export declare function invokeHelper(call: HelperCall, transport: RelayTransport): Promise<unknown>;
|
|
18
|
+
//# sourceMappingURL=yaml-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yaml-helpers.d.ts","sourceRoot":"","sources":["../src/yaml-helpers.ts"],"names":[],"mappings":"AACA,OAAO,EAA2C,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAC;AACxG,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAyDlF,MAAM,MAAM,UAAU,GAAG;KAAG,CAAC,IAAI,MAAM,gBAAgB,GAAG;SAAG,CAAC,IAAI,MAAM,gBAAgB,CAAC,CAAC,CAAC,GACzF;YAAE,IAAI,EAAE,QAAQ,CAAC;YAAC,QAAQ,EAAE,CAAC,CAAC;YAAC,IAAI,EAAE,CAAC,CAAC;YAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;SAAE;KACzE,CAAC,MAAM,gBAAgB,CAAC,CAAC,CAAC,CAAC;CAAE,CAAC,MAAM,gBAAgB,CAAC,CAAC;AA2BvD,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CA4BxD;AAED,sFAAsF;AACtF,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,aAAa,GAAG,eAAe,CAAC,GAAG,UAAU,GAAG,SAAS,CAKjG;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAGhG"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import Ajv from 'ajv';
|
|
2
|
+
import { githubClient, linearClient, slackClient } from '@relayfile/relay-helpers';
|
|
3
|
+
import { canonicalize } from './canonical.js';
|
|
4
|
+
import { unknownKeyErrors } from './unknown-keys.js';
|
|
5
|
+
const string = { type: 'string', minLength: 1 };
|
|
6
|
+
const text = { type: 'string' };
|
|
7
|
+
const strings = { type: 'array', items: string };
|
|
8
|
+
const object = (properties, required = Object.keys(properties)) => ({ type: 'object', properties, required, additionalProperties: false });
|
|
9
|
+
const target = object({ owner: string, repo: string, number: { type: 'integer', minimum: 1 } });
|
|
10
|
+
const issueChanges = { title: string, description: text, assigneeId: string, stateId: string,
|
|
11
|
+
projectId: string, labelIds: strings, addedLabelIds: strings, removedLabelIds: strings };
|
|
12
|
+
const ajv = new Ajv({ allErrors: true });
|
|
13
|
+
function verb(schema, invoke) {
|
|
14
|
+
const validate = ajv.compile(schema);
|
|
15
|
+
return { validate, invoke: (params, transport) => invoke(params, transport) };
|
|
16
|
+
}
|
|
17
|
+
/** Closed catalog: only write verbs with a declared argument schema can execute. */
|
|
18
|
+
const helpers = {
|
|
19
|
+
slack: {
|
|
20
|
+
post: verb(object({ channel: string, text,
|
|
21
|
+
opts: object({ replyTo: string }, []) }, ['channel', 'text']), (p, transport) => slackClient({ transport }).post(p.channel, p.text, p.opts)),
|
|
22
|
+
dm: verb(object({ user: string, text }), (p, transport) => slackClient({ transport }).dm(p.user, p.text)),
|
|
23
|
+
reply: verb(object({ channel: string, threadTs: string, text }), (p, transport) => slackClient({ transport }).reply(p.channel, p.threadTs, p.text)),
|
|
24
|
+
react: verb(object({ channel: string, messageTs: string, emoji: string }), (p, transport) => slackClient({ transport }).react(p.channel, p.messageTs, p.emoji)),
|
|
25
|
+
},
|
|
26
|
+
github: {
|
|
27
|
+
comment: verb(object({ target, body: text }), (p, transport) => githubClient({ transport }).comment(p.target, p.body)),
|
|
28
|
+
createIssue: verb(object({ owner: string, repo: string,
|
|
29
|
+
title: string, body: text, labels: strings }, ['owner', 'repo', 'title', 'body']), (p, transport) => githubClient({ transport }).createIssue(p)),
|
|
30
|
+
createPullRequest: verb(object({ owner: string,
|
|
31
|
+
repo: string, title: string, head: string, base: string, body: text, draft: { type: 'boolean' },
|
|
32
|
+
author: { enum: ['app', 'user'] } }, ['owner', 'repo', 'title', 'head', 'base']), (p, transport) => githubClient({ transport }).createPullRequest(p)),
|
|
33
|
+
closePullRequest: verb(target, (p, transport) => githubClient({ transport }).closePullRequest(p)),
|
|
34
|
+
},
|
|
35
|
+
linear: {
|
|
36
|
+
comment: verb(object({ issueId: string, body: text }), (p, transport) => linearClient({ transport }).comment(p.issueId, p.body)),
|
|
37
|
+
createIssue: verb(object({ teamId: string, title: string,
|
|
38
|
+
description: text, assigneeId: string, labelIds: strings, projectId: string, stateId: string }, ['teamId', 'title']), (p, transport) => linearClient({ transport }).createIssue(p)),
|
|
39
|
+
updateIssue: verb(object({ issueId: string,
|
|
40
|
+
args: object(issueChanges, []) }), (p, transport) => linearClient({ transport }).updateIssue(p.issueId, p.args)),
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
const prefix = 'relayflows:helper:v1\n';
|
|
44
|
+
const commonFields = ['id', 'dependsOn', 'maxIterations', 'verification', 'output'];
|
|
45
|
+
const isObject = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
46
|
+
function descriptor(provider, name) {
|
|
47
|
+
if (!Object.hasOwn(helpers, provider))
|
|
48
|
+
throw new Error(`unknown helper provider "${provider}"`);
|
|
49
|
+
const verbs = helpers[provider];
|
|
50
|
+
if (!Object.hasOwn(verbs, name))
|
|
51
|
+
throw new Error(`unknown ${provider} helper verb "${name}"`);
|
|
52
|
+
return verbs[name];
|
|
53
|
+
}
|
|
54
|
+
function validateCall(value) {
|
|
55
|
+
if (!isObject(value) || value.type !== 'effect' || typeof value.provider !== 'string' || typeof value.verb !== 'string') {
|
|
56
|
+
throw new Error('expected a helper effect call');
|
|
57
|
+
}
|
|
58
|
+
const extra = unknownKeyErrors(value, ['type', 'provider', 'verb', 'params'], 'helper');
|
|
59
|
+
if (extra.length)
|
|
60
|
+
throw new Error(extra.join('; '));
|
|
61
|
+
const entry = descriptor(value.provider, value.verb);
|
|
62
|
+
if (!entry.validate(value.params)) {
|
|
63
|
+
throw new Error(`${value.provider}.${value.verb}: ${ajv.errorsText(entry.validate.errors)}`);
|
|
64
|
+
}
|
|
65
|
+
return value;
|
|
66
|
+
}
|
|
67
|
+
/** Runs on the inert JSON snapshot, before ordinary step validation. */
|
|
68
|
+
export function expandYamlHelpers(spec) {
|
|
69
|
+
if (!isObject(spec) || !Array.isArray(spec.steps))
|
|
70
|
+
return spec;
|
|
71
|
+
return { ...spec, steps: spec.steps.map((step, index) => {
|
|
72
|
+
if (!isObject(step))
|
|
73
|
+
return step;
|
|
74
|
+
const providers = Object.keys(helpers).filter(provider => Object.hasOwn(step, provider));
|
|
75
|
+
if (!providers.length) {
|
|
76
|
+
// Recompiling a canonical envelope must fail with the same compile error
|
|
77
|
+
// contract as authoring it, before preflight or workers see it.
|
|
78
|
+
helperCall(step);
|
|
79
|
+
return step;
|
|
80
|
+
}
|
|
81
|
+
const at = `spec.steps[${index}]`;
|
|
82
|
+
try {
|
|
83
|
+
if (providers.length !== 1)
|
|
84
|
+
throw new Error('expected exactly one helper provider per step');
|
|
85
|
+
const provider = providers[0];
|
|
86
|
+
const errors = unknownKeyErrors(step, [...commonFields, provider], at);
|
|
87
|
+
if (errors.length)
|
|
88
|
+
throw new Error(errors.join('; '));
|
|
89
|
+
const verbs = step[provider];
|
|
90
|
+
if (!isObject(verbs) || Object.keys(verbs).length !== 1)
|
|
91
|
+
throw new Error(`${provider}: expected exactly one helper verb`);
|
|
92
|
+
const name = Object.keys(verbs)[0];
|
|
93
|
+
const call = validateCall({ type: 'effect', provider, verb: name, params: verbs[name] });
|
|
94
|
+
const { [provider]: _, ...base } = step;
|
|
95
|
+
return { ...base, type: 'agent', instruction: prefix + canonicalize(call),
|
|
96
|
+
recoveryMode: 'reset', surfaces: { external: [`/${provider}`] } };
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
throw new Error(`${at}: ${error instanceof Error ? error.message : String(error)}`);
|
|
100
|
+
}
|
|
101
|
+
}) };
|
|
102
|
+
}
|
|
103
|
+
/** The versioned instruction envelope survives canonical specs and journal resume. */
|
|
104
|
+
export function helperCall(step) {
|
|
105
|
+
if (step.type !== 'agent' || typeof step.instruction !== 'string' || !step.instruction.startsWith(prefix))
|
|
106
|
+
return undefined;
|
|
107
|
+
const call = validateCall(JSON.parse(step.instruction.slice(prefix.length)));
|
|
108
|
+
if (!step.surfaces?.external?.includes(`/${call.provider}`))
|
|
109
|
+
throw new Error('helper effect is missing its declared external surface');
|
|
110
|
+
return call;
|
|
111
|
+
}
|
|
112
|
+
export async function invokeHelper(call, transport) {
|
|
113
|
+
const validated = validateCall(call);
|
|
114
|
+
return (await descriptor(validated.provider, validated.verb).invoke(validated.params, transport)) ?? null;
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=yaml-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yaml-helpers.js","sourceRoot":"","sources":["../src/yaml-helpers.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@relayflows/sdk",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.10",
|
|
4
4
|
"description": "TypeScript-first authoring SDK for Relayflows. Compiles specs; speaks the journal protocol.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -12,6 +12,18 @@
|
|
|
12
12
|
".": {
|
|
13
13
|
"types": "./dist/index.d.ts",
|
|
14
14
|
"import": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./create-flow": {
|
|
17
|
+
"types": "./dist/create-flow.d.ts",
|
|
18
|
+
"import": "./dist/create-flow.js"
|
|
19
|
+
},
|
|
20
|
+
"./progress": {
|
|
21
|
+
"types": "./dist/progress.d.ts",
|
|
22
|
+
"import": "./dist/progress.js"
|
|
23
|
+
},
|
|
24
|
+
"./cli": {
|
|
25
|
+
"types": "./dist/cli.d.ts",
|
|
26
|
+
"import": "./dist/cli.js"
|
|
15
27
|
}
|
|
16
28
|
},
|
|
17
29
|
"files": [
|
|
@@ -30,11 +42,16 @@
|
|
|
30
42
|
},
|
|
31
43
|
"license": "Apache-2.0",
|
|
32
44
|
"dependencies": {
|
|
33
|
-
"@
|
|
45
|
+
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
46
|
+
"@relayfile/adapter-core": "0.5.24",
|
|
47
|
+
"@relayfile/relay-helpers": "0.4.11",
|
|
48
|
+
"@relayflows/surface": "2.0.10",
|
|
34
49
|
"@types/js-yaml": "^4.0.9",
|
|
50
|
+
"ai-hist": "0.4.1",
|
|
35
51
|
"ajv": "^8.17.1",
|
|
36
52
|
"ajv-draft-04": "^1.0.0",
|
|
37
53
|
"js-yaml": "^5.4.1",
|
|
54
|
+
"re2js": "^2.8.6",
|
|
38
55
|
"yaml": "^2.5.1"
|
|
39
56
|
},
|
|
40
57
|
"devDependencies": {
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* First-class headless adapter contract (flows#141).
|
|
3
|
+
*
|
|
4
|
+
* Every supported agent CLI ships one implementation. `worker-cli.ts` and
|
|
5
|
+
* `cli/check.ts` dispatch through the registry in `./index.ts` — never string
|
|
6
|
+
* formatting against per-CLI knowledge inline. Adding a new CLI is one new
|
|
7
|
+
* file that implements this interface.
|
|
8
|
+
*
|
|
9
|
+
* Behavior-preserving migration: the exported functions in `cli-adapter.ts`
|
|
10
|
+
* (`agentExecution`, `llmExecution`, `authenticationProbe`,
|
|
11
|
+
* `modelReadinessProbe`, `adapterIdentification`) now delegate to the
|
|
12
|
+
* registered adapter for the resolved kind, so callers don't change.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
export interface CliInvocation {
|
|
16
|
+
args: string[];
|
|
17
|
+
timeoutMs: number;
|
|
18
|
+
/** Set only for wrapper readiness probes; raw providers receive a model flag. */
|
|
19
|
+
modelEnv?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface CliAdapterIdentification {
|
|
23
|
+
invocation: CliInvocation;
|
|
24
|
+
expectedStdout?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The declared, per-CLI headless contract. Members intentionally mirror the
|
|
29
|
+
* function-scoped predecessors in `cli-adapter.ts` so migration is mechanical.
|
|
30
|
+
*/
|
|
31
|
+
export interface HeadlessAdapter {
|
|
32
|
+
/** Identity of this adapter — matches CliAdapterKind for registry keys. */
|
|
33
|
+
readonly kind: string;
|
|
34
|
+
|
|
35
|
+
/** Shape-check invocation before classifying an auth failure. */
|
|
36
|
+
buildIdentification(): CliAdapterIdentification;
|
|
37
|
+
|
|
38
|
+
/** Non-interactive auth-status probe. */
|
|
39
|
+
buildAuthProbe(): CliInvocation;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Real, noninteractive model round-trip. Providers hand the model via a
|
|
43
|
+
* native flag; wrappers hand it via the explicitly identified environment
|
|
44
|
+
* contract on `modelEnv`.
|
|
45
|
+
*/
|
|
46
|
+
buildModelReadinessProbe(model: string): CliInvocation;
|
|
47
|
+
|
|
48
|
+
/** Agent-step worker argv for an instruction under an optional model. */
|
|
49
|
+
buildAgentInvocation(instruction: string, model?: string): CliInvocation;
|
|
50
|
+
|
|
51
|
+
/** LLM-step worker argv for a prompt under an optional model. */
|
|
52
|
+
buildLlmInvocation(prompt: string, model?: string): CliInvocation;
|
|
53
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CliAdapterIdentification,
|
|
3
|
+
CliInvocation,
|
|
4
|
+
HeadlessAdapter,
|
|
5
|
+
} from './base.js';
|
|
6
|
+
|
|
7
|
+
const MODEL_PROBE_PROMPT = 'Reply with exactly RELAYFLOWS_MODEL_READY and nothing else.';
|
|
8
|
+
|
|
9
|
+
/** Claude Code CLI headless contract. Wire and behavior identical to the
|
|
10
|
+
* pre-#141 inline shape in `cli-adapter.ts` — only the packaging changed. */
|
|
11
|
+
export const claudeAdapter: HeadlessAdapter = {
|
|
12
|
+
kind: 'claude',
|
|
13
|
+
|
|
14
|
+
buildIdentification(): CliAdapterIdentification {
|
|
15
|
+
return { invocation: { args: ['auth', 'status', '--help'], timeoutMs: 10_000 } };
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
buildAuthProbe(): CliInvocation {
|
|
19
|
+
return { args: ['auth', 'status'], timeoutMs: 10_000 };
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
buildModelReadinessProbe(model: string): CliInvocation {
|
|
23
|
+
return {
|
|
24
|
+
args: [
|
|
25
|
+
'-p', '--model', model, '--tools', '', '--no-session-persistence',
|
|
26
|
+
MODEL_PROBE_PROMPT,
|
|
27
|
+
],
|
|
28
|
+
timeoutMs: 60_000,
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
buildAgentInvocation(instruction: string, model?: string): CliInvocation {
|
|
33
|
+
return {
|
|
34
|
+
args: [
|
|
35
|
+
'-p',
|
|
36
|
+
// Symmetric to codex's --dangerously-bypass-approvals-and-sandbox: in
|
|
37
|
+
// agent mode the flow explicitly delegates writes. Without this
|
|
38
|
+
// claude's headless mode prompts for tool approval, gets no TTY,
|
|
39
|
+
// and completes "successfully" without touching files.
|
|
40
|
+
'--dangerously-skip-permissions',
|
|
41
|
+
...(model === undefined ? [] : ['--model', model]),
|
|
42
|
+
instruction,
|
|
43
|
+
],
|
|
44
|
+
timeoutMs: 0,
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
buildLlmInvocation(prompt: string, model?: string): CliInvocation {
|
|
49
|
+
return {
|
|
50
|
+
args: ['-p', '--tools', '', '--no-session-persistence',
|
|
51
|
+
...(model === undefined ? [] : ['--model', model]), prompt],
|
|
52
|
+
timeoutMs: 0,
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CliAdapterIdentification,
|
|
3
|
+
CliInvocation,
|
|
4
|
+
HeadlessAdapter,
|
|
5
|
+
} from './base.js';
|
|
6
|
+
|
|
7
|
+
const MODEL_PROBE_PROMPT = 'Reply with exactly RELAYFLOWS_MODEL_READY and nothing else.';
|
|
8
|
+
|
|
9
|
+
/** OpenAI Codex CLI headless contract. Behavior identical to the pre-#141
|
|
10
|
+
* inline shape in `cli-adapter.ts` — only the packaging changed. */
|
|
11
|
+
export const codexAdapter: HeadlessAdapter = {
|
|
12
|
+
kind: 'codex',
|
|
13
|
+
|
|
14
|
+
buildIdentification(): CliAdapterIdentification {
|
|
15
|
+
return { invocation: { args: ['login', 'status', '--help'], timeoutMs: 10_000 } };
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
buildAuthProbe(): CliInvocation {
|
|
19
|
+
return { args: ['login', 'status'], timeoutMs: 10_000 };
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
buildModelReadinessProbe(model: string): CliInvocation {
|
|
23
|
+
return {
|
|
24
|
+
args: [
|
|
25
|
+
'exec', '--ephemeral', '--sandbox', 'read-only', '--skip-git-repo-check',
|
|
26
|
+
'--model', model, MODEL_PROBE_PROMPT,
|
|
27
|
+
],
|
|
28
|
+
timeoutMs: 60_000,
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
buildAgentInvocation(instruction: string, model?: string): CliInvocation {
|
|
33
|
+
return {
|
|
34
|
+
args: [
|
|
35
|
+
'exec', '--ephemeral', '--skip-git-repo-check',
|
|
36
|
+
// Agent-mode is where the flow explicitly delegates code changes to
|
|
37
|
+
// the CLI. Without this flag codex prompts for approval on every
|
|
38
|
+
// write, gets nothing (no TTY), and completes "successfully" without
|
|
39
|
+
// touching files — the dogfood no-op failure mode. LLM-mode stays
|
|
40
|
+
// read-only and does NOT get the bypass.
|
|
41
|
+
'--dangerously-bypass-approvals-and-sandbox',
|
|
42
|
+
...(model === undefined ? [] : ['--model', model]),
|
|
43
|
+
instruction,
|
|
44
|
+
],
|
|
45
|
+
timeoutMs: 0,
|
|
46
|
+
};
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
buildLlmInvocation(prompt: string, model?: string): CliInvocation {
|
|
50
|
+
return {
|
|
51
|
+
args: ['exec', '--ephemeral', '--sandbox', 'read-only', '--skip-git-repo-check',
|
|
52
|
+
...(model === undefined ? [] : ['--model', model]), prompt],
|
|
53
|
+
timeoutMs: 0,
|
|
54
|
+
};
|
|
55
|
+
},
|
|
56
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { basename } from 'node:path';
|
|
2
|
+
|
|
3
|
+
import { claudeAdapter } from './claude.js';
|
|
4
|
+
import { codexAdapter } from './codex.js';
|
|
5
|
+
import { wrapperAdapter } from './wrapper.js';
|
|
6
|
+
import type { HeadlessAdapter } from './base.js';
|
|
7
|
+
|
|
8
|
+
export type CliAdapterKind = 'claude' | 'codex' | 'relayflows-wrapper-v1';
|
|
9
|
+
|
|
10
|
+
/** The registered adapter set. Adding a CLI is adding one file + one entry. */
|
|
11
|
+
const ADAPTERS: Record<CliAdapterKind, HeadlessAdapter> = {
|
|
12
|
+
claude: claudeAdapter,
|
|
13
|
+
codex: codexAdapter,
|
|
14
|
+
'relayflows-wrapper-v1': wrapperAdapter,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/** Select the adapter for the resolved executable basename. */
|
|
18
|
+
export function resolveAdapter(executable: string): HeadlessAdapter {
|
|
19
|
+
const name = basename(executable).replace(/\.exe$/i, '');
|
|
20
|
+
if (name === 'claude') return ADAPTERS.claude;
|
|
21
|
+
if (name === 'codex') return ADAPTERS.codex;
|
|
22
|
+
return ADAPTERS['relayflows-wrapper-v1'];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Backward-compatible kind lookup for callers still speaking string-tag lang. */
|
|
26
|
+
export function resolveAdapterKind(executable: string): CliAdapterKind {
|
|
27
|
+
return resolveAdapter(executable).kind as CliAdapterKind;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Registered adapters by kind (read-only view for tests and diagnostics). */
|
|
31
|
+
export function registeredAdapters(): Readonly<Record<CliAdapterKind, HeadlessAdapter>> {
|
|
32
|
+
return ADAPTERS;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export { claudeAdapter, codexAdapter, wrapperAdapter };
|
|
36
|
+
export type { HeadlessAdapter, CliInvocation, CliAdapterIdentification } from './base.js';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CliAdapterIdentification,
|
|
3
|
+
CliInvocation,
|
|
4
|
+
HeadlessAdapter,
|
|
5
|
+
} from './base.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* `relayflows-adapter-v1` identifies a per-flow wrapper script — the pre-#141
|
|
9
|
+
* per-flow shim shape. The wrapper answers a probe with a known token; agent
|
|
10
|
+
* and llm execution flow through `runWrapperSession`, so this adapter refuses
|
|
11
|
+
* to construct a direct-argv invocation for them.
|
|
12
|
+
*/
|
|
13
|
+
export const WRAPPER_IDENTIFY_ARG = '--relayflows-adapter-v1';
|
|
14
|
+
export const WRAPPER_IDENTIFY_TOKEN = 'relayflows-agent-cli-v1';
|
|
15
|
+
export const WRAPPER_EXECUTE_TOKEN = 'relayflows-agent-cli-v1-execute';
|
|
16
|
+
|
|
17
|
+
export const wrapperAdapter: HeadlessAdapter = {
|
|
18
|
+
kind: 'relayflows-wrapper-v1',
|
|
19
|
+
|
|
20
|
+
buildIdentification(): CliAdapterIdentification {
|
|
21
|
+
return {
|
|
22
|
+
invocation: { args: [WRAPPER_IDENTIFY_ARG], timeoutMs: 10_000 },
|
|
23
|
+
expectedStdout: WRAPPER_IDENTIFY_TOKEN,
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
buildAuthProbe(): CliInvocation {
|
|
28
|
+
return { args: ['auth', 'status'], timeoutMs: 10_000 };
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
buildModelReadinessProbe(model: string): CliInvocation {
|
|
32
|
+
return { args: ['auth', 'status'], timeoutMs: 60_000, modelEnv: model };
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
buildAgentInvocation(): CliInvocation {
|
|
36
|
+
throw new Error('custom wrapper execution requires the runAgentCli same-process session');
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
buildLlmInvocation(): CliInvocation {
|
|
40
|
+
throw new Error('custom wrapper execution requires the same-process session');
|
|
41
|
+
},
|
|
42
|
+
};
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent-relay HTTP transport for f.agent step dispatch (flows#385).
|
|
3
|
+
*
|
|
4
|
+
* The SDK's default agent path is a direct `child_process.spawn(cli, ...)`
|
|
5
|
+
* in worker-cli.ts. That is unobservable — you cannot DM the spawned agent
|
|
6
|
+
* mid-flight, and every ecosystem tool that wants to steer or watch it
|
|
7
|
+
* ends up shelling out to the `agent-relay` CLI, which is fragile.
|
|
8
|
+
*
|
|
9
|
+
* This module speaks to agent-relay via structured HTTP: the same call
|
|
10
|
+
* shape the `mcp__agent-relay__spawn` MCP tool posts. The SDK becomes a
|
|
11
|
+
* first-class agent-relay participant, registered under a derived agent
|
|
12
|
+
* name a caller can DM against.
|
|
13
|
+
*
|
|
14
|
+
* Scope: spawn + close. Streaming inbox and observation are follow-ups.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export type AgentTransport = 'direct' | 'relay';
|
|
18
|
+
|
|
19
|
+
export interface AgentRelaySpawnRequest {
|
|
20
|
+
/** Registered agent name in the workspace. */
|
|
21
|
+
name: string;
|
|
22
|
+
/** CLI to launch. */
|
|
23
|
+
cli: 'claude' | 'codex' | 'gemini' | 'aider' | 'goose' | 'grok' | 'opencode';
|
|
24
|
+
/** Initial task instructions. */
|
|
25
|
+
task: string;
|
|
26
|
+
/** Optional model powering the worker. */
|
|
27
|
+
model?: string;
|
|
28
|
+
/** Optional working directory for the spawned worker process. */
|
|
29
|
+
worker_cwd?: string;
|
|
30
|
+
/** Optional target fleet node name. */
|
|
31
|
+
target_node?: string;
|
|
32
|
+
/** Declared objective for workforce reporting. */
|
|
33
|
+
objective?: string;
|
|
34
|
+
/** Declared role for workforce reporting. */
|
|
35
|
+
role?: string;
|
|
36
|
+
/** Declared project for workforce reporting. */
|
|
37
|
+
project?: string;
|
|
38
|
+
/** Declared workstream for workforce reporting. */
|
|
39
|
+
workstream?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface AgentRelayEnv {
|
|
43
|
+
/** `RELAY_BASE_URL` env; defaults to https://cast.agentrelay.com. */
|
|
44
|
+
baseUrl?: string;
|
|
45
|
+
/** `RELAY_API_KEY` env (rk_live_...). Required. */
|
|
46
|
+
apiKey?: string;
|
|
47
|
+
/** `RELAY_DEFAULT_WORKSPACE` env; workspace scoping for the spawn. */
|
|
48
|
+
workspaceId?: string;
|
|
49
|
+
/** Optional bearer token for the individual agent identity, if pre-registered. */
|
|
50
|
+
agentToken?: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface AgentSpawnHandle {
|
|
54
|
+
/** Registered agent name in the workspace — DM this to steer. */
|
|
55
|
+
readonly registeredName: string;
|
|
56
|
+
/** Invocation id returned by relay; use for status polling. */
|
|
57
|
+
readonly invocationId: string;
|
|
58
|
+
/** Best-effort deregistration/notification. */
|
|
59
|
+
close(): Promise<void>;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export class AgentRelayTransportError extends Error {
|
|
63
|
+
constructor(message: string, public readonly cause?: unknown) {
|
|
64
|
+
super(message);
|
|
65
|
+
this.name = 'AgentRelayTransportError';
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Read the same env the relay MCP already consumes. Explicit override wins.
|
|
71
|
+
* Missing RELAY_API_KEY refuses immediately — the transport cannot proceed
|
|
72
|
+
* unauthenticated and the direct-spawn fallback is a separate decision.
|
|
73
|
+
*/
|
|
74
|
+
export function readAgentRelayEnv(env: NodeJS.ProcessEnv = process.env): Required<Pick<AgentRelayEnv, 'baseUrl' | 'apiKey'>> & AgentRelayEnv {
|
|
75
|
+
const baseUrl = env['RELAY_BASE_URL']?.trim() || 'https://cast.agentrelay.com';
|
|
76
|
+
const apiKey = env['RELAY_API_KEY']?.trim();
|
|
77
|
+
if (!apiKey) {
|
|
78
|
+
throw new AgentRelayTransportError(
|
|
79
|
+
'agent-relay transport requires RELAY_API_KEY in the environment; falling back to direct transport is the caller\'s responsibility.',
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
baseUrl,
|
|
84
|
+
apiKey,
|
|
85
|
+
workspaceId: env['RELAY_DEFAULT_WORKSPACE']?.trim() || undefined,
|
|
86
|
+
agentToken: env['RELAY_AGENT_TOKEN']?.trim() || undefined,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Spawn a worker via agent-relay HTTP. The endpoint mirrors what the
|
|
92
|
+
* `mcp__agent-relay__spawn` MCP tool wraps — a POST that requests a fleet
|
|
93
|
+
* node dispatch. Returns a handle keyed on the registered agent name.
|
|
94
|
+
*
|
|
95
|
+
* The `fetch` argument is injected so tests can mock the transport without
|
|
96
|
+
* hitting the network.
|
|
97
|
+
*/
|
|
98
|
+
export async function agentRelaySpawn(
|
|
99
|
+
request: AgentRelaySpawnRequest,
|
|
100
|
+
env: AgentRelayEnv & { fetch?: typeof fetch } = {},
|
|
101
|
+
): Promise<AgentSpawnHandle> {
|
|
102
|
+
// Only fall back to process.env if the caller didn't supply the required
|
|
103
|
+
// fields directly. Tests pass { apiKey, fetch } inline; they shouldn't need
|
|
104
|
+
// to also set RELAY_API_KEY in the runner env.
|
|
105
|
+
const fromEnv: Partial<AgentRelayEnv> = env.apiKey
|
|
106
|
+
? { baseUrl: env.baseUrl || 'https://cast.agentrelay.com' }
|
|
107
|
+
: readAgentRelayEnv();
|
|
108
|
+
const resolved = { ...fromEnv, ...env };
|
|
109
|
+
const url = new URL('/api/v1/agents/spawn', resolved.baseUrl).toString();
|
|
110
|
+
const doFetch: typeof fetch = env.fetch ?? (globalThis as typeof globalThis & { fetch: typeof fetch }).fetch;
|
|
111
|
+
if (typeof doFetch !== 'function') {
|
|
112
|
+
throw new AgentRelayTransportError('global fetch is unavailable; provide { fetch } explicitly.');
|
|
113
|
+
}
|
|
114
|
+
const headers: Record<string, string> = {
|
|
115
|
+
'content-type': 'application/json',
|
|
116
|
+
'authorization': `Bearer ${resolved.apiKey}`,
|
|
117
|
+
};
|
|
118
|
+
if (resolved.workspaceId !== undefined) headers['x-relay-workspace'] = resolved.workspaceId;
|
|
119
|
+
if (resolved.agentToken !== undefined) headers['x-relay-agent-token'] = resolved.agentToken;
|
|
120
|
+
|
|
121
|
+
let response: Response;
|
|
122
|
+
try {
|
|
123
|
+
response = await doFetch(url, {
|
|
124
|
+
method: 'POST',
|
|
125
|
+
headers,
|
|
126
|
+
body: JSON.stringify(request),
|
|
127
|
+
});
|
|
128
|
+
} catch (cause) {
|
|
129
|
+
throw new AgentRelayTransportError(
|
|
130
|
+
`agent-relay spawn network error at ${url}: ${(cause as Error).message ?? String(cause)}`,
|
|
131
|
+
cause,
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (response.status < 200 || response.status >= 300) {
|
|
136
|
+
let body: string;
|
|
137
|
+
try { body = (await response.text()).slice(0, 512); } catch { body = '<no body>'; }
|
|
138
|
+
throw new AgentRelayTransportError(
|
|
139
|
+
`agent-relay spawn refused with status ${response.status}: ${body}`,
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
let json: { invocation?: { invocationId?: string; input?: { name?: string } } };
|
|
144
|
+
try { json = await response.json() as typeof json; } catch (cause) {
|
|
145
|
+
throw new AgentRelayTransportError(
|
|
146
|
+
'agent-relay spawn response was not JSON',
|
|
147
|
+
cause,
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
const invocationId = json.invocation?.invocationId;
|
|
151
|
+
const registeredName = json.invocation?.input?.name ?? request.name;
|
|
152
|
+
if (typeof invocationId !== 'string' || invocationId.length === 0) {
|
|
153
|
+
throw new AgentRelayTransportError(
|
|
154
|
+
'agent-relay spawn response missing invocation.invocationId',
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return {
|
|
159
|
+
registeredName,
|
|
160
|
+
invocationId,
|
|
161
|
+
async close(): Promise<void> {
|
|
162
|
+
// Best-effort: post to /api/v1/invocations/<id>/close if defined server-side;
|
|
163
|
+
// no throw on error because the invocation may already be terminal.
|
|
164
|
+
const closeUrl = new URL(`/api/v1/invocations/${encodeURIComponent(invocationId)}/close`, resolved.baseUrl).toString();
|
|
165
|
+
try {
|
|
166
|
+
await doFetch(closeUrl, {
|
|
167
|
+
method: 'POST',
|
|
168
|
+
headers,
|
|
169
|
+
body: JSON.stringify({ reason: 'sdk_transport_close' }),
|
|
170
|
+
});
|
|
171
|
+
} catch {
|
|
172
|
+
// Deliberate: close is advisory in this minimum-viable slice.
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Derive a workspace-unique agent name from a run identity + step id. The
|
|
180
|
+
* result is stable across replays of the same step so DMs can be addressed
|
|
181
|
+
* even during retries.
|
|
182
|
+
*/
|
|
183
|
+
export function deriveAgentName(runId: string, stepId: string): string {
|
|
184
|
+
// Keep readable + collision-safe: prefix with 'flow-' and use lower-kebab.
|
|
185
|
+
const clean = (s: string): string => s.toLowerCase().replace(/[^a-z0-9-]+/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');
|
|
186
|
+
return `flow-${clean(runId)}-${clean(stepId)}`.slice(0, 96);
|
|
187
|
+
}
|