@lanonasis/recall-forge 1.1.1
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/.claw/skills/SKILL.md +347 -0
- package/CHANGELOG.md +162 -0
- package/LICENSE +21 -0
- package/README.md +302 -0
- package/SETUP.md +190 -0
- package/dist/cli-common.d.ts +25 -0
- package/dist/cli-common.js +338 -0
- package/dist/cli-memory.d.ts +6 -0
- package/dist/cli-memory.js +146 -0
- package/dist/cli.d.ts +7 -0
- package/dist/cli.js +135 -0
- package/dist/client.d.ts +116 -0
- package/dist/client.js +643 -0
- package/dist/config.d.ts +41 -0
- package/dist/config.js +125 -0
- package/dist/enrichment/capture-filter.d.ts +4 -0
- package/dist/enrichment/capture-filter.js +44 -0
- package/dist/enrichment/prompt-safety.d.ts +13 -0
- package/dist/enrichment/prompt-safety.js +83 -0
- package/dist/enrichment/tag-extractor.d.ts +1 -0
- package/dist/enrichment/tag-extractor.js +47 -0
- package/dist/enrichment/type-detector.d.ts +2 -0
- package/dist/enrichment/type-detector.js +95 -0
- package/dist/extraction/cli-extract.d.ts +8 -0
- package/dist/extraction/cli-extract.js +66 -0
- package/dist/extraction/format-adapters.d.ts +8 -0
- package/dist/extraction/format-adapters.js +268 -0
- package/dist/extraction/index.d.ts +7 -0
- package/dist/extraction/index.js +7 -0
- package/dist/extraction/jsonl-extractor.d.ts +32 -0
- package/dist/extraction/jsonl-extractor.js +207 -0
- package/dist/extraction/markdown-extractor.d.ts +23 -0
- package/dist/extraction/markdown-extractor.js +228 -0
- package/dist/extraction/secret-redactor.d.ts +7 -0
- package/dist/extraction/secret-redactor.js +112 -0
- package/dist/extraction/sqlite-extractor.d.ts +15 -0
- package/dist/extraction/sqlite-extractor.js +245 -0
- package/dist/extraction/types.d.ts +50 -0
- package/dist/extraction/types.js +1 -0
- package/dist/hooks/capture.d.ts +23 -0
- package/dist/hooks/capture.js +162 -0
- package/dist/hooks/context-engine.d.ts +4 -0
- package/dist/hooks/context-engine.js +54 -0
- package/dist/hooks/local-fallback.d.ts +5 -0
- package/dist/hooks/local-fallback.js +31 -0
- package/dist/hooks/recall.d.ts +21 -0
- package/dist/hooks/recall.js +123 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +103 -0
- package/dist/plugin-sdk-stub.d.ts +53 -0
- package/dist/plugin-sdk-stub.js +3 -0
- package/dist/privacy/privacy-guard.d.ts +33 -0
- package/dist/privacy/privacy-guard.js +130 -0
- package/dist/privacy/privacy-log.d.ts +6 -0
- package/dist/privacy/privacy-log.js +44 -0
- package/dist/tools/memory-forget.d.ts +3 -0
- package/dist/tools/memory-forget.js +109 -0
- package/dist/tools/memory-get.d.ts +3 -0
- package/dist/tools/memory-get.js +46 -0
- package/dist/tools/memory-search.d.ts +4 -0
- package/dist/tools/memory-search.js +95 -0
- package/dist/tools/memory-store.d.ts +5 -0
- package/dist/tools/memory-store.js +199 -0
- package/openclaw.plugin.json +315 -0
- package/package.json +90 -0
- package/setup/agents-memory.md +63 -0
- package/setup/heartbeat-memory.md +53 -0
- package/setup/install.sh +179 -0
package/README.md
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
# RecallForge
|
|
2
|
+
|
|
3
|
+
**Secret-safe memory and context engine for OpenClaw.**
|
|
4
|
+
|
|
5
|
+
RecallForge fills both OpenClaw plugin slots at once:
|
|
6
|
+
|
|
7
|
+
| Slot | What it does |
|
|
8
|
+
|------|-------------|
|
|
9
|
+
| `plugins.slots.memory` | Persists knowledge across sessions, devices, and agents via LanOnasis MaaS |
|
|
10
|
+
| `plugins.slots.contextEngine` | Builds and injects relevant context into the agent's prompt window on demand |
|
|
11
|
+
|
|
12
|
+
Every piece of content that enters either slot first passes through a 30-pattern secret redactor. Credentials, tokens, private keys, and connection strings are stripped before they reach memory storage or the context window — not as an afterthought, but as the first step in the pipeline.
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
openclaw plugins install @lanonasis/recall-forge
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
> **Expected install warning:** OpenClaw's static scanner flags any plugin that reads environment variables and makes network requests. You will see:
|
|
21
|
+
> ```
|
|
22
|
+
> WARNING: Environment variable access combined with network send — possible credential harvesting
|
|
23
|
+
> ```
|
|
24
|
+
> This is a false positive with a documented explanation. RecallForge reads exactly two `LANONASIS_*` environment variables and sends requests to `api.lanonasis.com` — the service you configured. The credential resolution chain is documented in the module JSDoc in `dist/client.js`. Source is on [GitHub](https://github.com/thefixer3x/lan-onasis-monorepo/tree/main/apps/lanonasis-maas/packages/recall-forge) if you want to verify.
|
|
25
|
+
|
|
26
|
+
## How it Works
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
User prompt
|
|
30
|
+
│
|
|
31
|
+
▼
|
|
32
|
+
[contextEngine] buildContext(session)
|
|
33
|
+
│ Tiered semantic search: personal → shared namespace
|
|
34
|
+
│ Prompt injection filter
|
|
35
|
+
│ Secret redaction (30+ patterns)
|
|
36
|
+
│ Character budget enforcement
|
|
37
|
+
▼
|
|
38
|
+
Injected context block prepended to prompt
|
|
39
|
+
│
|
|
40
|
+
▼
|
|
41
|
+
Agent runs
|
|
42
|
+
│
|
|
43
|
+
▼
|
|
44
|
+
[memory] capture hook (agent_end / before_compaction)
|
|
45
|
+
│
|
|
46
|
+
├─ Privacy Guard — Stage 1: secret-redactor (30 patterns — always-on)
|
|
47
|
+
├─ Privacy Guard — Stage 2: privacy-sdk PII detection/masking
|
|
48
|
+
│ SSN, email, credit card, IBAN, passport, DOB, phone, IP...
|
|
49
|
+
│ Confidence threshold: 0.85 | Luhn + area-code validation
|
|
50
|
+
│ GDPR / CCPA / HIPAA / PCI-DSS compliance tagging
|
|
51
|
+
│
|
|
52
|
+
│ Capture filter (removes low-signal content)
|
|
53
|
+
│ Type detection + tag extraction + privacy tags
|
|
54
|
+
│ Vector dedup (0.985 threshold)
|
|
55
|
+
│ Privacy metadata written to memory.metadata
|
|
56
|
+
▼
|
|
57
|
+
Memory stored in LanOnasis MaaS
|
|
58
|
+
│
|
|
59
|
+
├─ [if localFallback] workspace/memory/YYYY-MM-DD.md (already sanitized)
|
|
60
|
+
└─ [if privacyNotifyUrl] webhook POST — privacy.intervention event
|
|
61
|
+
(action, piiTypes, regulations, timestamp — never content)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The recall hook (`before_agent_start`) and contextEngine are two separate integration surfaces. The recall hook is passive and event-driven. The contextEngine is active — OpenClaw calls `buildContext()` whenever it needs to assemble context, giving RecallForge a direct seat in prompt construction.
|
|
65
|
+
|
|
66
|
+
### Privacy Shield — What Gets Protected and Where You See It
|
|
67
|
+
|
|
68
|
+
Every memory that passes through a write path is scanned. When an intervention occurs:
|
|
69
|
+
|
|
70
|
+
**On the stored memory** (visible in `openclaw recall list` and `openclaw recall get <id>`):
|
|
71
|
+
```
|
|
72
|
+
Tags: pii:email privacy:redacted compliant:gdpr
|
|
73
|
+
Metadata: privacy.action = "redacted+masked"
|
|
74
|
+
privacy.piiTypes = ["email"]
|
|
75
|
+
privacy.regulations = ["GDPR", "CCPA"]
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**In the daily audit log** (`workspace/memory/privacy/YYYY-MM-DD.md`):
|
|
79
|
+
```markdown
|
|
80
|
+
| Time | Action | Secrets | PII Types | Sensitivity | Regulations |
|
|
81
|
+
|----------|-----------------|---------|-----------|-------------|-------------|
|
|
82
|
+
| 14:23:01 | redacted+masked | 1 | email | high | GDPR, CCPA |
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Via webhook** (if `privacyNotifyUrl` is set):
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"event": "privacy.intervention",
|
|
89
|
+
"plugin": "recall-forge",
|
|
90
|
+
"action": "redacted+masked",
|
|
91
|
+
"piiTypes": ["email"],
|
|
92
|
+
"regulations": ["GDPR", "CCPA"],
|
|
93
|
+
"timestamp": "2026-03-26T14:23:01Z"
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## What Gets Redacted
|
|
98
|
+
|
|
99
|
+
Before content enters memory or context:
|
|
100
|
+
|
|
101
|
+
| Category | Examples |
|
|
102
|
+
|----------|---------|
|
|
103
|
+
| Anthropic keys | `sk-ant-api03-...` |
|
|
104
|
+
| OpenAI keys | `sk-proj-...`, `sk-...` |
|
|
105
|
+
| GitHub tokens | `ghp_...`, `github_pat_...`, `gho_...`, `ghs_...` |
|
|
106
|
+
| Supabase keys | `sbp_...`, `sba_...` |
|
|
107
|
+
| Stripe keys | `sk_live_...`, `pk_live_...`, `sk_test_...`, `whsec_...` |
|
|
108
|
+
| AWS access keys | `AKIA...` |
|
|
109
|
+
| Google API keys | `AIzaSy...` |
|
|
110
|
+
| Notion tokens | `ntn_...`, `secret_...` |
|
|
111
|
+
| LanOnasis keys | `lano_...`, `lns_...` |
|
|
112
|
+
| JWT tokens | `eyJ...` three-part format |
|
|
113
|
+
| PEM private keys | `-----BEGIN ... PRIVATE KEY-----` blocks |
|
|
114
|
+
| Database URLs | `postgres://user:pass@host/db`, `mysql://...`, etc. |
|
|
115
|
+
| Bearer tokens | `Bearer <40+ char token>` |
|
|
116
|
+
| Env assignments | `API_KEY=value`, `export SECRET=value` |
|
|
117
|
+
| Hex secrets | 64+ character hex strings |
|
|
118
|
+
| ElevenLabs keys | `el_...` |
|
|
119
|
+
| Telegram bots | `123456789:AbCdEfGh...` |
|
|
120
|
+
|
|
121
|
+
Matched values are replaced with `[REDACTED_<TYPE>]`. The redaction runs before any network call.
|
|
122
|
+
|
|
123
|
+
## Configuration
|
|
124
|
+
|
|
125
|
+
Set credentials in `~/.openclaw/.env`:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
LANONASIS_API_KEY=your_key
|
|
129
|
+
LANONASIS_PROJECT_ID=your_project_id
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Or in `~/.openclaw/openclaw.json`:
|
|
133
|
+
|
|
134
|
+
```json
|
|
135
|
+
{
|
|
136
|
+
"plugins": {
|
|
137
|
+
"allow": ["recall-forge"],
|
|
138
|
+
"slots": {
|
|
139
|
+
"memory": "recall-forge",
|
|
140
|
+
"contextEngine": "recall-forge"
|
|
141
|
+
},
|
|
142
|
+
"entries": {
|
|
143
|
+
"recall-forge": {
|
|
144
|
+
"enabled": true,
|
|
145
|
+
"config": {
|
|
146
|
+
"apiKey": "YOUR_LANONASIS_API_KEY",
|
|
147
|
+
"projectId": "YOUR_PROJECT_ID",
|
|
148
|
+
"agentId": "main",
|
|
149
|
+
"captureMode": "hybrid",
|
|
150
|
+
"autoRecall": true,
|
|
151
|
+
"localFallback": true,
|
|
152
|
+
"searchThreshold": 0.75,
|
|
153
|
+
"dedupeThreshold": 0.985,
|
|
154
|
+
"maxRecallResults": 5,
|
|
155
|
+
"maxRecallChars": 1500,
|
|
156
|
+
"memoryMode": "hybrid",
|
|
157
|
+
"sharedNamespace": "",
|
|
158
|
+
"syncMode": "realtime"
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Config Reference
|
|
167
|
+
|
|
168
|
+
| Field | Default | Description |
|
|
169
|
+
|-------|---------|-------------|
|
|
170
|
+
| `apiKey` | — | **Required.** LanOnasis API key |
|
|
171
|
+
| `projectId` | — | **Required.** Project ID from dashboard |
|
|
172
|
+
| `baseUrl` | `https://api.lanonasis.com` | API base URL |
|
|
173
|
+
| `agentId` | `main` | Tags memories with this agent ID |
|
|
174
|
+
| `autoRecall` | `true` | Inject memories before each session via recall hook |
|
|
175
|
+
| `recallMode` | `auto` | `auto`: inject automatically. `ondemand`: disable auto-injection, tools still available |
|
|
176
|
+
| `maxRecallChars` | `1500` | Hard cap on injected recall characters. Use `400–600` for Ollama/small-context models |
|
|
177
|
+
| `maxRecallResults` | `5` | Max memories returned per recall |
|
|
178
|
+
| `captureMode` | `hybrid` | `auto`: capture everything. `hybrid`: stricter filter. `explicit`: agent calls `memory_store` directly |
|
|
179
|
+
| `localFallback` | `true` | Write Markdown copies to `workspace/memory/YYYY-MM-DD.md` |
|
|
180
|
+
| `searchThreshold` | `0.75` | Minimum similarity score for recall results. Raise to `0.80` to reduce noise |
|
|
181
|
+
| `dedupeThreshold` | `0.985` | Similarity threshold for `memory_store` duplicate detection |
|
|
182
|
+
| `memoryMode` | `hybrid` | `remote`: cloud only. `local`: filesystem only. `hybrid`: cloud primary with local fallback |
|
|
183
|
+
| `sharedNamespace` | — | Cross-agent shared memory namespace. Empty = disabled |
|
|
184
|
+
| `syncMode` | `realtime` | `realtime`: immediate writes. `batch`: deferred. `manual`: explicit only |
|
|
185
|
+
| `embeddingProvider` | — | Provider for vector embeddings (e.g. `openai`, `ollama`) |
|
|
186
|
+
| `embeddingModel` | — | Embedding model name (e.g. `text-embedding-3-small`) |
|
|
187
|
+
| `embeddingProfileId` | — | Stamped into stored memories for mismatch detection |
|
|
188
|
+
| `privacyMode` | `mask` | PII protection: `mask` (detect + mask), `detect` (scan + tag only), `off` (credentials only) |
|
|
189
|
+
| `privacyLocale` | `US` | PII locale hint: `US`, `UK`, `EU`, `DE`, `FR`, `JP`, `AU`, `CA` |
|
|
190
|
+
| `privacyNotifyUrl` | — | Webhook URL for out-of-band privacy intervention events |
|
|
191
|
+
|
|
192
|
+
## Context Window Management
|
|
193
|
+
|
|
194
|
+
The contextEngine and recall hook both respect `maxRecallChars`. For **Ollama and small-context models**:
|
|
195
|
+
|
|
196
|
+
```json
|
|
197
|
+
"recallMode": "ondemand",
|
|
198
|
+
"maxRecallChars": 500,
|
|
199
|
+
"searchThreshold": 0.80,
|
|
200
|
+
"maxRecallResults": 3
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
`recallMode: "ondemand"` disables the automatic recall hook. The contextEngine continues to respond to on-demand calls from OpenClaw. Memory tools remain available for manual recall.
|
|
204
|
+
|
|
205
|
+
## Wiring Agent Guidance
|
|
206
|
+
|
|
207
|
+
After install, append the memory snippet to your workspace AGENTS.md:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
cat "$(openclaw plugins path recall-forge)/setup/agents-memory.md" >> ~/.openclaw/workspace/AGENTS.md
|
|
211
|
+
cat "$(openclaw plugins path recall-forge)/setup/heartbeat-memory.md" >> ~/.openclaw/workspace/HEARTBEAT.md
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## CLI
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
openclaw recall status
|
|
218
|
+
openclaw recall create --title "Title" --content "Content"
|
|
219
|
+
openclaw recall get <id-or-prefix>
|
|
220
|
+
openclaw recall update <id-or-prefix> --title "Updated"
|
|
221
|
+
openclaw recall delete <id-or-prefix> --force
|
|
222
|
+
openclaw recall search "query" --threshold 0.7 --type knowledge --tags alpha,beta
|
|
223
|
+
openclaw recall list --page 1 --sort created_at --order desc
|
|
224
|
+
openclaw recall stats
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
The CLI accepts full UUIDs or unambiguous 8+ character prefixes for `get`, `update`, and `delete`.
|
|
228
|
+
|
|
229
|
+
## Extraction
|
|
230
|
+
|
|
231
|
+
Import memories from existing session logs, Markdown docs, or SQLite databases. All extraction passes through the same secret redaction pipeline before storing.
|
|
232
|
+
|
|
233
|
+
**JSONL formats** (auto-detected):
|
|
234
|
+
- `openclaw-session` — nested `{ type: "message", message: { role, content[] } }` session logs
|
|
235
|
+
- `openclaw-cache` — cache-trace records
|
|
236
|
+
- `claude-code` — flat `{ role, content }` session logs
|
|
237
|
+
- `codex` — `{ type: "message", sender }` format
|
|
238
|
+
- `generic` — fallback for any JSON with text fields
|
|
239
|
+
|
|
240
|
+
**Document formats** (auto-detected by extension):
|
|
241
|
+
- `markdown` — `.md` / `.mdx` files, splits by heading sections
|
|
242
|
+
- `sqlite` — `.sqlite` / `.db` files, reads the OpenClaw `chunks` table
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
openclaw recall extract ~/.openclaw/agents/main/sessions/sample.jsonl --dry-run
|
|
246
|
+
openclaw recall extract ~/.openclaw/workspace/SOUL.md --dry-run
|
|
247
|
+
openclaw recall extract ~/.openclaw/memory/main.sqlite --dry-run
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Agent Tools
|
|
251
|
+
|
|
252
|
+
RecallForge registers four tools always available to the agent:
|
|
253
|
+
|
|
254
|
+
| Tool | Description |
|
|
255
|
+
|------|-------------|
|
|
256
|
+
| `memory_search` | Semantic search through stored memories |
|
|
257
|
+
| `memory_get` | Fetch full memory by ID |
|
|
258
|
+
| `memory_store` | Store or update a memory (with auto-dedup) |
|
|
259
|
+
| `memory_forget` | Delete a memory by ID |
|
|
260
|
+
|
|
261
|
+
## Cross-Agent Memory
|
|
262
|
+
|
|
263
|
+
When `sharedNamespace` is configured, recall uses a tiered strategy:
|
|
264
|
+
|
|
265
|
+
1. **Personal** — search scoped to `agentId`
|
|
266
|
+
2. **Shared** — search scoped to `sharedNamespace`
|
|
267
|
+
3. **Deduplicate** — merge by memory ID, personal takes priority
|
|
268
|
+
4. **Cap** — trim to `maxRecallResults`, sorted by similarity
|
|
269
|
+
|
|
270
|
+
Capture routes `knowledge`, `project`, and `reference` type memories to the shared namespace automatically.
|
|
271
|
+
|
|
272
|
+
## Verification
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
npm run typecheck
|
|
276
|
+
npm run test
|
|
277
|
+
npm run build
|
|
278
|
+
npm run pack:dry-run
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
For local testing without publishing:
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
cd apps/lanonasis-maas/packages/recall-forge
|
|
285
|
+
npm run build
|
|
286
|
+
openclaw plugins install "$(pwd)" --link --force
|
|
287
|
+
openclaw recall status
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## Publish
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
npm run verify:release
|
|
294
|
+
npm publish --access public
|
|
295
|
+
git tag recall-forge-v$(node -p "require('./package.json').version")
|
|
296
|
+
git push origin main --follow-tags
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## More Docs
|
|
300
|
+
|
|
301
|
+
- [SETUP.md](./SETUP.md) — operator setup guide
|
|
302
|
+
- [CHANGELOG.md](./CHANGELOG.md) — release history
|
package/SETUP.md
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# RecallForge — Operator Setup Guide
|
|
2
|
+
|
|
3
|
+
RecallForge adds cloud-backed semantic memory and a context engine to OpenClaw via LanOnasis MaaS. It registers in both the `memory` and `contextEngine` plugin slots.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- OpenClaw `2026.3.1` or newer
|
|
8
|
+
- A LanOnasis API key ([dashboard](https://app.lanonasis.com))
|
|
9
|
+
- A LanOnasis project ID
|
|
10
|
+
|
|
11
|
+
## Install From npm
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
openclaw plugins install @lanonasis/recall-forge
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Then configure in `~/.openclaw/openclaw.json` (see below), or through the OpenClaw install flow if your UI supports manifest prompts.
|
|
18
|
+
|
|
19
|
+
## Local Development Install
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
cd apps/lanonasis-maas/packages/recall-forge
|
|
23
|
+
npm install
|
|
24
|
+
npm run build
|
|
25
|
+
openclaw plugins install "$(pwd)" --link
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
After editing source files, re-run `npm run build` before testing — `dist/` must stay current.
|
|
29
|
+
|
|
30
|
+
Or use the helper script:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
bash setup/install.sh
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Minimal Configuration
|
|
37
|
+
|
|
38
|
+
Add to `~/.openclaw/openclaw.json`:
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"plugins": {
|
|
43
|
+
"allow": ["recall-forge"],
|
|
44
|
+
"slots": {
|
|
45
|
+
"memory": "recall-forge",
|
|
46
|
+
"contextEngine": "recall-forge"
|
|
47
|
+
},
|
|
48
|
+
"entries": {
|
|
49
|
+
"recall-forge": {
|
|
50
|
+
"enabled": true,
|
|
51
|
+
"config": {
|
|
52
|
+
"apiKey": "YOUR_LANONASIS_API_KEY",
|
|
53
|
+
"projectId": "YOUR_PROJECT_ID",
|
|
54
|
+
"captureMode": "hybrid",
|
|
55
|
+
"localFallback": true,
|
|
56
|
+
"autoRecall": true,
|
|
57
|
+
"agentId": "main",
|
|
58
|
+
"dedupeThreshold": 0.985,
|
|
59
|
+
"privacyMode": "mask",
|
|
60
|
+
"privacyLocale": "US"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Note: Both slots (`memory` and `contextEngine`) must point to `recall-forge` for full dual-slot functionality.
|
|
69
|
+
|
|
70
|
+
Optional: add `privacyNotifyUrl` to route intervention events to Slack, n8n, or any webhook receiver:
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
"privacyNotifyUrl": "https://hooks.slack.com/services/YOUR/HOOK/URL"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Verify the Install
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
openclaw recall status
|
|
80
|
+
openclaw recall create --title "RecallForge test" --content "Hello from RecallForge"
|
|
81
|
+
openclaw recall list --page 1 --sort created_at --order desc
|
|
82
|
+
openclaw recall stats
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Expected behavior:
|
|
86
|
+
- `status` — prints connection status, project ID, and server version
|
|
87
|
+
- `create` — prints stored memory ID, title, type, tags, and preview
|
|
88
|
+
- `list` — prints a table of memories
|
|
89
|
+
- `stats` — prints server-side memory stats
|
|
90
|
+
|
|
91
|
+
## Workspace Snippets
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
cat "$(openclaw plugins path recall-forge)/setup/agents-memory.md" >> ~/.openclaw/workspace/AGENTS.md
|
|
95
|
+
cat "$(openclaw plugins path recall-forge)/setup/heartbeat-memory.md" >> ~/.openclaw/workspace/HEARTBEAT.md
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## CLI Commands
|
|
99
|
+
|
|
100
|
+
Core CRUD:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
openclaw recall create --title "..." --content "..."
|
|
104
|
+
openclaw recall get <id-or-prefix>
|
|
105
|
+
openclaw recall update <id-or-prefix> --title "..."
|
|
106
|
+
openclaw recall delete <id-or-prefix> --force
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Search and listing:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
openclaw recall search "query" --threshold 0.7 --type knowledge --tags alpha,beta
|
|
113
|
+
openclaw recall list --page 1 --sort created_at --order desc --tags alpha,beta
|
|
114
|
+
openclaw recall stats
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Extraction (secret-redacted before storing):
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
openclaw recall extract ./sessions.jsonl --dry-run
|
|
121
|
+
openclaw recall extract ./SOUL.md --dry-run
|
|
122
|
+
openclaw recall extract ~/.openclaw/memory/main.sqlite --dry-run
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Confirming Dual-Slot Registration
|
|
126
|
+
|
|
127
|
+
When the plugin loads successfully, the startup log shows both slots:
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
[recall-forge] Ready — slots: memory+contextEngine | mode: hybrid | memory: hybrid | recall: active | shared: off | fallback: true | privacy: mask | project: <project-id>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
If only the memory slot is needed, remove `"contextEngine": "recall-forge"` from the slots config — the contextEngine will still be registered internally, but OpenClaw will not route context-build calls to it.
|
|
134
|
+
|
|
135
|
+
## Secret Redaction Verification
|
|
136
|
+
|
|
137
|
+
To confirm credential redaction is active before a UAT run:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
openclaw recall create \
|
|
141
|
+
--title "Redaction test" \
|
|
142
|
+
--content "API_KEY=sk-ant-api03-test123456789012345678 postgres://user:password123@localhost/db"
|
|
143
|
+
openclaw recall list --page 1
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
The stored memory content should show `[REDACTED_ENV_SECRET]` and `[REDACTED_DATABASE_URL]` — not the original values.
|
|
147
|
+
|
|
148
|
+
## Privacy Guard Verification
|
|
149
|
+
|
|
150
|
+
To confirm the PII layer is active:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
openclaw recall create \
|
|
154
|
+
--title "PII test" \
|
|
155
|
+
--content "Contact john.doe@example.com or call +1-555-123-4567 for support."
|
|
156
|
+
openclaw recall get <id-from-above>
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Expected:
|
|
160
|
+
- `content` shows `j******e@example.com` and masked phone
|
|
161
|
+
- `tags` includes `pii:email`, `pii:phone`
|
|
162
|
+
- `metadata.privacy.action` is `"masked"`
|
|
163
|
+
- `metadata.privacy.regulations` includes `["GDPR", "CCPA"]`
|
|
164
|
+
|
|
165
|
+
To check the daily audit log:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
cat ~/.openclaw/workspace/memory/privacy/$(date +%Y-%m-%d).md
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
To test webhook delivery (replace with your endpoint):
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
# Add to config temporarily:
|
|
175
|
+
# "privacyNotifyUrl": "https://webhook.site/your-test-id"
|
|
176
|
+
openclaw recall create --title "Webhook test" --content "SSN: 123-45-6789"
|
|
177
|
+
# Check your webhook.site inbox for the privacy.intervention event
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Publish Checklist
|
|
181
|
+
|
|
182
|
+
Before publishing a new version:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
npm run typecheck
|
|
186
|
+
npm run build
|
|
187
|
+
npm pack --dry-run
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
The tarball must contain `dist/`, `openclaw.plugin.json`, setup assets, README, CHANGELOG, and LICENSE. No `.env` files, local configs, or workspace data.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { LanListSortField, LanMemory, LanMemoryStats, LanMemoryType, LanSortOrder } from "./client.js";
|
|
2
|
+
export declare const MEMORY_TYPES: LanMemoryType[];
|
|
3
|
+
export declare function exitWithError(error: unknown): never;
|
|
4
|
+
export declare function isNotFoundError(error: unknown): boolean;
|
|
5
|
+
export declare function normalizeTextInput(label: string, value: string | undefined): string | undefined;
|
|
6
|
+
export declare function resolveContentInput(options: {
|
|
7
|
+
content?: string;
|
|
8
|
+
contentFile?: string;
|
|
9
|
+
required?: boolean;
|
|
10
|
+
}): Promise<string | undefined>;
|
|
11
|
+
export declare function parseTags(input: string | undefined): string[] | undefined;
|
|
12
|
+
export declare function parsePositiveInt(flag: string, raw: string | undefined, defaultValue?: number): number | undefined;
|
|
13
|
+
export declare function parseThreshold(raw: string | undefined): number | undefined;
|
|
14
|
+
export declare function parseMemoryType(raw: string | undefined, flag?: string): LanMemoryType | undefined;
|
|
15
|
+
export declare function parseSortField(raw: string | undefined): LanListSortField | undefined;
|
|
16
|
+
export declare function parseSortOrder(raw: string | undefined): LanSortOrder | undefined;
|
|
17
|
+
export declare function requireMemoryId(id: string): string;
|
|
18
|
+
export declare function requireUpdateFields(updates: Record<string, unknown>, message?: string): void;
|
|
19
|
+
export declare function formatPreview(content: string, maxLength?: number): string;
|
|
20
|
+
export declare function memoryTypeOf(memory: LanMemory): string;
|
|
21
|
+
export declare function similarityOf(memory: LanMemory): number | undefined;
|
|
22
|
+
export declare function printMemorySummary(memory: LanMemory, heading: string): void;
|
|
23
|
+
export declare function printMemoryDetail(memory: LanMemory): void;
|
|
24
|
+
export declare function assertMemoryStatsShape(stats: unknown): LanMemoryStats;
|
|
25
|
+
export declare function printMemoryStats(stats: LanMemoryStats): void;
|