@juspay/neurolink 9.74.0 → 9.75.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 +6 -0
- package/dist/cli/factories/commandFactory.js +62 -0
- package/dist/cli/utils/toolRoutingFlags.d.ts +20 -0
- package/dist/cli/utils/toolRoutingFlags.js +115 -0
- package/dist/lib/session/globalSessionState.d.ts +10 -1
- package/dist/lib/session/globalSessionState.js +18 -0
- package/dist/lib/types/cli.d.ts +29 -3
- package/dist/session/globalSessionState.d.ts +10 -1
- package/dist/session/globalSessionState.js +18 -0
- package/dist/types/cli.d.ts +29 -3
- package/package.json +4 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## [9.75.0](https://github.com/juspay/neurolink/compare/v9.74.0...v9.75.0) (2026-06-20)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
- **(cli):** surface tool-routing config via CLI flags ([9ad353f](https://github.com/juspay/neurolink/commit/9ad353fa98759bee21ff79b14aa08d2bacfbaf7e))
|
|
6
|
+
|
|
1
7
|
## [9.74.0](https://github.com/juspay/neurolink/compare/v9.73.0...v9.74.0) (2026-06-20)
|
|
2
8
|
|
|
3
9
|
### Features
|
|
@@ -10,6 +10,7 @@ import { checkRedisAvailability } from "../../lib/utils/conversationMemory.js";
|
|
|
10
10
|
import { normalizeEvaluationData } from "../../lib/utils/evaluationUtils.js";
|
|
11
11
|
import { logger } from "../../lib/utils/logger.js";
|
|
12
12
|
import { createThinkingConfigFromRecord } from "../../lib/utils/thinkingConfig.js";
|
|
13
|
+
import { buildToolRoutingConfigFromCli } from "../utils/toolRoutingFlags.js";
|
|
13
14
|
import { configManager } from "../commands/config.js";
|
|
14
15
|
import { MCPCommandFactory } from "../commands/mcp.js";
|
|
15
16
|
import { ModelsCommandFactory } from "../commands/models.js";
|
|
@@ -540,6 +541,42 @@ export class CLICommandFactory {
|
|
|
540
541
|
description: "Thinking level for extended reasoning (Anthropic Claude, Gemini 2.5+, Gemini 3): minimal, low, medium, high",
|
|
541
542
|
choices: ["minimal", "low", "medium", "high"],
|
|
542
543
|
},
|
|
544
|
+
// Tool-routing options
|
|
545
|
+
toolRouting: {
|
|
546
|
+
type: "boolean",
|
|
547
|
+
description: "Enable pre-call per-turn tool routing (narrows MCP tools by relevance).",
|
|
548
|
+
},
|
|
549
|
+
toolRoutingTimeout: {
|
|
550
|
+
type: "number",
|
|
551
|
+
description: "Router LLM hard timeout in milliseconds.",
|
|
552
|
+
alias: "tool-routing-timeout",
|
|
553
|
+
},
|
|
554
|
+
toolRoutingRouterProvider: {
|
|
555
|
+
type: "string",
|
|
556
|
+
description: "Override the provider used for the router LLM call.",
|
|
557
|
+
alias: "tool-routing-router-provider",
|
|
558
|
+
},
|
|
559
|
+
toolRoutingRouterModel: {
|
|
560
|
+
type: "string",
|
|
561
|
+
description: "Override the model used for the router LLM call.",
|
|
562
|
+
alias: "tool-routing-router-model",
|
|
563
|
+
},
|
|
564
|
+
toolRoutingRouterRegion: {
|
|
565
|
+
type: "string",
|
|
566
|
+
description: "Override the region used for the router LLM call.",
|
|
567
|
+
alias: "tool-routing-router-region",
|
|
568
|
+
},
|
|
569
|
+
toolRoutingAlwaysInclude: {
|
|
570
|
+
type: "array",
|
|
571
|
+
description: "Server ids whose tools are always kept and never offered to the router (repeatable).",
|
|
572
|
+
alias: "tool-routing-always-include",
|
|
573
|
+
string: true,
|
|
574
|
+
},
|
|
575
|
+
toolRoutingServers: {
|
|
576
|
+
type: "string",
|
|
577
|
+
description: "Path to a JSON file OR inline JSON array of {id, description} server descriptors for the routable catalog.",
|
|
578
|
+
alias: "tool-routing-servers",
|
|
579
|
+
},
|
|
543
580
|
region: {
|
|
544
581
|
type: "string",
|
|
545
582
|
description: "Vertex AI region (e.g., us-central1, europe-west1, asia-northeast1)",
|
|
@@ -821,6 +858,16 @@ export class CLICommandFactory {
|
|
|
821
858
|
authMethod: argv.authMethod,
|
|
822
859
|
subscriptionTier: argv.subscriptionTier,
|
|
823
860
|
enableBeta: argv.enableBeta,
|
|
861
|
+
// Tool-routing flags — constructor-level config, not a per-call option.
|
|
862
|
+
// Passed through the options bag so handlers can inject into the SDK
|
|
863
|
+
// instance before the first getOrCreateNeuroLink() call.
|
|
864
|
+
toolRouting: argv.toolRouting,
|
|
865
|
+
toolRoutingTimeout: argv.toolRoutingTimeout,
|
|
866
|
+
toolRoutingRouterProvider: argv.toolRoutingRouterProvider,
|
|
867
|
+
toolRoutingRouterModel: argv.toolRoutingRouterModel,
|
|
868
|
+
toolRoutingRouterRegion: argv.toolRoutingRouterRegion,
|
|
869
|
+
toolRoutingAlwaysInclude: argv.toolRoutingAlwaysInclude,
|
|
870
|
+
toolRoutingServers: argv.toolRoutingServers,
|
|
824
871
|
};
|
|
825
872
|
}
|
|
826
873
|
/**
|
|
@@ -2217,6 +2264,11 @@ export class CLICommandFactory {
|
|
|
2217
2264
|
}
|
|
2218
2265
|
return;
|
|
2219
2266
|
}
|
|
2267
|
+
// Inject tool-routing config into the SDK instance before constructing it.
|
|
2268
|
+
const toolRoutingConfig = buildToolRoutingConfigFromCli(options);
|
|
2269
|
+
if (toolRoutingConfig) {
|
|
2270
|
+
globalSession.setToolRoutingConfig(toolRoutingConfig);
|
|
2271
|
+
}
|
|
2220
2272
|
// Initialize SDK and session
|
|
2221
2273
|
const sdk = globalSession.getOrCreateNeuroLink();
|
|
2222
2274
|
const sessionVariables = CLICommandFactory.normalizeLoopSessionVariables(globalSession.getSessionVariables());
|
|
@@ -2447,6 +2499,11 @@ export class CLICommandFactory {
|
|
|
2447
2499
|
* Execute real streaming with timeout handling
|
|
2448
2500
|
*/
|
|
2449
2501
|
static async executeRealStream(argv, options, inputText, contextMetadata) {
|
|
2502
|
+
// Inject tool-routing config into the SDK instance before constructing it.
|
|
2503
|
+
const toolRoutingConfig = buildToolRoutingConfigFromCli(options);
|
|
2504
|
+
if (toolRoutingConfig) {
|
|
2505
|
+
globalSession.setToolRoutingConfig(toolRoutingConfig);
|
|
2506
|
+
}
|
|
2450
2507
|
const sdk = globalSession.getOrCreateNeuroLink();
|
|
2451
2508
|
const sessionVariables = CLICommandFactory.normalizeLoopSessionVariables(globalSession.getSessionVariables());
|
|
2452
2509
|
const enhancedOptions = { ...options, ...sessionVariables };
|
|
@@ -2923,6 +2980,11 @@ export class CLICommandFactory {
|
|
|
2923
2980
|
logger.always(chalk.blue(`📦 Processing ${prompts.length} prompts...\n`));
|
|
2924
2981
|
}
|
|
2925
2982
|
const results = [];
|
|
2983
|
+
// Inject tool-routing config into the SDK instance before constructing it.
|
|
2984
|
+
const toolRoutingConfig = buildToolRoutingConfigFromCli(options);
|
|
2985
|
+
if (toolRoutingConfig) {
|
|
2986
|
+
globalSession.setToolRoutingConfig(toolRoutingConfig);
|
|
2987
|
+
}
|
|
2926
2988
|
const sdk = globalSession.getOrCreateNeuroLink();
|
|
2927
2989
|
const sessionVariables = CLICommandFactory.normalizeLoopSessionVariables(globalSession.getSessionVariables());
|
|
2928
2990
|
const enhancedOptions = { ...options, ...sessionVariables };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI helper: parse --tool-routing-* flags into a ToolRoutingConfig.
|
|
3
|
+
*
|
|
4
|
+
* This module is intentionally side-effect-free so it can be unit-tested
|
|
5
|
+
* without a running NeuroLink instance.
|
|
6
|
+
*/
|
|
7
|
+
import type { CliToolRoutingFlags, ToolRoutingConfig } from "../../lib/types/index.js";
|
|
8
|
+
/**
|
|
9
|
+
* Build a {@link ToolRoutingConfig} from the parsed CLI flags.
|
|
10
|
+
*
|
|
11
|
+
* Returns `undefined` when `--tool-routing` is absent or false, so callers
|
|
12
|
+
* can skip the setter entirely with a simple truthiness check — behaviour is
|
|
13
|
+
* identical to routing being disabled.
|
|
14
|
+
*
|
|
15
|
+
* `--tool-routing-servers` is parsed permissively:
|
|
16
|
+
* - If the value looks like an existing file path, the file is read and JSON-parsed.
|
|
17
|
+
* - Otherwise the value is treated as an inline JSON string.
|
|
18
|
+
* - On any parse error a warning is logged and `servers` is omitted (fail open).
|
|
19
|
+
*/
|
|
20
|
+
export declare function buildToolRoutingConfigFromCli(flags: CliToolRoutingFlags & Record<string, unknown>): ToolRoutingConfig | undefined;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI helper: parse --tool-routing-* flags into a ToolRoutingConfig.
|
|
3
|
+
*
|
|
4
|
+
* This module is intentionally side-effect-free so it can be unit-tested
|
|
5
|
+
* without a running NeuroLink instance.
|
|
6
|
+
*/
|
|
7
|
+
import fs from "node:fs";
|
|
8
|
+
import { logger } from "../../lib/utils/logger.js";
|
|
9
|
+
/**
|
|
10
|
+
* Build a {@link ToolRoutingConfig} from the parsed CLI flags.
|
|
11
|
+
*
|
|
12
|
+
* Returns `undefined` when `--tool-routing` is absent or false, so callers
|
|
13
|
+
* can skip the setter entirely with a simple truthiness check — behaviour is
|
|
14
|
+
* identical to routing being disabled.
|
|
15
|
+
*
|
|
16
|
+
* `--tool-routing-servers` is parsed permissively:
|
|
17
|
+
* - If the value looks like an existing file path, the file is read and JSON-parsed.
|
|
18
|
+
* - Otherwise the value is treated as an inline JSON string.
|
|
19
|
+
* - On any parse error a warning is logged and `servers` is omitted (fail open).
|
|
20
|
+
*/
|
|
21
|
+
export function buildToolRoutingConfigFromCli(flags) {
|
|
22
|
+
if (!flags.toolRouting) {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
const config = { enabled: true };
|
|
26
|
+
if (flags.toolRoutingTimeout !== undefined) {
|
|
27
|
+
const t = flags.toolRoutingTimeout;
|
|
28
|
+
if (Number.isFinite(t) && t > 0) {
|
|
29
|
+
config.timeoutMs = t;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
logger.warn(`[tool-routing] --tool-routing-timeout value ${String(t)} is not a positive finite number; ignoring (SDK default applies).`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const hasRouterProvider = typeof flags.toolRoutingRouterProvider === "string";
|
|
36
|
+
const hasRouterModel = typeof flags.toolRoutingRouterModel === "string";
|
|
37
|
+
const hasRouterRegion = typeof flags.toolRoutingRouterRegion === "string";
|
|
38
|
+
if (hasRouterProvider || hasRouterModel || hasRouterRegion) {
|
|
39
|
+
config.routerModel = {
|
|
40
|
+
...(hasRouterProvider && {
|
|
41
|
+
provider: flags.toolRoutingRouterProvider,
|
|
42
|
+
}),
|
|
43
|
+
...(hasRouterModel && {
|
|
44
|
+
model: flags.toolRoutingRouterModel,
|
|
45
|
+
}),
|
|
46
|
+
...(hasRouterRegion && {
|
|
47
|
+
region: flags.toolRoutingRouterRegion,
|
|
48
|
+
}),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
if (Array.isArray(flags.toolRoutingAlwaysInclude) &&
|
|
52
|
+
flags.toolRoutingAlwaysInclude.length > 0) {
|
|
53
|
+
config.alwaysIncludeServerIds = flags.toolRoutingAlwaysInclude;
|
|
54
|
+
}
|
|
55
|
+
if (typeof flags.toolRoutingServers === "string" &&
|
|
56
|
+
flags.toolRoutingServers.trim() !== "") {
|
|
57
|
+
config.servers = parseServersFlag(flags.toolRoutingServers);
|
|
58
|
+
}
|
|
59
|
+
return config;
|
|
60
|
+
}
|
|
61
|
+
// Trust model: --tool-routing-servers is a local, user-supplied CLI flag.
|
|
62
|
+
// The invoking user already holds the process's OS permissions, so absolute
|
|
63
|
+
// and home-dir config paths are fully supported — there is no cross-trust-
|
|
64
|
+
// boundary to enforce. The caps below are a robustness guard against
|
|
65
|
+
// accidentally pointing at a huge file (e.g. a log or binary) that would
|
|
66
|
+
// silently OOM the process or stall the CLI, not a security boundary.
|
|
67
|
+
const MAX_SERVERS_INPUT_BYTES = 1_000_000; // 1 MB
|
|
68
|
+
const MAX_SERVERS_ENTRIES = 1_000;
|
|
69
|
+
/**
|
|
70
|
+
* Parse the `--tool-routing-servers` value.
|
|
71
|
+
*
|
|
72
|
+
* Tries file-path first (if the string exists on disk), then inline JSON.
|
|
73
|
+
* Logs a warning and returns `undefined` on any error (fail open).
|
|
74
|
+
*/
|
|
75
|
+
function parseServersFlag(value) {
|
|
76
|
+
try {
|
|
77
|
+
// File-path branch: resolve relative to cwd, check existence.
|
|
78
|
+
const resolved = fs.existsSync(value) ? value : null;
|
|
79
|
+
if (resolved !== null) {
|
|
80
|
+
const { size } = fs.statSync(resolved);
|
|
81
|
+
if (size > MAX_SERVERS_INPUT_BYTES) {
|
|
82
|
+
logger.warn(`[tool-routing] --tool-routing-servers file exceeds ${MAX_SERVERS_INPUT_BYTES} bytes (got ${size}); ignoring to avoid excessive memory use.`);
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
else if (Buffer.byteLength(value, "utf8") > MAX_SERVERS_INPUT_BYTES) {
|
|
87
|
+
logger.warn(`[tool-routing] --tool-routing-servers inline JSON exceeds ${MAX_SERVERS_INPUT_BYTES} bytes; ignoring to avoid excessive memory use.`);
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
const jsonText = resolved ? fs.readFileSync(resolved, "utf8") : value;
|
|
91
|
+
const parsed = JSON.parse(jsonText);
|
|
92
|
+
if (!Array.isArray(parsed)) {
|
|
93
|
+
logger.warn("[tool-routing] --tool-routing-servers must be a JSON array; ignoring.");
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
// Validate shape loosely — only keep entries with id + description strings.
|
|
97
|
+
const valid = parsed.filter((entry) => typeof entry === "object" &&
|
|
98
|
+
entry !== null &&
|
|
99
|
+
typeof entry.id === "string" &&
|
|
100
|
+
typeof entry.description === "string");
|
|
101
|
+
if (valid.length !== parsed.length) {
|
|
102
|
+
logger.warn(`[tool-routing] ${parsed.length - valid.length} server descriptor(s) skipped — each must have string "id" and "description" fields.`);
|
|
103
|
+
}
|
|
104
|
+
if (valid.length > MAX_SERVERS_ENTRIES) {
|
|
105
|
+
logger.warn(`[tool-routing] --tool-routing-servers contains ${valid.length} entries; truncating to ${MAX_SERVERS_ENTRIES} to prevent pathological inputs.`);
|
|
106
|
+
return valid.slice(0, MAX_SERVERS_ENTRIES);
|
|
107
|
+
}
|
|
108
|
+
return valid.length > 0 ? valid : undefined;
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
logger.warn(`[tool-routing] Failed to parse --tool-routing-servers: ${err.message}. Omitting servers (fail open).`);
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=toolRoutingFlags.js.map
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { NeuroLink } from "../neurolink.js";
|
|
2
|
-
import type { ConversationMemoryConfig, LoopSessionState, SessionVariableValue } from "../types/index.js";
|
|
2
|
+
import type { ConversationMemoryConfig, LoopSessionState, SessionVariableValue, ToolRoutingConfig } from "../types/index.js";
|
|
3
3
|
export declare class GlobalSessionManager {
|
|
4
4
|
private static instance;
|
|
5
5
|
private loopSession;
|
|
6
|
+
/** Optional tool-routing config set by CLI handlers before SDK construction. */
|
|
7
|
+
private _toolRoutingConfig;
|
|
6
8
|
static getInstance(): GlobalSessionManager;
|
|
7
9
|
setLoopSession(config?: ConversationMemoryConfig): string;
|
|
8
10
|
/**
|
|
@@ -33,6 +35,13 @@ export declare class GlobalSessionManager {
|
|
|
33
35
|
updateSessionId(newSessionId: string): void;
|
|
34
36
|
getLoopSession(): LoopSessionState | null;
|
|
35
37
|
clearLoopSession(): void;
|
|
38
|
+
/**
|
|
39
|
+
* Store a tool-routing config to be injected at SDK construction time.
|
|
40
|
+
* Call this BEFORE `getOrCreateNeuroLink()` inside a command handler.
|
|
41
|
+
* When a loop session is already active the config is ignored (the instance
|
|
42
|
+
* already exists).
|
|
43
|
+
*/
|
|
44
|
+
setToolRoutingConfig(config: ToolRoutingConfig): void;
|
|
36
45
|
getOrCreateNeuroLink(): NeuroLink;
|
|
37
46
|
getCurrentSessionId(): string | undefined;
|
|
38
47
|
setSessionVariable(key: string, value: SessionVariableValue): void;
|
|
@@ -31,6 +31,8 @@ function buildMcpOutputLimitsFromEnv() {
|
|
|
31
31
|
export class GlobalSessionManager {
|
|
32
32
|
static instance;
|
|
33
33
|
loopSession = null;
|
|
34
|
+
/** Optional tool-routing config set by CLI handlers before SDK construction. */
|
|
35
|
+
_toolRoutingConfig = undefined;
|
|
34
36
|
static getInstance() {
|
|
35
37
|
if (!GlobalSessionManager.instance) {
|
|
36
38
|
GlobalSessionManager.instance = new GlobalSessionManager();
|
|
@@ -127,6 +129,18 @@ export class GlobalSessionManager {
|
|
|
127
129
|
this.loopSession = null;
|
|
128
130
|
}
|
|
129
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* Store a tool-routing config to be injected at SDK construction time.
|
|
134
|
+
* Call this BEFORE `getOrCreateNeuroLink()` inside a command handler.
|
|
135
|
+
* When a loop session is already active the config is ignored (the instance
|
|
136
|
+
* already exists).
|
|
137
|
+
*/
|
|
138
|
+
setToolRoutingConfig(config) {
|
|
139
|
+
if (this.hasActiveSession()) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
this._toolRoutingConfig = config;
|
|
143
|
+
}
|
|
130
144
|
getOrCreateNeuroLink() {
|
|
131
145
|
const session = this.getLoopSession();
|
|
132
146
|
if (session) {
|
|
@@ -142,6 +156,10 @@ export class GlobalSessionManager {
|
|
|
142
156
|
if (mcpOutputLimits) {
|
|
143
157
|
options.mcp = { outputLimits: mcpOutputLimits };
|
|
144
158
|
}
|
|
159
|
+
if (this._toolRoutingConfig) {
|
|
160
|
+
options.toolRouting = this._toolRoutingConfig;
|
|
161
|
+
this._toolRoutingConfig = undefined;
|
|
162
|
+
}
|
|
145
163
|
return new NeuroLink(Object.keys(options).length ? options : undefined);
|
|
146
164
|
}
|
|
147
165
|
getCurrentSessionId() {
|
package/dist/lib/types/cli.d.ts
CHANGED
|
@@ -45,7 +45,7 @@ export type BaseCommandArgs = {
|
|
|
45
45
|
/**
|
|
46
46
|
* Generate command arguments
|
|
47
47
|
*/
|
|
48
|
-
export type GenerateCommandArgs = BaseCommandArgs & {
|
|
48
|
+
export type GenerateCommandArgs = BaseCommandArgs & CliToolRoutingFlags & {
|
|
49
49
|
/** Input text or prompt */
|
|
50
50
|
input?: string;
|
|
51
51
|
/** AI provider to use */
|
|
@@ -110,7 +110,7 @@ export type GenerateCommandArgs = BaseCommandArgs & {
|
|
|
110
110
|
/**
|
|
111
111
|
* Stream command arguments
|
|
112
112
|
*/
|
|
113
|
-
export type StreamCommandArgs = BaseCommandArgs & {
|
|
113
|
+
export type StreamCommandArgs = BaseCommandArgs & CliToolRoutingFlags & {
|
|
114
114
|
/** Input text or prompt */
|
|
115
115
|
input?: string;
|
|
116
116
|
/** AI provider to use */
|
|
@@ -137,7 +137,7 @@ export type StreamCommandArgs = BaseCommandArgs & {
|
|
|
137
137
|
/**
|
|
138
138
|
* Batch command arguments
|
|
139
139
|
*/
|
|
140
|
-
export type BatchCommandArgs = BaseCommandArgs & {
|
|
140
|
+
export type BatchCommandArgs = BaseCommandArgs & CliToolRoutingFlags & {
|
|
141
141
|
/** Input file path */
|
|
142
142
|
file?: string;
|
|
143
143
|
/** AI provider to use */
|
|
@@ -1500,3 +1500,29 @@ export type CliServeFlatRoute = {
|
|
|
1500
1500
|
description?: string;
|
|
1501
1501
|
group: string;
|
|
1502
1502
|
};
|
|
1503
|
+
/**
|
|
1504
|
+
* Raw CLI flag shape for the tool-routing family of options.
|
|
1505
|
+
* Keys are camelCase as yargs delivers them after parsing kebab-case aliases.
|
|
1506
|
+
*/
|
|
1507
|
+
export type CliToolRoutingFlags = {
|
|
1508
|
+
/** Master enable switch (--tool-routing). */
|
|
1509
|
+
toolRouting?: boolean;
|
|
1510
|
+
/** Router LLM hard timeout in ms (--tool-routing-timeout). */
|
|
1511
|
+
toolRoutingTimeout?: number;
|
|
1512
|
+
/** Router LLM provider override (--tool-routing-router-provider). */
|
|
1513
|
+
toolRoutingRouterProvider?: string;
|
|
1514
|
+
/** Router LLM model override (--tool-routing-router-model). */
|
|
1515
|
+
toolRoutingRouterModel?: string;
|
|
1516
|
+
/** Router LLM region override (--tool-routing-router-region). */
|
|
1517
|
+
toolRoutingRouterRegion?: string;
|
|
1518
|
+
/**
|
|
1519
|
+
* Server ids that are always kept and never offered to the router
|
|
1520
|
+
* (--tool-routing-always-include, repeatable).
|
|
1521
|
+
*/
|
|
1522
|
+
toolRoutingAlwaysInclude?: string[];
|
|
1523
|
+
/**
|
|
1524
|
+
* Path to a JSON file OR inline JSON array of server descriptors
|
|
1525
|
+
* (--tool-routing-servers).
|
|
1526
|
+
*/
|
|
1527
|
+
toolRoutingServers?: string;
|
|
1528
|
+
};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { NeuroLink } from "../neurolink.js";
|
|
2
|
-
import type { ConversationMemoryConfig, LoopSessionState, SessionVariableValue } from "../types/index.js";
|
|
2
|
+
import type { ConversationMemoryConfig, LoopSessionState, SessionVariableValue, ToolRoutingConfig } from "../types/index.js";
|
|
3
3
|
export declare class GlobalSessionManager {
|
|
4
4
|
private static instance;
|
|
5
5
|
private loopSession;
|
|
6
|
+
/** Optional tool-routing config set by CLI handlers before SDK construction. */
|
|
7
|
+
private _toolRoutingConfig;
|
|
6
8
|
static getInstance(): GlobalSessionManager;
|
|
7
9
|
setLoopSession(config?: ConversationMemoryConfig): string;
|
|
8
10
|
/**
|
|
@@ -33,6 +35,13 @@ export declare class GlobalSessionManager {
|
|
|
33
35
|
updateSessionId(newSessionId: string): void;
|
|
34
36
|
getLoopSession(): LoopSessionState | null;
|
|
35
37
|
clearLoopSession(): void;
|
|
38
|
+
/**
|
|
39
|
+
* Store a tool-routing config to be injected at SDK construction time.
|
|
40
|
+
* Call this BEFORE `getOrCreateNeuroLink()` inside a command handler.
|
|
41
|
+
* When a loop session is already active the config is ignored (the instance
|
|
42
|
+
* already exists).
|
|
43
|
+
*/
|
|
44
|
+
setToolRoutingConfig(config: ToolRoutingConfig): void;
|
|
36
45
|
getOrCreateNeuroLink(): NeuroLink;
|
|
37
46
|
getCurrentSessionId(): string | undefined;
|
|
38
47
|
setSessionVariable(key: string, value: SessionVariableValue): void;
|
|
@@ -31,6 +31,8 @@ function buildMcpOutputLimitsFromEnv() {
|
|
|
31
31
|
export class GlobalSessionManager {
|
|
32
32
|
static instance;
|
|
33
33
|
loopSession = null;
|
|
34
|
+
/** Optional tool-routing config set by CLI handlers before SDK construction. */
|
|
35
|
+
_toolRoutingConfig = undefined;
|
|
34
36
|
static getInstance() {
|
|
35
37
|
if (!GlobalSessionManager.instance) {
|
|
36
38
|
GlobalSessionManager.instance = new GlobalSessionManager();
|
|
@@ -127,6 +129,18 @@ export class GlobalSessionManager {
|
|
|
127
129
|
this.loopSession = null;
|
|
128
130
|
}
|
|
129
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* Store a tool-routing config to be injected at SDK construction time.
|
|
134
|
+
* Call this BEFORE `getOrCreateNeuroLink()` inside a command handler.
|
|
135
|
+
* When a loop session is already active the config is ignored (the instance
|
|
136
|
+
* already exists).
|
|
137
|
+
*/
|
|
138
|
+
setToolRoutingConfig(config) {
|
|
139
|
+
if (this.hasActiveSession()) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
this._toolRoutingConfig = config;
|
|
143
|
+
}
|
|
130
144
|
getOrCreateNeuroLink() {
|
|
131
145
|
const session = this.getLoopSession();
|
|
132
146
|
if (session) {
|
|
@@ -142,6 +156,10 @@ export class GlobalSessionManager {
|
|
|
142
156
|
if (mcpOutputLimits) {
|
|
143
157
|
options.mcp = { outputLimits: mcpOutputLimits };
|
|
144
158
|
}
|
|
159
|
+
if (this._toolRoutingConfig) {
|
|
160
|
+
options.toolRouting = this._toolRoutingConfig;
|
|
161
|
+
this._toolRoutingConfig = undefined;
|
|
162
|
+
}
|
|
145
163
|
return new NeuroLink(Object.keys(options).length ? options : undefined);
|
|
146
164
|
}
|
|
147
165
|
getCurrentSessionId() {
|
package/dist/types/cli.d.ts
CHANGED
|
@@ -45,7 +45,7 @@ export type BaseCommandArgs = {
|
|
|
45
45
|
/**
|
|
46
46
|
* Generate command arguments
|
|
47
47
|
*/
|
|
48
|
-
export type GenerateCommandArgs = BaseCommandArgs & {
|
|
48
|
+
export type GenerateCommandArgs = BaseCommandArgs & CliToolRoutingFlags & {
|
|
49
49
|
/** Input text or prompt */
|
|
50
50
|
input?: string;
|
|
51
51
|
/** AI provider to use */
|
|
@@ -110,7 +110,7 @@ export type GenerateCommandArgs = BaseCommandArgs & {
|
|
|
110
110
|
/**
|
|
111
111
|
* Stream command arguments
|
|
112
112
|
*/
|
|
113
|
-
export type StreamCommandArgs = BaseCommandArgs & {
|
|
113
|
+
export type StreamCommandArgs = BaseCommandArgs & CliToolRoutingFlags & {
|
|
114
114
|
/** Input text or prompt */
|
|
115
115
|
input?: string;
|
|
116
116
|
/** AI provider to use */
|
|
@@ -137,7 +137,7 @@ export type StreamCommandArgs = BaseCommandArgs & {
|
|
|
137
137
|
/**
|
|
138
138
|
* Batch command arguments
|
|
139
139
|
*/
|
|
140
|
-
export type BatchCommandArgs = BaseCommandArgs & {
|
|
140
|
+
export type BatchCommandArgs = BaseCommandArgs & CliToolRoutingFlags & {
|
|
141
141
|
/** Input file path */
|
|
142
142
|
file?: string;
|
|
143
143
|
/** AI provider to use */
|
|
@@ -1500,3 +1500,29 @@ export type CliServeFlatRoute = {
|
|
|
1500
1500
|
description?: string;
|
|
1501
1501
|
group: string;
|
|
1502
1502
|
};
|
|
1503
|
+
/**
|
|
1504
|
+
* Raw CLI flag shape for the tool-routing family of options.
|
|
1505
|
+
* Keys are camelCase as yargs delivers them after parsing kebab-case aliases.
|
|
1506
|
+
*/
|
|
1507
|
+
export type CliToolRoutingFlags = {
|
|
1508
|
+
/** Master enable switch (--tool-routing). */
|
|
1509
|
+
toolRouting?: boolean;
|
|
1510
|
+
/** Router LLM hard timeout in ms (--tool-routing-timeout). */
|
|
1511
|
+
toolRoutingTimeout?: number;
|
|
1512
|
+
/** Router LLM provider override (--tool-routing-router-provider). */
|
|
1513
|
+
toolRoutingRouterProvider?: string;
|
|
1514
|
+
/** Router LLM model override (--tool-routing-router-model). */
|
|
1515
|
+
toolRoutingRouterModel?: string;
|
|
1516
|
+
/** Router LLM region override (--tool-routing-router-region). */
|
|
1517
|
+
toolRoutingRouterRegion?: string;
|
|
1518
|
+
/**
|
|
1519
|
+
* Server ids that are always kept and never offered to the router
|
|
1520
|
+
* (--tool-routing-always-include, repeatable).
|
|
1521
|
+
*/
|
|
1522
|
+
toolRoutingAlwaysInclude?: string[];
|
|
1523
|
+
/**
|
|
1524
|
+
* Path to a JSON file OR inline JSON array of server descriptors
|
|
1525
|
+
* (--tool-routing-servers).
|
|
1526
|
+
*/
|
|
1527
|
+
toolRoutingServers?: string;
|
|
1528
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juspay/neurolink",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.75.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": {
|
|
@@ -118,11 +118,13 @@
|
|
|
118
118
|
"test:autoresearch": "npx tsx test/continuous-test-suite-autoresearch.ts",
|
|
119
119
|
"test:autoresearch:redis": "npx tsx test/continuous-test-suite-autoresearch-redis.ts",
|
|
120
120
|
"test:envguard": "npx tsx test/helpers/envGuard.test.ts",
|
|
121
|
+
"test:tool-routing-cli:vitest": "pnpm exec vitest run test/toolRoutingCli.test.ts",
|
|
122
|
+
"test:tool-routing-cli": "pnpm run test:tool-routing-cli:vitest && npx tsx test/continuous-test-suite-tool-routing-cli.ts",
|
|
121
123
|
"test:ci": "pnpm run test && pnpm run test:client && pnpm run test:hitl",
|
|
122
124
|
"// CI tier — fast, no live AI calls, safe for every commit": "",
|
|
123
125
|
"test:unit:vitest": "pnpm exec vitest run test/toolRouting.test.ts",
|
|
124
126
|
"test:tool-routing": "pnpm run test:unit:vitest && npx tsx test/continuous-test-suite-tool-routing.ts",
|
|
125
|
-
"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",
|
|
127
|
+
"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",
|
|
126
128
|
"// 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)": "",
|
|
127
129
|
"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",
|
|
128
130
|
"// CI tier — product output (image/video/TTS/PPT) — costs $$ per run": "",
|