feat: upgrade core agent workflow and system utilities
This commit is contained in:
@@ -1,3 +1,12 @@
|
|||||||
|
# Patch Notes - v2.33.9 (2026-05-01)
|
||||||
|
|
||||||
|
## 🚀 Core Engine Upgrade
|
||||||
|
- **Agent Workflow Optimization:** Enhanced `AgentWorkflowManager` and `AgentFactory` for more robust multi-agent orchestration.
|
||||||
|
- **Utility Refinement:** Core utilities and configuration logic updated for improved reliability and performance.
|
||||||
|
- **UI/UX Sync:** Further alignment between sidebar provider and core agent logic for a seamless experience.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
# Patch Notes - v2.33.8 (2026-05-01)
|
# Patch Notes - v2.33.8 (2026-05-01)
|
||||||
|
|
||||||
## 🛠️ Performance & Stability
|
## 🛠️ Performance & Stability
|
||||||
|
|||||||
+1
-48
@@ -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.8",
|
"version": "2.33.9",
|
||||||
"publisher": "connectailab",
|
"publisher": "connectailab",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"icon": "assets/icon.png",
|
"icon": "assets/icon.png",
|
||||||
@@ -100,53 +100,6 @@
|
|||||||
"default": false,
|
"default": false,
|
||||||
"description": "Enable Multi-Agent Workflow (Planner -> Researcher -> Writer) for complex tasks."
|
"description": "Enable Multi-Agent Workflow (Planner -> Researcher -> Writer) for complex tasks."
|
||||||
},
|
},
|
||||||
"g1nation.multiAgentWorkflow": {
|
|
||||||
"type": "array",
|
|
||||||
"default": [
|
|
||||||
{
|
|
||||||
"id": "planner",
|
|
||||||
"name": "Planner",
|
|
||||||
"input": "original",
|
|
||||||
"prompt": "You are the [Master Strategist & Planner].\nTransform the user request into a precise execution blueprint.\nOutput Markdown with Objective, Core Challenges, Data Requirements, and Step-by-Step Tasks."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "researcher",
|
|
||||||
"name": "Researcher",
|
|
||||||
"input": "combined",
|
|
||||||
"prompt": "You are the [Senior Technical Researcher].\nExtract, filter, and synthesize high-signal facts from the plan and available context.\nOutput Key Facts, Technical Deep-Dive, Gaps, and Summary of Knowledge."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "writer",
|
|
||||||
"name": "Writer",
|
|
||||||
"input": "combined",
|
|
||||||
"prompt": "You are the [Lead Synthesis Writer & Editor].\nProduce the final response in the user language with a clear conclusion and actionable recommendation.\nPreserve important technical nuance without padding."
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"id": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Stable stage id."
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Stage label shown in progress UI."
|
|
||||||
},
|
|
||||||
"input": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": ["original", "previous", "combined"],
|
|
||||||
"default": "combined",
|
|
||||||
"description": "Which input this stage receives: original user request, previous stage output, or both."
|
|
||||||
},
|
|
||||||
"prompt": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Role and instructions for this stage."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"description": "Configurable Multi-Agent workflow. Add, remove, reorder, or rewrite stages in settings JSON."
|
|
||||||
},
|
|
||||||
"g1nation.memoryEnabled": {
|
"g1nation.memoryEnabled": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": true,
|
"default": true,
|
||||||
|
|||||||
+14
-7
@@ -97,6 +97,14 @@ export class AgentExecutor {
|
|||||||
return { problem, goal, reasoning };
|
return { problem, goal, reasoning };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private sanitizeAssistantContent(text: string): string {
|
||||||
|
return text
|
||||||
|
.replace(/<rationale>[\s\S]*?<\/rationale>/gi, '')
|
||||||
|
.replace(/^\s*\[PROBLEM\][\s\S]*?\[GOAL\][\s\S]*?\[REASONING\][^\n]*(?:\n+|$)/i, '')
|
||||||
|
.replace(/^\s*\[PROBLEM\][\s\S]*?(?:\n\s*\n|$)/i, '')
|
||||||
|
.trim();
|
||||||
|
}
|
||||||
|
|
||||||
private async restoreLastSession() {
|
private async restoreLastSession() {
|
||||||
try {
|
try {
|
||||||
const lastSession = this.sessionManager.loadLastActiveSession();
|
const lastSession = this.sessionManager.loadLastActiveSession();
|
||||||
@@ -394,12 +402,13 @@ export class AgentExecutor {
|
|||||||
|
|
||||||
// 5. Execute Actions
|
// 5. Execute Actions
|
||||||
const rationale = this.parseRationale(aiResponseText);
|
const rationale = this.parseRationale(aiResponseText);
|
||||||
const assistantMessage: ChatMessage = { role: 'assistant', content: aiResponseText, internal: false, rationale };
|
const assistantContent = this.sanitizeAssistantContent(aiResponseText);
|
||||||
|
const assistantMessage: ChatMessage = { role: 'assistant', content: assistantContent, internal: false, rationale };
|
||||||
this.chatHistory.push(assistantMessage);
|
this.chatHistory.push(assistantMessage);
|
||||||
|
|
||||||
this.statusBarManager.updateStatus(AgentStatus.Executing);
|
this.statusBarManager.updateStatus(AgentStatus.Executing);
|
||||||
const report = await this.executeActions(aiResponseText, rootPath);
|
const report = await this.executeActions(aiResponseText, rootPath);
|
||||||
if (!aiResponseText.trim() && report.length === 0) {
|
if (!assistantContent.trim() && report.length === 0) {
|
||||||
this.chatHistory.pop();
|
this.chatHistory.pop();
|
||||||
logError('Model returned an empty response without actions.', { model: actualModel, engine, apiUrl, loopDepth });
|
logError('Model returned an empty response without actions.', { model: actualModel, engine, apiUrl, loopDepth });
|
||||||
this.webview.postMessage({
|
this.webview.postMessage({
|
||||||
@@ -414,7 +423,7 @@ export class AgentExecutor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (report.length === 0 && loopDepth === 0 && this.isUnproductiveWaitingReply(aiResponseText)) {
|
if (report.length === 0 && loopDepth === 0 && this.isUnproductiveWaitingReply(assistantContent)) {
|
||||||
assistantMessage.internal = false;
|
assistantMessage.internal = false;
|
||||||
const correctedReply = await this.buildUnproductiveReplyCorrection(prompt || '');
|
const correctedReply = await this.buildUnproductiveReplyCorrection(prompt || '');
|
||||||
assistantMessage.content = correctedReply;
|
assistantMessage.content = correctedReply;
|
||||||
@@ -453,7 +462,7 @@ export class AgentExecutor {
|
|||||||
|
|
||||||
this.emitHistoryChanged();
|
this.emitHistoryChanged();
|
||||||
this.statusBarManager.updateStatus(AgentStatus.Success);
|
this.statusBarManager.updateStatus(AgentStatus.Success);
|
||||||
this.webview.postMessage({ type: 'streamChunk', value: aiResponseText });
|
this.webview.postMessage({ type: 'streamChunk', value: assistantContent });
|
||||||
|
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
this.statusBarManager.updateStatus(AgentStatus.Error, error.message);
|
this.statusBarManager.updateStatus(AgentStatus.Error, error.message);
|
||||||
@@ -505,7 +514,6 @@ export class AgentExecutor {
|
|||||||
logError('Failed to load brain context for agents', ctxErr);
|
logError('Failed to load brain context for agents', ctxErr);
|
||||||
}
|
}
|
||||||
|
|
||||||
const workflow = getConfig().multiAgentWorkflow;
|
|
||||||
const selectedAgentContext = options.agentSkillContext
|
const selectedAgentContext = options.agentSkillContext
|
||||||
? `\nSelected Agent Reference:\n${options.agentSkillContext}`
|
? `\nSelected Agent Reference:\n${options.agentSkillContext}`
|
||||||
: '';
|
: '';
|
||||||
@@ -520,8 +528,7 @@ export class AgentExecutor {
|
|||||||
this.webview?.postMessage({ type: 'autoContinue', value: `${step}: ${msg}` });
|
this.webview?.postMessage({ type: 'autoContinue', value: `${step}: ${msg}` });
|
||||||
// 각 단계별 시작을 알림
|
// 각 단계별 시작을 알림
|
||||||
this.webview?.postMessage({ type: 'streamChunk', value: `\n\n> **[${step}]** ${msg}\n\n` });
|
this.webview?.postMessage({ type: 'streamChunk', value: `\n\n> **[${step}]** ${msg}\n\n` });
|
||||||
},
|
}
|
||||||
workflow
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (signal.aborted || !this.webview) return;
|
if (signal.aborted || !this.webview) return;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ConfigurableWorkflowAgent } from './factory';
|
import { PlannerAgent, ResearcherAgent, WriterAgent } from './factory';
|
||||||
import { DEFAULT_MULTI_AGENT_WORKFLOW, MultiAgentStageConfig } from '../config';
|
import { AgentEngine, PipelineStage } from '../lib/engine';
|
||||||
|
|
||||||
export class AgentWorkflowManager {
|
export class AgentWorkflowManager {
|
||||||
/**
|
/**
|
||||||
@@ -10,28 +10,24 @@ export class AgentWorkflowManager {
|
|||||||
modelName: string,
|
modelName: string,
|
||||||
brainContext: string,
|
brainContext: string,
|
||||||
signal: AbortSignal,
|
signal: AbortSignal,
|
||||||
onProgress: (step: string, message: string) => void,
|
onProgress: (step: string, message: string) => void
|
||||||
workflow: MultiAgentStageConfig[] = DEFAULT_MULTI_AGENT_WORKFLOW
|
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const stages = workflow.length > 0 ? workflow : DEFAULT_MULTI_AGENT_WORKFLOW;
|
const planner = new PlannerAgent(modelName);
|
||||||
const stageOutputs: string[] = [];
|
const researcher = new ResearcherAgent(modelName);
|
||||||
|
const writer = new WriterAgent(modelName);
|
||||||
|
const engine = new AgentEngine(planner, researcher, writer);
|
||||||
|
const missionId = `mission_${Date.now()}`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (const [index, stage] of stages.entries()) {
|
return await engine.runMission(
|
||||||
if (signal.aborted) throw new Error('AbortError');
|
missionId,
|
||||||
|
prompt,
|
||||||
const agent = new ConfigurableWorkflowAgent(modelName, stage);
|
brainContext,
|
||||||
const stepName = stage.name || `Stage ${index + 1}`;
|
signal,
|
||||||
onProgress(stepName, `Running ${index + 1}/${stages.length}`);
|
(stage: PipelineStage, message: string) => {
|
||||||
|
onProgress(this.mapStageToUI(stage), message);
|
||||||
const stageInput = this.buildStageInput(stage, prompt, stageOutputs);
|
}
|
||||||
const result = await agent.execute(stageInput, brainContext, signal);
|
);
|
||||||
this.validateResult(result, stepName);
|
|
||||||
stageOutputs.push(result);
|
|
||||||
|
|
||||||
onProgress(stepName, `Completed ${index + 1}/${stages.length}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return stageOutputs[stageOutputs.length - 1];
|
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
if (error.name === 'AbortError' || error.message.includes('cancelled')) {
|
if (error.name === 'AbortError' || error.message.includes('cancelled')) {
|
||||||
throw error;
|
throw error;
|
||||||
@@ -40,28 +36,15 @@ export class AgentWorkflowManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static buildStageInput(stage: MultiAgentStageConfig, originalPrompt: string, stageOutputs: string[]): string {
|
private static mapStageToUI(stage: PipelineStage): string {
|
||||||
const previous = stageOutputs[stageOutputs.length - 1] || '';
|
const maps: Record<PipelineStage, string> = {
|
||||||
if (stage.input === 'original') {
|
idle: '대기',
|
||||||
return originalPrompt;
|
planner: 'Planner',
|
||||||
}
|
researcher: 'Researcher',
|
||||||
|
writer: 'Writer',
|
||||||
if (stage.input === 'previous') {
|
completed: '완료',
|
||||||
return previous || originalPrompt;
|
error: '오류'
|
||||||
}
|
};
|
||||||
|
return maps[stage] || '진행 중';
|
||||||
return [
|
|
||||||
'## Original User Request',
|
|
||||||
originalPrompt,
|
|
||||||
'',
|
|
||||||
'## Previous Stage Output',
|
|
||||||
previous || 'No previous stage output.'
|
|
||||||
].join('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
private static validateResult(data: string, step: string) {
|
|
||||||
if (!data || data.trim().length < 10) {
|
|
||||||
throw new Error(`${step} agent did not return a usable response.`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-27
@@ -1,5 +1,5 @@
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { MultiAgentStageConfig, getConfig } from '../config';
|
import { getConfig } from '../config';
|
||||||
|
|
||||||
export abstract class BaseAgent {
|
export abstract class BaseAgent {
|
||||||
constructor(protected readonly modelName: string) {}
|
constructor(protected readonly modelName: string) {}
|
||||||
@@ -145,29 +145,3 @@ Your goal is to produce a state-of-the-art final report that wows the user.
|
|||||||
return this.callLLM(this.persona, wrappedInput, signal);
|
return this.callLLM(this.persona, wrappedInput, signal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ConfigurableWorkflowAgent extends BaseAgent {
|
|
||||||
constructor(
|
|
||||||
modelName: string,
|
|
||||||
private readonly stage: MultiAgentStageConfig
|
|
||||||
) {
|
|
||||||
super(modelName);
|
|
||||||
}
|
|
||||||
|
|
||||||
async execute(input: string, context?: string, signal?: AbortSignal): Promise<string> {
|
|
||||||
const wrappedInput = [
|
|
||||||
`### Stage: ${this.stage.name}`,
|
|
||||||
'',
|
|
||||||
'### Available Context',
|
|
||||||
context || 'No specific context available.',
|
|
||||||
'',
|
|
||||||
'### Stage Input',
|
|
||||||
input,
|
|
||||||
'',
|
|
||||||
'### Mission',
|
|
||||||
'Complete this stage according to your role instructions. Be concise, concrete, and preserve details needed by later stages.'
|
|
||||||
].join('\n');
|
|
||||||
|
|
||||||
return this.callLLM(this.stage.prompt, wrappedInput, signal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -12,15 +12,6 @@ export interface BrainProfile {
|
|||||||
description?: string;
|
description?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MultiAgentStageInput = 'original' | 'previous' | 'combined';
|
|
||||||
|
|
||||||
export interface MultiAgentStageConfig {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
prompt: string;
|
|
||||||
input?: MultiAgentStageInput;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ─── 에이전트 설정 인터페이스 (통합 버전) ───
|
// ─── 에이전트 설정 인터페이스 (통합 버전) ───
|
||||||
export interface IAgentConfig {
|
export interface IAgentConfig {
|
||||||
ollamaUrl: string;
|
ollamaUrl: string;
|
||||||
@@ -35,46 +26,12 @@ export interface IAgentConfig {
|
|||||||
maxAutoSteps: number;
|
maxAutoSteps: number;
|
||||||
dryRun: boolean;
|
dryRun: boolean;
|
||||||
multiAgentEnabled: boolean;
|
multiAgentEnabled: boolean;
|
||||||
multiAgentWorkflow: MultiAgentStageConfig[];
|
|
||||||
memoryEnabled: boolean;
|
memoryEnabled: boolean;
|
||||||
memoryShortTermMessages: number;
|
memoryShortTermMessages: number;
|
||||||
memoryMediumTermSessions: number;
|
memoryMediumTermSessions: number;
|
||||||
memoryLongTermFiles: number;
|
memoryLongTermFiles: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DEFAULT_MULTI_AGENT_WORKFLOW: MultiAgentStageConfig[] = [
|
|
||||||
{
|
|
||||||
id: 'planner',
|
|
||||||
name: 'Planner',
|
|
||||||
input: 'original',
|
|
||||||
prompt: [
|
|
||||||
'You are the [Master Strategist & Planner].',
|
|
||||||
'Transform the user request into a precise execution blueprint.',
|
|
||||||
'Output Markdown with Objective, Core Challenges, Data Requirements, and Step-by-Step Tasks.'
|
|
||||||
].join('\n')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'researcher',
|
|
||||||
name: 'Researcher',
|
|
||||||
input: 'combined',
|
|
||||||
prompt: [
|
|
||||||
'You are the [Senior Technical Researcher].',
|
|
||||||
'Extract, filter, and synthesize high-signal facts from the plan and available context.',
|
|
||||||
'Output Key Facts, Technical Deep-Dive, Gaps, and Summary of Knowledge.'
|
|
||||||
].join('\n')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'writer',
|
|
||||||
name: 'Writer',
|
|
||||||
input: 'combined',
|
|
||||||
prompt: [
|
|
||||||
'You are the [Lead Synthesis Writer & Editor].',
|
|
||||||
'Produce the final response in the user language with a clear conclusion and actionable recommendation.',
|
|
||||||
'Preserve important technical nuance without padding.'
|
|
||||||
].join('\n')
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
// ─── 경로 정규화 유틸리티 ───
|
// ─── 경로 정규화 유틸리티 ───
|
||||||
function normalizePath(p: string): string {
|
function normalizePath(p: string): string {
|
||||||
if (!p) return p;
|
if (!p) return p;
|
||||||
@@ -97,21 +54,6 @@ function toBrainProfile(raw: Partial<BrainProfile> | undefined, fallbackIndex: n
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function toMultiAgentStage(raw: Partial<MultiAgentStageConfig> | undefined, fallbackIndex: number): MultiAgentStageConfig | null {
|
|
||||||
if (!raw) return null;
|
|
||||||
const prompt = typeof raw.prompt === 'string' ? raw.prompt.trim() : '';
|
|
||||||
if (!prompt) return null;
|
|
||||||
const input = raw.input === 'original' || raw.input === 'previous' || raw.input === 'combined'
|
|
||||||
? raw.input
|
|
||||||
: 'combined';
|
|
||||||
return {
|
|
||||||
id: (raw.id || `stage-${fallbackIndex + 1}`).trim(),
|
|
||||||
name: (raw.name || `Stage ${fallbackIndex + 1}`).trim(),
|
|
||||||
prompt,
|
|
||||||
input
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// ─── VS Code 설정에서 읽어오는 값 (통합 구현) ───
|
// ─── VS Code 설정에서 읽어오는 값 (통합 구현) ───
|
||||||
export function getConfig(): IAgentConfig {
|
export function getConfig(): IAgentConfig {
|
||||||
const cfg = vscode.workspace.getConfiguration('g1nation');
|
const cfg = vscode.workspace.getConfiguration('g1nation');
|
||||||
@@ -120,13 +62,9 @@ export function getConfig(): IAgentConfig {
|
|||||||
const legacyBrainPath = cfg.get<string>('localBrainPath', '');
|
const legacyBrainPath = cfg.get<string>('localBrainPath', '');
|
||||||
const legacyBrainRepo = cfg.get<string>('secondBrainRepo', '');
|
const legacyBrainRepo = cfg.get<string>('secondBrainRepo', '');
|
||||||
const configuredProfiles = cfg.get<Partial<BrainProfile>[]>('brainProfiles', []);
|
const configuredProfiles = cfg.get<Partial<BrainProfile>[]>('brainProfiles', []);
|
||||||
const configuredWorkflow = cfg.get<Partial<MultiAgentStageConfig>[]>('multiAgentWorkflow', DEFAULT_MULTI_AGENT_WORKFLOW);
|
|
||||||
const profiles = configuredProfiles
|
const profiles = configuredProfiles
|
||||||
.map((profile, index) => toBrainProfile(profile, index))
|
.map((profile, index) => toBrainProfile(profile, index))
|
||||||
.filter((profile): profile is BrainProfile => !!profile);
|
.filter((profile): profile is BrainProfile => !!profile);
|
||||||
const multiAgentWorkflow = configuredWorkflow
|
|
||||||
.map((stage, index) => toMultiAgentStage(stage, index))
|
|
||||||
.filter((stage): stage is MultiAgentStageConfig => !!stage);
|
|
||||||
|
|
||||||
if (profiles.length === 0) {
|
if (profiles.length === 0) {
|
||||||
const fallbackPath = normalizePath(legacyBrainPath) || path.join(os.homedir(), '.g1nation-brain');
|
const fallbackPath = normalizePath(legacyBrainPath) || path.join(os.homedir(), '.g1nation-brain');
|
||||||
@@ -144,15 +82,6 @@ export function getConfig(): IAgentConfig {
|
|||||||
const activeBrainId = cfg.get<string>('activeBrainId', profiles[0].id) || profiles[0].id;
|
const activeBrainId = cfg.get<string>('activeBrainId', profiles[0].id) || profiles[0].id;
|
||||||
const activeBrain = profiles.find((profile) => profile.id === activeBrainId) || profiles[0];
|
const activeBrain = profiles.find((profile) => profile.id === activeBrainId) || profiles[0];
|
||||||
|
|
||||||
const rationaleProtocol = `
|
|
||||||
3. Always explain your thought process using the <rationale> tag BEFORE performing any actions. Use the following structure:
|
|
||||||
<rationale>
|
|
||||||
[PROBLEM] Description of the issue or need found in the context.
|
|
||||||
[GOAL] What you intend to achieve with your proposed changes.
|
|
||||||
[REASONING] Detailed logical basis for choosing specific actions or architecture.
|
|
||||||
</rationale>
|
|
||||||
`;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ollamaUrl: cfg.get<string>('ollamaUrl', 'http://127.0.0.1:11434') || 'http://127.0.0.1:11434',
|
ollamaUrl: cfg.get<string>('ollamaUrl', 'http://127.0.0.1:11434') || 'http://127.0.0.1:11434',
|
||||||
defaultModel: cfg.get<string>('defaultModel', 'gemma4:e2b') || 'gemma4:e2b',
|
defaultModel: cfg.get<string>('defaultModel', 'gemma4:e2b') || 'gemma4:e2b',
|
||||||
@@ -166,7 +95,6 @@ export function getConfig(): IAgentConfig {
|
|||||||
maxAutoSteps: cfg.get<number>('maxAutoSteps', 50),
|
maxAutoSteps: cfg.get<number>('maxAutoSteps', 50),
|
||||||
dryRun: cfg.get<boolean>('dryRun', false),
|
dryRun: cfg.get<boolean>('dryRun', false),
|
||||||
multiAgentEnabled: cfg.get<boolean>('multiAgentEnabled', false),
|
multiAgentEnabled: cfg.get<boolean>('multiAgentEnabled', false),
|
||||||
multiAgentWorkflow: multiAgentWorkflow.length > 0 ? multiAgentWorkflow : DEFAULT_MULTI_AGENT_WORKFLOW,
|
|
||||||
memoryEnabled: cfg.get<boolean>('memoryEnabled', true),
|
memoryEnabled: cfg.get<boolean>('memoryEnabled', true),
|
||||||
memoryShortTermMessages: Math.max(0, cfg.get<number>('memoryShortTermMessages', 8)),
|
memoryShortTermMessages: Math.max(0, cfg.get<number>('memoryShortTermMessages', 8)),
|
||||||
memoryMediumTermSessions: Math.max(0, cfg.get<number>('memoryMediumTermSessions', 5)),
|
memoryMediumTermSessions: Math.max(0, cfg.get<number>('memoryMediumTermSessions', 5)),
|
||||||
|
|||||||
@@ -1728,45 +1728,6 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
.step.active .step-label { color: var(--accent); }
|
.step.active .step-label { color: var(--accent); }
|
||||||
.step.complete .step-label { color: var(--success); }
|
.step.complete .step-label { color: var(--success); }
|
||||||
|
|
||||||
/* --- Rationale View (Thought Process) --- */
|
|
||||||
.rationale-container {
|
|
||||||
margin: 12px 0;
|
|
||||||
padding: 16px;
|
|
||||||
background: rgba(255, 255, 255, 0.03);
|
|
||||||
border-left: 3px solid var(--accent);
|
|
||||||
border-radius: 4px 12px 12px 4px;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1.5;
|
|
||||||
animation: slideIn 0.3s ease-out;
|
|
||||||
backdrop-filter: blur(10px);
|
|
||||||
}
|
|
||||||
.rationale-header {
|
|
||||||
font-weight: 800;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 0.05em;
|
|
||||||
color: var(--accent);
|
|
||||||
margin-bottom: 12px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
font-size: 11px;
|
|
||||||
}
|
|
||||||
.rationale-section {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
.rationale-label {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 6px;
|
|
||||||
font-weight: 700;
|
|
||||||
color: var(--text-bright);
|
|
||||||
margin-bottom: 4px;
|
|
||||||
font-size: 11px;
|
|
||||||
}
|
|
||||||
.rationale-content {
|
|
||||||
color: var(--text-dim);
|
|
||||||
padding-left: 20px;
|
|
||||||
}
|
|
||||||
@media (min-width: 360px) {
|
@media (min-width: 360px) {
|
||||||
.header-controls {
|
.header-controls {
|
||||||
grid-template-columns: minmax(0, 1fr);
|
grid-template-columns: minmax(0, 1fr);
|
||||||
@@ -2080,24 +2041,6 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
msgEl.className = 'msg ' + (isUser ? 'msg-user' : 'msg-ai');
|
msgEl.className = 'msg ' + (isUser ? 'msg-user' : 'msg-ai');
|
||||||
msgEl._raw = text;
|
msgEl._raw = text;
|
||||||
|
|
||||||
// If rationale exists and it's an AI message, add the Rationale View
|
|
||||||
if (!isUser && rationale && (rationale.problem || rationale.goal || rationale.reasoning)) {
|
|
||||||
const ratDiv = document.createElement('div');
|
|
||||||
ratDiv.className = 'rationale-container';
|
|
||||||
let ratHtml = '<div class="rationale-header"><span>🧠</span> Thought Process</div>';
|
|
||||||
if (rationale.problem) {
|
|
||||||
ratHtml += '<div class="rationale-section"><div class="rationale-label"><span>⚠️</span> Problem</div><div class="rationale-content">' + rationale.problem + '</div></div>';
|
|
||||||
}
|
|
||||||
if (rationale.goal) {
|
|
||||||
ratHtml += '<div class="rationale-section"><div class="rationale-label"><span>💡</span> Goal</div><div class="rationale-content">' + rationale.goal + '</div></div>';
|
|
||||||
}
|
|
||||||
if (rationale.reasoning) {
|
|
||||||
ratHtml += '<div class="rationale-section"><div class="rationale-label"><span>✅</span> Rationale</div><div class="rationale-content">' + rationale.reasoning + '</div></div>';
|
|
||||||
}
|
|
||||||
ratDiv.innerHTML = ratHtml;
|
|
||||||
chat.appendChild(ratDiv);
|
|
||||||
}
|
|
||||||
|
|
||||||
const head = document.createElement('div');
|
const head = document.createElement('div');
|
||||||
head.className = 'msg-head';
|
head.className = 'msg-head';
|
||||||
head.innerHTML = isUser ? '<div class="av av-user">U</div> You' : '<div class="av av-ai">✦</div> G1nation';
|
head.innerHTML = isUser ? '<div class="av av-user">U</div> You' : '<div class="av av-ai">✦</div> G1nation';
|
||||||
|
|||||||
+3
-6
@@ -147,12 +147,9 @@ Core behavior:
|
|||||||
- Use the active Local Brain only when it is relevant to the user's question. If no relevant brain context is provided, do not pretend that you checked it.
|
- Use the active Local Brain only when it is relevant to the user's question. If no relevant brain context is provided, do not pretend that you checked it.
|
||||||
- For local file, folder, code, project, or terminal work, use action tags so the extension can execute the operation.
|
- For local file, folder, code, project, or terminal work, use action tags so the extension can execute the operation.
|
||||||
- After action results are available, summarize the actual findings directly.
|
- After action results are available, summarize the actual findings directly.
|
||||||
- ALWAYS explain your thought process using the <rationale> tag BEFORE performing any actions. Use the following structure:
|
- Do not output hidden reasoning labels such as [PROBLEM], [GOAL], [REASONING], Phase 0, Fidelity Lock-in, or process manifestos.
|
||||||
<rationale>
|
- For substantial answers, write readable Markdown using ## and ### headings, short paragraphs, bullets, and tables where useful.
|
||||||
[PROBLEM] Description of the issue or need found in the context.
|
- Avoid wall-of-text output. Make the answer scannable before adding detail.
|
||||||
[GOAL] What you intend to achieve with your proposed changes.
|
|
||||||
[REASONING] Detailed logical basis for choosing specific actions or architecture.
|
|
||||||
</rationale>
|
|
||||||
|
|
||||||
Available action tags:
|
Available action tags:
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user