mirror of
https://github.com/proffesor-for-testing/agentic-qe.git
synced 2026-09-19 08:45:47 +08:00
b3d2018ee2
Critical bug fixes and code quality improvements from brutal-honest-review. ## Critical Fixes (9/10 completed, 1 deferred) 1. Fixed Agent Pattern Isolation (CRITICAL) - Added SwarmMemoryManager.queryPatternsByAgent() - SQL filtering by agent_id in metadata - Each agent now isolated 2. Fixed Async Method Cascade - Changed getPatterns() to async - Fixed 10 callers across 6 files - Build passes 3. Fixed Misleading Logging - Added isRealAgentDB() detection - Honest mock vs real reporting 4. Consolidated Embedding Generation - Created EmbeddingGenerator utility - Removed 50+ duplicate lines 5. Added AgentDB Initialization Checks - Empty DB detection - HNSW index verification 6. Integration Test Suite - 26 new test cases - Error path coverage 7. Repository Cleanup - Removed 19 temp test files 8. New QE Skill: sherlock-review - Evidence-based investigative review - 38 QE skills total 9. Deferred: Wire Up Real Test Execution - Deferred to v1.9.0 (documented) ## Statistics - Fixes: 9/10 (90%, 1 deferred) - Files Modified: 16 - Files Created: 3 - Files Deleted: 19 - Integration Tests: 26 - Build: PASSING ## Breaking Changes - getPatterns() now async - add await 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
277 lines
8.4 KiB
TypeScript
277 lines
8.4 KiB
TypeScript
/**
|
|
* Integration tests for BaseAgent AgentDB integration
|
|
* Tests pattern storage, retrieval, and mock vs real adapter behavior
|
|
*/
|
|
|
|
import { BaseAgent } from '../../src/agents/BaseAgent';
|
|
import { AgentId, TaskRequirements, TaskResult } from '../../src/agents/BaseAgent';
|
|
import { SwarmMemoryManager } from '../../src/core/memory/SwarmMemoryManager';
|
|
import { RealAgentDBAdapter } from '../../src/core/memory/RealAgentDBAdapter';
|
|
import * as fs from 'fs';
|
|
import * as path from 'path';
|
|
|
|
// Test agent implementation
|
|
class TestAgent extends BaseAgent {
|
|
constructor(id: AgentId) {
|
|
super(id);
|
|
}
|
|
|
|
async executeTask(requirements: TaskRequirements): Promise<TaskResult> {
|
|
return {
|
|
success: true,
|
|
data: { message: 'Task completed' },
|
|
metadata: { executionTime: 100 }
|
|
};
|
|
}
|
|
}
|
|
|
|
describe('BaseAgent AgentDB Integration', () => {
|
|
let testAgent: TestAgent;
|
|
let testDbPath: string;
|
|
let memoryManager: SwarmMemoryManager;
|
|
|
|
beforeEach(async () => {
|
|
// Create unique test database path
|
|
testDbPath = path.join(process.cwd(), `.test-agentdb-${Date.now()}.db`);
|
|
|
|
// Create agent with memory manager
|
|
const agentId: AgentId = {
|
|
id: 'test-agent-001',
|
|
type: 'test',
|
|
capabilities: ['testing']
|
|
};
|
|
testAgent = new TestAgent(agentId);
|
|
|
|
// Initialize memory manager
|
|
memoryManager = new SwarmMemoryManager(testDbPath);
|
|
await memoryManager.initialize();
|
|
|
|
// Set up agent with memory
|
|
(testAgent as any).memoryStore = memoryManager;
|
|
});
|
|
|
|
afterEach(async () => {
|
|
// Cleanup test database
|
|
if (fs.existsSync(testDbPath)) {
|
|
fs.unlinkSync(testDbPath);
|
|
}
|
|
});
|
|
|
|
describe('Pattern Storage in onPostTask', () => {
|
|
it('should store patterns after successful task execution', async () => {
|
|
const requirements: TaskRequirements = {
|
|
capabilities: ['testing'],
|
|
context: { testData: 'sample' }
|
|
};
|
|
|
|
const result: TaskResult = {
|
|
success: true,
|
|
data: { output: 'test result' }
|
|
};
|
|
|
|
// Call onPostTask to store patterns
|
|
await (testAgent as any).onPostTask(requirements, result, 150);
|
|
|
|
// Verify patterns were stored
|
|
const patterns = await memoryManager.queryPatternsByAgent('test-agent-001', 0);
|
|
expect(patterns.length).toBeGreaterThan(0);
|
|
|
|
// Verify pattern metadata
|
|
const pattern = patterns[0];
|
|
expect(pattern.metadata).toBeDefined();
|
|
const metadata = JSON.parse(pattern.metadata);
|
|
expect(metadata.agent_id).toBe('test-agent-001');
|
|
});
|
|
|
|
it('should store patterns with correct confidence based on success', async () => {
|
|
const requirements: TaskRequirements = {
|
|
capabilities: ['testing']
|
|
};
|
|
|
|
const successResult: TaskResult = {
|
|
success: true,
|
|
data: { output: 'success' }
|
|
};
|
|
|
|
await (testAgent as any).onPostTask(requirements, successResult, 100);
|
|
|
|
const patterns = await memoryManager.queryPatternsByAgent('test-agent-001', 0);
|
|
expect(patterns.length).toBeGreaterThan(0);
|
|
|
|
// Success should have higher confidence
|
|
const successPattern = patterns[0];
|
|
expect(successPattern.confidence).toBeGreaterThanOrEqual(0.7);
|
|
});
|
|
});
|
|
|
|
describe('Pattern Retrieval in onPreTask', () => {
|
|
it('should retrieve patterns before task execution', async () => {
|
|
// First store some patterns
|
|
await memoryManager.storePattern({
|
|
id: 'pattern-001',
|
|
pattern: 'test:pattern:success',
|
|
confidence: 0.85,
|
|
usageCount: 5,
|
|
metadata: { agent_id: 'test-agent-001', task: 'testing' }
|
|
});
|
|
|
|
const requirements: TaskRequirements = {
|
|
capabilities: ['testing']
|
|
};
|
|
|
|
// Call onPreTask to retrieve patterns
|
|
const context = await (testAgent as any).onPreTask(requirements);
|
|
|
|
expect(context).toBeDefined();
|
|
// Patterns should be loaded from memory
|
|
});
|
|
|
|
it('should handle empty database gracefully', async () => {
|
|
const requirements: TaskRequirements = {
|
|
capabilities: ['testing']
|
|
};
|
|
|
|
// Call onPreTask with empty database
|
|
const context = await (testAgent as any).onPreTask(requirements);
|
|
|
|
// Should not throw error, just return empty or default context
|
|
expect(context).toBeDefined();
|
|
});
|
|
});
|
|
|
|
describe('Error Pattern Storage in onTaskError', () => {
|
|
it('should store error patterns when task fails', async () => {
|
|
const requirements: TaskRequirements = {
|
|
capabilities: ['testing']
|
|
};
|
|
|
|
const error = new Error('Test failure');
|
|
|
|
// Call onTaskError to store error pattern
|
|
await (testAgent as any).onTaskError(requirements, error);
|
|
|
|
// Verify error patterns were stored
|
|
const patterns = await memoryManager.queryPatternsByAgent('test-agent-001', 0);
|
|
expect(patterns.length).toBeGreaterThan(0);
|
|
|
|
// Verify pattern has error metadata
|
|
const pattern = patterns[0];
|
|
const metadata = JSON.parse(pattern.metadata);
|
|
expect(metadata.agent_id).toBe('test-agent-001');
|
|
expect(pattern.confidence).toBeLessThan(0.5); // Error patterns have low confidence
|
|
});
|
|
});
|
|
|
|
describe('Mock vs Real Adapter Detection', () => {
|
|
it('should detect mock adapter in test environment', () => {
|
|
// Set test environment
|
|
process.env.NODE_ENV = 'test';
|
|
|
|
const isReal = (testAgent as any).isRealAgentDB();
|
|
expect(isReal).toBe(false);
|
|
});
|
|
|
|
it('should detect real adapter in production environment', () => {
|
|
// Set production environment
|
|
const originalEnv = process.env.NODE_ENV;
|
|
delete process.env.NODE_ENV;
|
|
delete process.env.JEST_WORKER_ID;
|
|
process.env.AQE_USE_MOCK_AGENTDB = 'false';
|
|
|
|
// Create real AgentDB adapter
|
|
const realAdapter = new RealAgentDBAdapter({
|
|
dbPath: testDbPath,
|
|
dimension: 384
|
|
});
|
|
|
|
(testAgent as any).agentDB = realAdapter;
|
|
|
|
const isReal = (testAgent as any).isRealAgentDB();
|
|
expect(isReal).toBe(true);
|
|
|
|
// Restore environment
|
|
process.env.NODE_ENV = originalEnv;
|
|
});
|
|
});
|
|
|
|
describe('Agent-Specific Pattern Filtering', () => {
|
|
it('should only retrieve patterns for the specific agent', async () => {
|
|
// Store patterns for different agents
|
|
await memoryManager.storePattern({
|
|
id: 'pattern-agent-1',
|
|
pattern: 'agent1:pattern',
|
|
confidence: 0.8,
|
|
usageCount: 1,
|
|
metadata: { agent_id: 'test-agent-001' }
|
|
});
|
|
|
|
await memoryManager.storePattern({
|
|
id: 'pattern-agent-2',
|
|
pattern: 'agent2:pattern',
|
|
confidence: 0.8,
|
|
usageCount: 1,
|
|
metadata: { agent_id: 'other-agent-002' }
|
|
});
|
|
|
|
// Query patterns for test-agent-001
|
|
const patterns = await memoryManager.queryPatternsByAgent('test-agent-001', 0);
|
|
|
|
expect(patterns.length).toBe(1);
|
|
expect(patterns[0].id).toBe('pattern-agent-1');
|
|
|
|
const metadata = JSON.parse(patterns[0].metadata);
|
|
expect(metadata.agent_id).toBe('test-agent-001');
|
|
});
|
|
|
|
it('should not leak patterns between agents', async () => {
|
|
// Store patterns for agent 1
|
|
await memoryManager.storePattern({
|
|
id: 'secret-pattern',
|
|
pattern: 'sensitive:data',
|
|
confidence: 0.9,
|
|
usageCount: 10,
|
|
metadata: { agent_id: 'agent-001', secret: 'confidential' }
|
|
});
|
|
|
|
// Query patterns for agent 2
|
|
const patterns = await memoryManager.queryPatternsByAgent('agent-002', 0);
|
|
|
|
// Should not find agent 1's patterns
|
|
expect(patterns.length).toBe(0);
|
|
});
|
|
});
|
|
|
|
describe('AgentDB Error Handling', () => {
|
|
it('should continue task execution if pattern storage fails', async () => {
|
|
// Simulate storage failure by closing database
|
|
await memoryManager.close();
|
|
|
|
const requirements: TaskRequirements = {
|
|
capabilities: ['testing']
|
|
};
|
|
|
|
const result: TaskResult = {
|
|
success: true,
|
|
data: { output: 'test' }
|
|
};
|
|
|
|
// onPostTask should not throw even if storage fails
|
|
await expect((testAgent as any).onPostTask(requirements, result, 100))
|
|
.resolves.not.toThrow();
|
|
});
|
|
|
|
it('should continue task execution if pattern retrieval fails', async () => {
|
|
// Simulate retrieval failure by closing database
|
|
await memoryManager.close();
|
|
|
|
const requirements: TaskRequirements = {
|
|
capabilities: ['testing']
|
|
};
|
|
|
|
// onPreTask should not throw even if retrieval fails
|
|
await expect((testAgent as any).onPreTask(requirements))
|
|
.resolves.not.toThrow();
|
|
});
|
|
});
|
|
});
|