@juspay/neurolink 9.70.7 → 9.72.0
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/CHANGELOG.md +12 -0
- package/dist/browser/neurolink.min.js +362 -344
- package/dist/core/constants.d.ts +1 -0
- package/dist/core/constants.js +2 -0
- package/dist/core/toolRouting.d.ts +59 -0
- package/dist/core/toolRouting.js +232 -0
- package/dist/lib/core/constants.d.ts +1 -0
- package/dist/lib/core/constants.js +2 -0
- package/dist/lib/core/toolRouting.d.ts +59 -0
- package/dist/lib/core/toolRouting.js +233 -0
- package/dist/lib/neurolink.d.ts +31 -1
- package/dist/lib/neurolink.js +241 -17
- package/dist/lib/providers/googleVertex.js +257 -30
- package/dist/lib/services/server/ai/observability/instrumentation.d.ts +10 -1
- package/dist/lib/services/server/ai/observability/instrumentation.js +36 -1
- package/dist/lib/telemetry/attributes.d.ts +31 -0
- package/dist/lib/telemetry/attributes.js +48 -0
- package/dist/lib/telemetry/index.d.ts +1 -1
- package/dist/lib/telemetry/index.js +1 -1
- package/dist/lib/types/config.d.ts +8 -0
- package/dist/lib/types/index.d.ts +1 -0
- package/dist/lib/types/index.js +1 -0
- package/dist/lib/types/toolRouting.d.ts +91 -0
- package/dist/lib/types/toolRouting.js +19 -0
- package/dist/lib/utils/anthropicTraceSanitizer.d.ts +7 -0
- package/dist/lib/utils/anthropicTraceSanitizer.js +26 -0
- package/dist/lib/utils/mcpErrorText.d.ts +16 -0
- package/dist/lib/utils/mcpErrorText.js +36 -0
- package/dist/neurolink.d.ts +31 -1
- package/dist/neurolink.js +241 -17
- package/dist/providers/googleVertex.js +257 -30
- package/dist/services/server/ai/observability/instrumentation.d.ts +10 -1
- package/dist/services/server/ai/observability/instrumentation.js +36 -1
- package/dist/telemetry/attributes.d.ts +31 -0
- package/dist/telemetry/attributes.js +48 -0
- package/dist/telemetry/index.d.ts +1 -1
- package/dist/telemetry/index.js +1 -1
- package/dist/types/config.d.ts +8 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/toolRouting.d.ts +91 -0
- package/dist/types/toolRouting.js +18 -0
- package/dist/utils/anthropicTraceSanitizer.d.ts +7 -0
- package/dist/utils/anthropicTraceSanitizer.js +25 -0
- package/dist/utils/mcpErrorText.d.ts +16 -0
- package/dist/utils/mcpErrorText.js +36 -0
- package/package.json +2 -1
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-call tool routing — configuration and catalog types.
|
|
3
|
+
*
|
|
4
|
+
* Host applications can register large numbers of custom tools (typically MCP
|
|
5
|
+
* server tools) whose names are prefixed with their server id
|
|
6
|
+
* (`${serverId}_${toolName}`). When tool routing is enabled, a cheap router
|
|
7
|
+
* LLM call runs once per `stream()` turn, picks the servers relevant to the
|
|
8
|
+
* user query, and the tools of every unpicked server are appended to the
|
|
9
|
+
* request's `excludeTools` denylist before the main model call.
|
|
10
|
+
*
|
|
11
|
+
* Denylist semantics are deliberate: the router only knows the declared
|
|
12
|
+
* server catalog — a strict subset of the real tool set. Excluding unpicked
|
|
13
|
+
* servers leaves NeuroLink's built-in direct tools, always-include servers,
|
|
14
|
+
* and any tools outside the catalog untouched. The whole mechanism fails
|
|
15
|
+
* open: any router failure resolves to an empty exclusion list (all tools),
|
|
16
|
+
* identical to routing being disabled.
|
|
17
|
+
*/
|
|
18
|
+
import type { GenerateOptions, GenerateResult } from "./generate.js";
|
|
19
|
+
/** One routable server as declared by the host application. */
|
|
20
|
+
export type ToolRoutingServerDescriptor = {
|
|
21
|
+
/**
|
|
22
|
+
* Server id. Must be the prefix used when the host registered the server's
|
|
23
|
+
* tools (`${id}_${toolName}`) — tool names are grouped by this prefix.
|
|
24
|
+
*/
|
|
25
|
+
id: string;
|
|
26
|
+
/** Routing-grade server description shown to the router LLM. */
|
|
27
|
+
description: string;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* LLM settings for the router call. Fields omitted here fall back to the
|
|
31
|
+
* stream call's own provider/model/region, so the router uses the same model
|
|
32
|
+
* as the main chat call unless explicitly overridden.
|
|
33
|
+
*/
|
|
34
|
+
export type ToolRoutingModelConfig = {
|
|
35
|
+
provider?: string;
|
|
36
|
+
model?: string;
|
|
37
|
+
region?: string;
|
|
38
|
+
/** Router sampling temperature. Default: 0. */
|
|
39
|
+
temperature?: number;
|
|
40
|
+
};
|
|
41
|
+
/** Constructor-level configuration for pre-call tool routing. */
|
|
42
|
+
export type ToolRoutingConfig = {
|
|
43
|
+
/** Master switch. Routing runs only when true AND the server catalog is non-empty. */
|
|
44
|
+
enabled: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Routable server catalog. Hosts that only know their servers after
|
|
47
|
+
* constructing NeuroLink can supply it later via
|
|
48
|
+
* `neurolink.setToolRoutingServers()` instead.
|
|
49
|
+
*/
|
|
50
|
+
servers?: ToolRoutingServerDescriptor[];
|
|
51
|
+
/**
|
|
52
|
+
* Server ids whose tools are always kept and never offered to the router
|
|
53
|
+
* (e.g. utility / reasoning / chart servers every turn may need).
|
|
54
|
+
*/
|
|
55
|
+
alwaysIncludeServerIds?: string[];
|
|
56
|
+
/** Hard ceiling for the router LLM call before failing open. Default: 15000. */
|
|
57
|
+
timeoutMs?: number;
|
|
58
|
+
/** Router LLM override. Defaults to the stream call's provider/model/region at temperature 0. */
|
|
59
|
+
routerModel?: ToolRoutingModelConfig;
|
|
60
|
+
/**
|
|
61
|
+
* Override for the instruction text placed before the user query in the
|
|
62
|
+
* router prompt (role + task framing). When omitted, the SDK built-in
|
|
63
|
+
* default is used. The server catalog, user query, and output rules are
|
|
64
|
+
* always appended by the SDK regardless of this value.
|
|
65
|
+
*/
|
|
66
|
+
routerPromptPrefix?: string;
|
|
67
|
+
};
|
|
68
|
+
/** Catalog entry pairing a server descriptor with its registered tool names. */
|
|
69
|
+
export type ToolRoutingCatalogEntry = {
|
|
70
|
+
id: string;
|
|
71
|
+
description: string;
|
|
72
|
+
/** Registered tool names for this server, i.e. `${serverId}_${toolName}`. */
|
|
73
|
+
toolNames: string[];
|
|
74
|
+
};
|
|
75
|
+
/** Parameters for `resolveToolRoutingExclusions()`. */
|
|
76
|
+
export type ToolRoutingResolutionParams = {
|
|
77
|
+
/** Full catalog; always-include servers are filtered out internally. */
|
|
78
|
+
catalog: ToolRoutingCatalogEntry[];
|
|
79
|
+
/** Server ids never offered to the router. */
|
|
80
|
+
alwaysIncludeServerIds: string[];
|
|
81
|
+
/** Current user query (the stream input text, before memory enrichment). */
|
|
82
|
+
userQuery: string;
|
|
83
|
+
/** Instruction text placed before the user query. Defaults to the SDK built-in. */
|
|
84
|
+
routerPromptPrefix?: string;
|
|
85
|
+
/** Router LLM settings, already resolved against the stream call's options. */
|
|
86
|
+
routerModel: ToolRoutingModelConfig;
|
|
87
|
+
/** Timeout for the router call in milliseconds. */
|
|
88
|
+
timeoutMs: number;
|
|
89
|
+
/** Invokes the router LLM — `NeuroLink.generate` bound by the caller. */
|
|
90
|
+
generateFn: (options: GenerateOptions) => Promise<GenerateResult>;
|
|
91
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-call tool routing — configuration and catalog types.
|
|
3
|
+
*
|
|
4
|
+
* Host applications can register large numbers of custom tools (typically MCP
|
|
5
|
+
* server tools) whose names are prefixed with their server id
|
|
6
|
+
* (`${serverId}_${toolName}`). When tool routing is enabled, a cheap router
|
|
7
|
+
* LLM call runs once per `stream()` turn, picks the servers relevant to the
|
|
8
|
+
* user query, and the tools of every unpicked server are appended to the
|
|
9
|
+
* request's `excludeTools` denylist before the main model call.
|
|
10
|
+
*
|
|
11
|
+
* Denylist semantics are deliberate: the router only knows the declared
|
|
12
|
+
* server catalog — a strict subset of the real tool set. Excluding unpicked
|
|
13
|
+
* servers leaves NeuroLink's built-in direct tools, always-include servers,
|
|
14
|
+
* and any tools outside the catalog untouched. The whole mechanism fails
|
|
15
|
+
* open: any router failure resolves to an empty exclusion list (all tools),
|
|
16
|
+
* identical to routing being disabled.
|
|
17
|
+
*/
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { VertexAnthropicMessage } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Strips base64 image/PDF payloads from Anthropic messages before they go on a
|
|
4
|
+
* trace attribute — one screenshot would otherwise be megabytes on a span.
|
|
5
|
+
* Other block types pass through; the serializer still applies its length cap.
|
|
6
|
+
*/
|
|
7
|
+
export declare function sanitizeAnthropicMessagesForTrace(messages: VertexAnthropicMessage[]): Array<Record<string, unknown>>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strips base64 image/PDF payloads from Anthropic messages before they go on a
|
|
3
|
+
* trace attribute — one screenshot would otherwise be megabytes on a span.
|
|
4
|
+
* Other block types pass through; the serializer still applies its length cap.
|
|
5
|
+
*/
|
|
6
|
+
export function sanitizeAnthropicMessagesForTrace(messages) {
|
|
7
|
+
return messages.map((message) => {
|
|
8
|
+
if (typeof message.content === "string") {
|
|
9
|
+
return { role: message.role, content: message.content };
|
|
10
|
+
}
|
|
11
|
+
return {
|
|
12
|
+
role: message.role,
|
|
13
|
+
content: message.content.map((block) => {
|
|
14
|
+
if (block.type === "image" || block.type === "document") {
|
|
15
|
+
return {
|
|
16
|
+
type: block.type,
|
|
17
|
+
media_type: block.source.media_type,
|
|
18
|
+
base64_chars: block.source.data.length,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
return block;
|
|
22
|
+
}),
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
}
|
|
@@ -8,3 +8,19 @@
|
|
|
8
8
|
* must happen here and propagate to all three surfaces.
|
|
9
9
|
*/
|
|
10
10
|
export declare function extractMcpErrorText(raw: unknown): string;
|
|
11
|
+
/**
|
|
12
|
+
* MCP tools signal failure by RETURNING `{ isError: true, ... }`, not throwing,
|
|
13
|
+
* so execute()'s try/catch never sees it. Returns a capped status message for
|
|
14
|
+
* failures (undefined for success) for the caller to set the span error level.
|
|
15
|
+
*
|
|
16
|
+
* Generic over input shape: accepts either a result object or a JSON-stringified
|
|
17
|
+
* envelope (different providers hand back different shapes), mirroring
|
|
18
|
+
* `extractMcpErrorText`. A non-JSON string has no `isError` field, so it is
|
|
19
|
+
* correctly treated as "not an error" (→ undefined).
|
|
20
|
+
*
|
|
21
|
+
* Layered on `extractMcpErrorText`: this adds the `isError === true` gate and
|
|
22
|
+
* the human-readable "MCP tool returned isError: …" prefix, while the shared
|
|
23
|
+
* helper owns the content parsing and the 500-char cap. When `isError` is set
|
|
24
|
+
* but no readable text is present, falls back to a generic message.
|
|
25
|
+
*/
|
|
26
|
+
export declare function extractMcpToolErrorMessage(result: unknown): string | undefined;
|
|
@@ -33,3 +33,39 @@ export function extractMcpErrorText(raw) {
|
|
|
33
33
|
.map((c) => c.text);
|
|
34
34
|
return texts.join(" ").substring(0, 500);
|
|
35
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* MCP tools signal failure by RETURNING `{ isError: true, ... }`, not throwing,
|
|
38
|
+
* so execute()'s try/catch never sees it. Returns a capped status message for
|
|
39
|
+
* failures (undefined for success) for the caller to set the span error level.
|
|
40
|
+
*
|
|
41
|
+
* Generic over input shape: accepts either a result object or a JSON-stringified
|
|
42
|
+
* envelope (different providers hand back different shapes), mirroring
|
|
43
|
+
* `extractMcpErrorText`. A non-JSON string has no `isError` field, so it is
|
|
44
|
+
* correctly treated as "not an error" (→ undefined).
|
|
45
|
+
*
|
|
46
|
+
* Layered on `extractMcpErrorText`: this adds the `isError === true` gate and
|
|
47
|
+
* the human-readable "MCP tool returned isError: …" prefix, while the shared
|
|
48
|
+
* helper owns the content parsing and the 500-char cap. When `isError` is set
|
|
49
|
+
* but no readable text is present, falls back to a generic message.
|
|
50
|
+
*/
|
|
51
|
+
export function extractMcpToolErrorMessage(result) {
|
|
52
|
+
let resultObj = result;
|
|
53
|
+
if (typeof resultObj === "string") {
|
|
54
|
+
try {
|
|
55
|
+
resultObj = JSON.parse(resultObj);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (!resultObj || typeof resultObj !== "object") {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
if (resultObj.isError !== true) {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
const text = extractMcpErrorText(resultObj);
|
|
68
|
+
return text
|
|
69
|
+
? `MCP tool returned isError: ${text}`
|
|
70
|
+
: "MCP tool returned isError: true";
|
|
71
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juspay/neurolink",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.72.0",
|
|
4
4
|
"packageManager": "pnpm@10.15.1",
|
|
5
5
|
"description": "Universal AI Development Platform with working MCP integration, multi-provider support, voice (TTS/STT/realtime), and professional CLI. 58+ external MCP servers discoverable, multimodal file processing, RAG pipelines. Build, test, and deploy AI applications with 21+ providers: OpenAI, Anthropic, Google AI Studio, Google Vertex, AWS Bedrock, Azure OpenAI, Mistral, LiteLLM, SageMaker, Hugging Face, Ollama, OpenAI-compatible, OpenRouter, DeepSeek, NVIDIA NIM, LM Studio, llama.cpp, plus voice (OpenAI TTS, ElevenLabs, Deepgram, Azure Speech).",
|
|
6
6
|
"author": {
|
|
@@ -104,6 +104,7 @@
|
|
|
104
104
|
"test:log-sanitize": "npx tsx test/continuous-test-suite-log-sanitize.ts",
|
|
105
105
|
"test:sse-client": "npx tsx test/continuous-test-suite-sse-client.ts",
|
|
106
106
|
"test:stream-span": "npx tsx test/continuous-test-suite-stream-span.ts",
|
|
107
|
+
"test:vertex-langfuse-spans": "npx tsx test/continuous-test-suite-vertex-langfuse-spans.ts",
|
|
107
108
|
"test:credentials": "npx tsx test/continuous-test-suite-credentials.ts",
|
|
108
109
|
"test:dynamic": "npx tsx test/continuous-test-suite-dynamic.ts",
|
|
109
110
|
"test:proxy": "npx tsx test/continuous-test-suite-proxy.ts",
|