Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/providers/ChatViewProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
import * as path from "path";
import * as vscode from "vscode";
import { ErrorBuilder } from "./chat/ErrorBuilder";
import type { DisplayError } from "./chat/types";

Check warning on line 103 in src/providers/ChatViewProvider.ts

View workflow job for this annotation

GitHub Actions / verify

'DisplayError' is defined but never used
import {
CssGenerator,
FileThemeProcessor,
Expand Down Expand Up @@ -713,7 +713,7 @@
let permissions: unknown[] = [];

try {
const questionResponse = await (client as any).question.list();

Check warning on line 716 in src/providers/ChatViewProvider.ts

View workflow job for this annotation

GitHub Actions / verify

Unexpected any. Specify a different type
questions = extractList(questionResponse, "questions").filter(belongsToSession);
} catch (questionError) {
this.logger.warn("Failed to list pending SDK questions", {
Expand All @@ -723,7 +723,7 @@
}

try {
const permissionResponse = await (client as any).permission.list();

Check warning on line 726 in src/providers/ChatViewProvider.ts

View workflow job for this annotation

GitHub Actions / verify

Unexpected any. Specify a different type
permissions = extractList(permissionResponse, "permissions").filter(belongsToSession);
} catch (permissionError) {
this.logger.warn("Failed to list pending SDK permissions", {
Expand Down Expand Up @@ -857,8 +857,8 @@
private lastSendMessageArgs?: {
text: string;
files?: string[];
contexts?: any[];

Check warning on line 860 in src/providers/ChatViewProvider.ts

View workflow job for this annotation

GitHub Actions / verify

Unexpected any. Specify a different type
images?: any[];

Check warning on line 861 in src/providers/ChatViewProvider.ts

View workflow job for this annotation

GitHub Actions / verify

Unexpected any. Specify a different type
agent?: string;
};
/** OpenCode v2 accepts structured output only through the typed `format` field. */
Expand Down Expand Up @@ -951,7 +951,7 @@
this.fileThemeProcessor.subscribe(this);

// Load persisted model selection
const savedModel = this.context.globalState.get<any>("selectedModel");

Check warning on line 954 in src/providers/ChatViewProvider.ts

View workflow job for this annotation

GitHub Actions / verify

Unexpected any. Specify a different type
if (
savedModel &&
typeof savedModel.providerID === "string" &&
Expand Down Expand Up @@ -1089,7 +1089,7 @@
* Wire callbacks between modules and the shell
*/
private wireModuleCallbacks(): void {
const postMessage = (msg: any) => {

Check warning on line 1092 in src/providers/ChatViewProvider.ts

View workflow job for this annotation

GitHub Actions / verify

Unexpected any. Specify a different type
this.view?.webview.postMessage(msg);
};

Expand Down Expand Up @@ -1138,7 +1138,7 @@
clientRequestId?: string;
text?: string;
files?: string[];
contexts?: any[];

Check warning on line 1141 in src/providers/ChatViewProvider.ts

View workflow job for this annotation

GitHub Actions / verify

Unexpected any. Specify a different type
images?: any[];
agent?: string;
userFacingText?: string;
Expand Down Expand Up @@ -2008,7 +2008,7 @@
this.clearSessionTodos(sessionId);

// Restore per-session agent / model / thinking selections
await this.modelAndAgentManager.applySessionSettings(sessionId);
await this.applySessionSettings(sessionId);
if (abandonIfStale("applySessionSettings")) return;

// ============================================================================
Expand Down Expand Up @@ -9288,7 +9288,9 @@
* Applies session-specific model, agent, and thinking level
*/
private async applySessionSettings(sessionId: string): Promise<void> {
return this.modelAndAgentManager.applySessionSettings(sessionId);
await this.modelAndAgentManager.applySessionSettings(sessionId);
this.selectedModel = this.modelAndAgentManager.getSelectedModel();
this.selectedAgent = this.modelAndAgentManager.getSelectedAgent() ?? "build";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep the manager's agent selection synchronized

When a user changes agents, the selectAgent handler updates ChatViewProvider.selectedAgent and persistence but never calls modelAndAgentManager.setSelectedAgent. If the next loaded session has no persisted agent—for example, a legacy session—ModelAndAgentManager.applySessionSettings intentionally retains its stale or undefined value, and this new assignment overwrites the user's latest selection with that value (often build), causing the next prompt to use the wrong agent. Synchronize the manager in the selection handler or avoid copying its agent state here.

Useful? React with 👍 / 👎.

}

/**
Expand Down
32 changes: 32 additions & 0 deletions tests/regression/session-model-selection-regression.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import assert from "node:assert/strict";
import test from "node:test";

import { extractFunctionBody, joinFromRoot, readSource } from "../helpers/source-utils.mjs";

const provider = readSource(
[joinFromRoot("src", "providers", "ChatViewProvider.ts")],
"ChatViewProvider.ts",
);

test("session switches synchronize the prompt model with restored session settings", () => {
const applySessionSettings = extractFunctionBody(
provider,
"private async applySessionSettings(sessionId: string): Promise<void>",
);

assert.match(
applySessionSettings,
/await this\.modelAndAgentManager\.applySessionSettings\(sessionId\)/,
"session settings must be restored before synchronizing prompt state",
);
assert.match(
applySessionSettings,
/this\.selectedModel\s*=\s*this\.modelAndAgentManager\.getSelectedModel\(\)/,
"prompts must use the model restored for the active session",
);
assert.match(
provider,
/await this\.applySessionSettings\(sessionId\);/,
"session loading must use the synchronized restore path",
);
});
Loading