@relayflows/sdk 2.0.34 → 2.0.36

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.
Files changed (162) hide show
  1. package/dist/adapters/base.d.ts +16 -0
  2. package/dist/adapters/base.d.ts.map +1 -1
  3. package/dist/adapters/claude.d.ts.map +1 -1
  4. package/dist/adapters/claude.js +15 -0
  5. package/dist/adapters/claude.js.map +1 -1
  6. package/dist/adapters/codex.d.ts.map +1 -1
  7. package/dist/adapters/codex.js +4 -0
  8. package/dist/adapters/codex.js.map +1 -1
  9. package/dist/adapters/usage-limit.d.ts +2 -0
  10. package/dist/adapters/usage-limit.d.ts.map +1 -0
  11. package/dist/adapters/usage-limit.js +17 -0
  12. package/dist/adapters/usage-limit.js.map +1 -0
  13. package/dist/authored-activity.d.ts +17 -0
  14. package/dist/authored-activity.d.ts.map +1 -0
  15. package/dist/authored-activity.js +218 -0
  16. package/dist/authored-activity.js.map +1 -0
  17. package/dist/authored-child-run.d.ts +34 -0
  18. package/dist/authored-child-run.d.ts.map +1 -0
  19. package/dist/authored-child-run.js +128 -0
  20. package/dist/authored-child-run.js.map +1 -0
  21. package/dist/authored-dispatch.d.ts +24 -0
  22. package/dist/authored-dispatch.d.ts.map +1 -0
  23. package/dist/authored-dispatch.js +81 -0
  24. package/dist/authored-dispatch.js.map +1 -0
  25. package/dist/authored-flow-error.d.ts +32 -3
  26. package/dist/authored-flow-error.d.ts.map +1 -1
  27. package/dist/authored-flow-error.js +3 -1
  28. package/dist/authored-flow-error.js.map +1 -1
  29. package/dist/authored-flow-executor.d.ts +26 -1
  30. package/dist/authored-flow-executor.d.ts.map +1 -1
  31. package/dist/authored-flow-executor.js +122 -16
  32. package/dist/authored-flow-executor.js.map +1 -1
  33. package/dist/authored-flow-loader.d.ts.map +1 -1
  34. package/dist/authored-flow-loader.js +9 -0
  35. package/dist/authored-flow-loader.js.map +1 -1
  36. package/dist/authored-mcp.js +2 -2
  37. package/dist/authored-mcp.js.map +1 -1
  38. package/dist/authored-node-entry.js +4 -1
  39. package/dist/authored-node-entry.js.map +1 -1
  40. package/dist/authored-node-runner.d.ts.map +1 -1
  41. package/dist/authored-node-runner.js +40 -8
  42. package/dist/authored-node-runner.js.map +1 -1
  43. package/dist/authored-plugin-effect.js +2 -2
  44. package/dist/authored-plugin-effect.js.map +1 -1
  45. package/dist/authored-root.d.ts +10 -7
  46. package/dist/authored-root.d.ts.map +1 -1
  47. package/dist/authored-root.js +20 -0
  48. package/dist/authored-root.js.map +1 -1
  49. package/dist/authored-step-output.d.ts +24 -8
  50. package/dist/authored-step-output.d.ts.map +1 -1
  51. package/dist/authored-step-output.js +81 -15
  52. package/dist/authored-step-output.js.map +1 -1
  53. package/dist/authored-subscription-park.d.ts +5 -0
  54. package/dist/authored-subscription-park.d.ts.map +1 -0
  55. package/dist/authored-subscription-park.js +47 -0
  56. package/dist/authored-subscription-park.js.map +1 -0
  57. package/dist/authored-worker-step.d.ts +3 -1
  58. package/dist/authored-worker-step.d.ts.map +1 -1
  59. package/dist/authored-worker-step.js +25 -9
  60. package/dist/authored-worker-step.js.map +1 -1
  61. package/dist/cli/check-activities.d.ts +8 -0
  62. package/dist/cli/check-activities.d.ts.map +1 -0
  63. package/dist/cli/check-activities.js +155 -0
  64. package/dist/cli/check-activities.js.map +1 -0
  65. package/dist/cli/cli-probe.d.ts.map +1 -1
  66. package/dist/cli/cli-probe.js +14 -2
  67. package/dist/cli/cli-probe.js.map +1 -1
  68. package/dist/cli/direct-run.d.ts.map +1 -1
  69. package/dist/cli/direct-run.js +10 -2
  70. package/dist/cli/direct-run.js.map +1 -1
  71. package/dist/cli/run.d.ts +23 -5
  72. package/dist/cli/run.d.ts.map +1 -1
  73. package/dist/cli/run.js +32 -5
  74. package/dist/cli/run.js.map +1 -1
  75. package/dist/cli/subscription-report.d.ts +5 -0
  76. package/dist/cli/subscription-report.d.ts.map +1 -0
  77. package/dist/cli/subscription-report.js +48 -0
  78. package/dist/cli/subscription-report.js.map +1 -0
  79. package/dist/cli-adapter.d.ts +4 -2
  80. package/dist/cli-adapter.d.ts.map +1 -1
  81. package/dist/cli-adapter.js +4 -0
  82. package/dist/cli-adapter.js.map +1 -1
  83. package/dist/cli.d.ts +1 -1
  84. package/dist/cli.d.ts.map +1 -1
  85. package/dist/cli.js +16 -5
  86. package/dist/cli.js.map +1 -1
  87. package/dist/cloud-mirror-step.d.ts +2 -0
  88. package/dist/cloud-mirror-step.d.ts.map +1 -1
  89. package/dist/cloud-mirror-step.js +9 -1
  90. package/dist/cloud-mirror-step.js.map +1 -1
  91. package/dist/cloud-mirror.d.ts.map +1 -1
  92. package/dist/cloud-mirror.js +17 -2
  93. package/dist/cloud-mirror.js.map +1 -1
  94. package/dist/failure-kinds.d.ts +2 -2
  95. package/dist/failure-kinds.d.ts.map +1 -1
  96. package/dist/failure-kinds.js +2 -0
  97. package/dist/failure-kinds.js.map +1 -1
  98. package/dist/index.d.ts +1 -1
  99. package/dist/index.d.ts.map +1 -1
  100. package/dist/index.js.map +1 -1
  101. package/dist/journal-client.d.ts +17 -2
  102. package/dist/journal-client.d.ts.map +1 -1
  103. package/dist/journal-client.js +33 -2
  104. package/dist/journal-client.js.map +1 -1
  105. package/dist/journal-reader.d.ts.map +1 -1
  106. package/dist/journal-reader.js +2 -0
  107. package/dist/journal-reader.js.map +1 -1
  108. package/dist/local-agent.d.ts +4 -1
  109. package/dist/local-agent.d.ts.map +1 -1
  110. package/dist/local-agent.js +14 -4
  111. package/dist/local-agent.js.map +1 -1
  112. package/dist/preflight.d.ts +6 -0
  113. package/dist/preflight.d.ts.map +1 -1
  114. package/dist/preflight.js +36 -10
  115. package/dist/preflight.js.map +1 -1
  116. package/dist/protocol.d.ts +166 -1
  117. package/dist/protocol.d.ts.map +1 -1
  118. package/dist/step-settling.d.ts +11 -0
  119. package/dist/step-settling.d.ts.map +1 -0
  120. package/dist/step-settling.js +22 -0
  121. package/dist/step-settling.js.map +1 -0
  122. package/dist/worker-slots.d.ts +15 -0
  123. package/dist/worker-slots.d.ts.map +1 -1
  124. package/dist/worker-slots.js +40 -3
  125. package/dist/worker-slots.js.map +1 -1
  126. package/package.json +2 -2
  127. package/src/adapters/base.ts +19 -0
  128. package/src/adapters/claude.ts +15 -0
  129. package/src/adapters/codex.ts +6 -0
  130. package/src/adapters/usage-limit.ts +17 -0
  131. package/src/authored-activity.ts +251 -0
  132. package/src/authored-child-run.ts +138 -0
  133. package/src/authored-dispatch.ts +113 -0
  134. package/src/authored-flow-error.ts +36 -0
  135. package/src/authored-flow-executor.ts +166 -15
  136. package/src/authored-flow-loader.ts +12 -0
  137. package/src/authored-mcp.ts +2 -2
  138. package/src/authored-node-entry.ts +4 -1
  139. package/src/authored-node-runner.ts +41 -8
  140. package/src/authored-plugin-effect.ts +2 -2
  141. package/src/authored-root.ts +28 -4
  142. package/src/authored-step-output.ts +88 -15
  143. package/src/authored-subscription-park.ts +46 -0
  144. package/src/authored-worker-step.ts +24 -8
  145. package/src/cli/check-activities.ts +144 -0
  146. package/src/cli/cli-probe.ts +15 -3
  147. package/src/cli/direct-run.ts +9 -0
  148. package/src/cli/run.ts +56 -9
  149. package/src/cli/subscription-report.ts +51 -0
  150. package/src/cli-adapter.ts +8 -2
  151. package/src/cli.ts +16 -6
  152. package/src/cloud-mirror-step.ts +16 -2
  153. package/src/cloud-mirror.ts +15 -2
  154. package/src/failure-kinds.ts +2 -0
  155. package/src/index.ts +6 -0
  156. package/src/journal-client.ts +47 -3
  157. package/src/journal-reader.ts +2 -0
  158. package/src/local-agent.ts +17 -3
  159. package/src/preflight.ts +46 -10
  160. package/src/protocol.ts +129 -0
  161. package/src/step-settling.ts +19 -0
  162. package/src/worker-slots.ts +63 -4
