@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
104 lines (103 loc) • 5.64 kB
TypeScript
import type { GenerateOptions, MultimodalChatMessage, StreamOptions, TextGenerationOptions, VisionImageOutputFormat } from "../types/index.js";
import type { ModelMessage, ToolHistoryRow, ToolReplayMode } from "../types/index.js";
/**
* Type-safe conversion from MultimodalChatMessage[] to ModelMessage[]
* Filters out invalid content and ensures strict ModelMessage contract compliance
*/
export declare function convertToModelMessages(messages: MultimodalChatMessage[]): ModelMessage[];
/**
* Resolve the replay mode for a request: the per-request option, else the
* default. The instance-level `conversationMemory.replayToolSteps` is folded
* into the option by BaseProvider before the builder runs.
*/
export declare const resolveToolReplayMode: (options: {
replayToolSteps?: ToolReplayMode;
} | undefined) => ToolReplayMode;
/**
* Replay a session's tool rows into the prompt while the caller converts the
* regular rows its own way.
*
* Usage: normalise the history with `rows()`, then for each row call
* `consume(row)`; a `true` return means the row was a tool row and is now
* held. Before converting a non-tool row (and once after the last row) call
* `flush(messages, nextRole)`, which appends whatever the held tool rows
* amount to under `mode`:
*
* - `"full"`: paired tool-call / tool-result turns, one pair per step.
* - `"marker"`: markers are folded into the assistant text — returned for
* the caller to prepend when the next row is the assistant that answered
* after those tools; otherwise appended to the assistant turn just
* emitted, or emitted as a marker-only assistant turn when there is none.
* - `"off"`: dropped.
*
* The caller owns the conversion of regular rows so that the text and the
* multimodal builders keep their own (different) handling of them.
*/
export declare const createToolStepReplay: (mode: ToolReplayMode) => {
rows: <TRow extends ToolHistoryRow>(rows: ReadonlyArray<TRow>) => TRow[];
consume: (row: ToolHistoryRow) => boolean;
/**
* Append the held steps to `messages`. Returns marker text the caller must
* prepend to the assistant row it is about to convert, or undefined.
*/
flush: (messages: Array<ModelMessage | MultimodalChatMessage>, nextRole: string | undefined) => string | undefined;
};
/**
* Build a properly formatted message array for AI providers
* Combines system prompt, conversation history, and current user prompt
* Supports both TextGenerationOptions and StreamOptions
* Enhanced with CSV file processing support
*/
export declare function buildMessagesArray(options: TextGenerationOptions | StreamOptions): Promise<ModelMessage[]>;
/**
* Fold the `audioFiles` / `videoFiles` aliases into the unified `files` array.
*
* #284 gave audio and video their own input fields, but neither has a
* dedicated processor — both are meant to travel through the same
* auto-detecting `files` pipeline that already understands "audio"/"video"
* FileDetector results (see `appendDetectedFileResult`). The fold used to live
* inline in `buildMultimodalMessagesArray`, which meant any path that bypassed
* that builder never performed it and dropped the files silently: the model
* received the prompt alone and answered as though nothing were attached
* (#1259). GoogleVertex's native SDK path and `buildMultimodalOptions`
* (Bedrock) are both such paths, so the fold has to be callable from them.
*
* The aliases are cleared once merged, which makes the call idempotent: a
* provider override and the shared builder can both call this on the same
* options object without attaching every file twice.
*
* Mutates in place, matching `processUnifiedFilesArray` below — downstream
* stages all read `options.input.files`.
*/
export declare function mergeMediaFileAliases<TFile>(input: {
files?: Array<TFile | Buffer | string>;
audioFiles?: Array<Buffer | string>;
videoFiles?: Array<Buffer | string>;
}): void;
export declare function processUnifiedFilesArray(options: GenerateOptions, maxSize: number, provider: string): Promise<void>;
/**
* Build multimodal message array with image support
* Detects when images are present and routes through provider adapter
*/
export declare function buildMultimodalMessagesArray(options: GenerateOptions, provider: string, model: string): Promise<MultimodalChatMessage[]>;
/**
* The multimodal builder proper. Returns model messages so a session's tool
* steps can be replayed as real tool turns (`replayToolSteps: "full"`) on a
* turn that also carries files or images; `buildMultimodalMessagesArray`
* wraps this for callers on the older `MultimodalChatMessage[]` shape.
*/
export declare function buildMultimodalModelMessages(options: GenerateOptions, provider: string, model: string, replayMode?: ToolReplayMode): Promise<Array<MultimodalChatMessage | ModelMessage>>;
/**
* Transcode any image in `input.images` that no vision provider accepts,
* rewriting the entry in place as a PNG data URI.
*
* Mutates in place and is idempotent, matching `processUnifiedFilesArray` and
* `foldMediaAliasesIntoFiles`: the shared multimodal builder and the providers
* that bypass it (Google AI Studio's and Vertex's native SDK paths, Bedrock's
* Converse path) can all call it on the same options object without converting
* anything twice.
*
* Entries that are `http(s)` URLs are left alone — they have no bytes yet, and
* `processImageToBase64` converts them once they are downloaded.
*/
export declare function normalizeVisionImageFormats(input: GenerateOptions["input"], outputFormat?: VisionImageOutputFormat): Promise<void>;