@llblab/pi-actors 0.42.3 → 0.43.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +127 -175
- package/BACKLOG.md +189 -1
- package/CHANGELOG.md +183 -292
- package/README.md +115 -276
- package/dist/fixtures/protocol/control-endpoint.json +6 -0
- package/dist/fixtures/protocol/control-record.json +9 -0
- package/dist/fixtures/protocol/recipe-summary.json +4 -12
- package/dist/fixtures/protocol/trace-event.json +9 -0
- package/dist/index.js +1 -1
- package/dist/lib/async-runs.d.ts +15 -38
- package/dist/lib/async-runs.js +173 -111
- package/dist/lib/automatic-review-runtime.d.ts +1 -1
- package/dist/lib/automatic-review-runtime.js +5 -5
- package/dist/lib/command-templates.d.ts +2 -0
- package/dist/lib/command-templates.js +38 -4
- package/dist/lib/control-projection.d.ts +20 -0
- package/dist/lib/control-projection.js +66 -0
- package/dist/lib/control.d.ts +15 -0
- package/dist/lib/control.js +97 -0
- package/dist/lib/draft-sleep.js +3 -3
- package/dist/lib/execution-sessions.d.ts +17 -0
- package/dist/lib/execution-sessions.js +85 -0
- package/dist/lib/file-state.d.ts +2 -0
- package/dist/lib/file-state.js +114 -46
- package/dist/lib/inspector-actions.d.ts +2 -2
- package/dist/lib/inspector-actions.js +2 -2
- package/dist/lib/inspector-command.js +3 -3
- package/dist/lib/inspector-overlay.d.ts +54 -70
- package/dist/lib/inspector-overlay.js +576 -910
- package/dist/lib/inspector.d.ts +3 -71
- package/dist/lib/inspector.js +19 -665
- package/dist/lib/limits.d.ts +7 -3
- package/dist/lib/limits.js +7 -3
- package/dist/lib/observability.d.ts +16 -16
- package/dist/lib/observability.js +43 -82
- package/dist/lib/prompts.d.ts +1 -1
- package/dist/lib/prompts.js +3 -3
- package/dist/lib/recipe-control.d.ts +7 -0
- package/dist/lib/recipe-control.js +43 -0
- package/dist/lib/recipes-discovery.js +2 -0
- package/dist/lib/recipes-references.d.ts +1 -14
- package/dist/lib/recipes-references.js +6 -21
- package/dist/lib/review-control.d.ts +1 -1
- package/dist/lib/review-control.js +4 -5
- package/dist/lib/review-projection.js +1 -5
- package/dist/lib/run-ui-runtime.js +2 -2
- package/dist/lib/runs-control-delivery.d.ts +28 -0
- package/dist/lib/runs-control-delivery.js +150 -0
- package/dist/lib/runs-controls.d.ts +37 -0
- package/dist/lib/runs-controls.js +146 -0
- package/dist/lib/runs-retention.d.ts +7 -0
- package/dist/lib/runs-retention.js +27 -3
- package/dist/lib/runs-start.js +4 -2
- package/dist/lib/runs-status.js +11 -6
- package/dist/lib/runs-trace.d.ts +24 -0
- package/dist/lib/runs-trace.js +102 -0
- package/dist/lib/runtime-identity.d.ts +7 -0
- package/dist/lib/runtime-identity.js +35 -0
- package/dist/lib/runtime-notifier.d.ts +1 -1
- package/dist/lib/runtime-notifier.js +1 -1
- package/dist/lib/runtime-triage.d.ts +29 -0
- package/dist/lib/runtime-triage.js +76 -0
- package/dist/lib/tool-review-scheduler.js +7 -7
- package/dist/lib/tools-inspect.d.ts +3 -3
- package/dist/lib/tools-inspect.js +241 -707
- package/dist/lib/tools-local.js +2 -10
- package/dist/lib/tools-message.d.ts +6 -7
- package/dist/lib/tools-message.js +95 -396
- package/dist/lib/tools-response.d.ts +1 -5
- package/dist/lib/tools-response.js +5 -48
- package/dist/lib/tools-spawn.js +16 -28
- package/dist/lib/tools.d.ts +1 -1
- package/dist/lib/tools.js +2 -3
- package/dist/lib/trace-projection.d.ts +22 -0
- package/dist/lib/trace-projection.js +185 -0
- package/dist/recipes/draft-review.json +0 -10
- package/dist/recipes/lens-swarm.json +0 -14
- package/dist/recipes/music-player.json +10 -19
- package/dist/recipes/pipeline-architect-coordinator.json +0 -11
- package/dist/recipes/pipeline-artifact-bundle.json +1 -22
- package/dist/recipes/pipeline-artifact-report.json +1 -18
- package/dist/recipes/pipeline-artifact-write.json +1 -18
- package/dist/recipes/pipeline-async-run-ops.json +0 -12
- package/dist/recipes/pipeline-checkpoint-continuation.json +0 -14
- package/dist/recipes/pipeline-development-tasking.json +0 -12
- package/dist/recipes/pipeline-docs-maintenance.json +0 -12
- package/dist/recipes/pipeline-media-library.json +0 -12
- package/dist/recipes/pipeline-quorum-review.json +0 -12
- package/dist/recipes/pipeline-release-readiness.json +0 -12
- package/dist/recipes/pipeline-release-summary.json +0 -12
- package/dist/recipes/pipeline-repo-health.json +0 -12
- package/dist/recipes/pipeline-research-synthesis.json +0 -11
- package/dist/recipes/pipeline-review-readiness.json +0 -12
- package/dist/recipes/resource-locker.json +27 -0
- package/dist/recipes/subagent-artifact.json +0 -9
- package/dist/recipes/subagent-checkpoint.json +0 -10
- package/dist/recipes/subagent-conflict-report.json +0 -11
- package/dist/recipes/subagent-contradiction-map.json +0 -11
- package/dist/recipes/subagent-critic.json +0 -11
- package/dist/recipes/subagent-evidence-map.json +0 -11
- package/dist/recipes/subagent-followup.json +0 -10
- package/dist/recipes/subagent-judge.json +0 -11
- package/dist/recipes/subagent-merge.json +0 -11
- package/dist/recipes/subagent-normalize.json +0 -11
- package/dist/recipes/subagent-plan.json +0 -11
- package/dist/recipes/subagent-preflight.json +0 -11
- package/dist/recipes/subagent-prompt.json +0 -10
- package/dist/recipes/subagent-quorum.json +0 -10
- package/dist/recipes/subagent-review-coordinator.json +0 -14
- package/dist/recipes/subagent-review.json +0 -11
- package/dist/recipes/subagent-task-card.json +0 -11
- package/dist/recipes/subagent-tools.json +0 -10
- package/dist/recipes/subagent-verify.json +0 -11
- package/dist/recipes/subagents-prompts.json +0 -10
- package/dist/recipes/tool-review.json +0 -10
- package/dist/scripts/async-runner.mjs +25 -25
- package/dist/scripts/conformance.mjs +4 -2
- package/dist/scripts/locker.mjs +196 -69
- package/dist/scripts/music-player.mjs +162 -159
- package/dist/scripts/recipe-utils.mjs +6 -96
- package/dist/scripts/release-gates.mjs +91 -0
- package/dist/scripts/validate-recipe.mjs +8 -57
- package/dist/skills/actors/SKILL.md +57 -265
- package/dist/skills/swarm/SKILL.md +10 -34
- package/docs/0.43-baseline.md +39 -0
- package/docs/README.md +4 -6
- package/docs/actor-inspector.md +26 -64
- package/docs/async-runs.md +81 -328
- package/docs/command-templates.md +8 -118
- package/docs/recipe-library.md +55 -182
- package/docs/releasing.md +28 -0
- package/docs/template-recipes.md +76 -289
- package/docs/tool-registry.md +41 -161
- package/fixtures/protocol/control-endpoint.json +6 -0
- package/fixtures/protocol/control-record.json +9 -0
- package/fixtures/protocol/recipe-summary.json +4 -12
- package/fixtures/protocol/trace-event.json +9 -0
- package/index.ts +1 -1
- package/lib/async-runs.ts +218 -204
- package/lib/automatic-review-runtime.ts +7 -7
- package/lib/command-templates.ts +44 -4
- package/lib/control-projection.ts +105 -0
- package/lib/control.ts +117 -0
- package/lib/draft-sleep.ts +3 -3
- package/lib/execution-sessions.ts +111 -0
- package/lib/file-state.ts +84 -64
- package/lib/inspector-actions.ts +2 -2
- package/lib/inspector-command.ts +3 -3
- package/lib/inspector-overlay.ts +617 -1126
- package/lib/inspector.ts +46 -979
- package/lib/limits.ts +7 -3
- package/lib/observability.ts +60 -101
- package/lib/prompts.ts +3 -3
- package/lib/recipe-control.ts +52 -0
- package/lib/recipes-discovery.ts +2 -0
- package/lib/recipes-references.ts +9 -45
- package/lib/review-control.ts +4 -5
- package/lib/review-projection.ts +1 -5
- package/lib/run-ui-runtime.ts +2 -2
- package/lib/runs-control-delivery.ts +209 -0
- package/lib/runs-controls.ts +213 -0
- package/lib/runs-retention.ts +38 -3
- package/lib/runs-start.ts +4 -2
- package/lib/runs-status.ts +11 -6
- package/lib/runs-trace.ts +136 -0
- package/lib/runtime-identity.ts +39 -0
- package/lib/runtime-notifier.ts +1 -1
- package/lib/runtime-triage.ts +120 -0
- package/lib/tool-review-scheduler.ts +7 -7
- package/lib/tools-inspect.ts +283 -900
- package/lib/tools-local.ts +2 -12
- package/lib/tools-message.ts +112 -520
- package/lib/tools-response.ts +5 -64
- package/lib/tools-spawn.ts +16 -32
- package/lib/tools.ts +5 -6
- package/lib/trace-projection.ts +244 -0
- package/package.json +2 -1
- package/recipes/draft-review.json +0 -10
- package/recipes/lens-swarm.json +0 -14
- package/recipes/music-player.json +10 -19
- package/recipes/pipeline-architect-coordinator.json +0 -11
- package/recipes/pipeline-artifact-bundle.json +1 -22
- package/recipes/pipeline-artifact-report.json +1 -18
- package/recipes/pipeline-artifact-write.json +1 -18
- package/recipes/pipeline-async-run-ops.json +0 -12
- package/recipes/pipeline-checkpoint-continuation.json +0 -14
- package/recipes/pipeline-development-tasking.json +0 -12
- package/recipes/pipeline-docs-maintenance.json +0 -12
- package/recipes/pipeline-media-library.json +0 -12
- package/recipes/pipeline-quorum-review.json +0 -12
- package/recipes/pipeline-release-readiness.json +0 -12
- package/recipes/pipeline-release-summary.json +0 -12
- package/recipes/pipeline-repo-health.json +0 -12
- package/recipes/pipeline-research-synthesis.json +0 -11
- package/recipes/pipeline-review-readiness.json +0 -12
- package/recipes/resource-locker.json +27 -0
- package/recipes/subagent-artifact.json +0 -9
- package/recipes/subagent-checkpoint.json +0 -10
- package/recipes/subagent-conflict-report.json +0 -11
- package/recipes/subagent-contradiction-map.json +0 -11
- package/recipes/subagent-critic.json +0 -11
- package/recipes/subagent-evidence-map.json +0 -11
- package/recipes/subagent-followup.json +0 -10
- package/recipes/subagent-judge.json +0 -11
- package/recipes/subagent-merge.json +0 -11
- package/recipes/subagent-normalize.json +0 -11
- package/recipes/subagent-plan.json +0 -11
- package/recipes/subagent-preflight.json +0 -11
- package/recipes/subagent-prompt.json +0 -10
- package/recipes/subagent-quorum.json +0 -10
- package/recipes/subagent-review-coordinator.json +0 -14
- package/recipes/subagent-review.json +0 -11
- package/recipes/subagent-task-card.json +0 -11
- package/recipes/subagent-tools.json +0 -10
- package/recipes/subagent-verify.json +0 -11
- package/recipes/subagents-prompts.json +0 -10
- package/recipes/tool-review.json +0 -10
- package/scripts/async-runner.mjs +25 -25
- package/scripts/conformance.mjs +4 -2
- package/scripts/locker.mjs +196 -69
- package/scripts/music-player.mjs +162 -159
- package/scripts/recipe-utils.mjs +6 -96
- package/scripts/release-gates.mjs +91 -0
- package/scripts/validate-recipe.mjs +8 -57
- package/skills/actors/SKILL.md +57 -265
- package/skills/swarm/SKILL.md +10 -34
- package/dist/fixtures/protocol/actor-message-branch.json +0 -13
- package/dist/fixtures/protocol/mailbox-contract.json +0 -15
- package/dist/fixtures/protocol/room-message.json +0 -11
- package/dist/fixtures/protocol/room-roster.json +0 -11
- package/dist/fixtures/protocol/run-inbox-message.json +0 -9
- package/dist/fixtures/protocol/run-outbox-event.json +0 -9
- package/dist/lib/mailbox-loop.d.ts +0 -41
- package/dist/lib/mailbox-loop.js +0 -60
- package/dist/lib/messages.d.ts +0 -25
- package/dist/lib/messages.js +0 -122
- package/dist/lib/rooms.d.ts +0 -104
- package/dist/lib/rooms.js +0 -647
- package/dist/lib/runs-mailbox.d.ts +0 -25
- package/dist/lib/runs-mailbox.js +0 -146
- package/dist/lib/runs-messages.d.ts +0 -15
- package/dist/lib/runs-messages.js +0 -179
- package/dist/lib/runs-outbox.d.ts +0 -41
- package/dist/lib/runs-outbox.js +0 -87
- package/dist/lib/tools-mailbox.d.ts +0 -8
- package/dist/lib/tools-mailbox.js +0 -48
- package/dist/recipes/actor-worker.json +0 -39
- package/dist/recipes/coordinator-locker.json +0 -45
- package/dist/recipes/locker.json +0 -45
- package/dist/recipes/pipeline-room-swarm.json +0 -50
- package/dist/recipes/subagent-message.json +0 -32
- package/dist/recipes/utility-actor-message.json +0 -23
- package/dist/scripts/actor-worker.mjs +0 -214
- package/dist/scripts/coordinator.mjs +0 -799
- package/docs/actor-messages.md +0 -225
- package/docs/actors-deep-reference.md +0 -66
- package/docs/component-recipes.md +0 -148
- package/docs/task-first-recipes.md +0 -263
- package/fixtures/protocol/actor-message-branch.json +0 -13
- package/fixtures/protocol/mailbox-contract.json +0 -15
- package/fixtures/protocol/room-message.json +0 -11
- package/fixtures/protocol/room-roster.json +0 -11
- package/fixtures/protocol/run-inbox-message.json +0 -9
- package/fixtures/protocol/run-outbox-event.json +0 -9
- package/lib/mailbox-loop.ts +0 -144
- package/lib/messages.ts +0 -151
- package/lib/rooms.ts +0 -939
- package/lib/runs-mailbox.ts +0 -208
- package/lib/runs-messages.ts +0 -252
- package/lib/runs-outbox.ts +0 -144
- package/lib/tools-mailbox.ts +0 -56
- package/recipes/actor-worker.json +0 -39
- package/recipes/coordinator-locker.json +0 -45
- package/recipes/locker.json +0 -45
- package/recipes/pipeline-room-swarm.json +0 -50
- package/recipes/subagent-message.json +0 -32
- package/recipes/utility-actor-message.json +0 -23
- package/scripts/actor-worker.mjs +0 -214
- package/scripts/coordinator.mjs +0 -799
package/lib/runs-mailbox.ts
DELETED
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Async run mailbox state.
|
|
3
|
-
* Owns: durable run inbox records, claim locks, and handler status transitions.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { randomUUID } from "node:crypto";
|
|
7
|
-
import { mkdirSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
8
|
-
import { join } from "node:path";
|
|
9
|
-
|
|
10
|
-
import { readJsonlFileResilient } from "./state-readers.ts";
|
|
11
|
-
|
|
12
|
-
const RUN_INBOX_LOCK_TIMEOUT_MS = 5000;
|
|
13
|
-
const STALE_INBOX_LOCK_MAX_AGE_MS = 5 * 60 * 1000;
|
|
14
|
-
|
|
15
|
-
export type RunInboxStatus =
|
|
16
|
-
| "queued"
|
|
17
|
-
| "sent"
|
|
18
|
-
| "claimed"
|
|
19
|
-
| "handled"
|
|
20
|
-
| "failed";
|
|
21
|
-
|
|
22
|
-
export type RunInboxMessage = Record<string, unknown> & {
|
|
23
|
-
id?: string;
|
|
24
|
-
status?: RunInboxStatus | string;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export interface ProcessRunInboxResult {
|
|
28
|
-
claimed: number;
|
|
29
|
-
failed: number;
|
|
30
|
-
handled: number;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function runInboxFile(stateDir: string): string {
|
|
34
|
-
return join(stateDir, "inbox.jsonl");
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function parseRunInboxLine(line: string): RunInboxMessage | undefined {
|
|
38
|
-
try {
|
|
39
|
-
return JSON.parse(line) as RunInboxMessage;
|
|
40
|
-
} catch {
|
|
41
|
-
return undefined;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function readRunInboxMessagesFromStateDir(
|
|
46
|
-
stateDir: string,
|
|
47
|
-
): RunInboxMessage[] {
|
|
48
|
-
return readJsonlFileResilient<RunInboxMessage>(runInboxFile(stateDir))
|
|
49
|
-
.records;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function sleepSync(ms: number): void {
|
|
53
|
-
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function acquireRunInboxLock(stateDir: string): () => void {
|
|
57
|
-
const lockDir = join(stateDir, ".inbox.lock");
|
|
58
|
-
const started = Date.now();
|
|
59
|
-
while (true) {
|
|
60
|
-
try {
|
|
61
|
-
mkdirSync(lockDir, { recursive: false });
|
|
62
|
-
writeFileSync(
|
|
63
|
-
join(lockDir, "owner.json"),
|
|
64
|
-
`${JSON.stringify({ pid: process.pid, created_at: new Date().toISOString() })}\n`,
|
|
65
|
-
"utf8",
|
|
66
|
-
);
|
|
67
|
-
return () => rmSync(lockDir, { recursive: true, force: true });
|
|
68
|
-
} catch (error) {
|
|
69
|
-
try {
|
|
70
|
-
const stat = statSync(lockDir);
|
|
71
|
-
if (Date.now() - stat.mtimeMs > STALE_INBOX_LOCK_MAX_AGE_MS) {
|
|
72
|
-
rmSync(lockDir, { recursive: true, force: true });
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
} catch {
|
|
76
|
-
continue;
|
|
77
|
-
}
|
|
78
|
-
if (Date.now() - started > RUN_INBOX_LOCK_TIMEOUT_MS) {
|
|
79
|
-
throw new Error("Run inbox lock timed out.", { cause: error });
|
|
80
|
-
}
|
|
81
|
-
sleepSync(10);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function writeRunInboxMessages(
|
|
87
|
-
stateDir: string,
|
|
88
|
-
messages: RunInboxMessage[],
|
|
89
|
-
): void {
|
|
90
|
-
writeFileSync(
|
|
91
|
-
runInboxFile(stateDir),
|
|
92
|
-
messages.length
|
|
93
|
-
? `${messages.map((message) => JSON.stringify(message)).join("\n")}\n`
|
|
94
|
-
: "",
|
|
95
|
-
"utf8",
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export function updateRunInboxMessageStatusInStateDir(
|
|
100
|
-
stateDir: string,
|
|
101
|
-
id: string,
|
|
102
|
-
nextStatus: RunInboxStatus,
|
|
103
|
-
metadata: Record<string, unknown> = {},
|
|
104
|
-
): boolean {
|
|
105
|
-
const releaseLock = acquireRunInboxLock(stateDir);
|
|
106
|
-
try {
|
|
107
|
-
const messages = readRunInboxMessagesFromStateDir(stateDir);
|
|
108
|
-
const timestampKey = `${nextStatus}_at`;
|
|
109
|
-
let changed = false;
|
|
110
|
-
const updated = messages.map((message) => {
|
|
111
|
-
if (message.id !== id) return message;
|
|
112
|
-
changed = true;
|
|
113
|
-
return {
|
|
114
|
-
...message,
|
|
115
|
-
...metadata,
|
|
116
|
-
[timestampKey]: new Date().toISOString(),
|
|
117
|
-
status: nextStatus,
|
|
118
|
-
};
|
|
119
|
-
});
|
|
120
|
-
if (changed) writeRunInboxMessages(stateDir, updated);
|
|
121
|
-
return changed;
|
|
122
|
-
} finally {
|
|
123
|
-
releaseLock();
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export function claimRunInboxMessageInStateDir(
|
|
128
|
-
stateDir: string,
|
|
129
|
-
owner = "runtime",
|
|
130
|
-
statuses: string[] = ["queued"],
|
|
131
|
-
): RunInboxMessage | undefined {
|
|
132
|
-
const releaseLock = acquireRunInboxLock(stateDir);
|
|
133
|
-
try {
|
|
134
|
-
const messages = readRunInboxMessagesFromStateDir(stateDir);
|
|
135
|
-
const index = messages.findIndex((message) =>
|
|
136
|
-
statuses.includes(String(message.status ?? "queued")),
|
|
137
|
-
);
|
|
138
|
-
if (index < 0) return undefined;
|
|
139
|
-
const claimed = {
|
|
140
|
-
...messages[index],
|
|
141
|
-
claimed_at: new Date().toISOString(),
|
|
142
|
-
claimed_by: owner,
|
|
143
|
-
id:
|
|
144
|
-
typeof messages[index].id === "string"
|
|
145
|
-
? messages[index].id
|
|
146
|
-
: randomUUID(),
|
|
147
|
-
status: "claimed",
|
|
148
|
-
} satisfies RunInboxMessage;
|
|
149
|
-
messages[index] = claimed;
|
|
150
|
-
writeRunInboxMessages(stateDir, messages);
|
|
151
|
-
return claimed;
|
|
152
|
-
} finally {
|
|
153
|
-
releaseLock();
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
export function appendRunInboxMessageInStateDir(
|
|
158
|
-
stateDir: string,
|
|
159
|
-
record: Record<string, unknown>,
|
|
160
|
-
): string {
|
|
161
|
-
const id = randomUUID();
|
|
162
|
-
const ts = new Date().toISOString();
|
|
163
|
-
const releaseLock = acquireRunInboxLock(stateDir);
|
|
164
|
-
try {
|
|
165
|
-
writeFileSync(
|
|
166
|
-
runInboxFile(stateDir),
|
|
167
|
-
`${JSON.stringify({ ...record, id, queued_at: ts, received_at: ts, status: "queued" })}\n`,
|
|
168
|
-
{ flag: "a" },
|
|
169
|
-
);
|
|
170
|
-
} finally {
|
|
171
|
-
releaseLock();
|
|
172
|
-
}
|
|
173
|
-
return id;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
export async function processRunInboxMessagesInStateDir(
|
|
177
|
-
stateDir: string,
|
|
178
|
-
handler: (message: RunInboxMessage) => Promise<void> | void,
|
|
179
|
-
options: { limit?: number; owner?: string; statuses?: string[] } = {},
|
|
180
|
-
): Promise<ProcessRunInboxResult> {
|
|
181
|
-
const result: ProcessRunInboxResult = { claimed: 0, failed: 0, handled: 0 };
|
|
182
|
-
const limit = Math.max(1, Number(options.limit ?? 1));
|
|
183
|
-
const owner = options.owner ?? "runtime";
|
|
184
|
-
for (let index = 0; index < limit; index += 1) {
|
|
185
|
-
const message = claimRunInboxMessageInStateDir(
|
|
186
|
-
stateDir,
|
|
187
|
-
owner,
|
|
188
|
-
options.statuses,
|
|
189
|
-
);
|
|
190
|
-
if (!message?.id) break;
|
|
191
|
-
result.claimed += 1;
|
|
192
|
-
try {
|
|
193
|
-
await handler(message);
|
|
194
|
-
if (updateRunInboxMessageStatusInStateDir(stateDir, message.id, "handled")) {
|
|
195
|
-
result.handled += 1;
|
|
196
|
-
}
|
|
197
|
-
} catch (error) {
|
|
198
|
-
if (
|
|
199
|
-
updateRunInboxMessageStatusInStateDir(stateDir, message.id, "failed", {
|
|
200
|
-
error: error instanceof Error ? error.message : String(error),
|
|
201
|
-
})
|
|
202
|
-
) {
|
|
203
|
-
result.failed += 1;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
return result;
|
|
208
|
-
}
|
package/lib/runs-messages.ts
DELETED
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Async run message delivery.
|
|
3
|
-
* Owns: run control endpoint resolution, inbox enqueueing, wake notification,
|
|
4
|
-
* transport writes, and delivery receipts.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
closeSync,
|
|
9
|
-
constants,
|
|
10
|
-
existsSync,
|
|
11
|
-
openSync,
|
|
12
|
-
statSync,
|
|
13
|
-
writeFileSync,
|
|
14
|
-
writeSync,
|
|
15
|
-
} from "node:fs";
|
|
16
|
-
import { createConnection } from "node:net";
|
|
17
|
-
import { join } from "node:path";
|
|
18
|
-
|
|
19
|
-
import { markTerminalHandled } from "./runs-control.ts";
|
|
20
|
-
import {
|
|
21
|
-
appendRunInboxMessageInStateDir,
|
|
22
|
-
updateRunInboxMessageStatusInStateDir,
|
|
23
|
-
} from "./runs-mailbox.ts";
|
|
24
|
-
import { notifyRuntimeWake } from "./runtime-notifier.ts";
|
|
25
|
-
|
|
26
|
-
export interface RunControlEndpoint {
|
|
27
|
-
path: string;
|
|
28
|
-
type: "fifo" | "mailbox" | "named-pipe";
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface SendRunMessageOptions {
|
|
32
|
-
namedPipeSend?: (path: string, payload: string) => Promise<number>;
|
|
33
|
-
platform?: NodeJS.Platform;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function getRunControlEndpoint(
|
|
37
|
-
status: Record<string, unknown>,
|
|
38
|
-
stateDir: string,
|
|
39
|
-
): RunControlEndpoint {
|
|
40
|
-
const control = status.control;
|
|
41
|
-
if (control && typeof control === "object" && !Array.isArray(control)) {
|
|
42
|
-
const record = control as Record<string, unknown>;
|
|
43
|
-
if (
|
|
44
|
-
(record.type === "fifo" ||
|
|
45
|
-
record.type === "mailbox" ||
|
|
46
|
-
record.type === "named-pipe") &&
|
|
47
|
-
typeof record.path === "string" &&
|
|
48
|
-
record.path.trim()
|
|
49
|
-
) {
|
|
50
|
-
return { path: record.path, type: record.type };
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
return { path: join(stateDir, "control.fifo"), type: "fifo" };
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function appendRunInboxMessage(stateDir: string, message: string): string {
|
|
57
|
-
let record: Record<string, unknown>;
|
|
58
|
-
try {
|
|
59
|
-
const parsed = JSON.parse(message) as unknown;
|
|
60
|
-
record =
|
|
61
|
-
parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
62
|
-
? (parsed as Record<string, unknown>)
|
|
63
|
-
: { body: parsed, type: "run.message" };
|
|
64
|
-
} catch {
|
|
65
|
-
record = { body: message, type: "run.message" };
|
|
66
|
-
}
|
|
67
|
-
return appendRunInboxMessageInStateDir(stateDir, record);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function writeRunMessageReceipt(
|
|
71
|
-
stateDir: string,
|
|
72
|
-
message: string,
|
|
73
|
-
bytes: number,
|
|
74
|
-
inboxId: string,
|
|
75
|
-
): void {
|
|
76
|
-
const trimmedMessage = message.trim().toLowerCase();
|
|
77
|
-
const terminalMessage = ["stop", "cancel", "quit", "exit"].includes(
|
|
78
|
-
trimmedMessage,
|
|
79
|
-
);
|
|
80
|
-
const ts = new Date().toISOString();
|
|
81
|
-
writeFileSync(
|
|
82
|
-
join(stateDir, "events.jsonl"),
|
|
83
|
-
`${JSON.stringify({ bytes, event: "run.message", inbox_id: inboxId, terminal: terminalMessage || undefined, ts })}\n`,
|
|
84
|
-
{ flag: "a" },
|
|
85
|
-
);
|
|
86
|
-
updateRunInboxMessageStatusInStateDir(stateDir, inboxId, "sent", { bytes });
|
|
87
|
-
if (terminalMessage) {
|
|
88
|
-
markTerminalHandled(stateDir, {
|
|
89
|
-
event: "run.message",
|
|
90
|
-
message: trimmedMessage,
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function sendRunMessageToFifo(
|
|
96
|
-
endpoint: RunControlEndpoint,
|
|
97
|
-
payload: string,
|
|
98
|
-
): number {
|
|
99
|
-
if (!existsSync(endpoint.path))
|
|
100
|
-
throw new Error(`Run control FIFO not found: ${endpoint.path}`);
|
|
101
|
-
const stat = statSync(endpoint.path);
|
|
102
|
-
if ((stat.mode & constants.S_IFMT) !== constants.S_IFIFO) {
|
|
103
|
-
throw new Error(`Run control endpoint is not a FIFO: ${endpoint.path}`);
|
|
104
|
-
}
|
|
105
|
-
let fd: number | undefined;
|
|
106
|
-
try {
|
|
107
|
-
fd = openSync(endpoint.path, constants.O_WRONLY | constants.O_NONBLOCK);
|
|
108
|
-
return writeSync(fd, payload);
|
|
109
|
-
} finally {
|
|
110
|
-
if (fd !== undefined) closeSync(fd);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function notifyRunMessageWake(
|
|
115
|
-
stateDir: string,
|
|
116
|
-
run: string,
|
|
117
|
-
bytes: number,
|
|
118
|
-
endpoint: RunControlEndpoint,
|
|
119
|
-
inboxId: string,
|
|
120
|
-
): Record<string, unknown> | undefined {
|
|
121
|
-
try {
|
|
122
|
-
const event = notifyRuntimeWake(stateDir, {
|
|
123
|
-
actor: `run:${run}`,
|
|
124
|
-
metadata: { bytes, control_type: endpoint.type, inbox_id: inboxId },
|
|
125
|
-
reason: "run.message",
|
|
126
|
-
});
|
|
127
|
-
return { wake: "wake.jsonl", wake_id: event.id };
|
|
128
|
-
} catch {
|
|
129
|
-
return undefined;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function sendRunMessageToNamedPipe(
|
|
134
|
-
endpoint: RunControlEndpoint,
|
|
135
|
-
payload: string,
|
|
136
|
-
send?: (path: string, payload: string) => Promise<number>,
|
|
137
|
-
): Promise<number> {
|
|
138
|
-
if (send) return send(endpoint.path, payload);
|
|
139
|
-
return new Promise((resolve, reject) => {
|
|
140
|
-
const socket = createConnection(endpoint.path);
|
|
141
|
-
let settled = false;
|
|
142
|
-
const timeout = setTimeout(() => {
|
|
143
|
-
if (settled) return;
|
|
144
|
-
settled = true;
|
|
145
|
-
socket.destroy();
|
|
146
|
-
reject(new Error("named pipe connection timed out"));
|
|
147
|
-
}, 5000);
|
|
148
|
-
const finish = (error?: Error): void => {
|
|
149
|
-
if (settled) return;
|
|
150
|
-
settled = true;
|
|
151
|
-
clearTimeout(timeout);
|
|
152
|
-
if (error) reject(error);
|
|
153
|
-
else resolve(Buffer.byteLength(payload));
|
|
154
|
-
};
|
|
155
|
-
socket.on("error", finish);
|
|
156
|
-
socket.on("connect", () => {
|
|
157
|
-
socket.end(payload, () => finish());
|
|
158
|
-
});
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
export async function deliverRunMessage(
|
|
163
|
-
status: Record<string, unknown>,
|
|
164
|
-
run: string,
|
|
165
|
-
stateDir: string,
|
|
166
|
-
message: string,
|
|
167
|
-
options: SendRunMessageOptions = {},
|
|
168
|
-
): Promise<Record<string, unknown>> {
|
|
169
|
-
const endpoint = getRunControlEndpoint(status, stateDir);
|
|
170
|
-
const payload = message.endsWith("\n") ? message : `${message}\n`;
|
|
171
|
-
const payloadBytes = Buffer.byteLength(payload);
|
|
172
|
-
const inboxId = appendRunInboxMessage(stateDir, message);
|
|
173
|
-
const wake = notifyRunMessageWake(
|
|
174
|
-
stateDir,
|
|
175
|
-
run,
|
|
176
|
-
payloadBytes,
|
|
177
|
-
endpoint,
|
|
178
|
-
inboxId,
|
|
179
|
-
);
|
|
180
|
-
const runtimePlatform = options.platform ?? process.platform;
|
|
181
|
-
if (endpoint.type === "mailbox") {
|
|
182
|
-
return {
|
|
183
|
-
...(wake ?? {}),
|
|
184
|
-
bytes: payloadBytes,
|
|
185
|
-
control: "inbox.jsonl",
|
|
186
|
-
control_path: endpoint.path,
|
|
187
|
-
control_type: endpoint.type,
|
|
188
|
-
inbox_id: inboxId,
|
|
189
|
-
queued: true,
|
|
190
|
-
run,
|
|
191
|
-
sent: true,
|
|
192
|
-
state_dir: stateDir,
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
try {
|
|
196
|
-
if (endpoint.type === "fifo") {
|
|
197
|
-
if (runtimePlatform === "win32") {
|
|
198
|
-
throw new Error(
|
|
199
|
-
"run actor messages on native Windows require a named-pipe control endpoint; this recipe still exposes Unix FIFO control.",
|
|
200
|
-
);
|
|
201
|
-
}
|
|
202
|
-
const bytes = sendRunMessageToFifo(endpoint, payload);
|
|
203
|
-
writeRunMessageReceipt(stateDir, message, bytes, inboxId);
|
|
204
|
-
return {
|
|
205
|
-
...(wake ?? {}),
|
|
206
|
-
bytes,
|
|
207
|
-
control: "control.fifo",
|
|
208
|
-
control_path: endpoint.path,
|
|
209
|
-
control_type: endpoint.type,
|
|
210
|
-
inbox_id: inboxId,
|
|
211
|
-
run,
|
|
212
|
-
sent: true,
|
|
213
|
-
state_dir: stateDir,
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
const bytes = await sendRunMessageToNamedPipe(
|
|
217
|
-
endpoint,
|
|
218
|
-
payload,
|
|
219
|
-
options.namedPipeSend,
|
|
220
|
-
);
|
|
221
|
-
writeRunMessageReceipt(stateDir, message, bytes, inboxId);
|
|
222
|
-
return {
|
|
223
|
-
...(wake ?? {}),
|
|
224
|
-
bytes,
|
|
225
|
-
control: endpoint.path,
|
|
226
|
-
control_path: endpoint.path,
|
|
227
|
-
control_type: endpoint.type,
|
|
228
|
-
inbox_id: inboxId,
|
|
229
|
-
run,
|
|
230
|
-
sent: true,
|
|
231
|
-
state_dir: stateDir,
|
|
232
|
-
};
|
|
233
|
-
} catch (error) {
|
|
234
|
-
const deliveryError =
|
|
235
|
-
error instanceof Error ? error.message : String(error);
|
|
236
|
-
throw Object.assign(
|
|
237
|
-
new Error(
|
|
238
|
-
`Run control endpoint is not ready: ${endpoint.path}: ${deliveryError}`,
|
|
239
|
-
),
|
|
240
|
-
{
|
|
241
|
-
control_path: endpoint.path,
|
|
242
|
-
control_type: endpoint.type,
|
|
243
|
-
delivery_error: deliveryError,
|
|
244
|
-
inbox_id: inboxId,
|
|
245
|
-
queued: true,
|
|
246
|
-
run,
|
|
247
|
-
sent: false,
|
|
248
|
-
state_dir: stateDir,
|
|
249
|
-
},
|
|
250
|
-
);
|
|
251
|
-
}
|
|
252
|
-
}
|
package/lib/runs-outbox.ts
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Async run outbox events.
|
|
3
|
-
* Owns: outbox event normalization, parsing, and append payload formatting.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export type RunOutboxDelivery = "log" | "notify" | "followup";
|
|
7
|
-
export type RunOutboxLevel = "info" | "warning" | "error";
|
|
8
|
-
|
|
9
|
-
export interface RunOutboxEvent {
|
|
10
|
-
body?: unknown;
|
|
11
|
-
correlation_id?: string;
|
|
12
|
-
data?: unknown;
|
|
13
|
-
delivery: RunOutboxDelivery;
|
|
14
|
-
event: string;
|
|
15
|
-
from?: string;
|
|
16
|
-
id: string;
|
|
17
|
-
level: RunOutboxLevel;
|
|
18
|
-
metadata?: Record<string, unknown>;
|
|
19
|
-
reply_to?: string;
|
|
20
|
-
run: string;
|
|
21
|
-
state_dir: string;
|
|
22
|
-
summary: string;
|
|
23
|
-
to?: string;
|
|
24
|
-
ts: string;
|
|
25
|
-
type?: string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function normalizeRunOutboxDelivery(value: unknown): RunOutboxDelivery {
|
|
29
|
-
return value === "notify" || value === "followup" ? value : "log";
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export function normalizeRunOutboxLevel(value: unknown): RunOutboxLevel {
|
|
33
|
-
return value === "warning" || value === "error" ? value : "info";
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function normalizeRunOutboxEvent(
|
|
37
|
-
raw: unknown,
|
|
38
|
-
run: string,
|
|
39
|
-
stateDir: string,
|
|
40
|
-
index: number,
|
|
41
|
-
): RunOutboxEvent | undefined {
|
|
42
|
-
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return undefined;
|
|
43
|
-
const record = raw as Record<string, unknown>;
|
|
44
|
-
const event =
|
|
45
|
-
typeof record.event === "string" && record.event.trim()
|
|
46
|
-
? record.event.trim()
|
|
47
|
-
: "run.event";
|
|
48
|
-
const summary =
|
|
49
|
-
typeof record.summary === "string" && record.summary.trim()
|
|
50
|
-
? record.summary.trim()
|
|
51
|
-
: event;
|
|
52
|
-
const ts =
|
|
53
|
-
typeof record.ts === "string" && record.ts.trim()
|
|
54
|
-
? record.ts.trim()
|
|
55
|
-
: new Date(0).toISOString();
|
|
56
|
-
const id =
|
|
57
|
-
typeof record.id === "string" && record.id.trim()
|
|
58
|
-
? record.id.trim()
|
|
59
|
-
: `${run}:${index}`;
|
|
60
|
-
return {
|
|
61
|
-
...(record.body !== undefined ? { body: record.body } : {}),
|
|
62
|
-
...(typeof record.correlation_id === "string"
|
|
63
|
-
? { correlation_id: record.correlation_id }
|
|
64
|
-
: {}),
|
|
65
|
-
...(record.data !== undefined ? { data: record.data } : {}),
|
|
66
|
-
delivery: normalizeRunOutboxDelivery(record.delivery),
|
|
67
|
-
...(record.metadata &&
|
|
68
|
-
typeof record.metadata === "object" &&
|
|
69
|
-
!Array.isArray(record.metadata)
|
|
70
|
-
? { metadata: record.metadata as Record<string, unknown> }
|
|
71
|
-
: {}),
|
|
72
|
-
event,
|
|
73
|
-
...(typeof record.from === "string" ? { from: record.from } : {}),
|
|
74
|
-
id,
|
|
75
|
-
level: normalizeRunOutboxLevel(record.level),
|
|
76
|
-
...(typeof record.reply_to === "string"
|
|
77
|
-
? { reply_to: record.reply_to }
|
|
78
|
-
: {}),
|
|
79
|
-
run,
|
|
80
|
-
state_dir: stateDir,
|
|
81
|
-
summary,
|
|
82
|
-
...(typeof record.to === "string" ? { to: record.to } : {}),
|
|
83
|
-
ts,
|
|
84
|
-
...(typeof record.type === "string" ? { type: record.type } : {}),
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export function parseRunOutboxEventLine(
|
|
89
|
-
line: string,
|
|
90
|
-
run: string,
|
|
91
|
-
stateDir: string,
|
|
92
|
-
index: number,
|
|
93
|
-
): RunOutboxEvent | undefined {
|
|
94
|
-
try {
|
|
95
|
-
return normalizeRunOutboxEvent(JSON.parse(line), run, stateDir, index);
|
|
96
|
-
} catch {
|
|
97
|
-
return undefined;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export function buildRunOutboxEventPayload(
|
|
102
|
-
run: string,
|
|
103
|
-
event: {
|
|
104
|
-
body?: unknown;
|
|
105
|
-
correlation_id?: string;
|
|
106
|
-
data?: unknown;
|
|
107
|
-
delivery?: string;
|
|
108
|
-
event?: string;
|
|
109
|
-
from?: string;
|
|
110
|
-
level?: string;
|
|
111
|
-
metadata?: Record<string, unknown>;
|
|
112
|
-
reply_to?: string;
|
|
113
|
-
summary?: string;
|
|
114
|
-
to?: string;
|
|
115
|
-
type?: string;
|
|
116
|
-
},
|
|
117
|
-
): Record<string, unknown> {
|
|
118
|
-
const type = event.type || event.event || "run.message";
|
|
119
|
-
const to = event.to || "coordinator";
|
|
120
|
-
const metadata = event.metadata ?? {};
|
|
121
|
-
const requiresResponse = metadata.requires_response === true;
|
|
122
|
-
return {
|
|
123
|
-
...(event.body !== undefined ? { body: event.body } : {}),
|
|
124
|
-
...(event.correlation_id ? { correlation_id: event.correlation_id } : {}),
|
|
125
|
-
...(event.data !== undefined ? { data: event.data } : {}),
|
|
126
|
-
delivery: normalizeRunOutboxDelivery(
|
|
127
|
-
event.delivery ??
|
|
128
|
-
(requiresResponse
|
|
129
|
-
? "followup"
|
|
130
|
-
: to === "coordinator"
|
|
131
|
-
? "notify"
|
|
132
|
-
: "log"),
|
|
133
|
-
),
|
|
134
|
-
event: type,
|
|
135
|
-
from: event.from || `run:${run}`,
|
|
136
|
-
level: normalizeRunOutboxLevel(event.level),
|
|
137
|
-
...(event.metadata ? { metadata: event.metadata } : {}),
|
|
138
|
-
...(event.reply_to ? { reply_to: event.reply_to } : {}),
|
|
139
|
-
summary: event.summary || type,
|
|
140
|
-
to,
|
|
141
|
-
ts: new Date().toISOString(),
|
|
142
|
-
type,
|
|
143
|
-
};
|
|
144
|
-
}
|
package/lib/tools-mailbox.ts
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Public tool mailbox contract helpers
|
|
3
|
-
* Zones: accepted/emitted message type declarations, contract normalization, compact type extraction
|
|
4
|
-
* Owns mailbox metadata normalization for public message and inspect tool paths
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
function asRecord(value: unknown): Record<string, unknown> {
|
|
8
|
-
return value && typeof value === "object" && !Array.isArray(value)
|
|
9
|
-
? (value as Record<string, unknown>)
|
|
10
|
-
: {};
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function normalizeMailboxEntry(
|
|
14
|
-
value: unknown,
|
|
15
|
-
): Record<string, unknown> | undefined {
|
|
16
|
-
if (typeof value === "string") return { type: value };
|
|
17
|
-
const record = asRecord(value);
|
|
18
|
-
if (typeof record.type !== "string" || !record.type.trim()) return undefined;
|
|
19
|
-
return {
|
|
20
|
-
type: record.type.trim(),
|
|
21
|
-
...(record.body_schema !== undefined
|
|
22
|
-
? { body_schema: record.body_schema }
|
|
23
|
-
: {}),
|
|
24
|
-
...(record.ack !== undefined ? { ack: record.ack } : {}),
|
|
25
|
-
...(typeof record.idempotency === "string"
|
|
26
|
-
? { idempotency: record.idempotency }
|
|
27
|
-
: {}),
|
|
28
|
-
...(typeof record.level === "string" ? { level: record.level } : {}),
|
|
29
|
-
...(record.requires_response === true ? { requires_response: true } : {}),
|
|
30
|
-
...(typeof record.summary === "string" ? { summary: record.summary } : {}),
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function normalizeMailboxContracts(
|
|
35
|
-
mailbox: Record<string, unknown>,
|
|
36
|
-
): Record<string, unknown[]> {
|
|
37
|
-
const accepts = Array.isArray(mailbox.accepts)
|
|
38
|
-
? mailbox.accepts
|
|
39
|
-
.map(normalizeMailboxEntry)
|
|
40
|
-
.filter((entry): entry is Record<string, unknown> => Boolean(entry))
|
|
41
|
-
: [];
|
|
42
|
-
const emits = Array.isArray(mailbox.emits)
|
|
43
|
-
? mailbox.emits
|
|
44
|
-
.map(normalizeMailboxEntry)
|
|
45
|
-
.filter((entry): entry is Record<string, unknown> => Boolean(entry))
|
|
46
|
-
: [];
|
|
47
|
-
return { accepts, emits };
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export function mailboxTypes(entries: unknown[]): string[] {
|
|
51
|
-
return entries.flatMap((entry) =>
|
|
52
|
-
typeof asRecord(entry).type === "string"
|
|
53
|
-
? [String(asRecord(entry).type)]
|
|
54
|
-
: [],
|
|
55
|
-
);
|
|
56
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"async": true,
|
|
3
|
-
"description": "Start a canonical mailbox-backed branch worker demo actor.",
|
|
4
|
-
"args": [
|
|
5
|
-
"repo:path",
|
|
6
|
-
"branch:string",
|
|
7
|
-
"poll_ms:int",
|
|
8
|
-
"stale_claim_ms:int",
|
|
9
|
-
"write_artifacts:bool"
|
|
10
|
-
],
|
|
11
|
-
"defaults": {
|
|
12
|
-
"repo": "~/.pi/agent/extensions/pi-actors",
|
|
13
|
-
"branch": "worker",
|
|
14
|
-
"poll_ms": "1000",
|
|
15
|
-
"stale_claim_ms": "0",
|
|
16
|
-
"write_artifacts": "true"
|
|
17
|
-
},
|
|
18
|
-
"mailbox": {
|
|
19
|
-
"accepts": [
|
|
20
|
-
"task.assign",
|
|
21
|
-
"control.kill"
|
|
22
|
-
],
|
|
23
|
-
"emits": [
|
|
24
|
-
"actor.join",
|
|
25
|
-
"task.claim",
|
|
26
|
-
"task.result",
|
|
27
|
-
"awaiting_assignment",
|
|
28
|
-
"actor.leave",
|
|
29
|
-
"run.done",
|
|
30
|
-
"run.failed"
|
|
31
|
-
]
|
|
32
|
-
},
|
|
33
|
-
"artifacts": {
|
|
34
|
-
"journal": "{state_dir}/worker-events.jsonl",
|
|
35
|
-
"status": "{state_dir}/worker-status.json",
|
|
36
|
-
"results": "{state_dir}/worker-artifacts"
|
|
37
|
-
},
|
|
38
|
-
"template": "{repo}/scripts/actor-worker.mjs --state-dir {state_dir} --run {run_id} --branch {branch} --poll-ms {poll_ms} --stale-claim-ms {stale_claim_ms} --write-artifacts {write_artifacts}"
|
|
39
|
-
}
|