pi-subagents-j0k3r 1.3.0 → 1.3.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/CHANGELOG.md +14 -0
- package/package.json +1 -1
- package/src/manager.ts +13 -2
- package/src/render/tools/subagent-list-agents.ts +45 -0
- package/src/render/types.ts +1 -1
- package/src/runner/event-processing.ts +4 -8
- package/src/runner/snapshot-builder.ts +2 -6
- package/src/tools/subagent-list-agents.ts +10 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.3.1 - 2026-07-13
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- Fixed `/subagents` live rendering so `toolcall_delta` argument JSON is no longer displayed as assistant text before native tool cards.
|
|
7
|
+
- Preserved streamed thinking output while routing only `text_delta` events into assistant text, matching Pi's main-thread rendering behavior.
|
|
8
|
+
|
|
9
|
+
## 1.3.0 - 2026-07-12
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- Modularized extension composition, tools, renderers, UI, runner, and model-profile code into cohesive modules.
|
|
13
|
+
- Split each registered subagent tool into a dedicated file and separated complex rendering responsibilities.
|
|
14
|
+
- Reorganized monolithic tests into 24 domain-focused files with 206 passing scenarios.
|
|
15
|
+
- Preserved root exports, historical deep imports, runtime behavior, tool contracts, package contents, and privacy boundaries.
|
|
16
|
+
|
|
3
17
|
## 1.2.1 - 2026-07-12
|
|
4
18
|
|
|
5
19
|
### Fixed
|
package/package.json
CHANGED
package/src/manager.ts
CHANGED
|
@@ -175,8 +175,19 @@ export class SubagentManager {
|
|
|
175
175
|
private onTerminalBackgroundTask?: (task: SubagentTask) => void,
|
|
176
176
|
) {}
|
|
177
177
|
|
|
178
|
-
listAgents(cwd: string) {
|
|
179
|
-
|
|
178
|
+
listAgents(cwd: string, ctx: any = {}) {
|
|
179
|
+
const config = readSubagentsConfig(cwd);
|
|
180
|
+
return loadSubagents(cwd).map((definition) => {
|
|
181
|
+
const profile = resolveEffectiveSubagentProfile({ agentName: definition.name, definition, config, ctx });
|
|
182
|
+
return {
|
|
183
|
+
name: definition.name,
|
|
184
|
+
description: definition.description,
|
|
185
|
+
filePath: definition.filePath,
|
|
186
|
+
tools: definition.tools,
|
|
187
|
+
model: profile.model.value,
|
|
188
|
+
effort: profile.effort.value,
|
|
189
|
+
};
|
|
190
|
+
});
|
|
180
191
|
}
|
|
181
192
|
|
|
182
193
|
listTasks(cwd?: string) {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { ModelRef, ThinkingEffort } from '../types.js';
|
|
2
|
+
import { textComponent } from './components.js';
|
|
3
|
+
|
|
4
|
+
export type ListedSubagent = {
|
|
5
|
+
name: string;
|
|
6
|
+
model?: ModelRef;
|
|
7
|
+
effort?: ThinkingEffort;
|
|
8
|
+
tools: string[];
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
function modelLabel(model?: ModelRef): string {
|
|
12
|
+
return model ? `${model.provider}/${model.id}` : 'default/current';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function summary(agent: ListedSubagent): string {
|
|
16
|
+
return `${agent.name} · model: ${modelLabel(agent.model)} · effort: ${agent.effort ?? 'default/current'}`;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function formatSubagentList(agents: ListedSubagent[], includeTools: boolean): string {
|
|
20
|
+
if (!agents.length) return 'No subagents available.';
|
|
21
|
+
return agents.map((agent) => (
|
|
22
|
+
includeTools ? `${summary(agent)} · tools: ${agent.tools.join(', ') || 'none'}` : summary(agent)
|
|
23
|
+
)).join('\n');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function renderSubagentListResult(result: any, expanded: boolean, theme: any) {
|
|
27
|
+
const agents: ListedSubagent[] = Array.isArray(result?.details?.agents) ? result.details.agents : [];
|
|
28
|
+
if (!agents.length) return textComponent('No subagents available.');
|
|
29
|
+
const dim = (text: string) => theme?.fg?.('dim', text) ?? text;
|
|
30
|
+
|
|
31
|
+
if (expanded) {
|
|
32
|
+
return textComponent(agents.flatMap((agent) => [
|
|
33
|
+
summary(agent),
|
|
34
|
+
dim(` tools: ${agent.tools.join(', ') || 'none'}`),
|
|
35
|
+
]).join('\n'));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const visible = agents.slice(0, 5);
|
|
39
|
+
const hidden = agents.length - visible.length;
|
|
40
|
+
return textComponent([
|
|
41
|
+
...visible.map(summary),
|
|
42
|
+
hidden > 0 ? dim(`… ${hidden} more agents hidden`) : undefined,
|
|
43
|
+
dim('ctrl+o to expand'),
|
|
44
|
+
].filter((line): line is string => Boolean(line)).join('\n'));
|
|
45
|
+
}
|
package/src/render/types.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export type { SubagentTask } from '../types.js';
|
|
1
|
+
export type { ModelRef, SubagentTask, ThinkingEffort } from '../types.js';
|
|
@@ -64,11 +64,9 @@ function formatToolCall(name: string, args: any): string {
|
|
|
64
64
|
|
|
65
65
|
function eventTranscript(event: any): string {
|
|
66
66
|
const messageEvent = event?.assistantMessageEvent;
|
|
67
|
-
const delta = messageEvent?.type
|
|
67
|
+
const delta = messageEvent?.type === 'text_delta' && typeof messageEvent.delta === 'string'
|
|
68
68
|
? messageEvent.delta
|
|
69
|
-
:
|
|
70
|
-
? messageEvent.delta
|
|
71
|
-
: undefined;
|
|
69
|
+
: undefined;
|
|
72
70
|
if (event?.type === 'message_update' && typeof delta === 'string') return sanitizeInteractionTransportText(delta);
|
|
73
71
|
|
|
74
72
|
if (event?.type === 'tool_execution_start') {
|
|
@@ -188,11 +186,9 @@ export async function promptWithInactivity(
|
|
|
188
186
|
}
|
|
189
187
|
}
|
|
190
188
|
const messageEvent = event?.assistantMessageEvent;
|
|
191
|
-
const delta = messageEvent?.type
|
|
189
|
+
const delta = messageEvent?.type === 'text_delta' && typeof messageEvent.delta === 'string'
|
|
192
190
|
? messageEvent.delta
|
|
193
|
-
:
|
|
194
|
-
? messageEvent.delta
|
|
195
|
-
: undefined;
|
|
191
|
+
: undefined;
|
|
196
192
|
if (event?.type === 'message_end' && event.message?.role === 'assistant') usage = addUsage(usage, event.message.usage);
|
|
197
193
|
if (event?.type === 'message_update' && typeof delta === 'string') {
|
|
198
194
|
output += sanitizeInteractionTransportText(delta);
|
|
@@ -103,12 +103,8 @@ export class ThreadSnapshotBuilder {
|
|
|
103
103
|
update(event: any): void {
|
|
104
104
|
const now = new Date().toISOString();
|
|
105
105
|
const messageEvent = event?.assistantMessageEvent;
|
|
106
|
-
const textDelta = event?.type === 'message_update' && messageEvent?.type
|
|
107
|
-
?
|
|
108
|
-
? messageEvent.delta
|
|
109
|
-
: messageEvent?.type === 'text_delta' && typeof messageEvent.delta === 'string'
|
|
110
|
-
? messageEvent.delta
|
|
111
|
-
: undefined
|
|
106
|
+
const textDelta = event?.type === 'message_update' && messageEvent?.type === 'text_delta' && typeof messageEvent.delta === 'string'
|
|
107
|
+
? messageEvent.delta
|
|
112
108
|
: undefined;
|
|
113
109
|
const thinkingDelta = event?.type === 'message_update' && messageEvent?.type === 'thinking_delta' && typeof messageEvent.delta === 'string'
|
|
114
110
|
? messageEvent.delta
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Type } from 'typebox';
|
|
2
2
|
import type { SubagentManager } from '../manager.js';
|
|
3
|
+
import { formatSubagentList, renderSubagentListResult } from '../render/tools/subagent-list-agents.js';
|
|
3
4
|
import { ok, fail } from './tool-response.js';
|
|
4
5
|
|
|
5
6
|
export function createSubagentListAgentsTool(manager: SubagentManager) {
|
|
@@ -10,7 +11,15 @@ export function createSubagentListAgentsTool(manager: SubagentManager) {
|
|
|
10
11
|
promptSnippet: 'List available subagents loaded from global/project agents and subagents markdown directories.',
|
|
11
12
|
parameters: Type.Object({}),
|
|
12
13
|
async execute(_id: string, _params: any, _signal: any, _onUpdate: any, ctx: any) {
|
|
13
|
-
try {
|
|
14
|
+
try {
|
|
15
|
+
const agents = manager.listAgents(ctx?.cwd ?? process.cwd(), ctx);
|
|
16
|
+
return ok(formatSubagentList(agents, true), { agents });
|
|
17
|
+
} catch (e) {
|
|
18
|
+
return fail(e);
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
renderResult(result: any, { expanded }: any, theme: any) {
|
|
22
|
+
return renderSubagentListResult(result, Boolean(expanded), theme);
|
|
14
23
|
},
|
|
15
24
|
};
|
|
16
25
|
}
|