Remote agent host: fix model picker on new session page (#306553)

* Revert bad merge from #306130

Co-authored-by: Copilot <copilot@github.com>

* Always resolve language models on provider registration

Previously, registerLanguageModelProvider only eagerly resolved models
when _hasStoredModelForVendor returned true. Otherwise it waited for
onDidChange. This created a hidden temporal coupling: if a provider
populated models before registration (like AgentHostLanguageModelProvider),
the onDidChange event fired with no listener attached, and the models
never appeared.

Fix: always call _resolveAllLanguageModels on registration. This is safe
(the provider guard handles unregistration races, and the per-vendor
sequencer prevents duplicate work).

Also use ActiveSessionProviderIdContext.key instead of a hardcoded string
in the remote agent host context key expression.

(Written by Copilot)

* fix

Co-authored-by: Copilot <copilot@github.com>

* fix

Co-authored-by: Copilot <copilot@github.com>

---------

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
Rob Lourens
2026-03-30 19:47:26 -07:00
committed by GitHub
parent 9a11a08c75
commit d13d7c7add
2 changed files with 13 additions and 11 deletions

View File

@@ -3,6 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { coalesce } from '../../../../base/common/arrays.js';
import { Disposable } from '../../../../base/common/lifecycle.js';
import { IReader, autorun, observableValue } from '../../../../base/common/observable.js';
import { localize2 } from '../../../../nls.js';
@@ -40,7 +41,7 @@ const IsActiveSessionCopilotCloud = ContextKeyExpr.equals(ActiveSessionTypeConte
const IsActiveCopilotChatSessionProvider = ContextKeyExpr.equals(ActiveSessionProviderIdContext.key, COPILOT_PROVIDER_ID);
const IsActiveSessionCopilotChatCLI = ContextKeyExpr.and(IsActiveSessionCopilotCLI, IsActiveCopilotChatSessionProvider);
const IsActiveSessionCopilotChatCloud = ContextKeyExpr.and(IsActiveSessionCopilotCloud, IsActiveCopilotChatSessionProvider);
const IsActiveSessionRemoteAgentHost = ContextKeyExpr.regex('activeSessionProviderId', /^agenthost-/);
const IsActiveSessionRemoteAgentHost = ContextKeyExpr.regex(ActiveSessionProviderIdContext.key, /^agenthost-/);
// -- Actions --
@@ -246,7 +247,7 @@ class CopilotPickerActionViewItemContribution extends Disposable implements IWor
modelPicker.setEnabled(models.length > 0);
if (!currentModel.get() && models.length > 0) {
const remembered = rememberedModelId ? models.find(m => m.identifier === rememberedModelId) : undefined;
currentModel.set(remembered ?? models[0], undefined);
delegate.setModel(remembered ?? models[0]);
}
};
initModel();
@@ -362,17 +363,18 @@ class CopilotSessionContextMenuBridge extends Disposable implements IWorkbenchCo
this._bridgedIds.add(commandId);
const wrapperId = `sessionsViewPane.bridge.${commandId}`;
this._register(CommandsRegistry.registerCommand(wrapperId, (accessor, sessionData?: ISession) => {
if (!sessionData) {
this._register(CommandsRegistry.registerCommand(wrapperId, (accessor, context?: ISession | ISession[]) => {
if (!context) {
return;
}
const agentSession = this.agentSessionsService.getSession(sessionData.resource);
if (!agentSession) {
const sessions = Array.isArray(context) ? context : [context];
const agentSessions = coalesce(sessions.map(s => this.agentSessionsService.getSession(s.resource)));
if (agentSessions.length === 0) {
return;
}
return this.commandService.executeCommand(commandId, {
session: agentSession,
sessions: [agentSession],
session: agentSessions[0],
sessions: agentSessions,
$mid: MarshalledId.AgentSessionContext,
});
}));

View File

@@ -258,8 +258,8 @@ export class RemoteAgentHostContribution extends Disposable implements IWorkbenc
loggedConnection.logError('subscribe(root)', err);
});
// Authenticate with this new connection
this._authenticateWithConnection(loggedConnection);
// Authenticate with this new connection and refresh models afterward
this._authenticateWithConnection(loggedConnection).then(() => loggedConnection.refreshModels()).catch(() => { /* best-effort */ });
// Wire connection to existing sessions provider
this._providerInstances.get(address)?.setConnection(loggedConnection, connectionInfo.defaultDirectory);
@@ -380,7 +380,7 @@ export class RemoteAgentHostContribution extends Disposable implements IWorkbenc
private _authenticateAllConnections(): void {
for (const [, connState] of this._connections) {
this._authenticateWithConnection(connState.loggedConnection);
this._authenticateWithConnection(connState.loggedConnection).then(() => connState.loggedConnection.refreshModels()).catch(() => { /* best-effort */ });
}
}