@osolmaz/pi-workflows 0.13.4 → 0.15.0

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 (237) hide show
  1. package/README.md +146 -160
  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 +1 -2
  16. package/dist/controllers/index.js +0 -1
  17. package/dist/controllers/index.js.map +1 -1
  18. package/dist/controllers/sqlite.d.ts +85 -31
  19. package/dist/controllers/sqlite.js +541 -126
  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 -2928
  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/prune.js +36 -10
  94. package/dist/state/prune.js.map +1 -1
  95. package/dist/state/schema.d.ts +1 -1
  96. package/dist/state/schema.js +171 -3
  97. package/dist/state/schema.js.map +1 -1
  98. package/dist/state/viewer.d.ts +46 -0
  99. package/dist/state/viewer.js +249 -0
  100. package/dist/state/viewer.js.map +1 -0
  101. package/dist/viewer/cli.d.ts +1 -1
  102. package/dist/viewer/cli.js +47 -18
  103. package/dist/viewer/cli.js.map +1 -1
  104. package/dist/workflows/composition.js +25 -2
  105. package/dist/workflows/composition.js.map +1 -1
  106. package/dist/workflows/definition.d.ts +3 -1
  107. package/dist/workflows/definition.js +25 -0
  108. package/dist/workflows/definition.js.map +1 -1
  109. package/dist/workflows/engine.d.ts +1 -0
  110. package/dist/workflows/engine.js +157 -42
  111. package/dist/workflows/engine.js.map +1 -1
  112. package/dist/workflows/errors.d.ts +3 -1
  113. package/dist/workflows/errors.js +4 -7
  114. package/dist/workflows/errors.js.map +1 -1
  115. package/dist/workflows/human-decision.d.ts +3 -0
  116. package/dist/workflows/human-decision.js +31 -0
  117. package/dist/workflows/human-decision.js.map +1 -1
  118. package/dist/workflows/index.d.ts +1 -1
  119. package/dist/workflows/index.js +1 -1
  120. package/dist/workflows/index.js.map +1 -1
  121. package/dist/workflows/schema.js +17 -6
  122. package/dist/workflows/schema.js.map +1 -1
  123. package/dist/{viewer → workflows}/session-reducer.d.ts +3 -1
  124. package/dist/{viewer → workflows}/session-reducer.js +4 -0
  125. package/dist/workflows/session-reducer.js.map +1 -0
  126. package/dist/workflows/store.d.ts +87 -1
  127. package/dist/workflows/store.js +892 -93
  128. package/dist/workflows/store.js.map +1 -1
  129. package/dist/workflows/tool-input.d.ts +0 -22
  130. package/dist/workflows/tool-input.js +1 -44
  131. package/dist/workflows/tool-input.js.map +1 -1
  132. package/dist/workflows/types.d.ts +36 -4
  133. package/docs/2026-08-25-workflow-follow-ups.md +8 -6
  134. package/docs/2026-08-30-out-of-process-workflow-host-plan.md +353 -0
  135. package/docs/CONTROLLERS.md +11 -11
  136. package/docs/DEFERRED_TURNS.md +61 -27
  137. package/docs/HUMAN_DECISIONS.md +12 -4
  138. package/docs/SQLITE_STATE.md +42 -8
  139. package/docs/WORKFLOW_HOST.md +452 -0
  140. package/docs/development.md +46 -30
  141. package/docs/live-replay-protocol.md +129 -100
  142. package/docs/plans/2026-08-19-human-decision-gates-plan.md +34 -8
  143. package/docs/plans/2026-08-27-workflow-terminal-restart-plan.md +399 -0
  144. package/docs/plans/2026-08-28-piw-incremental-viewer-plan.md +293 -0
  145. package/docs/plans/piw-viewer-experience-implementation-plan.md +11 -1
  146. package/docs/plans/tui-viewer-implementation-plan.md +5 -0
  147. package/docs/tui-viewer.md +18 -3
  148. package/docs/workflows.md +164 -156
  149. package/examples/workflows/command-batch.workflow.ts +2 -0
  150. package/examples/workflows/shell.workflow.ts +2 -1
  151. package/herdr-plugin.toml +1 -1
  152. package/package.json +1 -1
  153. package/skills/autodoc/SKILL.md +1 -1
  154. package/skills/autoimplement/SKILL.md +1 -1
  155. package/skills/autoplan/SKILL.md +1 -1
  156. package/skills/pi-workflows/SKILL.md +2 -0
  157. package/src/builtins/autoimplement.workflow.ts +3 -0
  158. package/src/builtins/change-verification.workflow.ts +7 -2
  159. package/src/builtins/metadata.ts +9 -0
  160. package/src/builtins/monitor.workflow.ts +4 -0
  161. package/src/builtins/sanity-check.workflow.ts +4 -0
  162. package/src/builtins/workspace-preparation.workflow.ts +3 -1
  163. package/src/controllers/index.ts +3 -5
  164. package/src/controllers/sqlite.ts +929 -225
  165. package/src/controllers/store.ts +1 -0
  166. package/src/extension/controller-command.ts +45 -0
  167. package/src/extension/index.ts +948 -3506
  168. package/src/extension/message-card.ts +61 -0
  169. package/src/extension/step-message.ts +58 -63
  170. package/src/host/child-worker-supervisor.ts +183 -0
  171. package/src/host/client.ts +293 -0
  172. package/src/host/controller-worker-entry.ts +311 -0
  173. package/src/host/controller-worker-protocol.ts +104 -0
  174. package/src/host/controller-worker-supervisor.ts +79 -0
  175. package/src/host/host-entry.ts +23 -0
  176. package/src/host/processes.ts +171 -54
  177. package/src/host/protocol.ts +196 -0
  178. package/src/host/resolver-entry.ts +241 -0
  179. package/src/host/rpc-executor.ts +76 -34
  180. package/src/host/runner.ts +2813 -422
  181. package/src/host/state.ts +1160 -0
  182. package/src/host/worker-entry.ts +533 -0
  183. package/src/host/worker-protocol.ts +165 -0
  184. package/src/host/worker-store.ts +229 -0
  185. package/src/host/worker-supervisor.ts +74 -0
  186. package/src/render/canvas.ts +44 -10
  187. package/src/render/graph-render.ts +145 -90
  188. package/src/state/database.ts +2 -1
  189. package/src/state/index.ts +14 -0
  190. package/src/state/prune.ts +35 -9
  191. package/src/state/schema.ts +171 -3
  192. package/src/state/viewer.ts +356 -0
  193. package/src/viewer/cli.ts +49 -17
  194. package/src/workflows/composition.ts +36 -2
  195. package/src/workflows/definition.ts +32 -0
  196. package/src/workflows/engine.ts +157 -54
  197. package/src/workflows/errors.ts +11 -2
  198. package/src/workflows/human-decision.ts +49 -0
  199. package/src/workflows/index.ts +2 -0
  200. package/src/workflows/schema.ts +19 -6
  201. package/src/{viewer → workflows}/session-reducer.ts +11 -1
  202. package/src/workflows/store.ts +1316 -108
  203. package/src/workflows/tool-input.ts +2 -60
  204. package/src/workflows/types.ts +32 -4
  205. package/dist/controllers/workflow-engine-scheduler.d.ts +0 -29
  206. package/dist/controllers/workflow-engine-scheduler.js +0 -175
  207. package/dist/controllers/workflow-engine-scheduler.js.map +0 -1
  208. package/dist/extension/controller-host.d.ts +0 -48
  209. package/dist/extension/controller-host.js +0 -110
  210. package/dist/extension/controller-host.js.map +0 -1
  211. package/dist/extension/deferred-turn-coordinator.d.ts +0 -32
  212. package/dist/extension/deferred-turn-coordinator.js +0 -143
  213. package/dist/extension/deferred-turn-coordinator.js.map +0 -1
  214. package/dist/extension/deferred-turn.d.ts +0 -44
  215. package/dist/extension/deferred-turn.js +0 -110
  216. package/dist/extension/deferred-turn.js.map +0 -1
  217. package/dist/extension/executor.d.ts +0 -86
  218. package/dist/extension/executor.js +0 -311
  219. package/dist/extension/executor.js.map +0 -1
  220. package/dist/extension/follow-up-coordinator.d.ts +0 -27
  221. package/dist/extension/follow-up-coordinator.js +0 -131
  222. package/dist/extension/follow-up-coordinator.js.map +0 -1
  223. package/dist/extension/recorder.d.ts +0 -84
  224. package/dist/extension/recorder.js +0 -528
  225. package/dist/extension/recorder.js.map +0 -1
  226. package/dist/extension/session-events.d.ts +0 -133
  227. package/dist/extension/session-events.js +0 -61
  228. package/dist/extension/session-events.js.map +0 -1
  229. package/dist/viewer/session-reducer.js.map +0 -1
  230. package/src/controllers/workflow-engine-scheduler.ts +0 -246
  231. package/src/extension/controller-host.ts +0 -167
  232. package/src/extension/deferred-turn-coordinator.ts +0 -171
  233. package/src/extension/deferred-turn.ts +0 -166
  234. package/src/extension/executor.ts +0 -411
  235. package/src/extension/follow-up-coordinator.ts +0 -151
  236. package/src/extension/recorder.ts +0 -655
  237. package/src/extension/session-events.ts +0 -121
