@osolmaz/pi-workflows 0.14.0 → 0.15.1

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 (235) hide show
  1. package/README.md +78 -110
  2. package/dist/builtins/autoimplement.workflow.js +3 -1
  3. package/dist/builtins/autoimplement.workflow.js.map +1 -1
  4. package/dist/builtins/change-verification.workflow.js +7 -2
  5. package/dist/builtins/change-verification.workflow.js.map +1 -1
  6. package/dist/builtins/metadata.d.ts +22 -0
  7. package/dist/builtins/metadata.js +10 -0
  8. package/dist/builtins/metadata.js.map +1 -0
  9. package/dist/builtins/monitor.workflow.js +4 -1
  10. package/dist/builtins/monitor.workflow.js.map +1 -1
  11. package/dist/builtins/sanity-check.workflow.js +4 -1
  12. package/dist/builtins/sanity-check.workflow.js.map +1 -1
  13. package/dist/builtins/workspace-preparation.workflow.js +3 -1
  14. package/dist/builtins/workspace-preparation.workflow.js.map +1 -1
  15. package/dist/controllers/index.d.ts +0 -1
  16. package/dist/controllers/index.js +0 -1
  17. package/dist/controllers/index.js.map +1 -1
  18. package/dist/controllers/sqlite.d.ts +51 -0
  19. package/dist/controllers/sqlite.js +433 -57
  20. package/dist/controllers/sqlite.js.map +1 -1
  21. package/dist/controllers/store.d.ts +1 -0
  22. package/dist/extension/controller-command.d.ts +22 -0
  23. package/dist/extension/controller-command.js +32 -0
  24. package/dist/extension/controller-command.js.map +1 -0
  25. package/dist/extension/index.d.ts +2 -9
  26. package/dist/extension/index.js +876 -3447
  27. package/dist/extension/index.js.map +1 -1
  28. package/dist/extension/message-card.d.ts +13 -0
  29. package/dist/extension/message-card.js +46 -0
  30. package/dist/extension/message-card.js.map +1 -0
  31. package/dist/extension/step-message.d.ts +5 -6
  32. package/dist/extension/step-message.js +41 -52
  33. package/dist/extension/step-message.js.map +1 -1
  34. package/dist/host/child-worker-supervisor.d.ts +50 -0
  35. package/dist/host/child-worker-supervisor.js +159 -0
  36. package/dist/host/child-worker-supervisor.js.map +1 -0
  37. package/dist/host/client.d.ts +48 -0
  38. package/dist/host/client.js +216 -0
  39. package/dist/host/client.js.map +1 -0
  40. package/dist/host/controller-worker-entry.d.ts +2 -0
  41. package/dist/host/controller-worker-entry.js +244 -0
  42. package/dist/host/controller-worker-entry.js.map +1 -0
  43. package/dist/host/controller-worker-protocol.d.ts +36 -0
  44. package/dist/host/controller-worker-protocol.js +49 -0
  45. package/dist/host/controller-worker-protocol.js.map +1 -0
  46. package/dist/host/controller-worker-supervisor.d.ts +21 -0
  47. package/dist/host/controller-worker-supervisor.js +54 -0
  48. package/dist/host/controller-worker-supervisor.js.map +1 -0
  49. package/dist/host/host-entry.d.ts +2 -0
  50. package/dist/host/host-entry.js +23 -0
  51. package/dist/host/host-entry.js.map +1 -0
  52. package/dist/host/processes.d.ts +17 -12
  53. package/dist/host/processes.js +154 -50
  54. package/dist/host/processes.js.map +1 -1
  55. package/dist/host/protocol.d.ts +38 -0
  56. package/dist/host/protocol.js +156 -0
  57. package/dist/host/protocol.js.map +1 -0
  58. package/dist/host/resolver-entry.d.ts +49 -0
  59. package/dist/host/resolver-entry.js +149 -0
  60. package/dist/host/resolver-entry.js.map +1 -0
  61. package/dist/host/rpc-executor.d.ts +14 -3
  62. package/dist/host/rpc-executor.js +63 -30
  63. package/dist/host/rpc-executor.js.map +1 -1
  64. package/dist/host/runner.d.ts +95 -29
  65. package/dist/host/runner.js +2311 -348
  66. package/dist/host/runner.js.map +1 -1
  67. package/dist/host/state.d.ts +174 -0
  68. package/dist/host/state.js +689 -0
  69. package/dist/host/state.js.map +1 -0
  70. package/dist/host/worker-entry.d.ts +10 -0
  71. package/dist/host/worker-entry.js +446 -0
  72. package/dist/host/worker-entry.js.map +1 -0
  73. package/dist/host/worker-protocol.d.ts +31 -0
  74. package/dist/host/worker-protocol.js +122 -0
  75. package/dist/host/worker-protocol.js.map +1 -0
  76. package/dist/host/worker-store.d.ts +80 -0
  77. package/dist/host/worker-store.js +91 -0
  78. package/dist/host/worker-store.js.map +1 -0
  79. package/dist/host/worker-supervisor.d.ts +22 -0
  80. package/dist/host/worker-supervisor.js +54 -0
  81. package/dist/host/worker-supervisor.js.map +1 -0
  82. package/dist/render/canvas.d.ts +2 -1
  83. package/dist/render/canvas.js +40 -15
  84. package/dist/render/canvas.js.map +1 -1
  85. package/dist/render/graph-render.d.ts +7 -3
  86. package/dist/render/graph-render.js +125 -74
  87. package/dist/render/graph-render.js.map +1 -1
  88. package/dist/state/database.js +3 -1
  89. package/dist/state/database.js.map +1 -1
  90. package/dist/state/index.d.ts +1 -0
  91. package/dist/state/index.js +1 -0
  92. package/dist/state/index.js.map +1 -1
  93. package/dist/state/schema.d.ts +1 -1
  94. package/dist/state/schema.js +171 -3
  95. package/dist/state/schema.js.map +1 -1
  96. package/dist/state/viewer.d.ts +46 -0
  97. package/dist/state/viewer.js +249 -0
  98. package/dist/state/viewer.js.map +1 -0
  99. package/dist/viewer/cli.d.ts +1 -1
  100. package/dist/viewer/cli.js +47 -18
  101. package/dist/viewer/cli.js.map +1 -1
  102. package/dist/workflows/composition.js +25 -2
  103. package/dist/workflows/composition.js.map +1 -1
  104. package/dist/workflows/definition.d.ts +3 -1
  105. package/dist/workflows/definition.js +25 -0
  106. package/dist/workflows/definition.js.map +1 -1
  107. package/dist/workflows/engine.d.ts +1 -0
  108. package/dist/workflows/engine.js +157 -42
  109. package/dist/workflows/engine.js.map +1 -1
  110. package/dist/workflows/errors.d.ts +3 -1
  111. package/dist/workflows/errors.js +4 -7
  112. package/dist/workflows/errors.js.map +1 -1
  113. package/dist/workflows/human-decision.d.ts +3 -0
  114. package/dist/workflows/human-decision.js +31 -0
  115. package/dist/workflows/human-decision.js.map +1 -1
  116. package/dist/workflows/index.d.ts +1 -1
  117. package/dist/workflows/index.js +1 -1
  118. package/dist/workflows/index.js.map +1 -1
  119. package/dist/workflows/schema.js +17 -6
  120. package/dist/workflows/schema.js.map +1 -1
  121. package/dist/{viewer → workflows}/session-reducer.d.ts +3 -1
  122. package/dist/{viewer → workflows}/session-reducer.js +4 -0
  123. package/dist/workflows/session-reducer.js.map +1 -0
  124. package/dist/workflows/store.d.ts +87 -1
  125. package/dist/workflows/store.js +892 -93
  126. package/dist/workflows/store.js.map +1 -1
  127. package/dist/workflows/tool-input.d.ts +0 -26
  128. package/dist/workflows/tool-input.js +2 -50
  129. package/dist/workflows/tool-input.js.map +1 -1
  130. package/dist/workflows/types.d.ts +36 -4
  131. package/docs/2026-08-30-out-of-process-workflow-host-plan.md +353 -0
  132. package/docs/CONTROLLERS.md +11 -11
  133. package/docs/DEFERRED_TURNS.md +23 -2
  134. package/docs/SQLITE_STATE.md +41 -31
  135. package/docs/WORKFLOW_HOST.md +452 -0
  136. package/docs/development.md +46 -30
  137. package/docs/live-replay-protocol.md +129 -100
  138. package/docs/plans/2026-08-27-workflow-terminal-restart-plan.md +42 -0
  139. package/docs/plans/2026-08-28-piw-incremental-viewer-plan.md +293 -0
  140. package/docs/plans/piw-viewer-experience-implementation-plan.md +11 -1
  141. package/docs/plans/tui-viewer-implementation-plan.md +5 -0
  142. package/docs/tui-viewer.md +18 -3
  143. package/docs/workflows.md +162 -210
  144. package/examples/workflows/command-batch.workflow.ts +2 -0
  145. package/examples/workflows/shell.workflow.ts +2 -1
  146. package/herdr-plugin.toml +1 -1
  147. package/package.json +1 -1
  148. package/src/builtins/autoimplement.workflow.ts +3 -0
  149. package/src/builtins/change-verification.workflow.ts +7 -2
  150. package/src/builtins/metadata.ts +9 -0
  151. package/src/builtins/monitor.workflow.ts +4 -0
  152. package/src/builtins/sanity-check.workflow.ts +4 -0
  153. package/src/builtins/workspace-preparation.workflow.ts +3 -1
  154. package/src/controllers/index.ts +0 -5
  155. package/src/controllers/sqlite.ts +709 -76
  156. package/src/controllers/store.ts +1 -0
  157. package/src/extension/controller-command.ts +45 -0
  158. package/src/extension/index.ts +944 -4163
  159. package/src/extension/message-card.ts +61 -0
  160. package/src/extension/step-message.ts +58 -63
  161. package/src/host/child-worker-supervisor.ts +183 -0
  162. package/src/host/client.ts +293 -0
  163. package/src/host/controller-worker-entry.ts +311 -0
  164. package/src/host/controller-worker-protocol.ts +104 -0
  165. package/src/host/controller-worker-supervisor.ts +79 -0
  166. package/src/host/host-entry.ts +23 -0
  167. package/src/host/processes.ts +171 -54
  168. package/src/host/protocol.ts +196 -0
  169. package/src/host/resolver-entry.ts +241 -0
  170. package/src/host/rpc-executor.ts +76 -34
  171. package/src/host/runner.ts +2813 -422
  172. package/src/host/state.ts +1160 -0
  173. package/src/host/worker-entry.ts +533 -0
  174. package/src/host/worker-protocol.ts +165 -0
  175. package/src/host/worker-store.ts +229 -0
  176. package/src/host/worker-supervisor.ts +74 -0
  177. package/src/render/canvas.ts +44 -10
  178. package/src/render/graph-render.ts +145 -90
  179. package/src/state/database.ts +2 -1
  180. package/src/state/index.ts +14 -0
  181. package/src/state/schema.ts +171 -3
  182. package/src/state/viewer.ts +356 -0
  183. package/src/viewer/cli.ts +49 -17
  184. package/src/workflows/composition.ts +36 -2
  185. package/src/workflows/definition.ts +32 -0
  186. package/src/workflows/engine.ts +157 -54
  187. package/src/workflows/errors.ts +11 -2
  188. package/src/workflows/human-decision.ts +49 -0
  189. package/src/workflows/index.ts +2 -0
  190. package/src/workflows/schema.ts +19 -6
  191. package/src/{viewer → workflows}/session-reducer.ts +11 -1
  192. package/src/workflows/store.ts +1316 -108
  193. package/src/workflows/tool-input.ts +3 -69
  194. package/src/workflows/types.ts +32 -4
  195. package/dist/controllers/workflow-engine-scheduler.d.ts +0 -29
  196. package/dist/controllers/workflow-engine-scheduler.js +0 -175
  197. package/dist/controllers/workflow-engine-scheduler.js.map +0 -1
  198. package/dist/extension/controller-host.d.ts +0 -48
  199. package/dist/extension/controller-host.js +0 -110
  200. package/dist/extension/controller-host.js.map +0 -1
  201. package/dist/extension/deferred-turn-coordinator.d.ts +0 -32
  202. package/dist/extension/deferred-turn-coordinator.js +0 -143
  203. package/dist/extension/deferred-turn-coordinator.js.map +0 -1
  204. package/dist/extension/deferred-turn.d.ts +0 -44
  205. package/dist/extension/deferred-turn.js +0 -110
  206. package/dist/extension/deferred-turn.js.map +0 -1
  207. package/dist/extension/executor.d.ts +0 -86
  208. package/dist/extension/executor.js +0 -311
  209. package/dist/extension/executor.js.map +0 -1
  210. package/dist/extension/follow-up-coordinator.d.ts +0 -27
  211. package/dist/extension/follow-up-coordinator.js +0 -131
  212. package/dist/extension/follow-up-coordinator.js.map +0 -1
  213. package/dist/extension/recorder.d.ts +0 -84
  214. package/dist/extension/recorder.js +0 -528
  215. package/dist/extension/recorder.js.map +0 -1
  216. package/dist/extension/restart-policy.d.ts +0 -38
  217. package/dist/extension/restart-policy.js +0 -116
  218. package/dist/extension/restart-policy.js.map +0 -1
  219. package/dist/extension/session-events.d.ts +0 -133
  220. package/dist/extension/session-events.js +0 -61
  221. package/dist/extension/session-events.js.map +0 -1
  222. package/dist/extension/terminal-decision.d.ts +0 -51
  223. package/dist/extension/terminal-decision.js +0 -110
  224. package/dist/extension/terminal-decision.js.map +0 -1
  225. package/dist/viewer/session-reducer.js.map +0 -1
  226. package/src/controllers/workflow-engine-scheduler.ts +0 -246
  227. package/src/extension/controller-host.ts +0 -167
  228. package/src/extension/deferred-turn-coordinator.ts +0 -171
  229. package/src/extension/deferred-turn.ts +0 -166
  230. package/src/extension/executor.ts +0 -411
  231. package/src/extension/follow-up-coordinator.ts +0 -151
  232. package/src/extension/recorder.ts +0 -655
  233. package/src/extension/restart-policy.ts +0 -163
  234. package/src/extension/session-events.ts +0 -121
  235. package/src/extension/terminal-decision.ts +0 -172
