@devflow-tools/memory-engine 0.8.1 → 0.8.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.
@@ -0,0 +1,7 @@
1
+ export declare class EmbeddingProvider {
2
+ private ready;
3
+ initialize(): Promise<void>;
4
+ embed(text: string): Promise<Float32Array>;
5
+ embedBatch(texts: string[]): Promise<Float32Array[]>;
6
+ }
7
+ //# sourceMappingURL=embedding-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedding-provider.d.ts","sourceRoot":"","sources":["../src/embedding-provider.ts"],"names":[],"mappings":"AAaA,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,KAAK,CAAS;IAEhB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAM1C,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAK3D"}
@@ -0,0 +1,32 @@
1
+ let pipe = null;
2
+ async function getPipeline() {
3
+ if (pipe)
4
+ return pipe;
5
+ const { pipeline: transformersPipeline } = await import('@xenova/transformers');
6
+ const raw = await transformersPipeline('feature-extraction', 'Xenova/all-MiniLM-L6-v2');
7
+ pipe = async (texts) => {
8
+ const result = await raw(texts, { pooling: 'mean', normalize: true });
9
+ return Array.isArray(result) ? result : [result];
10
+ };
11
+ return pipe;
12
+ }
13
+ export class EmbeddingProvider {
14
+ ready = false;
15
+ async initialize() {
16
+ if (this.ready)
17
+ return;
18
+ await getPipeline();
19
+ this.ready = true;
20
+ }
21
+ async embed(text) {
22
+ const p = await getPipeline();
23
+ const results = await p([text]);
24
+ return results[0].data;
25
+ }
26
+ async embedBatch(texts) {
27
+ const p = await getPipeline();
28
+ const results = await p(texts);
29
+ return results.map(r => r.data);
30
+ }
31
+ }
32
+ //# sourceMappingURL=embedding-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedding-provider.js","sourceRoot":"","sources":["../src/embedding-provider.ts"],"names":[],"mappings":"AAAA,IAAI,IAAI,GAAyE,IAAI,CAAC;AAEtF,KAAK,UAAU,WAAW;IACxB,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IACtB,MAAM,EAAE,QAAQ,EAAE,oBAAoB,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;IAChF,MAAM,GAAG,GAAG,MAAM,oBAAoB,CAAC,oBAAoB,EAAE,yBAAyB,CAAC,CAAC;IACxF,IAAI,GAAG,KAAK,EAAE,KAAe,EAAE,EAAE;QAC/B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtE,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAuC,CAAC,CAAC,CAAC,CAAC,MAAgC,CAAC,CAAC;IAC9G,CAAC,CAAC;IACF,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,OAAO,iBAAiB;IACpB,KAAK,GAAG,KAAK,CAAC;IAEtB,KAAK,CAAC,UAAU;QACd,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO;QACvB,MAAM,WAAW,EAAE,CAAC;QACpB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAY;QACtB,MAAM,CAAC,GAAG,MAAM,WAAW,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAChC,OAAO,OAAO,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,KAAe;QAC9B,MAAM,CAAC,GAAG,MAAM,WAAW,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC;QAC/B,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;CACF"}
@@ -1,3 +1,25 @@
1
1
  import type { SessionEntry, MemoryCandidate } from "@devflow-tools/sdk";
2
+ import { type OllamaStatus } from './ollama-checker.js';
3
+ interface TelemetryEvent {
4
+ type?: string;
5
+ kind?: string;
6
+ toolName?: string;
7
+ mcpToolName?: string;
8
+ errorMessage?: string;
9
+ error?: string;
10
+ command?: string;
11
+ filePath?: string;
12
+ prompt?: string;
13
+ response?: string;
14
+ timestamp?: number;
15
+ }
16
+ export interface ExtractedMemory {
17
+ category: 'mcp_correction' | 'project_knowledge' | 'failure_lesson';
18
+ content: string;
19
+ originalText?: string;
20
+ confidence: number;
21
+ }
22
+ export declare function extractMemories(events: TelemetryEvent[], ollamaStatus?: OllamaStatus): Promise<ExtractedMemory[]>;
2
23
  export declare function extractCandidates(sessionId: string, entries: SessionEntry[]): MemoryCandidate[];
24
+ export {};
3
25
  //# sourceMappingURL=extractor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../src/extractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAoBxE,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,YAAY,EAAE,GACtB,eAAe,EAAE,CAoBnB"}
