opencode-mem 2.11.3 → 2.11.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -22,6 +22,24 @@ A persistent memory system for AI coding agents that enables long-term context r
22
22
 
23
23
  Local vector database with SQLite + HNSW (hnswlib-wasm), persistent project memories, automatic user profile learning, unified memory-prompt timeline, full-featured web UI, intelligent prompt-based memory extraction, multi-provider AI support (OpenAI, Anthropic), 12+ local embedding models, smart deduplication, and built-in privacy protection.
24
24
 
25
+ ## Prerequisites
26
+
27
+ This plugin uses `hnswlib-node` for fast vector similarity search, which requires native compilation. Ensure you have:
28
+
29
+ **All platforms:**
30
+
31
+ - Python 3.x
32
+ - A C++ compiler (gcc, clang, or MSVC)
33
+ - `make` or CMake
34
+
35
+ **Platform-specific setup:**
36
+
37
+ | Platform | Requirements |
38
+ | ----------- | ------------------------------------------------------------------------------------------------------------------------- |
39
+ | **macOS** | Xcode Command Line Tools: `xcode-select --install` |
40
+ | **Linux** | Build essentials: `sudo apt install build-essential python3` (Debian/Ubuntu) or `sudo pacman -S base-devel python` (Arch) |
41
+ | **Windows** | Visual Studio Build Tools with C++ workload, or Windows Build Tools: `npm install -g windows-build-tools` |
42
+
25
43
  ## Getting Started
26
44
 
27
45
  Add to your OpenCode configuration at `~/.config/opencode/opencode.json`:
@@ -32,7 +50,7 @@ Add to your OpenCode configuration at `~/.config/opencode/opencode.json`:
32
50
  }
