@gotgenes/pi-subagents 6.3.0 → 6.4.0
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 +23 -0
- package/docs/architecture/architecture.md +234 -263
- package/docs/plans/0108-extract-agent-type-registry.md +322 -0
- package/docs/retro/0100-replace-callback-threading-with-session-subscription.md +36 -0
- package/package.json +1 -1
- package/src/agent-manager.ts +5 -0
- package/src/agent-runner.ts +4 -0
- package/src/agent-types.ts +108 -91
- package/src/index.ts +16 -21
- package/src/session-config.ts +5 -4
- package/src/tools/agent-tool.ts +8 -8
- package/src/tools/get-result-tool.ts +3 -1
- package/src/types.ts +0 -3
- package/src/ui/agent-menu.ts +23 -25
- package/src/ui/agent-widget.ts +10 -9
- package/src/ui/conversation-viewer.ts +4 -2
package/src/ui/agent-widget.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { truncateToWidth } from "@earendil-works/pi-tui";
|
|
9
9
|
import type { AgentManager } from "../agent-manager.js";
|
|
10
|
-
import {
|
|
10
|
+
import { type AgentConfigLookup, AgentTypeRegistry } from "../agent-types.js";
|
|
11
11
|
import type { AgentInvocation, SubagentType } from "../types.js";
|
|
12
12
|
import { getLifetimeTotal, getSessionContextPercent, type LifetimeUsage, type SessionLike } from "../usage.js";
|
|
13
13
|
|
|
@@ -143,14 +143,14 @@ export function formatDuration(startedAt: number, completedAt?: number): string
|
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
/** Get display name for any agent type (built-in or custom). */
|
|
146
|
-
export function getDisplayName(type: SubagentType): string {
|
|
147
|
-
const config = resolveAgentConfig(type);
|
|
146
|
+
export function getDisplayName(type: SubagentType, registry: AgentConfigLookup): string {
|
|
147
|
+
const config = registry.resolveAgentConfig(type);
|
|
148
148
|
return config.displayName ?? config.name;
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
/** Short label for prompt mode: "twin" for append, nothing for replace (the default). */
|
|
152
|
-
export function getPromptModeLabel(type: SubagentType): string | undefined {
|
|
153
|
-
const config = resolveAgentConfig(type);
|
|
152
|
+
export function getPromptModeLabel(type: SubagentType, registry: AgentConfigLookup): string | undefined {
|
|
153
|
+
const config = registry.resolveAgentConfig(type);
|
|
154
154
|
return config.promptMode === "append" ? "twin" : undefined;
|
|
155
155
|
}
|
|
156
156
|
|
|
@@ -225,6 +225,7 @@ export class AgentWidget {
|
|
|
225
225
|
constructor(
|
|
226
226
|
private manager: AgentManager,
|
|
227
227
|
private agentActivity: Map<string, AgentActivity>,
|
|
228
|
+
private registry: AgentTypeRegistry,
|
|
228
229
|
) {}
|
|
229
230
|
|
|
230
231
|
/** Set the UI context (grabbed from first tool execution). */
|
|
@@ -275,8 +276,8 @@ export class AgentWidget {
|
|
|
275
276
|
|
|
276
277
|
/** Render a finished agent line. */
|
|
277
278
|
private renderFinishedLine(a: { id: string; type: SubagentType; status: string; description: string; toolUses: number; startedAt: number; completedAt?: number; error?: string }, theme: Theme): string {
|
|
278
|
-
const name = getDisplayName(a.type);
|
|
279
|
-
const modeLabel = getPromptModeLabel(a.type);
|
|
279
|
+
const name = getDisplayName(a.type, this.registry);
|
|
280
|
+
const modeLabel = getPromptModeLabel(a.type, this.registry);
|
|
280
281
|
const duration = formatMs((a.completedAt ?? Date.now()) - a.startedAt);
|
|
281
282
|
|
|
282
283
|
let icon: string;
|
|
@@ -345,8 +346,8 @@ export class AgentWidget {
|
|
|
345
346
|
|
|
346
347
|
const runningLines: string[][] = []; // each entry is [header, activity]
|
|
347
348
|
for (const a of running) {
|
|
348
|
-
const name = getDisplayName(a.type);
|
|
349
|
-
const modeLabel = getPromptModeLabel(a.type);
|
|
349
|
+
const name = getDisplayName(a.type, this.registry);
|
|
350
|
+
const modeLabel = getPromptModeLabel(a.type, this.registry);
|
|
350
351
|
const modeTag = modeLabel ? ` ${theme.fg("dim", `(${modeLabel})`)}` : "";
|
|
351
352
|
const elapsed = formatMs(Date.now() - a.startedAt);
|
|
352
353
|
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import type { AgentSession } from "@earendil-works/pi-coding-agent";
|
|
9
9
|
import { type Component, matchesKey, type TUI, truncateToWidth, visibleWidth, wrapTextWithAnsi } from "@earendil-works/pi-tui";
|
|
10
|
+
import type { AgentConfigLookup } from "../agent-types.js";
|
|
10
11
|
import { extractText } from "../context.js";
|
|
11
12
|
import type { AgentRecord } from "../types.js";
|
|
12
13
|
import { getLifetimeTotal, getSessionContextPercent } from "../usage.js";
|
|
@@ -33,6 +34,7 @@ export class ConversationViewer implements Component {
|
|
|
33
34
|
private activity: AgentActivity | undefined,
|
|
34
35
|
private theme: Theme,
|
|
35
36
|
private done: (result: undefined) => void,
|
|
37
|
+
private registry: AgentConfigLookup,
|
|
36
38
|
) {
|
|
37
39
|
this.unsubscribe = session.subscribe(() => {
|
|
38
40
|
if (this.closed) return;
|
|
@@ -91,8 +93,8 @@ export class ConversationViewer implements Component {
|
|
|
91
93
|
|
|
92
94
|
// Header
|
|
93
95
|
lines.push(hrTop);
|
|
94
|
-
const name = getDisplayName(this.record.type);
|
|
95
|
-
const modeLabel = getPromptModeLabel(this.record.type);
|
|
96
|
+
const name = getDisplayName(this.record.type, this.registry);
|
|
97
|
+
const modeLabel = getPromptModeLabel(this.record.type, this.registry);
|
|
96
98
|
const modeTag = modeLabel ? ` ${th.fg("dim", `(${modeLabel})`)}` : "";
|
|
97
99
|
const statusIcon = this.record.status === "running"
|
|
98
100
|
? th.fg("accent", "●")
|