release: v2.33.3 - Integrated Autoplan Intelligence Engine
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.2",
|
"version": "2.33.3",
|
||||||
"publisher": "connectailab",
|
"publisher": "connectailab",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"icon": "assets/icon.png",
|
"icon": "assets/icon.png",
|
||||||
|
|||||||
+181
-16
@@ -147,6 +147,9 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
case 'deleteBrain':
|
case 'deleteBrain':
|
||||||
await this._deleteBrainProfile(data.id);
|
await this._deleteBrainProfile(data.id);
|
||||||
break;
|
break;
|
||||||
|
case 'saveWikiRaw':
|
||||||
|
await this._saveWikiRaw();
|
||||||
|
break;
|
||||||
case 'setBrainProfile':
|
case 'setBrainProfile':
|
||||||
await this._setActiveBrainProfile(data.id);
|
await this._setActiveBrainProfile(data.id);
|
||||||
break;
|
break;
|
||||||
@@ -665,6 +668,150 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
this.injectSystemMessage(`**[Brain Deleted]** ${target.name}`);
|
this.injectSystemMessage(`**[Brain Deleted]** ${target.name}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _saveWikiRaw() {
|
||||||
|
const history = this._agent.getHistory();
|
||||||
|
if (history.length === 0) {
|
||||||
|
vscode.window.showWarningMessage('There is no conversation to save as wiki raw data.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const activeBrain = getActiveBrainProfile();
|
||||||
|
const rawDir = path.join(activeBrain.localBrainPath, 'raw-data');
|
||||||
|
if (!fs.existsSync(rawDir)) {
|
||||||
|
fs.mkdirSync(rawDir, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
const category = await vscode.window.showInputBox({
|
||||||
|
prompt: 'Wiki raw data category',
|
||||||
|
value: 'Project Notes'
|
||||||
|
});
|
||||||
|
if (category === undefined) return;
|
||||||
|
|
||||||
|
const expectedValue = await vscode.window.showInputBox({
|
||||||
|
prompt: 'Expected value or future use',
|
||||||
|
value: 'Reusable as source material for a future wiki document.'
|
||||||
|
});
|
||||||
|
if (expectedValue === undefined) return;
|
||||||
|
|
||||||
|
const timestamp = new Date();
|
||||||
|
const slug = this._slugify(history.find((message) => message.role === 'user')?.content || 'conversation');
|
||||||
|
const fileName = `${this._formatTimestampForFile(timestamp)}-${slug}.md`;
|
||||||
|
const filePath = path.join(rawDir, fileName);
|
||||||
|
const markdown = this._buildWikiRawMarkdown(history, {
|
||||||
|
category: category.trim() || 'Project Notes',
|
||||||
|
expectedValue: expectedValue.trim() || 'Reusable as source material for a future wiki document.',
|
||||||
|
activeBrainName: activeBrain.name,
|
||||||
|
activeBrainPath: activeBrain.localBrainPath,
|
||||||
|
createdAt: timestamp.toISOString()
|
||||||
|
});
|
||||||
|
|
||||||
|
await vscode.workspace.fs.writeFile(vscode.Uri.file(filePath), Buffer.from(markdown, 'utf8'));
|
||||||
|
vscode.window.showInformationMessage(`Wiki raw data saved: ${path.basename(filePath)}`);
|
||||||
|
this.injectSystemMessage(`**[Wiki Raw Saved]** \`${filePath}\``);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _buildWikiRawMarkdown(history: ChatMessage[], meta: {
|
||||||
|
category: string;
|
||||||
|
expectedValue: string;
|
||||||
|
activeBrainName: string;
|
||||||
|
activeBrainPath: string;
|
||||||
|
createdAt: string;
|
||||||
|
}): string {
|
||||||
|
const firstUserMessage = history.find((message) => message.role === 'user')?.content || '';
|
||||||
|
const latestUserMessage = [...history].reverse().find((message) => message.role === 'user')?.content || '';
|
||||||
|
const latestAssistantMessage = [...history].reverse().find((message) => message.role === 'assistant')?.content || '';
|
||||||
|
const rationaleNotes = history
|
||||||
|
.filter((message) => message.role === 'assistant' && message.rationale)
|
||||||
|
.map((message, index) => [
|
||||||
|
`### Process Note ${index + 1}`,
|
||||||
|
message.rationale?.problem ? `- Problem: ${message.rationale.problem}` : '',
|
||||||
|
message.rationale?.goal ? `- Goal: ${message.rationale.goal}` : '',
|
||||||
|
message.rationale?.reasoning ? `- Reasoning: ${message.rationale.reasoning}` : ''
|
||||||
|
].filter(Boolean).join('\n'))
|
||||||
|
.join('\n\n');
|
||||||
|
|
||||||
|
const transcript = history
|
||||||
|
.map((message, index) => [
|
||||||
|
`### ${index + 1}. ${message.role.toUpperCase()}`,
|
||||||
|
'',
|
||||||
|
message.content.trim() || '(empty)'
|
||||||
|
].join('\n'))
|
||||||
|
.join('\n\n');
|
||||||
|
|
||||||
|
return [
|
||||||
|
'---',
|
||||||
|
`title: "${this._escapeYamlString(this._summarizeForTitle(firstUserMessage))}"`,
|
||||||
|
`category: "${this._escapeYamlString(meta.category)}"`,
|
||||||
|
`created_at: "${meta.createdAt}"`,
|
||||||
|
`source: "ConnectAI conversation"`,
|
||||||
|
`brain: "${this._escapeYamlString(meta.activeBrainName)}"`,
|
||||||
|
'status: raw',
|
||||||
|
'---',
|
||||||
|
'',
|
||||||
|
`# ${this._summarizeForTitle(firstUserMessage)}`,
|
||||||
|
'',
|
||||||
|
'## Category',
|
||||||
|
meta.category,
|
||||||
|
'',
|
||||||
|
'## What This Contains',
|
||||||
|
this._summarizeTextForWiki(latestAssistantMessage || firstUserMessage),
|
||||||
|
'',
|
||||||
|
'## Expected Value',
|
||||||
|
meta.expectedValue,
|
||||||
|
'',
|
||||||
|
'## Discovery Process',
|
||||||
|
rationaleNotes || 'No explicit rationale metadata was captured. Use the transcript below to reconstruct the reasoning path.',
|
||||||
|
'',
|
||||||
|
'## Conclusion',
|
||||||
|
[
|
||||||
|
'This conclusion was derived from the latest user request and assistant response.',
|
||||||
|
'',
|
||||||
|
`- Latest user request: ${this._summarizeTextForWiki(latestUserMessage)}`,
|
||||||
|
`- Latest assistant conclusion: ${this._summarizeTextForWiki(latestAssistantMessage)}`
|
||||||
|
].join('\n'),
|
||||||
|
'',
|
||||||
|
'## Coding Implementation Notes',
|
||||||
|
'Use this section to turn the raw transcript into a wiki-ready implementation note. Capture which files changed, why they changed, and what verification was run.',
|
||||||
|
'',
|
||||||
|
'## Source Brain',
|
||||||
|
`- Name: ${meta.activeBrainName}`,
|
||||||
|
`- Path: ${meta.activeBrainPath}`,
|
||||||
|
'',
|
||||||
|
'## Raw Conversation Transcript',
|
||||||
|
transcript,
|
||||||
|
''
|
||||||
|
].join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
private _formatTimestampForFile(date: Date): string {
|
||||||
|
return date.toISOString().replace(/[:.]/g, '-').replace('T', '_').replace('Z', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
private _slugify(value: string): string {
|
||||||
|
const slug = value
|
||||||
|
.toLowerCase()
|
||||||
|
.replace(/[^a-z0-9가-힣]+/g, '-')
|
||||||
|
.replace(/^-|-$/g, '')
|
||||||
|
.slice(0, 48);
|
||||||
|
return slug || 'conversation';
|
||||||
|
}
|
||||||
|
|
||||||
|
private _summarizeForTitle(value: string): string {
|
||||||
|
const normalized = value.replace(/\s+/g, ' ').trim();
|
||||||
|
if (!normalized) return 'ConnectAI Conversation Raw Data';
|
||||||
|
return normalized.length > 80 ? `${normalized.slice(0, 80)}...` : normalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _summarizeTextForWiki(value: string): string {
|
||||||
|
const normalized = value.replace(/\s+/g, ' ').trim();
|
||||||
|
if (!normalized) return 'Not captured.';
|
||||||
|
return normalized.length > 500 ? `${normalized.slice(0, 500)}...` : normalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _escapeYamlString(value: string): string {
|
||||||
|
return value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
||||||
|
}
|
||||||
|
|
||||||
// --- BridgeInterface Methods ---
|
// --- BridgeInterface Methods ---
|
||||||
|
|
||||||
public injectSystemMessage(msg: string): void {
|
public injectSystemMessage(msg: string): void {
|
||||||
@@ -1083,6 +1230,19 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
}
|
}
|
||||||
.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; }
|
||||||
|
.control-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1fr) auto;
|
||||||
|
gap: 6px;
|
||||||
|
width: 100%;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.utility-row {
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
.brand { font-weight: 700; font-size: 14px; color: var(--text-bright); letter-spacing: 0; display: flex; align-items: center; gap: 8px; min-width: 0; }
|
.brand { font-weight: 700; font-size: 14px; color: var(--text-bright); letter-spacing: 0; display: flex; align-items: center; gap: 8px; min-width: 0; }
|
||||||
.logo { width: 22px; height: 22px; background: var(--accent); color: #fff; border-radius: 6px; display: flex; align-items: center; justify-content: center; font-size: 14px; font-weight: 900; }
|
.logo { width: 22px; height: 22px; background: var(--accent); color: #fff; border-radius: 6px; display: flex; align-items: center; justify-content: center; font-size: 14px; font-weight: 900; }
|
||||||
@@ -1589,26 +1749,29 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
<div class="status-pill"><span id="statusDot" class="status-dot"></span><span id="engineStatusText">Engine</span></div>
|
<div class="status-pill"><span id="statusDot" class="status-dot"></span><span id="engineStatusText">Engine</span></div>
|
||||||
<div class="select-wrap"><select id="modelSel" title="Select Model"></select></div>
|
<div class="select-wrap"><select id="modelSel" title="Select Model"></select></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="select-line">
|
<div class="control-row">
|
||||||
<div class="select-wrap"><select id="brainSel" title="Select Brain"></select></div>
|
<div class="select-wrap"><select id="brainSel" title="Select Brain"></select></div>
|
||||||
|
<div class="tool-group" aria-label="Brain actions">
|
||||||
|
<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>
|
||||||
|
<div class="control-row">
|
||||||
<div class="select-wrap"><select id="agentSel" title="Select Agentic Skill"></select></div>
|
<div class="select-wrap"><select id="agentSel" title="Select Agentic Skill"></select></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>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="utility-row">
|
||||||
<div class="tool-strip">
|
<button class="icon-btn" id="saveWikiRawBtn" data-tooltip="Save Wiki Raw">□</button>
|
||||||
<div class="tool-group" aria-label="Brain actions">
|
<button class="icon-btn" id="multiAgentBtn" data-tooltip="Multi-Agent Mode">⧉</button>
|
||||||
<button class="icon-btn" id="addBrainBtn" data-tooltip="Add Brain">+</button>
|
<button class="icon-btn" id="internetBtn" data-tooltip="Internet Access">↗</button>
|
||||||
<button class="icon-btn" id="editBrainBtn" data-tooltip="Edit Brain">✎</button>
|
<button class="icon-btn" id="historyBtn" data-tooltip="View History">◷</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>
|
||||||
<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="internetBtn" data-tooltip="Internet Access">↗</button>
|
|
||||||
<button class="icon-btn" id="historyBtn" data-tooltip="View History">◷</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1795,6 +1958,7 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
const addBrainBtn = document.getElementById('addBrainBtn');
|
const addBrainBtn = document.getElementById('addBrainBtn');
|
||||||
const editBrainBtn = document.getElementById('editBrainBtn');
|
const editBrainBtn = document.getElementById('editBrainBtn');
|
||||||
const deleteBrainBtn = document.getElementById('deleteBrainBtn');
|
const deleteBrainBtn = document.getElementById('deleteBrainBtn');
|
||||||
|
const saveWikiRawBtn = document.getElementById('saveWikiRawBtn');
|
||||||
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');
|
||||||
@@ -2167,6 +2331,7 @@ 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;
|
||||||
|
saveWikiRawBtn.onclick = () => vscode.postMessage({ type: 'saveWikiRaw' });
|
||||||
addBrainBtn.onclick = () => vscode.postMessage({ type: 'addBrain' });
|
addBrainBtn.onclick = () => vscode.postMessage({ type: 'addBrain' });
|
||||||
editBrainBtn.onclick = () => {
|
editBrainBtn.onclick = () => {
|
||||||
if (!brainSel.value || brainSel.value === 'new') return;
|
if (!brainSel.value || brainSel.value === 'new') return;
|
||||||
|
|||||||
Reference in New Issue
Block a user