@osolmaz/pi-workflows 0.16.1 → 0.16.3
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 +41 -41
- package/dist/builtins/monitor.workflow.d.ts +1 -1
- package/dist/builtins/monitor.workflow.js +8 -8
- package/dist/builtins/pi-agent-group.js +3 -3
- package/dist/builtins/pi-agent-group.js.map +1 -1
- package/dist/channels/adapter-entry.js +14 -14
- package/dist/channels/adapter-entry.js.map +1 -1
- package/dist/client/client.d.ts +6 -6
- package/dist/client/client.js +27 -27
- package/dist/client/client.js.map +1 -1
- package/dist/client/protocol.d.ts +4 -1
- package/dist/client/protocol.js +17 -11
- package/dist/client/protocol.js.map +1 -1
- package/dist/client/resolver.d.ts +4 -4
- package/dist/client/view.d.ts +7 -1
- package/dist/client/view.js +1 -0
- package/dist/client/view.js.map +1 -1
- package/dist/extension/index.d.ts +1 -1
- package/dist/extension/index.js +66 -47
- package/dist/extension/index.js.map +1 -1
- package/dist/extension/recorder.d.ts +1 -1
- package/dist/extension/recorder.js +1 -1
- package/dist/extension/recorder.js.map +1 -1
- package/dist/extension/remote-recorder-store.d.ts +1 -1
- package/dist/extension/remote-recorder-store.js +2 -2
- package/dist/extension/remote-recorder-store.js.map +1 -1
- package/dist/extension/{controller-command.d.ts → resource-manager-command.d.ts} +6 -6
- package/dist/extension/{controller-command.js → resource-manager-command.js} +7 -7
- package/dist/extension/resource-manager-command.js.map +1 -0
- package/dist/extension/session-delivery.d.ts +1 -1
- package/dist/extension/session-delivery.js +2 -2
- package/dist/extension/session-delivery.js.map +1 -1
- package/dist/extension/session-view.d.ts +1 -1
- package/dist/extension/session-view.js +1 -1
- package/dist/extension/session-view.js.map +1 -1
- package/dist/extension/workflow-message-coordinator.d.ts +4 -3
- package/dist/extension/workflow-message-coordinator.js +81 -29
- package/dist/extension/workflow-message-coordinator.js.map +1 -1
- package/dist/resource-managers/conditions.d.ts +6 -0
- package/dist/{controllers → resource-managers}/conditions.js +3 -3
- package/dist/resource-managers/conditions.js.map +1 -0
- package/dist/resource-managers/definition.d.ts +6 -0
- package/dist/resource-managers/definition.js +45 -0
- package/dist/resource-managers/definition.js.map +1 -0
- package/dist/resource-managers/effects.d.ts +15 -0
- package/dist/{controllers → resource-managers}/effects.js +2 -2
- package/dist/resource-managers/effects.js.map +1 -0
- package/dist/resource-managers/errors.d.ts +12 -0
- package/dist/resource-managers/errors.js +25 -0
- package/dist/resource-managers/errors.js.map +1 -0
- package/dist/resource-managers/index.d.ts +12 -0
- package/dist/resource-managers/index.js +12 -0
- package/dist/resource-managers/index.js.map +1 -0
- package/dist/resource-managers/json.js.map +1 -0
- package/dist/resource-managers/loader.d.ts +23 -0
- package/dist/resource-managers/loader.js +75 -0
- package/dist/resource-managers/loader.js.map +1 -0
- package/dist/resource-managers/results.d.ts +5 -0
- package/dist/resource-managers/results.js.map +1 -0
- package/dist/resource-managers/runtime.d.ts +59 -0
- package/dist/{controllers/manager.js → resource-managers/runtime.js} +57 -57
- package/dist/resource-managers/runtime.js.map +1 -0
- package/dist/{controllers → resource-managers}/sqlite.d.ts +51 -43
- package/dist/{controllers → resource-managers}/sqlite.js +187 -125
- package/dist/resource-managers/sqlite.js.map +1 -0
- package/dist/{controllers → resource-managers}/store.d.ts +33 -33
- package/dist/{controllers → resource-managers}/store.js.map +1 -1
- package/dist/{controllers → resource-managers}/types.d.ts +41 -41
- package/dist/{controllers → resource-managers}/types.js.map +1 -1
- package/dist/resource-managers/workflows.d.ts +34 -0
- package/dist/{controllers → resource-managers}/workflows.js +15 -15
- package/dist/resource-managers/workflows.js.map +1 -0
- package/dist/server/channel-effects.js.map +1 -0
- package/dist/{host → server}/channel-supervisor.d.ts +6 -6
- package/dist/{host → server}/channel-supervisor.js +3 -3
- package/dist/server/channel-supervisor.js.map +1 -0
- package/dist/{host/child-worker-supervisor.d.ts → server/child-runner-supervisor.d.ts} +15 -13
- package/dist/{host/child-worker-supervisor.js → server/child-runner-supervisor.js} +6 -5
- package/dist/server/child-runner-supervisor.js.map +1 -0
- package/dist/{host → server}/processes.d.ts +3 -3
- package/dist/{host → server}/processes.js +3 -3
- package/dist/server/processes.js.map +1 -0
- package/dist/{host → server}/resolver-entry.d.ts +6 -6
- package/dist/{host → server}/resolver-entry.js +14 -14
- package/dist/server/resolver-entry.js.map +1 -0
- package/dist/server/resource-runner-entry.d.ts +2 -0
- package/dist/{host/controller-worker-entry.js → server/resource-runner-entry.js} +33 -33
- package/dist/server/resource-runner-entry.js.map +1 -0
- package/dist/server/resource-runner-protocol.d.ts +36 -0
- package/dist/server/resource-runner-protocol.js +49 -0
- package/dist/server/resource-runner-protocol.js.map +1 -0
- package/dist/server/resource-runner-supervisor.d.ts +21 -0
- package/dist/{host/worker-supervisor.js → server/resource-runner-supervisor.js} +17 -17
- package/dist/server/resource-runner-supervisor.js.map +1 -0
- package/dist/{host → server}/rpc-bridge.d.ts +3 -3
- package/dist/{host → server}/rpc-bridge.js +3 -3
- package/dist/server/rpc-bridge.js.map +1 -0
- package/dist/{host → server}/rpc-executor.d.ts +1 -1
- package/dist/{host → server}/rpc-executor.js +3 -3
- package/dist/server/rpc-executor.js.map +1 -0
- package/dist/{host/host-entry.js → server/server-entry.js} +6 -6
- package/dist/server/server-entry.js.map +1 -0
- package/dist/{host/runner.d.ts → server/server.d.ts} +47 -39
- package/dist/{host/runner.js → server/server.js} +624 -535
- package/dist/server/server.js.map +1 -0
- package/dist/{host → server}/state.d.ts +25 -25
- package/dist/{host → server}/state.js +49 -49
- package/dist/server/state.js.map +1 -0
- package/dist/{host → server}/view.d.ts +7 -7
- package/dist/{host → server}/view.js +19 -15
- package/dist/server/view.js.map +1 -0
- package/dist/server/workflow-runner-content.d.ts +6 -0
- package/dist/server/workflow-runner-content.js +96 -0
- package/dist/server/workflow-runner-content.js.map +1 -0
- package/dist/server/workflow-runner-entry.d.ts +13 -0
- package/dist/{host/worker-entry.js → server/workflow-runner-entry.js} +89 -57
- package/dist/server/workflow-runner-entry.js.map +1 -0
- package/dist/server/workflow-runner-protocol.d.ts +69 -0
- package/dist/server/workflow-runner-protocol.js +176 -0
- package/dist/server/workflow-runner-protocol.js.map +1 -0
- package/dist/{host/worker-store.d.ts → server/workflow-runner-store.d.ts} +11 -11
- package/dist/{host/worker-store.js → server/workflow-runner-store.js} +8 -8
- package/dist/server/workflow-runner-store.js.map +1 -0
- package/dist/server/workflow-runner-supervisor.d.ts +22 -0
- package/dist/server/workflow-runner-supervisor.js +56 -0
- package/dist/server/workflow-runner-supervisor.js.map +1 -0
- package/dist/state/prune.d.ts +1 -1
- package/dist/state/prune.js +17 -10
- package/dist/state/prune.js.map +1 -1
- package/dist/state/schema.js +2 -2
- package/dist/state/workflow-messages.d.ts +3 -1
- package/dist/state/workflow-messages.js +32 -1
- package/dist/state/workflow-messages.js.map +1 -1
- package/dist/viewer/backup.js +1 -1
- package/dist/viewer/backup.js.map +1 -1
- package/dist/viewer/cli.d.ts +2 -2
- package/dist/viewer/cli.js +46 -32
- package/dist/viewer/cli.js.map +1 -1
- package/dist/viewer/tui.d.ts +1 -1
- package/dist/viewer/tui.js +1 -1
- package/dist/viewer/tui.js.map +1 -1
- package/dist/workflows/command-batch.js +2 -2
- package/dist/workflows/composition.js +0 -4
- package/dist/workflows/composition.js.map +1 -1
- package/dist/workflows/definition.js +0 -8
- package/dist/workflows/definition.js.map +1 -1
- package/dist/workflows/engine.js +18 -20
- package/dist/workflows/engine.js.map +1 -1
- package/dist/workflows/schema.js +0 -4
- package/dist/workflows/schema.js.map +1 -1
- package/dist/workflows/store.d.ts +27 -11
- package/dist/workflows/store.js +66 -18
- package/dist/workflows/store.js.map +1 -1
- package/dist/workflows/types.d.ts +3 -5
- package/docs/2026-08-20-durable-workflow-launch-plan.md +12 -12
- package/docs/2026-08-25-workflow-follow-ups.md +7 -7
- package/docs/2026-08-25-workflow-settings.md +3 -3
- package/docs/2026-08-30-out-of-process-workflow-host-plan.md +3 -3
- package/docs/2026-09-01-restore-session-delivery-controls-plan.md +5 -5
- package/docs/2026-09-01-unified-workflow-client-plan.md +6 -6
- package/docs/2026-09-02-installed-live-e2e-plan.md +3 -3
- package/docs/2026-09-02-unify-workflow-messages-plan.md +8 -8
- package/docs/2026-09-04-workflow-run-state-plan.md +363 -0
- package/docs/DEFERRED_TURNS.md +7 -7
- package/docs/DESIGN_PHILOSOPHY.md +1 -1
- package/docs/HUMAN_DECISIONS.md +11 -11
- package/docs/HUMAN_DECISION_PRESENTATIONS.md +4 -4
- package/docs/MONITOR.md +1 -1
- package/docs/RESOURCE_MANAGERS.md +221 -0
- package/docs/SQLITE_STATE.md +40 -34
- package/docs/WORKFLOW_COMPOSITION.md +1 -1
- package/docs/{WORKFLOW_HOST.md → WORKFLOW_SERVER.md} +131 -116
- package/docs/WORKFLOW_STEP_MESSAGES.md +18 -18
- package/docs/WORKFLOW_UPDATES.md +16 -16
- package/docs/development.md +15 -14
- package/docs/live-replay-protocol.md +20 -20
- package/docs/plans/2026-08-04-controller-runtime-plan.md +25 -25
- package/docs/plans/2026-08-05-always-on-workflows-plan.md +8 -8
- package/docs/plans/2026-08-10-agent-managed-monitor-workflows-plan.md +2 -2
- package/docs/plans/2026-08-13-session-addressed-workflow-notifications-plan.md +1 -1
- package/docs/plans/2026-08-16-workflow-updates-plan.md +5 -5
- package/docs/plans/2026-08-19-human-decision-gates-plan.md +1 -1
- package/docs/plans/2026-08-20-bounded-command-batches-plan.md +1 -1
- package/docs/plans/2026-08-21-deferred-turn-intents-plan.md +3 -3
- package/docs/plans/2026-08-21-sanity-check-plan.md +2 -2
- package/docs/plans/2026-08-23-assistant-agent-completion-plan.md +5 -5
- package/docs/plans/2026-08-23-sqlite-state-plan.md +25 -25
- package/docs/plans/2026-08-25-live-workflow-settings-plan.md +4 -4
- package/docs/plans/2026-08-27-workflow-terminal-restart-plan.md +3 -3
- package/docs/plans/2026-09-04-workflow-runner-resume-state-plan.md +318 -0
- package/docs/plans/piw-viewer-experience-implementation-plan.md +1 -1
- package/docs/tui-viewer.md +9 -9
- package/docs/workflows.md +78 -63
- package/examples/{controllers/pull-request.controller.ts → resource-managers/pull-request.resource-manager.ts} +12 -12
- package/herdr-plugin.toml +1 -1
- package/package.json +5 -5
- package/protocol/client.v1.schema.json +7 -7
- package/protocol/fixtures/client-v1.json +1 -1
- package/src/builtins/monitor.workflow.ts +9 -9
- package/src/builtins/pi-agent-group.ts +3 -3
- package/src/channels/adapter-entry.ts +14 -14
- package/src/client/client.ts +33 -32
- package/src/client/protocol.ts +16 -11
- package/src/client/resolver.ts +4 -4
- package/src/client/view.ts +9 -1
- package/src/extension/index.ts +81 -53
- package/src/extension/recorder.ts +1 -1
- package/src/extension/remote-recorder-store.ts +2 -2
- package/src/extension/resource-manager-command.ts +45 -0
- package/src/extension/session-delivery.ts +2 -2
- package/src/extension/session-view.ts +1 -1
- package/src/extension/workflow-message-coordinator.ts +94 -30
- package/src/{controllers → resource-managers}/conditions.ts +23 -23
- package/src/resource-managers/definition.ts +71 -0
- package/src/{controllers → resource-managers}/effects.ts +9 -9
- package/src/resource-managers/errors.ts +27 -0
- package/src/resource-managers/index.ts +88 -0
- package/src/resource-managers/loader.ts +111 -0
- package/src/{controllers → resource-managers}/results.ts +4 -4
- package/src/{controllers/manager.ts → resource-managers/runtime.ts} +95 -92
- package/src/{controllers → resource-managers}/sqlite.ts +275 -181
- package/src/{controllers → resource-managers}/store.ts +46 -38
- package/src/{controllers → resource-managers}/types.ts +50 -41
- package/src/{controllers → resource-managers}/workflows.ts +43 -41
- package/src/{host → server}/channel-supervisor.ts +8 -8
- package/src/{host/child-worker-supervisor.ts → server/child-runner-supervisor.ts} +22 -18
- package/src/{host → server}/processes.ts +3 -3
- package/src/{host → server}/resolver-entry.ts +28 -25
- package/src/{host/controller-worker-entry.ts → server/resource-runner-entry.ts} +67 -65
- package/src/server/resource-runner-protocol.ts +103 -0
- package/src/server/resource-runner-supervisor.ts +76 -0
- package/src/{host → server}/rpc-bridge.ts +3 -3
- package/src/{host → server}/rpc-executor.ts +4 -4
- package/src/{host/host-entry.ts → server/server-entry.ts} +5 -5
- package/src/{host/runner.ts → server/server.ts} +786 -672
- package/src/{host → server}/state.ts +78 -67
- package/src/{host → server}/view.ts +21 -17
- package/src/server/workflow-runner-content.ts +119 -0
- package/src/{host/worker-entry.ts → server/workflow-runner-entry.ts} +131 -82
- package/src/server/workflow-runner-protocol.ts +241 -0
- package/src/{host/worker-store.ts → server/workflow-runner-store.ts} +18 -20
- package/src/server/workflow-runner-supervisor.ts +79 -0
- package/src/state/prune.ts +27 -9
- package/src/state/schema.ts +2 -2
- package/src/state/workflow-messages.ts +52 -1
- package/src/viewer/backup.ts +1 -1
- package/src/viewer/cli.ts +50 -36
- package/src/viewer/tui.ts +1 -1
- package/src/workflows/command-batch.ts +2 -2
- package/src/workflows/composition.ts +0 -5
- package/src/workflows/definition.ts +0 -8
- package/src/workflows/engine.ts +18 -21
- package/src/workflows/schema.ts +0 -6
- package/src/workflows/store.ts +95 -28
- package/src/workflows/types.ts +3 -5
- package/dist/controllers/conditions.d.ts +0 -6
- package/dist/controllers/conditions.js.map +0 -1
- package/dist/controllers/definition.d.ts +0 -6
- package/dist/controllers/definition.js +0 -45
- package/dist/controllers/definition.js.map +0 -1
- package/dist/controllers/effects.d.ts +0 -15
- package/dist/controllers/effects.js.map +0 -1
- package/dist/controllers/errors.d.ts +0 -12
- package/dist/controllers/errors.js +0 -25
- package/dist/controllers/errors.js.map +0 -1
- package/dist/controllers/index.d.ts +0 -12
- package/dist/controllers/index.js +0 -12
- package/dist/controllers/index.js.map +0 -1
- package/dist/controllers/json.js.map +0 -1
- package/dist/controllers/loader.d.ts +0 -23
- package/dist/controllers/loader.js +0 -74
- package/dist/controllers/loader.js.map +0 -1
- package/dist/controllers/manager.d.ts +0 -59
- package/dist/controllers/manager.js.map +0 -1
- package/dist/controllers/results.d.ts +0 -5
- package/dist/controllers/results.js.map +0 -1
- package/dist/controllers/sqlite.js.map +0 -1
- package/dist/controllers/workflows.d.ts +0 -34
- package/dist/controllers/workflows.js.map +0 -1
- package/dist/extension/controller-command.js.map +0 -1
- package/dist/host/channel-effects.js.map +0 -1
- package/dist/host/channel-supervisor.js.map +0 -1
- package/dist/host/child-worker-supervisor.js.map +0 -1
- package/dist/host/controller-worker-entry.d.ts +0 -2
- package/dist/host/controller-worker-entry.js.map +0 -1
- package/dist/host/controller-worker-protocol.d.ts +0 -36
- package/dist/host/controller-worker-protocol.js +0 -49
- package/dist/host/controller-worker-protocol.js.map +0 -1
- package/dist/host/controller-worker-supervisor.d.ts +0 -21
- package/dist/host/controller-worker-supervisor.js +0 -54
- package/dist/host/controller-worker-supervisor.js.map +0 -1
- package/dist/host/host-entry.js.map +0 -1
- package/dist/host/processes.js.map +0 -1
- package/dist/host/resolver-entry.js.map +0 -1
- package/dist/host/rpc-bridge.js.map +0 -1
- package/dist/host/rpc-executor.js.map +0 -1
- package/dist/host/runner.js.map +0 -1
- package/dist/host/state.js.map +0 -1
- package/dist/host/view.js.map +0 -1
- package/dist/host/worker-entry.d.ts +0 -10
- package/dist/host/worker-entry.js.map +0 -1
- package/dist/host/worker-protocol.d.ts +0 -31
- package/dist/host/worker-protocol.js +0 -122
- package/dist/host/worker-protocol.js.map +0 -1
- package/dist/host/worker-store.js.map +0 -1
- package/dist/host/worker-supervisor.d.ts +0 -22
- package/dist/host/worker-supervisor.js.map +0 -1
- package/docs/CONTROLLERS.md +0 -217
- package/src/controllers/definition.ts +0 -65
- package/src/controllers/errors.ts +0 -27
- package/src/controllers/index.ts +0 -88
- package/src/controllers/loader.ts +0 -104
- package/src/extension/controller-command.ts +0 -45
- package/src/host/controller-worker-protocol.ts +0 -104
- package/src/host/controller-worker-supervisor.ts +0 -79
- package/src/host/worker-protocol.ts +0 -165
- package/src/host/worker-supervisor.ts +0 -74
- /package/dist/{controllers → resource-managers}/json.d.ts +0 -0
- /package/dist/{controllers → resource-managers}/json.js +0 -0
- /package/dist/{controllers → resource-managers}/results.js +0 -0
- /package/dist/{controllers → resource-managers}/store.js +0 -0
- /package/dist/{controllers → resource-managers}/types.js +0 -0
- /package/dist/{host → server}/channel-effects.d.ts +0 -0
- /package/dist/{host → server}/channel-effects.js +0 -0
- /package/dist/{host/host-entry.d.ts → server/server-entry.d.ts} +0 -0
- /package/src/{controllers → resource-managers}/json.ts +0 -0
- /package/src/{host → server}/channel-effects.ts +0 -0
|
@@ -20,7 +20,7 @@ type ChannelAdapterReport = ChannelAdapterMessage extends infer Message
|
|
|
20
20
|
: never
|
|
21
21
|
: never;
|
|
22
22
|
|
|
23
|
-
class
|
|
23
|
+
class AdapterServerConnection {
|
|
24
24
|
private sequence = 0;
|
|
25
25
|
private revision = 0;
|
|
26
26
|
private readonly lines = createInterface({ input: process.stdin, crlfDelay: Infinity })[
|
|
@@ -43,13 +43,13 @@ class AdapterHostConnection {
|
|
|
43
43
|
await new Promise<void>((resolve) => process.stdout.once("drain", resolve));
|
|
44
44
|
}
|
|
45
45
|
const next = await this.lines.next();
|
|
46
|
-
if (next.done) throw new Error("Workflow
|
|
46
|
+
if (next.done) throw new Error("Workflow server closed the channel adapter connection");
|
|
47
47
|
const response = parseChannelAdapterResponse(Buffer.from(next.value, "utf8"));
|
|
48
48
|
if (response.sequence !== this.sequence) {
|
|
49
|
-
throw new Error("Workflow
|
|
49
|
+
throw new Error("Workflow server returned a mismatched channel response");
|
|
50
50
|
}
|
|
51
51
|
if (response.outcome !== "accepted") {
|
|
52
|
-
throw new Error(response.error ?? "Workflow
|
|
52
|
+
throw new Error(response.error ?? "Workflow server rejected the channel adapter message");
|
|
53
53
|
}
|
|
54
54
|
this.revision = response.revision;
|
|
55
55
|
return response;
|
|
@@ -58,7 +58,7 @@ class AdapterHostConnection {
|
|
|
58
58
|
|
|
59
59
|
export async function runChannelAdapter(): Promise<number> {
|
|
60
60
|
const launch = readLaunch();
|
|
61
|
-
const
|
|
61
|
+
const server = new AdapterServerConnection(launch);
|
|
62
62
|
const telegram = new TelegramAdapter({
|
|
63
63
|
profile: launch.profile,
|
|
64
64
|
token: launch.token,
|
|
@@ -85,7 +85,7 @@ export async function runChannelAdapter(): Promise<number> {
|
|
|
85
85
|
stopping = true;
|
|
86
86
|
});
|
|
87
87
|
|
|
88
|
-
let response = await
|
|
88
|
+
let response = await server.report({
|
|
89
89
|
kind: "channel.ready",
|
|
90
90
|
stableMessageId: controlId("ready"),
|
|
91
91
|
cursor,
|
|
@@ -94,7 +94,7 @@ export async function runChannelAdapter(): Promise<number> {
|
|
|
94
94
|
const command = response.command;
|
|
95
95
|
if (command === null) {
|
|
96
96
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
97
|
-
response = await
|
|
97
|
+
response = await server.report({
|
|
98
98
|
kind: "channel.ready",
|
|
99
99
|
stableMessageId: controlId("ready"),
|
|
100
100
|
cursor,
|
|
@@ -108,7 +108,7 @@ export async function runChannelAdapter(): Promise<number> {
|
|
|
108
108
|
if (command.kind === "channel.present") {
|
|
109
109
|
try {
|
|
110
110
|
const messages = await telegram.present(command.request);
|
|
111
|
-
response = await
|
|
111
|
+
response = await server.report({
|
|
112
112
|
kind: "channel.present",
|
|
113
113
|
stableMessageId: command.stableMessageId,
|
|
114
114
|
decisionId: command.request.decisionId,
|
|
@@ -118,7 +118,7 @@ export async function runChannelAdapter(): Promise<number> {
|
|
|
118
118
|
messages,
|
|
119
119
|
});
|
|
120
120
|
} catch (error) {
|
|
121
|
-
response = await
|
|
121
|
+
response = await server.report({
|
|
122
122
|
kind: "channel.present",
|
|
123
123
|
stableMessageId: command.stableMessageId,
|
|
124
124
|
decisionId: command.request.decisionId,
|
|
@@ -134,7 +134,7 @@ export async function runChannelAdapter(): Promise<number> {
|
|
|
134
134
|
if (command.kind === "channel.settle") {
|
|
135
135
|
try {
|
|
136
136
|
await telegram.settle(command.outcome, command.response, command.messages);
|
|
137
|
-
response = await
|
|
137
|
+
response = await server.report({
|
|
138
138
|
kind: "channel.settle",
|
|
139
139
|
stableMessageId: command.stableMessageId,
|
|
140
140
|
decisionId: command.request.decisionId,
|
|
@@ -143,7 +143,7 @@ export async function runChannelAdapter(): Promise<number> {
|
|
|
143
143
|
state: "confirmed",
|
|
144
144
|
});
|
|
145
145
|
} catch (error) {
|
|
146
|
-
response = await
|
|
146
|
+
response = await server.report({
|
|
147
147
|
kind: "channel.settle",
|
|
148
148
|
stableMessageId: command.stableMessageId,
|
|
149
149
|
decisionId: command.request.decisionId,
|
|
@@ -160,7 +160,7 @@ export async function runChannelAdapter(): Promise<number> {
|
|
|
160
160
|
const polled = await telegram.poll(command.cursor);
|
|
161
161
|
cursor = polled.cursor;
|
|
162
162
|
for (const answer of polled.answers) {
|
|
163
|
-
await
|
|
163
|
+
await server.report({
|
|
164
164
|
kind: "channel.answer",
|
|
165
165
|
stableMessageId: channelStableMessageId([
|
|
166
166
|
launch.profile,
|
|
@@ -177,14 +177,14 @@ export async function runChannelAdapter(): Promise<number> {
|
|
|
177
177
|
cursor,
|
|
178
178
|
});
|
|
179
179
|
}
|
|
180
|
-
response = await
|
|
180
|
+
response = await server.report({
|
|
181
181
|
kind: "channel.ready",
|
|
182
182
|
stableMessageId: controlId("ready"),
|
|
183
183
|
cursor,
|
|
184
184
|
});
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
-
await
|
|
187
|
+
await server.report({
|
|
188
188
|
kind: "channel.exiting",
|
|
189
189
|
stableMessageId: controlId("exiting"),
|
|
190
190
|
cursor,
|
package/src/client/client.ts
CHANGED
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
type ClientResponse,
|
|
21
21
|
} from "./protocol.js";
|
|
22
22
|
import type {
|
|
23
|
-
|
|
23
|
+
ResolvedResourceManagerInitialization,
|
|
24
24
|
ResolvedSettingsChange,
|
|
25
25
|
ResolvedWorkflowLaunch,
|
|
26
26
|
} from "./resolver.js";
|
|
@@ -55,7 +55,7 @@ export class WorkflowClientVersionError extends Error {
|
|
|
55
55
|
export type WorkflowClientOptions = {
|
|
56
56
|
clientId?: string;
|
|
57
57
|
databasePath?: string;
|
|
58
|
-
|
|
58
|
+
serverEntryPath?: string;
|
|
59
59
|
env?: Record<string, string>;
|
|
60
60
|
};
|
|
61
61
|
|
|
@@ -64,7 +64,7 @@ export class WorkflowClient {
|
|
|
64
64
|
readonly databasePath: string;
|
|
65
65
|
readonly endpoint: string;
|
|
66
66
|
|
|
67
|
-
private readonly
|
|
67
|
+
private readonly serverEntryPath: string | undefined;
|
|
68
68
|
private readonly env: Record<string, string> | undefined;
|
|
69
69
|
private socket: Socket | null = null;
|
|
70
70
|
private connectTask: Promise<ClientHello> | null = null;
|
|
@@ -78,7 +78,7 @@ export class WorkflowClient {
|
|
|
78
78
|
this.clientId = options.clientId ?? `client-${randomUUID()}`;
|
|
79
79
|
this.databasePath = options.databasePath ?? workflowStatePath();
|
|
80
80
|
this.endpoint = clientSocketPath(this.databasePath);
|
|
81
|
-
this.
|
|
81
|
+
this.serverEntryPath = options.serverEntryPath;
|
|
82
82
|
this.env = options.env;
|
|
83
83
|
}
|
|
84
84
|
|
|
@@ -143,7 +143,7 @@ export class WorkflowClient {
|
|
|
143
143
|
const response = await this.request({ operation: "view.run.get", runId });
|
|
144
144
|
if (response.outcome === "notFound") return null;
|
|
145
145
|
if (response.outcome !== "accepted" || !isWorkflowRunView(response.receipt, runId)) {
|
|
146
|
-
throw new Error(response.error ?? "Workflow
|
|
146
|
+
throw new Error(response.error ?? "Workflow server returned an invalid run view");
|
|
147
147
|
}
|
|
148
148
|
return response.receipt;
|
|
149
149
|
}
|
|
@@ -216,13 +216,13 @@ export class WorkflowClient {
|
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
218
|
throw new Error(
|
|
219
|
-
`Workflow
|
|
219
|
+
`Workflow server did not become ready: ${lastError instanceof Error ? lastError.message : String(lastError)}`,
|
|
220
220
|
);
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
async ensureRunning(): Promise<ClientResponse> {
|
|
224
224
|
await this.ensureAvailable();
|
|
225
|
-
return await this.request({ operation: "
|
|
225
|
+
return await this.request({ operation: "server.status" });
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
async readContent(
|
|
@@ -367,23 +367,23 @@ export class WorkflowClient {
|
|
|
367
367
|
)) as unknown as ResolvedWorkflowLaunch;
|
|
368
368
|
}
|
|
369
369
|
|
|
370
|
-
async
|
|
370
|
+
async resolveResourceManagerInitialization(options: {
|
|
371
371
|
cwd: string;
|
|
372
|
-
|
|
372
|
+
resourceManagerName: string;
|
|
373
373
|
spec: JsonValue;
|
|
374
374
|
timeoutMs?: number;
|
|
375
|
-
}): Promise<
|
|
375
|
+
}): Promise<ResolvedResourceManagerInitialization> {
|
|
376
376
|
return (await this.runResolver(
|
|
377
377
|
{
|
|
378
|
-
schema: "pi-workflows.
|
|
378
|
+
schema: "pi-workflows.resource-manager-initialization-request.v1",
|
|
379
379
|
cwd: options.cwd,
|
|
380
|
-
|
|
380
|
+
resourceManagerName: options.resourceManagerName,
|
|
381
381
|
spec: options.spec,
|
|
382
382
|
},
|
|
383
383
|
options.cwd,
|
|
384
|
-
"pi-workflows.resolved-
|
|
384
|
+
"pi-workflows.resolved-resource-manager-initialization.v1",
|
|
385
385
|
options.timeoutMs,
|
|
386
|
-
)) as unknown as
|
|
386
|
+
)) as unknown as ResolvedResourceManagerInitialization;
|
|
387
387
|
}
|
|
388
388
|
|
|
389
389
|
async resolveSettingsChange(options: {
|
|
@@ -498,7 +498,7 @@ export class WorkflowClient {
|
|
|
498
498
|
|
|
499
499
|
private async send(request: ClientRequest, signal?: AbortSignal): Promise<ClientResponse> {
|
|
500
500
|
const socket = this.socket;
|
|
501
|
-
if (socket === null || socket.destroyed) throw new Error("Workflow
|
|
501
|
+
if (socket === null || socket.destroyed) throw new Error("Workflow server is unavailable");
|
|
502
502
|
if (signal?.aborted === true) throw abortReason(signal);
|
|
503
503
|
if (this.pending.has(request.requestId)) {
|
|
504
504
|
throw new Error(`Workflow request is already pending: ${request.requestId}`);
|
|
@@ -549,10 +549,11 @@ export class WorkflowClient {
|
|
|
549
549
|
for (const frame of decoder.push(chunk)) {
|
|
550
550
|
const message = parseClientMessage(frame);
|
|
551
551
|
if (!receivedHello) {
|
|
552
|
-
if (message.type !== "hello")
|
|
552
|
+
if (message.type !== "hello")
|
|
553
|
+
throw new Error("Workflow server did not send hello first");
|
|
553
554
|
if (message.packageVersion !== CLIENT_PACKAGE_VERSION) {
|
|
554
555
|
throw new WorkflowClientVersionError(
|
|
555
|
-
`Workflow client version mismatch:
|
|
556
|
+
`Workflow client version mismatch: server ${message.packageVersion}, client ${CLIENT_PACKAGE_VERSION}. Install matching pi-workflows and piw packages.`,
|
|
556
557
|
);
|
|
557
558
|
}
|
|
558
559
|
receivedHello = true;
|
|
@@ -597,9 +598,9 @@ export class WorkflowClient {
|
|
|
597
598
|
helloReject(error);
|
|
598
599
|
});
|
|
599
600
|
socket.once("close", () => {
|
|
600
|
-
if (!receivedHello) helloReject(new Error("Workflow
|
|
601
|
+
if (!receivedHello) helloReject(new Error("Workflow server closed before hello"));
|
|
601
602
|
if (this.socket === socket) {
|
|
602
|
-
this.resetConnection(new Error("Workflow
|
|
603
|
+
this.resetConnection(new Error("Workflow server connection closed"));
|
|
603
604
|
this.scheduleReconnect();
|
|
604
605
|
}
|
|
605
606
|
});
|
|
@@ -611,7 +612,7 @@ export class WorkflowClient {
|
|
|
611
612
|
helloPromise.then(() => undefined),
|
|
612
613
|
new Promise<never>((_, reject) => {
|
|
613
614
|
connectTimer = setTimeout(
|
|
614
|
-
() => reject(new Error("Workflow
|
|
615
|
+
() => reject(new Error("Workflow server connection timed out")),
|
|
615
616
|
CONNECT_TIMEOUT_MS,
|
|
616
617
|
);
|
|
617
618
|
connectTimer.unref?.();
|
|
@@ -620,7 +621,7 @@ export class WorkflowClient {
|
|
|
620
621
|
const hello = await Promise.race([
|
|
621
622
|
helloPromise,
|
|
622
623
|
delay(CONNECT_TIMEOUT_MS).then(() => {
|
|
623
|
-
throw new Error("Workflow
|
|
624
|
+
throw new Error("Workflow server hello timed out");
|
|
624
625
|
}),
|
|
625
626
|
]);
|
|
626
627
|
await this.restoreSubscriptions();
|
|
@@ -702,7 +703,7 @@ export class WorkflowClient {
|
|
|
702
703
|
}
|
|
703
704
|
}
|
|
704
705
|
|
|
705
|
-
private resetConnection(reason = new Error("Workflow
|
|
706
|
+
private resetConnection(reason = new Error("Workflow server is unavailable")): void {
|
|
706
707
|
const socket = this.socket;
|
|
707
708
|
this.socket = null;
|
|
708
709
|
this.hello = null;
|
|
@@ -718,7 +719,7 @@ export class WorkflowClient {
|
|
|
718
719
|
type: "event",
|
|
719
720
|
subscriptionId,
|
|
720
721
|
event: "unavailable",
|
|
721
|
-
payload: { message: "Workflow
|
|
722
|
+
payload: { message: "Workflow server connection is unavailable." },
|
|
722
723
|
});
|
|
723
724
|
} catch {
|
|
724
725
|
// One renderer cannot block reconnection for other subscriptions.
|
|
@@ -742,8 +743,8 @@ export class WorkflowClient {
|
|
|
742
743
|
expectedSchema: string,
|
|
743
744
|
timeoutMs = RESOLVER_TIMEOUT_MS,
|
|
744
745
|
): Promise<JsonValue> {
|
|
745
|
-
const builtEntry = fileURLToPath(new URL("../
|
|
746
|
-
const sourceEntry = fileURLToPath(new URL("../
|
|
746
|
+
const builtEntry = fileURLToPath(new URL("../server/resolver-entry.js", import.meta.url));
|
|
747
|
+
const sourceEntry = fileURLToPath(new URL("../server/resolver-entry.ts", import.meta.url));
|
|
747
748
|
const args = fs.existsSync(builtEntry)
|
|
748
749
|
? [builtEntry]
|
|
749
750
|
: ["--import", createRequire(import.meta.url).resolve("tsx"), sourceEntry];
|
|
@@ -791,11 +792,11 @@ export class WorkflowClient {
|
|
|
791
792
|
}
|
|
792
793
|
|
|
793
794
|
private startDetached(): void {
|
|
794
|
-
const builtEntry = fileURLToPath(new URL("../
|
|
795
|
-
const sourceEntry = fileURLToPath(new URL("../
|
|
796
|
-
const entry = this.
|
|
795
|
+
const builtEntry = fileURLToPath(new URL("../server/server-entry.js", import.meta.url));
|
|
796
|
+
const sourceEntry = fileURLToPath(new URL("../server/server-entry.ts", import.meta.url));
|
|
797
|
+
const entry = this.serverEntryPath ?? builtEntry;
|
|
797
798
|
const args =
|
|
798
|
-
this.
|
|
799
|
+
this.serverEntryPath === undefined && !fs.existsSync(builtEntry)
|
|
799
800
|
? ["--import", createRequire(import.meta.url).resolve("tsx"), sourceEntry]
|
|
800
801
|
: [entry];
|
|
801
802
|
const child = spawn(process.execPath, [...args, "--database", this.databasePath], {
|
|
@@ -829,7 +830,7 @@ function parseWorkflowRunListPage(value: unknown): WorkflowRunListPage {
|
|
|
829
830
|
isRecord(item) && typeof item.runId === "string" && typeof item.workflowName === "string",
|
|
830
831
|
)
|
|
831
832
|
) {
|
|
832
|
-
throw new Error("Workflow
|
|
833
|
+
throw new Error("Workflow server returned an invalid run list page");
|
|
833
834
|
}
|
|
834
835
|
return value as unknown as WorkflowRunListPage;
|
|
835
836
|
}
|
|
@@ -851,7 +852,7 @@ function abortReason(signal: AbortSignal): Error {
|
|
|
851
852
|
|
|
852
853
|
function waitForSocketDrain(socket: Socket, signal?: AbortSignal): Promise<void> {
|
|
853
854
|
if (signal?.aborted === true) return Promise.reject(abortReason(signal));
|
|
854
|
-
if (socket.destroyed) return Promise.reject(new Error("Workflow
|
|
855
|
+
if (socket.destroyed) return Promise.reject(new Error("Workflow server connection closed"));
|
|
855
856
|
return new Promise((resolve, reject) => {
|
|
856
857
|
const cleanup = (): void => {
|
|
857
858
|
socket.off("drain", onDrain);
|
|
@@ -865,7 +866,7 @@ function waitForSocketDrain(socket: Socket, signal?: AbortSignal): Promise<void>
|
|
|
865
866
|
else reject(error);
|
|
866
867
|
};
|
|
867
868
|
const onDrain = (): void => settle();
|
|
868
|
-
const onClose = (): void => settle(new Error("Workflow
|
|
869
|
+
const onClose = (): void => settle(new Error("Workflow server connection closed"));
|
|
869
870
|
const onError = (error: Error): void => settle(error);
|
|
870
871
|
const onAbort = (): void => settle(abortReason(signal as AbortSignal));
|
|
871
872
|
socket.once("drain", onDrain);
|
package/src/client/protocol.ts
CHANGED
|
@@ -28,13 +28,13 @@ export const CLIENT_OPERATIONS = [
|
|
|
28
28
|
"channel.status",
|
|
29
29
|
"channel.reload",
|
|
30
30
|
"channel.recover",
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
31
|
+
"resourceManager.list",
|
|
32
|
+
"resourceManager.get",
|
|
33
|
+
"resourceManager.apply",
|
|
34
|
+
"resourceManager.reconcile",
|
|
35
|
+
"resourceManager.delete",
|
|
36
|
+
"server.status",
|
|
37
|
+
"server.stop",
|
|
38
38
|
"view.runs.watch",
|
|
39
39
|
"view.runs.page",
|
|
40
40
|
"view.run.get",
|
|
@@ -185,10 +185,15 @@ export function clientSocketPath(databasePath: string): string {
|
|
|
185
185
|
export class NdjsonFrameDecoder {
|
|
186
186
|
private buffered = Buffer.alloc(0);
|
|
187
187
|
|
|
188
|
+
constructor(
|
|
189
|
+
private readonly maxMessageBytes = MAX_PROTOCOL_MESSAGE_BYTES,
|
|
190
|
+
private readonly oversizedMessage = "Client protocol message exceeds 1 MiB",
|
|
191
|
+
) {}
|
|
192
|
+
|
|
188
193
|
push(chunk: Buffer): Buffer[] {
|
|
189
194
|
this.buffered = Buffer.concat([this.buffered, chunk]);
|
|
190
|
-
if (this.buffered.byteLength >
|
|
191
|
-
throw new ClientProtocolError(
|
|
195
|
+
if (this.buffered.byteLength > this.maxMessageBytes && !this.buffered.includes(0x0a)) {
|
|
196
|
+
throw new ClientProtocolError(this.oversizedMessage);
|
|
192
197
|
}
|
|
193
198
|
const frames: Buffer[] = [];
|
|
194
199
|
for (;;) {
|
|
@@ -197,8 +202,8 @@ export class NdjsonFrameDecoder {
|
|
|
197
202
|
const frame = this.buffered.subarray(0, newline);
|
|
198
203
|
this.buffered = this.buffered.subarray(newline + 1);
|
|
199
204
|
if (frame.byteLength === 0) continue;
|
|
200
|
-
if (frame.byteLength + 1 >
|
|
201
|
-
throw new ClientProtocolError(
|
|
205
|
+
if (frame.byteLength + 1 > this.maxMessageBytes) {
|
|
206
|
+
throw new ClientProtocolError(this.oversizedMessage);
|
|
202
207
|
}
|
|
203
208
|
frames.push(frame);
|
|
204
209
|
}
|
package/src/client/resolver.ts
CHANGED
|
@@ -9,10 +9,10 @@ export type ResolvedWorkflowLaunch = {
|
|
|
9
9
|
definitionSnapshot: JsonValue;
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
export type
|
|
13
|
-
schema: "pi-workflows.resolved-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
export type ResolvedResourceManagerInitialization = {
|
|
13
|
+
schema: "pi-workflows.resolved-resource-manager-initialization.v1";
|
|
14
|
+
resourceManagerName: string;
|
|
15
|
+
resourceManagerPath: string;
|
|
16
16
|
sourceHash: string;
|
|
17
17
|
initialStatus: JsonValue;
|
|
18
18
|
};
|
package/src/client/view.ts
CHANGED
|
@@ -3,6 +3,8 @@ import type { WorkflowMessage, WorkflowTurn } from "../state/workflow-messages.j
|
|
|
3
3
|
|
|
4
4
|
export const RUN_VIEW_SCHEMA = "pi-workflows.run-view.v1" as const;
|
|
5
5
|
export const SESSION_VIEW_SCHEMA = "pi-workflows.session-view.v1" as const;
|
|
6
|
+
export const WORKFLOW_TURN_REPORT_RECEIPT_SCHEMA =
|
|
7
|
+
"pi-workflows.workflow-turn-report-receipt.v1" as const;
|
|
6
8
|
|
|
7
9
|
export type WorkflowDisplayStatus =
|
|
8
10
|
| "queued"
|
|
@@ -17,7 +19,7 @@ export type WorkflowDisplayStatus =
|
|
|
17
19
|
|
|
18
20
|
export type WorkflowDisplay = {
|
|
19
21
|
status: WorkflowDisplayStatus;
|
|
20
|
-
activity: "
|
|
22
|
+
activity: "supervised_runner" | "origin_turn" | null;
|
|
21
23
|
controls: Array<"pause" | "resume" | "cancel" | "answer" | "review">;
|
|
22
24
|
reason: string | null;
|
|
23
25
|
reasonContent?: JsonValue;
|
|
@@ -142,6 +144,12 @@ export type WorkflowBranchReport = {
|
|
|
142
144
|
hasPendingMessages: boolean;
|
|
143
145
|
};
|
|
144
146
|
|
|
147
|
+
export type WorkflowTurnReportReceipt = {
|
|
148
|
+
schema: typeof WORKFLOW_TURN_REPORT_RECEIPT_SCHEMA;
|
|
149
|
+
ownership: "active" | "settled" | "absent";
|
|
150
|
+
turn: WorkflowTurn | null;
|
|
151
|
+
};
|
|
152
|
+
|
|
145
153
|
export type WorkflowTurnReport =
|
|
146
154
|
| {
|
|
147
155
|
state: "started";
|