release: v2.33.3 - Integrated Autoplan Intelligence Engine

This commit is contained in:
g1nation
2026-05-01 18:46:45 +09:00
parent e91b0d9fb0
commit ddb96e6407
2 changed files with 182 additions and 17 deletions
+1 -1
View File
@@ -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.2",
"version": "2.33.3",
"publisher": "connectailab",
"license": "MIT",
"icon": "assets/icon.png",
+181 -16
View File
@@ -147,6 +147,9 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
case 'deleteBrain':
await this._deleteBrainProfile(data.id);
break;
case 'saveWikiRaw':
await this._saveWikiRaw();
break;
case 'setBrainProfile':
await this._setActiveBrainProfile(data.id);
break;
@@ -665,6 +668,150 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
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 ---
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-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; }
.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="select-wrap"><select id="modelSel" title="Select Model"></select></div>
</div>
<div class="select-line">
<div class="control-row">
<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="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 class="tool-strip">
<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 class="utility-row">
<button class="icon-btn" id="saveWikiRawBtn" data-tooltip="Save Wiki Raw">□</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="historyBtn" data-tooltip="View History"></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="internetBtn" data-tooltip="Internet Access">↗</button>
<button class="icon-btn" id="historyBtn" data-tooltip="View History">◷</button>
</div>
</div>
</div>
@@ -1795,6 +1958,7 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
const addBrainBtn = document.getElementById('addBrainBtn');
const editBrainBtn = document.getElementById('editBrainBtn');
const deleteBrainBtn = document.getElementById('deleteBrainBtn');
const saveWikiRawBtn = document.getElementById('saveWikiRawBtn');
const agentConfigPanel = document.getElementById('agentConfigPanel');
const agentPrompt = document.getElementById('agentPrompt');
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' }); };
document.getElementById('brainBtn').onclick = syncBrain;
saveWikiRawBtn.onclick = () => vscode.postMessage({ type: 'saveWikiRaw' });
addBrainBtn.onclick = () => vscode.postMessage({ type: 'addBrain' });
editBrainBtn.onclick = () => {
if (!brainSel.value || brainSel.value === 'new') return;