oira666_pi-subagent 0.3.7 → 0.3.9
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 +29 -4
- package/agents.ts +21 -22
- package/config.ts +81 -0
- package/index.ts +53 -46
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -56,13 +56,35 @@ Multiple tasks run in parallel:
|
|
|
56
56
|
|
|
57
57
|
Each task supports `agent` (the agent *type* to spawn) and `task`.
|
|
58
58
|
|
|
59
|
+
## Tool Prompt Overrides
|
|
60
|
+
|
|
61
|
+
The complete LLM-facing description of each extension tool can be replaced in
|
|
62
|
+
`pi-subagents.json`. Supported locations, from lowest to highest priority:
|
|
63
|
+
|
|
64
|
+
1. `~/.pi/pi-subagents.json`
|
|
65
|
+
2. `$PI_CODING_AGENT_DIR/pi-subagents.json` (normally `~/.pi/agent/pi-subagents.json`)
|
|
66
|
+
3. The nearest trusted project `.pi/pi-subagents.json`, walking up from the current directory
|
|
67
|
+
|
|
68
|
+
Project values override global values per tool. Missing prompts keep their
|
|
69
|
+
built-in defaults. Use a JSON object for `tool-prompts`:
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"tool-prompts": {
|
|
74
|
+
"subagents": "Your complete replacement prompt for the subagents tool.",
|
|
75
|
+
"resume_subagents": "Your complete replacement prompt for the resume tool."
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
59
80
|
## Bundled Agents
|
|
60
81
|
|
|
61
|
-
|
|
82
|
+
Four built-in agents ship with the extension and remain available alongside custom agents by default:
|
|
62
83
|
|
|
63
84
|
- `code-writer` — implementation and refactoring
|
|
64
85
|
- `code-reviwer` — code review and risk finding
|
|
65
86
|
- `code-architect` — technical design and approach selection
|
|
87
|
+
- `team-lead` — decomposition and delegated multi-agent implementation
|
|
66
88
|
|
|
67
89
|
## Defining Agents
|
|
68
90
|
|
|
@@ -72,8 +94,10 @@ Create Markdown files with YAML frontmatter:
|
|
|
72
94
|
- **Env agents:** `$PI_CODING_AGENT_DIR/agents/*.md` *(when `PI_CODING_AGENT_DIR` is set)*
|
|
73
95
|
- **Project agents:** `.pi/agents/*.md` *(may prompt for confirmation — see `PI_SUBAGENT_CONFIRM_PROJECT_AGENTS`)*
|
|
74
96
|
|
|
75
|
-
Agent discovery priority (highest wins on name collision): project > env >
|
|
76
|
-
Built-in agents
|
|
97
|
+
Agent discovery priority (highest wins on name collision): project > env/user > built-in.
|
|
98
|
+
Built-in agents remain available alongside custom agents unless
|
|
99
|
+
`PI_SUBAGENT_HIDE_BUILTIN_AGENTS=true`. A custom definition with the same name
|
|
100
|
+
as a built-in agent overrides that built-in definition.
|
|
77
101
|
|
|
78
102
|
```markdown
|
|
79
103
|
---
|
|
@@ -213,7 +237,8 @@ subagent *instance* by its unique name.
|
|
|
213
237
|
|
|
214
238
|
| Env Var | Description |
|
|
215
239
|
| ----------------------- | ------------------------------------------------------------ |
|
|
216
|
-
| `PI_CODING_AGENT_DIR` |
|
|
240
|
+
| `PI_CODING_AGENT_DIR` | Override Pi's agent config directory. Agents are read from `$PI_CODING_AGENT_DIR/agents/*.md`, and tool prompts from `$PI_CODING_AGENT_DIR/pi-subagents.json`. |
|
|
241
|
+
| `PI_SUBAGENT_HIDE_BUILTIN_AGENTS` | Set to `true`/`on`/`yes`/`1` to hide all bundled agents. By default they are available alongside custom agents. |
|
|
217
242
|
|
|
218
243
|
## CLI Argument Proxying
|
|
219
244
|
|
package/agents.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Lookup locations:
|
|
8
8
|
* - User agents: ~/.pi/agent/agents/*.md (or $PI_CODING_AGENT_DIR/agents/ when env var is set)
|
|
9
9
|
* - Project agents: .pi/agents/*.md (walks up from cwd)
|
|
10
|
-
* - Bundled agents: ./agents/*.md (
|
|
10
|
+
* - Bundled agents: ./agents/*.md (included unless PI_SUBAGENT_HIDE_BUILTIN_AGENTS is true)
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { getAgentDir, parseFrontmatter } from "@mariozechner/pi-coding-agent";
|
|
@@ -18,6 +18,8 @@ import { fileURLToPath } from "node:url";
|
|
|
18
18
|
export type AgentScope = "user" | "project" | "both";
|
|
19
19
|
export type AgentSource = "user" | "project" | "builtin";
|
|
20
20
|
|
|
21
|
+
export const SUBAGENT_HIDE_BUILTIN_AGENTS_ENV = "PI_SUBAGENT_HIDE_BUILTIN_AGENTS";
|
|
22
|
+
|
|
21
23
|
export interface AgentConfig {
|
|
22
24
|
name: string;
|
|
23
25
|
description: string;
|
|
@@ -167,19 +169,22 @@ function loadAgentsFromDir(dir: string, source: AgentSource): AgentConfig[] {
|
|
|
167
169
|
}
|
|
168
170
|
|
|
169
171
|
/**
|
|
170
|
-
* Merge
|
|
171
|
-
*
|
|
172
|
+
* Merge agent layers with last-write-wins deduplication by name.
|
|
173
|
+
* Layers must be passed from lowest to highest priority.
|
|
172
174
|
*/
|
|
173
|
-
function dedupeAgents(
|
|
174
|
-
userAgents: AgentConfig[],
|
|
175
|
-
projectAgents: AgentConfig[],
|
|
176
|
-
): AgentConfig[] {
|
|
175
|
+
function dedupeAgents(...layers: AgentConfig[][]): AgentConfig[] {
|
|
177
176
|
const agentMap = new Map<string, AgentConfig>();
|
|
178
|
-
for (const
|
|
179
|
-
|
|
177
|
+
for (const agents of layers) {
|
|
178
|
+
for (const agent of agents) agentMap.set(agent.name, agent);
|
|
179
|
+
}
|
|
180
180
|
return Array.from(agentMap.values());
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
+
function hideBuiltinAgents(): boolean {
|
|
184
|
+
const value = process.env[SUBAGENT_HIDE_BUILTIN_AGENTS_ENV]?.trim().toLowerCase();
|
|
185
|
+
return value === "1" || value === "true" || value === "yes" || value === "on";
|
|
186
|
+
}
|
|
187
|
+
|
|
183
188
|
// ---------------------------------------------------------------------------
|
|
184
189
|
// Public API
|
|
185
190
|
// ---------------------------------------------------------------------------
|
|
@@ -198,25 +203,19 @@ export function isAgentEnabledAtLayer(
|
|
|
198
203
|
/**
|
|
199
204
|
* Discover all available agents according to the requested scope.
|
|
200
205
|
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
206
|
+
* Built-in agents are included at the lowest priority unless
|
|
207
|
+
* PI_SUBAGENT_HIDE_BUILTIN_AGENTS is true. Custom agents with the same name
|
|
208
|
+
* override their built-in counterpart.
|
|
203
209
|
*/
|
|
204
210
|
export function discoverAgents(cwd: string, scope: AgentScope): AgentDiscoveryResult {
|
|
205
211
|
const userDir = path.join(getAgentDir(), "agents");
|
|
206
212
|
const projectAgentsDir = findNearestProjectAgentsDir(cwd);
|
|
207
213
|
|
|
214
|
+
const builtinAgents = hideBuiltinAgents() ? [] : loadAgentsFromDir(BUNDLED_AGENTS_DIR, "builtin");
|
|
208
215
|
const userAgents = loadAgentsFromDir(userDir, "user");
|
|
209
216
|
const projectAgents = projectAgentsDir ? loadAgentsFromDir(projectAgentsDir, "project") : [];
|
|
210
217
|
|
|
211
|
-
|
|
212
|
-
if (
|
|
213
|
-
|
|
214
|
-
agents: loadAgentsFromDir(BUNDLED_AGENTS_DIR, "builtin"),
|
|
215
|
-
projectAgentsDir,
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
if (scope === "user") return { agents: userAgents, projectAgentsDir };
|
|
220
|
-
if (scope === "project") return { agents: projectAgents, projectAgentsDir };
|
|
221
|
-
return { agents: dedupeAgents(userAgents, projectAgents), projectAgentsDir };
|
|
218
|
+
if (scope === "user") return { agents: dedupeAgents(builtinAgents, userAgents), projectAgentsDir };
|
|
219
|
+
if (scope === "project") return { agents: dedupeAgents(builtinAgents, projectAgents), projectAgentsDir };
|
|
220
|
+
return { agents: dedupeAgents(builtinAgents, userAgents, projectAgents), projectAgentsDir };
|
|
222
221
|
}
|
package/config.ts
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { getAgentDir } from "@mariozechner/pi-coding-agent";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as os from "node:os";
|
|
4
|
+
import * as path from "node:path";
|
|
5
|
+
|
|
6
|
+
export const PI_SUBAGENTS_CONFIG_FILE = "pi-subagents.json";
|
|
7
|
+
|
|
8
|
+
export interface PiSubagentsConfig {
|
|
9
|
+
toolPrompts: Record<string, string>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function readToolPrompts(filePath: string): Record<string, string> {
|
|
13
|
+
if (!fs.existsSync(filePath)) return {};
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
const parsed = JSON.parse(fs.readFileSync(filePath, "utf8")) as unknown;
|
|
17
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
18
|
+
console.warn(`[pi-subagent] Ignoring invalid config "${filePath}". Expected a JSON object.`);
|
|
19
|
+
return {};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const toolPrompts = (parsed as Record<string, unknown>)["tool-prompts"];
|
|
23
|
+
if (toolPrompts === undefined) return {};
|
|
24
|
+
if (!toolPrompts || typeof toolPrompts !== "object" || Array.isArray(toolPrompts)) {
|
|
25
|
+
console.warn(`[pi-subagent] Ignoring invalid tool-prompts in "${filePath}". Expected an object of tool-name to prompt strings.`);
|
|
26
|
+
return {};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const result: Record<string, string> = {};
|
|
30
|
+
for (const [toolName, prompt] of Object.entries(toolPrompts)) {
|
|
31
|
+
if (typeof prompt === "string" && prompt.trim().length > 0) {
|
|
32
|
+
result[toolName] = prompt;
|
|
33
|
+
} else {
|
|
34
|
+
console.warn(`[pi-subagent] Ignoring invalid prompt for tool "${toolName}" in "${filePath}". Expected a non-empty string.`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return result;
|
|
38
|
+
} catch (err) {
|
|
39
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
40
|
+
console.warn(`[pi-subagent] Failed to read config "${filePath}": ${message}`);
|
|
41
|
+
return {};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Find the nearest project-local .pi/pi-subagents.json while walking up from cwd. */
|
|
46
|
+
export function findProjectConfig(cwd: string): string | null {
|
|
47
|
+
let dir = path.resolve(cwd);
|
|
48
|
+
while (true) {
|
|
49
|
+
const candidate = path.join(dir, ".pi", PI_SUBAGENTS_CONFIG_FILE);
|
|
50
|
+
if (fs.existsSync(candidate)) return candidate;
|
|
51
|
+
const parent = path.dirname(dir);
|
|
52
|
+
if (parent === dir) return null;
|
|
53
|
+
dir = parent;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Load tool prompt overrides from lowest to highest priority:
|
|
59
|
+
* ~/.pi/pi-subagents.json
|
|
60
|
+
* $PI_CODING_AGENT_DIR/pi-subagents.json (normally ~/.pi/agent/pi-subagents.json)
|
|
61
|
+
* nearest project .pi/pi-subagents.json (trusted projects only)
|
|
62
|
+
*/
|
|
63
|
+
export function loadPiSubagentsConfig(
|
|
64
|
+
cwd?: string,
|
|
65
|
+
includeProject = false,
|
|
66
|
+
): PiSubagentsConfig {
|
|
67
|
+
const paths = [
|
|
68
|
+
path.join(os.homedir(), ".pi", PI_SUBAGENTS_CONFIG_FILE),
|
|
69
|
+
path.join(getAgentDir(), PI_SUBAGENTS_CONFIG_FILE),
|
|
70
|
+
];
|
|
71
|
+
if (cwd && includeProject) {
|
|
72
|
+
const projectConfig = findProjectConfig(cwd);
|
|
73
|
+
if (projectConfig) paths.push(projectConfig);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const toolPrompts: Record<string, string> = {};
|
|
77
|
+
for (const filePath of new Set(paths)) {
|
|
78
|
+
Object.assign(toolPrompts, readToolPrompts(filePath));
|
|
79
|
+
}
|
|
80
|
+
return { toolPrompts };
|
|
81
|
+
}
|
package/index.ts
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
} from "@mariozechner/pi-ai";
|
|
20
20
|
import { Type } from "@sinclair/typebox";
|
|
21
21
|
import { type AgentConfig, discoverAgents, isAgentEnabledAtLayer } from "./agents.js";
|
|
22
|
+
import { loadPiSubagentsConfig } from "./config.js";
|
|
22
23
|
import {
|
|
23
24
|
allocateSubagentNames,
|
|
24
25
|
clearResumeActive,
|
|
@@ -114,22 +115,21 @@ const BASE_SUBAGENTS_TOOL_DESCRIPTION = [
|
|
|
114
115
|
'Parallel: { tasks: [{ agent: "writer", task: "..." }, { agent: "tester", task: "..." }] }',
|
|
115
116
|
].join("\n");
|
|
116
117
|
|
|
117
|
-
const
|
|
118
|
+
const SUBAGENT_USAGE_GUIDANCE =
|
|
118
119
|
"Be careful with subagents: use them when the user explicitly asks or when they are truly necessary, because they are expensive. Good cases: running several exploration tasks in parallel, solving several tasks in parallel, or delegating several large tasks to separate subagents. Bad cases (don't do this): creating many nested subagents with similar tasks, using sequential subagents for simple short tasks, running a subagent just to read a file or execute a bash command, or delegating work that does not need a team or parallel execution (unless the user asked you to).";
|
|
119
120
|
|
|
120
|
-
export function
|
|
121
|
-
|
|
122
|
-
if (!model || typeof model !== "object") return false;
|
|
123
|
-
const candidate = model as { id?: unknown; name?: unknown };
|
|
124
|
-
return [candidate.id, candidate.name].some(
|
|
125
|
-
(value) => typeof value === "string" && value.toLowerCase().includes("gpt-5.6"),
|
|
126
|
-
);
|
|
121
|
+
export function getSubagentsToolDescription(): string {
|
|
122
|
+
return `${BASE_SUBAGENTS_TOOL_DESCRIPTION}\n\n${SUBAGENT_USAGE_GUIDANCE}`;
|
|
127
123
|
}
|
|
128
124
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
125
|
+
function sameToolPrompts(
|
|
126
|
+
left: Record<string, string>,
|
|
127
|
+
right: Record<string, string>,
|
|
128
|
+
): boolean {
|
|
129
|
+
const leftKeys = Object.keys(left);
|
|
130
|
+
const rightKeys = Object.keys(right);
|
|
131
|
+
return leftKeys.length === rightKeys.length &&
|
|
132
|
+
leftKeys.every((key) => left[key] === right[key]);
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
type ProjectAgentConfirmationSetting = "ask" | "never" | "session";
|
|
@@ -705,6 +705,8 @@ export function selectParentModelForSubagent(
|
|
|
705
705
|
// ---------------------------------------------------------------------------
|
|
706
706
|
|
|
707
707
|
export default function (pi: ExtensionAPI) {
|
|
708
|
+
let configuredToolPrompts = loadPiSubagentsConfig().toolPrompts;
|
|
709
|
+
let refreshRegisteredToolPrompts: ((cwd: string, includeProject: boolean) => void) | undefined;
|
|
708
710
|
let resumeModelRegistry: any | undefined;
|
|
709
711
|
let lastRestorableModel: any | undefined;
|
|
710
712
|
let latestSessionCtx: any | undefined;
|
|
@@ -1395,6 +1397,9 @@ export default function (pi: ExtensionAPI) {
|
|
|
1395
1397
|
lifecycleGeneration += 1;
|
|
1396
1398
|
sessionActive = true;
|
|
1397
1399
|
latestSessionCtx = ctx;
|
|
1400
|
+
const includeProjectConfig =
|
|
1401
|
+
typeof ctx.isProjectTrusted === "function" && ctx.isProjectTrusted() === true;
|
|
1402
|
+
refreshRegisteredToolPrompts?.(ctx.cwd, includeProjectConfig);
|
|
1398
1403
|
resumeModelRegistry = ctx.modelRegistry;
|
|
1399
1404
|
clearSyntheticResumeState();
|
|
1400
1405
|
pendingResumePlans = [];
|
|
@@ -1707,16 +1712,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1707
1712
|
const agentList = discoveredAgents
|
|
1708
1713
|
.map((a) => `- **${a.name}**: ${a.description}`)
|
|
1709
1714
|
.join("\n");
|
|
1710
|
-
|
|
1711
|
-
systemPrompt:
|
|
1712
|
-
event.systemPrompt +
|
|
1713
|
-
`\n\n## Available Subagents
|
|
1714
|
-
|
|
1715
|
-
The following subagents are available via the \`subagents\` tool:
|
|
1716
|
-
|
|
1717
|
-
${agentList}
|
|
1718
|
-
|
|
1719
|
-
### How to call the subagents tool
|
|
1715
|
+
const subagentsGuidance = configuredToolPrompts[SUBAGENT_TOOL_NAME] ?? `### How to call the subagents tool
|
|
1720
1716
|
|
|
1721
1717
|
Each subagent runs in an **isolated process**.
|
|
1722
1718
|
|
|
@@ -1738,9 +1734,10 @@ calls one after another. Do NOT put dependent tasks in the same array.
|
|
|
1738
1734
|
\`\`\`
|
|
1739
1735
|
|
|
1740
1736
|
- Max depth: current depth ${currentDepth}, max depth ${maxDepth}
|
|
1741
|
-
- Max subagents per tool call: ${maxParallelTasks}
|
|
1742
|
-
|
|
1743
|
-
|
|
1737
|
+
- Max subagents per tool call: ${maxParallelTasks}`;
|
|
1738
|
+
const resumeGuidance = resumableSubagentsDisabled()
|
|
1739
|
+
? ""
|
|
1740
|
+
: configuredToolPrompts[RESUME_SUBAGENTS_TOOL_NAME] ?? `### Resumable subagents
|
|
1744
1741
|
|
|
1745
1742
|
Every subagent run is assigned a unique, durable name (e.g. \`code-writer-01\`,
|
|
1746
1743
|
\`code-reviewer-02\`) which is returned together with its results. Use the
|
|
@@ -1756,8 +1753,13 @@ keeping their full previous context:
|
|
|
1756
1753
|
- All resumes in one call run in parallel.
|
|
1757
1754
|
- You may include subagent names in the task text you give YOUR OWN subagents,
|
|
1758
1755
|
so they can resume those subagents themselves.
|
|
1759
|
-
- Names survive restarts; you can resume them in a later session of this conversation
|
|
1760
|
-
|
|
1756
|
+
- Names survive restarts; you can resume them in a later session of this conversation.`;
|
|
1757
|
+
return {
|
|
1758
|
+
systemPrompt: `${event.systemPrompt}\n\n## Available Subagents
|
|
1759
|
+
|
|
1760
|
+
The following subagents are available via the \`subagents\` tool:
|
|
1761
|
+
|
|
1762
|
+
${agentList}\n\n${subagentsGuidance}${resumeGuidance ? `\n\n${resumeGuidance}` : ""}`,
|
|
1761
1763
|
};
|
|
1762
1764
|
} catch (err) {
|
|
1763
1765
|
console.error("[pi-subagent] Error in before_agent_start:", err);
|
|
@@ -1766,13 +1768,11 @@ keeping their full previous context:
|
|
|
1766
1768
|
|
|
1767
1769
|
// Register the subagents tool
|
|
1768
1770
|
if (canDelegate) {
|
|
1769
|
-
|
|
1770
|
-
const registerSubagentsTool = (model?: unknown) => {
|
|
1771
|
-
registeredForGpt56 = isGpt56Model(model);
|
|
1771
|
+
const registerSubagentsTool = () => {
|
|
1772
1772
|
pi.registerTool({
|
|
1773
1773
|
name: SUBAGENT_TOOL_NAME,
|
|
1774
1774
|
label: "Subagents",
|
|
1775
|
-
description: getSubagentsToolDescription(
|
|
1775
|
+
description: configuredToolPrompts[SUBAGENT_TOOL_NAME] ?? getSubagentsToolDescription(),
|
|
1776
1776
|
parameters: SubagentParams,
|
|
1777
1777
|
|
|
1778
1778
|
async execute(toolCallId, params, signal, onUpdate, ctx) {
|
|
@@ -1989,22 +1989,12 @@ This guard prevents self-recursion and cyclic handoffs (for example A -> B -> A)
|
|
|
1989
1989
|
});
|
|
1990
1990
|
};
|
|
1991
1991
|
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
registerSubagentsTool(event.model);
|
|
1996
|
-
}
|
|
1997
|
-
});
|
|
1998
|
-
pi.on("before_agent_start", (_event, ctx) => {
|
|
1999
|
-
if (registeredForGpt56 !== isGpt56Model(ctx.model)) {
|
|
2000
|
-
registerSubagentsTool(ctx.model);
|
|
2001
|
-
}
|
|
2002
|
-
});
|
|
2003
|
-
|
|
2004
|
-
if (!resumableSubagentsDisabled()) pi.registerTool({
|
|
1992
|
+
const registerResumeSubagentsTool = () => {
|
|
1993
|
+
if (resumableSubagentsDisabled()) return;
|
|
1994
|
+
pi.registerTool({
|
|
2005
1995
|
name: RESUME_SUBAGENTS_TOOL_NAME,
|
|
2006
1996
|
label: "Resume subagents",
|
|
2007
|
-
description: [
|
|
1997
|
+
description: configuredToolPrompts[RESUME_SUBAGENTS_TOOL_NAME] ?? [
|
|
2008
1998
|
"Resume previously run subagents by name with a new task, keeping their full context.",
|
|
2009
1999
|
"",
|
|
2010
2000
|
"Every subagent run returns a unique name (e.g. code-writer-01). Pass those names",
|
|
@@ -2207,7 +2197,24 @@ This guard prevents self-recursion and cyclic handoffs (for example A -> B -> A)
|
|
|
2207
2197
|
renderCall: (args, theme, context) => renderResumeCall(args, theme, context),
|
|
2208
2198
|
renderResult: (result, { expanded }, theme) =>
|
|
2209
2199
|
renderResult(result, expanded, theme),
|
|
2210
|
-
|
|
2200
|
+
});
|
|
2201
|
+
};
|
|
2202
|
+
|
|
2203
|
+
const registerToolsWithConfig = (
|
|
2204
|
+
cwd?: string,
|
|
2205
|
+
includeProject = false,
|
|
2206
|
+
force = false,
|
|
2207
|
+
) => {
|
|
2208
|
+
const nextToolPrompts = loadPiSubagentsConfig(cwd, includeProject).toolPrompts;
|
|
2209
|
+
if (!force && sameToolPrompts(configuredToolPrompts, nextToolPrompts)) return;
|
|
2210
|
+
configuredToolPrompts = nextToolPrompts;
|
|
2211
|
+
registerSubagentsTool();
|
|
2212
|
+
registerResumeSubagentsTool();
|
|
2213
|
+
};
|
|
2214
|
+
refreshRegisteredToolPrompts = (cwd, includeProject) => {
|
|
2215
|
+
registerToolsWithConfig(cwd, includeProject);
|
|
2216
|
+
};
|
|
2217
|
+
registerToolsWithConfig(undefined, false, true);
|
|
2211
2218
|
}
|
|
2212
2219
|
|
|
2213
2220
|
function getSessionDirForTask(toolCallId: string, index: number): string {
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oira666_pi-subagent",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.9",
|
|
4
4
|
"description": "Subagent extension for Pi coding agent. Delegate tasks to specialized agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
7
7
|
"files": [
|
|
8
8
|
"index.ts",
|
|
9
9
|
"agents.ts",
|
|
10
|
+
"config.ts",
|
|
10
11
|
"runner.ts",
|
|
11
12
|
"resume.ts",
|
|
12
13
|
"names.ts",
|