@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
88 lines (87 loc) • 4.2 kB
JavaScript
/**
* Builds a normalized multimodal options payload for streaming providers.
*
* This utility extracts and normalizes multimodal input fields from StreamOptions
* into a consistent format that can be consumed by buildMultimodalMessagesArray.
*
* @param {StreamOptions} options - Stream options containing:
* - input.text: Main text prompt
* - input.images: Image files (Buffer | string paths/URLs)
* - input.content: Advanced multimodal content array
* - input.files: Auto-detected file types
* - input.csvFiles: CSV files for tabular data
* - input.pdfFiles: PDF documents (Buffer | string paths)
* - input.audioFiles: Audio files (Buffer | string paths)
* - input.videoFiles: Video files (Buffer | string paths)
* - csvOptions: CSV parsing options
* - videoOptions: Video frame/quality/format/transcription options
* - officeOptions: DOCX/XLSX sheet selection and output-format options
* - systemPrompt: System-level instructions
* - conversationMessages: Chat history
* - temperature: Model temperature (0-1)
* - maxTokens: Maximum output tokens
* - enableAnalytics: Enable analytics tracking
* - enableEvaluation: Enable response evaluation
* - context: Additional context data
* @param {string} providerName - Provider identifier (e.g., "vertex", "openai", "anthropic")
* @param {string} modelName - Model identifier (e.g., "gemini-2.5-flash", "gpt-4o")
* @returns {object} Normalized options object with:
* - input: { text, images, content, files, csvFiles, pdfFiles, audioFiles, videoFiles }
* - csvOptions: CSV processing options
* - officeOptions: Office (DOCX/XLSX) processing options
* - systemPrompt: System prompt string
* - conversationHistory: Message history array
* - provider: Provider name
* - model: Model name
* - temperature: Temperature value
* - maxTokens: Token limit
* - enableAnalytics: Analytics flag
* - enableEvaluation: Evaluation flag
* - context: Context data
*
* @example
* ```typescript
* const opts = buildMultimodalOptions(streamOptions, "vertex", "gemini-2.5-flash");
* const messages = await buildMultimodalMessagesArray(opts, "vertex", "gemini-2.5-flash");
* ```
*/
export function buildMultimodalOptions(options, providerName, modelName) {
return {
input: {
text: options.input?.text || "",
images: options.input?.images,
content: options.input?.content,
files: options.input?.files,
csvFiles: options.input?.csvFiles,
pdfFiles: options.input?.pdfFiles,
// #1259: this is a whitelist — a field omitted here is dropped
// silently, and the model answers as though nothing were attached.
// audioFiles/videoFiles were missing, so Bedrock received neither.
audioFiles: options.input?.audioFiles,
videoFiles: options.input?.videoFiles,
},
csvOptions: options.csvOptions,
pdfOptions: options.pdfOptions,
imageOptions: options.imageOptions,
// Same whitelist hazard as above, one level up: `videoFiles` reaching
// the processor is not enough on its own — without `videoOptions` too,
// the frame/quality/format/transcribeAudio knobs a caller set on
// `StreamOptions` never reach VideoProcessor on the Bedrock branch, and
// it silently falls back to the duration-tier default.
videoOptions: options.videoOptions,
// Same #1259 whitelist-drop bug class as audioFiles/videoFiles above:
// omitted here, Bedrock's multimodal generate()/stream() path always got
// sheetName/formatStyle undefined regardless of what the caller passed.
officeOptions: options.officeOptions,
systemPrompt: options.systemPrompt,
conversationHistory: options.conversationMessages,
provider: providerName,
model: modelName,
temperature: options.temperature,
maxTokens: options.maxTokens,
enableAnalytics: options.enableAnalytics,
enableEvaluation: options.enableEvaluation,
context: options.context,
fileRegistry: options.fileRegistry,
};
}