@gotgenes/pi-subagents 13.2.0 → 13.2.2
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/CHANGELOG.md +14 -0
- package/README.md +21 -10
- package/dist/public.d.ts +34 -35
- package/docs/architecture/architecture.md +58 -148
- package/docs/architecture/history/phase-16-invert-dependencies.md +144 -0
- package/docs/decisions/0003-publish-bundled-type-declarations.md +3 -1
- package/docs/plans/0051-update-adr-0001-hard-fork.md +8 -6
- package/docs/plans/0257-extract-child-session-factory.md +3 -1
- package/docs/plans/0262-add-workspace-provider-seam.md +41 -39
- package/docs/plans/0264-remove-extension-lifecycle-control.md +100 -98
- package/docs/plans/0265-born-complete-subagent-session.md +5 -2
- package/docs/plans/0270-type-consumable-public-surface.md +3 -1
- package/docs/plans/0280-rename-agent-to-subagent.md +197 -0
- package/docs/retro/0051-update-adr-0001-hard-fork.md +4 -2
- package/docs/retro/0257-extract-child-session-factory.md +3 -1
- package/docs/retro/0262-add-workspace-provider-seam.md +3 -1
- package/docs/retro/0264-remove-extension-lifecycle-control.md +3 -1
- package/docs/retro/0270-type-consumable-public-surface.md +4 -2
- package/docs/retro/0277-encapsulate-agent-session.md +41 -0
- package/docs/retro/0280-rename-agent-to-subagent.md +96 -0
- package/package.json +1 -1
- package/src/index.ts +9 -9
- package/src/lifecycle/create-subagent-session.ts +1 -1
- package/src/lifecycle/{agent-manager.ts → subagent-manager.ts} +27 -27
- package/src/lifecycle/subagent-session.ts +2 -2
- package/src/lifecycle/{agent.ts → subagent.ts} +28 -28
- package/src/lifecycle/turn-limits.ts +1 -1
- package/src/lifecycle/workspace.ts +2 -2
- package/src/observation/notification.ts +9 -9
- package/src/observation/record-observer.ts +9 -9
- package/src/runtime.ts +1 -1
- package/src/service/service-adapter.ts +10 -10
- package/src/service/service.ts +5 -9
- package/src/tools/agent-tool.ts +5 -5
- package/src/tools/background-spawner.ts +3 -3
- package/src/tools/foreground-runner.ts +5 -5
- package/src/tools/get-result-tool.ts +2 -2
- package/src/tools/steer-tool.ts +2 -2
- package/src/types.ts +1 -1
- package/src/ui/agent-creation-wizard.ts +2 -2
- package/src/ui/agent-menu.ts +5 -5
- package/src/ui/agent-widget.ts +2 -2
- package/src/ui/conversation-viewer.ts +3 -3
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* synchronously at run-start. The core has no knowledge of git or worktrees.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import type {
|
|
14
|
+
import type { SubagentStatus } from "#src/lifecycle/subagent";
|
|
15
15
|
import type { AgentInvocation, SubagentType } from "#src/types";
|
|
16
16
|
|
|
17
17
|
/** Context the core hands a provider when a child run starts. */
|
|
@@ -24,7 +24,7 @@ export interface WorkspacePrepareContext {
|
|
|
24
24
|
|
|
25
25
|
/** Outcome the core reports to a workspace when the run ends. */
|
|
26
26
|
export interface WorkspaceDisposeOutcome {
|
|
27
|
-
status:
|
|
27
|
+
status: SubagentStatus;
|
|
28
28
|
description: string;
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { debugLog } from "#src/debug";
|
|
2
2
|
import { getLifetimeTotal } from "#src/lifecycle/usage";
|
|
3
|
-
import type {
|
|
3
|
+
import type { Subagent } from "#src/types";
|
|
4
4
|
import type { AgentActivityTracker } from "#src/ui/agent-activity-tracker";
|
|
5
5
|
|
|
6
6
|
/** Details attached to custom notification messages for visual rendering. */
|
|
@@ -42,7 +42,7 @@ export function getStatusLabel(status: string, error?: string): string {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
/** Format a structured task notification matching Claude Code's <task-notification> XML. */
|
|
45
|
-
export function formatTaskNotification(record:
|
|
45
|
+
export function formatTaskNotification(record: Subagent, resultMaxLen: number): string {
|
|
46
46
|
const status = getStatusLabel(record.status, record.error);
|
|
47
47
|
const durationMs = record.completedAt ? record.completedAt - record.startedAt : 0;
|
|
48
48
|
const totalTokens = getLifetimeTotal(record.lifetimeUsage);
|
|
@@ -64,7 +64,7 @@ export function formatTaskNotification(record: Agent, resultMaxLen: number): str
|
|
|
64
64
|
toolCallId ? `<tool-use-id>${escapeXml(toolCallId)}</tool-use-id>` : null,
|
|
65
65
|
outputFile ? `<output-file>${escapeXml(outputFile)}</output-file>` : null,
|
|
66
66
|
`<status>${escapeXml(status)}</status>`,
|
|
67
|
-
`<summary>
|
|
67
|
+
`<summary>Subagent "${escapeXml(record.description)}" ${record.status}</summary>`,
|
|
68
68
|
`<result>${escapeXml(resultPreview)}</result>`,
|
|
69
69
|
`<usage><total_tokens>${totalTokens}</total_tokens><tool_uses>${record.toolUses}</tool_uses>${ctxXml}${compactXml}<duration_ms>${durationMs}</duration_ms></usage>`,
|
|
70
70
|
"</task-notification>",
|
|
@@ -75,7 +75,7 @@ export function formatTaskNotification(record: Agent, resultMaxLen: number): str
|
|
|
75
75
|
|
|
76
76
|
/** Build notification details for the custom message renderer. */
|
|
77
77
|
export function buildNotificationDetails(
|
|
78
|
-
record:
|
|
78
|
+
record: Subagent,
|
|
79
79
|
resultMaxLen: number,
|
|
80
80
|
activity?: AgentActivityTracker,
|
|
81
81
|
): NotificationDetails {
|
|
@@ -100,8 +100,8 @@ export function buildNotificationDetails(
|
|
|
100
100
|
};
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
/** Build event data for lifecycle events from
|
|
104
|
-
export function buildEventData(record:
|
|
103
|
+
/** Build event data for lifecycle events from a Subagent. */
|
|
104
|
+
export function buildEventData(record: Subagent) {
|
|
105
105
|
const durationMs = record.completedAt ? record.completedAt - record.startedAt : Date.now() - record.startedAt;
|
|
106
106
|
const u = record.lifetimeUsage;
|
|
107
107
|
const total = getLifetimeTotal(u);
|
|
@@ -126,7 +126,7 @@ export function buildEventData(record: Agent) {
|
|
|
126
126
|
|
|
127
127
|
export interface NotificationSystem {
|
|
128
128
|
cancelNudge: (key: string) => void;
|
|
129
|
-
sendCompletion: (record:
|
|
129
|
+
sendCompletion: (record: Subagent) => void;
|
|
130
130
|
cleanupCompleted: (id: string) => void;
|
|
131
131
|
dispose: () => void;
|
|
132
132
|
}
|
|
@@ -154,7 +154,7 @@ export class NotificationManager implements NotificationSystem {
|
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
sendCompletion(record:
|
|
157
|
+
sendCompletion(record: Subagent): void {
|
|
158
158
|
this.agentActivity.delete(record.id);
|
|
159
159
|
this.markFinished(record.id);
|
|
160
160
|
this.scheduleNudge(record.id, () => this.emitIndividualNudge(record));
|
|
@@ -187,7 +187,7 @@ export class NotificationManager implements NotificationSystem {
|
|
|
187
187
|
);
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
-
private emitIndividualNudge(record:
|
|
190
|
+
private emitIndividualNudge(record: Subagent): void {
|
|
191
191
|
if (record.notification?.resultConsumed) return;
|
|
192
192
|
|
|
193
193
|
const notification = formatTaskNotification(record, 500);
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* record-observer.ts — Subscribes to session events and updates
|
|
2
|
+
* record-observer.ts — Subscribes to session events and updates Subagent stats.
|
|
3
3
|
*
|
|
4
|
-
* Replaces the scattered callback-wrapping logic in
|
|
4
|
+
* Replaces the scattered callback-wrapping logic in SubagentManager's startAgent()
|
|
5
5
|
* and resume() with a single direct subscription.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type {
|
|
8
|
+
import type { Subagent } from "#src/lifecycle/subagent";
|
|
9
9
|
import type { CompactionInfo, SubscribableSession } from "#src/types";
|
|
10
10
|
|
|
11
|
-
export interface
|
|
12
|
-
onCompact?: (record:
|
|
11
|
+
export interface SubagentObserverOptions {
|
|
12
|
+
onCompact?: (record: Subagent, info: CompactionInfo) => void;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* Subscribe to session events and accumulate stats on the
|
|
16
|
+
* Subscribe to session events and accumulate stats on the subagent record.
|
|
17
17
|
*
|
|
18
18
|
* Handles:
|
|
19
19
|
* - `tool_execution_end` → `record.incrementToolUses()`
|
|
@@ -22,10 +22,10 @@ export interface AgentObserverOptions {
|
|
|
22
22
|
*
|
|
23
23
|
* @returns An unsubscribe function.
|
|
24
24
|
*/
|
|
25
|
-
export function
|
|
25
|
+
export function subscribeSubagentObserver(
|
|
26
26
|
session: SubscribableSession,
|
|
27
|
-
record:
|
|
28
|
-
options?:
|
|
27
|
+
record: Subagent,
|
|
28
|
+
options?: SubagentObserverOptions,
|
|
29
29
|
): () => void {
|
|
30
30
|
return session.subscribe((event) => {
|
|
31
31
|
if (event.type === "tool_execution_end") {
|
package/src/runtime.ts
CHANGED
|
@@ -49,7 +49,7 @@ export class SubagentRuntime {
|
|
|
49
49
|
*/
|
|
50
50
|
readonly agentActivity: Map<string, AgentActivityTracker> = new Map();
|
|
51
51
|
/**
|
|
52
|
-
* Persistent widget reference. Null until constructed after
|
|
52
|
+
* Persistent widget reference. Null until constructed after SubagentManager.
|
|
53
53
|
* Delegation methods use optional chaining so callers never need `widget!`.
|
|
54
54
|
*/
|
|
55
55
|
widget: WidgetLike | null = null;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* service-adapter.ts — Adapter that wraps
|
|
2
|
+
* service-adapter.ts — Adapter that wraps SubagentManager to satisfy SubagentsService.
|
|
3
3
|
*
|
|
4
4
|
* Handles model resolution at the API boundary, record serialization
|
|
5
5
|
* (stripping non-serializable fields), and session gating.
|
|
@@ -9,13 +9,13 @@ import type { ParentSnapshot } from "#src/lifecycle/parent-snapshot";
|
|
|
9
9
|
import type { WorkspaceProvider } from "#src/lifecycle/workspace";
|
|
10
10
|
import type { SpawnOptions, SubagentRecord, SubagentsService } from "#src/service/service";
|
|
11
11
|
import type { ModelRegistry } from "#src/session/model-resolver";
|
|
12
|
-
import type {
|
|
12
|
+
import type { SessionContext, Subagent } from "#src/types";
|
|
13
13
|
|
|
14
|
-
/** Narrow interface for the
|
|
15
|
-
export interface
|
|
14
|
+
/** Narrow interface for the SubagentManager — avoids coupling to the concrete class. */
|
|
15
|
+
export interface SubagentManagerLike {
|
|
16
16
|
spawn(snapshot: ParentSnapshot, type: string, prompt: string, options: unknown): string;
|
|
17
|
-
getRecord(id: string):
|
|
18
|
-
listAgents():
|
|
17
|
+
getRecord(id: string): Subagent | undefined;
|
|
18
|
+
listAgents(): Subagent[];
|
|
19
19
|
abort(id: string): boolean;
|
|
20
20
|
waitForAll(): Promise<void>;
|
|
21
21
|
hasRunning(): boolean;
|
|
@@ -31,10 +31,10 @@ export interface ServiceRuntimeLike {
|
|
|
31
31
|
buildSnapshot(inheritContext: boolean): ParentSnapshot;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
/** Adapter that wraps
|
|
34
|
+
/** Adapter that wraps SubagentManager to satisfy SubagentsService. */
|
|
35
35
|
export class SubagentsServiceAdapter implements SubagentsService {
|
|
36
36
|
constructor(
|
|
37
|
-
private readonly manager:
|
|
37
|
+
private readonly manager: SubagentManagerLike,
|
|
38
38
|
private readonly resolveModel: (input: string, registry: ModelRegistry) => unknown,
|
|
39
39
|
private readonly runtime: ServiceRuntimeLike,
|
|
40
40
|
) {}
|
|
@@ -108,10 +108,10 @@ export class SubagentsServiceAdapter implements SubagentsService {
|
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
/**
|
|
111
|
-
* Convert an internal
|
|
111
|
+
* Convert an internal Subagent to a serializable SubagentRecord.
|
|
112
112
|
* Uses an explicit allowlist — new fields must be opted in.
|
|
113
113
|
*/
|
|
114
|
-
export function toSubagentRecord(record:
|
|
114
|
+
export function toSubagentRecord(record: Subagent): SubagentRecord {
|
|
115
115
|
const out: SubagentRecord = {
|
|
116
116
|
id: record.id,
|
|
117
117
|
type: record.type,
|
package/src/service/service.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* svc?.spawn("Explore", "Check for stale TODOs");
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
+
import type { SubagentStatus } from "#src/lifecycle/subagent";
|
|
12
13
|
import type { LifetimeUsage } from "#src/lifecycle/usage";
|
|
13
14
|
import type {
|
|
14
15
|
Workspace,
|
|
@@ -18,6 +19,10 @@ import type {
|
|
|
18
19
|
WorkspaceProvider,
|
|
19
20
|
} from "#src/lifecycle/workspace";
|
|
20
21
|
|
|
22
|
+
|
|
23
|
+
// SubagentStatus is defined in the lifecycle layer (single home) and re-exported
|
|
24
|
+
// here for the public API surface — mirrors the LifetimeUsage / workspace pattern.
|
|
25
|
+
export type { SubagentStatus } from "#src/lifecycle/subagent";
|
|
21
26
|
// Generative extension seam (ADR 0002, Phase 16 Step 2). The provider type
|
|
22
27
|
// and all four collaborator types it references are re-exported by name so
|
|
23
28
|
// consumers can import them directly rather than recovering them via
|
|
@@ -31,15 +36,6 @@ export type {
|
|
|
31
36
|
WorkspaceProvider,
|
|
32
37
|
};
|
|
33
38
|
|
|
34
|
-
export type SubagentStatus =
|
|
35
|
-
| "queued"
|
|
36
|
-
| "running"
|
|
37
|
-
| "completed"
|
|
38
|
-
| "steered"
|
|
39
|
-
| "aborted"
|
|
40
|
-
| "stopped"
|
|
41
|
-
| "error";
|
|
42
|
-
|
|
43
39
|
/** Serializable snapshot of an agent's state — no live session objects. */
|
|
44
40
|
export interface SubagentRecord {
|
|
45
41
|
id: string;
|
package/src/tools/agent-tool.ts
CHANGED
|
@@ -4,14 +4,14 @@ import { defineTool } from "@earendil-works/pi-coding-agent";
|
|
|
4
4
|
import { Text } from "@earendil-works/pi-tui";
|
|
5
5
|
import { Type } from "@sinclair/typebox";
|
|
6
6
|
import { AgentTypeRegistry } from "#src/config/agent-types";
|
|
7
|
-
import type { AgentSpawnConfig } from "#src/lifecycle/agent-manager";
|
|
8
7
|
import type { ParentSnapshot } from "#src/lifecycle/parent-snapshot";
|
|
8
|
+
import type { AgentSpawnConfig } from "#src/lifecycle/subagent-manager";
|
|
9
9
|
import { spawnBackground } from "#src/tools/background-spawner";
|
|
10
10
|
import { runForeground } from "#src/tools/foreground-runner";
|
|
11
11
|
import { buildDetails, buildTypeListText, textResult } from "#src/tools/helpers";
|
|
12
12
|
import { renderAgentResult } from "#src/tools/result-renderer";
|
|
13
13
|
import { type ModelInfo, resolveSpawnConfig } from "#src/tools/spawn-config";
|
|
14
|
-
import type {
|
|
14
|
+
import type { ParentSessionInfo, Subagent } from "#src/types";
|
|
15
15
|
import { AgentActivityTracker } from "#src/ui/agent-activity-tracker";
|
|
16
16
|
import { type UICtx } from "#src/ui/agent-widget";
|
|
17
17
|
import { type AgentDetails, getDisplayName } from "#src/ui/display";
|
|
@@ -33,9 +33,9 @@ export interface AgentActivityAccess {
|
|
|
33
33
|
/** Narrow manager interface — only the methods the Agent tool calls. */
|
|
34
34
|
export interface AgentToolManager {
|
|
35
35
|
spawn: (snapshot: ParentSnapshot, type: string, prompt: string, opts: AgentSpawnConfig) => string;
|
|
36
|
-
spawnAndWait: (snapshot: ParentSnapshot, type: string, prompt: string, opts: Omit<AgentSpawnConfig, "isBackground">) => Promise<
|
|
37
|
-
resume: (id: string, prompt: string, signal: AbortSignal) => Promise<
|
|
38
|
-
getRecord: (id: string) =>
|
|
36
|
+
spawnAndWait: (snapshot: ParentSnapshot, type: string, prompt: string, opts: Omit<AgentSpawnConfig, "isBackground">) => Promise<Subagent>;
|
|
37
|
+
resume: (id: string, prompt: string, signal: AbortSignal) => Promise<Subagent | undefined>;
|
|
38
|
+
getRecord: (id: string) => Subagent | undefined;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/** Narrow runtime interface — the Agent tool's slice of SubagentRuntime. */
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import type { AgentSpawnConfig } from "#src/lifecycle/agent-manager";
|
|
2
1
|
import type { ParentSnapshot } from "#src/lifecycle/parent-snapshot";
|
|
2
|
+
import type { AgentSpawnConfig } from "#src/lifecycle/subagent-manager";
|
|
3
3
|
import type { AgentActivityAccess } from "#src/tools/agent-tool";
|
|
4
4
|
import { textResult } from "#src/tools/helpers";
|
|
5
5
|
import type { ResolvedSpawnConfig } from "#src/tools/spawn-config";
|
|
6
|
-
import type {
|
|
6
|
+
import type { ParentSessionInfo, Subagent } from "#src/types";
|
|
7
7
|
import { AgentActivityTracker } from "#src/ui/agent-activity-tracker";
|
|
8
8
|
import { subscribeUIObserver } from "#src/ui/ui-observer";
|
|
9
9
|
|
|
10
10
|
/** Narrow manager interface for the background spawner. */
|
|
11
11
|
export interface BackgroundManagerDeps {
|
|
12
12
|
spawn(snapshot: ParentSnapshot, type: string, prompt: string, opts: AgentSpawnConfig): string;
|
|
13
|
-
getRecord(id: string):
|
|
13
|
+
getRecord(id: string): Subagent | undefined;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
/** Narrow widget interface for the background spawner. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AgentToolResult } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import type { AgentSpawnConfig } from "#src/lifecycle/agent-manager";
|
|
3
2
|
import type { ParentSnapshot } from "#src/lifecycle/parent-snapshot";
|
|
3
|
+
import type { AgentSpawnConfig } from "#src/lifecycle/subagent-manager";
|
|
4
4
|
import type { AgentActivityAccess } from "#src/tools/agent-tool";
|
|
5
5
|
import {
|
|
6
6
|
buildDetails,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
textResult,
|
|
10
10
|
} from "#src/tools/helpers";
|
|
11
11
|
import type { ResolvedSpawnConfig } from "#src/tools/spawn-config";
|
|
12
|
-
import type {
|
|
12
|
+
import type { ParentSessionInfo, Subagent } from "#src/types";
|
|
13
13
|
import { AgentActivityTracker } from "#src/ui/agent-activity-tracker";
|
|
14
14
|
import {
|
|
15
15
|
type AgentDetails,
|
|
@@ -26,7 +26,7 @@ export interface ForegroundManagerDeps {
|
|
|
26
26
|
type: string,
|
|
27
27
|
prompt: string,
|
|
28
28
|
opts: Omit<AgentSpawnConfig, "isBackground">,
|
|
29
|
-
): Promise<
|
|
29
|
+
): Promise<Subagent>;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
/** Narrow widget interface for the foreground runner. */
|
|
@@ -62,7 +62,7 @@ export async function runForeground(
|
|
|
62
62
|
|
|
63
63
|
const fgState = new AgentActivityTracker(execution.effectiveMaxTurns);
|
|
64
64
|
let unsubUI: (() => void) | undefined;
|
|
65
|
-
let recordRef:
|
|
65
|
+
let recordRef: Subagent | undefined;
|
|
66
66
|
|
|
67
67
|
const streamUpdate = () => {
|
|
68
68
|
const toolUses = recordRef?.toolUses ?? 0;
|
|
@@ -92,7 +92,7 @@ export async function runForeground(
|
|
|
92
92
|
|
|
93
93
|
streamUpdate();
|
|
94
94
|
|
|
95
|
-
let record:
|
|
95
|
+
let record: Subagent;
|
|
96
96
|
try {
|
|
97
97
|
record = await manager.spawnAndWait(
|
|
98
98
|
params.snapshot,
|
|
@@ -2,13 +2,13 @@ import { defineTool } from "@earendil-works/pi-coding-agent";
|
|
|
2
2
|
import { Type } from "@sinclair/typebox";
|
|
3
3
|
import type { AgentConfigLookup } from "#src/config/agent-types";
|
|
4
4
|
import { formatLifetimeTokens, textResult } from "#src/tools/helpers";
|
|
5
|
-
import type {
|
|
5
|
+
import type { Subagent } from "#src/types";
|
|
6
6
|
import { formatDuration, getDisplayName } from "#src/ui/display";
|
|
7
7
|
|
|
8
8
|
// ---- Deps interfaces ----
|
|
9
9
|
|
|
10
10
|
export interface GetResultToolManager {
|
|
11
|
-
getRecord(id: string):
|
|
11
|
+
getRecord(id: string): Subagent | undefined;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export interface GetResultToolNotifications {
|
package/src/tools/steer-tool.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { defineTool } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { Type } from "@sinclair/typebox";
|
|
3
3
|
import { formatLifetimeTokens, textResult } from "#src/tools/helpers";
|
|
4
|
-
import type {
|
|
4
|
+
import type { Subagent } from "#src/types";
|
|
5
5
|
|
|
6
6
|
// ---- Deps interfaces ----
|
|
7
7
|
|
|
8
8
|
export interface SteerToolManager {
|
|
9
|
-
getRecord(id: string):
|
|
9
|
+
getRecord(id: string): Subagent | undefined;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export interface SteerToolEvents {
|
package/src/types.ts
CHANGED
|
@@ -7,7 +7,7 @@ import type { AgentSessionEvent } from "@earendil-works/pi-coding-agent";
|
|
|
7
7
|
import type { ModelRegistry } from "#src/session/model-resolver";
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
export {
|
|
10
|
+
export { Subagent } from "#src/lifecycle/subagent";
|
|
11
11
|
export type { AgentSessionEvent, ThinkingLevel };
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -9,7 +9,7 @@ import { join } from "node:path";
|
|
|
9
9
|
|
|
10
10
|
import { BUILTIN_TOOL_NAMES } from "#src/config/agent-types";
|
|
11
11
|
import type { ParentSnapshot } from "#src/lifecycle/parent-snapshot";
|
|
12
|
-
import type {
|
|
12
|
+
import type { Subagent } from "#src/types";
|
|
13
13
|
import type { AgentFileOps } from "#src/ui/agent-file-ops";
|
|
14
14
|
import { writeAgentFile } from "#src/ui/agent-file-writer";
|
|
15
15
|
import type { MenuUI } from "#src/ui/agent-menu";
|
|
@@ -23,7 +23,7 @@ export interface WizardManager {
|
|
|
23
23
|
type: string,
|
|
24
24
|
prompt: string,
|
|
25
25
|
opts: { description: string; maxTurns: number },
|
|
26
|
-
) => Promise<
|
|
26
|
+
) => Promise<Subagent>;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/** Narrow registry interface for reloading after creation. */
|
package/src/ui/agent-menu.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { AgentTypeRegistry } from "#src/config/agent-types";
|
|
|
4
4
|
import type { ParentSnapshot } from "#src/lifecycle/parent-snapshot";
|
|
5
5
|
import { type ModelRegistry, resolveModel } from "#src/session/model-resolver";
|
|
6
6
|
import { getModelLabelFromConfig } from "#src/tools/helpers";
|
|
7
|
-
import type {
|
|
7
|
+
import type { AgentConfig, Subagent } from "#src/types";
|
|
8
8
|
import type { AgentActivityTracker } from "#src/ui/agent-activity-tracker";
|
|
9
9
|
import { AgentConfigEditor } from "#src/ui/agent-config-editor";
|
|
10
10
|
import { AgentCreationWizard } from "#src/ui/agent-creation-wizard";
|
|
@@ -15,15 +15,15 @@ import { formatDuration, getDisplayName } from "#src/ui/display";
|
|
|
15
15
|
|
|
16
16
|
/** Narrow manager interface for menu operations. */
|
|
17
17
|
export interface AgentMenuManager {
|
|
18
|
-
listAgents: () =>
|
|
19
|
-
getRecord: (id: string) =>
|
|
18
|
+
listAgents: () => Subagent[];
|
|
19
|
+
getRecord: (id: string) => Subagent | undefined;
|
|
20
20
|
/** Used by generate wizard to spawn an agent that writes the .md file. */
|
|
21
21
|
spawnAndWait: (
|
|
22
22
|
parentSnapshot: ParentSnapshot,
|
|
23
23
|
type: string,
|
|
24
24
|
prompt: string,
|
|
25
25
|
opts: { description: string; maxTurns: number },
|
|
26
|
-
) => Promise<
|
|
26
|
+
) => Promise<Subagent>;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/** Narrow settings interface required by the agent menu. */
|
|
@@ -251,7 +251,7 @@ export class AgentsMenuHandler {
|
|
|
251
251
|
await this.showRunningAgents(ui);
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
-
private async viewAgentConversation(ui: MenuUI, record:
|
|
254
|
+
private async viewAgentConversation(ui: MenuUI, record: Subagent): Promise<void> {
|
|
255
255
|
if (!record.isSessionReady()) {
|
|
256
256
|
ui.notify(
|
|
257
257
|
`Agent is ${record.status === "queued" ? "queued" : "expired"} — no session available.`,
|
package/src/ui/agent-widget.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { AgentTypeRegistry } from "#src/config/agent-types";
|
|
10
|
-
import type {
|
|
10
|
+
import type { SubagentManager } from "#src/lifecycle/subagent-manager";
|
|
11
11
|
import type { AgentActivityTracker } from "#src/ui/agent-activity-tracker";
|
|
12
12
|
import { ERROR_STATUSES, type Theme } from "#src/ui/display";
|
|
13
13
|
import { renderWidgetLines } from "#src/ui/widget-renderer";
|
|
@@ -78,7 +78,7 @@ export class AgentWidget {
|
|
|
78
78
|
private lastStatusText: string | undefined;
|
|
79
79
|
|
|
80
80
|
constructor(
|
|
81
|
-
private manager:
|
|
81
|
+
private manager: SubagentManager,
|
|
82
82
|
private agentActivity: Map<string, AgentActivityTracker>,
|
|
83
83
|
private registry: AgentTypeRegistry,
|
|
84
84
|
) {}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import { type Component, matchesKey, type TUI, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
9
9
|
import type { AgentConfigLookup } from "#src/config/agent-types";
|
|
10
10
|
import { getLifetimeTotal } from "#src/lifecycle/usage";
|
|
11
|
-
import type {
|
|
11
|
+
import type { Subagent } from "#src/types";
|
|
12
12
|
import type { AgentActivityTracker } from "#src/ui/agent-activity-tracker";
|
|
13
13
|
import { buildInvocationTags, formatDuration, formatSessionTokens, getDisplayName, getPromptModeLabel, type Theme } from "#src/ui/display";
|
|
14
14
|
import { formatMessage, formatStreamingIndicator } from "#src/ui/message-formatters";
|
|
@@ -23,7 +23,7 @@ export const VIEWPORT_HEIGHT_PCT = 70;
|
|
|
23
23
|
|
|
24
24
|
export interface ConversationViewerOptions {
|
|
25
25
|
tui: TUI;
|
|
26
|
-
record:
|
|
26
|
+
record: Subagent;
|
|
27
27
|
activity: AgentActivityTracker | undefined;
|
|
28
28
|
theme: Theme;
|
|
29
29
|
done: (result: undefined) => void;
|
|
@@ -39,7 +39,7 @@ export class ConversationViewer implements Component {
|
|
|
39
39
|
private closed = false;
|
|
40
40
|
|
|
41
41
|
private tui: TUI;
|
|
42
|
-
private record:
|
|
42
|
+
private record: Subagent;
|
|
43
43
|
private activity: AgentActivityTracker | undefined;
|
|
44
44
|
private theme: Theme;
|
|
45
45
|
private done: (result: undefined) => void;
|