@agentmemory/agentmemory 0.9.13 → 0.9.15
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 +23 -21
- package/dist/cli.mjs +1612 -113
- package/dist/cli.mjs.map +1 -1
- package/dist/connect-hRTF7E2c.mjs +525 -0
- package/dist/connect-hRTF7E2c.mjs.map +1 -0
- package/dist/{image-refs-HVu22rfu.mjs → image-refs-R3tin9MR.mjs} +2 -2
- package/dist/{image-refs-HVu22rfu.mjs.map → image-refs-R3tin9MR.mjs.map} +1 -1
- package/dist/{image-store-BfN1vDbj.mjs → image-store-DyrKZKqZ.mjs} +1 -1
- package/dist/index.mjs +63 -35
- package/dist/index.mjs.map +1 -1
- package/dist/{src-Ca9oX6Hq.mjs → src-BGcqJR1a.mjs} +62 -72
- package/dist/src-BGcqJR1a.mjs.map +1 -0
- package/dist/{standalone-BpbiNqr9.mjs → standalone-BQOaGF4z.mjs} +3 -3
- package/dist/{standalone-BpbiNqr9.mjs.map → standalone-BQOaGF4z.mjs.map} +1 -1
- package/dist/standalone.mjs +1 -1
- package/dist/standalone.mjs.map +1 -1
- package/dist/{tools-registry-D5l632PP.mjs → tools-registry-BF0pgZmI.mjs} +2 -6
- package/dist/tools-registry-BF0pgZmI.mjs.map +1 -0
- package/package.json +6 -6
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/dist/src-Ca9oX6Hq.mjs.map +0 -1
- package/dist/tools-registry-D5l632PP.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1452,6 +1452,17 @@ const logger = {
|
|
|
1452
1452
|
emit("error", msg, fields);
|
|
1453
1453
|
}
|
|
1454
1454
|
};
|
|
1455
|
+
let bootVerbose = process.env["AGENTMEMORY_VERBOSE"] === "1" || process.env["AGENTMEMORY_VERBOSE"] === "true";
|
|
1456
|
+
const bootBuffer = [];
|
|
1457
|
+
function bootLog(msg) {
|
|
1458
|
+
if (bootVerbose) {
|
|
1459
|
+
try {
|
|
1460
|
+
process.stderr.write(`[agentmemory] ${msg}\n`);
|
|
1461
|
+
} catch {}
|
|
1462
|
+
return;
|
|
1463
|
+
}
|
|
1464
|
+
if (bootBuffer.length < 500) bootBuffer.push(msg);
|
|
1465
|
+
}
|
|
1455
1466
|
|
|
1456
1467
|
//#endregion
|
|
1457
1468
|
//#region src/functions/query-expansion.ts
|
|
@@ -5956,7 +5967,7 @@ function registerAutoForgetFunction(sdk, kv) {
|
|
|
5956
5967
|
|
|
5957
5968
|
//#endregion
|
|
5958
5969
|
//#region src/version.ts
|
|
5959
|
-
const VERSION = "0.9.
|
|
5970
|
+
const VERSION = "0.9.15";
|
|
5960
5971
|
|
|
5961
5972
|
//#endregion
|
|
5962
5973
|
//#region src/functions/export-import.ts
|
|
@@ -6087,7 +6098,9 @@ function registerExportImportFunction(sdk, kv) {
|
|
|
6087
6098
|
"0.9.10",
|
|
6088
6099
|
"0.9.11",
|
|
6089
6100
|
"0.9.12",
|
|
6090
|
-
"0.9.13"
|
|
6101
|
+
"0.9.13",
|
|
6102
|
+
"0.9.14",
|
|
6103
|
+
"0.9.15"
|
|
6091
6104
|
]).has(importData.version)) return {
|
|
6092
6105
|
success: false,
|
|
6093
6106
|
error: `Unsupported export version: ${importData.version}`
|
|
@@ -19394,8 +19407,10 @@ function readBody(req) {
|
|
|
19394
19407
|
req.on("error", reject);
|
|
19395
19408
|
});
|
|
19396
19409
|
}
|
|
19410
|
+
const MAX_VIEWER_PORT_RETRIES = 10;
|
|
19397
19411
|
function startViewerServer(port, _kv, _sdk, secret, restPort) {
|
|
19398
19412
|
const resolvedRestPort = restPort ?? port - 2;
|
|
19413
|
+
const requestedPort = port;
|
|
19399
19414
|
const server = createServer(async (req, res) => {
|
|
19400
19415
|
const raw = req.url || "/";
|
|
19401
19416
|
const qIdx = raw.indexOf("?");
|
|
@@ -19432,13 +19447,26 @@ function startViewerServer(port, _kv, _sdk, secret, restPort) {
|
|
|
19432
19447
|
json(res, 502, { error: "upstream error" }, req);
|
|
19433
19448
|
}
|
|
19434
19449
|
});
|
|
19450
|
+
let attempt = 0;
|
|
19451
|
+
let currentPort = requestedPort;
|
|
19452
|
+
const tryListen = () => {
|
|
19453
|
+
server.listen(currentPort, "127.0.0.1");
|
|
19454
|
+
};
|
|
19455
|
+
server.on("listening", () => {
|
|
19456
|
+
if (currentPort === requestedPort) console.log(`[agentmemory] Viewer: http://localhost:${currentPort}`);
|
|
19457
|
+
else console.log(`[agentmemory] Viewer started on http://localhost:${currentPort} (fallback from ${requestedPort})`);
|
|
19458
|
+
});
|
|
19435
19459
|
server.on("error", (err) => {
|
|
19436
|
-
if (err.code === "EADDRINUSE"
|
|
19460
|
+
if (err.code === "EADDRINUSE" && attempt < MAX_VIEWER_PORT_RETRIES) {
|
|
19461
|
+
attempt++;
|
|
19462
|
+
currentPort = requestedPort + attempt;
|
|
19463
|
+
setImmediate(tryListen);
|
|
19464
|
+
return;
|
|
19465
|
+
}
|
|
19466
|
+
if (err.code === "EADDRINUSE") console.warn(`[agentmemory] Viewer ports ${requestedPort}-${requestedPort + MAX_VIEWER_PORT_RETRIES} all in use, skipping viewer.`);
|
|
19437
19467
|
else console.error(`[agentmemory] Viewer error:`, err.message);
|
|
19438
19468
|
});
|
|
19439
|
-
|
|
19440
|
-
console.log(`[agentmemory] Viewer: http://localhost:${port}`);
|
|
19441
|
-
});
|
|
19469
|
+
tryListen();
|
|
19442
19470
|
return server;
|
|
19443
19471
|
}
|
|
19444
19472
|
async function proxyToRestApi(restPort, pathname, qs, method, req, res, secret) {
|
|
@@ -19632,14 +19660,14 @@ async function main() {
|
|
|
19632
19660
|
const provider = fallbackConfig.providers.length > 0 ? createFallbackProvider(config.provider, fallbackConfig) : createProvider(config.provider);
|
|
19633
19661
|
const embeddingProvider = createEmbeddingProvider();
|
|
19634
19662
|
const imageEmbeddingProvider = createImageEmbeddingProvider();
|
|
19635
|
-
|
|
19636
|
-
|
|
19637
|
-
|
|
19638
|
-
if (embeddingProvider)
|
|
19639
|
-
else
|
|
19640
|
-
if (imageEmbeddingProvider)
|
|
19641
|
-
|
|
19642
|
-
|
|
19663
|
+
bootLog(`Starting worker v${VERSION}...`);
|
|
19664
|
+
bootLog(`Engine: ${config.engineUrl}`);
|
|
19665
|
+
bootLog(`Provider: ${config.provider.provider} (${config.provider.model})`);
|
|
19666
|
+
if (embeddingProvider) bootLog(`Embedding provider: ${embeddingProvider.name} (${embeddingProvider.dimensions} dims)`);
|
|
19667
|
+
else bootLog(`Embedding provider: none (BM25-only mode)`);
|
|
19668
|
+
if (imageEmbeddingProvider) bootLog(`Image embedding provider: ${imageEmbeddingProvider.name} (${imageEmbeddingProvider.dimensions} dims) — vision-search active`);
|
|
19669
|
+
bootLog(`REST API: http://localhost:${config.restPort}/agentmemory/*`);
|
|
19670
|
+
bootLog(`Streams: ws://localhost:${config.streamsPort}`);
|
|
19643
19671
|
const sdk = registerWorker(config.engineUrl, {
|
|
19644
19672
|
workerName: "agentmemory",
|
|
19645
19673
|
invocationTimeoutMs: 18e4,
|
|
@@ -19682,22 +19710,22 @@ async function main() {
|
|
|
19682
19710
|
const claudeBridgeConfig = loadClaudeBridgeConfig();
|
|
19683
19711
|
if (claudeBridgeConfig.enabled) {
|
|
19684
19712
|
registerClaudeBridgeFunction(sdk, kv, claudeBridgeConfig);
|
|
19685
|
-
|
|
19713
|
+
bootLog(`Claude bridge: syncing to ${claudeBridgeConfig.memoryFilePath}`);
|
|
19686
19714
|
}
|
|
19687
19715
|
if (isGraphExtractionEnabled()) {
|
|
19688
19716
|
registerGraphFunction(sdk, kv, provider);
|
|
19689
|
-
|
|
19717
|
+
bootLog(`Knowledge graph: extraction enabled`);
|
|
19690
19718
|
}
|
|
19691
19719
|
registerConsolidationPipelineFunction(sdk, kv, provider);
|
|
19692
|
-
|
|
19693
|
-
if (isAutoCompressEnabled())
|
|
19694
|
-
else
|
|
19695
|
-
if (isContextInjectionEnabled())
|
|
19696
|
-
else
|
|
19720
|
+
bootLog(`Consolidation pipeline: registered (CONSOLIDATION_ENABLED=${isConsolidationEnabled() ? "true" : "false"})`);
|
|
19721
|
+
if (isAutoCompressEnabled()) bootLog(`WARNING: AGENTMEMORY_AUTO_COMPRESS=true — every PostToolUse observation will be sent to your LLM provider for compression. This spends API tokens proportional to your session tool-use frequency (see #138). Set AGENTMEMORY_AUTO_COMPRESS=false to disable.`);
|
|
19722
|
+
else bootLog(`Auto-compress: OFF (default, #138) — observations indexed via zero-LLM synthetic compression. Set AGENTMEMORY_AUTO_COMPRESS=true to opt-in to LLM-powered summaries (uses your API key).`);
|
|
19723
|
+
if (isContextInjectionEnabled()) bootLog(`WARNING: AGENTMEMORY_INJECT_CONTEXT=true — the PreToolUse and SessionStart hooks will inject up to ~4000 chars of memory context into every tool turn. On Claude Pro this burns session tokens proportional to your tool-call frequency (see #143). Set AGENTMEMORY_INJECT_CONTEXT=false to disable.`);
|
|
19724
|
+
else bootLog(`Context injection: OFF (default, #143) — hooks capture observations but do not inject context into Claude Code's conversation. Set AGENTMEMORY_INJECT_CONTEXT=true to opt-in (warning: expect your Claude Pro allocation to drain faster).`);
|
|
19697
19725
|
const teamConfig = loadTeamConfig();
|
|
19698
19726
|
if (teamConfig) {
|
|
19699
19727
|
registerTeamFunction(sdk, kv, teamConfig);
|
|
19700
|
-
|
|
19728
|
+
bootLog(`Team memory: ${teamConfig.teamId} (${teamConfig.mode})`);
|
|
19701
19729
|
}
|
|
19702
19730
|
registerGovernanceFunction(sdk, kv);
|
|
19703
19731
|
registerActionsFunction(sdk, kv);
|
|
@@ -19727,13 +19755,13 @@ async function main() {
|
|
|
19727
19755
|
registerRetentionFunctions(sdk, kv);
|
|
19728
19756
|
registerCompressFileFunction(sdk, kv, provider);
|
|
19729
19757
|
registerReplayFunctions(sdk, kv);
|
|
19730
|
-
|
|
19731
|
-
|
|
19732
|
-
if (isSlotsEnabled())
|
|
19758
|
+
bootLog(`v0.6 advanced retrieval: sliding-window, query-expansion, temporal-graph, retention-scoring`);
|
|
19759
|
+
bootLog(`Orchestration layer: actions, frontier, leases, routines, signals, checkpoints, flow-compress, mesh, branch-aware, sentinels, sketches, crystallize, diagnostics, facets`);
|
|
19760
|
+
if (isSlotsEnabled()) bootLog(`Slots: enabled (pinned editable memory). Reflect on Stop hook: ${isReflectEnabled() ? "on" : "off"}`);
|
|
19733
19761
|
const snapshotConfig = loadSnapshotConfig();
|
|
19734
19762
|
if (snapshotConfig.enabled) {
|
|
19735
19763
|
registerSnapshotFunction(sdk, kv, snapshotConfig.dir);
|
|
19736
|
-
|
|
19764
|
+
bootLog(`Git snapshots: ${snapshotConfig.dir} (every ${snapshotConfig.interval}s)`);
|
|
19737
19765
|
}
|
|
19738
19766
|
const bm25Index = getSearchIndex();
|
|
19739
19767
|
const graphWeight = parseFloat(getEnvVar("AGENTMEMORY_GRAPH_WEIGHT") || "0.3");
|
|
@@ -19750,7 +19778,7 @@ async function main() {
|
|
|
19750
19778
|
});
|
|
19751
19779
|
if (loaded?.bm25 && loaded.bm25.size > 0) {
|
|
19752
19780
|
bm25Index.restoreFrom(loaded.bm25);
|
|
19753
|
-
|
|
19781
|
+
bootLog(`Loaded persisted BM25 index (${bm25Index.size} docs)`);
|
|
19754
19782
|
}
|
|
19755
19783
|
if (loaded?.vector && vectorIndex && loaded.vector.size > 0) {
|
|
19756
19784
|
const activeDim = embeddingProvider?.dimensions ?? 0;
|
|
@@ -19765,7 +19793,7 @@ async function main() {
|
|
|
19765
19793
|
else throw new Error(`[agentmemory] Refusing to start: persisted vector index has ${mismatches.length} of ${loaded.vector.size} vectors with the wrong dimension. Active provider (${embeddingProvider?.name}) declares ${activeDim}; dimensions seen on disk: ${distinct}. First mismatched obsIds: ${sample}. Loading would silently corrupt search (cross-dimension cosine returns 0). Choose one:\n - Re-embed the existing index against the new provider, then start.\n - Set AGENTMEMORY_DROP_STALE_INDEX=true to discard the persisted vectors and rebuild from live observations.\n - Switch the embedding provider back to the one that wrote the index.`);
|
|
19766
19794
|
} else {
|
|
19767
19795
|
vectorIndex.restoreFrom(loaded.vector);
|
|
19768
|
-
|
|
19796
|
+
bootLog(`Loaded persisted vector index (${vectorIndex.size} vectors)`);
|
|
19769
19797
|
}
|
|
19770
19798
|
}
|
|
19771
19799
|
if (bm25Index.size === 0) {
|
|
@@ -19774,7 +19802,7 @@ async function main() {
|
|
|
19774
19802
|
return 0;
|
|
19775
19803
|
});
|
|
19776
19804
|
if (indexCount > 0) {
|
|
19777
|
-
|
|
19805
|
+
bootLog(`Search index rebuilt: ${indexCount} entries`);
|
|
19778
19806
|
indexPersistence.scheduleSave();
|
|
19779
19807
|
}
|
|
19780
19808
|
} else try {
|
|
@@ -19799,14 +19827,14 @@ async function main() {
|
|
|
19799
19827
|
backfilled++;
|
|
19800
19828
|
}
|
|
19801
19829
|
if (backfilled > 0) {
|
|
19802
|
-
|
|
19830
|
+
bootLog(`Backfilled ${backfilled} memories into BM25 (legacy gap before #257)`);
|
|
19803
19831
|
indexPersistence.scheduleSave();
|
|
19804
19832
|
}
|
|
19805
19833
|
} catch (err) {
|
|
19806
19834
|
console.warn(`[agentmemory] Failed to backfill memories into BM25:`, err);
|
|
19807
19835
|
}
|
|
19808
|
-
|
|
19809
|
-
|
|
19836
|
+
bootLog(`Ready. ${embeddingProvider ? "Triple-stream (BM25+Vector+Graph)" : "BM25+Graph"} search active.`);
|
|
19837
|
+
bootLog(`Endpoints: 107 REST + ${getAllTools().length} MCP tools + 6 MCP resources + 3 MCP prompts`);
|
|
19810
19838
|
const viewerServer = startViewerServer(config.restPort + 2, kv, sdk, secret, config.restPort);
|
|
19811
19839
|
const autoForgetIntervalMs = parseInt(process.env.AUTO_FORGET_INTERVAL_MS || "3600000", 10);
|
|
19812
19840
|
const consolidationIntervalMs = parseInt(process.env.CONSOLIDATION_INTERVAL_MS || "7200000", 10);
|
|
@@ -19819,7 +19847,7 @@ async function main() {
|
|
|
19819
19847
|
});
|
|
19820
19848
|
} catch {}
|
|
19821
19849
|
}, autoForgetIntervalMs).unref();
|
|
19822
|
-
|
|
19850
|
+
bootLog(`Auto-forget: enabled (every ${autoForgetIntervalMs / 6e4}m)`);
|
|
19823
19851
|
}
|
|
19824
19852
|
if (process.env.LESSON_DECAY_ENABLED !== "false") {
|
|
19825
19853
|
setInterval(async () => {
|
|
@@ -19830,7 +19858,7 @@ async function main() {
|
|
|
19830
19858
|
});
|
|
19831
19859
|
} catch {}
|
|
19832
19860
|
}, 864e5).unref();
|
|
19833
|
-
|
|
19861
|
+
bootLog(`Lesson decay sweep: enabled (every 24h)`);
|
|
19834
19862
|
}
|
|
19835
19863
|
if (process.env.INSIGHT_DECAY_ENABLED !== "false") setInterval(async () => {
|
|
19836
19864
|
try {
|
|
@@ -19849,7 +19877,7 @@ async function main() {
|
|
|
19849
19877
|
});
|
|
19850
19878
|
} catch {}
|
|
19851
19879
|
}, consolidationIntervalMs).unref();
|
|
19852
|
-
|
|
19880
|
+
bootLog(`Auto-consolidation: enabled (every ${consolidationIntervalMs / 6e4}m)`);
|
|
19853
19881
|
}
|
|
19854
19882
|
const shutdown = async () => {
|
|
19855
19883
|
console.log(`\n[agentmemory] Shutting down...`);
|