@devflow-tools/memory-engine 0.16.12 → 0.16.13
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/explicit-memory-enricher.d.ts +24 -0
- package/dist/explicit-memory-enricher.d.ts.map +1 -0
- package/dist/explicit-memory-enricher.js +292 -0
- package/dist/explicit-memory-enricher.js.map +1 -0
- package/dist/hybrid-search.d.ts +23 -0
- package/dist/hybrid-search.d.ts.map +1 -1
- package/dist/hybrid-search.js +97 -24
- package/dist/hybrid-search.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/memory-engine.d.ts +18 -0
- package/dist/memory-engine.d.ts.map +1 -1
- package/dist/memory-engine.js +140 -12
- package/dist/memory-engine.js.map +1 -1
- package/dist/memory-gate.d.ts +17 -0
- package/dist/memory-gate.d.ts.map +1 -1
- package/dist/memory-gate.js +72 -28
- package/dist/memory-gate.js.map +1 -1
- package/dist/memory-relevance.d.ts +38 -0
- package/dist/memory-relevance.d.ts.map +1 -0
- package/dist/memory-relevance.js +289 -0
- package/dist/memory-relevance.js.map +1 -0
- package/dist/memory-store.d.ts +14 -1
- package/dist/memory-store.d.ts.map +1 -1
- package/dist/memory-store.js +114 -18
- package/dist/memory-store.js.map +1 -1
- package/dist/migrations/v2-to-v3.js +1 -1
- package/dist/migrations/v2-to-v3.js.map +1 -1
- package/dist/migrations/v7-to-v8.d.ts +3 -0
- package/dist/migrations/v7-to-v8.d.ts.map +1 -0
- package/dist/migrations/v7-to-v8.js +20 -0
- package/dist/migrations/v7-to-v8.js.map +1 -0
- package/dist/migrations/v8-to-v9.d.ts +3 -0
- package/dist/migrations/v8-to-v9.d.ts.map +1 -0
- package/dist/migrations/v8-to-v9.js +18 -0
- package/dist/migrations/v8-to-v9.js.map +1 -0
- package/package.json +4 -4
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ObservationType } from './observation-types.js';
|
|
2
|
+
export interface ExplicitMemoryEvidenceItem {
|
|
3
|
+
kind: 'dependency' | 'config' | 'instruction' | 'source_event';
|
|
4
|
+
source: string;
|
|
5
|
+
summary: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ExplicitMemoryEvidence {
|
|
8
|
+
type: ObservationType;
|
|
9
|
+
title: string;
|
|
10
|
+
narrative: string;
|
|
11
|
+
facts: string[];
|
|
12
|
+
concepts: string[];
|
|
13
|
+
files: string[];
|
|
14
|
+
tools: string[];
|
|
15
|
+
evidenceStatus: 'verified' | 'unverified';
|
|
16
|
+
evidence: ExplicitMemoryEvidenceItem[];
|
|
17
|
+
}
|
|
18
|
+
export interface EnrichExplicitMemoryInput {
|
|
19
|
+
projectRoot: string;
|
|
20
|
+
content: string;
|
|
21
|
+
sourceEventIds?: string[];
|
|
22
|
+
}
|
|
23
|
+
export declare function enrichExplicitMemory(input: EnrichExplicitMemoryInput): ExplicitMemoryEvidence;
|
|
24
|
+
//# sourceMappingURL=explicit-memory-enricher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explicit-memory-enricher.d.ts","sourceRoot":"","sources":["../src/explicit-memory-enricher.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,YAAY,GAAG,QAAQ,GAAG,aAAa,GAAG,cAAc,CAAC;IAC/D,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,eAAe,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,cAAc,EAAE,UAAU,GAAG,YAAY,CAAC;IAC1C,QAAQ,EAAE,0BAA0B,EAAE,CAAC;CACxC;AAED,MAAM,WAAW,yBAAyB;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAwED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,yBAAyB,GAAG,sBAAsB,CAqC7F"}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import { closeSync, existsSync, openSync, readSync } from 'node:fs';
|
|
2
|
+
import { join, relative } from 'node:path';
|
|
3
|
+
const MAX_PACKAGE_JSON_BYTES = 256 * 1024;
|
|
4
|
+
const MAX_LOCKFILE_BYTES = 512 * 1024;
|
|
5
|
+
const MAX_CONFIG_BYTES = 128 * 1024;
|
|
6
|
+
const MAX_INSTRUCTION_BYTES = 96 * 1024;
|
|
7
|
+
const MAX_CONTENT_LENGTH = 4_000;
|
|
8
|
+
const ENTITIES = [
|
|
9
|
+
{
|
|
10
|
+
canonical: 'motion',
|
|
11
|
+
aliases: ['motion', 'framer motion', 'framer-motion'],
|
|
12
|
+
packages: ['motion', 'framer-motion'],
|
|
13
|
+
concepts: ['motion', 'animation', 'framer-motion'],
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
canonical: 'react',
|
|
17
|
+
aliases: ['react', 'reactjs', 'react.js'],
|
|
18
|
+
packages: ['react'],
|
|
19
|
+
concepts: ['react'],
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
canonical: 'tailwind',
|
|
23
|
+
aliases: ['tailwind', 'tailwind css', 'tailwindcss'],
|
|
24
|
+
packages: ['tailwindcss'],
|
|
25
|
+
concepts: ['tailwind', 'tailwindcss', 'css'],
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
canonical: 'shadcn',
|
|
29
|
+
aliases: ['shadcn', 'shadcn ui', 'shadcn/ui'],
|
|
30
|
+
packages: ['shadcn'],
|
|
31
|
+
concepts: ['shadcn', 'ui-components'],
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
canonical: 'pnpm',
|
|
35
|
+
aliases: ['pnpm'],
|
|
36
|
+
concepts: ['pnpm', 'package-manager'],
|
|
37
|
+
tool: 'pnpm',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
canonical: 'npm',
|
|
41
|
+
aliases: ['npm'],
|
|
42
|
+
concepts: ['npm', 'package-manager'],
|
|
43
|
+
tool: 'npm',
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
canonical: 'yarn',
|
|
47
|
+
aliases: ['yarn'],
|
|
48
|
+
concepts: ['yarn', 'package-manager'],
|
|
49
|
+
tool: 'yarn',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
canonical: 'bun',
|
|
53
|
+
aliases: ['bun'],
|
|
54
|
+
concepts: ['bun', 'package-manager'],
|
|
55
|
+
tool: 'bun',
|
|
56
|
+
},
|
|
57
|
+
];
|
|
58
|
+
const PROJECT_SCOPE = /(?:\bproject\b|\brepository\b|\bcodebase\b|\bteam\b|项目|仓库|代码库|团队|全局|统一|一律)/iu;
|
|
59
|
+
const PERSONAL_PREFERENCE = /(?:\bi\s+(?:prefer|like|want)\b|\bmy preference\b|我(?:更)?(?:喜欢|偏好|希望))/iu;
|
|
60
|
+
const DECISION = /(?:\bdecid(?:e|ed)\b|\bchosen?\b|决定|选定|已选)/iu;
|
|
61
|
+
const CONVENTION = /(?:\b(?:always|never|must|should|required?|standard(?:ize|ized)?)\b|\b(?:do not|don't)\s+use\b|\buse\s+[^\s]+|统一|一律|必须|需要|默认|规范|约定|不要|不使用|使用)/iu;
|
|
62
|
+
export function enrichExplicitMemory(input) {
|
|
63
|
+
const narrative = input.content.normalize('NFKC').trim().slice(0, MAX_CONTENT_LENGTH);
|
|
64
|
+
if (!narrative)
|
|
65
|
+
throw new Error('Explicit memory content must be nonblank');
|
|
66
|
+
const matchedEntities = ENTITIES.filter(entity => containsAlias(narrative, entity.aliases));
|
|
67
|
+
const type = classifyExplicitMemory(narrative);
|
|
68
|
+
const projectEvidence = collectProjectEvidence(input.projectRoot, matchedEntities);
|
|
69
|
+
const sourceEvidence = uniqueStrings(input.sourceEventIds ?? []).map(source => ({
|
|
70
|
+
kind: 'source_event',
|
|
71
|
+
source,
|
|
72
|
+
summary: 'Explicit user memory request captured from the canonical session event.',
|
|
73
|
+
}));
|
|
74
|
+
const evidence = dedupeEvidence([...projectEvidence.evidence, ...sourceEvidence]);
|
|
75
|
+
const concepts = uniqueStrings(matchedEntities.flatMap(entity => entity.concepts));
|
|
76
|
+
const tools = uniqueStrings(matchedEntities.flatMap(entity => entity.tool ? [entity.tool] : []));
|
|
77
|
+
const entitySummary = matchedEntities.map(entity => entity.canonical).join(', ');
|
|
78
|
+
const titlePrefix = type === 'project_convention'
|
|
79
|
+
? 'Project convention'
|
|
80
|
+
: type === 'decision_made'
|
|
81
|
+
? 'Project decision'
|
|
82
|
+
: 'User preference';
|
|
83
|
+
const titleSubject = entitySummary || firstClause(narrative);
|
|
84
|
+
return {
|
|
85
|
+
type,
|
|
86
|
+
title: `${titlePrefix}: ${titleSubject}`.slice(0, 160),
|
|
87
|
+
narrative,
|
|
88
|
+
facts: uniqueStrings([
|
|
89
|
+
narrative,
|
|
90
|
+
...matchedEntities.map(entity => `Referenced entity: ${entity.canonical}`),
|
|
91
|
+
]),
|
|
92
|
+
concepts,
|
|
93
|
+
files: uniqueStrings(projectEvidence.files),
|
|
94
|
+
tools,
|
|
95
|
+
evidenceStatus: projectEvidence.evidence.length > 0 ? 'verified' : 'unverified',
|
|
96
|
+
evidence,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function classifyExplicitMemory(content) {
|
|
100
|
+
if (PROJECT_SCOPE.test(content) && (CONVENTION.test(content) || DECISION.test(content))) {
|
|
101
|
+
return 'project_convention';
|
|
102
|
+
}
|
|
103
|
+
if (PERSONAL_PREFERENCE.test(content))
|
|
104
|
+
return 'user_preference';
|
|
105
|
+
if (DECISION.test(content))
|
|
106
|
+
return 'decision_made';
|
|
107
|
+
if (CONVENTION.test(content))
|
|
108
|
+
return 'project_convention';
|
|
109
|
+
return 'user_preference';
|
|
110
|
+
}
|
|
111
|
+
function collectProjectEvidence(projectRoot, entities) {
|
|
112
|
+
if (entities.length === 0)
|
|
113
|
+
return { evidence: [], files: [] };
|
|
114
|
+
const evidence = [];
|
|
115
|
+
const files = [];
|
|
116
|
+
const packagePath = join(projectRoot, 'package.json');
|
|
117
|
+
const packageText = readBoundedText(packagePath, MAX_PACKAGE_JSON_BYTES);
|
|
118
|
+
if (packageText !== null) {
|
|
119
|
+
const dependencyVersions = parseDependencyVersions(packageText);
|
|
120
|
+
const packageManager = parsePackageManager(packageText);
|
|
121
|
+
for (const entity of entities) {
|
|
122
|
+
for (const packageName of entity.packages ?? []) {
|
|
123
|
+
const version = dependencyVersions.get(packageName);
|
|
124
|
+
if (!version)
|
|
125
|
+
continue;
|
|
126
|
+
addEvidence(evidence, files, projectRoot, packagePath, {
|
|
127
|
+
kind: 'dependency',
|
|
128
|
+
source: 'package.json',
|
|
129
|
+
summary: `${packageName} is declared at ${version}.`,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
if (entity.tool && packageManager?.name === entity.tool) {
|
|
133
|
+
addEvidence(evidence, files, projectRoot, packagePath, {
|
|
134
|
+
kind: 'config',
|
|
135
|
+
source: 'package.json',
|
|
136
|
+
summary: `packageManager selects ${packageManager.raw}.`,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
const lockfiles = [
|
|
142
|
+
{ name: 'package-lock.json', tool: 'npm' },
|
|
143
|
+
{ name: 'pnpm-lock.yaml', tool: 'pnpm' },
|
|
144
|
+
{ name: 'yarn.lock', tool: 'yarn' },
|
|
145
|
+
{ name: 'bun.lock', tool: 'bun' },
|
|
146
|
+
{ name: 'bun.lockb', tool: 'bun' },
|
|
147
|
+
];
|
|
148
|
+
for (const lockfile of lockfiles) {
|
|
149
|
+
const path = join(projectRoot, lockfile.name);
|
|
150
|
+
const text = readBoundedText(path, MAX_LOCKFILE_BYTES);
|
|
151
|
+
if (text === null)
|
|
152
|
+
continue;
|
|
153
|
+
for (const entity of entities) {
|
|
154
|
+
const packageMatch = (entity.packages ?? []).find(packageName => lockfileContainsPackage(text, packageName));
|
|
155
|
+
if (packageMatch) {
|
|
156
|
+
addEvidence(evidence, files, projectRoot, path, {
|
|
157
|
+
kind: 'dependency',
|
|
158
|
+
source: lockfile.name,
|
|
159
|
+
summary: `${packageMatch} is resolved by ${lockfile.name}.`,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
if (entity.tool === lockfile.tool) {
|
|
163
|
+
addEvidence(evidence, files, projectRoot, path, {
|
|
164
|
+
kind: 'config',
|
|
165
|
+
source: lockfile.name,
|
|
166
|
+
summary: `${lockfile.name} confirms the ${lockfile.tool} package-manager workflow.`,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
const configFiles = ['.devflow/config.json', 'components.json'];
|
|
172
|
+
for (const name of configFiles) {
|
|
173
|
+
collectTextEvidence(projectRoot, name, MAX_CONFIG_BYTES, 'config', entities, evidence, files);
|
|
174
|
+
}
|
|
175
|
+
const instructionFiles = ['CLAUDE.md', 'AGENTS.md', 'GEMINI.md', '.github/copilot-instructions.md'];
|
|
176
|
+
for (const name of instructionFiles) {
|
|
177
|
+
collectTextEvidence(projectRoot, name, MAX_INSTRUCTION_BYTES, 'instruction', entities, evidence, files);
|
|
178
|
+
}
|
|
179
|
+
return { evidence: dedupeEvidence(evidence), files: uniqueStrings(files) };
|
|
180
|
+
}
|
|
181
|
+
function collectTextEvidence(projectRoot, name, maxBytes, kind, entities, evidence, files) {
|
|
182
|
+
const path = join(projectRoot, name);
|
|
183
|
+
const text = readBoundedText(path, maxBytes);
|
|
184
|
+
if (text === null)
|
|
185
|
+
return;
|
|
186
|
+
for (const entity of entities) {
|
|
187
|
+
if (!containsAlias(text, entity.aliases))
|
|
188
|
+
continue;
|
|
189
|
+
addEvidence(evidence, files, projectRoot, path, {
|
|
190
|
+
kind,
|
|
191
|
+
source: name,
|
|
192
|
+
summary: `${name} references ${entity.canonical}.`,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
function addEvidence(evidence, files, projectRoot, path, item) {
|
|
197
|
+
evidence.push(item);
|
|
198
|
+
files.push(relative(projectRoot, path) || item.source);
|
|
199
|
+
}
|
|
200
|
+
function parseDependencyVersions(text) {
|
|
201
|
+
try {
|
|
202
|
+
const parsed = JSON.parse(text);
|
|
203
|
+
const result = new Map();
|
|
204
|
+
for (const field of ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies']) {
|
|
205
|
+
const dependencies = parsed[field];
|
|
206
|
+
if (!dependencies || typeof dependencies !== 'object' || Array.isArray(dependencies))
|
|
207
|
+
continue;
|
|
208
|
+
for (const [name, version] of Object.entries(dependencies)) {
|
|
209
|
+
if (typeof version === 'string')
|
|
210
|
+
result.set(name, version);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return result;
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
return new Map();
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
function parsePackageManager(text) {
|
|
220
|
+
try {
|
|
221
|
+
const parsed = JSON.parse(text);
|
|
222
|
+
if (typeof parsed.packageManager !== 'string')
|
|
223
|
+
return null;
|
|
224
|
+
const raw = parsed.packageManager.trim();
|
|
225
|
+
const name = raw.split('@')[0]?.toLowerCase();
|
|
226
|
+
return name ? { name, raw } : null;
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
function lockfileContainsPackage(text, packageName) {
|
|
233
|
+
const escaped = escapeRegExp(packageName);
|
|
234
|
+
return new RegExp(`(?:node_modules/|[/'\"\\s])${escaped}(?:@|[/'\"\\s:])`, 'iu').test(text);
|
|
235
|
+
}
|
|
236
|
+
function containsAlias(text, aliases) {
|
|
237
|
+
const normalized = text.normalize('NFKC').toLocaleLowerCase('en-US');
|
|
238
|
+
return aliases.some(alias => {
|
|
239
|
+
const escaped = escapeRegExp(alias.toLocaleLowerCase('en-US')).replace(/\\[\s/.-]/g, '[\\s/.-]+');
|
|
240
|
+
// ASCII technology names often touch CJK text directly, as in
|
|
241
|
+
// "使用motion作为". Only adjacent ASCII identifier characters block a match.
|
|
242
|
+
return new RegExp(`(^|[^a-z0-9_])${escaped}(?=$|[^a-z0-9_])`, 'u').test(normalized);
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
function readBoundedText(path, maxBytes) {
|
|
246
|
+
if (!existsSync(path))
|
|
247
|
+
return null;
|
|
248
|
+
let descriptor;
|
|
249
|
+
try {
|
|
250
|
+
descriptor = openSync(path, 'r');
|
|
251
|
+
const buffer = Buffer.allocUnsafe(maxBytes);
|
|
252
|
+
const bytesRead = readSync(descriptor, buffer, 0, maxBytes, 0);
|
|
253
|
+
return buffer.subarray(0, bytesRead).toString('utf8');
|
|
254
|
+
}
|
|
255
|
+
catch {
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
finally {
|
|
259
|
+
if (descriptor !== undefined)
|
|
260
|
+
closeSync(descriptor);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
function firstClause(value) {
|
|
264
|
+
return value.split(/[.。!!??\n]/u)[0].trim().slice(0, 120) || 'explicit memory';
|
|
265
|
+
}
|
|
266
|
+
function dedupeEvidence(items) {
|
|
267
|
+
const seen = new Set();
|
|
268
|
+
return items.filter(item => {
|
|
269
|
+
const key = `${item.kind}\0${item.source}\0${item.summary}`;
|
|
270
|
+
if (seen.has(key))
|
|
271
|
+
return false;
|
|
272
|
+
seen.add(key);
|
|
273
|
+
return true;
|
|
274
|
+
}).slice(0, 32);
|
|
275
|
+
}
|
|
276
|
+
function uniqueStrings(values) {
|
|
277
|
+
const seen = new Set();
|
|
278
|
+
const result = [];
|
|
279
|
+
for (const value of values) {
|
|
280
|
+
const normalized = value.normalize('NFKC').trim();
|
|
281
|
+
const key = normalized.toLocaleLowerCase('en-US');
|
|
282
|
+
if (!normalized || seen.has(key))
|
|
283
|
+
continue;
|
|
284
|
+
seen.add(key);
|
|
285
|
+
result.push(normalized);
|
|
286
|
+
}
|
|
287
|
+
return result.slice(0, 32);
|
|
288
|
+
}
|
|
289
|
+
function escapeRegExp(value) {
|
|
290
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
291
|
+
}
|
|
292
|
+
//# sourceMappingURL=explicit-memory-enricher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explicit-memory-enricher.js","sourceRoot":"","sources":["../src/explicit-memory-enricher.ts"],"names":[],"mappings":"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"}
|
package/dist/hybrid-search.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ export interface SearchOptions {
|
|
|
11
11
|
sessionId?: string;
|
|
12
12
|
maxPerFailureCategory?: number;
|
|
13
13
|
excludedIds?: ReadonlySet<string>;
|
|
14
|
+
requestId?: string;
|
|
15
|
+
executionId?: string;
|
|
14
16
|
}
|
|
15
17
|
export interface SearchResultEntry {
|
|
16
18
|
id: string;
|
|
@@ -31,10 +33,30 @@ export interface SearchResultEntry {
|
|
|
31
33
|
resolutionState: 'current' | 'resolved' | 'superseded';
|
|
32
34
|
failureCategory: FailureCategory | null;
|
|
33
35
|
clusterKey: string;
|
|
36
|
+
concepts: string[];
|
|
37
|
+
evidenceStatus: 'verified' | 'unverified';
|
|
34
38
|
}
|
|
35
39
|
export interface SearchResult {
|
|
36
40
|
entry: SearchResultEntry;
|
|
37
41
|
score: number;
|
|
42
|
+
applicability?: string[];
|
|
43
|
+
relevanceSignals?: {
|
|
44
|
+
semantic: number;
|
|
45
|
+
entityOverlap: number;
|
|
46
|
+
evidenceStrength: number;
|
|
47
|
+
taskApplicability: number;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export interface SearchDiagnostics {
|
|
51
|
+
threshold: number;
|
|
52
|
+
candidateCount: number;
|
|
53
|
+
selectedCount: number;
|
|
54
|
+
rejectedCount: number;
|
|
55
|
+
rejectionCategories: Record<string, number>;
|
|
56
|
+
}
|
|
57
|
+
export interface SearchWithDiagnosticsResult {
|
|
58
|
+
results: SearchResult[];
|
|
59
|
+
diagnostics: SearchDiagnostics;
|
|
38
60
|
}
|
|
39
61
|
export declare function rrfFusion(results: Map<string, {
|
|
40
62
|
ranks: Map<string, number>;
|
|
@@ -49,5 +71,6 @@ export declare class HybridSearch {
|
|
|
49
71
|
private engine;
|
|
50
72
|
constructor(store: MemoryStore, embedder: EmbeddingProvider, engine?: MemoryEngine);
|
|
51
73
|
search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
|
|
74
|
+
searchWithDiagnostics(query: string, options?: SearchOptions): Promise<SearchWithDiagnosticsResult>;
|
|
52
75
|
}
|
|
53
76
|
//# sourceMappingURL=hybrid-search.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hybrid-search.d.ts","sourceRoot":"","sources":["../src/hybrid-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"hybrid-search.d.ts","sourceRoot":"","sources":["../src/hybrid-search.ts"],"names":[],"mappings":"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"}
|
package/dist/hybrid-search.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { classifyFailureCategory, observationClusterKey, } from './observation-quality.js';
|
|
2
|
+
import { evaluateMemoryRelevance, MEMORY_SELECTION_THRESHOLD, } from './memory-relevance.js';
|
|
2
3
|
const DEFAULT_WEIGHTS = {
|
|
3
4
|
bm25: 0.25,
|
|
4
5
|
observationBm25: 0.2,
|
|
@@ -53,10 +54,12 @@ function rowToEntry(row) {
|
|
|
53
54
|
title: row.title,
|
|
54
55
|
narrative: row.content,
|
|
55
56
|
}),
|
|
57
|
+
concepts: [],
|
|
58
|
+
evidenceStatus: row.source === 'manual' ? 'verified' : 'unverified',
|
|
56
59
|
};
|
|
57
60
|
}
|
|
58
61
|
function observationToEntry(row) {
|
|
59
|
-
const createdAt = row.source === 'explicit_intent'
|
|
62
|
+
const createdAt = row.source === 'explicit_intent'
|
|
60
63
|
? row.explicit_accepted_at ?? row.timestamp
|
|
61
64
|
: row.timestamp;
|
|
62
65
|
return {
|
|
@@ -83,6 +86,8 @@ function observationToEntry(row) {
|
|
|
83
86
|
narrative: row.narrative,
|
|
84
87
|
facts: parseStringArray(row.facts),
|
|
85
88
|
}),
|
|
89
|
+
concepts: parseStringArray(row.concepts),
|
|
90
|
+
evidenceStatus: row.evidence_status,
|
|
86
91
|
};
|
|
87
92
|
}
|
|
88
93
|
const MIN_EFFECTIVE_CONFIDENCE = 0.3;
|
|
@@ -96,10 +101,22 @@ export class HybridSearch {
|
|
|
96
101
|
this.engine = engine ?? null;
|
|
97
102
|
}
|
|
98
103
|
async search(query, options = {}) {
|
|
104
|
+
return (await this.searchWithDiagnostics(query, options)).results;
|
|
105
|
+
}
|
|
106
|
+
async searchWithDiagnostics(query, options = {}) {
|
|
99
107
|
const requestedLimit = options.limit ?? 10;
|
|
100
108
|
const limit = Number.isFinite(requestedLimit) ? Math.max(0, Math.floor(requestedLimit)) : 10;
|
|
101
109
|
if (limit === 0)
|
|
102
|
-
return
|
|
110
|
+
return {
|
|
111
|
+
results: [],
|
|
112
|
+
diagnostics: {
|
|
113
|
+
threshold: MEMORY_SELECTION_THRESHOLD,
|
|
114
|
+
candidateCount: 0,
|
|
115
|
+
selectedCount: 0,
|
|
116
|
+
rejectedCount: 0,
|
|
117
|
+
rejectionCategories: {},
|
|
118
|
+
},
|
|
119
|
+
};
|
|
103
120
|
const exclusionAllowance = options.excludedIds?.size ?? 0;
|
|
104
121
|
const fetchLimit = limit * 3 + exclusionAllowance;
|
|
105
122
|
let bm25Results = [];
|
|
@@ -114,10 +131,17 @@ export class HybridSearch {
|
|
|
114
131
|
catch { /* Observation lexical retrieval is independently non-fatal */ }
|
|
115
132
|
let vectorResults = [];
|
|
116
133
|
let observationResults = [];
|
|
134
|
+
const semanticScores = new Map();
|
|
117
135
|
try {
|
|
118
136
|
const embedding = await this.embedder.embed(query);
|
|
119
137
|
vectorResults = this.store.searchVector(embedding, fetchLimit);
|
|
120
138
|
observationResults = this.store.searchObservationVector(embedding, fetchLimit, options.excludedIds);
|
|
139
|
+
for (const result of vectorResults) {
|
|
140
|
+
semanticScores.set(result.id, cosineSimilarityFromDistance(result.distance));
|
|
141
|
+
}
|
|
142
|
+
for (const result of observationResults) {
|
|
143
|
+
semanticScores.set(result.observation.id, cosineSimilarityFromDistance(result.distance));
|
|
144
|
+
}
|
|
121
145
|
}
|
|
122
146
|
catch { /* embedding may fail */ }
|
|
123
147
|
const graphIds = new Set();
|
|
@@ -207,30 +231,53 @@ export class HybridSearch {
|
|
|
207
231
|
continue;
|
|
208
232
|
newestResolutionByCategory.set(entry.failureCategory, Math.max(newestResolutionByCategory.get(entry.failureCategory) ?? 0, entry.createdAt));
|
|
209
233
|
}
|
|
210
|
-
const
|
|
234
|
+
const rejected = new Map();
|
|
211
235
|
const ranked = fused.map(result => {
|
|
212
236
|
const entry = docs.get(result.id).entry;
|
|
213
|
-
const ageDays = Math.max(0, now - entry.createdAt) / 86_400_000;
|
|
214
|
-
const recency = Math.exp(-ageDays / 180);
|
|
215
|
-
const accessFeedback = Math.min(1, Math.log1p(entry.accessCount) / Math.log(11));
|
|
216
|
-
const projectMatch = options.scope ? (entry.scope === options.scope ? 1 : 0) : 0.5;
|
|
217
|
-
const evidenceScore = 0.28 * entry.confidence
|
|
218
|
-
+ 0.22 * entry.strength
|
|
219
|
-
+ 0.2 * recency
|
|
220
|
-
+ 0.15 * projectMatch
|
|
221
|
-
+ 0.15 * accessFeedback;
|
|
222
|
-
let score = 0.55 * result.score + 0.45 * evidenceScore;
|
|
223
|
-
if (entry.resolutionState === 'resolved')
|
|
224
|
-
score *= 0.85;
|
|
225
|
-
if (entry.resolutionState === 'superseded')
|
|
226
|
-
score *= 0.1;
|
|
227
237
|
const newerResolution = entry.failureCategory
|
|
228
238
|
? newestResolutionByCategory.get(entry.failureCategory)
|
|
229
239
|
: undefined;
|
|
230
|
-
|
|
231
|
-
|
|
240
|
+
const failureCategory = entry.type !== 'error_resolution'
|
|
241
|
+
&& newerResolution
|
|
242
|
+
&& newerResolution > entry.createdAt
|
|
243
|
+
? entry.failureCategory
|
|
244
|
+
: entry.failureCategory;
|
|
245
|
+
const evaluation = evaluateMemoryRelevance({
|
|
246
|
+
query,
|
|
247
|
+
purpose: options.purpose,
|
|
248
|
+
type: entry.type,
|
|
249
|
+
source: entry.source === 'observation' ? this.store.getObservation(entry.id)?.source ?? 'distill' : entry.source,
|
|
250
|
+
title: entry.title,
|
|
251
|
+
content: entry.content,
|
|
252
|
+
concepts: entry.concepts,
|
|
253
|
+
evidenceStatus: entry.evidenceStatus,
|
|
254
|
+
confidence: entry.confidence,
|
|
255
|
+
importance: entry.strength * 10,
|
|
256
|
+
createdAt: entry.createdAt,
|
|
257
|
+
semanticScore: semanticScores.get(entry.id) ?? 0,
|
|
258
|
+
resolutionState: entry.resolutionState,
|
|
259
|
+
failureCategory,
|
|
260
|
+
});
|
|
261
|
+
if (!evaluation.eligible && evaluation.rejectionReason) {
|
|
262
|
+
rejected.set(evaluation.rejectionReason, (rejected.get(evaluation.rejectionReason) ?? 0) + 1);
|
|
263
|
+
if (options.requestId) {
|
|
264
|
+
try {
|
|
265
|
+
this.store.recordRetrievalAccess({
|
|
266
|
+
sourceType: entry.source === 'observation' ? 'observation' : 'memory',
|
|
267
|
+
sourceId: entry.id,
|
|
268
|
+
accessType: 'rejected',
|
|
269
|
+
sessionId: options.sessionId,
|
|
270
|
+
requestId: options.requestId,
|
|
271
|
+
executionId: options.executionId,
|
|
272
|
+
query,
|
|
273
|
+
purpose: `${options.purpose ?? 'search'}:${evaluation.rejectionReason}`,
|
|
274
|
+
score: 0,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
catch { /* rejection telemetry is non-critical */ }
|
|
278
|
+
}
|
|
232
279
|
}
|
|
233
|
-
return { ...result, score };
|
|
280
|
+
return { ...result, score: evaluation.score, evaluation };
|
|
234
281
|
}).sort((left, right) => right.score - left.score
|
|
235
282
|
|| docs.get(right.id).entry.createdAt - docs.get(left.id).entry.createdAt
|
|
236
283
|
|| left.id.localeCompare(right.id));
|
|
@@ -239,7 +286,9 @@ export class HybridSearch {
|
|
|
239
286
|
const sessionCounts = new Map();
|
|
240
287
|
const failureCategoryCounts = new Map();
|
|
241
288
|
const maxPerFailureCategory = Math.max(1, options.maxPerFailureCategory ?? 2);
|
|
242
|
-
for (const { id, score } of ranked) {
|
|
289
|
+
for (const { id, score, evaluation } of ranked) {
|
|
290
|
+
if (!evaluation.eligible)
|
|
291
|
+
continue;
|
|
243
292
|
if (options.excludedIds?.has(id))
|
|
244
293
|
continue;
|
|
245
294
|
const doc = docs.get(id);
|
|
@@ -280,18 +329,30 @@ export class HybridSearch {
|
|
|
280
329
|
sessionCounts.set(doc.entry.sessionId, (sessionCounts.get(doc.entry.sessionId) ?? 0) + 1);
|
|
281
330
|
}
|
|
282
331
|
const roundedScore = Math.round(score * 10000) / 10000;
|
|
283
|
-
results.push({
|
|
332
|
+
results.push({
|
|
333
|
+
entry: doc.entry,
|
|
334
|
+
score: roundedScore,
|
|
335
|
+
applicability: evaluation.applicability,
|
|
336
|
+
relevanceSignals: {
|
|
337
|
+
semantic: evaluation.signals.semantic,
|
|
338
|
+
entityOverlap: evaluation.signals.entityOverlap,
|
|
339
|
+
evidenceStrength: evaluation.signals.evidenceStrength,
|
|
340
|
+
taskApplicability: evaluation.signals.taskApplicability,
|
|
341
|
+
},
|
|
342
|
+
});
|
|
284
343
|
if (options.recordAccess !== false) {
|
|
285
344
|
try {
|
|
286
345
|
this.store.recordRetrievalAccess({
|
|
287
346
|
sourceType: doc.entry.source === 'observation' ? 'observation' : 'memory',
|
|
288
347
|
sourceId: doc.entry.id,
|
|
289
|
-
accessType: '
|
|
348
|
+
accessType: 'exposed',
|
|
290
349
|
sessionId: options.sessionId,
|
|
291
350
|
query,
|
|
292
351
|
purpose: options.purpose ?? 'search',
|
|
293
352
|
rank: results.length,
|
|
294
353
|
score: roundedScore,
|
|
354
|
+
requestId: options.requestId,
|
|
355
|
+
executionId: options.executionId,
|
|
295
356
|
});
|
|
296
357
|
}
|
|
297
358
|
catch { /* non-critical */ }
|
|
@@ -299,9 +360,21 @@ export class HybridSearch {
|
|
|
299
360
|
if (results.length >= limit)
|
|
300
361
|
break;
|
|
301
362
|
}
|
|
302
|
-
return
|
|
363
|
+
return {
|
|
364
|
+
results,
|
|
365
|
+
diagnostics: {
|
|
366
|
+
threshold: MEMORY_SELECTION_THRESHOLD,
|
|
367
|
+
candidateCount: docs.size,
|
|
368
|
+
selectedCount: results.length,
|
|
369
|
+
rejectedCount: Math.max(0, docs.size - results.length),
|
|
370
|
+
rejectionCategories: Object.fromEntries(rejected),
|
|
371
|
+
},
|
|
372
|
+
};
|
|
303
373
|
}
|
|
304
374
|
}
|
|
375
|
+
function cosineSimilarityFromDistance(distance) {
|
|
376
|
+
return Math.max(0, Math.min(1, 1 - distance));
|
|
377
|
+
}
|
|
305
378
|
function parseStringArray(value) {
|
|
306
379
|
try {
|
|
307
380
|
const parsed = JSON.parse(value);
|