@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.25 kB
TypeScript
/**
* Tool Use/Result Pair Repair
*
* After compaction (or a pointer-based history slice) the message array can
* contain a `tool_call` whose `tool_result` was dropped, or a `tool_result`
* whose `tool_call` was dropped. Providers reject both, so orphans are filled
* with synthetic placeholders.
*
* Pairing is BATCH- and ID-aware, not adjacency-based. A single agent step
* with parallel tool calls is persisted as every `tool_call` followed by every
* `tool_result` (see flushPendingToolData), so `tool_call` is routinely
* followed by another `tool_call` in perfectly healthy history. Matching on
* adjacency treats that as an orphan and injects a bogus "result unavailable"
* over a result that is present a few entries later.
*
* Two modes, chosen per batch:
* - ID mode — `toolCallId` present: pair by id, order-independent.
* - legacy mode — sessions written before `toolCallId` existed: pair
* positionally WITHIN the batch (call[i] ↔ result[i]).
*/
import type { ChatMessage, RepairResult } from "../types/index.js";
/**
* Move a summarize/keep split so it never falls INSIDE a tool batch.
*
* `splitIndex` means "messages[0..splitIndex) get summarized" — so the summary
* pointer lands on messages[splitIndex - 1]. Landing mid-batch leaves the
* recent window starting on an orphaned `tool_result`, which providers reject.
*
* Preferred direction is BACKWARD (summarize less, keep the whole batch in the
* recent window) since that never loses detail. When the batch starts at index
* 0 there is nothing left to summarize, so the split moves forward past the
* batch instead — the caller's "at least one message summarized" invariant
* wins over keeping the batch recent.
*/
export declare function snapSplitToBatchBoundary(messages: ChatMessage[], splitIndex: number): number;
/**
* Repair orphaned tool_call/tool_result pairs in a message array.
*
* Guarantees on return: every `tool_call` is followed (within its batch) by
* exactly one `tool_result`, and no `tool_result` precedes its `tool_call`.
* A healthy batch — including a parallel one — is returned untouched.
*/
export declare function repairToolPairs(messages: ChatMessage[]): RepairResult;