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

77 lines (76 loc) • 3.38 kB
import { isImageGenerationModel } from "./constants.js"; /** * Which text a `generate({ tts })` request synthesizes. An explicit * `tts.mode` wins; otherwise the legacy `useAiResponse` flag decides, and the * absence of both means `"direct"` — the documented default that every * "speak this text" caller relies on. * * Every precedence site (this module, `BaseProvider.synthesizeAIResponseIfNeeded`, * `NeuroLink.attemptMCPGeneration`, the AI Studio generate() override) reads * the answer from here so the rule cannot drift between them. */ export function resolveTTSMode(tts) { if (tts?.mode === "direct" || tts?.mode === "response") { return tts.mode; } return tts?.useAiResponse ? "response" : "direct"; } /** * True when TTS is enabled and the request wants the input text synthesized, * bypassing the LLM turn. `enabled` is tested for truthiness, as the dispatch * it replaced did and as `synthesizeAIResponseIfNeeded` still does: a caller * off the declared type (`enabled: 1`, `"true"`) reaches the same branch at * every site rather than being routed to a model call by one of them. */ export function isDirectTTSRequest(tts) { return Boolean(tts?.enabled) && resolveTTSMode(tts) === "direct"; } /** * The dispatch decision for "what kind of request is this" — text, image, * video, music, avatar, direct TTS synthesis, or PPT generation — at the * CORE call sites: neurolink.ts's maybeHandleEarlyGenerateResult * (music/avatar/ppt/workflow routing) and baseProvider.ts's * stream()/runGenerateInActiveContext (image/video/tts-direct routing) call * this instead of independently re-deriving the decision. * * Also the only copy at the provider-override level: replicate.ts's * generate() override and googleVertex/client.ts's generate()/stream() * overrides (which bypass BaseProvider's paths) call this too, so an edit * to this precedence table reaches every dispatch site. * * Precedence, checked in order: * 1. output.mode (music/avatar/video/ppt) — an explicit mode always wins. * 2. an image-generation model, unless the caller explicitly asked for a * non-image output.format (json/structured/text) — this lets dual-mode * models like gemini-3.1-flash-image-preview still perform text or * structured generation when requested. * 3. tts.enabled with `resolveTTSMode()` answering "direct" — i.e. no * `mode: "response"` and no legacy `useAiResponse: true` — direct * synthesis, bypassing the LLM turn entirely (response mode means the * LLM's own text gets synthesized afterward, which is NOT this branch). * 4. otherwise, "text". */ export function resolveRequestKind(options, modelName) { if (options.output?.mode === "music") { return "music"; } if (options.output?.mode === "avatar") { return "avatar"; } if (options.output?.mode === "video") { return "video"; } if (options.output?.mode === "ppt") { return "ppt"; } const requestsNonImageOutput = options.output?.format === "json" || options.output?.format === "structured" || options.output?.format === "text"; if (isImageGenerationModel(modelName) && !requestsNonImageOutput) { return "image"; } if (isDirectTTSRequest(options.tts)) { return "tts-direct"; } return "text"; }