monomind 1.16.1 → 1.16.3
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 +3 -2
- package/packages/@monomind/cli/dist/src/commands/daemon.js +5 -1
- package/packages/@monomind/cli/dist/src/commands/doctor.js +5 -1
- 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/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-read.js +10 -1
- package/packages/@monomind/cli/package.json +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "monomind",
|
|
3
|
-
"version": "1.16.
|
|
3
|
+
"version": "1.16.3",
|
|
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",
|
|
@@ -60,7 +60,8 @@
|
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
62
|
"semver": "^7.6.0",
|
|
63
|
-
"
|
|
63
|
+
"zod": "^3.22.0",
|
|
64
|
+
"@monoes/monograph": "^1.2.2",
|
|
64
65
|
"@monoes/monobrowse": "^1.0.0"
|
|
65
66
|
},
|
|
66
67
|
"overrides": {
|
|
@@ -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) {
|
|
@@ -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
|
}
|
|
@@ -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
|
|
@@ -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.3",
|
|
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",
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"dependencies": {
|
|
88
88
|
"ws": "^8.21.0",
|
|
89
89
|
"@noble/ed25519": "^2.1.0",
|
|
90
|
-
"@monoes/monograph": "^1.2.
|
|
90
|
+
"@monoes/monograph": "^1.2.2",
|
|
91
91
|
"@monoes/monobrowse": "^1.0.1",
|
|
92
92
|
"@monomind/security": "workspace:*"
|
|
93
93
|
},
|