pi-subagents 0.11.0 → 0.11.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 +5 -0
- package/index.ts +38 -19
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.11.1] - 2026-03-08
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
- **Session persistence**: Subagent sessions are now stored alongside the parent session file instead of in `/tmp`. If the parent session is `~/.pi/agent/sessions/abc123.jsonl`, subagent sessions go to `~/.pi/agent/sessions/abc123/{runId}/run-{N}/`. This enables tracking subagent performance over time, analyzing token usage patterns, and debugging past delegations. Falls back to a unique temp directory when no parent session exists (API/headless mode).
|
|
9
|
+
|
|
5
10
|
## [0.11.0] - 2026-02-23
|
|
6
11
|
|
|
7
12
|
### Added
|
package/index.ts
CHANGED
|
@@ -57,6 +57,22 @@ import { handleManagementAction } from "./agent-management.js";
|
|
|
57
57
|
|
|
58
58
|
// ExtensionConfig is now imported from ./types.js
|
|
59
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Derive subagent session base directory from parent session file.
|
|
62
|
+
* If parent session is ~/.pi/agent/sessions/abc123.jsonl,
|
|
63
|
+
* returns ~/.pi/agent/sessions/abc123/ as the base.
|
|
64
|
+
* Callers add runId to create the actual session root: abc123/{runId}/
|
|
65
|
+
* Falls back to a unique temp directory if no parent session.
|
|
66
|
+
*/
|
|
67
|
+
function getSubagentSessionRoot(parentSessionFile: string | null): string {
|
|
68
|
+
if (parentSessionFile) {
|
|
69
|
+
const baseName = path.basename(parentSessionFile, ".jsonl");
|
|
70
|
+
const sessionsDir = path.dirname(parentSessionFile);
|
|
71
|
+
return path.join(sessionsDir, baseName);
|
|
72
|
+
}
|
|
73
|
+
return fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagent-session-"));
|
|
74
|
+
}
|
|
75
|
+
|
|
60
76
|
function loadConfig(): ExtensionConfig {
|
|
61
77
|
const configPath = path.join(os.homedir(), ".pi", "agent", "extensions", "subagent", "config.json");
|
|
62
78
|
try {
|
|
@@ -277,23 +293,22 @@ MANAGEMENT (use action field — omit agent/task/chain/tasks):
|
|
|
277
293
|
}
|
|
278
294
|
|
|
279
295
|
const scope: AgentScope = resolveExecutionAgentScope(params.agentScope);
|
|
280
|
-
|
|
296
|
+
const parentSessionFile = ctx.sessionManager.getSessionFile() ?? null;
|
|
297
|
+
currentSessionId = parentSessionFile ?? `session-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
281
298
|
const agents = discoverAgents(ctx.cwd, scope).agents;
|
|
282
299
|
const runId = randomUUID().slice(0, 8);
|
|
283
300
|
const shareEnabled = params.share === true;
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
:
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
} catch {}
|
|
294
|
-
}
|
|
301
|
+
// Session root: explicit param > derived from parent session > temp fallback
|
|
302
|
+
// Sessions are always enabled now - stored alongside parent session for tracking
|
|
303
|
+
// Include runId to ensure uniqueness across multiple subagent calls
|
|
304
|
+
const sessionRoot = params.sessionDir
|
|
305
|
+
? path.resolve(params.sessionDir)
|
|
306
|
+
: path.join(getSubagentSessionRoot(parentSessionFile), runId);
|
|
307
|
+
try {
|
|
308
|
+
fs.mkdirSync(sessionRoot, { recursive: true });
|
|
309
|
+
} catch {}
|
|
295
310
|
const sessionDirForIndex = (idx?: number) =>
|
|
296
|
-
|
|
311
|
+
path.join(sessionRoot, `run-${idx ?? 0}`);
|
|
297
312
|
|
|
298
313
|
const hasChain = (params.chain?.length ?? 0) > 0;
|
|
299
314
|
const hasTasks = (params.tasks?.length ?? 0) > 0;
|
|
@@ -315,8 +330,7 @@ MANAGEMENT (use action field — omit agent/task/chain/tasks):
|
|
|
315
330
|
enabled: params.artifacts !== false,
|
|
316
331
|
};
|
|
317
332
|
|
|
318
|
-
const
|
|
319
|
-
const artifactsDir = effectiveAsync ? tempArtifactsDir : getArtifactsDir(sessionFile);
|
|
333
|
+
const artifactsDir = effectiveAsync ? tempArtifactsDir : getArtifactsDir(parentSessionFile);
|
|
320
334
|
|
|
321
335
|
if (Number(hasChain) + Number(hasTasks) + Number(hasSingle) !== 1) {
|
|
322
336
|
return {
|
|
@@ -1019,12 +1033,16 @@ MANAGEMENT (use action field — omit agent/task/chain/tasks):
|
|
|
1019
1033
|
|
|
1020
1034
|
const setupDirectRun = (ctx: ExtensionContext) => {
|
|
1021
1035
|
const runId = randomUUID().slice(0, 8);
|
|
1022
|
-
const
|
|
1036
|
+
const parentSessionFile = ctx.sessionManager.getSessionFile() ?? null;
|
|
1037
|
+
const sessionRoot = path.join(getSubagentSessionRoot(parentSessionFile), runId);
|
|
1038
|
+
try {
|
|
1039
|
+
fs.mkdirSync(sessionRoot, { recursive: true });
|
|
1040
|
+
} catch {}
|
|
1023
1041
|
return {
|
|
1024
1042
|
runId,
|
|
1025
1043
|
shareEnabled: false,
|
|
1026
1044
|
sessionDirForIndex: (idx?: number) => path.join(sessionRoot, `run-${idx ?? 0}`),
|
|
1027
|
-
artifactsDir: getArtifactsDir(
|
|
1045
|
+
artifactsDir: getArtifactsDir(parentSessionFile),
|
|
1028
1046
|
artifactConfig: { ...DEFAULT_ARTIFACT_CONFIG } as ArtifactConfig,
|
|
1029
1047
|
};
|
|
1030
1048
|
};
|
|
@@ -1085,7 +1103,8 @@ MANAGEMENT (use action field — omit agent/task/chain/tasks):
|
|
|
1085
1103
|
}
|
|
1086
1104
|
const id = randomUUID();
|
|
1087
1105
|
const asyncCtx = { pi, cwd: ctx.cwd, currentSessionId: ctx.sessionManager.getSessionId() ?? id };
|
|
1088
|
-
const
|
|
1106
|
+
const asyncSessionRoot = getSubagentSessionRoot(ctx.sessionManager.getSessionFile() ?? null);
|
|
1107
|
+
try { fs.mkdirSync(asyncSessionRoot, { recursive: true }); } catch {}
|
|
1089
1108
|
executeAsyncChain(id, {
|
|
1090
1109
|
chain: r.requestedAsync.chain,
|
|
1091
1110
|
agents,
|
|
@@ -1094,7 +1113,7 @@ MANAGEMENT (use action field — omit agent/task/chain/tasks):
|
|
|
1094
1113
|
artifactsDir: exec.artifactsDir,
|
|
1095
1114
|
artifactConfig: exec.artifactConfig,
|
|
1096
1115
|
shareEnabled: false,
|
|
1097
|
-
sessionRoot,
|
|
1116
|
+
sessionRoot: asyncSessionRoot,
|
|
1098
1117
|
chainSkills: r.requestedAsync.chainSkills,
|
|
1099
1118
|
}).then((asyncResult) => {
|
|
1100
1119
|
pi.sendUserMessage(asyncResult.content[0]?.text || "(launched in background)");
|
package/package.json
CHANGED