@joshuaswarren/openclaw-engram 9.0.89 → 9.0.92
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/README.md +26 -1
- package/dist/{chunk-O4KLNIZ3.js → chunk-DDJJSZIV.js} +33 -4
- package/dist/chunk-DDJJSZIV.js.map +1 -0
- package/dist/{chunk-BNMGDMNG.js → chunk-LARLNIEW.js} +2 -2
- package/dist/{engine-DV7ASNS5.js → engine-A33VEWKG.js} +3 -3
- package/dist/index.js +525 -45
- package/dist/index.js.map +1 -1
- package/dist/{storage-BBRPVBJH.js → storage-IGAVYRWY.js} +2 -2
- package/package.json +4 -1
- package/dist/chunk-O4KLNIZ3.js.map +0 -1
- /package/dist/{chunk-BNMGDMNG.js.map → chunk-LARLNIEW.js.map} +0 -0
- /package/dist/{engine-DV7ASNS5.js.map → engine-A33VEWKG.js.map} +0 -0
- /package/dist/{storage-BBRPVBJH.js.map → storage-IGAVYRWY.js.map} +0 -0
package/README.md
CHANGED
|
@@ -134,7 +134,24 @@ Run the stdio MCP server:
|
|
|
134
134
|
openclaw engram access mcp-serve
|
|
135
135
|
```
|
|
136
136
|
|
|
137
|
-
Point your MCP client's command at `openclaw engram access mcp-serve`. Works with Claude Code, and any other MCP-compatible client. The server exposes the same
|
|
137
|
+
Point your MCP client's command at `openclaw engram access mcp-serve`. Works with Claude Code, and any other MCP-compatible client. The server exposes the same tools as the HTTP endpoint.
|
|
138
|
+
|
|
139
|
+
**Claude Code (MCP over HTTP):** Start the Engram HTTP server, then add to `~/.claude.json`:
|
|
140
|
+
|
|
141
|
+
```json
|
|
142
|
+
{
|
|
143
|
+
"mcpServers": {
|
|
144
|
+
"engram": {
|
|
145
|
+
"url": "http://localhost:4318/mcp",
|
|
146
|
+
"headers": {
|
|
147
|
+
"Authorization": "Bearer ${ENGRAM_TOKEN}"
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
See the [Standalone Server Guide](docs/guides/standalone-server.md) for multi-tenant setups and connecting multiple agent harnesses.
|
|
138
155
|
|
|
139
156
|
## How It Works
|
|
140
157
|
|
|
@@ -202,6 +219,10 @@ Use a preset to jump to a recommended level: `conservative`, `balanced`, `resear
|
|
|
202
219
|
- **Scripts & automation** — Authenticated REST API for custom integrations
|
|
203
220
|
- **Local LLMs** — Run extraction and reranking with local models (Ollama, LM Studio, etc.)
|
|
204
221
|
|
|
222
|
+
### Standalone Multi-Tenant Server
|
|
223
|
+
|
|
224
|
+
Run Engram as a standalone HTTP server that multiple agent harnesses share. Isolate tenants with namespace policies, feed conversations from any client via the observe endpoint, and search archived history with LCM full-text search. Works with OpenClaw, Codex CLI, Claude Code, and custom HTTP agents. See the [Standalone Server Guide](docs/guides/standalone-server.md).
|
|
225
|
+
|
|
205
226
|
### Built for production
|
|
206
227
|
|
|
207
228
|
- **672 tests** with CI enforcement
|
|
@@ -215,6 +236,7 @@ Use a preset to jump to a recommended level: `conservative`, `balanced`, `resear
|
|
|
215
236
|
### Core
|
|
216
237
|
|
|
217
238
|
- **Automatic memory extraction** — Facts, decisions, preferences, corrections extracted from conversations
|
|
239
|
+
- **Observe endpoint** — Feed conversation messages from any agent into the extraction pipeline via HTTP or MCP
|
|
218
240
|
- **Recall injection** — Relevant memories injected before each agent turn
|
|
219
241
|
- **Entity tracking** — People, projects, tools, companies tracked as structured entities
|
|
220
242
|
- **Lifecycle management** — Memories age through active, validated, stale, archived states
|
|
@@ -320,6 +342,8 @@ Available via both stdio and HTTP transports:
|
|
|
320
342
|
| `engram.suggestion_submit` | Queue a memory for review |
|
|
321
343
|
| `engram.entity_get` | Look up a known entity |
|
|
322
344
|
| `engram.review_queue_list` | View the governance review queue |
|
|
345
|
+
| `engram.observe` | Feed conversation messages into memory pipeline (LCM + extraction) |
|
|
346
|
+
| `engram.lcm_search` | Full-text search over LCM-archived conversations |
|
|
323
347
|
| `engram_context_search` | Full-text search across all archived conversation history (LCM) |
|
|
324
348
|
| `engram_context_describe` | Get a compressed summary of a turn range (LCM) |
|
|
325
349
|
| `engram_context_expand` | Retrieve raw lossless messages for a turn range (LCM) |
|
|
@@ -395,6 +419,7 @@ All settings live in `openclaw.json` under `plugins.entries.openclaw-engram.conf
|
|
|
395
419
|
- [Writing a Search Backend](docs/writing-a-search-backend.md) — Build your own adapter
|
|
396
420
|
- [API Reference](docs/api.md) — HTTP, MCP, and CLI documentation
|
|
397
421
|
- [Codex CLI Integration](docs/guides/codex-cli.md) — Setup Engram with OpenAI's Codex
|
|
422
|
+
- [Standalone Server Guide](docs/guides/standalone-server.md) — Multi-tenant HTTP server for multiple agent harnesses
|
|
398
423
|
- [Local LLM Guide](docs/guides/local-llm.md) — Local-first extraction and reranking
|
|
399
424
|
- [Cost Control Guide](docs/guides/cost-control.md) — Budget mappings and presets
|
|
400
425
|
- [Namespaces](docs/namespaces.md) — Multi-agent memory isolation
|
|
@@ -1216,9 +1216,29 @@ function serializeFrontmatter(fm) {
|
|
|
1216
1216
|
if (fm.sourceMemoryId) lines.push(`sourceMemoryId: ${fm.sourceMemoryId}`);
|
|
1217
1217
|
if (fm.sourceTurnId) lines.push(`sourceTurnId: ${fm.sourceTurnId}`);
|
|
1218
1218
|
if (fm.memoryKind) lines.push(`memoryKind: ${fm.memoryKind}`);
|
|
1219
|
+
if (fm.structuredAttributes && Object.keys(fm.structuredAttributes).length > 0) {
|
|
1220
|
+
lines.push(`structuredAttributes: ${JSON.stringify(fm.structuredAttributes)}`);
|
|
1221
|
+
}
|
|
1219
1222
|
lines.push("---");
|
|
1220
1223
|
return lines.join("\n");
|
|
1221
1224
|
}
|
|
1225
|
+
function parseStructuredAttributes(raw) {
|
|
1226
|
+
if (!raw || !raw.trim()) return void 0;
|
|
1227
|
+
try {
|
|
1228
|
+
const parsed = JSON.parse(raw);
|
|
1229
|
+
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
|
|
1230
|
+
const result = {};
|
|
1231
|
+
for (const [k, v] of Object.entries(parsed)) {
|
|
1232
|
+
if (typeof k === "string" && typeof v === "string") {
|
|
1233
|
+
result[k] = v;
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
1237
|
+
}
|
|
1238
|
+
} catch {
|
|
1239
|
+
}
|
|
1240
|
+
return void 0;
|
|
1241
|
+
}
|
|
1222
1242
|
function parseLinkReasonValue(rawValue) {
|
|
1223
1243
|
const legacyValue = rawValue.replace(/\\"/g, '"');
|
|
1224
1244
|
const looksLikeLegacyPath = !rawValue.includes("\\\\") && (/[A-Za-z]:\\[A-Za-z0-9._ -]+(?:\\[A-Za-z0-9._ -]+)*/.test(rawValue) || /\\[A-Za-z0-9._ -]+\\[A-Za-z0-9._ -]+/.test(rawValue));
|
|
@@ -1331,7 +1351,9 @@ function parseFrontmatter2(raw) {
|
|
|
1331
1351
|
sourceMemoryId: fm.sourceMemoryId || void 0,
|
|
1332
1352
|
sourceTurnId: fm.sourceTurnId || void 0,
|
|
1333
1353
|
// v8.0 Phase 2B: HiMem episode/note classification
|
|
1334
|
-
memoryKind: fm.memoryKind || void 0
|
|
1354
|
+
memoryKind: fm.memoryKind || void 0,
|
|
1355
|
+
// Structured attributes (JSON on a single line)
|
|
1356
|
+
structuredAttributes: parseStructuredAttributes(fm.structuredAttributes)
|
|
1335
1357
|
},
|
|
1336
1358
|
content
|
|
1337
1359
|
};
|
|
@@ -1812,9 +1834,16 @@ var StorageManager = class _StorageManager {
|
|
|
1812
1834
|
artifactType: options.artifactType,
|
|
1813
1835
|
sourceMemoryId: options.sourceMemoryId,
|
|
1814
1836
|
sourceTurnId: options.sourceTurnId,
|
|
1815
|
-
memoryKind: options.memoryKind
|
|
1837
|
+
memoryKind: options.memoryKind,
|
|
1838
|
+
structuredAttributes: options.structuredAttributes
|
|
1816
1839
|
};
|
|
1817
|
-
|
|
1840
|
+
let enrichedContent = content;
|
|
1841
|
+
if (options.structuredAttributes && Object.keys(options.structuredAttributes).length > 0) {
|
|
1842
|
+
const attrLines = Object.entries(options.structuredAttributes).map(([k, v]) => `${k}: ${v}`).join("; ");
|
|
1843
|
+
enrichedContent = `${content}
|
|
1844
|
+
[Attributes: ${attrLines}]`;
|
|
1845
|
+
}
|
|
1846
|
+
const sanitized = sanitizeMemoryContent(enrichedContent);
|
|
1818
1847
|
if (!sanitized.clean) {
|
|
1819
1848
|
log.warn(`memory content sanitized for ${id}; violations=${sanitized.violations.join(", ")}`);
|
|
1820
1849
|
}
|
|
@@ -3859,4 +3888,4 @@ export {
|
|
|
3859
3888
|
serializeEntityFile,
|
|
3860
3889
|
StorageManager
|
|
3861
3890
|
};
|
|
3862
|
-
//# sourceMappingURL=chunk-
|
|
3891
|
+
//# sourceMappingURL=chunk-DDJJSZIV.js.map
|