33
51
  ```
34
52
 
35
- The plugin downloads automatically on next startup. No additional dependencies required - vector search is powered by pure WASM for cross-platform compatibility.
53
+ The plugin downloads automatically on next startup.
36
54
 
37
55
  ## Usage Examples
38
56
 
@@ -13,7 +13,6 @@ export declare class HNSWIndex {
13
13
  private initialized;
14
14
  constructor(dimensions: number, indexPath: string);
15
15
  private ensureInitialized;
16
- private vectorToArray;
17
16
  insert(id: string, vector: Float32Array): Promise<void>;
18
17
  insertBatch(items: HNSWIndexData[]): Promise<void>;
19
18
  search(queryVector: Float32Array, k: number): Promise<{
@@ -23,6 +22,7 @@ export declare class HNSWIndex {
23
22
  delete(id: string): Promise<void>;
24
23
  save(): Promise<void>;
25
24
  getCount(): number;
25
+ isPopulated(): boolean;
26
26
  }
27
27
  export declare class HNSWIndexManager {
28
28
  private indexes;
@@ -1 +1 @@
1
- {"version":3,"file":"hnsw-index.d.ts","sourceRoot":"","sources":["../../../src/services/sqlite/hnsw-index.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,KAAK,CAAkC;IAC/C,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,WAAW,CAAkB;gBAEzB,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;YAKnC,iBAAiB;IAyC/B,OAAO,CAAC,aAAa;IAIf,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBvD,WAAW,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBlD,MAAM,CAAC,WAAW,EAAE,YAAY,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAkBzF,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYjC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB3B,QAAQ,IAAI,MAAM;CAGnB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,MAAM;IAO3B,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS;IAWzE,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS;IAWvE,gBAAgB,CACpB,EAAE,EAAE,GAAG,EACP,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IAoCV,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBhF,sBAAsB,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CA0BpE"}
1
+ {"version":3,"file":"hnsw-index.d.ts","sourceRoot":"","sources":["../../../src/services/sqlite/hnsw-index.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,KAAK,CAAkC;IAC/C,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,WAAW,CAAkB;gBAEzB,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;YAKnC,iBAAiB;IAyBzB,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBvD,WAAW,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBlD,MAAM,CAAC,WAAW,EAAE,YAAY,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAqBzF,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYjC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB3B,QAAQ,IAAI,MAAM;IAIlB,WAAW,IAAI,OAAO;CAGvB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,MAAM;IAO3B,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS;IAWzE,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS;IAWvE,gBAAgB,CACpB,EAAE,EAAE,GAAG,EACP,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IAoCV,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBhF,sBAAsB,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CA0BpE"}
@@ -1,8 +1,20 @@
1
- import { mkdirSync, existsSync, writeFileSync, readFileSync, unlinkSync, readdirSync, } from "node:fs";
1
+ import { mkdirSync, existsSync, writeFileSync, unlinkSync, readdirSync } from "node:fs";
2
2
  import { join, dirname, basename } from "node:path";
3
3
  import { log } from "../logger.js";
4
4
  import { CONFIG } from "../../config.js";
5
- import { HierarchicalNSW } from "hnswlib-node";
5
+ let HNSWLib = null;
6
+ async function loadHNSWLib() {
7
+ if (!HNSWLib) {
8
+ // hnswlib-wasm is compiled with Emscripten -sENVIRONMENT=web and requires
9
+ // a browser-like global. This monkey-patch allows it to load in Node.js/Bun.
10
+ if (typeof globalThis.window === "undefined") {
11
+ globalThis.window = globalThis;
12
+ }
13
+ const { loadHnswlib } = await import("hnswlib-wasm");
14
+ HNSWLib = await loadHnswlib();
15
+ }
16
+ return HNSWLib;
17
+ }
6
18
  export class HNSWIndex {
7
19
  index = null;
8
20
  idMap = new Map();
@@ -19,41 +31,23 @@ export class HNSWIndex {
19
31
  async ensureInitialized() {
20
32
  if (this.initialized)
21
33
  return;
34
+ const hnsw = await loadHNSWLib();
22
35
  const dir = dirname(this.indexPath);
23
36
  if (!existsSync(dir)) {
24
37
  mkdirSync(dir, { recursive: true });
25
38
  }
26
- if (existsSync(this.indexPath)) {
27
- try {
28
- this.index = new HierarchicalNSW("cosine", this.dimensions);
29
- await this.index.readIndex(this.indexPath);
30
- const metaPath = this.indexPath + ".meta";
31
- if (existsSync(metaPath)) {
32
- const meta = JSON.parse(readFileSync(metaPath, "utf-8"));
33
- this.nextId = meta.nextId || 0;
34
- this.idMap = new Map(Object.entries(meta.idMap || {}).map(([k, v]) => [Number(k), v]));
35
- this.reverseMap = new Map(Object.entries(meta.reverseMap || {}));
36
- }
37
- log("HNSW index loaded", { path: this.indexPath, count: this.nextId });
38
- }
39
- catch (error) {
40
- log("Failed to load HNSW index, creating new", {
41
- path: this.indexPath,
42
- error: String(error),
43
- });
44
- this.index = new HierarchicalNSW("cosine", this.dimensions);
45
- await this.index.initIndex(this.maxElements);
46
- }
47
- }
48
- else {
49
- this.index = new HierarchicalNSW("cosine", this.dimensions);
50
- await this.index.initIndex(this.maxElements);
51
- log("HNSW index created", { path: this.indexPath, dimensions: this.dimensions });
52
- }
39
+ // hnswlib-wasm uses Emscripten MEMFS (in-memory virtual FS) and has no
40
+ // exported FS API for bridging to real filesystem. HNSW indexes are kept
41
+ // purely in-memory and rebuilt from SQLite vectors on process restart.
42
+ // Constructor requires 3 args: (spaceName, numDimensions, autoSaveFilename)
43
+ this.index = new hnsw.HierarchicalNSW("cosine", this.dimensions, "");
44
+ // initIndex requires 4 args: (maxElements, m, efConstruction, randomSeed)
45
+ this.index.initIndex(this.maxElements, 16, 200, 100);
53
46
  this.initialized = true;
54
- }
55
- vectorToArray(vector) {
56
- return Array.from(vector);
47
+ log("HNSW index initialized (in-memory)", {
48
+ path: this.indexPath,
49
+ dimensions: this.dimensions,
50
+ });
57
51
  }
58
52
  async insert(id, vector) {
59
53
  await this.ensureInitialized();
@@ -62,7 +56,8 @@ export class HNSWIndex {
62
56
  this.index.markDelete(internalId);
63
57
  }
64
58
  const internalId = this.nextId++;
65
- await this.index.addPoint(this.vectorToArray(vector), internalId);
59
+ // hnswlib-wasm addPoint requires 3 args: (point, label, replaceDeleted)
60
+ this.index.addPoint(vector, internalId, false);
66
61
  this.idMap.set(internalId, id);
67
62
  this.reverseMap.set(id, internalId);
68
63
  await this.save();
@@ -75,7 +70,8 @@ export class HNSWIndex {
75
70
  this.index.markDelete(internalId);
76
71
  }
77
72
  const internalId = this.nextId++;
78
- await this.index.addPoint(this.vectorToArray(item.vector), internalId);
73
+ // hnswlib-wasm addPoint requires 3 args: (point, label, replaceDeleted)
74
+ this.index.addPoint(item.vector, internalId, false);
79
75
  this.idMap.set(internalId, item.id);
80
76
  this.reverseMap.set(item.id, internalId);
81
77
  }
@@ -84,7 +80,11 @@ export class HNSWIndex {
84
80
  async search(queryVector, k) {
85
81
  await this.ensureInitialized();
86
82
  try {
87
- const results = await this.index.searchKnn(this.vectorToArray(queryVector), k);
83
+ // hnswlib-wasm searchKnn requires 3 args: (queryPoint, numNeighbors, filter)
84
+ const actualK = Math.min(k, this.reverseMap.size);
85
+ if (actualK === 0)
86
+ return [];
87
+ const results = this.index.searchKnn(queryVector, actualK, null);
88
88
  return results.neighbors
89
89
  .map((internalId, idx) => ({
90
90
  id: this.idMap.get(internalId) || "",
@@ -114,7 +114,8 @@ export class HNSWIndex {
114
114
  if (!existsSync(dir)) {
115
115
  mkdirSync(dir, { recursive: true });
116
116
  }
117
- await this.index.writeIndex(this.indexPath);
117
+ // Only persist id mapping (.meta file). HNSW index data lives in-memory
118
+ // and is rebuilt from SQLite vectors on process restart.
118
119
  const metaPath = this.indexPath + ".meta";
119
120
  const meta = {
120
121
  nextId: this.nextId,
@@ -126,6 +127,9 @@ export class HNSWIndex {
126
127
  getCount() {
127
128
  return this.reverseMap.size;
128
129
  }
130
+ isPopulated() {
131
+ return this.reverseMap.size > 0;
132
+ }
129
133
  }
130
134
  export class HNSWIndexManager {
131
135
  indexes = new Map();
@@ -1 +1 @@
1
- {"version":3,"file":"vector-search.d.ts","sourceRoot":"","sources":["../../../src/services/sqlite/vector-search.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGnD,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAExE,QAAA,MAAM,QAAQ,sCAAgB,CAAC;AAC/B,KAAK,YAAY,GAAG,OAAO,QAAQ,CAAC,SAAS,CAAC;AAI9C,qBAAa,YAAY;IACvB,YAAY,CAAC,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,CAAC,EAAE,SAAS,GAAG,IAAI;IAqDvE,aAAa,CACjB,KAAK,EAAE,SAAS,EAChB,WAAW,EAAE,YAAY,EACzB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC;IA6EpB,kBAAkB,CACtB,MAAM,EAAE,SAAS,EAAE,EACnB,WAAW,EAAE,YAAY,EACzB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EACb,mBAAmB,EAAE,MAAM,EAC3B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC;IAiBpB,YAAY,CAAC,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBlF,YAAY,CAChB,EAAE,EAAE,YAAY,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,YAAY,EACpB,KAAK,CAAC,EAAE,SAAS,EACjB,UAAU,CAAC,EAAE,YAAY,GACxB,OAAO,CAAC,IAAI,CAAC;IA4BhB,YAAY,CAAC,EAAE,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG,EAAE;IAW1E,cAAc,CAAC,EAAE,EAAE,YAAY,GAAG,GAAG,EAAE;IAKvC,aAAa,CAAC,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,GAAG,IAAI;IAK7D,sBAAsB,CAAC,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,GAAG,EAAE;IAgBlE,YAAY,CAAC,EAAE,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM;IAM5D,eAAe,CAAC,EAAE,EAAE,YAAY,GAAG,MAAM;IAMzC,eAAe,CAAC,EAAE,EAAE,YAAY,GAAG,GAAG,EAAE;IAexC,SAAS,CAAC,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKnD,WAAW,CAAC,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAK/C,gBAAgB,CACpB,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IAIhB,eAAe,IAAI,gBAAgB;CAGpC;AAED,eAAO,MAAM,YAAY,cAAqB,CAAC"}
1
+ {"version":3,"file":"vector-search.d.ts","sourceRoot":"","sources":["../../../src/services/sqlite/vector-search.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGnD,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAExE,QAAA,MAAM,QAAQ,sCAAgB,CAAC;AAC/B,KAAK,YAAY,GAAG,OAAO,QAAQ,CAAC,SAAS,CAAC;AAI9C,qBAAa,YAAY;IACvB,YAAY,CAAC,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,CAAC,EAAE,SAAS,GAAG,IAAI;IAqDvE,aAAa,CACjB,KAAK,EAAE,SAAS,EAChB,WAAW,EAAE,YAAY,EACzB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC;IAmFpB,kBAAkB,CACtB,MAAM,EAAE,SAAS,EAAE,EACnB,WAAW,EAAE,YAAY,EACzB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EACb,mBAAmB,EAAE,MAAM,EAC3B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC;IAiBpB,YAAY,CAAC,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBlF,YAAY,CAChB,EAAE,EAAE,YAAY,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,YAAY,EACpB,KAAK,CAAC,EAAE,SAAS,EACjB,UAAU,CAAC,EAAE,YAAY,GACxB,OAAO,CAAC,IAAI,CAAC;IA4BhB,YAAY,CAAC,EAAE,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG,EAAE;IAW1E,cAAc,CAAC,EAAE,EAAE,YAAY,GAAG,GAAG,EAAE;IAKvC,aAAa,CAAC,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,GAAG,IAAI;IAK7D,sBAAsB,CAAC,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,GAAG,EAAE;IAgBlE,YAAY,CAAC,EAAE,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM;IAM5D,eAAe,CAAC,EAAE,EAAE,YAAY,GAAG,MAAM;IAMzC,eAAe,CAAC,EAAE,EAAE,YAAY,GAAG,GAAG,EAAE;IAexC,SAAS,CAAC,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKnD,WAAW,CAAC,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAK/C,gBAAgB,CACpB,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IAIhB,eAAe,IAAI,gBAAgB;CAGpC;AAED,eAAO,MAAM,YAAY,cAAqB,CAAC"}
@@ -33,6 +33,11 @@ export class VectorSearch {
33
33
  const db = connectionManager.getConnection(shard.dbPath);
34
34
  const contentIndex = hnswIndexManager.getIndex(shard.scope, shard.scopeHash, shard.shardIndex);
35
35
  const tagsIndex = hnswIndexManager.getTagsIndex(shard.scope, shard.scopeHash, shard.shardIndex);
36
+ // HNSW indexes are in-memory only (hnswlib-wasm has no real FS bridging).
37
+ // Auto-rebuild from SQLite vectors if indexes are empty after process restart.
38
+ if (!contentIndex.isPopulated()) {
39
+ await hnswIndexManager.rebuildFromShard(db, shard.scope, shard.scopeHash, shard.shardIndex);
40
+ }
36
41
  const contentResults = await contentIndex.search(queryVector, limit * 4);
37
42
  const tagsResults = await tagsIndex.search(queryVector, limit * 4);
38
43
  const scoreMap = new Map();
@@ -1 +1 @@
1
- {"version":3,"file":"web-server.d.ts","sourceRoot":"","sources":["../../src/services/web-server.ts"],"names":[],"mappings":"AAiCA,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAA6C;IAC3D,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,mBAAmB,CAA+B;IAC1D,OAAO,CAAC,kBAAkB,CAAsC;gBAEpD,MAAM,EAAE,eAAe;IAInC,qBAAqB,CAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAIpD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YASd,MAAM;IAgCpB,OAAO,CAAC,oBAAoB;IAe5B,OAAO,CAAC,mBAAmB;YAOb,eAAe;IA+BvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAY3B,SAAS,IAAI,OAAO;IAIpB,aAAa,IAAI,OAAO;IAIxB,MAAM,IAAI,MAAM;IAIV,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC;YAchC,aAAa;IAmN3B,OAAO,CAAC,eAAe;IA4BvB,OAAO,CAAC,YAAY;CAWrB;AAED,wBAAsB,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC,CAIhF"}
1
+ {"version":3,"file":"web-server.d.ts","sourceRoot":"","sources":["../../src/services/web-server.ts"],"names":[],"mappings":"AAiCA,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAA6C;IAC3D,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,mBAAmB,CAA+B;IAC1D,OAAO,CAAC,kBAAkB,CAAsC;gBAEpD,MAAM,EAAE,eAAe;IAInC,qBAAqB,CAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAIpD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YASd,MAAM;IAgCpB,OAAO,CAAC,oBAAoB;IAe5B,OAAO,CAAC,mBAAmB;YAOb,eAAe;IA+BvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAY3B,SAAS,IAAI,OAAO;IAIpB,aAAa,IAAI,OAAO;IAIxB,MAAM,IAAI,MAAM;IAIV,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC;YAchC,aAAa;IAuN3B,OAAO,CAAC,eAAe;IA4BvB,OAAO,CAAC,YAAY;CAWrB;AAED,wBAAsB,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC,CAIhF"}
@@ -145,6 +145,9 @@ export class WebServer {
145
145
  if (path === "/app.js") {
146
146
  return this.serveStaticFile("app.js", "application/javascript");
147
147
  }
148
+ if (path === "/i18n.js") {
149
+ return this.serveStaticFile("i18n.js", "application/javascript");
150
+ }
148
151
  if (path === "/favicon.ico") {
149
152
  return this.serveStaticFile("favicon.ico", "image/x-icon");
150
153
  }