@juspay/neurolink 13.6.0 → 13.6.1

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.
@@ -6,6 +6,7 @@ import { logger } from "../../utils/logger.js";
6
6
  import { TOOL_EVENTS_WRAPPED } from "../../types/index.js";
7
7
  import { getKeyCount } from "../../utils/transformationUtils.js";
8
8
  import { extractIsErrorText } from "../../utils/toolResultStatus.js";
9
+ import { createToolExecutionId } from "../../utils/toolExecutionId.js";
9
10
  import { convertJsonSchemaToZod } from "../../utils/schemaConversion.js";
10
11
  import { generateToolOutputPreview, DEFAULT_MAX_PREVIEW_BYTES, RETRIEVE_CONTEXT_TOOL_NAME, } from "../../context/toolOutputLimits.js";
11
12
  /**
@@ -516,9 +517,7 @@ export class ToolsManager {
516
517
  // listener can pair this start with its end.
517
518
  const eventIds = {
518
519
  ...idField,
519
- executionId: `${toolName}-${Date.now()}-${Math.random()
520
- .toString(36)
521
- .slice(2, 11)}`,
520
+ executionId: createToolExecutionId(toolName),
522
521
  };
523
522
  return withSpan({
524
523
  name: toolSpanName(toolName),
@@ -353,6 +353,7 @@ const validateToolInput = (tool, input) => {
353
353
  ? resolveToolInputSchema(tool.inputSchema)
354
354
  : undefined;
355
355
  if (!schema ||
356
+ typeof schema !== "object" ||
356
357
  !("safeParse" in schema) ||
357
358
  typeof schema.safeParse !== "function") {
358
359
  return undefined;
package/dist/neurolink.js CHANGED
@@ -76,6 +76,7 @@ import { SpanSerializer } from "./observability/utils/spanSerializer.js";
76
76
  import { endSpanWhenDropped, withSpan } from "./telemetry/withSpan.js";
77
77
  import { getActiveTraceContext } from "./telemetry/traceContext.js";
78
78
  import { calculateCost } from "./utils/pricing.js";
79
+ import { createToolExecutionId } from "./utils/toolExecutionId.js";
79
80
  import { acquireTelemetry, ensureTelemetry, flushOpenTelemetry, getLangfuseHealthStatus, isOpenTelemetryInitialized, releaseTelemetry, setLangfuseContext, traceMetadataFromContext, } from "./services/server/ai/observability/instrumentation.js";
80
81
  import { clearChecklistState, createChecklistTools, getChecklistState, resolveChecklistSessionId, } from "./agent/taskChecklist.js";
81
82
  import { cancelDelegates as cancelBackgroundDelegates, collectDelegates as collectBackgroundDelegates, configureDelegation, createDelegationTools, spawnDelegate as spawnBackgroundDelegate, } from "./agent/backgroundDelegation.js";
@@ -10599,7 +10600,7 @@ Current user's request: ${currentInput}`;
10599
10600
  * @returns executionId for tracking this specific execution
10600
10601
  */
10601
10602
  emitToolStart(toolName, input, startTime = Date.now()) {
10602
- const executionId = `${toolName}-${startTime}-${Math.random().toString(36).substr(2, 9)}`;
10603
+ const executionId = createToolExecutionId(toolName, startTime);
10603
10604
  // Create execution context for tracking
10604
10605
  const context = {
10605
10606
  executionId,
@@ -443,6 +443,13 @@ export type ToolConfig = {
443
443
  * full. Note: the instance-level `include` list deliberately does NOT
444
444
  * force tools hot — it scopes the catalog, and discovery defers within
445
445
  * that scope (a scoped-but-large catalog is exactly where deferral pays).
446
+ *
447
+ * What the model and your listeners see once discovery is on: the
448
+ * `search_tools` description ends with an instruction to check the catalog
449
+ * before saying a task cannot be done; each `search_tools` call emits
450
+ * `tool:start` and `tool:end` (paired by `executionId`) and is traced and
451
+ * observed like any other tool call; and the events of every wrapped
452
+ * external tool carry an `executionId`.
446
453
  * Default: false.
447
454
  */
448
455
  discovery?: boolean;
@@ -451,7 +458,12 @@ export type ToolConfig = {
451
458
  * - `"external"`: tools of servers attached with `addExternalMCPServer`.
452
459
  * - `"all"`: every tool in the request's record except the built-in tools,
453
460
  * so tools registered with `registerTool`/`registerTools` and in-process
454
- * MCP tools are deferred as well.
461
+ * MCP tools are deferred as well. That includes the tools NeuroLink
462
+ * registers for its own features through `registerTool()`, such as
463
+ * `retrieve_context` (memory retrieval), the skills tools, and the tools
464
+ * of `registerTaskTools`, `registerDelegationTools`,
465
+ * `registerBackgroundCommandTools` and `registerGitTools`. Name them in
466
+ * `discoveryAlwaysVisible` to keep them in full.
455
467
  * Per-call tools, per-call whitelists, forced `toolChoice` tools and
456
468
  * already-discovered tools stay hot in both scopes. Ignored unless
457
469
  * `discovery` is true.
@@ -1843,7 +1843,9 @@ export type NativeGenerateLoopArgs = {
1843
1843
  /**
1844
1844
  * Builds the v3 declaration for one tool. When set, every step declares any
1845
1845
  * tool that joined `toolsRecord` mid-turn (discovery's search_tools loads
1846
- * tools into it), so the model can call what it just loaded.
1846
+ * tools into it), so the model can call what it just loaded. Only the
1847
+ * OpenAI-compatible `generate()` path supplies it; the other providers that
1848
+ * run this loop do not declare a tool `search_tools` loaded mid-turn.
1847
1849
  */
1848
1850
  declareTool?: (name: string, tool: Tool) => Record<string, unknown>;
1849
1851
  /** The turn's resolved tool choice, applied per step via `resolveStepToolChoice`. */
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @description Builds the id that pairs one tool call's `tool:start` and `tool:end` events.
3
+ * @param toolName {string} - Name of the tool being run.
4
+ * @param startTime {number} - When the call started, in epoch milliseconds.
5
+ * @returns {string} `<toolName>-<startTime>-<nine random base-36 characters>`.
6
+ */
7
+ export declare function createToolExecutionId(toolName: string, startTime?: number): string;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @description Builds the id that pairs one tool call's `tool:start` and `tool:end` events.
3
+ * @param toolName {string} - Name of the tool being run.
4
+ * @param startTime {number} - When the call started, in epoch milliseconds.
5
+ * @returns {string} `<toolName>-<startTime>-<nine random base-36 characters>`.
6
+ */
7
+ export function createToolExecutionId(toolName, startTime = Date.now()) {
8
+ return `${toolName}-${startTime}-${Math.random().toString(36).slice(2, 11)}`;
9
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/neurolink",
3
- "version": "13.6.0",
3
+ "version": "13.6.1",
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": {