feat: let agents start new sessions via spawn_session tool

Add a project-scoped spawn_session tool so agents can dispatch new,
independent sessions (ralph loops, long-plan chaining). Spawned sessions
are constrained to a workspace/worktree of the same registered project,
appear in the session list immediately via a new session.created event,
and the capability is on by default with a Settings -> Session daemon
toggle (spawnSessions / PI_WEB_SPAWN_SESSIONS).

Note: adds a session daemon code path, so pi-web-sessiond.service must be
restarted manually for the server side to take effect.
This commit is contained in:
Federico Jaramillo Martinez
2026-06-16 14:53:37 +02:00
parent bfcd975c83
commit 95c151233a
26 changed files with 630 additions and 18 deletions
+3 -3
View File
@@ -37,11 +37,11 @@ describe("config routes", () => {
const response = await app.inject({
method: "PUT",
url: "/api/config",
payload: { config: { host: "0.0.0.0", port: 9000, allowedHosts: true, shortcuts: { "core:view.chat": "mod+1", "core:session.stop": null }, plugins: { info: { enabled: false, settings: { note: "hidden" } } } } },
payload: { config: { host: "0.0.0.0", port: 9000, allowedHosts: true, spawnSessions: true, shortcuts: { "core:view.chat": "mod+1", "core:session.stop": null }, plugins: { info: { enabled: false, settings: { note: "hidden" } } } } },
});
expect(response.statusCode).toBe(200);
expect(savedConfig).toEqual({ host: "0.0.0.0", port: 9000, allowedHosts: true, shortcuts: { "core:view.chat": "mod+1", "core:session.stop": null }, plugins: { info: { enabled: false, settings: { note: "hidden" } } } });
expect(savedConfig).toEqual({ host: "0.0.0.0", port: 9000, allowedHosts: true, spawnSessions: true, shortcuts: { "core:view.chat": "mod+1", "core:session.stop": null }, plugins: { info: { enabled: false, settings: { note: "hidden" } } } });
expect(response.json<PiWebConfigResponse>().config).toEqual(savedConfig);
});
@@ -64,6 +64,6 @@ function responseFor(config: PiWebConfigValues, exists: boolean): PiWebConfigRes
exists,
config,
effectiveConfig: config,
envOverrides: { host: false, port: false, allowedHosts: false },
envOverrides: { host: false, port: false, allowedHosts: false, spawnSessions: false },
};
}