feat: Resilience Hardening & Boundary Stress Validation (v2.77.3)
This commit is contained in:
@@ -4,7 +4,7 @@ export class AgentDataValidator {
|
||||
/**
|
||||
* 에이전트 간 핸드오프(Handoff) 시 데이터 무결성을 검증하고 품질 점수를 반환합니다.
|
||||
*/
|
||||
public static validateHandoff(stage: string, data: string): number {
|
||||
public static validateHandoff(stage: string, data: string): { score: number, conflictRisk: number } {
|
||||
if (!data || data.trim().length === 0) {
|
||||
throw new Error(`[IntegrityError] 데이터 누락: ${stage} 에이전트의 출력이 비어 있습니다.`);
|
||||
}
|
||||
@@ -46,7 +46,7 @@ export class AgentDataValidator {
|
||||
logInfo(`[ConflictAlert] ${stage} 단계에서 지식 충돌 위험 감지 (Risk: ${conflictRisk}).`);
|
||||
}
|
||||
|
||||
return score - (conflictRisk * 0.5); // 충돌 위험이 높으면 전체 품질 점수를 감쇄함
|
||||
return { score, conflictRisk };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+29
-14
@@ -120,8 +120,7 @@ export class MissionState {
|
||||
*/
|
||||
private saveToDisk(): void {
|
||||
try {
|
||||
const workspacePath = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath || '';
|
||||
if (!workspacePath) return;
|
||||
const workspacePath = process.env.ASTRA_TEST_ROOT || vscode.workspace.workspaceFolders?.[0]?.uri.fsPath || process.cwd();
|
||||
|
||||
const astraDir = path.join(workspacePath, '.astra', 'missions');
|
||||
if (!fs.existsSync(astraDir)) {
|
||||
@@ -156,8 +155,7 @@ export class MissionState {
|
||||
*/
|
||||
public static loadFromDisk(missionId: string): MissionState | null {
|
||||
try {
|
||||
const workspacePath = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath || '';
|
||||
if (!workspacePath) return null;
|
||||
const workspacePath = process.env.ASTRA_TEST_ROOT || vscode.workspace.workspaceFolders?.[0]?.uri.fsPath || process.cwd();
|
||||
const filePath = path.join(workspacePath, '.astra', 'missions', `${missionId}.json`);
|
||||
if (!fs.existsSync(filePath)) return null;
|
||||
|
||||
@@ -165,6 +163,12 @@ export class MissionState {
|
||||
const state = new MissionState(missionId);
|
||||
state._stage = data.status;
|
||||
state._results = data.results || {};
|
||||
state.resilienceMetrics = data.resilienceMetrics || {
|
||||
fallbacks: 0,
|
||||
retries: 0,
|
||||
maxConflictScore: 0,
|
||||
deduplications: 0
|
||||
};
|
||||
return state;
|
||||
} catch (err) {
|
||||
return null;
|
||||
@@ -221,7 +225,8 @@ export class MissionState {
|
||||
durationMs: e.durationFromPrev,
|
||||
message: e.message,
|
||||
ts: new Date(e.timestamp).toISOString()
|
||||
}))
|
||||
})),
|
||||
resilienceMetrics: this.resilienceMetrics
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -378,7 +383,7 @@ export class ErrorClassifier {
|
||||
*/
|
||||
export class CacheManager {
|
||||
private static getCacheDir(): string {
|
||||
const workspacePath = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath || '';
|
||||
const workspacePath = process.env.ASTRA_TEST_ROOT || vscode.workspace.workspaceFolders?.[0]?.uri.fsPath || process.cwd();
|
||||
const cacheDir = path.join(workspacePath, '.astra', 'cache');
|
||||
if (!fs.existsSync(cacheDir)) {
|
||||
fs.mkdirSync(cacheDir, { recursive: true });
|
||||
@@ -444,7 +449,8 @@ export class AgentEngine {
|
||||
prompt: string,
|
||||
brainContext: string,
|
||||
signal: AbortSignal,
|
||||
onProgress: (stage: PipelineStage, message: string) => void
|
||||
onProgress: (stage: PipelineStage, message: string) => void,
|
||||
options?: AgentExecuteOptions
|
||||
): Promise<string> {
|
||||
let state: MissionState;
|
||||
|
||||
@@ -470,7 +476,10 @@ export class AgentEngine {
|
||||
// --- Phase 1: Planner ---
|
||||
const plan = await this.executeStep(
|
||||
state, 'planner', '전략 수립 중...',
|
||||
() => this.resilientExecute(state, this.planner, 'Planner', prompt, brainContext, signal, onProgress, { context: brainContext, signal, config: { role: 'planner' } }),
|
||||
() => this.resilientExecute(state, this.planner, 'Planner', prompt, brainContext, signal, onProgress, {
|
||||
...options,
|
||||
context: brainContext, signal, config: { ...options?.config, role: 'planner' }
|
||||
}),
|
||||
prompt, brainContext, signal, onProgress
|
||||
);
|
||||
|
||||
@@ -480,7 +489,11 @@ export class AgentEngine {
|
||||
// --- Phase 2: Researcher ---
|
||||
const research = await this.executeStep(
|
||||
state, 'researcher', '핵심 정보 수집 및 분석 중...',
|
||||
() => this.resilientExecute(state, this.researcher, 'Researcher', plan, brainContext, signal, onProgress, { context: brainContext, signal, config: { role: 'researcher' }, abstractionLevel: researcherLevel }),
|
||||
() => this.resilientExecute(state, this.researcher, 'Researcher', plan, brainContext, signal, onProgress, {
|
||||
...options,
|
||||
context: brainContext, signal, config: { ...options?.config, role: 'researcher' },
|
||||
abstractionLevel: researcherLevel
|
||||
}),
|
||||
plan, brainContext, signal, onProgress
|
||||
);
|
||||
|
||||
@@ -498,8 +511,9 @@ export class AgentEngine {
|
||||
const finalReport = await this.executeStep(
|
||||
state, 'writer', '최종 리포트 작성 및 편집 중...',
|
||||
() => this.resilientExecute(state, this.writer, 'Writer', research, prompt, signal, onProgress, {
|
||||
context: brainContext, signal, config: { role: 'writer', allowFallback: true },
|
||||
priorResults: { plan, writerPrep, previousValidData: state.getResult('finalReport') },
|
||||
...options,
|
||||
context: brainContext, signal, config: { role: 'writer', allowFallback: true, ...options?.config },
|
||||
priorResults: { plan, writerPrep, previousValidData: state.getResult('finalReport'), ...options?.priorResults },
|
||||
abstractionLevel: writerLevel
|
||||
}),
|
||||
research, prompt, signal, onProgress
|
||||
@@ -631,8 +645,8 @@ export class AgentEngine {
|
||||
const durationMs = Date.now() - startTime;
|
||||
|
||||
// [Reliability Check] 충돌 위험도 추적
|
||||
const conflictScore = AgentDataValidator.validateHandoff(agentName, result);
|
||||
state.resilienceMetrics.maxConflictScore = Math.max(state.resilienceMetrics.maxConflictScore, conflictScore);
|
||||
const validation = AgentDataValidator.validateHandoff(agentName, result);
|
||||
state.resilienceMetrics.maxConflictScore = Math.max(state.resilienceMetrics.maxConflictScore, validation.conflictRisk);
|
||||
|
||||
PerformanceProfiler.logLLMLatency(agentName, durationMs, result.length);
|
||||
|
||||
@@ -729,7 +743,8 @@ export class AgentEngine {
|
||||
|
||||
private validateResult(data: string, step: string): number {
|
||||
// Error Recovery Matrix: Permanent 오류 발생을 방지하기 위한 선제적 핸드오프 검증
|
||||
return AgentDataValidator.validateHandoff(step, data);
|
||||
const validation = AgentDataValidator.validateHandoff(step, data);
|
||||
return validation.score;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user