fix: chat history persistence and webview state restoration
This commit is contained in:
@@ -1,3 +1,12 @@
|
||||
# Patch Notes - v2.33.6 (2026-05-01)
|
||||
|
||||
## 🛠️ Critical Bug Fixes
|
||||
- **Chat Persistence Overhaul:** Resolved an issue where chat history disappeared after switching sidebar tabs.
|
||||
- **Webview State Management:** Implemented `vscode.setState` for instant UI restoration.
|
||||
- **Internal Message Logic:** Refined message filtering to ensure intermediate agent steps are visible to the user.
|
||||
|
||||
---
|
||||
|
||||
# Patch Notes - v2.33.5 (2026-05-01)
|
||||
|
||||
## 🎨 UI Refinement
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
"name": "g1nation",
|
||||
"displayName": "G1nation",
|
||||
"description": "High-performance autonomous local AI coding agent for VS Code. Features vectorized inference, asynchronous task management, and 100% offline processing.",
|
||||
"version": "2.33.5",
|
||||
"version": "2.33.6",
|
||||
"publisher": "connectailab",
|
||||
"license": "MIT",
|
||||
"icon": "assets/icon.png",
|
||||
|
||||
+2
-3
@@ -119,7 +119,7 @@ export class AgentExecutor {
|
||||
}
|
||||
|
||||
public getHistory() {
|
||||
return this.chatHistory.filter(message => !message.internal);
|
||||
return this.chatHistory.filter(message => !message.internal || message.role === 'assistant');
|
||||
}
|
||||
|
||||
public setHistory(history: ChatMessage[]) {
|
||||
@@ -394,7 +394,7 @@ export class AgentExecutor {
|
||||
|
||||
// 5. Execute Actions
|
||||
const rationale = this.parseRationale(aiResponseText);
|
||||
const assistantMessage: ChatMessage = { role: 'assistant', content: aiResponseText, internal: true, rationale };
|
||||
const assistantMessage: ChatMessage = { role: 'assistant', content: aiResponseText, internal: false, rationale };
|
||||
this.chatHistory.push(assistantMessage);
|
||||
|
||||
this.statusBarManager.updateStatus(AgentStatus.Executing);
|
||||
@@ -443,7 +443,6 @@ export class AgentExecutor {
|
||||
return;
|
||||
}
|
||||
|
||||
assistantMessage.internal = false;
|
||||
this.emitHistoryChanged();
|
||||
this.statusBarManager.updateStatus(AgentStatus.Success);
|
||||
this.webview.postMessage({ type: 'streamChunk', value: aiResponseText });
|
||||
|
||||
+45
-10
@@ -200,7 +200,9 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
||||
if (!this._view) return;
|
||||
|
||||
const blankChatActive = this._context.globalState.get<boolean>(SidebarChatProvider.blankChatStateKey, false);
|
||||
if (blankChatActive) {
|
||||
const currentHistory = this._agent.getHistory();
|
||||
|
||||
if (blankChatActive && currentHistory.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -212,7 +214,6 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
||||
await this._context.globalState.update(SidebarChatProvider.activeSessionStateKey, null);
|
||||
}
|
||||
|
||||
const currentHistory = this._agent.getHistory();
|
||||
if (currentHistory.length > 0) {
|
||||
this._view.webview.postMessage({ type: 'restoreHistory', value: currentHistory });
|
||||
await this._persistLastVisibleChat(currentHistory);
|
||||
@@ -1893,6 +1894,29 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
||||
const vscode = acquireVsCodeApi();
|
||||
const chat = document.getElementById('chat');
|
||||
const input = document.getElementById('input');
|
||||
|
||||
// [State Persistence - Tier 0] 즉시 복원 (Instant Restore from WebView State)
|
||||
const previousState = vscode.getState();
|
||||
if (previousState && previousState.history && previousState.history.length > 0) {
|
||||
console.log('[G1nation] Restoring from Webview State...');
|
||||
renderHistory(previousState.history);
|
||||
}
|
||||
|
||||
function saveWebviewState(history) {
|
||||
vscode.setState({ history });
|
||||
}
|
||||
|
||||
function renderHistory(history) {
|
||||
if (!history || history.length === 0) return;
|
||||
chat.innerHTML = '';
|
||||
history.forEach(m => {
|
||||
if (!m) return;
|
||||
// Only skip truly internal system messages, keep assistant thoughts
|
||||
if (m.role === 'system' && m.internal) return;
|
||||
addMsg(m.content, m.role === 'assistant' ? 'assistant' : 'user', m.rationale);
|
||||
});
|
||||
chat.scrollTop = chat.scrollHeight;
|
||||
}
|
||||
const sendBtn = document.getElementById('sendBtn');
|
||||
const stopBtn = document.getElementById('stopBtn');
|
||||
const cancelBtn = document.getElementById('cancelBtn');
|
||||
@@ -2112,6 +2136,10 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
||||
switch(msg.type) {
|
||||
case 'addMessage':
|
||||
addMsg(msg.value, msg.role, msg.rationale);
|
||||
// Update state for non-streamed messages
|
||||
const s = vscode.getState() || { history: [] };
|
||||
s.history.push({ role: msg.role === 'assistant' ? 'assistant' : 'user', content: msg.value, rationale: msg.rationale });
|
||||
saveWebviewState(s.history);
|
||||
break;
|
||||
case 'streamStart':
|
||||
thinkingBar.classList.remove('active');
|
||||
@@ -2128,9 +2156,15 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
||||
}
|
||||
break;
|
||||
case 'streamEnd':
|
||||
if (streamBody) streamBody.classList.remove('stream-active');
|
||||
if (streamBody) {
|
||||
streamBody.classList.remove('stream-active');
|
||||
// Update state after stream finishes
|
||||
const state = vscode.getState() || { history: [] };
|
||||
state.history.push({ role: 'assistant', content: streamBody._parent._raw });
|
||||
saveWebviewState(state.history);
|
||||
}
|
||||
streamBody = null;
|
||||
// \uc0dd\uc131 \uc644\ub8cc \uc2dc Stop \ubc84\ud2bc \uc228\uae30\uace0 Send \ubcf5\uad50
|
||||
// 생성 완료 시 Stop 버튼 숨기고 Send 복구
|
||||
setGenerating(false);
|
||||
resetStepper();
|
||||
Sound.success();
|
||||
@@ -2143,12 +2177,8 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
||||
: (Array.isArray(historyPayload?.history) ? historyPayload.history : []);
|
||||
|
||||
if (history && history.length > 0) {
|
||||
chat.innerHTML = '';
|
||||
history.forEach(m => {
|
||||
if (!m || m.internal) return;
|
||||
addMsg(m.content, m.role === 'assistant' ? 'assistant' : 'user', m.rationale);
|
||||
});
|
||||
chat.scrollTop = chat.scrollHeight;
|
||||
renderHistory(history);
|
||||
saveWebviewState(history);
|
||||
}
|
||||
if (historyPayload?.negativePrompt !== undefined) {
|
||||
negativePrompt.value = historyPayload.negativePrompt;
|
||||
@@ -2358,6 +2388,11 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
||||
setDraftActive(false);
|
||||
setGenerating(true);
|
||||
thinkingBar.classList.add('active');
|
||||
|
||||
// Save state after sending
|
||||
const currentState = vscode.getState() || { history: [] };
|
||||
currentState.history.push({ role: 'user', content: val });
|
||||
saveWebviewState(currentState.history);
|
||||
}
|
||||
|
||||
sendBtn.onclick = send;
|
||||
|
||||
Reference in New Issue
Block a user