@juspay/neurolink 12.49.1 → 12.49.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -220,9 +220,15 @@ export function createGeminiLoopAdapter(config) {
220
220
  },
221
221
  mapFinishReason(rawStopReason, hadToolCallsAtCap) {
222
222
  const mapped = mapGeminiFinishReason(rawStopReason);
223
- // A turn cut off at the step cap ended because of the cap, not because
224
- // the last response said "STOP".
225
- return hadToolCallsAtCap && mapped === "stop" ? "tool-calls" : mapped;
223
+ // "tool-calls" from this hook means the step cap cut the turn off with
224
+ // calls still pending, so a last response that said "STOP" does not make
225
+ // it a finished turn. Gemini's own tool-call limit (TOO_MANY_TOOL_CALLS)
226
+ // also maps to "tool-calls" on the turn's result, but it is not that
227
+ // cap, so it counts here only when the cap was actually hit.
228
+ if (mapped === "stop" || mapped === "tool-calls") {
229
+ return hadToolCallsAtCap ? "tool-calls" : "stop";
230
+ }
231
+ return mapped;
226
232
  },
227
233
  };
228
234
  }
@@ -110,21 +110,35 @@ export declare function computeMaxSteps(rawMaxSteps?: number): number;
110
110
  * Map a `@google/genai` `Candidate.finishReason` enum value onto NeuroLink's
111
111
  * unified finish reason, mirroring anthropic.ts `mapAnthropicStopReason`.
112
112
  *
113
- * Enum values per `@google/genai` `FinishReason`: STOP, MAX_TOKENS, SAFETY,
114
- * RECITATION, LANGUAGE, OTHER, BLOCKLIST, PROHIBITED_CONTENT, SPII,
115
- * MALFORMED_FUNCTION_CALL, IMAGE_SAFETY, UNEXPECTED_TOOL_CALL,
116
- * FINISH_REASON_UNSPECIFIED. Unknown / unset / non-terminal values default to
117
- * "stop" (a clean completion is the safe assumption).
113
+ * Every member of `@google/genai`'s `FinishReason` and where it lands:
114
+ *
115
+ * - "length": MAX_TOKENS, and CONTINUATION (the response hit the per-request
116
+ * token limit before the model was done; it can be continued with the
117
+ * returned continuation token)
118
+ * - "tool-calls": TOO_MANY_TOOL_CALLS (the model called tools consecutively
119
+ * until the system cut the turn off, so it still wanted tools)
120
+ * - "error": MALFORMED_FUNCTION_CALL, UNEXPECTED_TOOL_CALL
121
+ * - "content-filter": SAFETY, RECITATION, BLOCKLIST, PROHIBITED_CONTENT, SPII,
122
+ * LANGUAGE (generation stopped over an unsupported language), and the image
123
+ * refusals IMAGE_SAFETY, IMAGE_PROHIBITED_CONTENT, IMAGE_RECITATION
124
+ * - "stop": STOP, and the members that name no cause the unified type can
125
+ * carry: OTHER, IMAGE_OTHER, NO_IMAGE, FINISH_REASON_UNSPECIFIED. An unknown
126
+ * or unset value also reads "stop" (a clean completion is the safe
127
+ * assumption), so a member a newer SDK adds needs an explicit case here.
118
128
  *
119
129
  * Returns a plain string (not a `{ unified, raw }` object): the Vertex result
120
130
  * builders and the consuming layer (neurolink.ts `finishReason || "unknown"`
121
131
  * and `finishReason === "length"`) compare against plain strings.
122
132
  *
123
133
  * MALFORMED_FUNCTION_CALL / UNEXPECTED_TOOL_CALL map to "error", NOT
