bluera-knowledge 0.19.5 → 0.19.7

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/CHANGELOG.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
4
4
 
5
+ ## [0.19.7](https://github.com/blueraai/bluera-knowledge/compare/v0.19.4...v0.19.7) (2026-01-31)
6
+
7
+
8
+ ### Features
9
+
10
+ * **suggest:** present selectable list instead of copy-paste commands ([b8f3de2](https://github.com/blueraai/bluera-knowledge/commit/b8f3de2ab02dfa2dfa0d219bb3785c1491ae3d1a))
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * **embeddings:** improve reliability and performance ([d37c219](https://github.com/blueraai/bluera-knowledge/commit/d37c2190500f845c6bb7da78b432cf11b272b0f4))
16
+ * **gitignore:** add logs directory to ignored patterns ([ec9faf4](https://github.com/blueraai/bluera-knowledge/commit/ec9faf482e8fc8ba1cbf6619a8c561eb51e35f3c))
17
+
18
+ ## [0.19.6](https://github.com/blueraai/bluera-knowledge/compare/v0.19.4...v0.19.6) (2026-01-31)
19
+
20
+
21
+ ### Features
22
+
23
+ * **suggest:** present selectable list instead of copy-paste commands ([b8f3de2](https://github.com/blueraai/bluera-knowledge/commit/b8f3de2ab02dfa2dfa0d219bb3785c1491ae3d1a))
24
+
25
+
26
+ ### Bug Fixes
27
+
28
+ * **gitignore:** add logs directory to ignored patterns ([ec9faf4](https://github.com/blueraai/bluera-knowledge/commit/ec9faf482e8fc8ba1cbf6619a8c561eb51e35f3c))
29
+
5
30
  ## [0.19.5](https://github.com/blueraai/bluera-knowledge/compare/v0.19.4...v0.19.5) (2026-01-31)
6
31
 
7
32
 
@@ -9,7 +9,7 @@ import {
9
9
  isRepoStoreDefinition,
10
10
  isWebStoreDefinition,
11
11
  summarizePayload
12
- } from "./chunk-T7MENUKF.js";
12
+ } from "./chunk-JPJI3VMA.js";
13
13
 
14
14
  // src/mcp/server.ts
15
15
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
@@ -2202,4 +2202,4 @@ export {
2202
2202
  createMCPServer,
2203
2203
  runMCPServer
2204
2204
  };
2205
- //# sourceMappingURL=chunk-VR5EDQTX.js.map
2205
+ //# sourceMappingURL=chunk-6BC5OG4M.js.map
@@ -5420,21 +5420,46 @@ import { pipeline, env } from "@huggingface/transformers";
5420
5420
  env.cacheDir = join11(homedir2(), ".cache", "huggingface-transformers");
5421
5421
  var EmbeddingEngine = class {
5422
5422
  extractor = null;
5423
- // eslint-disable-next-line @typescript-eslint/prefer-readonly -- mutated in embed()
5423
+ initPromise = null;
5424
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly -- mutated in embed() and embedBatch()
5424
5425
  _dimensions = null;
5426
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly -- mutated in dispose()
5427
+ disposed = false;
5425
5428
  modelName;
5426
5429
  batchSize;
5427
5430
  constructor(modelName = "Xenova/all-MiniLM-L6-v2", batchSize = 32) {
5428
5431
  this.modelName = modelName;
5429
5432
  this.batchSize = batchSize;
5430
5433
  }
5434
+ /**
5435
+ * Guard against use-after-dispose
5436
+ */
5437
+ assertNotDisposed() {
5438
+ if (this.disposed) {
5439
+ throw new Error("EmbeddingEngine has been disposed");
5440
+ }
5441
+ }
5442
+ /**
5443
+ * Initialize the embedding pipeline (concurrency-safe).
5444
+ * Multiple concurrent calls will share the same initialization promise.
5445
+ */
5431
5446
  async initialize() {
5447
+ this.assertNotDisposed();
5432
5448
  if (this.extractor !== null) return;
5433
- this.extractor = await pipeline("feature-extraction", this.modelName, {
5434
- dtype: "fp32"
5435
- });
5449
+ this.initPromise ??= (async () => {
5450
+ try {
5451
+ this.extractor = await pipeline("feature-extraction", this.modelName, {
5452
+ dtype: "fp32"
5453
+ });
5454
+ } catch (error) {
5455
+ this.initPromise = null;
5456
+ throw error;
5457
+ }
5458
+ })();
5459
+ await this.initPromise;
5436
5460
  }
5437
5461
  async embed(text) {
5462
+ this.assertNotDisposed();
5438
5463
  if (this.extractor === null) {
5439
5464
  await this.initialize();
5440
5465
  }
@@ -5445,18 +5470,34 @@ var EmbeddingEngine = class {
5445
5470
  pooling: "mean",
5446
5471
  normalize: true
5447
5472
  });
5448
- const result = Array.from(output.data);
5473
+ const result = Array.from(output.data, (v) => Number(v));
5449
5474
  this._dimensions ??= result.length;
5450
- return result.map((v) => Number(v));
5475
+ return result;
5451
5476
  }
5452
5477
  async embedBatch(texts) {
5478
+ this.assertNotDisposed();
5479
+ if (this.extractor === null) {
5480
+ await this.initialize();
5481
+ }
5482
+ if (this.extractor === null) {
5483
+ throw new Error("Failed to initialize embedding model");
5484
+ }
5453
5485
  const results = [];
5454
5486
  for (let i = 0; i < texts.length; i += this.batchSize) {
5455
5487
  const batch = texts.slice(i, i + this.batchSize);
5456
- const batchResults = await Promise.all(batch.map((text) => this.embed(text)));
5457
- results.push(...batchResults);
5488
+ const output = await this.extractor(batch, {
5489
+ pooling: "mean",
5490
+ normalize: true
5491
+ });
5492
+ const dim = output.dims[output.dims.length - 1] ?? 0;
5493
+ for (let b = 0; b < batch.length; b++) {
5494
+ const start = b * dim;
5495
+ const end = start + dim;
5496
+ results.push(Array.from(output.data.slice(start, end), (v) => Number(v)));
5497
+ }
5498
+ this._dimensions ??= dim;
5458
5499
  if (i + this.batchSize < texts.length) {
5459
- await new Promise((resolve4) => setTimeout(resolve4, 100));
5500
+ await new Promise((resolve4) => setImmediate(resolve4));
5460
5501
  }
5461
5502
  }
5462
5503
  return results;
@@ -5477,7 +5518,7 @@ var EmbeddingEngine = class {
5477
5518
  */
5478
5519
  async ensureDimensions() {
5479
5520
  if (this._dimensions === null) {
5480
- await this.embed("");
5521
+ await this.embed("dimension probe");
5481
5522
  }
5482
5523
  if (this._dimensions === null) {
5483
5524
  throw new Error("Failed to determine embedding dimensions");
@@ -5487,12 +5528,16 @@ var EmbeddingEngine = class {
5487
5528
  /**
5488
5529
  * Dispose the embedding pipeline to free resources.
5489
5530
  * Should be called before process exit to prevent ONNX runtime cleanup issues on macOS.
5531
+ * After disposal, this engine cannot be used again.
5490
5532
  */
5491
5533
  async dispose() {
5492
5534
  if (this.extractor !== null) {
5493
5535
  await this.extractor.dispose();
5494
5536
  this.extractor = null;
5495
5537
  }
5538
+ this.initPromise = null;
5539
+ this._dimensions = null;
5540
+ this.disposed = true;
5496
5541
  }
5497
5542
  };
5498
5543
 
@@ -5901,4 +5946,4 @@ export {
5901
5946
  createServices,
5902
5947
  destroyServices
5903
5948
  };
5904
- //# sourceMappingURL=chunk-T7MENUKF.js.map
5949
+ //# sourceMappingURL=chunk-JPJI3VMA.js.map