import { AgentEngine, IAgent, ErrorClassifier, ErrorType, MissionState } from '../src/lib/engine'; import { AgentDataValidator } from '../src/lib/diagnostics'; import * as path from 'path'; import * as fs from 'fs'; describe('ConnectAI Resilience v4.0 Validation', () => { describe('Enhanced Error Classification', () => { test('GPU OOM (out of memory) should be classified as TRANSIENT', () => { const error = new Error('Ollama error: GPU out of memory, failed to allocate weights'); const result = ErrorClassifier.classify(error); expect(result.type).toBe(ErrorType.TRANSIENT); expect(result.rule.action).toBe('retry'); }); test('Context length exceeded should be classified as PERMANENT', () => { const error = new Error('Validation failed: context_length_exceeded for model gemini-pro'); const result = ErrorClassifier.classify(error); expect(result.type).toBe(ErrorType.PERMANENT); expect(result.rule.action).toBe('fail_with_message'); }); test('Safety filter triggers should be classified as PERMANENT', () => { const error = new Error('Response blocked by safety_filter: harmful content detected'); const result = ErrorClassifier.classify(error); expect(result.type).toBe(ErrorType.PERMANENT); }); test('500 Internal Server Error should be classified as TRANSIENT', () => { const error = new Error('HTTP 500: Internal Server Error'); const result = ErrorClassifier.classify(error); expect(result.type).toBe(ErrorType.TRANSIENT); }); }); describe('Safe Pre-Failure Audit', () => { class MockPermanentOOMAgent implements IAgent { async execute(): Promise { // 이 에러는 패턴상 PERMANENT로 분류되도록 유도 (테스트용) throw new Error('404: model not found'); } } test('Permanent error should trigger audit without crashing', async () => { const engine = new AgentEngine( new MockPermanentOOMAgent(), {} as IAgent, {} as IAgent ); const state = new MissionState('audit_test_mission'); const input = 'This is a test input that should be audited upon failure.'; // audit 메서드가 에러를 던지지 않는지 확인 const auditResult = AgentDataValidator.audit('Planner', input); expect(auditResult).toHaveProperty('score'); expect(auditResult).toHaveProperty('issues'); // 실제 resilientExecute 흐름에서 에러가 전파되는지 확인 await expect((engine as any).resilientExecute( state, new MockPermanentOOMAgent(), 'TestAgent', input, 'context', new AbortController().signal, () => {} )).rejects.toThrow(/TestAgent/); }); test('Audit should handle empty input gracefully', () => { const result = AgentDataValidator.audit('Tester', ''); expect(result.score).toBe(0); expect(result.issues).toContain('데이터가 완전히 비어 있음'); }); }); });