@osolmaz/pi-workflows 0.12.1 → 0.13.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 (209) hide show
  1. package/README.md +52 -28
  2. package/dist/builtins/autodoc.workflow.d.ts +4 -4
  3. package/dist/builtins/autoimplement.workflow.d.ts +369 -73
  4. package/dist/builtins/autoplan.workflow.d.ts +126 -13
  5. package/dist/builtins/autoplan.workflow.js +200 -29
  6. package/dist/builtins/autoplan.workflow.js.map +1 -1
  7. package/dist/builtins/catalog.js +6 -4
  8. package/dist/builtins/catalog.js.map +1 -1
  9. package/dist/builtins/index.d.ts +2 -1
  10. package/dist/builtins/index.js +1 -0
  11. package/dist/builtins/index.js.map +1 -1
  12. package/dist/builtins/monitor.workflow.d.ts +56 -21
  13. package/dist/builtins/monitor.workflow.js +497 -216
  14. package/dist/builtins/monitor.workflow.js.map +1 -1
  15. package/dist/builtins/plain-summary.workflow.d.ts +32 -0
  16. package/dist/builtins/plain-summary.workflow.js +134 -0
  17. package/dist/builtins/plain-summary.workflow.js.map +1 -0
  18. package/dist/builtins/plan-change.workflow.d.ts +170 -22
  19. package/dist/builtins/sanity-check.workflow.d.ts +45 -3
  20. package/dist/builtins/sanity-check.workflow.js +45 -7
  21. package/dist/builtins/sanity-check.workflow.js.map +1 -1
  22. package/dist/controllers/effects.d.ts +3 -2
  23. package/dist/controllers/effects.js +8 -1
  24. package/dist/controllers/effects.js.map +1 -1
  25. package/dist/controllers/index.d.ts +1 -1
  26. package/dist/controllers/index.js +1 -1
  27. package/dist/controllers/index.js.map +1 -1
  28. package/dist/controllers/manager.d.ts +1 -0
  29. package/dist/controllers/manager.js +41 -17
  30. package/dist/controllers/manager.js.map +1 -1
  31. package/dist/controllers/sqlite.d.ts +107 -85
  32. package/dist/controllers/sqlite.js +1611 -1486
  33. package/dist/controllers/sqlite.js.map +1 -1
  34. package/dist/controllers/store.d.ts +9 -8
  35. package/dist/controllers/store.js +1 -31
  36. package/dist/controllers/store.js.map +1 -1
  37. package/dist/controllers/types.d.ts +3 -0
  38. package/dist/controllers/workflow-engine-scheduler.d.ts +1 -1
  39. package/dist/controllers/workflow-engine-scheduler.js +3 -5
  40. package/dist/controllers/workflow-engine-scheduler.js.map +1 -1
  41. package/dist/controllers/workflows.d.ts +2 -2
  42. package/dist/controllers/workflows.js +11 -10
  43. package/dist/controllers/workflows.js.map +1 -1
  44. package/dist/extension/controller-host.js +2 -2
  45. package/dist/extension/controller-host.js.map +1 -1
  46. package/dist/extension/decision-channels.d.ts +2 -0
  47. package/dist/extension/decision-channels.js +311 -118
  48. package/dist/extension/decision-channels.js.map +1 -1
  49. package/dist/extension/executor.d.ts +9 -2
  50. package/dist/extension/executor.js +89 -2
  51. package/dist/extension/executor.js.map +1 -1
  52. package/dist/extension/herdr-viewer.d.ts +0 -1
  53. package/dist/extension/herdr-viewer.js +0 -4
  54. package/dist/extension/herdr-viewer.js.map +1 -1
  55. package/dist/extension/index.js +156 -103
  56. package/dist/extension/index.js.map +1 -1
  57. package/dist/extension/recorder.d.ts +3 -10
  58. package/dist/extension/recorder.js +13 -22
  59. package/dist/extension/recorder.js.map +1 -1
  60. package/dist/extension/step-message.d.ts +7 -2
  61. package/dist/extension/step-message.js +94 -2
  62. package/dist/extension/step-message.js.map +1 -1
  63. package/dist/extension/widget.js +6 -0
  64. package/dist/extension/widget.js.map +1 -1
  65. package/dist/host/rpc-executor.d.ts +3 -0
  66. package/dist/host/rpc-executor.js +2 -0
  67. package/dist/host/rpc-executor.js.map +1 -1
  68. package/dist/host/runner.d.ts +3 -6
  69. package/dist/host/runner.js +83 -32
  70. package/dist/host/runner.js.map +1 -1
  71. package/dist/render/graph-render.js +14 -8
  72. package/dist/render/graph-render.js.map +1 -1
  73. package/dist/state/database.d.ts +35 -0
  74. package/dist/state/database.js +287 -0
  75. package/dist/state/database.js.map +1 -0
  76. package/dist/state/index.d.ts +4 -0
  77. package/dist/state/index.js +5 -0
  78. package/dist/state/index.js.map +1 -0
  79. package/dist/state/json.d.ts +6 -0
  80. package/dist/state/json.js +38 -0
  81. package/dist/state/json.js.map +1 -0
  82. package/dist/state/mutation.d.ts +57 -0
  83. package/dist/state/mutation.js +255 -0
  84. package/dist/state/mutation.js.map +1 -0
  85. package/dist/state/schema.d.ts +6 -0
  86. package/dist/state/schema.js +473 -0
  87. package/dist/state/schema.js.map +1 -0
  88. package/dist/viewer/cli.d.ts +2 -2
  89. package/dist/viewer/cli.js +142 -122
  90. package/dist/viewer/cli.js.map +1 -1
  91. package/dist/viewer/render.d.ts +4 -4
  92. package/dist/viewer/render.js +2 -17
  93. package/dist/viewer/render.js.map +1 -1
  94. package/dist/viewer/session-reducer.d.ts +1 -1
  95. package/dist/viewer/session-reducer.js +1 -1
  96. package/dist/viewer/tui.d.ts +3 -3
  97. package/dist/viewer/tui.js +15 -13
  98. package/dist/viewer/tui.js.map +1 -1
  99. package/dist/viewer/watch.d.ts +2 -5
  100. package/dist/viewer/watch.js +13 -13
  101. package/dist/viewer/watch.js.map +1 -1
  102. package/dist/workflows/composition.js +12 -2
  103. package/dist/workflows/composition.js.map +1 -1
  104. package/dist/workflows/definition.d.ts +6 -2
  105. package/dist/workflows/definition.js +17 -0
  106. package/dist/workflows/definition.js.map +1 -1
  107. package/dist/workflows/engine.d.ts +6 -6
  108. package/dist/workflows/engine.js +183 -103
  109. package/dist/workflows/engine.js.map +1 -1
  110. package/dist/workflows/errors.d.ts +3 -3
  111. package/dist/workflows/errors.js +3 -3
  112. package/dist/workflows/human-decision.d.ts +29 -4
  113. package/dist/workflows/human-decision.js +547 -283
  114. package/dist/workflows/human-decision.js.map +1 -1
  115. package/dist/workflows/index.d.ts +4 -5
  116. package/dist/workflows/index.js +3 -4
  117. package/dist/workflows/index.js.map +1 -1
  118. package/dist/workflows/schema.js +17 -1
  119. package/dist/workflows/schema.js.map +1 -1
  120. package/dist/workflows/store.d.ts +83 -103
  121. package/dist/workflows/store.js +902 -951
  122. package/dist/workflows/store.js.map +1 -1
  123. package/dist/workflows/types.d.ts +55 -81
  124. package/docs/CONTROLLERS.md +10 -8
  125. package/docs/DEFERRED_TURNS.md +2 -2
  126. package/docs/DESIGN_PHILOSOPHY.md +4 -2
  127. package/docs/HUMAN_DECISIONS.md +13 -14
  128. package/docs/MONITOR.md +179 -231
  129. package/docs/SQLITE_STATE.md +219 -0
  130. package/docs/WORKFLOW_COMPOSITION.md +19 -19
  131. package/docs/WORKFLOW_STEP_MESSAGES.md +20 -18
  132. package/docs/WORKFLOW_UPDATES.md +10 -9
  133. package/docs/development.md +9 -9
  134. package/docs/live-replay-protocol.md +28 -37
  135. package/docs/plans/2026-08-16-workflow-updates-plan.md +1 -1
  136. package/docs/plans/2026-08-19-human-decision-gates-plan.md +1 -1
  137. package/docs/plans/2026-08-21-autoimplement-timeout-fallback-plan.md +1 -1
  138. package/docs/plans/2026-08-21-plan-change-approval-policy-plan.md +1 -1
  139. package/docs/plans/2026-08-21-sanity-check-plan.md +30 -16
  140. package/docs/plans/2026-08-22-goal-finishing-monitor-plan.md +200 -0
  141. package/docs/plans/2026-08-23-assistant-agent-completion-plan.md +701 -0
  142. package/docs/plans/2026-08-23-sqlite-state-plan.md +970 -0
  143. package/docs/plans/replayable-run-bundles-implementation-plan.md +2 -2
  144. package/docs/plans/session-event-replay-implementation-plan.md +1 -1
  145. package/docs/plans/tui-viewer-implementation-plan.md +1 -1
  146. package/docs/session-event-journal.md +63 -434
  147. package/docs/tui-viewer.md +13 -15
  148. package/docs/workflows.md +104 -50
  149. package/examples/workflows/plain-summary.workflow.ts +1 -0
  150. package/herdr-plugin.toml +1 -1
  151. package/package.json +1 -1
  152. package/plugins/herdr/viewer.mjs +1 -11
  153. package/skills/autoplan/SKILL.md +5 -4
  154. package/skills/monitor/SKILL.md +91 -163
  155. package/skills/pi-workflows/SKILL.md +7 -7
  156. package/skills/sanity-check/SKILL.md +1 -1
  157. package/src/builtins/autoplan.workflow.ts +290 -40
  158. package/src/builtins/catalog.ts +6 -4
  159. package/src/builtins/index.ts +7 -1
  160. package/src/builtins/monitor.workflow.ts +663 -249
  161. package/src/builtins/plain-summary.workflow.ts +185 -0
  162. package/src/builtins/sanity-check.workflow.ts +62 -7
  163. package/src/controllers/effects.ts +7 -0
  164. package/src/controllers/index.ts +0 -6
  165. package/src/controllers/manager.ts +72 -32
  166. package/src/controllers/sqlite.ts +2420 -1948
  167. package/src/controllers/store.ts +17 -38
  168. package/src/controllers/types.ts +3 -0
  169. package/src/controllers/workflow-engine-scheduler.ts +4 -8
  170. package/src/controllers/workflows.ts +45 -21
  171. package/src/extension/controller-host.ts +1 -2
  172. package/src/extension/decision-channels.ts +427 -144
  173. package/src/extension/executor.ts +105 -2
  174. package/src/extension/herdr-viewer.ts +0 -5
  175. package/src/extension/index.ts +180 -118
  176. package/src/extension/recorder.ts +13 -22
  177. package/src/extension/step-message.ts +106 -4
  178. package/src/extension/widget.ts +8 -0
  179. package/src/host/rpc-executor.ts +4 -0
  180. package/src/host/runner.ts +93 -41
  181. package/src/render/graph-render.ts +11 -4
  182. package/src/state/database.ts +375 -0
  183. package/src/state/index.ts +29 -0
  184. package/src/state/json.ts +42 -0
  185. package/src/state/mutation.ts +435 -0
  186. package/src/state/schema.ts +475 -0
  187. package/src/viewer/cli.ts +151 -144
  188. package/src/viewer/render.ts +12 -24
  189. package/src/viewer/session-reducer.ts +1 -1
  190. package/src/viewer/tui.ts +18 -17
  191. package/src/viewer/watch.ts +13 -17
  192. package/src/workflows/composition.ts +12 -3
  193. package/src/workflows/definition.ts +36 -3
  194. package/src/workflows/engine.ts +212 -116
  195. package/src/workflows/errors.ts +3 -3
  196. package/src/workflows/human-decision.ts +795 -340
  197. package/src/workflows/index.ts +15 -19
  198. package/src/workflows/schema.ts +19 -1
  199. package/src/workflows/store.ts +1295 -1163
  200. package/src/workflows/types.ts +61 -81
  201. package/dist/workflows/artifacts.d.ts +0 -40
  202. package/dist/workflows/artifacts.js +0 -155
  203. package/dist/workflows/artifacts.js.map +0 -1
  204. package/dist/workflows/migrate-sources.d.ts +0 -42
  205. package/dist/workflows/migrate-sources.js +0 -133
  206. package/dist/workflows/migrate-sources.js.map +0 -1
  207. package/docs/run-bundles.md +0 -481
  208. package/src/workflows/artifacts.ts +0 -188
  209. package/src/workflows/migrate-sources.ts +0 -178
