mirror of
https://github.com/karakeep-app/karakeep.git
synced 2026-10-08 18:49:07 +02:00
* Fix headers timeout for AI interference jobs. * Take greptile feedback into account * Fix OpenAI timeouts and node 24 incompatibility. Use undici's own fetch together with its Agent/ProxyAgent so that both always come from the same undici copy. Passing an npm undici Agent as the dispatcher of the runtime's built-in fetch fails immediately on Node >= 24, which bundles a different undici major (undici 7). The OpenAI client now sets headersTimeout/bodyTimeout from OPENAI_TIMEOUT_SEC via the Agent dispatcher, so slow OpenAI-compatible servers are no longer cut off by undici's default 5 minute header timeout. Log fetch failures with their underlying cause for easier debugging. * refactor: simplify inference fetch timeout handling Replace the manual header/body timers, signal merging and dynamic undici import with a single helper that pairs undici's fetch with an Agent (or ProxyAgent) whose headersTimeout/bodyTimeout match the configured timeout. Overall deadlines are already enforced by the inference job timeout and the OpenAI SDK's own timeout. * Reuse undici dispatchers across inference client builds --------- Co-authored-by: Mohamed Bassem <me@mbassem.com> Co-authored-by: pullfrog[bot] <226033991+pullfrog[bot]@users.noreply.github.com>
36 lines
1.4 KiB
TypeScript
36 lines
1.4 KiB
TypeScript
import { Agent, Dispatcher, ProxyAgent, fetch as undiciFetch } from "undici";
|
|
|
|
// Dispatchers are reused across calls so that clients built per job (e.g. the
|
|
// inference, embeddings and asset-preprocessing workers) share a connection
|
|
// pool instead of opening fresh sockets each time.
|
|
const dispatchers = new Map<string, Dispatcher>();
|
|
|
|
function getDispatcher(timeoutMs: number, proxyUrl?: string): Dispatcher {
|
|
const key = `${proxyUrl ?? ""}:${timeoutMs}`;
|
|
let dispatcher = dispatchers.get(key);
|
|
if (!dispatcher) {
|
|
const opts = { headersTimeout: timeoutMs, bodyTimeout: timeoutMs };
|
|
dispatcher = proxyUrl
|
|
? new ProxyAgent({ uri: proxyUrl, ...opts })
|
|
: new Agent(opts);
|
|
dispatchers.set(key, dispatcher);
|
|
}
|
|
return dispatcher;
|
|
}
|
|
|
|
// Creates a fetch whose undici headers/body timeouts match the given timeout.
|
|
// Without this, undici's defaults (5 mins) cut off slow inference requests
|
|
// regardless of the configured timeout. We use undici's own fetch alongside
|
|
// its Agent so that the fetch and the dispatcher come from the same undici copy.
|
|
export function createCustomFetch(
|
|
timeoutMs: number,
|
|
proxyUrl?: string,
|
|
): typeof fetch {
|
|
const dispatcher = getDispatcher(timeoutMs, proxyUrl);
|
|
return ((input: RequestInfo | URL, init?: RequestInit) =>
|
|
undiciFetch(
|
|
input as Parameters<typeof undiciFetch>[0],
|
|
{ ...init, dispatcher } as Parameters<typeof undiciFetch>[1],
|
|
)) as unknown as typeof fetch;
|
|
}
|