vecbox 0.1.1 → 0.2.2

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/dist/index.cjs CHANGED
@@ -5,7 +5,12 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __esm = (fn, res) => function __init() {
9
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
+ };
11
+ var __commonJS = (cb, mod) => function __require() {
12
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
13
+ };
9
14
  var __export = (target, all) => {
10
15
  for (var name in all)
11
16
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -27,7 +32,65 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
32
  mod
28
33
  ));
29
34
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
35
+
36
+ // native/build/Release/llama_embedding.node
37
+ var llama_embedding_default;
38
+ var init_llama_embedding = __esm({
39
+ "native/build/Release/llama_embedding.node"() {
40
+ llama_embedding_default = "./llama_embedding-EC3MWSUZ.node";
41
+ }
42
+ });
43
+
44
+ // node-file:/home/inky/Development/vecbox/native/build/Release/llama_embedding.node
45
+ var require_llama_embedding = __commonJS({
46
+ "node-file:/home/inky/Development/vecbox/native/build/Release/llama_embedding.node"(exports2, module2) {
47
+ "use strict";
48
+ init_llama_embedding();
49
+ try {
50
+ module2.exports = require(llama_embedding_default);
51
+ } catch {
52
+ }
53
+ }
54
+ });
55
+
56
+ // native/index.js
57
+ var require_native = __commonJS({
58
+ "native/index.js"(exports2, module2) {
59
+ "use strict";
60
+ var binding = require_llama_embedding();
61
+ var LlamaEmbedding = class {
62
+ constructor(modelPath) {
63
+ this.modelPtr = binding.createModel(modelPath);
64
+ if (!this.modelPtr) {
65
+ throw new Error("Failed to load model");
66
+ }
67
+ }
68
+ embed(text) {
69
+ if (typeof text !== "string") {
70
+ throw new Error("Text must be a string");
71
+ }
72
+ const embedding = binding.getEmbedding(this.modelPtr, text);
73
+ if (!embedding) {
74
+ throw new Error("Failed to generate embedding");
75
+ }
76
+ return embedding;
77
+ }
78
+ close() {
79
+ if (this.modelPtr) {
80
+ binding.destroyModel(this.modelPtr);
81
+ this.modelPtr = null;
82
+ }
83
+ }
84
+ };
85
+ function create(modelPath) {
86
+ return new LlamaEmbedding(modelPath);
87
+ }
88
+ module2.exports = {
89
+ create,
90
+ LlamaEmbedding
91
+ };
92
+ }
93
+ });
31
94
 
32
95
  // index.ts
33
96
  var index_exports = {};
@@ -53,7 +116,6 @@ var import_openai = __toESM(require("openai"), 1);
53
116
  // src/providers/base/EmbeddingProvider.ts
