feat: refactor AI engine logic, remove cross-engine fallback, add retry with backoff, and bump version to 2.80.18
This commit is contained in:
+30
-25
@@ -51,6 +51,7 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
||||
private _currentSessionBrainId: string | null = null;
|
||||
private _currentNegativePrompt: string = '';
|
||||
private readonly _chronicle = new ProjectChronicleManager();
|
||||
private _modelDiscoveryInFlight = false;
|
||||
|
||||
constructor(
|
||||
private readonly _extensionUri: vscode.Uri,
|
||||
@@ -75,13 +76,18 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
||||
};
|
||||
|
||||
// [State Persistence Fix] 사이드바가 다시 보여질 때 세팅값 자동 복원
|
||||
let _lastVisibilityRefresh = 0;
|
||||
webviewView.onDidChangeVisibility(() => {
|
||||
if (webviewView.visible) {
|
||||
logInfo('Sidebar became visible, restoring state...');
|
||||
void this._sendModels();
|
||||
void this._sendBrainProfiles();
|
||||
void this._sendAgentsList();
|
||||
}
|
||||
if (!webviewView.visible) return;
|
||||
const now = Date.now();
|
||||
// 5초 이내에 이미 갱신했으면 건너뜀
|
||||
if (now - _lastVisibilityRefresh < 5000) return;
|
||||
_lastVisibilityRefresh = now;
|
||||
|
||||
logInfo('Sidebar became visible, restoring state...');
|
||||
void this._sendModels();
|
||||
void this._sendBrainProfiles();
|
||||
void this._sendAgentsList();
|
||||
});
|
||||
|
||||
webviewView.webview.html = this._getHtml(webviewView.webview);
|
||||
@@ -1950,26 +1956,26 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
||||
|
||||
private async _sendModels() {
|
||||
if (!this._view) return;
|
||||
if (this._modelDiscoveryInFlight) {
|
||||
logInfo('Model discovery already in progress, skipping.');
|
||||
return;
|
||||
}
|
||||
this._modelDiscoveryInFlight = true;
|
||||
try {
|
||||
const config = getConfig();
|
||||
const url = config.ollamaUrl;
|
||||
let defaultModel = config.defaultModel;
|
||||
let models: string[] = [];
|
||||
|
||||
const primaryEngine = resolveEngine(url);
|
||||
const engines = primaryEngine === 'lmstudio' ? ['lmstudio', 'ollama'] as const : ['ollama', 'lmstudio'] as const;
|
||||
|
||||
for (const engine of engines) {
|
||||
const modelsUrl = buildApiUrl(url, engine, 'models');
|
||||
try {
|
||||
logInfo('Model discovery started.', { engine, modelsUrl });
|
||||
const res = await fetch(modelsUrl, { signal: AbortSignal.timeout(5000) });
|
||||
const rawText = await res.text();
|
||||
if (!res.ok) {
|
||||
logError('Model discovery returned non-OK status.', { engine, modelsUrl, status: res.status, body: summarizeText(rawText, 300) });
|
||||
continue;
|
||||
}
|
||||
|
||||
const engine = resolveEngine(url); // 단일 엔진만
|
||||
const modelsUrl = buildApiUrl(url, engine, 'models');
|
||||
try {
|
||||
logInfo('Model discovery started.', { engine, modelsUrl });
|
||||
const res = await fetch(modelsUrl, { signal: AbortSignal.timeout(5000) });
|
||||
const rawText = await res.text();
|
||||
if (!res.ok) {
|
||||
logError('Model discovery returned non-OK status.', { engine, modelsUrl, status: res.status, body: summarizeText(rawText, 300) });
|
||||
} else {
|
||||
const data = rawText ? JSON.parse(rawText) as any : {};
|
||||
models = engine === 'lmstudio'
|
||||
? (data.data || []).map((m: any) => m.id)
|
||||
@@ -1977,11 +1983,10 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
||||
|
||||
if (models.length > 0) {
|
||||
logInfo('Model discovery succeeded.', { engine, count: models.length, modelsPreview: models.slice(0, 5) });
|
||||
break;
|
||||
}
|
||||
} catch (e: any) {
|
||||
logError('Model discovery failed.', { engine, modelsUrl, error: e?.message || String(e) });
|
||||
}
|
||||
} catch (e: any) {
|
||||
logError('Model discovery failed.', { engine, modelsUrl, error: e?.message || String(e) });
|
||||
}
|
||||
|
||||
if (models.length === 0) {
|
||||
@@ -2017,8 +2022,8 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
||||
this._view.webview.postMessage({ type: 'modelsList', value: { models, selected: defaultModel } });
|
||||
} catch (err) {
|
||||
logError('Model list update failed.', err);
|
||||
const fallbackModel = getConfig().defaultModel;
|
||||
this._view.webview.postMessage({ type: 'modelsList', value: { models: fallbackModel ? [fallbackModel] : [], selected: fallbackModel } });
|
||||
} finally {
|
||||
this._modelDiscoveryInFlight = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user