nano-brain 2026.8.1 → 2026.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/dist/bench/compare.d.ts +8 -0
  2. package/dist/bench/compare.d.ts.map +1 -0
  3. package/dist/bench/compare.js +154 -0
  4. package/dist/bench/compare.js.map +1 -0
  5. package/dist/bench/generator.d.ts +11 -0
  6. package/dist/bench/generator.d.ts.map +1 -0
  7. package/dist/bench/generator.js +249 -0
  8. package/dist/bench/generator.js.map +1 -0
  9. package/dist/bench/index.d.ts +3 -0
  10. package/dist/bench/index.d.ts.map +1 -0
  11. package/dist/bench/index.js +134 -0
  12. package/dist/bench/index.js.map +1 -0
  13. package/dist/bench/runner.d.ts +10 -0
  14. package/dist/bench/runner.d.ts.map +1 -0
  15. package/dist/bench/runner.js +484 -0
  16. package/dist/bench/runner.js.map +1 -0
  17. package/dist/bench/types.d.ts +87 -0
  18. package/dist/bench/types.d.ts.map +1 -0
  19. package/dist/bench/types.js +2 -0
  20. package/dist/bench/types.js.map +1 -0
  21. package/dist/bench.d.ts.map +1 -1
  22. package/dist/bench.js +5 -0
  23. package/dist/bench.js.map +1 -1
  24. package/dist/cli/commands/write.d.ts.map +1 -1
  25. package/dist/cli/commands/write.js +17 -17
  26. package/dist/cli/commands/write.js.map +1 -1
  27. package/dist/cli/utils.js +1 -1
  28. package/dist/cli/utils.js.map +1 -1
  29. package/dist/fts-worker.js +8 -17
  30. package/dist/fts-worker.js.map +1 -1
  31. package/dist/host.d.ts.map +1 -1
  32. package/dist/host.js +3 -0
  33. package/dist/host.js.map +1 -1
  34. package/dist/jobs/consolidation-worker.d.ts +0 -1
  35. package/dist/jobs/consolidation-worker.d.ts.map +1 -1
  36. package/dist/jobs/consolidation-worker.js +0 -6
  37. package/dist/jobs/consolidation-worker.js.map +1 -1
  38. package/dist/mcp/tools/memory.js +10 -10
  39. package/dist/mcp/tools/memory.js.map +1 -1
  40. package/dist/providers/qdrant.d.ts +0 -5
  41. package/dist/providers/qdrant.d.ts.map +1 -1
  42. package/dist/providers/qdrant.js +1 -17
  43. package/dist/providers/qdrant.js.map +1 -1
  44. package/dist/providers/vector-store.d.ts +0 -1
  45. package/dist/providers/vector-store.d.ts.map +1 -1
  46. package/dist/providers/vector-store.js.map +1 -1
  47. package/dist/search.d.ts +0 -2
  48. package/dist/search.d.ts.map +1 -1
  49. package/dist/search.js +0 -45
  50. package/dist/search.js.map +1 -1
  51. package/dist/server/bootstrap.d.ts.map +1 -1
  52. package/dist/server/bootstrap.js +0 -7
  53. package/dist/server/bootstrap.js.map +1 -1
  54. package/dist/store/documents.d.ts.map +1 -1
  55. package/dist/store/documents.js +10 -17
  56. package/dist/store/documents.js.map +1 -1
  57. package/dist/store/index.d.ts.map +1 -1
  58. package/dist/store/index.js +1 -45
  59. package/dist/store/index.js.map +1 -1
  60. package/dist/store/schema.js +1 -38
  61. package/dist/store/schema.js.map +1 -1
  62. package/dist/store/vectors.d.ts +0 -1
  63. package/dist/store/vectors.d.ts.map +1 -1
  64. package/dist/store/vectors.js +3 -45
  65. package/dist/store/vectors.js.map +1 -1
  66. package/dist/treesitter.d.ts.map +1 -1
  67. package/dist/treesitter.js +10 -10
  68. package/dist/treesitter.js.map +1 -1
  69. package/dist/types.d.ts +0 -19
  70. package/dist/types.d.ts.map +1 -1
  71. package/dist/types.js +1 -4
  72. package/dist/types.js.map +1 -1
  73. package/package.json +1 -1
  74. package/src/bench/compare.ts +186 -0
  75. package/src/bench/generator.ts +278 -0
  76. package/src/bench/index.ts +135 -0
  77. package/src/bench/runner.ts +568 -0
  78. package/src/bench/types.ts +98 -0
  79. package/src/bench.ts +6 -0
  80. package/src/cli/utils.ts +1 -1
  81. package/src/host.ts +4 -0
  82. package/src/treesitter.ts +13 -14
