Files
proffesor-for-testing__agen…/scripts/rvf-baseline-benchmark.ts
Dragan Spiridonov 122f223c9a fix(security): migrate from @xenova/transformers to @huggingface/transformers
@xenova/transformers v2.17.2 (last publish 2024-05-29) pins
onnxruntime-web@1.14.0, which pulls onnx-proto → protobufjs <=7.5.5.
That chain has 8 GHSA advisories including a critical arbitrary-code-
execution one (GHSA-xq3m-2v4x-88gg). Our top-level `overrides` block
forced protobufjs@^7.5.6 in our own tree, hiding the vulns from
`npm audit` in this repo — but `overrides` are root-only by design and
do not propagate to downstream consumers. End users running
`npm install agentic-qe` were getting 5 vulns (4 high, 1 critical).

@huggingface/transformers@4.2.0 is the official maintained successor
(same project, renamed). It pulls onnxruntime-web@1.26 which depends
on protobufjs@^7.2.4 directly (no onnx-proto), so the version range
resolves cleanly to the patched line.

API changes handled:
- pipeline()/Tensor: drop-in compatible, just the import path changes
- `quantized: bool` → `dtype: DataType` (mapped from our QuantizationType
  enum: 'none'→'fp32', 'fp16'→'fp16', 'int8'→'int8', 'binary'→'q8';
  binary stays a post-process step downstream)
- progress_callback signature: ProgressInfo is now a discriminated union;
  `progress` only exists on the "progress" variant — narrowed accordingly

Also added onnxruntime-node and onnxruntime-web to the CLI and MCP
bundle externals lists. @huggingface/transformers ships both runtimes
(node for Node.js, web as fallback); esbuild can't bundle the
native .node binary so it must remain external.

End-user verification (npm pack + clean install in /tmp/aqe-canary):
- 183 packages (was 180 pre-migration; same order of magnitude)
- 0 vulnerabilities (was 5: 4 high, 1 critical)
- aqe init --auto runs in 93 ms; all 13 phases pass; optional-peers
  hint renders correctly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 09:27:22 +00:00

844 lines
29 KiB
TypeScript

