@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
44 lines (43 loc) • 2.16 kB
TypeScript
/**
* Provider-neutral agent-loop reclaim policy.
*
* Every native provider loop grows its own history as the model calls tools,
* and every one of them can overflow the model's window mid-turn. The policy
* for reclaiming that budget is identical regardless of message shape:
*
* Stage 1 — shrink old tool outputs to head/tail previews.
* Stage 2 — drop the oldest complete tool batches, as units, when previews
* are not enough (or when outputs are already small enough that
* truncation buys nothing).
*
* What differs per provider is only the message SHAPE. So this module owns the
* decision and adapters own the mechanics: map your history onto
* `LoopGuardEntry[]`, call `planLoopGuardReclaim`, apply the returned indices.
*
* Two invariants the policy never violates:
* - entry 0 (the task) is never touched
* - a tool batch is dropped whole or not at all, so a `tool_call` never
* loses its `tool_result` (providers hard-reject the orphan)
*/
import type { LoopGuardEntry, LoopGuardPlan, LoopGuardPolicy } from "../types/index.js";
/**
* Fraction of the window the guard reclaims DOWN TO once it fires.
*
* The threshold decides *when*; this decides *how far*. Reclaiming only back to
* the threshold means the next step — which appends an assistant turn plus its
* tool results — crosses it again, so the guard rewrites the oldest messages on
* every single step. That mutation invalidates the provider's cached prompt
* prefix each time. One deeper reclaim every N steps saves the same tokens and
* leaves the prefix stable in between.
*/
export declare const DEFAULT_LOOP_GUARD_LOW_WATER_RATIO = 0.6;
/** Newest entries the guard never modifies. */
export declare const DEFAULT_LOOP_GUARD_PROTECTED_TAIL = 4;
/**
* Decide what to reclaim, if anything.
*
* Returns `fire: false` when the projected request is within threshold — the
* caller must then leave its history completely untouched, so a loop that fits
* never pays a cache invalidation.
*/
export declare function planLoopGuardReclaim(entries: readonly LoopGuardEntry[], policy: LoopGuardPolicy): LoopGuardPlan;