@@ -0,0 +1,81 @@
1
+ import { AuthoredFlowExecutionError } from './authored-flow-error.js';
2
+ import { flowRequirements } from './flow-requirements.js';
3
+ export const MAX_DISPATCH_DEPTH = 3;
4
+ /** Resolve one attenuated direct child from the statically loaded `use` graph. */
5
+ export function resolveDispatchChild(options) {
6
+ if (typeof options.flowName !== 'string' || options.flowName.trim() === '') {
7
+ throw new AuthoredFlowExecutionError('dispatch_invalid', 'f.dispatch requires a non-empty declared child flow name');
8
+ }
9
+ if (options.depth >= MAX_DISPATCH_DEPTH) {
10
+ throw new AuthoredFlowExecutionError('dispatch_depth_exceeded', `f.dispatch depth exceeds ${MAX_DISPATCH_DEPTH}; flatten the flow tree or move work into the current child`);
11
+ }
12
+ const current = options.graph?.find(node => node.handle === options.handle);
13
+ const direct = current?.use.map(path => options.graph.find(node => node.path === path)) ?? [];
14
+ const matches = direct.filter((node) => node !== undefined && node.getDefinition(node.handle).name === options.flowName);
15
+ if (matches.length !== 1) {
16
+ const declared = direct.filter((node) => node !== undefined)
17
+ .map(node => node.getDefinition(node.handle).name).sort();
18
+ throw new AuthoredFlowExecutionError(matches.length > 1 ? 'dispatch_invalid' : 'dispatch_unknown', `flow "${options.definition.name}" cannot dispatch ${JSON.stringify(options.flowName)}; direct use children: ${declared.length === 0 ? '(none)' : declared.join(', ')}`);
19
+ }
20
+ const child = matches[0];
21
+ const childDefinition = child.getDefinition(child.handle);
22
+ assertChildCapabilities(options.definition, childDefinition);
23
+ if (childDefinition.header.budget !== undefined) {
24
+ throw new AuthoredFlowExecutionError('dispatch_invalid', `child flow "${childDefinition.name}" declares its own budget; put the run-tree ceiling on "${options.definition.name}" until nested budget intersection ships`);
25
+ }
26
+ return child;
27
+ }
28
+ export function parseDispatchReceipt(value, step) {
29
+ let parsed;
30
+ try {
31
+ parsed = JSON.parse(value);
32
+ }
33
+ catch {
34
+ throw new AuthoredFlowExecutionError('journal_protocol_violation', `dispatch step "${step}" recorded invalid JSON`);
35
+ }
36
+ const receipt = parsed;
37
+ if (typeof receipt !== 'object' || receipt === null || typeof receipt.name !== 'string'
38
+ || receipt.completionReason !== 'success'
39
+ || (receipt.completionDetail !== undefined && typeof receipt.completionDetail !== 'string')) {
40
+ throw new AuthoredFlowExecutionError('journal_protocol_violation', `dispatch step "${step}" recorded an invalid child receipt`);
41
+ }
42
+ return {
43
+ name: receipt.name,
44
+ completionReason: 'success',
45
+ ...(receipt.completionDetail === undefined ? {} : { completionDetail: receipt.completionDetail }),
46
+ };
47
+ }
48
+ /** Last visible child operations; the dispatch receipt joins all of them. */
49
+ export function childLeaves(steps) {
50
+ const visible = steps.filter(step => !/(?:^|--)complete-[1-9][0-9]*$/.test(step.id));
51
+ const parents = new Set(visible.flatMap(step => step.after ?? []));
52
+ return visible.map(step => step.id).filter(id => !parents.has(id));
53
+ }
54
+ /** A child may use only provider/MCP capabilities its parent already declared. */
55
+ function assertChildCapabilities(parent, child) {
56
+ const parentTools = parent.header?.tools ?? {};
57
+ const childTools = child.header?.tools ?? {};
58
+ for (const [tool, declared] of Object.entries(childTools)) {
59
+ if (tool === 'mcp') {
60
+ const allowed = new Set(Array.isArray(parentTools.mcp) ? parentTools.mcp : []);
61
+ const requested = Array.isArray(declared) ? declared : [];
62
+ if (requested.some(server => !allowed.has(server))) {
63
+ throw new AuthoredFlowExecutionError('dispatch_invalid', `child flow "${child.name}" widens tools.mcp beyond parent "${parent.name}"`);
64
+ }
65
+ }
66
+ }
67
+ const parentHelpers = helperAuthority(parent);
68
+ for (const requirement of flowRequirements(child).integrations) {
69
+ if ((requirement.from === 'tools' || requirement.from === 'helper')
70
+ && !parentHelpers.has(requirement.provider)) {
71
+ throw new AuthoredFlowExecutionError('dispatch_invalid', `child flow "${child.name}" requires ${requirement.detail}, which parent "${parent.name}" did not grant`);
72
+ }
73
+ }
74
+ }
75
+ /** Helper providers this flow can delegate, from explicit or statically visible use. */
76
+ export function helperAuthority(definition) {
77
+ return new Set(flowRequirements(definition).integrations
78
+ .filter(requirement => requirement.from === 'tools' || requirement.from === 'helper')
79
+ .map(requirement => requirement.provider));
80
+ }
81
+ //# sourceMappingURL=authored-dispatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authored-dispatch.js","sourceRoot":"","sources":["../src/authored-dispatch.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,17 @@
1
1
  import type { HumanRecipient } from './human-to.js';
