feat: ConnectAI structural hardening and retrieval precision improvements
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
|
||||
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<string> {
|
||||
// 이 에러는 패턴상 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('데이터가 완전히 비어 있음');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user