@osolmaz/pi-workflows 0.14.0 → 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.
- package/README.md +78 -110
- package/dist/builtins/autoimplement.workflow.js +3 -1
- package/dist/builtins/autoimplement.workflow.js.map +1 -1
- package/dist/builtins/change-verification.workflow.js +7 -2
- package/dist/builtins/change-verification.workflow.js.map +1 -1
- package/dist/builtins/metadata.d.ts +22 -0
- package/dist/builtins/metadata.js +10 -0
- package/dist/builtins/metadata.js.map +1 -0
- package/dist/builtins/monitor.workflow.js +4 -1
- package/dist/builtins/monitor.workflow.js.map +1 -1
- package/dist/builtins/sanity-check.workflow.js +4 -1
- package/dist/builtins/sanity-check.workflow.js.map +1 -1
- package/dist/builtins/workspace-preparation.workflow.js +3 -1
- package/dist/builtins/workspace-preparation.workflow.js.map +1 -1
- package/dist/controllers/index.d.ts +0 -1
- package/dist/controllers/index.js +0 -1
- package/dist/controllers/index.js.map +1 -1
- package/dist/controllers/sqlite.d.ts +51 -0
- package/dist/controllers/sqlite.js +433 -57
- package/dist/controllers/sqlite.js.map +1 -1
- package/dist/controllers/store.d.ts +1 -0
- package/dist/extension/controller-command.d.ts +22 -0
- package/dist/extension/controller-command.js +32 -0
- package/dist/extension/controller-command.js.map +1 -0
- package/dist/extension/index.d.ts +2 -9
- package/dist/extension/index.js +876 -3447
- package/dist/extension/index.js.map +1 -1
- package/dist/extension/message-card.d.ts +13 -0
- package/dist/extension/message-card.js +46 -0
- package/dist/extension/message-card.js.map +1 -0
- package/dist/extension/step-message.d.ts +5 -6
- package/dist/extension/step-message.js +41 -52
- package/dist/extension/step-message.js.map +1 -1
- package/dist/host/child-worker-supervisor.d.ts +50 -0
- package/dist/host/child-worker-supervisor.js +159 -0
- package/dist/host/child-worker-supervisor.js.map +1 -0
- package/dist/host/client.d.ts +48 -0
- package/dist/host/client.js +216 -0
- package/dist/host/client.js.map +1 -0
- package/dist/host/controller-worker-entry.d.ts +2 -0
- package/dist/host/controller-worker-entry.js +244 -0
- package/dist/host/controller-worker-entry.js.map +1 -0
- package/dist/host/controller-worker-protocol.d.ts +36 -0
- package/dist/host/controller-worker-protocol.js +49 -0
- package/dist/host/controller-worker-protocol.js.map +1 -0
- package/dist/host/controller-worker-supervisor.d.ts +21 -0
- package/dist/host/controller-worker-supervisor.js +54 -0
- package/dist/host/controller-worker-supervisor.js.map +1 -0
- package/dist/host/host-entry.d.ts +2 -0
- package/dist/host/host-entry.js +23 -0
- package/dist/host/host-entry.js.map +1 -0
- package/dist/host/processes.d.ts +17 -12
- package/dist/host/processes.js +154 -50
- package/dist/host/processes.js.map +1 -1
- package/dist/host/protocol.d.ts +38 -0
- package/dist/host/protocol.js +156 -0
- package/dist/host/protocol.js.map +1 -0
- package/dist/host/resolver-entry.d.ts +49 -0
- package/dist/host/resolver-entry.js +149 -0
- package/dist/host/resolver-entry.js.map +1 -0
- package/dist/host/rpc-executor.d.ts +14 -3
- package/dist/host/rpc-executor.js +63 -30
- package/dist/host/rpc-executor.js.map +1 -1
- package/dist/host/runner.d.ts +95 -29
- package/dist/host/runner.js +2311 -348
- package/dist/host/runner.js.map +1 -1
- package/dist/host/state.d.ts +174 -0
- package/dist/host/state.js +689 -0
- package/dist/host/state.js.map +1 -0
- package/dist/host/worker-entry.d.ts +10 -0
- package/dist/host/worker-entry.js +446 -0
- package/dist/host/worker-entry.js.map +1 -0
- package/dist/host/worker-protocol.d.ts +31 -0
- package/dist/host/worker-protocol.js +122 -0
- package/dist/host/worker-protocol.js.map +1 -0
- package/dist/host/worker-store.d.ts +80 -0
- package/dist/host/worker-store.js +91 -0
- package/dist/host/worker-store.js.map +1 -0
- package/dist/host/worker-supervisor.d.ts +22 -0
- package/dist/host/worker-supervisor.js +54 -0
- package/dist/host/worker-supervisor.js.map +1 -0
- package/dist/render/canvas.d.ts +2 -1
- package/dist/render/canvas.js +40 -15
- package/dist/render/canvas.js.map +1 -1
- package/dist/render/graph-render.d.ts +7 -3
- package/dist/render/graph-render.js +125 -74
- package/dist/render/graph-render.js.map +1 -1
- package/dist/state/database.js +3 -1
- package/dist/state/database.js.map +1 -1
- package/dist/state/index.d.ts +1 -0
- package/dist/state/index.js +1 -0
- package/dist/state/index.js.map +1 -1
- package/dist/state/schema.d.ts +1 -1
- package/dist/state/schema.js +171 -3
- package/dist/state/schema.js.map +1 -1
- package/dist/state/viewer.d.ts +46 -0
- package/dist/state/viewer.js +249 -0
- package/dist/state/viewer.js.map +1 -0
- package/dist/viewer/cli.d.ts +1 -1
- package/dist/viewer/cli.js +47 -18
- package/dist/viewer/cli.js.map +1 -1
- package/dist/workflows/composition.js +25 -2
- package/dist/workflows/composition.js.map +1 -1
- package/dist/workflows/definition.d.ts +3 -1
- package/dist/workflows/definition.js +25 -0
- package/dist/workflows/definition.js.map +1 -1
- package/dist/workflows/engine.d.ts +1 -0
- package/dist/workflows/engine.js +157 -42
- package/dist/workflows/engine.js.map +1 -1
- package/dist/workflows/errors.d.ts +3 -1
- package/dist/workflows/errors.js +4 -7
- package/dist/workflows/errors.js.map +1 -1
- package/dist/workflows/human-decision.d.ts +3 -0
- package/dist/workflows/human-decision.js +31 -0
- package/dist/workflows/human-decision.js.map +1 -1
- package/dist/workflows/index.d.ts +1 -1
- package/dist/workflows/index.js +1 -1
- package/dist/workflows/index.js.map +1 -1
- package/dist/workflows/schema.js +17 -6
- package/dist/workflows/schema.js.map +1 -1
- package/dist/{viewer → workflows}/session-reducer.d.ts +3 -1
- package/dist/{viewer → workflows}/session-reducer.js +4 -0
- package/dist/workflows/session-reducer.js.map +1 -0
- package/dist/workflows/store.d.ts +87 -1
- package/dist/workflows/store.js +892 -93
- package/dist/workflows/store.js.map +1 -1
- package/dist/workflows/tool-input.d.ts +0 -26
- package/dist/workflows/tool-input.js +2 -50
- package/dist/workflows/tool-input.js.map +1 -1
- package/dist/workflows/types.d.ts +36 -4
- package/docs/2026-08-30-out-of-process-workflow-host-plan.md +353 -0
- package/docs/CONTROLLERS.md +11 -11
- package/docs/DEFERRED_TURNS.md +23 -2
- package/docs/SQLITE_STATE.md +41 -31
- package/docs/WORKFLOW_HOST.md +452 -0
- package/docs/development.md +46 -30
- package/docs/live-replay-protocol.md +129 -100
- package/docs/plans/2026-08-27-workflow-terminal-restart-plan.md +42 -0
- package/docs/plans/2026-08-28-piw-incremental-viewer-plan.md +293 -0
- package/docs/plans/piw-viewer-experience-implementation-plan.md +11 -1
- package/docs/plans/tui-viewer-implementation-plan.md +5 -0
- package/docs/tui-viewer.md +18 -3
- package/docs/workflows.md +162 -210
- package/examples/workflows/command-batch.workflow.ts +2 -0
- package/examples/workflows/shell.workflow.ts +2 -1
- package/herdr-plugin.toml +1 -1
- package/package.json +1 -1
- package/src/builtins/autoimplement.workflow.ts +3 -0
- package/src/builtins/change-verification.workflow.ts +7 -2
- package/src/builtins/metadata.ts +9 -0
- package/src/builtins/monitor.workflow.ts +4 -0
- package/src/builtins/sanity-check.workflow.ts +4 -0
- package/src/builtins/workspace-preparation.workflow.ts +3 -1
- package/src/controllers/index.ts +0 -5
- package/src/controllers/sqlite.ts +709 -76
- package/src/controllers/store.ts +1 -0
- package/src/extension/controller-command.ts +45 -0
- package/src/extension/index.ts +944 -4163
- package/src/extension/message-card.ts +61 -0
- package/src/extension/step-message.ts +58 -63
- package/src/host/child-worker-supervisor.ts +183 -0
- package/src/host/client.ts +293 -0
- package/src/host/controller-worker-entry.ts +311 -0
- package/src/host/controller-worker-protocol.ts +104 -0
- package/src/host/controller-worker-supervisor.ts +79 -0
- package/src/host/host-entry.ts +23 -0
- package/src/host/processes.ts +171 -54
- package/src/host/protocol.ts +196 -0
- package/src/host/resolver-entry.ts +241 -0
- package/src/host/rpc-executor.ts +76 -34
- package/src/host/runner.ts +2813 -422
- package/src/host/state.ts +1160 -0
- package/src/host/worker-entry.ts +533 -0
- package/src/host/worker-protocol.ts +165 -0
- package/src/host/worker-store.ts +229 -0
- package/src/host/worker-supervisor.ts +74 -0
- package/src/render/canvas.ts +44 -10
- package/src/render/graph-render.ts +145 -90
- package/src/state/database.ts +2 -1
- package/src/state/index.ts +14 -0
- package/src/state/schema.ts +171 -3
- package/src/state/viewer.ts +356 -0
- package/src/viewer/cli.ts +49 -17
- package/src/workflows/composition.ts +36 -2
- package/src/workflows/definition.ts +32 -0
- package/src/workflows/engine.ts +157 -54
- package/src/workflows/errors.ts +11 -2
- package/src/workflows/human-decision.ts +49 -0
- package/src/workflows/index.ts +2 -0
- package/src/workflows/schema.ts +19 -6
- package/src/{viewer → workflows}/session-reducer.ts +11 -1
- package/src/workflows/store.ts +1316 -108
- package/src/workflows/tool-input.ts +3 -69
- package/src/workflows/types.ts +32 -4
- package/dist/controllers/workflow-engine-scheduler.d.ts +0 -29
- package/dist/controllers/workflow-engine-scheduler.js +0 -175
- package/dist/controllers/workflow-engine-scheduler.js.map +0 -1
- package/dist/extension/controller-host.d.ts +0 -48
- package/dist/extension/controller-host.js +0 -110
- package/dist/extension/controller-host.js.map +0 -1
- package/dist/extension/deferred-turn-coordinator.d.ts +0 -32
- package/dist/extension/deferred-turn-coordinator.js +0 -143
- package/dist/extension/deferred-turn-coordinator.js.map +0 -1
- package/dist/extension/deferred-turn.d.ts +0 -44
- package/dist/extension/deferred-turn.js +0 -110
- package/dist/extension/deferred-turn.js.map +0 -1
- package/dist/extension/executor.d.ts +0 -86
- package/dist/extension/executor.js +0 -311
- package/dist/extension/executor.js.map +0 -1
- package/dist/extension/follow-up-coordinator.d.ts +0 -27
- package/dist/extension/follow-up-coordinator.js +0 -131
- package/dist/extension/follow-up-coordinator.js.map +0 -1
- package/dist/extension/recorder.d.ts +0 -84
- package/dist/extension/recorder.js +0 -528
- package/dist/extension/recorder.js.map +0 -1
- package/dist/extension/restart-policy.d.ts +0 -38
- package/dist/extension/restart-policy.js +0 -116
- package/dist/extension/restart-policy.js.map +0 -1
- package/dist/extension/session-events.d.ts +0 -133
- package/dist/extension/session-events.js +0 -61
- package/dist/extension/session-events.js.map +0 -1
- package/dist/extension/terminal-decision.d.ts +0 -51
- package/dist/extension/terminal-decision.js +0 -110
- package/dist/extension/terminal-decision.js.map +0 -1
- package/dist/viewer/session-reducer.js.map +0 -1
- package/src/controllers/workflow-engine-scheduler.ts +0 -246
- package/src/extension/controller-host.ts +0 -167
- package/src/extension/deferred-turn-coordinator.ts +0 -171
- package/src/extension/deferred-turn.ts +0 -166
- package/src/extension/executor.ts +0 -411
- package/src/extension/follow-up-coordinator.ts +0 -151
- package/src/extension/recorder.ts +0 -655
- package/src/extension/restart-policy.ts +0 -163
- package/src/extension/session-events.ts +0 -121
- package/src/extension/terminal-decision.ts +0 -172
package/docs/CONTROLLERS.md
CHANGED
|
@@ -19,7 +19,7 @@ The controller runtime provides:
|
|
|
19
19
|
- Recoverable records for external effects.
|
|
20
20
|
- Child workflow runs with stable request keys.
|
|
21
21
|
- Conditions and generations, with cleanup and structured events.
|
|
22
|
-
- Local
|
|
22
|
+
- Local resource control through the Pi extension and reconciliation through the global host.
|
|
23
23
|
|
|
24
24
|
The first production use case is pull request automation. A controller can observe a pull request, start a review or repair workflow, wait for checks, validate the current head, and apply an approved change through deterministic code.
|
|
25
25
|
|
|
@@ -27,7 +27,7 @@ The first production use case is pull request automation. A controller can obser
|
|
|
27
27
|
|
|
28
28
|
The graph engine remains the execution layer for finite work. A finite workflow can include another finite workflow in the same run through `includeWorkflow()`. Use a controller child run when work needs an independent retry history, stable request key, parallel lifecycle, or indefinite reconciliation. The graph engine does not import the controller runtime. The controller runtime may start workflows through a narrow scheduler interface.
|
|
29
29
|
|
|
30
|
-
The Pi extension is a
|
|
30
|
+
The Pi extension is a thin client. It resolves controller initialization in a dedicated child process and sends declarative resource commands to the one global host. The host schedules reconciliation but does not load controller definitions in its event loop. A supervised controller worker loads one definition and proposes bounded state changes through the host.
|
|
31
31
|
|
|
32
32
|
External events are wake-up hints. An event enqueues a resource key and carries no transition command. The reconciler reloads the resource and the external system before deciding what to do.
|
|
33
33
|
|
|
@@ -155,15 +155,15 @@ export type EffectRecord = {
|
|
|
155
155
|
|
|
156
156
|
The key names one intended effect. Reusing the key with another request fingerprint is an error. The next reconciliation observes the external system before retrying an existing pending or indeterminate effect. The effect can be treated as effectively once when the provider offers an idempotency token, a conditional request, or a reliable way to observe the requested result. The runtime does not promise generic exactly-once execution.
|
|
157
157
|
|
|
158
|
-
Mutation policy stays in deterministic effect drivers. Agent workflows return findings or artifacts for deterministic code to check and apply.
|
|
158
|
+
Mutation policy stays in deterministic effect drivers. Agent workflows return findings or artifacts for deterministic code to check and apply. Worker processes run as the same operating-system user and are not credential sandboxes. Deployments that require credential isolation should put authenticated effects behind a separate broker.
|
|
159
159
|
|
|
160
160
|
## Child workflows
|
|
161
161
|
|
|
162
162
|
`ctx.workflows.ensure()` creates or finds a workflow run by a stable request key and input fingerprint. Repeated reconciliations find the same active or completed request. A changed input must use a new key. An asynchronous child completion validates the reserved request and run IDs through a separate scheduler-completion command; it never reuses the controller claim that launched the child. The controller transaction reserves and saves each attempt's run ID before the scheduler starts it, so recovery can find the run row.
|
|
163
163
|
|
|
164
|
-
A child run
|
|
164
|
+
A child run has one durable execution record. The parent resource points to the current run, and workflow completion enqueues the parent key. The global host runs it through the same queue and supervised worker protocol as other workflows.
|
|
165
165
|
|
|
166
|
-
|
|
166
|
+
A stopped worker does not make the child failed by itself. The host reads the last committed node and effect state. It resumes pure or idempotent work in a new worker epoch. An uncertain manual effect becomes ambiguous and blocks automatic retry. A changed input still requires a new stable request key.
|
|
167
167
|
|
|
168
168
|
## Deletion and cleanup
|
|
169
169
|
|
|
@@ -175,9 +175,9 @@ Controllers should add finalizers only when they own something that needs cleanu
|
|
|
175
175
|
|
|
176
176
|
A source maps an external event to one or more resource keys. Sources include filesystem watches, webhooks, scheduled polling, and child workflow completion. They share the same enqueue API.
|
|
177
177
|
|
|
178
|
-
|
|
178
|
+
The global host claims controller keys and starts a supervised process group for each active reconciliation. A reconciliation deadline stops and requeues the child even when controller code ignores its abort signal. Reconciler code must still pass the signal to provider calls and keep consequential writes inside guarded effect drivers. One host owns the local database. Distributed leader election remains outside this local runtime.
|
|
179
179
|
|
|
180
|
-
The
|
|
180
|
+
The extension starts the package host on demand. Reconciliation continues when the Pi session closes. The package installs no operating-system service.
|
|
181
181
|
|
|
182
182
|
## Observability
|
|
183
183
|
|
|
@@ -202,13 +202,13 @@ A production controller must follow these rules:
|
|
|
202
202
|
|
|
203
203
|
The controller API is exported from `@osolmaz/pi-workflows/controllers`. Controller definitions use a `.controller.ts` suffix. Project definitions live under `.pi/controllers/`; global definitions live under `~/.pi/agent/controllers/`.
|
|
204
204
|
|
|
205
|
-
The implementation uses documented Pi extension APIs only.
|
|
205
|
+
The implementation uses documented Pi extension APIs only. `/controller` lists and inspects resources, applies specs, and requests reconciliation or deletion. There are no extension-local worker start or stop controls.
|
|
206
206
|
|
|
207
|
-
|
|
207
|
+
For `apply`, a source resolver child discovers the named controller, verifies its exported name, computes `initialStatus(spec)`, and hashes the source. The host accepts the proposal only while the path still follows discovery rules and the exact digest still matches. Reconcile code runs only in a supervised controller worker.
|
|
208
208
|
|
|
209
|
-
Controller resources use the canonical [SQLite state](SQLITE_STATE.md) database. `projects` separates repository-local resources by canonical project path. Controller claims use the shared lease generation, token, expiry, and expected resource revision. Effects and child workflows use
|
|
209
|
+
Controller resources use the canonical [SQLite state](SQLITE_STATE.md) database. `projects` separates repository-local resources by canonical project path. Controller claims use the shared lease generation, token, expiry, and expected resource revision. Effects and child workflows use durable request keys and receipts.
|
|
210
210
|
|
|
211
|
-
|
|
211
|
+
One global host owns that database for all Pi sessions and projects. The extension and mutating CLI paths are local protocol clients; viewers remain read-only. A controller child without an origin session uses a headless `pi --mode rpc` process for structured agent steps.
|
|
212
212
|
|
|
213
213
|
Normal workflow prompts, tool calls, and replies remain part of the Pi session. No Pi internal type, private API, or persistent Pi schema changes.
|
|
214
214
|
|
package/docs/DEFERRED_TURNS.md
CHANGED
|
@@ -219,10 +219,21 @@ The fallback custom message uses this details object:
|
|
|
219
219
|
"schema": "pi-workflows.deferred-turn-message.v1",
|
|
220
220
|
"turnIntentId": "deferred-turn:...",
|
|
221
221
|
"runId": "20260821T081731Z-autoimplement-407480dd",
|
|
222
|
-
"cause": "failed"
|
|
222
|
+
"cause": "failed",
|
|
223
|
+
"presentation": {
|
|
224
|
+
"workflowName": "autoimplement",
|
|
225
|
+
"state": "failed",
|
|
226
|
+
"reasonKind": "maxSteps",
|
|
227
|
+
"restart": {
|
|
228
|
+
"count": 0,
|
|
229
|
+
"limit": 3
|
|
230
|
+
}
|
|
231
|
+
}
|
|
223
232
|
}
|
|
224
233
|
```
|
|
225
234
|
|
|
235
|
+
`presentation` contains small, bounded display fields. `reasonKind` and `restart` are present only when the run records provide them. These fields do not replace or shorten the model prompt.
|
|
236
|
+
|
|
226
237
|
The message type is `pi-workflows-deferred-turn`. Delivery uses:
|
|
227
238
|
|
|
228
239
|
```ts
|
|
@@ -232,7 +243,17 @@ The message type is `pi-workflows-deferred-turn`. Delivery uses:
|
|
|
232
243
|
}
|
|
233
244
|
```
|
|
234
245
|
|
|
235
|
-
|
|
246
|
+
### Compact TUI card
|
|
247
|
+
|
|
248
|
+
Interactive Pi registers a custom renderer for `pi-workflows-deferred-turn`. The collapsed card shows the workflow name, state or cause, run identity, and restart count when it is available. It does not show the terminal facts JSON, exact input, result, fingerprint, or model instructions.
|
|
249
|
+
|
|
250
|
+
The renderer reads only the structured message details for its compact fields. It sanitizes workflow-derived text and uses Pi's standard TUI components, theme colors, and `expanded` state. A message with missing or invalid details renders as a safe generic workflow card.
|
|
251
|
+
|
|
252
|
+
Expanding the card shows the complete existing message content. The model and session history receive that same content whether the card is collapsed or expanded. Restored messages use the same renderer and do not create another entry or model turn.
|
|
253
|
+
|
|
254
|
+
This display behavior uses the documented `pi.sendMessage()` and `pi.registerMessageRenderer()` APIs. It does not change headless or RPC delivery. Presentation messages that already use `display: false` stay hidden. It adds no Pi core change, private API, database table, migration, store, or external resource.
|
|
255
|
+
|
|
256
|
+
For a terminal run, the complete content contains the workflow identity and revision, terminal run ID, exact stored input, bounded result, terminal state and reason, restart count, and earlier terminal outcomes in the chain. It tells the model to use the current conversation, prefer a safe restart for an unfinished task after a technical or temporary failure, and stop for completed work, cancellation, missing authority, a required user decision, or a repeated failure. Values from input and result are data, not instructions.
|
|
236
257
|
|
|
237
258
|
The content comes only from existing run and queue records. Pi owns conversation history. Pi Workflows does not identify, hash, copy, or store an original user message.
|
|
238
259
|
|
package/docs/SQLITE_STATE.md
CHANGED
|
@@ -8,11 +8,25 @@ Pi Workflows stores all live durable state in one database:
|
|
|
8
8
|
|
|
9
9
|
There is one database for the user installation. Project and run IDs separate data inside it. Workflow targets do not read or write this database.
|
|
10
10
|
|
|
11
|
+
## Viewer projection
|
|
12
|
+
|
|
13
|
+
The database includes the [incremental and virtualized viewer design](plans/2026-08-28-piw-incremental-viewer-plan.md).
|
|
14
|
+
|
|
15
|
+
`viewer_runs` stores one presentation revision and retained revision floor for each run. `viewer_deltas` stores ordered target patches by run, presentation revision, and delta index. `viewer_session_checkpoints` stores the bounded active message and tool state at each 256-event boundary. A viewer-visible transaction writes the domain change, advances the presentation revision, and writes its patch blobs before the same commit. Session-event transactions write each reached replay checkpoint in that transaction.
|
|
16
|
+
|
|
17
|
+
The store retains 256 presentation revisions. A reader with an older cursor must take a bounded snapshot. Patches use `add`, `replace`, `remove`, and `append`. They target small projection documents or pages. Patch creation does not reconstruct and compare complete run views.
|
|
18
|
+
|
|
19
|
+
`session_entries` and `session_events` have run-wide sequence numbers and indexed `(run_id, run_seq)` ranges. Step, trace, entry, and event reads contain at most 256 rows. Run-list queries read metadata, status, lease facts, and the presentation revision. They do not read payload bodies.
|
|
20
|
+
|
|
21
|
+
This is an in-place alpha schema change. The schema name and version remain `pi-workflows-state` version 1. The DDL digest and exact shape changed. An older alpha database fails with the standard reset instruction and remains untouched. There is no compatibility reader, migration shim, dual path, feature flag, alias, or `v2` schema.
|
|
22
|
+
|
|
11
23
|
## Storage boundary
|
|
12
24
|
|
|
13
25
|
The database stores:
|
|
14
26
|
|
|
15
27
|
- workflow definitions, runs, events, node attempts, outputs, and updates
|
|
28
|
+
- global host epochs, command receipts, worker epochs, and worker messages
|
|
29
|
+
- durable origin-session interaction requests and submissions
|
|
16
30
|
- captured Pi session entries and events
|
|
17
31
|
- run and controller queues, claims, retries, and continuations
|
|
18
32
|
- human-decision requests, submissions, resolutions, and cancellations
|
|
@@ -98,7 +112,8 @@ The shared records do not replace domain schemas. The following `STRICT` tables
|
|
|
98
112
|
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
|
99
113
|
| Schema and projects | `schema_meta`, `projects` |
|
|
100
114
|
| Content | `blobs` |
|
|
101
|
-
| Shared lifecycle | `resources`, `leases`, `events`
|
|
115
|
+
| Shared lifecycle | `resources`, `leases`, `events`, `workflow_host_state` |
|
|
116
|
+
| Host protocol | `host_commands`, `run_workers`, `worker_messages`, `interactive_requests`, `interactive_submissions` |
|
|
102
117
|
| Workflows | `workflow_definitions`, `runs`, `run_sources`, `run_steps`, `run_bindings`, `run_queue`, `node_attempts`, `workflow_updates` |
|
|
103
118
|
| Live settings | `workflow_settings`, `workflow_setting_changes` |
|
|
104
119
|
| Post-run follow-ups | `workflow_follow_up_queues`, `workflow_follow_ups` |
|
|
@@ -111,29 +126,23 @@ The shared records do not replace domain schemas. The following `STRICT` tables
|
|
|
111
126
|
|
|
112
127
|
Foreign keys join projects, runs, attempts, decisions, controllers, effects, and channel records. Partial unique indexes enforce one active node attempt per run, one queued or running reservation per Pi session, one decision winner, and one deterministic effect key. A parked waiting parent does not block its continuation. Reserving that continuation settles the parked parent queue in the same transaction, so a failed reservation leaves the parent recoverable.
|
|
113
128
|
|
|
114
|
-
###
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
Restart creates a new run. The terminal run remains unchanged. Restart lineage
|
|
133
|
-
allows three restarts after the original run and rejects a repeated terminal
|
|
134
|
-
fingerprint in the same chain. A Monitor selection records terminal selection
|
|
135
|
-
but no restart lineage. Conversation history remains in Pi. This state does not
|
|
136
|
-
identify, hash, copy, or store an original user message.
|
|
129
|
+
### Hosted commands and interactions
|
|
130
|
+
|
|
131
|
+
`workflow_host_state` stores the one current host epoch and its live local
|
|
132
|
+
claim. `host_commands` stores each client request fingerprint, operation,
|
|
133
|
+
outcome, revision, and receipt or error. Repeating an exact request adopts the
|
|
134
|
+
stored receipt. Reusing an ID or idempotency key for another request is a
|
|
135
|
+
conflict.
|
|
136
|
+
|
|
137
|
+
`run_workers` records each worker epoch before spawn and later records its exact
|
|
138
|
+
process identity and terminal outcome. `worker_messages` deduplicates accepted
|
|
139
|
+
state-changing child messages.
|
|
140
|
+
|
|
141
|
+
`interactive_requests` owns durable origin-session work. It stores the run,
|
|
142
|
+
node attempt, target session, contract, presentation claim, accepted
|
|
143
|
+
submission, and revision. `interactive_submissions` stores the idempotency key,
|
|
144
|
+
payload, outcome, and receipt. Pi reload can adopt the saved presentation entry
|
|
145
|
+
without inserting another visible message.
|
|
137
146
|
|
|
138
147
|
## Content-addressed values
|
|
139
148
|
|
|
@@ -149,9 +158,9 @@ Readers derive `steps`, `outputs`, `results`, carried-step count, current-node f
|
|
|
149
158
|
|
|
150
159
|
An agent definition records `expectedOutput` as either a submitted-output description or `{ "kind": "assistant-message", "maxChars"?: number }`. Omitted `maxChars` means that Pi Workflows adds no character limit.
|
|
151
160
|
|
|
152
|
-
A completed interactive assistant-message attempt
|
|
161
|
+
A completed interactive assistant-message attempt stores the accepted visible text as its node output. Its small receipt keeps the text digest, final Pi session entry ID, optional author-supplied limit, and whether recovery adopted an existing response.
|
|
153
162
|
|
|
154
|
-
An interrupted assistant-message attempt keeps its attempt ID
|
|
163
|
+
An interrupted assistant-message attempt keeps its attempt ID. The extension adopts a matching durable request and existing Pi branch entry instead of displaying the prompt or accepting the response twice. Submitted and non-agent attempts use a fresh execution attempt after an uncommitted worker exit.
|
|
155
164
|
|
|
156
165
|
## Write contract
|
|
157
166
|
|
|
@@ -163,6 +172,7 @@ verify the exact schema
|
|
|
163
172
|
verify the actor and operation
|
|
164
173
|
verify the expected resource revision
|
|
165
174
|
verify the claim token, generation, and expiry when ownership is required
|
|
175
|
+
renew that exact still-live token and generation
|
|
166
176
|
verify the domain transition
|
|
167
177
|
write content-addressed values
|
|
168
178
|
increment the resource revision
|
|
@@ -189,7 +199,7 @@ Reading or finding a row never gives write authority.
|
|
|
189
199
|
- Control commands have narrow explicit operations, such as requesting cancellation or deletion.
|
|
190
200
|
- Model-originated workflow answers cannot resolve protected human decisions.
|
|
191
201
|
|
|
192
|
-
|
|
202
|
+
The global host is the normal state writer. Its protected stores check ownership and renew the exact live claim in the same transaction as the write. A stale or expired owner cannot renew itself. Pi extensions and mutating CLI commands use the local host protocol. Shared scans, status commands, lists, viewers, and the Rust `piw` program are read-only.
|
|
193
203
|
|
|
194
204
|
## Competing outcomes
|
|
195
205
|
|
|
@@ -209,9 +219,9 @@ Status is a pure projection of domain rows, immutable facts, current leases, and
|
|
|
209
219
|
|
|
210
220
|
A settings scope uses its resource revision as its public change number. Each accepted patch, current value, and node binding is saved in one transaction. A checkpoint continuation keeps the same settings resources and transfers them to the continuation run.
|
|
211
221
|
|
|
212
|
-
A follow-up queue records acceptance order and
|
|
222
|
+
A follow-up queue records acceptance order and settlement state. Failure, timeout, and cancellation cancel unsent items.
|
|
213
223
|
|
|
214
|
-
- A terminal run fact overrides stale
|
|
224
|
+
- A terminal run fact overrides stale delivery state.
|
|
215
225
|
- An accepted decision is accepted even if its continuation effect is still pending.
|
|
216
226
|
- A cancelled decision is cancelled even if parent cleanup is still pending.
|
|
217
227
|
- A stale owner is not shown as current.
|
|
@@ -221,7 +231,7 @@ Read paths do not repair state. Owner reconcilers apply pending effects and writ
|
|
|
221
231
|
|
|
222
232
|
## Projects and concurrency
|
|
223
233
|
|
|
224
|
-
All projects use the same file. `projects` stores a stable ID and canonical path. Project-scoped controller and run queries use that key.
|
|
234
|
+
All projects use the same file. `projects` stores a stable ID and canonical path. Project-scoped controller and run queries use that key. One global host owns the file for the user installation. Its socket, lock, and exact child-process registry are under `~/.pi/agent/workflows/host/`. A second live host is rejected even when it was started from another project.
|
|
225
235
|
|
|
226
236
|
SQLite WAL permits concurrent readers while one writer commits. Writers are serialized by SQLite and must keep transactions short. Hashing, model calls, shell work, and external requests happen outside write transactions.
|
|
227
237
|
|
|
@@ -259,4 +269,4 @@ It does not print actor IDs, channel references, payloads, or credentials.
|
|
|
259
269
|
|
|
260
270
|
This is a hard cut. Pi Workflows has no normal reader or writer for older live storage. It does not use dual reads, dual writes, aliases, versioned state roots, or automatic import.
|
|
261
271
|
|
|
262
|
-
Older state remains untouched.
|
|
272
|
+
Older state remains untouched. Pi Workflows fails before mutation with this instruction: “Pi Workflows durable state is incompatible. Back up and move state.sqlite with its -wal and -shm files, then start Pi Workflows to create a new state.sqlite database. The incompatible state was not changed.”
|