File size: 2,118 Bytes
22ff301
73a1dae
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22ff301
73a1dae
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import { XenovaTransformersEmbeddings } from '@/embed/hf';
import fs from 'fs-extra';
import {
  HNSWLib,
  type HNSWLib as StoreTypeHNSWLib,
} from 'langchain/vectorstores/hnswlib';
import path from 'path';

const ifDev = process.env.NODE_ENV === 'development';
// in prod mode, only allowed to write to /tmp/
// https://vercel.com/guides/how-can-i-use-files-in-serverless-functions
export const storesDir = ifDev ? 'tmp/hnswlib-stores' : '/tmp/hnswlib-stores';

type HNSWLibModel = {
  args: string;
  docstore: string;
  hnswlibIndex: string;
};

const HNSWLibModelFilesName = {
  args: 'args.json',
  docstore: 'docstore.json',
  hnswlibIndex: 'hnswlib.index',
};

// looking forward to a better way to transfrom hnswlibStore <=> indexes
export async function HNSWLibModelToVectorStore(
  model: HNSWLibModel,
  embeddings: XenovaTransformersEmbeddings,
) {
  await saveHNSWLibModelToLocal(model);
  // load from dir
  const vectorStore = await HNSWLib.load(storesDir, embeddings);
  return vectorStore;
}

export async function saveHNSWLibModelToLocal(model: HNSWLibModel) {
  // save model to /tmp/
  await Promise.all(
    Object.keys(HNSWLibModelFilesName).map((key) => {
      const fullPath = path.join(
        storesDir,
        (HNSWLibModelFilesName as Record<string, string>)[key],
      );
      console.log(fullPath);
      const data = (model as Record<string, string>)[key];
      console.log(data);

      return fs.writeFile(fullPath, data);
    }),
  );
}

export async function vectorStoreToHNSWLibModel(
  store: StoreTypeHNSWLib,
): Promise<HNSWLibModel> {
  await store.save(storesDir);
  return await readHNSWLibModelFromLocal();
}

export async function readHNSWLibModelFromLocal(): Promise<HNSWLibModel> {
  const [args, docstore, hnswlibIndex] = await Promise.all([
    fs.readFile(path.join(storesDir, HNSWLibModelFilesName.args), 'utf-8'),
    fs.readFile(path.join(storesDir, HNSWLibModelFilesName.docstore), 'utf-8'),
    fs.readFile(
      path.join(storesDir, HNSWLibModelFilesName.hnswlibIndex),
      'hex',
    ),
  ]);
  return {
    args,
    docstore,
    hnswlibIndex,
  };
}