@monoes/monomindcli 2.9.20 → 2.9.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/.claude/helpers/control-start.cjs +7 -1
  2. package/.claude/skills/mastermind-createorg/SKILL.md +26 -3
  3. package/dist/src/commands/events.d.ts +9 -0
  4. package/dist/src/commands/events.d.ts.map +1 -0
  5. package/dist/src/commands/events.js +89 -0
  6. package/dist/src/commands/events.js.map +1 -0
  7. package/dist/src/commands/index.d.ts +1 -1
  8. package/dist/src/commands/index.d.ts.map +1 -1
  9. package/dist/src/commands/index.js +2 -1
  10. package/dist/src/commands/index.js.map +1 -1
  11. package/dist/src/commands/org-observe.d.ts +21 -0
  12. package/dist/src/commands/org-observe.d.ts.map +1 -1
  13. package/dist/src/commands/org-observe.js +88 -6
  14. package/dist/src/commands/org-observe.js.map +1 -1
  15. package/dist/src/commands/org.d.ts.map +1 -1
  16. package/dist/src/commands/org.js +20 -0
  17. package/dist/src/commands/org.js.map +1 -1
  18. package/dist/src/orgrt/approvals.d.ts +16 -1
  19. package/dist/src/orgrt/approvals.d.ts.map +1 -1
  20. package/dist/src/orgrt/approvals.js +44 -2
  21. package/dist/src/orgrt/approvals.js.map +1 -1
  22. package/dist/src/orgrt/copilot-runner.d.ts +14 -0
  23. package/dist/src/orgrt/copilot-runner.d.ts.map +1 -0
  24. package/dist/src/orgrt/copilot-runner.js +250 -0
  25. package/dist/src/orgrt/copilot-runner.js.map +1 -0
  26. package/dist/src/orgrt/crush-runner.d.ts +24 -0
  27. package/dist/src/orgrt/crush-runner.d.ts.map +1 -0
  28. package/dist/src/orgrt/crush-runner.js +251 -0
  29. package/dist/src/orgrt/crush-runner.js.map +1 -0
  30. package/dist/src/orgrt/daemon.d.ts +40 -1
  31. package/dist/src/orgrt/daemon.d.ts.map +1 -1
  32. package/dist/src/orgrt/daemon.js +68 -4
  33. package/dist/src/orgrt/daemon.js.map +1 -1
  34. package/dist/src/orgrt/grok-runner.d.ts +18 -0
  35. package/dist/src/orgrt/grok-runner.d.ts.map +1 -0
  36. package/dist/src/orgrt/grok-runner.js +323 -0
  37. package/dist/src/orgrt/grok-runner.js.map +1 -0
  38. package/dist/src/orgrt/pi-rpc-runner.d.ts +68 -0
  39. package/dist/src/orgrt/pi-rpc-runner.d.ts.map +1 -0
  40. package/dist/src/orgrt/pi-rpc-runner.js +400 -0
  41. package/dist/src/orgrt/pi-rpc-runner.js.map +1 -0
  42. package/dist/src/orgrt/pi-runner.d.ts +16 -0
  43. package/dist/src/orgrt/pi-runner.d.ts.map +1 -0
  44. package/dist/src/orgrt/pi-runner.js +264 -0
  45. package/dist/src/orgrt/pi-runner.js.map +1 -0
  46. package/dist/src/orgrt/qwen-runner.d.ts +18 -0
  47. package/dist/src/orgrt/qwen-runner.d.ts.map +1 -0
  48. package/dist/src/orgrt/qwen-runner.js +267 -0
  49. package/dist/src/orgrt/qwen-runner.js.map +1 -0
  50. package/dist/src/orgrt/session.js +1 -1
  51. package/dist/src/orgrt/session.js.map +1 -1
  52. package/dist/src/orgrt/types.d.ts +21 -0
  53. package/dist/src/orgrt/types.d.ts.map +1 -1
  54. package/dist/src/orgrt/types.js +9 -2
  55. package/dist/src/orgrt/types.js.map +1 -1
  56. package/dist/src/orgrt/usage-proxy.d.ts +32 -0
  57. package/dist/src/orgrt/usage-proxy.d.ts.map +1 -0
  58. package/dist/src/orgrt/usage-proxy.js +226 -0
  59. package/dist/src/orgrt/usage-proxy.js.map +1 -0
  60. package/dist/src/ui/dashboard.html +63 -0
  61. package/dist/src/ui/orgs.html +8 -1
  62. package/dist/src/ui/routes-org.mjs +26 -0
  63. package/dist/src/utils/resource-governor.d.ts.map +1 -1
  64. package/dist/src/utils/resource-governor.js +11 -2
  65. package/dist/src/utils/resource-governor.js.map +1 -1
  66. package/dist/tsconfig.tsbuildinfo +1 -1
  67. package/package.json +1 -1
