memgrid 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/LICENSE +21 -0
  3. package/README.md +251 -0
  4. package/dist/index.d.ts +2 -0
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.js +2 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/learn/index.d.ts +44 -0
  9. package/dist/learn/index.d.ts.map +1 -0
  10. package/dist/learn/index.js +234 -0
  11. package/dist/learn/index.js.map +1 -0
  12. package/dist/memgrid.d.ts +50 -0
  13. package/dist/memgrid.d.ts.map +1 -0
  14. package/dist/memgrid.js +175 -0
  15. package/dist/memgrid.js.map +1 -0
  16. package/dist/retrieve/index.d.ts +27 -0
  17. package/dist/retrieve/index.d.ts.map +1 -0
  18. package/dist/retrieve/index.js +209 -0
  19. package/dist/retrieve/index.js.map +1 -0
  20. package/dist/retrieve/semantic.d.ts +67 -0
  21. package/dist/retrieve/semantic.d.ts.map +1 -0
  22. package/dist/retrieve/semantic.js +240 -0
  23. package/dist/retrieve/semantic.js.map +1 -0
  24. package/dist/scanner/composite.d.ts +27 -0
  25. package/dist/scanner/composite.d.ts.map +1 -0
  26. package/dist/scanner/composite.js +58 -0
  27. package/dist/scanner/composite.js.map +1 -0
  28. package/dist/scanner/config.d.ts +15 -0
  29. package/dist/scanner/config.d.ts.map +1 -0
  30. package/dist/scanner/config.js +167 -0
  31. package/dist/scanner/config.js.map +1 -0
  32. package/dist/scanner/golang.d.ts +19 -0
  33. package/dist/scanner/golang.d.ts.map +1 -0
  34. package/dist/scanner/golang.js +190 -0
  35. package/dist/scanner/golang.js.map +1 -0
  36. package/dist/scanner/index.d.ts +11 -0
  37. package/dist/scanner/index.d.ts.map +1 -0
  38. package/dist/scanner/index.js +10 -0
  39. package/dist/scanner/index.js.map +1 -0
  40. package/dist/scanner/javascript.d.ts +20 -0
  41. package/dist/scanner/javascript.d.ts.map +1 -0
  42. package/dist/scanner/javascript.js +167 -0
  43. package/dist/scanner/javascript.js.map +1 -0
  44. package/dist/scanner/markdown.d.ts +17 -0
  45. package/dist/scanner/markdown.d.ts.map +1 -0
  46. package/dist/scanner/markdown.js +106 -0
  47. package/dist/scanner/markdown.js.map +1 -0
  48. package/dist/scanner/python.d.ts +19 -0
  49. package/dist/scanner/python.d.ts.map +1 -0
  50. package/dist/scanner/python.js +177 -0
  51. package/dist/scanner/python.js.map +1 -0
  52. package/dist/scanner/rules.d.ts +15 -0
  53. package/dist/scanner/rules.d.ts.map +1 -0
  54. package/dist/scanner/rules.js +86 -0
  55. package/dist/scanner/rules.js.map +1 -0
  56. package/dist/scanner/rust.d.ts +18 -0
  57. package/dist/scanner/rust.d.ts.map +1 -0
  58. package/dist/scanner/rust.js +178 -0
  59. package/dist/scanner/rust.js.map +1 -0
  60. package/dist/scanner/scanner.d.ts +33 -0
  61. package/dist/scanner/scanner.d.ts.map +1 -0
  62. package/dist/scanner/scanner.js +2 -0
  63. package/dist/scanner/scanner.js.map +1 -0
  64. package/dist/scanner/typescript.d.ts +28 -0
  65. package/dist/scanner/typescript.d.ts.map +1 -0
  66. package/dist/scanner/typescript.js +522 -0
  67. package/dist/scanner/typescript.js.map +1 -0
  68. package/dist/serve/cli.d.ts +3 -0
  69. package/dist/serve/cli.d.ts.map +1 -0
  70. package/dist/serve/cli.js +145 -0
  71. package/dist/serve/cli.js.map +1 -0
  72. package/dist/serve/mcp-server.d.ts +11 -0
  73. package/dist/serve/mcp-server.d.ts.map +1 -0
  74. package/dist/serve/mcp-server.js +276 -0
  75. package/dist/serve/mcp-server.js.map +1 -0
  76. package/dist/shared/constants.d.ts +2 -0
  77. package/dist/shared/constants.d.ts.map +1 -0
  78. package/dist/shared/constants.js +2 -0
  79. package/dist/shared/constants.js.map +1 -0
  80. package/dist/shared/types.d.ts +99 -0
  81. package/dist/shared/types.d.ts.map +1 -0
  82. package/dist/shared/types.js +3 -0
  83. package/dist/shared/types.js.map +1 -0
  84. package/dist/store/file-store.d.ts +62 -0
  85. package/dist/store/file-store.d.ts.map +1 -0
  86. package/dist/store/file-store.js +241 -0
  87. package/dist/store/file-store.js.map +1 -0
  88. package/dist/store/index.d.ts +3 -0
  89. package/dist/store/index.d.ts.map +1 -0
  90. package/dist/store/index.js +2 -0
  91. package/dist/store/index.js.map +1 -0
  92. package/dist/sync/index.d.ts +56 -0
  93. package/dist/sync/index.d.ts.map +1 -0
  94. package/dist/sync/index.js +580 -0
  95. package/dist/sync/index.js.map +1 -0
  96. package/package.json +51 -0