124
- * "tool-calls": they are provider/model failures, while "tool-calls" is the
125
- * exclusive contract for "step budget exhausted while the model still wanted
126
- * tools" — consumers (e.g. curator's step-cap intercept) branch on it and
127
- * were rendering fake step-limit messages for 2-4-step malformed-call turns.
134
+ * "tool-calls": they are provider/model failures, while "tool-calls" means the
135
+ * turn ended with the model still wanting tools because a tool-call budget ran
136
+ * out: the loop's own step cap, or Gemini's TOO_MANY_TOOL_CALLS limit. Consumers
137
+ * (e.g. curator's step-cap intercept) branch on it and were rendering fake
138
+ * step-limit messages for 2-4-step malformed-call turns. `stopReason` is the
139
+ * discriminator that tells the two budgets apart: TOO_MANY_TOOL_CALLS reads
140
+ * "tool-calls" here but stays `stopReason: "completed"`, because `maxSteps` did
141
+ * not run out.
128
142
  */
129
143
  export declare function mapGeminiFinishReason(raw: string | null | undefined): "stop" | "length" | "tool-calls" | "content-filter" | "error";
130
144
  /**
@@ -491,26 +491,43 @@ export function computeMaxSteps(rawMaxSteps) {
491
491
  * Map a `@google/genai` `Candidate.finishReason` enum value onto NeuroLink's
492
492
  * unified finish reason, mirroring anthropic.ts `mapAnthropicStopReason`.
493
493
  *
494
- * Enum values per `@google/genai` `FinishReason`: STOP, MAX_TOKENS, SAFETY,
495
- * RECITATION, LANGUAGE, OTHER, BLOCKLIST, PROHIBITED_CONTENT, SPII,
496
- * MALFORMED_FUNCTION_CALL, IMAGE_SAFETY, UNEXPECTED_TOOL_CALL,
497
- * FINISH_REASON_UNSPECIFIED. Unknown / unset / non-terminal values default to
498
- * "stop" (a clean completion is the safe assumption).
494
+ * Every member of `@google/genai`'s `FinishReason` and where it lands:
495
+ *
496
+ * - "length": MAX_TOKENS, and CONTINUATION (the response hit the per-request
497
+ * token limit before the model was done; it can be continued with the
498
+ * returned continuation token)
499
+ * - "tool-calls": TOO_MANY_TOOL_CALLS (the model called tools consecutively
500
+ * until the system cut the turn off, so it still wanted tools)
501
+ * - "error": MALFORMED_FUNCTION_CALL, UNEXPECTED_TOOL_CALL
502
+ * - "content-filter": SAFETY, RECITATION, BLOCKLIST, PROHIBITED_CONTENT, SPII,
503
+ * LANGUAGE (generation stopped over an unsupported language), and the image
504
+ * refusals IMAGE_SAFETY, IMAGE_PROHIBITED_CONTENT, IMAGE_RECITATION
505
+ * - "stop": STOP, and the members that name no cause the unified type can
506
+ * carry: OTHER, IMAGE_OTHER, NO_IMAGE, FINISH_REASON_UNSPECIFIED. An unknown
507
+ * or unset value also reads "stop" (a clean completion is the safe
508
+ * assumption), so a member a newer SDK adds needs an explicit case here.
499
509
  *
500
510
  * Returns a plain string (not a `{ unified, raw }` object): the Vertex result
501
511
  * builders and the consuming layer (neurolink.ts `finishReason || "unknown"`
502
512
  * and `finishReason === "length"`) compare against plain strings.
503
513
  *
504
514
  * MALFORMED_FUNCTION_CALL / UNEXPECTED_TOOL_CALL map to "error", NOT
505
- * "tool-calls": they are provider/model failures, while "tool-calls" is the
506
- * exclusive contract for "step budget exhausted while the model still wanted
507
- * tools" — consumers (e.g. curator's step-cap intercept) branch on it and
508
- * were rendering fake step-limit messages for 2-4-step malformed-call turns.
515
+ * "tool-calls": they are provider/model failures, while "tool-calls" means the
516
+ * turn ended with the model still wanting tools because a tool-call budget ran
517
+ * out: the loop's own step cap, or Gemini's TOO_MANY_TOOL_CALLS limit. Consumers
518
+ * (e.g. curator's step-cap intercept) branch on it and were rendering fake
519
+ * step-limit messages for 2-4-step malformed-call turns. `stopReason` is the
520
+ * discriminator that tells the two budgets apart: TOO_MANY_TOOL_CALLS reads
521
+ * "tool-calls" here but stays `stopReason: "completed"`, because `maxSteps` did
522
+ * not run out.
509
523
  */
510
524
  export function mapGeminiFinishReason(raw) {
511
525
  switch (raw) {
512
526
  case "MAX_TOKENS":
527
+ case "CONTINUATION":
513
528
  return "length";
529
+ case "TOO_MANY_TOOL_CALLS":
530
+ return "tool-calls";
514
531
  case "MALFORMED_FUNCTION_CALL":
515
532
  case "UNEXPECTED_TOOL_CALL":
516
533
  return "error";
@@ -519,7 +536,10 @@ export function mapGeminiFinishReason(raw) {
519
536
  case "BLOCKLIST":
520
537
  case "PROHIBITED_CONTENT":
521
538
  case "SPII":
539
+ case "LANGUAGE":
522
540
  case "IMAGE_SAFETY":
541
+ case "IMAGE_PROHIBITED_CONTENT":
542
+ case "IMAGE_RECITATION":
523
543
  return "content-filter";
524
544
  default:
525
545
  return "stop";
@@ -4604,6 +4604,7 @@
4604
4604
  {"objectID":"8569960f5df3455464e766e118794ee1116e63943713b4e396669abb164ea759","title":"stopReason — the turn-exit discriminator","url":"/docs/features/turn-time-budget#stopreason-the-turn-exit-discriminator","content":"finishReason is provider-shaped and historically overloaded (\"tool-calls\"\ncovered both step-cap exits and Gemini MALFORMED_FUNCTION_CALL failures).\nBranch on result.stopReason instead:\n\n| stopReason | Meaning |\n| ---------------- | ------------------------------------------------------------------ |\n| completed | The model finished on its own (text answer or final_result) |\n| step-cap | The maxSteps budget ran out while the model still wanted tools |\n| time-limit | The turnTimeoutMs (or defensive) wall-clock deadline passed |\n| stalled | No progress for stallTimeoutMs |\n| aborted | The caller's abortSignal ended the turn |\n| context-cap | The in-loop context guard stopped the turn (Vertex loops only) |\n| provider-error | Provider/model failure (e.g. persistent MALFORMED_FUNCTION_CALL) |\n\nA loop only reports what it can observe. The AI Studio loops never report\ncontext-cap, because their context guard reclaims room or does nothing — it\nhas no stop-the-turn branch to report.\n\nAlso on the result: rawFinishReason (the verbatim provider value, e.g.\nMALFORMED_FUNCTION_CALL, max_tokens) and stepsUsed. On stream()\nresults, read metadata.stopReason / metadata.rawFinishReason /\nmetadata.stepsUsed after draining the stream — background loops resolve\nthem at close, and metadata is the mutable reference that survives wrapper\nspreads.\n\nProviders without a native loop leave stopReason undefined — keep any\nlegacy finishReason heuristics as a fallback.","hierarchy":{"lvl0":"Features","lvl1":"Turn Time Budget","lvl2":"stopReason — the turn-exit discriminator","lvl3":""}},
4605
4605
  {"objectID":"beefbc9fd412625dfb71572fe43e8c19a1634aa91a3778825806507e43eb5f84","title":"Honest terminal messages","url":"/docs/features/turn-time-budget#honest-terminal-messages","content":"Each exit cause has its own user-facing message; the step-cap text\n(\"...reached the N-step limit...\") is emitted only when step >= maxSteps\ngenuinely terminated the loop:\ntime-limit: _\"I had to stop after Xm Ys — this turn hit its processing time\n limit. I completed N tool calls before stopping; ask me to continue and\n I'll pick up from there.\"_\nstalled: _\"I had to stop because this turn made no progress for Xs — a tool\n or model call appears to be stuck. ...\"_\naborted: \"This turn was stopped before I could finish. ...\"","hierarchy":{"lvl0":"Features","lvl1":"Turn Time Budget","lvl2":"Honest terminal messages","lvl3":""}},
4606
4606
  {"objectID":"8a1f451537135b3f1ef892866610bb0dbabfe58ed1764bac2753046b8da98222","title":"MALFORMED_FUNCTION_CALL handling","url":"/docs/features/turn-time-budget#malformed_function_call-handling","content":"Gemini's MALFORMED_FUNCTION_CALL / UNEXPECTED_TOOL_CALL finish reasons\nmap to unified finishReason: \"error\" (never \"tool-calls\"). A\nMALFORMED_FUNCTION_CALL step is retried once with a corrective note;\nif it persists, the turn ends with stopReason: \"provider-error\" — usually\nworth a caller-side retry.","hierarchy":{"lvl0":"Features","lvl1":"Turn Time Budget","lvl2":"MALFORMED_FUNCTION_CALL handling","lvl3":""}},
4607
+ {"objectID":"b858770b3853e797dfaac8ecfbd0c1f86c320e6a94e46a2e60f8407f328f6090","title":"Other Gemini finish reasons","url":"/docs/features/turn-time-budget#other-gemini-finish-reasons","content":"The native Gemini loops (AI Studio and Vertex) map the SDK's finish reason onto\nthe unified values below and keep the verbatim value in rawFinishReason.\nVertex puts the unified value on finishReason; on AI Studio it is the\nunified field of the finish part that model middleware receives.\n\n| Gemini finish reason | finishReason |\n| ----------------------------------------------------------------------------------------- | ---------------- |\n| MAX_TOKENS, CONTINUATION (token limit reached before the model was done) | length |\n| TOO_MANY_TOOL_CALLS (the model called tools until the system cut the turn off) | tool-calls |\n| MALFORMED_FUNCTION_CALL, UNEXPECTED_TOOL_CALL | error |\n| SAFETY, RECITATION, BLOCKLIST, PROHIBITED_CONTENT, SPII, LANGUAGE, IMAGE_*¹ | content-filter |\n| STOP, OTHER, FINISH_REASON_UNSPECIFIED, IMAGE_OTHER, NO_IMAGE | stop |\n\n¹ IMAGE_SAFETY, IMAGE_PROHIBITED_CONTENT and IMAGE_RECITATION.\n\ntool-calls also marks a turn that ran out of maxSteps, so branch on\nstopReason to tell the two apart: TOO_MANY_TOOL_CALLS leaves\nstopReason: \"completed\", a spent step budget reports step-cap. A value the\nSDK adds later reads stop until it is mapped.","hierarchy":{"lvl0":"Features","lvl1":"Turn Time Budget","lvl2":"Other Gemini finish reasons","lvl3":""}},
4607
4608
  {"objectID":"a975fa8c9a970f09409f0cd78f26180dbef30bebfc60396f0eebda7776d8a3c3","title":"Telemetry","url":"/docs/features/turn-time-budget#telemetry","content":"result.analytics (when enableAnalytics is on) carries stepsUsed,\n toolCallCount, stopReason, elapsedMs, rawFinishReason.\nThe SDK emitter fires turn:lifecycle events (alongside\n tool:start/tool:end) for non-completed exits, tool timeouts, and\n malformed-call retries:","hierarchy":{"lvl0":"Features","lvl1":"Turn Time Budget","lvl2":"Telemetry","lvl3":""}},
4608
4609
  {"objectID":"4237dd71854673dfa0c8c155353abb6bf61149758ab7cd851436a49841b8dba3","title":"Video Analysis","url":"/docs/features/video-analysis","content":"Video Analysis\n\nComprehensive video analysis for NeuroLink, powered by Gemini 2.0 Flash. This feature goes beyond basic visual description—it provides a deep logical audit of video sequences to understand \"why\" and \"how\" events occur.\n\nKey Capabilities\nLogical Analysis: Dissect any video to extract the underlying intent, cause-and-effect, and logical progression.\nAction-Reaction Chain: A step-by-step audit of user or system actions and their immediate visual results.\nEvidence-Based Reporting: Detailed reasoning backed by structured visual indicators (colors, labels, text) in JSON format.\nStrategic Verdicts: High-level assessments of whether a workflow succeeded or failed logically.\n\nQuick Start\n\nHow It Works\nFrame Extraction: The system uses ffmpeg to extract high-quality keyframes from the video at calculated intervals.\nAnalysis Pipeline: These frames are sent to Gemini 2.0 Flash with a specialized system instruction focused on critical logic auditing.\nUnified Results: The resulting report is added directly to your standard generation output.\n\nUsage\n\nCLI Usage\n\nAnalyze any video file with a natural language prompt.\n\nSDK Usage\n\nIntegrate video analysis into your TypeScript/JavaScript projects.\n\nAdvanced SDK Examples\n\nCustom Model Configuration\nFine-tune the analysis by adjusting token limits and temperature.\n\nDisabling Tool Interference\nBy default, the model might try to use available tools. For pure video analysis, you can disable them.\n\nExamples\nUI/UX Bug Analysis\n\nIdentify why a user is unable to complete a form or where the interface is misleading.\n\nPrompt: \"Find why the user is getting stuck at the payment step. Look for validation errors or hidden UI elements.\"\nSilent Failure Detection\n\nDetect cases where an action is taken but the system provides no feedback (no loaders, no success messages).\n\nPrompt: \"Audit the 'Submit' button click. Is there a visual 'bond' between the click and the next state? Report any lag or missing loading indicators.\"\nWorkflow Validation\n\nVerify if a complex multi-step process follows the intended business logic.\n\nPrompt: \"Trace the logical progression from 'Item Selection' to 'Checkout'. Does every state change correspond to a user action?\"\nComparison Analysis\n\nCompare two recordings to find discrepancies in behavior.\n\nPrompt: \"Compare these two clips. The first one is the expected behavior and the second one has a bug. Identify the exact frame or timestamp where the logic deviates.\"\n\nCommand Gallery\n\nQuick CLI recipes for common tasks:\n\nThe Analysis Report\n\nThe output is structured into four major sections designed to give you a complete understanding of the video:\nStrategic Overview & Intent: Defines the core activity, expected logic, and provides a primary verdict.\nThe Action-Reaction Chain: A granular, step-by-step audit of attempts, results, and technical inferences.\nCritical Findings: Categorized milestones or anomalies with root cause analysis and visual evidence in JSON.\nFinal Assessment: A conclusive summary of the logical flow based on the observed evidence.\n\nBest Practices\nFrame Depth: Short videos (under 10s) get high-density frame coverage (1 per second), while long ones are intelligently sampled.\nPrompt Precision: While the model is a \"Critical Logic Auditor,\" you can guide it with specific questions about the activity.\nFormat: The analysis is returned as text in result.content, making it easy to store, display, or pipe to other tools.","hierarchy":{"lvl0":"Features","lvl1":"Video Analysis","lvl2":"","lvl3":""}},
4609
4610
  {"objectID":"288c031674e78fd4fcd753b2d753bff8b085367a321fac3e9845113df6361a2d","title":"Video Analysis","url":"/docs/features/video-analysis#video-analysis","content":"Comprehensive video analysis for NeuroLink, powered by Gemini 2.0 Flash. This feature goes beyond basic visual description—it provides a deep logical audit of video sequences to understand \"why\" and \"how\" events occur.","hierarchy":{"lvl0":"Features","lvl1":"Video Analysis","lvl2":"Video Analysis","lvl3":""}},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/neurolink",
3
- "version": "12.49.1",
3
+ "version": "12.49.2",
4
4
  "packageManager": "pnpm@10.15.1",
5
5
  "description": "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/call) for routing, tool selection and context budgeting. MCP-native (4 transports), voice TTS/STT/realtime, RAG, agents, memory, compaction, 9 observability exporters. OpenAI · Anthropic · Gemini · Bedrock · Azure · Ollama · TypeSafe Jev and more.",
6
6
  "author": {