moflo 4.8.80-rc.7 → 4.8.81
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/.claude/agents/sparc/pseudocode.md +2 -2
- package/.claude/guidance/shipped/moflo-core-guidance.md +3 -3
- package/.claude/skills/memory-optimization/SKILL.md +121 -0
- package/.claude/skills/memory-patterns/SKILL.md +136 -0
- package/.claude/skills/reasoningbank-intelligence/SKILL.md +98 -151
- package/.claude/skills/v3-security-overhaul/SKILL.md +0 -10
- package/.claude/skills/vector-search/SKILL.md +141 -0
- package/bin/session-start-launcher.mjs +14 -2
- package/package.json +15 -10
- package/src/modules/cli/dist/src/commands/doctor-checks-deep.js +48 -0
- package/src/modules/cli/dist/src/commands/doctor.js +4 -44
- package/src/modules/cli/dist/src/commands/embeddings.js +1 -1
- package/src/modules/cli/dist/src/commands/hooks.js +45 -118
- package/src/modules/cli/dist/src/commands/mcp.js +3 -47
- package/src/modules/cli/dist/src/commands/plugins.js +0 -1
- package/src/modules/cli/dist/src/commands/start.js +3 -16
- package/src/modules/cli/dist/src/commands/status.js +4 -11
- package/src/modules/cli/dist/src/config-adapter.js +3 -7
- package/src/modules/cli/dist/src/index.js +27 -2
- package/src/modules/cli/dist/src/init/executor.js +0 -6
- package/src/modules/cli/dist/src/mcp-client.js +3 -3
- package/src/modules/cli/dist/src/mcp-server.js +11 -137
- package/src/modules/cli/dist/src/mcp-tools/{aidefence-agentdb-store.js → aidefence-moflodb-store.js} +7 -7
- package/src/modules/cli/dist/src/mcp-tools/hooks-tools.js +16 -18
- package/src/modules/cli/dist/src/mcp-tools/{agentdb-tools.js → moflodb-tools.js} +101 -84
- package/src/modules/cli/dist/src/mcp-tools/neural-tools.js +14 -33
- package/src/modules/cli/dist/src/mcp-tools/security-tools.js +5 -5
- package/src/modules/cli/dist/src/mcp-tools/system-tools.js +8 -46
- package/src/modules/cli/dist/src/memory/bridge-core.js +323 -0
- package/src/modules/cli/dist/src/memory/bridge-entries.js +394 -0
- package/src/modules/cli/dist/src/memory/memory-bridge.js +230 -1336
- package/src/modules/cli/dist/src/memory/memory-initializer.js +13 -43
- package/src/modules/cli/dist/src/movector/enhanced-model-router.js +1 -17
- package/src/modules/cli/dist/src/services/moflo-require.js +36 -5
- package/src/modules/cli/dist/src/update/validator.js +0 -1
- package/src/modules/cli/dist/src/version.js +1 -1
- package/src/modules/cli/package.json +2 -4
- package/src/modules/embeddings/package.json +2 -3
- package/src/modules/hooks/dist/reasoningbank/index.js +49 -41
- package/src/modules/memory/dist/agent-memory-scope.js +1 -1
- package/src/modules/memory/dist/auto-memory-bridge.js +12 -12
- package/src/modules/memory/dist/cache-manager.js +18 -0
- package/src/modules/memory/dist/controller-registry.js +125 -703
- package/src/modules/memory/dist/controller-spec.js +11 -0
- package/src/modules/memory/dist/controller-specs.js +50 -0
- package/src/modules/memory/dist/controllers/_shared.js +174 -0
- package/src/modules/memory/dist/controllers/attestation-log.js +165 -0
- package/src/modules/memory/dist/controllers/batch-operations.js +186 -0
- package/src/modules/memory/dist/controllers/causal-graph.js +154 -0
- package/src/modules/memory/dist/controllers/causal-recall.js +115 -0
- package/src/modules/memory/dist/controllers/context-synthesizer.js +118 -0
- package/src/modules/memory/dist/controllers/hierarchical-memory.js +447 -0
- package/src/modules/memory/dist/controllers/learning-system.js +209 -0
- package/src/modules/memory/dist/controllers/memory-consolidation.js +96 -0
- package/src/modules/memory/dist/controllers/mutation-guard.js +116 -0
- package/src/modules/memory/dist/controllers/nightly-learner.js +127 -0
- package/src/modules/memory/dist/controllers/placeholder-specs.js +22 -0
- package/src/modules/memory/dist/controllers/reflexion.js +214 -0
- package/src/modules/memory/dist/controllers/semantic-router.js +194 -0
- package/src/modules/memory/dist/controllers/skills.js +237 -0
- package/src/modules/memory/dist/controllers/types.js +9 -0
- package/src/modules/memory/dist/database-provider.js +2 -2
- package/src/modules/memory/dist/index.js +7 -7
- package/src/modules/memory/dist/infrastructure/index.js +1 -1
- package/src/modules/memory/dist/infrastructure/repositories/hybrid-memory-repository.js +3 -3
- package/src/modules/memory/dist/learning-bridge.js +17 -1
- package/src/modules/memory/dist/memory-graph.js +18 -0
- package/src/modules/memory/dist/migration.js +1 -1
- package/src/modules/memory/dist/{agentdb-adapter.js → moflo-db-adapter.js} +9 -8
- package/src/modules/memory/dist/rvf-migration.js +2 -2
- package/src/modules/memory/dist/sqljs-backend.js +65 -22
- package/src/modules/memory/dist/types.js +1 -1
- package/src/modules/memory/package.json +0 -1
- package/src/modules/neural/dist/reasoning-bank.js +100 -93
- package/src/modules/neural/package.json +0 -3
- package/src/modules/security/dist/CVE-REMEDIATION.js +3 -28
- package/src/modules/security/dist/index.js +0 -29
- package/src/modules/security/dist/input-validator.js +0 -1
- package/src/modules/security/package.json +0 -2
- package/src/modules/shared/dist/core/config/loader.js +4 -14
- package/src/modules/shared/dist/core/config/schema.js +4 -4
- package/src/modules/shared/dist/mcp/index.js +2 -6
- package/src/modules/shared/dist/mcp/server.js +2 -30
- package/src/modules/shared/dist/mcp/session-manager.js +0 -22
- package/src/modules/shared/dist/mcp/transport/index.js +0 -41
- package/src/modules/shared/dist/mcp/types.js +1 -4
- package/src/modules/shared/package.json +0 -7
- package/src/modules/spells/dist/commands/wait-command.js +19 -11
- package/.claude/skills/agentdb-advanced/SKILL.md +0 -550
- package/.claude/skills/agentdb-learning/SKILL.md +0 -545
- package/.claude/skills/agentdb-memory-patterns/SKILL.md +0 -339
- package/.claude/skills/agentdb-optimization/SKILL.md +0 -509
- package/.claude/skills/agentdb-vector-search/SKILL.md +0 -339
- package/.claude/skills/reasoningbank-agentdb/SKILL.md +0 -446
- package/src/modules/cli/dist/src/services/agentic-flow-bridge.js +0 -105
- package/src/modules/memory/dist/agentdb-backend.js +0 -842
- package/src/modules/security/dist/password-hasher.js +0 -183
- package/src/modules/shared/dist/mcp/connection-pool.js +0 -364
- package/src/modules/shared/dist/mcp/transport/http.js +0 -476
- package/src/modules/shared/dist/mcp/transport/websocket.js +0 -396
- package/src/modules/spells/dist/connectors/graph-auth.js +0 -167
|
@@ -58,7 +58,7 @@ BEGIN
|
|
|
58
58
|
END IF
|
|
59
59
|
|
|
60
60
|
// Verify password
|
|
61
|
-
isValid ←
|
|
61
|
+
isValid ← CredentialStore.verify(password, user.passwordHash)
|
|
62
62
|
|
|
63
63
|
IF NOT isValid THEN
|
|
64
64
|
// Log failed attempt
|
|
@@ -225,7 +225,7 @@ ANALYSIS: User Authentication Flow
|
|
|
225
225
|
Time Complexity:
|
|
226
226
|
- Email validation: O(1)
|
|
227
227
|
- Database lookup: O(log n) with index
|
|
228
|
-
- Password verification: O(1) - fixed
|
|
228
|
+
- Password verification: O(1) - fixed-cost hash compare
|
|
229
229
|
- Session creation: O(1)
|
|
230
230
|
- Total: O(log n)
|
|
231
231
|
|
|
@@ -149,7 +149,7 @@ This gives Claude access to 200+ MCP tools (`mcp__moflo__memory_*`, `mcp__moflo_
|
|
|
149
149
|
| `init` | 4 | Project initialization with wizard, presets, skills, hooks |
|
|
150
150
|
| `agent` | 8 | Agent lifecycle (spawn, list, status, stop, metrics, pool, health, logs) |
|
|
151
151
|
| `swarm` | 6 | Multi-agent swarm coordination and orchestration |
|
|
152
|
-
| `memory` | 11 |
|
|
152
|
+
| `memory` | 11 | sql.js + HNSW vector search, 150x-12,500x faster |
|
|
153
153
|
| `mcp` | 9 | MCP server management and tool execution |
|
|
154
154
|
| `task` | 6 | Task creation, assignment, and lifecycle |
|
|
155
155
|
| `session` | 7 | Session state management and persistence |
|
|
@@ -535,7 +535,7 @@ auto_index:
|
|
|
535
535
|
|
|
536
536
|
# Memory backend
|
|
537
537
|
memory:
|
|
538
|
-
backend: sql.js # sql.js (WASM) |
|
|
538
|
+
backend: sql.js # sql.js (WASM) | json
|
|
539
539
|
embedding_model: Xenova/all-MiniLM-L6-v2 # 384-dim neural embeddings
|
|
540
540
|
namespace: default # Default namespace for memory operations
|
|
541
541
|
|
|
@@ -582,7 +582,7 @@ status_line:
|
|
|
582
582
|
show_mcp: true # MCP server count
|
|
583
583
|
show_security: true # CVE/security status (dashboard only)
|
|
584
584
|
show_adrs: true # ADR compliance (dashboard only)
|
|
585
|
-
show_agentdb: true #
|
|
585
|
+
show_agentdb: true # MofloDb vectors/size (dashboard only)
|
|
586
586
|
show_tests: true # Test file count (dashboard only)
|
|
587
587
|
|
|
588
588
|
# Spell step sandboxing (OS-level process isolation for bash steps)
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "memory-optimization"
|
|
3
|
+
description: "Tune moflo's memory stack for speed, RAM, and index quality. Covers HNSW parameters (M, efConstruction, ef), vector quantization, batch operations, and common bottlenecks. Use when scaling past ~100k entries or when search latency regresses."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# MoFlo Memory Optimization
|
|
7
|
+
|
|
8
|
+
When the default `@moflo/memory` settings stop being enough — past ~100k entries, or when p95 search latency climbs — these are the levers.
|
|
9
|
+
|
|
10
|
+
## HNSW Parameters
|
|
11
|
+
|
|
12
|
+
HNSW has three knobs. They trade build time, query time, memory, and recall.
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
import { HNSWIndex } from '@moflo/memory';
|
|
16
|
+
|
|
17
|
+
const index = new HNSWIndex({
|
|
18
|
+
dimensions: 1536, // must match your embedding model
|
|
19
|
+
maxElements: 1_000_000, // pre-allocated capacity
|
|
20
|
+
M: 16, // graph connectivity (default 16)
|
|
21
|
+
efConstruction: 200, // build-time search width (default 200)
|
|
22
|
+
metric: 'cosine', // 'cosine' | 'l2' | 'ip'
|
|
23
|
+
});
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
| Knob | Higher | Lower | When to change |
|
|
27
|
+
|------|--------|-------|----------------|
|
|
28
|
+
| `M` | better recall, more RAM (~2×M pointers per point) | less RAM, worse recall | Bump to 32–64 if recall@10 < 0.95; drop to 8 if memory-bound |
|
|
29
|
+
| `efConstruction` | better index quality, slower build | faster build, worse queries | 200–400 is sweet spot; only lower in test fixtures |
|
|
30
|
+
| `ef` (search-time, passed to `search()`) | better recall, slower queries | faster queries, worse recall | Start at 2×k, raise until recall plateaus |
|
|
31
|
+
|
|
32
|
+
Rule of thumb: `M` and `efConstruction` are set once. `ef` is the runtime dial.
|
|
33
|
+
|
|
34
|
+
## Quantization
|
|
35
|
+
|
|
36
|
+
`@moflo/memory` supports scalar quantization (Float32 → Int8) for a ~4× memory reduction with a ~1-2% recall hit. Turn it on when the index doesn't fit comfortably in RAM.
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
const index = new HNSWIndex({
|
|
40
|
+
dimensions: 1536,
|
|
41
|
+
maxElements: 5_000_000,
|
|
42
|
+
quantization: {
|
|
43
|
+
enabled: true,
|
|
44
|
+
type: 'scalar', // scalar (Int8) is the supported path
|
|
45
|
+
rebuildThreshold: 10_000,
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Measure recall before/after on your own query distribution — public benchmarks don't predict your domain.
|
|
51
|
+
|
|
52
|
+
## Batch Operations
|
|
53
|
+
|
|
54
|
+
Single-entry writes pay the HNSW insert cost per call. For bulk ingest, batch:
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
const entries: Array<[string, Float32Array]> = buildCorpus();
|
|
58
|
+
|
|
59
|
+
// Parallelise at the adapter level; don't await sequentially.
|
|
60
|
+
await Promise.all(
|
|
61
|
+
entries.map(([id, vec]) => index.addPoint(id, vec))
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
// Or via MCP for moflo-native batch into .swarm/memory.db:
|
|
65
|
+
await mcp.memory_store(/* … */); // upsert: true + Promise.all is fine
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
For >10k entries, prefer `bin/build-embeddings.mjs` / `bin/index-all.mjs` — they stream in batches with a progress bar and skip unchanged chunks via a hash file.
|
|
69
|
+
|
|
70
|
+
## Caching
|
|
71
|
+
|
|
72
|
+
`MofloDbAdapter` has a built-in LRU cache (default 10k entries, 5-min TTL):
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { MofloDbAdapter } from '@moflo/memory';
|
|
76
|
+
|
|
77
|
+
const store = new MofloDbAdapter({
|
|
78
|
+
cacheEnabled: true,
|
|
79
|
+
cacheSize: 50_000, // scale with working set, not total corpus
|
|
80
|
+
cacheTtl: 10 * 60_000, // 10 minutes
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Cache hits on exact keys bypass HNSW entirely. If your workload is read-heavy and hits a narrow keyspace, this is the cheapest win.
|
|
85
|
+
|
|
86
|
+
## Measuring
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
npx vitest bench src/modules/memory/benchmarks/vector-search.bench.ts
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
The bench prints linear vs HNSW times for 1k and 10k vectors. Run it before and after any parameter change — "it felt faster" is not a benchmark.
|
|
93
|
+
|
|
94
|
+
For production memory stats:
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
const stats = await mcp.memory_stats({});
|
|
98
|
+
// { entryCount, indexSize, cacheHitRate, avgSearchMs, … }
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Common Bottlenecks
|
|
102
|
+
|
|
103
|
+
| Symptom | Likely cause | Fix |
|
|
104
|
+
|---------|--------------|-----|
|
|
105
|
+
| Cold-start of 5s on first search | HNSW loading from disk | Share a single instance via `beforeAll` in tests; keep the adapter resident in long-running processes |
|
|
106
|
+
| Search latency climbs linearly with `limit` | Over-fetching and re-ranking on the hot path | Lower `limit`; raise `threshold` to prune |
|
|
107
|
+
| Inserts slow past ~100k entries | `maxElements` too close to entry count → reallocation | Set `maxElements` to 2× expected corpus |
|
|
108
|
+
| High RSS on a small corpus | Vector dimension mismatch with index | Confirm `dimensions` matches embedder output (OpenAI = 1536, local models vary) |
|
|
109
|
+
|
|
110
|
+
## Anti-Patterns
|
|
111
|
+
|
|
112
|
+
- **Don't rebuild the index on every test.** Use a module-level singleton + `beforeAll`. HNSW cold-boot is ~5s.
|
|
113
|
+
- **Don't raise `ef` globally.** Raise it on the specific queries that need recall. Default is fine for 90% of calls.
|
|
114
|
+
- **Don't quantize a small corpus.** Below ~500k vectors the RAM saving doesn't justify the recall cost.
|
|
115
|
+
- **Don't measure in dev mode.** sql.js WASM behaves differently under `NODE_ENV=production`; benches should match the target.
|
|
116
|
+
|
|
117
|
+
## See Also
|
|
118
|
+
|
|
119
|
+
- `memory-patterns` skill — API usage and namespace design
|
|
120
|
+
- `vector-search` skill — RAG-specific patterns on top of the optimized index
|
|
121
|
+
- `src/modules/memory/benchmarks/` — runnable benches for every knob above
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "memory-patterns"
|
|
3
|
+
description: "Persistent memory patterns for moflo agents — session memory, long-term knowledge, pattern learning, and cross-session context via moflo's sql.js + HNSW vector store. Use when building stateful agents or assistants that need to remember across runs."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# MoFlo Memory Patterns
|
|
7
|
+
|
|
8
|
+
Persistent, semantically-searchable memory for moflo-enabled projects. Backed by `.swarm/memory.db` (sql.js + HNSW vector index) and exposed through MCP tools.
|
|
9
|
+
|
|
10
|
+
## Core API
|
|
11
|
+
|
|
12
|
+
Three things to know:
|
|
13
|
+
|
|
14
|
+
1. **MCP tools** — call from Claude Code sessions:
|
|
15
|
+
- `mcp__moflo__memory_store { key, value, namespace?, tags?, ttl?, upsert? }`
|
|
16
|
+
- `mcp__moflo__memory_search { query, namespace?, limit?, threshold? }` — semantic, HNSW-backed
|
|
17
|
+
- `mcp__moflo__memory_retrieve { key, namespace? }` — exact key lookup
|
|
18
|
+
- `mcp__moflo__memory_list { namespace?, limit? }`
|
|
19
|
+
- `mcp__moflo__memory_delete { key, namespace? }`
|
|
20
|
+
- `mcp__moflo__memory_stats {}`
|
|
21
|
+
|
|
22
|
+
2. **CLI** — `flo-search "<query>" --namespace <ns>` for quick semantic lookup from the shell.
|
|
23
|
+
|
|
24
|
+
3. **Namespaces** — namespace + key is the unique identity. Default namespaces shipped by moflo: `knowledge`, `patterns`, `guidance`, `code-map`. Create your own for application memory (e.g. `app:sessions`, `app:users`).
|
|
25
|
+
|
|
26
|
+
## Pattern 1: Session Memory
|
|
27
|
+
|
|
28
|
+
Rolling per-conversation memory with TTL so old sessions expire:
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
// Store a turn
|
|
32
|
+
await mcp.memory_store({
|
|
33
|
+
namespace: 'app:sessions',
|
|
34
|
+
key: `${sessionId}:msg:${turnIndex}`,
|
|
35
|
+
value: { role, content, ts: Date.now() },
|
|
36
|
+
ttl: 60 * 60 * 24 * 7, // 7 days
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Recall the session — keys sort lexicographically, so prefixing with
|
|
40
|
+
// sessionId groups a conversation.
|
|
41
|
+
const all = await mcp.memory_list({ namespace: 'app:sessions' });
|
|
42
|
+
const current = all.filter(t => t.key.startsWith(`${sessionId}:`));
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Why namespace-per-use: search scope stays small and delete-by-namespace becomes `memory_list` + `memory_delete` in a loop.
|
|
46
|
+
|
|
47
|
+
## Pattern 2: Long-Term Knowledge
|
|
48
|
+
|
|
49
|
+
Facts that should survive any session and be findable by meaning, not exact key:
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
await mcp.memory_store({
|
|
53
|
+
namespace: 'knowledge',
|
|
54
|
+
key: 'auth:session-token-rotation',
|
|
55
|
+
value: 'Session tokens are rotated every 15 minutes by the auth middleware. Refresh happens transparently on the client.',
|
|
56
|
+
tags: ['auth', 'security'],
|
|
57
|
+
upsert: true,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// Retrieval: semantic, not keyword
|
|
61
|
+
const hits = await mcp.memory_search({
|
|
62
|
+
namespace: 'knowledge',
|
|
63
|
+
query: 'how do auth tokens refresh?',
|
|
64
|
+
limit: 5,
|
|
65
|
+
threshold: 0.4,
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`upsert: true` is the norm — you're updating your own knowledge, not guarding against collisions.
|
|
70
|
+
|
|
71
|
+
## Pattern 3: Pattern Learning (store + promote)
|
|
72
|
+
|
|
73
|
+
Capture what worked, then let the next run find it:
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
// After a successful task
|
|
77
|
+
await mcp.memory_store({
|
|
78
|
+
namespace: 'patterns',
|
|
79
|
+
key: `${patternType}:${shortHash(signature)}`,
|
|
80
|
+
value: {
|
|
81
|
+
signature, // what triggered this
|
|
82
|
+
approach, // what you did
|
|
83
|
+
outcome: 'success', // how it landed
|
|
84
|
+
occurrences: 1,
|
|
85
|
+
},
|
|
86
|
+
tags: [patternType],
|
|
87
|
+
upsert: true,
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// Before starting a similar task
|
|
91
|
+
const similar = await mcp.memory_search({
|
|
92
|
+
namespace: 'patterns',
|
|
93
|
+
query: currentTaskDescription,
|
|
94
|
+
limit: 3,
|
|
95
|
+
threshold: 0.5,
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
On repeated hits, read the existing entry, increment `occurrences`, and `upsert`.
|
|
100
|
+
|
|
101
|
+
## Pattern 4: Context Recall at Prompt Start
|
|
102
|
+
|
|
103
|
+
moflo's gate hooks enforce "search memory before exploring files." Mirror that in your own agents:
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
async function beforeTask(description: string) {
|
|
107
|
+
const [guidance, patterns, codeMap] = await Promise.all([
|
|
108
|
+
mcp.memory_search({ namespace: 'guidance', query: description, limit: 5 }),
|
|
109
|
+
mcp.memory_search({ namespace: 'patterns', query: description, limit: 5 }),
|
|
110
|
+
mcp.memory_search({ namespace: 'code-map', query: description, limit: 8 }),
|
|
111
|
+
]);
|
|
112
|
+
return { guidance, patterns, codeMap };
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
This is the same fan-out the `/flo` spell does — cheap (HNSW, parallel) and replaces a lot of exploratory Glob/Grep.
|
|
117
|
+
|
|
118
|
+
## Anti-Patterns
|
|
119
|
+
|
|
120
|
+
- **Don't put large blobs in `value`.** Store pointers/keys — the embedding is built from the value string, and huge values bloat the index.
|
|
121
|
+
- **Don't search without a namespace.** Cross-namespace search mixes `guidance` (prose) with `patterns` (structured) — signal collapses.
|
|
122
|
+
- **Don't use sequential numeric keys** if you also want semantic search over them. Pick keys humans/agents would search for by meaning.
|
|
123
|
+
- **Don't use `ttl` on knowledge you want long-lived.** TTL is for sessions, ephemeral cache, WIP notes.
|
|
124
|
+
|
|
125
|
+
## Persistence & Indexing
|
|
126
|
+
|
|
127
|
+
- File: `.swarm/memory.db` at project root (sql.js).
|
|
128
|
+
- Embeddings: built by `@moflo/embeddings`; indexed with HNSW from `@moflo/memory`.
|
|
129
|
+
- Cold-start cost: ~5 seconds to initialize HNSW. Tests should share a single instance (`beforeAll`, not `beforeEach`).
|
|
130
|
+
- Namespace isolation: each namespace is a logical partition, but the HNSW index spans the table. Query time scales with `limit` and `threshold`, not total row count.
|
|
131
|
+
|
|
132
|
+
## See Also
|
|
133
|
+
|
|
134
|
+
- `vector-search` skill — RAG patterns over your own documents
|
|
135
|
+
- `memory-optimization` skill — HNSW tuning, quantization, batch ops
|
|
136
|
+
- `.claude/guidance/shipped/moflo-core-guidance.md` — CLI/MCP reference
|
|
@@ -1,201 +1,148 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: "reasoningbank-intelligence"
|
|
3
|
-
description: "
|
|
3
|
+
description: "Adaptive learning for moflo agents via ReasoningBank: trajectory storage, verdict judgment, memory distillation, consolidation, and MMR retrieval. Use when building agents that should improve from experience across runs."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# ReasoningBank Intelligence
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
Implements ReasoningBank's adaptive learning system for AI agents to learn from experience, recognize patterns, and optimize strategies over time. Enables meta-cognitive capabilities and continuous improvement.
|
|
8
|
+
Trajectory-based learning pipeline for moflo-enabled agents. Records what an agent did, judges the outcome, distills successful runs into reusable patterns, and retrieves relevant prior experience on the next task.
|
|
11
9
|
|
|
12
10
|
## Prerequisites
|
|
13
11
|
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
- Node.js 18+
|
|
12
|
+
- `@moflo/neural` (ships with moflo)
|
|
13
|
+
- Moflo's memory DB at `.swarm/memory.db` (created on first run)
|
|
17
14
|
|
|
18
15
|
## Quick Start
|
|
19
16
|
|
|
20
17
|
```typescript
|
|
21
|
-
import {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
18
|
+
import { createInitializedReasoningBank } from '@moflo/neural';
|
|
19
|
+
|
|
20
|
+
const rb = await createInitializedReasoningBank({
|
|
21
|
+
namespace: 'reasoning-bank',
|
|
22
|
+
vectorDimension: 768,
|
|
23
|
+
retrievalK: 3,
|
|
24
|
+
mmrLambda: 0.7, // 0=pure relevance, 1=pure diversity
|
|
25
|
+
distillationThreshold: 0.6, // min verdict score to keep
|
|
26
|
+
dedupThreshold: 0.95,
|
|
28
27
|
});
|
|
28
|
+
```
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
await rb.recordExperience({
|
|
32
|
-
task: 'code_review',
|
|
33
|
-
approach: 'static_analysis_first',
|
|
34
|
-
outcome: {
|
|
35
|
-
success: true,
|
|
36
|
-
metrics: {
|
|
37
|
-
bugs_found: 5,
|
|
38
|
-
time_taken: 120,
|
|
39
|
-
false_positives: 1
|
|
40
|
-
}
|
|
41
|
-
},
|
|
42
|
-
context: {
|
|
43
|
-
language: 'typescript',
|
|
44
|
-
complexity: 'medium'
|
|
45
|
-
}
|
|
46
|
-
});
|
|
30
|
+
## The Pipeline
|
|
47
31
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
32
|
+
Four stages. You typically call each once per task:
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
1. Record trajectory → storeTrajectory({ id, input, actions, outcome, reward, ... })
|
|
36
|
+
2. Judge → const verdict = await rb.judge(trajectory)
|
|
37
|
+
3. Distill → const memory = await rb.distill(trajectory) // if verdict good enough
|
|
38
|
+
4. Retrieve (next task) → const hits = await rb.retrieveByContent(query, k)
|
|
53
39
|
```
|
|
54
40
|
|
|
55
|
-
|
|
41
|
+
### 1. Record
|
|
56
42
|
|
|
57
|
-
### 1. Pattern Recognition
|
|
58
43
|
```typescript
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
44
|
+
const trajectory = {
|
|
45
|
+
id: taskId,
|
|
46
|
+
input: userRequest,
|
|
47
|
+
actions: ['read_file', 'edit_file', 'run_tests'],
|
|
48
|
+
outcome: 'success' as const,
|
|
49
|
+
reward: 1.0, // 0..1
|
|
50
|
+
metadata: { toolCalls: 3, durationMs: 1800 },
|
|
51
|
+
timestamp: new Date(),
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
rb.storeTrajectory(trajectory);
|
|
69
55
|
```
|
|
70
56
|
|
|
71
|
-
### 2.
|
|
57
|
+
### 2. Judge
|
|
58
|
+
|
|
59
|
+
The built-in judge scores on outcome + reward + action-step quality. No external LLM call.
|
|
60
|
+
|
|
72
61
|
```typescript
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
'tdd_approach',
|
|
76
|
-
'debug_first',
|
|
77
|
-
'reproduce_then_fix'
|
|
78
|
-
]);
|
|
79
|
-
|
|
80
|
-
// Get best strategy
|
|
81
|
-
const best = comparison.strategies[0];
|
|
82
|
-
console.log(`Best: ${best.name} (score: ${best.score})`);
|
|
62
|
+
const verdict = await rb.judge(trajectory);
|
|
63
|
+
// { score: 0-1, outcome: 'success' | ..., reasoning: string }
|
|
83
64
|
```
|
|
84
65
|
|
|
85
|
-
|
|
66
|
+
Swap in your own judge by extending `ReasoningBank` if you want LLM-in-the-loop scoring — this was designed as a rule-based baseline so the hot path stays cheap.
|
|
67
|
+
|
|
68
|
+
### 3. Distill
|
|
69
|
+
|
|
70
|
+
Compresses a trajectory into a reusable `DistilledMemory` (signature, approach, outcome-tagged). Skips if the verdict is below `distillationThreshold`.
|
|
71
|
+
|
|
86
72
|
```typescript
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
threshold: 0.7, // Only learn from high-confidence outcomes
|
|
90
|
-
updateFrequency: 100 // Update models every 100 experiences
|
|
91
|
-
});
|
|
73
|
+
const memory = await rb.distill(trajectory);
|
|
74
|
+
// null if verdict below threshold → not worth learning from
|
|
92
75
|
```
|
|
93
76
|
|
|
94
|
-
|
|
77
|
+
For batch runs (nightly, offline replay):
|
|
95
78
|
|
|
96
|
-
### Meta-Learning
|
|
97
79
|
```typescript
|
|
98
|
-
|
|
99
|
-
await rb.metaLearn({
|
|
100
|
-
observation: 'parallel_execution_faster_for_independent_tasks',
|
|
101
|
-
confidence: 0.95,
|
|
102
|
-
applicability: {
|
|
103
|
-
task_types: ['batch_processing', 'data_transformation'],
|
|
104
|
-
conditions: ['tasks_independent', 'io_bound']
|
|
105
|
-
}
|
|
106
|
-
});
|
|
80
|
+
const memories = await rb.distillBatch(trajectories);
|
|
107
81
|
```
|
|
108
82
|
|
|
109
|
-
###
|
|
83
|
+
### 4. Retrieve
|
|
84
|
+
|
|
85
|
+
Query by text (embedding generated for you) or by pre-computed vector:
|
|
86
|
+
|
|
110
87
|
```typescript
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
from: 'code_review_javascript',
|
|
114
|
-
to: 'code_review_typescript',
|
|
115
|
-
similarity: 0.8
|
|
116
|
-
});
|
|
88
|
+
const hits = await rb.retrieveByContent(newTaskDescription, 5);
|
|
89
|
+
// [{ memory, relevanceScore, diversityScore, combinedScore }]
|
|
117
90
|
```
|
|
118
91
|
|
|
119
|
-
|
|
92
|
+
MMR (maximal marginal relevance) prevents the top-K from collapsing to "five slight variations of the same thing" — tune `mmrLambda` to push more diversity.
|
|
93
|
+
|
|
94
|
+
## Consolidation
|
|
95
|
+
|
|
96
|
+
Memory quality degrades over time without maintenance. Run consolidation periodically (once a week, once after N new entries, etc.):
|
|
97
|
+
|
|
120
98
|
```typescript
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
async execute(task: Task) {
|
|
124
|
-
// Get optimal strategy
|
|
125
|
-
const strategy = await rb.recommendStrategy(task.type, task.context);
|
|
126
|
-
|
|
127
|
-
// Execute with strategy
|
|
128
|
-
const result = await this.executeWithStrategy(task, strategy);
|
|
129
|
-
|
|
130
|
-
// Learn from outcome
|
|
131
|
-
await rb.recordExperience({
|
|
132
|
-
task: task.type,
|
|
133
|
-
approach: strategy.name,
|
|
134
|
-
outcome: result,
|
|
135
|
-
context: task.context
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
return result;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
99
|
+
const result = await rb.consolidate();
|
|
100
|
+
// { removedDuplicates, contradictionsDetected, prunedPatterns, mergedPatterns }
|
|
141
101
|
```
|
|
142
102
|
|
|
143
|
-
|
|
103
|
+
Consolidation:
|
|
104
|
+
- Removes duplicates above `dedupThreshold` similarity.
|
|
105
|
+
- Detects contradictions (same signature, opposite outcomes) if `enableContradictionDetection`.
|
|
106
|
+
- Prunes entries older than `maxPatternAgeDays`.
|
|
107
|
+
- Merges semantically-adjacent patterns.
|
|
144
108
|
|
|
145
|
-
|
|
146
|
-
// Persist ReasoningBank data
|
|
147
|
-
await rb.configure({
|
|
148
|
-
storage: {
|
|
149
|
-
type: 'agentdb',
|
|
150
|
-
options: {
|
|
151
|
-
database: './reasoning-bank.db',
|
|
152
|
-
enableVectorSearch: true
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
});
|
|
109
|
+
## Persistence
|
|
156
110
|
|
|
157
|
-
|
|
158
|
-
const patterns = await rb.query({
|
|
159
|
-
category: 'optimization',
|
|
160
|
-
minConfidence: 0.8,
|
|
161
|
-
timeRange: { last: '30d' }
|
|
162
|
-
});
|
|
163
|
-
```
|
|
111
|
+
ReasoningBank persists through `MofloDbAdapter` to `.swarm/memory.db`. Set `enableMofloDb: false` for ephemeral in-memory use (tests).
|
|
164
112
|
|
|
165
|
-
|
|
113
|
+
The `namespace` config isolates reasoning-bank entries from general memory. Default is `reasoning-bank`.
|
|
166
114
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
Improvement Over Time: ${metrics.improvement}
|
|
175
|
-
`);
|
|
176
|
-
```
|
|
115
|
+
## Anti-Patterns
|
|
116
|
+
|
|
117
|
+
- **Don't record every step as a separate trajectory.** A trajectory = one task. Steps are a field inside the trajectory.
|
|
118
|
+
- **Don't skip the judge.** Distilling every trajectory poisons the pool with failures — that's what `distillationThreshold` guards against.
|
|
119
|
+
- **Don't run consolidation on the hot path.** It's a sweep — do it out-of-band.
|
|
120
|
+
- **Don't share `namespace` between different agent roles.** Keep `reasoning-bank:reviewer`, `reasoning-bank:researcher`, etc. separate; signatures overlap otherwise.
|
|
121
|
+
- **Don't raise `retrievalK` to tame bad retrieval.** Tune `mmrLambda` or the embedder instead — more K just dilutes the top results.
|
|
177
122
|
|
|
178
|
-
##
|
|
123
|
+
## Integration with moflo's Hooks
|
|
179
124
|
|
|
180
|
-
|
|
181
|
-
2. **Provide context**: Rich context improves pattern matching
|
|
182
|
-
3. **Set thresholds**: Filter low-confidence learnings
|
|
183
|
-
4. **Review periodically**: Audit learned patterns for quality
|
|
184
|
-
5. **Use vector search**: Enable semantic pattern matching
|
|
125
|
+
Moflo's session/hook system already wires ReasoningBank into the `/flo` spell and the SubAgentStart hook. If you're building a custom agent that should participate, hook into `post-task`:
|
|
185
126
|
|
|
186
|
-
|
|
127
|
+
```typescript
|
|
128
|
+
await mcp.hooks_post_task({
|
|
129
|
+
trajectoryId: taskId,
|
|
130
|
+
outcome: 'success',
|
|
131
|
+
reward: 1.0,
|
|
132
|
+
});
|
|
133
|
+
```
|
|
187
134
|
|
|
188
|
-
|
|
189
|
-
**Solution**: Ensure sufficient training data (100+ experiences per task type)
|
|
135
|
+
That records, judges, and distills in one call.
|
|
190
136
|
|
|
191
|
-
|
|
192
|
-
**Solution**: Enable vector indexing in AgentDB
|
|
137
|
+
## Performance
|
|
193
138
|
|
|
194
|
-
|
|
195
|
-
|
|
139
|
+
- Retrieve (k=5, corpus of 10k): ~3–8ms.
|
|
140
|
+
- Distill: single call ≈ vector embed + a few similarity checks; ~10–50ms.
|
|
141
|
+
- Consolidate: O(n²) in the namespace — run offline for corpora > 10k.
|
|
196
142
|
|
|
197
|
-
##
|
|
143
|
+
## See Also
|
|
198
144
|
|
|
199
|
-
-
|
|
200
|
-
-
|
|
201
|
-
-
|
|
145
|
+
- `memory-patterns` skill — for non-trajectory memory (sessions, knowledge)
|
|
146
|
+
- `memory-optimization` skill — HNSW tuning, quantization
|
|
147
|
+
- `src/modules/neural/src/reasoning-bank.ts` — full API
|
|
148
|
+
- `src/modules/neural/src/domain/services/learning-service.ts` — trajectory types
|
|
@@ -26,16 +26,6 @@ npm update @anthropic-ai/claude-code@^2.0.31
|
|
|
26
26
|
npm audit --audit-level high
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
### CVE-2: Weak Password Hashing
|
|
30
|
-
```typescript
|
|
31
|
-
// ❌ Old: SHA-256 with hardcoded salt
|
|
32
|
-
const hash = crypto.createHash('sha256').update(password + salt).digest('hex');
|
|
33
|
-
|
|
34
|
-
// ✅ New: bcrypt with 12 rounds
|
|
35
|
-
import bcrypt from 'bcrypt';
|
|
36
|
-
const hash = await bcrypt.hash(password, 12);
|
|
37
|
-
```
|
|
38
|
-
|
|
39
29
|
### CVE-3: Hardcoded Credentials
|
|
40
30
|
```typescript
|
|
41
31
|
// ✅ Generate secure random credentials
|