/**
* RVF Integration Baseline Benchmark
*
* Captures current system performance metrics BEFORE RVF integration.
* Run again AFTER integration to compare.
*
* Usage: npx tsx scripts/rvf-baseline-benchmark.ts [--output reports/baseline-benchmarks.json]
*/
import { performance } from 'perf_hooks';
import { existsSync, readFileSync, writeFileSync } from 'fs';
import { resolve } from 'path';
import Database from 'better-sqlite3';
const OUTPUT_FILE = process.argv.includes('--output')
? process.argv[process.argv.indexOf('--output') + 1]
: 'reports/baseline-benchmarks.json';
interface BenchmarkResult {
timestamp: string;
label: string;
system: {
platform: string;
arch: string;
nodeVersion: string;
memoryTotal: number;
};
benchmarks: {
bootTime: BootTimeBenchmark;
patternSearch: SearchBenchmark;
memoryUsage: MemoryBenchmark;
databaseStats: DatabaseStats;
hnswImplementations: HnswAudit;
routingLatency: RoutingBenchmark;
dreamCycle: DreamBenchmark;
mincutAvailability: MincutBenchmark;
// RVF integration benchmarks (new)
mincutRouting?: MincutRoutingBenchmark;
unifiedHnswSearch?: UnifiedHnswSearchBenchmark;
witnessChain?: WitnessChainBenchmark;
structuralHealth?: StructuralHealthBenchmark;
};
}
interface BootTimeBenchmark {
description: string;
reasoningBankInitMs: number;
embeddingModelLoadMs: number;
hnswInitMs: number;
totalBootMs: number;
}
interface SearchBenchmark {
description: string;
queriesRun: number;
p50Ms: number;
p95Ms: number;
p99Ms: number;
meanMs: number;
recall: number | null;
}
interface MemoryBenchmark {
description: string;
rssBeforeMb: number;
rssAfterLoadMb: number;
heapUsedMb: number;
heapTotalMb: number;
externalMb: number;
}
interface DatabaseStats {
description: string;
dbSizeBytes: number;
dbSizeMb: number;
patternCount: number;
vectorCount: number;
kvCount: number;
qValueCount: number;
dreamCycleCount: number;
dreamInsightCount: number;
tables: string[];
}
interface HnswAudit {
description: string;
implementationCount: number;
implementations: string[];
total?: number;
deprecated?: number;
active?: number;
unified?: boolean;
}
interface RoutingBenchmark {
description: string;
currentMethod: string;
queriesRun: number;
p50Ms: number;
p95Ms: number;
meanMs: number;
}
interface DreamBenchmark {
description: string;
pendingExperiences: number;
lastDreamTime: string | null;
totalDreamCycles: number;
totalInsights: number;
}
interface MincutBenchmark {
description: string;
typescriptAvailable: boolean;
nativeAvailable: boolean;
typescriptLatencyUs: number | null;
nativeLatencyUs: number | null;
}
interface MincutRoutingBenchmark {
description: string;
topologySize: number;
queriesRun: number;
p50Ms: number;
p95Ms: number;
meanMs: number;
}
interface UnifiedHnswSearchBenchmark {
description: string;
vectorCount: number;
dimensions: number;
queriesRun: number;
k: number;
p50Ms: number;
p95Ms: number;
meanMs: number;
recallEstimate: number;
}
interface WitnessChainBenchmark {
description: string;
chainLength: number;
appendP50Ms: number;
appendP95Ms: number;
appendMeanMs: number;
verifyMs: number;
}
interface StructuralHealthBenchmark {
description: string;
agentCount: number;
computeMs: number;
status: string;
lambda: number;
}
function percentile(arr: number[], p: number): number {
const sorted = [...arr].sort((a, b) => a - b);
const idx = Math.ceil((p / 100) * sorted.length) - 1;
return sorted[Math.max(0, idx)];
}
async function benchmarkBoot(): Promise<BootTimeBenchmark> {
console.log(' [1/12] Benchmarking boot time...');
const t0 = performance.now();
// Measure embedding model load
const tEmb0 = performance.now();
let embeddingLoaded = false;
try {
const { pipeline } = await import('@huggingface/transformers');
await pipeline('feature-extraction', 'Xenova/all-MiniLM-L6-v2');
embeddingLoaded = true;
} catch {
// Model may already be cached
}
const tEmb1 = performance.now();
// Measure HNSW init
const tHnsw0 = performance.now();
let hnswInitialized = false;
try {
const gnn = await import('@ruvector/gnn');
if (gnn.differentiableSearch) {
// Quick probe to force initialization
const q = new Float32Array(384).fill(0.1);
const c = new Float32Array(384).fill(0.2);
gnn.differentiableSearch(q, c, 1, 1, 0.5);
hnswInitialized = true;
}
} catch {
// GNN not available
}
const tHnsw1 = performance.now();
// Measure ReasoningBank init (pattern loading)
const tRb0 = performance.now();
const dbPath = resolve(process.cwd(), '.agentic-qe/memory.db');
if (existsSync(dbPath)) {
const db = new Database(dbPath, { readonly: true });
try {
const patterns = db.prepare('SELECT COUNT(*) as cnt FROM qe_patterns').get() as any;
// Simulate loading top patterns (what ReasoningBank does on init)
db.prepare('SELECT * FROM qe_patterns ORDER BY confidence DESC LIMIT 200').all();
} catch { /* table may not exist */ }
db.close();
}
const tRb1 = performance.now();
const totalBoot = performance.now() - t0;
return {
description: 'Time from cold start to first query capability',
reasoningBankInitMs: Math.round((tRb1 - tRb0) * 100) / 100,
embeddingModelLoadMs: Math.round((tEmb1 - tEmb0) * 100) / 100,
hnswInitMs: Math.round((tHnsw1 - tHnsw0) * 100) / 100,
totalBootMs: Math.round(totalBoot * 100) / 100,
};
}
async function benchmarkSearch(): Promise<SearchBenchmark> {
console.log(' [2/12] Benchmarking pattern search latency...');
const dbPath = resolve(process.cwd(), '.agentic-qe/memory.db');
const latencies: number[] = [];
if (!existsSync(dbPath)) {
return { description: 'Pattern search latency', queriesRun: 0, p50Ms: 0, p95Ms: 0, p99Ms: 0, meanMs: 0, recall: null };
}
const db = new Database(dbPath, { readonly: true });
// Get sample patterns to use as queries
let samplePatterns: any[] = [];
try {
samplePatterns = db.prepare(
"SELECT id, domain, pattern_data FROM qe_patterns ORDER BY RANDOM() LIMIT 20"
).all();
} catch { /* table may not exist */ }
if (samplePatterns.length === 0) {
db.close();
return { description: 'Pattern search latency', queriesRun: 0, p50Ms: 0, p95Ms: 0, p99Ms: 0, meanMs: 0, recall: null };
}
// Benchmark: search by domain (simulates ReasoningBank.routeTask)
const domains = ['test-generation', 'coverage-analysis', 'quality-assessment', 'defect-intelligence', 'security-compliance'];
for (const domain of domains) {
for (let i = 0; i < 4; i++) {
const t0 = performance.now();
db.prepare(
"SELECT * FROM qe_patterns WHERE domain = ? ORDER BY confidence DESC LIMIT 10"
).all(domain);
latencies.push(performance.now() - t0);
}
}
// Benchmark: full-text-ish search (LIKE queries, simulating pattern matching)
const queries = ['authentication', 'coverage', 'security', 'performance', 'regression'];
for (const q of queries) {
const t0 = performance.now();
db.prepare(
"SELECT * FROM qe_patterns WHERE pattern_data LIKE ? ORDER BY confidence DESC LIMIT 10"
).all(`%${q}%`);
latencies.push(performance.now() - t0);
}
db.close();
const mean = latencies.reduce((a, b) => a + b, 0) / latencies.length;
return {
description: 'Pattern search latency (SQLite queries, no vector search)',
queriesRun: latencies.length,
p50Ms: Math.round(percentile(latencies, 50) * 100) / 100,
p95Ms: Math.round(percentile(latencies, 95) * 100) / 100,
p99Ms: Math.round(percentile(latencies, 99) * 100) / 100,
meanMs: Math.round(mean * 100) / 100,
recall: null, // No vector recall benchmark yet (needs embedding + search)
};
}
function benchmarkMemory(): MemoryBenchmark {
console.log(' [3/12] Benchmarking memory usage...');
const mem = process.memoryUsage();
return {
description: 'Node.js process memory usage',
rssBeforeMb: Math.round(mem.rss / 1024 / 1024 * 100) / 100,
rssAfterLoadMb: Math.round(mem.rss / 1024 / 1024 * 100) / 100,
heapUsedMb: Math.round(mem.heapUsed / 1024 / 1024 * 100) / 100,
heapTotalMb: Math.round(mem.heapTotal / 1024 / 1024 * 100) / 100,
externalMb: Math.round(mem.external / 1024 / 1024 * 100) / 100,
};
}
function benchmarkDatabase(): DatabaseStats {
console.log(' [4/12] Benchmarking database stats...');
const dbPath = resolve(process.cwd(), '.agentic-qe/memory.db');
if (!existsSync(dbPath)) {
return {
description: 'Database not found',
dbSizeBytes: 0, dbSizeMb: 0,
patternCount: 0, vectorCount: 0, kvCount: 0, qValueCount: 0,
dreamCycleCount: 0, dreamInsightCount: 0, tables: [],
};
}
const { statSync } = require('fs');
const stats = statSync(dbPath);
const db = new Database(dbPath, { readonly: true });
const getCount = (table: string): number => {
try {
const row = db.prepare(`SELECT COUNT(*) as cnt FROM ${table}`).get() as any;
return row?.cnt ?? 0;
} catch { return 0; }
};
// Get all tables
const tables = (db.prepare("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name").all() as any[])
.map(r => r.name);
const result: DatabaseStats = {
description: 'SQLite database statistics',
dbSizeBytes: stats.size,
dbSizeMb: Math.round(stats.size / 1024 / 1024 * 100) / 100,
patternCount: getCount('qe_patterns'),
vectorCount: getCount('vectors'),
kvCount: getCount('kv_store'),
qValueCount: getCount('rl_q_values'),
dreamCycleCount: getCount('dream_cycles'),
dreamInsightCount: getCount('dream_insights'),
tables,
};
db.close();
return result;
}
function auditHnswImplementations(): HnswAudit {
console.log(' [5/12] Auditing HNSW implementations...');
// Dynamically detect HNSW implementation classes by scanning source files
const sourceRoot = resolve(process.cwd(), 'src');
const implementations: string[] = [];
const deprecatedImpls: string[] = [];
let hasUnifiedBackend = false;
// Known implementation locations to scan
const implLocations: Array<{ file: string; classPattern: RegExp; deprecated: boolean }> = [
{ file: 'kernel/unified-memory-hnsw.ts', classPattern: /export class (\w*(?:HNSW|Hnsw|FlatIndex)\w*)/g, deprecated: true },
{ file: 'kernel/progressive-hnsw-backend.ts', classPattern: /export class (\w*(?:Hnsw|HNSW)\w*)/g, deprecated: false },
{ file: 'kernel/hnsw-adapter.ts', classPattern: /export class (\w*(?:Hnsw|HNSW)\w*)/g, deprecated: false },
{ file: 'integrations/ruvector/gnn-wrapper.ts', classPattern: /export class (\w*(?:EmbeddingIndex|HNSW|Hnsw)\w*)/g, deprecated: true },
{ file: 'integrations/embeddings/index/HNSWIndex.ts', classPattern: /export class (\w*(?:HNSW|Hnsw)\w*)/g, deprecated: true },
{ file: 'domains/coverage-analysis/services/hnsw-index.ts', classPattern: /export class (\w*(?:HNSW|Hnsw|Index)\w*)/g, deprecated: true },
];
for (const loc of implLocations) {
const filePath = resolve(sourceRoot, loc.file);
if (existsSync(filePath)) {
try {
const content = readFileSync(filePath, 'utf-8');
let match: RegExpExecArray | null;
while ((match = loc.classPattern.exec(content)) !== null) {
const className = match[1];
const label = `${className} — src/${loc.file}`;
implementations.push(label);
if (loc.deprecated) {
deprecatedImpls.push(label);
}
if (className === 'ProgressiveHnswBackend' || className === 'HnswAdapter') {
hasUnifiedBackend = true;
}
}
} catch { /* file not readable */ }
}
}
const activeCount = implementations.length - deprecatedImpls.length;
return {
description: 'Count of distinct HNSW/search implementations (dynamically detected)',
implementationCount: implementations.length,
implementations,
total: implementations.length,
deprecated: deprecatedImpls.length,
active: activeCount,
unified: hasUnifiedBackend,
};
}
async function benchmarkRouting(): Promise<RoutingBenchmark> {
console.log(' [6/12] Benchmarking routing latency (heuristic)...');
// Simulate routing decisions (what model_route MCP tool does)
const latencies: number[] = [];
const tasks = [
'Generate unit tests for auth module',
'Analyze coverage gaps in payment service',
'Run security scan on API endpoints',
'Fix flaky test in CI pipeline',
'Review pull request for performance regression',
'Add type annotations to legacy module',
'Refactor database queries for optimization',
'Create integration tests for webhook handler',
'Validate API contract for breaking changes',
'Assess code quality for release readiness',
];
// Simple heuristic routing simulation (what current system does)
for (const task of tasks) {
const t0 = performance.now();
// Current routing: keyword matching + complexity heuristic
const words = task.toLowerCase().split(' ');
const complexity = words.length > 8 ? 'high' : words.length > 5 ? 'medium' : 'low';
const domain = words.includes('test') ? 'test-generation' :
words.includes('coverage') ? 'coverage-analysis' :
words.includes('security') ? 'security-compliance' :
words.includes('quality') ? 'quality-assessment' : 'test-generation';
const tier = complexity === 'high' ? 3 : complexity === 'medium' ? 2 : 1;
latencies.push(performance.now() - t0);
}
const mean = latencies.reduce((a, b) => a + b, 0) / latencies.length;
return {
description: 'Task routing decision latency (heuristic method)',
currentMethod: 'keyword-matching + complexity-heuristic (3-tier static)',
queriesRun: latencies.length,
p50Ms: Math.round(percentile(latencies, 50) * 1000) / 1000,
p95Ms: Math.round(percentile(latencies, 95) * 1000) / 1000,
meanMs: Math.round(mean * 1000) / 1000,
};
}
function benchmarkDreamCycles(): DreamBenchmark {
console.log(' [7/12] Benchmarking dream cycle stats...');
const dbPath = resolve(process.cwd(), '.agentic-qe/memory.db');
if (!existsSync(dbPath)) {
return {
description: 'Dream cycle statistics',
pendingExperiences: 0, lastDreamTime: null,
totalDreamCycles: 0, totalInsights: 0,
};
}
const db = new Database(dbPath, { readonly: true });
let totalCycles = 0;
let totalInsights = 0;
let lastDream: string | null = null;
try {
totalCycles = (db.prepare('SELECT COUNT(*) as cnt FROM dream_cycles').get() as any)?.cnt ?? 0;
} catch { /* table may not exist */ }
try {
totalInsights = (db.prepare('SELECT COUNT(*) as cnt FROM dream_insights').get() as any)?.cnt ?? 0;
} catch { /* table may not exist */ }
try {
const row = db.prepare('SELECT MAX(created_at) as last_dream FROM dream_cycles').get() as any;
lastDream = row?.last_dream ?? null;
} catch { /* table may not exist */ }
db.close();
return {
description: 'Dream cycle statistics (no safe branching currently)',
pendingExperiences: 27, // From session startup hook
lastDreamTime: lastDream,
totalDreamCycles: totalCycles,
totalInsights: totalInsights,
};
}
async function benchmarkMincut(): Promise<MincutBenchmark> {
console.log(' [8/12] Checking mincut availability...');
let tsAvailable = false;
let tsLatency: number | null = null;
let nativeAvailable = false;
let nativeLatency: number | null = null;
// Check TypeScript MinCutCalculator
try {
const { MinCutCalculator } = await import('../src/coordination/mincut/mincut-calculator.js');
if (MinCutCalculator) {
tsAvailable = true;
// Quick benchmark: create a small graph and compute mincut
const t0 = performance.now();
const calc = new MinCutCalculator();
// If it has a compute method, benchmark it
const elapsed = (performance.now() - t0) * 1000; // to microseconds
tsLatency = Math.round(elapsed * 100) / 100;
}
} catch {
// TypeScript mincut not importable in this context
tsAvailable = false;
}
// Check native @ruvector/mincut-node
try {
const mincut = await import('@ruvector/mincut-node');
if (mincut) {
nativeAvailable = true;
}
} catch {
nativeAvailable = false;
}
return {
description: 'MinCut algorithm availability and latency',
typescriptAvailable: tsAvailable,
nativeAvailable: nativeAvailable,
typescriptLatencyUs: tsLatency,
nativeLatencyUs: nativeLatency,
};
}
// ============================================================================
// RVF Integration Benchmarks (new)
// ============================================================================
/**
* Build a test agent topology for mincut and structural health benchmarks.
* Creates 5 agents across 2 domains with cross-domain dependencies.
*/
function buildTestTopology(size: number = 5): any[] {
const domains = ['test-generation', 'coverage-analysis', 'security-compliance'];
const agents: any[] = [];
for (let i = 0; i < size; i++) {
const domain = domains[i % domains.length];
const dependsOn: string[] = [];
// Each agent depends on 1-2 previous agents (creates realistic connectivity)
if (i > 0) dependsOn.push(`agent-${i - 1}`);
if (i > 2) dependsOn.push(`agent-${i - 2}`);
agents.push({
id: `agent-${i}`,
name: `Agent ${i}`,
domain,
capabilities: ['code-analysis', 'test-generation'],
dependsOn,
weight: 0.5 + Math.random() * 0.5,
});
}
return agents;
}
async function benchmarkMincutRouting(): Promise<MincutRoutingBenchmark> {
console.log(' [9/12] Benchmarking mincut routing with topology...');
try {
const { QEMinCutService } = await import('../src/integrations/ruvector/mincut-wrapper.js');
const service = new QEMinCutService();
const topology = buildTestTopology(5);
const tasks = [
'Generate unit tests for auth module',
'Analyze coverage gaps in payment service',
'Run security scan on API endpoints',
'Fix flaky test in CI pipeline',
'Review pull request for performance regression',
'Add type annotations to legacy module',
'Refactor database queries for optimization',
'Create integration tests for webhook handler',
'Validate API contract for breaking changes',
'Assess code quality for release readiness',
];
const latencies: number[] = [];
// Run 100 calls cycling through the task list
for (let i = 0; i < 100; i++) {
const task = tasks[i % tasks.length];
const t0 = performance.now();
service.computeRoutingTier(task, topology);
latencies.push(performance.now() - t0);
}
const mean = latencies.reduce((a, b) => a + b, 0) / latencies.length;
return {
description: 'MinCut routing with 5-agent topology (QEMinCutService.computeRoutingTier)',
topologySize: 5,
queriesRun: 100,
p50Ms: Math.round(percentile(latencies, 50) * 1000) / 1000,
p95Ms: Math.round(percentile(latencies, 95) * 1000) / 1000,
meanMs: Math.round(mean * 1000) / 1000,
};
} catch (err) {
console.log(` [skip] MinCut routing benchmark failed: ${err instanceof Error ? err.message : String(err)}`);
return {
description: 'MinCut routing benchmark (skipped - import failed)',
topologySize: 0,
queriesRun: 0,
p50Ms: 0,
p95Ms: 0,
meanMs: 0,
};
}
}
async function benchmarkUnifiedHnswSearch(): Promise<UnifiedHnswSearchBenchmark> {
console.log(' [10/12] Benchmarking unified HNSW search (ProgressiveHnswBackend)...');
try {
const { ProgressiveHnswBackend } = await import('../src/kernel/progressive-hnsw-backend.js');
const backend = new ProgressiveHnswBackend({ dimensions: 384, M: 16, efConstruction: 200, efSearch: 100, metric: 'cosine' });
const VECTOR_COUNT = 1000;
const QUERY_COUNT = 100;
const K = 10;
const DIM = 384;
// Add 1000 random vectors
for (let i = 0; i < VECTOR_COUNT; i++) {
const vec = new Float32Array(DIM);
for (let d = 0; d < DIM; d++) {
vec[d] = (Math.random() - 0.5) * 2;
}
backend.add(i, vec);
}
// Run 100 search queries
const latencies: number[] = [];
for (let i = 0; i < QUERY_COUNT; i++) {
const query = new Float32Array(DIM);
for (let d = 0; d < DIM; d++) {
query[d] = (Math.random() - 0.5) * 2;
}
const t0 = performance.now();
backend.search(query, K);
latencies.push(performance.now() - t0);
}
const mean = latencies.reduce((a, b) => a + b, 0) / latencies.length;
const recallEstimate = backend.recall();
return {
description: 'Unified HNSW search via ProgressiveHnswBackend (384-dim, 1000 vectors, k=10)',
vectorCount: VECTOR_COUNT,
dimensions: DIM,
queriesRun: QUERY_COUNT,
k: K,
p50Ms: Math.round(percentile(latencies, 50) * 1000) / 1000,
p95Ms: Math.round(percentile(latencies, 95) * 1000) / 1000,
meanMs: Math.round(mean * 1000) / 1000,
recallEstimate,
};
} catch (err) {
console.log(` [skip] Unified HNSW benchmark failed: ${err instanceof Error ? err.message : String(err)}`);
return {
description: 'Unified HNSW search benchmark (skipped - import failed)',
vectorCount: 0,
dimensions: 384,
queriesRun: 0,
k: 10,
p50Ms: 0,
p95Ms: 0,
meanMs: 0,
recallEstimate: 0,
};
}
}
async function benchmarkWitnessChain(): Promise<WitnessChainBenchmark> {
console.log(' [11/12] Benchmarking witness chain append + verify...');
try {
const { createWitnessChain } = await import('../src/audit/witness-chain.js');
// Use an in-memory SQLite database to avoid touching production data
const inMemDb = new Database(':memory:');
const chain = createWitnessChain(inMemDb as any);
await chain.initialize();
const ENTRY_COUNT = 100;
const appendLatencies: number[] = [];
// Append 100 entries, measuring each
const actionTypes: Array<'PATTERN_CREATE' | 'PATTERN_UPDATE' | 'QUALITY_GATE_PASS' | 'ROUTING_DECISION' | 'DREAM_MERGE'> =
['PATTERN_CREATE', 'PATTERN_UPDATE', 'QUALITY_GATE_PASS', 'ROUTING_DECISION', 'DREAM_MERGE'];
for (let i = 0; i < ENTRY_COUNT; i++) {
const actionType = actionTypes[i % actionTypes.length];
const actionData = {
index: i,
domain: 'test-generation',
confidence: 0.85 + Math.random() * 0.15,
detail: `Benchmark entry ${i}`,
};
const t0 = performance.now();
chain.append(actionType, actionData, 'benchmark-agent');
appendLatencies.push(performance.now() - t0);
}
// Measure verify latency for the full chain
const tVerify0 = performance.now();
chain.verify();
const verifyMs = performance.now() - tVerify0;
const chainLength = chain.getChainLength();
const appendMean = appendLatencies.reduce((a, b) => a + b, 0) / appendLatencies.length;
inMemDb.close();
return {
description: `Witness chain: ${ENTRY_COUNT} appends + full verify (in-memory SQLite)`,
chainLength,
appendP50Ms: Math.round(percentile(appendLatencies, 50) * 1000) / 1000,
appendP95Ms: Math.round(percentile(appendLatencies, 95) * 1000) / 1000,
appendMeanMs: Math.round(appendMean * 1000) / 1000,
verifyMs: Math.round(verifyMs * 100) / 100,
};
} catch (err) {
console.log(` [skip] Witness chain benchmark failed: ${err instanceof Error ? err.message : String(err)}`);
return {
description: 'Witness chain benchmark (skipped - import failed)',
chainLength: 0,
appendP50Ms: 0,
appendP95Ms: 0,
appendMeanMs: 0,
verifyMs: 0,
};
}
}
async function benchmarkStructuralHealth(): Promise<StructuralHealthBenchmark> {
console.log(' [12/12] Benchmarking structural health computation...');
try {
const { StructuralHealthMonitor } = await import('../src/monitoring/structural-health.js');
const monitor = new StructuralHealthMonitor({ enableLogging: false });
const topology = buildTestTopology(10);
const t0 = performance.now();
const health = monitor.computeFleetHealth(topology);
const computeMs = performance.now() - t0;
return {
description: 'Structural health computation for 10-agent fleet topology',
agentCount: 10,
computeMs: Math.round(computeMs * 100) / 100,
status: health.status,
lambda: Math.round(health.normalizedLambda * 1000) / 1000,
};
} catch (err) {
console.log(` [skip] Structural health benchmark failed: ${err instanceof Error ? err.message : String(err)}`);
return {
description: 'Structural health benchmark (skipped - import failed)',
agentCount: 0,
computeMs: 0,
status: 'empty',
lambda: 0,
};
}
}
async function main() {
console.log('=== RVF Integration Baseline Benchmark ===\n');
console.log(`Output: ${OUTPUT_FILE}\n`);
const memBefore = process.memoryUsage();
const boot = await benchmarkBoot();
const search = await benchmarkSearch();
const memory = benchmarkMemory();
const dbStats = benchmarkDatabase();
const hnsw = auditHnswImplementations();
const routing = await benchmarkRouting();
const dream = benchmarkDreamCycles();
const mincut = await benchmarkMincut();
// RVF integration benchmarks (new)
const mincutRouting = await benchmarkMincutRouting();
const unifiedHnsw = await benchmarkUnifiedHnswSearch();
const witnessChainResult = await benchmarkWitnessChain();
const structuralHealth = await benchmarkStructuralHealth();
const result: BenchmarkResult = {
timestamp: new Date().toISOString(),
label: process.argv.includes('--label')
? process.argv[process.argv.indexOf('--label') + 1]
: 'baseline',
system: {
platform: process.platform,
arch: process.arch,
nodeVersion: process.version,
memoryTotal: require('os').totalmem(),
},
benchmarks: {
bootTime: boot,
patternSearch: search,
memoryUsage: memory,
databaseStats: dbStats,
hnswImplementations: hnsw,
routingLatency: routing,
dreamCycle: dream,
mincutAvailability: mincut,
mincutRouting,
unifiedHnswSearch: unifiedHnsw,
witnessChain: witnessChainResult,
structuralHealth,
},
};
writeFileSync(resolve(process.cwd(), OUTPUT_FILE), JSON.stringify(result, null, 2));
console.log('\n=== Results Summary ===\n');
console.log(`Boot time: ${boot.totalBootMs}ms (embedding: ${boot.embeddingModelLoadMs}ms, HNSW: ${boot.hnswInitMs}ms, patterns: ${boot.reasoningBankInitMs}ms)`);
console.log(`Search latency: p50=${search.p50Ms}ms p95=${search.p95Ms}ms (${search.queriesRun} queries)`);
console.log(`Memory RSS: ${memory.rssAfterLoadMb}MB (heap: ${memory.heapUsedMb}MB)`);
console.log(`Database: ${dbStats.dbSizeMb}MB, ${dbStats.patternCount} patterns, ${dbStats.vectorCount} vectors, ${dbStats.kvCount} kv entries`);
console.log(`HNSW impls: ${hnsw.implementationCount} total (${hnsw.active ?? '?'} active, ${hnsw.deprecated ?? '?'} deprecated, unified=${hnsw.unified ?? false})`);
console.log(`Routing latency: p50=${routing.p50Ms}ms p95=${routing.p95Ms}ms (${routing.currentMethod})`);
console.log(`Dream cycles: ${dream.totalDreamCycles} completed, ${dream.totalInsights} insights, ${dream.pendingExperiences} pending`);
console.log(`MinCut: TS=${mincut.typescriptAvailable}, Native=${mincut.nativeAvailable}`);
console.log('');
console.log('--- RVF Integration Benchmarks ---');
console.log(`MinCut routing: p50=${mincutRouting.p50Ms}ms p95=${mincutRouting.p95Ms}ms (${mincutRouting.queriesRun} calls, ${mincutRouting.topologySize}-agent topology)`);
console.log(`Unified HNSW: p50=${unifiedHnsw.p50Ms}ms p95=${unifiedHnsw.p95Ms}ms (${unifiedHnsw.vectorCount} vectors, k=${unifiedHnsw.k}, recall=${unifiedHnsw.recallEstimate})`);
console.log(`Witness chain: append p50=${witnessChainResult.appendP50Ms}ms p95=${witnessChainResult.appendP95Ms}ms, verify=${witnessChainResult.verifyMs}ms (${witnessChainResult.chainLength} entries)`);
console.log(`Structural health: ${structuralHealth.computeMs}ms (${structuralHealth.agentCount} agents, status=${structuralHealth.status}, lambda=${structuralHealth.lambda})`);
console.log(`\nSaved to: ${OUTPUT_FILE}`);
}
main().catch(err => {
console.error('Benchmark failed:', err);
process.exit(1);
});