@@ -0,0 +1,68 @@
1
+ import type { AgentRunner, AgentRunArgs, AgentMessage } from './agent-runner.js';
2
+ interface PiContentBlock {
3
+ type: string;
4
+ text?: string;
5
+ thinking?: string;
6
+ id?: string;
7
+ name?: string;
8
+ arguments?: Record<string, unknown>;
9
+ }
10
+ interface PiRpcMessage {
11
+ content?: PiContentBlock[];
12
+ }
13
+ /** Pure, transport-independent JSONL line decoder — feed it raw string
14
+ * chunks, get back every complete parsed object found so far (silently
15
+ * skipping malformed lines rather than throwing, matching this repo's
16
+ * other subprocess parsers). Exported for unit testing without a real
17
+ * subprocess. */
18
+ export declare class JsonlDecoder {
19
+ private buf;
20
+ feed(chunk: string): Record<string, unknown>[];
21
+ }
22
+ /** Encode a client→server RPC command as one LF-terminated JSON line.
23
+ * Exported for unit testing the exact wire format. */
24
+ export declare function encodePiRpcCommand(cmd: {
25
+ type: string;
26
+ message?: string;
27
+ id?: string;
28
+ }): string;
29
+ /** Extract assistant-visible text and org tool_call fences from a
30
+ * message_end event's `message.content` array. `thinking` blocks are
31
+ * dropped (internal reasoning, not meant for the bus); `toolCall` blocks
32
+ * are pi's own native tool calls, executed autonomously by pi itself —
33
+ * this runner never sees their results and doesn't need to. Exported for
34
+ * unit testing against fixture content arrays. */
35
+ export declare function extractPiRpcText(message: PiRpcMessage): string;
36
+ /** The subset of a spawned child process this runner needs — narrower than
37
+ * node:child_process's real type, and deliberately duck-typed so tests can
38
+ * supply a fake implementation (an EventEmitter-backed fake process) to
39
+ * exercise the full turn-completion state machine without a real `pi`
40
+ * binary. Given the residual protocol-inference risk documented in this
41
+ * file's header, testing the orchestration logic itself — not just the
42
+ * pure JSONL/extraction helpers — is the point of this seam. */
43
+ export interface PiRpcProcess {
44
+ stdin: {
45
+ write(data: string): void;
46
+ } | null;
47
+ stdout: {
48
+ on(event: 'data', cb: (chunk: Buffer) => void): void;
49
+ } | null;
50
+ stderr: {
51
+ on(event: 'data', cb: (chunk: Buffer) => void): void;
52
+ } | null;
53
+ on(event: 'close', cb: (code: number | null) => void): void;
54
+ on(event: 'error', cb: (err: Error) => void): void;
55
+ kill(signal?: string): void;
56
+ }
57
+ export type SpawnPiRpc = (bin: string, args: string[], opts: {
58
+ cwd: string;
59
+ env: Record<string, string | undefined>;
60
+ }) => PiRpcProcess;
61
+ export declare class PiRpcAgentRunner implements AgentRunner {
62
+ private piBin?;
63
+ private spawnFn;
64
+ constructor(piBin?: string | undefined, spawnFn?: SpawnPiRpc);
65
+ run(args: AgentRunArgs): AsyncIterable<AgentMessage>;
66
+ }
67
+ export {};
68
+ //# sourceMappingURL=pi-rpc-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-rpc-runner.d.ts","sourceRoot":"","sources":["../../../src/orgrt/pi-rpc-runner.ts"],"names":[],"mappings":"AA2DA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAUjF,UAAU,cAAc;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAAE;AAC7I,UAAU,YAAY;IAAG,OAAO,CAAC,EAAE,cAAc,EAAE,CAAC;CAAE;AAEtD;;;;kBAIkB;AAClB,qBAAa,YAAY;IACvB,OAAO,CAAC,GAAG,CAAM;IACjB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAW7C;CACF;AAED;uDACuD;AACvD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAE/F;AAED;;;;;mDAKmD;AACnD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAK9D;AAED;;;;;;iEAMiE;AACjE,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE;QAAE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IAC5C,MAAM,EAAE;QAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IACxE,MAAM,EAAE;QAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IACxE,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC;IAC5D,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;IACnD,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;CAAE,KAAK,YAAY,CAAC;AAKvI,qBAAa,gBAAiB,YAAW,WAAW;IACtC,OAAO,CAAC,KAAK,CAAC;IAAU,OAAO,CAAC,OAAO;IAAnD,YAAoB,KAAK,CAAC,EAAE,MAAM,YAAA,EAAU,OAAO,GAAE,UAA8B,EAAI;IAEhF,GAAG,CAAC,IAAI,EAAE,YAAY,GAAG,aAAa,CAAC,YAAY,CAAC,CAqR1D;CACF"}
@@ -0,0 +1,400 @@
1
+ // packages/@monomind/cli/src/orgrt/pi-rpc-runner.ts
2
+ /**
3
+ * PiRpcAgentRunner — AgentRunner impl backed by the Pi coding agent CLI's
4
+ * `--mode rpc` (session-lifetime, bidirectional JSON-over-stdio), instead of
5
+ * the default PiAgentRunner (pi-runner.ts), which spawns a fresh `pi --mode
6
+ * json` process per mailbox turn.
7
+ *
8
+ * OPT-IN, not the default. Select via role/org `runtime: 'pi-rpc'`. Prefer
9
+ * plain `runtime: 'pi'` (PiAgentRunner) unless you specifically want the
10
+ * benefit this buys: the subprocess stays alive for the WHOLE mailbox
11
+ * session, so conversational context carries naturally (no --session-dir
12
+ * resume guessing) and there's no per-turn spawn/bootstrap cost.
13
+ *
14
+ * Protocol — JSON objects, one per line (LF-delimited), verified against
15
+ * pi-mono's rpc.md doc source directly (literal JSON examples quoted below,
16
+ * not paraphrased from prose — unlike this file's sibling runners, which
17
+ * work from public docs that don't always show raw wire examples):
18
+ *
19
+ * Client → server (this runner sends), each with an optional "id" for
20
+ * response correlation:
21
+ * {"type":"prompt","message":"<text>"} — new/continuing turn
22
+ * {"type":"get_state"} — poll idle/streaming status
23
+ * {"type":"abort"} — not used by this runner
24
+ *
25
+ * Server → client:
26
+ * {"type":"response","command":"prompt","success":true}
27
+ * {"type":"response","command":"get_state","success":true,
28
+ * "data":{"isStreaming":false, ...}}
29
+ * {"type":"agent_start"}
30
+ * {"type":"message_update","usage":{"input":N,"output":N,"totalTokens":N,
31
+ * "cost":{"total":N}},"assistantMessageEvent":{...}} — streaming deltas, ignored
32
+ * {"type":"message_end","message":{"role":"assistant","content":[
33
+ * {"type":"text","text":"..."},
34
+ * {"type":"thinking","thinking":"..."},
35
+ * {"type":"toolCall","id":"call_1","name":"bash","arguments":{...}}
36
+ * ]}}
37
+ *
38
+ * KNOWN GAP — turn-completion detection is a best-effort HEURISTIC, not a
39
+ * confirmed protocol contract: pi executes its own native tools (bash, file
40
+ * edits, …) autonomously inside the RPC session, so a single `prompt` can
41
+ * produce MULTIPLE agent_start/message_end cycles before pi is genuinely
42
+ * done responding, and the docs don't show an explicit "fully idle" event
43
+ * distinct from message_end. This runner sends `get_state` after every
44
+ * message_end and treats `data.isStreaming === false` as "done" — a
45
+ * reasonable, protocol-grounded inference (get_state IS documented), but
46
+ * NOT independently verified against a live pi install (none was available
47
+ * here). If pi's real behavior differs, this could end a turn early or hang
48
+ * waiting past STARTUP_GRACE_MS. Validate against a real `pi --mode rpc`
49
+ * session before relying on this in production; fall back to plain
50
+ * `runtime: 'pi'` if it misbehaves.
51
+ *
52
+ * Org tools (org_send, knowledge_search, ask_human, …) — FENCE PROTOCOL:
53
+ * Pi's own native tools (bash, file edits) execute autonomously inside pi
54
+ * itself and never reach this runner — only org tools ride the shared
55
+ * tool-fence protocol (tool-fence.ts), extracted from message_end's text
56
+ * content and fed back as a new `prompt` command in the SAME session.
57
+ */
58
+ import { spawn } from 'node:child_process';
59
+ import { join } from 'node:path';
60
+ import { buildToolProtocol, parseToolCalls, executeToolCall, formatToolResults, MAX_TOOL_ROUNDS, TOOL_CALL_RE } from './tool-fence.js';
61
+ /** Distinct from a turn timeout — this is how long we wait for pi to settle
62
+ * to isStreaming:false after a message_end before giving up on the
63
+ * heuristic and treating the turn as complete anyway (better to risk
64
+ * cutting a turn slightly short than to hang forever on a wrong inference). */
65
+ const SETTLE_TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes
66
+ const STARTUP_GRACE_MS = 45_000;
67
+ /** Pure, transport-independent JSONL line decoder — feed it raw string
68
+ * chunks, get back every complete parsed object found so far (silently
69
+ * skipping malformed lines rather than throwing, matching this repo's
70
+ * other subprocess parsers). Exported for unit testing without a real
71
+ * subprocess. */
72
+ export class JsonlDecoder {
73
+ buf = '';
74
+ feed(chunk) {
75
+ this.buf += chunk;
76
+ const parts = this.buf.split('\n');
77
+ this.buf = parts.pop() ?? '';
78
+ const out = [];
79
+ for (const line of parts) {
80
+ const trimmed = line.trim();
81
+ if (!trimmed)
82
+ continue;
83
+ try {
84
+ out.push(JSON.parse(trimmed));
85
+ }
86
+ catch { /* skip malformed line */ }
87
+ }
88
+ return out;
89
+ }
90
+ }
91
+ /** Encode a client→server RPC command as one LF-terminated JSON line.
92
+ * Exported for unit testing the exact wire format. */
93
+ export function encodePiRpcCommand(cmd) {
94
+ return JSON.stringify(cmd) + '\n';
95
+ }
96
+ /** Extract assistant-visible text and org tool_call fences from a
97
+ * message_end event's `message.content` array. `thinking` blocks are
98
+ * dropped (internal reasoning, not meant for the bus); `toolCall` blocks
99
+ * are pi's own native tool calls, executed autonomously by pi itself —
100
+ * this runner never sees their results and doesn't need to. Exported for
101
+ * unit testing against fixture content arrays. */
102
+ export function extractPiRpcText(message) {
103
+ return (message.content ?? [])
104
+ .filter((b) => b.type === 'text' && typeof b.text === 'string')
105
+ .map((b) => b.text)
106
+ .join('\n');
107
+ }
108
+ const defaultSpawnPiRpc = (bin, args, opts) => spawn(bin, args, { cwd: opts.cwd, env: opts.env, stdio: ['pipe', 'pipe', 'pipe'] });
109
+ export class PiRpcAgentRunner {
110
+ piBin;
111
+ spawnFn;
112
+ constructor(piBin, spawnFn = defaultSpawnPiRpc) {
113
+ this.piBin = piBin;
114
+ this.spawnFn = spawnFn;
115
+ }
116
+ async *run(args) {
117
+ const bin = this.piBin || process.env.PI_CLI_BIN || 'pi';
118
+ const sessionDir = join(args.cwd, '.monomind-pi-session');
119
+ const cliArgs = ['--mode', 'rpc', '--approve', '--session-dir', sessionDir];
120
+ if (args.model)
121
+ cliArgs.push('--model', args.model);
122
+ const child = this.spawnFn(bin, cliArgs, {
123
+ cwd: args.cwd,
124
+ env: { ...process.env, PI_TELEMETRY: '0', PI_SKIP_VERSION_CHECK: '1', ...args.env },
125
+ });
126
+ let stderrTail = '';
127
+ child.stderr?.on('data', (c) => { stderrTail = (stderrTail + c.toString()).slice(-4000); });
128
+ const decoder = new JsonlDecoder();
129
+ const eventQueue = [];
130
+ const waiters = [];
131
+ let closed = false;
132
+ let closeCode = null;
133
+ // Bumped only by REAL stdout activity (not the synthetic __closed__/
134
+ // __error__/__hang__ events pushed below) — see silenceWatchdog further
135
+ // down, which uses this to detect a mid-session hang.
136
+ let lastEventAt = Date.now();
137
+ const pushEvents = (evs) => {
138
+ for (const ev of evs) {
139
+ const waiter = waiters.shift();
140
+ if (waiter)
141
+ waiter(ev);
142
+ else
143
+ eventQueue.push(ev);
144
+ }
145
+ };
146
+ child.stdout?.on('data', (c) => { lastEventAt = Date.now(); pushEvents(decoder.feed(c.toString())); });
147
+ // Distinct from `closed` (which WE set to stop routing new commands, e.g.
148
+ // as soon as a hang is suspected) — this is only true once the OS
149
+ // confirms the process actually exited. The finally block below uses it
150
+ // to decide whether a pending SIGKILL escalation is still needed.
151
+ let processExited = false;
152
+ child.on('close', (code) => { closed = true; processExited = true; closeCode = code; pushEvents([{ type: '__closed__', code }]); });
153
+ child.on('error', (err) => { closed = true; pushEvents([{ type: '__error__', error: err }]); });
154
+ const nextEvent = () => {
155
+ const queued = eventQueue.shift();
156
+ if (queued)
157
+ return Promise.resolve(queued);
158
+ if (closed)
159
+ return Promise.resolve({ type: '__closed__', code: closeCode });
160
+ return new Promise((resolve) => waiters.push(resolve));
161
+ };
162
+ const send = (cmd) => {
163
+ child.stdin?.write(encodePiRpcCommand(cmd));
164
+ };
165
+ // SIGTERM→SIGKILL escalation, matching the other subprocess runners'
166
+ // pattern — a hang detection that only ever sends SIGTERM would leave a
167
+ // zombie process behind if pi ignores it.
168
+ const KILL_GRACE_MS = 5000;
169
+ let killTimer;
170
+ const killChild = () => {
171
+ try {
172
+ child.kill('SIGTERM');
173
+ }
174
+ catch { /* already gone */ }
175
+ killTimer = setTimeout(() => { try {
176
+ child.kill('SIGKILL');
177
+ }
178
+ catch { /* already gone */ } }, KILL_GRACE_MS);
179
+ killTimer.unref?.();
180
+ };
181
+ // Startup-hang detection — same rationale as the other subprocess
182
+ // runners' STARTUP_GRACE_MS, applied once at process start rather than
183
+ // per turn since the process is long-lived here.
184
+ let sawAnyEvent = false;
185
+ let hangTimer = setTimeout(() => {
186
+ if (!sawAnyEvent) {
187
+ closed = true;
188
+ killChild();
189
+ pushEvents([{ type: '__hang__' }]);
190
+ }
191
+ }, STARTUP_GRACE_MS);
192
+ const disarmHang = () => { if (!sawAnyEvent) {
193
+ sawAnyEvent = true;
194
+ if (hangTimer) {
195
+ clearTimeout(hangTimer);
196
+ hangTimer = undefined;
197
+ }
198
+ } };
199
+ // Rolling watchdog — catches a hang AFTER the startup check has already
200
+ // passed (e.g. pi wedges mid-session on turn 5), which the one-shot
201
+ // startup timer above can't see since it disarms itself on the first
202
+ // event. Checked periodically rather than a single per-turn timer,
203
+ // since a turn's own wait can legitimately take a long time (real model
204
+ // latency) — what matters is total SILENCE from the process, not how
205
+ // long any one turn takes.
206
+ //
207
+ // PAUSED (not just clock-bumped) whenever this runner isn't actually
208
+ // waiting on pi — either an org tool call is in flight (executeToolCall
209
+ // can run ask_human, which waits on a real person and can legitimately
210
+ // take far longer than MID_SESSION_SILENCE_MS), or there's no turn in
211
+ // flight at all: `for await (const p of args.prompt)` blocks on the
212
+ // ROLE'S OWN MAILBOX (session.ts), which idles for as long as the role
213
+ // has nothing new to do — completely normal, and NOT "pi is wedged".
214
+ // A pure "bump lastEventAt" approach would still let the watchdog fire
215
+ // mid-wait for anything slower than the silence window itself; pausing
216
+ // the check entirely for the duration is the correct fix in both cases.
217
+ let toolCallInFlight = false;
218
+ let turnInFlight = false;
219
+ const MID_SESSION_SILENCE_MS = SETTLE_TIMEOUT_MS; // reuse the same bound the settle-heuristic gives up at
220
+ const silenceWatchdog = setInterval(() => {
221
+ if (closed || toolCallInFlight || !turnInFlight)
222
+ return;
223
+ if (Date.now() - lastEventAt > MID_SESSION_SILENCE_MS) {
224
+ closed = true;
225
+ killChild();
226
+ pushEvents([{ type: '__hang__' }]);
227
+ }
228
+ }, 30_000);
229
+ silenceWatchdog.unref?.();
230
+ try {
231
+ let first = true;
232
+ for await (const p of args.prompt) {
233
+ const text = typeof p === 'string' ? p : (p?.message?.content ?? String(p ?? ''));
234
+ let nextMessage = first ? `${args.systemPrompt}${buildToolProtocol(args.tools)}\n\n---\n\n${text}` : text;
235
+ first = false;
236
+ let turnInputTokens = 0;
237
+ let turnOutputTokens = 0;
238
+ let round = 0;
239
+ // The silence watchdog only applies from here to the end of this
240
+ // turn's work — see its declaration above. Always cleared in
241
+ // `finally` so a thrown error (which exits the loop) can't leave it
242
+ // stuck true and permanently disable the watchdog for the rest of
243
+ // the session.
244
+ turnInFlight = true;
245
+ try {
246
+ turnLoop: for (;;) {
247
+ send({ type: 'prompt', message: nextMessage });
248
+ const collectedText = [];
249
+ const settleDeadline = Date.now() + SETTLE_TIMEOUT_MS;
250
+ let sawMessageEnd = false;
251
+ for (;;) {
252
+ const ev = await nextEvent();
253
+ disarmHang();
254
+ const kind = ev.type;
255
+ // Checked on EVERY event, not only get_state responses — a
256
+ // stream of message_update/message_end events with pi never
257
+ // actually answering get_state (e.g. it doesn't recognize the
258
+ // command, or a response gets lost) would otherwise never hit
259
+ // the deadline check below and could wait past it indefinitely.
260
+ if (sawMessageEnd && Date.now() > settleDeadline)
261
+ break;
262
+ if (kind === '__closed__' || kind === '__error__' || kind === '__hang__') {
263
+ if (kind === '__error__') {
264
+ // Rethrow the ORIGINAL spawn error (not a fresh generic one)
265
+ // so the outer catch's `err.code === 'ENOENT'` check below
266
+ // can actually match it — a wrapped/re-created Error loses
267
+ // the .code property, which silently broke the "missing pi
268
+ // binary" install-instructions message.
269
+ throw ev.error;
270
+ }
271
+ const hangSuspected = kind === '__hang__';
272
+ throw new Error(hangSuspected
273
+ ? `PiRpcAgentRunner: pi produced no output within ${STARTUP_GRACE_MS / 1000}s and was killed. ` +
274
+ 'This usually means it is stuck on a prompt headless mode has no way to answer. Run `pi` ' +
275
+ `once manually in a real terminal in this project to check, then retry.${stderrTail ? `\nstderr: ${stderrTail.slice(-500)}` : ''}`
276
+ : `PiRpcAgentRunner: pi rpc process ended unexpectedly (${kind})` +
277
+ (stderrTail ? `\nstderr: ${stderrTail.slice(-500)}` : ''));
278
+ }
279
+ if (kind === 'message_update') {
280
+ // Overwrite (not accumulate) — the confirmed example in this
281
+ // file's header shows `usage` as a running total FOR THE
282
+ // CURRENT RESPONSE, so the latest value read during a turn is
283
+ // that turn's correct total. UNCONFIRMED: whether it's scoped
284
+ // to the current prompt or to the whole (session-lifetime) rpc
285
+ // process. If it turns out to be session-cumulative, every
286
+ // turn after the first would over-report by including prior
287
+ // turns' tokens — inflating org budget consumption. Validate
288
+ // against a live pi install before relying on this for tight
289
+ // budget enforcement; this is exactly the kind of gap opt-in
290
+ // 'pi-rpc' (vs. default 'pi') is meant to warn callers about.
291
+ const usage = ev.usage;
292
+ if (usage) {
293
+ turnInputTokens = usage.input ?? turnInputTokens;
294
+ turnOutputTokens = usage.output ?? turnOutputTokens;
295
+ }
296
+ continue;
297
+ }
298
+ if (kind === 'message_end') {
299
+ sawMessageEnd = true;
300
+ const message = ev.message;
301
+ if (message) {
302
+ const text2 = extractPiRpcText(message);
303
+ if (text2)
304
+ collectedText.push(text2);
305
+ }
306
+ // See file header: get_state is the documented, best-effort
307
+ // signal for "pi is done responding to this prompt", since a
308
+ // single prompt can trigger multiple internal tool-use cycles.
309
+ send({ type: 'get_state' });
310
+ continue;
311
+ }
312
+ if (kind === 'response' && ev.command === 'get_state') {
313
+ const data = ev.data;
314
+ if (data?.isStreaming === false)
315
+ break; // turn settled — fall through to tool-fence handling below
316
+ if (Date.now() > settleDeadline)
317
+ break; // heuristic gave up — proceed rather than hang forever
318
+ continue; // still streaming — keep waiting for more message_end cycles
319
+ }
320
+ // agent_start, other response acks, tool_execution_* (pi's own
321
+ // native tools — nothing for this runner to do) — ignored.
322
+ }
323
+ if (!sawMessageEnd)
324
+ break turnLoop; // nothing to extract this round — avoid an infinite loop on an empty settle
325
+ const rawText = collectedText.join('\n');
326
+ const visibleText = rawText.replace(TOOL_CALL_RE, '').trim();
327
+ if (visibleText)
328
+ yield { type: 'assistant', text: visibleText };
329
+ const malformed = [];
330
+ const calls = parseToolCalls([rawText], (raw, err) => malformed.push(`[monomind] ignored malformed tool_call fence (${err}): ${raw.slice(0, 200)}`));
331
+ for (const note of malformed)
332
+ yield { type: 'assistant', text: note };
333
+ if (calls.length === 0)
334
+ break turnLoop;
335
+ round += 1;
336
+ if (round > MAX_TOOL_ROUNDS) {
337
+ yield { type: 'assistant', text: `[monomind] tool-call round cap (${MAX_TOOL_ROUNDS}) reached — dropping ${calls.length} pending tool call(s)` };
338
+ break turnLoop;
339
+ }
340
+ // Pause the silence watchdog for the duration — see its
341
+ // declaration above for why a call like ask_human blocking on a
342
+ // human isn't "pi is wedged". Always un-paused in `finally` so an
343
+ // exception out of executeToolCall can't leave it stuck off.
344
+ toolCallInFlight = true;
345
+ const results = [];
346
+ try {
347
+ for (const call of calls)
348
+ results.push(await executeToolCall(args.tools, call, args.canUseTool));
349
+ }
350
+ finally {
351
+ toolCallInFlight = false;
352
+ lastEventAt = Date.now(); // the post-tool-call silence window starts fresh, not already partway elapsed
353
+ }
354
+ nextMessage = formatToolResults(calls, results);
355
+ }
356
+ }
357
+ finally {
358
+ turnInFlight = false;
359
+ }
360
+ yield {
361
+ type: 'result',
362
+ subtype: 'success',
363
+ input_tokens: turnInputTokens,
364
+ output_tokens: turnOutputTokens,
365
+ };
366
+ }
367
+ }
368
+ catch (err) {
369
+ if (err.code === 'ENOENT') {
370
+ throw new Error('PiRpcAgentRunner requires the Pi coding agent CLI (pi) on PATH. ' +
371
+ 'Install it: npm install -g @mariozechner/pi-coding-agent, then configure a ' +
372
+ 'provider. Or unset the runtime to use Claude.');
373
+ }
374
+ throw err;
375
+ }
376
+ finally {
377
+ if (hangTimer)
378
+ clearTimeout(hangTimer);
379
+ clearInterval(silenceWatchdog);
380
+ if (processExited) {
381
+ // Process is confirmed dead — any pending SIGKILL escalation from
382
+ // killChild() is no longer needed.
383
+ if (killTimer)
384
+ clearTimeout(killTimer);
385
+ }
386
+ else {
387
+ // NOT confirmed dead (e.g. the hang/silence watchdog fired and
388
+ // sent SIGTERM, but the process hasn't closed yet). Clearing
389
+ // killTimer here would cancel the SIGKILL escalation mid-grace-
390
+ // period and orphan a process that's ignoring SIGTERM — exactly
391
+ // the wedged case these watchdogs exist to handle. Leave the
392
+ // existing (unref'd) escalation timer running, or arm a fresh one
393
+ // if we're exiting via a path that never called killChild() at all.
394
+ if (!killTimer)
395
+ killChild();
396
+ }
397
+ }
398
+ }
399
+ }
400
+ //# sourceMappingURL=pi-rpc-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-rpc-runner.js","sourceRoot":"","sources":["../../../src/orgrt/pi-rpc-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { AgentRunner, AgentRunArgs, AgentMessage } from './agent-runner.js';
2
+ /** Pure JSON-event parser — exported for unit testing against fixture lines
3
+ * (pi-runner.test.ts). */
4
+ export declare function parsePiEvents(lines: string[]): {
5
+ texts: string[];
6
+ rawTexts: string[];
7
+ inputTokens: number;
8
+ outputTokens: number;
9
+ };
10
+ export declare class PiAgentRunner implements AgentRunner {
11
+ private piBin?;
12
+ constructor(piBin?: string | undefined);
13
+ run(args: AgentRunArgs): AsyncIterable<AgentMessage>;
14
+ private runTurn;
15
+ }
16
+ //# sourceMappingURL=pi-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-runner.d.ts","sourceRoot":"","sources":["../../../src/orgrt/pi-runner.ts"],"names":[],"mappings":"AA6CA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAkBjF;2BAC2B;AAC3B,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG;IAC9C,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;CAChF,CA4BA;AAeD,qBAAa,aAAc,YAAW,WAAW;IACnC,OAAO,CAAC,KAAK,CAAC;IAA1B,YAAoB,KAAK,CAAC,EAAE,MAAM,YAAA,EAAI;IAE/B,GAAG,CAAC,IAAI,EAAE,YAAY,GAAG,aAAa,CAAC,YAAY,CAAC,CA0E1D;IAED,OAAO,CAAC,OAAO;CA8FhB"}