@joshuaswarren/openclaw-engram 8.3.21 → 8.3.22
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 +186 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8238,7 +8238,10 @@ var LastRecallStore = class {
|
|
|
8238
8238
|
recordedAt: now,
|
|
8239
8239
|
queryHash,
|
|
8240
8240
|
queryLen: opts.query.length,
|
|
8241
|
-
memoryIds: opts.memoryIds
|
|
8241
|
+
memoryIds: opts.memoryIds,
|
|
8242
|
+
identityInjectionMode: opts.identityInjection?.mode,
|
|
8243
|
+
identityInjectedChars: opts.identityInjection?.injectedChars,
|
|
8244
|
+
identityInjectionTruncated: opts.identityInjection?.truncated
|
|
8242
8245
|
};
|
|
8243
8246
|
this.state[opts.sessionKey] = snapshot;
|
|
8244
8247
|
const keys = Object.keys(this.state);
|
|
@@ -10971,6 +10974,22 @@ function resolveEffectiveRecallMode(options) {
|
|
|
10971
10974
|
}
|
|
10972
10975
|
return plannedMode;
|
|
10973
10976
|
}
|
|
10977
|
+
function hasIdentityRecoveryIntent(prompt) {
|
|
10978
|
+
const text = typeof prompt === "string" ? prompt.toLowerCase() : "";
|
|
10979
|
+
if (!text) return false;
|
|
10980
|
+
return /\b(identity|continuity|recover(?:y|ing|ed)?|incident|drift|restore|regress(?:ion|ed|ing)?)\b/i.test(
|
|
10981
|
+
text
|
|
10982
|
+
);
|
|
10983
|
+
}
|
|
10984
|
+
function resolveEffectiveIdentityInjectionMode(options) {
|
|
10985
|
+
if (options.configuredMode === "recovery_only" && !hasIdentityRecoveryIntent(options.prompt)) {
|
|
10986
|
+
return { mode: "recovery_only", shouldInject: false };
|
|
10987
|
+
}
|
|
10988
|
+
if (options.recallMode === "minimal" && options.configuredMode === "full") {
|
|
10989
|
+
return { mode: "minimal", shouldInject: true };
|
|
10990
|
+
}
|
|
10991
|
+
return { mode: options.configuredMode, shouldInject: true };
|
|
10992
|
+
}
|
|
10974
10993
|
function computeArtifactCandidateFetchLimit(targetCount) {
|
|
10975
10994
|
const cappedTarget = Math.max(0, targetCount);
|
|
10976
10995
|
if (cappedTarget === 0) return 0;
|
|
@@ -11822,6 +11841,9 @@ var Orchestrator = class _Orchestrator {
|
|
|
11822
11841
|
let impressionRecorded = false;
|
|
11823
11842
|
let recallSource = "none";
|
|
11824
11843
|
let recalledMemoryCount = 0;
|
|
11844
|
+
let identityInjectionModeUsed = "none";
|
|
11845
|
+
let identityInjectedChars = 0;
|
|
11846
|
+
let identityInjectionTruncated = false;
|
|
11825
11847
|
timings.queryPolicy = `${queryPolicy.promptShape}/${queryPolicy.retrievalBudgetMode}${queryPolicy.skipConversationRecall ? "/skip-conv" : ""}`;
|
|
11826
11848
|
const recallMode = resolveEffectiveRecallMode({
|
|
11827
11849
|
plannerEnabled: this.config.recallPlannerEnabled,
|
|
@@ -11866,6 +11888,9 @@ var Orchestrator = class _Orchestrator {
|
|
|
11866
11888
|
recalledMemoryCount,
|
|
11867
11889
|
injected: false,
|
|
11868
11890
|
contextChars: 0,
|
|
11891
|
+
identityInjectionMode: identityInjectionModeUsed,
|
|
11892
|
+
identityInjectedChars,
|
|
11893
|
+
identityInjectionTruncated,
|
|
11869
11894
|
durationMs: Date.now() - recallStart,
|
|
11870
11895
|
timings: { ...timings }
|
|
11871
11896
|
});
|
|
@@ -11899,6 +11924,16 @@ var Orchestrator = class _Orchestrator {
|
|
|
11899
11924
|
timings.profile = `${Date.now() - t0}ms`;
|
|
11900
11925
|
return profile2 || null;
|
|
11901
11926
|
})();
|
|
11927
|
+
const identityContinuityPromise = (async () => {
|
|
11928
|
+
const t0 = Date.now();
|
|
11929
|
+
const section = await this.buildIdentityContinuitySection({
|
|
11930
|
+
storage: profileStorage,
|
|
11931
|
+
recallMode,
|
|
11932
|
+
prompt: retrievalQuery
|
|
11933
|
+
});
|
|
11934
|
+
timings.identityContinuity = `${Date.now() - t0}ms`;
|
|
11935
|
+
return section;
|
|
11936
|
+
})();
|
|
11902
11937
|
const knowledgeIndexPromise = (async () => {
|
|
11903
11938
|
if (!this.config.knowledgeIndexEnabled) return null;
|
|
11904
11939
|
const t0 = Date.now();
|
|
@@ -11956,9 +11991,10 @@ var Orchestrator = class _Orchestrator {
|
|
|
11956
11991
|
timings.qmd = `${Date.now() - t0}ms`;
|
|
11957
11992
|
return { memoryResultsLists: [filteredResults], globalResults: [] };
|
|
11958
11993
|
})();
|
|
11959
|
-
const [sharedCtx, profile, kiResult, artifacts, qmdResult] = await Promise.all([
|
|
11994
|
+
const [sharedCtx, profile, identityContinuity, kiResult, artifacts, qmdResult] = await Promise.all([
|
|
11960
11995
|
sharedContextPromise,
|
|
11961
11996
|
profilePromise,
|
|
11997
|
+
identityContinuityPromise,
|
|
11962
11998
|
knowledgeIndexPromise,
|
|
11963
11999
|
artifactsPromise,
|
|
11964
12000
|
qmdPromise
|
|
@@ -11967,6 +12003,12 @@ var Orchestrator = class _Orchestrator {
|
|
|
11967
12003
|
if (profile) sections.push(`## User Profile
|
|
11968
12004
|
|
|
11969
12005
|
${profile}`);
|
|
12006
|
+
if (identityContinuity) {
|
|
12007
|
+
sections.push(identityContinuity.section);
|
|
12008
|
+
identityInjectionModeUsed = identityContinuity.mode;
|
|
12009
|
+
identityInjectedChars = identityContinuity.injectedChars;
|
|
12010
|
+
identityInjectionTruncated = identityContinuity.truncated;
|
|
12011
|
+
}
|
|
11970
12012
|
if (kiResult?.result) {
|
|
11971
12013
|
sections.push(kiResult.result);
|
|
11972
12014
|
log.debug(`Knowledge Index: ${kiResult.result.split("\n").length - 4} entities, ${kiResult.result.length} chars${kiResult.cached ? " (cached)" : ""}`);
|
|
@@ -12078,7 +12120,12 @@ ${tmtNode.summary}`);
|
|
|
12078
12120
|
results: memoryResults,
|
|
12079
12121
|
sections,
|
|
12080
12122
|
retrievalQuery,
|
|
12081
|
-
sessionKey
|
|
12123
|
+
sessionKey,
|
|
12124
|
+
identityInjection: {
|
|
12125
|
+
mode: identityInjectionModeUsed,
|
|
12126
|
+
injectedChars: identityInjectedChars,
|
|
12127
|
+
truncated: identityInjectionTruncated
|
|
12128
|
+
}
|
|
12082
12129
|
});
|
|
12083
12130
|
impressionRecorded = true;
|
|
12084
12131
|
} else {
|
|
@@ -12101,7 +12148,12 @@ ${tmtNode.summary}`);
|
|
|
12101
12148
|
results: scoped,
|
|
12102
12149
|
sections,
|
|
12103
12150
|
retrievalQuery,
|
|
12104
|
-
sessionKey
|
|
12151
|
+
sessionKey,
|
|
12152
|
+
identityInjection: {
|
|
12153
|
+
mode: identityInjectionModeUsed,
|
|
12154
|
+
injectedChars: identityInjectedChars,
|
|
12155
|
+
truncated: identityInjectionTruncated
|
|
12156
|
+
}
|
|
12105
12157
|
});
|
|
12106
12158
|
impressionRecorded = true;
|
|
12107
12159
|
} else {
|
|
@@ -12118,7 +12170,12 @@ ${tmtNode.summary}`);
|
|
|
12118
12170
|
results: longTerm,
|
|
12119
12171
|
sections,
|
|
12120
12172
|
retrievalQuery,
|
|
12121
|
-
sessionKey
|
|
12173
|
+
sessionKey,
|
|
12174
|
+
identityInjection: {
|
|
12175
|
+
mode: identityInjectionModeUsed,
|
|
12176
|
+
injectedChars: identityInjectedChars,
|
|
12177
|
+
truncated: identityInjectionTruncated
|
|
12178
|
+
}
|
|
12122
12179
|
});
|
|
12123
12180
|
impressionRecorded = true;
|
|
12124
12181
|
}
|
|
@@ -12164,7 +12221,12 @@ ${tmtNode.summary}`);
|
|
|
12164
12221
|
results: scoped,
|
|
12165
12222
|
sections,
|
|
12166
12223
|
retrievalQuery,
|
|
12167
|
-
sessionKey
|
|
12224
|
+
sessionKey,
|
|
12225
|
+
identityInjection: {
|
|
12226
|
+
mode: identityInjectionModeUsed,
|
|
12227
|
+
injectedChars: identityInjectedChars,
|
|
12228
|
+
truncated: identityInjectionTruncated
|
|
12229
|
+
}
|
|
12168
12230
|
});
|
|
12169
12231
|
impressionRecorded = true;
|
|
12170
12232
|
} else {
|
|
@@ -12199,7 +12261,12 @@ ${tmtNode.summary}`);
|
|
|
12199
12261
|
results: recent,
|
|
12200
12262
|
sections,
|
|
12201
12263
|
retrievalQuery,
|
|
12202
|
-
sessionKey
|
|
12264
|
+
sessionKey,
|
|
12265
|
+
identityInjection: {
|
|
12266
|
+
mode: identityInjectionModeUsed,
|
|
12267
|
+
injectedChars: identityInjectedChars,
|
|
12268
|
+
truncated: identityInjectionTruncated
|
|
12269
|
+
}
|
|
12203
12270
|
});
|
|
12204
12271
|
impressionRecorded = true;
|
|
12205
12272
|
} else {
|
|
@@ -12216,7 +12283,12 @@ ${tmtNode.summary}`);
|
|
|
12216
12283
|
results: longTerm,
|
|
12217
12284
|
sections,
|
|
12218
12285
|
retrievalQuery,
|
|
12219
|
-
sessionKey
|
|
12286
|
+
sessionKey,
|
|
12287
|
+
identityInjection: {
|
|
12288
|
+
mode: identityInjectionModeUsed,
|
|
12289
|
+
injectedChars: identityInjectedChars,
|
|
12290
|
+
truncated: identityInjectionTruncated
|
|
12291
|
+
}
|
|
12220
12292
|
});
|
|
12221
12293
|
impressionRecorded = true;
|
|
12222
12294
|
}
|
|
@@ -12235,7 +12307,12 @@ ${tmtNode.summary}`);
|
|
|
12235
12307
|
results: longTerm,
|
|
12236
12308
|
sections,
|
|
12237
12309
|
retrievalQuery,
|
|
12238
|
-
sessionKey
|
|
12310
|
+
sessionKey,
|
|
12311
|
+
identityInjection: {
|
|
12312
|
+
mode: identityInjectionModeUsed,
|
|
12313
|
+
injectedChars: identityInjectedChars,
|
|
12314
|
+
truncated: identityInjectionTruncated
|
|
12315
|
+
}
|
|
12239
12316
|
});
|
|
12240
12317
|
impressionRecorded = true;
|
|
12241
12318
|
}
|
|
@@ -12374,7 +12451,16 @@ _Context: ${topQuestion.context}_`);
|
|
|
12374
12451
|
const timingParts = Object.entries(timings).map(([k, v]) => `${k}=${v}`).join(", ");
|
|
12375
12452
|
log.debug(`recall: ${timingParts}`);
|
|
12376
12453
|
if (!impressionRecorded && sessionKey && this.config.recordEmptyRecallImpressions) {
|
|
12377
|
-
this.lastRecall.record({
|
|
12454
|
+
this.lastRecall.record({
|
|
12455
|
+
sessionKey,
|
|
12456
|
+
query: retrievalQuery,
|
|
12457
|
+
memoryIds: [],
|
|
12458
|
+
identityInjection: {
|
|
12459
|
+
mode: identityInjectionModeUsed,
|
|
12460
|
+
injectedChars: identityInjectedChars,
|
|
12461
|
+
truncated: identityInjectionTruncated
|
|
12462
|
+
}
|
|
12463
|
+
}).catch((err) => log.debug(`last recall record failed: ${err}`));
|
|
12378
12464
|
}
|
|
12379
12465
|
const context = sections.length === 0 ? "" : sections.join("\n\n---\n\n");
|
|
12380
12466
|
this.emitTrace({
|
|
@@ -12395,6 +12481,9 @@ _Context: ${topQuestion.context}_`);
|
|
|
12395
12481
|
recalledMemoryCount,
|
|
12396
12482
|
injected: context.length > 0,
|
|
12397
12483
|
contextChars: context.length,
|
|
12484
|
+
identityInjectionMode: identityInjectionModeUsed,
|
|
12485
|
+
identityInjectedChars,
|
|
12486
|
+
identityInjectionTruncated,
|
|
12398
12487
|
durationMs: Date.now() - recallStart,
|
|
12399
12488
|
timings: { ...timings }
|
|
12400
12489
|
});
|
|
@@ -13490,6 +13579,86 @@ ${snippet}`;
|
|
|
13490
13579
|
|
|
13491
13580
|
${lines.join("\n\n")}`;
|
|
13492
13581
|
}
|
|
13582
|
+
summarizeIdentityText(raw, maxLines, maxChars) {
|
|
13583
|
+
const lines = raw.replace(/\r/g, "").split("\n").map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
|
|
13584
|
+
const compact = lines.slice(0, Math.max(1, maxLines)).join(" ");
|
|
13585
|
+
if (compact.length <= maxChars) return compact;
|
|
13586
|
+
return `${compact.slice(0, Math.max(0, maxChars - 1))}\u2026`;
|
|
13587
|
+
}
|
|
13588
|
+
formatOpenIncidentLine(incident, includeDetails) {
|
|
13589
|
+
const base = `[${incident.id}] ${incident.symptom.trim()}`;
|
|
13590
|
+
if (!includeDetails) return `- ${base}`;
|
|
13591
|
+
const parts = [base];
|
|
13592
|
+
if (incident.suspectedCause) parts.push(`cause: ${incident.suspectedCause.trim()}`);
|
|
13593
|
+
if (incident.triggerWindow) parts.push(`window: ${incident.triggerWindow.trim()}`);
|
|
13594
|
+
return `- ${parts.join(" | ")}`;
|
|
13595
|
+
}
|
|
13596
|
+
trimIdentitySection(content, maxChars) {
|
|
13597
|
+
if (maxChars <= 0) return { text: "", truncated: false };
|
|
13598
|
+
if (content.length <= maxChars) return { text: content, truncated: false };
|
|
13599
|
+
const suffix = "\n\n...(identity continuity trimmed)";
|
|
13600
|
+
if (maxChars <= suffix.length) {
|
|
13601
|
+
return { text: content.slice(0, maxChars), truncated: true };
|
|
13602
|
+
}
|
|
13603
|
+
const headroom = Math.max(0, maxChars - suffix.length);
|
|
13604
|
+
return { text: `${content.slice(0, headroom)}${suffix}`, truncated: true };
|
|
13605
|
+
}
|
|
13606
|
+
async buildIdentityContinuitySection(options) {
|
|
13607
|
+
if (!this.config.identityContinuityEnabled) return null;
|
|
13608
|
+
if (this.config.identityMaxInjectChars <= 0) return null;
|
|
13609
|
+
const resolved = resolveEffectiveIdentityInjectionMode({
|
|
13610
|
+
configuredMode: this.config.identityInjectionMode,
|
|
13611
|
+
recallMode: options.recallMode,
|
|
13612
|
+
prompt: options.prompt
|
|
13613
|
+
});
|
|
13614
|
+
if (!resolved.shouldInject) return null;
|
|
13615
|
+
const [anchorRaw, loopsRaw, incidents] = await Promise.all([
|
|
13616
|
+
options.storage.readIdentityAnchor(),
|
|
13617
|
+
options.storage.readIdentityImprovementLoops(),
|
|
13618
|
+
options.storage.readContinuityIncidents(200)
|
|
13619
|
+
]);
|
|
13620
|
+
const openIncidents = incidents.filter((incident) => incident.state === "open");
|
|
13621
|
+
const lines = [];
|
|
13622
|
+
if (resolved.mode === "full") {
|
|
13623
|
+
lines.push("## Identity Continuity");
|
|
13624
|
+
if (anchorRaw && anchorRaw.trim().length > 0) {
|
|
13625
|
+
lines.push("", "### Anchor", "", anchorRaw.trim());
|
|
13626
|
+
}
|
|
13627
|
+
if (loopsRaw && loopsRaw.trim().length > 0) {
|
|
13628
|
+
lines.push("", "### Improvement Loops", "", loopsRaw.trim());
|
|
13629
|
+
}
|
|
13630
|
+
lines.push("", "### Open Incidents", "");
|
|
13631
|
+
if (openIncidents.length === 0) {
|
|
13632
|
+
lines.push("- none");
|
|
13633
|
+
} else {
|
|
13634
|
+
lines.push(
|
|
13635
|
+
...openIncidents.slice(0, 5).map((incident) => this.formatOpenIncidentLine(incident, true))
|
|
13636
|
+
);
|
|
13637
|
+
}
|
|
13638
|
+
} else {
|
|
13639
|
+
const anchorSummary = anchorRaw ? this.summarizeIdentityText(anchorRaw, 3, 320) : "";
|
|
13640
|
+
const loopsSummary = loopsRaw ? this.summarizeIdentityText(loopsRaw, 2, 240) : "";
|
|
13641
|
+
lines.push("## Identity Continuity Signals", "");
|
|
13642
|
+
if (anchorSummary) lines.push(`- anchor: ${anchorSummary}`);
|
|
13643
|
+
if (loopsSummary) lines.push(`- loops: ${loopsSummary}`);
|
|
13644
|
+
if (openIncidents.length === 0) {
|
|
13645
|
+
lines.push("- incidents: 0 open");
|
|
13646
|
+
} else {
|
|
13647
|
+
lines.push(`- incidents: ${openIncidents.length} open`);
|
|
13648
|
+
lines.push(...openIncidents.slice(0, 2).map((incident) => this.formatOpenIncidentLine(incident, false)));
|
|
13649
|
+
}
|
|
13650
|
+
}
|
|
13651
|
+
const body = lines.join("\n").trim();
|
|
13652
|
+
if (!body) return null;
|
|
13653
|
+
const { text, truncated } = this.trimIdentitySection(body, this.config.identityMaxInjectChars);
|
|
13654
|
+
if (!text) return null;
|
|
13655
|
+
return {
|
|
13656
|
+
section: text,
|
|
13657
|
+
mode: resolved.mode,
|
|
13658
|
+
injectedChars: text.length,
|
|
13659
|
+
truncated
|
|
13660
|
+
};
|
|
13661
|
+
}
|
|
13493
13662
|
emitTrace(event) {
|
|
13494
13663
|
try {
|
|
13495
13664
|
const cb = globalThis.__openclawEngramTrace;
|
|
@@ -13503,7 +13672,12 @@ ${lines.join("\n\n")}`;
|
|
|
13503
13672
|
this.trackMemoryAccess(memoryIds);
|
|
13504
13673
|
if (options.sessionKey) {
|
|
13505
13674
|
const unique = Array.from(new Set(memoryIds)).slice(0, 40);
|
|
13506
|
-
this.lastRecall.record({
|
|
13675
|
+
this.lastRecall.record({
|
|
13676
|
+
sessionKey: options.sessionKey,
|
|
13677
|
+
query: options.retrievalQuery,
|
|
13678
|
+
memoryIds: unique,
|
|
13679
|
+
identityInjection: options.identityInjection
|
|
13680
|
+
}).catch((err) => log.debug(`last recall record failed: ${err}`));
|
|
13507
13681
|
}
|
|
13508
13682
|
options.sections.push(this.formatQmdResults(options.title, options.results));
|
|
13509
13683
|
}
|
|
@@ -14497,6 +14671,7 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
|
|
|
14497
14671
|
"",
|
|
14498
14672
|
`Recorded at: ${snap.recordedAt}`,
|
|
14499
14673
|
`Query hash: ${snap.queryHash} (len=${snap.queryLen})`,
|
|
14674
|
+
`Identity injection: mode=${snap.identityInjectionMode ?? "none"}, chars=${snap.identityInjectedChars ?? 0}, truncated=${snap.identityInjectionTruncated === true ? "yes" : "no"}`,
|
|
14500
14675
|
`Memories (${snap.memoryIds.length}):`,
|
|
14501
14676
|
...snap.memoryIds.map((id) => `- ${id}`)
|
|
14502
14677
|
].join("\n")
|