memory-braid 0.4.1 → 0.4.3
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/package.json +1 -1
- package/src/entities.ts +90 -6
- package/src/index.ts +353 -4
package/package.json
CHANGED
package/src/entities.ts
CHANGED
|
@@ -11,6 +11,8 @@ type NerRecord = {
|
|
|
11
11
|
entity_group?: unknown;
|
|
12
12
|
entity?: unknown;
|
|
13
13
|
score?: unknown;
|
|
14
|
+
start?: unknown;
|
|
15
|
+
end?: unknown;
|
|
14
16
|
};
|
|
15
17
|
|
|
16
18
|
export type ExtractedEntity = {
|
|
@@ -79,6 +81,76 @@ function normalizeEntityText(raw: unknown): string {
|
|
|
79
81
|
return normalizeWhitespace(raw.replace(/^##/, "").replace(/^▁/, ""));
|
|
80
82
|
}
|
|
81
83
|
|
|
84
|
+
type NormalizedEntityToken = {
|
|
85
|
+
text: string;
|
|
86
|
+
type: ExtractedEntity["type"];
|
|
87
|
+
score: number;
|
|
88
|
+
start?: number;
|
|
89
|
+
end?: number;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
function asFiniteNumber(value: unknown): number | undefined {
|
|
93
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
return value;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function joinEntityText(left: NormalizedEntityToken, right: NormalizedEntityToken): string {
|
|
100
|
+
const leftEnd = left.end;
|
|
101
|
+
const rightStart = right.start;
|
|
102
|
+
if (typeof leftEnd === "number" && typeof rightStart === "number") {
|
|
103
|
+
const gap = rightStart - leftEnd;
|
|
104
|
+
if (gap <= 0) {
|
|
105
|
+
return `${left.text}${right.text}`;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return `${left.text} ${right.text}`;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function shouldMergeEntityTokens(left: NormalizedEntityToken, right: NormalizedEntityToken): boolean {
|
|
112
|
+
if (left.type !== right.type || !left.text || !right.text) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const leftEnd = left.end;
|
|
117
|
+
const rightStart = right.start;
|
|
118
|
+
if (typeof leftEnd === "number" && typeof rightStart === "number") {
|
|
119
|
+
const gap = rightStart - leftEnd;
|
|
120
|
+
if (gap < 0) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
return gap <= 1;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (/[.,!?;:]$/.test(left.text) || /^[.,!?;:]/.test(right.text)) {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function collapseAdjacentEntityTokens(tokens: NormalizedEntityToken[]): NormalizedEntityToken[] {
|
|
133
|
+
if (tokens.length <= 1) {
|
|
134
|
+
return tokens;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const collapsed: NormalizedEntityToken[] = [];
|
|
138
|
+
for (const token of tokens) {
|
|
139
|
+
const previous = collapsed[collapsed.length - 1];
|
|
140
|
+
if (!previous || !shouldMergeEntityTokens(previous, token)) {
|
|
141
|
+
collapsed.push({ ...token });
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
previous.text = normalizeWhitespace(joinEntityText(previous, token));
|
|
146
|
+
previous.score = Math.min(previous.score, token.score);
|
|
147
|
+
previous.start = typeof previous.start === "number" ? previous.start : token.start;
|
|
148
|
+
previous.end = typeof token.end === "number" ? token.end : previous.end;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return collapsed;
|
|
152
|
+
}
|
|
153
|
+
|
|
82
154
|
type EntityExtractionOptions = {
|
|
83
155
|
stateDir?: string;
|
|
84
156
|
};
|
|
@@ -319,7 +391,7 @@ export class EntityExtractionManager {
|
|
|
319
391
|
});
|
|
320
392
|
const rows = Array.isArray(raw) ? raw : [];
|
|
321
393
|
|
|
322
|
-
const
|
|
394
|
+
const normalized: NormalizedEntityToken[] = [];
|
|
323
395
|
for (const row of rows) {
|
|
324
396
|
if (!row || typeof row !== "object") {
|
|
325
397
|
continue;
|
|
@@ -335,13 +407,25 @@ export class EntityExtractionManager {
|
|
|
335
407
|
}
|
|
336
408
|
|
|
337
409
|
const type = normalizeEntityType(record.entity_group ?? record.entity);
|
|
338
|
-
|
|
410
|
+
normalized.push({
|
|
411
|
+
text: entityText,
|
|
412
|
+
type,
|
|
413
|
+
score,
|
|
414
|
+
start: asFiniteNumber(record.start),
|
|
415
|
+
end: asFiniteNumber(record.end),
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
const collapsed = collapseAdjacentEntityTokens(normalized);
|
|
420
|
+
const deduped = new Map<string, ExtractedEntity>();
|
|
421
|
+
for (const token of collapsed) {
|
|
422
|
+
const canonicalUri = buildCanonicalEntityUri(token.type, token.text);
|
|
339
423
|
const current = deduped.get(canonicalUri);
|
|
340
|
-
if (!current || score > current.score) {
|
|
424
|
+
if (!current || token.score > current.score) {
|
|
341
425
|
deduped.set(canonicalUri, {
|
|
342
|
-
text:
|
|
343
|
-
type,
|
|
344
|
-
score,
|
|
426
|
+
text: token.text,
|
|
427
|
+
type: token.type,
|
|
428
|
+
score: token.score,
|
|
345
429
|
canonicalUri,
|
|
346
430
|
});
|
|
347
431
|
}
|
package/src/index.ts
CHANGED
|
@@ -105,6 +105,315 @@ function asRecord(value: unknown): Record<string, unknown> {
|
|
|
105
105
|
return value as Record<string, unknown>;
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
+
const OVERLAP_STOPWORDS = new Set([
|
|
109
|
+
"a",
|
|
110
|
+
"an",
|
|
111
|
+
"and",
|
|
112
|
+
"are",
|
|
113
|
+
"as",
|
|
114
|
+
"at",
|
|
115
|
+
"be",
|
|
116
|
+
"by",
|
|
117
|
+
"for",
|
|
118
|
+
"from",
|
|
119
|
+
"how",
|
|
120
|
+
"i",
|
|
121
|
+
"in",
|
|
122
|
+
"is",
|
|
123
|
+
"it",
|
|
124
|
+
"my",
|
|
125
|
+
"of",
|
|
126
|
+
"on",
|
|
127
|
+
"or",
|
|
128
|
+
"our",
|
|
129
|
+
"that",
|
|
130
|
+
"the",
|
|
131
|
+
"this",
|
|
132
|
+
"to",
|
|
133
|
+
"we",
|
|
134
|
+
"with",
|
|
135
|
+
"you",
|
|
136
|
+
"your",
|
|
137
|
+
"de",
|
|
138
|
+
"del",
|
|
139
|
+
"el",
|
|
140
|
+
"en",
|
|
141
|
+
"es",
|
|
142
|
+
"la",
|
|
143
|
+
"las",
|
|
144
|
+
"los",
|
|
145
|
+
"mi",
|
|
146
|
+
"mis",
|
|
147
|
+
"para",
|
|
148
|
+
"por",
|
|
149
|
+
"que",
|
|
150
|
+
"se",
|
|
151
|
+
"su",
|
|
152
|
+
"sus",
|
|
153
|
+
"un",
|
|
154
|
+
"una",
|
|
155
|
+
"y",
|
|
156
|
+
]);
|
|
157
|
+
|
|
158
|
+
function normalizeToken(value: string): string {
|
|
159
|
+
return value
|
|
160
|
+
.toLowerCase()
|
|
161
|
+
.normalize("NFKD")
|
|
162
|
+
.replace(/\p{M}+/gu, "");
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function tokenizeForOverlap(text: string): Set<string> {
|
|
166
|
+
const tokens = text.match(/[\p{L}\p{N}]+/gu) ?? [];
|
|
167
|
+
const out = new Set<string>();
|
|
168
|
+
for (const token of tokens) {
|
|
169
|
+
const normalized = normalizeToken(token);
|
|
170
|
+
if (normalized.length < 3 || OVERLAP_STOPWORDS.has(normalized)) {
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
out.add(normalized);
|
|
174
|
+
}
|
|
175
|
+
return out;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function lexicalOverlap(queryTokens: Set<string>, text: string): { shared: number; ratio: number } {
|
|
179
|
+
if (queryTokens.size === 0) {
|
|
180
|
+
return { shared: 0, ratio: 0 };
|
|
181
|
+
}
|
|
182
|
+
const textTokens = tokenizeForOverlap(text);
|
|
183
|
+
let shared = 0;
|
|
184
|
+
for (const token of queryTokens) {
|
|
185
|
+
if (textTokens.has(token)) {
|
|
186
|
+
shared += 1;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
shared,
|
|
191
|
+
ratio: shared / queryTokens.size,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function normalizeCategory(raw: unknown): "preference" | "decision" | "fact" | "task" | "other" | undefined {
|
|
196
|
+
if (typeof raw !== "string") {
|
|
197
|
+
return undefined;
|
|
198
|
+
}
|
|
199
|
+
const normalized = raw.trim().toLowerCase();
|
|
200
|
+
if (
|
|
201
|
+
normalized === "preference" ||
|
|
202
|
+
normalized === "decision" ||
|
|
203
|
+
normalized === "fact" ||
|
|
204
|
+
normalized === "task" ||
|
|
205
|
+
normalized === "other"
|
|
206
|
+
) {
|
|
207
|
+
return normalized;
|
|
208
|
+
}
|
|
209
|
+
return undefined;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function normalizeSessionKey(raw: unknown): string | undefined {
|
|
213
|
+
if (typeof raw !== "string") {
|
|
214
|
+
return undefined;
|
|
215
|
+
}
|
|
216
|
+
const trimmed = raw.trim();
|
|
217
|
+
return trimmed || undefined;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function isGenericUserSummary(text: string): boolean {
|
|
221
|
+
const normalized = text.trim().toLowerCase();
|
|
222
|
+
return (
|
|
223
|
+
/^(the user|user|usuario)\b/.test(normalized) ||
|
|
224
|
+
/\b(user|usuario)\s+(asked|wants|needs|prefers|likes|said)\b/.test(normalized)
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function applyMem0QualityAdjustments(params: {
|
|
229
|
+
results: MemoryBraidResult[];
|
|
230
|
+
query: string;
|
|
231
|
+
scope: ScopeKey;
|
|
232
|
+
nowMs: number;
|
|
233
|
+
}): {
|
|
234
|
+
results: MemoryBraidResult[];
|
|
235
|
+
adjusted: number;
|
|
236
|
+
overlapBoosted: number;
|
|
237
|
+
overlapPenalized: number;
|
|
238
|
+
categoryPenalized: number;
|
|
239
|
+
sessionBoosted: number;
|
|
240
|
+
sessionPenalized: number;
|
|
241
|
+
genericPenalized: number;
|
|
242
|
+
} {
|
|
243
|
+
if (params.results.length === 0) {
|
|
244
|
+
return {
|
|
245
|
+
results: params.results,
|
|
246
|
+
adjusted: 0,
|
|
247
|
+
overlapBoosted: 0,
|
|
248
|
+
overlapPenalized: 0,
|
|
249
|
+
categoryPenalized: 0,
|
|
250
|
+
sessionBoosted: 0,
|
|
251
|
+
sessionPenalized: 0,
|
|
252
|
+
genericPenalized: 0,
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const queryTokens = tokenizeForOverlap(params.query);
|
|
257
|
+
let adjusted = 0;
|
|
258
|
+
let overlapBoosted = 0;
|
|
259
|
+
let overlapPenalized = 0;
|
|
260
|
+
let categoryPenalized = 0;
|
|
261
|
+
let sessionBoosted = 0;
|
|
262
|
+
let sessionPenalized = 0;
|
|
263
|
+
let genericPenalized = 0;
|
|
264
|
+
|
|
265
|
+
const next = params.results.map((result, index) => {
|
|
266
|
+
let multiplier = 1;
|
|
267
|
+
const metadata = asRecord(result.metadata);
|
|
268
|
+
const overlap = lexicalOverlap(queryTokens, result.snippet);
|
|
269
|
+
const category = normalizeCategory(metadata.category);
|
|
270
|
+
const isGeneric = isGenericUserSummary(result.snippet);
|
|
271
|
+
const ts = resolveTimestampMs(result);
|
|
272
|
+
const ageDays = ts ? Math.max(0, (params.nowMs - ts) / (24 * 60 * 60 * 1000)) : undefined;
|
|
273
|
+
|
|
274
|
+
if ((category === "task" || category === "other") && typeof ageDays === "number") {
|
|
275
|
+
if (ageDays >= 30) {
|
|
276
|
+
multiplier *= 0.5;
|
|
277
|
+
categoryPenalized += 1;
|
|
278
|
+
} else if (ageDays >= 7) {
|
|
279
|
+
multiplier *= category === "task" ? 0.65 : 0.72;
|
|
280
|
+
categoryPenalized += 1;
|
|
281
|
+
}
|
|
282
|
+
} else if (typeof ageDays === "number" && ageDays >= 180) {
|
|
283
|
+
multiplier *= 0.9;
|
|
284
|
+
categoryPenalized += 1;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (queryTokens.size > 0) {
|
|
288
|
+
if (overlap.shared >= 2 || overlap.ratio >= 0.45) {
|
|
289
|
+
multiplier *= 1.25;
|
|
290
|
+
overlapBoosted += 1;
|
|
291
|
+
} else if (overlap.shared === 1 || overlap.ratio >= 0.2) {
|
|
292
|
+
multiplier *= 1.1;
|
|
293
|
+
overlapBoosted += 1;
|
|
294
|
+
} else {
|
|
295
|
+
multiplier *= 0.62;
|
|
296
|
+
overlapPenalized += 1;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const metadataSession =
|
|
301
|
+
normalizeSessionKey(metadata.sessionKey) ??
|
|
302
|
+
normalizeSessionKey(metadata.runId) ??
|
|
303
|
+
normalizeSessionKey(metadata.run_id);
|
|
304
|
+
if (params.scope.sessionKey && metadataSession) {
|
|
305
|
+
if (metadataSession === params.scope.sessionKey) {
|
|
306
|
+
multiplier *= 1.1;
|
|
307
|
+
sessionBoosted += 1;
|
|
308
|
+
} else {
|
|
309
|
+
multiplier *= 0.82;
|
|
310
|
+
sessionPenalized += 1;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (isGeneric && overlap.ratio < 0.2 && overlap.shared < 2) {
|
|
315
|
+
multiplier *= 0.6;
|
|
316
|
+
genericPenalized += 1;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
const normalizedMultiplier = Math.min(2.5, Math.max(0.1, multiplier));
|
|
320
|
+
const nextScore = result.score * normalizedMultiplier;
|
|
321
|
+
if (nextScore !== result.score) {
|
|
322
|
+
adjusted += 1;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
return {
|
|
326
|
+
index,
|
|
327
|
+
result: {
|
|
328
|
+
...result,
|
|
329
|
+
score: nextScore,
|
|
330
|
+
},
|
|
331
|
+
};
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
next.sort((left, right) => {
|
|
335
|
+
const scoreDelta = right.result.score - left.result.score;
|
|
336
|
+
if (scoreDelta !== 0) {
|
|
337
|
+
return scoreDelta;
|
|
338
|
+
}
|
|
339
|
+
return left.index - right.index;
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
return {
|
|
343
|
+
results: next.map((entry) => entry.result),
|
|
344
|
+
adjusted,
|
|
345
|
+
overlapBoosted,
|
|
346
|
+
overlapPenalized,
|
|
347
|
+
categoryPenalized,
|
|
348
|
+
sessionBoosted,
|
|
349
|
+
sessionPenalized,
|
|
350
|
+
genericPenalized,
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
function selectMemoriesForInjection(params: {
|
|
355
|
+
query: string;
|
|
356
|
+
results: MemoryBraidResult[];
|
|
357
|
+
limit: number;
|
|
358
|
+
}): {
|
|
359
|
+
injected: MemoryBraidResult[];
|
|
360
|
+
queryTokens: number;
|
|
361
|
+
filteredOut: number;
|
|
362
|
+
genericRejected: number;
|
|
363
|
+
} {
|
|
364
|
+
const limit = Math.max(0, Math.floor(params.limit));
|
|
365
|
+
if (limit === 0 || params.results.length === 0) {
|
|
366
|
+
return {
|
|
367
|
+
injected: [],
|
|
368
|
+
queryTokens: 0,
|
|
369
|
+
filteredOut: 0,
|
|
370
|
+
genericRejected: 0,
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
const queryTokens = tokenizeForOverlap(params.query);
|
|
375
|
+
if (queryTokens.size === 0) {
|
|
376
|
+
return {
|
|
377
|
+
injected: params.results.slice(0, limit),
|
|
378
|
+
queryTokens: 0,
|
|
379
|
+
filteredOut: Math.max(0, params.results.length - Math.min(limit, params.results.length)),
|
|
380
|
+
genericRejected: 0,
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const injected: MemoryBraidResult[] = [];
|
|
385
|
+
let filteredOut = 0;
|
|
386
|
+
let genericRejected = 0;
|
|
387
|
+
|
|
388
|
+
for (const result of params.results) {
|
|
389
|
+
if (injected.length >= limit) {
|
|
390
|
+
break;
|
|
391
|
+
}
|
|
392
|
+
const overlap = lexicalOverlap(queryTokens, result.snippet);
|
|
393
|
+
const generic = isGenericUserSummary(result.snippet);
|
|
394
|
+
const strongThreshold = result.source === "local" ? 0.26 : 0.34;
|
|
395
|
+
const weakThreshold = result.source === "local" ? 0.12 : 0.18;
|
|
396
|
+
const strongMatch = overlap.shared >= 2 || overlap.ratio >= strongThreshold;
|
|
397
|
+
const weakMatch = overlap.shared >= 1 && overlap.ratio >= weakThreshold;
|
|
398
|
+
const keep = generic ? overlap.shared >= 2 || overlap.ratio >= 0.5 : strongMatch || weakMatch;
|
|
399
|
+
if (keep) {
|
|
400
|
+
injected.push(result);
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
filteredOut += 1;
|
|
404
|
+
if (generic) {
|
|
405
|
+
genericRejected += 1;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
return {
|
|
410
|
+
injected,
|
|
411
|
+
queryTokens: queryTokens.size,
|
|
412
|
+
filteredOut,
|
|
413
|
+
genericRejected,
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
|
|
108
417
|
function resolveCoreTemporalDecay(params: {
|
|
109
418
|
config?: unknown;
|
|
110
419
|
agentId?: string;
|
|
@@ -528,6 +837,27 @@ async function runHybridRecall(params: {
|
|
|
528
837
|
});
|
|
529
838
|
}
|
|
530
839
|
}
|
|
840
|
+
const qualityAdjusted = applyMem0QualityAdjustments({
|
|
841
|
+
results: mem0ForMerge,
|
|
842
|
+
query: params.query,
|
|
843
|
+
scope,
|
|
844
|
+
nowMs: Date.now(),
|
|
845
|
+
});
|
|
846
|
+
mem0ForMerge = qualityAdjusted.results;
|
|
847
|
+
params.log.debug("memory_braid.search.mem0_quality", {
|
|
848
|
+
runId: params.runId,
|
|
849
|
+
agentId: scope.agentId,
|
|
850
|
+
sessionKey: scope.sessionKey,
|
|
851
|
+
workspaceHash: scope.workspaceHash,
|
|
852
|
+
inputCount: mem0Search.length,
|
|
853
|
+
adjusted: qualityAdjusted.adjusted,
|
|
854
|
+
overlapBoosted: qualityAdjusted.overlapBoosted,
|
|
855
|
+
overlapPenalized: qualityAdjusted.overlapPenalized,
|
|
856
|
+
categoryPenalized: qualityAdjusted.categoryPenalized,
|
|
857
|
+
sessionBoosted: qualityAdjusted.sessionBoosted,
|
|
858
|
+
sessionPenalized: qualityAdjusted.sessionPenalized,
|
|
859
|
+
genericPenalized: qualityAdjusted.genericPenalized,
|
|
860
|
+
});
|
|
531
861
|
params.log.debug("memory_braid.search.mem0", {
|
|
532
862
|
runId: params.runId,
|
|
533
863
|
agentId: scope.agentId,
|
|
@@ -913,19 +1243,38 @@ const memoryBraidPlugin = {
|
|
|
913
1243
|
runId,
|
|
914
1244
|
});
|
|
915
1245
|
|
|
916
|
-
const
|
|
917
|
-
|
|
1246
|
+
const selected = selectMemoriesForInjection({
|
|
1247
|
+
query: event.prompt,
|
|
1248
|
+
results: recall.merged,
|
|
1249
|
+
limit: cfg.recall.injectTopK,
|
|
1250
|
+
});
|
|
1251
|
+
if (selected.injected.length === 0) {
|
|
1252
|
+
const scope = resolveScopeFromHookContext(ctx);
|
|
1253
|
+
log.debug("memory_braid.search.inject", {
|
|
1254
|
+
runId,
|
|
1255
|
+
agentId: scope.agentId,
|
|
1256
|
+
sessionKey: scope.sessionKey,
|
|
1257
|
+
workspaceHash: scope.workspaceHash,
|
|
1258
|
+
count: 0,
|
|
1259
|
+
queryTokens: selected.queryTokens,
|
|
1260
|
+
filteredOut: selected.filteredOut,
|
|
1261
|
+
genericRejected: selected.genericRejected,
|
|
1262
|
+
reason: "no_relevant_memories",
|
|
1263
|
+
});
|
|
918
1264
|
return;
|
|
919
1265
|
}
|
|
920
1266
|
|
|
921
|
-
const prependContext = formatRelevantMemories(injected, cfg.debug.maxSnippetChars);
|
|
1267
|
+
const prependContext = formatRelevantMemories(selected.injected, cfg.debug.maxSnippetChars);
|
|
922
1268
|
const scope = resolveScopeFromHookContext(ctx);
|
|
923
1269
|
log.debug("memory_braid.search.inject", {
|
|
924
1270
|
runId,
|
|
925
1271
|
agentId: scope.agentId,
|
|
926
1272
|
sessionKey: scope.sessionKey,
|
|
927
1273
|
workspaceHash: scope.workspaceHash,
|
|
928
|
-
count: injected.length,
|
|
1274
|
+
count: selected.injected.length,
|
|
1275
|
+
queryTokens: selected.queryTokens,
|
|
1276
|
+
filteredOut: selected.filteredOut,
|
|
1277
|
+
genericRejected: selected.genericRejected,
|
|
929
1278
|
injectedTextPreview: prependContext,
|
|
930
1279
|
});
|
|
931
1280
|
|