monomind 1.18.9 → 1.18.10

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 (46) hide show
  1. package/package.json +1 -1
  2. package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.d.ts +1 -2
  3. package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.js +1 -2
  4. package/packages/@monomind/cli/dist/src/commands/hooks-coverage-gaps.d.ts +1 -2
  5. package/packages/@monomind/cli/dist/src/commands/hooks-coverage-gaps.js +2 -117
  6. package/packages/@monomind/cli/dist/src/commands/hooks.js +1 -2
  7. package/packages/@monomind/cli/dist/src/commands/index.d.ts +0 -1
  8. package/packages/@monomind/cli/dist/src/commands/index.js +0 -1
  9. package/packages/@monomind/cli/dist/src/init/executor.d.ts +3 -0
  10. package/packages/@monomind/cli/dist/src/init/executor.js +20 -111
  11. package/packages/@monomind/cli/dist/src/mcp-client.js +0 -2
  12. package/packages/@monomind/cli/dist/src/mcp-tools/index.d.ts +0 -1
  13. package/packages/@monomind/cli/dist/src/mcp-tools/index.js +0 -1
  14. package/packages/@monomind/cli/dist/src/mcp-tools/quality/coverage-analysis/track-trends.d.ts +4 -4
  15. package/packages/@monomind/cli/dist/src/mcp-tools/quality/test-generation/suggest-tests.d.ts +4 -4
  16. package/packages/@monomind/cli/package.json +1 -1
  17. package/packages/@monomind/cli/dist/src/benchmarks/benchmark-runner.d.ts +0 -134
  18. package/packages/@monomind/cli/dist/src/benchmarks/benchmark-runner.js +0 -340
  19. package/packages/@monomind/cli/dist/src/benchmarks/metric-evaluators.d.ts +0 -36
  20. package/packages/@monomind/cli/dist/src/benchmarks/metric-evaluators.js +0 -125
  21. package/packages/@monomind/cli/dist/src/commands/benchmark.d.ts +0 -10
  22. package/packages/@monomind/cli/dist/src/commands/benchmark.js +0 -586
  23. package/packages/@monomind/cli/dist/src/commands/migrate.d.ts +0 -8
  24. package/packages/@monomind/cli/dist/src/commands/migrate.js +0 -789
  25. package/packages/@monomind/cli/dist/src/commands/monovector/backup.d.ts +0 -11
  26. package/packages/@monomind/cli/dist/src/commands/monovector/backup.js +0 -752
  27. package/packages/@monomind/cli/dist/src/commands/monovector/benchmark.d.ts +0 -11
  28. package/packages/@monomind/cli/dist/src/commands/monovector/benchmark.js +0 -502
  29. package/packages/@monomind/cli/dist/src/commands/monovector/import.d.ts +0 -18
  30. package/packages/@monomind/cli/dist/src/commands/monovector/import.js +0 -374
  31. package/packages/@monomind/cli/dist/src/commands/monovector/index.d.ts +0 -29
  32. package/packages/@monomind/cli/dist/src/commands/monovector/index.js +0 -129
  33. package/packages/@monomind/cli/dist/src/commands/monovector/init.d.ts +0 -11
  34. package/packages/@monomind/cli/dist/src/commands/monovector/init.js +0 -481
  35. package/packages/@monomind/cli/dist/src/commands/monovector/migrate.d.ts +0 -11
  36. package/packages/@monomind/cli/dist/src/commands/monovector/migrate.js +0 -500
  37. package/packages/@monomind/cli/dist/src/commands/monovector/optimize.d.ts +0 -11
  38. package/packages/@monomind/cli/dist/src/commands/monovector/optimize.js +0 -515
  39. package/packages/@monomind/cli/dist/src/commands/monovector/setup.d.ts +0 -18
  40. package/packages/@monomind/cli/dist/src/commands/monovector/setup.js +0 -775
  41. package/packages/@monomind/cli/dist/src/commands/monovector/status.d.ts +0 -11
  42. package/packages/@monomind/cli/dist/src/commands/monovector/status.js +0 -491
  43. package/packages/@monomind/cli/dist/src/commands/progress.d.ts +0 -11
  44. package/packages/@monomind/cli/dist/src/commands/progress.js +0 -261
  45. package/packages/@monomind/cli/dist/src/mcp-tools/progress-tools.d.ts +0 -14
  46. package/packages/@monomind/cli/dist/src/mcp-tools/progress-tools.js +0 -353