@@ -0,0 +1,50 @@
1
+ import type { MemoryUnit, ScanOptions, SearchOptions, SearchResult, SyncOptions, SyncResult } from './shared/types.js';
2
+ import { FileStore } from './store/file-store.js';
3
+ import { type Scanner } from './scanner/index.js';
4
+ import { RetrieveEngine } from './retrieve/index.js';
5
+ import { SemanticRetriever, type EmbeddingProvider } from './retrieve/semantic.js';
6
+ import { LearnEngine, type TaskResult, type LearningSuggestions } from './learn/index.js';
7
+ import { SyncEngine } from './sync/index.js';
8
+ export declare class MemGrid {
9
+ store: FileStore;
10
+ scanner: Scanner;
11
+ retrieve: RetrieveEngine;
12
+ semantic: SemanticRetriever;
13
+ learn: LearnEngine;
14
+ syncEngine: SyncEngine;
15
+ projectRoot: string;
16
+ constructor(projectRoot: string, provider?: EmbeddingProvider, scanner?: Scanner);
17
+ init(options: ScanOptions): Promise<MemoryUnit[]>;
18
+ /**
19
+ * Generate and persist fileSnapshot for all scanned files.
20
+ * Done once on init; sync() diffs against this baseline.
21
+ */
22
+ private saveFileSnapshot;
23
+ search(query: string, options?: SearchOptions): Promise<SearchResult>;
24
+ add(unit: Partial<MemoryUnit> & {
25
+ id: string;
26
+ type: MemoryUnit['type'];
27
+ summary: string;
28
+ content: MemoryUnit['content'];
29
+ }): Promise<MemoryUnit>;
30
+ update(id: string, patch: Partial<MemoryUnit>): Promise<MemoryUnit | null>;
31
+ archive(id: string): Promise<void>;
32
+ context(result: SearchResult): string;
33
+ analyzeTask(task: TaskResult): Promise<LearningSuggestions>;
34
+ applySuggestions(suggestions: LearningSuggestions): Promise<string[]>;
35
+ formatSuggestions(suggestions: LearningSuggestions): string;
36
+ /**
37
+ * Incremental sync — re-scan only changed files and repair associations.
38
+ * Much faster than full init() when only a few files changed.
39
+ */
40
+ sync(options: SyncOptions): Promise<SyncResult>;
41
+ stats(): Promise<{
42
+ lastScanAt: string | null;
43
+ version: string;
44
+ totalUnits: number;
45
+ activeUnits: number;
46
+ archivedUnits: number;
47
+ typeDistribution: Record<string, number>;
48
+ }>;
49
+ }
50
+ //# sourceMappingURL=memgrid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memgrid.d.ts","sourceRoot":"","sources":["../src/memgrid.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAgB,MAAM,mBAAmB,CAAC;AACrI,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAKL,KAAK,OAAO,EACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,KAAK,iBAAiB,EAA4B,MAAM,wBAAwB,CAAC;AAC7G,OAAO,EAAE,WAAW,EAAE,KAAK,UAAU,EAAE,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC1F,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,qBAAa,OAAO;IAClB,KAAK,EAAE,SAAS,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,cAAc,CAAC;IACzB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,KAAK,EAAE,WAAW,CAAC;IACnB,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;gBAER,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,iBAAiB,EAAE,OAAO,CAAC,EAAE,OAAO;IAW1E,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAiCvD;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAmDlB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IASrE,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,UAAU,CAAC,SAAS,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IAmB/I,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAW1E,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,OAAO,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM;IAI/B,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAI3D,gBAAgB,CAAC,WAAW,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAI3E,iBAAiB,CAAC,WAAW,EAAE,mBAAmB,GAAG,MAAM;IAI3D;;;OAGG;IACG,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAI/C,KAAK;;;;;;;;CAUZ"}
@@ -0,0 +1,175 @@
1
+ import * as fs from 'fs';
2
+ import * as crypto from 'crypto';
3
+ import * as path from 'path';
4
+ import { FileStore } from './store/file-store.js';
5
+ import { TypeScriptScanner, RulesScanner, ConfigScanner, MarkdownScanner, } from './scanner/index.js';
6
+ import { RetrieveEngine } from './retrieve/index.js';
7
+ import { SemanticRetriever, KeywordEmbeddingProvider } from './retrieve/semantic.js';
8
+ import { LearnEngine } from './learn/index.js';
9
+ import { SyncEngine } from './sync/index.js';
10
+ export class MemGrid {
11
+ store;
12
+ scanner;
13
+ retrieve;
14
+ semantic;
15
+ learn;
16
+ syncEngine;
17
+ projectRoot;
18
+ constructor(projectRoot, provider, scanner) {
19
+ this.projectRoot = projectRoot;
20
+ this.store = new FileStore(projectRoot);
21
+ // Accept optional scanner injection, default to TypeScript
22
+ this.scanner = scanner ?? new TypeScriptScanner(this.store, projectRoot);
23
+ this.retrieve = new RetrieveEngine(this.store);
24
+ this.semantic = new SemanticRetriever(this.store, provider || new KeywordEmbeddingProvider());
25
+ this.learn = new LearnEngine(this.store);
26
+ this.syncEngine = new SyncEngine(this.store, this.scanner, projectRoot);
27
+ }
28
+ async init(options) {
29
+ // Load existing cache first (if any)
30
+ this.store.load();
31
+ // Run language scanner
32
+ const units = await this.scanner.scan(options);
33
+ // Run universal scanners (rules, config, markdown) in parallel
34
+ const universalScans = [];
35
+ if (options.includeRules) {
36
+ const rulesScanner = new RulesScanner(this.projectRoot);
37
+ if (rulesScanner.detect(this.projectRoot))
38
+ universalScans.push(rulesScanner.scan(options));
39
+ }
40
+ universalScans.push(new ConfigScanner(this.projectRoot).scan(options));
41
+ const mdScanner = new MarkdownScanner(this.projectRoot);
42
+ if (mdScanner.detect(this.projectRoot))
43
+ universalScans.push(mdScanner.scan(options));
44
+ const universalResults = await Promise.all(universalScans);
45
+ for (const result of universalResults) {
46
+ // Save universal scanner units (language scanner saves its own)
47
+ for (const unit of result) {
48
+ this.store.saveUnit(unit);
49
+ units.push(unit);
50
+ }
51
+ }
52
+ // Build semantic index after scan
53
+ await this.semantic.buildIndex();
54
+ // Record file snapshot for future incremental syncs
55
+ this.saveFileSnapshot(options);
56
+ return units;
57
+ }
58
+ /**
59
+ * Generate and persist fileSnapshot for all scanned files.
60
+ * Done once on init; sync() diffs against this baseline.
61
+ */
62
+ saveFileSnapshot(options) {
63
+ const snapshot = {};
64
+ const sourceExts = new Set(['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs', '.py', '.go', '.rs', '.md']);
65
+ const testPatterns = ['.spec.', '.test.', '_test.'];
66
+ const collectHashes = (dir) => {
67
+ if (!fs.existsSync(dir))
68
+ return;
69
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
70
+ const abs = path.join(dir, entry.name);
71
+ const rel = path.relative(this.projectRoot, abs);
72
+ if (entry.isDirectory()) {
73
+ const skipDirs = new Set(['node_modules', 'dist', '.next', 'vendor', 'target', '__pycache__']);
74
+ if (!skipDirs.has(entry.name) && !entry.name.startsWith('.')) {
75
+ collectHashes(abs);
76
+ }
77
+ }
78
+ else {
79
+ const ext = path.extname(entry.name);
80
+ if (sourceExts.has(ext)) {
81
+ // Skip test files
82
+ if (testPatterns.some((p) => entry.name.includes(p)))
83
+ continue;
84
+ snapshot[rel] = crypto.createHash('sha256').update(fs.readFileSync(abs, 'utf-8')).digest('hex');
85
+ }
86
+ }
87
+ }
88
+ };
89
+ // Scan source dirs
90
+ ['apps', 'packages', 'src', 'lib', 'cmd', 'internal', 'pkg', 'app'].forEach((d) => collectHashes(path.join(this.projectRoot, d)));
91
+ // Rules and examples
92
+ if (options.includeRules)
93
+ collectHashes(path.join(this.projectRoot, '.claude', 'rules'));
94
+ if (options.includeExamples)
95
+ collectHashes(path.join(this.projectRoot, '.claude', 'examples'));
96
+ // Config files
97
+ for (const f of ['package.json', 'pyproject.toml', 'go.mod', 'Cargo.toml', 'docker-compose.yml']) {
98
+ const abs = path.join(this.projectRoot, f);
99
+ if (fs.existsSync(abs)) {
100
+ snapshot[f] = crypto.createHash('sha256').update(fs.readFileSync(abs, 'utf-8')).digest('hex');
101
+ }
102
+ }
103
+ const grid = this.store.getGrid();
104
+ if (grid) {
105
+ grid.fileSnapshot = snapshot;
106
+ this.store.saveGrid(grid);
107
+ }
108
+ }
109
+ async search(query, options) {
110
+ const result = await this.semantic.search(query, options);
111
+ // Touch usage counts for retrieved units (in-memory, periodically flushed)
112
+ for (const unit of result.units) {
113
+ this.store.touch(unit.id);
114
+ }
115
+ return result;
116
+ }
117
+ async add(unit) {
118
+ const fullUnit = {
119
+ ...unit,
120
+ signatures: unit.signatures || [],
121
+ associations: unit.associations || [],
122
+ meta: {
123
+ created: new Date().toISOString(),
124
+ updated: new Date().toISOString(),
125
+ confidence: unit.meta?.confidence ?? 0.7,
126
+ usage_count: 0,
127
+ status: 'active',
128
+ },
129
+ };
130
+ this.store.ensureDirs();
131
+ this.store.saveUnit(fullUnit);
132
+ return fullUnit;
133
+ }
134
+ async update(id, patch) {
135
+ const unit = this.store.getUnit(id);
136
+ if (!unit)
137
+ return null;
138
+ Object.assign(unit, patch);
139
+ unit.meta.updated = new Date().toISOString();
140
+ this.store.saveUnit(unit);
141
+ return unit;
142
+ }
143
+ async archive(id) {
144
+ this.store.archiveUnit(id);
145
+ }
146
+ context(result) {
147
+ return this.semantic.toContext(result);
148
+ }
149
+ async analyzeTask(task) {
150
+ return await this.learn.analyze(task);
151
+ }
152
+ async applySuggestions(suggestions) {
153
+ return await this.learn.apply(suggestions);
154
+ }
155
+ formatSuggestions(suggestions) {
156
+ return this.learn.formatSuggestions(suggestions);
157
+ }
158
+ /**
159
+ * Incremental sync — re-scan only changed files and repair associations.
160
+ * Much faster than full init() when only a few files changed.
161
+ */
162
+ async sync(options) {
163
+ return this.syncEngine.sync(options);
164
+ }
165
+ async stats() {
166
+ const cached = this.store.getStats();
167
+ const grid = this.store.getGrid();
168
+ return {
169
+ ...cached,
170
+ lastScanAt: grid?.lastScanAt || null,
171
+ version: grid?.version || '0.1.0',
172
+ };
173
+ }
174
+ }
175
+ //# sourceMappingURL=memgrid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memgrid.js","sourceRoot":"","sources":["../src/memgrid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,eAAe,GAEhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAA0B,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAC7G,OAAO,EAAE,WAAW,EAA6C,MAAM,kBAAkB,CAAC;AAC1F,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,MAAM,OAAO,OAAO;IAClB,KAAK,CAAY;IACjB,OAAO,CAAU;IACjB,QAAQ,CAAiB;IACzB,QAAQ,CAAoB;IAC5B,KAAK,CAAc;IACnB,UAAU,CAAa;IACvB,WAAW,CAAS;IAEpB,YAAY,WAAmB,EAAE,QAA4B,EAAE,OAAiB;QAC9E,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,KAAK,GAAG,IAAI,SAAS,CAAC,WAAW,CAAC,CAAC;QACxC,2DAA2D;QAC3D,IAAI,CAAC,OAAO,GAAG,OAAO,IAAI,IAAI,iBAAiB,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QACzE,IAAI,CAAC,QAAQ,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,CAAC,QAAQ,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,IAAI,IAAI,wBAAwB,EAAE,CAAC,CAAC;QAC9F,IAAI,CAAC,KAAK,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAC1E,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAoB;QAC7B,qCAAqC;QACrC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAElB,uBAAuB;QACvB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAE/C,+DAA+D;QAC/D,MAAM,cAAc,GAA4B,EAAE,CAAC;QACnD,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;YACzB,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACxD,IAAI,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC;gBAAE,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAC7F,CAAC;QACD,cAAc,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QACvE,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACxD,IAAI,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC;YAAE,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAErF,MAAM,gBAAgB,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAC3D,KAAK,MAAM,MAAM,IAAI,gBAAgB,EAAE,CAAC;YACtC,gEAAgE;YAChE,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;gBAC1B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC1B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,CAAC;QACH,CAAC;QAED,kCAAkC;QAClC,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;QACjC,oDAAoD;QACpD,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;OAGG;IACK,gBAAgB,CAAC,OAAoB;QAC3C,MAAM,QAAQ,GAAiB,EAAE,CAAC;QAElC,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QACvG,MAAM,YAAY,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAEpD,MAAM,aAAa,GAAG,CAAC,GAAW,EAAE,EAAE;YACpC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,OAAO;YAChC,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;gBACjE,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBACvC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;gBACjD,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;oBACxB,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC;oBAC/F,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBAC7D,aAAa,CAAC,GAAG,CAAC,CAAC;oBACrB,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBACrC,IAAI,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;wBACxB,kBAAkB;wBAClB,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;4BAAE,SAAS;wBAC/D,QAAQ,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBAClG,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC,CAAC;QAEF,mBAAmB;QACnB,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,OAAO,CACzE,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CACrD,CAAC;QAEF,qBAAqB;QACrB,IAAI,OAAO,CAAC,YAAY;YAAE,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;QACzF,IAAI,OAAO,CAAC,eAAe;YAAE,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;QAE/F,eAAe;QACf,KAAK,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,gBAAgB,EAAE,QAAQ,EAAE,YAAY,EAAE,oBAAoB,CAAC,EAAE,CAAC;YACjG,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;YAC3C,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvB,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAChG,CAAC;QACH,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QAClC,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC;YAC7B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,OAAuB;QACjD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC1D,2EAA2E;QAC3E,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAChC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC5B,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,IAAqH;QAC7H,MAAM,QAAQ,GAAe;YAC3B,GAAG,IAAI;YACP,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,EAAE;YACjC,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,EAAE;YACrC,IAAI,EAAE;gBACJ,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACjC,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACjC,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,IAAI,GAAG;gBACxC,WAAW,EAAE,CAAC;gBACd,MAAM,EAAE,QAAQ;aACjB;SACF,CAAC;QAEF,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;QACxB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC9B,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU,EAAE,KAA0B;QACjD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QAEvB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAE7C,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,EAAU;QACtB,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC;IAED,OAAO,CAAC,MAAoB;QAC1B,OAAO,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,IAAgB;QAChC,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,WAAgC;QACrD,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC7C,CAAC;IAED,iBAAiB,CAAC,WAAgC;QAChD,OAAO,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;IACnD,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAI,CAAC,OAAoB;QAC7B,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QAElC,OAAO;YACL,GAAG,MAAM;YACT,UAAU,EAAE,IAAI,EAAE,UAAU,IAAI,IAAI;YACpC,OAAO,EAAE,IAAI,EAAE,OAAO,IAAI,OAAO;SAClC,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,27 @@
1
+ import type { MemoryUnit, SearchResult } from '../shared/types.js';
2
+ import type { FileStore } from '../store/file-store.js';
3
+ export declare class RetrieveEngine {
4
+ private store;
5
+ private index;
6
+ private indexBuilt;
7
+ private unitVersion;
8
+ private resultCache;
9
+ constructor(store: FileStore);
10
+ /**
11
+ * Build MiniSearch index once. Call after init or when units change.
12
+ */
13
+ ensureIndex(): void;
14
+ /**
15
+ * Incremental index update — call when a single unit is added/updated.
16
+ */
17
+ updateIndex(unit: MemoryUnit): void;
18
+ invalidateIndex(): void;
19
+ search(query: string, maxResults?: number, maxHops?: number): Promise<SearchResult>;
20
+ private computeAssociationBonus;
21
+ /**
22
+ * Get units from store's in-memory cache (no disk I/O).
23
+ */
24
+ private getCachedUnits;
25
+ toContext(result: SearchResult): string;
26
+ }
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/retrieve/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAe,MAAM,oBAAoB,CAAC;AAChF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAoBxD,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAK;IAGxB,OAAO,CAAC,WAAW,CAA2C;gBAElD,KAAK,EAAE,SAAS;IAI5B;;OAEG;IACH,WAAW,IAAI,IAAI;IA+BnB;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAcnC,eAAe,IAAI,IAAI;IAMjB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,SAAK,EAAE,OAAO,SAAI,GAAG,OAAO,CAAC,YAAY,CAAC;IAkFhF,OAAO,CAAC,uBAAuB;IAe/B;;OAEG;IACH,OAAO,CAAC,cAAc;IAatB,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM;CAoCxC"}
@@ -0,0 +1,209 @@
1
+ import MiniSearch from 'minisearch';
2
+ /**
3
+ * Simple LRU cache for search results.
4
+ */
5
+ class LRUCache {
6
+ max;
7
+ map = new Map();
8
+ constructor(max = 200) {
9
+ this.max = max;
10
+ }
11
+ get(key) { return this.map.get(key); }
12
+ set(key, value) {
13
+ if (this.map.size >= this.max) {
14
+ const first = this.map.keys().next().value;
15
+ this.map.delete(first);
16
+ }
17
+ this.map.set(key, value);
18
+ }
19
+ clear() { this.map.clear(); }
20
+ }
21
+ export class RetrieveEngine {
22
+ store;
23
+ index = null;
24
+ indexBuilt = false;
25
+ unitVersion = 0; // Incremented on add/update/archive — invalidates index
26
+ // LRU cache: query hash → SearchResult
27
+ resultCache = new LRUCache(200);
28
+ constructor(store) {
29
+ this.store = store;
30
+ }
31
+ /**
32
+ * Build MiniSearch index once. Call after init or when units change.
33
+ */
34
+ ensureIndex() {
35
+ if (this.index && this.indexBuilt)
36
+ return;
37
+ this.index = new MiniSearch({
38
+ fields: ['summary', 'signatures', 'content.description', 'content.trigger', 'content.action'],
39
+ storeFields: ['id'],
40
+ searchOptions: {
41
+ boost: { summary: 5, signatures: 3 },
42
+ prefix: true,
43
+ fuzzy: 0.2,
44
+ },
45
+ });
46
+ // Load from cache (already in memory)
47
+ const units = this.getCachedUnits();
48
+ if (units.length > 0) {
49
+ this.index.addAll(units.map((u) => ({
50
+ id: u.id,
51
+ summary: u.summary,
52
+ signatures: u.signatures.join(' '),
53
+ 'content.description': u.content.description,
54
+ 'content.trigger': u.content.trigger || '',
55
+ 'content.action': u.content.action || '',
56
+ })));
57
+ }
58
+ this.indexBuilt = true;
59
+ }
60
+ /**
61
+ * Incremental index update — call when a single unit is added/updated.
62
+ */
63
+ updateIndex(unit) {
64
+ if (!this.index)
65
+ return;
66
+ this.index.remove(unit.id);
67
+ this.index.add({
68
+ id: unit.id,
69
+ summary: unit.summary,
70
+ signatures: unit.signatures.join(' '),
71
+ 'content.description': unit.content.description,
72
+ 'content.trigger': unit.content.trigger || '',
73
+ 'content.action': unit.content.action || '',
74
+ });
75
+ this.resultCache.clear(); // Invalidate cache on any change
76
+ }
77
+ invalidateIndex() {
78
+ this.index = null;
79
+ this.indexBuilt = false;
80
+ this.resultCache.clear();
81
+ }
82
+ async search(query, maxResults = 10, maxHops = 2) {
83
+ const startTime = Date.now();
84
+ // Check result cache first (exact query match)
85
+ const cacheKey = `${query}::${maxResults}::${maxHops}`;
86
+ const cached = this.resultCache.get(cacheKey);
87
+ if (cached) {
88
+ return { ...cached, elapsedMs: Date.now() - startTime };
89
+ }
90
+ // Ensure index is built
91
+ this.ensureIndex();
92
+ if (!this.index) {
93
+ return { query, units: [], totalHops: 0, elapsedMs: Date.now() - startTime };
94
+ }
95
+ // Step 1: Keyword search (reused index — no rebuild!)
96
+ const results = this.index.search(query, { prefix: true, fuzzy: 0.2 });
97
+ const keywordUnitIds = new Map();
98
+ for (const r of results) {
99
+ keywordUnitIds.set(r.id, r.score);
100
+ }
101
+ // Step 2: Traverse associations (BFS)
102
+ const visited = new Set();
103
+ const queue = [];
104
+ for (const [id] of keywordUnitIds) {
105
+ visited.add(id);
106
+ queue.push({ id, hop: 0 });
107
+ }
108
+ const grid = this.store.getGrid();
109
+ const edgeIndex = grid?.edgeIndex ?? {};
110
+ while (queue.length > 0) {
111
+ const current = queue.shift();
112
+ if (current.hop >= maxHops)
113
+ continue;
114
+ const edges = edgeIndex[current.id] || [];
115
+ for (const edge of edges) {
116
+ if (!visited.has(edge.to)) {
117
+ visited.add(edge.to);
118
+ queue.push({ id: edge.to, hop: current.hop + 1 });
119
+ }
120
+ }
121
+ }
122
+ // Step 3: Collect and rank (from cache, O(1) lookups)
123
+ const matchedUnits = [];
124
+ const allUnits = this.getCachedUnits();
125
+ const unitMap = new Map();
126
+ for (const u of allUnits)
127
+ unitMap.set(u.id, u);
128
+ for (const id of visited) {
129
+ const unit = unitMap.get(id);
130
+ if (!unit)
131
+ continue;
132
+ const keywordScore = keywordUnitIds.get(id) || 0;
133
+ const associationBonus = this.computeAssociationBonus(id, keywordUnitIds, edgeIndex);
134
+ const usageBonus = Math.min(unit.meta.usage_count / 50, 0.2);
135
+ const score = keywordScore * 0.7 + associationBonus * 0.2 + usageBonus * 0.1;
136
+ matchedUnits.push({ unit, score });
137
+ }
138
+ matchedUnits.sort((a, b) => b.score - a.score);
139
+ const topUnits = matchedUnits.slice(0, maxResults).map((m) => m.unit);
140
+ const result = {
141
+ query,
142
+ units: topUnits,
143
+ totalHops: maxHops,
144
+ elapsedMs: Date.now() - startTime,
145
+ };
146
+ // Cache result
147
+ this.resultCache.set(cacheKey, result);
148
+ return result;
149
+ }
150
+ computeAssociationBonus(unitId, seedScores, edgeIndex) {
151
+ let bonus = 0;
152
+ for (const [seedId, score] of seedScores) {
153
+ const edges = edgeIndex[seedId] || [];
154
+ if (edges.some((e) => e.to === unitId)) {
155
+ bonus += score * 0.1;
156
+ }
157
+ }
158
+ return Math.min(bonus, 1.0);
159
+ }
160
+ /**
161
+ * Get units from store's in-memory cache (no disk I/O).
162
+ */
163
+ getCachedUnits() {
164
+ // FileStore.load() already loaded everything into memory
165
+ // We access via listUnits() which reads from Map, not disk
166
+ const units = [];
167
+ const storeWithCache = this.store;
168
+ if (storeWithCache.cache && storeWithCache.cache.size > 0) {
169
+ for (const u of storeWithCache.cache.values()) {
170
+ units.push(u);
171
+ }
172
+ }
173
+ return units;
174
+ }
175
+ toContext(result) {
176
+ if (result.units.length === 0) {
177
+ return 'No relevant memory units found.';
178
+ }
179
+ const lines = [
180
+ `## MemGrid Context (${result.units.length} units, ${result.elapsedMs}ms)`,
181
+ '',
182
+ ];
183
+ for (const unit of result.units) {
184
+ lines.push(`### ${unit.id} (${unit.type})`);
185
+ lines.push(`- **${unit.summary}**`);
186
+ if (unit.source) {
187
+ lines.push(`- location: \`${unit.source.file}\`${unit.source.lines ? `:${unit.source.lines}` : ''}`);
188
+ }
189
+ if (unit.content.inputs && unit.content.inputs !== 'none') {
190
+ lines.push(`- inputs: ${unit.content.inputs}`);
191
+ }
192
+ if (unit.content.outputs && unit.content.outputs !== 'void') {
193
+ lines.push(`- outputs: ${unit.content.outputs}`);
194
+ }
195
+ lines.push(`- ${unit.content.description}`);
196
+ if (unit.content.style_notes) {
197
+ lines.push(`- style: ${unit.content.style_notes}`);
198
+ }
199
+ if (unit.content.code_snippet) {
200
+ lines.push('```ts');
201
+ lines.push(unit.content.code_snippet.slice(0, 300));
202
+ lines.push('```');
203
+ }
204
+ lines.push('');
205
+ }
206
+ return lines.join('\n');
207
+ }
208
+ }
209
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/retrieve/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Semantic search layer for MemGrid.
3
+ * v0.4: Pluggable embedding providers + cosine similarity ranking.
4
+ * No native dependencies (pure JS). Embedding API calls are optional —
5
+ * falls back gracefully to keyword-only search if no embedding provider configured.
6
+ */
7
+ import type { FileStore } from '../store/file-store.js';
8
+ import type { SearchResult } from '../shared/types.js';
9
+ export interface EmbeddingProvider {
10
+ name: string;
11
+ embed(texts: string[]): Promise<number[][]>;
12
+ dimensions: number;
13
+ }
14
+ export interface SemanticSearchOptions {
15
+ maxResults?: number;
16
+ maxHops?: number;
17
+ /** Weight of semantic vs keyword score: 0.0 = keyword only, 1.0 = semantic only */
18
+ semanticWeight?: number;
19
+ }
20
+ export declare class SemanticRetriever {
21
+ private baseEngine;
22
+ private store;
23
+ private provider;
24
+ private vectorCache;
25
+ private resultCache;
26
+ constructor(store: FileStore, provider?: EmbeddingProvider);
27
+ setProvider(provider: EmbeddingProvider): void;
28
+ /**
29
+ * Build embedding vectors for all units in the grid.
30
+ * Called after memgrid init to pre-compute embeddings.
31
+ */
32
+ buildIndex(): Promise<{
33
+ indexed: number;
34
+ errors: number;
35
+ }>;
36
+ /**
37
+ * Hybrid search: semantic (cosine) + keyword (minisearch) → merged & reranked.
38
+ */
39
+ search(query: string, options?: SemanticSearchOptions): Promise<SearchResult>;
40
+ toContext(result: SearchResult): string;
41
+ private cosine;
42
+ }
43
+ /**
44
+ * No-external-dependency provider: uses keyword overlap as pseudo-embedding.
45
+ * Not real semantic search but provides scoring diversity without API calls.
46
+ */
47
+ export declare class KeywordEmbeddingProvider implements EmbeddingProvider {
48
+ name: string;
49
+ dimensions: number;
50
+ embed(texts: string[]): Promise<number[][]>;
51
+ }
52
+ /**
53
+ * Provider that calls an external embedding API (OpenAI-compatible format).
54
+ *
55
+ * Usage:
56
+ * const provider = new APIEmbeddingProvider('https://api.deepseek.com/v1/embeddings', 'sk-...');
57
+ */
58
+ export declare class APIEmbeddingProvider implements EmbeddingProvider {
59
+ name: string;
60
+ dimensions: number;
61
+ private baseUrl;
62
+ private apiKey;
63
+ private model;
64
+ constructor(baseUrl: string, apiKey: string, model?: string, dimensions?: number);
65
+ embed(texts: string[]): Promise<number[][]>;
66
+ }
67
+ //# sourceMappingURL=semantic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic.d.ts","sourceRoot":"","sources":["../../src/retrieve/semantic.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAc,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAcnE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC5C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mFAAmF;IACnF,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,WAAW,CAAoC;IACvD,OAAO,CAAC,WAAW,CAAqD;gBAE5D,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,iBAAiB;IAQ1D,WAAW,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI;IAK9C;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IA8BhE;;OAEG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,YAAY,CAAC;IAoFnF,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM;IAIvC,OAAO,CAAC,MAAM;CAgBf;AASD;;;GAGG;AACH,qBAAa,wBAAyB,YAAW,iBAAiB;IAChE,IAAI,SAAa;IACjB,UAAU,SAAK;IAET,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;CA6BlD;AAED;;;;;GAKG;AACH,qBAAa,oBAAqB,YAAW,iBAAiB;IAC5D,IAAI,SAAS;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;gBAEV,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,SAA2B,EAAE,UAAU,SAAO;IAO1F,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;CAoBlD"}