@@ -0,0 +1,701 @@
1
+ ---
2
+ title: Add assistant completion to agent workflows
3
+ author: Onur Solmaz <2453968+osolmaz@users.noreply.github.com>
4
+ date: 2026-08-23
5
+ status: implemented
6
+ ---
7
+
8
+ ## Selected design
9
+
10
+ Keep `agent` as the only model-work node.
11
+
12
+ Use the existing `expectedOutput` key to select a visible assistant response:
13
+
14
+ ```ts
15
+ agent({
16
+ prompt: ({ input }) => `Summarize this:\n${JSON.stringify(input)}`,
17
+ expectedOutput: assistantMessage(),
18
+ });
19
+ ```
20
+
21
+ The two behaviors are:
22
+
23
+ - **Current agent:** the model calls `workflow submit`; the submitted JSON becomes the node output.
24
+ - **Assistant agent:** the model writes a normal assistant response; its exact visible text becomes the node output, and the workflow follows its normal edge.
25
+
26
+ The assistant mode is not a decision or checkpoint. It schedules one model turn, waits until that turn fully settles, records the result, and continues.
27
+
28
+ This needs no Pi API change and no new node type.
29
+
30
+ ---
31
+
32
+ # Implementation plan
33
+
34
+ ## 1. Record the completion-mode contract
35
+
36
+ ### Change
37
+
38
+ Document that `agent` supports two mutually exclusive completion methods:
39
+
40
+ 1. Workflow-tool submission.
41
+ 2. Visible assistant response.
42
+
43
+ Define these rules:
44
+
45
+ - Existing agents keep their current workflow-tool behavior.
46
+ - Assistant completion is explicit through `expectedOutput: assistantMessage()`.
47
+ - Output-transforming `validate` is invalid with `assistantMessage()`.
48
+ - The assistant node output is the exact visible text.
49
+ - The text must be non-empty. A character limit applies only when the author sets `maxChars`.
50
+ - The node follows its configured edge after the assistant turn settles.
51
+ - It does not ask for human input and does not create a checkpoint.
52
+ - Intermediate tool-call assistant messages do not complete the node.
53
+ - Aborted, failed, and tool-only turns do not complete the node.
54
+ - A visible response is not retried after validation failure because that would show duplicate answers.
55
+ - Session-bound assistant output is unavailable to detached jobs without an origin session.
56
+
57
+ ### Where
58
+
59
+ - New canonical plan under `docs/plans/`.
60
+ - `docs/workflows.md`
61
+ - `docs/WORKFLOW_STEP_MESSAGES.md`
62
+ - `docs/WORKFLOW_COMPOSITION.md`
63
+ - `docs/SQLITE_STATE.md`
64
+
65
+ ### Verification
66
+
67
+ The documents distinguish assistant completion from:
68
+
69
+ - `workflow submit`;
70
+ - `notify`;
71
+ - root `presentationPrompt`;
72
+ - `checkpoint`;
73
+ - `humanDecision()`.
74
+
75
+ ---
76
+
77
+ ## 2. Extend the public `agent()` definition
78
+
79
+ ### Change
80
+
81
+ Add a public assistant output builder:
82
+
83
+ ```ts
84
+ assistantMessage();
85
+ ```
86
+
87
+ Make `AgentNodeDefinition` a type-safe union:
88
+
89
+ ```ts
90
+ type SubmittedAgentNodeDefinition = {
91
+ nodeType: "agent";
92
+ prompt: ...;
93
+ expectedOutput?: string;
94
+ validate?: ...;
95
+ };
96
+
97
+ type AssistantAgentNodeDefinition = {
98
+ nodeType: "agent";
99
+ prompt: ...;
100
+ expectedOutput: AssistantMessageOutput;
101
+ validate?: never;
102
+ };
103
+ ```
104
+
105
+ Keep the existing submitted-agent API unchanged. This is an additive mode, not a compatibility shim.
106
+
107
+ `assistantMessage()` adds no Pi Workflows character limit by default. Authors can opt in with `assistantMessage({ maxChars: 2_000 })`. When supplied, `maxChars` must be a positive integer. A specific workflow such as `plain-summary` can set its own explicit limit.
108
+
109
+ ### Where
110
+
111
+ - `src/workflows/types.ts`
112
+ - `src/workflows/definition.ts`
113
+ - `src/workflows/schema.ts`
114
+ - `src/workflows/index.ts`
115
+ - Type-level tests
116
+
117
+ ### Verification
118
+
119
+ Type tests prove:
120
+
121
+ - existing agents still compile;
122
+ - assistant agents compile;
123
+ - `assistantMessage()` plus `validate` does not compile;
124
+ - omitted limits remain omitted in the definition;
125
+ - invalid explicit limits fail during definition validation;
126
+ - no new node type appears in graph or run records.
127
+
128
+ ---
129
+
130
+ ## 3. Add completion mode to the executor contract
131
+
132
+ ### Change
133
+
134
+ Extend `AgentStepContract` with:
135
+
136
+ ```ts
137
+ completion: "submit" | "assistant";
138
+ maxOutputChars?: number;
139
+ ```
140
+
141
+ For existing submitted agents:
142
+
143
+ - append the current workflow step contract;
144
+ - keep `accept(output)`;
145
+ - keep nudges when the model settles without submitting.
146
+
147
+ For assistant agents:
148
+
149
+ - do not append workflow-submit instructions;
150
+ - append a short assistant completion contract;
151
+ - tell the model to answer normally and not call `workflow submit`;
152
+ - capture only visible text blocks;
153
+ - complete after `agent_settled`;
154
+ - return the exact text as `AgentStepSubmission.output`.
155
+
156
+ Example model contract:
157
+
158
+ ```text
159
+ Reply with a normal assistant message.
160
+ Do not call the workflow tool to complete this step.
161
+ Your visible reply becomes the workflow step output.
162
+ ```
163
+
164
+ When the author supplies `maxChars`, append that explicit limit to the model contract.
165
+
166
+ ### Where
167
+
168
+ - `src/workflows/types.ts`
169
+ - `src/workflows/engine.ts`
170
+ - `src/extension/step-message.ts`
171
+ - `src/extension/executor.ts`
172
+
173
+ ### Verification
174
+
175
+ Engine tests prove both completion modes use the same `agent` node type and route through ordinary edges.
176
+
177
+ ---
178
+
179
+ ## 4. Capture the interactive assistant response
180
+
181
+ ### Change
182
+
183
+ Extend `ConversationStepExecutor` to track the pending completion mode.
184
+
185
+ For assistant completion:
186
+
187
+ 1. Mark the conversation before sending the prompt.
188
+ 2. Deliver the existing compact workflow step message.
189
+ 3. Record `message_end`, then use the later `turn_end` message after all documented message replacements have run.
190
+ 4. Keep the latest finalized assistant message from the current attempt.
191
+ 5. Ignore thinking blocks and tool calls.
192
+ 6. Wait for `agent_settled`.
193
+ 7. Reject aborted, errored, empty, or tool-only outcomes.
194
+ 8. Check the character limit when the author supplied one.
195
+ 9. Record the conversation range.
196
+ 10. Resolve the node with the exact assistant text.
197
+
198
+ Do not set `suppressWorkflowAssistantTail` for this mode. The response must stay visible.
199
+
200
+ When the model calls `workflow submit` during an assistant step, return a clear error:
201
+
202
+ > This step completes with a normal assistant response. Do not submit workflow output.
203
+
204
+ Updates can remain unavailable for assistant completion unless later evidence shows a real need.
205
+
206
+ ### Where
207
+
208
+ - `src/extension/executor.ts`
209
+ - `src/extension/index.ts`
210
+ - `src/extension/session-events.ts`
211
+ - `src/extension/recorder.ts`
212
+ - `src/extension/step-message.ts`
213
+
214
+ ### Verification
215
+
216
+ Tests cover:
217
+
218
+ - one visible assistant message;
219
+ - exact captured text;
220
+ - text mixed with thinking;
221
+ - tool call followed by final text;
222
+ - several tool turns;
223
+ - auto-retry before final settlement;
224
+ - empty response;
225
+ - length stop;
226
+ - provider error;
227
+ - user Escape;
228
+ - timeout and cancellation;
229
+ - incorrect `workflow submit`;
230
+ - parent continuation only after settlement.
231
+
232
+ ---
233
+
234
+ ## 5. Make recovery duplicate-safe
235
+
236
+ ### Change
237
+
238
+ Bind the assistant response to the existing run, node, and attempt IDs.
239
+
240
+ The custom workflow prompt already carries those IDs. Extend its message details with the completion mode.
241
+
242
+ Record an attempt-scoped assistant completion receipt containing:
243
+
244
+ - run ID;
245
+ - node ID;
246
+ - attempt ID;
247
+ - assistant session entry ID;
248
+ - text digest;
249
+ - bounded text;
250
+ - conversation range.
251
+
252
+ Before redelivering an unfinished assistant step, inspect the current session branch:
253
+
254
+ - If the matching prompt has a completed assistant child, validate and adopt it.
255
+ - If the matching prompt exists without a completed assistant response, resume the attempt.
256
+ - If no matching prompt exists, send it.
257
+ - Never adopt a response from another attempt or branch.
258
+
259
+ Use existing run state, trace, and session recording. Do not add a new store.
260
+
261
+ ### Where
262
+
263
+ - `src/workflows/types.ts`
264
+ - `src/workflows/store.ts`
265
+ - `src/workflows/engine.ts`
266
+ - `src/extension/recorder.ts`
267
+ - `src/extension/executor.ts`
268
+ - SQLite run projection and recovery tests
269
+
270
+ ### Verification
271
+
272
+ Crash tests cover:
273
+
274
+ - before prompt delivery;
275
+ - after prompt delivery;
276
+ - during streaming;
277
+ - after `message_end` but before `agent_settled`;
278
+ - after settlement but before node persistence;
279
+ - after node persistence but before routing;
280
+ - process restart;
281
+ - session reload;
282
+ - claim loss;
283
+ - stale branch response;
284
+ - repeated loop visits to the same node.
285
+
286
+ Each case produces at most one visible assistant response.
287
+
288
+ ---
289
+
290
+ ## 6. Handle interactive and detached execution honestly
291
+
292
+ ### Change
293
+
294
+ Assistant completion needs a conversation where the user can see the assistant response.
295
+
296
+ Add an executor capability that distinguishes:
297
+
298
+ - session-visible execution;
299
+ - detached execution.
300
+
301
+ The interactive Pi executor supports assistant completion.
302
+
303
+ A detached WorkflowHost must not run such a node in an invisible RPC child. It must:
304
+
305
+ - park the run before the node;
306
+ - leave it claimable by the origin Pi session;
307
+ - resume when that session is available.
308
+
309
+ A controller child or detached run with no origin session must fail clearly before prompting:
310
+
311
+ > Assistant completion requires an origin Pi session.
312
+
313
+ Do not replace the response with a workflow notification.
314
+
315
+ Direct RPC clients can support assistant completion because RPC exposes `message_end` and `agent_settled` events to the client.
316
+
317
+ ### Where
318
+
319
+ - `src/workflows/types.ts`
320
+ - `src/workflows/engine.ts`
321
+ - `src/host/runner.ts`
322
+ - `src/host/rpc-executor.ts`
323
+ - `src/host/rpc-bridge.ts` only if the bridge needs completion metadata
324
+ - Queue and host tests
325
+
326
+ ### Verification
327
+
328
+ Tests prove:
329
+
330
+ - interactive TUI works;
331
+ - direct RPC captures the assistant response;
332
+ - a detached host parks before visible output;
333
+ - the origin session resumes and emits it once;
334
+ - a detached run without an origin session fails clearly;
335
+ - no assistant response is silently converted into a notification.
336
+
337
+ ---
338
+
339
+ ## 7. Add the general `plain-summary` workflow
340
+
341
+ ### Change
342
+
343
+ Create a reusable built-in workflow with this input:
344
+
345
+ ```ts
346
+ type PlainSummaryInput = {
347
+ source: unknown;
348
+ purpose: string;
349
+ mustInclude?: string[];
350
+ maxChars?: number;
351
+ maxSentences?: number;
352
+ format?: "paragraphs" | "bullets" | "mixed";
353
+ };
354
+ ```
355
+
356
+ Use strict limits:
357
+
358
+ - serialized source: at most 50,000 characters;
359
+ - purpose: at most 1,000 characters;
360
+ - up to 32 required points;
361
+ - each required point: at most 500 characters;
362
+ - `maxChars`: default 2,000, maximum 10,000;
363
+ - `maxSentences`: default 5, maximum 20.
364
+
365
+ The workflow uses one assistant-completion agent. Its prompt says:
366
+
367
+ - use only the supplied source;
368
+ - start with the main point;
369
+ - use short, complete sentences;
370
+ - use common, concrete words;
371
+ - keep technical terms only when needed;
372
+ - do not invent facts;
373
+ - do not add a meta introduction;
374
+ - include every required point;
375
+ - obey the requested format and limits;
376
+ - do not use tools;
377
+ - do not call the workflow tool.
378
+
379
+ Do not import or depend on OnurPi’s personal `amk` skill. Put the stable plain-writing rules directly in this public workflow.
380
+
381
+ Return:
382
+
383
+ ```ts
384
+ type PlainSummaryResult = {
385
+ text: string;
386
+ };
387
+ ```
388
+
389
+ The text is both:
390
+
391
+ - the visible assistant message;
392
+ - the included workflow’s result.
393
+
394
+ The workflow has no `notify` node and no `presentationPrompt`, because its assistant agent already presents the result.
395
+
396
+ ### Where
397
+
398
+ - `src/builtins/plain-summary.workflow.ts`
399
+ - `src/builtins/index.ts`
400
+ - `src/builtins/catalog.ts`
401
+ - `examples/workflows/plain-summary.workflow.ts`
402
+ - `test/builtin-plain-summary.test.ts`
403
+
404
+ ### Verification
405
+
406
+ Test it:
407
+
408
+ - standalone;
409
+ - included in a parent;
410
+ - nested;
411
+ - repeated in a loop;
412
+ - with paragraphs, bullets, and mixed output;
413
+ - with missing required facts;
414
+ - with excessive input;
415
+ - with excessive output;
416
+ - with hostile instructions inside `source`;
417
+ - with cancellation;
418
+ - with no duplicate final presentation.
419
+
420
+ ---
421
+
422
+ ## 8. Make Autoplan record every considered plan
423
+
424
+ ### Change
425
+
426
+ Autoplan cannot summarize plans that exist only in hidden model reasoning. Make every candidate explicit in the durable `propose` output.
427
+
428
+ Change `propose` to return a bounded candidate list:
429
+
430
+ ```ts
431
+ {
432
+ candidates: [
433
+ {
434
+ id: "stable-id",
435
+ title: "short title",
436
+ gist: "plain description",
437
+ solution: "full proposal",
438
+ rationale: "why it could work",
439
+ parts: ["part"],
440
+ tradeoffs: ["trade-off"],
441
+ },
442
+ ];
443
+ }
444
+ ```
445
+
446
+ Require two through four practical candidates.
447
+
448
+ Keep the separate ideal stage. Treat the ideal as another named candidate during selection.
449
+
450
+ When `previousPlan` exists, require the proposal stage to identify whether it remains a candidate or was rejected by new evidence.
451
+
452
+ Change `choose` to return:
453
+
454
+ ```ts
455
+ {
456
+ status: "ready",
457
+ selectedId: "candidate-id-or-ideal",
458
+ why: "reason",
459
+ rejected: [
460
+ { "id": "other-id", "reason": "why it was not selected" }
461
+ ],
462
+ compromises: ["compromise"]
463
+ }
464
+ ```
465
+
466
+ Validate that:
467
+
468
+ - the selected ID exists;
469
+ - every non-selected candidate appears exactly once under `rejected`;
470
+ - no unknown candidate appears;
471
+ - no candidate is omitted;
472
+ - the previous plan is accounted for when supplied.
473
+
474
+ “All proposed plans” means these explicit records. It does not include or request hidden chain-of-thought.
475
+
476
+ ### Where
477
+
478
+ - `src/builtins/autoplan.workflow.ts`
479
+ - `test/builtin-autoplan.test.ts`
480
+ - Autoplan docs and skill text
481
+
482
+ ### Verification
483
+
484
+ Tests cover candidate completeness, stable IDs, ideal selection, practical selection, previous-plan treatment, duplicate rejection entries, missing candidates, and blocked selection.
485
+
486
+ ---
487
+
488
+ ## 9. Compose `plain-summary` into Autoplan
489
+
490
+ ### Change
491
+
492
+ Add `plain-summary` as an included workflow.
493
+
494
+ For a successful selection, pass:
495
+
496
+ - the chosen candidate;
497
+ - why it was chosen;
498
+ - the detailed implementation plan;
499
+ - every rejected candidate;
500
+ - every rejection reason;
501
+ - the relationship to the ideal;
502
+ - important limits and compromises.
503
+
504
+ Require the visible response to contain:
505
+
506
+ 1. A plain explanation of the chosen plan.
507
+ 2. A short list of the main implementation steps.
508
+ 3. One-line summaries of all rejected plans and why each lost.
509
+ 4. A clear note when the recommendation is still awaiting approval.
510
+
511
+ Use a bounded format, for example:
512
+
513
+ - maximum 2,500 characters;
514
+ - maximum 12 sentences;
515
+ - mixed paragraph and bullets.
516
+
517
+ For a blocked selection, run the same summarizer with:
518
+
519
+ - the blocker;
520
+ - all considered candidates;
521
+ - why none can meet the goal.
522
+
523
+ Route both successful and blocked paths through the summarizer.
524
+
525
+ Remove Autoplan’s root `presentationPrompt`. Otherwise it would create a second assistant response.
526
+
527
+ Preserve the full technical outputs in `AutoplanReady` and add:
528
+
529
+ ```ts
530
+ plainSummary: {
531
+ text: string;
532
+ }
533
+ ```
534
+
535
+ ### Where
536
+
537
+ - `src/builtins/autoplan.workflow.ts`
538
+ - `test/builtin-autoplan.test.ts`
539
+ - `docs/workflows.md`
540
+ - `skills/autoplan/SKILL.md`
541
+
542
+ ### Verification
543
+
544
+ A real-Pi mock-provider test proves:
545
+
546
+ - Autoplan emits one plain assistant message;
547
+ - it does not call `workflow submit` for the summary node;
548
+ - the message includes the chosen plan;
549
+ - every explicit rejected plan is present;
550
+ - the detailed plan remains in durable SQLite run state;
551
+ - no long second presentation appears;
552
+ - a parent workflow continues after the summary settles.
553
+
554
+ ---
555
+
556
+ ## 10. Preserve behavior when Autoplan is included elsewhere
557
+
558
+ ### Change
559
+
560
+ Check every current Autoplan composition:
561
+
562
+ - shared plan-change workflow;
563
+ - Autoimplement redesign;
564
+ - Monitor repair planning.
565
+
566
+ The summary will appear before documentation and human approval. Its wording must say “recommended plan” or “plan selected for approval,” not “approved plan.”
567
+
568
+ Human approval remains separate. The summary does not answer or bypass `humanDecision()`.
569
+
570
+ ### Where
571
+
572
+ - `src/builtins/plan-change.workflow.ts`
573
+ - `src/builtins/autoimplement.workflow.ts`
574
+ - `src/builtins/monitor.workflow.ts`
575
+ - Related tests
576
+
577
+ ### Verification
578
+
579
+ Tests prove:
580
+
581
+ - the summary appears before approval;
582
+ - Telegram and Pi still receive the actual human decision;
583
+ - the summary cannot satisfy that decision;
584
+ - approval, stop, replan, timeout, and skip routes remain unchanged;
585
+ - replanning emits one new summary for the new candidate set.
586
+
587
+ ---
588
+
589
+ ## 11. Update snapshots, rendering, and revisions
590
+
591
+ ### Change
592
+
593
+ Show assistant-completion agents as ordinary agent nodes, with a small completion marker in piw and expanded details.
594
+
595
+ Do not add a node color or node type.
596
+
597
+ Update definition snapshots to include:
598
+
599
+ ```json
600
+ {
601
+ "nodeType": "agent",
602
+ "expectedOutput": {
603
+ "kind": "assistant-message",
604
+ "maxChars": 2000
605
+ }
606
+ }
607
+ ```
608
+
609
+ Omit `maxChars` from the snapshot when the author did not set it.
610
+
611
+ Bump affected built-ins:
612
+
613
+ - `plain-summary`: revision 1;
614
+ - `autoplan`: revision 2;
615
+ - Autoimplement and Monitor revisions if their compiled mounted-source graphs change.
616
+
617
+ Use the alpha hard-cutover policy for unfinished runs whose definitions changed. Keep terminal SQLite runs readable.
618
+
619
+ ### Where
620
+
621
+ - `src/workflows/store.ts`
622
+ - `src/render/`
623
+ - `src/viewer/`
624
+ - `src/extension/widget.ts`
625
+ - `src/builtins/catalog.ts`
626
+ - Snapshot and revision tests
627
+
628
+ ### Verification
629
+
630
+ The widget and piw show the node as an agent and clearly state “assistant response.” Old terminal runs still render. Incompatible unfinished runs get clear restart guidance.
631
+
632
+ ---
633
+
634
+ ## 12. Full verification
635
+
636
+ Run focused tests first:
637
+
638
+ ```bash
639
+ npx vitest run test/executor.test.ts
640
+ npx vitest run test/rpc-executor.test.ts test/rpc-executor-flow.test.ts
641
+ npx vitest run test/engine.test.ts test/store.test.ts
642
+ npx vitest run test/builtin-plain-summary.test.ts test/builtin-autoplan.test.ts
643
+ npx vitest run test/extension.test.ts test/step-message.test.ts
644
+ ```
645
+
646
+ Then run all required repository gates:
647
+
648
+ ```bash
649
+ npm run check
650
+ npm run test:e2e
651
+ npx slophammer-ts@latest dry .
652
+ npx slophammer-ts@latest check . --only ts.dependency-boundaries-required
653
+ ```
654
+
655
+ The real-Pi end-to-end test must verify the session transcript directly:
656
+
657
+ - one assistant-completion prompt;
658
+ - one normal assistant message;
659
+ - no summary `workflow submit` call;
660
+ - one following parent step;
661
+ - no duplicate summary after reload;
662
+ - no workflow notification containing the summary.
663
+
664
+ Run Pi Reviewer until no P0 or P1 findings remain, then verify CI.
665
+
666
+ ---
667
+
668
+ ## Compatibility and release
669
+
670
+ This is a compatible public capability addition to `agent()` and a new built-in workflow. At the current `0.12.1` baseline, the likely release is `0.13.0`.
671
+
672
+ Existing submitted-agent workflows remain valid. No legacy adapter or second agent implementation is added.
673
+
674
+ Autoplan’s structured proposal and selection outputs change in place. Its built-in revision must change, and unfinished older runs must restart.
675
+
676
+ Do not update OnurPi, install the release, or change another repository as part of this implementation unless separately authorized.
677
+
678
+ ---
679
+
680
+ ## Main risks
681
+
682
+ | Risk | Mitigation |
683
+ | ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
684
+ | Duplicate assistant response after a crash | Bind prompt and response to run/node/attempt IDs and reconcile the session branch before redelivery. |
685
+ | Parent advances before the assistant finishes | Resolve assistant mode only from `agent_settled`. |
686
+ | Tool-only response completes the node | Require non-empty final visible text after tool activity settles. |
687
+ | A workflow receives more text than it needs | Set `maxChars` explicitly for that workflow. Keep the general API unlimited by default and do not retry an already visible response. |
688
+ | Detached host produces an invisible assistant response | Park before the node and require the origin Pi session. |
689
+ | Summary bypasses human approval | Keep it as an agent output; human decisions remain protected checkpoints. |
690
+ | “All plans” implies hidden reasoning | Include every explicit candidate record and never request hidden reasoning. |
691
+ | Generic summary leaks source data into chat | Document that callers choose the source and that the assistant response becomes normal session state. |
692
+ | Extra model cost | Autoplan replaces its existing final presentation turn, so standalone use should not add a second final model call. Included use intentionally adds one visible summary turn. |
693
+
694
+ ## Contract impact
695
+
696
+ - **Session state:** one normal assistant message for each assistant-completion node.
697
+ - **Run state:** exact text, output mode, conversation range, recovery receipt, and the optional author-supplied character limit.
698
+ - **Other persistent data:** none beyond existing SQLite workflow state and Pi session entries.
699
+ - **Pi internals:** none.
700
+ - **Pi API:** existing documented message and lifecycle events only.
701
+ - **pi-workflows API:** additive `expectedOutput: assistantMessage()` mode for `agent()` and the new composable `plain-summary` workflow.