release: v2.33.2 - Final polish and build
This commit is contained in:
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
"name": "g1nation",
|
"name": "g1nation",
|
||||||
"displayName": "G1nation",
|
"displayName": "G1nation",
|
||||||
"description": "High-performance autonomous local AI coding agent for VS Code. Features vectorized inference, asynchronous task management, and 100% offline processing.",
|
"description": "High-performance autonomous local AI coding agent for VS Code. Features vectorized inference, asynchronous task management, and 100% offline processing.",
|
||||||
"version": "2.33.1",
|
"version": "2.33.2",
|
||||||
"publisher": "connectailab",
|
"publisher": "connectailab",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"icon": "assets/icon.png",
|
"icon": "assets/icon.png",
|
||||||
|
|||||||
+182
-20
@@ -141,6 +141,12 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
case 'addBrain':
|
case 'addBrain':
|
||||||
await this._addBrainProfile();
|
await this._addBrainProfile();
|
||||||
break;
|
break;
|
||||||
|
case 'editBrain':
|
||||||
|
await this._editBrainProfile(data.id);
|
||||||
|
break;
|
||||||
|
case 'deleteBrain':
|
||||||
|
await this._deleteBrainProfile(data.id);
|
||||||
|
break;
|
||||||
case 'setBrainProfile':
|
case 'setBrainProfile':
|
||||||
await this._setActiveBrainProfile(data.id);
|
await this._setActiveBrainProfile(data.id);
|
||||||
break;
|
break;
|
||||||
@@ -150,6 +156,9 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
case 'updateAgent':
|
case 'updateAgent':
|
||||||
await this._updateAgent(data.path, data.content, data.negativePrompt);
|
await this._updateAgent(data.path, data.content, data.negativePrompt);
|
||||||
break;
|
break;
|
||||||
|
case 'deleteAgent':
|
||||||
|
await this._deleteAgent(data.path);
|
||||||
|
break;
|
||||||
case 'refreshModels':
|
case 'refreshModels':
|
||||||
await this._sendModels();
|
await this._sendModels();
|
||||||
break;
|
break;
|
||||||
@@ -449,6 +458,23 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _postBrainProfiles(profiles: any[], activeBrainId: string) {
|
||||||
|
if (!this._view) return;
|
||||||
|
this._view.webview.postMessage({
|
||||||
|
type: 'brainProfiles',
|
||||||
|
value: {
|
||||||
|
activeBrainId,
|
||||||
|
profiles: profiles.map((p: any) => ({
|
||||||
|
id: p.id || '',
|
||||||
|
name: p.name || '',
|
||||||
|
path: p.localBrainPath || '',
|
||||||
|
description: p.description || '',
|
||||||
|
repo: p.secondBrainRepo || ''
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private async _setActiveBrainProfile(profileId: string, silent: boolean = false) {
|
private async _setActiveBrainProfile(profileId: string, silent: boolean = false) {
|
||||||
const profiles = getBrainProfiles();
|
const profiles = getBrainProfiles();
|
||||||
const nextProfile = profiles.find((profile) => profile.id === profileId) || profiles[0];
|
const nextProfile = profiles.find((profile) => profile.id === profileId) || profiles[0];
|
||||||
@@ -555,28 +581,90 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
await cfg.update('activeBrainId', id, vscode.ConfigurationTarget.Global);
|
await cfg.update('activeBrainId', id, vscode.ConfigurationTarget.Global);
|
||||||
this._currentSessionBrainId = id;
|
this._currentSessionBrainId = id;
|
||||||
|
|
||||||
// Directly post the freshly-built profile list to the webview.
|
|
||||||
// cfg.update() is async and VSCode's config cache may not reflect the new value
|
// cfg.update() is async and VSCode's config cache may not reflect the new value
|
||||||
// immediately, so we avoid re-reading via getBrainProfiles() here.
|
// immediately, so we post the freshly-built profile list directly.
|
||||||
if (this._view) {
|
this._postBrainProfiles(nextProfiles, id);
|
||||||
this._view.webview.postMessage({
|
|
||||||
type: 'brainProfiles',
|
|
||||||
value: {
|
|
||||||
activeBrainId: id,
|
|
||||||
profiles: nextProfiles.map((p: any) => ({
|
|
||||||
id: p.id || '',
|
|
||||||
name: p.name || '',
|
|
||||||
path: p.localBrainPath || '',
|
|
||||||
description: p.description || '',
|
|
||||||
repo: p.secondBrainRepo || ''
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
await this._sendBrainStatus();
|
await this._sendBrainStatus();
|
||||||
this.injectSystemMessage(`**[Brain Added]** ${name.trim()}\n\`${folder}\``);
|
this.injectSystemMessage(`**[Brain Added]** ${name.trim()}\n\`${folder}\``);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _editBrainProfile(profileId?: string) {
|
||||||
|
const currentProfiles = getBrainProfiles();
|
||||||
|
const target = currentProfiles.find((profile) => profile.id === profileId) || getActiveBrainProfile();
|
||||||
|
if (!target) return;
|
||||||
|
|
||||||
|
const name = await vscode.window.showInputBox({
|
||||||
|
prompt: 'Edit brain profile name',
|
||||||
|
value: target.name,
|
||||||
|
validateInput: (value) => value.trim() ? null : 'Brain name is required.'
|
||||||
|
});
|
||||||
|
if (!name) return;
|
||||||
|
|
||||||
|
const folder = await vscode.window.showInputBox({
|
||||||
|
prompt: 'Edit local brain folder path',
|
||||||
|
value: target.localBrainPath,
|
||||||
|
validateInput: (value) => value.trim() ? null : 'Brain folder path is required.'
|
||||||
|
});
|
||||||
|
if (!folder) return;
|
||||||
|
|
||||||
|
const description = await vscode.window.showInputBox({
|
||||||
|
prompt: 'Edit optional description shown in the G1nation sidebar',
|
||||||
|
value: target.description || ''
|
||||||
|
});
|
||||||
|
|
||||||
|
const repo = await vscode.window.showInputBox({
|
||||||
|
prompt: 'Edit optional Second Brain Git repository URL',
|
||||||
|
value: target.secondBrainRepo || ''
|
||||||
|
});
|
||||||
|
|
||||||
|
const nextProfiles = currentProfiles.map((profile) => profile.id === target.id
|
||||||
|
? {
|
||||||
|
...profile,
|
||||||
|
name: name.trim(),
|
||||||
|
localBrainPath: folder.trim(),
|
||||||
|
secondBrainRepo: (repo || '').trim(),
|
||||||
|
description: (description || '').trim()
|
||||||
|
}
|
||||||
|
: profile
|
||||||
|
);
|
||||||
|
|
||||||
|
const cfg = vscode.workspace.getConfiguration('g1nation');
|
||||||
|
await cfg.update('brainProfiles', nextProfiles, vscode.ConfigurationTarget.Global);
|
||||||
|
await cfg.update('activeBrainId', target.id, vscode.ConfigurationTarget.Global);
|
||||||
|
this._currentSessionBrainId = target.id;
|
||||||
|
this._postBrainProfiles(nextProfiles, target.id);
|
||||||
|
await this._sendBrainStatus();
|
||||||
|
this.injectSystemMessage(`**[Brain Updated]** ${name.trim()}\n\`${folder.trim()}\``);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _deleteBrainProfile(profileId?: string) {
|
||||||
|
const currentProfiles = getBrainProfiles();
|
||||||
|
const target = currentProfiles.find((profile) => profile.id === profileId) || getActiveBrainProfile();
|
||||||
|
if (!target) return;
|
||||||
|
|
||||||
|
if (currentProfiles.length <= 1) {
|
||||||
|
vscode.window.showWarningMessage('At least one brain profile is required.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirm = await vscode.window.showWarningMessage(
|
||||||
|
`Delete brain profile "${target.name}"? The folder itself will not be deleted.`,
|
||||||
|
{ modal: true },
|
||||||
|
'Delete Profile'
|
||||||
|
);
|
||||||
|
if (confirm !== 'Delete Profile') return;
|
||||||
|
|
||||||
|
const nextProfiles = currentProfiles.filter((profile) => profile.id !== target.id);
|
||||||
|
const nextActive = nextProfiles[0];
|
||||||
|
const cfg = vscode.workspace.getConfiguration('g1nation');
|
||||||
|
await cfg.update('brainProfiles', nextProfiles, vscode.ConfigurationTarget.Global);
|
||||||
|
await cfg.update('activeBrainId', nextActive.id, vscode.ConfigurationTarget.Global);
|
||||||
|
this._currentSessionBrainId = nextActive.id;
|
||||||
|
this._postBrainProfiles(nextProfiles, nextActive.id);
|
||||||
|
await this._sendBrainStatus();
|
||||||
|
this.injectSystemMessage(`**[Brain Deleted]** ${target.name}`);
|
||||||
|
}
|
||||||
|
|
||||||
// --- BridgeInterface Methods ---
|
// --- BridgeInterface Methods ---
|
||||||
|
|
||||||
public injectSystemMessage(msg: string): void {
|
public injectSystemMessage(msg: string): void {
|
||||||
@@ -741,6 +829,40 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _deleteAgent(agentPath: string) {
|
||||||
|
if (!agentPath || agentPath === 'none') return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const agentsDir = path.resolve(this._getAgentsDir());
|
||||||
|
const targetPath = path.resolve(agentPath);
|
||||||
|
if (!targetPath.startsWith(`${agentsDir}${path.sep}`) || path.extname(targetPath) !== '.md') {
|
||||||
|
vscode.window.showErrorMessage('Selected agent skill path is not valid.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fs.existsSync(targetPath)) {
|
||||||
|
await this._context.globalState.update(SidebarChatProvider.lastAgentStateKey, 'none');
|
||||||
|
await this._sendAgentsList();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirm = await vscode.window.showWarningMessage(
|
||||||
|
`Delete agent skill "${path.basename(targetPath, '.md')}"?`,
|
||||||
|
{ modal: true },
|
||||||
|
'Delete Skill'
|
||||||
|
);
|
||||||
|
if (confirm !== 'Delete Skill') return;
|
||||||
|
|
||||||
|
fs.unlinkSync(targetPath);
|
||||||
|
await this._context.globalState.update(SidebarChatProvider.lastAgentStateKey, 'none');
|
||||||
|
await this._sendAgentsList();
|
||||||
|
this._view?.webview.postMessage({ type: 'agentDeleted' });
|
||||||
|
vscode.window.showInformationMessage('Agent skill deleted successfully.');
|
||||||
|
} catch (err: any) {
|
||||||
|
vscode.window.showErrorMessage(`Failed to delete agent: ${err.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async _handlePrompt(data: any) {
|
private async _handlePrompt(data: any) {
|
||||||
if (!this._view) return;
|
if (!this._view) return;
|
||||||
|
|
||||||
@@ -942,6 +1064,7 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
|
|
||||||
.header-actions,
|
.header-actions,
|
||||||
.tool-strip,
|
.tool-strip,
|
||||||
|
.tool-group,
|
||||||
.select-stack,
|
.select-stack,
|
||||||
.select-line,
|
.select-line,
|
||||||
.status-pill {
|
.status-pill {
|
||||||
@@ -951,6 +1074,13 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
|
|
||||||
.header-actions { gap: 6px; flex-shrink: 0; }
|
.header-actions { gap: 6px; flex-shrink: 0; }
|
||||||
.tool-strip { gap: 6px; flex-wrap: wrap; }
|
.tool-strip { gap: 6px; flex-wrap: wrap; }
|
||||||
|
.tool-group {
|
||||||
|
gap: 4px;
|
||||||
|
padding: 3px;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 8px;
|
||||||
|
background: rgba(255, 255, 255, 0.02);
|
||||||
|
}
|
||||||
.select-stack { flex-direction: column; gap: 6px; min-width: 0; }
|
.select-stack { flex-direction: column; gap: 6px; min-width: 0; }
|
||||||
.select-line { gap: 6px; width: 100%; min-width: 0; }
|
.select-line { gap: 6px; width: 100%; min-width: 0; }
|
||||||
|
|
||||||
@@ -1465,11 +1595,19 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tool-strip">
|
<div class="tool-strip">
|
||||||
<button class="icon-btn" id="editAgentBtn" data-tooltip="Edit Agent Skill">✎</button>
|
<div class="tool-group" aria-label="Brain actions">
|
||||||
<button class="icon-btn" id="addAgentBtn" data-tooltip="Create Agent">+</button>
|
<button class="icon-btn" id="addBrainBtn" data-tooltip="Add Brain">+</button>
|
||||||
|
<button class="icon-btn" id="editBrainBtn" data-tooltip="Edit Brain">✎</button>
|
||||||
|
<button class="icon-btn" id="deleteBrainBtn" data-tooltip="Delete Brain">−</button>
|
||||||
|
<button class="icon-btn" id="brainBtn" data-tooltip="Sync Knowledge">↻</button>
|
||||||
|
</div>
|
||||||
|
<div class="tool-group" aria-label="Agent actions">
|
||||||
|
<button class="icon-btn" id="addAgentBtn" data-tooltip="Create Agent">+</button>
|
||||||
|
<button class="icon-btn" id="editAgentBtn" data-tooltip="Edit Agent Skill">✎</button>
|
||||||
|
<button class="icon-btn" id="deleteAgentBtn" data-tooltip="Delete Agent Skill">−</button>
|
||||||
|
</div>
|
||||||
<button class="icon-btn" id="multiAgentBtn" data-tooltip="Multi-Agent Mode">⧉</button>
|
<button class="icon-btn" id="multiAgentBtn" data-tooltip="Multi-Agent Mode">⧉</button>
|
||||||
<button class="icon-btn" id="internetBtn" data-tooltip="Internet Access">↗</button>
|
<button class="icon-btn" id="internetBtn" data-tooltip="Internet Access">↗</button>
|
||||||
<button class="icon-btn" id="brainBtn" data-tooltip="Sync Knowledge">↻</button>
|
|
||||||
<button class="icon-btn" id="historyBtn" data-tooltip="View History">◷</button>
|
<button class="icon-btn" id="historyBtn" data-tooltip="View History">◷</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1653,6 +1791,10 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
const agentSel = document.getElementById('agentSel');
|
const agentSel = document.getElementById('agentSel');
|
||||||
const editAgentBtn = document.getElementById('editAgentBtn');
|
const editAgentBtn = document.getElementById('editAgentBtn');
|
||||||
const addAgentBtn = document.getElementById('addAgentBtn');
|
const addAgentBtn = document.getElementById('addAgentBtn');
|
||||||
|
const deleteAgentBtn = document.getElementById('deleteAgentBtn');
|
||||||
|
const addBrainBtn = document.getElementById('addBrainBtn');
|
||||||
|
const editBrainBtn = document.getElementById('editBrainBtn');
|
||||||
|
const deleteBrainBtn = document.getElementById('deleteBrainBtn');
|
||||||
const agentConfigPanel = document.getElementById('agentConfigPanel');
|
const agentConfigPanel = document.getElementById('agentConfigPanel');
|
||||||
const agentPrompt = document.getElementById('agentPrompt');
|
const agentPrompt = document.getElementById('agentPrompt');
|
||||||
const negativePrompt = document.getElementById('negativePrompt');
|
const negativePrompt = document.getElementById('negativePrompt');
|
||||||
@@ -1865,6 +2007,13 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
agentPrompt.value = msg.value;
|
agentPrompt.value = msg.value;
|
||||||
negativePrompt.value = msg.negativePrompt || '';
|
negativePrompt.value = msg.negativePrompt || '';
|
||||||
break;
|
break;
|
||||||
|
case 'agentDeleted':
|
||||||
|
agentConfigPanel.style.display = 'none';
|
||||||
|
editMode = false;
|
||||||
|
editAgentBtn.classList.remove('active');
|
||||||
|
agentPrompt.value = '';
|
||||||
|
negativePrompt.value = '';
|
||||||
|
break;
|
||||||
case 'error':
|
case 'error':
|
||||||
thinkingBar.classList.remove('active'); sendBtn.disabled = false;
|
thinkingBar.classList.remove('active'); sendBtn.disabled = false;
|
||||||
addMsg(msg.value, 'error');
|
addMsg(msg.value, 'error');
|
||||||
@@ -2018,6 +2167,15 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
|
|
||||||
const syncBrain = () => { Sound.play(550, 'sine', 0.1); vscode.postMessage({ type: 'syncBrain' }); };
|
const syncBrain = () => { Sound.play(550, 'sine', 0.1); vscode.postMessage({ type: 'syncBrain' }); };
|
||||||
document.getElementById('brainBtn').onclick = syncBrain;
|
document.getElementById('brainBtn').onclick = syncBrain;
|
||||||
|
addBrainBtn.onclick = () => vscode.postMessage({ type: 'addBrain' });
|
||||||
|
editBrainBtn.onclick = () => {
|
||||||
|
if (!brainSel.value || brainSel.value === 'new') return;
|
||||||
|
vscode.postMessage({ type: 'editBrain', id: brainSel.value });
|
||||||
|
};
|
||||||
|
deleteBrainBtn.onclick = () => {
|
||||||
|
if (!brainSel.value || brainSel.value === 'new') return;
|
||||||
|
vscode.postMessage({ type: 'deleteBrain', id: brainSel.value });
|
||||||
|
};
|
||||||
document.getElementById('inputSyncBtn').onclick = syncBrain;
|
document.getElementById('inputSyncBtn').onclick = syncBrain;
|
||||||
document.getElementById('historyBtn').onclick = () => vscode.postMessage({ type: 'getSessions' });
|
document.getElementById('historyBtn').onclick = () => vscode.postMessage({ type: 'getSessions' });
|
||||||
document.getElementById('historyBtn').addEventListener('click', () => historyOverlay.classList.add('visible'));
|
document.getElementById('historyBtn').addEventListener('click', () => historyOverlay.classList.add('visible'));
|
||||||
@@ -2092,6 +2250,10 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
};
|
};
|
||||||
|
|
||||||
addAgentBtn.onclick = () => vscode.postMessage({ type: 'createAgent' });
|
addAgentBtn.onclick = () => vscode.postMessage({ type: 'createAgent' });
|
||||||
|
deleteAgentBtn.onclick = () => {
|
||||||
|
if (agentSel.value === 'none') return;
|
||||||
|
vscode.postMessage({ type: 'deleteAgent', path: agentSel.value });
|
||||||
|
};
|
||||||
|
|
||||||
vscode.postMessage({ type: 'getModels' });
|
vscode.postMessage({ type: 'getModels' });
|
||||||
vscode.postMessage({ type: 'getAgents' });
|
vscode.postMessage({ type: 'getAgents' });
|
||||||
|
|||||||
Reference in New Issue
Block a user