@juspay/neurolink
Version:
The pipe layer of an AI nervous system: one interface connecting provider neurons to your application, across three inference types — generate, stream and decide. `decide` returns typed, calibrated judgements from a non-generative model (~400ms, ~$0.00002
193 lines (192 loc) • 7.85 kB
JavaScript
/** Internal native-diagnostic policy; inference and provider selection are separate. */
import { logger } from "./logger.js";
import { DEFAULT_OLLAMA_MODEL } from "../providers/ollama/constants.js";
import { redactUrlsInText } from "./logSanitize.js";
export const OLLAMA_DIAGNOSTIC_RESET_MS = 300000;
let validatedFailureThreshold;
/**
* Validate the shared failure threshold once and reuse that first-use value.
* Missing or invalid PROVIDER_FAILURE_THRESHOLD values use the existing default
* of three; ProviderHealthChecker retains its original initialization point.
*/
export function getValidatedProviderFailureThreshold() {
if (validatedFailureThreshold !== undefined) {
return validatedFailureThreshold;
}
const envValue = process.env.PROVIDER_FAILURE_THRESHOLD;
if (!envValue) {
validatedFailureThreshold = 3;
return validatedFailureThreshold;
}
const parsed = Number(envValue);
if (isNaN(parsed) || parsed <= 0 || parsed > 10) {
logger.warn(`Invalid PROVIDER_FAILURE_THRESHOLD: ${envValue} (must be between 1 and 10), using default: 3`);
validatedFailureThreshold = 3;
return validatedFailureThreshold;
}
validatedFailureThreshold = parsed;
return validatedFailureThreshold;
}
/** Return diagnostic error text with URL secrets redacted for logs and status. */
export function getOllamaDiagnosticErrorMessage(error) {
return redactUrlsInText(error instanceof Error ? error.message : String(error));
}
const states = new Map();
const completed = new WeakSet();
let clearGeneration = 0;
/**
* Normalize an endpoint identity without its fragment, retaining path and query.
* The key can contain credentials and must remain private like the source URL.
*/
export function getOllamaDiagnosticEndpointKey(url) {
const parsed = new URL(url);
parsed.hash = "";
return parsed.toString();
}
/**
* Resolve native /api/tags at the configured Ollama origin, independently of a
* compatible /v1 base path. OLLAMA_BASE_URL precedes the legacy OLLAMA_API_BASE
* alias, then localhost; malformed URLs and non-HTTP(S) schemes are rejected.
*/
export function resolveOllamaNativeTagsUrl() {
const base = process.env.OLLAMA_BASE_URL ||
process.env.OLLAMA_API_BASE ||
"http://localhost:11434";
const resolved = new URL("/api/tags", base);
if (resolved.protocol !== "http:" && resolved.protocol !== "https:") {
throw new Error("Invalid OLLAMA_BASE_URL format (OLLAMA_API_BASE is still accepted as a legacy alias)");
}
resolved.hash = "";
return resolved.toString();
}
/**
* Capture endpoint identity and model before asynchronous diagnostic work.
* Later environment changes cannot retarget this context or its health-cache
* identity; failure accounting remains shared by endpoint rather than model.
*/
export function captureOllamaDiagnosticContext(model = process.env.OLLAMA_MODEL || DEFAULT_OLLAMA_MODEL) {
const url = resolveOllamaNativeTagsUrl();
return { url, key: getOllamaDiagnosticEndpointKey(url), model };
}
/**
* Initialize endpoint state or expire failures five minutes after the latest one.
* Expiry clears the count/timestamp and advances revision, retaining generation
* so existing in-flight permits remain valid. Only an explicit clear changes
* generation and invalidates those permits.
*/
function getState(context) {
let state = states.get(context.key);
if (!state) {
state = {
count: 0,
lastFailureAt: undefined,
revision: 0,
generation: clearGeneration,
};
states.set(context.key, state);
}
if (state.lastFailureAt !== undefined &&
Date.now() - state.lastFailureAt >= OLLAMA_DIAGNOSTIC_RESET_MS) {
// This is a fixed-window expiry, not an outcome from a cache hit/probe.
state.count = 0;
state.lastFailureAt = undefined;
state.revision++;
}
return state;
}
/**
* Copy the current policy state after applying initialization or timed expiry.
* This observation issues no request and records neither failure nor recovery.
*/
export function getOllamaDiagnosticSnapshot(context) {
return { ...getState(context) };
}
/**
* Admit a native probe or report backoff at the current failure threshold.
* Timed expiry is applied before this decision. Admission captures the clear
* generation without reserving a request or recording an outcome; callers must
* record the actual outcome on completion.
*/
export function beginOllamaDiagnostic(context) {
const state = getState(context);
if (state.count >= getValidatedProviderFailureThreshold()) {
return {
kind: "suppressed",
count: state.count,
reason: `Ollama native diagnostic backed off after ${state.count} consecutive transport failures`,
generation: state.generation,
};
}
return { kind: "allowed", context, generation: state.generation };
}
/**
* Apply timed expiry, then an admitted outcome once to the latest endpoint state.
* Transport/protocol failures increment its current count; success clears a
* nonzero count; not-run records no outcome. Timed expiry preserves permits,
* including those admitted before the boundary and completed after it.
* Duplicate permits and permits invalidated by explicit clearing are ignored.
*
* @returns A copy of the resulting state, or undefined for an ignored permit.
*/
export function completeOllamaDiagnostic(attempt, outcome) {
if (completed.has(attempt)) {
return undefined;
}
completed.add(attempt);
const storedState = states.get(attempt.context.key);
if (!storedState || storedState.generation !== attempt.generation) {
return undefined; // Explicit clearing invalidated this in-flight token.
}
const state = getState(attempt.context);
if (outcome === "transport-failure" || outcome === "protocol-failure") {
// Read and increment the latest completed state, never the starting count.
state.count++;
state.lastFailureAt = Date.now();
state.revision++;
}
else if (outcome === "success" && state.count !== 0) {
state.count = 0;
state.lastFailureAt = undefined;
state.revision++;
}
// Only admitted probes may reach this function. not-run cannot claim failure
// or recovery; genuine success while already clear retains the cache revision.
return { ...state };
}
/**
* Clear every endpoint and advance generation, invalidating in-flight permits.
* Unlike timed expiry, this prevents an older completion from repopulating state.
*/
export function clearOllamaDiagnostics() {
clearGeneration++;
states.clear();
}
/**
* Separate cached health by captured endpoint and model without splitting the
* endpoint-wide diagnostic counter. This private key can contain URL secrets.
*/
export function getOllamaHealthCacheKey(context) {
return JSON.stringify(["ollama", context.key, context.model]);
}
export class OllamaProtocolError extends Error {
/** Identify an answered tags response whose models envelope is malformed. */
constructor() {
super("Invalid models format from Ollama API");
this.name = "OllamaProtocolError";
}
}
/**
* Require an object containing a models array, including an empty array.
* Individual model entries are left to existing normalization; a malformed
* envelope throws OllamaProtocolError rather than appearing as no models.
*/
export function readOllamaTagsModels(payload) {
if (payload === null ||
typeof payload !== "object" ||
Array.isArray(payload) ||
!("models" in payload) ||
!Array.isArray(payload.models)) {
throw new OllamaProtocolError();
}
return payload.models;
}