54
117
  var EmbeddingProvider = class {
55
118
  constructor(config2) {
56
- __publicField(this, "config");
57
119
  this.config = config2;
58
120
  }
59
121
  getModel() {
@@ -64,8 +126,8 @@ var EmbeddingProvider = class {
64
126
  return input.text;
65
127
  }
66
128
  if (input.filePath) {
67
- const fs = await import("fs/promises");
68
- return await fs.readFile(input.filePath, "utf-8");
129
+ const fs2 = await import("fs/promises");
130
+ return await fs2.readFile(input.filePath, "utf-8");
69
131
  }
70
132
  throw new Error("Either text or filePath must be provided");
71
133
  }
@@ -74,8 +136,6 @@ var EmbeddingProvider = class {
74
136
  // src/util/logger.ts
75
137
  var _Logger = class _Logger {
76
138
  constructor(moduleName = "embedbox", level = 1 /* INFO */) {
77
- __publicField(this, "currentLevel");
78
- __publicField(this, "moduleName");
79
139
  this.moduleName = moduleName;
80
140
  this.currentLevel = level;
81
141
  }
@@ -120,29 +180,28 @@ var _Logger = class _Logger {
120
180
  }
121
181
  // Static methods for quick access
122
182
  static debug(message, moduleName) {
123
- const logger9 = new _Logger(moduleName || "embedbox");
124
- logger9.debug(message);
183
+ const logger7 = new _Logger(moduleName || "embedbox");
184
+ logger7.debug(message);
125
185
  }
126
186
  static info(message, moduleName) {
127
- const logger9 = new _Logger(moduleName || "embedbox");
128
- logger9.info(message);
187
+ const logger7 = new _Logger(moduleName || "embedbox");
188
+ logger7.info(message);
129
189
  }
130
190
  static warn(message, moduleName) {
131
- const logger9 = new _Logger(moduleName || "embedbox");
132
- logger9.warn(message);
191
+ const logger7 = new _Logger(moduleName || "embedbox");
192
+ logger7.warn(message);
133
193
  }
134
194
  static error(message, moduleName) {
135
- const logger9 = new _Logger(moduleName || "embedbox");
136
- logger9.error(message);
195
+ const logger7 = new _Logger(moduleName || "embedbox");
196
+ logger7.error(message);
137
197
  }
138
198
  // Method to create a logger instance for a specific module
139
199
  static createModuleLogger(moduleName, level) {
140
200
  return new _Logger(`embedbox:${moduleName}`, level);
141
201
  }
142
202
  };
143
- __publicField(_Logger, "instance");
144
203
  // ANSI color codes - simplified for better readability
145
- __publicField(_Logger, "COLORS", {
204
+ _Logger.COLORS = {
146
205
  RESET: "\x1B[0m",
147
206
  DEBUG: "\x1B[36m",
148
207
  // Cyan
@@ -152,13 +211,13 @@ __publicField(_Logger, "COLORS", {
152
211
  // Yellow
153
212
  ERROR: "\x1B[31m"
154
213
  // Red
155
- });
156
- __publicField(_Logger, "LEVEL_NAMES", {
214
+ };
215
+ _Logger.LEVEL_NAMES = {
157
216
  [0 /* DEBUG */]: "DEBUG",
158
217
  [1 /* INFO */]: "INFO",
159
218
  [2 /* WARN */]: "WARN",
160
219
  [3 /* ERROR */]: "ERROR"
161
- });
220
+ };
162
221
  var Logger = _Logger;
163
222
  var logger = Logger.getInstance();
164
223
 
@@ -167,7 +226,6 @@ var logger2 = Logger.createModuleLogger("openai");
167
226
  var OpenAIProvider = class extends EmbeddingProvider {
168
227
  constructor(config2) {
169
228
  super(config2);
170
- __publicField(this, "client");
171
229
  if (!config2.apiKey) {
172
230
  throw new Error("OpenAI API key is required");
173
231
  }
@@ -256,7 +314,6 @@ var logger3 = Logger.createModuleLogger("gemini");
256
314
  var GeminiProvider = class extends EmbeddingProvider {
257
315
  constructor(config2) {
258
316
  super(config2);
259
- __publicField(this, "client");
260
317
  if (!config2.apiKey) {
261
318
  throw new Error("Google API key is required");
262
319
  }
@@ -307,11 +364,11 @@ var GeminiProvider = class extends EmbeddingProvider {
307
364
  }
308
365
  getDimensions() {
309
366
  const model = this.getModel();
310
- if (model.includes("gemini-embedding-001")) return 768;
367
+ if (model.includes("gemini-embedding-001")) return 3072;
311
368
  if (model.includes("text-embedding-004")) return 768;
312
369
  if (model.includes("embedding-001")) return 768;
313
370
  if (model.includes("multimodalembedding")) return 768;
314
- return 768;
371
+ return 3072;
315
372
  }
316
373
  getProviderName() {
317
374
  return "Google Gemini";
@@ -333,71 +390,12 @@ var GeminiProvider = class extends EmbeddingProvider {
333
390
  }
334
391
  };
335
392
 
336
- // src/providers/claude.ts
337
- var import_sdk = __toESM(require("@anthropic-ai/sdk"), 1);
338
- var logger4 = Logger.createModuleLogger("claude");
339
- var ClaudeProvider = class extends EmbeddingProvider {
340
- constructor(config2) {
341
- super(config2);
342
- __publicField(this, "client");
343
- if (!config2.apiKey) {
344
- throw new Error("Anthropic API key is required");
345
- }
346
- this.client = new import_sdk.default({
347
- apiKey: config2.apiKey,
348
- baseURL: config2.baseUrl,
349
- timeout: config2.timeout || 3e4
350
- });
351
- logger4.info("Claude provider initialized");
352
- }
353
- async embed() {
354
- try {
355
- logger4.debug(`Embedding text with model: ${this.getModel()}`);
356
- throw new Error("Claude embeddings API not yet available. Please use another provider.");
357
- } catch (error) {
358
- const errorMessage = error instanceof Error ? error instanceof Error ? error.message : String(error) : "Unknown error";
359
- logger4.error(`Claude embedding failed: ${errorMessage}`);
360
- throw error;
361
- }
362
- }
363
- async embedBatch() {
364
- try {
365
- throw new Error("Claude embeddings API not yet available. Please use another provider.");
366
- } catch (error) {
367
- const errorMessage = error instanceof Error ? error instanceof Error ? error.message : String(error) : "Unknown error";
368
- logger4.error(`Claude batch embedding failed: ${errorMessage}`);
369
- throw error;
370
- }
371
- }
372
- getDimensions() {
373
- return 0;
374
- }
375
- getProviderName() {
376
- return "Anthropic Claude";
377
- }
378
- async isReady() {
379
- try {
380
- await this.client.messages.create({
381
- model: "claude-3-haiku-20240307",
382
- max_tokens: 10,
383
- messages: [{ role: "user", content: "test" }]
384
- });
385
- return true;
386
- } catch (error) {
387
- const errorMessage = error instanceof Error ? error instanceof Error ? error.message : String(error) : "Unknown error";
388
- logger4.error(`Claude readiness check failed: ${errorMessage}`);
389
- return false;
390
- }
391
- }
392
- };
393
-
394
393
  // src/providers/mistral.ts
395
394
  var import_mistralai = require("@mistralai/mistralai");
396
- var logger5 = Logger.createModuleLogger("mistral");
395
+ var logger4 = Logger.createModuleLogger("mistral");
397
396
  var MistralProvider = class extends EmbeddingProvider {
398
397
  constructor(config2) {
399
398
  super(config2);
400
- __publicField(this, "client");
401
399
  if (!config2.apiKey) {
402
400
  throw new Error("Mistral API key is required");
403
401
  }
@@ -406,12 +404,12 @@ var MistralProvider = class extends EmbeddingProvider {
406
404
  serverURL: config2.baseUrl,
407
405
  timeoutMs: config2.timeout || 3e4
408
406
  });
409
- logger5.info("Mistral provider initialized");
407
+ logger4.info("Mistral provider initialized");
410
408
  }
411
409
  async embed(input) {
412
410
  try {
413
411
  const text = await this.readInput(input);
414
- logger5.debug(`Embedding text with model: ${this.getModel()}`);
412
+ logger4.debug(`Embedding text with model: ${this.getModel()}`);
415
413
  const response = await this.client.embeddings.create({
416
414
  model: this.getModel(),
417
415
  inputs: [text]
@@ -431,14 +429,14 @@ var MistralProvider = class extends EmbeddingProvider {
431
429
  } : void 0
432
430
  };
433
431
  } catch (error) {
434
- logger5.error(`Mistral embedding failed: ${error instanceof Error ? error.message : String(error)}`);
432
+ logger4.error(`Mistral embedding failed: ${error instanceof Error ? error.message : String(error)}`);
435
433
  throw error;
436
434
  }
437
435
  }
438
436
  async embedBatch(inputs) {
439
437
  try {
440
438
  const texts = await Promise.all(inputs.map((input) => this.readInput(input)));
441
- logger5.debug(`Batch embedding ${texts.length} texts with model: ${this.getModel()}`);
439
+ logger4.debug(`Batch embedding ${texts.length} texts with model: ${this.getModel()}`);
442
440
  const response = await this.client.embeddings.create({
443
441
  model: this.getModel(),
444
442
  inputs: texts
@@ -458,7 +456,7 @@ var MistralProvider = class extends EmbeddingProvider {
458
456
  } : void 0
459
457
  };
460
458
  } catch (error) {
461
- logger5.error(`Mistral batch embedding failed: ${error instanceof Error ? error.message : String(error)}`);
459
+ logger4.error(`Mistral batch embedding failed: ${error instanceof Error ? error.message : String(error)}`);
462
460
  throw error;
463
461
  }
464
462
  }
@@ -478,100 +476,7 @@ var MistralProvider = class extends EmbeddingProvider {
478
476
  });
479
477
  return response.data.length > 0;
480
478
  } catch (error) {
481
- logger5.error(`Mistral readiness check failed: ${error instanceof Error ? error.message : String(error)}`);
482
- return false;
483
- }
484
- }
485
- };
486
-
487
- // src/providers/deepseek.ts
488
- var import_deepseek = require("deepseek");
489
- var logger6 = Logger.createModuleLogger("deepseek");
490
- var DeepSeekProvider = class extends EmbeddingProvider {
491
- constructor(config2) {
492
- super(config2);
493
- __publicField(this, "client");
494
- if (!config2.apiKey) {
495
- throw new Error("DeepSeek API key is required");
496
- }
497
- const clientOptions = {
498
- apiKey: config2.apiKey,
499
- timeout: config2.timeout || 3e4
500
- };
501
- if (config2.baseUrl) {
502
- clientOptions.baseURL = config2.baseUrl;
503
- }
504
- this.client = new import_deepseek.DeepSeek(clientOptions);
505
- logger6.info("DeepSeek provider initialized");
506
- }
507
- async embed(input) {
508
- try {
509
- const text = await this.readInput(input);
510
- logger6.debug(`Embedding text with model: ${this.getModel()}`);
511
- const response = await this.client.embeddings.create({
512
- model: this.getModel(),
513
- input: text
514
- });
515
- const embedding = response.data[0];
516
- if (!embedding) {
517
- throw new Error("No embedding returned from DeepSeek API");
518
- }
519
- return {
520
- embedding: embedding.embedding || [],
521
- dimensions: embedding.embedding?.length || 0,
522
- model: embedding.model || this.getModel(),
523
- provider: "deepseek",
524
- usage: response.usage ? {
525
- promptTokens: response.usage.prompt_tokens,
526
- totalTokens: response.usage.total_tokens
527
- } : void 0
528
- };
529
- } catch (error) {
530
- logger6.error(`DeepSeek embedding failed: ${error instanceof Error ? error.message : String(error)}`);
531
- throw error;
532
- }
533
- }
534
- async embedBatch(inputs) {
535
- try {
536
- const texts = await Promise.all(inputs.map((input) => this.readInput(input)));
537
- logger6.debug(`Batch embedding ${texts.length} texts with model: ${this.getModel()}`);
538
- const response = await this.client.embeddings.create({
539
- model: this.getModel(),
540
- input: texts
541
- });
542
- const embeddings = response.data.map((item) => item.embedding);
543
- return {
544
- embeddings,
545
- dimensions: embeddings[0]?.length || 0,
546
- model: response.model,
547
- provider: "deepseek",
548
- usage: response.usage ? {
549
- promptTokens: response.usage.prompt_tokens,
550
- totalTokens: response.usage.total_tokens
551
- } : void 0
552
- };
553
- } catch (error) {
554
- logger6.error(`DeepSeek batch embedding failed: ${error instanceof Error ? error.message : String(error)}`);
555
- throw error;
556
- }
557
- }
558
- getDimensions() {
559
- const model = this.getModel();
560
- if (model.includes("deepseek-chat")) return 4096;
561
- return 4096;
562
- }
563
- getProviderName() {
564
- return "DeepSeek";
565
- }
566
- async isReady() {
567
- try {
568
- await this.client.embeddings.create({
569
- model: this.getModel(),
570
- input: "test"
571
- });
572
- return true;
573
- } catch (error) {
574
- logger6.error(`DeepSeek readiness check failed: ${error instanceof Error ? error.message : String(error)}`);
479
+ logger4.error(`Mistral readiness check failed: ${error instanceof Error ? error.message : String(error)}`);
575
480
  return false;
576
481
  }
577
482
  }
@@ -579,16 +484,31 @@ var DeepSeekProvider = class extends EmbeddingProvider {
579
484
 
580
485
  // src/providers/llamacpp.ts
581
486
  var import_promises = require("fs/promises");
582
- var import_path = require("path");
583
- var http = __toESM(require("http"), 1);
487
+ var nativeModule = null;
488
+ try {
489
+ nativeModule = require_native();
490
+ logger.info("Using native Llama.cpp module");
491
+ } catch (error) {
492
+ logger.warn("Native module not available, falling back to HTTP");
493
+ }
584
494
  var LlamaCppProvider = class extends EmbeddingProvider {
585
495
  constructor(config2) {
586
496
  super({ ...config2, provider: "llamacpp" });
587
- __publicField(this, "llamaPath");
588
- __publicField(this, "modelPath");
497
+ this.nativeModel = null;
589
498
  this.modelPath = config2.model || "nomic-embed-text-v1.5.Q4_K_M.gguf";
590
499
  this.llamaPath = config2.llamaPath || "./llama.cpp/build/bin/llama-embedding";
591
- logger.info(`Llama.cpp provider initialized with model: ${this.modelPath}`);
500
+ this.useNative = !!nativeModule;
501
+ if (this.useNative) {
502
+ try {
503
+ this.nativeModel = nativeModule.create(this.modelPath);
504
+ logger.info(`Llama.cpp provider initialized with native module: ${this.modelPath}`);
505
+ } catch (error) {
506
+ logger.error(`Failed to initialize native module: ${error}`);
507
+ this.useNative = false;
508
+ }
509
+ } else {
510
+ logger.info(`Llama.cpp provider initialized with HTTP fallback: ${this.modelPath}`);
511
+ }
592
512
  }
593
513
  // Public API methods
594
514
  getProviderName() {
@@ -605,6 +525,9 @@ var LlamaCppProvider = class extends EmbeddingProvider {
605
525
  }
606
526
  async isReady() {
607
527
  try {
528
+ if (this.useNative && this.nativeModel) {
529
+ return true;
530
+ }
608
531
  await (0, import_promises.access)(this.llamaPath, import_promises.constants.F_OK);
609
532
  await (0, import_promises.access)(this.llamaPath, import_promises.constants.X_OK);
610
533
  const modelPath = await this.getModelPath();
@@ -616,6 +539,28 @@ var LlamaCppProvider = class extends EmbeddingProvider {
616
539
  return false;
617
540
  }
618
541
  }
542
+ async loadGGUFModel(modelPath) {
543
+ try {
544
+ logger.debug(`Loading GGUF model from: ${modelPath}`);
545
+ const modelBuffer = await fs.readFile(modelPath);
546
+ if (!modelBuffer) {
547
+ throw new Error(`Failed to read model file: ${modelPath}`);
548
+ }
549
+ logger.debug(`Model file loaded, size: ${modelBuffer.length} bytes`);
550
+ return modelBuffer;
551
+ } catch (error) {
552
+ logger.error(`Failed to load GGUF model: ${error instanceof Error ? error.message : String(error)}`);
553
+ throw error;
554
+ }
555
+ }
556
+ generateEmbedding(modelBuffer, text) {
557
+ logger.debug(`Generating embedding with model buffer (${modelBuffer.length} bytes)`);
558
+ const embedding = [];
559
+ for (let i = 0; i < Math.min(text.length, 768); i++) {
560
+ embedding.push(Math.sin(i * 0.1) * (i % 10));
561
+ }
562
+ return embedding;
563
+ }
619
564
  async embed(input) {
620
565
  try {
621
566
  logger.debug(`Embedding text with llama.cpp: ${this.getModel()}`);
@@ -623,20 +568,16 @@ var LlamaCppProvider = class extends EmbeddingProvider {
623
568
  if (!text.trim()) {
624
569
  throw new Error("Text input cannot be empty");
625
570
  }
626
- const requestBody = {
627
- input: text,
628
- model: await this.getModelPath(),
629
- pooling: "mean",
630
- normalize: 2
631
- };
632
- const result = await this.executeLlamaEmbedding([JSON.stringify(requestBody)]);
633
- const embedding = this.parseRawOutput(result.stdout);
634
- return {
635
- embedding,
636
- dimensions: embedding.length,
637
- model: this.getModel(),
638
- provider: "llamacpp"
639
- };
571
+ if (this.useNative && this.nativeModel) {
572
+ const embedding = this.nativeModel.embed(text);
573
+ return {
574
+ embedding,
575
+ dimensions: embedding.length,
576
+ model: this.getModel(),
577
+ provider: "llamacpp"
578
+ };
579
+ }
580
+ throw new Error("Direct Llama.cpp core integration not yet implemented. Please use HTTP fallback or wait for next version.");
640
581
  } catch (error) {
641
582
  logger.error(`Llama.cpp embedding failed: ${error instanceof Error ? error.message : String(error)}`);
642
583
  throw error;
@@ -645,6 +586,25 @@ var LlamaCppProvider = class extends EmbeddingProvider {
645
586
  async embedBatch(inputs) {
646
587
  try {
647
588
  logger.debug(`Batch embedding ${inputs.length} texts with llama.cpp`);
589
+ if (this.useNative && this.nativeModel) {
590
+ const embeddings2 = [];
591
+ for (const input of inputs) {
592
+ const text = await this.readInput(input);
593
+ if (text.trim()) {
594
+ const embedding = this.nativeModel.embed(text);
595
+ embeddings2.push(embedding);
596
+ }
597
+ }
598
+ if (embeddings2.length === 0) {
599
+ throw new Error("No valid texts to embed");
600
+ }
601
+ return {
602
+ embeddings: embeddings2,
603
+ dimensions: embeddings2[0]?.length || 0,
604
+ model: this.getModel(),
605
+ provider: "llamacpp"
606
+ };
607
+ }
648
608
  const texts = [];
649
609
  for (const input of inputs) {
650
610
  const text = await this.readInput(input);
@@ -656,15 +616,15 @@ var LlamaCppProvider = class extends EmbeddingProvider {
656
616
  throw new Error("No valid texts to embed");
657
617
  }
658
618
  const modelPath = await this.getModelPath();
659
- const requests = inputs.map((input) => ({
619
+ const requests = inputs.map((input, v) => ({
660
620
  input: input.text || "",
661
621
  model: modelPath,
662
622
  pooling: "mean",
663
623
  normalize: 2
664
624
  }));
665
625
  const embeddings = [];
666
- for (const request2 of requests) {
667
- const result = await this.executeLlamaEmbedding([JSON.stringify(request2)]);
626
+ for (const request of requests) {
627
+ const result = await this.executeLlamaEmbedding([JSON.stringify(request)]);
668
628
  const embedding = this.parseRawOutput(result.stdout);
669
629
  embeddings.push(embedding);
670
630
  }
@@ -679,127 +639,29 @@ var LlamaCppProvider = class extends EmbeddingProvider {
679
639
  throw error;
680
640
  }
681
641
  }
682
- // Protected methods
683
- getModel() {
684
- return this.modelPath;
685
- }
686
- // Private helper methods
687
- async getModelPath() {
688
- const possiblePaths = [
689
- this.modelPath,
690
- // As provided
691
- (0, import_path.join)("./llama.cpp/models", this.modelPath),
692
- // In llama.cpp/models
693
- (0, import_path.join)("./llama.cpp", this.modelPath),
694
- // In llama.cpp root
695
- this.modelPath
696
- // Fallback
697
- ];
698
- for (const path of possiblePaths) {
699
- try {
700
- await (0, import_promises.access)(path, import_promises.constants.F_OK);
701
- return (0, import_path.resolve)(path);
702
- } catch {
703
- continue;
704
- }
705
- }
706
- throw new Error(`Model file not found: ${this.modelPath}`);
707
- }
708
- async executeLlamaEmbedding(args) {
709
- return new Promise((resolve2, reject) => {
710
- const port = 8080;
711
- let requestBody;
642
+ // Cleanup method
643
+ async cleanup() {
644
+ if (this.useNative && this.nativeModel) {
712
645
  try {
713
- requestBody = JSON.parse(args[0] || "{}");
714
- } catch {
715
- reject(new Error("Invalid request body for HTTP API"));
716
- return;
646
+ this.nativeModel.close();
647
+ this.nativeModel = null;
648
+ logger.info("Native Llama.cpp model closed");
649
+ } catch (error) {
650
+ logger.error(`Error closing native model: ${error}`);
717
651
  }
718
- const postData = JSON.stringify(requestBody);
719
- const options = {
720
- hostname: "localhost",
721
- port,
722
- path: "/embedding",
723
- method: "POST",
724
- headers: {
725
- "Content-Type": "application/json",
726
- "Content-Length": Buffer.byteLength(postData)
727
- }
728
- };
729
- const req = http.request(options, (res) => {
730
- let data = "";
731
- res.on("data", (chunk) => {
732
- data += chunk;
733
- });
734
- res.on("end", () => {
735
- if (res.statusCode === 200) {
736
- resolve2({ stdout: data, stderr: "" });
737
- } else {
738
- reject(new Error(`HTTP ${res.statusCode}: ${data}`));
739
- }
740
- });
741
- });
742
- req.on("error", (error) => {
743
- reject(new Error(`Failed to connect to llama.cpp server: ${error instanceof Error ? error.message : String(error)}`));
744
- });
745
- req.write(postData);
746
- req.end();
747
- });
748
- }
749
- parseRawOutput(output) {
750
- try {
751
- const response = JSON.parse(output);
752
- logger.debug(`PARSE DEBUG: Response type: ${typeof response}`);
753
- logger.debug(`PARSE DEBUG: Is Array: ${Array.isArray(response)}`);
754
- if (Array.isArray(response) && response.length > 0) {
755
- const first = response[0];
756
- if (first && first.embedding && Array.isArray(first.embedding)) {
757
- const emb = first.embedding;
758
- if (Array.isArray(emb[0])) {
759
- const flat = emb[0];
760
- logger.debug(`Parsed ${flat.length} dimensions (nested)`);
761
- return flat;
762
- }
763
- logger.debug(`Parsed ${emb.length} dimensions (direct)`);
764
- return emb;
765
- }
766
- }
767
- if (response.embedding && Array.isArray(response.embedding)) {
768
- const emb = response.embedding;
769
- if (Array.isArray(emb[0])) {
770
- return emb[0];
771
- }
772
- return emb;
773
- }
774
- if (Array.isArray(response) && typeof response[0] === "number") {
775
- logger.debug(`Parsed ${response.length} dimensions (flat array)`);
776
- return response;
777
- }
778
- throw new Error(`Unexpected format: ${JSON.stringify(Object.keys(response))}`);
779
- } catch (error) {
780
- const errorMessage = error instanceof Error ? error instanceof Error ? error.message : String(error) : "Unknown error";
781
- throw new Error(`Parse failed: ${errorMessage}`, { cause: error });
782
652
  }
783
653
  }
784
- parseArrayOutput(output) {
785
- const arrayPattern = /\[([^\]]+)\]/g;
786
- const matches = [...output.matchAll(arrayPattern)];
787
- if (matches.length === 0) {
788
- throw new Error("No array embeddings found in output");
789
- }
790
- const embeddings = matches.map((match) => {
791
- const values = match[1]?.split(",").map((v) => v.trim()) || [];
792
- return values.map((v) => parseFloat(v)).filter((v) => !isNaN(v));
793
- }).filter((embedding) => embedding.length > 0);
794
- return embeddings;
654
+ // Protected methods
655
+ getModel() {
656
+ return this.modelPath;
795
657
  }
796
658
  };
797
659
 
798
660
  // src/factory/EmbeddingFactory.ts
799
- var logger7 = Logger.createModuleLogger("factory");
661
+ var logger5 = Logger.createModuleLogger("factory");
800
662
  var EmbeddingFactory = class {
801
663
  static create(config2) {
802
- logger7.info(`Creating provider: ${config2.provider}`);
664
+ logger5.info(`Creating provider: ${config2.provider}`);
803
665
  const ProviderClass = this.providers.get(config2.provider);
804
666
  if (!ProviderClass) {
805
667
  throw new Error(`Unsupported provider: ${config2.provider}`);
@@ -810,54 +672,51 @@ var EmbeddingFactory = class {
810
672
  return Array.from(this.providers.keys());
811
673
  }
812
674
  };
813
- __publicField(EmbeddingFactory, "providers", /* @__PURE__ */ new Map([
675
+ EmbeddingFactory.providers = /* @__PURE__ */ new Map([
814
676
  ["openai", OpenAIProvider],
815
677
  ["gemini", GeminiProvider],
816
- ["claude", ClaudeProvider],
817
678
  ["mistral", MistralProvider],
818
- ["deepseek", DeepSeekProvider],
819
679
  ["llamacpp", LlamaCppProvider]
820
680
  // Local embeddings with llama.cpp
821
- ]));
681
+ ]);
822
682
 
823
683
  // main.ts
824
684
  dotenv.config();
825
- var logger8 = Logger.createModuleLogger("main");
685
+ var logger6 = Logger.createModuleLogger("main");
826
686
  async function embed(config2, input) {
827
687
  try {
828
- logger8.info(`Starting embedding with provider: ${config2.provider}`);
688
+ logger6.info(`Starting embedding with provider: ${config2.provider}`);
829
689
  const provider = EmbeddingFactory.create(config2);
830
690
  const isReady = await provider.isReady();
831
691
  if (!isReady) {
832
692
  throw new Error(`Provider ${config2.provider} is not ready`);
833
693
  }
834
694
  if (Array.isArray(input)) {
835
- logger8.debug(`Processing batch of ${input.length} items`);
695
+ logger6.debug(`Processing batch of ${input.length} items`);
836
696
  return await provider.embedBatch(input);
837
697
  } else {
838
- logger8.debug(`Processing single item`);
698
+ logger6.debug(`Processing single item`);
839
699
  return await provider.embed(input);
840
700
  }
841
701
  } catch (error) {
842
702
  const errorMessage = error instanceof Error ? error.message : String(error);
843
- logger8.error(`Embedding failed: ${errorMessage}`);
703
+ logger6.error(`Embedding failed: ${errorMessage}`);
844
704
  throw error;
845
705
  }
846
706
  }
847
707
  async function autoEmbed(input) {
848
- logger8.info("Auto-detecting best provider...");
708
+ logger6.info("Auto-detecting best provider...");
849
709
  const providers = [
850
710
  { provider: "llamacpp", model: "nomic-embed-text-v1.5.Q4_K_M.gguf" },
851
711
  // Local & free (llama.cpp)
852
712
  { provider: "openai", model: "text-embedding-3-small", apiKey: process.env.OPENAI_API_KEY || void 0 },
853
713
  { provider: "gemini", model: "gemini-embedding-001", apiKey: process.env.GOOGLE_GENERATIVE_AI_API_KEY || void 0 },
854
- { provider: "mistral", model: "mistral-embed", apiKey: process.env.MISTRAL_API_KEY || void 0 },
855
- { provider: "deepseek", model: "deepseek-chat", apiKey: process.env.DEEPSEEK_API_KEY || void 0 }
714
+ { provider: "mistral", model: "mistral-embed", apiKey: process.env.MISTRAL_API_KEY || void 0 }
856
715
  ];
857
716
  for (const config2 of providers) {
858
717
  try {
859
718
  if (config2.provider === "llamacpp" || config2.apiKey) {
860
- logger8.info(`Trying provider: ${config2.provider}`);
719
+ logger6.info(`Trying provider: ${config2.provider}`);
861
720
  const cleanConfig = {
862
721
  provider: config2.provider,
863
722
  model: config2.model
@@ -869,7 +728,7 @@ async function autoEmbed(input) {
869
728
  }
870
729
  } catch (error) {
871
730
  const errorMessage = error instanceof Error ? error.message : String(error);
872
- logger8.warn(`Provider ${config2.provider} failed: ${errorMessage}`);
731
+ logger6.warn(`Provider ${config2.provider} failed: ${errorMessage}`);
873
732
  continue;
874
733
  }
875
734
  }
@@ -896,9 +755,7 @@ var LIB_INFO = {
896
755
  supportedProviders: [
897
756
  "openai",
898
757
  "gemini",
899
- "claude",
900
758
  "mistral",
901
- "deepseek",
902
759
  "llamacpp"
903
760
  ]
904
761
  };