@devflow-tools/memory-engine 0.16.10 → 0.16.12

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.
Files changed (55) hide show
  1. package/dist/embedding-model-store.d.ts +67 -0
  2. package/dist/embedding-model-store.d.ts.map +1 -0
  3. package/dist/embedding-model-store.js +350 -0
  4. package/dist/embedding-model-store.js.map +1 -0
  5. package/dist/embedding-provider.d.ts +8 -0
  6. package/dist/embedding-provider.d.ts.map +1 -1
  7. package/dist/embedding-provider.js +68 -11
  8. package/dist/embedding-provider.js.map +1 -1
  9. package/dist/hybrid-search.d.ts +8 -0
  10. package/dist/hybrid-search.d.ts.map +1 -1
  11. package/dist/hybrid-search.js +37 -10
  12. package/dist/hybrid-search.js.map +1 -1
  13. package/dist/index.d.ts +5 -3
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +3 -2
  16. package/dist/index.js.map +1 -1
  17. package/dist/memory-engine.d.ts +4 -0
  18. package/dist/memory-engine.d.ts.map +1 -1
  19. package/dist/memory-engine.js +62 -39
  20. package/dist/memory-engine.js.map +1 -1
  21. package/dist/memory-gate.d.ts +3 -1
  22. package/dist/memory-gate.d.ts.map +1 -1
  23. package/dist/memory-gate.js +22 -40
  24. package/dist/memory-gate.js.map +1 -1
  25. package/dist/memory-maintenance.d.ts.map +1 -1
  26. package/dist/memory-maintenance.js +4 -2
  27. package/dist/memory-maintenance.js.map +1 -1
  28. package/dist/memory-store.d.ts +38 -1
  29. package/dist/memory-store.d.ts.map +1 -1
  30. package/dist/memory-store.js +488 -5
  31. package/dist/memory-store.js.map +1 -1
  32. package/dist/migrations/v3-to-v4.d.ts.map +1 -1
  33. package/dist/migrations/v3-to-v4.js +4 -0
  34. package/dist/migrations/v3-to-v4.js.map +1 -1
  35. package/dist/migrations/v6-to-v7.d.ts +3 -0
  36. package/dist/migrations/v6-to-v7.d.ts.map +1 -0
  37. package/dist/migrations/v6-to-v7.js +18 -0
  38. package/dist/migrations/v6-to-v7.js.map +1 -0
  39. package/dist/migrations/v6-to-v7.test.d.ts +2 -0
  40. package/dist/migrations/v6-to-v7.test.d.ts.map +1 -0
  41. package/dist/migrations/v6-to-v7.test.js +33 -0
  42. package/dist/migrations/v6-to-v7.test.js.map +1 -0
  43. package/dist/observation-types.d.ts +2 -0
  44. package/dist/observation-types.d.ts.map +1 -1
  45. package/dist/observation-types.js +13 -0
  46. package/dist/observation-types.js.map +1 -1
  47. package/dist/preference-conflicts.d.ts +19 -0
  48. package/dist/preference-conflicts.d.ts.map +1 -0
  49. package/dist/preference-conflicts.js +293 -0
  50. package/dist/preference-conflicts.js.map +1 -0
  51. package/dist/preference-conflicts.test.d.ts +2 -0
  52. package/dist/preference-conflicts.test.d.ts.map +1 -0
  53. package/dist/preference-conflicts.test.js +72 -0
  54. package/dist/preference-conflicts.test.js.map +1 -0
  55. package/package.json +4 -4
