UNPKG

@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
/** * 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;