@juspay/neurolink 12.17.3 → 12.17.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.
package/dist/neurolink.js CHANGED
@@ -4470,6 +4470,14 @@ Current user's request: ${currentInput}`;
4470
4470
  // remains false for backwards-compat with existing listeners that only
4471
4471
  // branch on the boolean.
4472
4472
  const aborted = isAbortError(error);
4473
+ // A native path that already emitted its own `generation:end` for this
4474
+ // failure marks the error, because on the failure path it has no result
4475
+ // object to mark. Re-emitting here would double every native failure.
4476
+ if (error &&
4477
+ typeof error === "object" &&
4478
+ error._generationEndEmitted) {
4479
+ return;
4480
+ }
4473
4481
  try {
4474
4482
  this.emitter.emit("generation:end", {
4475
4483
  provider: errProvider,
@@ -6501,10 +6509,27 @@ Current user's request: ${currentInput}`;
6501
6509
  // naming the one provider that failed is clearer than the generic
6502
6510
  // multi-provider wording. The multi-provider prefix is left untouched
6503
6511
  // so existing message-matching suites keep passing.
6512
+ // Both wrappers replace the provider's error with a new one, discarding
6513
+ // anything attached to it. `_generationEndEmitted` has to survive: lose it
6514
+ // and emitGenerateErrorEvent emits a second event for a failure the native
6515
+ // provider already reported. Returns the error rather than throwing so each
6516
+ // call site keeps its own `throw` — a never-returning helper reads better
6517
+ // but tsconfig.cli.json will not accept it as terminating the enclosing
6518
+ // function (TS2366). `cause` is set because the original error and its
6519
+ // stack were simply being thrown away.
6520
+ const wrapProviderError = (message) => {
6521
+ const wrapped = new Error(message, { cause: lastError });
6522
+ if (lastError &&
6523
+ lastError._generationEndEmitted) {
6524
+ wrapped._generationEndEmitted =
6525
+ true;
6526
+ }
6527
+ return wrapped;
6528
+ };
6504
6529
  if (providersToTry.length === 1) {
6505
- throw new Error(`Provider ${providersToTry[0]} failed: ${lastError?.message || "Unknown error"}`);
6530
+ throw wrapProviderError(`Provider ${providersToTry[0]} failed: ${lastError?.message || "Unknown error"}`);
6506
6531
  }
6507
- throw new Error(`Failed to generate text with all providers. Last error: ${lastError?.message || "Unknown error"}`);
6532
+ throw wrapProviderError(`Failed to generate text with all providers. Last error: ${lastError?.message || "Unknown error"}`);
6508
6533
  }
6509
6534
  /**
6510
6535
  * Create tool-aware system prompt that informs AI about available tools
@@ -1364,6 +1364,16 @@ export class GoogleAIStudioProvider extends BaseProvider {
1364
1364
  result._generationEndEmitted =
1365
1365
  true;
1366
1366
  }
1367
+ // The failure path has no result to carry that flag — `result` is null —
1368
+ // so mark the error instead. Without this the provider's own
1369
+ // `generation:end` (success: false) and the SDK's emitGenerateErrorEvent
1370
+ // both fire for one failed native generate, double-counting every failure
1371
+ // in analytics and as two Pipeline B spans. The success path above was
1372
+ // already deduplicated; only the catch branch was missed.
1373
+ if (!success && error && typeof error === "object") {
1374
+ error._generationEndEmitted =
1375
+ true;
1376
+ }
1367
1377
  emitter.emit("generation:end", {
1368
1378
  provider: this.providerName,
1369
1379
  responseTime: Date.now() - startTime,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/neurolink",
3
- "version": "12.17.3",
3
+ "version": "12.17.4",
4
4
  "packageManager": "pnpm@10.15.1",
5
5
  "description": "TypeScript AI SDK with 24+ LLM providers behind one consistent API. MCP-native (connect any MCP server), voice TTS/STT/realtime, RAG, agents, memory, context compaction. OpenAI · Anthropic · Gemini · Bedrock · Azure · Ollama · DeepSeek · NVIDIA NIM and more.",
6
6
  "author": {
@@ -254,7 +254,8 @@
254
254
  "test:aistudio-loop-characterization": "tsx test/continuous-test-suite-aistudio-loop-characterization.ts",
255
255
  "test:docs-mcp": "pnpm exec tsx test/continuous-test-suite-docs-mcp.ts",
256
256
  "test:vertex-claude-characterization": "tsx test/continuous-test-suite-vertex-claude-characterization.ts",
257
- "test:toolfree-guard-overhead": "pnpm exec tsx test/continuous-test-suite-toolfree-guard-overhead.ts"
257
+ "test:toolfree-guard-overhead": "pnpm exec tsx test/continuous-test-suite-toolfree-guard-overhead.ts",
258
+ "test:native-failure-events": "pnpm exec tsx test/continuous-test-suite-native-failure-events.ts"
258
259
  },
259
260
  "files": [
260
261
  "dist",