@@ -5,6 +5,14 @@ import { Ollama } from "ollama";
55import { readFile , writeFile , mkdir } from "fs/promises" ;
66import { join } from "path" ;
77
8+ const EMBED_TIMEOUT_MS = 60_000 ;
9+ let embedAbortController = new AbortController ( ) ;
10+
11+ export function cancelAllEmbeddings ( ) : void {
12+ embedAbortController . abort ( ) ;
13+ embedAbortController = new AbortController ( ) ;
14+ }
15+
816export interface SearchDocument {
917 path : string ;
1018 header : string ;
@@ -120,6 +128,12 @@ function buildEmbedRequest(input: string[]): { model: string; input: string[]; o
120128 return options ? { model : EMBED_MODEL , input, options } : { model : EMBED_MODEL , input } ;
121129}
122130
131+ async function embedWithTimeout ( request : ReturnType < typeof buildEmbedRequest > ) : Promise < { embeddings : number [ ] [ ] } > {
132+ const timeoutCtrl = AbortSignal . timeout ( EMBED_TIMEOUT_MS ) ;
133+ const signal = AbortSignal . any ( [ embedAbortController . signal , timeoutCtrl ] ) ;
134+ return ollama . embed ( { ...request , signal } as Parameters < typeof ollama . embed > [ 0 ] ) ;
135+ }
136+
123137export function getEmbeddingBatchSize ( ) : number {
124138 const requested = toIntegerOr ( process . env . CONTEXTPLUS_EMBED_BATCH_SIZE , DEFAULT_EMBED_BATCH_SIZE ) ;
125139 return Math . min ( MAX_EMBED_BATCH_SIZE , Math . max ( MIN_EMBED_BATCH_SIZE , requested ) ) ;
@@ -153,7 +167,7 @@ async function embedSingleAdaptive(input: string): Promise<number[]> {
153167
154168 for ( let attempt = 0 ; attempt <= MAX_SINGLE_INPUT_RETRIES ; attempt ++ ) {
155169 try {
156- const response = await ollama . embed ( buildEmbedRequest ( [ candidate ] ) ) ;
170+ const response = await embedWithTimeout ( buildEmbedRequest ( [ candidate ] ) ) ;
157171 if ( ! response . embeddings [ 0 ] ) throw new Error ( "Missing embedding vector in Ollama response" ) ;
158172 return response . embeddings [ 0 ] ;
159173 } catch ( error ) {
@@ -169,7 +183,7 @@ async function embedSingleAdaptive(input: string): Promise<number[]> {
169183
170184async function embedBatchAdaptive ( batch : string [ ] ) : Promise < number [ ] [ ] > {
171185 try {
172- const response = await ollama . embed ( buildEmbedRequest ( batch ) ) ;
186+ const response = await embedWithTimeout ( buildEmbedRequest ( batch ) ) ;
173187 if ( response . embeddings . length !== batch . length ) {
174188 throw new Error ( `Embedding response size mismatch: expected ${ batch . length } , got ${ response . embeddings . length } ` ) ;
175189 }
0 commit comments