@@ -8,10 +8,11 @@ const workflowSchema = Type.String({
8
8
  description: "Discovered workflow name or workflow file path; required when action is start",
9
9
  });
10
10
  const inputSchema = Type.Unknown({
11
- description: "Checkpoint answer for answer; optional structured workflow input for start",
11
+ description:
12
+ "Ordinary checkpoint answer for answer; protected human decisions require a human channel; optional structured workflow input for start",
12
13
  });
13
14
  const runIdSchema = Type.String({
14
- description: "Run id; required for restart and optional for status, cancel, and answer",
15
+ description: "Run id; optional for status, cancel, and answer",
15
16
  });
16
17
  const stepSchema = Type.String({
17
18
  description: "Workflow step id; required when action is update or submit",
@@ -30,33 +31,6 @@ const updateSchema = Type.Object(
30
31
  const outputSchema = Type.Unknown({
31
32
  description: "Step output matching the expected shape; required when action is submit",
32
33
  });
33
- const scopeIdSchema = Type.String({
34
- description: "Settings scope id; defaults to the active node scope",
35
- });
36
- const expectedChangeNumberSchema = Type.Integer({
37
- minimum: 0,
38
- description: "Optional settings change number for an atomic compare-and-change",
39
- });
40
- const patchOperationSchema = Type.Object(
41
- {
42
- op: Type.String({ enum: ["add", "remove", "replace", "move", "copy", "test"] }),
43
- path: Type.String(),
44
- from: Type.Optional(Type.String()),
45
- value: Type.Optional(Type.Unknown()),
46
- },
47
- noExtraProperties,
48
- );
49
- const patchSchema = Type.Array(patchOperationSchema, {
50
- maxItems: 256,
51
- description: "RFC 6902 JSON Patch operations",
52
- });
53
- const followUpPromptSchema = Type.String({
54
- minLength: 1,
55
- maxLength: 65536,
56
- description: "Normal user prompt to send after successful workflow completion",
57
- });
58
- const followUpIdSchema = Type.String({ description: "Queued follow-up id" });
59
-
60
34
  export const WorkflowActionSchemas = {
61
35
  list: Type.Object(
62
36
  { action: Type.Literal("list"), offset: Type.Optional(offsetSchema) },
@@ -70,13 +44,6 @@ export const WorkflowActionSchemas = {
70
44
  },
71
45
  noExtraProperties,
72
46
  ),
73
- restart: Type.Object(
74
- {
75
- action: Type.Literal("restart"),
76
- runId: runIdSchema,
77
- },
78
- noExtraProperties,
79
- ),
80
47
  status: Type.Object(
81
48
  { action: Type.Literal("status"), runId: Type.Optional(runIdSchema) },
82
49
  noExtraProperties,
@@ -95,32 +62,6 @@ export const WorkflowActionSchemas = {
95
62
  },
96
63
  noExtraProperties,
97
64
  ),
98
- "change-settings": Type.Object(
99
- {
100
- action: Type.Literal("change-settings"),
101
- runId: Type.Optional(runIdSchema),
102
- scopeId: Type.Optional(scopeIdSchema),
103
- expectedChangeNumber: Type.Optional(expectedChangeNumberSchema),
104
- patch: patchSchema,
105
- },
106
- noExtraProperties,
107
- ),
108
- "queue-follow-up": Type.Object(
109
- {
110
- action: Type.Literal("queue-follow-up"),
111
- runId: Type.Optional(runIdSchema),
112
- prompt: followUpPromptSchema,
113
- },
114
- noExtraProperties,
115
- ),
116
- "remove-follow-up": Type.Object(
117
- {
118
- action: Type.Literal("remove-follow-up"),
119
- runId: Type.Optional(runIdSchema),
120
- followUpId: followUpIdSchema,
121
- },
122
- noExtraProperties,
123
- ),
124
65
  update: Type.Object(
125
66
  {
126
67
  action: Type.Literal("update"),
@@ -161,18 +102,11 @@ type ToolInputParser<Output> = (value: unknown) => Output;
161
102
  const workflowInputParsers = {
162
103
  list: (value) => parseToolInput(WorkflowActionSchemas.list, value, "workflow"),
163
104
  start: (value) => parseToolInput(WorkflowActionSchemas.start, value, "workflow"),
164
- restart: (value) => parseToolInput(WorkflowActionSchemas.restart, value, "workflow"),
165
105
  status: (value) => parseToolInput(WorkflowActionSchemas.status, value, "workflow"),
166
106
  pause: (value) => parseToolInput(WorkflowActionSchemas.pause, value, "workflow"),
167
107
  resume: (value) => parseToolInput(WorkflowActionSchemas.resume, value, "workflow"),
168
108
  cancel: (value) => parseToolInput(WorkflowActionSchemas.cancel, value, "workflow"),
169
109
  answer: (value) => parseToolInput(WorkflowActionSchemas.answer, value, "workflow"),
170
- "change-settings": (value) =>
171
- parseToolInput(WorkflowActionSchemas["change-settings"], value, "workflow"),
172
- "queue-follow-up": (value) =>
173
- parseToolInput(WorkflowActionSchemas["queue-follow-up"], value, "workflow"),
174
- "remove-follow-up": (value) =>
175
- parseToolInput(WorkflowActionSchemas["remove-follow-up"], value, "workflow"),
176
110
  update: (value) => parseToolInput(WorkflowActionSchemas.update, value, "workflow"),
177
111
  submit: (value) => parseToolInput(WorkflowActionSchemas.submit, value, "workflow"),
178
112
  } satisfies Record<keyof typeof WorkflowActionSchemas, ToolInputParser<WorkflowToolInput>>;
@@ -48,10 +48,31 @@ export type WorkflowUpdateReceipt = Pick<
48
48
  "updateId" | "seq" | "at" | "type" | "key"
49
49
  >;
50
50
 
51
+ export type WorkflowEffectRecovery = "idempotent" | "manual";
52
+
53
+ export type WorkflowManagedEffect = {
54
+ /** Stable external effect category, for example `github.comment`. */
55
+ type: string;
56
+ /** Stable key. Idempotent adapters must pass this key to the external system. */
57
+ idempotencyKey: string | ((context: WorkflowNodeContext) => MaybePromise<string>);
58
+ /** Canonical request data used to reject key reuse with another operation. */
59
+ request: unknown | ((context: WorkflowNodeContext) => MaybePromise<unknown>);
60
+ /** `manual` never retries after an uncertain child exit. */
61
+ recovery: WorkflowEffectRecovery;
62
+ };
63
+
51
64
  export type WorkflowActionContext<TInput = unknown> = WorkflowNodeContext<TInput> & {
65
+ effect: { type: string; idempotencyKey: string; recovery: WorkflowEffectRecovery };
52
66
  publishUpdate(update: WorkflowUpdateInput): Promise<WorkflowUpdateReceipt>;
53
67
  };
54
68
 
69
+ export type WorkflowEffectReservation = {
70
+ effectId: string;
71
+ attemptNumber: number;
72
+ disposition: "execute" | "adopted" | "ambiguous";
73
+ result?: unknown;
74
+ };
75
+
55
76
  export type WorkflowProgressStatus =
56
77
  | "pending"
57
78
  | "running"
@@ -150,6 +171,7 @@ export type NotifyNodeDefinition = WorkflowNodeCommon & {
150
171
  /** A deterministic runtime-owned step implemented as a local function. */
151
172
  export type FunctionActionNodeDefinition = WorkflowNodeCommon & {
152
173
  nodeType: "action";
174
+ effect?: WorkflowManagedEffect;
153
175
  run: (context: WorkflowActionContext) => MaybePromise<unknown>;
154
176
  };
155
177
 
@@ -193,8 +215,9 @@ export type ShellActionUpdates = {
193
215
 
194
216
  export type ShellActionNodeDefinition = WorkflowNodeCommon & {
195
217
  nodeType: "action";
196
- exec: (context: WorkflowNodeContext) => MaybePromise<ShellActionExecution>;
197
- parse?: (result: ShellActionResult, context: WorkflowNodeContext) => MaybePromise<unknown>;
218
+ effect?: WorkflowManagedEffect;
219
+ exec: (context: WorkflowActionContext) => MaybePromise<ShellActionExecution>;
220
+ parse?: (result: ShellActionResult, context: WorkflowActionContext) => MaybePromise<unknown>;
198
221
  updates?: ShellActionUpdates;
199
222
  };
200
223
 
@@ -696,6 +719,8 @@ export type WorkflowRunState = {
696
719
  currentNode?: string;
697
720
  currentAttemptId?: string;
698
721
  currentNodeStartedAt?: string;
722
+ /** Durable wall-clock deadline for the current attempt. Null disables the deadline. */
723
+ currentNodeDeadlineAt?: string | null;
699
724
  currentSettingsScopeId?: string;
700
725
  currentSettingsChangeNumber?: number;
701
726
  currentSettingsHash?: string;
@@ -717,6 +742,7 @@ export type WorkflowNodeSnapshot = {
717
742
  expectedOutput?: AgentExpectedOutput;
718
743
  settingsRoute?: true;
719
744
  actionExecution?: "function" | "shell";
745
+ effect?: { type: string; recovery: WorkflowEffectRecovery };
720
746
  mountPath?: string[];
721
747
  localNodeId?: string;
722
748
  includeTransition?: "entry" | "exit";
@@ -907,6 +933,8 @@ export interface AgentStepExecutor {
907
933
  * leave the run claimable for an origin session. Omission is unsupported.
908
934
  */
909
935
  readonly assistantMessageMode?: "visible" | "park" | "unsupported";
936
+ /** True when the executor can park outside this process and resume the same attempt. */
937
+ readonly preservesDeadlineWhileParked?: boolean;
910
938
  runAgentStep(request: AgentStepRequest, signal: AbortSignal): Promise<AgentStepSubmission>;
911
939
  }
912
940
 
@@ -936,8 +964,8 @@ export type WorkflowEngineOptions = {
936
964
  notificationSink?: WorkflowNotificationSink;
937
965
  /** Canonical SQLite database. Defaults to `~/.pi/agent/workflows/state.sqlite`. */
938
966
  databasePath?: string;
939
- /** Shared SQLite run store. */
940
- store?: import("./store.js").WorkflowRunStore;
967
+ /** Durable execution store. Workers use a host-backed implementation. */
968
+ store?: import("./store.js").WorkflowExecutionStore;
941
969
  /**
942
970
  * Awaited after `run_started` is persisted, before any node executes.
943
971
  */
@@ -1,29 +0,0 @@
1
- import { WorkflowEngine } from "../workflows/engine.js";
2
- import type { WorkflowRunStore } from "../workflows/store.js";
3
- import type { WorkflowDefinition, WorkflowSource } from "../workflows/types.js";
4
- import type { ControllerFollowUpResult, ControllerQueueFollowUpRequest, ControllerRemoveFollowUpRequest, ControllerSettingsChangeRequest, ControllerSettingsChangeResult } from "./types.js";
5
- import type { ControllerWorkflowControlRequest, ControllerWorkflowScheduler, WorkflowSchedulerRequest, WorkflowSchedulerResult } from "./workflows.js";
6
- export type ResolvedChildWorkflow = {
7
- workflow: WorkflowDefinition;
8
- workflowSource?: WorkflowSource;
9
- };
10
- export type WorkflowEngineSchedulerOptions = {
11
- store: WorkflowRunStore;
12
- resolveWorkflow: (name: string) => Promise<ResolvedChildWorkflow>;
13
- createEngine: (request: WorkflowSchedulerRequest) => WorkflowEngine;
14
- /**
15
- * Release resources the engine held after its run settles, for example a
16
- * headless child process. Called once per finished run.
17
- */
18
- disposeEngine?: (engine: WorkflowEngine) => Promise<void>;
19
- };
20
- export declare class WorkflowEngineScheduler implements ControllerWorkflowScheduler {
21
- private readonly options;
22
- private readonly active;
23
- constructor(options: WorkflowEngineSchedulerOptions);
24
- ensure(request: WorkflowSchedulerRequest, signal: AbortSignal, onComplete: (result: WorkflowSchedulerResult) => void): Promise<WorkflowSchedulerResult>;
25
- changeSettings(request: ControllerWorkflowControlRequest<ControllerSettingsChangeRequest>, signal: AbortSignal): Promise<ControllerSettingsChangeResult>;
26
- queueFollowUp(request: ControllerWorkflowControlRequest<ControllerQueueFollowUpRequest>, signal: AbortSignal): Promise<ControllerFollowUpResult>;
27
- removeFollowUp(request: ControllerWorkflowControlRequest<ControllerRemoveFollowUpRequest>, signal: AbortSignal): Promise<ControllerFollowUpResult>;
28
- waitForIdle(): Promise<void>;
29
- }
@@ -1,175 +0,0 @@
1
- import { compositionMetadata } from "../workflows/composition.js";
2
- import { WorkflowEngine, workflowIdentityMismatch } from "../workflows/engine.js";
3
- export class WorkflowEngineScheduler {
4
- options;
5
- active = new Map();
6
- constructor(options) {
7
- this.options = options;
8
- }
9
- async ensure(request, signal, onComplete) {
10
- if (signal.aborted) {
11
- throw signal.reason ?? new Error("Workflow scheduling aborted");
12
- }
13
- const activeKey = requestKey(request);
14
- const active = this.active.get(activeKey);
15
- if (active !== undefined) {
16
- return { state: "running", runId: active.runId };
17
- }
18
- const bundle = this.options.store.readRun(request.runId, { includeTrace: true });
19
- if (bundle !== null) {
20
- const recovered = bundle.state.status === "running"
21
- ? await this.options.store.markRunInterrupted(request.runId)
22
- : bundle;
23
- if (recovered !== null) {
24
- const lastTraceEvent = recovered.traceEvents?.at(-1) ?? null;
25
- return resultFromStatus(recovered.state.status, request.runId, recovered.state.error, lastTraceEvent?.type === "run_interrupted");
26
- }
27
- return { state: "pending" };
28
- }
29
- const resolved = await this.options.resolveWorkflow(request.workflow);
30
- if (signal.aborted) {
31
- throw signal.reason ?? new Error("Workflow scheduling aborted");
32
- }
33
- const runId = request.runId;
34
- const engine = this.options.createEngine(request);
35
- const promise = engine
36
- .run(resolved.workflow, request.input, {
37
- runId,
38
- ...(resolved.workflowSource !== undefined
39
- ? { workflowSource: resolved.workflowSource }
40
- : {}),
41
- })
42
- .then((result) => {
43
- callCompletion(onComplete, resultFromRun(result));
44
- })
45
- .catch((error) => {
46
- callCompletion(onComplete, {
47
- state: "failed",
48
- runId,
49
- error: error instanceof Error ? error.message : String(error),
50
- });
51
- })
52
- .finally(() => {
53
- this.active.delete(activeKey);
54
- void this.options.disposeEngine?.(engine).catch(() => undefined);
55
- });
56
- this.active.set(activeKey, { runId, promise });
57
- return { state: "running", runId };
58
- }
59
- async changeSettings(request, signal) {
60
- signal.throwIfAborted();
61
- const bundle = this.options.store.readRun(request.runId);
62
- if (bundle === null)
63
- throw new Error(`Workflow run not found: ${request.runId}`);
64
- const resolved = await this.options.resolveWorkflow(bundle.state.workflowName);
65
- signal.throwIfAborted();
66
- if (workflowIdentityMismatch(bundle.state, resolved.workflow, resolved.workflowSource)) {
67
- throw new Error(`Workflow source changed since run ${request.runId} started`);
68
- }
69
- const scopes = this.options.store.listSettingsScopes(request.runId);
70
- const scopeId = request.scopeId ?? (scopes.length === 1 ? scopes[0]?.scopeId : undefined);
71
- if (scopeId === undefined) {
72
- throw new Error("Controller settings changes require scopeId when several scopes exist");
73
- }
74
- const scope = this.options.store.getSettingsScope(scopeId);
75
- if (scope === undefined || scope.activeRunId !== request.runId) {
76
- throw new Error(`Workflow settings scope not found: ${scopeId}`);
77
- }
78
- const definition = scope.mountPath === ""
79
- ? resolved.workflow.settings
80
- : compositionMetadata(resolved.workflow)?.scopes[scope.mountPath]?.settings;
81
- if (definition === undefined) {
82
- throw new Error(`Workflow scope ${scopeId} does not declare editable settings`);
83
- }
84
- const result = await this.options.store.changeSettings(definition, {
85
- runId: request.runId,
86
- scopeId,
87
- requestId: request.actorRequestKey,
88
- ...(request.expectedChangeNumber !== undefined
89
- ? { expectedChangeNumber: request.expectedChangeNumber }
90
- : {}),
91
- actor: { type: "controller", id: request.controllerResourceUid },
92
- source: "controller-request",
93
- patch: request.patch,
94
- });
95
- return {
96
- runId: request.runId,
97
- scopeId,
98
- changeNumber: result.scope.changeNumber,
99
- adopted: result.adopted,
100
- };
101
- }
102
- async queueFollowUp(request, signal) {
103
- signal.throwIfAborted();
104
- const targetSessionId = this.options.store.originSessionId(request.runId);
105
- if (targetSessionId === undefined) {
106
- throw new Error("Controller follow-up requires a workflow run with an origin Pi session");
107
- }
108
- const result = this.options.store.queueFollowUp({
109
- runId: request.runId,
110
- requestId: request.actorRequestKey,
111
- targetSessionId,
112
- actor: { type: "controller", id: request.controllerResourceUid },
113
- source: "controller-request",
114
- prompt: request.prompt,
115
- });
116
- return {
117
- runId: request.runId,
118
- followUpId: result.followUp.followUpId,
119
- order: result.followUp.order,
120
- state: result.followUp.state,
121
- adopted: result.adopted,
122
- };
123
- }
124
- async removeFollowUp(request, signal) {
125
- signal.throwIfAborted();
126
- const result = this.options.store.removeFollowUp({
127
- runId: request.runId,
128
- followUpId: request.followUpId,
129
- actor: { type: "controller", id: request.controllerResourceUid },
130
- source: "controller-request",
131
- });
132
- return {
133
- runId: request.runId,
134
- followUpId: result.followUpId,
135
- order: result.order,
136
- state: result.state,
137
- adopted: false,
138
- };
139
- }
140
- async waitForIdle() {
141
- await Promise.all([...this.active.values()].map((entry) => entry.promise));
142
- }
143
- }
144
- function callCompletion(callback, result) {
145
- try {
146
- callback(result);
147
- }
148
- catch {
149
- // A later reconciliation recovers completion from the immutable run event.
150
- }
151
- }
152
- function requestKey(request) {
153
- return `${request.requestId}:${request.attempt}`;
154
- }
155
- function resultFromRun(result) {
156
- return resultFromStatus(result.state.status, result.state.runId, result.state.error);
157
- }
158
- function resultFromStatus(status, runId, error, interrupted = false) {
159
- if (interrupted) {
160
- return { state: "interrupted", runId, ...(error !== undefined ? { error } : {}) };
161
- }
162
- switch (status) {
163
- case "running":
164
- return { state: "running", runId };
165
- case "waiting":
166
- return { state: "waiting", runId };
167
- case "completed":
168
- return { state: "succeeded", runId };
169
- case "failed":
170
- case "timed_out":
171
- case "cancelled":
172
- return { state: "failed", runId, ...(error !== undefined ? { error } : {}) };
173
- }
174
- }
175
- //# sourceMappingURL=workflow-engine-scheduler.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"workflow-engine-scheduler.js","sourceRoot":"","sources":["../../src/controllers/workflow-engine-scheduler.ts"],"names":[],"mappings":"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"}
@@ -1,48 +0,0 @@
1
- import { ControllerManager, SqliteControllerStore, type AnyControllerDefinition, type ControllerResource, type ControllerWorkflowScheduler, type WorkflowSchedulerRequest, type WorkflowSchedulerResult } from "../controllers/index.js";
2
- export type ParsedControllerArgs = {
3
- kind: "list";
4
- } | {
5
- kind: "get";
6
- controller: string;
7
- key: string;
8
- } | {
9
- kind: "apply";
10
- controller: string;
11
- key: string;
12
- spec: unknown;
13
- } | {
14
- kind: "reconcile";
15
- controller: string;
16
- key: string;
17
- } | {
18
- kind: "delete";
19
- controller: string;
20
- key: string;
21
- } | {
22
- kind: "start";
23
- } | {
24
- kind: "stop";
25
- };
26
- export type PiChildWorkflowStarter = (request: WorkflowSchedulerRequest, signal: AbortSignal, onComplete: (result: WorkflowSchedulerResult) => void) => Promise<WorkflowSchedulerResult>;
27
- export declare function parseControllerArgs(args: string): ParsedControllerArgs;
28
- export declare class PiControllerHost {
29
- readonly definitions: AnyControllerDefinition[];
30
- readonly store: SqliteControllerStore;
31
- readonly manager: ControllerManager;
32
- private running;
33
- private constructor();
34
- static create(options: {
35
- cwd: string;
36
- startChild: PiChildWorkflowStarter;
37
- workflowControls?: Pick<ControllerWorkflowScheduler, "changeSettings" | "queueFollowUp" | "removeFollowUp">;
38
- }): Promise<PiControllerHost | undefined>;
39
- start(): void;
40
- stop(): Promise<void>;
41
- close(): Promise<void>;
42
- get isRunning(): boolean;
43
- list(): string;
44
- get(controller: string, key: string): string;
45
- apply(controller: string, key: string, spec: unknown): ControllerResource;
46
- reconcile(controller: string, key: string): void;
47
- delete(controller: string, key: string): void;
48
- }
@@ -1,110 +0,0 @@
1
- import { ControllerManager, SqliteControllerStore, loadDiscoveredControllers, } from "../controllers/index.js";
2
- export function parseControllerArgs(args) {
3
- const trimmed = args.trim();
4
- if (trimmed.length === 0 || trimmed === "list") {
5
- return { kind: "list" };
6
- }
7
- if (trimmed === "start" || trimmed === "stop") {
8
- return { kind: trimmed };
9
- }
10
- const apply = trimmed.match(/^apply\s+(\S+)\s+(\S+)\s+([\s\S]+)$/);
11
- if (apply !== null) {
12
- let spec;
13
- try {
14
- spec = JSON.parse(apply[3]);
15
- }
16
- catch (error) {
17
- throw new Error(`Invalid controller spec JSON: ${error instanceof Error ? error.message : String(error)}`);
18
- }
19
- return {
20
- kind: "apply",
21
- controller: apply[1],
22
- key: apply[2],
23
- spec,
24
- };
25
- }
26
- const operation = trimmed.match(/^(get|reconcile|delete)\s+(\S+)\s+(\S+)$/);
27
- if (operation !== null) {
28
- return {
29
- kind: operation[1],
30
- controller: operation[2],
31
- key: operation[3],
32
- };
33
- }
34
- throw new Error("Usage: /controller [list|get <controller> <key>|apply <controller> <key> <json>|reconcile <controller> <key>|delete <controller> <key>|start|stop]");
35
- }
36
- export class PiControllerHost {
37
- definitions;
38
- store;
39
- manager;
40
- running = false;
41
- constructor(definitions, store, manager) {
42
- this.definitions = definitions;
43
- this.store = store;
44
- this.manager = manager;
45
- }
46
- static async create(options) {
47
- const definitions = await loadDiscoveredControllers({ cwd: options.cwd });
48
- if (definitions.length === 0) {
49
- return undefined;
50
- }
51
- const store = new SqliteControllerStore(undefined, { projectPath: options.cwd });
52
- const manager = new ControllerManager({
53
- store,
54
- controllers: definitions,
55
- workflowScheduler: { ensure: options.startChild, ...options.workflowControls },
56
- });
57
- return new PiControllerHost(definitions, store, manager);
58
- }
59
- start() {
60
- this.manager.start();
61
- this.running = true;
62
- }
63
- async stop() {
64
- await this.manager.stop();
65
- this.running = false;
66
- }
67
- async close() {
68
- await this.stop();
69
- this.store.close();
70
- }
71
- get isRunning() {
72
- return this.running;
73
- }
74
- list() {
75
- const names = this.definitions.map((item) => item.name).join(", ");
76
- const resources = this.store.listResources();
77
- if (resources.length === 0) {
78
- return `Controllers: ${names}. No resources.`;
79
- }
80
- const rows = resources.map((resource) => resourceSummary(resource)).join("; ");
81
- return `Controllers: ${names}. Resources: ${rows}.`;
82
- }
83
- get(controller, key) {
84
- const resource = this.store.getResource({ controller, key });
85
- if (resource === undefined) {
86
- throw new Error(`Controller resource not found: ${controller}/${key}`);
87
- }
88
- return JSON.stringify({
89
- resource,
90
- effects: this.store.listEffects(resource.metadata.uid),
91
- workflows: this.store.listWorkflows(resource.metadata.uid),
92
- }, null, 2);
93
- }
94
- apply(controller, key, spec) {
95
- return this.manager.putResourceByName(controller, key, spec);
96
- }
97
- reconcile(controller, key) {
98
- this.manager.enqueue({ controller, key });
99
- }
100
- delete(controller, key) {
101
- this.manager.requestDeletion({ controller, key });
102
- }
103
- }
104
- function resourceSummary(resource) {
105
- const condition = resource.status.conditions.find((item) => item.type === "Ready") ??
106
- resource.status.conditions[0];
107
- const state = condition === undefined ? "unknown" : `${String(condition.status)}:${condition.reason}`;
108
- return `${resource.metadata.controller}/${resource.metadata.key} generation=${resource.metadata.generation} ready=${state}`;
109
- }
110
- //# sourceMappingURL=controller-host.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"controller-host.js","sourceRoot":"","sources":["../../src/extension/controller-host.ts"],"names":[],"mappings":"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"}
@@ -1,32 +0,0 @@
1
- import type { SqliteControllerStore, WorkflowTurnIntentRecord, WorkflowTurnIntentResolution } from "../controllers/sqlite.js";
2
- export type BranchIntentResolution = {
3
- resolution: WorkflowTurnIntentResolution;
4
- messageId: string;
5
- };
6
- type NaturalDelivery = {
7
- runId: string;
8
- targetSessionId: string;
9
- resolution: Exclude<WorkflowTurnIntentResolution, "fallback">;
10
- send: (turnIntentId?: string) => void;
11
- };
12
- type FallbackDelivery = {
13
- targetSessionId: string;
14
- send: (intent: WorkflowTurnIntentRecord) => void;
15
- };
16
- export declare class DeferredTurnCoordinator {
17
- private readonly store;
18
- private readonly branchResolution;
19
- private readonly leaseMs;
20
- private readonly deferredNatural;
21
- constructor(options: {
22
- store: () => SqliteControllerStore | null;
23
- branchResolution: (intentId: string) => BranchIntentResolution | null;
24
- leaseMs: number;
25
- });
26
- sendNatural(delivery: NaturalDelivery, idle: boolean): "sent" | "deferred" | "suppressed";
27
- flushNatural(idle: boolean): number;
28
- deliverFallbacks(delivery: FallbackDelivery, idle: boolean): number;
29
- clearDeferred(): void;
30
- private deliverNatural;
31
- }
32
- export {};