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.js CHANGED
@@ -1,6 +1,75 @@
1
- var __defProp = Object.defineProperty;
2
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
1
+ var __getOwnPropNames = Object.getOwnPropertyNames;
2
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
3
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
4
+ }) : x)(function(x) {
5
+ if (typeof require !== "undefined") return require.apply(this, arguments);
6
+ throw Error('Dynamic require of "' + x + '" is not supported');
7
+ });
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 __require2() {
12
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
13
+ };
14
+
15
+ // native/build/Release/llama_embedding.node
16
+ var llama_embedding_default;
17
+ var init_llama_embedding = __esm({
18
+ "native/build/Release/llama_embedding.node"() {
19
+ llama_embedding_default = "./llama_embedding-EC3MWSUZ.node";
20
+ }
21
+ });
22
+
23
+ // node-file:/home/inky/Development/vecbox/native/build/Release/llama_embedding.node
24
+ var require_llama_embedding = __commonJS({
25
+ "node-file:/home/inky/Development/vecbox/native/build/Release/llama_embedding.node"(exports, module) {
26
+ "use strict";
27
+ init_llama_embedding();
28
+ try {
29
+ module.exports = __require(llama_embedding_default);
30
+ } catch {
31
+ }
32
+ }
33
+ });
34
+
35
+ // native/index.js
36
+ var require_native = __commonJS({
37
+ "native/index.js"(exports, module) {
38
+ "use strict";
39
+ var binding = require_llama_embedding();
40
+ var LlamaEmbedding = class {
41
+ constructor(modelPath) {
42
+ this.modelPtr = binding.createModel(modelPath);
43
+ if (!this.modelPtr) {
44
+ throw new Error("Failed to load model");
45
+ }
46
+ }
47
+ embed(text) {
48
+ if (typeof text !== "string") {
49
+ throw new Error("Text must be a string");
50
+ }
51
+ const embedding = binding.getEmbedding(this.modelPtr, text);
52
+ if (!embedding) {
53
+ throw new Error("Failed to generate embedding");
54
+ }
55
+ return embedding;
56
+ }
57
+ close() {
58
+ if (this.modelPtr) {
59
+ binding.destroyModel(this.modelPtr);
60
+ this.modelPtr = null;
61
+ }
62
+ }
63
+ };
64
+ function create(modelPath) {
65
+ return new LlamaEmbedding(modelPath);
66
+ }
67
+ module.exports = {
68
+ create,
69
+ LlamaEmbedding
70
+ };
71
+ }
72
+ });
4
73
 
5
74
  // main.ts
6
75
  import * as dotenv from "dotenv";
@@ -11,7 +80,6 @@ import OpenAI from "openai";
11
80
  // src/providers/base/EmbeddingProvider.ts
