From f04d9bc428d639d6cb5403fd8af5ce054a90eb60 Mon Sep 17 00:00:00 2001 From: Haoyu Zha Date: Fri, 13 Mar 2026 17:34:48 -0700 Subject: [PATCH] feat(session-manager): allow supplying custom session ID in newSession() (#2130) * feat(session-manager): allow supplying custom session ID in newSession() Add optional `id` field to `NewSessionOptions`. When provided, this ID is used as the session ID instead of generating a random UUID. Existing callers are unaffected since the field is optional and falls back to `randomUUID()`. Closes #2097 * test(session-manager): add tests for custom session ID in newSession() Verify that newSession() uses the provided id when supplied, falls back to randomUUID() when omitted, and includes the custom id in the session header. --- .../coding-agent/src/core/session-manager.ts | 3 +- .../session-manager/custom-session-id.test.ts | 35 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 packages/coding-agent/test/session-manager/custom-session-id.test.ts diff --git a/packages/coding-agent/src/core/session-manager.ts b/packages/coding-agent/src/core/session-manager.ts index a7edb634..49b0f422 100644 --- a/packages/coding-agent/src/core/session-manager.ts +++ b/packages/coding-agent/src/core/session-manager.ts @@ -36,6 +36,7 @@ export interface SessionHeader { } export interface NewSessionOptions { + id?: string; parentSession?: string; } @@ -721,7 +722,7 @@ export class SessionManager { } newSession(options?: NewSessionOptions): string | undefined { - this.sessionId = randomUUID(); + this.sessionId = options?.id ?? randomUUID(); const timestamp = new Date().toISOString(); const header: SessionHeader = { type: "session", diff --git a/packages/coding-agent/test/session-manager/custom-session-id.test.ts b/packages/coding-agent/test/session-manager/custom-session-id.test.ts new file mode 100644 index 00000000..8cded2d2 --- /dev/null +++ b/packages/coding-agent/test/session-manager/custom-session-id.test.ts @@ -0,0 +1,35 @@ +import { describe, expect, it } from "vitest"; +import { SessionManager } from "../../src/core/session-manager.js"; + +describe("SessionManager.newSession with custom id", () => { + it("uses the provided id instead of generating one", () => { + const session = SessionManager.inMemory(); + session.newSession({ id: "my-custom-id" }); + expect(session.getSessionId()).toBe("my-custom-id"); + }); + + it("generates a random id when no id is provided", () => { + const session = SessionManager.inMemory(); + session.newSession(); + const id = session.getSessionId(); + expect(id).toBeDefined(); + expect(id).not.toBe(""); + }); + + it("generates a random id when options is provided without id", () => { + const session = SessionManager.inMemory(); + session.newSession({ parentSession: "parent.jsonl" }); + const id = session.getSessionId(); + expect(id).toBeDefined(); + expect(id).not.toBe(""); + }); + + it("includes the custom id in the session header", () => { + const session = SessionManager.inMemory(); + session.newSession({ id: "header-test-id" }); + + const header = session.getHeader(); + expect(header).not.toBeNull(); + expect(header!.id).toBe("header-test-id"); + }); +});