@ferris1225/pi-subagents 0.32.2 → 1.0.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/README.md +45 -22
- package/agents/reviewer.md +2 -0
- package/package.json +2 -2
- package/src/agents.ts +2 -7
- package/src/announcements.ts +62 -0
- package/src/completion.ts +7 -36
- package/src/config.ts +327 -364
- package/src/dispatch.ts +1682 -1878
- package/src/fixloop.ts +0 -16
- package/src/format.ts +4 -8
- package/src/index.ts +8 -9
- package/src/models.ts +17 -39
- package/src/monitor.ts +64 -175
- package/src/rpc-run.ts +2 -41
- package/src/runtime.ts +272 -285
- package/src/session-fork.ts +0 -4
- package/src/setup.ts +4 -4
- package/src/spawn.ts +542 -562
- package/src/tools.ts +706 -748
- package/src/ui.ts +3 -7
- package/src/widget.ts +90 -178
- package/src/worktree.ts +1 -1
- package/src/inspector-panel.ts +0 -363
- package/src/inspector.ts +0 -369
- package/src/trajectory.ts +0 -503
package/src/rpc-run.ts
CHANGED
|
@@ -14,7 +14,7 @@ import { tmpdir } from "node:os";
|
|
|
14
14
|
import { basename, join } from "node:path";
|
|
15
15
|
import { StringDecoder } from "node:string_decoder";
|
|
16
16
|
import type { Message } from "@earendil-works/pi-ai";
|
|
17
|
-
import type { AgentConfig
|
|
17
|
+
import type { AgentConfig } from "./agents.ts";
|
|
18
18
|
import type { ThinkingLevel } from "./config.ts";
|
|
19
19
|
import type { IsolationMode, WorktreeFinalizationStatus } from "./worktree.ts";
|
|
20
20
|
|
|
@@ -43,7 +43,6 @@ export interface UsageStats {
|
|
|
43
43
|
|
|
44
44
|
export interface RpcSingleResult {
|
|
45
45
|
agent: string;
|
|
46
|
-
agentSource: AgentSource | "unknown";
|
|
47
46
|
task: string;
|
|
48
47
|
exitCode: number;
|
|
49
48
|
messages: Message[];
|
|
@@ -65,16 +64,12 @@ export interface RpcSingleResult {
|
|
|
65
64
|
failedTools?: Array<{ toolName: string; error: string }>;
|
|
66
65
|
sessionId?: string;
|
|
67
66
|
sessionDir?: string;
|
|
68
|
-
resumed?: boolean;
|
|
69
67
|
/** Internal disposition: dispatch suppresses completion delivery for parks. */
|
|
70
68
|
parked?: boolean;
|
|
71
69
|
/** Stable logical run id assigned by dispatch (also present on queued results). */
|
|
72
70
|
runId?: number;
|
|
73
71
|
/** Filesystem isolation selected for this logical thread. */
|
|
74
72
|
isolation?: IsolationMode;
|
|
75
|
-
/** Original parent cwd; isolated children execute at isolationCwd instead. */
|
|
76
|
-
originalCwd?: string;
|
|
77
|
-
isolationCwd?: string;
|
|
78
73
|
/** Final integration state for a worktree-isolated settlement. */
|
|
79
74
|
integrationStatus?: "pending" | WorktreeFinalizationStatus;
|
|
80
75
|
integrationApplied?: boolean;
|
|
@@ -96,15 +91,6 @@ export type SubagentLiveEvent =
|
|
|
96
91
|
| { kind: "thinking" }
|
|
97
92
|
| { kind: "text" };
|
|
98
93
|
|
|
99
|
-
/** Carries the actual streamed payload (dropped by the plain text/thinking
|
|
100
|
-
* live events). Emitted in addition to the aliveness events so monitor
|
|
101
|
-
* observers stay unchanged while the inspector can apply its rolling budget
|
|
102
|
-
* without silently losing part of a transport delta. */
|
|
103
|
-
export interface SubagentRecordEvent {
|
|
104
|
-
kind: "thinking" | "text";
|
|
105
|
-
delta: string;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
94
|
export type RpcControlPhase =
|
|
109
95
|
| "queued"
|
|
110
96
|
| "starting"
|
|
@@ -177,10 +163,6 @@ export class RpcRunControl {
|
|
|
177
163
|
this.setPhase("parked");
|
|
178
164
|
}
|
|
179
165
|
|
|
180
|
-
markQueued(): void {
|
|
181
|
-
this.setPhase("queued");
|
|
182
|
-
}
|
|
183
|
-
|
|
184
166
|
markStarting(): void {
|
|
185
167
|
this.setPhase("starting");
|
|
186
168
|
}
|
|
@@ -413,15 +395,13 @@ export interface RunRpcAttemptOptions {
|
|
|
413
395
|
prompt: string;
|
|
414
396
|
signal?: AbortSignal;
|
|
415
397
|
onLive?: (event: SubagentLiveEvent) => void;
|
|
416
|
-
/** Receives the raw streamed deltas; observer errors are swallowed. */
|
|
417
|
-
onRecord?: (event: SubagentRecordEvent) => void;
|
|
418
398
|
env?: NodeJS.ProcessEnv;
|
|
419
399
|
control?: RpcRunControl;
|
|
420
400
|
}
|
|
421
401
|
|
|
422
402
|
/** Run one persistent RPC child until a stable `agent_settled` or control action. */
|
|
423
403
|
export async function runRpcAgentAttempt(options: RunRpcAttemptOptions): Promise<RpcSingleResult> {
|
|
424
|
-
const { agent, agentName, task, thinkingLevel, idleTimeoutMs, signal, onLive,
|
|
404
|
+
const { agent, agentName, task, thinkingLevel, idleTimeoutMs, signal, onLive, control } = options;
|
|
425
405
|
const args: string[] = ["--mode", "rpc", "--exclude-tools", "subagent,subagent_control"];
|
|
426
406
|
if (options.sessionDir && options.sessionId) {
|
|
427
407
|
args.push("--session-dir", options.sessionDir);
|
|
@@ -442,12 +422,8 @@ export async function runRpcAgentAttempt(options: RunRpcAttemptOptions): Promise
|
|
|
442
422
|
args.push("--append-system-prompt", tmpPromptPath);
|
|
443
423
|
}
|
|
444
424
|
|
|
445
|
-
const resumed = Boolean(
|
|
446
|
-
options.sessionDir && options.sessionId && sessionExists(options.sessionDir, options.sessionId),
|
|
447
|
-
);
|
|
448
425
|
const result: RpcSingleResult = {
|
|
449
426
|
agent: agentName,
|
|
450
|
-
agentSource: agent.source,
|
|
451
427
|
task,
|
|
452
428
|
exitCode: 0,
|
|
453
429
|
messages: [],
|
|
@@ -457,7 +433,6 @@ export async function runRpcAgentAttempt(options: RunRpcAttemptOptions): Promise
|
|
|
457
433
|
thinking: thinkingLevel,
|
|
458
434
|
sessionId: options.sessionId,
|
|
459
435
|
sessionDir: options.sessionDir,
|
|
460
|
-
resumed,
|
|
461
436
|
};
|
|
462
437
|
|
|
463
438
|
const childDepth = currentSubagentDepth(options.env) + 1;
|
|
@@ -506,14 +481,6 @@ export async function runRpcAgentAttempt(options: RunRpcAttemptOptions): Promise
|
|
|
506
481
|
}
|
|
507
482
|
};
|
|
508
483
|
|
|
509
|
-
const emitRecord = (event: SubagentRecordEvent): void => {
|
|
510
|
-
try {
|
|
511
|
-
onRecord?.(event);
|
|
512
|
-
} catch {
|
|
513
|
-
/* record observers must never break protocol handling */
|
|
514
|
-
}
|
|
515
|
-
};
|
|
516
|
-
|
|
517
484
|
const setAttemptPhase = (phase: RpcControlPhase): void => {
|
|
518
485
|
if (attemptToken !== undefined) control?.updateAttemptPhase(attemptToken, phase);
|
|
519
486
|
switch (phase) {
|
|
@@ -806,12 +773,6 @@ export async function runRpcAgentAttempt(options: RunRpcAttemptOptions): Promise
|
|
|
806
773
|
const type = event.assistantMessageEvent?.type;
|
|
807
774
|
if (type === "thinking_delta" || type === "text_delta") {
|
|
808
775
|
emit({ kind: type === "thinking_delta" ? "thinking" : "text" });
|
|
809
|
-
const delta = event.assistantMessageEvent?.delta;
|
|
810
|
-
if (typeof delta === "string" && delta) {
|
|
811
|
-
// TranscriptBuffer owns the complete rolling-budget decision. Truncating
|
|
812
|
-
// one RPC delta here would silently lose text without setting its flag.
|
|
813
|
-
emitRecord({ kind: type === "thinking_delta" ? "thinking" : "text", delta });
|
|
814
|
-
}
|
|
815
776
|
}
|
|
816
777
|
}
|
|
817
778
|
|