2
2
  import type { ParkCause, StepFailedDetails } from './failure-kinds.js';
3
3
  import type { CompletionReason as ProtocolCompletionReason, RunCompletionReason as ProtocolRunCompletionReason } from './protocol.js';
4
- export type AuthoredFlowExecutionErrorCode = 'helper_provider.mount_required' | 'helper_provider.unsupported' | 'helper_slack.credential_missing' | 'helper_slack.mount_required' | 'budget_syntax_invalid' | 'agent_cli_unresolved' | 'agent_parked' | 'llm_cli_unresolved' | 'llm_parked' | 'duplicate_completion' | 'journal_protocol_violation' | 'missing_completion' | 'memory_unreachable' | 'operation_after_completion' | 'operation_callback_failed' | 'step_failed' | 'lease_exceeded' | 'unsupported_completion' | 'unsupported_gate' | 'gate_failed'
4
+ export type AuthoredFlowExecutionErrorCode = 'helper_provider.mount_required' | 'helper_provider.unsupported' | 'helper_slack.credential_missing' | 'helper_slack.mount_required' | 'budget_syntax_invalid'
5
+ /** The step's CLI is too old for its model — an environment refusal, not a spec error. */
6
+ | 'cli_outdated'
7
+ /** The step's credential hit a provider usage/rate limit during preflight. */
8
+ | 'provider_usage_limited' | 'agent_cli_unresolved' | 'agent_parked' | 'llm_cli_unresolved' | 'llm_parked' | 'duplicate_completion' | 'dispatch_depth_exceeded' | 'dispatch_invalid' | 'dispatch_unknown' | 'journal_protocol_violation' | 'missing_completion' | 'memory_unreachable' | 'operation_after_completion' | 'operation_callback_failed' | 'step_failed' | 'lease_exceeded' | 'unsupported_completion' | 'unsupported_gate' | 'gate_failed'
5
9
  /** The body reached an unanswered `f.human`; the root parked on it. */
6
10
  | 'human_parked'
7
11
  /** A recorded answer to `f.human` was not `{ answer: boolean }`. */
8
12
  | 'human_answer_invalid'
9
13
  /** `f.human`'s `to` is not one of the documented recipient forms (human-to.ts). */
10
- | 'human_to_invalid' | 'unsupported_header' | 'unsettled_derived_work' | 'unsupported_promise_lifecycle' | 'unsupported_workspace_permission' | 'unawaited_step' | 'unsupported_verb';
14
+ | 'human_to_invalid' | 'unsupported_header' | 'unsettled_derived_work' | 'unsupported_promise_lifecycle' | 'unsupported_workspace_permission' | 'unbounded_subscription' | 'activity_closed' | 'subscription_suspended' | 'unawaited_step' | 'unsupported_verb';
11
15
  export declare class AuthoredFlowExecutionError extends Error {
12
16
  readonly code: AuthoredFlowExecutionErrorCode;
13
17
  readonly completionReason?: (ProtocolCompletionReason | ProtocolRunCompletionReason) | undefined;
@@ -26,6 +30,7 @@ export declare class AuthoredFlowExecutionError extends Error {
26
30
  * Node-child error frame — can forward it instead of dropping it.
27
31
  */
28
32
  readonly details?: StepFailedDetails | undefined;
33
+ readonly suspension?: AuthoredFlowSuspension | undefined;
29
34
  /** Set by the durable root driver after the child error crosses any IPC boundary. */
30
35
  rootRunId?: string;
31
36
  /**
@@ -55,8 +60,32 @@ export declare class AuthoredFlowExecutionError extends Error {
55
60
  * wrapper on the way out — the `lease_exceeded` remap, the authenticated
56
61
  * Node-child error frame — can forward it instead of dropping it.
57
62
  */
58
- details?: StepFailedDetails | undefined);
63
+ details?: StepFailedDetails | undefined, suspension?: AuthoredFlowSuspension | undefined);
59
64
  }
