diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index e857000f5..84eecd820 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -19,6 +19,7 @@ - Fixed llama.cpp login guidance to direct users to `/llama` before `/model` when no local models are loaded ([#8203](https://github.com/earendil-works/pi/issues/8203)). - Fixed hung pi.dev model catalog requests consuming the entire refresh deadline without retrying ([#8198](https://github.com/earendil-works/pi/issues/8198)). - Fixed inherited Xiaomi model catalogs listing shut-down MiMo V2 models in `/model` and `--list-models` ([#8187](https://github.com/earendil-works/pi/issues/8187)). +- Fixed branch summary entries recording the navigation destination in `fromId` instead of the pre-navigation source leaf. ## [0.84.2] - 2026-08-14 diff --git a/packages/coding-agent/src/core/session-manager.ts b/packages/coding-agent/src/core/session-manager.ts index cd9d2f437..f8db9b0e5 100644 --- a/packages/coding-agent/src/core/session-manager.ts +++ b/packages/coding-agent/src/core/session-manager.ts @@ -1388,13 +1388,14 @@ export class SessionManager { if (branchFromId !== null && !this.byId.has(branchFromId)) { throw new Error(`Entry ${branchFromId} not found`); } + const fromId = this.leafId ?? "root"; this.leafId = branchFromId; const entry: BranchSummaryEntry = { type: "branch_summary", id: generateId(this.byId), parentId: branchFromId, timestamp: new Date().toISOString(), - fromId: branchFromId ?? "root", + fromId, summary, details, usage, diff --git a/packages/coding-agent/test/branch-summary-extensions.test.ts b/packages/coding-agent/test/branch-summary-extensions.test.ts index 9c47cb81a..ecdc01797 100644 --- a/packages/coding-agent/test/branch-summary-extensions.test.ts +++ b/packages/coding-agent/test/branch-summary-extensions.test.ts @@ -38,12 +38,14 @@ describe("Branch summary extensions", () => { const targetId = harness.sessionManager.appendMessage(userMsg("first branch")); harness.sessionManager.appendMessage(assistantMsg("first reply")); harness.sessionManager.appendMessage(userMsg("abandoned branch work")); - harness.sessionManager.appendMessage(assistantMsg("abandoned reply")); + const sourceId = harness.sessionManager.appendMessage(assistantMsg("abandoned reply")); const result = await harness.session.navigateTree(targetId, { summarize: true }); const summaryEntry = result.summaryEntry; expect(summaryEntry?.type).toBe("branch_summary"); + expect(summaryEntry?.parentId).toBeNull(); + expect(summaryEntry?.fromId).toBe(sourceId); expect(summaryEntry?.fromHook).toBe(true); expect(summaryEntry?.summary).toBe("Summary provided by extension"); expect(summaryEntry?.usage).toEqual(usage); diff --git a/packages/coding-agent/test/session-manager/tree-traversal.test.ts b/packages/coding-agent/test/session-manager/tree-traversal.test.ts index d6e20f043..123dc65cd 100644 --- a/packages/coding-agent/test/session-manager/tree-traversal.test.ts +++ b/packages/coding-agent/test/session-manager/tree-traversal.test.ts @@ -321,12 +321,12 @@ describe("SessionManager append and tree traversal", () => { }); describe("branchWithSummary", () => { - it("inserts branch summary and advances leaf", () => { + it("inserts branch summary with the source and destination and advances leaf", () => { const session = SessionManager.inMemory(); const id1 = session.appendMessage(userMsg("1")); const _id2 = session.appendMessage(assistantMsg("2")); - const _id3 = session.appendMessage(userMsg("3")); + const id3 = session.appendMessage(userMsg("3")); const usage = { input: 10, @@ -345,6 +345,7 @@ describe("SessionManager append and tree traversal", () => { expect(summaryEntry).toBeDefined(); expect(summaryEntry?.parentId).toBe(id1); if (summaryEntry?.type === "branch_summary") { + expect(summaryEntry.fromId).toBe(id3); expect(summaryEntry.summary).toBe("Summary of abandoned work"); expect(summaryEntry.usage).toEqual(usage); }