@johnnywu/pi-subagents 1.0.1 → 1.1.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 +7 -0
- package/extensions/env-utils.ts +26 -0
- package/extensions/subagent-tool.ts +9 -27
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# [1.1.0](https://github.com/jwu/pi-subagents/compare/v1.0.1...v1.1.0) (2026-05-31)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* **subagent:** list available agents in system prompt Guidelines ([317ed58](https://github.com/jwu/pi-subagents/commit/317ed5845379d3edd535bc03dab8460b29a82164))
|
|
7
|
+
|
|
1
8
|
## [1.0.1](https://github.com/jwu/pi-subagents/compare/v1.0.0...v1.0.1) (2026-05-31)
|
|
2
9
|
|
|
3
10
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type RecursionEnv = Partial<
|
|
2
|
+
Record<'PI_SUBAGENT_ALLOWED' | 'PI_SUBAGENT_DEPTH' | 'PI_SUBAGENT_MAX_DEPTH', string>
|
|
3
|
+
>;
|
|
4
|
+
|
|
5
|
+
export function parseEnvNumber(value: string | undefined): number | undefined {
|
|
6
|
+
if (value === undefined) return undefined;
|
|
7
|
+
const parsed = Number(value);
|
|
8
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function allowedAgentNames(env: RecursionEnv): Set<string> | undefined {
|
|
12
|
+
const raw = env?.PI_SUBAGENT_ALLOWED;
|
|
13
|
+
if (!raw) return undefined;
|
|
14
|
+
return new Set(
|
|
15
|
+
raw
|
|
16
|
+
.split(',')
|
|
17
|
+
.map((name) => name.trim())
|
|
18
|
+
.filter(Boolean),
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function isPastMaxDepth(env: RecursionEnv): boolean {
|
|
23
|
+
const depth = parseEnvNumber(env?.PI_SUBAGENT_DEPTH);
|
|
24
|
+
const maxDepth = parseEnvNumber(env?.PI_SUBAGENT_MAX_DEPTH);
|
|
25
|
+
return depth !== undefined && maxDepth !== undefined && depth > maxDepth;
|
|
26
|
+
}
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
type SubagentResultLine,
|
|
18
18
|
} from './subagent-render.ts';
|
|
19
19
|
import { numberArg, preview, shortenPath, stringArg } from './tool-args.ts';
|
|
20
|
+
import { allowedAgentNames, isPastMaxDepth, type RecursionEnv } from './env-utils.ts';
|
|
20
21
|
|
|
21
22
|
const SubagentParams = {
|
|
22
23
|
type: 'object',
|
|
@@ -36,10 +37,6 @@ type SubagentParamsType = {
|
|
|
36
37
|
};
|
|
37
38
|
|
|
38
39
|
type RegisterablePi = Pick<ExtensionAPI, 'registerTool'>;
|
|
39
|
-
type RecursionEnv = Partial<
|
|
40
|
-
Record<'PI_SUBAGENT_ALLOWED' | 'PI_SUBAGENT_DEPTH' | 'PI_SUBAGENT_MAX_DEPTH', string>
|
|
41
|
-
>;
|
|
42
|
-
|
|
43
40
|
export interface RegisterSubagentToolOptions {
|
|
44
41
|
agents: AgentConfig[];
|
|
45
42
|
run?: typeof runSubagent;
|
|
@@ -70,29 +67,6 @@ function toProgressResult(progress: AgentProgress) {
|
|
|
70
67
|
};
|
|
71
68
|
}
|
|
72
69
|
|
|
73
|
-
function parseEnvNumber(value: string | undefined): number | undefined {
|
|
74
|
-
if (value === undefined) return undefined;
|
|
75
|
-
const parsed = Number(value);
|
|
76
|
-
return Number.isFinite(parsed) ? parsed : undefined;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function allowedAgentNames(env: RecursionEnv): Set<string> | undefined {
|
|
80
|
-
const raw = env?.PI_SUBAGENT_ALLOWED;
|
|
81
|
-
if (!raw) return undefined;
|
|
82
|
-
return new Set(
|
|
83
|
-
raw
|
|
84
|
-
.split(',')
|
|
85
|
-
.map((name) => name.trim())
|
|
86
|
-
.filter(Boolean),
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function isPastMaxDepth(env: RecursionEnv): boolean {
|
|
91
|
-
const depth = parseEnvNumber(env?.PI_SUBAGENT_DEPTH);
|
|
92
|
-
const maxDepth = parseEnvNumber(env?.PI_SUBAGENT_MAX_DEPTH);
|
|
93
|
-
return depth !== undefined && maxDepth !== undefined && depth > maxDepth;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
70
|
type CollapsedTheme = {
|
|
97
71
|
fg: (name: ThemeColor, text: string) => string;
|
|
98
72
|
bold: (text: string) => string;
|
|
@@ -243,11 +217,19 @@ export function registerSubagentTool(
|
|
|
243
217
|
: options.agents;
|
|
244
218
|
const runner = options.run ?? runSubagent;
|
|
245
219
|
|
|
220
|
+
const agentNames = agents
|
|
221
|
+
.map((a) => a.name)
|
|
222
|
+
.sort()
|
|
223
|
+
.join(', ');
|
|
224
|
+
const promptGuidelines =
|
|
225
|
+
agentNames.length > 0 ? [`Available subagents: ${agentNames}`] : undefined;
|
|
226
|
+
|
|
246
227
|
pi.registerTool({
|
|
247
228
|
name: 'subagent',
|
|
248
229
|
label: 'Subagent',
|
|
249
230
|
description: 'Delegate a task to a named sub-agent running in an isolated pi process.',
|
|
250
231
|
promptSnippet: 'Delegate isolated tasks with subagent({ agent, task, cwd? }).',
|
|
232
|
+
promptGuidelines,
|
|
251
233
|
parameters: SubagentParams,
|
|
252
234
|
|
|
253
235
|
async execute(
|