65
+ /** Serialized into the CLI report so Cloud can atomically finish activation or wait for a wake. */
66
+ export type AuthoredFlowSuspension =
67
+ /**
68
+ * Exact durable `subscription.prepared` facts Cloud must persist before it
69
+ * fences provider ingress and invokes `subscription.activate`. Binding
70
+ * generation and ingress cursor are Cloud-assigned receipts, deliberately
71
+ * absent from the authored request.
72
+ */
73
+ {
74
+ readonly kind: 'activation';
75
+ readonly subscriptionId: string;
76
+ readonly eventTypes: readonly string[];
77
+ readonly pattern?: Readonly<Record<string, unknown>>;
78
+ readonly stream: string;
79
+ readonly settleMs: number;
80
+ readonly idleMs: number;
81
+ readonly deadlineAtMs: number;
82
+ readonly includeSelf: boolean;
83
+ } | {
84
+ readonly kind: 'event_wait';
85
+ readonly subscriptionId: string;
86
+ readonly stream: string;
87
+ readonly deadlineAtMs: number;
88
+ };
60
89
  /** The question an authored body parked on, as the kernel journals it. */
61
90
  export interface AuthoredHumanWait {
62
91
  readonly waitId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"authored-flow-error.d.ts","sourceRoot":"","sources":["../src/authored-flow-error.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,KAAK,EACV,gBAAgB,IAAI,wBAAwB,EAC5C,mBAAmB,IAAI,2BAA2B,EACnD,MAAM,eAAe,CAAC;AAEvB,MAAM,MAAM,8BAA8B,GACtC,gCAAgC,GAChC,6BAA6B,GAC7B,iCAAiC,GACjC,6BAA6B,GAC7B,uBAAuB,GACvB,sBAAsB,GACtB,cAAc,GACd,oBAAoB,GACpB,YAAY,GACZ,sBAAsB,GACtB,4BAA4B,GAC5B,oBAAoB,GACpB,oBAAoB,GACpB,4BAA4B,GAC5B,2BAA2B,GAC3B,aAAa,GACb,gBAAgB,GAChB,wBAAwB,GACxB,kBAAkB,GAClB,aAAa;AACf,uEAAuE;GACrE,cAAc;AAChB,oEAAoE;GAClE,sBAAsB;AACxB,mFAAmF;GACjF,kBAAkB,GAClB,oBAAoB,GACpB,wBAAwB,GACxB,+BAA+B,GAC/B,kCAAkC,GAClC,gBAAgB,GAChB,kBAAkB,CAAC;AAEvB,qBAAa,0BAA2B,SAAQ,KAAK;IAgBjD,QAAQ,CAAC,IAAI,EAAE,8BAA8B;IAE7C,QAAQ,CAAC,gBAAgB,CAAC,GAAE,wBAAwB,GAAG,2BAA2B;IAClF;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM;IACvB;;;;;;;OAOG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,iBAAiB;IAhCtC,qFAAqF;IACrF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;OAUG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;gBAEX,IAAI,EAAE,8BAA8B,EAC7C,OAAO,EAAE,MAAM,EACN,gBAAgB,CAAC,GAAE,wBAAwB,GAAG,2BAA2B,aAAA;IAClF;;;;OAIG;IACM,KAAK,CAAC,EAAE,MAAM,YAAA;IACvB;;;;;;;OAOG;IACM,OAAO,CAAC,EAAE,iBAAiB,YAAA;CAKvC;AAED,0EAA0E;AAC1E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,8EAA8E;IAC9E,QAAQ,CAAC,SAAS,CAAC,EAAE,cAAc,CAAC;CACrC;AAED;;;;;GAKG;AACH,qBAAa,mBAAoB,SAAQ,0BAA0B;IACrD,QAAQ,CAAC,IAAI,EAAE,iBAAiB;gBAAvB,IAAI,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM;CAShE"}
1
+ {"version":3,"file":"authored-flow-error.d.ts","sourceRoot":"","sources":["../src/authored-flow-error.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@ export class AuthoredFlowExecutionError extends Error {
3
3
  completionReason;
4
4
  runId;
5
5
  details;
6
+ suspension;
6
7
  /** Set by the durable root driver after the child error crosses any IPC boundary. */
7
8
  rootRunId;
8
9
  /**
@@ -32,12 +33,13 @@ export class AuthoredFlowExecutionError extends Error {
32
33
  * wrapper on the way out — the `lease_exceeded` remap, the authenticated
33
34
  * Node-child error frame — can forward it instead of dropping it.
34
35
  */
35
- details) {
36
+ details, suspension) {
36
37
  super(`${code}: ${message}`);
37
38
  this.code = code;
38
39
  this.completionReason = completionReason;
39
40
  this.runId = runId;
40
41
  this.details = details;
42
+ this.suspension = suspension;
41
43
  this.name = 'AuthoredFlowExecutionError';
42
44
  }
43
45
  }
@@ -1 +1 @@
1
- {"version":3,"file":"authored-flow-error.js","sourceRoot":"","sources":["../src/authored-flow-error.ts"],"names":[],"mappings":"AAyCA,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IAgBxC;IAEA;IAMA;IASA;IAhCX,qFAAqF;IACrF,SAAS,CAAU;IACnB;;;;;;;;;;OAUG;IACH,SAAS,CAAa;IACtB,YACW,IAAoC,EAC7C,OAAe,EACN,gBAAyE;IAClF;;;;OAIG;IACM,KAAc;IACvB;;;;;;;OAOG;IACM,OAA2B;QAEpC,KAAK,CAAC,GAAG,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC;QAnBpB,SAAI,GAAJ,IAAI,CAAgC;QAEpC,qBAAgB,GAAhB,gBAAgB,CAAyD;QAMzE,UAAK,GAAL,KAAK,CAAS;QASd,YAAO,GAAP,OAAO,CAAoB;QAGpC,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;IAC3C,CAAC;CACF;AAWD;;;;;GAKG;AACH,MAAM,OAAO,mBAAoB,SAAQ,0BAA0B;IAC5C;IAArB,YAAqB,IAAuB,EAAE,SAAiB;QAC7D,KAAK,CACH,cAAc,EACd,uBAAuB,IAAI,CAAC,EAAE,cAAc,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,MAAM,GAAG,EAC5F,SAAS,EACT,SAAS,CACV,CAAC;QANiB,SAAI,GAAJ,IAAI,CAAmB;QAO1C,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF"}
1
+ {"version":3,"file":"authored-flow-error.js","sourceRoot":"","sources":["../src/authored-flow-error.ts"],"names":[],"mappings":"AAmDA,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IAgBxC;IAEA;IAMA;IASA;IACA;IAjCX,qFAAqF;IACrF,SAAS,CAAU;IACnB;;;;;;;;;;OAUG;IACH,SAAS,CAAa;IACtB,YACW,IAAoC,EAC7C,OAAe,EACN,gBAAyE;IAClF;;;;OAIG;IACM,KAAc;IACvB;;;;;;;OAOG;IACM,OAA2B,EAC3B,UAAmC;QAE5C,KAAK,CAAC,GAAG,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC;QApBpB,SAAI,GAAJ,IAAI,CAAgC;QAEpC,qBAAgB,GAAhB,gBAAgB,CAAyD;QAMzE,UAAK,GAAL,KAAK,CAAS;QASd,YAAO,GAAP,OAAO,CAAoB;QAC3B,eAAU,GAAV,UAAU,CAAyB;QAG5C,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;IAC3C,CAAC;CACF;AAoCD;;;;;GAKG;AACH,MAAM,OAAO,mBAAoB,SAAQ,0BAA0B;IAC5C;IAArB,YAAqB,IAAuB,EAAE,SAAiB;QAC7D,KAAK,CACH,cAAc,EACd,uBAAuB,IAAI,CAAC,EAAE,cAAc,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,MAAM,GAAG,EAC5F,SAAS,EACT,SAAS,CACV,CAAC;QANiB,SAAI,GAAJ,IAAI,CAAmB;QAO1C,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF"}
@@ -1,13 +1,16 @@
1
+ import { AuthoredBudget } from './authored-budget.js';
1
2
  import { type LoweredCompletionReason } from './authored-completion.js';
2
3
  import { type FlowHandle } from '@relayflows/surface/runtime';
3
4
  import { type ProgressEvent } from './progress.js';
4
5
  import type { GetFlowDefinition } from './authored-flow-loader.js';
6
+ import type { LoadedAuthoredFlowNode } from './authored-flow-loader.js';
5
7
  import type { RunLifecycleOptions } from './cli/run.js';
6
- import { AuthoredFlowExecutionError, type AuthoredFlowExecutionErrorCode } from './authored-flow-error.js';
8
+ import { AuthoredFlowExecutionError, type AuthoredFlowSuspension, type AuthoredFlowExecutionErrorCode } from './authored-flow-error.js';
7
9
  import { type AuthoredStepEdges } from './authored-step-index.js';
8
10
  import { JournalClient } from './journal-client.js';
9
11
  import { type HostedExtensionDispatch, type LoadedFlowExtension } from './flow-extension-loader.js';
10
12
  import type { CompletionReason as ProtocolCompletionReason } from './protocol.js';
13
+ import type { AuthoredWorkerSlots } from './worker-slots.js';
11
14
  export { AuthoredFlowExecutionError, type AuthoredFlowExecutionErrorCode };
12
15
  export interface AuthoredFlowJournalStep extends AuthoredStepEdges {
13
16
  readonly id: string;
@@ -21,6 +24,7 @@ export interface AuthoredExecutionRuntime {
21
24
  readonly payloadSha256: string;
22
25
  }
23
26
  export interface AuthoredFlowExecutionResult {
27
+ readonly state?: undefined;
24
28
  readonly executionRuntime?: AuthoredExecutionRuntime;
25
29
  readonly rootRunId?: string;
26
30
  readonly name: string;
@@ -33,6 +37,13 @@ export interface AuthoredFlowExecutionResult {
33
37
  readonly completionDetail?: string;
34
38
  readonly journalSteps: readonly AuthoredFlowJournalStep[];
35
39
  }
40
+ /** A body reached a durable event boundary and released its worker lease. */
41
+ export interface AuthoredFlowSuspendedResult {
42
+ readonly state: 'suspended';
43
+ readonly name: string;
44
+ readonly suspension: AuthoredFlowSuspension;
45
+ readonly journalSteps: readonly AuthoredFlowJournalStep[];
46
+ }
36
47
  /**
37
48
  * Exercise the internal authored-flow lowering seam through protocol v0.
38
49
  *
@@ -87,6 +98,20 @@ export interface ExecuteAuthoredFlowOptions {
87
98
  * from authored input: direct `/workflows/run` callers control that JSON.
88
99
  */
89
100
  readonly extensionDispatch?: HostedExtensionDispatch;
101
+ /** Pinned static `use:` graph available to `f.dispatch`. */
102
+ readonly flowGraph?: readonly LoadedAuthoredFlowNode[];
103
+ /** Internal namespace for descendant step/admission identities. */
104
+ readonly stepPrefix?: string;
105
+ /** Current child depth. Root is zero; dispatch is capped at three. */
106
+ readonly dispatchDepth?: number;
107
+ /** Parent predecessors inherited by the first operation in a child body. */
108
+ readonly entryAfter?: readonly string[];
109
+ /** Root-owned budget accumulator shared by every descendant. */
110
+ readonly sharedBudget?: AuthoredBudget;
111
+ /** Root-owned worker capacity shared by every descendant. */
112
+ readonly workerSlots?: AuthoredWorkerSlots;
113
+ /** Parent helper authority inherited by this dispatched child. */
114
+ readonly allowedHelperProviders?: ReadonlySet<string>;
90
115
  }
91
116
  export declare function executeAuthoredFlow<Input = undefined>(handle: FlowHandle, journal: JournalClient, input?: Input, options?: ExecuteAuthoredFlowOptions): Promise<AuthoredFlowExecutionResult>;
92
117
  //# sourceMappingURL=authored-flow-executor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"authored-flow-executor.d.ts","sourceRoot":"","sources":["../src/authored-flow-executor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"authored-flow-executor.d.ts","sourceRoot":"","sources":["../src/authored-flow-executor.ts"],"names":[],"mappings":"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"}
@@ -24,10 +24,12 @@ import { readHumanAnswer } from './authored-human.js';
24
24
  import { parseHumanTo } from './human-to.js';
25
25
  import { AuthoredFlowOperation, stopAuthoredOperations, verifyAuthoredOperations, } from './authored-flow-operation.js';
26
26
  import { AuthoredFlowLifecycle } from './authored-flow-lifecycle.js';
27
+ import { AuthoredActivities } from './authored-activity.js';
27
28
  import { displayLabel } from './authored-step-index.js';
28
29
  import { PluginError } from './plugin-manifest.js';
29
30
  import { createHookEvaluator } from './authored-hooks.js';
30
31
  import { extensionHandlerForHostedDispatch, probeFlowExtension, } from './flow-extension-loader.js';
32
+ import { childLeaves, helperAuthority, parseDispatchReceipt, resolveDispatchChild } from './authored-dispatch.js';
31
33
  export { AuthoredFlowExecutionError };
32
34
  export async function executeAuthoredFlow(handle, journal, input, options = {}) {
33
35
  assertAuthoredPromiseHooks();
@@ -46,7 +48,7 @@ export async function executeAuthoredFlow(handle, journal, input, options = {})
46
48
  };
47
49
  const definition = getDefinition(handle);
48
50
  const hostedHandler = extensionHandlerForHostedDispatch(options.extensionDispatch, options.extensions ?? []);
49
- const headerFields = Object.keys(definition.header).filter(key => key !== 'tools' && key !== 'budget' && key !== 'memory' && key !== 'version' && key !== 'hooks');
51
+ const headerFields = Object.keys(definition.header).filter(key => key !== 'tools' && key !== 'budget' && key !== 'memory' && key !== 'version' && key !== 'hooks' && key !== 'use');
50
52
  if (definition.header.tools && Object.keys(definition.header.tools).some(key => !['mcp', ...helperProviders.map(p => p.namespace)].includes(key)))
51
53
  headerFields.push('tools');
52
54
  if (definition.header.tools?.relayfile !== undefined)
@@ -75,7 +77,7 @@ export async function executeAuthoredFlow(handle, journal, input, options = {})
75
77
  // the manifest boundary, not merely proxy selected Ctx properties.
76
78
  throw new PluginError('plugin_unsupported', `${hostedHandler.extension.name}: hosted extension handlers require enforced manifest permission isolation (gate 8 / #442).`);
77
79
  }
78
- const budget = new AuthoredBudget(definition.header.budget);
80
+ const budget = options.sharedBudget ?? new AuthoredBudget(definition.header.budget);
79
81
  if (definition.header.memory?.agent === true) {
80
82
  throw new AuthoredFlowExecutionError('unsupported_header', 'memory.agent requires the follow-up identity-scoped agent memory adapter');
81
83
  }
@@ -87,16 +89,35 @@ export async function executeAuthoredFlow(handle, journal, input, options = {})
87
89
  const journalSteps = [];
88
90
  const authoredSteps = [];
89
91
  const lifecycle = new AuthoredFlowLifecycle();
90
- const stepEdges = (step) => lifecycle.stepEdges(step);
92
+ const activities = new AuthoredActivities(journal, options.rootRunId);
93
+ const edgeOverrides = new Map();
94
+ const stepEdges = (step) => {
95
+ const overridden = edgeOverrides.get(step);
96
+ if (overridden !== undefined)
97
+ return overridden;
98
+ const local = lifecycle.stepEdges(step);
99
+ if (local === undefined || (local.after !== undefined && local.after.length > 0) || options.entryAfter === undefined
100
+ || options.entryAfter.length === 0)
101
+ return local;
102
+ return { ...local, after: [...options.entryAfter] };
103
+ };
91
104
  let nextStep = 1;
92
105
  let requestedCompletion;
93
106
  let requestedDetail;
107
+ const qualify = (id) => `${options.stepPrefix ?? ''}${id}`;
108
+ const nextId = (kind) => qualify(`${kind}-${nextStep++}`);
109
+ const assertHelperAllowed = (provider) => {
110
+ if (options.allowedHelperProviders !== undefined && !options.allowedHelperProviders.has(provider)) {
111
+ throw new AuthoredFlowExecutionError('dispatch_invalid', `child flow "${definition.name}" attempted helper provider "${provider}" outside its parent's granted integrations`);
112
+ }
113
+ };
94
114
  const lowerDeterministic = authoredDeterministicRunner(definition.name, journal, journalSteps, budget, {
95
115
  ...(options.rootRunId === undefined ? {} : { rootRunId: options.rootRunId }),
96
116
  ...(options.dataDir === undefined ? {} : { dataDir: options.dataDir }),
117
+ ...(options.signal === undefined ? {} : { signal: options.signal }),
97
118
  stepEdges,
98
119
  });
99
- const worker = authoredWorkerRunner(definition, journal, flowPath, journalSteps, waitOptions, localAgentStream, budget, definition.header.budget, options.rootRunId, options.workerCapacity, stepEdges);
120
+ const worker = authoredWorkerRunner(definition, journal, flowPath, journalSteps, waitOptions, localAgentStream, budget, definition.header.budget, options.rootRunId, options.workerCapacity, stepEdges, options.workerSlots);
100
121
  /**
101
122
  * Predicate gates (docs/SURFACE.md §6). The closure runs here, once, on the
102
123
  * value the journal handed back; the VERDICT is then journaled as a lowered
@@ -194,7 +215,7 @@ export async function executeAuthoredFlow(handle, journal, input, options = {})
194
215
  lifecycle.applyPredicateGate = applyPredicateGate;
195
216
  function llmOperation(prompt, ...values) {
196
217
  assertOperationAllowed('llm', definition.name, requestedCompletion);
197
- const id = `llm-${nextStep++}`;
218
+ const id = nextId('llm');
198
219
  // Hoist the operation reference so the start closure can read the
199
220
  // caller's `.gate(config)` at spec-build time. AuthoredFlowOperation
200
221
  // begins after construction returns, so `llmOp` is defined by then.
@@ -222,7 +243,7 @@ export async function executeAuthoredFlow(handle, journal, input, options = {})
222
243
  if (policy !== undefined && policy !== 'fail' && policy !== 'record') {
223
244
  throw new AuthoredFlowExecutionError('unsupported_verb', `f.run options.onNonZero must be 'fail' or 'record' (got ${JSON.stringify(policy)}).`);
224
245
  }
225
- const id = `run-${nextStep++}`;
246
+ const id = nextId('run');
226
247
  if (policy === 'record') {
227
248
  let recordOp;
228
249
  recordOp = new AuthoredFlowOperation(id, 'run', () => assertOperationAllowed('run', definition.name, requestedCompletion), () => observeStep(id, 'deterministic', () => lowerDeterministic.recording(id, command, leaseMs, recordOp.namedGate), options.onProgress), lifecycle,
@@ -241,8 +262,9 @@ export async function executeAuthoredFlow(handle, journal, input, options = {})
241
262
  const slackRun = options.rootRunId ?? randomUUID();
242
263
  function slackOperation(call) {
243
264
  assertOperationAllowed(`slack.${call.verb}`, definition.name, requestedCompletion);
265
+ assertHelperAllowed(call.provider);
244
266
  const snapshot = snapshotJsonValue(call, 'f.slack call');
245
- const id = `slack-${slackRun}-${nextStep++}`;
267
+ const id = qualify(`slack-${slackRun}-${nextStep++}`);
246
268
  return trackStep(authoredSteps, new AuthoredFlowOperation(id, `slack.${call.verb}`, () => assertOperationAllowed(`slack.${call.verb}`, definition.name, requestedCompletion), async () => {
247
269
  const receipt = await runHelperEffect(journal, definition.name, id, snapshot, options.dataDir ?? dirname(journal.socketPath), journalSteps, options.rootRunId);
248
270
  return (call.verb === 'react' ? undefined : receipt);
@@ -262,8 +284,9 @@ export async function executeAuthoredFlow(handle, journal, input, options = {})
262
284
  ...createHelpers((call) => {
263
285
  const verb = `${call.provider}.${call.verb}`;
264
286
  assertOperationAllowed(verb, definition.name, requestedCompletion);
287
+ assertHelperAllowed(call.provider);
265
288
  const snapshot = snapshotJsonValue(call, `f.${verb} call`);
266
- const id = `${call.provider}-${slackRun}-${nextStep++}`;
289
+ const id = qualify(`${call.provider}-${slackRun}-${nextStep++}`);
267
290
  return trackStep(authoredSteps, new AuthoredFlowOperation(id, verb, () => assertOperationAllowed(verb, definition.name, requestedCompletion), async () => await runHelperEffect(journal, definition.name, id, snapshot, options.dataDir ?? dirname(journal.socketPath), journalSteps, options.rootRunId), lifecycle));
268
291
  }),
269
292
  slack: {
@@ -274,7 +297,7 @@ export async function executeAuthoredFlow(handle, journal, input, options = {})
274
297
  },
275
298
  mcp: buildMcpProxy(checkedMcp.inventory, (server, tool, args, known) => {
276
299
  assertOperationAllowed('mcp', definition.name, requestedCompletion);
277
- const id = `mcp-${nextStep++}`;
300
+ const id = nextId('mcp');
278
301
  return trackStep(authoredSteps, new AuthoredFlowOperation(id, 'mcp', () => assertOperationAllowed('mcp', definition.name, requestedCompletion), () => runMcpEffect(journal, definition.name, id, server, tool, args, known, checkedMcp.servers[server], journalSteps, options.rootRunId), lifecycle));
279
302
  }),
280
303
  memory: authoredMemory(scriptMemoryScope(flowPath, definition.name), () => assertOperationAllowed('memory', definition.name, requestedCompletion), definition.header.memory?.script !== false),
@@ -284,11 +307,19 @@ export async function executeAuthoredFlow(handle, journal, input, options = {})
284
307
  assertOperationAllowed('agent', definition.name, requestedCompletion);
285
308
  // Authored headers do not yet declare reusable named agents, so the name
286
309
  // identifies nothing to the kernel; it is the step's label in the DAG.
287
- const id = `agent-${nextStep++}`;
310
+ const id = nextId('agent');
288
311
  let agentOp;
289
312
  agentOp = new AuthoredFlowOperation(id, 'agent', () => assertOperationAllowed('agent', definition.name, requestedCompletion), () => observeStep(id, 'agent', () => worker.agent(id, options, agentOp.namedGate), onProgress), lifecycle, displayLabel(typeof name === 'string' ? name : undefined));
290
313
  return trackStep(authoredSteps, agentOp);
291
314
  },
315
+ on(source, activityOptions) {
316
+ assertOperationAllowed('on', definition.name, requestedCompletion);
317
+ // Activity ids are root-scoped (`activity-N`); a child's own counter would collide.
318
+ if ((options.dispatchDepth ?? 0) > 0) {
319
+ throw new AuthoredFlowExecutionError('dispatch_invalid', `child flow "${definition.name}" cannot call f.on in this release; activities are root-scoped`);
320
+ }
321
+ return activities.open(source, activityOptions);
322
+ },
292
323
  /**
293
324
  * `f.human` (docs/SURFACE.md §1, §7). The question is not a child run: it
294
325
  * is the ROOT attempt parking on the kernel's `wait.human`. The body
@@ -306,6 +337,9 @@ export async function executeAuthoredFlow(handle, journal, input, options = {})
306
337
  */
307
338
  human(question, humanOptions) {
308
339
  assertOperationAllowed('human', definition.name, requestedCompletion);
340
+ if ((options.dispatchDepth ?? 0) > 0) {
341
+ throw new AuthoredFlowExecutionError('dispatch_invalid', `child flow "${definition.name}" cannot call f.human in this release; the parent owns approval authority`);
342
+ }
309
343
  if (typeof question !== 'string' || question.trim() === '') {
310
344
  throw new AuthoredFlowExecutionError('human_answer_invalid', 'f.human requires a non-empty question');
311
345
  }
@@ -319,7 +353,7 @@ export async function executeAuthoredFlow(handle, journal, input, options = {})
319
353
  if (!parsedTo.ok) {
320
354
  throw new AuthoredFlowExecutionError('human_to_invalid', `f.human to ${parsedTo.reason}`);
321
355
  }
322
- const id = `human-${nextStep++}`;
356
+ const id = nextId('human');
323
357
  const to = humanOptions.to;
324
358
  // Hoisted like `llmOp`/`runOp`: the start closure reads the caller's
325
359
  // `.gate(config)` at spec-build time, so a named gate on the answer is
@@ -343,13 +377,66 @@ export async function executeAuthoredFlow(handle, journal, input, options = {})
343
377
  }, options.onProgress), lifecycle, {});
