monomind 1.16.2 → 1.16.4
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.
- package/package.json +1 -1
- package/packages/@monomind/cli/dist/src/commands/daemon.js +5 -1
- package/packages/@monomind/cli/dist/src/commands/doctor.js +6 -48
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.js +1 -1
- package/packages/@monomind/cli/dist/src/commands/hooks-extended-commands.js +8 -45
- package/packages/@monomind/cli/dist/src/init/executor.js +2 -5
- package/packages/@monomind/cli/dist/src/init/settings-generator.js +11 -5
- package/packages/@monomind/cli/dist/src/init/statusline-generator.js +12 -7
- package/packages/@monomind/cli/dist/src/mcp-server.js +1 -1
- package/packages/@monomind/cli/dist/src/mcp-tools/daa-tools.js +5 -4
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-intelligence.js +15 -13
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-routing.js +72 -77
- package/packages/@monomind/cli/dist/src/mcp-tools/memory-tools.js +21 -18
- package/packages/@monomind/cli/dist/src/mcp-tools/neural-tools.d.ts +2 -2
- package/packages/@monomind/cli/dist/src/mcp-tools/neural-tools.js +18 -9
- package/packages/@monomind/cli/dist/src/memory/embedding-operations.js +2 -39
- package/packages/@monomind/cli/dist/src/memory/hnsw-operations.js +0 -14
- package/packages/@monomind/cli/dist/src/memory/memory-crud.js +1 -1
- package/packages/@monomind/cli/dist/src/memory/memory-initializer.js +0 -2
- package/packages/@monomind/cli/dist/src/memory/memory-read.js +10 -1
- package/packages/@monomind/cli/package.json +1 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "monomind",
|
|
3
|
-
"version": "1.16.
|
|
3
|
+
"version": "1.16.4",
|
|
4
4
|
"description": "Monomind - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -213,7 +213,11 @@ async function startBackgroundDaemon(projectRoot, quiet, maxCpuLoad, minFreeMemo
|
|
|
213
213
|
const __dirname = dirname(__filename);
|
|
214
214
|
// dist/src/commands -> dist/src -> dist -> package root -> bin/cli.js
|
|
215
215
|
const cliPath = resolve(join(__dirname, '..', '..', '..', 'bin', 'cli.js'));
|
|
216
|
-
|
|
216
|
+
// monolean: CLI may be in global npm install (different drive on Windows) — only
|
|
217
|
+
// check for injection, not directory containment
|
|
218
|
+
if (cliPath.includes('\0') || /[;&|`$<>]/.test(cliPath)) {
|
|
219
|
+
throw new Error('CLI path contains invalid characters');
|
|
220
|
+
}
|
|
217
221
|
// Verify CLI path exists
|
|
218
222
|
if (!fs.existsSync(cliPath)) {
|
|
219
223
|
output.printError(`CLI not found at: ${cliPath}`);
|
|
@@ -186,7 +186,11 @@ async function checkMcpServers() {
|
|
|
186
186
|
const mcpConfigPaths = [
|
|
187
187
|
join(homedir(), '.claude/claude_desktop_config.json'),
|
|
188
188
|
join(homedir(), '.config/claude/mcp.json'),
|
|
189
|
-
'.mcp.json'
|
|
189
|
+
'.mcp.json',
|
|
190
|
+
// Claude Code local/project scope stores MCP servers in settings files
|
|
191
|
+
'.claude/settings.json',
|
|
192
|
+
'.claude/settings.local.json',
|
|
193
|
+
join(homedir(), '.claude/settings.json'),
|
|
190
194
|
];
|
|
191
195
|
for (const configPath of mcpConfigPaths) {
|
|
192
196
|
if (existsSync(configPath) && statSync(configPath).size <= MAX_DOCTOR_CONFIG_BYTES) {
|
|
@@ -550,7 +554,6 @@ async function checkMonoesMemory() {
|
|
|
550
554
|
return { name: 'Vector Memory', status: 'warn', message: 'Vector memory check failed' };
|
|
551
555
|
}
|
|
552
556
|
}
|
|
553
|
-
// Check agentic-flow v1 integration (filesystem-based to avoid slow WASM/DB init)
|
|
554
557
|
// Resolve the path to the bundled (npm-installed) copy of a helper file.
|
|
555
558
|
// Walks up from this module's location to find the package root, then joins
|
|
556
559
|
// the relative path. Returns null if not found.
|
|
@@ -635,49 +638,6 @@ async function checkHelpersFresh() {
|
|
|
635
638
|
return { name: 'Helper Files', status: 'warn', message: `check failed: ${e instanceof Error ? e.message : 'unknown'}` };
|
|
636
639
|
}
|
|
637
640
|
}
|
|
638
|
-
async function checkAgenticFlow() {
|
|
639
|
-
try {
|
|
640
|
-
// Walk common node_modules paths to find agentic-flow/package.json
|
|
641
|
-
const candidates = [
|
|
642
|
-
join(process.cwd(), 'node_modules', 'agentic-flow', 'package.json'),
|
|
643
|
-
join(process.cwd(), '..', 'node_modules', 'agentic-flow', 'package.json'),
|
|
644
|
-
];
|
|
645
|
-
let pkgJsonPath = null;
|
|
646
|
-
for (const p of candidates) {
|
|
647
|
-
if (existsSync(p)) {
|
|
648
|
-
pkgJsonPath = p;
|
|
649
|
-
break;
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
|
-
if (!pkgJsonPath) {
|
|
653
|
-
return {
|
|
654
|
-
name: 'agentic-flow',
|
|
655
|
-
status: 'warn',
|
|
656
|
-
message: 'Not installed (optional — embeddings/routing will use fallbacks)',
|
|
657
|
-
fix: 'npm install agentic-flow@latest'
|
|
658
|
-
};
|
|
659
|
-
}
|
|
660
|
-
if (statSync(pkgJsonPath).size > MAX_DOCTOR_PKG_BYTES) {
|
|
661
|
-
return { name: 'agentic-flow', status: 'warn', message: 'package.json too large to parse' };
|
|
662
|
-
}
|
|
663
|
-
const pkg = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));
|
|
664
|
-
const version = pkg.version || 'unknown';
|
|
665
|
-
const exports = pkg.exports || {};
|
|
666
|
-
const features = [
|
|
667
|
-
exports['./reasoningbank'] ? 'ReasoningBank' : null,
|
|
668
|
-
exports['./router'] ? 'Router' : null,
|
|
669
|
-
exports['./transport/quic'] ? 'QUIC' : null,
|
|
670
|
-
].filter(Boolean);
|
|
671
|
-
return {
|
|
672
|
-
name: 'agentic-flow',
|
|
673
|
-
status: 'pass',
|
|
674
|
-
message: `v${version}${features.length ? ' (' + features.join(', ') + ')' : ' (installed)'}`
|
|
675
|
-
};
|
|
676
|
-
}
|
|
677
|
-
catch {
|
|
678
|
-
return { name: 'agentic-flow', status: 'warn', message: 'Check failed' };
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
641
|
// Check @monoes native acceleration integration (sona/router/attention/learning-wasm)
|
|
682
642
|
// Format a 0..1 accuracy as a whole-percent string, or 'n/a' when null.
|
|
683
643
|
function fmtPct(v) {
|
|
@@ -876,7 +836,7 @@ export const doctorCommand = {
|
|
|
876
836
|
{
|
|
877
837
|
name: 'component',
|
|
878
838
|
short: 'c',
|
|
879
|
-
description: 'Check specific component (version, node, npm, config, daemon, memory, api, git, mcp, claude, disk, typescript, monograph, graph-freshness, memory-pkg, helpers,
|
|
839
|
+
description: 'Check specific component (version, node, npm, config, daemon, memory, api, git, mcp, claude, disk, typescript, monograph, graph-freshness, memory-pkg, helpers, monoes, gates, gitignore)',
|
|
880
840
|
type: 'string'
|
|
881
841
|
},
|
|
882
842
|
{
|
|
@@ -922,7 +882,6 @@ export const doctorCommand = {
|
|
|
922
882
|
checkMonographFreshness,
|
|
923
883
|
checkMonoesMemory,
|
|
924
884
|
checkHelpersFresh,
|
|
925
|
-
checkAgenticFlow,
|
|
926
885
|
checkMonoesIntegration,
|
|
927
886
|
checkGuidanceGates,
|
|
928
887
|
checkGitignoreCoverage,
|
|
@@ -945,7 +904,6 @@ export const doctorCommand = {
|
|
|
945
904
|
'graph-freshness': checkMonographFreshness,
|
|
946
905
|
'memory-pkg': checkMonoesMemory,
|
|
947
906
|
'helpers': checkHelpersFresh,
|
|
948
|
-
'agentic-flow': checkAgenticFlow,
|
|
949
907
|
'monoes': checkMonoesIntegration,
|
|
950
908
|
'gates': checkGuidanceGates,
|
|
951
909
|
'gitignore': checkGitignoreCoverage,
|
|
@@ -880,7 +880,7 @@ export const statuslineCommand = {
|
|
|
880
880
|
try {
|
|
881
881
|
const psCmd = isWindows
|
|
882
882
|
? 'tasklist /FI "IMAGENAME eq node.exe" 2>NUL | findstr /I /C:"node" >NUL && echo 1 || echo 0'
|
|
883
|
-
: 'ps aux 2>/dev/null | grep -c
|
|
883
|
+
: 'ps aux 2>/dev/null | grep -c "mcp.*start" || echo "0"';
|
|
884
884
|
const ps = execSync(psCmd, { encoding: 'utf-8' });
|
|
885
885
|
const raw = parseInt(ps.trim());
|
|
886
886
|
activeAgents = Math.max(0, isWindows ? raw : raw - 1);
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { output } from '../output.js';
|
|
7
7
|
import { callMCPTool, MCPClientError } from '../mcp-client.js';
|
|
8
|
-
// Token Optimizer command
|
|
8
|
+
// Token Optimizer command
|
|
9
9
|
export const tokenOptimizeCommand = {
|
|
10
10
|
name: 'token-optimize',
|
|
11
|
-
description: 'Token optimization via
|
|
11
|
+
description: 'Token optimization via memory-based context retrieval (30-50% savings)',
|
|
12
12
|
options: [
|
|
13
13
|
{ name: 'query', short: 'q', type: 'string', description: 'Query for compact context retrieval' },
|
|
14
14
|
{ name: 'agents', short: 'A', type: 'number', description: 'Agent count for optimal config', default: '6' },
|
|
@@ -25,7 +25,7 @@ export const tokenOptimizeCommand = {
|
|
|
25
25
|
const agentCount = parseInt(ctx.flags['agents'] || '6', 10);
|
|
26
26
|
const showReport = ctx.flags['report'];
|
|
27
27
|
const showStats = ctx.flags['stats'];
|
|
28
|
-
const spinner = output.createSpinner({ text: 'Checking
|
|
28
|
+
const spinner = output.createSpinner({ text: 'Checking memory integration...', spinner: 'dots' });
|
|
29
29
|
spinner.start();
|
|
30
30
|
// Inline TokenOptimizer (self-contained, no external imports)
|
|
31
31
|
const stats = {
|
|
@@ -35,26 +35,8 @@ export const tokenOptimizeCommand = {
|
|
|
35
35
|
cacheMisses: 0,
|
|
36
36
|
memoriesRetrieved: 0,
|
|
37
37
|
};
|
|
38
|
-
let agenticFlowAvailable = false;
|
|
39
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
40
|
-
let reasoningBank = null;
|
|
41
38
|
try {
|
|
42
|
-
|
|
43
|
-
const rb = await import('agentic-flow/reasoningbank').catch(() => null);
|
|
44
|
-
if (rb) {
|
|
45
|
-
agenticFlowAvailable = true;
|
|
46
|
-
if (typeof rb.retrieveMemories === 'function') {
|
|
47
|
-
reasoningBank = rb;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
// Legacy check for older agentic-flow
|
|
52
|
-
const af = await import('agentic-flow').catch(() => null);
|
|
53
|
-
if (af)
|
|
54
|
-
agenticFlowAvailable = true;
|
|
55
|
-
}
|
|
56
|
-
const versionLabel = agenticFlowAvailable ? `agentic-flow v1 detected (ReasoningBank: ${reasoningBank ? 'active' : 'unavailable'})` : 'agentic-flow not available (using fallbacks)';
|
|
57
|
-
spinner.succeed(versionLabel);
|
|
39
|
+
spinner.succeed('Memory-based token optimization active');
|
|
58
40
|
output.writeln();
|
|
59
41
|
// Anti-drift config (hardcoded optimal values from research)
|
|
60
42
|
const config = {
|
|
@@ -69,27 +51,9 @@ export const tokenOptimizeCommand = {
|
|
|
69
51
|
`Batch Size: ${config.batchSize}\n` +
|
|
70
52
|
`Cache: ${config.cacheSizeMB}MB\n` +
|
|
71
53
|
`Success Rate: ${(config.expectedSuccessRate * 100)}%`);
|
|
72
|
-
|
|
73
|
-
if (query && reasoningBank) {
|
|
74
|
-
output.writeln();
|
|
75
|
-
output.printInfo(`Retrieving compact context for: "${query}"`);
|
|
76
|
-
const memories = await reasoningBank.retrieveMemories(query, { k: 5 });
|
|
77
|
-
const compactPrompt = reasoningBank.formatMemoriesForPrompt ? reasoningBank.formatMemoriesForPrompt(memories) : '';
|
|
78
|
-
// Estimate based on actual query vs compact prompt size difference
|
|
79
|
-
const queryTokenEstimate = Math.ceil((query?.length || 0) / 4);
|
|
80
|
-
const used = Math.ceil((compactPrompt?.length || 0) / 4);
|
|
81
|
-
const tokensSaved = Math.max(0, queryTokenEstimate - used);
|
|
82
|
-
stats.totalTokensSaved += tokensSaved;
|
|
83
|
-
stats.memoriesRetrieved += Array.isArray(memories) ? memories.length : 0;
|
|
84
|
-
output.writeln(` Memories found: ${Array.isArray(memories) ? memories.length : 0}`);
|
|
85
|
-
output.writeln(` Tokens saved: ${output.success(String(tokensSaved))}`);
|
|
86
|
-
if (compactPrompt) {
|
|
87
|
-
output.writeln(` Compact prompt (${compactPrompt.length} chars)`);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
else if (query) {
|
|
54
|
+
if (query) {
|
|
91
55
|
output.writeln();
|
|
92
|
-
output.printInfo(
|
|
56
|
+
output.printInfo(`Context retrieval for: "${query}" — use monomind memory search`);
|
|
93
57
|
}
|
|
94
58
|
// Simulate some token savings for demo
|
|
95
59
|
stats.totalTokensSaved += 200;
|
|
@@ -112,7 +76,6 @@ export const tokenOptimizeCommand = {
|
|
|
112
76
|
{ metric: 'Cache Hit Rate', value: `${hitRate}%` },
|
|
113
77
|
{ metric: 'Memories Retrieved', value: String(stats.memoriesRetrieved) },
|
|
114
78
|
{ metric: 'Est. Monthly Savings', value: `$${savings}` },
|
|
115
|
-
{ metric: 'Agentic-Flow Active', value: agenticFlowAvailable ? '✓' : '✗' },
|
|
116
79
|
],
|
|
117
80
|
});
|
|
118
81
|
}
|
|
@@ -131,9 +94,9 @@ export const tokenOptimizeCommand = {
|
|
|
131
94
|
| Cache Hit Rate | ${hitRate}% |
|
|
132
95
|
| Memories Retrieved | ${stats.memoriesRetrieved} |
|
|
133
96
|
| Est. Monthly Savings | $${savings} |
|
|
134
|
-
|
|
|
97
|
+
| Memories Retrieved | ${stats.memoriesRetrieved} |`);
|
|
135
98
|
}
|
|
136
|
-
return { success: true, data: { config, stats
|
|
99
|
+
return { success: true, data: { config, stats } };
|
|
137
100
|
}
|
|
138
101
|
catch (error) {
|
|
139
102
|
spinner.fail('TokenOptimizer failed');
|
|
@@ -757,9 +757,9 @@ export async function executeUpgrade(targetDir, upgradeSettings = false) {
|
|
|
757
757
|
if (!fs.existsSync(activityPath)) {
|
|
758
758
|
const activity = {
|
|
759
759
|
timestamp: new Date().toISOString(),
|
|
760
|
-
processes: {
|
|
760
|
+
processes: { mcp_server: 0, estimated_agents: 0 },
|
|
761
761
|
swarm: { active: false, agent_count: 0, coordination_active: false },
|
|
762
|
-
integration: {
|
|
762
|
+
integration: { mcp_active: false },
|
|
763
763
|
_initialized: true
|
|
764
764
|
};
|
|
765
765
|
atomicWriteFile(activityPath, JSON.stringify(activity, null, 2));
|
|
@@ -1582,7 +1582,6 @@ async function writeInitialMetrics(targetDir, options, result) {
|
|
|
1582
1582
|
const activity = {
|
|
1583
1583
|
timestamp: new Date().toISOString(),
|
|
1584
1584
|
processes: {
|
|
1585
|
-
agentic_flow: 0,
|
|
1586
1585
|
mcp_server: 0,
|
|
1587
1586
|
estimated_agents: 0
|
|
1588
1587
|
},
|
|
@@ -1592,7 +1591,6 @@ async function writeInitialMetrics(targetDir, options, result) {
|
|
|
1592
1591
|
coordination_active: false
|
|
1593
1592
|
},
|
|
1594
1593
|
integration: {
|
|
1595
|
-
agentic_flow_active: false,
|
|
1596
1594
|
mcp_active: false
|
|
1597
1595
|
},
|
|
1598
1596
|
_initialized: true
|
|
@@ -1977,7 +1975,6 @@ npx monomind@latest hive-mind consensus --propose "task"
|
|
|
1977
1975
|
### Integrated Packages
|
|
1978
1976
|
| Package | Version | Purpose |
|
|
1979
1977
|
|---------|---------|---------|
|
|
1980
|
-
| agentic-flow | 3.0.0-alpha.1 | Core coordination + ReasoningBank + Router |
|
|
1981
1978
|
| @lancedb/lancedb | latest | Vector database (ANN search) |
|
|
1982
1979
|
|
|
1983
1980
|
### Optional Integrations
|
|
@@ -159,7 +159,7 @@ const IS_WINDOWS = process.platform === 'win32';
|
|
|
159
159
|
*/
|
|
160
160
|
function hookCmd(script, subcommand) {
|
|
161
161
|
if (IS_WINDOWS) {
|
|
162
|
-
return `cmd /c node %CLAUDE_PROJECT_DIR%/${script} ${subcommand}`.trim();
|
|
162
|
+
return `cmd /c node "%CLAUDE_PROJECT_DIR%/${script}" ${subcommand}`.trim();
|
|
163
163
|
}
|
|
164
164
|
// Use sh -c to ensure $CLAUDE_PROJECT_DIR is expanded by a real shell,
|
|
165
165
|
// even if Claude Code doesn't invoke hooks through a shell on macOS.
|
|
@@ -180,13 +180,13 @@ function captureHandlerCmd(subcommand) {
|
|
|
180
180
|
// capture-handler does not use sh -c wrapper — it reads stdin directly
|
|
181
181
|
const dir = IS_WINDOWS ? '%CLAUDE_PROJECT_DIR%' : '${CLAUDE_PROJECT_DIR:-.}';
|
|
182
182
|
return IS_WINDOWS
|
|
183
|
-
? `node ${dir}/.claude/helpers/handlers/capture-handler.cjs ${subcommand}`
|
|
183
|
+
? `node "${dir}/.claude/helpers/handlers/capture-handler.cjs" ${subcommand}`
|
|
184
184
|
: `node "${dir}/.claude/helpers/handlers/capture-handler.cjs" ${subcommand}`;
|
|
185
185
|
}
|
|
186
186
|
/** Shorthand for standalone CJS helper scripts (no subcommand) */
|
|
187
187
|
function standaloneHelperCmd(script) {
|
|
188
188
|
if (IS_WINDOWS) {
|
|
189
|
-
return `cmd /c node %CLAUDE_PROJECT_DIR%/.claude/helpers/${script}`;
|
|
189
|
+
return `cmd /c node "%CLAUDE_PROJECT_DIR%/.claude/helpers/${script}"`;
|
|
190
190
|
}
|
|
191
191
|
// eslint-disable-next-line no-template-curly-in-string
|
|
192
192
|
const dir = '${CLAUDE_PROJECT_DIR:-.}';
|
|
@@ -200,8 +200,14 @@ function generateStatusLineConfig(_options) {
|
|
|
200
200
|
// Claude Code pipes JSON session data to the script via stdin.
|
|
201
201
|
// Valid fields: type, command, padding (optional).
|
|
202
202
|
// The script runs after each assistant message (debounced 300ms).
|
|
203
|
-
// NOTE: statusline must NOT use `cmd /c` — Claude Code
|
|
204
|
-
// directly for statusline commands
|
|
203
|
+
// NOTE: statusline must NOT use `cmd /c` on Windows either — Claude Code
|
|
204
|
+
// manages stdin directly for statusline commands; wrappers block forwarding.
|
|
205
|
+
if (IS_WINDOWS) {
|
|
206
|
+
return {
|
|
207
|
+
type: 'command',
|
|
208
|
+
command: 'node "%CLAUDE_PROJECT_DIR%/.claude/helpers/statusline.cjs"',
|
|
209
|
+
};
|
|
210
|
+
}
|
|
205
211
|
// eslint-disable-next-line no-template-curly-in-string
|
|
206
212
|
const dir = '${CLAUDE_PROJECT_DIR:-.}';
|
|
207
213
|
return {
|
|
@@ -70,17 +70,22 @@ function getVersion() {
|
|
|
70
70
|
}
|
|
71
71
|
} catch { /* ignore */ }
|
|
72
72
|
}
|
|
73
|
-
// 2. Fallback: npm global prefix
|
|
73
|
+
// 2. Fallback: npm global prefix (lib/node_modules on POSIX, node_modules on Windows)
|
|
74
74
|
try {
|
|
75
75
|
const { execSync } = require('child_process');
|
|
76
76
|
const prefix = execSync('npm config get prefix', { encoding: 'utf-8', timeout: 2000 }).trim();
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
77
|
+
const candidates = [
|
|
78
|
+
path.join(prefix, 'lib', 'node_modules', 'monomind', 'package.json'),
|
|
79
|
+
path.join(prefix, 'node_modules', 'monomind', 'package.json'),
|
|
80
|
+
];
|
|
81
|
+
for (const globalPkgPath of candidates) {
|
|
82
|
+
const globalPkgStat = safeStat(globalPkgPath);
|
|
83
|
+
if (!globalPkgStat || globalPkgStat.size > 1024 * 1024) continue;
|
|
84
|
+
const pkg = JSON.parse(fs.readFileSync(globalPkgPath, 'utf-8'));
|
|
85
|
+
if (pkg.version) return \`v\${pkg.version}\`;
|
|
86
|
+
}
|
|
82
87
|
} catch { /* ignore */ }
|
|
83
|
-
return '
|
|
88
|
+
return 'v?';
|
|
84
89
|
}
|
|
85
90
|
const VERSION = getVersion();
|
|
86
91
|
|
|
@@ -657,7 +657,7 @@ export class MCPServerManager extends EventEmitter {
|
|
|
657
657
|
}
|
|
658
658
|
// Dynamically import the MCP server package
|
|
659
659
|
// FIX for issue #942: Use proper package import instead of broken relative path
|
|
660
|
-
// @ts-
|
|
660
|
+
// @ts-ignore — @monomind/mcp is an optional peer resolved at runtime
|
|
661
661
|
const { createMCPServer } = await import('@monomind/mcp');
|
|
662
662
|
const logger = {
|
|
663
663
|
debug: (msg, data) => this.emit('log', { level: 'debug', msg, data }),
|
|
@@ -182,10 +182,11 @@ export const daaTools = [
|
|
|
182
182
|
try {
|
|
183
183
|
const bridge = await import('../memory/memory-bridge.js');
|
|
184
184
|
await bridge.bridgeRecordFeedback({
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
185
|
+
taskType: agentId,
|
|
186
|
+
action: `adapt-${agentId}-${agent.metrics.adaptations}`,
|
|
187
|
+
outcome: performanceScore >= 0.5 ? 'success' : 'failure',
|
|
188
|
+
confidence: performanceScore,
|
|
189
|
+
metadata: { agentId, adaptations: agent.metrics.adaptations },
|
|
189
190
|
});
|
|
190
191
|
_storedIn = 'lancedb';
|
|
191
192
|
}
|
|
@@ -354,7 +354,7 @@ export const hooksPatternStore = {
|
|
|
354
354
|
let reasoningResult = null;
|
|
355
355
|
try {
|
|
356
356
|
const bridge = await import('../memory/memory-bridge.js');
|
|
357
|
-
reasoningResult = await bridge.bridgeStorePattern({ pattern, type, confidence
|
|
357
|
+
reasoningResult = await bridge.bridgeStorePattern({ pattern, taskType: type, confidence });
|
|
358
358
|
}
|
|
359
359
|
catch {
|
|
360
360
|
// Bridge not available
|
|
@@ -379,20 +379,20 @@ export const hooksPatternStore = {
|
|
|
379
379
|
}
|
|
380
380
|
}
|
|
381
381
|
const success = reasoningResult?.success || storeResult.success;
|
|
382
|
-
const controller = reasoningResult?.
|
|
382
|
+
const controller = reasoningResult?.success ? 'lancedb' : (storeResult.success ? 'bridge-store' : 'none');
|
|
383
383
|
return {
|
|
384
|
-
patternId: reasoningResult?.
|
|
384
|
+
patternId: reasoningResult?.id || storeResult.id || patternId,
|
|
385
385
|
pattern,
|
|
386
386
|
type,
|
|
387
387
|
confidence,
|
|
388
388
|
indexed: success,
|
|
389
|
-
hnswIndexed: success && (!!storeResult.embedding || controller === '
|
|
389
|
+
hnswIndexed: success && (!!storeResult.embedding || controller === 'lancedb'),
|
|
390
390
|
embedding: storeResult.embedding,
|
|
391
391
|
timestamp,
|
|
392
392
|
controller,
|
|
393
|
-
implementation: controller === '
|
|
394
|
-
note: controller === '
|
|
395
|
-
? 'Pattern stored via
|
|
393
|
+
implementation: controller === 'lancedb' ? 'lancedb-controller' : (storeResult.success ? 'real-hnsw-indexed' : 'memory-only'),
|
|
394
|
+
note: controller === 'lancedb'
|
|
395
|
+
? 'Pattern stored via lancedb bridge with HNSW indexing'
|
|
396
396
|
: (storeResult.success ? 'Pattern stored with vector embedding for semantic search' : (storeResult.error || 'Store function unavailable')),
|
|
397
397
|
};
|
|
398
398
|
},
|
|
@@ -428,20 +428,22 @@ export const hooksPatternSearch = {
|
|
|
428
428
|
// Phase 3: Try ReasoningBank search via bridge first
|
|
429
429
|
try {
|
|
430
430
|
const bridge = await import('../memory/memory-bridge.js');
|
|
431
|
-
const rbResult = await bridge.bridgeSearchPatterns({ query, topK
|
|
432
|
-
if (rbResult && rbResult.
|
|
431
|
+
const rbResult = await bridge.bridgeSearchPatterns({ query, limit: topK });
|
|
432
|
+
if (rbResult && rbResult.patterns.length > 0) {
|
|
433
433
|
return {
|
|
434
434
|
query,
|
|
435
|
-
results: rbResult.
|
|
435
|
+
results: rbResult.patterns
|
|
436
|
+
.filter((r) => r.score >= minConfidence)
|
|
437
|
+
.map((r) => ({
|
|
436
438
|
patternId: r.id,
|
|
437
|
-
pattern: r.
|
|
439
|
+
pattern: r.pattern,
|
|
438
440
|
similarity: r.score,
|
|
439
441
|
confidence: r.score,
|
|
440
442
|
namespace,
|
|
441
443
|
})),
|
|
442
444
|
searchTimeMs: 0,
|
|
443
|
-
backend:
|
|
444
|
-
note:
|
|
445
|
+
backend: 'lancedb',
|
|
446
|
+
note: 'Results from lancedb bridge',
|
|
445
447
|
};
|
|
446
448
|
}
|
|
447
449
|
}
|
|
@@ -91,13 +91,10 @@ export const hooksPostEdit = {
|
|
|
91
91
|
try {
|
|
92
92
|
const bridge = await import('../memory/memory-bridge.js');
|
|
93
93
|
feedbackResult = await bridge.bridgeRecordFeedback({
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
// B1.2: give the SONA embedder real semantics (the edited file) instead of
|
|
99
|
-
// the opaque task ID.
|
|
100
|
-
task: `edit ${filePath}`,
|
|
94
|
+
taskType: agent ?? 'coder',
|
|
95
|
+
action: `edit ${filePath}`,
|
|
96
|
+
outcome: success ? 'success' : 'failure',
|
|
97
|
+
confidence: success ? 0.85 : 0.3,
|
|
101
98
|
});
|
|
102
99
|
}
|
|
103
100
|
catch {
|
|
@@ -111,8 +108,8 @@ export const hooksPostEdit = {
|
|
|
111
108
|
learningUpdate: success ? 'pattern_reinforced' : 'pattern_adjusted',
|
|
112
109
|
feedback: feedbackResult ? {
|
|
113
110
|
recorded: feedbackResult.success,
|
|
114
|
-
controller: feedbackResult.
|
|
115
|
-
updates: feedbackResult.
|
|
111
|
+
controller: feedbackResult.success ? 'lancedb' : 'unavailable',
|
|
112
|
+
updates: feedbackResult.success ? 1 : 0,
|
|
116
113
|
} : { recorded: false, controller: 'unavailable', updates: 0 },
|
|
117
114
|
};
|
|
118
115
|
},
|
|
@@ -259,51 +256,56 @@ export const hooksRoute = {
|
|
|
259
256
|
if (useSemanticRouter) {
|
|
260
257
|
try {
|
|
261
258
|
const bridge = await import('../memory/memory-bridge.js');
|
|
262
|
-
const memoryRoute = await bridge.bridgeRouteTask({ task
|
|
263
|
-
if (memoryRoute && memoryRoute.
|
|
264
|
-
const
|
|
265
|
-
const
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
259
|
+
const memoryRoute = await bridge.bridgeRouteTask({ task });
|
|
260
|
+
if (memoryRoute && memoryRoute.routes && memoryRoute.routes.length > 0) {
|
|
261
|
+
const topRoute = memoryRoute.routes[0];
|
|
262
|
+
const routeConfidence = topRoute.confidence ?? 0;
|
|
263
|
+
if (routeConfidence > 0.5) {
|
|
264
|
+
const agents = memoryRoute.routes.map((r) => r.agentType);
|
|
265
|
+
const complexity = task.length > 200 ? 'high' : task.length < 50 ? 'low' : 'medium';
|
|
266
|
+
const memoryMethod = 'memory-lancedb';
|
|
267
|
+
const memoryConfidence = Math.round(routeConfidence * 100) / 100;
|
|
268
|
+
const matchedPattern = topRoute.pattern ?? task.slice(0, 60);
|
|
269
|
+
// Record the route recommendation so post-task can join the actual outcome
|
|
270
|
+
const routeId = randomUUID();
|
|
271
|
+
await recordRoute(getRouteOutcomesBaseDir(), {
|
|
272
|
+
routeId,
|
|
273
|
+
ts: Date.now(),
|
|
274
|
+
task,
|
|
275
|
+
recommendedAgent: agents[0],
|
|
276
|
+
routingMethod: memoryMethod,
|
|
277
|
+
confidence: memoryConfidence,
|
|
278
|
+
learningMode: 'js',
|
|
279
|
+
});
|
|
280
|
+
return {
|
|
281
|
+
routeId,
|
|
282
|
+
task,
|
|
283
|
+
routing: {
|
|
284
|
+
method: memoryMethod,
|
|
285
|
+
backend: 'lancedb',
|
|
286
|
+
latencyMs: 0,
|
|
287
|
+
throughput: 'N/A',
|
|
288
|
+
},
|
|
289
|
+
matchedPattern,
|
|
290
|
+
semanticMatches: [{ pattern: matchedPattern, score: routeConfidence }],
|
|
291
|
+
primaryAgent: {
|
|
292
|
+
type: agents[0],
|
|
293
|
+
confidence: memoryConfidence,
|
|
294
|
+
reason: `memory:lancedb: "${matchedPattern}" (${Math.round(routeConfidence * 100)}%)`,
|
|
295
|
+
},
|
|
296
|
+
alternativeAgents: agents.slice(1).map((agent, i) => ({
|
|
297
|
+
type: agent,
|
|
298
|
+
confidence: Math.round((routeConfidence - (0.1 * (i + 1))) * 100) / 100,
|
|
299
|
+
reason: 'Alternative from lancedb',
|
|
300
|
+
})),
|
|
301
|
+
estimatedMetrics: {
|
|
302
|
+
successProbability: memoryConfidence,
|
|
303
|
+
estimatedDuration: complexity === 'high' ? '2-4 hours' : complexity === 'medium' ? '30-60 min' : '10-30 min',
|
|
304
|
+
complexity,
|
|
305
|
+
},
|
|
306
|
+
swarmRecommendation: agents.length > 2 ? { topology: 'hierarchical', agents, coordination: 'queen-led' } : null,
|
|
307
|
+
};
|
|
308
|
+
}
|
|
307
309
|
}
|
|
308
310
|
}
|
|
309
311
|
catch {
|
|
@@ -682,17 +684,11 @@ export const hooksPostTask = {
|
|
|
682
684
|
try {
|
|
683
685
|
const bridge = await import('../memory/memory-bridge.js');
|
|
684
686
|
feedbackResult = await bridge.bridgeRecordFeedback({
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
// embedder encodes meaning, not the opaque task ID.
|
|
691
|
-
task: cappedPostTask || undefined,
|
|
692
|
-
// B1.3: only feed the SONA LoRA update when the outcome is actually known.
|
|
693
|
-
outcomeKnown,
|
|
694
|
-
duration: params.duration || undefined,
|
|
695
|
-
patterns: params.patterns || undefined,
|
|
687
|
+
taskType: agent ?? 'task',
|
|
688
|
+
action: cappedPostTask?.slice(0, 80) ?? taskId,
|
|
689
|
+
outcome: success ? 'success' : (outcomeKnown ? 'failure' : 'partial'),
|
|
690
|
+
confidence: quality,
|
|
691
|
+
metadata: { taskId, duration: params.duration || undefined, patterns: params.patterns || undefined },
|
|
696
692
|
});
|
|
697
693
|
}
|
|
698
694
|
catch {
|
|
@@ -705,7 +701,7 @@ export const hooksPostTask = {
|
|
|
705
701
|
sourceId: taskId,
|
|
706
702
|
targetId: `outcome-${taskId}`,
|
|
707
703
|
relation: success ? 'succeeded' : 'failed',
|
|
708
|
-
|
|
704
|
+
strength: quality,
|
|
709
705
|
});
|
|
710
706
|
}
|
|
711
707
|
catch {
|
|
@@ -830,17 +826,17 @@ export const hooksPostTask = {
|
|
|
830
826
|
successSource,
|
|
831
827
|
duration,
|
|
832
828
|
learningUpdates: {
|
|
833
|
-
patternsUpdated: feedbackResult?.
|
|
829
|
+
patternsUpdated: feedbackResult?.success ? (success ? 2 : 1) : 0,
|
|
834
830
|
newPatterns: success ? 1 : 0,
|
|
835
831
|
trajectoryId: `traj-${Date.now()}`,
|
|
836
|
-
controller: feedbackResult?.
|
|
832
|
+
controller: feedbackResult?.success ? 'lancedb' : 'none',
|
|
837
833
|
outcomePersisted,
|
|
838
834
|
},
|
|
839
835
|
quality,
|
|
840
836
|
feedback: feedbackResult ? {
|
|
841
837
|
recorded: feedbackResult.success,
|
|
842
|
-
controller: feedbackResult.
|
|
843
|
-
updates: feedbackResult.
|
|
838
|
+
controller: feedbackResult.success ? 'lancedb' : 'unavailable',
|
|
839
|
+
updates: feedbackResult.success ? 1 : 0,
|
|
844
840
|
} : { recorded: false, controller: 'unavailable', updates: 0 },
|
|
845
841
|
marReflection,
|
|
846
842
|
timestamp: new Date().toISOString(),
|
|
@@ -1261,12 +1257,12 @@ export const hooksSessionStart = {
|
|
|
1261
1257
|
const bridge = await import('../memory/memory-bridge.js');
|
|
1262
1258
|
const result = await bridge.bridgeSessionStart({
|
|
1263
1259
|
sessionId,
|
|
1264
|
-
context: restoreLatest ? 'restore previous session patterns' : 'new session',
|
|
1260
|
+
metadata: { context: restoreLatest ? 'restore previous session patterns' : 'new session' },
|
|
1265
1261
|
});
|
|
1266
1262
|
if (result) {
|
|
1267
1263
|
sessionMemory = {
|
|
1268
|
-
controller: result.
|
|
1269
|
-
restoredPatterns:
|
|
1264
|
+
controller: result.success ? 'lancedb' : 'none',
|
|
1265
|
+
restoredPatterns: 0,
|
|
1270
1266
|
};
|
|
1271
1267
|
}
|
|
1272
1268
|
}
|
|
@@ -1351,13 +1347,12 @@ export const hooksSessionEnd = {
|
|
|
1351
1347
|
const result = await bridge.bridgeSessionEnd({
|
|
1352
1348
|
sessionId,
|
|
1353
1349
|
summary: saveState ? 'Session ended with state saved' : 'Session ended',
|
|
1354
|
-
tasksCompleted: taskCount,
|
|
1355
|
-
patternsLearned: patternCount,
|
|
1350
|
+
metrics: { tasksCompleted: taskCount, patternsLearned: patternCount },
|
|
1356
1351
|
});
|
|
1357
1352
|
if (result) {
|
|
1358
1353
|
sessionPersistence = {
|
|
1359
|
-
controller: result.
|
|
1360
|
-
persisted: result.
|
|
1354
|
+
controller: result.success ? 'lancedb' : 'none',
|
|
1355
|
+
persisted: result.success,
|
|
1361
1356
|
};
|
|
1362
1357
|
}
|
|
1363
1358
|
}
|
|
@@ -94,9 +94,9 @@ export const memoryControllers = {
|
|
|
94
94
|
return { available: false, controllers: [], error: 'Memory bridge not available — @monomind/memory not installed or missing controller-registry. Use memory_store/memory_search tools instead.' };
|
|
95
95
|
return {
|
|
96
96
|
available: true,
|
|
97
|
-
controllers,
|
|
98
|
-
total: controllers.length,
|
|
99
|
-
active: controllers.
|
|
97
|
+
controllers: controllers.controllers,
|
|
98
|
+
total: controllers.controllers.length,
|
|
99
|
+
active: controllers.active.length,
|
|
100
100
|
};
|
|
101
101
|
}
|
|
102
102
|
catch (error) {
|
|
@@ -125,7 +125,7 @@ export const memoryPatternStore = {
|
|
|
125
125
|
const bridge = await getBridge();
|
|
126
126
|
const result = await bridge.bridgeStorePattern({
|
|
127
127
|
pattern,
|
|
128
|
-
|
|
128
|
+
taskType: validateString(params.type, 'type', 200) ?? 'general',
|
|
129
129
|
confidence: validateScore(params.confidence, 0.8),
|
|
130
130
|
});
|
|
131
131
|
return result ?? { success: false, error: 'Memory bridge not available. Use memory_store/memory_search instead.' };
|
|
@@ -154,12 +154,17 @@ export const memoryPatternSearch = {
|
|
|
154
154
|
if (!query)
|
|
155
155
|
return { results: [], error: 'query is required (non-empty string, max 10KB)' };
|
|
156
156
|
const bridge = await getBridge();
|
|
157
|
+
const minConfidence = validateScore(params.minConfidence, 0.3);
|
|
157
158
|
const result = await bridge.bridgeSearchPatterns({
|
|
158
159
|
query,
|
|
159
|
-
|
|
160
|
-
minConfidence: validateScore(params.minConfidence, 0.3),
|
|
160
|
+
limit: validatePositiveInt(params.topK, 5, MAX_TOP_K),
|
|
161
161
|
});
|
|
162
|
-
|
|
162
|
+
if (!result)
|
|
163
|
+
return { results: [], controller: 'unavailable' };
|
|
164
|
+
return {
|
|
165
|
+
...result,
|
|
166
|
+
patterns: result.patterns.filter((p) => p.score >= minConfidence),
|
|
167
|
+
};
|
|
163
168
|
}
|
|
164
169
|
catch (error) {
|
|
165
170
|
return { results: [], error: sanitizeError(error) };
|
|
@@ -187,10 +192,11 @@ export const memoryFeedback = {
|
|
|
187
192
|
return { success: false, error: 'taskId is required (non-empty string, max 500 chars)' };
|
|
188
193
|
const bridge = await getBridge();
|
|
189
194
|
const result = await bridge.bridgeRecordFeedback({
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
195
|
+
taskType: validateString(params.agent, 'agent', 200) ?? 'task',
|
|
196
|
+
action: taskId,
|
|
197
|
+
outcome: params.success === true ? 'success' : 'failure',
|
|
198
|
+
confidence: validateScore(params.quality, 0.85),
|
|
199
|
+
metadata: { taskId },
|
|
194
200
|
});
|
|
195
201
|
return result ?? { success: false, error: 'Memory bridge not available. Use memory_store/memory_search instead.' };
|
|
196
202
|
}
|
|
@@ -229,7 +235,7 @@ export const memoryCausalEdge = {
|
|
|
229
235
|
sourceId,
|
|
230
236
|
targetId,
|
|
231
237
|
relation,
|
|
232
|
-
|
|
238
|
+
strength: typeof params.weight === 'number' ? validateScore(params.weight, 0.5) : undefined,
|
|
233
239
|
});
|
|
234
240
|
return result ?? { success: false, error: 'Memory bridge not available. Use memory_store/memory_search instead.' };
|
|
235
241
|
}
|
|
@@ -256,10 +262,7 @@ export const memoryRoute = {
|
|
|
256
262
|
if (!task)
|
|
257
263
|
return { route: 'general', confidence: 0.5, agents: ['coder'], controller: 'error', error: 'task is required (non-empty string)' };
|
|
258
264
|
const bridge = await getBridge();
|
|
259
|
-
const result = await bridge.bridgeRouteTask({
|
|
260
|
-
task,
|
|
261
|
-
context: validateString(params.context, 'context', 10_000) ?? undefined,
|
|
262
|
-
});
|
|
265
|
+
const result = await bridge.bridgeRouteTask({ task });
|
|
263
266
|
return result ?? { route: 'general', confidence: 0.5, agents: ['coder'], controller: 'fallback' };
|
|
264
267
|
}
|
|
265
268
|
catch (error) {
|
|
@@ -287,7 +290,7 @@ export const memorySessionStart = {
|
|
|
287
290
|
const bridge = await getBridge();
|
|
288
291
|
const result = await bridge.bridgeSessionStart({
|
|
289
292
|
sessionId,
|
|
290
|
-
context: validateString(params.context, 'context', 10_000) ?? undefined,
|
|
293
|
+
metadata: { context: validateString(params.context, 'context', 10_000) ?? undefined },
|
|
291
294
|
});
|
|
292
295
|
return result ?? { success: false, error: 'Memory bridge not available. Use memory_store/memory_search instead.' };
|
|
293
296
|
}
|
|
@@ -318,7 +321,7 @@ export const memorySessionEnd = {
|
|
|
318
321
|
const result = await bridge.bridgeSessionEnd({
|
|
319
322
|
sessionId,
|
|
320
323
|
summary: validateString(params.summary, 'summary', 50_000) ?? undefined,
|
|
321
|
-
tasksCompleted: validatePositiveInt(params.tasksCompleted, 0, 10_000),
|
|
324
|
+
metrics: { tasksCompleted: validatePositiveInt(params.tasksCompleted, 0, 10_000) },
|
|
322
325
|
});
|
|
323
326
|
return result ?? { success: false, error: 'Memory bridge not available. Use memory_store/memory_search instead.' };
|
|
324
327
|
}
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* V2 Compatibility - Neural network and ML tools
|
|
5
5
|
*
|
|
6
6
|
* ✅ HYBRID Implementation:
|
|
7
|
-
* - Uses
|
|
8
|
-
* - Falls back to deterministic hash-based embeddings
|
|
7
|
+
* - Uses monovector ONNX embeddings when available
|
|
8
|
+
* - Falls back to deterministic hash-based embeddings otherwise
|
|
9
9
|
* - Pattern storage and search with cosine similarity (real math in all tiers)
|
|
10
10
|
* - Training stores patterns as searchable embeddings (not simulated)
|
|
11
11
|
*
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* V2 Compatibility - Neural network and ML tools
|
|
5
5
|
*
|
|
6
6
|
* ✅ HYBRID Implementation:
|
|
7
|
-
* - Uses
|
|
8
|
-
* - Falls back to deterministic hash-based embeddings
|
|
7
|
+
* - Uses monovector ONNX embeddings when available
|
|
8
|
+
* - Falls back to deterministic hash-based embeddings otherwise
|
|
9
9
|
* - Pattern storage and search with cosine similarity (real math in all tiers)
|
|
10
10
|
* - Training stores patterns as searchable embeddings (not simulated)
|
|
11
11
|
*
|
|
@@ -16,19 +16,28 @@ import { existsSync, readFileSync, writeFileSync, renameSync, mkdirSync, statSyn
|
|
|
16
16
|
import { join } from 'node:path';
|
|
17
17
|
const MAX_NEURAL_STORE_BYTES = 50 * 1024 * 1024; // 50 MB
|
|
18
18
|
const NEURAL_RESERVED_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
|
|
19
|
-
//
|
|
20
|
-
// otherwise the deterministic hash fallback below.
|
|
19
|
+
// Embeddings via monovector ONNX when available; deterministic hash fallback otherwise.
|
|
21
20
|
let realEmbeddings = null;
|
|
22
21
|
let embeddingServiceName = 'none';
|
|
23
22
|
try {
|
|
24
|
-
const
|
|
25
|
-
if (
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
const monovector = await import('monovector').catch(() => null);
|
|
24
|
+
if (monovector?.getOptimizedOnnxEmbedder) {
|
|
25
|
+
await monovector.initOnnxEmbedder?.();
|
|
26
|
+
const onnxEmb = monovector.getOptimizedOnnxEmbedder();
|
|
27
|
+
if (onnxEmb?.embed) {
|
|
28
|
+
const probe = await onnxEmb.embed('test');
|
|
29
|
+
const hasNonZero = ArrayBuffer.isView(probe) || Array.isArray(probe)
|
|
30
|
+
? [...probe].some((v) => v !== 0)
|
|
31
|
+
: false;
|
|
32
|
+
if (probe && probe.length > 0 && hasNonZero) {
|
|
33
|
+
realEmbeddings = { embed: async (text) => Array.from(await onnxEmb.embed(text)) };
|
|
34
|
+
embeddingServiceName = 'monovector/onnx';
|
|
35
|
+
}
|
|
36
|
+
}
|
|
28
37
|
}
|
|
29
38
|
}
|
|
30
39
|
catch {
|
|
31
|
-
// No embedding provider available, will use fallback
|
|
40
|
+
// No ONNX embedding provider available, will use hash fallback
|
|
32
41
|
}
|
|
33
42
|
// Storage paths
|
|
34
43
|
const STORAGE_DIR = '.monomind';
|
|
@@ -76,25 +76,6 @@ export async function loadEmbeddingModel(options) {
|
|
|
76
76
|
loadTime: Date.now() - startTime
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
|
-
// Fallback: Check for agentic-flow ReasoningBank embeddings (v1)
|
|
80
|
-
const reasoningBank = await import('agentic-flow/reasoningbank').catch(() => null);
|
|
81
|
-
if (reasoningBank?.computeEmbedding) {
|
|
82
|
-
if (verbose) {
|
|
83
|
-
console.log('Loading agentic-flow ReasoningBank embedding model...');
|
|
84
|
-
}
|
|
85
|
-
embeddingModelState = {
|
|
86
|
-
loaded: true,
|
|
87
|
-
model: { embed: reasoningBank.computeEmbedding },
|
|
88
|
-
tokenizer: null,
|
|
89
|
-
dimensions: 768
|
|
90
|
-
};
|
|
91
|
-
return {
|
|
92
|
-
success: true,
|
|
93
|
-
dimensions: 768,
|
|
94
|
-
modelName: 'agentic-flow/reasoningbank',
|
|
95
|
-
loadTime: Date.now() - startTime
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
79
|
// Fallback: Check for monovector ONNX embedder (bundled MiniLM-L6-v2 since v0.2.15)
|
|
99
80
|
// v0.2.16: LoRA B=0 fix makes AdaptiveEmbedder safe (identity when untrained)
|
|
100
81
|
// Note: isReady() returns false until first embed() call (lazy init), so we
|
|
@@ -108,7 +89,8 @@ export async function loadEmbeddingModel(options) {
|
|
|
108
89
|
if (onnxEmb?.embed) {
|
|
109
90
|
// Probe embed to trigger lazy ONNX init and verify it works
|
|
110
91
|
const probe = await onnxEmb.embed('test');
|
|
111
|
-
|
|
92
|
+
const probeArr = ArrayBuffer.isView(probe) ? Array.from(probe) : (Array.isArray(probe) ? probe : []);
|
|
93
|
+
if (probe && probe.length > 0 && probeArr.some((v) => v !== 0)) {
|
|
112
94
|
if (verbose) {
|
|
113
95
|
console.log(`Loading monovector ONNX embedder (all-MiniLM-L6-v2, ${probe.length}d)...`);
|
|
114
96
|
}
|
|
@@ -131,25 +113,6 @@ export async function loadEmbeddingModel(options) {
|
|
|
131
113
|
// monovector ONNX init failed, continue to next fallback
|
|
132
114
|
}
|
|
133
115
|
}
|
|
134
|
-
// Legacy fallback: Check for agentic-flow core embeddings
|
|
135
|
-
const agenticFlow = await import('agentic-flow').catch(() => null);
|
|
136
|
-
if (agenticFlow && agenticFlow.embeddings) {
|
|
137
|
-
if (verbose) {
|
|
138
|
-
console.log('Loading agentic-flow embedding model...');
|
|
139
|
-
}
|
|
140
|
-
embeddingModelState = {
|
|
141
|
-
loaded: true,
|
|
142
|
-
model: agenticFlow.embeddings,
|
|
143
|
-
tokenizer: null,
|
|
144
|
-
dimensions: 768
|
|
145
|
-
};
|
|
146
|
-
return {
|
|
147
|
-
success: true,
|
|
148
|
-
dimensions: 768,
|
|
149
|
-
modelName: 'agentic-flow',
|
|
150
|
-
loadTime: Date.now() - startTime
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
116
|
// No ONNX model available - use fallback
|
|
154
117
|
embeddingModelState = {
|
|
155
118
|
loaded: true,
|
|
@@ -85,13 +85,6 @@ function saveHNSWMetadata() {
|
|
|
85
85
|
* Add entry to HNSW index (with automatic persistence)
|
|
86
86
|
*/
|
|
87
87
|
export async function addToHNSWIndex(id, embedding, entry) {
|
|
88
|
-
// ADR-053: Try LanceDB memory bridge first
|
|
89
|
-
const bridge = await getBridge();
|
|
90
|
-
if (bridge) {
|
|
91
|
-
const bridgeResult = await bridge.bridgeAddToHNSW(id, embedding, entry);
|
|
92
|
-
if (bridgeResult === true)
|
|
93
|
-
return true;
|
|
94
|
-
}
|
|
95
88
|
const index = await getHNSWIndex({ dimensions: embedding.length });
|
|
96
89
|
if (!index)
|
|
97
90
|
return false;
|
|
@@ -115,13 +108,6 @@ export async function addToHNSWIndex(id, embedding, entry) {
|
|
|
115
108
|
* Returns results sorted by similarity (highest first)
|
|
116
109
|
*/
|
|
117
110
|
export async function searchHNSWIndex(queryEmbedding, options) {
|
|
118
|
-
// ADR-053: Try LanceDB memory bridge first
|
|
119
|
-
const bridge = await getBridge();
|
|
120
|
-
if (bridge) {
|
|
121
|
-
const bridgeResult = await bridge.bridgeSearchHNSW(queryEmbedding, options);
|
|
122
|
-
if (bridgeResult)
|
|
123
|
-
return bridgeResult;
|
|
124
|
-
}
|
|
125
111
|
const index = await getHNSWIndex({ dimensions: queryEmbedding.length });
|
|
126
112
|
if (!index)
|
|
127
113
|
return null;
|
|
@@ -320,7 +320,7 @@ export async function deleteEntry(options) {
|
|
|
320
320
|
if (bridgeResult.deleted) {
|
|
321
321
|
rebuildSearchIndex();
|
|
322
322
|
}
|
|
323
|
-
return bridgeResult;
|
|
323
|
+
return { ...bridgeResult, key: options.key, namespace: options.namespace ?? 'default', remainingEntries: 0 };
|
|
324
324
|
}
|
|
325
325
|
}
|
|
326
326
|
// Fallback: raw sql.js
|
|
@@ -65,8 +65,6 @@ INSERT OR REPLACE INTO metadata (key, value) VALUES
|
|
|
65
65
|
|
|
66
66
|
-- Create default vector index configuration
|
|
67
67
|
-- Dimensions match BRIDGE_EMBEDDING_DIMS=384 (Xenova/all-MiniLM-L6-v2).
|
|
68
|
-
-- 768 was a legacy value from the agentic-flow era; 384 is the actual
|
|
69
|
-
-- embedding size used by memory-bridge.ts and LanceDB.
|
|
70
68
|
INSERT OR IGNORE INTO vector_indexes (id, name, dimensions) VALUES
|
|
71
69
|
('default', 'default', 384),
|
|
72
70
|
('patterns', 'patterns', 384);
|
|
@@ -166,7 +166,16 @@ export async function listEntries(options) {
|
|
|
166
166
|
if (bridge) {
|
|
167
167
|
const bridgeResult = await bridge.bridgeListEntries(options);
|
|
168
168
|
if (bridgeResult)
|
|
169
|
-
return
|
|
169
|
+
return {
|
|
170
|
+
success: bridgeResult.success,
|
|
171
|
+
total: bridgeResult.total,
|
|
172
|
+
error: bridgeResult.error,
|
|
173
|
+
entries: bridgeResult.entries.map((e) => ({
|
|
174
|
+
id: e.id, key: e.key, namespace: e.namespace,
|
|
175
|
+
size: typeof e.content === 'string' ? e.content.length : 0,
|
|
176
|
+
accessCount: e.accessCount, createdAt: e.createdAt, updatedAt: e.updatedAt, hasEmbedding: e.hasEmbedding,
|
|
177
|
+
})),
|
|
178
|
+
};
|
|
170
179
|
}
|
|
171
180
|
// Fallback: raw sql.js
|
|
172
181
|
const { namespace, limit = 20, offset = 0, dbPath: customPath } = options;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monoes/monomindcli",
|
|
3
|
-
"version": "1.16.
|
|
3
|
+
"version": "1.16.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Monomind CLI - Enterprise AI agent orchestration with 60+ specialized agents, swarm coordination, MCP server, self-learning hooks, and vector memory for Claude Code",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -94,7 +94,6 @@
|
|
|
94
94
|
"optionalDependencies": {
|
|
95
95
|
"sql.js": "^1.14.1",
|
|
96
96
|
"@monoes/memory": "^1.0.0",
|
|
97
|
-
"agentic-flow": "^3.0.0-alpha.1",
|
|
98
97
|
"@huggingface/transformers": "^3.8.1",
|
|
99
98
|
"monofence-ai": "*",
|
|
100
99
|
"@monomind/hooks": "*",
|