@relayflows/sdk 2.0.29 → 2.0.31
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/agent-artifacts.d.ts.map +1 -1
- package/dist/agent-artifacts.js +2 -9
- package/dist/agent-artifacts.js.map +1 -1
- package/dist/agent-cwd.d.ts +69 -0
- package/dist/agent-cwd.d.ts.map +1 -0
- package/dist/agent-cwd.js +140 -0
- package/dist/agent-cwd.js.map +1 -0
- package/dist/artifact-scan-policy.d.ts +35 -0
- package/dist/artifact-scan-policy.d.ts.map +1 -0
- package/dist/artifact-scan-policy.js +49 -0
- package/dist/artifact-scan-policy.js.map +1 -0
- package/dist/authored-completion-record.d.ts +35 -0
- package/dist/authored-completion-record.d.ts.map +1 -0
- package/dist/authored-completion-record.js +92 -0
- package/dist/authored-completion-record.js.map +1 -0
- package/dist/authored-completion.d.ts +99 -0
- package/dist/authored-completion.d.ts.map +1 -0
- package/dist/authored-completion.js +184 -0
- package/dist/authored-completion.js.map +1 -0
- package/dist/authored-flow-error.d.ts +13 -1
- package/dist/authored-flow-error.d.ts.map +1 -1
- package/dist/authored-flow-error.js +12 -0
- package/dist/authored-flow-error.js.map +1 -1
- package/dist/authored-flow-executor.d.ts +7 -30
- package/dist/authored-flow-executor.d.ts.map +1 -1
- package/dist/authored-flow-executor.js +64 -48
- package/dist/authored-flow-executor.js.map +1 -1
- package/dist/authored-human.d.ts.map +1 -1
- package/dist/authored-human.js +1 -3
- package/dist/authored-human.js.map +1 -1
- package/dist/authored-node-entry.js +4 -1
- package/dist/authored-node-entry.js.map +1 -1
- package/dist/authored-node-runner.d.ts +9 -1
- package/dist/authored-node-runner.d.ts.map +1 -1
- package/dist/authored-node-runner.js +92 -17
- package/dist/authored-node-runner.js.map +1 -1
- package/dist/authored-root.d.ts +5 -0
- package/dist/authored-root.d.ts.map +1 -1
- package/dist/authored-root.js +20 -2
- package/dist/authored-root.js.map +1 -1
- package/dist/authored-step-output.d.ts +35 -10
- package/dist/authored-step-output.d.ts.map +1 -1
- package/dist/authored-step-output.js +108 -40
- package/dist/authored-step-output.js.map +1 -1
- package/dist/authored-verdict.d.ts +28 -0
- package/dist/authored-verdict.d.ts.map +1 -0
- package/dist/authored-verdict.js +79 -0
- package/dist/authored-verdict.js.map +1 -0
- package/dist/authored-worker-step.d.ts +5 -2
- package/dist/authored-worker-step.d.ts.map +1 -1
- package/dist/authored-worker-step.js +48 -11
- package/dist/authored-worker-step.js.map +1 -1
- package/dist/bundle-extensions.d.ts.map +1 -1
- package/dist/bundle-extensions.js +4 -7
- package/dist/bundle-extensions.js.map +1 -1
- package/dist/bundle.d.ts.map +1 -1
- package/dist/bundle.js +41 -7
- package/dist/bundle.js.map +1 -1
- package/dist/canonical.d.ts.map +1 -1
- package/dist/canonical.js +18 -6
- package/dist/canonical.js.map +1 -1
- package/dist/cli/check-worker-surface.d.ts +27 -0
- package/dist/cli/check-worker-surface.d.ts.map +1 -0
- package/dist/cli/check-worker-surface.js +63 -0
- package/dist/cli/check-worker-surface.js.map +1 -0
- package/dist/cli/check.d.ts +19 -2
- package/dist/cli/check.d.ts.map +1 -1
- package/dist/cli/check.js +12 -4
- package/dist/cli/check.js.map +1 -1
- package/dist/cli/cloud-format.d.ts +9 -0
- package/dist/cli/cloud-format.d.ts.map +1 -0
- package/dist/cli/cloud-format.js +77 -0
- package/dist/cli/cloud-format.js.map +1 -0
- package/dist/cli/cloud-live.d.ts +39 -0
- package/dist/cli/cloud-live.d.ts.map +1 -0
- package/dist/cli/cloud-live.js +325 -0
- package/dist/cli/cloud-live.js.map +1 -0
- package/dist/cli/cloud-read.d.ts +3 -7
- package/dist/cli/cloud-read.d.ts.map +1 -1
- package/dist/cli/cloud-read.js +14 -266
- package/dist/cli/cloud-read.js.map +1 -1
- package/dist/cli/cloud-refusal.d.ts +39 -0
- package/dist/cli/cloud-refusal.d.ts.map +1 -0
- package/dist/cli/cloud-refusal.js +95 -0
- package/dist/cli/cloud-refusal.js.map +1 -0
- package/dist/cli/cloud-status-view.d.ts +7 -0
- package/dist/cli/cloud-status-view.d.ts.map +1 -0
- package/dist/cli/cloud-status-view.js +214 -0
- package/dist/cli/cloud-status-view.js.map +1 -0
- package/dist/cli/direct-run.d.ts.map +1 -1
- package/dist/cli/direct-run.js +16 -2
- package/dist/cli/direct-run.js.map +1 -1
- package/dist/cli/hn-monitor.d.ts +0 -13
- 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/local-agent-remedy.d.ts +80 -0
- package/dist/cli/local-agent-remedy.d.ts.map +1 -0
- package/dist/cli/local-agent-remedy.js +116 -0
- package/dist/cli/local-agent-remedy.js.map +1 -0
- package/dist/cli/observer-session.d.ts +41 -0
- package/dist/cli/observer-session.d.ts.map +1 -0
- package/dist/cli/observer-session.js +78 -0
- package/dist/cli/observer-session.js.map +1 -0
- package/dist/cli/run.d.ts +30 -2
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +186 -24
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/status.d.ts +9 -0
- package/dist/cli/status.d.ts.map +1 -1
- package/dist/cli/status.js +31 -2
- package/dist/cli/status.js.map +1 -1
- package/dist/cli/step-evidence.d.ts +90 -0
- package/dist/cli/step-evidence.d.ts.map +1 -0
- package/dist/cli/step-evidence.js +259 -0
- package/dist/cli/step-evidence.js.map +1 -0
- package/dist/cli/step-failure.d.ts +14 -4
- package/dist/cli/step-failure.d.ts.map +1 -1
- package/dist/cli/step-failure.js +41 -76
- package/dist/cli/step-failure.js.map +1 -1
- package/dist/cli-commands.d.ts +6 -0
- package/dist/cli-commands.d.ts.map +1 -1
- package/dist/cli-commands.js +2 -0
- package/dist/cli-commands.js.map +1 -1
- package/dist/cli.d.ts +10 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +53 -42
- package/dist/cli.js.map +1 -1
- package/dist/cloud-read.d.ts +15 -0
- package/dist/cloud-read.d.ts.map +1 -1
- package/dist/cloud-read.js +20 -1
- package/dist/cloud-read.js.map +1 -1
- package/dist/cloud-run-record.d.ts +27 -0
- package/dist/cloud-run-record.d.ts.map +1 -0
- package/dist/cloud-run-record.js +56 -0
- package/dist/cloud-run-record.js.map +1 -0
- package/dist/cloud-run.d.ts +2 -9
- package/dist/cloud-run.d.ts.map +1 -1
- package/dist/cloud-run.js +3 -20
- package/dist/cloud-run.js.map +1 -1
- package/dist/communication/local.d.ts.map +1 -1
- package/dist/communication/local.js +2 -1
- package/dist/communication/local.js.map +1 -1
- package/dist/communication/worker.d.ts +1 -1
- package/dist/communication/worker.d.ts.map +1 -1
- package/dist/communication/worker.js +13 -5
- package/dist/communication/worker.js.map +1 -1
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +28 -6
- package/dist/compile.js.map +1 -1
- package/dist/direct-input.d.ts.map +1 -1
- package/dist/direct-input.js +21 -1
- package/dist/direct-input.js.map +1 -1
- package/dist/failure-kinds.d.ts +96 -6
- package/dist/failure-kinds.d.ts.map +1 -1
- package/dist/failure-kinds.js +29 -2
- package/dist/failure-kinds.js.map +1 -1
- package/dist/flow-extension-compat.d.ts.map +1 -1
- package/dist/flow-extension-compat.js +26 -8
- package/dist/flow-extension-compat.js.map +1 -1
- package/dist/flow-extension-loader.d.ts +7 -0
- package/dist/flow-extension-loader.d.ts.map +1 -1
- package/dist/flow-extension-loader.js +48 -22
- package/dist/flow-extension-loader.js.map +1 -1
- package/dist/flow-requirements.d.ts.map +1 -1
- package/dist/flow-requirements.js +24 -9
- package/dist/flow-requirements.js.map +1 -1
- package/dist/fs-descriptor.d.ts +17 -0
- package/dist/fs-descriptor.d.ts.map +1 -0
- package/dist/fs-descriptor.js +96 -0
- package/dist/fs-descriptor.js.map +1 -0
- package/dist/gate-contract.d.ts +7 -0
- package/dist/gate-contract.d.ts.map +1 -1
- package/dist/gate-contract.js +6 -1
- package/dist/gate-contract.js.map +1 -1
- package/dist/helper-preflight.d.ts.map +1 -1
- package/dist/helper-preflight.js +10 -3
- package/dist/helper-preflight.js.map +1 -1
- package/dist/helper-reference.d.ts +25 -0
- package/dist/helper-reference.d.ts.map +1 -0
- package/dist/helper-reference.js +129 -0
- package/dist/helper-reference.js.map +1 -0
- package/dist/hosted-base-snapshot.d.ts +25 -0
- package/dist/hosted-base-snapshot.d.ts.map +1 -0
- package/dist/hosted-base-snapshot.js +278 -0
- package/dist/hosted-base-snapshot.js.map +1 -0
- package/dist/hosted-extension-declarations.d.ts +10 -0
- package/dist/hosted-extension-declarations.d.ts.map +1 -0
- package/dist/hosted-extension-declarations.js +272 -0
- package/dist/hosted-extension-declarations.js.map +1 -0
- package/dist/hosted-extension-isolation.d.ts +82 -0
- package/dist/hosted-extension-isolation.d.ts.map +1 -0
- package/dist/hosted-extension-isolation.js +322 -0
- package/dist/hosted-extension-isolation.js.map +1 -0
- package/dist/hosted-extension-manifest.d.ts +9 -0
- package/dist/hosted-extension-manifest.d.ts.map +1 -0
- package/dist/hosted-extension-manifest.js +235 -0
- package/dist/hosted-extension-manifest.js.map +1 -0
- package/dist/hosted-extension-protocol.d.ts +16 -0
- package/dist/hosted-extension-protocol.d.ts.map +1 -0
- package/dist/hosted-extension-protocol.js +224 -0
- package/dist/hosted-extension-protocol.js.map +1 -0
- package/dist/hosted-extension-runtime.d.ts +30 -0
- package/dist/hosted-extension-runtime.d.ts.map +1 -0
- package/dist/hosted-extension-runtime.js +167 -0
- package/dist/hosted-extension-runtime.js.map +1 -0
- package/dist/hosted-extension-sandbox-source.d.ts +9 -0
- package/dist/hosted-extension-sandbox-source.d.ts.map +1 -0
- package/dist/hosted-extension-sandbox-source.js +95 -0
- package/dist/hosted-extension-sandbox-source.js.map +1 -0
- package/dist/hosted-extension-sandbox.d.ts +39 -0
- package/dist/hosted-extension-sandbox.d.ts.map +1 -0
- package/dist/hosted-extension-sandbox.js +418 -0
- package/dist/hosted-extension-sandbox.js.map +1 -0
- package/dist/hosted-project.d.ts +3 -0
- package/dist/hosted-project.d.ts.map +1 -0
- package/dist/hosted-project.js +19 -0
- package/dist/hosted-project.js.map +1 -0
- package/dist/hosted-promise-safety.d.ts +12 -0
- package/dist/hosted-promise-safety.d.ts.map +1 -0
- package/dist/hosted-promise-safety.js +63 -0
- package/dist/hosted-promise-safety.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/intrinsic-array.d.ts +3 -0
- package/dist/intrinsic-array.d.ts.map +1 -0
- package/dist/intrinsic-array.js +14 -0
- package/dist/intrinsic-array.js.map +1 -0
- package/dist/journal-client.d.ts +3 -1
- package/dist/journal-client.d.ts.map +1 -1
- package/dist/journal-client.js +17 -2
- package/dist/journal-client.js.map +1 -1
- package/dist/journal-projection.d.ts +16 -0
- package/dist/journal-projection.d.ts.map +1 -0
- package/dist/journal-projection.js +108 -0
- package/dist/journal-projection.js.map +1 -0
- package/dist/json-value.d.ts +6 -1
- package/dist/json-value.d.ts.map +1 -1
- package/dist/json-value.js +155 -36
- package/dist/json-value.js.map +1 -1
- package/dist/llm-worker.d.ts +9 -0
- package/dist/llm-worker.d.ts.map +1 -1
- package/dist/llm-worker.js +16 -2
- package/dist/llm-worker.js.map +1 -1
- package/dist/local-agent.d.ts +1 -1
- package/dist/local-agent.d.ts.map +1 -1
- package/dist/local-agent.js +4 -3
- package/dist/local-agent.js.map +1 -1
- package/dist/named-gate-lowering.js +35 -5
- package/dist/named-gate-lowering.js.map +1 -1
- package/dist/named-gate-preflight.d.ts +27 -0
- package/dist/named-gate-preflight.d.ts.map +1 -0
- package/dist/named-gate-preflight.js +47 -0
- package/dist/named-gate-preflight.js.map +1 -0
- package/dist/named-gates.d.ts +1 -1
- package/dist/named-gates.d.ts.map +1 -1
- package/dist/named-gates.js +3 -0
- package/dist/named-gates.js.map +1 -1
- package/dist/observer-link.d.ts +7 -0
- package/dist/observer-link.d.ts.map +1 -1
- package/dist/observer-link.js +3 -1
- package/dist/observer-link.js.map +1 -1
- package/dist/plugin-store.d.ts +8 -2
- package/dist/plugin-store.d.ts.map +1 -1
- package/dist/plugin-store.js +233 -56
- package/dist/plugin-store.js.map +1 -1
- package/dist/preflight.d.ts.map +1 -1
- package/dist/preflight.js +7 -0
- package/dist/preflight.js.map +1 -1
- package/dist/protocol.d.ts +2 -0
- package/dist/protocol.d.ts.map +1 -1
- package/dist/redact.d.ts +42 -0
- package/dist/redact.d.ts.map +1 -1
- package/dist/redact.js +128 -0
- package/dist/redact.js.map +1 -1
- package/dist/run-projection.d.ts +83 -0
- package/dist/run-projection.d.ts.map +1 -0
- package/dist/run-projection.js +199 -0
- package/dist/run-projection.js.map +1 -0
- package/dist/semver-range.d.ts.map +1 -1
- package/dist/semver-range.js +27 -15
- package/dist/semver-range.js.map +1 -1
- package/dist/shell-word.d.ts +19 -0
- package/dist/shell-word.d.ts.map +1 -0
- package/dist/shell-word.js +23 -0
- package/dist/shell-word.js.map +1 -0
- package/dist/spec.d.ts +52 -3
- package/dist/spec.d.ts.map +1 -1
- package/dist/spec.js.map +1 -1
- package/dist/step-fields.d.ts +1 -1
- package/dist/step-fields.js +1 -1
- package/dist/step-fields.js.map +1 -1
- package/dist/steps-green.d.ts +27 -0
- package/dist/steps-green.d.ts.map +1 -0
- package/dist/steps-green.js +164 -0
- package/dist/steps-green.js.map +1 -0
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +39 -8
- package/dist/validate.js.map +1 -1
- package/dist/worker-lease.d.ts +8 -1
- package/dist/worker-lease.d.ts.map +1 -1
- package/dist/worker-lease.js +34 -4
- package/dist/worker-lease.js.map +1 -1
- package/dist/worker.d.ts +8 -0
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +17 -9
- package/dist/worker.js.map +1 -1
- package/package.json +3 -7
- package/src/agent-artifacts.ts +2 -10
- package/src/agent-cwd.ts +139 -0
- package/src/artifact-scan-policy.ts +51 -0
- package/src/authored-completion-record.ts +119 -0
- package/src/authored-completion.ts +203 -0
- package/src/authored-flow-error.ts +13 -1
- package/src/authored-flow-executor.ts +101 -59
- package/src/authored-human.ts +1 -4
- package/src/authored-node-entry.ts +4 -1
- package/src/authored-node-runner.ts +96 -22
- package/src/authored-root.ts +20 -2
- package/src/authored-step-output.ts +139 -42
- package/src/authored-verdict.ts +87 -0
- package/src/authored-worker-step.ts +60 -12
- package/src/bundle-extensions.ts +6 -5
- package/src/bundle.ts +52 -7
- package/src/canonical.ts +20 -6
- package/src/cli/check-worker-surface.ts +66 -0
- package/src/cli/check.ts +35 -4
- package/src/cli/cloud-format.ts +82 -0
- package/src/cli/cloud-live.ts +366 -0
- package/src/cli/cloud-read.ts +13 -282
- package/src/cli/cloud-refusal.ts +113 -0
- package/src/cli/cloud-status-view.ts +213 -0
- package/src/cli/direct-run.ts +19 -2
- package/src/cli/hn-monitor.ts +2 -1
- package/src/cli/local-agent-remedy.ts +160 -0
- package/src/cli/observer-session.ts +107 -0
- package/src/cli/run.ts +233 -28
- package/src/cli/status.ts +59 -3
- package/src/cli/step-evidence.ts +310 -0
- package/src/cli/step-failure.ts +57 -81
- package/src/cli-commands.ts +2 -0
- package/src/cli.ts +64 -44
- package/src/cloud-read.ts +25 -1
- package/src/cloud-run-record.ts +64 -0
- package/src/cloud-run.ts +5 -24
- package/src/communication/local.ts +2 -1
- package/src/communication/worker.ts +13 -5
- package/src/compile.ts +28 -6
- package/src/direct-input.ts +22 -1
- package/src/failure-kinds.ts +104 -2
- package/src/flow-extension-compat.ts +32 -7
- package/src/flow-extension-loader.ts +56 -21
- package/src/flow-requirements.ts +24 -9
- package/src/fs-descriptor.ts +127 -0
- package/src/gate-contract.ts +13 -1
- package/src/helper-preflight.ts +10 -3
- package/src/helper-reference.ts +130 -0
- package/src/hosted-base-snapshot.ts +351 -0
- package/src/hosted-extension-declarations.ts +387 -0
- package/src/hosted-extension-isolation.ts +457 -0
- package/src/hosted-extension-manifest.ts +249 -0
- package/src/hosted-extension-protocol.ts +262 -0
- package/src/hosted-extension-runtime.ts +266 -0
- package/src/hosted-extension-sandbox-source.ts +94 -0
- package/src/hosted-extension-sandbox.ts +489 -0
- package/src/hosted-project.ts +18 -0
- package/src/hosted-promise-safety.ts +68 -0
- package/src/index.ts +20 -0
- package/src/intrinsic-array.ts +14 -0
- package/src/journal-client.ts +19 -2
- package/src/journal-projection.ts +106 -0
- package/src/json-value.ts +184 -32
- package/src/llm-worker.ts +16 -2
- package/src/local-agent.ts +4 -2
- package/src/named-gate-lowering.ts +35 -5
- package/src/named-gate-preflight.ts +47 -0
- package/src/named-gates.ts +3 -0
- package/src/observer-link.ts +10 -1
- package/src/plugin-store.ts +323 -56
- package/src/preflight.ts +7 -0
- package/src/protocol.ts +2 -0
- package/src/redact.ts +111 -0
- package/src/run-projection.ts +247 -0
- package/src/semver-range.ts +39 -14
- package/src/shell-word.ts +24 -0
- package/src/spec.ts +54 -3
- package/src/step-fields.ts +1 -1
- package/src/steps-green.ts +168 -0
- package/src/validate.ts +35 -8
- package/src/worker-lease.ts +35 -5
- package/src/worker.ts +27 -11
package/src/validate.ts
CHANGED
|
@@ -19,10 +19,12 @@ import type {
|
|
|
19
19
|
import { SPEC_SCHEMA_VERSION } from './spec.js';
|
|
20
20
|
import { validateOutputDeclaration } from './output-schema.js';
|
|
21
21
|
import { modelNameError } from './model-name.js';
|
|
22
|
+
import { agentCwdDeclarationError, agentCwdTransportError } from './agent-cwd.js';
|
|
22
23
|
import { unknownKeyErrors } from './unknown-keys.js';
|
|
23
24
|
import { stepDependencyErrors } from './step-dependencies.js';
|
|
24
25
|
import { inputBindingErrors } from './input-binding.js';
|
|
25
26
|
import { NAMED_GATE_KEYS, namedGateErrors } from './named-gates.js';
|
|
27
|
+
import { STEPS_GREEN_KEYS, stepsGreenErrors, stepsGreenReferenceErrors } from './steps-green.js';
|
|
26
28
|
import {
|
|
27
29
|
AGENT_DECLARATION_FIELDS,
|
|
28
30
|
FLOW_FIELDS,
|
|
@@ -74,6 +76,7 @@ const BUDGET_KEYS = ['maxTokensIn', 'maxTokensOut', 'maxDollars', 'maxTokens', '
|
|
|
74
76
|
const VERIFICATION_KEYS: Record<string, readonly string[]> = {
|
|
75
77
|
...NAMED_GATE_KEYS,
|
|
76
78
|
exit_code: ['type', 'expect'],
|
|
79
|
+
steps_green: STEPS_GREEN_KEYS,
|
|
77
80
|
output_contains: ['type', 'value'],
|
|
78
81
|
json_schema: ['type', 'schema'],
|
|
79
82
|
};
|
|
@@ -195,6 +198,9 @@ class Validator {
|
|
|
195
198
|
// Dependents must reference real step ids and form a DAG (no cycles).
|
|
196
199
|
for (const error of stepDependencyErrors(steps, this.ids)) this.fail(error);
|
|
197
200
|
for (const error of inputBindingErrors(steps)) this.fail(error);
|
|
201
|
+
// A steps_green gate that names nothing readable is the `|| true` failure
|
|
202
|
+
// it replaces, so its references are refused at the flow level, not lowered.
|
|
203
|
+
for (const error of stepsGreenReferenceErrors(steps)) this.fail(error);
|
|
198
204
|
return this.result();
|
|
199
205
|
}
|
|
200
206
|
|
|
@@ -443,10 +449,14 @@ class Validator {
|
|
|
443
449
|
} catch (error) {
|
|
444
450
|
this.fail(error instanceof Error ? error.message : `${at}.schema: expected JSON-compatible data`);
|
|
445
451
|
}
|
|
452
|
+
// Below here are the gates the COMPILER lowers; above are the three the
|
|
453
|
+
// kernel evaluates itself. The enumeration follows the same split.
|
|
454
|
+
} else if (gate.type === 'steps_green') {
|
|
455
|
+
for (const error of stepsGreenErrors(v, at, stepType)) this.fail(error);
|
|
446
456
|
} else if (Object.hasOwn(NAMED_GATE_KEYS, gate.type)) {
|
|
447
457
|
for (const error of namedGateErrors(v, input, at)) this.fail(error);
|
|
448
458
|
} else {
|
|
449
|
-
this.fail(`${at}.type: unknown_gate_kind: expected exit_code | output_contains | json_schema | references_input | subprocess_gate | word_count_bounds | regex_match | artifact_exists`);
|
|
459
|
+
this.fail(`${at}.type: unknown_gate_kind: expected exit_code | output_contains | json_schema | steps_green | references_input | subprocess_gate | word_count_bounds | regex_match | artifact_exists`);
|
|
450
460
|
}
|
|
451
461
|
}
|
|
452
462
|
|
|
@@ -460,6 +470,12 @@ class Validator {
|
|
|
460
470
|
if (st.timeoutMs !== undefined && !isPosInt(st.timeoutMs)) {
|
|
461
471
|
this.fail(`${at}.timeoutMs: expected a positive integer`);
|
|
462
472
|
}
|
|
473
|
+
// Only the two policies the kernel enum names. A third spelling would
|
|
474
|
+
// deserialize-fail in the kernel, so it is refused where the author can
|
|
475
|
+
// still read the error.
|
|
476
|
+
if (st.onNonZero !== undefined && st.onNonZero !== 'fail' && st.onNonZero !== 'record') {
|
|
477
|
+
this.fail(`${at}.onNonZero: expected fail | record`);
|
|
478
|
+
}
|
|
463
479
|
}
|
|
464
480
|
|
|
465
481
|
private validateLlm(st: LlmStepSpec, at: string): void {
|
|
@@ -486,13 +502,7 @@ class Validator {
|
|
|
486
502
|
}
|
|
487
503
|
this.validateCli(st.cli, at);
|
|
488
504
|
this.validateModel(st.model, at);
|
|
489
|
-
|
|
490
|
-
// check` and the run agree. Not resolved against the checking directory:
|
|
491
|
-
// that would make the compiled spec (and its hash) depend on where the
|
|
492
|
-
// check ran. `f.agent` resolves before compiling, so it never lands here.
|
|
493
|
-
if (st.cwd !== undefined && (!isNonEmptyString(st.cwd) || !st.cwd.startsWith('/'))) {
|
|
494
|
-
this.fail(`${at}.cwd: expected an absolute path (got ${JSON.stringify(st.cwd)})`);
|
|
495
|
-
}
|
|
505
|
+
this.validateCwd(st, at);
|
|
496
506
|
if (st.surfaces !== undefined) this.validateSurfaces(st.surfaces, `${at}.surfaces`);
|
|
497
507
|
if (st.permissions !== undefined) this.validatePermissions(st.permissions, `${at}.permissions`);
|
|
498
508
|
}
|
|
@@ -503,6 +513,23 @@ class Validator {
|
|
|
503
513
|
}
|
|
504
514
|
}
|
|
505
515
|
|
|
516
|
+
/**
|
|
517
|
+
* The declaration half of `cwd`: lexical, so an author sees the refusal from
|
|
518
|
+
* `flows check` rather than from a dispatch. Whether the directory exists and
|
|
519
|
+
* lies inside the run root is the worker's question (`agent-cwd.ts`), asked on
|
|
520
|
+
* the host that shares the agent's filesystem.
|
|
521
|
+
*/
|
|
522
|
+
private validateCwd(st: AgentStepSpec, at: string): void {
|
|
523
|
+
if (st.cwd === undefined) return;
|
|
524
|
+
const problem = agentCwdDeclarationError(st.cwd);
|
|
525
|
+
if (problem !== undefined) {
|
|
526
|
+
this.fail(`${at}.cwd: ${problem}`);
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
const unsupported = agentCwdTransportError(st.cwd, st.transport);
|
|
530
|
+
if (unsupported !== undefined) this.fail(`${at}.${unsupported}`);
|
|
531
|
+
}
|
|
532
|
+
|
|
506
533
|
private validateModel(model: unknown, at: string, required = false): void {
|
|
507
534
|
// Rejecting the empty string matters: it would reach the CLI as
|
|
508
535
|
// RELAYFLOW_MODEL='', which reads as "declared, and declared as
|
package/src/worker-lease.ts
CHANGED
|
@@ -1,6 +1,33 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { JournalProtocolError, type JournalClient } from './journal-client.js';
|
|
2
2
|
import type { StepDispatchEvent } from './protocol.js';
|
|
3
3
|
|
|
4
|
+
export class WorkerLeaseLostError extends Error {
|
|
5
|
+
constructor(readonly reason: 'already_expired' | 'renewal_expired' | 'completion_expired', message: string) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = 'WorkerLeaseLostError';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** No cause traversal: worker errors preserve their original identity. */
|
|
12
|
+
export function isLeaseLost(error: unknown): boolean {
|
|
13
|
+
return error instanceof WorkerLeaseLostError || (error instanceof JournalProtocolError
|
|
14
|
+
&& (error.code === 'lease_conflict' || (error.code === 'run_terminal'
|
|
15
|
+
&& ['step.heartbeat', 'step.complete', 'step.wait'].includes(error.verb ?? ''))));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function onWorkerFailure(label: string, fatal: (error: unknown) => void) {
|
|
19
|
+
return (error: unknown, dispatch?: StepDispatchEvent): void => {
|
|
20
|
+
// Without the dispatch there is no attempt to hand back to the kernel: fail closed.
|
|
21
|
+
if (!isLeaseLost(error) || dispatch === undefined) { fatal(error); return; }
|
|
22
|
+
// The kernel owns this attempt's fate; its journal supplies the run outcome.
|
|
23
|
+
// stderr keeps this diagnostic out of structured reports on stdout.
|
|
24
|
+
process.emitWarning(
|
|
25
|
+
`${label}: run_id=${dispatch.run_id} step_id=${dispatch.step_id} attempt=${dispatch.attempt}: ${String(error)}`,
|
|
26
|
+
{ code: 'FLOWS_WORKER_LEASE_LOST' },
|
|
27
|
+
);
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
4
31
|
/** Hold the dispatched lease only while its subprocess is still ours to run. */
|
|
5
32
|
export async function withWorkerLease<T>(
|
|
6
33
|
client: JournalClient,
|
|
@@ -16,12 +43,15 @@ export async function withWorkerLease<T>(
|
|
|
16
43
|
const fail = (error: unknown): void => { controller.abort(error); };
|
|
17
44
|
const armExpiry = (deadline: number): number => {
|
|
18
45
|
const remaining = deadline - Date.now();
|
|
19
|
-
if (!Number.isFinite(remaining)
|
|
46
|
+
if (!Number.isFinite(remaining)) {
|
|
20
47
|
throw new Error(`Agent lease is already expired for ${dispatch.run_id}/${dispatch.step_id}.`);
|
|
21
48
|
}
|
|
49
|
+
if (remaining <= 0) {
|
|
50
|
+
throw new WorkerLeaseLostError('already_expired', `Agent lease is already expired for ${dispatch.run_id}/${dispatch.step_id}.`);
|
|
51
|
+
}
|
|
22
52
|
latestDeadline = deadline;
|
|
23
53
|
if (expiryTimer !== undefined) clearTimeout(expiryTimer);
|
|
24
|
-
expiryTimer = setTimeout(() => fail(new
|
|
54
|
+
expiryTimer = setTimeout(() => fail(new WorkerLeaseLostError('renewal_expired',
|
|
25
55
|
`Agent lease expired before renewal for ${dispatch.run_id}/${dispatch.step_id}.`,
|
|
26
56
|
)), remaining);
|
|
27
57
|
return remaining;
|
|
@@ -34,7 +64,7 @@ export async function withWorkerLease<T>(
|
|
|
34
64
|
// A response handled after local expiry cannot revive ownership, even
|
|
35
65
|
// if its future deadline was issued before this event loop stalled.
|
|
36
66
|
if (Date.now() >= latestDeadline) {
|
|
37
|
-
throw new
|
|
67
|
+
throw new WorkerLeaseLostError('renewal_expired', `Agent lease expired before renewal for ${dispatch.run_id}/${dispatch.step_id}.`);
|
|
38
68
|
}
|
|
39
69
|
const remaining = armExpiry(result.lease_deadline_ms);
|
|
40
70
|
if (!stopped) {
|
|
@@ -57,7 +87,7 @@ export async function withWorkerLease<T>(
|
|
|
57
87
|
// Timer callbacks can be delayed behind a resolved subprocess promise.
|
|
58
88
|
// Check the clock itself before permitting step.complete.
|
|
59
89
|
if (Date.now() >= latestDeadline) {
|
|
60
|
-
throw new
|
|
90
|
+
throw new WorkerLeaseLostError('completion_expired', `Agent lease expired before completion for ${dispatch.run_id}/${dispatch.step_id}.`);
|
|
61
91
|
}
|
|
62
92
|
return result;
|
|
63
93
|
} finally {
|
package/src/worker.ts
CHANGED
|
@@ -6,6 +6,7 @@ import type { JournalClient } from './journal-client.js';
|
|
|
6
6
|
import type { Pins, StepDispatchEvent } from './protocol.js';
|
|
7
7
|
import type { KernelAgentStep } from './spec.js';
|
|
8
8
|
import { runAgentCli } from './worker-cli.js';
|
|
9
|
+
import { agentStepCwd } from './agent-cwd.js';
|
|
9
10
|
import { resolveCliModel } from './cli-adapter.js';
|
|
10
11
|
import { withWorkerLease } from './worker-lease.js';
|
|
11
12
|
import { workerInstruction } from './worker-input.js';
|
|
@@ -22,6 +23,14 @@ export interface AgentWorkerOptions {
|
|
|
22
23
|
requiredStreams?: string[];
|
|
23
24
|
dataDir?: string;
|
|
24
25
|
onPtyReady?: (path: string) => void;
|
|
26
|
+
/**
|
|
27
|
+
* The run root a step's declared `cwd` is resolved against and held inside.
|
|
28
|
+
* Defaults to this process's working directory, which is what the run root
|
|
29
|
+
* is: `flows run` attaches the worker from the directory it was invoked in,
|
|
30
|
+
* and that directory is the uploaded tree on the Cloud path. Named here so
|
|
31
|
+
* the root a dispatch is measured against is a value, not an assumption.
|
|
32
|
+
*/
|
|
33
|
+
runRoot?: string;
|
|
25
34
|
}
|
|
26
35
|
|
|
27
36
|
/**
|
|
@@ -95,7 +104,7 @@ export class AgentWorker extends EventEmitter {
|
|
|
95
104
|
if (this.closing) return;
|
|
96
105
|
if (dispatch.step_type !== 'agent') return;
|
|
97
106
|
const running: Promise<void> = this.execute(dispatch).catch((error: unknown) => {
|
|
98
|
-
this.emit('error', error);
|
|
107
|
+
this.emit('error', error, dispatch);
|
|
99
108
|
});
|
|
100
109
|
this.inFlight.add(running);
|
|
101
110
|
void running.finally(() => { this.inFlight.delete(running); });
|
|
@@ -113,21 +122,28 @@ export class AgentWorker extends EventEmitter {
|
|
|
113
122
|
if (communication) {
|
|
114
123
|
if (!this.options.dataDir) throw new Error('Agent communication requires a worker data directory');
|
|
115
124
|
const { completeCommunicationDispatch } = await import('./communication/worker.js');
|
|
116
|
-
await completeCommunicationDispatch(this.client, dispatch, communication, this.options.dataDir);
|
|
125
|
+
await completeCommunicationDispatch(this.client, dispatch, communication, this.options.dataDir, this.options.runRoot);
|
|
117
126
|
return;
|
|
118
127
|
}
|
|
119
128
|
let humanIntervention = false;
|
|
120
129
|
const effectiveModel = typeof spec.cli === 'string' ? resolveCliModel(spec.cli, spec.model) : spec.model;
|
|
130
|
+
// Resolved here, before the lease, because this is the process that shares
|
|
131
|
+
// the agent's filesystem. A refusal completes the step the way a missing
|
|
132
|
+
// CLI does — journaled as `worker_error` with the reason — rather than
|
|
133
|
+
// spawning into a directory nobody established is inside the run root.
|
|
134
|
+
const cwd = agentStepCwd(spec, dispatch.step_id, this.options.runRoot);
|
|
121
135
|
const completed: WorkerCliResult = await withWorkerLease(this.client, dispatch, signal =>
|
|
122
|
-
|
|
123
|
-
?
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
136
|
+
'refusal' in cwd
|
|
137
|
+
? Promise.resolve({ exit_code: null, stdout_tail: '', stderr_tail: cwd.refusal })
|
|
138
|
+
: typeof spec.cli === 'string' && typeof spec.instruction === 'string'
|
|
139
|
+
? runAgentCli(spec.cli, workerInstruction(spec.instruction, dispatch), dispatch.wake_context, effectiveModel, undefined, signal, 'agent', this.options.dataDir === undefined ? undefined : {
|
|
140
|
+
dataDir: this.options.dataDir, runId: dispatch.run_id, stepId: dispatch.step_id, attempt: dispatch.attempt,
|
|
141
|
+
onReady: this.options.onPtyReady, onDrive: () => { humanIntervention = true; },
|
|
142
|
+
}, cwd.directory ?? (spec.transport === 'relay' ? undefined : this.options.runRoot),
|
|
143
|
+
spec.transport === 'relay' ? 'relay' : 'direct',
|
|
144
|
+
{ runId: dispatch.run_id, stepId: dispatch.step_id, idempotencyKey: dispatch.idempotency_key,
|
|
145
|
+
dataDir: this.options.dataDir, resultSchema: spec.verification?.json_schema })
|
|
146
|
+
: Promise.resolve({ exit_code: null, stdout_tail: '', stderr_tail: 'agent step has no declared CLI' }));
|
|
131
147
|
const { result, usage } = workerSpend(completed, effectiveModel);
|
|
132
148
|
const completionReason = result.exit_code === 0 ? 'success' : 'worker_error';
|
|
133
149
|
|