@@ -0,0 +1,293 @@
1
+ import { createHash } from 'node:crypto';
2
+ const EXCLUSIVE_FAMILIES = [
3
+ { family: 'package_manager', entity: 'package manager', values: ['npm', 'pnpm', 'yarn', 'bun'] },
4
+ { family: 'test_runner', entity: 'test runner', values: ['vitest', 'jest', 'mocha'] },
5
+ { family: 'build_tool', entity: 'build tool', values: ['vite', 'webpack', 'rspack', 'rsbuild', 'esbuild', 'rollup'] },
6
+ ];
7
+ const VERSIONED_ENTITIES = [
8
+ { family: 'react', aliases: ['react'] },
9
+ { family: 'vue', aliases: ['vue', 'vue.js'] },
10
+ { family: 'angular', aliases: ['angular'] },
11
+ { family: 'node', aliases: ['node', 'node.js', 'nodejs'] },
12
+ { family: 'typescript', aliases: ['typescript'] },
13
+ ];
14
+ export const MAX_PREFERENCE_ANALYSIS_CODE_POINTS = 4_096;
15
+ export const MAX_EXPLICIT_PREFERENCE_CODE_POINTS = 4_000;
16
+ const INTENT_MARKER = /(?<negative>\b(?:do\s+not|don't|dont|never)\s+(?:use|prefer|choose|adopt|run)\b|\bavoid\s+(?:using\s+)?|(?:不要再|不要|不再|不|避免)(?:使用|采用|选择|运行|优先使用))|(?<positiveRun>\brun\b)|(?<positive>\b(?:use|prefer|choose|adopt|standardize\s+on)\b|(?:统一|默认|优先)?(?:使用|采用|选择|运行))/giu;
17
+ const SPAN_TERMINATORS = new Set([',', ';', '!', '?', '\n', '。', ',', ';', '!', '?']);
18
+ const IDENTIFIER_CHARACTERS = '\\p{L}\\p{N}_-';
19
+ const GENERIC_RESIDUAL_CONNECTOR = /^\s*(?:(?:with|and|plus)\s+|(?:和|并且|以及)\s*)(.+?)\s*$/iu;
20
+ function takeCodePoints(value, limit) {
21
+ const result = [];
22
+ let count = 0;
23
+ for (const codePoint of value) {
24
+ if (count >= limit)
25
+ break;
26
+ result.push(codePoint);
27
+ count += 1;
28
+ }
29
+ return result.join('');
30
+ }
31
+ function normalizeBoundedText(text, limit) {
32
+ const boundedInput = takeCodePoints(text, MAX_PREFERENCE_ANALYSIS_CODE_POINTS);
33
+ const normalized = boundedInput
34
+ .normalize('NFKC')
35
+ .replace(/\r\n?/gu, '\n')
36
+ .replace(/[^\S\n]+/gu, ' ')
37
+ .trim();
38
+ return takeCodePoints(normalized, limit);
39
+ }
40
+ function normalizedText(text) {
41
+ return normalizeBoundedText(text, MAX_PREFERENCE_ANALYSIS_CODE_POINTS)
42
+ .toLocaleLowerCase('en-US');
43
+ }
44
+ export function normalizeExplicitPreferenceContent(content) {
45
+ if (typeof content !== 'string')
46
+ return '';
47
+ return normalizeBoundedText(content, MAX_EXPLICIT_PREFERENCE_CODE_POINTS);
48
+ }
49
+ function escapeRegExp(value) {
50
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
51
+ }
52
+ function isSpanTerminator(text, index) {
53
+ const character = text[index];
54
+ if (character === '.') {
55
+ const next = text[index + 1];
56
+ return next === undefined || /\s/u.test(next);
57
+ }
58
+ return SPAN_TERMINATORS.has(character);
59
+ }
60
+ function extractIntentSpans(text) {
61
+ const markers = [];
62
+ let sentenceStart = 0;
63
+ let boundaryCursor = 0;
64
+ for (const match of text.matchAll(INTENT_MARKER)) {
65
+ const start = match.index ?? 0;
66
+ for (let cursor = boundaryCursor; cursor < start; cursor += 1) {
67
+ if (isSpanTerminator(text, cursor))
68
+ sentenceStart = cursor + 1;
69
+ }
70
+ boundaryCursor = start + match[0].length;
71
+ const positiveRun = match.groups?.positiveRun !== undefined;
72
+ if (positiveRun) {
73
+ const prefix = text.slice(sentenceStart, start).trim();
74
+ if (prefix !== '' && prefix !== 'always')
75
+ continue;
76
+ }
77
+ const englishRunMarker = positiveRun || /\brun\s*$/iu.test(match[0]);
78
+ markers.push({
79
+ start,
80
+ end: start + match[0].length,
81
+ polarity: match.groups?.negative ? 'negative' : 'positive',
82
+ allowGeneric: !englishRunMarker,
83
+ });
84
+ }
85
+ const spans = [];
86
+ for (let index = 0; index < markers.length; index += 1) {
87
+ const marker = markers[index];
88
+ const nextMarkerStart = markers[index + 1]?.start ?? text.length;
89
+ let end = nextMarkerStart;
90
+ for (let cursor = marker.end; cursor < nextMarkerStart; cursor += 1) {
91
+ if (isSpanTerminator(text, cursor)) {
92
+ end = cursor;
93
+ break;
94
+ }
95
+ }
96
+ const body = text.slice(marker.end, end).trim();
97
+ if (body)
98
+ spans.push({
99
+ polarity: marker.polarity,
100
+ body,
101
+ allowGeneric: marker.allowGeneric,
102
+ });
103
+ }
104
+ return spans;
105
+ }
106
+ function classifyFamilyFacets(kind, family, entity, occurrences) {
107
+ const positives = new Set(occurrences.filter(item => item.polarity === 'positive').map(item => item.value));
108
+ const negatives = new Set(occurrences.filter(item => item.polarity === 'negative').map(item => item.value));
109
+ const ambiguous = positives.size > 1
110
+ || (positives.size === 1 && negatives.has([...positives][0]))
111
+ || (positives.size === 0 && negatives.size > 1);
112
+ const confidence = ambiguous ? 'ambiguous' : 'high';
113
+ return [...new Map(occurrences.map(item => [
114
+ `${item.polarity}:${item.value}`,
115
+ { kind, family, entity, value: item.value, polarity: item.polarity, confidence },
116
+ ])).values()];
117
+ }
118
+ function parseStructuredOccurrences(span) {
119
+ const occurrences = [];
120
+ for (const definition of EXCLUSIVE_FAMILIES) {
121
+ for (const value of definition.values) {
122
+ const expression = new RegExp(`(?<![${IDENTIFIER_CHARACTERS}])${escapeRegExp(value)}(?![${IDENTIFIER_CHARACTERS}])`, 'giu');
123
+ for (const match of span.body.matchAll(expression)) {
124
+ const start = match.index ?? 0;
125
+ occurrences.push({
126
+ kind: 'exclusive_choice',
127
+ family: definition.family,
128
+ entity: definition.entity,
129
+ value,
130
+ polarity: span.polarity,
131
+ start,
132
+ end: start + match[0].length,
133
+ });
134
+ }
135
+ }
136
+ }
137
+ for (const definition of VERSIONED_ENTITIES) {
138
+ const aliases = definition.aliases.map(escapeRegExp).join('|');
139
+ const expression = new RegExp(`(?<![${IDENTIFIER_CHARACTERS}])(?:${aliases})(?![${IDENTIFIER_CHARACTERS}])`
140
+ + `\\s*(?:version\\s*|v\\s*)?(\\d+(?:\\.\\d+){0,2})(?![${IDENTIFIER_CHARACTERS}])`, 'giu');
141
+ for (const match of span.body.matchAll(expression)) {
142
+ if (!match[1])
143
+ continue;
144
+ const start = match.index ?? 0;
145
+ occurrences.push({
146
+ kind: 'version_choice',
147
+ family: `version:${definition.family}`,
148
+ entity: definition.family,
149
+ value: match[1],
150
+ polarity: span.polarity,
151
+ start,
152
+ end: start + match[0].length,
153
+ });
154
+ }
155
+ }
156
+ return occurrences;
157
+ }
158
+ function parseGenericResiduals(span, structured) {
159
+ const ordered = [...structured].sort((left, right) => left.start - right.start || left.end - right.end);
160
+ const residuals = [];
161
+ for (let index = 0; index < ordered.length; index += 1) {
162
+ const occurrence = ordered[index];
163
+ const nextStart = ordered[index + 1]?.start ?? span.body.length;
164
+ const connectorMatch = span.body.slice(occurrence.end, nextStart).match(GENERIC_RESIDUAL_CONNECTOR);
165
+ if (!connectorMatch?.[1])
166
+ continue;
167
+ const entity = takeCodePoints(normalizeGenericEntity(connectorMatch[1]), 80);
168
+ if (!entity)
169
+ continue;
170
+ residuals.push({
171
+ kind: 'entity_polarity',
172
+ family: `entity:${entity}`,
173
+ entity,
174
+ value: entity,
175
+ polarity: span.polarity,
176
+ });
177
+ }
178
+ return residuals;
179
+ }
180
+ function normalizeGenericEntity(value) {
181
+ return value
182
+ .replace(/^(?:(?:and|or|then)\s+|(?:并且|并|以及|然后)\s*)/u, '')
183
+ .replace(/^(?:the|a|an)\s+/u, '')
184
+ .replace(/\s+(?:in|for)\s+(?:this|the)\s+(?:project|repository|repo)$/u, '')
185
+ .replace(/(?:在)?(?:这个|该|本)?项目中?$/u, '')
186
+ .replace(/\s+/gu, ' ')
187
+ .trim();
188
+ }
189
+ export function analyzePreference(content) {
190
+ const text = normalizedText(content);
191
+ if (!text)
192
+ return { status: 'unclassified', facets: [] };
193
+ const occurrences = [];
194
+ for (const span of extractIntentSpans(text)) {
195
+ const structured = parseStructuredOccurrences(span);
196
+ occurrences.push(...structured);
197
+ if (structured.length > 0) {
198
+ occurrences.push(...parseGenericResiduals(span, structured));
199
+ continue;
200
+ }
201
+ if (!span.allowGeneric)
202
+ continue;
203
+ const entity = takeCodePoints(normalizeGenericEntity(span.body), 80);
204
+ if (!entity)
205
+ continue;
206
+ occurrences.push({
207
+ kind: 'entity_polarity',
208
+ family: `entity:${entity}`,
209
+ entity,
210
+ value: entity,
211
+ polarity: span.polarity,
212
+ });
213
+ }
214
+ const byFamily = new Map();
215
+ for (const occurrence of occurrences) {
216
+ const family = byFamily.get(occurrence.family) ?? [];
217
+ family.push(occurrence);
218
+ byFamily.set(occurrence.family, family);
219
+ }
220
+ const facets = [...byFamily.values()].flatMap(family => classifyFamilyFacets(family[0].kind, family[0].family, family[0].entity, family.map(occurrence => ({ value: occurrence.value, polarity: occurrence.polarity }))));
221
+ if (facets.length === 0)
222
+ return { status: 'unclassified', facets: [] };
223
+ return {
224
+ status: facets.some(facet => facet.confidence === 'ambiguous') ? 'ambiguous' : 'high_confidence',
225
+ facets,
226
+ };
227
+ }
228
+ export function analyzePreferenceObservation(observation) {
229
+ return analyzePreference(observation.narrative.trim() || observation.title);
230
+ }
231
+ export function preferenceFacetsConflict(left, right) {
232
+ if (left.confidence !== 'high' || right.confidence !== 'high' || left.family !== right.family) {
233
+ return false;
234
+ }
235
+ if (left.kind === 'entity_polarity' || right.kind === 'entity_polarity') {
236
+ return left.entity === right.entity && left.polarity !== right.polarity;
237
+ }
238
+ if (left.polarity !== right.polarity)
239
+ return left.value === right.value;
240
+ return left.polarity === 'positive' && left.value !== right.value;
241
+ }
242
+ export function analysesConflict(left, right) {
243
+ return left.facets.some(leftFacet => right.facets.some(rightFacet => preferenceFacetsConflict(leftFacet, rightFacet)));
244
+ }
245
+ export function buildPreferenceConflictDiagnostics(observations) {
246
+ const analyzed = observations.map(observation => ({
247
+ observation,
248
+ analysis: analyzePreferenceObservation(observation),
249
+ }));
250
+ const byFamily = new Map();
251
+ for (const item of analyzed) {
252
+ for (const facet of item.analysis.facets) {
253
+ const members = byFamily.get(facet.family) ?? [];
254
+ members.push({ observation: item.observation, facet });
255
+ byFamily.set(facet.family, members);
256
+ }
257
+ }
258
+ const diagnostics = [];
259
+ for (const [family, members] of byFamily) {
260
+ const positiveValues = new Set(members
261
+ .filter(member => member.facet.polarity === 'positive')
262
+ .map(member => member.facet.value ?? member.facet.entity));
263
+ const polaritiesByValue = new Map();
264
+ for (const member of members) {
265
+ const value = member.facet.value ?? member.facet.entity;
266
+ const polarities = polaritiesByValue.get(value) ?? new Set();
267
+ polarities.add(member.facet.polarity);
268
+ polaritiesByValue.set(value, polarities);
269
+ }
270
+ const ambiguous = members.some(member => member.facet.confidence === 'ambiguous')
271
+ || positiveValues.size > 1
272
+ || [...polaritiesByValue.values()].some(polarities => polarities.size > 1);
273
+ if (!ambiguous)
274
+ continue;
275
+ const facet = members[0].facet;
276
+ const memoryIds = [...new Set(members.map(member => member.observation.id))].sort();
277
+ const id = `preference-conflict:${createHash('sha256')
278
+ .update(`${family}:${memoryIds.join(',')}`)
279
+ .digest('hex')
280
+ .slice(0, 16)}`;
281
+ diagnostics.push({
282
+ id,
283
+ kind: facet.kind,
284
+ family,
285
+ entity: facet.entity,
286
+ memoryIds,
287
+ status: 'withheld',
288
+ summary: `Withheld ambiguous ${facet.entity} preference; an explicit choice is required.`,
289
+ });
290
+ }
291
+ return diagnostics.sort((left, right) => left.id.localeCompare(right.id));
292
+ }
293
+ //# sourceMappingURL=preference-conflicts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preference-conflicts.js","sourceRoot":"","sources":["../src/preference-conflicts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=preference-conflicts.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preference-conflicts.test.d.ts","sourceRoot":"","sources":["../src/preference-conflicts.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,72 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { analyzePreference, MAX_PREFERENCE_ANALYSIS_CODE_POINTS, normalizeExplicitPreferenceContent, } from './preference-conflicts.js';
3
+ describe('explicit preference parsing boundaries', () => {
4
+ it('extracts structured and generic facets from separate intent spans', () => {
5
+ const result = analyzePreference('use pnpm and prefer semicolons');
6
+ expect(result.status).toBe('high_confidence');
7
+ expect(result.facets).toEqual(expect.arrayContaining([
8
+ expect.objectContaining({ family: 'package_manager', value: 'pnpm', polarity: 'positive' }),
9
+ expect.objectContaining({ family: 'entity:semicolons', entity: 'semicolons', polarity: 'positive' }),
10
+ ]));
11
+ });
12
+ it('extracts generic residuals only after explicit connectors', () => {
13
+ const mixed = analyzePreference('use pnpm with semicolons');
14
+ const framework = analyzePreference('use React 19 syntax');
15
+ expect(mixed.facets).toEqual(expect.arrayContaining([
16
+ expect.objectContaining({ family: 'package_manager', value: 'pnpm' }),
17
+ expect.objectContaining({ family: 'entity:semicolons', entity: 'semicolons' }),
18
+ ]));
19
+ expect(framework.facets).toEqual([
20
+ expect.objectContaining({ family: 'version:react', value: '19' }),
21
+ ]);
22
+ expect(framework.facets.some(facet => facet.entity === 'syntax')).toBe(false);
23
+ });
24
+ it('preserves decimal versions and dot-qualified framework aliases', () => {
25
+ expect(analyzePreference('Use React 18.2').facets).toEqual([
26
+ expect.objectContaining({ family: 'version:react', value: '18.2' }),
27
+ ]);
28
+ expect(analyzePreference('Use React 18.3').facets).toEqual([
29
+ expect.objectContaining({ family: 'version:react', value: '18.3' }),
30
+ ]);
31
+ expect(analyzePreference('Use Node.js 20').facets).toEqual([
32
+ expect.objectContaining({ family: 'version:node', value: '20' }),
33
+ ]);
34
+ expect(analyzePreference('Use Vue.js 3').facets).toEqual([
35
+ expect.objectContaining({ family: 'version:vue', value: '3' }),
36
+ ]);
37
+ });
38
+ it('accepts bounded command-style run markers without matching narration or npm scripts', () => {
39
+ expect(analyzePreference('run vitest').facets).toEqual([
40
+ expect.objectContaining({ family: 'test_runner', value: 'vitest', polarity: 'positive' }),
41
+ ]);
42
+ expect(analyzePreference('always run jest').facets).toEqual([
43
+ expect.objectContaining({ family: 'test_runner', value: 'jest', polarity: 'positive' }),
44
+ ]);
45
+ expect(analyzePreference('never run jest').facets).toEqual([
46
+ expect.objectContaining({ family: 'test_runner', value: 'jest', polarity: 'negative' }),
47
+ ]);
48
+ expect(analyzePreference('we run jest').status).toBe('unclassified');
49
+ expect(analyzePreference('use npm run dev').facets).toEqual([
50
+ expect.objectContaining({ family: 'package_manager', value: 'npm' }),
51
+ ]);
52
+ });
53
+ it.each([
54
+ ['use vite-plugin-react', 'build_tool'],
55
+ ['use jest-dom', 'test_runner'],
56
+ ['use npm_package', 'package_manager'],
57
+ ])('does not classify identifier-embedded tokens in %s', (content, forbiddenFamily) => {
58
+ const result = analyzePreference(content);
59
+ expect(result.facets.some(facet => facet.family === forbiddenFamily)).toBe(false);
60
+ expect(result.facets).toHaveLength(1);
61
+ expect(result.facets[0]?.kind).toBe('entity_polarity');
62
+ });
63
+ it('bounds normalization and analysis before scanning intent markers', () => {
64
+ const oversized = `use semicolons ${'x'.repeat(MAX_PREFERENCE_ANALYSIS_CODE_POINTS + 2_000)} prefer pnpm`;
65
+ const result = analyzePreference(oversized);
66
+ const normalized = normalizeExplicitPreferenceContent(oversized);
67
+ expect(result.facets.some(facet => facet.family === 'package_manager')).toBe(false);
68
+ expect([...normalized].length).toBe(4_000);
69
+ expect(Buffer.byteLength(normalized, 'utf8')).toBeLessThanOrEqual(16_384);
70
+ });
71
+ });
72
+ //# sourceMappingURL=preference-conflicts.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preference-conflicts.test.js","sourceRoot":"","sources":["../src/preference-conflicts.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devflow-tools/memory-engine",
3
- "version": "0.16.10",
3
+ "version": "0.16.12",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -17,19 +17,19 @@
17
17
  "clean": "rm -rf dist"
18
18
  },
19
19
  "dependencies": {
20
- "@devflow-tools/sdk": "0.16.10",
20
+ "@devflow-tools/sdk": "0.16.12",
21
21
  "@xenova/transformers": "^2.17.0",
22
22
  "better-sqlite3": "^12.0.0",
23
23
  "sqlite-vec": "^0.1.9",
24
24
  "ulidx": "^2.4.1"
25
25
  },
26
26
  "devDependencies": {
27
- "@devflow-tools/knowledge-engine": "0.16.10",
27
+ "@devflow-tools/knowledge-engine": "0.16.12",
28
28
  "typescript": "^5.5.0",
29
29
  "vitest": "^2.0.0"
30
30
  },
31
31
  "files": [
32
32
  "dist"
33
33
  ],
34
- "gitHead": "964af33767bf232606e63d973b3a29d7d53c8119"
34
+ "gitHead": "d4a018f3031a3570c794c253f8edeff405956133"
35
35
  }