@juspay/neurolink 12.27.1 → 12.28.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 +3 -3
- package/dist/agent/directTools.d.ts +118 -94
- package/dist/agent/directTools.js +578 -446
- package/dist/agent/index.d.ts +1 -0
- package/dist/agent/index.js +1 -0
- package/dist/agent/prompts/terminalAgentPrompt.d.ts +13 -0
- package/dist/agent/prompts/terminalAgentPrompt.js +59 -0
- package/dist/browser/neurolink.min.js +382 -378
- package/dist/cli/factories/commandFactory.d.ts +25 -0
- package/dist/cli/factories/commandFactory.js +94 -8
- package/dist/cli/loop/optionsSchema.d.ts +1 -1
- package/dist/cli/loop/session.js +6 -0
- package/dist/cli/utils/stdinRef.d.ts +16 -0
- package/dist/cli/utils/stdinRef.js +21 -0
- package/dist/core/baseProvider.d.ts +17 -1
- package/dist/core/baseProvider.js +48 -1
- package/dist/core/modules/ToolsManager.d.ts +7 -1
- package/dist/core/modules/ToolsManager.js +8 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/mcp/externalServerManager.js +173 -8
- package/dist/mcp/mcpCircuitBreaker.d.ts +8 -3
- package/dist/mcp/mcpCircuitBreaker.js +25 -9
- package/dist/mcp/mcpClientFactory.d.ts +9 -4
- package/dist/mcp/mcpClientFactory.js +26 -15
- package/dist/mcp/toolDiscoveryService.d.ts +8 -3
- package/dist/mcp/toolDiscoveryService.js +17 -7
- package/dist/mcp/toolRegistry.d.ts +12 -1
- package/dist/mcp/toolRegistry.js +26 -2
- package/dist/neurolink.d.ts +13 -0
- package/dist/neurolink.js +97 -10
- package/dist/session/globalSessionState.d.ts +8 -0
- package/dist/session/globalSessionState.js +17 -0
- package/dist/types/agentMode.d.ts +9 -0
- package/dist/types/agentMode.js +1 -0
- package/dist/types/cli.d.ts +6 -0
- package/dist/types/config.d.ts +9 -0
- package/dist/types/fileToolRoots.d.ts +17 -0
- package/dist/types/fileToolRoots.js +7 -0
- package/dist/types/generate.d.ts +17 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +2 -0
- package/dist/types/providers.d.ts +6 -0
- package/dist/types/stream.d.ts +7 -0
- package/dist/types/tools.d.ts +7 -0
- package/dist/utils/fileToolRoots.d.ts +34 -0
- package/dist/utils/fileToolRoots.js +111 -0
- package/dist/utils/pathSandbox.d.ts +9 -6
- package/dist/utils/pathSandbox.js +35 -9
- package/docs-site/static/search-index.json +6 -5
- package/package.json +6 -2
package/dist/neurolink.js
CHANGED
|
@@ -62,6 +62,7 @@ import { createSkillCallTools, createSkillTools } from "./skills/skillTools.js";
|
|
|
62
62
|
import { getMetricsAggregator, MetricsAggregator, } from "./observability/metricsAggregator.js";
|
|
63
63
|
import { AnalyticsService, calculateAdvancedCost, parseAnalyticsQualityScore, } from "./analytics/index.js";
|
|
64
64
|
import { SpanStatus, SpanType, CircuitBreakerOpenError, ConversationMemoryError, ModelAccessDeniedError, } from "./types/index.js";
|
|
65
|
+
import { resolveTerminalAgentMode } from "./agent/prompts/terminalAgentPrompt.js";
|
|
65
66
|
import { SpanSerializer } from "./observability/utils/spanSerializer.js";
|
|
66
67
|
import { withSpan } from "./telemetry/withSpan.js";
|
|
67
68
|
import { getActiveTraceContext } from "./telemetry/traceContext.js";
|
|
@@ -99,6 +100,7 @@ import { isZodSchema, convertZodToJsonSchema, } from "./utils/schemaConversion.j
|
|
|
99
100
|
import { resolveToolPolicy } from "./tools/toolPolicy.js";
|
|
100
101
|
import { applyToolGate } from "./tools/toolGate.js";
|
|
101
102
|
import { directAgentTools } from "./agent/directTools.js";
|
|
103
|
+
import { bindFileToolRoots, boundFileToolRoots, resolveFileToolRootPolicy, } from "./utils/fileToolRoots.js";
|
|
102
104
|
import { BinaryTaskClassifier } from "./utils/taskClassifier.js";
|
|
103
105
|
// Tool detection and execution imports
|
|
104
106
|
// Transformation utilities
|
|
@@ -899,7 +901,15 @@ export class NeuroLink {
|
|
|
899
901
|
return metricsTraceContextStorage.getStore() ?? null;
|
|
900
902
|
}
|
|
901
903
|
constructor(config) {
|
|
902
|
-
|
|
904
|
+
if (config?.toolRegistry) {
|
|
905
|
+
// A supplied registry (a host's, shared with a worker) keeps its owner's
|
|
906
|
+
// roots; per-call executeTool() binds this instance's policy anyway.
|
|
907
|
+
this.toolRegistry = config.toolRegistry;
|
|
908
|
+
}
|
|
909
|
+
else {
|
|
910
|
+
this.toolRegistry = new MCPToolRegistry();
|
|
911
|
+
this.toolRegistry.setFileToolRootResolver(() => this.resolveFileToolRoots(undefined));
|
|
912
|
+
}
|
|
903
913
|
this.fileRegistry = new FileReferenceRegistry();
|
|
904
914
|
this.observabilityConfig = config?.observability;
|
|
905
915
|
this.analyticsService = new AnalyticsService();
|
|
@@ -3310,6 +3320,9 @@ Current user's request: ${currentInput}`;
|
|
|
3310
3320
|
// String prompts are immutable, so they pass through.
|
|
3311
3321
|
if (typeof optionsOrPrompt !== "string") {
|
|
3312
3322
|
optionsOrPrompt = cloneOptionsForCallIsolation(optionsOrPrompt);
|
|
3323
|
+
// Resolved once per call and always overwrites a caller-supplied
|
|
3324
|
+
// policy; an invalid root fails here, before any model call.
|
|
3325
|
+
bindFileToolRoots(optionsOrPrompt, this.resolveFileToolRoots(optionsOrPrompt.toolRoots));
|
|
3313
3326
|
// The deprecated `conversationHistory` field is not wired into message
|
|
3314
3327
|
// building — messages passed there never reach the model, which reads
|
|
3315
3328
|
// as "the SDK forgot my context" rather than a caller bug. Warn loudly
|
|
@@ -3321,6 +3334,20 @@ Current user's request: ${currentInput}`;
|
|
|
3321
3334
|
logger.warn("[NeuroLink.generate] `conversationHistory` is deprecated and NOT passed to the model — use `conversationMessages` (ChatMessage[]) instead.");
|
|
3322
3335
|
}
|
|
3323
3336
|
}
|
|
3337
|
+
// Resolved once here and removed from the options, so no internal
|
|
3338
|
+
// re-entrant generate() can prepend the agent instructions twice.
|
|
3339
|
+
let agentModeVersion;
|
|
3340
|
+
if (typeof optionsOrPrompt !== "string") {
|
|
3341
|
+
const { agentMode, ...rest } = optionsOrPrompt;
|
|
3342
|
+
if (agentMode !== undefined) {
|
|
3343
|
+
const resolved = resolveTerminalAgentMode(agentMode, rest.systemPrompt);
|
|
3344
|
+
agentModeVersion = resolved.version;
|
|
3345
|
+
optionsOrPrompt = {
|
|
3346
|
+
...rest,
|
|
3347
|
+
systemPrompt: resolved.systemPrompt,
|
|
3348
|
+
};
|
|
3349
|
+
}
|
|
3350
|
+
}
|
|
3324
3351
|
// Retrieve once at the public call boundary so fallback attempts reuse the
|
|
3325
3352
|
// same grounding block and internal preparation cannot inject it twice.
|
|
3326
3353
|
const groundingOptions = typeof optionsOrPrompt === "string"
|
|
@@ -3348,6 +3375,9 @@ Current user's request: ${currentInput}`;
|
|
|
3348
3375
|
if (knowledgeOutcome) {
|
|
3349
3376
|
result.knowledge = knowledgeOutcome.metadata;
|
|
3350
3377
|
}
|
|
3378
|
+
if (agentModeVersion) {
|
|
3379
|
+
result.agentModeVersion = agentModeVersion;
|
|
3380
|
+
}
|
|
3351
3381
|
return result;
|
|
3352
3382
|
}
|
|
3353
3383
|
catch (error) {
|
|
@@ -4198,6 +4228,7 @@ Current user's request: ${currentInput}`;
|
|
|
4198
4228
|
// (which spreads its options) honoured it.
|
|
4199
4229
|
disableInternalFallback: options.disableInternalFallback,
|
|
4200
4230
|
maxSteps: options.maxSteps,
|
|
4231
|
+
toolRoots: options.toolRoots,
|
|
4201
4232
|
toolChoice: options.toolChoice,
|
|
4202
4233
|
prepareStep: options.prepareStep,
|
|
4203
4234
|
enabledToolNames: options.enabledToolNames,
|
|
@@ -4266,7 +4297,7 @@ Current user's request: ${currentInput}`;
|
|
|
4266
4297
|
: {}),
|
|
4267
4298
|
};
|
|
4268
4299
|
}
|
|
4269
|
-
const textOptions = enhanceTextGenerationOptions(baseOptions, factoryResult);
|
|
4300
|
+
const textOptions = bindFileToolRoots(enhanceTextGenerationOptions(baseOptions, factoryResult), this.fileToolRootsFor(options));
|
|
4270
4301
|
if (this.conversationMemory) {
|
|
4271
4302
|
textOptions.conversationMemoryConfig = this.conversationMemory.config;
|
|
4272
4303
|
textOptions.originalPrompt = originalPrompt;
|
|
@@ -4943,10 +4974,15 @@ Current user's request: ${currentInput}`;
|
|
|
4943
4974
|
options.prompt.trim() === "") {
|
|
4944
4975
|
throw new Error("GenerateText options must include prompt as a non-empty string");
|
|
4945
4976
|
}
|
|
4977
|
+
// Isolate from the caller's object, then resolve file-tool roots exactly
|
|
4978
|
+
// as generate() does: a widening or missing root rejects here, before any
|
|
4979
|
+
// model call, and the resolved policy travels on the private channel.
|
|
4980
|
+
const isolated = cloneOptionsForCallIsolation(options);
|
|
4946
4981
|
// NL-004: Resolve model aliases/deprecations before processing
|
|
4947
|
-
|
|
4982
|
+
isolated.model = resolveModel(isolated.model, this.modelAliasConfig);
|
|
4983
|
+
bindFileToolRoots(isolated, this.resolveFileToolRoots(isolated.toolRoots));
|
|
4948
4984
|
// Use internal generation method directly
|
|
4949
|
-
return await this.generateTextInternal(
|
|
4985
|
+
return await this.generateTextInternal(isolated);
|
|
4950
4986
|
}
|
|
4951
4987
|
/**
|
|
4952
4988
|
* REDESIGNED INTERNAL GENERATION - NO CIRCULAR DEPENDENCIES
|
|
@@ -5940,6 +5976,7 @@ Current user's request: ${currentInput}`;
|
|
|
5940
5976
|
maxSteps: options.maxSteps,
|
|
5941
5977
|
skipToolPromptInjection: options.skipToolPromptInjection,
|
|
5942
5978
|
});
|
|
5979
|
+
provider.setFileToolRootPolicy?.(this.fileToolRootsFor(options));
|
|
5943
5980
|
const result = await provider.generate({
|
|
5944
5981
|
...options,
|
|
5945
5982
|
systemPrompt: enhancedSystemPrompt,
|
|
@@ -6108,6 +6145,7 @@ Current user's request: ${currentInput}`;
|
|
|
6108
6145
|
disableToolCache: options.disableToolCache,
|
|
6109
6146
|
}),
|
|
6110
6147
|
}, functionTag);
|
|
6148
|
+
poolProvider.setFileToolRootPolicy?.(this.fileToolRootsFor(options));
|
|
6111
6149
|
const poolResult = await poolProvider.generate({
|
|
6112
6150
|
...options,
|
|
6113
6151
|
conversationMessages: poolConversationMessages,
|
|
@@ -6482,6 +6520,7 @@ Current user's request: ${currentInput}`;
|
|
|
6482
6520
|
disableToolCache: options.disableToolCache,
|
|
6483
6521
|
}),
|
|
6484
6522
|
}, functionTag);
|
|
6523
|
+
provider.setFileToolRootPolicy?.(this.fileToolRootsFor(options));
|
|
6485
6524
|
const result = await provider.generate({
|
|
6486
6525
|
...options,
|
|
6487
6526
|
conversationMessages, // Inject conversation history
|
|
@@ -6830,6 +6869,16 @@ Current user's request: ${currentInput}`;
|
|
|
6830
6869
|
// shallow rebind at the orchestration site only covered the
|
|
6831
6870
|
// top-level keys and left `options.input` shared with the caller.
|
|
6832
6871
|
options = cloneOptionsForCallIsolation(options);
|
|
6872
|
+
let agentModeVersion;
|
|
6873
|
+
{
|
|
6874
|
+
const { agentMode, ...rest } = options;
|
|
6875
|
+
if (agentMode !== undefined) {
|
|
6876
|
+
const resolved = resolveTerminalAgentMode(agentMode, rest.systemPrompt);
|
|
6877
|
+
agentModeVersion = resolved.version;
|
|
6878
|
+
options = { ...rest, systemPrompt: resolved.systemPrompt };
|
|
6879
|
+
}
|
|
6880
|
+
}
|
|
6881
|
+
bindFileToolRoots(options, this.resolveFileToolRoots(options.toolRoots));
|
|
6833
6882
|
const startedAt = Date.now();
|
|
6834
6883
|
// Retrieve once before provider/model fallback orchestration. Every fallback
|
|
6835
6884
|
// receives the same explicitly enriched options, without the retrieval helper
|
|
@@ -6847,6 +6896,9 @@ Current user's request: ${currentInput}`;
|
|
|
6847
6896
|
if (knowledgeOutcome) {
|
|
6848
6897
|
result.knowledge = knowledgeOutcome.metadata;
|
|
6849
6898
|
}
|
|
6899
|
+
if (agentModeVersion) {
|
|
6900
|
+
result.agentModeVersion = agentModeVersion;
|
|
6901
|
+
}
|
|
6850
6902
|
return result;
|
|
6851
6903
|
}
|
|
6852
6904
|
catch (error) {
|
|
@@ -8415,6 +8467,7 @@ Current user's request: ${currentInput}`;
|
|
|
8415
8467
|
prompt: enhancedOptions.input.text,
|
|
8416
8468
|
context: enhancedOptions.context,
|
|
8417
8469
|
});
|
|
8470
|
+
fallbackProvider.setFileToolRootPolicy?.(this.fileToolRootsFor(enhancedOptions));
|
|
8418
8471
|
const fallbackResult = await fallbackProvider.stream({
|
|
8419
8472
|
...this.deferProviderStreamTTS(enhancedOptions),
|
|
8420
8473
|
model: fallbackRoute.model,
|
|
@@ -8846,6 +8899,7 @@ Current user's request: ${currentInput}`;
|
|
|
8846
8899
|
disableToolCache: options.disableToolCache,
|
|
8847
8900
|
}),
|
|
8848
8901
|
}, "NeuroLink.createMCPStream");
|
|
8902
|
+
poolStreamProvider.setFileToolRootPolicy?.(this.fileToolRootsFor(options));
|
|
8849
8903
|
const poolStreamResult = await poolStreamProvider.stream({
|
|
8850
8904
|
...this.deferProviderStreamTTS(options),
|
|
8851
8905
|
provider: poolStreamProviderName,
|
|
@@ -8925,6 +8979,7 @@ Current user's request: ${currentInput}`;
|
|
|
8925
8979
|
// ─── End ModelPool stream path ────────────────────────────────────────────
|
|
8926
8980
|
// 🔧 FIX: Pass enhanced system prompt to real streaming
|
|
8927
8981
|
// Tools will be accessed through the streamText call in executeStream
|
|
8982
|
+
provider.setFileToolRootPolicy?.(this.fileToolRootsFor(options));
|
|
8928
8983
|
const streamResult = await provider.stream({
|
|
8929
8984
|
...this.deferProviderStreamTTS(options),
|
|
8930
8985
|
systemPrompt: enhancedSystemPrompt, // Use enhanced prompt with tool descriptions
|
|
@@ -9048,6 +9103,7 @@ Current user's request: ${currentInput}`;
|
|
|
9048
9103
|
const responseTime = Date.now() - startTime;
|
|
9049
9104
|
const providerName = await getBestProvider(options.provider);
|
|
9050
9105
|
const provider = await AIProviderFactory.createProvider(providerName, options.model, true, undefined, undefined, this.resolveCredentials(options.credentials));
|
|
9106
|
+
provider.setFileToolRootPolicy?.(this.fileToolRootsFor(options));
|
|
9051
9107
|
const fallbackStreamResult = await provider.stream({
|
|
9052
9108
|
input: { text: options.input.text },
|
|
9053
9109
|
model: options.model,
|
|
@@ -9422,6 +9478,39 @@ Current user's request: ${currentInput}`;
|
|
|
9422
9478
|
* Called by `BaseProvider.applyToolFiltering` so the tool gate composes the
|
|
9423
9479
|
* instance policy with per-call options on every generate/stream call.
|
|
9424
9480
|
*/
|
|
9481
|
+
/**
|
|
9482
|
+
* The policy an entry point bound to `options`, or — for an internal path
|
|
9483
|
+
* that built its own options — the instance policy narrowed by any
|
|
9484
|
+
* per-call `toolRoots`. Never trusts a public field.
|
|
9485
|
+
*/
|
|
9486
|
+
fileToolRootsFor(options) {
|
|
9487
|
+
return (boundFileToolRoots(options) ??
|
|
9488
|
+
this.resolveFileToolRoots(options.toolRoots));
|
|
9489
|
+
}
|
|
9490
|
+
/**
|
|
9491
|
+
* A worker's tool config: it inherits this instance's file-tool roots, and a
|
|
9492
|
+
* worker-level `fileRoots` may only narrow them (throws otherwise).
|
|
9493
|
+
*/
|
|
9494
|
+
workerToolsConfig(override) {
|
|
9495
|
+
const hostRoots = this.toolsConfig?.fileRoots;
|
|
9496
|
+
if (override?.fileRoots === undefined) {
|
|
9497
|
+
return hostRoots === undefined
|
|
9498
|
+
? override
|
|
9499
|
+
: { ...override, fileRoots: hostRoots };
|
|
9500
|
+
}
|
|
9501
|
+
const narrowed = resolveFileToolRootPolicy({
|
|
9502
|
+
perCall: override.fileRoots,
|
|
9503
|
+
instance: hostRoots,
|
|
9504
|
+
}).roots;
|
|
9505
|
+
return { ...override, fileRoots: narrowed ? [...narrowed] : [] };
|
|
9506
|
+
}
|
|
9507
|
+
/** File-tool roots for one call: per-call roots narrow the instance's `tools.fileRoots`. */
|
|
9508
|
+
resolveFileToolRoots(perCall) {
|
|
9509
|
+
return resolveFileToolRootPolicy({
|
|
9510
|
+
perCall,
|
|
9511
|
+
instance: this.toolsConfig?.fileRoots,
|
|
9512
|
+
});
|
|
9513
|
+
}
|
|
9425
9514
|
getToolsConfig() {
|
|
9426
9515
|
return this.toolsConfig;
|
|
9427
9516
|
}
|
|
@@ -10679,11 +10768,8 @@ Current user's request: ${currentInput}`;
|
|
|
10679
10768
|
try {
|
|
10680
10769
|
const storedContext = this.toolExecutionContext || {};
|
|
10681
10770
|
const passedAuthContext = options.authContext || {};
|
|
10682
|
-
|
|
10683
|
-
|
|
10684
|
-
...passedAuthContext,
|
|
10685
|
-
hitlState: HITLState,
|
|
10686
|
-
};
|
|
10771
|
+
// This instance's roots, on the private channel (overwrites the caller's).
|
|
10772
|
+
const context = bindFileToolRoots({ ...storedContext, ...passedAuthContext, hitlState: HITLState }, this.resolveFileToolRoots(undefined));
|
|
10687
10773
|
logger.debug(`[Using merged context for unified registry tool:`, {
|
|
10688
10774
|
toolName,
|
|
10689
10775
|
storedContextKeys: Object.keys(storedContext),
|
|
@@ -13206,7 +13292,8 @@ Current user's request: ${currentInput}`;
|
|
|
13206
13292
|
toolRegistry: this.toolRegistry,
|
|
13207
13293
|
}),
|
|
13208
13294
|
};
|
|
13209
|
-
const
|
|
13295
|
+
const workerTools = this.workerToolsConfig(configOverrides.tools);
|
|
13296
|
+
const worker = new NeuroLink(workerTools ? { ...workerConfig, tools: workerTools } : workerConfig);
|
|
13210
13297
|
// The cacheable:false flag lives BESIDE the registry, not in it, so a
|
|
13211
13298
|
// shared registry alone would re-enable caching on the worker for exactly
|
|
13212
13299
|
// the tools whose results are live state (tasks_list, command_status,
|
|
@@ -9,6 +9,7 @@ export declare class GlobalSessionManager {
|
|
|
9
9
|
private _classifierRouterConfig;
|
|
10
10
|
/** Optional skills config set by CLI handlers before SDK construction. */
|
|
11
11
|
private _skillsConfig;
|
|
12
|
+
private _fileToolRoots;
|
|
12
13
|
static getInstance(): GlobalSessionManager;
|
|
13
14
|
setLoopSession(config?: ConversationMemoryConfig): string;
|
|
14
15
|
/**
|
|
@@ -60,6 +61,13 @@ export declare class GlobalSessionManager {
|
|
|
60
61
|
* already exists).
|
|
61
62
|
*/
|
|
62
63
|
setSkillsConfig(config: SkillsConfig): void;
|
|
64
|
+
/**
|
|
65
|
+
* Store file-tool roots (`--tool-root`) to be injected at SDK construction
|
|
66
|
+
* time as `tools.fileRoots`. Call this BEFORE `getOrCreateNeuroLink()`.
|
|
67
|
+
* When a loop session is already active the roots are ignored (the
|
|
68
|
+
* instance already exists).
|
|
69
|
+
*/
|
|
70
|
+
setFileToolRoots(roots: string[] | undefined): void;
|
|
63
71
|
getOrCreateNeuroLink(): NeuroLink;
|
|
64
72
|
getCurrentSessionId(): string | undefined;
|
|
65
73
|
setSessionVariable(key: string, value: SessionVariableValue): void;
|
|
@@ -37,6 +37,7 @@ export class GlobalSessionManager {
|
|
|
37
37
|
_classifierRouterConfig = undefined;
|
|
38
38
|
/** Optional skills config set by CLI handlers before SDK construction. */
|
|
39
39
|
_skillsConfig = undefined;
|
|
40
|
+
_fileToolRoots = undefined;
|
|
40
41
|
static getInstance() {
|
|
41
42
|
if (!GlobalSessionManager.instance) {
|
|
42
43
|
GlobalSessionManager.instance = new GlobalSessionManager();
|
|
@@ -169,6 +170,18 @@ export class GlobalSessionManager {
|
|
|
169
170
|
}
|
|
170
171
|
this._skillsConfig = config;
|
|
171
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* Store file-tool roots (`--tool-root`) to be injected at SDK construction
|
|
175
|
+
* time as `tools.fileRoots`. Call this BEFORE `getOrCreateNeuroLink()`.
|
|
176
|
+
* When a loop session is already active the roots are ignored (the
|
|
177
|
+
* instance already exists).
|
|
178
|
+
*/
|
|
179
|
+
setFileToolRoots(roots) {
|
|
180
|
+
if (this.hasActiveSession() || !roots?.length) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
this._fileToolRoots = roots;
|
|
184
|
+
}
|
|
172
185
|
getOrCreateNeuroLink() {
|
|
173
186
|
const session = this.getLoopSession();
|
|
174
187
|
if (session) {
|
|
@@ -196,6 +209,10 @@ export class GlobalSessionManager {
|
|
|
196
209
|
options.skills = this._skillsConfig;
|
|
197
210
|
this._skillsConfig = undefined;
|
|
198
211
|
}
|
|
212
|
+
if (this._fileToolRoots) {
|
|
213
|
+
options.tools = { ...options.tools, fileRoots: this._fileToolRoots };
|
|
214
|
+
this._fileToolRoots = undefined;
|
|
215
|
+
}
|
|
199
216
|
return new NeuroLink(Object.keys(options).length ? options : undefined);
|
|
200
217
|
}
|
|
201
218
|
getCurrentSessionId() {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Version of the terminal agent instructions applied by `agentMode`. */
|
|
2
|
+
export type TerminalAgentModeVersion = "1" | "2";
|
|
3
|
+
/**
|
|
4
|
+
* Opt-in terminal agent mode. `true` applies the current instructions; the
|
|
5
|
+
* object form pins a version so results stay comparable across releases.
|
|
6
|
+
*/
|
|
7
|
+
export type TerminalAgentModeOption = boolean | {
|
|
8
|
+
version?: TerminalAgentModeVersion;
|
|
9
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/types/cli.d.ts
CHANGED
|
@@ -55,6 +55,8 @@ export type GenerateCommandArgs = BaseCommandArgs & CliToolRoutingFlags & CliCla
|
|
|
55
55
|
model?: string;
|
|
56
56
|
/** System prompt */
|
|
57
57
|
system?: string;
|
|
58
|
+
/** Prepend Neurolink's versioned terminal agent instructions */
|
|
59
|
+
agentMode?: boolean;
|
|
58
60
|
/** Temperature setting */
|
|
59
61
|
temperature?: number;
|
|
60
62
|
/** Maximum tokens */
|
|
@@ -120,6 +122,10 @@ export type StreamCommandArgs = BaseCommandArgs & CliToolRoutingFlags & CliClass
|
|
|
120
122
|
model?: string;
|
|
121
123
|
/** System prompt */
|
|
122
124
|
system?: string;
|
|
125
|
+
/** Prepend Neurolink's versioned terminal agent instructions */
|
|
126
|
+
agentMode?: boolean;
|
|
127
|
+
/** Maximum tool-calling steps */
|
|
128
|
+
maxSteps?: number;
|
|
123
129
|
/** Temperature setting */
|
|
124
130
|
temperature?: number;
|
|
125
131
|
/** Maximum tokens */
|
package/dist/types/config.d.ts
CHANGED
|
@@ -427,6 +427,15 @@ export type ToolConfig = {
|
|
|
427
427
|
enableMCPTools?: boolean;
|
|
428
428
|
/** Whether the bash command execution tool should be enabled (opt-in, defaults to false) */
|
|
429
429
|
enableBashTool?: boolean;
|
|
430
|
+
/**
|
|
431
|
+
* Directories the built-in file tools (readFile, listDirectory, writeFile,
|
|
432
|
+
* analyzeCSV) and bash's `cwd` argument may touch. Resolved through
|
|
433
|
+
* symlinks; each must be an existing directory. Default: the process
|
|
434
|
+
* working directory. An empty array denies all file access. Per-call
|
|
435
|
+
* `toolRoots` can only narrow this list. Roots do not sandbox the shell
|
|
436
|
+
* commands themselves — a command can still `cd` anywhere.
|
|
437
|
+
*/
|
|
438
|
+
fileRoots?: string[];
|
|
430
439
|
/**
|
|
431
440
|
* Byte ceiling for the safety-net truncation `ToolsManager` applies to
|
|
432
441
|
* every direct/custom/external-MCP tool result before it reaches the AI
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filesystem roots for the built-in file tools — types.
|
|
3
|
+
*
|
|
4
|
+
* Naming: `pathSandbox.ts` owns `PathSandbox*` and `file.ts` owns `FilePath*`,
|
|
5
|
+
* so this carries the `FileToolRoot` prefix (Critical Rule 9).
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* The directories the built-in file tools (readFile, listDirectory,
|
|
9
|
+
* writeFile, analyzeCSV) and bash's `cwd` argument may touch for one request.
|
|
10
|
+
*
|
|
11
|
+
* `roots` are real, existing directories resolved once when the request
|
|
12
|
+
* starts. `null` means the historical default: the process working
|
|
13
|
+
* directory, read at call time. An empty array denies all file access.
|
|
14
|
+
*/
|
|
15
|
+
export type FileToolRootPolicy = {
|
|
16
|
+
readonly roots: readonly string[] | null;
|
|
17
|
+
};
|
package/dist/types/generate.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import type { SkillsCallOptions } from "./skills.js";
|
|
|
5
5
|
import type { AnalyticsData, TokenUsage } from "./analytics.js";
|
|
6
6
|
import type { ClaudeLimitSnapshot } from "./subscription.js";
|
|
7
7
|
import type { JsonValue } from "./common.js";
|
|
8
|
+
import type { TerminalAgentModeOption, TerminalAgentModeVersion } from "./agentMode.js";
|
|
8
9
|
import type { Content, ImageWithAltText } from "./content.js";
|
|
9
10
|
import type { ChatMessage, ConversationMemoryConfig } from "./conversation.js";
|
|
10
11
|
import type { EvaluationData } from "./evaluation.js";
|
|
@@ -310,6 +311,11 @@ export type GenerateOptions = {
|
|
|
310
311
|
/** Stop sequences that will halt generation when encountered. */
|
|
311
312
|
stopSequences?: string[];
|
|
312
313
|
systemPrompt?: string;
|
|
314
|
+
/**
|
|
315
|
+
* Opt-in terminal agent mode: prepends Neurolink's versioned autonomous-agent
|
|
316
|
+
* instructions to `systemPrompt`. Omitted means no change in behaviour.
|
|
317
|
+
*/
|
|
318
|
+
agentMode?: TerminalAgentModeOption;
|
|
313
319
|
/**
|
|
314
320
|
* Zod schema for structured output validation
|
|
315
321
|
*
|
|
@@ -517,6 +523,13 @@ export type GenerateOptions = {
|
|
|
517
523
|
disableInternalFallback?: boolean;
|
|
518
524
|
/** Maximum number of tool execution steps (default: 200) */
|
|
519
525
|
maxSteps?: number;
|
|
526
|
+
/**
|
|
527
|
+
* Directories the built-in file tools and bash's `cwd` argument may touch
|
|
528
|
+
* for this call. Can only narrow the instance's `tools.fileRoots` (or the
|
|
529
|
+
* working-directory default); a root outside them is rejected before any
|
|
530
|
+
* model call. An empty array denies all file access.
|
|
531
|
+
*/
|
|
532
|
+
toolRoots?: string[];
|
|
520
533
|
/**
|
|
521
534
|
* Tool choice configuration for the generation.
|
|
522
535
|
* Controls whether and which tools the model must call.
|
|
@@ -985,6 +998,8 @@ export type GenerateResult = {
|
|
|
985
998
|
content: string;
|
|
986
999
|
/** Knowledge-grounding diagnostics for this turn (present only when grounding ran). */
|
|
987
1000
|
knowledge?: KnowledgeGroundingMetadata;
|
|
1001
|
+
/** Terminal agent instructions version applied (present only with `agentMode`). */
|
|
1002
|
+
agentModeVersion?: TerminalAgentModeVersion;
|
|
988
1003
|
/**
|
|
989
1004
|
* Parsed structured object when a `schema` was requested. Populated from
|
|
990
1005
|
* AI-SDK experimental_output, or from text-mode coercion (balanced-scan +
|
|
@@ -1281,6 +1296,8 @@ export type TextGenerationOptions = {
|
|
|
1281
1296
|
/** Disable the schema-driven tool call repair mechanism (BZ-665). Default: false (repair enabled). */
|
|
1282
1297
|
disableToolCallRepair?: boolean;
|
|
1283
1298
|
maxSteps?: number;
|
|
1299
|
+
/** Directories the built-in file tools may touch for this call; see GenerateOptions.toolRoots. */
|
|
1300
|
+
toolRoots?: string[];
|
|
1284
1301
|
/** Include only these tools by name (whitelist). If set, only matching tools are available. */
|
|
1285
1302
|
toolFilter?: string[];
|
|
1286
1303
|
/** Exclude these tools by name (blacklist). Applied after toolFilter. */
|
package/dist/types/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export * from "./enums.js";
|
|
6
6
|
export * from "./action.js";
|
|
7
|
+
export * from "./agentMode.js";
|
|
7
8
|
export * from "./aliases.js";
|
|
8
9
|
export * from "./analytics.js";
|
|
9
10
|
export * from "./artifact.js";
|
|
@@ -23,6 +24,7 @@ export * from "./delegation.js";
|
|
|
23
24
|
export * from "./backgroundCommand.js";
|
|
24
25
|
export * from "./gitTools.js";
|
|
25
26
|
export * from "./pathSandbox.js";
|
|
27
|
+
export * from "./fileToolRoots.js";
|
|
26
28
|
export * from "./domain.js";
|
|
27
29
|
export * from "./errors.js";
|
|
28
30
|
export * from "./evaluation.js";
|
package/dist/types/index.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// All type files (alphabetical)
|
|
6
6
|
export * from "./enums.js";
|
|
7
7
|
export * from "./action.js";
|
|
8
|
+
export * from "./agentMode.js";
|
|
8
9
|
export * from "./aliases.js";
|
|
9
10
|
export * from "./analytics.js";
|
|
10
11
|
export * from "./artifact.js";
|
|
@@ -27,6 +28,7 @@ export * from "./backgroundCommand.js";
|
|
|
27
28
|
export * from "./gitTools.js";
|
|
28
29
|
// Path containment guard shared by the sandboxed execution paths
|
|
29
30
|
export * from "./pathSandbox.js";
|
|
31
|
+
export * from "./fileToolRoots.js";
|
|
30
32
|
export * from "./domain.js";
|
|
31
33
|
export * from "./errors.js";
|
|
32
34
|
export * from "./evaluation.js";
|
|
@@ -6,6 +6,7 @@ import type { NeuroLink } from "../neurolink.js";
|
|
|
6
6
|
import { AIProviderName, AnthropicModels, BedrockModels, DeepSeekModels, GoogleAIModels, LlamaCppModels, LMStudioModels, NvidiaNimModels, OpenAIModels, VertexModels } from "../constants/enums.js";
|
|
7
7
|
import type { ValidationSchema } from "./aliases.js";
|
|
8
8
|
import type { DecisionLimits, DecisionRequest, DecisionResult } from "./decision.js";
|
|
9
|
+
import type { FileToolRootPolicy } from "./fileToolRoots.js";
|
|
9
10
|
import type { EnhancedGenerateResult, TextGenerationOptions } from "./generate.js";
|
|
10
11
|
import type { MultimodalAudioEntry, MultimodalVideoEntry } from "./file.js";
|
|
11
12
|
import type { StreamOptions, StreamResult } from "./stream.js";
|
|
@@ -833,6 +834,11 @@ export type AIProvider = {
|
|
|
833
834
|
traceId: string;
|
|
834
835
|
parentSpanId: string;
|
|
835
836
|
} | null): void;
|
|
837
|
+
/**
|
|
838
|
+
* Bind the built-in file tools to one request's root policy. Optional so
|
|
839
|
+
* custom provider implementations keep compiling; BaseProvider implements it.
|
|
840
|
+
*/
|
|
841
|
+
setFileToolRootPolicy?(policy: FileToolRootPolicy | undefined): void;
|
|
836
842
|
/**
|
|
837
843
|
* Whether this provider supports native tool/function calling for the
|
|
838
844
|
* current model. Implemented by BaseProvider (default true); overridden by
|
package/dist/types/stream.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import type { AnalyticsData, ToolExecutionEvent, ToolExecutionSummary } from "..
|
|
|
7
7
|
import type { MiddlewareFactoryOptions, OnChunkCallback, OnErrorCallback, OnFinishCallback } from "../types/middleware.js";
|
|
8
8
|
import type { TokenUsage } from "./analytics.js";
|
|
9
9
|
import type { JsonValue, UnknownRecord } from "./common.js";
|
|
10
|
+
import type { TerminalAgentModeOption, TerminalAgentModeVersion } from "./agentMode.js";
|
|
10
11
|
import type { Content, ImageWithAltText } from "./content.js";
|
|
11
12
|
import type { ChatMessage } from "./conversation.js";
|
|
12
13
|
import type { StreamNoOutputSentinel } from "./noOutputSentinel.js";
|
|
@@ -504,6 +505,8 @@ export type StreamOptions = {
|
|
|
504
505
|
/** Stop sequences that will halt generation when encountered. */
|
|
505
506
|
stopSequences?: string[];
|
|
506
507
|
systemPrompt?: string;
|
|
508
|
+
/** Opt-in terminal agent mode. See GenerateOptions.agentMode. */
|
|
509
|
+
agentMode?: TerminalAgentModeOption;
|
|
507
510
|
schema?: ValidationSchema;
|
|
508
511
|
tools?: Record<string, Tool>;
|
|
509
512
|
timeout?: number | string;
|
|
@@ -550,6 +553,8 @@ export type StreamOptions = {
|
|
|
550
553
|
/** Disable the schema-driven tool call repair mechanism (BZ-665). Default: false (repair enabled). */
|
|
551
554
|
disableToolCallRepair?: boolean;
|
|
552
555
|
maxSteps?: number;
|
|
556
|
+
/** Directories the built-in file tools may touch for this call; see GenerateOptions.toolRoots; can only narrow tools.fileRoots. */
|
|
557
|
+
toolRoots?: string[];
|
|
553
558
|
/**
|
|
554
559
|
* Tool choice configuration for streaming generation.
|
|
555
560
|
* Mirrors generate() so translated/fallback requests can preserve forced tool use.
|
|
@@ -777,6 +782,8 @@ export type StreamOptions = {
|
|
|
777
782
|
export type StreamResult = {
|
|
778
783
|
/** Knowledge-grounding diagnostics for this turn (present only when grounding ran). */
|
|
779
784
|
knowledge?: KnowledgeGroundingMetadata;
|
|
785
|
+
/** Terminal agent instructions version applied (present only with `agentMode`). */
|
|
786
|
+
agentModeVersion?: TerminalAgentModeVersion;
|
|
780
787
|
stream: AsyncIterable<{
|
|
781
788
|
content: string;
|
|
782
789
|
reasoning?: string;
|
package/dist/types/tools.d.ts
CHANGED
|
@@ -412,6 +412,13 @@ export type SdkSimpleTool<TArgs = ToolArgs, TResult = JsonValue> = Omit<SimpleTo
|
|
|
412
412
|
[key: string]: JsonValue | undefined;
|
|
413
413
|
};
|
|
414
414
|
};
|
|
415
|
+
/** Arguments of the built-in analyzeCSV tool, after schema defaults. */
|
|
416
|
+
export type AnalyzeCsvToolArgs = {
|
|
417
|
+
filePath: string;
|
|
418
|
+
operation: "count_by_column" | "sum_by_column" | "average_by_column" | "min_max_by_column" | "describe";
|
|
419
|
+
column: string;
|
|
420
|
+
maxRows?: number;
|
|
421
|
+
};
|
|
415
422
|
/** Subset of directAgentTools exposing only the "basic" category. */
|
|
416
423
|
export type BasicToolsMap = {
|
|
417
424
|
getCurrentTime: Tool;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve which directories the built-in file tools may touch for a request.
|
|
3
|
+
*
|
|
4
|
+
* Precedence follows the credential pattern: per-call beats instance, and
|
|
5
|
+
* instance beats the `NEUROLINK_TOOL_ROOTS` environment variable. The
|
|
6
|
+
* instance list (or the environment, or the working directory) is a
|
|
7
|
+
* ceiling — per-call roots may only narrow it, so a server that forwards
|
|
8
|
+
* caller options cannot be talked into widening file access.
|
|
9
|
+
*
|
|
10
|
+
* Every root is resolved through realpath once, here, so a root reached
|
|
11
|
+
* through a symlink (`/home/user` → `/home/agent`) admits its own files, and
|
|
12
|
+
* a later `chdir` cannot move the boundary mid-request.
|
|
13
|
+
*
|
|
14
|
+
* @module utils/fileToolRoots
|
|
15
|
+
*/
|
|
16
|
+
import type { FileToolRootPolicy } from "../types/index.js";
|
|
17
|
+
/**
|
|
18
|
+
* The file-tool root policy for one request.
|
|
19
|
+
*
|
|
20
|
+
* Returns `{ roots: null }` when nothing is configured anywhere, which keeps
|
|
21
|
+
* the historical behaviour: the working directory, read at call time.
|
|
22
|
+
*
|
|
23
|
+
* @throws when a root does not exist, is not a directory, or a per-call root
|
|
24
|
+
* lies outside the instance ceiling. Callers invoke this before any model
|
|
25
|
+
* request so a misconfiguration fails fast.
|
|
26
|
+
*/
|
|
27
|
+
export declare function resolveFileToolRootPolicy(input: {
|
|
28
|
+
perCall?: readonly string[];
|
|
29
|
+
instance?: readonly string[];
|
|
30
|
+
}): FileToolRootPolicy;
|
|
31
|
+
/** Attach a resolved policy to `target` (an options bag or execution context). */
|
|
32
|
+
export declare function bindFileToolRoots<T extends object>(target: T, policy: FileToolRootPolicy): T;
|
|
33
|
+
/** The policy bound by {@link bindFileToolRoots}, if any. */
|
|
34
|
+
export declare function boundFileToolRoots(source: unknown): FileToolRootPolicy | undefined;
|