@@ -0,0 +1,8 @@
1
+ export interface CompareOptions {
2
+ resultPath: string;
3
+ baselinePath: string;
4
+ savePath?: string;
5
+ force: boolean;
6
+ }
7
+ export declare function runCompare(opts: CompareOptions): number;
8
+ //# sourceMappingURL=compare.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../src/bench/compare.ts"],"names":[],"mappings":"AAwGA,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CA0EvD"}
@@ -0,0 +1,154 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ const THRESHOLDS = {
4
+ p5: { warn: 0.05, fail: 0.10 },
5
+ r10: { warn: 0.05, fail: 0.10 },
6
+ mrr: { warn: 0.03, fail: 0.05 },
7
+ cmd_rate: { warnBelow: 1.00, failBelow: 0.90 },
8
+ };
9
+ function metricStatus(drop, thresholds) {
10
+ if (drop > thresholds.fail)
11
+ return 'FAIL';
12
+ if (drop > thresholds.warn)
13
+ return 'WARN';
14
+ return 'PASS';
15
+ }
16
+ function commandPassRate(result, scale) {
17
+ const sr = result.scales[scale];
18
+ if (!sr || sr.commands.length === 0)
19
+ return 1;
20
+ const passed = sr.commands.filter(c => c.status === 'pass').length;
21
+ return passed / sr.commands.length;
22
+ }
23
+ function collectMetricRows(current, baseline, scale) {
24
+ const rows = [];
25
+ const cur = current.scales[scale];
26
+ const bas = baseline.scales[scale];
27
+ if (!cur || !bas)
28
+ return rows;
29
+ const metrics = [
30
+ { name: `P@5 fts (scale=${scale})`, cur: cur.quality.fts.mean_p5, bas: bas.quality.fts.mean_p5, thr: THRESHOLDS.p5 },
31
+ { name: `R@10 fts (scale=${scale})`, cur: cur.quality.fts.mean_r10, bas: bas.quality.fts.mean_r10, thr: THRESHOLDS.r10 },
32
+ { name: `MRR fts (scale=${scale})`, cur: cur.quality.fts.mean_mrr, bas: bas.quality.fts.mean_mrr, thr: THRESHOLDS.mrr },
33
+ ];
34
+ if (cur.quality.hybrid !== null || bas.quality.hybrid !== null) {
35
+ metrics.unshift({ name: `P@5 hybrid (scale=${scale})`, cur: cur.quality.hybrid?.mean_p5 ?? 0, bas: bas.quality.hybrid?.mean_p5 ?? 0, thr: THRESHOLDS.p5 }, { name: `R@10 hybrid (scale=${scale})`, cur: cur.quality.hybrid?.mean_r10 ?? 0, bas: bas.quality.hybrid?.mean_r10 ?? 0, thr: THRESHOLDS.r10 }, { name: `MRR hybrid (scale=${scale})`, cur: cur.quality.hybrid?.mean_mrr ?? 0, bas: bas.quality.hybrid?.mean_mrr ?? 0, thr: THRESHOLDS.mrr });
36
+ }
37
+ for (const m of metrics) {
38
+ const drop = m.bas - m.cur;
39
+ rows.push({ metric: m.name, baseline: m.bas, current: m.cur, delta: -drop, status: metricStatus(drop, m.thr) });
40
+ }
41
+ const curRate = commandPassRate(current, scale);
42
+ const basRate = commandPassRate(baseline, scale);
43
+ let cmdStatus = 'PASS';
44
+ if (curRate < THRESHOLDS.cmd_rate.failBelow)
45
+ cmdStatus = 'FAIL';
46
+ else if (curRate < THRESHOLDS.cmd_rate.warnBelow)
47
+ cmdStatus = 'WARN';
48
+ rows.push({ metric: `Command pass rate (scale=${scale})`, baseline: basRate, current: curRate, delta: curRate - basRate, status: cmdStatus });
49
+ const hybBeatsFts = cur.quality.hybrid_beats_fts;
50
+ if (hybBeatsFts === false) {
51
+ rows.push({ metric: `Hybrid≥FTS assertion (scale=${scale})`, baseline: 1, current: 0, delta: -1, status: 'WARN' });
52
+ }
53
+ else if (hybBeatsFts === true) {
54
+ rows.push({ metric: `Hybrid≥FTS assertion (scale=${scale})`, baseline: 1, current: 1, delta: 0, status: 'PASS' });
55
+ }
56
+ return rows;
57
+ }
58
+ function printTable(rows) {
59
+ const colWidths = { metric: 45, baseline: 10, current: 10, delta: 10, status: 6 };
60
+ const header = [
61
+ 'Metric'.padEnd(colWidths.metric),
62
+ 'Baseline'.padStart(colWidths.baseline),
63
+ 'Current'.padStart(colWidths.current),
64
+ 'Delta'.padStart(colWidths.delta),
65
+ 'Status'.padEnd(colWidths.status),
66
+ ].join(' ');
67
+ const sep = '-'.repeat(header.length);
68
+ console.log(sep);
69
+ console.log(header);
70
+ console.log(sep);
71
+ for (const row of rows) {
72
+ const sign = row.delta >= 0 ? '+' : '';
73
+ const line = [
74
+ row.metric.substring(0, colWidths.metric).padEnd(colWidths.metric),
75
+ row.baseline.toFixed(4).padStart(colWidths.baseline),
76
+ row.current.toFixed(4).padStart(colWidths.current),
77
+ `${sign}${row.delta.toFixed(4)}`.padStart(colWidths.delta),
78
+ row.status.padEnd(colWidths.status),
79
+ ].join(' ');
80
+ console.log(line);
81
+ }
82
+ console.log(sep);
83
+ }
84
+ export function runCompare(opts) {
85
+ const { resultPath, baselinePath, savePath, force } = opts;
86
+ if (!fs.existsSync(resultPath)) {
87
+ console.error(`Result file not found: ${resultPath}`);
88
+ return 1;
89
+ }
90
+ if (!fs.existsSync(baselinePath)) {
91
+ console.error(`Baseline file not found: ${baselinePath}`);
92
+ return 1;
93
+ }
94
+ let current;
95
+ let baseline;
96
+ try {
97
+ current = JSON.parse(fs.readFileSync(resultPath, 'utf-8'));
98
+ }
99
+ catch (err) {
100
+ console.error(`Failed to parse ${resultPath}: ${err instanceof Error ? err.message : String(err)}`);
101
+ process.exit(1);
102
+ }
103
+ try {
104
+ baseline = JSON.parse(fs.readFileSync(baselinePath, 'utf-8'));
105
+ }
106
+ catch (err) {
107
+ console.error(`Failed to parse ${baselinePath}: ${err instanceof Error ? err.message : String(err)}`);
108
+ process.exit(1);
109
+ }
110
+ if (current.corpus_hash !== baseline.corpus_hash) {
111
+ console.warn(`Warning: Corpus hash mismatch — results may not be comparable`);
112
+ console.warn(` baseline: ${baseline.corpus_hash}`);
113
+ console.warn(` current: ${current.corpus_hash}`);
114
+ }
115
+ if (current.environment.ollama_model_digest !== baseline.environment.ollama_model_digest) {
116
+ console.warn(`Warning: Embedding model digest changed — metric shifts may be expected`);
117
+ console.warn(` baseline: ${baseline.environment.ollama_model_digest}`);
118
+ console.warn(` current: ${current.environment.ollama_model_digest}`);
119
+ }
120
+ const allScales = new Set([...Object.keys(current.scales), ...Object.keys(baseline.scales)]);
121
+ const allRows = [];
122
+ for (const scale of allScales) {
123
+ const rows = collectMetricRows(current, baseline, scale);
124
+ allRows.push(...rows);
125
+ }
126
+ console.log('\nnano-brain Benchmark Comparison');
127
+ printTable(allRows);
128
+ const hasFail = allRows.some(r => r.status === 'FAIL');
129
+ const hasWarn = allRows.some(r => r.status === 'WARN');
130
+ if (!hasFail && !hasWarn) {
131
+ console.log('ALL PASS');
132
+ }
133
+ else if (hasFail) {
134
+ console.log('REGRESSION DETECTED: one or more FAIL conditions');
135
+ }
136
+ else {
137
+ console.log('WARNINGS: one or more WARN conditions');
138
+ }
139
+ if (savePath) {
140
+ if (fs.existsSync(savePath) && !force) {
141
+ console.error(`Error: ${savePath} already exists, use --force to overwrite`);
142
+ return 3;
143
+ }
144
+ fs.mkdirSync(path.dirname(savePath), { recursive: true });
145
+ fs.copyFileSync(resultPath, savePath);
146
+ console.log(`Saved result to ${savePath}`);
147
+ }
148
+ if (hasFail)
149
+ return 1;
150
+ if (hasWarn)
151
+ return 2;
152
+ return 0;
153
+ }
154
+ //# sourceMappingURL=compare.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare.js","sourceRoot":"","sources":["../../src/bench/compare.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { TopicCluster } from './types.js';
2
+ declare const TOPIC_CLUSTERS: TopicCluster[];
3
+ export declare function computeCorpusHash(seed: number): string;
4
+ export interface GenerateOptions {
5
+ scale: number;
6
+ seed: number;
7
+ outDir: string;
8
+ }
9
+ export declare function generateCorpus(opts: GenerateOptions): void;
10
+ export { TOPIC_CLUSTERS };
11
+ //# sourceMappingURL=generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/bench/generator.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAA8C,MAAM,YAAY,CAAC;AAa3F,QAAA,MAAM,cAAc,EAAE,YAAY,EAyHjC,CAAC;AAwEF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGtD;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CAuD1D;AAED,OAAO,EAAE,cAAc,EAAE,CAAC"}
@@ -0,0 +1,249 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as crypto from 'crypto';
4
+ function mulberry32(seed) {
5
+ let s = seed;
6
+ return function () {
7
+ s |= 0;
8
+ s = (s + 0x6d2b79f5) | 0;
9
+ let t = Math.imul(s ^ (s >>> 15), 1 | s);
10
+ t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
11
+ return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
12
+ };
13
+ }
14
+ const TOPIC_CLUSTERS = [
15
+ {
16
+ id: 'auth',
17
+ label: 'JWT authentication middleware',
18
+ keywords: ['JWT', 'token', 'bearer', 'OAuth', 'session', 'login', 'credentials', 'refresh token', 'auth middleware', 'password hash'],
19
+ noiseKeywords: ['image resize', 'CSV export', 'color palette', 'PDF generation'],
20
+ },
21
+ {
22
+ id: 'caching',
23
+ label: 'Redis session caching',
24
+ keywords: ['Redis', 'cache hit', 'TTL', 'cache miss', 'eviction', 'Memcached', 'LRU', 'cache invalidation', 'pub/sub', 'cache layer'],
25
+ noiseKeywords: ['binary search', 'font rendering', 'timezone offset', 'audio codec'],
26
+ },
27
+ {
28
+ id: 'payments',
29
+ label: 'Stripe payment processing',
30
+ keywords: ['Stripe', 'webhook', 'idempotency key', 'refund', 'charge', 'payment intent', 'PCI compliance', 'subscription', 'invoice', 'billing'],
31
+ noiseKeywords: ['log rotation', 'dark mode', 'pagination cursor', 'queue priority'],
32
+ },
33
+ {
34
+ id: 'deployment',
35
+ label: 'Kubernetes deployment pipelines',
36
+ keywords: ['Kubernetes', 'Docker', 'Helm chart', 'rolling update', 'CI/CD', 'canary release', 'blue-green', 'container registry', 'pod scaling', 'ingress'],
37
+ noiseKeywords: ['regex pattern', 'fibonacci', 'color theory', 'mouse event'],
38
+ },
39
+ {
40
+ id: 'debugging',
41
+ label: 'Production debugging and tracing',
42
+ keywords: ['stack trace', 'breakpoint', 'profiler', 'memory leak', 'core dump', 'heap snapshot', 'distributed trace', 'OpenTelemetry', 'log correlation', 'flamegraph'],
43
+ noiseKeywords: ['gradient descent', 'user avatar', 'zip archive', 'SMS gateway'],
44
+ },
45
+ {
46
+ id: 'api_design',
47
+ label: 'REST and GraphQL API design',
48
+ keywords: ['REST', 'GraphQL', 'versioning', 'rate limiting', 'pagination', 'HATEOAS', 'OpenAPI', 'schema validation', 'endpoint', 'response format'],
49
+ noiseKeywords: ['pixel art', 'spreadsheet formula', 'hardware interrupt', 'color gradient'],
50
+ },
51
+ {
52
+ id: 'database',
53
+ label: 'PostgreSQL query optimization',
54
+ keywords: ['index', 'query plan', 'N+1 problem', 'connection pool', 'transaction', 'deadlock', 'explain analyze', 'vacuum', 'partition', 'materialized view'],
55
+ noiseKeywords: ['HTTP header', 'game physics', 'invoice template', 'drag and drop'],
56
+ },
57
+ {
58
+ id: 'testing',
59
+ label: 'Unit and integration testing strategies',
60
+ keywords: ['unit test', 'integration test', 'mock', 'stub', 'fixture', 'test coverage', 'assertion', 'snapshot test', 'test runner', 'property-based testing'],
61
+ noiseKeywords: ['grid layout', 'video encoding', 'microphone input', 'barcode scanner'],
62
+ },
63
+ {
64
+ id: 'monitoring',
65
+ label: 'Prometheus metrics and alerting',
66
+ keywords: ['Prometheus', 'Grafana', 'metric', 'alert', 'histogram', 'gauge', 'SLO', 'error rate', 'latency p99', 'on-call'],
67
+ noiseKeywords: ['emoji rendering', 'print stylesheet', 'GPS coordinate', 'Bluetooth pairing'],
68
+ },
69
+ {
70
+ id: 'security',
71
+ label: 'Application security and OWASP',
72
+ keywords: ['SQL injection', 'XSS', 'CSRF token', 'OWASP', 'input sanitization', 'TLS', 'secret rotation', 'vulnerability scan', 'penetration test', 'dependency audit'],
73
+ noiseKeywords: ['font loading', 'calendar widget', 'thumbnail generation', 'dark mode toggle'],
74
+ },
75
+ {
76
+ id: 'frontend',
77
+ label: 'React performance optimization',
78
+ keywords: ['React', 'virtual DOM', 'memo', 'useCallback', 'code splitting', 'lazy loading', 'bundle size', 'hydration', 'server components', 'suspense'],
79
+ noiseKeywords: ['batch processing', 'SSH tunnel', 'binary protocol', 'LDAP directory'],
80
+ },
81
+ {
82
+ id: 'mobile',
83
+ label: 'React Native and mobile development',
84
+ keywords: ['React Native', 'Expo', 'native module', 'push notification', 'offline mode', 'AsyncStorage', 'bridge', 'Hermes engine', 'deep link', 'app store'],
85
+ noiseKeywords: ['matrix multiplication', 'SQL join', 'log buffer', 'memory pool'],
86
+ },
87
+ {
88
+ id: 'data_pipeline',
89
+ label: 'ETL data pipeline architecture',
90
+ keywords: ['ETL', 'data pipeline', 'Airflow', 'Kafka', 'Spark', 'batch job', 'data lake', 'schema registry', 'partitioning', 'backfill'],
91
+ noiseKeywords: ['OAuth scopes', 'CSS animation', 'keyboard shortcut', 'tooltip position'],
92
+ },
93
+ {
94
+ id: 'ml',
95
+ label: 'Machine learning model serving',
96
+ keywords: ['model serving', 'inference', 'feature store', 'A/B test', 'shadow mode', 'ONNX', 'model drift', 'training pipeline', 'embedding vector', 'GPU batch'],
97
+ noiseKeywords: ['HTML table', 'file upload form', 'locale string', 'skeleton screen'],
98
+ },
99
+ {
100
+ id: 'messaging',
101
+ label: 'Message queue and event-driven architecture',
102
+ keywords: ['message queue', 'dead letter queue', 'consumer group', 'at-least-once', 'idempotent consumer', 'event sourcing', 'CQRS', 'saga pattern', 'outbox pattern', 'RabbitMQ'],
103
+ noiseKeywords: ['password strength', 'image cropping', 'column resize', 'date picker'],
104
+ },
105
+ {
106
+ id: 'search',
107
+ label: 'Elasticsearch full-text search indexing',
108
+ keywords: ['Elasticsearch', 'index mapping', 'analyzer', 'tokenizer', 'BM25', 'fuzzy match', 'aggregation', 'relevance scoring', 'search as you type', 'synonym'],
109
+ noiseKeywords: ['binary tree', 'network interface', 'GPU shader', 'SVG animation'],
110
+ },
111
+ {
112
+ id: 'file_storage',
113
+ label: 'S3 object storage and CDN',
114
+ keywords: ['S3', 'presigned URL', 'CDN', 'CloudFront', 'multipart upload', 'object lifecycle', 'bucket policy', 'signed cookie', 'CORS header', 'object versioning'],
115
+ noiseKeywords: ['unit conversion', 'form validation', 'context menu', 'map projection'],
116
+ },
117
+ {
118
+ id: 'notifications',
119
+ label: 'Push notifications and email delivery',
120
+ keywords: ['push notification', 'FCM', 'APNs', 'email delivery', 'SMTP', 'bounce handling', 'unsubscribe', 'notification template', 'webhook delivery', 'retry backoff'],
121
+ noiseKeywords: ['binary encoding', 'drag handle', 'chart tooltip', 'keyboard navigation'],
122
+ },
123
+ {
124
+ id: 'analytics',
125
+ label: 'Product analytics and event tracking',
126
+ keywords: ['event tracking', 'funnel analysis', 'cohort', 'session replay', 'heatmap', 'A/B experiment', 'conversion rate', 'retention', 'DAU', 'analytics pipeline'],
127
+ noiseKeywords: ['sprite sheet', 'HTTP/2 push', 'file locking', 'terminal emulator'],
128
+ },
129
+ {
130
+ id: 'config_mgmt',
131
+ label: 'Configuration management and feature flags',
132
+ keywords: ['feature flag', 'LaunchDarkly', 'environment variable', 'secrets manager', 'config reload', 'blue-green config', 'rollout percentage', 'kill switch', 'remote config', 'override'],
133
+ noiseKeywords: ['CSS grid', 'binary heap', 'audio visualization', 'handwriting recognition'],
134
+ },
135
+ ];
136
+ const SENTENCE_TEMPLATES = [
137
+ 'This document covers {topic} including {kw1} and {kw2}.',
138
+ 'When implementing {kw1}, consider how {kw2} interacts with your system.',
139
+ 'A common pattern for {topic} involves using {kw1} alongside {kw2}.',
140
+ 'The {kw1} approach helps teams manage {kw2} more effectively in production.',
141
+ 'Engineers often configure {kw1} to improve {kw2} reliability.',
142
+ 'Debugging {kw1} issues requires understanding the relationship with {kw2}.',
143
+ 'Best practices for {topic} recommend {kw1} as a foundational component.',
144
+ 'Teams adopting {kw1} frequently encounter {kw2} configuration challenges.',
145
+ ];
146
+ function pickOne(arr, rand) {
147
+ return arr[Math.floor(rand() * arr.length)];
148
+ }
149
+ function renderTemplate(template, topic, kw1, kw2) {
150
+ return template
151
+ .replace('{topic}', topic)
152
+ .replace('{kw1}', kw1)
153
+ .replace('{kw2}', kw2);
154
+ }
155
+ function generateDocBody(cluster, docIndex, rand) {
156
+ const sentences = [];
157
+ const sentenceCount = 4;
158
+ for (let i = 0; i < Math.ceil(sentenceCount * 0.8); i++) {
159
+ const tmpl = pickOne(SENTENCE_TEMPLATES, rand);
160
+ const kw1 = pickOne(cluster.keywords, rand);
161
+ const kw2 = pickOne(cluster.keywords.filter(k => k !== kw1), rand);
162
+ sentences.push(renderTemplate(tmpl, cluster.label, kw1, kw2));
163
+ }
164
+ const noiseSentences = Math.ceil(sentenceCount * 0.2);
165
+ for (let i = 0; i < noiseSentences; i++) {
166
+ const noiseKw = pickOne(cluster.noiseKeywords, rand);
167
+ sentences.push(`Additionally, note that ${noiseKw} may require separate consideration depending on your deployment context (doc-${docIndex}).`);
168
+ }
169
+ for (let i = sentences.length - 1; i > 0; i--) {
170
+ const j = Math.floor(rand() * (i + 1));
171
+ [sentences[i], sentences[j]] = [sentences[j], sentences[i]];
172
+ }
173
+ return sentences.join(' ');
174
+ }
175
+ const QUERIES_PER_TOPIC = {
176
+ auth: ['JWT authentication middleware token validation', 'OAuth session credentials bearer token'],
177
+ caching: ['Redis cache TTL eviction strategy', 'cache invalidation LRU Memcached'],
178
+ payments: ['Stripe payment webhook idempotency', 'billing subscription invoice refund'],
179
+ deployment: ['Kubernetes rolling update Helm chart', 'Docker CI/CD canary blue-green deployment'],
180
+ debugging: ['production debugging stack trace profiler', 'distributed tracing memory leak flamegraph'],
181
+ api_design: ['REST API versioning rate limiting', 'GraphQL schema OpenAPI pagination'],
182
+ database: ['PostgreSQL index query plan optimization', 'N+1 problem connection pool deadlock'],
183
+ testing: ['unit test mock integration fixture', 'test coverage snapshot property-based testing'],
184
+ monitoring: ['Prometheus metrics alerting histogram', 'Grafana SLO error rate latency p99'],
185
+ security: ['SQL injection XSS CSRF OWASP', 'TLS secret rotation vulnerability penetration test'],
186
+ frontend: ['React memo useCallback performance', 'code splitting lazy loading bundle hydration'],
187
+ mobile: ['React Native push notification offline', 'Expo deep link AsyncStorage Hermes'],
188
+ data_pipeline: ['ETL Airflow Kafka pipeline batch job', 'data lake schema registry partitioning backfill'],
189
+ ml: ['model serving inference feature store', 'ONNX model drift training embedding GPU'],
190
+ messaging: ['message queue dead letter consumer group', 'event sourcing CQRS outbox saga pattern'],
191
+ search: ['Elasticsearch BM25 index analyzer tokenizer', 'fuzzy match aggregation relevance scoring'],
192
+ file_storage: ['S3 presigned URL CDN multipart upload', 'bucket policy CORS object versioning lifecycle'],
193
+ notifications: ['push notification FCM APNs email delivery', 'SMTP bounce unsubscribe webhook retry'],
194
+ analytics: ['event tracking funnel cohort A/B experiment', 'session replay heatmap retention DAU'],
195
+ config_mgmt: ['feature flag LaunchDarkly rollout percentage', 'secrets manager config reload kill switch'],
196
+ };
197
+ export function computeCorpusHash(seed) {
198
+ const topicDefs = TOPIC_CLUSTERS.map(t => `${t.id}:${t.label}:${t.keywords.join(',')}`).join('|');
199
+ return crypto.createHash('sha256').update(`seed=${seed}|topics=${topicDefs}`).digest('hex');
200
+ }
201
+ export function generateCorpus(opts) {
202
+ const { scale, seed, outDir } = opts;
203
+ const rand = mulberry32(seed);
204
+ const topicCount = TOPIC_CLUSTERS.length;
205
+ const docsPerTopic = Math.max(1, Math.floor(scale / topicCount));
206
+ const docs = [];
207
+ const groundTruth = [];
208
+ for (const cluster of TOPIC_CLUSTERS) {
209
+ const clusterDocIds = [];
210
+ for (let i = 0; i < docsPerTopic; i++) {
211
+ const docId = `${cluster.id}-${String(i + 1).padStart(4, '0')}`;
212
+ const kw1 = pickOne(cluster.keywords, rand);
213
+ const title = `${cluster.label}: ${kw1} (${i + 1})`;
214
+ const body = generateDocBody(cluster, i, rand);
215
+ docs.push({ id: docId, topic: cluster.id, title, body });
216
+ clusterDocIds.push(docId);
217
+ }
218
+ const queries = QUERIES_PER_TOPIC[cluster.id] ?? [cluster.label];
219
+ for (const query of queries) {
220
+ groundTruth.push({
221
+ query,
222
+ topic: cluster.id,
223
+ relevant_doc_ids: [...clusterDocIds],
224
+ });
225
+ }
226
+ }
227
+ const corpusHash = computeCorpusHash(seed);
228
+ const meta = {
229
+ corpus_hash: corpusHash,
230
+ seed,
231
+ scale,
232
+ topic_count: topicCount,
233
+ docs_per_topic: docsPerTopic,
234
+ generated_at: new Date().toISOString(),
235
+ };
236
+ const docsDir = path.join(outDir, 'docs');
237
+ fs.mkdirSync(docsDir, { recursive: true });
238
+ for (const doc of docs) {
239
+ const docPath = path.join(docsDir, `${doc.id}.md`);
240
+ const content = `# ${doc.title}\n\n${doc.body}\n`;
241
+ fs.writeFileSync(docPath, content, 'utf-8');
242
+ }
243
+ fs.writeFileSync(path.join(outDir, 'ground-truth.json'), JSON.stringify(groundTruth, null, 2), 'utf-8');
244
+ fs.writeFileSync(path.join(outDir, 'corpus.json'), JSON.stringify(meta, null, 2), 'utf-8');
245
+ console.log(`Generated ${docs.length} docs across ${topicCount} topics → ${outDir}`);
246
+ console.log(`corpus_hash: ${corpusHash}`);
247
+ }
248
+ export { TOPIC_CLUSTERS };
249
+ //# sourceMappingURL=generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/bench/generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { GlobalOptions } from '../cli/types.js';
2
+ export declare function handleBenchSuite(_globalOpts: GlobalOptions, args: string[]): Promise<void>;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bench/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAkBrD,wBAAsB,gBAAgB,CAAC,WAAW,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBhG"}
@@ -0,0 +1,134 @@
1
+ import * as path from 'path';
2
+ import { generateCorpus } from './generator.js';
3
+ import { runBenchmarkSuite } from './runner.js';
4
+ import { runCompare } from './compare.js';
5
+ const REPO_ROOT = new URL('../../', import.meta.url).pathname;
6
+ const DEFAULT_FIXTURES_DIR = path.join(REPO_ROOT, 'benchmarks', 'fixtures');
7
+ const DEFAULT_RESULTS_DIR = path.join(REPO_ROOT, 'benchmarks', 'results');
8
+ const VALID_SCALES = [100, 1000, 5000, 10000, 100000];
9
+ function parseScales(raw) {
10
+ return raw.split(',').map(s => {
11
+ const n = parseInt(s.trim(), 10);
12
+ if (!VALID_SCALES.includes(n)) {
13
+ console.error(`Invalid scale: ${n}. Valid: ${VALID_SCALES.join(', ')}`);
14
+ process.exit(1);
15
+ }
16
+ return n;
17
+ });
18
+ }
19
+ export async function handleBenchSuite(_globalOpts, args) {
20
+ const subcommand = args[0];
21
+ const subArgs = args.slice(1);
22
+ switch (subcommand) {
23
+ case 'generate':
24
+ return handleGenerate(subArgs);
25
+ case 'run':
26
+ return handleRun(subArgs);
27
+ case 'compare':
28
+ return handleCompare(subArgs);
29
+ default:
30
+ console.error(`Unknown bench subcommand: ${subcommand}`);
31
+ console.error('Usage: nano-brain bench <generate|run|compare> [options]');
32
+ process.exit(1);
33
+ }
34
+ }
35
+ function handleGenerate(args) {
36
+ let scale = 100;
37
+ let seed = 42;
38
+ let outDir = DEFAULT_FIXTURES_DIR;
39
+ let outExplicit = false;
40
+ for (let i = 0; i < args.length; i++) {
41
+ const arg = args[i];
42
+ if (arg.startsWith('--scale=')) {
43
+ scale = parseInt(arg.substring(8), 10);
44
+ }
45
+ else if (arg === '--scale' && i + 1 < args.length) {
46
+ scale = parseInt(args[++i], 10);
47
+ }
48
+ else if (arg.startsWith('--seed=')) {
49
+ seed = parseInt(arg.substring(7), 10);
50
+ }
51
+ else if (arg === '--seed' && i + 1 < args.length) {
52
+ seed = parseInt(args[++i], 10);
53
+ }
54
+ else if (arg.startsWith('--out=')) {
55
+ outDir = arg.substring(6);
56
+ outExplicit = true;
57
+ }
58
+ else if (arg === '--out' && i + 1 < args.length) {
59
+ outDir = args[++i];
60
+ outExplicit = true;
61
+ }
62
+ }
63
+ if (!VALID_SCALES.includes(scale)) {
64
+ console.error(`Invalid scale: ${scale}. Valid scales: ${VALID_SCALES.join(', ')}`);
65
+ process.exit(1);
66
+ }
67
+ // When --out is explicitly set, treat it as the final output dir.
68
+ // When using the default fixtures dir, append scale-N for organisation.
69
+ const scaleDir = outExplicit ? outDir : path.join(outDir, `scale-${scale}`);
70
+ generateCorpus({ scale, seed, outDir: scaleDir });
71
+ }
72
+ async function handleRun(args) {
73
+ let scales = [100];
74
+ let noCleanup = false;
75
+ let seed = 42;
76
+ let fixturesDir = DEFAULT_FIXTURES_DIR;
77
+ let resultsDir = DEFAULT_RESULTS_DIR;
78
+ for (let i = 0; i < args.length; i++) {
79
+ const arg = args[i];
80
+ if (arg.startsWith('--scale=')) {
81
+ scales = parseScales(arg.substring(8));
82
+ }
83
+ else if (arg === '--scale' && i + 1 < args.length) {
84
+ scales = parseScales(args[++i]);
85
+ }
86
+ else if (arg === '--no-cleanup') {
87
+ noCleanup = true;
88
+ }
89
+ else if (arg.startsWith('--seed=')) {
90
+ seed = parseInt(arg.substring(7), 10);
91
+ }
92
+ else if (arg === '--seed' && i + 1 < args.length) {
93
+ seed = parseInt(args[++i], 10);
94
+ }
95
+ else if (arg.startsWith('--fixtures=')) {
96
+ fixturesDir = arg.substring(11);
97
+ }
98
+ else if (arg.startsWith('--results=')) {
99
+ resultsDir = arg.substring(10);
100
+ }
101
+ }
102
+ await runBenchmarkSuite({ scales, noCleanup, fixturesBaseDir: fixturesDir, resultsDir, seed });
103
+ }
104
+ function handleCompare(args) {
105
+ let resultPath = '';
106
+ let baselinePath = '';
107
+ let savePath;
108
+ let force = false;
109
+ for (let i = 0; i < args.length; i++) {
110
+ const arg = args[i];
111
+ if (arg.startsWith('--save=')) {
112
+ savePath = arg.substring(7);
113
+ }
114
+ else if (arg === '--save' && i + 1 < args.length) {
115
+ savePath = args[++i];
116
+ }
117
+ else if (arg === '--force') {
118
+ force = true;
119
+ }
120
+ else if (!resultPath) {
121
+ resultPath = arg;
122
+ }
123
+ else if (!baselinePath) {
124
+ baselinePath = arg;
125
+ }
126
+ }
127
+ if (!resultPath || !baselinePath) {
128
+ console.error('Usage: nano-brain bench compare <result.json> <baseline.json> [--save <path>] [--force]');
129
+ process.exit(1);
130
+ }
131
+ const exitCode = runCompare({ resultPath, baselinePath, savePath, force });
132
+ process.exit(exitCode);
133
+ }
134
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/bench/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { BenchResult } from './types.js';
2
+ export interface RunOptions {
3
+ scales: number[];
4
+ noCleanup: boolean;
5
+ fixturesBaseDir: string;
6
+ resultsDir: string;
7
+ seed: number;
8
+ }
9
+ export declare function runBenchmarkSuite(opts: RunOptions): Promise<BenchResult>;
10
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/bench/runner.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,WAAW,EAYZ,MAAM,YAAY,CAAC;AAuVpB,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAyH9E"}