@@ -8,7 +8,8 @@ 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
15
  description: "Run id; optional for status, cancel, and answer",
@@ -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) },
@@ -88,32 +62,6 @@ export const WorkflowActionSchemas = {
88
62
  },
89
63
  noExtraProperties,
90
64
  ),
91
- "change-settings": Type.Object(
92
- {
93
- action: Type.Literal("change-settings"),
94
- runId: Type.Optional(runIdSchema),
95
- scopeId: Type.Optional(scopeIdSchema),
96
- expectedChangeNumber: Type.Optional(expectedChangeNumberSchema),
97
- patch: patchSchema,
98
- },
99
- noExtraProperties,
100
- ),
101
- "queue-follow-up": Type.Object(
102
- {
103
- action: Type.Literal("queue-follow-up"),
104
- runId: Type.Optional(runIdSchema),
105
- prompt: followUpPromptSchema,
106
- },
107
- noExtraProperties,
108
- ),
109
- "remove-follow-up": Type.Object(
110
- {
111
- action: Type.Literal("remove-follow-up"),
112
- runId: Type.Optional(runIdSchema),
113
- followUpId: followUpIdSchema,
114
- },
115
- noExtraProperties,
116
- ),
117
65
  update: Type.Object(
118
66
  {
119
67
  action: Type.Literal("update"),
@@ -159,12 +107,6 @@ const workflowInputParsers = {
159
107
  resume: (value) => parseToolInput(WorkflowActionSchemas.resume, value, "workflow"),
160
108
  cancel: (value) => parseToolInput(WorkflowActionSchemas.cancel, value, "workflow"),
161
109
  answer: (value) => parseToolInput(WorkflowActionSchemas.answer, value, "workflow"),
162
- "change-settings": (value) =>
163
- parseToolInput(WorkflowActionSchemas["change-settings"], value, "workflow"),
164
- "queue-follow-up": (value) =>
165
- parseToolInput(WorkflowActionSchemas["queue-follow-up"], value, "workflow"),
166
- "remove-follow-up": (value) =>
167
- parseToolInput(WorkflowActionSchemas["remove-follow-up"], value, "workflow"),
168
110
  update: (value) => parseToolInput(WorkflowActionSchemas.update, value, "workflow"),
169
111
  submit: (value) => parseToolInput(WorkflowActionSchemas.submit, value, "workflow"),
170
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 {};