@@ -1,340 +0,0 @@
1
- /**
2
- * Benchmark Runner for Regression Testing (Task 34)
3
- * Loads benchmark definitions, evaluates quality metrics, and detects regressions.
4
- */
5
- import * as fs from 'fs';
6
- import * as path from 'path';
7
- import { randomUUID } from 'crypto';
8
- import { containsExpected, lengthRange, noHallucination, jsonValid, customRegex, } from './metric-evaluators.js';
9
- export class BenchmarkRunner {
10
- baselines = new Map();
11
- /**
12
- * Load benchmark definitions from JSON files in a directory.
13
- * Each JSON file should contain a single BenchmarkDefinition or an array of them.
14
- */
15
- loadBenchmarks(dir) {
16
- const benchmarks = [];
17
- // Safe-root constraint: reject any path that escapes the working directory
18
- const safeRoot = path.resolve(process.cwd());
19
- const resolved = path.resolve(dir);
20
- const rel = path.relative(safeRoot, resolved);
21
- if (rel.startsWith('..') || path.isAbsolute(rel))
22
- return [];
23
- if (!fs.existsSync(resolved)) {
24
- return benchmarks;
25
- }
26
- const MAX_BENCH_FILE_SIZE = 1 * 1024 * 1024; // 1 MB per benchmark file
27
- const files = fs.readdirSync(resolved).filter((f) => f.endsWith('.json'));
28
- for (const file of files) {
29
- const filePath = path.join(resolved, file);
30
- // Guard against OOM: reject symlinks and oversized files before reading
31
- let stat;
32
- try {
33
- stat = fs.lstatSync(filePath);
34
- }
35
- catch {
36
- continue;
37
- }
38
- if (stat.isSymbolicLink())
39
- continue;
40
- if (stat.size > MAX_BENCH_FILE_SIZE)
41
- continue;
42
- const raw = fs.readFileSync(filePath, 'utf-8');
43
- try {
44
- const parsed = JSON.parse(raw);
45
- if (Array.isArray(parsed)) {
46
- benchmarks.push(...parsed);
47
- }
48
- else {
49
- benchmarks.push(parsed);
50
- }
51
- }
52
- catch {
53
- // skip malformed file
54
- continue;
55
- }
56
- }
57
- return benchmarks;
58
- }
59
- /**
60
- * Evaluate quality metrics against an output string.
61
- */
62
- evaluateMetrics(output, metrics) {
63
- return metrics.map((metric) => this.evaluateSingleMetric(output, metric));
64
- }
65
- /**
66
- * Run a single benchmark against provided agent output.
67
- */
68
- runBenchmark(def, agentOutput) {
69
- const startTime = Date.now();
70
- const metricResults = this.evaluateMetrics(agentOutput, def.qualityMetrics);
71
- const durationMs = Date.now() - startTime;
72
- const passed = metricResults.every((r) => r.passed);
73
- return {
74
- benchmarkId: def.benchmarkId,
75
- runId: randomUUID(),
76
- agentSlug: def.agentSlug,
77
- passed,
78
- metricResults,
79
- runAt: new Date().toISOString(),
80
- durationMs,
81
- };
82
- }
83
- /**
84
- * Pin current results as the baseline for a benchmark.
85
- */
86
- pinBaseline(benchmarkId, results) {
87
- const relevantResults = results.filter((r) => r.benchmarkId === benchmarkId);
88
- if (relevantResults.length === 0) {
89
- const baseline = {
90
- pinnedAt: new Date().toISOString(),
91
- passRate: 0,
92
- avgDurationMs: 0,
93
- };
94
- this.baselines.set(benchmarkId, baseline);
95
- return baseline;
96
- }
97
- const passCount = relevantResults.filter((r) => r.passed).length;
98
- const passRate = passCount / relevantResults.length;
99
- const avgDurationMs = relevantResults.reduce((sum, r) => sum + r.durationMs, 0) /
100
- relevantResults.length;
101
- const baseline = {
102
- pinnedAt: new Date().toISOString(),
103
- passRate,
104
- avgDurationMs,
105
- };
106
- this.baselines.set(benchmarkId, baseline);
107
- return baseline;
108
- }
109
- /**
110
- * Detect regression by comparing current results against a baseline.
111
- * Returns true if the current pass rate is strictly below the baseline pass rate.
112
- */
113
- detectRegression(current, baseline) {
114
- if (current.length === 0) {
115
- return false;
116
- }
117
- const passCount = current.filter((r) => r.passed).length;
118
- const currentPassRate = passCount / current.length;
119
- return currentPassRate < baseline.passRate;
120
- }
121
- /**
122
- * Get a stored baseline by benchmark ID.
123
- */
124
- getBaseline(benchmarkId) {
125
- return this.baselines.get(benchmarkId);
126
- }
127
- // ------------------------------------------------------------------
128
- // Private helpers
129
- // ------------------------------------------------------------------
130
- evaluateSingleMetric(output, metric) {
131
- switch (metric.type) {
132
- case 'contains_expected':
133
- return containsExpected(output, metric.config);
134
- case 'length_range':
135
- return lengthRange(output, metric.config);
136
- case 'no_hallucination':
137
- return noHallucination(output, metric.config);
138
- case 'json_valid':
139
- return jsonValid(output);
140
- case 'custom_regex':
141
- return customRegex(output, metric.config);
142
- default:
143
- return {
144
- type: metric.type,
145
- passed: false,
146
- actual: null,
147
- expected: null,
148
- message: `Unknown metric type: ${metric.type}`,
149
- };
150
- }
151
- }
152
- }
153
- // ------------------------------------------------------------------
154
- // Default benchmark suite (5 coordination task types)
155
- // ------------------------------------------------------------------
156
- /** Pursuit — agents must collectively report a common target string. */
157
- const pursuitTask = {
158
- id: 'swarm-pursuit-01',
159
- type: 'pursuit',
160
- description: 'All agents converge on and name the same moving target within the step budget',
161
- agentCount: 4,
162
- stepBudget: 10,
163
- evaluate(agentOutputs) {
164
- const target = 'TARGET_FOUND';
165
- const hits = agentOutputs.filter((o) => o.includes(target)).length;
166
- const score = agentOutputs.length > 0 ? hits / agentOutputs.length : 0;
167
- return {
168
- taskId: this.id,
169
- type: this.type,
170
- passed: score >= 0.75,
171
- score,
172
- stepsTaken: 1,
173
- agentCount: agentOutputs.length,
174
- details: `${hits}/${agentOutputs.length} agents converged`,
175
- };
176
- },
177
- };
178
- /** Synchronization — all agents must emit the same token at the same logical step. */
179
- const synchronizationTask = {
180
- id: 'swarm-sync-01',
181
- type: 'synchronization',
182
- description: 'Agents reach consensus on a shared value simultaneously without direct communication',
183
- agentCount: 6,
184
- stepBudget: 5,
185
- evaluate(agentOutputs) {
186
- if (agentOutputs.length === 0)
187
- return {
188
- taskId: this.id,
189
- type: this.type,
190
- passed: false,
191
- score: 0,
192
- stepsTaken: 0,
193
- agentCount: 0,
194
- details: 'no outputs',
195
- };
196
- const counts = new Map();
197
- for (const o of agentOutputs) {
198
- const tok = o.trim().split(/\s+/)[0] ?? '';
199
- counts.set(tok, (counts.get(tok) ?? 0) + 1);
200
- }
201
- const maxAgree = Math.max(...counts.values());
202
- const score = maxAgree / agentOutputs.length;
203
- return {
204
- taskId: this.id,
205
- type: this.type,
206
- passed: score >= 0.8,
207
- score,
208
- stepsTaken: 1,
209
- agentCount: agentOutputs.length,
210
- details: `majority agreement: ${(score * 100).toFixed(0)}%`,
211
- };
212
- },
213
- };
214
- /** Foraging — agents must collectively mention ≥ N distinct resources. */
215
- const foragingTask = {
216
- id: 'swarm-forage-01',
217
- type: 'foraging',
218
- description: 'Agents distribute to discover and collect distinct resources from the environment',
219
- agentCount: 5,
220
- stepBudget: 15,
221
- evaluate(agentOutputs) {
222
- const resourcePattern = /RESOURCE_[A-Z]+/g;
223
- const found = new Set();
224
- for (const o of agentOutputs) {
225
- for (const m of o.matchAll(resourcePattern))
226
- found.add(m[0]);
227
- }
228
- const goal = 4;
229
- const score = Math.min(1, found.size / goal);
230
- return {
231
- taskId: this.id,
232
- type: this.type,
233
- passed: found.size >= goal,
234
- score,
235
- stepsTaken: 1,
236
- agentCount: agentOutputs.length,
237
- details: `${found.size}/${goal} resources found: ${[...found].join(', ')}`,
238
- };
239
- },
240
- };
241
- /** Flocking — each agent must maintain formation by referencing its neighbour. */
242
- const flockingTask = {
243
- id: 'swarm-flock-01',
244
- type: 'flocking',
245
- description: 'Agents maintain cohesion and alignment while navigating toward a goal',
246
- agentCount: 8,
247
- stepBudget: 20,
248
- evaluate(agentOutputs) {
249
- const cohesionKeyword = 'NEIGHBOUR_OK';
250
- const aligned = agentOutputs.filter((o) => o.includes(cohesionKeyword)).length;
251
- const score = agentOutputs.length > 0 ? aligned / agentOutputs.length : 0;
252
- return {
253
- taskId: this.id,
254
- type: this.type,
255
- passed: score >= 0.7,
256
- score,
257
- stepsTaken: 1,
258
- agentCount: agentOutputs.length,
259
- details: `${aligned}/${agentOutputs.length} in formation`,
260
- };
261
- },
262
- };
263
- /** Transport — item must appear in successive agent outputs showing relay progress. */
264
- const transportTask = {
265
- id: 'swarm-transport-01',
266
- type: 'transport',
267
- description: 'Agents relay a payload across a chain; payload must appear in last agent output',
268
- agentCount: 4,
269
- stepBudget: 8,
270
- evaluate(agentOutputs) {
271
- const payload = 'PAYLOAD_DELIVERED';
272
- const lastAgentDelivered = agentOutputs.length > 0 && agentOutputs[agentOutputs.length - 1].includes(payload);
273
- const relayCount = agentOutputs.filter((o) => o.includes('RELAY')).length;
274
- const score = lastAgentDelivered ? 1 : relayCount / Math.max(agentOutputs.length, 1);
275
- return {
276
- taskId: this.id,
277
- type: this.type,
278
- passed: lastAgentDelivered,
279
- score,
280
- stepsTaken: agentOutputs.length,
281
- agentCount: agentOutputs.length,
282
- details: lastAgentDelivered
283
- ? 'payload delivered'
284
- : `relay progress: ${relayCount}/${agentOutputs.length}`,
285
- };
286
- },
287
- };
288
- export const SWARM_BENCH_TASKS = [
289
- pursuitTask,
290
- synchronizationTask,
291
- foragingTask,
292
- flockingTask,
293
- transportTask,
294
- ];
295
- /**
296
- * Alias for {@link SWARM_BENCH_TASKS}. Kept for ergonomic imports.
297
- */
298
- export const SWARM = SWARM_BENCH_TASKS;
299
- /**
300
- * SwarmBenchRunner — runs the 5 SwarmBench coordination task types.
301
- * Wraps BenchmarkRunner for regression baseline tracking.
302
- *
303
- * Source: https://arxiv.org/abs/2505.04364
304
- */
305
- export class SwarmBenchRunner {
306
- inner = new BenchmarkRunner();
307
- baselines = new Map();
308
- /** Run all (or a subset of) SwarmBench tasks against simulated agent outputs. */
309
- runAll(agentOutputsByTask) {
310
- return SWARM_BENCH_TASKS.map((task) => {
311
- const outputs = agentOutputsByTask.get(task.id) ?? [];
312
- return task.evaluate(outputs);
313
- });
314
- }
315
- /** Run a single task type by id. */
316
- runTask(taskId, agentOutputs) {
317
- const task = SWARM_BENCH_TASKS.find((t) => t.id === taskId);
318
- return task?.evaluate(agentOutputs);
319
- }
320
- /** Pin current results as the regression baseline. */
321
- pinBaseline(results) {
322
- for (const r of results) {
323
- this.baselines.set(r.taskId, r);
324
- }
325
- }
326
- /** Detect regression: returns task IDs whose score dropped below baseline. */
327
- detectRegressions(current) {
328
- return current
329
- .filter((r) => {
330
- const baseline = this.baselines.get(r.taskId);
331
- return baseline !== undefined && r.score < baseline.score;
332
- })
333
- .map((r) => r.taskId);
334
- }
335
- /** Expose underlying BenchmarkRunner for general benchmarks. */
336
- get benchmarkRunner() {
337
- return this.inner;
338
- }
339
- }
340
- //# sourceMappingURL=benchmark-runner.js.map
@@ -1,36 +0,0 @@
1
- /**
2
- * Metric Evaluators for Benchmark Runner (Task 34)
3
- * Individual metric evaluation functions for quality assessment.
4
- */
5
- type MetricResult = any;
6
- /**
7
- * Checks whether the output contains the expected substring.
8
- */
9
- export declare function containsExpected(output: string, config: {
10
- expected: string;
11
- }): MetricResult;
12
- /**
13
- * Checks whether the output length falls within the specified range.
14
- */
15
- export declare function lengthRange(output: string, config: {
16
- min: number;
17
- max: number;
18
- }): MetricResult;
19
- /**
20
- * Checks that the output does not contain any forbidden words (hallucination markers).
21
- */
22
- export declare function noHallucination(output: string, config: {
23
- forbidden: string[];
24
- }): MetricResult;
25
- /**
26
- * Checks whether the output is valid JSON.
27
- */
28
- export declare function jsonValid(output: string): MetricResult;
29
- /**
30
- * Checks whether the output matches a custom regex pattern.
31
- */
32
- export declare function customRegex(output: string, config: {
33
- pattern: string;
34
- }): MetricResult;
35
- export {};
36
- //# sourceMappingURL=metric-evaluators.d.ts.map
@@ -1,125 +0,0 @@
1
- /**
2
- * Metric Evaluators for Benchmark Runner (Task 34)
3
- * Individual metric evaluation functions for quality assessment.
4
- */
5
- /**
6
- * Checks whether the output contains the expected substring.
7
- */
8
- export function containsExpected(output, config) {
9
- // Cap expected to prevent huge strings from inflating returned objects
10
- const expected = typeof config.expected === 'string' ? config.expected.slice(0, 200) : '';
11
- const found = output.includes(expected);
12
- return {
13
- type: 'contains_expected',
14
- passed: found,
15
- actual: found ? expected : null,
16
- expected,
17
- message: found
18
- ? `Output contains expected string "${expected}"`
19
- : `Output missing expected string "${expected}"`,
20
- };
21
- }
22
- /**
23
- * Checks whether the output length falls within the specified range.
24
- */
25
- export function lengthRange(output, config) {
26
- const len = output.length;
27
- const passed = len >= config.min && len <= config.max;
28
- return {
29
- type: 'length_range',
30
- passed,
31
- actual: len,
32
- expected: { min: config.min, max: config.max },
33
- message: passed
34
- ? `Output length ${len} within range [${config.min}, ${config.max}]`
35
- : `Output length ${len} outside range [${config.min}, ${config.max}]`,
36
- };
37
- }
38
- /**
39
- * Checks that the output does not contain any forbidden words (hallucination markers).
40
- */
41
- export function noHallucination(output, config) {
42
- const lowerOutput = output.toLowerCase();
43
- // Cap forbidden array to 200 entries to prevent unbounded O(n) scan
44
- const forbidden = Array.isArray(config.forbidden) ? config.forbidden.slice(0, 200) : [];
45
- const found = forbidden.filter((word) => typeof word === 'string' && lowerOutput.includes(word.toLowerCase()));
46
- const passed = found.length === 0;
47
- // Truncate reflected words to avoid inflated messages
48
- const truncatedFound = found.map((w) => w.slice(0, 50));
49
- return {
50
- type: 'no_hallucination',
51
- passed,
52
- actual: found.length > 0 ? truncatedFound : null,
53
- expected: null,
54
- message: passed
55
- ? 'No forbidden words found in output'
56
- : `Forbidden words found: ${truncatedFound.join(', ')}`,
57
- };
58
- }
59
- /**
60
- * Checks whether the output is valid JSON.
61
- */
62
- export function jsonValid(output) {
63
- let passed = false;
64
- let parsedType = null;
65
- // Cap output before JSON.parse to prevent OOM on huge strings
66
- const MAX_JSON_BYTES = 1 * 1024 * 1024; // 1 MB
67
- const bounded = typeof output === 'string' && output.length > MAX_JSON_BYTES
68
- ? output.slice(0, MAX_JSON_BYTES)
69
- : output;
70
- try {
71
- const parsed = JSON.parse(bounded);
72
- passed = true;
73
- parsedType = typeof parsed;
74
- }
75
- catch {
76
- // not valid JSON
77
- }
78
- return {
79
- type: 'json_valid',
80
- passed,
81
- actual: passed ? parsedType : 'invalid',
82
- expected: 'valid JSON',
83
- message: passed ? 'Output is valid JSON' : 'Output is not valid JSON',
84
- };
85
- }
86
- /**
87
- * Checks whether the output matches a custom regex pattern.
88
- */
89
- export function customRegex(output, config) {
90
- // Reject overly long patterns and those with nested/repeated quantifiers
91
- // (catastrophic backtracking — a malicious benchmark definition could
92
- // pin CI runners with `^(a+)+$` against a long output string).
93
- if (typeof config.pattern !== 'string' || config.pattern.length > 200) {
94
- return {
95
- type: 'custom_regex',
96
- passed: false,
97
- actual: null,
98
- expected: config.pattern,
99
- message: 'Pattern rejected: too long or invalid',
100
- };
101
- }
102
- if (/(\(.*[+*?].*\)|[+*?]){2,}|\{[0-9,]+\}.*[+*?]|\([^)]*\|[^)]*\)[+*?{]/.test(config.pattern)) {
103
- return {
104
- type: 'custom_regex',
105
- passed: false,
106
- actual: null,
107
- expected: config.pattern,
108
- message: 'Pattern rejected: nested quantifiers risk catastrophic backtracking',
109
- };
110
- }
111
- // Cap output length so even slow patterns can't burn unlimited CPU
112
- const boundedOutput = output.length > 1024 * 1024 ? output.slice(0, 1024 * 1024) : output;
113
- const regex = new RegExp(config.pattern);
114
- const match = regex.test(boundedOutput);
115
- return {
116
- type: 'custom_regex',
117
- passed: match,
118
- actual: match ? boundedOutput.match(regex)?.[0] ?? null : null,
119
- expected: config.pattern,
120
- message: match
121
- ? `Output matches pattern /${config.pattern}/`
122
- : `Output does not match pattern /${config.pattern}/`,
123
- };
124
- }
125
- //# sourceMappingURL=metric-evaluators.js.map
@@ -1,10 +0,0 @@
1
- /**
2
- * CLI Benchmark Command
3
- * Comprehensive benchmarking for self-learning, pre-training, and neural systems
4
- *
5
- * @module v1/cli/commands/benchmark
6
- */
7
- import type { Command } from '../types.js';
8
- export declare const benchmarkCommand: Command;
9
- export default benchmarkCommand;
10
- //# sourceMappingURL=benchmark.d.ts.map