@juspay/neurolink 12.37.2 → 12.37.4

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.
@@ -118,6 +118,7 @@ export const MODEL_CONTEXT_WINDOWS = {
118
118
  // Claude 5.5 / 5.1 (Sep 2026) — 1M context window, confirmed on
119
119
  // platform.claude.com/docs/en/about-claude/models/overview
120
120
  "claude-opus-5-5": 1_000_000,
121
+ "claude-sonnet-5-5": 1_000_000,
121
122
  "claude-fable-5-1": 1_000_000,
122
123
  // Claude 5 (mid 2026) — 1M context window
123
124
  "claude-sonnet-5": 1_000_000,
@@ -216,6 +217,7 @@ export const MODEL_CONTEXT_WINDOWS = {
216
217
  _default: 1_048_576,
217
218
  // Claude on Vertex
218
219
  "claude-opus-5-5": 1_000_000,
220
+ "claude-sonnet-5-5": 1_000_000,
219
221
  "claude-fable-5-1": 1_000_000,
220
222
  "claude-sonnet-5": 1_000_000,
221
223
  "claude-opus-4-6": 1_000_000,
@@ -255,6 +257,7 @@ export const MODEL_CONTEXT_WINDOWS = {
255
257
  _default: 200_000,
256
258
  // Claude 5.5 / 5.1 (Sep 2026)
257
259
  "anthropic.claude-opus-5-5": 1_000_000,
260
+ "anthropic.claude-sonnet-5-5": 1_000_000,
258
261
  "anthropic.claude-fable-5-1": 1_000_000,
259
262
  // Claude 4.6
260
263
  "anthropic.claude-opus-4-6-v1": 1_000_000,
@@ -366,6 +366,7 @@ export declare enum AnthropicModels {
366
366
  CLAUDE_SONNET_5 = "claude-sonnet-5",
367
367
  CLAUDE_FABLE_5 = "claude-fable-5",
368
368
  CLAUDE_OPUS_5_5 = "claude-opus-5-5",
369
+ CLAUDE_SONNET_5_5 = "claude-sonnet-5-5",
369
370
  CLAUDE_FABLE_5_1 = "claude-fable-5-1",
370
371
  CLAUDE_OPUS_4_8 = "claude-opus-4-8",
371
372
  CLAUDE_OPUS_4_7 = "claude-opus-4-7",
@@ -502,6 +502,7 @@ export var AnthropicModels;
502
502
  // Claude 5.5 / 5.1 Series (September 2026) — confirmed on
503
503
  // platform.claude.com/docs/en/about-claude/models/overview
504
504
  AnthropicModels["CLAUDE_OPUS_5_5"] = "claude-opus-5-5";
505
+ AnthropicModels["CLAUDE_SONNET_5_5"] = "claude-sonnet-5-5";
505
506
  AnthropicModels["CLAUDE_FABLE_5_1"] = "claude-fable-5-1";
506
507
  // Claude 4.7 / 4.8 Series
507
508
  AnthropicModels["CLAUDE_OPUS_4_8"] = "claude-opus-4-8";
@@ -37,6 +37,14 @@ export function createGeminiLoopAdapter(config) {
37
37
  }
38
38
  return original;
39
39
  };
40
+ // Per-turn monotonic counter for `toolCallId` generation. `executeStep` is
41
+ // called once per loop step, and a fresh `createGeminiLoopAdapter` closure
42
+ // is made per turn (per generate()/stream() call), so this resets at the
43
+ // right lifetime while staying unique across every step of one turn —
44
+ // unlike the step-local array index it replaces, which restarted at 0 on
45
+ // every step and let two calls to the same tool in different steps collide
46
+ // on one id once both landed in the same flattened per-turn list.
47
+ let nextCallIndex = 0;
40
48
  return {
41
49
  providerLabel: config.providerLabel,
42
50
  maxSteps: config.maxSteps,
@@ -138,9 +146,11 @@ export function createGeminiLoopAdapter(config) {
138
146
  // projects the next request from.
139
147
  config.noteUsage?.(collected.inputTokens, collected.outputTokens);
140
148
  const text = extractTextFromParts(collected.rawResponseParts);
141
- // Names cross the engine boundary in their ORIGINAL form.
142
- const allCalls = collected.stepFunctionCalls.map((call, index) => ({
143
- id: `${config.providerLabel}_${index}_${call.name}`,
149
+ // Names cross the engine boundary in their ORIGINAL form. `id` uses the
150
+ // turn-scoped counter above, not a step-local map index, so two calls
151
+ // to the same tool in different steps of one turn get distinct ids.
152
+ const allCalls = collected.stepFunctionCalls.map((call) => ({
153
+ id: `${config.providerLabel}_${nextCallIndex++}_${call.name}`,
144
154
  name: originalNameFor(call.name),
145
155
  args: call.args,
146
156
  }));
@@ -37,6 +37,20 @@ export const anthropicManifest = {
37
37
  jsonMode: true,
38
38
  samplingParams: false, // matches SAMPLING_PARAM_REJECTING_FAMILIES /opus[-_.]?5(?![0-9])/i
39
39
  },
40
+ "claude-sonnet-5-5": {
41
+ aliases: ["sonnet-5.5"],
42
+ displayName: "Claude Sonnet 5.5",
43
+ contextWindow: 1_000_000,
44
+ maxOutputTokens: 128_000,
45
+ // No pricingPerMTok DELIBERATELY: PRICING.anthropic already carries
46
+ // real rates for this id (input 2.0/output 10.0 per MTok) — see the
47
+ // claude-sonnet-5 comment below for why this defers to that table.
48
+ vision: true,
49
+ functionCalling: true,
50
+ reasoning: true,
51
+ jsonMode: true,
52
+ samplingParams: false, // matches SAMPLING_PARAM_REJECTING_FAMILIES /sonnet[-_.]?5(?![0-9])/i
53
+ },
40
54
  "claude-fable-5-1": {
41
55
  aliases: ["fable-5.1"],
42
56
  displayName: "Claude Fable 5.1",
@@ -1174,6 +1174,48 @@ const LEGACY_MODEL_REGISTRY = {
1174
1174
  releaseDate: "2026-06-30",
1175
1175
  category: "general",
1176
1176
  },
1177
+ // "claude-sonnet-latest" stays on CLAUDE_SONNET_5 until someone decides to
1178
+ // move it; this entry sits after that one so resolver ties still go to it.
1179
+ [AnthropicModels.CLAUDE_SONNET_5_5]: {
1180
+ id: AnthropicModels.CLAUDE_SONNET_5_5,
1181
+ name: "Claude Sonnet 5.5",
1182
+ provider: AIProviderName.ANTHROPIC,
1183
+ description: "The best combination of speed and intelligence",
1184
+ capabilities: {
1185
+ vision: true,
1186
+ functionCalling: true,
1187
+ codeGeneration: true,
1188
+ reasoning: true,
1189
+ multimodal: true,
1190
+ streaming: true,
1191
+ jsonMode: false,
1192
+ },
1193
+ pricing: {
1194
+ inputCostPer1K: 0.002,
1195
+ outputCostPer1K: 0.01,
1196
+ currency: "USD",
1197
+ },
1198
+ performance: { speed: "fast", quality: "high", accuracy: "high" },
1199
+ limits: {
1200
+ maxContextTokens: 1000000,
1201
+ maxOutputTokens: 128000,
1202
+ maxRequestsPerMinute: 50,
1203
+ },
1204
+ useCases: {
1205
+ coding: 9,
1206
+ creative: 9,
1207
+ analysis: 9,
1208
+ conversation: 9,
1209
+ reasoning: 9,
1210
+ translation: 9,
1211
+ summarization: 9,
1212
+ },
1213
+ aliases: ["sonnet-5.5"],
1214
+ deprecated: false,
1215
+ isLocal: false,
1216
+ releaseDate: "2026-09-28",
1217
+ category: "general",
1218
+ },
1177
1219
  [AnthropicModels.CLAUDE_FABLE_5]: {
1178
1220
  id: AnthropicModels.CLAUDE_FABLE_5,
1179
1221
  name: "Claude Fable 5",
@@ -2595,7 +2595,11 @@ export class GoogleVertexProvider extends BaseProvider {
2595
2595
  finalText = engineResult.text;
2596
2596
  lastFinishReason = engineResult.rawStopReason ?? lastFinishReason;
2597
2597
  for (const call of engineResult.toolCalls) {
2598
- allToolCalls.push({ toolName: call.name, args: call.args });
2598
+ allToolCalls.push({
2599
+ toolCallId: call.id,
2600
+ toolName: call.name,
2601
+ args: call.args,
2602
+ });
2599
2603
  }
2600
2604
  for (const execution of engineResult.toolExecutions) {
2601
2605
  toolExecutions.push({
@@ -2747,6 +2751,17 @@ export class GoogleVertexProvider extends BaseProvider {
2747
2751
  reasoningTokens: totalReasoningTokens,
2748
2752
  }),
2749
2753
  responseTime,
2754
+ // The complete attempted-call record (name/args/id), independent of
2755
+ // toolsUsed's success-only names — mirrors the native Anthropic direct
2756
+ // / OpenAI-compatible / SageMaker paths (toolCallsFromSummaries) and
2757
+ // the working Gemini-on-Vertex STREAM path just above. Previously
2758
+ // absent here, so a tool the loop ran internally never reached the
2759
+ // caller's result.toolCalls even though toolsUsed/toolExecutions did.
2760
+ toolCalls: externalToolCalls.map((tc) => ({
2761
+ toolCallId: tc.toolCallId,
2762
+ toolName: tc.toolName,
2763
+ args: tc.args,
2764
+ })),
2750
2765
  toolsUsed: externalToolCalls.map((tc) => tc.toolName),
2751
2766
  toolExecutions: resolveToolExecutionRecords(options, externalToolExecutions),
2752
2767
  enhancedWithTools: externalToolCalls.length > 0,
@@ -4699,7 +4714,11 @@ export class GoogleVertexProvider extends BaseProvider {
4699
4714
  },
4700
4715
  buildToolResultMessages: (conversation, stepResult, toolResults, engineStep) => {
4701
4716
  for (const result of toolResults) {
4702
- allToolCalls.push({ toolName: result.name, args: result.args });
4717
+ allToolCalls.push({
4718
+ toolCallId: result.id,
4719
+ toolName: result.name,
4720
+ args: result.args,
4721
+ });
4703
4722
  // Recorded here as well: `toolExecutions` feeds
4704
4723
  // resolveToolExecutionRecords and the result's own
4705
4724
  // toolExecutions, and pushing only to allToolCalls left it empty
@@ -5059,7 +5078,23 @@ export class GoogleVertexProvider extends BaseProvider {
5059
5078
  }
5060
5079
  releaseTurnResources();
5061
5080
  const responseTime = Date.now() - startTime;
5062
- const externalToolCalls = allToolCalls.filter((tc) => tc.toolName !== "final_result");
5081
+ // Sourced from `engineResult.toolCalls` when the turn produced one, not
5082
+ // the local `allToolCalls` (fed only by the `buildToolResultMessages`
5083
+ // hook below). The engine's own accumulator is pushed to unconditionally
5084
+ // per dispatched batch, before the abortedMidBatch check that skips
5085
+ // `buildToolResultMessages` for that step — so a tool that finished
5086
+ // executing in a batch cut short by an abort is present in
5087
+ // `engineResult.toolCalls` but would otherwise never reach
5088
+ // `allToolCalls`. `allToolCalls` remains the fallback for the rare case
5089
+ // where `resultPromise` itself rejects and `engineResult` never resolves.
5090
+ const engineToolCalls = engineResult
5091
+ ? engineResult.toolCalls.map((call) => ({
5092
+ toolCallId: call.id,
5093
+ toolName: call.name,
5094
+ args: call.args,
5095
+ }))
5096
+ : allToolCalls;
5097
+ const externalToolCalls = engineToolCalls.filter((tc) => tc.toolName !== "final_result");
5063
5098
  const externalToolExecutions = toolExecutions.filter((te) => te.name !== "final_result");
5064
5099
  // Absolute backstop — no code path may surface empty content on a turn
5065
5100
  // that ran tools (the consumer-facing "empty response" incident shape).
@@ -5136,6 +5171,17 @@ export class GoogleVertexProvider extends BaseProvider {
5136
5171
  ...(totalReasoningTokens > 0 && { reasoning: totalReasoningTokens }),
5137
5172
  },
5138
5173
  responseTime,
5174
+ // The complete attempted-call record (name/args/id), independent of
5175
+ // toolsUsed's success-only names — mirrors the native Anthropic direct
5176
+ // / OpenAI-compatible / SageMaker paths (toolCallsFromSummaries) and
5177
+ // the working Gemini-on-Vertex STREAM path. Previously absent here, so
5178
+ // a tool the loop ran internally never reached the caller's
5179
+ // result.toolCalls even though toolsUsed/toolExecutions did.
5180
+ toolCalls: externalToolCalls.map((tc) => ({
5181
+ toolCallId: tc.toolCallId,
5182
+ toolName: tc.toolName,
5183
+ args: tc.args,
5184
+ })),
5139
5185
  toolsUsed: externalToolCalls.map((tc) => tc.toolName),
5140
5186
  toolExecutions: resolveToolExecutionRecords(options, externalToolExecutions),
5141
5187
  enhancedWithTools: externalToolCalls.length > 0,
@@ -100,6 +100,13 @@ const PRICING = {
100
100
  cacheRead: 0.2 / 1_000_000,
101
101
  cacheCreation: 5.0 / 1_000_000,
102
102
  },
103
+ // Sonnet 5.5 bills exactly as Sonnet 5 does, cache rates included.
104
+ "claude-sonnet-5-5": {
105
+ input: 2.0 / 1_000_000,
106
+ output: 10.0 / 1_000_000,
107
+ cacheRead: 0.2 / 1_000_000,
108
+ cacheCreation: 2.5 / 1_000_000,
109
+ },
103
110
  "claude-fable-5": {
104
111
  input: 10.0 / 1_000_000,
105
112
  output: 50.0 / 1_000_000,
@@ -281,6 +288,13 @@ const PRICING = {
281
288
  cacheRead: 0.2 / 1_000_000,
282
289
  cacheCreation: 5.0 / 1_000_000,
283
290
  },
291
+ // Sonnet 5.5 bills exactly as Sonnet 5 does, cache rates included.
292
+ "claude-sonnet-5-5": {
293
+ input: 2.0 / 1_000_000,
294
+ output: 10.0 / 1_000_000,
295
+ cacheRead: 0.2 / 1_000_000,
296
+ cacheCreation: 2.5 / 1_000_000,
297
+ },
284
298
  "claude-opus-5": {
285
299
  input: 5.0 / 1_000_000,
286
300
  output: 25.0 / 1_000_000,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/neurolink",
3
- "version": "12.37.2",
3
+ "version": "12.37.4",
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": {