release: v2.33.3 - Integrated Autoplan Intelligence Engine
This commit is contained in:
+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.2",
|
||||
"version": "2.33.3",
|
||||
"publisher": "connectailab",
|
||||
"license": "MIT",
|
||||
"icon": "assets/icon.png",
|
||||
|
||||
+181
-16
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user