From a0b9a85a20afe420c175b8088fe945092dafda39 Mon Sep 17 00:00:00 2001 From: mastertyko <11311479+mastertyko@users.noreply.github.com> Date: Fri, 27 Mar 2026 21:47:14 +0100 Subject: [PATCH] fix(gsd): preserve auto start model through discuss (#2837) --- src/resources/extensions/gsd/auto-start.ts | 18 ++++++++---- .../tests/auto-start-model-capture.test.ts | 28 +++++++++++++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts diff --git a/src/resources/extensions/gsd/auto-start.ts b/src/resources/extensions/gsd/auto-start.ts index f0b45a04e..38012e2c2 100644 --- a/src/resources/extensions/gsd/auto-start.ts +++ b/src/resources/extensions/gsd/auto-start.ts @@ -131,6 +131,15 @@ export async function bootstrapAutoSession( return false; } + // Capture the user's session model before guided-flow dispatch can apply a + // phase-specific planning model for a discuss turn (#2829). + const startModelSnapshot = ctx.model + ? { + provider: ctx.model.provider, + id: ctx.model.id, + } + : null; + try { // Validate GSD_PROJECT_ID early so the user gets immediate feedback const customProjectId = process.env.GSD_PROJECT_ID; @@ -576,12 +585,11 @@ export async function bootstrapAutoSession( // Initialize routing history initRoutingHistory(s.basePath); - // Capture session's model at auto-mode start (#650) - const currentModel = ctx.model; - if (currentModel) { + // Restore the model that was active when auto bootstrap began (#650, #2829). + if (startModelSnapshot) { s.autoModeStartModel = { - provider: currentModel.provider, - id: currentModel.id, + provider: startModelSnapshot.provider, + id: startModelSnapshot.id, }; } diff --git a/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts b/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts new file mode 100644 index 000000000..3daa00f3f --- /dev/null +++ b/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts @@ -0,0 +1,28 @@ +import test from "node:test"; +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import { join } from "node:path"; + +const sourcePath = join(import.meta.dirname, "..", "auto-start.ts"); +const source = readFileSync(sourcePath, "utf-8"); + +test("bootstrapAutoSession snapshots ctx.model before guided-flow entry (#2829)", () => { + const snapshotIdx = source.indexOf("const startModelSnapshot = ctx.model"); + assert.ok(snapshotIdx > -1, "auto-start.ts should snapshot ctx.model at bootstrap start"); + + const firstDiscussIdx = source.indexOf('await showSmartEntry(ctx, pi, base, { step: requestedStepMode });'); + assert.ok(firstDiscussIdx > -1, "auto-start.ts should route through showSmartEntry during guided flow"); + + assert.ok( + snapshotIdx < firstDiscussIdx, + "auto-start.ts must capture the start model before guided-flow can mutate ctx.model", + ); +}); + +test("bootstrapAutoSession restores autoModeStartModel from the early snapshot (#2829)", () => { + const assignmentIdx = source.indexOf("s.autoModeStartModel = {"); + assert.ok(assignmentIdx > -1, "auto-start.ts should assign autoModeStartModel"); + + const snapshotRefIdx = source.indexOf("provider: startModelSnapshot.provider", assignmentIdx); + assert.ok(snapshotRefIdx > -1, "autoModeStartModel should be restored from startModelSnapshot"); +});