@juspay/neurolink 9.81.3 → 9.82.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/README.md +4 -0
- package/dist/browser/neurolink.min.js +337 -337
- package/dist/cli/commands/proxy.js +5 -0
- package/dist/cli/factories/commandFactory.d.ts +2 -1
- package/dist/cli/factories/commandFactory.js +36 -16
- package/dist/cli/utils/audioPlayer.d.ts +37 -0
- package/dist/cli/utils/audioPlayer.js +138 -0
- package/dist/core/modules/GenerationHandler.js +7 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +14 -6
- package/dist/lib/core/modules/GenerationHandler.js +7 -1
- package/dist/lib/index.d.ts +6 -1
- package/dist/lib/index.js +14 -6
- package/dist/lib/proxy/proxyDispatcher.d.ts +5 -0
- package/dist/lib/proxy/proxyDispatcher.js +61 -0
- package/dist/lib/utils/systemMessages.d.ts +29 -0
- package/dist/lib/utils/systemMessages.js +45 -0
- package/dist/proxy/proxyDispatcher.d.ts +5 -0
- package/dist/proxy/proxyDispatcher.js +60 -0
- package/dist/utils/systemMessages.d.ts +29 -0
- package/dist/utils/systemMessages.js +44 -0
- package/package.json +3 -2
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tuned global undici dispatcher for the proxy's upstream forwards.
|
|
3
|
+
*
|
|
4
|
+
* The Claude passthrough (`claudeProxyRoutes.ts`) forwards every request to
|
|
5
|
+
* Anthropic via the global `fetch` → undici global dispatcher. undici keep-alives
|
|
6
|
+
* by default, but with a ~4s idle timeout: between Claude Code turns (the user
|
|
7
|
+
* reads output, a tool runs, the model thinks) the idle socket closes, so the
|
|
8
|
+
* next request opens a brand-new TCP connection. Under sustained use that is a
|
|
9
|
+
* high rate of short-lived outbound flows.
|
|
10
|
+
*
|
|
11
|
+
* On hosts running a socket content-filter (CFIL) — e.g. SentinelOne or
|
|
12
|
+
* GlobalProtect network extensions — every new flow allocates per-flow kernel
|
|
13
|
+
* state, so a high flow rate amplifies any leak in that path. Reusing connections
|
|
14
|
+
* cuts the flow rate sharply, so we install a dispatcher with a longer keep-alive
|
|
15
|
+
* and a bounded, reused connection pool.
|
|
16
|
+
*
|
|
17
|
+
* Everything is overridable via env so it can be tuned (or disabled) per host:
|
|
18
|
+
* NEUROLINK_PROXY_KEEPALIVE=off disable; keep undici defaults
|
|
19
|
+
* NEUROLINK_PROXY_KEEPALIVE_MS idle keep-alive timeout (default 30000)
|
|
20
|
+
* NEUROLINK_PROXY_KEEPALIVE_MAX_MS keep-alive upper bound (default 600000)
|
|
21
|
+
* NEUROLINK_PROXY_MAX_CONNECTIONS max pooled connections per origin (default 64)
|
|
22
|
+
*/
|
|
23
|
+
import { Agent, setGlobalDispatcher } from "undici";
|
|
24
|
+
import { logger } from "../utils/logger.js";
|
|
25
|
+
function readPositiveInt(name, fallback) {
|
|
26
|
+
const raw = process.env[name];
|
|
27
|
+
if (!raw) {
|
|
28
|
+
return fallback;
|
|
29
|
+
}
|
|
30
|
+
const parsed = Number.parseInt(raw, 10);
|
|
31
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
32
|
+
}
|
|
33
|
+
let configured = false;
|
|
34
|
+
/**
|
|
35
|
+
* Install the tuned global undici dispatcher. Idempotent — safe to call once at
|
|
36
|
+
* proxy startup. No-op when `NEUROLINK_PROXY_KEEPALIVE` is off/false/0.
|
|
37
|
+
*/
|
|
38
|
+
export function configureProxyKeepAliveDispatcher() {
|
|
39
|
+
if (configured) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
configured = true;
|
|
43
|
+
const toggle = (process.env.NEUROLINK_PROXY_KEEPALIVE ?? "").toLowerCase();
|
|
44
|
+
if (toggle === "off" || toggle === "false" || toggle === "0") {
|
|
45
|
+
logger.debug("[proxy] keep-alive dispatcher disabled via env");
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const keepAliveTimeout = readPositiveInt("NEUROLINK_PROXY_KEEPALIVE_MS", 30_000);
|
|
49
|
+
const keepAliveMaxTimeout = readPositiveInt("NEUROLINK_PROXY_KEEPALIVE_MAX_MS", 600_000);
|
|
50
|
+
const connections = readPositiveInt("NEUROLINK_PROXY_MAX_CONNECTIONS", 64);
|
|
51
|
+
setGlobalDispatcher(new Agent({
|
|
52
|
+
keepAliveTimeout,
|
|
53
|
+
keepAliveMaxTimeout,
|
|
54
|
+
connections,
|
|
55
|
+
pipelining: 1,
|
|
56
|
+
}));
|
|
57
|
+
logger.debug(`[proxy] tuned undici dispatcher installed ` +
|
|
58
|
+
`(keepAliveTimeout=${keepAliveTimeout}ms, ` +
|
|
59
|
+
`keepAliveMaxTimeout=${keepAliveMaxTimeout}ms, connections=${connections})`);
|
|
60
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ModelMessage, SystemModelMessage } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Partition a built message array into system messages and the rest, so the
|
|
4
|
+
* system prompt can ride `generateText`'s top-level `system` option instead of
|
|
5
|
+
* the `messages` array.
|
|
6
|
+
*
|
|
7
|
+
* The AI SDK deprecates system-role entries inside `messages` (warns by default
|
|
8
|
+
* from ai@6.0.170 via the `allowSystemInMessages` option, rejected by default
|
|
9
|
+
* in v7, flagged as a prompt-injection risk). The `system` option accepts full
|
|
10
|
+
* SystemModelMessage objects, so per-message providerOptions (e.g. the anthropic
|
|
11
|
+
* cacheControl breakpoint set by buildMessagesArray) survive the move. See
|
|
12
|
+
* issue #1024.
|
|
13
|
+
*
|
|
14
|
+
* Order is preserved within both partitions and the input is not mutated.
|
|
15
|
+
*
|
|
16
|
+
* Guard: the partition only runs when it leaves a non-empty `messages` array.
|
|
17
|
+
* If every message is a system message (a system-only priming call) — or there
|
|
18
|
+
* are no system messages at all — the original array is returned untouched with
|
|
19
|
+
* `system: undefined`. The AI SDK rejects an empty `messages` array, and a
|
|
20
|
+
* system-only call has no hoisted form (the SDK also requires a non-system
|
|
21
|
+
* message), so that degenerate case is deliberately left on the old
|
|
22
|
+
* system-in-`messages` path rather than made to throw — it keeps whatever
|
|
23
|
+
* behaviour it had before #1024. The normal system-plus-conversation path is
|
|
24
|
+
* always hoisted.
|
|
25
|
+
*/
|
|
26
|
+
export declare function extractSystemMessages(messages: ModelMessage[]): {
|
|
27
|
+
system: SystemModelMessage[] | undefined;
|
|
28
|
+
messages: ModelMessage[];
|
|
29
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Partition a built message array into system messages and the rest, so the
|
|
3
|
+
* system prompt can ride `generateText`'s top-level `system` option instead of
|
|
4
|
+
* the `messages` array.
|
|
5
|
+
*
|
|
6
|
+
* The AI SDK deprecates system-role entries inside `messages` (warns by default
|
|
7
|
+
* from ai@6.0.170 via the `allowSystemInMessages` option, rejected by default
|
|
8
|
+
* in v7, flagged as a prompt-injection risk). The `system` option accepts full
|
|
9
|
+
* SystemModelMessage objects, so per-message providerOptions (e.g. the anthropic
|
|
10
|
+
* cacheControl breakpoint set by buildMessagesArray) survive the move. See
|
|
11
|
+
* issue #1024.
|
|
12
|
+
*
|
|
13
|
+
* Order is preserved within both partitions and the input is not mutated.
|
|
14
|
+
*
|
|
15
|
+
* Guard: the partition only runs when it leaves a non-empty `messages` array.
|
|
16
|
+
* If every message is a system message (a system-only priming call) — or there
|
|
17
|
+
* are no system messages at all — the original array is returned untouched with
|
|
18
|
+
* `system: undefined`. The AI SDK rejects an empty `messages` array, and a
|
|
19
|
+
* system-only call has no hoisted form (the SDK also requires a non-system
|
|
20
|
+
* message), so that degenerate case is deliberately left on the old
|
|
21
|
+
* system-in-`messages` path rather than made to throw — it keeps whatever
|
|
22
|
+
* behaviour it had before #1024. The normal system-plus-conversation path is
|
|
23
|
+
* always hoisted.
|
|
24
|
+
*/
|
|
25
|
+
export function extractSystemMessages(messages) {
|
|
26
|
+
const system = [];
|
|
27
|
+
const rest = [];
|
|
28
|
+
for (const message of messages) {
|
|
29
|
+
if (message.role === "system") {
|
|
30
|
+
system.push(message);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
rest.push(message);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// Only hoist when a non-empty messages array remains. A system-only call (or
|
|
37
|
+
// a no-system array) passes through unchanged: hoisting would empty
|
|
38
|
+
// `messages`, which the SDK rejects, and a system-only call has no compliant
|
|
39
|
+
// hoisted form.
|
|
40
|
+
if (system.length === 0 || rest.length === 0) {
|
|
41
|
+
return { system: undefined, messages };
|
|
42
|
+
}
|
|
43
|
+
return { system, messages: rest };
|
|
44
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juspay/neurolink",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.82.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": {
|
|
@@ -135,9 +135,10 @@
|
|
|
135
135
|
"test:unit:vitest": "pnpm exec vitest run test/toolRouting.test.ts",
|
|
136
136
|
"test:tool-routing": "pnpm run test:unit:vitest && npx tsx test/continuous-test-suite-tool-routing.ts",
|
|
137
137
|
"test:classifier-router": "npx tsx test/continuous-test-suite-classifier-router.ts",
|
|
138
|
+
"test:system-messages:vitest": "pnpm exec vitest run test/systemMessages.test.ts",
|
|
138
139
|
"test:tool-routing-semantic:vitest": "pnpm exec vitest run test/toolRoutingSemantic.test.ts",
|
|
139
140
|
"test:tool-routing-semantic": "pnpm run test:tool-routing-semantic:vitest && npx tsx test/continuous-test-suite-tool-routing-semantic.ts",
|
|
140
|
-
"test:unit": "pnpm run test:envguard && pnpm run test:bugfixes && pnpm run test:mcp:infra && pnpm run test:mcp:bash && pnpm run test:mcp:limits && pnpm run test:mcp:spans && pnpm run test:autoresearch:redis && pnpm run test:unit:vitest && pnpm run test:tool-routing-cli:vitest && pnpm run test:tool-dedup:vitest && pnpm run test:model-pool:vitest && pnpm run test:tool-routing-semantic:vitest && pnpm run test:anthropic-tools-policy && pnpm run test:anthropic-multimodal && pnpm run test:excel-interop",
|
|
141
|
+
"test:unit": "pnpm run test:envguard && pnpm run test:bugfixes && pnpm run test:mcp:infra && pnpm run test:mcp:bash && pnpm run test:mcp:limits && pnpm run test:mcp:spans && pnpm run test:autoresearch:redis && pnpm run test:unit:vitest && pnpm run test:tool-routing-cli:vitest && pnpm run test:tool-dedup:vitest && pnpm run test:model-pool:vitest && pnpm run test:system-messages:vitest && pnpm run test:tool-routing-semantic:vitest && pnpm run test:anthropic-tools-policy && pnpm run test:anthropic-multimodal && pnpm run test:excel-interop",
|
|
141
142
|
"// CI tier — live providers, runs only when API keys are present (test:credentials and test:dynamic make real provider calls when keys are set, so they live here, not in test:unit)": "",
|
|
142
143
|
"test:live": "pnpm run test:providers && pnpm run test:mcp:http && pnpm run test:mcp:sdk && pnpm run test:mcp:cli && pnpm run test:observability && pnpm run test:context && pnpm run test:memory && pnpm run test:tool-reliability && pnpm run test:evaluation && pnpm run test:autoresearch && pnpm run test:credentials && pnpm run test:dynamic",
|
|
143
144
|
"// CI tier — product output (image/video/TTS/PPT) — costs $$ per run": "",
|