anno-extension 0.1.0
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/LICENSE +7 -0
- package/README.md +30 -0
- package/THIRD_PARTY_NOTICES.md +8 -0
- package/dist/browser-fs.d.ts +14 -0
- package/dist/browser-fs.d.ts.map +1 -0
- package/dist/browser-fs.js +69 -0
- package/dist/browser-fs.js.map +1 -0
- package/dist/config.d.ts +81 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +82 -0
- package/dist/config.js.map +1 -0
- package/dist/consolidate-v2.d.ts +15 -0
- package/dist/consolidate-v2.d.ts.map +1 -0
- package/dist/consolidate-v2.js +125 -0
- package/dist/consolidate-v2.js.map +1 -0
- package/dist/consolidation.d.ts +12 -0
- package/dist/consolidation.d.ts.map +1 -0
- package/dist/consolidation.js +199 -0
- package/dist/consolidation.js.map +1 -0
- package/dist/dedup.d.ts +18 -0
- package/dist/dedup.d.ts.map +1 -0
- package/dist/dedup.js +85 -0
- package/dist/dedup.js.map +1 -0
- package/dist/diagnostics.d.ts +24 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +53 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/embedding-index.d.ts +27 -0
- package/dist/embedding-index.d.ts.map +1 -0
- package/dist/embedding-index.js +111 -0
- package/dist/embedding-index.js.map +1 -0
- package/dist/engine-archive.d.ts +37 -0
- package/dist/engine-archive.d.ts.map +1 -0
- package/dist/engine-archive.js +155 -0
- package/dist/engine-archive.js.map +1 -0
- package/dist/engine-episode-sync.d.ts +19 -0
- package/dist/engine-episode-sync.d.ts.map +1 -0
- package/dist/engine-episode-sync.js +186 -0
- package/dist/engine-episode-sync.js.map +1 -0
- package/dist/engine-injection-text.d.ts +46 -0
- package/dist/engine-injection-text.d.ts.map +1 -0
- package/dist/engine-injection-text.js +271 -0
- package/dist/engine-injection-text.js.map +1 -0
- package/dist/engine-insights.d.ts +22 -0
- package/dist/engine-insights.d.ts.map +1 -0
- package/dist/engine-insights.js +127 -0
- package/dist/engine-insights.js.map +1 -0
- package/dist/engine-links.d.ts +43 -0
- package/dist/engine-links.d.ts.map +1 -0
- package/dist/engine-links.js +223 -0
- package/dist/engine-links.js.map +1 -0
- package/dist/engine-recall-select.d.ts +84 -0
- package/dist/engine-recall-select.d.ts.map +1 -0
- package/dist/engine-recall-select.js +127 -0
- package/dist/engine-recall-select.js.map +1 -0
- package/dist/engine-reinforce.d.ts +18 -0
- package/dist/engine-reinforce.d.ts.map +1 -0
- package/dist/engine-reinforce.js +116 -0
- package/dist/engine-reinforce.js.map +1 -0
- package/dist/engine-scoring-v2.d.ts +35 -0
- package/dist/engine-scoring-v2.d.ts.map +1 -0
- package/dist/engine-scoring-v2.js +178 -0
- package/dist/engine-scoring-v2.js.map +1 -0
- package/dist/engine-v2-mapping.d.ts +17 -0
- package/dist/engine-v2-mapping.d.ts.map +1 -0
- package/dist/engine-v2-mapping.js +190 -0
- package/dist/engine-v2-mapping.js.map +1 -0
- package/dist/engine.d.ts +339 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +1964 -0
- package/dist/engine.js.map +1 -0
- package/dist/eviction.d.ts +14 -0
- package/dist/eviction.d.ts.map +1 -0
- package/dist/eviction.js +26 -0
- package/dist/eviction.js.map +1 -0
- package/dist/extraction.d.ts +11 -0
- package/dist/extraction.d.ts.map +1 -0
- package/dist/extraction.js +261 -0
- package/dist/extraction.js.map +1 -0
- package/dist/full-insights-html.d.ts +9 -0
- package/dist/full-insights-html.d.ts.map +1 -0
- package/dist/full-insights-html.js +422 -0
- package/dist/full-insights-html.js.map +1 -0
- package/dist/full-insights-sections.d.ts +48 -0
- package/dist/full-insights-sections.d.ts.map +1 -0
- package/dist/full-insights-sections.js +231 -0
- package/dist/full-insights-sections.js.map +1 -0
- package/dist/full-insights.d.ts +22 -0
- package/dist/full-insights.d.ts.map +1 -0
- package/dist/full-insights.js +370 -0
- package/dist/full-insights.js.map +1 -0
- package/dist/hash-embedding.d.ts +9 -0
- package/dist/hash-embedding.d.ts.map +1 -0
- package/dist/hash-embedding.js +44 -0
- package/dist/hash-embedding.js.map +1 -0
- package/dist/human-insights.d.ts +28 -0
- package/dist/human-insights.d.ts.map +1 -0
- package/dist/human-insights.js +260 -0
- package/dist/human-insights.js.map +1 -0
- package/dist/i18n.d.ts +64 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/i18n.js +367 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/insights-html.d.ts +9 -0
- package/dist/insights-html.d.ts.map +1 -0
- package/dist/insights-html.js +432 -0
- package/dist/insights-html.js.map +1 -0
- package/dist/linking.d.ts +22 -0
- package/dist/linking.d.ts.map +1 -0
- package/dist/linking.js +192 -0
- package/dist/linking.js.map +1 -0
- package/dist/llm-json.d.ts +10 -0
- package/dist/llm-json.d.ts.map +1 -0
- package/dist/llm-json.js +193 -0
- package/dist/llm-json.js.map +1 -0
- package/dist/privacy.d.ts +17 -0
- package/dist/privacy.d.ts.map +1 -0
- package/dist/privacy.js +53 -0
- package/dist/privacy.js.map +1 -0
- package/dist/procedural-v2.d.ts +9 -0
- package/dist/procedural-v2.d.ts.map +1 -0
- package/dist/procedural-v2.js +123 -0
- package/dist/procedural-v2.js.map +1 -0
- package/dist/reconsolidate-v2.d.ts +19 -0
- package/dist/reconsolidate-v2.d.ts.map +1 -0
- package/dist/reconsolidate-v2.js +115 -0
- package/dist/reconsolidate-v2.js.map +1 -0
- package/dist/scoring.d.ts +32 -0
- package/dist/scoring.d.ts.map +1 -0
- package/dist/scoring.js +108 -0
- package/dist/scoring.js.map +1 -0
- package/dist/store-v2.d.ts +35 -0
- package/dist/store-v2.d.ts.map +1 -0
- package/dist/store-v2.js +98 -0
- package/dist/store-v2.js.map +1 -0
- package/dist/store.d.ts +22 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +116 -0
- package/dist/store.js.map +1 -0
- package/dist/turn-context.d.ts +37 -0
- package/dist/turn-context.d.ts.map +1 -0
- package/dist/turn-context.js +31 -0
- package/dist/turn-context.js.map +1 -0
- package/dist/types-v2.d.ts +190 -0
- package/dist/types-v2.d.ts.map +1 -0
- package/dist/types-v2.js +8 -0
- package/dist/types-v2.js.map +1 -0
- package/dist/types.d.ts +330 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/update.d.ts +31 -0
- package/dist/update.d.ts.map +1 -0
- package/dist/update.js +250 -0
- package/dist/update.js.map +1 -0
- package/package.json +34 -0
- package/src/browser-fs.ts +67 -0
- package/src/config.ts +138 -0
- package/src/consolidate-v2.ts +158 -0
- package/src/consolidation.ts +229 -0
- package/src/dedup.ts +91 -0
- package/src/diagnostics.ts +81 -0
- package/src/embedding-index.ts +138 -0
- package/src/engine-archive.ts +167 -0
- package/src/engine-episode-sync.ts +237 -0
- package/src/engine-injection-text.ts +334 -0
- package/src/engine-insights.ts +182 -0
- package/src/engine-links.ts +311 -0
- package/src/engine-recall-select.ts +298 -0
- package/src/engine-reinforce.ts +154 -0
- package/src/engine-scoring-v2.ts +188 -0
- package/src/engine-v2-mapping.ts +204 -0
- package/src/engine.ts +2499 -0
- package/src/eviction.ts +38 -0
- package/src/extraction.ts +300 -0
- package/src/full-insights-html.ts +474 -0
- package/src/full-insights-sections.ts +305 -0
- package/src/full-insights.ts +423 -0
- package/src/hash-embedding.ts +48 -0
- package/src/human-insights.ts +345 -0
- package/src/i18n.ts +455 -0
- package/src/index.ts +117 -0
- package/src/insights-html.ts +478 -0
- package/src/linking.ts +228 -0
- package/src/llm-json.ts +194 -0
- package/src/privacy.ts +54 -0
- package/src/procedural-v2.ts +142 -0
- package/src/reconsolidate-v2.ts +145 -0
- package/src/scoring.ts +156 -0
- package/src/store-v2.ts +138 -0
- package/src/store.ts +137 -0
- package/src/turn-context.ts +56 -0
- package/src/types-v2.ts +244 -0
- package/src/types.ts +372 -0
- package/src/update.ts +271 -0
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* [WHO]: Provides AUTO_V2_LINK_PREFIX, buildProceduralChains, materializeV2Links, detectProceduralConflicts, detectSemanticConflicts, detectAlignmentConflicts, suggestConflictAction, explainConflictAction
|
|
3
|
+
* [FROM]: Depends on ./scoring.js for daysSince, extractTags, tagOverlap; ./types.js, ./types-v2.js
|
|
4
|
+
* [TO]: Consumed by engine.ts (rebuildV2Links, inspectV2Memory, getAlignmentSnapshot)
|
|
5
|
+
* [HERE]: packages/mem-core/src/engine-links.ts - V2 link materialization, conflict detection, procedural chain building
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { daysSince, extractTags, tagOverlap } from "./scoring.js";
|
|
9
|
+
import type { MemoryEntry } from "./types.js";
|
|
10
|
+
import type { MemoryLink, ProceduralMemory, SemanticMemory } from "./types-v2.js";
|
|
11
|
+
|
|
12
|
+
export const AUTO_V2_LINK_PREFIX = "auto:v2:";
|
|
13
|
+
|
|
14
|
+
// ── Procedural chains ──────────────────────────────────────
|
|
15
|
+
|
|
16
|
+
export function buildProceduralChains(entries: ProceduralMemory[]): Array<{
|
|
17
|
+
rootId: string;
|
|
18
|
+
name: string;
|
|
19
|
+
status: ProceduralMemory["status"];
|
|
20
|
+
versionDepth: number;
|
|
21
|
+
ids: string[];
|
|
22
|
+
}> {
|
|
23
|
+
const byId = new Map(entries.map((entry) => [entry.id, entry]));
|
|
24
|
+
const roots = entries.filter((entry) => !entry.supersededById || !byId.has(entry.supersededById));
|
|
25
|
+
return roots
|
|
26
|
+
.map((root) => {
|
|
27
|
+
const ids = new Set<string>();
|
|
28
|
+
const stack = [root.id];
|
|
29
|
+
while (stack.length) {
|
|
30
|
+
const currentId = stack.pop();
|
|
31
|
+
if (!currentId || ids.has(currentId)) continue;
|
|
32
|
+
ids.add(currentId);
|
|
33
|
+
for (const entry of entries) {
|
|
34
|
+
if (entry.supersededById === currentId) stack.push(entry.id);
|
|
35
|
+
if (entry.supersedesIds?.includes(currentId)) stack.push(entry.id);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const chainEntries = [...ids].map((id) => byId.get(id)).filter((entry): entry is ProceduralMemory => Boolean(entry));
|
|
39
|
+
return {
|
|
40
|
+
rootId: root.id,
|
|
41
|
+
name: root.name,
|
|
42
|
+
status: root.status,
|
|
43
|
+
versionDepth: chainEntries.length,
|
|
44
|
+
ids: chainEntries
|
|
45
|
+
.sort((a, b) => {
|
|
46
|
+
const aVersion = a.version ?? 0;
|
|
47
|
+
const bVersion = b.version ?? 0;
|
|
48
|
+
if (aVersion !== bVersion) return bVersion - aVersion;
|
|
49
|
+
return a.updatedAt.localeCompare(b.updatedAt);
|
|
50
|
+
})
|
|
51
|
+
.map((entry) => entry.id),
|
|
52
|
+
};
|
|
53
|
+
})
|
|
54
|
+
.filter((chain) => chain.versionDepth > 1)
|
|
55
|
+
.sort((a, b) => b.versionDepth - a.versionDepth || a.name.localeCompare(b.name));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ── V2 link materialization ────────────────────────────────
|
|
59
|
+
|
|
60
|
+
export function materializeV2Links(
|
|
61
|
+
semantic: SemanticMemory[],
|
|
62
|
+
procedural: ProceduralMemory[],
|
|
63
|
+
existingLinks: MemoryLink[],
|
|
64
|
+
autoLinkPrefix: string,
|
|
65
|
+
now = new Date().toISOString(),
|
|
66
|
+
): MemoryLink[] {
|
|
67
|
+
const manualLinks = existingLinks.filter((link) => !link.id.startsWith(autoLinkPrefix));
|
|
68
|
+
const autoLinks = new Map<string, MemoryLink>();
|
|
69
|
+
const proceduralConflicts = detectProceduralConflicts(
|
|
70
|
+
procedural.filter((entry) => entry.status !== "deprecated" && entry.status !== "superseded"),
|
|
71
|
+
);
|
|
72
|
+
const semanticConflicts = detectSemanticConflicts(semantic);
|
|
73
|
+
|
|
74
|
+
const addAutoLink = (
|
|
75
|
+
fromId: string,
|
|
76
|
+
toId: string,
|
|
77
|
+
type: MemoryLink["type"],
|
|
78
|
+
weight: number,
|
|
79
|
+
evidence: MemoryLink["evidence"] = [],
|
|
80
|
+
): void => {
|
|
81
|
+
if (!fromId || !toId || fromId === toId) return;
|
|
82
|
+
const directional = type === "supersedes";
|
|
83
|
+
const [normalizedFrom, normalizedTo] = directional || fromId < toId ? [fromId, toId] : [toId, fromId];
|
|
84
|
+
const id = `${autoLinkPrefix}${type}:${normalizedFrom}->${normalizedTo}`;
|
|
85
|
+
autoLinks.set(id, {
|
|
86
|
+
id,
|
|
87
|
+
fromId: normalizedFrom,
|
|
88
|
+
toId: normalizedTo,
|
|
89
|
+
type,
|
|
90
|
+
weight,
|
|
91
|
+
explicit: false,
|
|
92
|
+
createdAt: autoLinks.get(id)?.createdAt ?? now,
|
|
93
|
+
updatedAt: now,
|
|
94
|
+
evidence,
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
for (const entry of semantic) {
|
|
99
|
+
for (const supersededId of entry.supersedesIds ?? []) {
|
|
100
|
+
addAutoLink(entry.id, supersededId, "supersedes", 0.92);
|
|
101
|
+
}
|
|
102
|
+
if (entry.supersededById) {
|
|
103
|
+
addAutoLink(entry.supersededById, entry.id, "supersedes", 0.92);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
for (const entry of procedural) {
|
|
108
|
+
for (const supersededId of entry.supersedesIds ?? []) {
|
|
109
|
+
addAutoLink(entry.id, supersededId, "supersedes", 0.94);
|
|
110
|
+
}
|
|
111
|
+
if (entry.supersededById) {
|
|
112
|
+
addAutoLink(entry.supersededById, entry.id, "supersedes", 0.94);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
for (const conflict of semanticConflicts) {
|
|
117
|
+
addAutoLink(conflict.aId, conflict.bId, "conflicts-with", 0.88);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
for (const conflict of proceduralConflicts) {
|
|
121
|
+
addAutoLink(conflict.aId, conflict.bId, "conflicts-with", Math.max(0.72, conflict.score));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return [...manualLinks, ...autoLinks.values()].sort((a, b) => a.id.localeCompare(b.id));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// ── Conflict detection ─────────────────────────────────────
|
|
128
|
+
|
|
129
|
+
export function detectProceduralConflicts(entries: ProceduralMemory[]): Array<{
|
|
130
|
+
aId: string;
|
|
131
|
+
bId: string;
|
|
132
|
+
aName: string;
|
|
133
|
+
bName: string;
|
|
134
|
+
score: number;
|
|
135
|
+
reason: string;
|
|
136
|
+
}> {
|
|
137
|
+
const conflicts: Array<{
|
|
138
|
+
aId: string;
|
|
139
|
+
bId: string;
|
|
140
|
+
aName: string;
|
|
141
|
+
bName: string;
|
|
142
|
+
score: number;
|
|
143
|
+
reason: string;
|
|
144
|
+
}> = [];
|
|
145
|
+
for (let i = 0; i < entries.length; i++) {
|
|
146
|
+
for (let j = i + 1; j < entries.length; j++) {
|
|
147
|
+
const a = entries[i];
|
|
148
|
+
const b = entries[j];
|
|
149
|
+
if (!a || !b || a.id === b.id) continue;
|
|
150
|
+
const tagScore = tagOverlap(a.tags ?? [], b.tags ?? []);
|
|
151
|
+
const lexicalScore = tagOverlap(
|
|
152
|
+
extractTags(`${a.name} ${a.searchText} ${a.summary}`),
|
|
153
|
+
extractTags(`${b.name} ${b.searchText} ${b.summary}`),
|
|
154
|
+
);
|
|
155
|
+
const similarity = Math.max(tagScore, lexicalScore);
|
|
156
|
+
const sameIntent =
|
|
157
|
+
a.searchText.trim().toLowerCase() === b.searchText.trim().toLowerCase() ||
|
|
158
|
+
a.name.trim().toLowerCase() === b.name.trim().toLowerCase();
|
|
159
|
+
const boundariesDiffer =
|
|
160
|
+
(a.boundaries ?? "").trim().toLowerCase() !== (b.boundaries ?? "").trim().toLowerCase() ||
|
|
161
|
+
(a.contextText ?? "").trim().toLowerCase() !== (b.contextText ?? "").trim().toLowerCase();
|
|
162
|
+
if ((similarity >= 0.72 || sameIntent) && boundariesDiffer) {
|
|
163
|
+
conflicts.push({
|
|
164
|
+
aId: a.id,
|
|
165
|
+
bId: b.id,
|
|
166
|
+
aName: a.name,
|
|
167
|
+
bName: b.name,
|
|
168
|
+
score: Number(similarity.toFixed(3)),
|
|
169
|
+
reason: "High-overlap active procedures differ in boundaries or context.",
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return conflicts.sort((a, b) => b.score - a.score || a.aName.localeCompare(b.aName));
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export function detectSemanticConflicts(entries: SemanticMemory[]): Array<{
|
|
178
|
+
aId: string;
|
|
179
|
+
bId: string;
|
|
180
|
+
aName: string;
|
|
181
|
+
bName: string;
|
|
182
|
+
reason: string;
|
|
183
|
+
}> {
|
|
184
|
+
const byId = new Map(entries.map((entry) => [entry.id, entry]));
|
|
185
|
+
const seen = new Set<string>();
|
|
186
|
+
const conflicts: Array<{
|
|
187
|
+
aId: string;
|
|
188
|
+
bId: string;
|
|
189
|
+
aName: string;
|
|
190
|
+
bName: string;
|
|
191
|
+
reason: string;
|
|
192
|
+
}> = [];
|
|
193
|
+
for (const entry of entries) {
|
|
194
|
+
for (const conflictId of entry.conflictWithIds ?? []) {
|
|
195
|
+
const other = byId.get(conflictId);
|
|
196
|
+
if (!other) continue;
|
|
197
|
+
const pairKey = [entry.id, other.id].sort().join("::");
|
|
198
|
+
if (seen.has(pairKey)) continue;
|
|
199
|
+
seen.add(pairKey);
|
|
200
|
+
conflicts.push({
|
|
201
|
+
aId: entry.id,
|
|
202
|
+
bId: other.id,
|
|
203
|
+
aName: entry.name,
|
|
204
|
+
bName: other.name,
|
|
205
|
+
reason: "Explicit semantic conflict link.",
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return conflicts.sort((a, b) => a.aName.localeCompare(b.aName) || a.bName.localeCompare(b.bName));
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// ── Alignment conflict detection ───────────────────────────
|
|
213
|
+
|
|
214
|
+
export function detectAlignmentConflicts(
|
|
215
|
+
entries: MemoryEntry[],
|
|
216
|
+
): Array<{
|
|
217
|
+
aId: string;
|
|
218
|
+
bId: string;
|
|
219
|
+
reason: string;
|
|
220
|
+
severity: number;
|
|
221
|
+
recommendation: "merge" | "demote" | "forget" | "mark-situational";
|
|
222
|
+
rationale: string;
|
|
223
|
+
}> {
|
|
224
|
+
const candidates = entries.filter(
|
|
225
|
+
(entry) =>
|
|
226
|
+
entry.stability !== "situational" &&
|
|
227
|
+
(entry.retention === "core" || entry.retention === "key-event") &&
|
|
228
|
+
!!(entry.summary || entry.detail || entry.name),
|
|
229
|
+
);
|
|
230
|
+
const conflicts: Array<{
|
|
231
|
+
aId: string;
|
|
232
|
+
bId: string;
|
|
233
|
+
reason: string;
|
|
234
|
+
severity: number;
|
|
235
|
+
recommendation: "merge" | "demote" | "forget" | "mark-situational";
|
|
236
|
+
rationale: string;
|
|
237
|
+
}> = [];
|
|
238
|
+
const seen = new Set<string>();
|
|
239
|
+
const positiveMarkers = ["prefer", "always", "use", "enable", "include", "like", "keep", "should"];
|
|
240
|
+
const negativeMarkers = ["avoid", "never", "disable", "remove", "dislike", "hate", "stop", "do not", "don't"];
|
|
241
|
+
const getText = (entry: MemoryEntry) =>
|
|
242
|
+
`${entry.name || ""} ${entry.summary || ""} ${entry.detail || ""}`.toLowerCase();
|
|
243
|
+
const polarity = (text: string): "positive" | "negative" | "neutral" => {
|
|
244
|
+
const hasPositive = positiveMarkers.some((marker) => text.includes(marker));
|
|
245
|
+
const hasNegative = negativeMarkers.some((marker) => text.includes(marker));
|
|
246
|
+
if (hasPositive && !hasNegative) return "positive";
|
|
247
|
+
if (hasNegative && !hasPositive) return "negative";
|
|
248
|
+
return "neutral";
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
for (let i = 0; i < candidates.length; i++) {
|
|
252
|
+
for (let j = i + 1; j < candidates.length; j++) {
|
|
253
|
+
const a = candidates[i]!;
|
|
254
|
+
const b = candidates[j]!;
|
|
255
|
+
if (a.id === b.id) continue;
|
|
256
|
+
const overlap = tagOverlap(a.tags, b.tags);
|
|
257
|
+
if (overlap < 0.45) continue;
|
|
258
|
+
const aPolarity = polarity(getText(a));
|
|
259
|
+
const bPolarity = polarity(getText(b));
|
|
260
|
+
if (aPolarity === "neutral" || bPolarity === "neutral" || aPolarity === bPolarity) continue;
|
|
261
|
+
const pairKey = [a.id, b.id].sort().join(":");
|
|
262
|
+
if (seen.has(pairKey)) continue;
|
|
263
|
+
seen.add(pairKey);
|
|
264
|
+
const severity = Math.min(
|
|
265
|
+
1,
|
|
266
|
+
overlap * 0.6 + ((a.salience ?? a.importance) + (b.salience ?? b.importance)) / 20 * 0.4,
|
|
267
|
+
);
|
|
268
|
+
const reason = `Potential conflict on shared context: ${aPolarity} vs ${bPolarity}`;
|
|
269
|
+
const recommendation = suggestConflictAction(a, b, severity);
|
|
270
|
+
const rationale = explainConflictAction(a, b, recommendation);
|
|
271
|
+
conflicts.push({ aId: a.id, bId: b.id, reason, severity, recommendation, rationale });
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return conflicts.sort((a, b) => b.severity - a.severity);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export function suggestConflictAction(
|
|
279
|
+
a: MemoryEntry,
|
|
280
|
+
b: MemoryEntry,
|
|
281
|
+
severity: number,
|
|
282
|
+
): "merge" | "demote" | "forget" | "mark-situational" {
|
|
283
|
+
const aStable = a.stability !== "situational";
|
|
284
|
+
const bStable = b.stability !== "situational";
|
|
285
|
+
const aRecent = daysSince(a.created) <= 14;
|
|
286
|
+
const bRecent = daysSince(b.created) <= 14;
|
|
287
|
+
const aLowSignal = (a.salience ?? a.importance) <= 4;
|
|
288
|
+
const bLowSignal = (b.salience ?? b.importance) <= 4;
|
|
289
|
+
|
|
290
|
+
if (aStable !== bStable) return "mark-situational";
|
|
291
|
+
if (severity >= 0.8 && (aLowSignal || bLowSignal)) return "forget";
|
|
292
|
+
if (severity >= 0.65 && (aRecent || bRecent)) return "demote";
|
|
293
|
+
return "merge";
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export function explainConflictAction(
|
|
297
|
+
a: MemoryEntry,
|
|
298
|
+
b: MemoryEntry,
|
|
299
|
+
action: "merge" | "demote" | "forget" | "mark-situational",
|
|
300
|
+
): string {
|
|
301
|
+
switch (action) {
|
|
302
|
+
case "mark-situational":
|
|
303
|
+
return "One side looks more temporary than the other, so this conflict likely comes from short-term context rather than true identity drift.";
|
|
304
|
+
case "forget":
|
|
305
|
+
return "One side has weak signal compared with the conflict risk, so forgetting the weaker memory is safer than keeping both.";
|
|
306
|
+
case "demote":
|
|
307
|
+
return "At least one side is recent enough that it may be an overfit; demoting it reduces the chance of personality drift.";
|
|
308
|
+
default:
|
|
309
|
+
return "Both memories may describe the same preference from different angles, so a merged memory is likely safer than keeping them separate.";
|
|
310
|
+
}
|
|
311
|
+
}
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* [WHO]: Provides selectRecallEntries — budget/tier/pick logic for progressive recall
|
|
3
|
+
* [FROM]: Depends on ./scoring.js for pickTop, scoreEntry, scoreEpisode, scoreWorkEntry, tierEntries; ./linking.js for getGraphNeighborhoodBySeeds; ./engine-scoring-v2.js for V2 scoring; ./engine-injection-text.js for conversation prefs
|
|
4
|
+
* [TO]: Consumed by engine.ts (getMemoryInjection)
|
|
5
|
+
* [HERE]: packages/mem-core/src/engine-recall-select.ts - recall entry selection and budget allocation
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { selectConversationPreferences, mergeUniqueEntries } from "./engine-injection-text.js";
|
|
9
|
+
import {
|
|
10
|
+
scoreEpisodeMemory,
|
|
11
|
+
scoreEpisodeFacet,
|
|
12
|
+
scoreV2SemanticMemory,
|
|
13
|
+
scoreProceduralMemory,
|
|
14
|
+
} from "./engine-scoring-v2.js";
|
|
15
|
+
import { getGraphNeighborhoodBySeeds, type GraphNeighbor } from "./linking.js";
|
|
16
|
+
import {
|
|
17
|
+
pickTop,
|
|
18
|
+
scoreEntry,
|
|
19
|
+
scoreEpisode,
|
|
20
|
+
scoreWorkEntry,
|
|
21
|
+
tierEntries,
|
|
22
|
+
} from "./scoring.js";
|
|
23
|
+
import type { ProgressiveRecallConfig } from "./config.js";
|
|
24
|
+
import type { MemoryEntry, MemoryScope, WorkEntry, Episode } from "./types.js";
|
|
25
|
+
import type { EpisodeFacet, EpisodeMemory, ProceduralMemory, SemanticMemory } from "./types-v2.js";
|
|
26
|
+
|
|
27
|
+
export interface RecallSelectionResult {
|
|
28
|
+
active: {
|
|
29
|
+
knowledge: MemoryEntry[];
|
|
30
|
+
lessons: MemoryEntry[];
|
|
31
|
+
events: MemoryEntry[];
|
|
32
|
+
preferences: MemoryEntry[];
|
|
33
|
+
facets: MemoryEntry[];
|
|
34
|
+
episodeMemories: EpisodeMemory[];
|
|
35
|
+
episodeFacets: EpisodeFacet[];
|
|
36
|
+
semanticMemories: SemanticMemory[];
|
|
37
|
+
procedural: ProceduralMemory[];
|
|
38
|
+
};
|
|
39
|
+
cue: {
|
|
40
|
+
knowledge: MemoryEntry[];
|
|
41
|
+
lessons: MemoryEntry[];
|
|
42
|
+
events: MemoryEntry[];
|
|
43
|
+
preferences: MemoryEntry[];
|
|
44
|
+
facets: MemoryEntry[];
|
|
45
|
+
episodes: Episode[];
|
|
46
|
+
work: WorkEntry[];
|
|
47
|
+
episodeMemories: EpisodeMemory[];
|
|
48
|
+
episodeFacets: EpisodeFacet[];
|
|
49
|
+
semanticMemories: SemanticMemory[];
|
|
50
|
+
procedural: ProceduralMemory[];
|
|
51
|
+
};
|
|
52
|
+
allEntries: MemoryEntry[];
|
|
53
|
+
graphContext: GraphNeighbor[];
|
|
54
|
+
// For reinforcement
|
|
55
|
+
injectedActiveKnowledge: MemoryEntry[];
|
|
56
|
+
injectedActiveLessons: MemoryEntry[];
|
|
57
|
+
injectedActiveEvents: MemoryEntry[];
|
|
58
|
+
injectedActivePrefs: MemoryEntry[];
|
|
59
|
+
injectedCueKnowledge: MemoryEntry[];
|
|
60
|
+
injectedCueLessons: MemoryEntry[];
|
|
61
|
+
injectedCueEvents: MemoryEntry[];
|
|
62
|
+
injectedCuePrefs: MemoryEntry[];
|
|
63
|
+
injectedCueEpisodes: Episode[];
|
|
64
|
+
legacyFacetBridgeActive: MemoryEntry[];
|
|
65
|
+
legacyFacetBridgeCue: MemoryEntry[];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function selectRecallEntries(params: {
|
|
69
|
+
// Legacy entries (filtered)
|
|
70
|
+
knowledge: MemoryEntry[]; lessons: MemoryEntry[]; events: MemoryEntry[];
|
|
71
|
+
prefs: MemoryEntry[]; facets: MemoryEntry[]; work: WorkEntry[]; episodes: Episode[];
|
|
72
|
+
// V2 entries (filtered)
|
|
73
|
+
v2Episodes: EpisodeMemory[]; v2EpisodeFacets: EpisodeFacet[];
|
|
74
|
+
v2Semantic: SemanticMemory[]; procedural: ProceduralMemory[];
|
|
75
|
+
// Raw entries for graph context
|
|
76
|
+
allKnowledge: MemoryEntry[]; allLessons: MemoryEntry[]; allEvents: MemoryEntry[];
|
|
77
|
+
allPrefs: MemoryEntry[]; allFacets: MemoryEntry[];
|
|
78
|
+
// Semantic candidates from embedding search
|
|
79
|
+
semanticCandidates: Array<{ memoryId: string; memoryKind: string; score: number }>;
|
|
80
|
+
// Config
|
|
81
|
+
halfLife: Record<string, number>;
|
|
82
|
+
scoreWeights: { recency: number; importance: number; relevance: number };
|
|
83
|
+
progressiveRecall: ProgressiveRecallConfig;
|
|
84
|
+
tokenBudget: number;
|
|
85
|
+
structuralWeight: number;
|
|
86
|
+
project: string;
|
|
87
|
+
contextTags: string[];
|
|
88
|
+
}): RecallSelectionResult {
|
|
89
|
+
const {
|
|
90
|
+
knowledge, lessons, events, prefs, facets, work, episodes,
|
|
91
|
+
v2Episodes, v2EpisodeFacets, v2Semantic, procedural,
|
|
92
|
+
allKnowledge, allLessons, allEvents, allPrefs, allFacets,
|
|
93
|
+
semanticCandidates, halfLife: hl, scoreWeights: sw, progressiveRecall: pr,
|
|
94
|
+
tokenBudget, structuralWeight, project, contextTags,
|
|
95
|
+
} = params;
|
|
96
|
+
|
|
97
|
+
const semanticEpisodeIds = new Set(
|
|
98
|
+
semanticCandidates.filter((item) => item.memoryKind === "episode").map((item) => item.memoryId),
|
|
99
|
+
);
|
|
100
|
+
const semanticFacetIds = new Set(
|
|
101
|
+
semanticCandidates.filter((item) => item.memoryKind === "facet").map((item) => item.memoryId),
|
|
102
|
+
);
|
|
103
|
+
const semanticProcedureIds = new Set(
|
|
104
|
+
semanticCandidates.filter((item) => item.memoryKind === "procedural").map((item) => item.memoryId),
|
|
105
|
+
);
|
|
106
|
+
const semanticV2SemanticIds = new Set(
|
|
107
|
+
semanticCandidates.filter((item) => item.memoryKind === "semantic").map((item) => item.memoryId),
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
// Tier all MemoryEntry categories
|
|
111
|
+
const tieredKnowledge = tierEntries(knowledge, project, contextTags, hl, sw, pr);
|
|
112
|
+
const tieredLessons = tierEntries(lessons, project, contextTags, hl, sw, pr);
|
|
113
|
+
const tieredEvents = tierEntries(events, project, contextTags, hl, sw, pr);
|
|
114
|
+
const tieredPrefs = tierEntries(prefs, project, contextTags, hl, sw, pr);
|
|
115
|
+
const tieredFacets = tierEntries(facets, project, contextTags, hl, sw, pr);
|
|
116
|
+
const forcedConversationPrefs = selectConversationPreferences(prefs);
|
|
117
|
+
|
|
118
|
+
// Budget calculation
|
|
119
|
+
const totalChars = tokenBudget * 4;
|
|
120
|
+
const activeChars = Math.floor(totalChars * pr.budgetActive);
|
|
121
|
+
const cueChars = Math.floor(totalChars * pr.budgetCue);
|
|
122
|
+
const proceduralChars = Math.floor(totalChars * 0.18);
|
|
123
|
+
|
|
124
|
+
// Entry length helpers
|
|
125
|
+
const activeLen = (e: MemoryEntry) =>
|
|
126
|
+
(e.name?.length || 0) + (e.summary?.length || 0) + (e.detail?.length || 0) + 30;
|
|
127
|
+
const cueLen = (e: MemoryEntry) => (e.name?.length || 0) + (e.summary?.length || 0) + 30;
|
|
128
|
+
const scoreFn = (e: MemoryEntry) => scoreEntry(e, project, contextTags, hl, sw);
|
|
129
|
+
const proceduralLen = (pItem: ProceduralMemory) =>
|
|
130
|
+
(pItem.name?.length || 0) + (pItem.summary?.length || 0) + pItem.steps.reduce((sum, step) => sum + step.text.length, 0) + 60;
|
|
131
|
+
const proceduralCueLen = (pItem: ProceduralMemory) =>
|
|
132
|
+
(pItem.name?.length || 0) + (pItem.summary?.length || 0) + 40;
|
|
133
|
+
const proceduralScoreFn = (pItem: ProceduralMemory) => scoreProceduralMemory(pItem, project, contextTags, structuralWeight);
|
|
134
|
+
const episodeMemoryLen = (item: EpisodeMemory) => (item.title?.length || 0) + item.summary.length + 40;
|
|
135
|
+
const episodeFacetLen = (item: EpisodeFacet) =>
|
|
136
|
+
item.searchText.length + (item.anchorText?.length || 0) + (item.summary?.length || 0) + 40;
|
|
137
|
+
const episodeCueLen = (item: EpisodeMemory) => (item.title?.length || 0) + item.summary.length + 36;
|
|
138
|
+
const episodeFacetCueLen = (item: EpisodeFacet) =>
|
|
139
|
+
item.searchText.length + (item.summary?.length || 0) + (item.anchorText?.length || 0) + 36;
|
|
140
|
+
const semanticMemoryLen = (item: SemanticMemory) =>
|
|
141
|
+
(item.name?.length || 0) + item.summary.length + (item.detail?.length || 0) + 40;
|
|
142
|
+
const semanticMemoryCueLen = (item: SemanticMemory) => (item.name?.length || 0) + item.summary.length + 36;
|
|
143
|
+
const episodeScoreFn = (item: EpisodeMemory) => scoreEpisodeMemory(item, project, contextTags, structuralWeight);
|
|
144
|
+
const episodeFacetScoreFn = (item: EpisodeFacet) => scoreEpisodeFacet(item, project, contextTags, structuralWeight);
|
|
145
|
+
const semanticMemoryScoreFn = (item: SemanticMemory) => scoreV2SemanticMemory(item, project, contextTags, structuralWeight);
|
|
146
|
+
|
|
147
|
+
// Active tier
|
|
148
|
+
const activeBudgetPer = Math.floor(activeChars / 5);
|
|
149
|
+
const activeKnowledge = pickTop(tieredKnowledge.active, scoreFn, activeLen, activeBudgetPer);
|
|
150
|
+
const activeLessons = pickTop(tieredLessons.active, scoreFn, activeLen, activeBudgetPer);
|
|
151
|
+
const activeEvents = pickTop(tieredEvents.active, scoreFn, activeLen, activeBudgetPer);
|
|
152
|
+
const activePrefs = mergeUniqueEntries(
|
|
153
|
+
forcedConversationPrefs,
|
|
154
|
+
pickTop(tieredPrefs.active, scoreFn, activeLen, activeBudgetPer),
|
|
155
|
+
);
|
|
156
|
+
const activeFacets = pickTop(tieredFacets.active, scoreFn, activeLen, activeBudgetPer);
|
|
157
|
+
const activeProcedural = pickTop(
|
|
158
|
+
procedural.filter((item) => semanticProcedureIds.has(item.id) || proceduralScoreFn(item) >= 0.45),
|
|
159
|
+
proceduralScoreFn,
|
|
160
|
+
proceduralLen,
|
|
161
|
+
Math.max(400, Math.floor(proceduralChars * 0.55)),
|
|
162
|
+
);
|
|
163
|
+
const activeEpisodeMemories = pickTop(
|
|
164
|
+
v2Episodes.filter((item) => semanticEpisodeIds.has(item.id) || episodeScoreFn(item) >= 0.45),
|
|
165
|
+
episodeScoreFn,
|
|
166
|
+
episodeMemoryLen,
|
|
167
|
+
Math.max(320, Math.floor(activeChars * 0.18)),
|
|
168
|
+
);
|
|
169
|
+
const activeEpisodeFacets = pickTop(
|
|
170
|
+
v2EpisodeFacets.filter((item) => semanticFacetIds.has(item.id) || episodeFacetScoreFn(item) >= 0.42),
|
|
171
|
+
episodeFacetScoreFn,
|
|
172
|
+
episodeFacetLen,
|
|
173
|
+
Math.max(320, Math.floor(activeChars * 0.18)),
|
|
174
|
+
);
|
|
175
|
+
const activeSemanticMemories = pickTop(
|
|
176
|
+
v2Semantic.filter((item) => semanticV2SemanticIds.has(item.id) || semanticMemoryScoreFn(item) >= 0.42),
|
|
177
|
+
semanticMemoryScoreFn,
|
|
178
|
+
semanticMemoryLen,
|
|
179
|
+
Math.max(280, Math.floor(activeChars * 0.16)),
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
const activeSeeds = [...activeKnowledge, ...activeLessons, ...activeEvents, ...activePrefs, ...activeFacets];
|
|
183
|
+
const allEntries = [...allKnowledge, ...allLessons, ...allEvents, ...allPrefs, ...allFacets];
|
|
184
|
+
const activeIds = new Set(activeSeeds.map((entry) => entry.id));
|
|
185
|
+
const graphContext = getGraphNeighborhoodBySeeds(activeSeeds, allEntries, 8).filter(
|
|
186
|
+
(neighbor) => !activeIds.has(neighbor.entry.id),
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
// Cue tier
|
|
190
|
+
const cueBudgetPer = Math.floor(cueChars / 7);
|
|
191
|
+
const cueKnowledge = pickTop(tieredKnowledge.cue, scoreFn, cueLen, cueBudgetPer);
|
|
192
|
+
const cueLessons = pickTop(tieredLessons.cue, scoreFn, cueLen, cueBudgetPer);
|
|
193
|
+
const cueEvents = pickTop(tieredEvents.cue, scoreFn, cueLen, cueBudgetPer);
|
|
194
|
+
const forcedConversationPrefIds = new Set(forcedConversationPrefs.map((entry) => entry.id));
|
|
195
|
+
const cuePrefs = pickTop(
|
|
196
|
+
tieredPrefs.cue.filter((entry) => !forcedConversationPrefIds.has(entry.id)),
|
|
197
|
+
scoreFn,
|
|
198
|
+
cueLen,
|
|
199
|
+
cueBudgetPer,
|
|
200
|
+
);
|
|
201
|
+
const cueFacets = pickTop(tieredFacets.cue, scoreFn, cueLen, cueBudgetPer);
|
|
202
|
+
const graphContextIds = new Set(graphContext.map((neighbor) => neighbor.entry.id));
|
|
203
|
+
const dedupeCue = (entries: MemoryEntry[]) => entries.filter((entry) => !graphContextIds.has(entry.id));
|
|
204
|
+
const dedupedCueKnowledge = dedupeCue(cueKnowledge);
|
|
205
|
+
const dedupedCueLessons = dedupeCue(cueLessons);
|
|
206
|
+
const dedupedCueEvents = dedupeCue(cueEvents);
|
|
207
|
+
const dedupedCuePrefs = dedupeCue(cuePrefs);
|
|
208
|
+
const dedupedCueFacets = dedupeCue(cueFacets);
|
|
209
|
+
|
|
210
|
+
const topEpisodes = pickTop(
|
|
211
|
+
episodes,
|
|
212
|
+
(ep) => scoreEpisode(ep, project, contextTags, hl, sw),
|
|
213
|
+
(ep) => ep.summary.length + 30,
|
|
214
|
+
cueBudgetPer,
|
|
215
|
+
);
|
|
216
|
+
const topWork = pickTop(
|
|
217
|
+
work,
|
|
218
|
+
(w) => scoreWorkEntry(w, project, contextTags, hl, sw),
|
|
219
|
+
(w) => w.goal.length + w.summary.length + 30,
|
|
220
|
+
cueBudgetPer,
|
|
221
|
+
);
|
|
222
|
+
const cueProcedural = pickTop(
|
|
223
|
+
procedural.filter((item) => !activeProcedural.some((activeItem) => activeItem.id === item.id)),
|
|
224
|
+
proceduralScoreFn,
|
|
225
|
+
proceduralCueLen,
|
|
226
|
+
Math.max(280, Math.floor(proceduralChars * 0.45)),
|
|
227
|
+
);
|
|
228
|
+
const cueEpisodeMemories = pickTop(
|
|
229
|
+
v2Episodes.filter((item) => !activeEpisodeMemories.some((activeItem) => activeItem.id === item.id)),
|
|
230
|
+
episodeScoreFn,
|
|
231
|
+
episodeCueLen,
|
|
232
|
+
Math.max(220, Math.floor(cueChars * 0.12)),
|
|
233
|
+
);
|
|
234
|
+
const cueEpisodeFacets = pickTop(
|
|
235
|
+
v2EpisodeFacets.filter((item) => !activeEpisodeFacets.some((activeItem) => activeItem.id === item.id)),
|
|
236
|
+
episodeFacetScoreFn,
|
|
237
|
+
episodeFacetCueLen,
|
|
238
|
+
Math.max(220, Math.floor(cueChars * 0.12)),
|
|
239
|
+
);
|
|
240
|
+
const cueSemanticMemories = pickTop(
|
|
241
|
+
v2Semantic.filter((item) => !activeSemanticMemories.some((activeItem) => activeItem.id === item.id)),
|
|
242
|
+
semanticMemoryScoreFn,
|
|
243
|
+
semanticMemoryCueLen,
|
|
244
|
+
Math.max(220, Math.floor(cueChars * 0.12)),
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
const legacyFacetBridgeActive = activeFacets.filter(
|
|
248
|
+
(entry) => entry.facetData?.kind === "pattern" || entry.facetData?.kind === "struggle",
|
|
249
|
+
);
|
|
250
|
+
const legacyFacetBridgeCue = dedupedCueFacets.filter(
|
|
251
|
+
(entry) => entry.facetData?.kind === "pattern" || entry.facetData?.kind === "struggle",
|
|
252
|
+
);
|
|
253
|
+
const v2SignalCount =
|
|
254
|
+
activeEpisodeMemories.length + activeEpisodeFacets.length + activeSemanticMemories.length + activeProcedural.length +
|
|
255
|
+
cueEpisodeMemories.length + cueEpisodeFacets.length + cueSemanticMemories.length + cueProcedural.length;
|
|
256
|
+
const useLegacyFallback = v2SignalCount === 0;
|
|
257
|
+
const injectedActiveKnowledge = useLegacyFallback ? activeKnowledge : [];
|
|
258
|
+
const injectedActiveLessons = useLegacyFallback ? activeLessons : [];
|
|
259
|
+
const injectedActiveEvents = useLegacyFallback ? activeEvents : [];
|
|
260
|
+
const injectedActivePrefs = useLegacyFallback ? activePrefs : [];
|
|
261
|
+
const injectedCueKnowledge = useLegacyFallback ? dedupedCueKnowledge : [];
|
|
262
|
+
const injectedCueLessons = useLegacyFallback ? dedupedCueLessons : [];
|
|
263
|
+
const injectedCueEvents = useLegacyFallback ? dedupedCueEvents : [];
|
|
264
|
+
const injectedCuePrefs = useLegacyFallback ? dedupedCuePrefs : [];
|
|
265
|
+
const injectedCueEpisodes = useLegacyFallback ? topEpisodes : [];
|
|
266
|
+
|
|
267
|
+
return {
|
|
268
|
+
active: {
|
|
269
|
+
knowledge: injectedActiveKnowledge,
|
|
270
|
+
lessons: injectedActiveLessons,
|
|
271
|
+
events: injectedActiveEvents,
|
|
272
|
+
preferences: injectedActivePrefs,
|
|
273
|
+
facets: legacyFacetBridgeActive,
|
|
274
|
+
episodeMemories: activeEpisodeMemories,
|
|
275
|
+
episodeFacets: activeEpisodeFacets,
|
|
276
|
+
semanticMemories: activeSemanticMemories,
|
|
277
|
+
procedural: activeProcedural,
|
|
278
|
+
},
|
|
279
|
+
cue: {
|
|
280
|
+
knowledge: injectedCueKnowledge,
|
|
281
|
+
lessons: injectedCueLessons,
|
|
282
|
+
events: injectedCueEvents,
|
|
283
|
+
preferences: injectedCuePrefs,
|
|
284
|
+
facets: legacyFacetBridgeCue,
|
|
285
|
+
episodes: injectedCueEpisodes,
|
|
286
|
+
work: topWork,
|
|
287
|
+
episodeMemories: cueEpisodeMemories,
|
|
288
|
+
episodeFacets: cueEpisodeFacets,
|
|
289
|
+
semanticMemories: cueSemanticMemories,
|
|
290
|
+
procedural: cueProcedural,
|
|
291
|
+
},
|
|
292
|
+
allEntries,
|
|
293
|
+
graphContext,
|
|
294
|
+
injectedActiveKnowledge, injectedActiveLessons, injectedActiveEvents, injectedActivePrefs,
|
|
295
|
+
injectedCueKnowledge, injectedCueLessons, injectedCueEvents, injectedCuePrefs, injectedCueEpisodes,
|
|
296
|
+
legacyFacetBridgeActive, legacyFacetBridgeCue,
|
|
297
|
+
};
|
|
298
|
+
}
|