12
81
  var EmbeddingProvider = class {
13
82
  constructor(config2) {
14
- __publicField(this, "config");
15
83
  this.config = config2;
16
84
  }
17
85
  getModel() {
@@ -22,8 +90,8 @@ var EmbeddingProvider = class {
22
90
  return input.text;
23
91
  }
24
92
  if (input.filePath) {
25
- const fs = await import("fs/promises");
26
- return await fs.readFile(input.filePath, "utf-8");
93
+ const fs2 = await import("fs/promises");
94
+ return await fs2.readFile(input.filePath, "utf-8");
27
95
  }
28
96
  throw new Error("Either text or filePath must be provided");
29
97
  }
@@ -32,8 +100,6 @@ var EmbeddingProvider = class {
32
100
  // src/util/logger.ts
33
101
  var _Logger = class _Logger {
34
102
  constructor(moduleName = "embedbox", level = 1 /* INFO */) {
35
- __publicField(this, "currentLevel");
36
- __publicField(this, "moduleName");
37
103
  this.moduleName = moduleName;
38
104
  this.currentLevel = level;
39
105
  }
@@ -78,29 +144,28 @@ var _Logger = class _Logger {
78
144
  }
79
145
  // Static methods for quick access
80
146
  static debug(message, moduleName) {
81
- const logger9 = new _Logger(moduleName || "embedbox");
82
- logger9.debug(message);
147
+ const logger7 = new _Logger(moduleName || "embedbox");
148
+ logger7.debug(message);
83
149
  }
84
150
  static info(message, moduleName) {
85
- const logger9 = new _Logger(moduleName || "embedbox");
86
- logger9.info(message);
151
+ const logger7 = new _Logger(moduleName || "embedbox");
152
+ logger7.info(message);
87
153
  }
88
154
  static warn(message, moduleName) {
89
- const logger9 = new _Logger(moduleName || "embedbox");
90
- logger9.warn(message);
155
+ const logger7 = new _Logger(moduleName || "embedbox");
156
+ logger7.warn(message);
91
157
  }
92
158
  static error(message, moduleName) {
93
- const logger9 = new _Logger(moduleName || "embedbox");
94
- logger9.error(message);
159
+ const logger7 = new _Logger(moduleName || "embedbox");
160
+ logger7.error(message);
95
161
  }
96
162
  // Method to create a logger instance for a specific module
97
163
  static createModuleLogger(moduleName, level) {
98
164
  return new _Logger(`embedbox:${moduleName}`, level);
99
165
  }
100
166
  };
101
- __publicField(_Logger, "instance");
102
167
  // ANSI color codes - simplified for better readability
103
- __publicField(_Logger, "COLORS", {
168
+ _Logger.COLORS = {
104
169
  RESET: "\x1B[0m",
105
170
  DEBUG: "\x1B[36m",
106
171
  // Cyan
@@ -110,13 +175,13 @@ __publicField(_Logger, "COLORS", {
110
175
  // Yellow
111
176
  ERROR: "\x1B[31m"
112
177
  // Red
113
- });
114
- __publicField(_Logger, "LEVEL_NAMES", {
178
+ };
179
+ _Logger.LEVEL_NAMES = {
115
180
  [0 /* DEBUG */]: "DEBUG",
116
181
  [1 /* INFO */]: "INFO",
117
182
  [2 /* WARN */]: "WARN",
118
183
  [3 /* ERROR */]: "ERROR"
119
- });
184
+ };
120
185
  var Logger = _Logger;
121
186
  var logger = Logger.getInstance();
122
187
 
@@ -125,7 +190,6 @@ var logger2 = Logger.createModuleLogger("openai");
125
190
  var OpenAIProvider = class extends EmbeddingProvider {
126
191
  constructor(config2) {
127
192
  super(config2);
128
- __publicField(this, "client");
129
193
  if (!config2.apiKey) {
130
194
  throw new Error("OpenAI API key is required");
131
195
  }
@@ -214,7 +278,6 @@ var logger3 = Logger.createModuleLogger("gemini");
214
278
  var GeminiProvider = class extends EmbeddingProvider {
215
279
  constructor(config2) {
216
280
  super(config2);
217
- __publicField(this, "client");
218
281
  if (!config2.apiKey) {
219
282
  throw new Error("Google API key is required");
220
283
  }
@@ -265,11 +328,11 @@ var GeminiProvider = class extends EmbeddingProvider {
265
328
  }
266
329
  getDimensions() {
267
330
  const model = this.getModel();
268
- if (model.includes("gemini-embedding-001")) return 768;
331
+ if (model.includes("gemini-embedding-001")) return 3072;
269
332
  if (model.includes("text-embedding-004")) return 768;
270
333
  if (model.includes("embedding-001")) return 768;
271
334
  if (model.includes("multimodalembedding")) return 768;
272
- return 768;
335
+ return 3072;
273
336
  }
274
337
  getProviderName() {
275
338
  return "Google Gemini";
@@ -291,71 +354,12 @@ var GeminiProvider = class extends EmbeddingProvider {
291
354
  }
292
355
  };
293
356
 
294
- // src/providers/claude.ts
295
- import Anthropic from "@anthropic-ai/sdk";
296
- var logger4 = Logger.createModuleLogger("claude");
297
- var ClaudeProvider = class extends EmbeddingProvider {
298
- constructor(config2) {
299
- super(config2);
300
- __publicField(this, "client");
301
- if (!config2.apiKey) {
302
- throw new Error("Anthropic API key is required");
303
- }
304
- this.client = new Anthropic({
305
- apiKey: config2.apiKey,
306
- baseURL: config2.baseUrl,
307
- timeout: config2.timeout || 3e4
308
- });
309
- logger4.info("Claude provider initialized");
310
- }
311
- async embed() {
312
- try {
313
- logger4.debug(`Embedding text with model: ${this.getModel()}`);
314
- throw new Error("Claude embeddings API not yet available. Please use another provider.");
315
- } catch (error) {
316
- const errorMessage = error instanceof Error ? error instanceof Error ? error.message : String(error) : "Unknown error";
317
- logger4.error(`Claude embedding failed: ${errorMessage}`);
318
- throw error;
319
- }
320
- }
321
- async embedBatch() {
322
- try {
323
- throw new Error("Claude embeddings API not yet available. Please use another provider.");
324
- } catch (error) {
325
- const errorMessage = error instanceof Error ? error instanceof Error ? error.message : String(error) : "Unknown error";
326
- logger4.error(`Claude batch embedding failed: ${errorMessage}`);
327
- throw error;
328
- }
329
- }
330
- getDimensions() {
331
- return 0;
332
- }
333
- getProviderName() {
334
- return "Anthropic Claude";
335
- }
336
- async isReady() {
337
- try {
338
- await this.client.messages.create({
339
- model: "claude-3-haiku-20240307",
340
- max_tokens: 10,
341
- messages: [{ role: "user", content: "test" }]
342
- });
343
- return true;
344
- } catch (error) {
345
- const errorMessage = error instanceof Error ? error instanceof Error ? error.message : String(error) : "Unknown error";
346
- logger4.error(`Claude readiness check failed: ${errorMessage}`);
347
- return false;
348
- }
349
- }
350
- };
351
-
352
357
  // src/providers/mistral.ts
353
358
  import { Mistral } from "@mistralai/mistralai";
354
- var logger5 = Logger.createModuleLogger("mistral");
359
+ var logger4 = Logger.createModuleLogger("mistral");
355
360
  var MistralProvider = class extends EmbeddingProvider {
356
361
  constructor(config2) {
357
362
  super(config2);
358
- __publicField(this, "client");
359
363
  if (!config2.apiKey) {
360
364
  throw new Error("Mistral API key is required");
361
365
  }
@@ -364,12 +368,12 @@ var MistralProvider = class extends EmbeddingProvider {
364
368
  serverURL: config2.baseUrl,
365
369
  timeoutMs: config2.timeout || 3e4
366
370
  });
367
- logger5.info("Mistral provider initialized");
371
+ logger4.info("Mistral provider initialized");
368
372
  }
369
373
  async embed(input) {
370
374
  try {
371
375
  const text = await this.readInput(input);
372
- logger5.debug(`Embedding text with model: ${this.getModel()}`);
376
+ logger4.debug(`Embedding text with model: ${this.getModel()}`);
373
377
  const response = await this.client.embeddings.create({
374
378
  model: this.getModel(),
375
379
  inputs: [text]
@@ -389,14 +393,14 @@ var MistralProvider = class extends EmbeddingProvider {
389
393
  } : void 0
390
394
  };
391
395
  } catch (error) {
392
- logger5.error(`Mistral embedding failed: ${error instanceof Error ? error.message : String(error)}`);
396
+ logger4.error(`Mistral embedding failed: ${error instanceof Error ? error.message : String(error)}`);
393
397
  throw error;
394
398
  }
395
399
  }
396
400
  async embedBatch(inputs) {
397
401
  try {
398
402
  const texts = await Promise.all(inputs.map((input) => this.readInput(input)));
399
- logger5.debug(`Batch embedding ${texts.length} texts with model: ${this.getModel()}`);
403
+ logger4.debug(`Batch embedding ${texts.length} texts with model: ${this.getModel()}`);
400
404
  const response = await this.client.embeddings.create({
401
405
  model: this.getModel(),
402
406
  inputs: texts
@@ -416,7 +420,7 @@ var MistralProvider = class extends EmbeddingProvider {
416
420
  } : void 0
417
421
  };
418
422
  } catch (error) {
419
- logger5.error(`Mistral batch embedding failed: ${error instanceof Error ? error.message : String(error)}`);
423
+ logger4.error(`Mistral batch embedding failed: ${error instanceof Error ? error.message : String(error)}`);
420
424
  throw error;
421
425
  }
422
426
  }
@@ -436,100 +440,7 @@ var MistralProvider = class extends EmbeddingProvider {
436
440
  });
437
441
  return response.data.length > 0;
438
442
  } catch (error) {
439
- logger5.error(`Mistral readiness check failed: ${error instanceof Error ? error.message : String(error)}`);
440
- return false;
441
- }
442
- }
443
- };
444
-
445
- // src/providers/deepseek.ts
446
- import { DeepSeek } from "deepseek";
447
- var logger6 = Logger.createModuleLogger("deepseek");
448
- var DeepSeekProvider = class extends EmbeddingProvider {
449
- constructor(config2) {
450
- super(config2);
451
- __publicField(this, "client");
452
- if (!config2.apiKey) {
453
- throw new Error("DeepSeek API key is required");
454
- }
455
- const clientOptions = {
456
- apiKey: config2.apiKey,
457
- timeout: config2.timeout || 3e4
458
- };
459
- if (config2.baseUrl) {
460
- clientOptions.baseURL = config2.baseUrl;
461
- }
462
- this.client = new DeepSeek(clientOptions);
463
- logger6.info("DeepSeek provider initialized");
464
- }
465
- async embed(input) {
466
- try {
467
- const text = await this.readInput(input);
468
- logger6.debug(`Embedding text with model: ${this.getModel()}`);
469
- const response = await this.client.embeddings.create({
470
- model: this.getModel(),
471
- input: text
472
- });
473
- const embedding = response.data[0];
474
- if (!embedding) {
475
- throw new Error("No embedding returned from DeepSeek API");
476
- }
477
- return {
478
- embedding: embedding.embedding || [],
479
- dimensions: embedding.embedding?.length || 0,
480
- model: embedding.model || this.getModel(),
481
- provider: "deepseek",
482
- usage: response.usage ? {
483
- promptTokens: response.usage.prompt_tokens,
484
- totalTokens: response.usage.total_tokens
485
- } : void 0
486
- };
487
- } catch (error) {
488
- logger6.error(`DeepSeek embedding failed: ${error instanceof Error ? error.message : String(error)}`);
489
- throw error;
490
- }
491
- }
492
- async embedBatch(inputs) {
493
- try {
494
- const texts = await Promise.all(inputs.map((input) => this.readInput(input)));
495
- logger6.debug(`Batch embedding ${texts.length} texts with model: ${this.getModel()}`);
496
- const response = await this.client.embeddings.create({
497
- model: this.getModel(),
498
- input: texts
499
- });
500
- const embeddings = response.data.map((item) => item.embedding);
501
- return {
502
- embeddings,
503
- dimensions: embeddings[0]?.length || 0,
504
- model: response.model,
505
- provider: "deepseek",
506
- usage: response.usage ? {
507
- promptTokens: response.usage.prompt_tokens,
508
- totalTokens: response.usage.total_tokens
509
- } : void 0
510
- };
511
- } catch (error) {
512
- logger6.error(`DeepSeek batch embedding failed: ${error instanceof Error ? error.message : String(error)}`);
513
- throw error;
514
- }
515
- }
516
- getDimensions() {
517
- const model = this.getModel();
518
- if (model.includes("deepseek-chat")) return 4096;
519
- return 4096;
520
- }
521
- getProviderName() {
522
- return "DeepSeek";
523
- }
524
- async isReady() {
525
- try {
526
- await this.client.embeddings.create({
527
- model: this.getModel(),
528
- input: "test"
529
- });
530
- return true;
531
- } catch (error) {
532
- logger6.error(`DeepSeek readiness check failed: ${error instanceof Error ? error.message : String(error)}`);
443
+ logger4.error(`Mistral readiness check failed: ${error instanceof Error ? error.message : String(error)}`);
533
444
  return false;
534
445
  }
535
446
  }
@@ -537,16 +448,31 @@ var DeepSeekProvider = class extends EmbeddingProvider {
537
448
 
538
449
  // src/providers/llamacpp.ts
539
450
  import { access, constants } from "fs/promises";
540
- import { join, resolve } from "path";
541
- import * as http from "http";
451
+ var nativeModule = null;
452
+ try {
453
+ nativeModule = require_native();
454
+ logger.info("Using native Llama.cpp module");
455
+ } catch (error) {
456
+ logger.warn("Native module not available, falling back to HTTP");
457
+ }
542
458
  var LlamaCppProvider = class extends EmbeddingProvider {
543
459
  constructor(config2) {
544
460
  super({ ...config2, provider: "llamacpp" });
545
- __publicField(this, "llamaPath");
546
- __publicField(this, "modelPath");
461
+ this.nativeModel = null;
547
462
  this.modelPath = config2.model || "nomic-embed-text-v1.5.Q4_K_M.gguf";
548
463
  this.llamaPath = config2.llamaPath || "./llama.cpp/build/bin/llama-embedding";
549
- logger.info(`Llama.cpp provider initialized with model: ${this.modelPath}`);
464
+ this.useNative = !!nativeModule;
465
+ if (this.useNative) {
466
+ try {
467
+ this.nativeModel = nativeModule.create(this.modelPath);
468
+ logger.info(`Llama.cpp provider initialized with native module: ${this.modelPath}`);
469
+ } catch (error) {
470
+ logger.error(`Failed to initialize native module: ${error}`);
471
+ this.useNative = false;
472
+ }
473
+ } else {
474
+ logger.info(`Llama.cpp provider initialized with HTTP fallback: ${this.modelPath}`);
475
+ }
550
476
  }
551
477
  // Public API methods
552
478
  getProviderName() {
@@ -563,6 +489,9 @@ var LlamaCppProvider = class extends EmbeddingProvider {
563
489
  }
564
490
  async isReady() {
565
491
  try {
492
+ if (this.useNative && this.nativeModel) {
493
+ return true;
494
+ }
566
495
  await access(this.llamaPath, constants.F_OK);
567
496
  await access(this.llamaPath, constants.X_OK);
568
497
  const modelPath = await this.getModelPath();
@@ -574,6 +503,28 @@ var LlamaCppProvider = class extends EmbeddingProvider {
574
503
  return false;
575
504
  }
576
505
  }
506
+ async loadGGUFModel(modelPath) {
507
+ try {
508
+ logger.debug(`Loading GGUF model from: ${modelPath}`);
509
+ const modelBuffer = await fs.readFile(modelPath);
510
+ if (!modelBuffer) {
511
+ throw new Error(`Failed to read model file: ${modelPath}`);
512
+ }
513
+ logger.debug(`Model file loaded, size: ${modelBuffer.length} bytes`);
514
+ return modelBuffer;
515
+ } catch (error) {
516
+ logger.error(`Failed to load GGUF model: ${error instanceof Error ? error.message : String(error)}`);
517
+ throw error;
518
+ }
519
+ }
520
+ generateEmbedding(modelBuffer, text) {
521
+ logger.debug(`Generating embedding with model buffer (${modelBuffer.length} bytes)`);
522
+ const embedding = [];
523
+ for (let i = 0; i < Math.min(text.length, 768); i++) {
524
+ embedding.push(Math.sin(i * 0.1) * (i % 10));
525
+ }
526
+ return embedding;
527
+ }
577
528
  async embed(input) {
578
529
  try {
579
530
  logger.debug(`Embedding text with llama.cpp: ${this.getModel()}`);
@@ -581,20 +532,16 @@ var LlamaCppProvider = class extends EmbeddingProvider {
581
532
  if (!text.trim()) {
582
533
  throw new Error("Text input cannot be empty");
583
534
  }
584
- const requestBody = {
585
- input: text,
586
- model: await this.getModelPath(),
587
- pooling: "mean",
588
- normalize: 2
589
- };
590
- const result = await this.executeLlamaEmbedding([JSON.stringify(requestBody)]);
591
- const embedding = this.parseRawOutput(result.stdout);
592
- return {
593
- embedding,
594
- dimensions: embedding.length,
595
- model: this.getModel(),
596
- provider: "llamacpp"
597
- };
535
+ if (this.useNative && this.nativeModel) {
536
+ const embedding = this.nativeModel.embed(text);
537
+ return {
538
+ embedding,
539
+ dimensions: embedding.length,
540
+ model: this.getModel(),
541
+ provider: "llamacpp"
542
+ };
543
+ }
544
+ throw new Error("Direct Llama.cpp core integration not yet implemented. Please use HTTP fallback or wait for next version.");
598
545
  } catch (error) {
599
546
  logger.error(`Llama.cpp embedding failed: ${error instanceof Error ? error.message : String(error)}`);
600
547
  throw error;
@@ -603,6 +550,25 @@ var LlamaCppProvider = class extends EmbeddingProvider {
603
550
  async embedBatch(inputs) {
604
551
  try {
605
552
  logger.debug(`Batch embedding ${inputs.length} texts with llama.cpp`);
553
+ if (this.useNative && this.nativeModel) {
554
+ const embeddings2 = [];
555
+ for (const input of inputs) {
556
+ const text = await this.readInput(input);
557
+ if (text.trim()) {
558
+ const embedding = this.nativeModel.embed(text);
559
+ embeddings2.push(embedding);
560
+ }
561
+ }
562
+ if (embeddings2.length === 0) {
563
+ throw new Error("No valid texts to embed");
564
+ }
565
+ return {
566
+ embeddings: embeddings2,
567
+ dimensions: embeddings2[0]?.length || 0,
568
+ model: this.getModel(),
569
+ provider: "llamacpp"
570
+ };
571
+ }
606
572
  const texts = [];
607
573
  for (const input of inputs) {
608
574
  const text = await this.readInput(input);
@@ -614,15 +580,15 @@ var LlamaCppProvider = class extends EmbeddingProvider {
614
580
  throw new Error("No valid texts to embed");
615
581
  }
616
582
  const modelPath = await this.getModelPath();
617
- const requests = inputs.map((input) => ({
583
+ const requests = inputs.map((input, v) => ({
618
584
  input: input.text || "",
619
585
  model: modelPath,
620
586
  pooling: "mean",
621
587
  normalize: 2
622
588
  }));
623
589
  const embeddings = [];
624
- for (const request2 of requests) {
625
- const result = await this.executeLlamaEmbedding([JSON.stringify(request2)]);
590
+ for (const request of requests) {
591
+ const result = await this.executeLlamaEmbedding([JSON.stringify(request)]);
626
592
  const embedding = this.parseRawOutput(result.stdout);
627
593
  embeddings.push(embedding);
628
594
  }
@@ -637,127 +603,29 @@ var LlamaCppProvider = class extends EmbeddingProvider {
637
603
  throw error;
638
604
  }
639
605
  }
640
- // Protected methods
641
- getModel() {
642
- return this.modelPath;
643
- }
644
- // Private helper methods
645
- async getModelPath() {
646
- const possiblePaths = [
647
- this.modelPath,
648
- // As provided
649
- join("./llama.cpp/models", this.modelPath),
650
- // In llama.cpp/models
651
- join("./llama.cpp", this.modelPath),
652
- // In llama.cpp root
653
- this.modelPath
654
- // Fallback
655
- ];
656
- for (const path of possiblePaths) {
657
- try {
658
- await access(path, constants.F_OK);
659
- return resolve(path);
660
- } catch {
661
- continue;
662
- }
663
- }
664
- throw new Error(`Model file not found: ${this.modelPath}`);
665
- }
666
- async executeLlamaEmbedding(args) {
667
- return new Promise((resolve2, reject) => {
668
- const port = 8080;
669
- let requestBody;
606
+ // Cleanup method
607
+ async cleanup() {
608
+ if (this.useNative && this.nativeModel) {
670
609
  try {
671
- requestBody = JSON.parse(args[0] || "{}");
672
- } catch {
673
- reject(new Error("Invalid request body for HTTP API"));
674
- return;
610
+ this.nativeModel.close();
611
+ this.nativeModel = null;
612
+ logger.info("Native Llama.cpp model closed");
613
+ } catch (error) {
614
+ logger.error(`Error closing native model: ${error}`);
675
615
  }
676
- const postData = JSON.stringify(requestBody);
677
- const options = {
678
- hostname: "localhost",
679
- port,
680
- path: "/embedding",
681
- method: "POST",
682
- headers: {
683
- "Content-Type": "application/json",
684
- "Content-Length": Buffer.byteLength(postData)
685
- }
686
- };
687
- const req = http.request(options, (res) => {
688
- let data = "";
689
- res.on("data", (chunk) => {
690
- data += chunk;
691
- });
692
- res.on("end", () => {
693
- if (res.statusCode === 200) {
694
- resolve2({ stdout: data, stderr: "" });
695
- } else {
696
- reject(new Error(`HTTP ${res.statusCode}: ${data}`));
697
- }
698
- });
699
- });
700
- req.on("error", (error) => {
701
- reject(new Error(`Failed to connect to llama.cpp server: ${error instanceof Error ? error.message : String(error)}`));
702
- });
703
- req.write(postData);
704
- req.end();
705
- });
706
- }
707
- parseRawOutput(output) {
708
- try {
709
- const response = JSON.parse(output);
710
- logger.debug(`PARSE DEBUG: Response type: ${typeof response}`);
711
- logger.debug(`PARSE DEBUG: Is Array: ${Array.isArray(response)}`);
712
- if (Array.isArray(response) && response.length > 0) {
713
- const first = response[0];
714
- if (first && first.embedding && Array.isArray(first.embedding)) {
715
- const emb = first.embedding;
716
- if (Array.isArray(emb[0])) {
717
- const flat = emb[0];
718
- logger.debug(`Parsed ${flat.length} dimensions (nested)`);
719
- return flat;
720
- }
721
- logger.debug(`Parsed ${emb.length} dimensions (direct)`);
722
- return emb;
723
- }
724
- }
725
- if (response.embedding && Array.isArray(response.embedding)) {
726
- const emb = response.embedding;
727
- if (Array.isArray(emb[0])) {
728
- return emb[0];
729
- }
730
- return emb;
731
- }
732
- if (Array.isArray(response) && typeof response[0] === "number") {
733
- logger.debug(`Parsed ${response.length} dimensions (flat array)`);
734
- return response;
735
- }
736
- throw new Error(`Unexpected format: ${JSON.stringify(Object.keys(response))}`);
737
- } catch (error) {
738
- const errorMessage = error instanceof Error ? error instanceof Error ? error.message : String(error) : "Unknown error";
739
- throw new Error(`Parse failed: ${errorMessage}`, { cause: error });
740
616
  }
741
617
  }
742
- parseArrayOutput(output) {
743
- const arrayPattern = /\[([^\]]+)\]/g;
744
- const matches = [...output.matchAll(arrayPattern)];
745
- if (matches.length === 0) {
746
- throw new Error("No array embeddings found in output");
747
- }
748
- const embeddings = matches.map((match) => {
749
- const values = match[1]?.split(",").map((v) => v.trim()) || [];
750
- return values.map((v) => parseFloat(v)).filter((v) => !isNaN(v));
751
- }).filter((embedding) => embedding.length > 0);
752
- return embeddings;
618
+ // Protected methods
619
+ getModel() {
620
+ return this.modelPath;
753
621
  }
754
622
  };
755
623
 
756
624
  // src/factory/EmbeddingFactory.ts
757
- var logger7 = Logger.createModuleLogger("factory");
625
+ var logger5 = Logger.createModuleLogger("factory");
758
626
  var EmbeddingFactory = class {
759
627
  static create(config2) {
760
- logger7.info(`Creating provider: ${config2.provider}`);
628
+ logger5.info(`Creating provider: ${config2.provider}`);
761
629
  const ProviderClass = this.providers.get(config2.provider);
762
630
  if (!ProviderClass) {
763
631
  throw new Error(`Unsupported provider: ${config2.provider}`);
@@ -768,54 +636,51 @@ var EmbeddingFactory = class {
768
636
  return Array.from(this.providers.keys());
769
637
  }
770
638
  };
771
- __publicField(EmbeddingFactory, "providers", /* @__PURE__ */ new Map([
639
+ EmbeddingFactory.providers = /* @__PURE__ */ new Map([
772
640
  ["openai", OpenAIProvider],
773
641
  ["gemini", GeminiProvider],
774
- ["claude", ClaudeProvider],
775
642
  ["mistral", MistralProvider],
776
- ["deepseek", DeepSeekProvider],
777
643
  ["llamacpp", LlamaCppProvider]
778
644
  // Local embeddings with llama.cpp
779
- ]));
645
+ ]);
780
646
 
781
647
  // main.ts
782
648
  dotenv.config();
783
- var logger8 = Logger.createModuleLogger("main");
649
+ var logger6 = Logger.createModuleLogger("main");
784
650
  async function embed(config2, input) {
785
651
  try {
786
- logger8.info(`Starting embedding with provider: ${config2.provider}`);
652
+ logger6.info(`Starting embedding with provider: ${config2.provider}`);
787
653
  const provider = EmbeddingFactory.create(config2);
788
654
  const isReady = await provider.isReady();
789
655
  if (!isReady) {
790
656
  throw new Error(`Provider ${config2.provider} is not ready`);
791
657
  }
792
658
  if (Array.isArray(input)) {
793
- logger8.debug(`Processing batch of ${input.length} items`);
659
+ logger6.debug(`Processing batch of ${input.length} items`);
794
660
  return await provider.embedBatch(input);
795
661
  } else {
796
- logger8.debug(`Processing single item`);
662
+ logger6.debug(`Processing single item`);
797
663
  return await provider.embed(input);
798
664
  }
799
665
  } catch (error) {
800
666
  const errorMessage = error instanceof Error ? error.message : String(error);
801
- logger8.error(`Embedding failed: ${errorMessage}`);
667
+ logger6.error(`Embedding failed: ${errorMessage}`);
802
668
  throw error;
803
669
  }
804
670
  }
805
671
  async function autoEmbed(input) {
806
- logger8.info("Auto-detecting best provider...");
672
+ logger6.info("Auto-detecting best provider...");
807
673
  const providers = [
808
674
  { provider: "llamacpp", model: "nomic-embed-text-v1.5.Q4_K_M.gguf" },
809
675
  // Local & free (llama.cpp)
810
676
  { provider: "openai", model: "text-embedding-3-small", apiKey: process.env.OPENAI_API_KEY || void 0 },
811
677
  { provider: "gemini", model: "gemini-embedding-001", apiKey: process.env.GOOGLE_GENERATIVE_AI_API_KEY || void 0 },
812
- { provider: "mistral", model: "mistral-embed", apiKey: process.env.MISTRAL_API_KEY || void 0 },
813
- { provider: "deepseek", model: "deepseek-chat", apiKey: process.env.DEEPSEEK_API_KEY || void 0 }
678
+ { provider: "mistral", model: "mistral-embed", apiKey: process.env.MISTRAL_API_KEY || void 0 }
814
679
  ];
815
680
  for (const config2 of providers) {
816
681
  try {
817
682
  if (config2.provider === "llamacpp" || config2.apiKey) {
818
- logger8.info(`Trying provider: ${config2.provider}`);
683
+ logger6.info(`Trying provider: ${config2.provider}`);
819
684
  const cleanConfig = {
820
685
  provider: config2.provider,
821
686
  model: config2.model
@@ -827,7 +692,7 @@ async function autoEmbed(input) {
827
692
  }
828
693
  } catch (error) {
829
694
  const errorMessage = error instanceof Error ? error.message : String(error);
830
- logger8.warn(`Provider ${config2.provider} failed: ${errorMessage}`);
695
+ logger6.warn(`Provider ${config2.provider} failed: ${errorMessage}`);
831
696
  continue;
832
697
  }
833
698
  }
@@ -854,9 +719,7 @@ var LIB_INFO = {
854
719
  supportedProviders: [
855
720
  "openai",
856
721
  "gemini",
857
- "claude",
858
722
  "mistral",
859
- "deepseek",
860
723
  "llamacpp"
861
724
  ]
862
725
  };