Archived
feat(sessions): add tracked subsessions behind a beta flag
Add spawn_subsession / list_subsessions / read_subsession tools that let an agent start child sessions it stays attached to: the child records its parent in the session tree, the parent is notified (as a system-authored custom message that wakes an idle parent and queues behind in-flight work) when the child stops working, and the parent can inspect children's status and result. Gated behind a beta flag, off by default, mirroring spawnSessions: enable via PI_WEB_SUBSESSIONS, the subsessions config key, or the Settings toggle. Also requires spawnSessions. Also fix the release skill so the version step resyncs package-lock.json (npm install --package-lock-only) and the commit step refuses a release where package.json and package-lock.json versions disagree.
This commit is contained in:
@@ -85,6 +85,8 @@ export function effectivePiWebConfig(options: LoadOptions = {}): LoadedPiWebConf
|
||||
// Always resolved (on by default) so the effective config is the single
|
||||
// source of truth for the runtime state and the settings UI toggle.
|
||||
spawnSessions: spawnSessionsEnabled(env, loaded.config),
|
||||
// Beta capability, resolved off by default.
|
||||
subsessions: subsessionsEnabled(env, loaded.config),
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -101,6 +103,7 @@ export function savePiWebConfig(config: PiWebConfig, options: LoadOptions = {}):
|
||||
delete existing["plugins"];
|
||||
delete existing["maxUploadBytes"];
|
||||
delete existing["spawnSessions"];
|
||||
delete existing["subsessions"];
|
||||
const merged = { ...existing, ...piWebConfigRecord(normalized) };
|
||||
mkdirSync(dirname(path), { recursive: true });
|
||||
writeFileSync(path, `${JSON.stringify(merged, null, 2)}\n`, "utf8");
|
||||
@@ -123,6 +126,7 @@ function piWebConfigRecord(config: PiWebConfig): Record<string, unknown> {
|
||||
...(config.plugins !== undefined ? { plugins: config.plugins } : {}),
|
||||
...(config.maxUploadBytes !== undefined ? { maxUploadBytes: config.maxUploadBytes } : {}),
|
||||
...(config.spawnSessions !== undefined ? { spawnSessions: config.spawnSessions } : {}),
|
||||
...(config.subsessions !== undefined ? { subsessions: config.subsessions } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -135,6 +139,7 @@ function parsePiWebConfig(value: Record<string, unknown>, path: string): PiWebCo
|
||||
...(value["plugins"] !== undefined ? { plugins: parsePlugins(value["plugins"], path) } : {}),
|
||||
...(value["maxUploadBytes"] !== undefined ? { maxUploadBytes: parseMaxUploadBytes(value["maxUploadBytes"], "maxUploadBytes", path) } : {}),
|
||||
...(value["spawnSessions"] !== undefined ? { spawnSessions: parseSpawnSessions(value["spawnSessions"], path) } : {}),
|
||||
...(value["subsessions"] !== undefined ? { subsessions: parseSubsessions(value["subsessions"], path) } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -161,6 +166,25 @@ export function spawnSessionsEnabled(env: NodeJS.ProcessEnv = process.env, confi
|
||||
return config.spawnSessions ?? true;
|
||||
}
|
||||
|
||||
function parseSubsessions(value: unknown, path: string): boolean {
|
||||
if (typeof value !== "boolean") throw new Error(`PI WEB config subsessions must be a boolean: ${path}`);
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Beta: whether LLMs may start tracked child sessions via the spawn_subsession
|
||||
* family of tools. Off by default while the capability stabilizes, so it can
|
||||
* ship in main without affecting releases; enable with the env var
|
||||
* `PI_WEB_SUBSESSIONS` or the `subsessions` config key. The env var takes
|
||||
* precedence over the config file. Subsessions also require spawnSessions to be
|
||||
* enabled (they share the same project-scope resolver).
|
||||
*/
|
||||
export function subsessionsEnabled(env: NodeJS.ProcessEnv = process.env, config: PiWebConfig = {}): boolean {
|
||||
const fromEnv = env["PI_WEB_SUBSESSIONS"];
|
||||
if (fromEnv !== undefined && fromEnv !== "") return fromEnv === "1" || fromEnv.toLowerCase() === "true";
|
||||
return config.subsessions ?? false;
|
||||
}
|
||||
|
||||
function parseString(value: unknown, key: string, path: string): string {
|
||||
if (typeof value !== "string" || value === "") throw new Error(`PI WEB config ${key} must be a non-empty string: ${path}`);
|
||||
return value;
|
||||
|
||||
Reference in New Issue
Block a user