@agentmemory/agentmemory 0.9.2 → 0.9.4
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 +8 -3
- package/dist/cli.mjs +235 -26
- package/dist/cli.mjs.map +1 -1
- package/dist/image-refs-BfT7XAa-.mjs +3 -0
- package/dist/{image-store-BLOkD0xV.mjs → image-store-Cn9eD-7D.mjs} +1 -1
- package/dist/index.mjs +231 -36
- package/dist/index.mjs.map +1 -1
- package/dist/{src-tmuZyobT.mjs → src-uDy2jLO-.mjs} +226 -43
- package/dist/src-uDy2jLO-.mjs.map +1 -0
- package/dist/{standalone-BiwX0rdC.mjs → standalone-CqqEcfNR.mjs} +2 -2
- package/dist/{standalone-BiwX0rdC.mjs.map → standalone-CqqEcfNR.mjs.map} +1 -1
- package/dist/standalone.mjs +9 -2
- package/dist/standalone.mjs.map +1 -1
- package/dist/{tools-registry-CHH84gIQ.mjs → tools-registry-Co8VIL4t.mjs} +16 -4
- package/dist/tools-registry-Co8VIL4t.mjs.map +1 -0
- package/dist/viewer/index.html +283 -10
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/image-refs-Dq5wcV-a.mjs +0 -3
- package/dist/src-tmuZyobT.mjs.map +0 -1
- package/dist/tools-registry-CHH84gIQ.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -50,7 +50,14 @@ function loadEnvFile() {
|
|
|
50
50
|
if (eqIdx === -1) continue;
|
|
51
51
|
const key = trimmed.slice(0, eqIdx).trim();
|
|
52
52
|
let val = trimmed.slice(eqIdx + 1).trim();
|
|
53
|
-
|
|
53
|
+
const quoteChar = val[0] === "\"" || val[0] === "'" ? val[0] : "";
|
|
54
|
+
if (quoteChar) {
|
|
55
|
+
const closeIdx = val.indexOf(quoteChar, 1);
|
|
56
|
+
if (closeIdx !== -1) val = val.slice(1, closeIdx);
|
|
57
|
+
} else {
|
|
58
|
+
const hashIdx = val.indexOf(" #");
|
|
59
|
+
if (hashIdx !== -1) val = val.slice(0, hashIdx).trim();
|
|
60
|
+
}
|
|
54
61
|
vars[key] = val;
|
|
55
62
|
}
|
|
56
63
|
return vars;
|
|
@@ -123,6 +130,11 @@ function getMergedEnv(overrides) {
|
|
|
123
130
|
function getEnvVar(key) {
|
|
124
131
|
return getMergedEnv()[key];
|
|
125
132
|
}
|
|
133
|
+
function detectLlmProviderKind() {
|
|
134
|
+
const env = getMergedEnv();
|
|
135
|
+
if (hasRealValue(env["ANTHROPIC_API_KEY"]) || hasRealValue(env["GEMINI_API_KEY"]) || hasRealValue(env["GOOGLE_API_KEY"]) || hasRealValue(env["OPENROUTER_API_KEY"]) || hasRealValue(env["MINIMAX_API_KEY"])) return "llm";
|
|
136
|
+
return "noop";
|
|
137
|
+
}
|
|
126
138
|
function loadEmbeddingConfig() {
|
|
127
139
|
const env = getMergedEnv();
|
|
128
140
|
let bm25Weight = parseFloat(env["BM25_WEIGHT"] || "0.4");
|
|
@@ -2183,8 +2195,10 @@ var SearchIndex = class SearchIndex {
|
|
|
2183
2195
|
//#endregion
|
|
2184
2196
|
//#region src/state/index-persistence.ts
|
|
2185
2197
|
const DEBOUNCE_MS = 5e3;
|
|
2198
|
+
const FAILURE_LOG_THROTTLE_MS = 6e4;
|
|
2186
2199
|
var IndexPersistence = class {
|
|
2187
2200
|
timer = null;
|
|
2201
|
+
lastFailureLogAt = 0;
|
|
2188
2202
|
constructor(kv, bm25, vector) {
|
|
2189
2203
|
this.kv = kv;
|
|
2190
2204
|
this.bm25 = bm25;
|
|
@@ -2192,15 +2206,21 @@ var IndexPersistence = class {
|
|
|
2192
2206
|
}
|
|
2193
2207
|
scheduleSave() {
|
|
2194
2208
|
if (this.timer) clearTimeout(this.timer);
|
|
2195
|
-
this.timer = setTimeout(() =>
|
|
2209
|
+
this.timer = setTimeout(() => {
|
|
2210
|
+
this.save().catch((err) => this.logFailure(err));
|
|
2211
|
+
}, DEBOUNCE_MS);
|
|
2196
2212
|
}
|
|
2197
2213
|
async save() {
|
|
2198
2214
|
if (this.timer) {
|
|
2199
2215
|
clearTimeout(this.timer);
|
|
2200
2216
|
this.timer = null;
|
|
2201
2217
|
}
|
|
2202
|
-
|
|
2203
|
-
|
|
2218
|
+
try {
|
|
2219
|
+
await this.kv.set(KV.bm25Index, "data", this.bm25.serialize());
|
|
2220
|
+
if (this.vector && this.vector.size > 0) await this.kv.set(KV.bm25Index, "vectors", this.vector.serialize());
|
|
2221
|
+
} catch (err) {
|
|
2222
|
+
this.logFailure(err);
|
|
2223
|
+
}
|
|
2204
2224
|
}
|
|
2205
2225
|
async load() {
|
|
2206
2226
|
let bm25 = null;
|
|
@@ -2220,6 +2240,18 @@ var IndexPersistence = class {
|
|
|
2220
2240
|
this.timer = null;
|
|
2221
2241
|
}
|
|
2222
2242
|
}
|
|
2243
|
+
logFailure(err) {
|
|
2244
|
+
const now = Date.now();
|
|
2245
|
+
if (now - this.lastFailureLogAt < FAILURE_LOG_THROTTLE_MS) return;
|
|
2246
|
+
this.lastFailureLogAt = now;
|
|
2247
|
+
const code = err?.code;
|
|
2248
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2249
|
+
logger.warn("index persistence: failed to save BM25/vector index", {
|
|
2250
|
+
code,
|
|
2251
|
+
message,
|
|
2252
|
+
hint: code === "TIMEOUT" ? "iii-engine state::set timed out; recent index updates remain in memory and will retry on the next debounce flush" : void 0
|
|
2253
|
+
});
|
|
2254
|
+
}
|
|
2223
2255
|
};
|
|
2224
2256
|
|
|
2225
2257
|
//#endregion
|
|
@@ -5618,7 +5650,7 @@ function registerAutoForgetFunction(sdk, kv) {
|
|
|
5618
5650
|
|
|
5619
5651
|
//#endregion
|
|
5620
5652
|
//#region src/version.ts
|
|
5621
|
-
const VERSION = "0.9.
|
|
5653
|
+
const VERSION = "0.9.4";
|
|
5622
5654
|
|
|
5623
5655
|
//#endregion
|
|
5624
5656
|
//#region src/functions/export-import.ts
|
|
@@ -5738,7 +5770,9 @@ function registerExportImportFunction(sdk, kv) {
|
|
|
5738
5770
|
"0.8.13",
|
|
5739
5771
|
"0.9.0",
|
|
5740
5772
|
"0.9.1",
|
|
5741
|
-
"0.9.2"
|
|
5773
|
+
"0.9.2",
|
|
5774
|
+
"0.9.3",
|
|
5775
|
+
"0.9.4"
|
|
5742
5776
|
]).has(importData.version)) return {
|
|
5743
5777
|
success: false,
|
|
5744
5778
|
error: `Unsupported export version: ${importData.version}`
|
|
@@ -12356,7 +12390,7 @@ function parseJsonlText(text, fallbackSessionId) {
|
|
|
12356
12390
|
const parsed = JSON.parse(line);
|
|
12357
12391
|
if (parsed && typeof parsed === "object") entries.push(parsed);
|
|
12358
12392
|
} catch {}
|
|
12359
|
-
let sessionId =
|
|
12393
|
+
let sessionId = "";
|
|
12360
12394
|
let cwd = "";
|
|
12361
12395
|
let firstTs = "";
|
|
12362
12396
|
let lastTs = "";
|
|
@@ -12417,7 +12451,7 @@ function parseJsonlText(text, fallbackSessionId) {
|
|
|
12417
12451
|
});
|
|
12418
12452
|
} else if (entry.type === "summary" || entry.type === "system") {}
|
|
12419
12453
|
}
|
|
12420
|
-
const effectiveSessionId = sessionId || generateId("sess");
|
|
12454
|
+
const effectiveSessionId = sessionId || fallbackSessionId || generateId("sess");
|
|
12421
12455
|
for (const obs of observations) if (obs.sessionId === "imported") obs.sessionId = effectiveSessionId;
|
|
12422
12456
|
const nowIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
12423
12457
|
return {
|
|
@@ -12527,6 +12561,8 @@ function projectTimeline(observations) {
|
|
|
12527
12561
|
|
|
12528
12562
|
//#endregion
|
|
12529
12563
|
//#region src/functions/replay.ts
|
|
12564
|
+
const MAX_FILES_DEFAULT = 200;
|
|
12565
|
+
const MAX_FILES_UPPER_BOUND = 1e3;
|
|
12530
12566
|
const SENSITIVE_PATH_PATTERNS = [
|
|
12531
12567
|
/(^|[\\/_.-])secret([\\/_.-]|s?$)/i,
|
|
12532
12568
|
/(^|[\\/_.-])credentials?([\\/_.-]|$)/i,
|
|
@@ -12661,8 +12697,11 @@ async function loadObservations(kv, sessionId) {
|
|
|
12661
12697
|
}
|
|
12662
12698
|
async function findJsonlFiles(root, limit = 200) {
|
|
12663
12699
|
const out = [];
|
|
12700
|
+
let discovered = 0;
|
|
12701
|
+
let walked = 0;
|
|
12702
|
+
const traversalCap = Math.max(limit * 50, 5e4);
|
|
12664
12703
|
async function walk(dir) {
|
|
12665
|
-
if (
|
|
12704
|
+
if (walked >= traversalCap) return;
|
|
12666
12705
|
let names;
|
|
12667
12706
|
try {
|
|
12668
12707
|
names = await readdir(dir);
|
|
@@ -12670,7 +12709,8 @@ async function findJsonlFiles(root, limit = 200) {
|
|
|
12670
12709
|
return;
|
|
12671
12710
|
}
|
|
12672
12711
|
for (const name of names) {
|
|
12673
|
-
if (
|
|
12712
|
+
if (walked >= traversalCap) return;
|
|
12713
|
+
walked++;
|
|
12674
12714
|
const full = join(dir, name);
|
|
12675
12715
|
let st;
|
|
12676
12716
|
try {
|
|
@@ -12680,11 +12720,20 @@ async function findJsonlFiles(root, limit = 200) {
|
|
|
12680
12720
|
}
|
|
12681
12721
|
if (st.isSymbolicLink()) continue;
|
|
12682
12722
|
if (st.isDirectory()) await walk(full);
|
|
12683
|
-
else if (st.isFile() && name.endsWith(".jsonl"))
|
|
12723
|
+
else if (st.isFile() && name.endsWith(".jsonl")) {
|
|
12724
|
+
discovered++;
|
|
12725
|
+
if (out.length < limit) out.push(full);
|
|
12726
|
+
}
|
|
12684
12727
|
}
|
|
12685
12728
|
}
|
|
12686
12729
|
await walk(root);
|
|
12687
|
-
|
|
12730
|
+
const traversalCapped = walked >= traversalCap;
|
|
12731
|
+
return {
|
|
12732
|
+
files: out,
|
|
12733
|
+
truncated: discovered > out.length || traversalCapped,
|
|
12734
|
+
discovered,
|
|
12735
|
+
traversalCapped
|
|
12736
|
+
};
|
|
12688
12737
|
}
|
|
12689
12738
|
function registerReplayFunctions(sdk, kv) {
|
|
12690
12739
|
sdk.registerFunction("mem::replay::load", async (data) => {
|
|
@@ -12732,10 +12781,21 @@ function registerReplayFunctions(sdk, kv) {
|
|
|
12732
12781
|
error: "path not found"
|
|
12733
12782
|
};
|
|
12734
12783
|
}
|
|
12784
|
+
const maxFiles = Number.isInteger(data.maxFiles) && data.maxFiles > 0 ? Math.min(data.maxFiles, MAX_FILES_UPPER_BOUND) : MAX_FILES_DEFAULT;
|
|
12735
12785
|
let files = [];
|
|
12736
|
-
|
|
12737
|
-
|
|
12738
|
-
|
|
12786
|
+
let truncated = false;
|
|
12787
|
+
let discovered = 0;
|
|
12788
|
+
let traversalCapped = false;
|
|
12789
|
+
if (stat.isDirectory()) {
|
|
12790
|
+
const found = await findJsonlFiles(abs, maxFiles);
|
|
12791
|
+
files = found.files;
|
|
12792
|
+
truncated = found.truncated;
|
|
12793
|
+
discovered = found.discovered;
|
|
12794
|
+
traversalCapped = found.traversalCapped;
|
|
12795
|
+
} else if (stat.isFile() && abs.endsWith(".jsonl")) {
|
|
12796
|
+
files = [abs];
|
|
12797
|
+
discovered = 1;
|
|
12798
|
+
} else return {
|
|
12739
12799
|
success: false,
|
|
12740
12800
|
error: "path must be a .jsonl file or directory"
|
|
12741
12801
|
};
|
|
@@ -12743,7 +12803,12 @@ function registerReplayFunctions(sdk, kv) {
|
|
|
12743
12803
|
success: true,
|
|
12744
12804
|
imported: 0,
|
|
12745
12805
|
sessionIds: [],
|
|
12746
|
-
observations: 0
|
|
12806
|
+
observations: 0,
|
|
12807
|
+
discovered,
|
|
12808
|
+
truncated,
|
|
12809
|
+
traversalCapped,
|
|
12810
|
+
maxFiles,
|
|
12811
|
+
maxFilesUpperBound: MAX_FILES_UPPER_BOUND
|
|
12747
12812
|
};
|
|
12748
12813
|
const sessionIds = [];
|
|
12749
12814
|
let observationCount = 0;
|
|
@@ -12809,7 +12874,12 @@ function registerReplayFunctions(sdk, kv) {
|
|
|
12809
12874
|
success: true,
|
|
12810
12875
|
imported: files.length,
|
|
12811
12876
|
sessionIds,
|
|
12812
|
-
observations: observationCount
|
|
12877
|
+
observations: observationCount,
|
|
12878
|
+
discovered,
|
|
12879
|
+
truncated,
|
|
12880
|
+
traversalCapped,
|
|
12881
|
+
maxFiles,
|
|
12882
|
+
maxFilesUpperBound: MAX_FILES_UPPER_BOUND
|
|
12813
12883
|
};
|
|
12814
12884
|
});
|
|
12815
12885
|
}
|
|
@@ -13036,6 +13106,28 @@ function requireConfiguredSecret(secret, feature) {
|
|
|
13036
13106
|
body: { error: `${feature} requires AGENTMEMORY_SECRET` }
|
|
13037
13107
|
};
|
|
13038
13108
|
}
|
|
13109
|
+
function flagDisabledResponse(opts) {
|
|
13110
|
+
return {
|
|
13111
|
+
status_code: 503,
|
|
13112
|
+
body: opts
|
|
13113
|
+
};
|
|
13114
|
+
}
|
|
13115
|
+
function graphDisabledResponse() {
|
|
13116
|
+
return flagDisabledResponse({
|
|
13117
|
+
error: "Knowledge graph not enabled",
|
|
13118
|
+
flag: "GRAPH_EXTRACTION_ENABLED",
|
|
13119
|
+
enableHow: "Set GRAPH_EXTRACTION_ENABLED=true and restart. Requires an LLM provider key.",
|
|
13120
|
+
docsHref: "https://github.com/rohitg00/agentmemory#knowledge-graph"
|
|
13121
|
+
});
|
|
13122
|
+
}
|
|
13123
|
+
function consolidationDisabledResponse() {
|
|
13124
|
+
return flagDisabledResponse({
|
|
13125
|
+
error: "Consolidation pipeline not enabled",
|
|
13126
|
+
flag: "CONSOLIDATION_ENABLED",
|
|
13127
|
+
enableHow: "Set CONSOLIDATION_ENABLED=true and restart. Requires an LLM provider key.",
|
|
13128
|
+
docsHref: "https://github.com/rohitg00/agentmemory#consolidation"
|
|
13129
|
+
});
|
|
13130
|
+
}
|
|
13039
13131
|
function asNonEmptyString$1(value) {
|
|
13040
13132
|
if (typeof value !== "string") return null;
|
|
13041
13133
|
const trimmed = value.trim();
|
|
@@ -13087,6 +13179,77 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
|
|
|
13087
13179
|
http_method: "GET"
|
|
13088
13180
|
}
|
|
13089
13181
|
});
|
|
13182
|
+
sdk.registerFunction("api::config-flags", async (req) => {
|
|
13183
|
+
const authErr = checkAuth(req, secret);
|
|
13184
|
+
if (authErr) return authErr;
|
|
13185
|
+
return {
|
|
13186
|
+
status_code: 200,
|
|
13187
|
+
body: {
|
|
13188
|
+
version: VERSION,
|
|
13189
|
+
provider: detectLlmProviderKind(),
|
|
13190
|
+
embeddingProvider: detectEmbeddingProvider() ? "embeddings" : "none",
|
|
13191
|
+
flags: [
|
|
13192
|
+
{
|
|
13193
|
+
key: "GRAPH_EXTRACTION_ENABLED",
|
|
13194
|
+
label: "Knowledge graph extraction",
|
|
13195
|
+
enabled: isGraphExtractionEnabled(),
|
|
13196
|
+
default: false,
|
|
13197
|
+
affects: ["Graph", "Dashboard"],
|
|
13198
|
+
needsLlm: true,
|
|
13199
|
+
description: "Extracts entities and relations from observations into a knowledge graph.",
|
|
13200
|
+
enableHow: "Set GRAPH_EXTRACTION_ENABLED=true and provide an LLM key, then restart.",
|
|
13201
|
+
docsHref: "https://github.com/rohitg00/agentmemory#knowledge-graph"
|
|
13202
|
+
},
|
|
13203
|
+
{
|
|
13204
|
+
key: "CONSOLIDATION_ENABLED",
|
|
13205
|
+
label: "Memory consolidation",
|
|
13206
|
+
enabled: isConsolidationEnabled(),
|
|
13207
|
+
default: false,
|
|
13208
|
+
affects: [
|
|
13209
|
+
"Dashboard",
|
|
13210
|
+
"Memories",
|
|
13211
|
+
"Crystals"
|
|
13212
|
+
],
|
|
13213
|
+
needsLlm: true,
|
|
13214
|
+
description: "Periodically summarizes sessions into semantic facts + procedures.",
|
|
13215
|
+
enableHow: "Set CONSOLIDATION_ENABLED=true and provide an LLM key, then restart.",
|
|
13216
|
+
docsHref: "https://github.com/rohitg00/agentmemory#consolidation"
|
|
13217
|
+
},
|
|
13218
|
+
{
|
|
13219
|
+
key: "AGENTMEMORY_AUTO_COMPRESS",
|
|
13220
|
+
label: "LLM-powered observation compression",
|
|
13221
|
+
enabled: isAutoCompressEnabled(),
|
|
13222
|
+
default: false,
|
|
13223
|
+
affects: ["Memories", "Timeline"],
|
|
13224
|
+
needsLlm: true,
|
|
13225
|
+
description: "Every observation is compressed by the LLM for richer summaries (costs tokens). OFF uses zero-LLM synthetic compression.",
|
|
13226
|
+
enableHow: "Set AGENTMEMORY_AUTO_COMPRESS=true and provide an LLM key.",
|
|
13227
|
+
docsHref: "https://github.com/rohitg00/agentmemory/issues/138"
|
|
13228
|
+
},
|
|
13229
|
+
{
|
|
13230
|
+
key: "AGENTMEMORY_INJECT_CONTEXT",
|
|
13231
|
+
label: "In-conversation context injection",
|
|
13232
|
+
enabled: isContextInjectionEnabled(),
|
|
13233
|
+
default: false,
|
|
13234
|
+
affects: ["Hooks"],
|
|
13235
|
+
needsLlm: false,
|
|
13236
|
+
description: "Hooks write recalled context into Claude Code's conversation. OFF captures in the background without injecting.",
|
|
13237
|
+
enableHow: "Set AGENTMEMORY_INJECT_CONTEXT=true and restart.",
|
|
13238
|
+
docsHref: "https://github.com/rohitg00/agentmemory/issues/143"
|
|
13239
|
+
}
|
|
13240
|
+
]
|
|
13241
|
+
}
|
|
13242
|
+
};
|
|
13243
|
+
});
|
|
13244
|
+
sdk.registerTrigger({
|
|
13245
|
+
type: "http",
|
|
13246
|
+
function_id: "api::config-flags",
|
|
13247
|
+
config: {
|
|
13248
|
+
api_path: "/agentmemory/config/flags",
|
|
13249
|
+
http_method: "GET",
|
|
13250
|
+
middleware_function_ids: ["middleware::api-auth"]
|
|
13251
|
+
}
|
|
13252
|
+
});
|
|
13090
13253
|
sdk.registerFunction("api::health", async (req) => {
|
|
13091
13254
|
const health = await getLatestHealth(kv);
|
|
13092
13255
|
const functionMetrics = metricsStore ? await metricsStore.getAll() : [];
|
|
@@ -13321,11 +13484,12 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
|
|
|
13321
13484
|
payload.path = body.path.trim();
|
|
13322
13485
|
}
|
|
13323
13486
|
if (body.maxFiles !== void 0) {
|
|
13324
|
-
|
|
13487
|
+
const n = body.maxFiles;
|
|
13488
|
+
if (!Number.isInteger(n) || n < 1 || n > MAX_FILES_UPPER_BOUND) return {
|
|
13325
13489
|
status_code: 400,
|
|
13326
|
-
body: { error:
|
|
13490
|
+
body: { error: `maxFiles must be an integer between 1 and ${MAX_FILES_UPPER_BOUND}` }
|
|
13327
13491
|
};
|
|
13328
|
-
payload.maxFiles =
|
|
13492
|
+
payload.maxFiles = n;
|
|
13329
13493
|
}
|
|
13330
13494
|
return {
|
|
13331
13495
|
status_code: 202,
|
|
@@ -13907,10 +14071,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
|
|
|
13907
14071
|
})
|
|
13908
14072
|
};
|
|
13909
14073
|
} catch {
|
|
13910
|
-
return
|
|
13911
|
-
status_code: 404,
|
|
13912
|
-
body: { error: "Knowledge graph not enabled" }
|
|
13913
|
-
};
|
|
14074
|
+
return graphDisabledResponse();
|
|
13914
14075
|
}
|
|
13915
14076
|
});
|
|
13916
14077
|
sdk.registerTrigger({
|
|
@@ -13933,10 +14094,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
|
|
|
13933
14094
|
})
|
|
13934
14095
|
};
|
|
13935
14096
|
} catch {
|
|
13936
|
-
return
|
|
13937
|
-
status_code: 404,
|
|
13938
|
-
body: { error: "Knowledge graph not enabled" }
|
|
13939
|
-
};
|
|
14097
|
+
return graphDisabledResponse();
|
|
13940
14098
|
}
|
|
13941
14099
|
});
|
|
13942
14100
|
sdk.registerTrigger({
|
|
@@ -13963,10 +14121,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
|
|
|
13963
14121
|
})
|
|
13964
14122
|
};
|
|
13965
14123
|
} catch {
|
|
13966
|
-
return
|
|
13967
|
-
status_code: 404,
|
|
13968
|
-
body: { error: "Knowledge graph not enabled" }
|
|
13969
|
-
};
|
|
14124
|
+
return graphDisabledResponse();
|
|
13970
14125
|
}
|
|
13971
14126
|
});
|
|
13972
14127
|
sdk.registerTrigger({
|
|
@@ -13989,10 +14144,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
|
|
|
13989
14144
|
})
|
|
13990
14145
|
};
|
|
13991
14146
|
} catch {
|
|
13992
|
-
return
|
|
13993
|
-
status_code: 404,
|
|
13994
|
-
body: { error: "Consolidation pipeline not enabled" }
|
|
13995
|
-
};
|
|
14147
|
+
return consolidationDisabledResponse();
|
|
13996
14148
|
}
|
|
13997
14149
|
});
|
|
13998
14150
|
sdk.registerTrigger({
|
|
@@ -14253,6 +14405,32 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
|
|
|
14253
14405
|
http_method: "GET"
|
|
14254
14406
|
}
|
|
14255
14407
|
});
|
|
14408
|
+
sdk.registerFunction("api::memory-by-id", async (req) => {
|
|
14409
|
+
const authErr = checkAuth(req, secret);
|
|
14410
|
+
if (authErr) return authErr;
|
|
14411
|
+
const id = req.path_params?.["id"];
|
|
14412
|
+
if (!id || typeof id !== "string") return {
|
|
14413
|
+
status_code: 400,
|
|
14414
|
+
body: { error: "id path parameter is required" }
|
|
14415
|
+
};
|
|
14416
|
+
const memory = await kv.get(KV.memories, id);
|
|
14417
|
+
if (!memory) return {
|
|
14418
|
+
status_code: 404,
|
|
14419
|
+
body: { error: `memory not found: ${id}` }
|
|
14420
|
+
};
|
|
14421
|
+
return {
|
|
14422
|
+
status_code: 200,
|
|
14423
|
+
body: { memory }
|
|
14424
|
+
};
|
|
14425
|
+
});
|
|
14426
|
+
sdk.registerTrigger({
|
|
14427
|
+
type: "http",
|
|
14428
|
+
function_id: "api::memory-by-id",
|
|
14429
|
+
config: {
|
|
14430
|
+
api_path: "/agentmemory/memories/:id",
|
|
14431
|
+
http_method: "GET"
|
|
14432
|
+
}
|
|
14433
|
+
});
|
|
14256
14434
|
sdk.registerFunction("api::semantic-list", async (req) => {
|
|
14257
14435
|
const authErr = checkAuth(req, secret);
|
|
14258
14436
|
if (authErr) return authErr;
|
|
@@ -16131,6 +16309,15 @@ function registerEventTriggers(sdk, kv) {
|
|
|
16131
16309
|
error: err instanceof Error ? err.message : String(err)
|
|
16132
16310
|
});
|
|
16133
16311
|
}
|
|
16312
|
+
if (isGraphExtractionEnabled()) try {
|
|
16313
|
+
const compressed = (await kv.list(KV.observations(data.sessionId))).filter((o) => o.title);
|
|
16314
|
+
if (compressed.length > 0) sdk.triggerVoid("mem::graph-extract", { observations: compressed });
|
|
16315
|
+
} catch (err) {
|
|
16316
|
+
logger.warn("graph-extract triggerVoid failed", {
|
|
16317
|
+
sessionId: data.sessionId,
|
|
16318
|
+
error: err instanceof Error ? err.message : String(err)
|
|
16319
|
+
});
|
|
16320
|
+
}
|
|
16134
16321
|
return summary;
|
|
16135
16322
|
});
|
|
16136
16323
|
sdk.registerTrigger({
|
|
@@ -19115,6 +19302,14 @@ function initMetrics(getMeter) {
|
|
|
19115
19302
|
function hasGetMeter(sdk) {
|
|
19116
19303
|
return typeof sdk === "object" && sdk !== null && "getMeter" in sdk && typeof sdk.getMeter === "function";
|
|
19117
19304
|
}
|
|
19305
|
+
let lastUnhandledLogAt = 0;
|
|
19306
|
+
process.on("unhandledRejection", (reason) => {
|
|
19307
|
+
const now = Date.now();
|
|
19308
|
+
if (now - lastUnhandledLogAt < 6e4) return;
|
|
19309
|
+
lastUnhandledLogAt = now;
|
|
19310
|
+
const r = reason;
|
|
19311
|
+
console.warn(`[agentmemory] unhandledRejection (suppressed):`, r?.code ? `${r.code} ${r.function_id ?? ""} ${r.message ?? ""}`.trim() : reason);
|
|
19312
|
+
});
|
|
19118
19313
|
async function main() {
|
|
19119
19314
|
const config = loadConfig();
|
|
19120
19315
|
const embeddingConfig = loadEmbeddingConfig();
|