Skip to content

Commit 61dd50f

Browse files
authored
fix(provider): avoid Copilot BYOK activation deadlock (#275)
Register and refresh the DeepSeek provider synchronously so activation can finish while Copilot activation continues in the background. Refresh models after Copilot activates and ignore late completion after disposal. Fixes #274
1 parent e20b408 commit 61dd50f

2 files changed

Lines changed: 24 additions & 13 deletions

File tree

src/runtime/lifecycle.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
1313
registerActionUrls(context);
1414

1515
try {
16-
const provider = await registerProvider(context);
16+
const provider = registerProvider(context);
1717

1818
void showWelcomeIfNeeded(context, provider).catch((error) => {
1919
logger.warn(t('extension.welcomeFailed'), error);

src/runtime/provider.ts

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ import vscode from 'vscode';
22
import { logger } from '../logger';
33
import { DeepSeekChatProvider } from '../provider';
44

5-
export async function registerProvider(
6-
context: vscode.ExtensionContext,
7-
): Promise<DeepSeekChatProvider> {
5+
export function registerProvider(context: vscode.ExtensionContext): DeepSeekChatProvider {
86
const provider = new DeepSeekChatProvider(context);
97

108
context.subscriptions.push(
@@ -16,18 +14,31 @@ export async function registerProvider(
1614
vscode.lm.registerLanguageModelChatProvider('deepseek', provider),
1715
);
1816

19-
// Copilot Chat can serve cached model info without configurationSchema.
20-
// Activate it first so this refresh reaches a live listener and re-queries the provider.
21-
await activateCopilotChat();
17+
// Make models discoverable without waiting for Copilot, which may itself be waiting for BYOK.
2218
provider.refreshModelPicker();
19+
context.subscriptions.push(refreshModelsAfterCopilotActivation(provider));
2320

2421
return provider;
2522
}
2623

27-
async function activateCopilotChat(): Promise<void> {
28-
try {
29-
await vscode.extensions.getExtension('github.copilot-chat')?.activate();
30-
} catch (error) {
31-
logger.warn('Copilot Chat activation unavailable; model picker refresh may be delayed', error);
32-
}
24+
function refreshModelsAfterCopilotActivation(provider: DeepSeekChatProvider): vscode.Disposable {
25+
let disposed = false;
26+
27+
// Keep the post-activation refresh to replace cached model info missing configurationSchema.
28+
Promise.resolve(vscode.extensions.getExtension('github.copilot-chat')?.activate())
29+
.then(() => {
30+
if (!disposed) {
31+
provider.refreshModelPicker();
32+
}
33+
})
34+
.catch((error) => {
35+
if (!disposed) {
36+
logger.warn('Failed to activate Copilot Chat or refresh model information', error);
37+
}
38+
});
39+
40+
// Ignore late activation results after this extension is disposed.
41+
return new vscode.Disposable(() => {
42+
disposed = true;
43+
});
3344
}

0 commit comments

Comments
 (0)