@joshuaswarren/openclaw-engram 9.0.8 → 9.0.10
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/dist/index.js +46 -14
- package/dist/index.js.map +1 -1
- package/openclaw.plugin.json +5 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -74,7 +74,8 @@ var VALID_MEMORY_CATEGORIES = /* @__PURE__ */ new Set([
|
|
|
74
74
|
"principle",
|
|
75
75
|
"commitment",
|
|
76
76
|
"moment",
|
|
77
|
-
"skill"
|
|
77
|
+
"skill",
|
|
78
|
+
"rule"
|
|
78
79
|
]);
|
|
79
80
|
var DEFAULT_BEHAVIOR_LOOP_PROTECTED_PARAMS = [
|
|
80
81
|
"maxMemoryTokens",
|
|
@@ -472,6 +473,7 @@ function parseConfig(raw) {
|
|
|
472
473
|
delinearizeEnabled: cfg.delinearizeEnabled !== false,
|
|
473
474
|
recallConfidenceGateEnabled: cfg.recallConfidenceGateEnabled === true,
|
|
474
475
|
recallConfidenceGateThreshold: typeof cfg.recallConfidenceGateThreshold === "number" ? Math.max(0, Math.min(1, cfg.recallConfidenceGateThreshold)) : 0.12,
|
|
476
|
+
causalRuleExtractionEnabled: cfg.causalRuleExtractionEnabled === true,
|
|
475
477
|
graphLateralInhibitionEnabled: cfg.graphLateralInhibitionEnabled !== false,
|
|
476
478
|
graphLateralInhibitionBeta: typeof cfg.graphLateralInhibitionBeta === "number" ? Math.max(0, Math.min(1, cfg.graphLateralInhibitionBeta)) : 0.15,
|
|
477
479
|
graphLateralInhibitionTopM: typeof cfg.graphLateralInhibitionTopM === "number" ? Math.max(0, Math.round(cfg.graphLateralInhibitionTopM)) : 7,
|
|
@@ -1904,7 +1906,7 @@ function parseMemoryActionEligibilityContext(value) {
|
|
|
1904
1906
|
};
|
|
1905
1907
|
}
|
|
1906
1908
|
var ExtractedFactSchema = z.object({
|
|
1907
|
-
category: z.enum(["fact", "preference", "correction", "entity", "decision", "relationship", "principle", "commitment", "moment", "skill"]),
|
|
1909
|
+
category: z.enum(["fact", "preference", "correction", "entity", "decision", "relationship", "principle", "commitment", "moment", "skill", "rule"]),
|
|
1908
1910
|
content: z.string().describe("The memory content \u2014 a clear, standalone statement"),
|
|
1909
1911
|
confidence: z.number().min(0).max(1).describe("How confident are you this is correct (0-1)"),
|
|
1910
1912
|
tags: z.array(z.string()).describe("Relevant tags for categorization"),
|
|
@@ -2936,12 +2938,13 @@ Memory categories:
|
|
|
2936
2938
|
- principle: Durable rules, values, or operating beliefs (e.g., "never use Chat Completions API")
|
|
2937
2939
|
- commitment: Promises, obligations, or deadlines (e.g., "deploy by Friday", "call accountant Monday")
|
|
2938
2940
|
- moment: Emotionally significant events or milestones (e.g., "first successful deployment of engram")
|
|
2939
|
-
- skill: Capabilities the user or agent has demonstrated (e.g., "user is proficient with Kubernetes")
|
|
2941
|
+
- skill: Capabilities the user or agent has demonstrated (e.g., "user is proficient with Kubernetes")${this.config.causalRuleExtractionEnabled ? `
|
|
2942
|
+
- rule: Causal rules discovered through experience (format: "IF <condition> THEN <action/outcome>", e.g., "IF Shopify API returns 401 THEN the admin token is missing read_products scope")` : ""}
|
|
2940
2943
|
|
|
2941
2944
|
Rules:
|
|
2942
2945
|
- Only extract genuinely NEW information worth remembering across sessions
|
|
2943
2946
|
- Skip transient task details (file paths being edited, current errors, etc.)
|
|
2944
|
-
- Priority: corrections > principles > preferences > commitments > decisions > relationships > entities > moments > skills > facts
|
|
2947
|
+
- Priority: corrections > principles${this.config.causalRuleExtractionEnabled ? " > rules" : ""} > preferences > commitments > decisions > relationships > entities > moments > skills > facts
|
|
2945
2948
|
- Corrections (user saying "actually, don't do X" or "I prefer Y") get highest confidence
|
|
2946
2949
|
- Each fact should be a standalone, self-contained statement
|
|
2947
2950
|
- Entity references should use normalized names (lowercase, hyphenated: "jane-doe", "acme-corp")
|
|
@@ -3034,7 +3037,8 @@ Actions:
|
|
|
3034
3037
|
|
|
3035
3038
|
Also:
|
|
3036
3039
|
- Suggest profile updates based on patterns across memories
|
|
3037
|
-
- Identify entity updates for entity tracking`
|
|
3040
|
+
- Identify entity updates for entity tracking${this.config.causalRuleExtractionEnabled ? `
|
|
3041
|
+
- When merging or updating memories, look for IF\u2192THEN causal patterns. If a memory describes "X failed/succeeded because Y" or "doing X led to Y", rewrite its content to make the causal rule explicit in the form "IF <condition> THEN <action/outcome>".` : ""}`
|
|
3038
3042
|
},
|
|
3039
3043
|
{
|
|
3040
3044
|
role: "user",
|
|
@@ -3080,7 +3084,8 @@ Actions:
|
|
|
3080
3084
|
|
|
3081
3085
|
Also:
|
|
3082
3086
|
- Suggest profile updates based on patterns across memories
|
|
3083
|
-
- Identify entity updates for entity tracking
|
|
3087
|
+
- Identify entity updates for entity tracking${this.config.causalRuleExtractionEnabled ? `
|
|
3088
|
+
- When merging or updating memories, look for IF\u2192THEN causal patterns. If a memory describes "X failed/succeeded because Y" or "doing X led to Y", rewrite its content to make the causal rule explicit in the form "IF <condition> THEN <action/outcome>".` : ""}
|
|
3084
3089
|
|
|
3085
3090
|
Current behavioral profile:
|
|
3086
3091
|
${currentProfile || "(empty)"}
|
|
@@ -3198,7 +3203,8 @@ Actions:
|
|
|
3198
3203
|
|
|
3199
3204
|
Also:
|
|
3200
3205
|
- Suggest profile updates based on patterns across memories
|
|
3201
|
-
- Identify entity updates for entity tracking
|
|
3206
|
+
- Identify entity updates for entity tracking${this.config.causalRuleExtractionEnabled ? `
|
|
3207
|
+
- When merging or updating memories, look for IF\u2192THEN causal patterns. If a memory describes "X failed/succeeded because Y" or "doing X led to Y", rewrite its content to make the causal rule explicit in the form "IF <condition> THEN <action/outcome>".` : ""}
|
|
3202
3208
|
|
|
3203
3209
|
Current behavioral profile:
|
|
3204
3210
|
${currentProfile || "(empty)"}
|
|
@@ -3927,6 +3933,8 @@ var CATEGORY_BOOSTS = {
|
|
|
3927
3933
|
// Corrections are always important
|
|
3928
3934
|
principle: 0.12,
|
|
3929
3935
|
// Durable rules/values
|
|
3936
|
+
rule: 0.11,
|
|
3937
|
+
// Causal IF→THEN rules
|
|
3930
3938
|
preference: 0.1,
|
|
3931
3939
|
// User preferences matter
|
|
3932
3940
|
commitment: 0.1,
|
|
@@ -12528,6 +12536,9 @@ function serializeBoxFrontmatter(fm) {
|
|
|
12528
12536
|
];
|
|
12529
12537
|
if (fm.sessionKey) lines.push(`sessionKey: ${fm.sessionKey}`);
|
|
12530
12538
|
if (fm.traceId) lines.push(`traceId: ${fm.traceId}`);
|
|
12539
|
+
if (fm.goal) lines.push(`goal: ${fm.goal.replace(/[\r\n]+/g, " ")}`);
|
|
12540
|
+
if (fm.toolsUsed?.length) lines.push(`toolsUsed: [${fm.toolsUsed.map((t) => `"${t}"`).join(", ")}]`);
|
|
12541
|
+
if (fm.outcome) lines.push(`outcome: ${fm.outcome}`);
|
|
12531
12542
|
lines.push("---");
|
|
12532
12543
|
return lines.join("\n");
|
|
12533
12544
|
}
|
|
@@ -12547,6 +12558,7 @@ function parseBoxFrontmatter(raw) {
|
|
|
12547
12558
|
if (!m) return [];
|
|
12548
12559
|
return m[1].split(",").map((s) => s.trim().replace(/^"|"$/g, "")).filter(Boolean);
|
|
12549
12560
|
};
|
|
12561
|
+
const outcome = fm.outcome;
|
|
12550
12562
|
return {
|
|
12551
12563
|
id: fm.id ?? "",
|
|
12552
12564
|
memoryKind: "box",
|
|
@@ -12556,7 +12568,10 @@ function parseBoxFrontmatter(raw) {
|
|
|
12556
12568
|
sessionKey: fm.sessionKey,
|
|
12557
12569
|
topics: parseArray(fm.topics),
|
|
12558
12570
|
memoryIds: parseArray(fm.memoryIds),
|
|
12559
|
-
traceId: fm.traceId
|
|
12571
|
+
traceId: fm.traceId,
|
|
12572
|
+
goal: fm.goal || void 0,
|
|
12573
|
+
toolsUsed: fm.toolsUsed ? parseArray(fm.toolsUsed) : void 0,
|
|
12574
|
+
outcome: outcome && ["success", "failure", "partial", "unknown"].includes(outcome) ? outcome : void 0
|
|
12560
12575
|
};
|
|
12561
12576
|
}
|
|
12562
12577
|
var BoxBuilder = class {
|
|
@@ -12642,6 +12657,10 @@ var BoxBuilder = class {
|
|
|
12642
12657
|
const topicSet = /* @__PURE__ */ new Set([...this.openBox.topics, ...newTopics]);
|
|
12643
12658
|
this.openBox.topics = [...topicSet];
|
|
12644
12659
|
this.openBox.memoryIds.push(...event.memoryIds);
|
|
12660
|
+
if (event.toolsUsed?.length) {
|
|
12661
|
+
const toolSet = /* @__PURE__ */ new Set([...this.openBox.toolsUsed ?? [], ...event.toolsUsed]);
|
|
12662
|
+
this.openBox.toolsUsed = [...toolSet];
|
|
12663
|
+
}
|
|
12645
12664
|
await this.sealCurrent("max_memories");
|
|
12646
12665
|
} else if (topicShifted) {
|
|
12647
12666
|
await this.sealCurrent("topic_shift");
|
|
@@ -12656,6 +12675,10 @@ var BoxBuilder = class {
|
|
|
12656
12675
|
const topicSet = /* @__PURE__ */ new Set([...this.openBox.topics, ...newTopics]);
|
|
12657
12676
|
this.openBox.topics = [...topicSet];
|
|
12658
12677
|
this.openBox.lastActivityAt = now.toISOString();
|
|
12678
|
+
if (event.toolsUsed?.length) {
|
|
12679
|
+
const toolSet = /* @__PURE__ */ new Set([...this.openBox.toolsUsed ?? [], ...event.toolsUsed]);
|
|
12680
|
+
this.openBox.toolsUsed = [...toolSet];
|
|
12681
|
+
}
|
|
12659
12682
|
await this.saveOpenBox();
|
|
12660
12683
|
}
|
|
12661
12684
|
} else {
|
|
@@ -12673,7 +12696,9 @@ var BoxBuilder = class {
|
|
|
12673
12696
|
createdAt: ts,
|
|
12674
12697
|
lastActivityAt: ts,
|
|
12675
12698
|
topics: event.topics.filter(Boolean),
|
|
12676
|
-
memoryIds: [...event.memoryIds]
|
|
12699
|
+
memoryIds: [...event.memoryIds],
|
|
12700
|
+
goal: event.goal,
|
|
12701
|
+
toolsUsed: event.toolsUsed?.length ? [...event.toolsUsed] : void 0
|
|
12677
12702
|
};
|
|
12678
12703
|
}
|
|
12679
12704
|
/**
|
|
@@ -12705,7 +12730,10 @@ var BoxBuilder = class {
|
|
|
12705
12730
|
sealReason: reason,
|
|
12706
12731
|
topics: box.topics,
|
|
12707
12732
|
memoryIds: box.memoryIds,
|
|
12708
|
-
traceId
|
|
12733
|
+
traceId,
|
|
12734
|
+
goal: box.goal,
|
|
12735
|
+
toolsUsed: box.toolsUsed?.length ? box.toolsUsed : void 0,
|
|
12736
|
+
outcome: "unknown"
|
|
12709
12737
|
};
|
|
12710
12738
|
const content = `${serializeBoxFrontmatter(fm)}
|
|
12711
12739
|
|
|
@@ -15462,7 +15490,8 @@ var DEFAULT_CATEGORIES = [
|
|
|
15462
15490
|
"principle",
|
|
15463
15491
|
"commitment",
|
|
15464
15492
|
"moment",
|
|
15465
|
-
"skill"
|
|
15493
|
+
"skill",
|
|
15494
|
+
"rule"
|
|
15466
15495
|
];
|
|
15467
15496
|
function normalizeNamespace(namespace) {
|
|
15468
15497
|
return namespace.trim();
|
|
@@ -18378,10 +18407,13 @@ _Context: ${topQuestion.context}_`
|
|
|
18378
18407
|
await clearBuffer();
|
|
18379
18408
|
if (this.config.memoryBoxesEnabled && persistedIds.length > 0) {
|
|
18380
18409
|
const extractionTopics = deriveTopicsFromExtraction(result);
|
|
18410
|
+
const firstUserTurn = turns.find((t) => t.role === "user");
|
|
18411
|
+
const boxGoal = firstUserTurn?.content?.slice(0, 100)?.trim() || void 0;
|
|
18381
18412
|
await this.boxBuilderFor(storage).onExtraction({
|
|
18382
18413
|
topics: extractionTopics,
|
|
18383
18414
|
memoryIds: persistedIds,
|
|
18384
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
18415
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
18416
|
+
goal: boxGoal
|
|
18385
18417
|
}).catch((err) => log.warn("[boxes] onExtraction failed (non-fatal)", err));
|
|
18386
18418
|
}
|
|
18387
18419
|
if (this.config.threadingEnabled && threadIdForExtraction && persistedIds.length > 0) {
|
|
@@ -21991,8 +22023,8 @@ Best for:
|
|
|
21991
22023
|
),
|
|
21992
22024
|
category: Type.Optional(
|
|
21993
22025
|
Type.String({
|
|
21994
|
-
description: 'Category: "fact", "preference", "correction", "entity", "decision", "relationship", "principle", "commitment", "moment", "skill" (default: "fact")',
|
|
21995
|
-
enum: ["fact", "preference", "correction", "entity", "decision", "relationship", "principle", "commitment", "moment", "skill"]
|
|
22026
|
+
description: 'Category: "fact", "preference", "correction", "entity", "decision", "relationship", "principle", "commitment", "moment", "skill", "rule" (default: "fact")',
|
|
22027
|
+
enum: ["fact", "preference", "correction", "entity", "decision", "relationship", "principle", "commitment", "moment", "skill", "rule"]
|
|
21996
22028
|
})
|
|
21997
22029
|
),
|
|
21998
22030
|
tags: Type.Optional(
|