From 4e3bcfc616af4a6330749647a393e415cae5d229 Mon Sep 17 00:00:00 2001 From: Timothy Carambat Date: Mon, 9 Mar 2026 11:47:00 -0700 Subject: [PATCH] Add custom fetch to embedder for Ollama (#5180) Refactor ollama timeout to be shared. Add custom fetch to embedder for ollama as well --- server/utils/AiProviders/ollama/index.js | 13 +++--- server/utils/EmbeddingEngines/ollama/index.js | 8 +++- .../utils/agents/aibitat/providers/ollama.js | 42 +------------------ 3 files changed, 16 insertions(+), 47 deletions(-) diff --git a/server/utils/AiProviders/ollama/index.js b/server/utils/AiProviders/ollama/index.js index cfcf03ba..547e2201 100644 --- a/server/utils/AiProviders/ollama/index.js +++ b/server/utils/AiProviders/ollama/index.js @@ -33,7 +33,7 @@ class OllamaAILLM { this.client = new Ollama({ host: this.basePath, headers: headers, - fetch: this.#applyFetch(), + fetch: OllamaAILLM.applyOllamaFetch(), }); this.embedder = embedder ?? new NativeEmbedder(); this.defaultTemp = 0.7; @@ -132,7 +132,7 @@ class OllamaAILLM { * for machines which run responses very slowly. * @returns {Function} The custom fetch function. */ - #applyFetch() { + static applyOllamaFetch() { try { if (!("OLLAMA_RESPONSE_TIMEOUT" in process.env)) return fetch; const { Agent } = require("undici"); @@ -140,7 +140,7 @@ class OllamaAILLM { let timeout = process.env.OLLAMA_RESPONSE_TIMEOUT; if (!timeout || isNaN(Number(timeout)) || Number(timeout) <= 5 * 60_000) { - this.#log( + OllamaAILLM.#slog( "Timeout option was not set, is not a number, or is less than 5 minutes in ms - falling back to default", { timeout } ); @@ -155,10 +155,13 @@ class OllamaAILLM { }; const humanDiff = moment.duration(timeout).humanize(); - this.#log(`Applying custom fetch w/timeout of ${humanDiff}.`); + OllamaAILLM.#slog(`Applying custom fetch w/timeout of ${humanDiff}.`); return noTimeoutFetch; } catch (error) { - this.#log("Error applying custom fetch - using default fetch", error); + OllamaAILLM.#slog( + "Error applying custom fetch - using default fetch", + error + ); return fetch; } } diff --git a/server/utils/EmbeddingEngines/ollama/index.js b/server/utils/EmbeddingEngines/ollama/index.js index de5db4f0..60ba8e07 100644 --- a/server/utils/EmbeddingEngines/ollama/index.js +++ b/server/utils/EmbeddingEngines/ollama/index.js @@ -1,5 +1,6 @@ const { maximumChunkLength } = require("../../helpers"); const { Ollama } = require("ollama"); +const { OllamaAILLM } = require("../../AiProviders/ollama"); class OllamaEmbedder { constructor() { @@ -16,10 +17,15 @@ class OllamaEmbedder { : 1; this.embeddingMaxChunkLength = maximumChunkLength(); this.authToken = process.env.OLLAMA_AUTH_TOKEN; + const headers = this.authToken ? { Authorization: `Bearer ${this.authToken}` } : {}; - this.client = new Ollama({ host: this.basePath, headers }); + this.client = new Ollama({ + host: this.basePath, + headers, + fetch: OllamaAILLM.applyOllamaFetch(), + }); this.log( `initialized with model ${this.model} at ${this.basePath}. Batch size: ${this.maxConcurrentChunks}, num_ctx: ${this.embeddingMaxChunkLength}` ); diff --git a/server/utils/agents/aibitat/providers/ollama.js b/server/utils/agents/aibitat/providers/ollama.js index af7da8aa..d7885418 100644 --- a/server/utils/agents/aibitat/providers/ollama.js +++ b/server/utils/agents/aibitat/providers/ollama.js @@ -28,7 +28,7 @@ class OllamaProvider extends InheritMultiple([Provider, UnTooled]) { this._client = new Ollama({ host: basePath, headers: headers, - fetch: this.#applyFetch(), + fetch: OllamaAILLM.applyOllamaFetch(), }); this.model = model; this.verbose = true; @@ -526,46 +526,6 @@ class OllamaProvider extends InheritMultiple([Provider, UnTooled]) { getCost(_usage) { return 0; } - - /** - * Apply a custom fetch function to the Ollama client. - * This is useful when we want to bypass the default 5m timeout for global fetch - * for machines which run responses very slowly. - * @returns {Function} The custom fetch function. - */ - #applyFetch() { - try { - if (!("OLLAMA_RESPONSE_TIMEOUT" in process.env)) return fetch; - const { Agent } = require("undici"); - const moment = require("moment"); - let timeout = process.env.OLLAMA_RESPONSE_TIMEOUT; - - if (!timeout || isNaN(Number(timeout)) || Number(timeout) <= 5 * 60_000) { - this.providerLog( - "Timeout option was not set, is not a number, or is less than 5 minutes in ms - falling back to default", - { timeout } - ); - return fetch; - } else timeout = Number(timeout); - - const noTimeoutFetch = (input, init = {}) => { - return fetch(input, { - ...init, - dispatcher: new Agent({ headersTimeout: timeout }), - }); - }; - - const humanDiff = moment.duration(timeout).humanize(); - this.providerLog(`Applying custom fetch w/timeout of ${humanDiff}.`); - return noTimeoutFetch; - } catch (error) { - this.providerLog( - "Error applying custom fetch - using default fetch", - error - ); - return fetch; - } - } } module.exports = OllamaProvider;