@agentmemory/agentmemory 0.9.27 → 0.9.28
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/AGENTS.md +5 -5
- package/README.md +97 -37
- package/dist/cli.d.mts.map +1 -1
- package/dist/cli.mjs +206 -154
- package/dist/cli.mjs.map +1 -1
- package/dist/config-ChC9EtgV.mjs +259 -0
- package/dist/config-ChC9EtgV.mjs.map +1 -0
- package/dist/{connect-bmZ5eqYN.mjs → connect-JnsJXc68.mjs} +136 -42
- package/dist/connect-JnsJXc68.mjs.map +1 -0
- package/dist/hooks/notification.mjs +2 -1
- package/dist/hooks/notification.mjs.map +1 -1
- package/dist/hooks/post-commit.mjs +2 -1
- package/dist/hooks/post-commit.mjs.map +1 -1
- package/dist/hooks/post-tool-failure.mjs +2 -1
- package/dist/hooks/post-tool-failure.mjs.map +1 -1
- package/dist/hooks/post-tool-use.mjs +2 -1
- package/dist/hooks/post-tool-use.mjs.map +1 -1
- package/dist/hooks/pre-compact.mjs +2 -1
- package/dist/hooks/pre-compact.mjs.map +1 -1
- package/dist/hooks/pre-tool-use.mjs +2 -1
- package/dist/hooks/pre-tool-use.mjs.map +1 -1
- package/dist/hooks/prompt-submit.mjs +2 -1
- package/dist/hooks/prompt-submit.mjs.map +1 -1
- package/dist/hooks/session-end.mjs +2 -1
- package/dist/hooks/session-end.mjs.map +1 -1
- package/dist/hooks/session-start.mjs +2 -1
- package/dist/hooks/session-start.mjs.map +1 -1
- package/dist/hooks/stop.mjs +2 -1
- package/dist/hooks/stop.mjs.map +1 -1
- package/dist/hooks/subagent-start.mjs +2 -1
- package/dist/hooks/subagent-start.mjs.map +1 -1
- package/dist/hooks/subagent-stop.mjs +2 -1
- package/dist/hooks/subagent-stop.mjs.map +1 -1
- package/dist/hooks/task-completed.mjs +2 -1
- package/dist/hooks/task-completed.mjs.map +1 -1
- package/dist/image-refs-BKLmp_sD.mjs +34 -0
- package/dist/image-refs-BKLmp_sD.mjs.map +1 -0
- package/dist/{image-refs-B5Zf_Djo.mjs → image-refs-C2YU7BIm.mjs} +3 -21
- package/dist/image-refs-C2YU7BIm.mjs.map +1 -0
- package/dist/index.mjs +118 -150
- package/dist/index.mjs.map +1 -1
- package/dist/{image-store-Gpo2mgM9.mjs → keyed-mutex-DTHtcZrt.mjs} +14 -11
- package/dist/keyed-mutex-DTHtcZrt.mjs.map +1 -0
- package/dist/{logger-yHTcEBAI.mjs → logger-BEB7pCI9.mjs} +1 -1
- package/dist/{logger-yHTcEBAI.mjs.map → logger-BEB7pCI9.mjs.map} +1 -1
- package/dist/{src-MOg2zKJs.mjs → src-CzgoepGU.mjs} +49 -30
- package/dist/src-CzgoepGU.mjs.map +1 -0
- package/dist/{standalone-BORXC71-.mjs → standalone-YsZFFQBM.mjs} +7 -4
- package/dist/standalone-YsZFFQBM.mjs.map +1 -0
- package/dist/standalone.d.mts.map +1 -1
- package/dist/standalone.mjs +6 -2
- package/dist/standalone.mjs.map +1 -1
- package/dist/{tools-registry-D8XVVPbJ.mjs → tools-registry-D3NEoe5m.mjs} +4 -256
- package/dist/tools-registry-D3NEoe5m.mjs.map +1 -0
- package/package.json +4 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/plugin.json +2 -2
- package/plugin/scripts/notification.mjs +2 -1
- package/plugin/scripts/notification.mjs.map +1 -1
- package/plugin/scripts/post-commit.mjs +2 -1
- package/plugin/scripts/post-commit.mjs.map +1 -1
- package/plugin/scripts/post-tool-failure.mjs +2 -1
- package/plugin/scripts/post-tool-failure.mjs.map +1 -1
- package/plugin/scripts/post-tool-use.mjs +2 -1
- package/plugin/scripts/post-tool-use.mjs.map +1 -1
- package/plugin/scripts/pre-compact.mjs +2 -1
- package/plugin/scripts/pre-compact.mjs.map +1 -1
- package/plugin/scripts/pre-tool-use.mjs +2 -1
- package/plugin/scripts/pre-tool-use.mjs.map +1 -1
- package/plugin/scripts/prompt-submit.mjs +2 -1
- package/plugin/scripts/prompt-submit.mjs.map +1 -1
- package/plugin/scripts/session-end.mjs +2 -1
- package/plugin/scripts/session-end.mjs.map +1 -1
- package/plugin/scripts/session-start.mjs +2 -1
- package/plugin/scripts/session-start.mjs.map +1 -1
- package/plugin/scripts/stop.mjs +2 -1
- package/plugin/scripts/stop.mjs.map +1 -1
- package/plugin/scripts/subagent-start.mjs +2 -1
- package/plugin/scripts/subagent-start.mjs.map +1 -1
- package/plugin/scripts/subagent-stop.mjs +2 -1
- package/plugin/scripts/subagent-stop.mjs.map +1 -1
- package/plugin/scripts/task-completed.mjs +2 -1
- package/plugin/scripts/task-completed.mjs.map +1 -1
- package/plugin/skills/_shared/TROUBLESHOOTING.md +38 -0
- package/plugin/skills/agentmemory-agents/REFERENCE.md +28 -0
- package/plugin/skills/agentmemory-agents/SKILL.md +34 -0
- package/plugin/skills/agentmemory-architecture/SKILL.md +33 -0
- package/plugin/skills/agentmemory-config/REFERENCE.md +42 -0
- package/plugin/skills/agentmemory-config/SKILL.md +37 -0
- package/plugin/skills/agentmemory-hooks/REFERENCE.md +20 -0
- package/plugin/skills/agentmemory-hooks/SKILL.md +39 -0
- package/plugin/skills/agentmemory-mcp-tools/REFERENCE.md +65 -0
- package/plugin/skills/agentmemory-mcp-tools/SKILL.md +39 -0
- package/plugin/skills/agentmemory-rest-api/REFERENCE.md +129 -0
- package/plugin/skills/agentmemory-rest-api/SKILL.md +43 -0
- package/plugin/skills/commit-context/EXAMPLES.md +71 -0
- package/plugin/skills/commit-context/SKILL.md +53 -8
- package/plugin/skills/commit-history/EXAMPLES.md +71 -0
- package/plugin/skills/commit-history/SKILL.md +51 -9
- package/plugin/skills/forget/EXAMPLES.md +75 -0
- package/plugin/skills/forget/SKILL.md +54 -14
- package/plugin/skills/handoff/EXAMPLES.md +56 -0
- package/plugin/skills/handoff/SKILL.md +56 -9
- package/plugin/skills/recall/EXAMPLES.md +74 -0
- package/plugin/skills/recall/SKILL.md +50 -11
- package/plugin/skills/recap/EXAMPLES.md +60 -0
- package/plugin/skills/recap/SKILL.md +51 -13
- package/plugin/skills/remember/EXAMPLES.md +67 -0
- package/plugin/skills/remember/SKILL.md +53 -17
- package/plugin/skills/session-history/EXAMPLES.md +59 -0
- package/plugin/skills/session-history/SKILL.md +54 -11
- package/plugin/skills/write-agentmemory-skill/SKILL.md +40 -0
- package/dist/connect-bmZ5eqYN.mjs.map +0 -1
- package/dist/image-refs-B5Zf_Djo.mjs.map +0 -1
- package/dist/image-store-Gpo2mgM9.mjs.map +0 -1
- package/dist/rolldown-runtime-twds-ZHy.mjs +0 -14
- package/dist/src-MOg2zKJs.mjs.map +0 -1
- package/dist/standalone-BORXC71-.mjs.map +0 -1
- package/dist/tools-registry-D8XVVPbJ.mjs.map +0 -1
- package/dist/version-9DNrRyph.mjs +0 -6
- package/dist/version-9DNrRyph.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -4,6 +4,7 @@ import { TriggerAction, registerWorker } from "iii-sdk";
|
|
|
4
4
|
import { constants, existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { basename, dirname, extname, join, resolve, sep } from "node:path";
|
|
6
6
|
import { homedir } from "node:os";
|
|
7
|
+
import pc from "picocolors";
|
|
7
8
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
8
9
|
import Anthropic from "@anthropic-ai/sdk";
|
|
9
10
|
import { lstat, mkdir, open, readFile, readdir, stat, unlink, utimes, writeFile } from "node:fs/promises";
|
|
@@ -15,18 +16,6 @@ import { lookup } from "node:dns/promises";
|
|
|
15
16
|
import { isIP } from "node:net";
|
|
16
17
|
import { fileURLToPath } from "node:url";
|
|
17
18
|
import { createServer } from "node:http";
|
|
18
|
-
//#region \0rolldown/runtime.js
|
|
19
|
-
var __defProp = Object.defineProperty;
|
|
20
|
-
var __exportAll = (all, no_symbols) => {
|
|
21
|
-
let target = {};
|
|
22
|
-
for (var name in all) __defProp(target, name, {
|
|
23
|
-
get: all[name],
|
|
24
|
-
enumerable: true
|
|
25
|
-
});
|
|
26
|
-
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
27
|
-
return target;
|
|
28
|
-
};
|
|
29
|
-
//#endregion
|
|
30
19
|
//#region src/config.ts
|
|
31
20
|
function safeParseInt(value, fallback) {
|
|
32
21
|
if (!value) return fallback;
|
|
@@ -102,14 +91,14 @@ function detectProvider(env) {
|
|
|
102
91
|
};
|
|
103
92
|
}
|
|
104
93
|
if (!(env["AGENTMEMORY_ALLOW_AGENT_SDK"] === "true")) {
|
|
105
|
-
process.stderr.write("[agentmemory] No LLM provider key
|
|
94
|
+
process.stderr.write(pc.dim("[agentmemory] No LLM provider key set — running zero-LLM (BM25 + on-device embeddings). Set ANTHROPIC_API_KEY (or GEMINI/OPENAI/OPENROUTER/MINIMAX) in ~/.agentmemory/.env for LLM compression and summaries. Agent-SDK fallback stays off by default to avoid a Stop-hook recursion loop; opt in with AGENTMEMORY_AUTO_COMPRESS=true + AGENTMEMORY_ALLOW_AGENT_SDK=true.\n"));
|
|
106
95
|
return {
|
|
107
96
|
provider: "noop",
|
|
108
97
|
model: "noop",
|
|
109
98
|
maxTokens
|
|
110
99
|
};
|
|
111
100
|
}
|
|
112
|
-
process.stderr.write("[agentmemory] WARNING: agent-sdk fallback enabled via AGENTMEMORY_ALLOW_AGENT_SDK=true. This spawns @anthropic-ai/claude-agent-sdk child sessions that can trigger the Stop-hook recursion loop
|
|
101
|
+
process.stderr.write("[agentmemory] WARNING: agent-sdk fallback enabled via AGENTMEMORY_ALLOW_AGENT_SDK=true. This spawns @anthropic-ai/claude-agent-sdk child sessions that can trigger the Stop-hook recursion loop. A SDK-child env marker is set to block re-entry, but prefer setting a real API key in ~/.agentmemory/.env instead.\n");
|
|
113
102
|
return {
|
|
114
103
|
provider: "agent-sdk",
|
|
115
104
|
model: "claude-sonnet-4-20250514",
|
|
@@ -269,7 +258,7 @@ function loadFallbackConfig() {
|
|
|
269
258
|
const allowAgentSdk = env["AGENTMEMORY_ALLOW_AGENT_SDK"] === "true";
|
|
270
259
|
return { providers: raw.split(",").map((p) => p.trim()).filter((p) => Boolean(p) && VALID_PROVIDERS.has(p)).filter((p) => {
|
|
271
260
|
if (p === "agent-sdk" && !allowAgentSdk) {
|
|
272
|
-
process.stderr.write("[agentmemory] Ignoring FALLBACK_PROVIDERS entry 'agent-sdk' (AGENTMEMORY_ALLOW_AGENT_SDK is not 'true'). The agent-sdk fallback can spawn Claude Agent SDK child sessions that trigger the Stop-hook recursion loop
|
|
261
|
+
process.stderr.write("[agentmemory] Ignoring FALLBACK_PROVIDERS entry 'agent-sdk' (AGENTMEMORY_ALLOW_AGENT_SDK is not 'true'). The agent-sdk fallback can spawn Claude Agent SDK child sessions that trigger the Stop-hook recursion loop. Opt in explicitly with AGENTMEMORY_ALLOW_AGENT_SDK=true if this is intentional.\n");
|
|
273
262
|
return false;
|
|
274
263
|
}
|
|
275
264
|
return true;
|
|
@@ -3639,6 +3628,74 @@ function registerSearchFunction(sdk, kv) {
|
|
|
3639
3628
|
});
|
|
3640
3629
|
}
|
|
3641
3630
|
//#endregion
|
|
3631
|
+
//#region src/utils/image-store.ts
|
|
3632
|
+
const IMAGES_DIR = join(homedir(), ".agentmemory", "images");
|
|
3633
|
+
const DEFAULT_MAX_BYTES = 500 * 1024 * 1024;
|
|
3634
|
+
function getMaxBytes() {
|
|
3635
|
+
return Number(process.env.AGENTMEMORY_IMAGE_STORE_MAX_BYTES) || DEFAULT_MAX_BYTES;
|
|
3636
|
+
}
|
|
3637
|
+
function isManagedImagePath(filePath) {
|
|
3638
|
+
const resolved = resolve(filePath);
|
|
3639
|
+
const normalizedImagesDir = resolve(IMAGES_DIR);
|
|
3640
|
+
return resolved.startsWith(normalizedImagesDir + sep) || resolved === normalizedImagesDir;
|
|
3641
|
+
}
|
|
3642
|
+
function contentHash(data) {
|
|
3643
|
+
return createHash("sha256").update(data).digest("hex");
|
|
3644
|
+
}
|
|
3645
|
+
async function saveImageToDisk(base64Data) {
|
|
3646
|
+
if (!base64Data) return {
|
|
3647
|
+
filePath: "",
|
|
3648
|
+
bytesWritten: 0
|
|
3649
|
+
};
|
|
3650
|
+
if (!existsSync(IMAGES_DIR)) await mkdir(IMAGES_DIR, { recursive: true });
|
|
3651
|
+
let cleanBase64 = base64Data;
|
|
3652
|
+
let ext = "png";
|
|
3653
|
+
if (base64Data.startsWith("data:image/")) {
|
|
3654
|
+
const commaIdx = base64Data.indexOf(",");
|
|
3655
|
+
if (commaIdx !== -1) {
|
|
3656
|
+
const meta = base64Data.substring(0, commaIdx);
|
|
3657
|
+
if (meta.includes("jpeg") || meta.includes("jpg")) ext = "jpg";
|
|
3658
|
+
else if (meta.includes("webp")) ext = "webp";
|
|
3659
|
+
else if (meta.includes("gif")) ext = "gif";
|
|
3660
|
+
cleanBase64 = base64Data.substring(commaIdx + 1);
|
|
3661
|
+
}
|
|
3662
|
+
} else if (base64Data.startsWith("/9j/")) ext = "jpg";
|
|
3663
|
+
const filePath = join(IMAGES_DIR, `${contentHash(cleanBase64)}.${ext}`);
|
|
3664
|
+
if (existsSync(filePath)) return {
|
|
3665
|
+
filePath,
|
|
3666
|
+
bytesWritten: 0
|
|
3667
|
+
};
|
|
3668
|
+
await writeFile(filePath, Buffer.from(cleanBase64, "base64"));
|
|
3669
|
+
return {
|
|
3670
|
+
filePath,
|
|
3671
|
+
bytesWritten: (await stat(filePath)).size
|
|
3672
|
+
};
|
|
3673
|
+
}
|
|
3674
|
+
async function deleteImage(filePath) {
|
|
3675
|
+
if (!filePath) return { deletedBytes: 0 };
|
|
3676
|
+
if (!isManagedImagePath(filePath)) return { deletedBytes: 0 };
|
|
3677
|
+
try {
|
|
3678
|
+
if (existsSync(filePath)) {
|
|
3679
|
+
const size = (await stat(filePath)).size;
|
|
3680
|
+
await unlink(filePath);
|
|
3681
|
+
return { deletedBytes: size };
|
|
3682
|
+
}
|
|
3683
|
+
} catch (err) {
|
|
3684
|
+
console.error("[agentmemory] Failed to delete image context:", err);
|
|
3685
|
+
}
|
|
3686
|
+
return { deletedBytes: 0 };
|
|
3687
|
+
}
|
|
3688
|
+
/** Touch an image file to update its mtime (marking it as recently used for LRU eviction) */
|
|
3689
|
+
async function touchImage(filePath) {
|
|
3690
|
+
if (!filePath || !isManagedImagePath(filePath)) return;
|
|
3691
|
+
try {
|
|
3692
|
+
if (existsSync(filePath)) {
|
|
3693
|
+
const now = /* @__PURE__ */ new Date();
|
|
3694
|
+
await utimes(filePath, now, now);
|
|
3695
|
+
}
|
|
3696
|
+
} catch (err) {}
|
|
3697
|
+
}
|
|
3698
|
+
//#endregion
|
|
3642
3699
|
//#region src/functions/observe.ts
|
|
3643
3700
|
function extractImage(d) {
|
|
3644
3701
|
if (!d) return void 0;
|
|
@@ -3716,10 +3773,9 @@ function registerObserveFunction(sdk, kv, dedupMap, maxObservationsPerSession) {
|
|
|
3716
3773
|
const inheritedAgentId = existingSession ? existingSession.agentId : getAgentId();
|
|
3717
3774
|
if (inheritedAgentId) raw.agentId = inheritedAgentId;
|
|
3718
3775
|
if (pendingImageData && (pendingImageData.startsWith("data:image/") || pendingImageData.startsWith("iVBORw0KGgo") || pendingImageData.startsWith("/9j/"))) {
|
|
3719
|
-
const { saveImageToDisk } = await Promise.resolve().then(() => image_store_exports);
|
|
3720
3776
|
const { filePath, bytesWritten } = await saveImageToDisk(pendingImageData);
|
|
3721
3777
|
raw.imageData = filePath;
|
|
3722
|
-
const { incrementImageRef } = await
|
|
3778
|
+
const { incrementImageRef } = await import("./image-refs-BKLmp_sD.mjs");
|
|
3723
3779
|
await incrementImageRef(kv, filePath);
|
|
3724
3780
|
sdk.trigger({
|
|
3725
3781
|
function_id: "mem::disk-size-delta",
|
|
@@ -3739,13 +3795,13 @@ function registerObserveFunction(sdk, kv, dedupMap, maxObservationsPerSession) {
|
|
|
3739
3795
|
try {
|
|
3740
3796
|
await kv.set(KV.observations(payload.sessionId), obsId, raw);
|
|
3741
3797
|
} catch (error) {
|
|
3742
|
-
if (raw.imageData) {
|
|
3743
|
-
const {
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
|
|
3798
|
+
if (raw.imageData) try {
|
|
3799
|
+
const { decrementImageRef } = await import("./image-refs-BKLmp_sD.mjs");
|
|
3800
|
+
await decrementImageRef(kv, sdk, raw.imageData);
|
|
3801
|
+
} catch (rollbackError) {
|
|
3802
|
+
logger.error("Failed to roll back image ref after observation write failure", {
|
|
3803
|
+
imageRef: raw.imageData,
|
|
3804
|
+
error: rollbackError instanceof Error ? rollbackError.message : String(rollbackError)
|
|
3749
3805
|
});
|
|
3750
3806
|
}
|
|
3751
3807
|
throw error;
|
|
@@ -3867,115 +3923,6 @@ function registerObserveFunction(sdk, kv, dedupMap, maxObservationsPerSession) {
|
|
|
3867
3923
|
});
|
|
3868
3924
|
}
|
|
3869
3925
|
//#endregion
|
|
3870
|
-
//#region src/utils/image-store.ts
|
|
3871
|
-
var image_store_exports = /* @__PURE__ */ __exportAll({
|
|
3872
|
-
IMAGES_DIR: () => IMAGES_DIR,
|
|
3873
|
-
deleteImage: () => deleteImage,
|
|
3874
|
-
getMaxBytes: () => getMaxBytes,
|
|
3875
|
-
isManagedImagePath: () => isManagedImagePath,
|
|
3876
|
-
saveImageToDisk: () => saveImageToDisk,
|
|
3877
|
-
touchImage: () => touchImage
|
|
3878
|
-
});
|
|
3879
|
-
const IMAGES_DIR = join(homedir(), ".agentmemory", "images");
|
|
3880
|
-
const DEFAULT_MAX_BYTES = 500 * 1024 * 1024;
|
|
3881
|
-
function getMaxBytes() {
|
|
3882
|
-
return Number(process.env.AGENTMEMORY_IMAGE_STORE_MAX_BYTES) || DEFAULT_MAX_BYTES;
|
|
3883
|
-
}
|
|
3884
|
-
function isManagedImagePath(filePath) {
|
|
3885
|
-
const resolved = resolve(filePath);
|
|
3886
|
-
const normalizedImagesDir = resolve(IMAGES_DIR);
|
|
3887
|
-
return resolved.startsWith(normalizedImagesDir + sep) || resolved === normalizedImagesDir;
|
|
3888
|
-
}
|
|
3889
|
-
function contentHash(data) {
|
|
3890
|
-
return createHash("sha256").update(data).digest("hex");
|
|
3891
|
-
}
|
|
3892
|
-
async function saveImageToDisk(base64Data) {
|
|
3893
|
-
if (!base64Data) return {
|
|
3894
|
-
filePath: "",
|
|
3895
|
-
bytesWritten: 0
|
|
3896
|
-
};
|
|
3897
|
-
if (!existsSync(IMAGES_DIR)) await mkdir(IMAGES_DIR, { recursive: true });
|
|
3898
|
-
let cleanBase64 = base64Data;
|
|
3899
|
-
let ext = "png";
|
|
3900
|
-
if (base64Data.startsWith("data:image/")) {
|
|
3901
|
-
const commaIdx = base64Data.indexOf(",");
|
|
3902
|
-
if (commaIdx !== -1) {
|
|
3903
|
-
const meta = base64Data.substring(0, commaIdx);
|
|
3904
|
-
if (meta.includes("jpeg") || meta.includes("jpg")) ext = "jpg";
|
|
3905
|
-
else if (meta.includes("webp")) ext = "webp";
|
|
3906
|
-
else if (meta.includes("gif")) ext = "gif";
|
|
3907
|
-
cleanBase64 = base64Data.substring(commaIdx + 1);
|
|
3908
|
-
}
|
|
3909
|
-
} else if (base64Data.startsWith("/9j/")) ext = "jpg";
|
|
3910
|
-
const filePath = join(IMAGES_DIR, `${contentHash(cleanBase64)}.${ext}`);
|
|
3911
|
-
if (existsSync(filePath)) return {
|
|
3912
|
-
filePath,
|
|
3913
|
-
bytesWritten: 0
|
|
3914
|
-
};
|
|
3915
|
-
await writeFile(filePath, Buffer.from(cleanBase64, "base64"));
|
|
3916
|
-
return {
|
|
3917
|
-
filePath,
|
|
3918
|
-
bytesWritten: (await stat(filePath)).size
|
|
3919
|
-
};
|
|
3920
|
-
}
|
|
3921
|
-
async function deleteImage(filePath) {
|
|
3922
|
-
if (!filePath) return { deletedBytes: 0 };
|
|
3923
|
-
if (!isManagedImagePath(filePath)) return { deletedBytes: 0 };
|
|
3924
|
-
try {
|
|
3925
|
-
if (existsSync(filePath)) {
|
|
3926
|
-
const size = (await stat(filePath)).size;
|
|
3927
|
-
await unlink(filePath);
|
|
3928
|
-
return { deletedBytes: size };
|
|
3929
|
-
}
|
|
3930
|
-
} catch (err) {
|
|
3931
|
-
console.error("[agentmemory] Failed to delete image context:", err);
|
|
3932
|
-
}
|
|
3933
|
-
return { deletedBytes: 0 };
|
|
3934
|
-
}
|
|
3935
|
-
/** Touch an image file to update its mtime (marking it as recently used for LRU eviction) */
|
|
3936
|
-
async function touchImage(filePath) {
|
|
3937
|
-
if (!filePath || !isManagedImagePath(filePath)) return;
|
|
3938
|
-
try {
|
|
3939
|
-
if (existsSync(filePath)) {
|
|
3940
|
-
const now = /* @__PURE__ */ new Date();
|
|
3941
|
-
await utimes(filePath, now, now);
|
|
3942
|
-
}
|
|
3943
|
-
} catch (err) {}
|
|
3944
|
-
}
|
|
3945
|
-
//#endregion
|
|
3946
|
-
//#region src/functions/image-refs.ts
|
|
3947
|
-
var image_refs_exports = /* @__PURE__ */ __exportAll({
|
|
3948
|
-
decrementImageRef: () => decrementImageRef,
|
|
3949
|
-
getImageRefCount: () => getImageRefCount,
|
|
3950
|
-
incrementImageRef: () => incrementImageRef
|
|
3951
|
-
});
|
|
3952
|
-
async function getImageRefCount(kv, filePath) {
|
|
3953
|
-
const count = await kv.get(KV.imageRefs, filePath);
|
|
3954
|
-
return count ? Number(count) : 0;
|
|
3955
|
-
}
|
|
3956
|
-
async function incrementImageRef(kv, filePath) {
|
|
3957
|
-
return withKeyedLock(`imgRef:${filePath}`, async () => {
|
|
3958
|
-
const current = await getImageRefCount(kv, filePath);
|
|
3959
|
-
await kv.set(KV.imageRefs, filePath, current + 1);
|
|
3960
|
-
await touchImage(filePath);
|
|
3961
|
-
});
|
|
3962
|
-
}
|
|
3963
|
-
async function decrementImageRef(kv, sdk, filePath) {
|
|
3964
|
-
return withKeyedLock(`imgRef:${filePath}`, async () => {
|
|
3965
|
-
const current = await getImageRefCount(kv, filePath);
|
|
3966
|
-
if (current <= 1) {
|
|
3967
|
-
await kv.delete(KV.imageEmbeddings, filePath);
|
|
3968
|
-
await kv.delete(KV.imageRefs, filePath);
|
|
3969
|
-
const { deletedBytes } = await deleteImage(filePath);
|
|
3970
|
-
if (deletedBytes > 0) sdk.trigger({
|
|
3971
|
-
function_id: "mem::disk-size-delta",
|
|
3972
|
-
payload: { deltaBytes: -deletedBytes },
|
|
3973
|
-
action: TriggerAction.Void()
|
|
3974
|
-
});
|
|
3975
|
-
} else await kv.set(KV.imageRefs, filePath, current - 1);
|
|
3976
|
-
});
|
|
3977
|
-
}
|
|
3978
|
-
//#endregion
|
|
3979
3926
|
//#region src/functions/image-quota-cleanup.ts
|
|
3980
3927
|
const GRACE_PERIOD_MS = 3e4;
|
|
3981
3928
|
function registerImageQuotaCleanup(sdk, kv) {
|
|
@@ -4023,6 +3970,7 @@ function registerImageQuotaCleanup(sdk, kv) {
|
|
|
4023
3970
|
await withKeyedLock(`imgRef:${f.filePath}`, async () => {
|
|
4024
3971
|
let refCount;
|
|
4025
3972
|
try {
|
|
3973
|
+
const { getImageRefCount } = await import("./image-refs-BKLmp_sD.mjs");
|
|
4026
3974
|
refCount = await getImageRefCount(kv, f.filePath);
|
|
4027
3975
|
} catch (err) {
|
|
4028
3976
|
logger.error("Failed to read refCount; skipping eviction", {
|
|
@@ -5113,6 +5061,12 @@ function registerContextFunction(sdk, kv, tokenBudget) {
|
|
|
5113
5061
|
sdk.registerFunction("mem::context", async (data) => {
|
|
5114
5062
|
const budget = data.budget || tokenBudget;
|
|
5115
5063
|
const blocks = [];
|
|
5064
|
+
const isolated = isAgentScopeIsolated();
|
|
5065
|
+
const explicitAgentId = typeof data.agentId === "string" && data.agentId.trim().length > 0 ? data.agentId.trim() : void 0;
|
|
5066
|
+
const wildcardAgent = explicitAgentId === "*";
|
|
5067
|
+
const envAgentId = isolated ? getAgentId() : void 0;
|
|
5068
|
+
const filterAgentId = wildcardAgent ? void 0 : explicitAgentId ?? envAgentId;
|
|
5069
|
+
if (isolated && !wildcardAgent && !explicitAgentId && !envAgentId) throw new Error("mem::context: AGENTMEMORY_AGENT_SCOPE=isolated is set but no agent id is available (env AGENT_ID unset and no explicit agentId in the call). Refusing to read cross-agent rows. Pass agentId: \"*\" to opt in to a wildcard read.");
|
|
5116
5070
|
const [pinnedSlots, profile, lessons] = await Promise.all([
|
|
5117
5071
|
isSlotsEnabled() ? listPinnedSlots(kv).catch(() => []) : Promise.resolve([]),
|
|
5118
5072
|
kv.get(KV.profiles, data.project).catch(() => null),
|
|
@@ -5159,7 +5113,7 @@ function registerContextFunction(sdk, kv, tokenBudget) {
|
|
|
5159
5113
|
sourceIds: relevantLessons.map((l) => l.id)
|
|
5160
5114
|
});
|
|
5161
5115
|
}
|
|
5162
|
-
const sessions = (await kv.list(KV.sessions)).filter((s) => s.project === data.project && s.id !== data.sessionId).sort((a, b) => new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime()).slice(0, 10);
|
|
5116
|
+
const sessions = (await kv.list(KV.sessions)).filter((s) => s.project === data.project && s.id !== data.sessionId && (filterAgentId === void 0 || s.agentId === filterAgentId)).sort((a, b) => new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime()).slice(0, 10);
|
|
5163
5117
|
const summariesPerSession = await Promise.all(sessions.map((s) => kv.get(KV.summaries, s.id).catch(() => null)));
|
|
5164
5118
|
const sessionsNeedingObs = [];
|
|
5165
5119
|
for (let i = 0; i < sessions.length; i++) {
|
|
@@ -6149,7 +6103,7 @@ function registerRememberFunction(sdk, kv) {
|
|
|
6149
6103
|
const deletedMemoryIds = [];
|
|
6150
6104
|
const deletedObservationIds = [];
|
|
6151
6105
|
let deletedSession = false;
|
|
6152
|
-
const { decrementImageRef } = await
|
|
6106
|
+
const { decrementImageRef } = await import("./image-refs-BKLmp_sD.mjs");
|
|
6153
6107
|
if (data.memoryId) {
|
|
6154
6108
|
const mem = await kv.get(KV.memories, data.memoryId);
|
|
6155
6109
|
await kv.delete(KV.memories, data.memoryId);
|
|
@@ -6256,7 +6210,7 @@ async function runRecoveredSessionConsolidation(sdk) {
|
|
|
6256
6210
|
function registerEvictFunction(sdk, kv) {
|
|
6257
6211
|
sdk.registerFunction("mem::evict", async (data) => {
|
|
6258
6212
|
const dryRun = data?.dryRun ?? false;
|
|
6259
|
-
const { decrementImageRef } = await
|
|
6213
|
+
const { decrementImageRef } = await import("./image-refs-BKLmp_sD.mjs");
|
|
6260
6214
|
const configOverride = await kv.get(KV.config, "eviction").catch(() => null);
|
|
6261
6215
|
const cfg = {
|
|
6262
6216
|
...DEFAULTS$1,
|
|
@@ -6704,7 +6658,7 @@ async function findByKeyword(kv, keyword, project) {
|
|
|
6704
6658
|
}
|
|
6705
6659
|
//#endregion
|
|
6706
6660
|
//#region src/version.ts
|
|
6707
|
-
const VERSION = "0.9.
|
|
6661
|
+
const VERSION = "0.9.28";
|
|
6708
6662
|
//#endregion
|
|
6709
6663
|
//#region src/telemetry/setup.ts
|
|
6710
6664
|
const OTEL_CONFIG = {
|
|
@@ -7074,7 +7028,7 @@ function registerAutoForgetFunction(sdk, kv) {
|
|
|
7074
7028
|
sdk.registerFunction("mem::auto-forget", async (data) => {
|
|
7075
7029
|
const dryRun = data?.dryRun ?? false;
|
|
7076
7030
|
const now = Date.now();
|
|
7077
|
-
const { decrementImageRef } = await
|
|
7031
|
+
const { decrementImageRef } = await import("./image-refs-BKLmp_sD.mjs");
|
|
7078
7032
|
const result = {
|
|
7079
7033
|
ttlExpired: [],
|
|
7080
7034
|
contradictions: [],
|
|
@@ -7334,7 +7288,8 @@ function registerExportImportFunction(sdk, kv) {
|
|
|
7334
7288
|
"0.9.24",
|
|
7335
7289
|
"0.9.25",
|
|
7336
7290
|
"0.9.26",
|
|
7337
|
-
"0.9.27"
|
|
7291
|
+
"0.9.27",
|
|
7292
|
+
"0.9.28"
|
|
7338
7293
|
]).has(importData.version)) return {
|
|
7339
7294
|
success: false,
|
|
7340
7295
|
error: `Unsupported export version: ${importData.version}`
|
|
@@ -14212,7 +14167,7 @@ function registerRetentionFunctions(sdk, kv) {
|
|
|
14212
14167
|
const threshold = typeof data?.threshold === "number" && Number.isFinite(data.threshold) ? data.threshold : DEFAULT_DECAY.tierThresholds.cold;
|
|
14213
14168
|
const maxEvictRaw = typeof data?.maxEvict === "number" && Number.isInteger(data.maxEvict) ? data.maxEvict : 50;
|
|
14214
14169
|
const maxEvict = Math.min(1e3, Math.max(0, maxEvictRaw));
|
|
14215
|
-
const { decrementImageRef } = await
|
|
14170
|
+
const { decrementImageRef } = await import("./image-refs-BKLmp_sD.mjs");
|
|
14216
14171
|
const candidates = (await kv.list(KV.retentionScores)).filter((s) => s.score < threshold).sort((a, b) => a.score - b.score).slice(0, maxEvict);
|
|
14217
14172
|
if (data?.dryRun) return {
|
|
14218
14173
|
success: true,
|
|
@@ -15680,11 +15635,15 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
|
|
|
15680
15635
|
status_code: 400,
|
|
15681
15636
|
body: { error: "budget must be a positive integer" }
|
|
15682
15637
|
};
|
|
15638
|
+
const queryAgentId = typeof req.query_params?.["agentId"] === "string" ? req.query_params["agentId"] : void 0;
|
|
15639
|
+
const bodyAgentId = typeof body.agentId === "string" && body.agentId.trim().length > 0 ? body.agentId.trim() : void 0;
|
|
15683
15640
|
const payload = {
|
|
15684
15641
|
sessionId,
|
|
15685
15642
|
project
|
|
15686
15643
|
};
|
|
15687
15644
|
if (budget !== void 0) payload.budget = budget;
|
|
15645
|
+
const agentId = bodyAgentId ?? queryAgentId;
|
|
15646
|
+
if (agentId !== void 0) payload.agentId = agentId;
|
|
15688
15647
|
return {
|
|
15689
15648
|
status_code: 200,
|
|
15690
15649
|
body: await sdk.trigger({
|
|
@@ -15896,7 +15855,8 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
|
|
|
15896
15855
|
function_id: "mem::context",
|
|
15897
15856
|
payload: {
|
|
15898
15857
|
sessionId,
|
|
15899
|
-
project
|
|
15858
|
+
project,
|
|
15859
|
+
...agentId ? { agentId } : {}
|
|
15900
15860
|
}
|
|
15901
15861
|
})).context
|
|
15902
15862
|
}
|
|
@@ -16088,9 +16048,14 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
|
|
|
16088
16048
|
const normalizedAgentId = typeof req.query_params?.["agentId"] === "string" ? req.query_params["agentId"].trim() : void 0;
|
|
16089
16049
|
const wildcardAgent = normalizedAgentId === "*";
|
|
16090
16050
|
const filterAgentId = wildcardAgent ? void 0 : (normalizedAgentId && !wildcardAgent ? normalizedAgentId : void 0) ?? (isAgentScopeIsolated() ? getAgentId() : void 0);
|
|
16051
|
+
const filtered = filterAgentId ? sessions.filter((s) => s.agentId === filterAgentId) : sessions;
|
|
16052
|
+
const summaries = await Promise.all(filtered.map((s) => kv.get(KV.summaries, s.id).catch(() => null)));
|
|
16091
16053
|
return {
|
|
16092
16054
|
status_code: 200,
|
|
16093
|
-
body: { sessions:
|
|
16055
|
+
body: { sessions: filtered.map((s, i) => summaries[i] ? {
|
|
16056
|
+
...s,
|
|
16057
|
+
summary: summaries[i]
|
|
16058
|
+
} : s) }
|
|
16094
16059
|
};
|
|
16095
16060
|
});
|
|
16096
16061
|
sdk.registerTrigger({
|
|
@@ -18970,13 +18935,15 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
|
|
|
18970
18935
|
//#region src/triggers/events.ts
|
|
18971
18936
|
function registerEventTriggers(sdk, kv) {
|
|
18972
18937
|
sdk.registerFunction("event::session::started", async (data) => {
|
|
18938
|
+
const agentId = (typeof data.agentId === "string" && data.agentId.trim().length > 0 ? data.agentId.trim().slice(0, 128) : void 0) ?? getAgentId();
|
|
18973
18939
|
const session = {
|
|
18974
18940
|
id: data.sessionId,
|
|
18975
18941
|
project: data.project,
|
|
18976
18942
|
cwd: data.cwd,
|
|
18977
18943
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
18978
18944
|
status: "active",
|
|
18979
|
-
observationCount: 0
|
|
18945
|
+
observationCount: 0,
|
|
18946
|
+
...agentId ? { agentId } : {}
|
|
18980
18947
|
};
|
|
18981
18948
|
await kv.set(KV.sessions, data.sessionId, session);
|
|
18982
18949
|
return {
|
|
@@ -18985,7 +18952,8 @@ function registerEventTriggers(sdk, kv) {
|
|
|
18985
18952
|
function_id: "mem::context",
|
|
18986
18953
|
payload: {
|
|
18987
18954
|
sessionId: data.sessionId,
|
|
18988
|
-
project: data.project
|
|
18955
|
+
project: data.project,
|
|
18956
|
+
...agentId ? { agentId } : {}
|
|
18989
18957
|
}
|
|
18990
18958
|
})).context
|
|
18991
18959
|
};
|
|
@@ -22019,10 +21987,10 @@ async function main() {
|
|
|
22019
21987
|
}
|
|
22020
21988
|
registerConsolidationPipelineFunction(sdk, kv, provider);
|
|
22021
21989
|
bootLog(`Consolidation pipeline: registered (CONSOLIDATION_ENABLED=${isConsolidationEnabled() ? "true" : "false"})`);
|
|
22022
|
-
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
|
|
22023
|
-
else bootLog(`Auto-compress: OFF (default
|
|
22024
|
-
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
|
|
22025
|
-
else bootLog(`Context injection: OFF (default
|
|
21990
|
+
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. Set AGENTMEMORY_AUTO_COMPRESS=false to disable.`);
|
|
21991
|
+
else bootLog(`Auto-compress: OFF (default) — observations indexed via zero-LLM synthetic compression. Set AGENTMEMORY_AUTO_COMPRESS=true to opt-in to LLM-powered summaries (uses your API key).`);
|
|
21992
|
+
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. Set AGENTMEMORY_INJECT_CONTEXT=false to disable.`);
|
|
21993
|
+
else bootLog(`Context injection: OFF (default) — 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).`);
|
|
22026
21994
|
const teamConfig = loadTeamConfig();
|
|
22027
21995
|
if (teamConfig) {
|
|
22028
21996
|
registerTeamFunction(sdk, kv, teamConfig);
|
|
@@ -22129,7 +22097,7 @@ async function main() {
|
|
|
22129
22097
|
backfilled++;
|
|
22130
22098
|
}
|
|
22131
22099
|
if (backfilled > 0) {
|
|
22132
|
-
bootLog(`Backfilled ${backfilled} memories into BM25 (legacy gap
|
|
22100
|
+
bootLog(`Backfilled ${backfilled} memories into BM25 (legacy index gap)`);
|
|
22133
22101
|
indexPersistence.scheduleSave();
|
|
22134
22102
|
}
|
|
22135
22103
|
} catch (err) {
|
|
@@ -22211,6 +22179,6 @@ main().catch((err) => {
|
|
|
22211
22179
|
process.exit(1);
|
|
22212
22180
|
});
|
|
22213
22181
|
//#endregion
|
|
22214
|
-
export {};
|
|
22182
|
+
export { KV as i, touchImage as n, withKeyedLock as r, deleteImage as t };
|
|
22215
22183
|
|
|
22216
22184
|
//# sourceMappingURL=index.mjs.map
|