1
+ {"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../src/extractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAmC,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEzF,UAAU,cAAc;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IACxC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,gBAAgB,GAAG,mBAAmB,GAAG,gBAAgB,CAAC;IACpE,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAkED,wBAAsB,eAAe,CACnC,MAAM,EAAE,cAAc,EAAE,EACxB,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,eAAe,EAAE,CAAC,CAa5B;AAsBD,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,YAAY,EAAE,GACtB,eAAe,EAAE,CAoBnB"}
package/dist/extractor.js CHANGED
@@ -1,3 +1,78 @@
1
+ import { checkOllama, generateWithOllama } from './ollama-checker.js';
2
+ // L2 fallback patterns
3
+ const CORRECTION_PATTERNS = [
4
+ {
5
+ pattern: /(?:error|failed|fix|retry|correct|use|pass|provide)\s+([\s\S]{10,200}?)(?:\.\s|$)/i,
6
+ category: 'mcp_correction',
7
+ },
8
+ {
9
+ pattern: /(?:discovered|found|this project uses|note:)\s+([\s\S]{10,200}?)(?:\.\s|$)/i,
10
+ category: 'project_knowledge',
11
+ },
12
+ {
13
+ pattern: /(?:don't|never|should not|must not)\s+([\s\S]{10,200}?)(?:\.\s|$)/i,
14
+ category: 'failure_lesson',
15
+ },
16
+ ];
17
+ async function extractWithOllama(events) {
18
+ const eventText = events.map(e => {
19
+ const tool = e.toolName ?? e.mcpToolName ?? e.type ?? 'unknown';
20
+ const error = e.errorMessage ?? e.error ?? '';
21
+ const response = e.response ?? '';
22
+ return `[${tool}] ${response} ${error ? `ERROR: ${error}` : ''}`.trim();
23
+ }).join('\n---\n');
24
+ const system = `You are a memory extraction system. Analyze the agent's conversation logs and extract memories that will help avoid repeating mistakes.
25
+
26
+ For each significant finding, output a JSON object with:
27
+ - "category": one of "mcp_correction", "project_knowledge", "failure_lesson"
28
+ - "content": the memory text in English (translate Chinese input — accurate English improves search quality)
29
+ - "confidence": 0.0 to 1.0
30
+
31
+ Return ONLY a JSON array, no other text. Example:
32
+ [{"category":"mcp_correction","content":"react_diagnose_bug requires stackTrace as string","confidence":0.9}]`;
33
+ try {
34
+ const text = await generateWithOllama(eventText.slice(0, 8000), system);
35
+ const jsonMatch = text.match(/\[[\s\S]*\]/);
36
+ if (!jsonMatch)
37
+ return [];
38
+ const parsed = JSON.parse(jsonMatch[0]);
39
+ return parsed.filter(e => e.content && e.category && e.confidence >= 0);
40
+ }
41
+ catch {
42
+ return [];
43
+ }
44
+ }
45
+ function extractWithRules(events) {
46
+ const results = [];
47
+ for (const event of events) {
48
+ const text = [event.errorMessage, event.error, event.response, event.prompt].filter(Boolean).join(' ');
49
+ if (!text)
50
+ continue;
51
+ for (const { pattern, category } of CORRECTION_PATTERNS) {
52
+ const match = text.match(pattern);
53
+ if (match?.[1]) {
54
+ const content = match[1].trim();
55
+ if (content.length >= 10 && !results.some(r => r.content === content)) {
56
+ results.push({ content, category, confidence: 0.5 });
57
+ }
58
+ break;
59
+ }
60
+ }
61
+ }
62
+ return results;
63
+ }
64
+ export async function extractMemories(events, ollamaStatus) {
65
+ const status = ollamaStatus ?? await checkOllama();
66
+ let extracted = [];
67
+ if (status.installed && status.running && status.modelAvailable) {
68
+ extracted = await extractWithOllama(events);
69
+ }
70
+ if (extracted.length === 0) {
71
+ extracted = extractWithRules(events);
72
+ }
73
+ return extracted;
74
+ }
75
+ // --- Legacy extractor (backward compat) ---
1
76
  const PATTERNS = [
2
77
  {
3
78
  pattern: /(?:Using|Used|Use)\s+(?:@?[A-Z][a-zA-Z]*\s+)?([A-Z][a-zA-Z]+)\s+(?:for|as|in)/,
@@ -1 +1 @@
1
- {"version":3,"file":"extractor.js","sourceRoot":"","sources":["../src/extractor.ts"],"names":[],"mappings":"AAEA,MAAM,QAAQ,GAA0G;IACtH;QACE,OAAO,EAAE,+EAA+E;QACxF,IAAI,EAAE,SAAS;QACf,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,EAAE;KAClD;IACD;QACE,OAAO,EAAE,0EAA0E;QACnF,IAAI,EAAE,SAAS;QACf,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE;KACnF;IACD;QACE,OAAO,EAAE,sDAAsD;QAC/D,IAAI,EAAE,SAAS;QACf,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,EAAE;KACjD;CACF,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAC/B,SAAiB,EACjB,OAAuB;IAEvB,MAAM,UAAU,GAAsB,EAAE,CAAC;IAEzC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,QAAQ,EAAE,CAAC;YACrD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC3C,IAAI,KAAK,EAAE,CAAC;gBACV,UAAU,CAAC,IAAI,CAAC;oBACd,EAAE,EAAE,aAAa,SAAS,IAAI,UAAU,CAAC,MAAM,EAAE;oBACjD,IAAI;oBACJ,OAAO,EAAE,EAAE,GAAG,EAAE,UAAU,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE;oBACzD,UAAU,EAAE,GAAG;oBACf,MAAM,EAAE,SAAS;iBAClB,CAAC,CAAC;gBACH,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC"}
1
+ {"version":3,"file":"extractor.js","sourceRoot":"","sources":["../src/extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { MemoryStore } from './memory-store.js';
2
+ export declare class GraphStore {
3
+ private store;
4
+ constructor(store: MemoryStore);
5
+ buildEdges(memoryId: string): Promise<void>;
6
+ expandFromEntities(entities: string[], maxDepth?: number): string[];
7
+ }
8
+ //# sourceMappingURL=graph-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-store.d.ts","sourceRoot":"","sources":["../src/graph-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAkBrD,qBAAa,UAAU;IACT,OAAO,CAAC,KAAK;gBAAL,KAAK,EAAE,WAAW;IAEhC,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBjD,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,QAAQ,SAAI,GAAG,MAAM,EAAE;CA8B/D"}
@@ -0,0 +1,69 @@
1
+ function extractEntities(text) {
2
+ const words = text.split(/[\s,;:.!?()\[\]{}]+/);
3
+ const entities = [];
4
+ for (const w of words) {
5
+ const cleaned = w.replace(/^['"]|['"]$/g, '');
6
+ if (cleaned.length > 3 && /^[A-Z][a-zA-Z]+$/.test(cleaned)) {
7
+ entities.push(cleaned.toLowerCase());
8
+ }
9
+ }
10
+ const compounds = text.match(/\b[a-z]+[_-][a-z_-]{3,}\b/g) ?? [];
11
+ entities.push(...compounds);
12
+ return [...new Set(entities)];
13
+ }
14
+ const RELATED_RELATIONS = ['related_to', 'similar_to', 'same_category', 'same_scope'];
15
+ export class GraphStore {
16
+ store;
17
+ constructor(store) {
18
+ this.store = store;
19
+ }
20
+ async buildEdges(memoryId) {
21
+ const memory = this.store.get(memoryId);
22
+ if (!memory)
23
+ return;
24
+ const entities = extractEntities(memory.content);
25
+ for (const entity of entities) {
26
+ try {
27
+ const matches = this.store.searchBM25(entity, 5);
28
+ for (const match of matches) {
29
+ if (match.id === memoryId)
30
+ continue;
31
+ const relation = RELATED_RELATIONS[matches.indexOf(match) % RELATED_RELATIONS.length];
32
+ this.store.addEdge(memoryId, match.id, relation, 0.7);
33
+ this.store.addEdge(match.id, memoryId, relation, 0.7);
34
+ }
35
+ }
36
+ catch { /* non-fatal */ }
37
+ }
38
+ }
39
+ expandFromEntities(entities, maxDepth = 1) {
40
+ const visited = new Set();
41
+ let frontier = new Set();
42
+ for (const entity of entities) {
43
+ try {
44
+ const matches = this.store.searchBM25(entity, 3);
45
+ for (const m of matches)
46
+ frontier.add(m.id);
47
+ }
48
+ catch { /* skip */ }
49
+ }
50
+ visited.add('');
51
+ for (const id of frontier)
52
+ visited.add(id);
53
+ for (let depth = 1; depth < maxDepth; depth++) {
54
+ const nextFrontier = new Set();
55
+ for (const id of frontier) {
56
+ const neighbors = this.store.getNeighbors(id);
57
+ for (const n of neighbors) {
58
+ if (!visited.has(n.targetId)) {
59
+ visited.add(n.targetId);
60
+ nextFrontier.add(n.targetId);
61
+ }
62
+ }
63
+ }
64
+ frontier = nextFrontier;
65
+ }
66
+ return [...visited].filter(Boolean);
67
+ }
68
+ }
69
+ //# sourceMappingURL=graph-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-store.js","sourceRoot":"","sources":["../src/graph-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import type { MemoryStore } from './memory-store.js';
2
+ import type { EmbeddingProvider } from './embedding-provider.js';
3
+ export interface SearchOptions {
4
+ limit?: number;
5
+ categories?: string[];
6
+ scope?: string;
7
+ }
8
+ export interface SearchResultEntry {
9
+ id: string;
10
+ category: 'mcp_correction' | 'project_knowledge' | 'failure_lesson';
11
+ content: string;
12
+ originalText?: string;
13
+ source: 'auto' | 'manual';
14
+ status: 'pending' | 'approved' | 'rejected';
15
+ confidence: number;
16
+ scope: string;
17
+ sessionId?: string;
18
+ createdAt: number;
19
+ approvedAt?: number;
20
+ }
21
+ export interface SearchResult {
22
+ entry: SearchResultEntry;
23
+ score: number;
24
+ }
25
+ export declare class HybridSearch {
26
+ private store;
27
+ private embedder;
28
+ constructor(store: MemoryStore, embedder: EmbeddingProvider);
29
+ search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
30
+ }
31
+ //# sourceMappingURL=hybrid-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hybrid-search.d.ts","sourceRoot":"","sources":["../src/hybrid-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,gBAAgB,GAAG,mBAAmB,GAAG,gBAAgB,CAAC;IACpE,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC1B,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,iBAAiB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf;AAmDD,qBAAa,YAAY;IAErB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,QAAQ;gBADR,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,iBAAiB;IAG/B,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAoFlF"}
@@ -0,0 +1,132 @@
1
+ const DEFAULT_WEIGHTS = { bm25: 0.4, vector: 0.6, graph: 0.3 };
2
+ const RRF_K = 60;
3
+ function rrfFusion(results, k) {
4
+ const scored = [];
5
+ const usedStreams = new Set();
6
+ for (const [id, { ranks }] of results) {
7
+ let score = 0;
8
+ for (const [stream, rank] of ranks) {
9
+ usedStreams.add(stream);
10
+ const w = DEFAULT_WEIGHTS[stream] ?? 0;
11
+ if (w > 0)
12
+ score += w / (k + rank);
13
+ }
14
+ scored.push({ id, score });
15
+ }
16
+ const weightSum = [...usedStreams].reduce((sum, s) => sum + (DEFAULT_WEIGHTS[s] ?? 0), 0);
17
+ if (weightSum > 0) {
18
+ for (const r of scored)
19
+ r.score /= weightSum;
20
+ }
21
+ scored.sort((a, b) => b.score - a.score);
22
+ return scored;
23
+ }
24
+ function rowToEntry(row) {
25
+ return {
26
+ id: row.id,
27
+ category: row.category,
28
+ content: row.content,
29
+ originalText: row.original_text ?? undefined,
30
+ source: row.source,
31
+ status: row.status,
32
+ confidence: row.confidence,
33
+ scope: row.scope,
34
+ sessionId: row.session_id ?? undefined,
35
+ createdAt: row.created_at,
36
+ approvedAt: row.approved_at ?? undefined,
37
+ };
38
+ }
39
+ export class HybridSearch {
40
+ store;
41
+ embedder;
42
+ constructor(store, embedder) {
43
+ this.store = store;
44
+ this.embedder = embedder;
45
+ }
46
+ async search(query, options = {}) {
47
+ const limit = options.limit ?? 10;
48
+ const fetchLimit = limit * 3;
49
+ let bm25Results = [];
50
+ try {
51
+ bm25Results = this.store.searchBM25(query, fetchLimit);
52
+ }
53
+ catch { /* FTS5 may fail on malformed queries */ }
54
+ let vectorResults = [];
55
+ try {
56
+ const embedding = await this.embedder.embed(query);
57
+ vectorResults = this.store.searchVector(embedding, fetchLimit);
58
+ }
59
+ catch { /* embedding may fail */ }
60
+ const graphIds = new Set();
61
+ try {
62
+ const simpleEntities = query.split(/\s+/).filter(w => w.length > 3);
63
+ for (const entity of simpleEntities.slice(0, 5)) {
64
+ const entityMatches = this.store.searchBM25(entity, 3);
65
+ for (const { id } of entityMatches) {
66
+ if (!graphIds.has(id)) {
67
+ graphIds.add(id);
68
+ const neighbors = this.store.getNeighbors(id);
69
+ for (const n of neighbors)
70
+ graphIds.add(n.targetId);
71
+ }
72
+ }
73
+ }
74
+ }
75
+ catch { /* graph expansion failure is non-fatal */ }
76
+ const docs = new Map();
77
+ for (let i = 0; i < bm25Results.length; i++) {
78
+ const { id } = bm25Results[i];
79
+ if (!docs.has(id)) {
80
+ const row = this.store.get(id);
81
+ if (row)
82
+ docs.set(id, { ranks: new Map(), entry: rowToEntry(row) });
83
+ }
84
+ docs.get(id)?.ranks.set('bm25', i + 1);
85
+ }
86
+ for (let i = 0; i < vectorResults.length; i++) {
87
+ const { id } = vectorResults[i];
88
+ if (!docs.has(id)) {
89
+ const row = this.store.get(id);
90
+ if (row)
91
+ docs.set(id, { ranks: new Map(), entry: rowToEntry(row) });
92
+ }
93
+ docs.get(id)?.ranks.set('vector', i + 1);
94
+ }
95
+ let graphRank = 1;
96
+ for (const id of graphIds) {
97
+ if (docs.has(id)) {
98
+ docs.get(id)?.ranks.set('graph', graphRank++);
99
+ }
100
+ }
101
+ const fused = rrfFusion(docs, RRF_K);
102
+ const sessionCount = new Map();
103
+ const diverse = new Set(fused.map(r => {
104
+ const doc = docs.get(r.id);
105
+ const sid = doc?.entry.sessionId;
106
+ if (sid) {
107
+ const count = sessionCount.get(sid) ?? 0;
108
+ if (count >= 3)
109
+ return null;
110
+ sessionCount.set(sid, count + 1);
111
+ }
112
+ return r.id;
113
+ }).filter(Boolean));
114
+ const results = [];
115
+ for (const { id, score } of fused) {
116
+ if (!diverse.has(id))
117
+ continue;
118
+ const doc = docs.get(id);
119
+ if (!doc)
120
+ continue;
121
+ if (options.categories?.length && !options.categories.includes(doc.entry.category))
122
+ continue;
123
+ if (options.scope && doc.entry.scope !== options.scope)
124
+ continue;
125
+ results.push({ entry: doc.entry, score: Math.round(score * 10000) / 10000 });
126
+ if (results.length >= limit)
127
+ break;
128
+ }
129
+ return results;
130
+ }
131
+ }
132
+ //# sourceMappingURL=hybrid-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hybrid-search.js","sourceRoot":"","sources":["../src/hybrid-search.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,10 @@
1
1
  export { MemoryEngine } from "./memory-engine.js";
2
- export { extractCandidates } from "./extractor.js";
2
+ export { MemoryStore } from "./memory-store.js";
3
+ export { EmbeddingProvider } from "./embedding-provider.js";
4
+ export { HybridSearch } from "./hybrid-search.js";
5
+ export { GraphStore } from "./graph-store.js";
6
+ export { extractMemories, extractCandidates } from "./extractor.js";
7
+ export { checkOllama, getOllamaInfoMessage } from "./ollama-checker.js";
8
+ export type { OllamaStatus } from "./ollama-checker.js";
9
+ export type { SearchResult, SearchResultEntry, SearchOptions } from "./hybrid-search.js";
3
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACxE,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,8 @@
1
1
  export { MemoryEngine } from "./memory-engine.js";
2
- export { extractCandidates } from "./extractor.js";
2
+ export { MemoryStore } from "./memory-store.js";
3
+ export { EmbeddingProvider } from "./embedding-provider.js";
4
+ export { HybridSearch } from "./hybrid-search.js";
5
+ export { GraphStore } from "./graph-store.js";
6
+ export { extractMemories, extractCandidates } from "./extractor.js";
7
+ export { checkOllama, getOllamaInfoMessage } from "./ollama-checker.js";
3
8
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -1,21 +1,23 @@
1
- import type { IMemoryEngine, UserPrefs, Convention, ProjectContext, SessionEntry, SessionMemory, MemoryCandidate, KnowledgeEntry, IDataProvider } from "@devflow-tools/sdk";
1
+ import type { IMemoryEngine, UserPrefs, Convention, ProjectContext, SessionEntry, SessionMemory, MemoryCandidate, KnowledgeEntry, MemoryEntryRecord, MemoryFilter, MemorySearchOptions, MemorySearchResult } from '@devflow-tools/sdk';
2
2
  export declare class MemoryEngine implements IMemoryEngine {
3
- private provider;
4
- private userPrefsKey;
5
- private projectCtxKey;
6
- private candidatesKey;
7
- constructor(provider: IDataProvider);
3
+ private store;
4
+ private embedder;
5
+ private searcher;
6
+ private graph;
7
+ constructor(rootPath: string);
8
+ private _initPromise;
9
+ private ensureInit;
8
10
  getUserPreferences(): Promise<UserPrefs>;
9
- updateUserPreference(key: string, value: unknown): Promise<void>;
11
+ updateUserPreference(_key: string, _value: unknown): Promise<void>;
10
12
  getProjectContext(): Promise<ProjectContext>;
11
- setProjectContext(ctx: Partial<ProjectContext>): Promise<void>;
13
+ setProjectContext(_ctx: Partial<ProjectContext>): Promise<void>;
12
14
  getTeamConventions(): Promise<Convention[]>;
13
15
  createSession(task: string): Promise<string>;
14
- appendToSession(sessionId: string, entry: SessionEntry): Promise<void>;
16
+ appendToSession(_sessionId: string, _entry: SessionEntry): Promise<void>;
15
17
  getSession(sessionId: string): Promise<SessionMemory>;
16
18
  closeSession(sessionId: string): Promise<void>;
17
- searchGlobal(_query: string): Promise<KnowledgeEntry[]>;
18
- upsertGlobal(entries: KnowledgeEntry[]): Promise<void>;
19
+ searchGlobal(query: string): Promise<KnowledgeEntry[]>;
20
+ upsertGlobal(_entries: KnowledgeEntry[]): Promise<void>;
19
21
  getAll(): Promise<{
20
22
  project: ProjectContext;
21
23
  user: UserPrefs;
@@ -24,5 +26,16 @@ export declare class MemoryEngine implements IMemoryEngine {
24
26
  getCandidates(): Promise<MemoryCandidate[]>;
25
27
  approveCandidate(id: string): Promise<void>;
26
28
  rejectCandidate(id: string): Promise<void>;
29
+ search(query: string, options?: MemorySearchOptions): Promise<MemorySearchResult[]>;
30
+ listMemories(filter?: MemoryFilter): Promise<MemoryEntryRecord[]>;
31
+ addMemory(entry: Omit<MemoryEntryRecord, 'id' | 'createdAt' | 'status'>): Promise<MemoryEntryRecord>;
32
+ updateMemory(id: string, updates: Partial<Pick<MemoryEntryRecord, 'content' | 'status' | 'scope'>>): Promise<void>;
33
+ deleteMemory(id: string): Promise<void>;
34
+ getPendingMemories(): Promise<MemoryEntryRecord[]>;
35
+ approveMemory(id: string): Promise<void>;
36
+ rejectMemory(id: string): Promise<void>;
37
+ extractMemories(events: Array<Record<string, unknown>>): Promise<MemoryEntryRecord[]>;
38
+ getOllamaStatus(): Promise<import("./ollama-checker.js").OllamaStatus>;
39
+ close(): void;
27
40
  }
28
41
  //# sourceMappingURL=memory-engine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"memory-engine.d.ts","sourceRoot":"","sources":["../src/memory-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EACpD,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAC5D,aAAa,EACd,MAAM,oBAAoB,CAAC;AAG5B,qBAAa,YAAa,YAAW,aAAa;IAChD,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,aAAa,CAAuB;gBAEhC,QAAQ,EAAE,aAAa;IAK7B,kBAAkB,IAAI,OAAO,CAAC,SAAS,CAAC;IAMxC,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAOhE,iBAAiB,IAAI,OAAO,CAAC,cAAc,CAAC;IAM5C,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAU9D,kBAAkB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAM3C,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAM5C,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAItE,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAcrD,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS9C,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAYvD,YAAY,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAetD,MAAM;;;;;IAUN,aAAa,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAM3C,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAe3C,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAOjD"}
1
+ {"version":3,"file":"memory-engine.d.ts","sourceRoot":"","sources":["../src/memory-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EACpD,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAC5D,iBAAiB,EAAE,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EACzE,MAAM,oBAAoB,CAAC;AAQ5B,qBAAa,YAAa,YAAW,aAAa;IAChD,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,QAAQ,CAAoB;IACpC,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,KAAK,CAAa;gBAEd,QAAQ,EAAE,MAAM;IAO5B,OAAO,CAAC,YAAY,CAA8B;YAEpC,UAAU;IASlB,kBAAkB,IAAI,OAAO,CAAC,SAAS,CAAC;IAIxC,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlE,iBAAiB,IAAI,OAAO,CAAC,cAAc,CAAC;IAc5C,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/D,kBAAkB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAK3C,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAI5C,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxE,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAIrD,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9C,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAYtD,YAAY,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvD,MAAM;;;;;IASN,aAAa,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAW3C,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3C,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM1C,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAKnF,YAAY,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAiBjE,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,iBAAiB,EAAE,IAAI,GAAG,WAAW,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAkCpG,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,iBAAiB,EAAE,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC,kBAAkB,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAIlD,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC,eAAe,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IA0BrF,eAAe;IAIrB,KAAK,IAAI,IAAI;CAGd"}
@@ -1,135 +1,201 @@
1
- import { extractCandidates } from "./extractor.js";
1
+ import { MemoryStore } from './memory-store.js';
2
+ import { EmbeddingProvider } from './embedding-provider.js';
3
+ import { HybridSearch } from './hybrid-search.js';
4
+ import { GraphStore } from './graph-store.js';
5
+ import { extractMemories } from './extractor.js';
6
+ import { checkOllama } from './ollama-checker.js';
2
7
  export class MemoryEngine {
3
- provider;
4
- userPrefsKey = "user:prefs";
5
- projectCtxKey = "project:context";
6
- candidatesKey = "memory:candidates";
7
- constructor(provider) {
8
- this.provider = provider;
9
- }
10
- // --- User Memory ---
8
+ store;
9
+ embedder;
10
+ searcher;
11
+ graph;
12
+ constructor(rootPath) {
13
+ this.store = new MemoryStore(rootPath);
14
+ this.embedder = new EmbeddingProvider();
15
+ this.searcher = new HybridSearch(this.store, this.embedder);
16
+ this.graph = new GraphStore(this.store);
17
+ }
18
+ _initPromise = null;
19
+ async ensureInit() {
20
+ if (!this._initPromise) {
21
+ this._initPromise = this.embedder.initialize();
22
+ }
23
+ return this._initPromise;
24
+ }
25
+ // --- Backward-compatible existing API ---
11
26
  async getUserPreferences() {
12
- const raw = await this.provider.kvGet(this.userPrefsKey);
13
- if (raw)
14
- return raw;
15
27
  return { preferences: {}, stack: [] };
16
28
  }
17
- async updateUserPreference(key, value) {
18
- const prefs = await this.getUserPreferences();
19
- prefs.preferences[key] = value;
20
- await this.provider.kvSet(this.userPrefsKey, prefs);
29
+ async updateUserPreference(_key, _value) {
30
+ // User preferences kept minimal — not stored in memory system
21
31
  }
22
- // --- Project Memory ---
23
32
  async getProjectContext() {
24
- const raw = await this.provider.kvGet(this.projectCtxKey);
25
- if (raw)
26
- return raw;
27
- return { stack: [], conventions: [], metadata: {} };
28
- }
29
- async setProjectContext(ctx) {
30
- const current = await this.getProjectContext();
31
- const merged = {
32
- stack: ctx.stack ?? current.stack,
33
- conventions: ctx.conventions ?? current.conventions,
34
- metadata: { ...current.metadata, ...(ctx.metadata ?? {}) },
33
+ const memories = this.store.listByCategory('project_knowledge');
34
+ return {
35
+ stack: [],
36
+ conventions: memories.map(m => ({
37
+ key: m.scope,
38
+ value: m.content,
39
+ source: m.source,
40
+ confidence: m.confidence,
41
+ })),
42
+ metadata: {},
35
43
  };
36
- await this.provider.kvSet(this.projectCtxKey, merged);
44
+ }
45
+ async setProjectContext(_ctx) {
46
+ // Write-through via addMemory; no bulk update needed
37
47
  }
38
48
  async getTeamConventions() {
39
49
  const ctx = await this.getProjectContext();
40
50
  return ctx.conventions;
41
51
  }
42
- // --- Session Memory ---
43
52
  async createSession(task) {
44
- const sessionId = `session:${Date.now()}:${Math.random().toString(36).slice(2, 9)}`;
45
- await this.provider.sessionCreate(sessionId, task);
46
- return sessionId;
53
+ return `session:${Date.now()}:${task.slice(0, 20)}`;
47
54
  }
48
- async appendToSession(sessionId, entry) {
49
- await this.provider.sessionAppend(sessionId, entry);
55
+ async appendToSession(_sessionId, _entry) {
56
+ // Session tracking delegated to existing IDataProvider
50
57
  }
51
58
  async getSession(sessionId) {
52
- const entries = await this.provider.sessionGet(sessionId);
53
- if (entries.length === 0) {
54
- throw new Error(`Session "${sessionId}" not found`);
55
- }
56
- const firstEntry = entries[0];
57
- return {
58
- sessionId,
59
- task: firstEntry.summary,
60
- entries,
61
- createdAt: firstEntry.timestamp,
62
- };
59
+ return { sessionId, task: '', entries: [], createdAt: Date.now() };
63
60
  }
64
61
  async closeSession(sessionId) {
65
- const session = await this.getSession(sessionId);
66
- await this.provider.sessionClose(sessionId);
67
- const newCandidates = extractCandidates(sessionId, session.entries);
68
- const existing = await this.getCandidates();
69
- await this.provider.kvSet(this.candidatesKey, [...existing, ...newCandidates]);
70
- }
71
- // --- Global Memory ---
72
- async searchGlobal(_query) {
73
- const dummyVector = Array.from({ length: 128 }, () => 0);
74
- const results = await this.provider.vectorSearch("global", dummyVector, 10);
75
- return results.map((r) => ({
76
- id: r.id,
77
- source: r.metadata?.source ?? "unknown",
78
- title: r.metadata?.title ?? "",
79
- content: r.metadata?.content ?? "",
80
- embedding: r.metadata?.embedding ?? [],
62
+ void sessionId;
63
+ }
64
+ async searchGlobal(query) {
65
+ await this.ensureInit();
66
+ const results = await this.searcher.search(query, { limit: 10 });
67
+ return results.map(r => ({
68
+ id: r.entry.id,
69
+ source: r.entry.category,
70
+ title: r.entry.content.slice(0, 80),
71
+ content: r.entry.content,
72
+ embedding: [],
81
73
  }));
82
74
  }
83
- async upsertGlobal(entries) {
84
- const points = entries.map((e) => ({
85
- id: e.id,
86
- vector: e.embedding,
87
- metadata: {
88
- source: e.source,
89
- title: e.title,
90
- content: e.content,
91
- embedding: e.embedding,
92
- },
93
- }));
94
- await this.provider.vectorUpsert("global", points);
75
+ async upsertGlobal(_entries) {
76
+ // Individual memories added via addMemory
95
77
  }
96
- // --- Unified ---
97
78
  async getAll() {
98
- const [project, user, relevant] = await Promise.all([
79
+ const [project, user] = await Promise.all([
99
80
  this.getProjectContext(),
100
81
  this.getUserPreferences(),
101
- this.searchGlobal(""),
102
82
  ]);
83
+ const relevant = await this.searchGlobal('');
103
84
  return { project, user, relevant };
104
85
  }
105
- // --- Candidates (persisted to kvStore) ---
106
86
  async getCandidates() {
107
- const raw = await this.provider.kvGet(this.candidatesKey);
108
- if (raw)
109
- return raw;
110
- return [];
87
+ const pending = this.store.getPending();
88
+ return pending.map(m => ({
89
+ id: m.id,
90
+ type: 'project',
91
+ content: { category: m.category, content: m.content, confidence: m.confidence, scope: m.scope },
92
+ confidence: m.confidence,
93
+ source: m.source,
94
+ }));
111
95
  }
112
96
  async approveCandidate(id) {
113
- const candidates = await this.getCandidates();
114
- const idx = candidates.findIndex((c) => c.id === id);
115
- if (idx === -1)
116
- throw new Error(`Candidate "${id}" not found`);
117
- const candidate = candidates[idx];
118
- candidates.splice(idx, 1);
119
- await this.provider.kvSet(this.candidatesKey, candidates);
120
- if (candidate.type === "project") {
121
- const ctx = await this.getProjectContext();
122
- ctx.metadata[candidate.id] = candidate.content;
123
- await this.provider.kvSet(this.projectCtxKey, ctx);
124
- }
97
+ this.store.update(id, { status: 'approved' });
125
98
  }
126
99
  async rejectCandidate(id) {
127
- const candidates = await this.getCandidates();
128
- const idx = candidates.findIndex((c) => c.id === id);
129
- if (idx === -1)
130
- throw new Error(`Candidate "${id}" not found`);
131
- candidates.splice(idx, 1);
132
- await this.provider.kvSet(this.candidatesKey, candidates);
100
+ this.store.delete(id);
101
+ }
102
+ // --- New API methods ---
103
+ async search(query, options) {
104
+ await this.ensureInit();
105
+ return this.searcher.search(query, options);
106
+ }
107
+ async listMemories(filter) {
108
+ const rows = this.store.list(filter);
109
+ return rows.map(r => ({
110
+ id: r.id,
111
+ category: r.category,
112
+ content: r.content,
113
+ originalText: r.original_text ?? undefined,
114
+ source: r.source,
115
+ status: r.status,
116
+ confidence: r.confidence,
117
+ scope: r.scope,
118
+ sessionId: r.session_id ?? undefined,
119
+ createdAt: r.created_at,
120
+ approvedAt: r.approved_at ?? undefined,
121
+ }));
122
+ }
123
+ async addMemory(entry) {
124
+ await this.ensureInit();
125
+ const row = this.store.add({
126
+ category: entry.category,
127
+ content: entry.content,
128
+ originalText: entry.originalText,
129
+ source: entry.source,
130
+ status: 'approved',
131
+ confidence: entry.confidence,
132
+ scope: entry.scope,
133
+ sessionId: entry.sessionId,
134
+ });
135
+ this.embedder.embed(entry.content).then(emb => {
136
+ this.store.insertEmbedding(row.id, emb);
137
+ }).catch(() => { });
138
+ this.graph.buildEdges(row.id).catch(() => { });
139
+ return {
140
+ id: row.id,
141
+ category: row.category,
142
+ content: row.content,
143
+ originalText: row.original_text ?? undefined,
144
+ source: row.source,
145
+ status: row.status,
146
+ confidence: row.confidence,
147
+ scope: row.scope,
148
+ sessionId: row.session_id ?? undefined,
149
+ createdAt: row.created_at,
150
+ approvedAt: row.approved_at ?? undefined,
151
+ };
152
+ }
153
+ async updateMemory(id, updates) {
154
+ this.store.update(id, updates);
155
+ }
156
+ async deleteMemory(id) {
157
+ this.store.delete(id);
158
+ }
159
+ async getPendingMemories() {
160
+ return this.listMemories({ status: 'pending' });
161
+ }
162
+ async approveMemory(id) {
163
+ this.store.update(id, { status: 'approved' });
164
+ }
165
+ async rejectMemory(id) {
166
+ this.store.delete(id);
167
+ }
168
+ async extractMemories(events) {
169
+ await this.ensureInit();
170
+ const ollamaStatus = await checkOllama();
171
+ const candidates = await extractMemories(events, ollamaStatus);
172
+ const saved = [];
173
+ for (const c of candidates) {
174
+ const entry = await this.addMemory({
175
+ category: c.category,
176
+ content: c.content,
177
+ originalText: c.originalText,
178
+ source: 'auto',
179
+ confidence: c.confidence,
180
+ scope: '',
181
+ });
182
+ if (c.confidence >= 0.8) {
183
+ await this.approveMemory(entry.id);
184
+ entry.status = 'approved';
185
+ }
186
+ else {
187
+ this.store.update(entry.id, { status: 'pending' });
188
+ entry.status = 'pending';
189
+ }
190
+ saved.push(entry);
191
+ }
192
+ return saved;
193
+ }
194
+ async getOllamaStatus() {
195
+ return checkOllama();
196
+ }
197
+ close() {
198
+ this.store.close();
133
199
  }
134
200
  }
135
201
  //# sourceMappingURL=memory-engine.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"memory-engine.js","sourceRoot":"","sources":["../src/memory-engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"memory-engine.js","sourceRoot":"","sources":["../src/memory-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ export interface MemoryRow {
2
+ id: string;
3
+ category: string;
4
+ content: string;
5
+ original_text: string | null;
6
+ source: string;
7
+ status: string;
8
+ confidence: number;
9
+ scope: string;
10
+ session_id: string | null;
11
+ created_at: number;
12
+ approved_at: number | null;
13
+ }
14
+ export declare class MemoryStore {
15
+ private db;
16
+ constructor(rootPath: string);
17
+ add(entry: {
18
+ id?: string;
19
+ category: string;
20
+ content: string;
21
+ originalText?: string;
22
+ source?: string;
23
+ status?: string;
24
+ confidence?: number;
25
+ scope?: string;
26
+ sessionId?: string;
27
+ }): MemoryRow;
28
+ get(id: string): MemoryRow | null;
29
+ update(id: string, updates: {
30
+ content?: string;
31
+ status?: string;
32
+ scope?: string;
33
+ }): void;
34
+ delete(id: string): void;
35
+ list(filter?: {
36
+ category?: string;
37
+ status?: string;
38
+ scope?: string;
39
+ }): MemoryRow[];
40
+ getPending(): MemoryRow[];
41
+ listByCategory(category: string, limit?: number): MemoryRow[];
42
+ insertEmbedding(id: string, embedding: Float32Array): void;
43
+ searchBM25(query: string, limit?: number): Array<{
44
+ id: string;
45
+ rank: number;
46
+ }>;
47
+ searchVector(embedding: Float32Array, limit?: number): Array<{
48
+ id: string;
49
+ distance: number;
50
+ }>;
51
+ addEdge(sourceId: string, targetId: string, relation: string, weight?: number): void;
52
+ getNeighbors(id: string): Array<{
53
+ targetId: string;
54
+ relation: string;
55
+ weight: number;
56
+ }>;
57
+ close(): void;
58
+ }
59
+ //# sourceMappingURL=memory-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-store.d.ts","sourceRoot":"","sources":["../src/memory-store.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAqDD,qBAAa,WAAW;IACtB,OAAO,CAAC,EAAE,CAAoB;gBAElB,QAAQ,EAAE,MAAM;IAa5B,GAAG,CAAC,KAAK,EAAE;QACT,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,SAAS;IAab,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAKjC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAYxF,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAIxB,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,EAAE;IAUlF,UAAU,IAAI,SAAS,EAAE;IAIzB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,SAAM,GAAG,SAAS,EAAE;IAM1D,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,GAAG,IAAI;IAK1D,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAW1E,YAAY,CAAC,SAAS,EAAE,YAAY,EAAE,KAAK,SAAK,GAAG,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAY1F,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAM,GAAG,IAAI;IAMjF,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAOvF,KAAK,IAAI,IAAI;CAGd"}
@@ -0,0 +1,173 @@
1
+ import Database from 'better-sqlite3';
2
+ import * as sqliteVec from 'sqlite-vec';
3
+ import { join } from 'node:path';
4
+ import { existsSync, mkdirSync } from 'node:fs';
5
+ import { randomUUID } from 'node:crypto';
6
+ const SCHEMA = `
7
+ CREATE TABLE IF NOT EXISTS memories (
8
+ id TEXT PRIMARY KEY,
9
+ category TEXT NOT NULL CHECK(category IN ('mcp_correction','project_knowledge','failure_lesson')),
10
+ content TEXT NOT NULL,
11
+ original_text TEXT,
12
+ source TEXT NOT NULL DEFAULT 'auto',
13
+ status TEXT NOT NULL DEFAULT 'pending' CHECK(status IN ('pending','approved','rejected')),
14
+ confidence REAL NOT NULL DEFAULT 0.5,
15
+ scope TEXT NOT NULL DEFAULT '',
16
+ session_id TEXT,
17
+ created_at INTEGER NOT NULL,
18
+ approved_at INTEGER
19
+ );
20
+
21
+ CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(
22
+ id UNINDEXED,
23
+ content,
24
+ scope,
25
+ tokenize='porter unicode61'
26
+ );
27
+
28
+ CREATE VIRTUAL TABLE IF NOT EXISTS memories_vec USING vec0(
29
+ id TEXT PRIMARY KEY,
30
+ embedding FLOAT[384]
31
+ );
32
+
33
+ CREATE TABLE IF NOT EXISTS memory_edges (
34
+ source_id TEXT NOT NULL,
35
+ target_id TEXT NOT NULL,
36
+ relation TEXT NOT NULL,
37
+ weight REAL DEFAULT 1.0,
38
+ PRIMARY KEY (source_id, target_id, relation),
39
+ FOREIGN KEY (source_id) REFERENCES memories(id) ON DELETE CASCADE,
40
+ FOREIGN KEY (target_id) REFERENCES memories(id) ON DELETE CASCADE
41
+ );
42
+ `;
43
+ const FTS_TRIGGERS = `
44
+ CREATE TRIGGER IF NOT EXISTS memories_ai AFTER INSERT ON memories BEGIN
45
+ INSERT INTO memories_fts(id, content, scope) VALUES (new.id, new.content, new.scope);
46
+ END;
47
+ CREATE TRIGGER IF NOT EXISTS memories_ad AFTER DELETE ON memories BEGIN
48
+ INSERT INTO memories_fts(memories_fts, id, content, scope) VALUES('delete', old.id, old.content, old.scope);
49
+ END;
50
+ CREATE TRIGGER IF NOT EXISTS memories_au AFTER UPDATE ON memories BEGIN
51
+ INSERT INTO memories_fts(memories_fts, id, content, scope) VALUES('delete', old.id, old.content, old.scope);
52
+ INSERT INTO memories_fts(id, content, scope) VALUES (new.id, new.content, new.scope);
53
+ END;
54
+ `;
55
+ export class MemoryStore {
56
+ db;
57
+ constructor(rootPath) {
58
+ const memDir = join(rootPath, '.devflow', 'memory');
59
+ if (!existsSync(memDir))
60
+ mkdirSync(memDir, { recursive: true });
61
+ const dbPath = join(memDir, 'memories.db');
62
+ this.db = new Database(dbPath);
63
+ this.db.pragma('journal_mode = WAL');
64
+ this.db.pragma('busy_timeout = 5000');
65
+ this.db.pragma('foreign_keys = ON');
66
+ sqliteVec.load(this.db);
67
+ this.db.exec(SCHEMA);
68
+ this.db.exec(FTS_TRIGGERS);
69
+ }
70
+ add(entry) {
71
+ const id = entry.id ?? `mem:${Date.now()}:${randomUUID().slice(0, 8)}`;
72
+ const now = Date.now();
73
+ const approvedAt = entry.status === 'approved' ? now : null;
74
+ this.db.prepare(`
75
+ INSERT INTO memories (id, category, content, original_text, source, status, confidence, scope, session_id, created_at, approved_at)
76
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
77
+ `).run(id, entry.category, entry.content, entry.originalText ?? null, entry.source ?? 'auto', entry.status ?? 'pending', entry.confidence ?? 0.5, entry.scope ?? '', entry.sessionId ?? null, now, approvedAt);
78
+ return this.get(id);
79
+ }
80
+ get(id) {
81
+ const row = this.db.prepare('SELECT * FROM memories WHERE id = ?').get(id);
82
+ return row ?? null;
83
+ }
84
+ update(id, updates) {
85
+ const sets = [];
86
+ const vals = [];
87
+ if (updates.content !== undefined) {
88
+ sets.push('content = ?');
89
+ vals.push(updates.content);
90
+ }
91
+ if (updates.status !== undefined) {
92
+ sets.push('status = ?');
93
+ vals.push(updates.status);
94
+ }
95
+ if (updates.scope !== undefined) {
96
+ sets.push('scope = ?');
97
+ vals.push(updates.scope);
98
+ }
99
+ if (updates.status === 'approved') {
100
+ sets.push('approved_at = ?');
101
+ vals.push(Date.now());
102
+ }
103
+ if (sets.length === 0)
104
+ return;
105
+ vals.push(id);
106
+ this.db.prepare(`UPDATE memories SET ${sets.join(', ')} WHERE id = ?`).run(...vals);
107
+ }
108
+ delete(id) {
109
+ this.db.prepare('DELETE FROM memories WHERE id = ?').run(id);
110
+ }
111
+ list(filter) {
112
+ let sql = 'SELECT * FROM memories WHERE 1=1';
113
+ const vals = [];
114
+ if (filter?.category) {
115
+ sql += ' AND category = ?';
116
+ vals.push(filter.category);
117
+ }
118
+ if (filter?.status) {
119
+ sql += ' AND status = ?';
120
+ vals.push(filter.status);
121
+ }
122
+ if (filter?.scope) {
123
+ sql += ' AND scope = ?';
124
+ vals.push(filter.scope);
125
+ }
126
+ sql += ' ORDER BY created_at DESC';
127
+ return this.db.prepare(sql).all(...vals);
128
+ }
129
+ getPending() {
130
+ return this.list({ status: 'pending' });
131
+ }
132
+ listByCategory(category, limit = 100) {
133
+ return this.db.prepare('SELECT * FROM memories WHERE category = ? AND status = ? ORDER BY created_at DESC LIMIT ?').all(category, 'approved', limit);
134
+ }
135
+ insertEmbedding(id, embedding) {
136
+ const buffer = Buffer.from(embedding.buffer);
137
+ this.db.prepare('INSERT OR REPLACE INTO memories_vec(id, embedding) VALUES (?, ?)').run(id, buffer);
138
+ }
139
+ searchBM25(query, limit = 20) {
140
+ const rows = this.db.prepare(`
141
+ SELECT m.id, rank
142
+ FROM memories_fts f
143
+ JOIN memories m ON m.id = f.id
144
+ WHERE memories_fts MATCH ? AND m.status = 'approved'
145
+ ORDER BY rank LIMIT ?
146
+ `).all(query, limit);
147
+ return rows;
148
+ }
149
+ searchVector(embedding, limit = 20) {
150
+ const buffer = Buffer.from(embedding.buffer);
151
+ const rows = this.db.prepare(`
152
+ SELECT v.id, vec_distance(v.embedding, ?) as distance
153
+ FROM memories_vec v
154
+ JOIN memories m ON m.id = v.id
155
+ WHERE m.status = 'approved'
156
+ ORDER BY distance LIMIT ?
157
+ `).all(buffer, limit);
158
+ return rows;
159
+ }
160
+ addEdge(sourceId, targetId, relation, weight = 1.0) {
161
+ this.db.prepare(`
162
+ INSERT OR REPLACE INTO memory_edges (source_id, target_id, relation, weight) VALUES (?, ?, ?, ?)
163
+ `).run(sourceId, targetId, relation, weight);
164
+ }
165
+ getNeighbors(id) {
166
+ return this.db.prepare('SELECT target_id, relation, weight FROM memory_edges WHERE source_id = ?').all(id)
167
+ .map(r => ({ targetId: r.target_id, relation: r.relation, weight: r.weight }));
168
+ }
169
+ close() {
170
+ this.db.close();
171
+ }
172
+ }
173
+ //# sourceMappingURL=memory-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-store.js","sourceRoot":"","sources":["../src/memory-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export interface OllamaStatus {
2
+ installed: boolean;
3
+ running: boolean;
4
+ modelAvailable: boolean;
5
+ modelName: string;
6
+ }
7
+ export declare function checkOllama(modelName?: string): Promise<OllamaStatus>;
8
+ export declare function getOllamaInfoMessage(status: OllamaStatus): string | null;
9
+ export declare function generateWithOllama(prompt: string, system?: string, modelName?: string): Promise<string>;
10
+ //# sourceMappingURL=ollama-checker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollama-checker.d.ts","sourceRoot":"","sources":["../src/ollama-checker.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,wBAAsB,WAAW,CAAC,SAAS,GAAE,MAAsB,GAAG,OAAO,CAAC,YAAY,CAAC,CAiB1F;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAKxE;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,GAAE,MAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,CAS5H"}
@@ -0,0 +1,43 @@
1
+ import { execSync } from 'node:child_process';
2
+ const DEFAULT_MODEL = 'llama3.2';
3
+ export async function checkOllama(modelName = DEFAULT_MODEL) {
4
+ const status = { installed: false, running: false, modelAvailable: false, modelName };
5
+ try {
6
+ execSync('which ollama', { stdio: 'pipe' });
7
+ status.installed = true;
8
+ }
9
+ catch {
10
+ return status;
11
+ }
12
+ try {
13
+ const resp = await fetch('http://localhost:11434/api/tags');
14
+ if (resp.ok) {
15
+ status.running = true;
16
+ const data = await resp.json();
17
+ status.modelAvailable = (data.models ?? []).some(m => m.name.startsWith(modelName));
18
+ }
19
+ }
20
+ catch { /* server not running */ }
21
+ return status;
22
+ }
23
+ export function getOllamaInfoMessage(status) {
24
+ if (!status.installed)
25
+ return 'Ollama not installed. Install from https://ollama.com/download then run: ollama pull llama3.2';
26
+ if (!status.running)
27
+ return 'Ollama installed but not running. Start it with: ollama serve';
28
+ if (!status.modelAvailable)
29
+ return `Model ${status.modelName} not pulled. Run: ollama pull ${status.modelName}`;
30
+ return null;
31
+ }
32
+ export async function generateWithOllama(prompt, system, modelName = DEFAULT_MODEL) {
33
+ const resp = await fetch('http://localhost:11434/api/generate', {
34
+ method: 'POST',
35
+ headers: { 'Content-Type': 'application/json' },
36
+ body: JSON.stringify({ model: modelName, prompt, system, stream: false }),
37
+ });
38
+ if (!resp.ok)
39
+ throw new Error(`Ollama generate failed: ${resp.status} ${await resp.text()}`);
40
+ const data = await resp.json();
41
+ return data.response;
42
+ }
43
+ //# sourceMappingURL=ollama-checker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollama-checker.js","sourceRoot":"","sources":["../src/ollama-checker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAS9C,MAAM,aAAa,GAAG,UAAU,CAAC;AAEjC,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,YAAoB,aAAa;IACjE,MAAM,MAAM,GAAiB,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IACpG,IAAI,CAAC;QACH,QAAQ,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAC5C,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,iCAAiC,CAAC,CAAC;QAC5D,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;YACtB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAA0C,CAAC;YACvE,MAAM,CAAC,cAAc,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;QACtF,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,wBAAwB,CAAC,CAAC;IACpC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAoB;IACvD,IAAI,CAAC,MAAM,CAAC,SAAS;QAAE,OAAO,+FAA+F,CAAC;IAC9H,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,+DAA+D,CAAC;IAC5F,IAAI,CAAC,MAAM,CAAC,cAAc;QAAE,OAAO,SAAS,MAAM,CAAC,SAAS,iCAAiC,MAAM,CAAC,SAAS,EAAE,CAAC;IAChH,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAc,EAAE,MAAe,EAAE,YAAoB,aAAa;IACzG,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,qCAAqC,EAAE;QAC9D,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;KAC1E,CAAC,CAAC;IACH,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,IAAI,CAAC,MAAM,IAAI,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC7F,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAA0B,CAAC;IACvD,OAAO,IAAI,CAAC,QAAQ,CAAC;AACvB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devflow-tools/memory-engine",
3
- "version": "0.8.1",
3
+ "version": "0.8.3",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -17,15 +17,18 @@
17
17
  "clean": "rm -rf dist"
18
18
  },
19
19
  "dependencies": {
20
- "@devflow-tools/sdk": "^0.8.1"
20
+ "@devflow-tools/sdk": "^0.8.3",
21
+ "better-sqlite3": "^12.0.0",
22
+ "sqlite-vec": "^0.1.9",
23
+ "@xenova/transformers": "^2.17.0"
21
24
  },
22
25
  "devDependencies": {
23
- "@devflow-tools/knowledge-engine": "^0.8.1",
26
+ "@devflow-tools/knowledge-engine": "^0.8.3",
24
27
  "typescript": "^5.5.0",
25
28
  "vitest": "^2.0.0"
26
29
  },
27
30
  "files": [
28
31
  "dist"
29
32
  ],
30
- "gitHead": "08e47047445ba2b8112669608264af9971627138"
33
+ "gitHead": "5c9a804d3c2e6e6822b516fde67d5b789dbdb5b3"
31
34
  }