From 471da49c59324e9d8a450fbe8df5f0949f383034 Mon Sep 17 00:00:00 2001 From: Tak Hoffman <781889+Takhoffman@users.noreply.github.com> Date: Thu, 26 Mar 2026 10:31:00 -0500 Subject: [PATCH] fix: preserve reset ownership metadata --- ...sessions.gateway-server-sessions-a.test.ts | 37 +++++++++++++++++++ src/gateway/session-reset-service.ts | 2 + 2 files changed, 39 insertions(+) diff --git a/src/gateway/server.sessions.gateway-server-sessions-a.test.ts b/src/gateway/server.sessions.gateway-server-sessions-a.test.ts index 225a31e886b..18dd1ee45ad 100644 --- a/src/gateway/server.sessions.gateway-server-sessions-a.test.ts +++ b/src/gateway/server.sessions.gateway-server-sessions-a.test.ts @@ -1004,6 +1004,43 @@ describe("gateway server sessions", () => { ws.close(); }); + test("sessions.reset preserves spawned session ownership metadata", async () => { + const { storePath } = await createSessionStoreDir(); + await writeSessionStore({ + entries: { + "subagent:child": { + sessionId: "sess-owned-child", + updatedAt: Date.now(), + spawnedBy: "agent:main:main", + parentSessionKey: "agent:main:main", + label: "owned child", + }, + }, + }); + + const { ws } = await openClient(); + const reset = await rpcReq<{ + ok: true; + key: string; + entry: { spawnedBy?: string; parentSessionKey?: string; label?: string }; + }>(ws, "sessions.reset", { key: "subagent:child" }); + + expect(reset.ok).toBe(true); + expect(reset.payload?.entry.spawnedBy).toBe("agent:main:main"); + expect(reset.payload?.entry.parentSessionKey).toBe("agent:main:main"); + expect(reset.payload?.entry.label).toBe("owned child"); + + const store = JSON.parse(await fs.readFile(storePath, "utf-8")) as Record< + string, + { spawnedBy?: string; parentSessionKey?: string; label?: string } + >; + expect(store["agent:main:subagent:child"]?.spawnedBy).toBe("agent:main:main"); + expect(store["agent:main:subagent:child"]?.parentSessionKey).toBe("agent:main:main"); + expect(store["agent:main:subagent:child"]?.label).toBe("owned child"); + + ws.close(); + }); + test("sessions.preview resolves legacy mixed-case main alias with custom mainKey", async () => { const { dir, storePath } = await createSessionStoreDir(); testState.agentsConfig = { list: [{ id: "ops", default: true }] }; diff --git a/src/gateway/session-reset-service.ts b/src/gateway/session-reset-service.ts index 48066b6e2a7..5c0210e728f 100644 --- a/src/gateway/session-reset-service.ts +++ b/src/gateway/session-reset-service.ts @@ -320,6 +320,8 @@ export async function performGatewaySessionReset(params: { modelProvider: resolvedModel.provider, contextTokens: resetEntry?.contextTokens, sendPolicy: currentEntry?.sendPolicy, + spawnedBy: currentEntry?.spawnedBy, + parentSessionKey: currentEntry?.parentSessionKey, label: currentEntry?.label, origin: snapshotSessionOrigin(currentEntry), lastChannel: currentEntry?.lastChannel,