344
378
  return trackStep(authoredSteps, humanOp);
345
379
  },
346
- dispatch() {
380
+ dispatch(flowName, dispatchInput) {
347
381
  assertOperationAllowed('dispatch', definition.name, requestedCompletion);
348
- throw unsupportedVerb('dispatch');
382
+ const depth = options.dispatchDepth ?? 0;
383
+ const child = resolveDispatchChild({
384
+ handle, definition, graph: options.flowGraph,
385
+ flowName, depth,
386
+ });
387
+ const childDefinition = child.getDefinition(child.handle);
388
+ const inputSnapshot = snapshotJsonValue(dispatchInput, `f.dispatch(${JSON.stringify(flowName)}) input`);
389
+ const id = nextId('dispatch');
390
+ let dispatchOp;
391
+ dispatchOp = new AuthoredFlowOperation(id, 'dispatch', () => assertOperationAllowed('dispatch', definition.name, requestedCompletion), async () => {
392
+ const inheritedAfter = stepEdges(id)?.after ?? [];
393
+ const currentHelperAuthority = helperAuthority(definition);
394
+ const allowedHelperProviders = options.allowedHelperProviders === undefined
395
+ ? currentHelperAuthority
396
+ : new Set([...currentHelperAuthority].filter(provider => options.allowedHelperProviders.has(provider)));
397
+ const childResult = await executeAuthoredFlow(child.handle, journal, inputSnapshot, {
398
+ getDefinition: child.getDefinition,
399
+ dataDir: options.dataDir,
400
+ flowPath: child.path,
401
+ ...(localAgentStream === undefined ? {} : { localAgentStream }),
402
+ ...(options.workerCapacity === undefined ? {} : { workerCapacity: options.workerCapacity }),
403
+ ...(options.rootRunId === undefined ? {} : { rootRunId: options.rootRunId }),
404
+ flowGraph: options.flowGraph,
405
+ stepPrefix: `${id}--`,
406
+ dispatchDepth: depth + 1,
407
+ entryAfter: inheritedAfter,
408
+ sharedBudget: budget,
409
+ ...(worker.slots === undefined ? {} : { workerSlots: worker.slots }),
410
+ allowedHelperProviders,
411
+ ...(options.extensions === undefined ? {} : { extensions: options.extensions }),
412
+ onProgress,
413
+ ...(options.onWait === undefined ? {} : { onWait: options.onWait }),
414
+ ...(options.signal === undefined ? {} : { signal: options.signal }),
415
+ });
416
+ if (childResult.completionReason !== 'success') {
417
+ throw new AuthoredFlowExecutionError('step_failed', `child flow "${childResult.name}" completed with ${childResult.completionReason}`
418
+ + (childResult.completionDetail === undefined ? '' : `: ${childResult.completionDetail}`), childResult.completionReason === 'step_failed' ? 'step_failed' : undefined);
419
+ }
420
+ const leaves = childLeaves(childResult.journalSteps);
421
+ edgeOverrides.set(id, {
422
+ ...displayLabel(childResult.name),
423
+ ...(leaves.length > 0 ? { after: leaves } : inheritedAfter.length === 0
424
+ ? {} : { after: inheritedAfter }),
425
+ });
426
+ const receipt = {
427
+ name: childResult.name,
428
+ completionReason: 'success',
429
+ ...(childResult.completionDetail === undefined ? {} : { completionDetail: childResult.completionDetail }),
430
+ };
431
+ const literal = `'${JSON.stringify(receipt).replaceAll("'", "'\\''")}'`;
432
+ const recorded = await lowerDeterministic(id, `printf '%s' ${literal}`, false, undefined, dispatchOp.namedGate);
433
+ return parseDispatchReceipt(recorded, id);
434
+ }, lifecycle, displayLabel(flowName));
435
+ return trackStep(authoredSteps, dispatchOp);
349
436
  },
350
437
  hook(name, input) {
351
438
  assertOperationAllowed('hook', definition.name, requestedCompletion);
352
- const id = `hook-${nextStep++}`;
439
+ const id = nextId('hook');
353
440
  const snapshot = snapshotJsonValue(input, 'f.hook input');
354
441
  return trackStep(authoredSteps, new AuthoredFlowOperation(id, 'hook', () => assertOperationAllowed('hook', definition.name, requestedCompletion), async () => {
355
442
  const verdict = await evaluateHook(id, name, snapshot, context);
@@ -395,7 +482,7 @@ export async function executeAuthoredFlow(handle, journal, input, options = {})
395
482
  Object.assign(context, pluginHelpers(checkedMcp.plugins ?? [], (plugin, verb, args) => {
396
483
  const label = `${verb.namespace}.${verb.method}`;
397
484
  assertOperationAllowed(label, definition.name, requestedCompletion);
398
- const id = `plugin-${nextStep++}`;
485
+ const id = nextId('plugin');
399
486
  return trackStep(authoredSteps, new AuthoredFlowOperation(id, label, () => assertOperationAllowed(label, definition.name, requestedCompletion), () => runPluginEffect(journal, definition.name, id, plugin, verb, args, journalSteps, budget, options.rootRunId), lifecycle));
400
487
  }));
401
488
  let bodyFailed = false;
@@ -412,6 +499,12 @@ export async function executeAuthoredFlow(handle, journal, input, options = {})
412
499
  try {
413
500
  worker.stop(bodyFailure);
414
501
  await stopAuthoredOperations(authoredSteps, bodyFailure);
502
+ // A durable wait hands execution back to the control plane. Its
503
+ // subscriptions must keep receiving events while no body is running.
504
+ const parked = bodyFailure instanceof AuthoredFlowExecutionError
505
+ && (bodyFailure.code === 'subscription_suspended' || bodyFailure.code === 'human_parked');
506
+ if (!parked)
507
+ await activities.closeAll('canceled');
415
508
  }
416
509
  finally {
417
510
  lifecycle.close();
@@ -437,6 +530,7 @@ export async function executeAuthoredFlow(handle, journal, input, options = {})
437
530
  try {
438
531
  worker.stop(missingCompletion);
439
532
  await stopAuthoredOperations(authoredSteps, missingCompletion);
533
+ await activities.closeAll('canceled');
440
534
  }
441
535
  finally {
442
536
  lifecycle.close();
@@ -446,6 +540,18 @@ export async function executeAuthoredFlow(handle, journal, input, options = {})
446
540
  try {
447
541
  await verifyAuthoredOperations(definition.name, authoredSteps, lifecycle);
448
542
  }
543
+ catch (error) {
544
+ try {
545
+ await activities.closeAll('canceled');
546
+ }
547
+ finally {
548
+ lifecycle.close();
549
+ }
550
+ throw error;
551
+ }
552
+ try {
553
+ await activities.closeAll('run_completed');
554
+ }
449
555
  finally {
450
556
  lifecycle.close();
451
557
  }
@@ -463,7 +569,7 @@ export async function executeAuthoredFlow(handle, journal, input, options = {})
463
569
  // explanation the root had already journaled to `run_admission_conflict`.
464
570
  // With no detail there is no environment in the command and nothing to
465
571
  // commit, so that path is untouched.
466
- const terminalId = `complete-${nextStep}`;
572
+ const terminalId = qualify(`complete-${nextStep}`);
467
573
  const verdict = await commitAuthoredVerdict(journal, options.rootRunId, terminalId, {
468
574
  reason: requestedCompletion,
469
575
  ...(requestedDetail === undefined ? {} : { detail: requestedDetail }),