| 4 | let extractorPromise: Promise<any> | null = null; |
| 5 | |
| 6 | function getExtractor(log: Logger): Promise<any> { |
| 7 | if (extractorPromise) return extractorPromise; |
| 8 | |
| 9 | extractorPromise = (async () => { |
| 10 | log.info("Loading local embedding model (first call may download ~23MB)..."); |
| 11 | const { pipeline } = await import("@huggingface/transformers"); |
| 12 | const ext = await pipeline("feature-extraction", DEFAULTS.localEmbeddingModel, { |
| 13 | dtype: "q8", |
| 14 | device: "cpu", |
| 15 | }); |
| 16 | log.info("Local embedding model ready"); |
| 17 | return ext; |
| 18 | })().catch((err) => { |
| 19 | extractorPromise = null; |
| 20 | throw err; |
| 21 | }); |
| 22 | |
| 23 | return extractorPromise; |
| 24 | } |
| 25 | |
| 26 | export async function embedLocal(texts: string[], log: Logger): Promise<number[][]> { |
| 27 | const ext = await getExtractor(log); |