@juspay/neurolink 9.83.0 → 9.84.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/agent/agent.d.ts +104 -0
- package/dist/agent/agent.js +401 -0
- package/dist/agent/agentNetwork.d.ts +87 -0
- package/dist/agent/agentNetwork.js +458 -0
- package/dist/agent/communication/index.d.ts +9 -0
- package/dist/agent/communication/index.js +9 -0
- package/dist/agent/communication/message-bus.d.ts +113 -0
- package/dist/agent/communication/message-bus.js +406 -0
- package/dist/agent/coordination/coordinator.d.ts +83 -0
- package/dist/agent/coordination/coordinator.js +598 -0
- package/dist/agent/coordination/index.d.ts +10 -0
- package/dist/agent/coordination/index.js +10 -0
- package/dist/agent/coordination/task-distributor.d.ts +113 -0
- package/dist/agent/coordination/task-distributor.js +585 -0
- package/dist/agent/index.d.ts +38 -0
- package/dist/agent/index.js +44 -0
- package/dist/agent/orchestration/index.d.ts +10 -0
- package/dist/agent/orchestration/index.js +10 -0
- package/dist/agent/orchestration/orchestrator.d.ts +114 -0
- package/dist/agent/orchestration/orchestrator.js +476 -0
- package/dist/agent/orchestration/topology.d.ts +164 -0
- package/dist/agent/orchestration/topology.js +520 -0
- package/dist/agent/prompts/routingPrompts.d.ts +63 -0
- package/dist/agent/prompts/routingPrompts.js +201 -0
- package/dist/browser/neurolink.min.js +377 -358
- package/dist/cli/commands/agent.d.ts +37 -0
- package/dist/cli/commands/agent.js +718 -0
- package/dist/cli/factories/commandFactory.d.ts +8 -0
- package/dist/cli/factories/commandFactory.js +116 -0
- package/dist/cli/loop/optionsSchema.d.ts +1 -1
- package/dist/cli/parser.js +4 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +19 -0
- package/dist/lib/agent/agent.d.ts +104 -0
- package/dist/lib/agent/agent.js +402 -0
- package/dist/lib/agent/agentNetwork.d.ts +87 -0
- package/dist/lib/agent/agentNetwork.js +459 -0
- package/dist/lib/agent/communication/index.d.ts +9 -0
- package/dist/lib/agent/communication/index.js +10 -0
- package/dist/lib/agent/communication/message-bus.d.ts +113 -0
- package/dist/lib/agent/communication/message-bus.js +407 -0
- package/dist/lib/agent/coordination/coordinator.d.ts +83 -0
- package/dist/lib/agent/coordination/coordinator.js +599 -0
- package/dist/lib/agent/coordination/index.d.ts +10 -0
- package/dist/lib/agent/coordination/index.js +11 -0
- package/dist/lib/agent/coordination/task-distributor.d.ts +113 -0
- package/dist/lib/agent/coordination/task-distributor.js +586 -0
- package/dist/lib/agent/index.d.ts +38 -0
- package/dist/lib/agent/index.js +45 -0
- package/dist/lib/agent/orchestration/index.d.ts +10 -0
- package/dist/lib/agent/orchestration/index.js +11 -0
- package/dist/lib/agent/orchestration/orchestrator.d.ts +114 -0
- package/dist/lib/agent/orchestration/orchestrator.js +477 -0
- package/dist/lib/agent/orchestration/topology.d.ts +164 -0
- package/dist/lib/agent/orchestration/topology.js +521 -0
- package/dist/lib/agent/prompts/routingPrompts.d.ts +63 -0
- package/dist/lib/agent/prompts/routingPrompts.js +202 -0
- package/dist/lib/index.d.ts +6 -0
- package/dist/lib/index.js +19 -0
- package/dist/lib/neurolink.d.ts +129 -0
- package/dist/lib/neurolink.js +276 -0
- package/dist/lib/processors/config/{fileTypes.js → fileExtensions.js} +1 -1
- package/dist/lib/processors/config/index.d.ts +2 -2
- package/dist/lib/processors/config/index.js +2 -2
- package/dist/lib/processors/config/{mimeTypes.js → mimeConstants.js} +1 -1
- package/dist/lib/processors/index.js +8 -0
- package/dist/lib/providers/googleAiStudio.js +3 -3
- package/dist/lib/providers/googleNativeGemini3.d.ts +18 -0
- package/dist/lib/providers/googleNativeGemini3.js +47 -1
- package/dist/lib/providers/googleVertex.js +5 -5
- package/dist/lib/types/agentNetwork.d.ts +1184 -0
- package/dist/lib/types/agentNetwork.js +8 -0
- package/dist/lib/types/cli.d.ts +66 -0
- package/dist/lib/types/generate.d.ts +53 -0
- package/dist/lib/types/index.d.ts +2 -0
- package/dist/lib/types/index.js +3 -0
- package/dist/lib/types/ioProcessor.d.ts +119 -0
- package/dist/lib/types/ioProcessor.js +10 -0
- package/dist/lib/types/stream.d.ts +36 -0
- package/dist/lib/utils/piiDetector.d.ts +24 -0
- package/dist/lib/utils/piiDetector.js +221 -0
- package/dist/lib/utils/responseValidator.d.ts +21 -0
- package/dist/lib/utils/responseValidator.js +354 -0
- package/dist/lib/utils/tripwireEvaluator.d.ts +73 -0
- package/dist/lib/utils/tripwireEvaluator.js +285 -0
- package/dist/neurolink.d.ts +129 -0
- package/dist/neurolink.js +276 -0
- package/dist/processors/config/index.d.ts +2 -2
- package/dist/processors/config/index.js +2 -2
- package/dist/processors/index.js +8 -0
- package/dist/providers/googleAiStudio.js +3 -3
- package/dist/providers/googleNativeGemini3.d.ts +18 -0
- package/dist/providers/googleNativeGemini3.js +47 -1
- package/dist/providers/googleVertex.js +5 -5
- package/dist/types/agentNetwork.d.ts +1184 -0
- package/dist/types/agentNetwork.js +7 -0
- package/dist/types/cli.d.ts +66 -0
- package/dist/types/generate.d.ts +53 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +3 -0
- package/dist/types/ioProcessor.d.ts +119 -0
- package/dist/types/ioProcessor.js +9 -0
- package/dist/types/stream.d.ts +36 -0
- package/dist/utils/piiDetector.d.ts +24 -0
- package/dist/utils/piiDetector.js +220 -0
- package/dist/utils/responseValidator.d.ts +21 -0
- package/dist/utils/responseValidator.js +353 -0
- package/dist/utils/tripwireEvaluator.d.ts +73 -0
- package/dist/utils/tripwireEvaluator.js +284 -0
- package/package.json +1 -1
- /package/dist/lib/processors/config/{fileTypes.d.ts → fileExtensions.d.ts} +0 -0
- /package/dist/lib/processors/config/{mimeTypes.d.ts → mimeConstants.d.ts} +0 -0
- /package/dist/processors/config/{fileTypes.d.ts → fileExtensions.d.ts} +0 -0
- /package/dist/processors/config/{fileTypes.js → fileExtensions.js} +0 -0
- /package/dist/processors/config/{mimeTypes.d.ts → mimeConstants.d.ts} +0 -0
- /package/dist/processors/config/{mimeTypes.js → mimeConstants.js} +0 -0
package/dist/neurolink.js
CHANGED
|
@@ -90,6 +90,8 @@ import { runWorkflow } from "./workflow/core/workflowRunner.js";
|
|
|
90
90
|
import { ModelPool, classifyProviderError } from "./routing/index.js";
|
|
91
91
|
import { ClassifierRouter } from "./routing/classifierRouter.js";
|
|
92
92
|
import { looksLikeModelAccessDenied as sharedLooksLikeModelAccessDenied, isNonRetryableProviderError as sharedIsNonRetryableProviderError, } from "./utils/providerErrorClassification.js";
|
|
93
|
+
import { detectAndRedactPII } from "./utils/piiDetector.js";
|
|
94
|
+
import { validateResponse } from "./utils/responseValidator.js";
|
|
93
95
|
/**
|
|
94
96
|
* NL-002: Classify MCP error messages into categories for AI disambiguation.
|
|
95
97
|
* Returns a human-readable error category based on error message content.
|
|
@@ -3063,6 +3065,41 @@ Current user's request: ${currentInput}`;
|
|
|
3063
3065
|
if (!hasSttAudio && !isMediaModalityMode) {
|
|
3064
3066
|
this.assertInputText(options.input?.text, "Input text is required and must be a non-empty string");
|
|
3065
3067
|
}
|
|
3068
|
+
// Input validation (trimWhitespace, minLength, maxLength, requireContent).
|
|
3069
|
+
// Guard on a string input.text — release's media-only / STT flows may leave
|
|
3070
|
+
// it empty/undefined, and those never carry inputValidation anyway.
|
|
3071
|
+
if (options.inputValidation && typeof options.input.text === "string") {
|
|
3072
|
+
const iv = options.inputValidation;
|
|
3073
|
+
if (iv.trimWhitespace) {
|
|
3074
|
+
options.input.text = options.input.text.trim();
|
|
3075
|
+
}
|
|
3076
|
+
if (iv.requireContent && !options.input.text.trim()) {
|
|
3077
|
+
throw new Error("Input content is required but was empty or whitespace");
|
|
3078
|
+
}
|
|
3079
|
+
if (iv.minLength && options.input.text.length < iv.minLength) {
|
|
3080
|
+
throw new Error(`Input text is too short (${options.input.text.length} < ${iv.minLength})`);
|
|
3081
|
+
}
|
|
3082
|
+
if (iv.maxLength && options.input.text.length > iv.maxLength) {
|
|
3083
|
+
throw new Error(`Input text is too long (${options.input.text.length} > ${iv.maxLength})`);
|
|
3084
|
+
}
|
|
3085
|
+
}
|
|
3086
|
+
// PII detection and redaction
|
|
3087
|
+
if (options.piiDetection?.enabled &&
|
|
3088
|
+
typeof options.input.text === "string") {
|
|
3089
|
+
const piiResult = await detectAndRedactPII(options.input.text, {
|
|
3090
|
+
enabled: true,
|
|
3091
|
+
action: options.piiDetection.action ?? "warn",
|
|
3092
|
+
detectTypes: options.piiDetection.detectTypes,
|
|
3093
|
+
customPatterns: options.piiDetection.customPatterns,
|
|
3094
|
+
allowList: options.piiDetection.allowList,
|
|
3095
|
+
redactionText: options.piiDetection.redactionText,
|
|
3096
|
+
});
|
|
3097
|
+
if (piiResult.action === "abort") {
|
|
3098
|
+
throw new Error(piiResult.feedback ?? "Request blocked: PII detected in input");
|
|
3099
|
+
}
|
|
3100
|
+
// Replace input text with redacted version
|
|
3101
|
+
options.input.text = piiResult.text;
|
|
3102
|
+
}
|
|
3066
3103
|
this.enforceSessionBudget(options.maxBudgetUsd);
|
|
3067
3104
|
this.applyGenerateLifecycleMiddleware(options);
|
|
3068
3105
|
await this.applyAuthenticatedRequestContext(options);
|
|
@@ -3702,6 +3739,29 @@ Current user's request: ${currentInput}`;
|
|
|
3702
3739
|
reasoningTokens: textResult.reasoningTokens,
|
|
3703
3740
|
...(textResult.retries && { retries: textResult.retries }),
|
|
3704
3741
|
};
|
|
3742
|
+
// Response validation (if configured)
|
|
3743
|
+
if (options.responseValidation) {
|
|
3744
|
+
const validationResult = validateResponse(generateResult.content ?? "", {
|
|
3745
|
+
minLength: options.responseValidation.minLength,
|
|
3746
|
+
maxLength: options.responseValidation.maxLength,
|
|
3747
|
+
requiredPhrases: options.responseValidation.requiredPhrases,
|
|
3748
|
+
forbiddenPhrases: options.responseValidation.forbiddenPhrases,
|
|
3749
|
+
jsonSchema: options.responseValidation.jsonSchema,
|
|
3750
|
+
customValidator: options.responseValidation.customValidator,
|
|
3751
|
+
truncationAction: options.responseValidation.truncationAction,
|
|
3752
|
+
truncationSuffix: options.responseValidation.truncationSuffix,
|
|
3753
|
+
retryOnFailure: options.responseValidation.retryOnFailure,
|
|
3754
|
+
maxRetries: options.responseValidation.maxRetries,
|
|
3755
|
+
});
|
|
3756
|
+
if (validationResult.action === "abort") {
|
|
3757
|
+
throw new Error(validationResult.feedback ??
|
|
3758
|
+
`Response validation failed: ${validationResult.issues.map((i) => i.message).join("; ")}`);
|
|
3759
|
+
}
|
|
3760
|
+
// Apply validated/truncated text
|
|
3761
|
+
if (validationResult.text !== generateResult.content) {
|
|
3762
|
+
generateResult.content = validationResult.text;
|
|
3763
|
+
}
|
|
3764
|
+
}
|
|
3705
3765
|
if (generateResult.analytics?.cost && generateResult.analytics.cost > 0) {
|
|
3706
3766
|
this._sessionCostUsd += generateResult.analytics.cost;
|
|
3707
3767
|
}
|
|
@@ -6452,6 +6512,37 @@ Current user's request: ${currentInput}`;
|
|
|
6452
6512
|
}
|
|
6453
6513
|
async validateStreamRequestOptions(options, startTime) {
|
|
6454
6514
|
await this.validateStreamInput(options);
|
|
6515
|
+
// Input validation for stream
|
|
6516
|
+
if (options.inputValidation && options.input?.text) {
|
|
6517
|
+
const iv = options.inputValidation;
|
|
6518
|
+
if (iv.trimWhitespace) {
|
|
6519
|
+
options.input.text = options.input.text.trim();
|
|
6520
|
+
}
|
|
6521
|
+
if (iv.requireContent && !options.input.text.trim()) {
|
|
6522
|
+
throw new Error("Input content is required but was empty or whitespace");
|
|
6523
|
+
}
|
|
6524
|
+
if (iv.minLength && options.input.text.length < iv.minLength) {
|
|
6525
|
+
throw new Error(`Input text is too short (${options.input.text.length} < ${iv.minLength})`);
|
|
6526
|
+
}
|
|
6527
|
+
if (iv.maxLength && options.input.text.length > iv.maxLength) {
|
|
6528
|
+
throw new Error(`Input text is too long (${options.input.text.length} > ${iv.maxLength})`);
|
|
6529
|
+
}
|
|
6530
|
+
}
|
|
6531
|
+
// PII detection and redaction for stream
|
|
6532
|
+
if (options.piiDetection?.enabled && options.input?.text) {
|
|
6533
|
+
const piiResult = await detectAndRedactPII(options.input.text, {
|
|
6534
|
+
enabled: true,
|
|
6535
|
+
action: options.piiDetection.action ?? "warn",
|
|
6536
|
+
detectTypes: options.piiDetection.detectTypes,
|
|
6537
|
+
customPatterns: options.piiDetection.customPatterns,
|
|
6538
|
+
allowList: options.piiDetection.allowList,
|
|
6539
|
+
redactionText: options.piiDetection.redactionText,
|
|
6540
|
+
});
|
|
6541
|
+
if (piiResult.action === "abort") {
|
|
6542
|
+
throw new Error(piiResult.feedback ?? "Request blocked: PII detected in input");
|
|
6543
|
+
}
|
|
6544
|
+
options.input.text = piiResult.text;
|
|
6545
|
+
}
|
|
6455
6546
|
this.enforceSessionBudget(options.maxBudgetUsd);
|
|
6456
6547
|
await this.applyAuthenticatedRequestContext(options);
|
|
6457
6548
|
this.emitStreamStartEvents(options, startTime);
|
|
@@ -11216,6 +11307,191 @@ Current user's request: ${currentInput}`;
|
|
|
11216
11307
|
const { getPreset } = await withTimeout(import("./evaluation/pipeline/index.js"), 10000, ErrorFactory.evaluationTimeout("evaluation module load", 10000));
|
|
11217
11308
|
return getPreset(presetName);
|
|
11218
11309
|
}
|
|
11310
|
+
// ============================================================================
|
|
11311
|
+
// MULTI-AGENT ORCHESTRATION METHODS
|
|
11312
|
+
// ============================================================================
|
|
11313
|
+
/**
|
|
11314
|
+
* Create an Agent instance for multi-agent orchestration.
|
|
11315
|
+
*
|
|
11316
|
+
* Agents are specialized AI entities with defined instructions, tools, and behavior.
|
|
11317
|
+
* They can be composed into networks for complex task orchestration.
|
|
11318
|
+
*
|
|
11319
|
+
* @param definition - Agent definition specifying behavior and capabilities
|
|
11320
|
+
* @returns A new Agent instance
|
|
11321
|
+
*
|
|
11322
|
+
* @example
|
|
11323
|
+
* ```typescript
|
|
11324
|
+
* const researcher = neurolink.createAgent({
|
|
11325
|
+
* id: 'researcher',
|
|
11326
|
+
* name: 'Research Agent',
|
|
11327
|
+
* description: 'Searches and analyzes information from various sources',
|
|
11328
|
+
* instructions: 'You are a research assistant. Search thoroughly and cite sources.',
|
|
11329
|
+
* tools: ['websearchGrounding', 'readFile'],
|
|
11330
|
+
* model: 'gpt-4o'
|
|
11331
|
+
* });
|
|
11332
|
+
*
|
|
11333
|
+
* const result = await researcher.execute('Find recent AI breakthroughs');
|
|
11334
|
+
* ```
|
|
11335
|
+
*
|
|
11336
|
+
* @see {@link AgentDefinition} for definition options
|
|
11337
|
+
* @see {@link Agent} for agent methods
|
|
11338
|
+
* @since 8.38.0
|
|
11339
|
+
*/
|
|
11340
|
+
async createAgent(definition) {
|
|
11341
|
+
const { Agent } = await import("./agent/agent.js");
|
|
11342
|
+
logger.debug("[NeuroLink] Creating agent", {
|
|
11343
|
+
id: definition.id,
|
|
11344
|
+
name: definition.name,
|
|
11345
|
+
tools: definition.tools?.length || 0,
|
|
11346
|
+
});
|
|
11347
|
+
return new Agent(definition, this);
|
|
11348
|
+
}
|
|
11349
|
+
/**
|
|
11350
|
+
* Create an AgentNetwork for multi-agent orchestration.
|
|
11351
|
+
*
|
|
11352
|
+
* Networks coordinate multiple agents, workflows, and tools with intelligent
|
|
11353
|
+
* LLM-powered routing. The router agent analyzes tasks and delegates to
|
|
11354
|
+
* the most appropriate primitive.
|
|
11355
|
+
*
|
|
11356
|
+
* @param config - Network configuration with agents, workflows, and routing settings
|
|
11357
|
+
* @returns A new AgentNetwork instance
|
|
11358
|
+
*
|
|
11359
|
+
* @example
|
|
11360
|
+
* ```typescript
|
|
11361
|
+
* const network = neurolink.createNetwork({
|
|
11362
|
+
* name: 'Content Team',
|
|
11363
|
+
* description: 'Collaborative content creation pipeline',
|
|
11364
|
+
* agents: [
|
|
11365
|
+
* {
|
|
11366
|
+
* id: 'researcher',
|
|
11367
|
+
* name: 'Researcher',
|
|
11368
|
+
* description: 'Finds and verifies information',
|
|
11369
|
+
* instructions: 'Research topics thoroughly...',
|
|
11370
|
+
* },
|
|
11371
|
+
* {
|
|
11372
|
+
* id: 'writer',
|
|
11373
|
+
* name: 'Writer',
|
|
11374
|
+
* description: 'Creates engaging content',
|
|
11375
|
+
* instructions: 'Write clear, engaging content...',
|
|
11376
|
+
* },
|
|
11377
|
+
* {
|
|
11378
|
+
* id: 'editor',
|
|
11379
|
+
* name: 'Editor',
|
|
11380
|
+
* description: 'Reviews and improves content',
|
|
11381
|
+
* instructions: 'Review for clarity and accuracy...',
|
|
11382
|
+
* }
|
|
11383
|
+
* ],
|
|
11384
|
+
* router: {
|
|
11385
|
+
* model: 'gpt-4o',
|
|
11386
|
+
* confidenceThreshold: 0.7
|
|
11387
|
+
* }
|
|
11388
|
+
* });
|
|
11389
|
+
*
|
|
11390
|
+
* const result = await network.execute({
|
|
11391
|
+
* message: 'Write an article about quantum computing'
|
|
11392
|
+
* });
|
|
11393
|
+
* ```
|
|
11394
|
+
*
|
|
11395
|
+
* @see {@link AgentNetworkConfig} for configuration options
|
|
11396
|
+
* @see {@link AgentNetwork} for network methods
|
|
11397
|
+
* @since 8.38.0
|
|
11398
|
+
*/
|
|
11399
|
+
async createNetwork(config) {
|
|
11400
|
+
const { AgentNetwork } = await import("./agent/agentNetwork.js");
|
|
11401
|
+
logger.debug("[NeuroLink] Creating agent network", {
|
|
11402
|
+
name: config.name,
|
|
11403
|
+
agentCount: config.agents.length,
|
|
11404
|
+
workflowCount: config.workflows?.length || 0,
|
|
11405
|
+
toolCount: config.tools?.length || 0,
|
|
11406
|
+
});
|
|
11407
|
+
return new AgentNetwork(config, this);
|
|
11408
|
+
}
|
|
11409
|
+
/**
|
|
11410
|
+
* Execute an agent network with the given input.
|
|
11411
|
+
*
|
|
11412
|
+
* @param network - The agent network to execute
|
|
11413
|
+
* @param input - Execution input (message and context)
|
|
11414
|
+
* @param options - Optional execution options
|
|
11415
|
+
* @returns Network execution result with content, trace, and usage
|
|
11416
|
+
*
|
|
11417
|
+
* @see {@link NetworkExecutionInput} for input options
|
|
11418
|
+
* @see {@link NetworkExecutionResult} for result structure
|
|
11419
|
+
* @since 8.38.0
|
|
11420
|
+
*/
|
|
11421
|
+
async executeNetwork(network, input, options) {
|
|
11422
|
+
logger.debug("[NeuroLink] Executing agent network", {
|
|
11423
|
+
networkId: network.id,
|
|
11424
|
+
networkName: network.name,
|
|
11425
|
+
hasContext: !!input.context,
|
|
11426
|
+
});
|
|
11427
|
+
return network.execute(input, options);
|
|
11428
|
+
}
|
|
11429
|
+
/**
|
|
11430
|
+
* Stream agent network execution with real-time events.
|
|
11431
|
+
*
|
|
11432
|
+
* @param network - The agent network to stream
|
|
11433
|
+
* @param input - Execution input (message and context)
|
|
11434
|
+
* @param options - Optional execution options
|
|
11435
|
+
* @returns Async iterable of network stream chunks
|
|
11436
|
+
*
|
|
11437
|
+
* @see {@link NetworkStreamChunk} for chunk types
|
|
11438
|
+
* @since 8.38.0
|
|
11439
|
+
*/
|
|
11440
|
+
async *streamNetwork(network, input, options) {
|
|
11441
|
+
logger.debug("[NeuroLink] Streaming agent network", {
|
|
11442
|
+
networkId: network.id,
|
|
11443
|
+
networkName: network.name,
|
|
11444
|
+
hasContext: !!input.context,
|
|
11445
|
+
});
|
|
11446
|
+
yield* network.stream(input, options);
|
|
11447
|
+
}
|
|
11448
|
+
// ============================================================================
|
|
11449
|
+
// ADVANCED ORCHESTRATION METHODS
|
|
11450
|
+
// ============================================================================
|
|
11451
|
+
/**
|
|
11452
|
+
* Create a NetworkOrchestrator for managing multiple agent networks.
|
|
11453
|
+
*
|
|
11454
|
+
* @param config - Orchestrator configuration options
|
|
11455
|
+
* @returns A new NetworkOrchestrator instance
|
|
11456
|
+
* @since 8.38.0
|
|
11457
|
+
*/
|
|
11458
|
+
async createOrchestrator(config) {
|
|
11459
|
+
const { NetworkOrchestrator } = await import("./agent/orchestration/index.js");
|
|
11460
|
+
logger.debug("[NeuroLink] Creating network orchestrator", {
|
|
11461
|
+
maxConcurrentExecutions: config?.maxConcurrentExecutions,
|
|
11462
|
+
defaultMode: config?.defaultMode,
|
|
11463
|
+
});
|
|
11464
|
+
return new NetworkOrchestrator(this, config);
|
|
11465
|
+
}
|
|
11466
|
+
/**
|
|
11467
|
+
* Create an AgentCoordinator for managing agent coordination strategies.
|
|
11468
|
+
*
|
|
11469
|
+
* @param config - Coordinator configuration options
|
|
11470
|
+
* @returns A new AgentCoordinator instance
|
|
11471
|
+
* @since 8.38.0
|
|
11472
|
+
*/
|
|
11473
|
+
async createCoordinator(config) {
|
|
11474
|
+
const { AgentCoordinator } = await import("./agent/coordination/index.js");
|
|
11475
|
+
logger.debug("[NeuroLink] Creating agent coordinator", {
|
|
11476
|
+
strategy: config?.strategy,
|
|
11477
|
+
maxConcurrency: config?.maxConcurrency,
|
|
11478
|
+
});
|
|
11479
|
+
return new AgentCoordinator(config);
|
|
11480
|
+
}
|
|
11481
|
+
/**
|
|
11482
|
+
* Create a MessageBus for inter-agent communication.
|
|
11483
|
+
*
|
|
11484
|
+
* @param config - Message bus configuration options
|
|
11485
|
+
* @returns A new MessageBus instance
|
|
11486
|
+
* @since 8.38.0
|
|
11487
|
+
*/
|
|
11488
|
+
async createMessageBus(config) {
|
|
11489
|
+
const { MessageBus } = await import("./agent/communication/index.js");
|
|
11490
|
+
logger.debug("[NeuroLink] Creating message bus", {
|
|
11491
|
+
maxHistorySize: config?.maxHistorySize,
|
|
11492
|
+
});
|
|
11493
|
+
return new MessageBus(config);
|
|
11494
|
+
}
|
|
11219
11495
|
/**
|
|
11220
11496
|
* Dispose of all resources and cleanup connections
|
|
11221
11497
|
* Call this method when done using the NeuroLink instance to prevent resource leaks
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* const maxSize = SIZE_LIMITS.IMAGE_MAX_MB; // 10
|
|
27
27
|
* ```
|
|
28
28
|
*/
|
|
29
|
-
export { ARCHIVE_MIME_TYPES, AUDIO_MIME_TYPES, DATA_MIME_TYPES, DOCUMENT_MIME_TYPES, EXTENSION_MIME_MAP, getMimeTypeForExtension, IMAGE_MIME_TYPES, MIME_TYPES, SOURCE_CODE_MIME_TYPES, TEXT_MIME_TYPES, VIDEO_MIME_TYPES, } from "./
|
|
30
|
-
export { ADA_EXTENSIONS, AI_VISION_EXTENSIONS, ARCHIVE_EXTENSIONS, ASSEMBLY_EXTENSIONS, AUDIO_EXTENSIONS, C_EXTENSIONS, CLOJURE_EXTENSIONS, COBOL_EXTENSIONS, CONFIG_EXTENSIONS, CPP_EXTENSIONS, CRYSTAL_EXTENSIONS, CSHARP_EXTENSIONS, CSS_EXTENSIONS, CSV_EXTENSIONS, D_EXTENSIONS, DART_EXTENSIONS, DATA_EXTENSIONS, DATABASE_EXTENSIONS, DESIGN_EXTENSIONS, DOCKERFILE_EXTENSIONS, DOCUMENT_EXTENSIONS, EJS_EXTENSIONS, ELIXIR_EXTENSIONS, ERLANG_EXTENSIONS, EXCEL_EXTENSIONS, EXECUTABLE_EXTENSIONS, FILE_EXTENSIONS, FORTRAN_EXTENSIONS, FSHARP_EXTENSIONS, GO_EXTENSIONS, GROOVY_EXTENSIONS, HANDLEBARS_EXTENSIONS, HASKELL_EXTENSIONS, HTML_EXTENSIONS, IMAGE_EXTENSIONS, JAVA_EXTENSIONS, JAVASCRIPT_EXTENSIONS, JSON_EXTENSIONS, JULIA_EXTENSIONS, KOTLIN_EXTENSIONS, LESS_EXTENSIONS, LISP_EXTENSIONS, LUA_EXTENSIONS, MAKEFILE_EXTENSIONS, MARKDOWN_EXTENSIONS, NIM_EXTENSIONS, OBJECTIVE_C_EXTENSIONS, OCAML_EXTENSIONS, OPENDOCUMENT_EXTENSIONS, PASCAL_EXTENSIONS, PDF_EXTENSIONS, PERL_EXTENSIONS, PHP_EXTENSIONS, POWERPOINT_EXTENSIONS, POWERSHELL_EXTENSIONS, PUG_EXTENSIONS, PYTHON_EXTENSIONS, R_EXTENSIONS, RTF_EXTENSIONS, RUBY_EXTENSIONS, RUST_EXTENSIONS, SCALA_EXTENSIONS, SCHEME_EXTENSIONS, SCSS_EXTENSIONS, SHELL_EXTENSIONS, SOURCE_CODE_EXTENSIONS, SQL_EXTENSIONS, STYLUS_EXTENSIONS, SVELTE_EXTENSIONS, SWIFT_EXTENSIONS, TEXT_EXTENSIONS, TYPESCRIPT_EXTENSIONS, V_EXTENSIONS, VIDEO_EXTENSIONS, VUE_EXTENSIONS, WORD_EXTENSIONS, XML_EXTENSIONS, YAML_EXTENSIONS, ZIG_EXTENSIONS, } from "./
|
|
29
|
+
export { ARCHIVE_MIME_TYPES, AUDIO_MIME_TYPES, DATA_MIME_TYPES, DOCUMENT_MIME_TYPES, EXTENSION_MIME_MAP, getMimeTypeForExtension, IMAGE_MIME_TYPES, MIME_TYPES, SOURCE_CODE_MIME_TYPES, TEXT_MIME_TYPES, VIDEO_MIME_TYPES, } from "./mimeConstants.js";
|
|
30
|
+
export { ADA_EXTENSIONS, AI_VISION_EXTENSIONS, ARCHIVE_EXTENSIONS, ASSEMBLY_EXTENSIONS, AUDIO_EXTENSIONS, C_EXTENSIONS, CLOJURE_EXTENSIONS, COBOL_EXTENSIONS, CONFIG_EXTENSIONS, CPP_EXTENSIONS, CRYSTAL_EXTENSIONS, CSHARP_EXTENSIONS, CSS_EXTENSIONS, CSV_EXTENSIONS, D_EXTENSIONS, DART_EXTENSIONS, DATA_EXTENSIONS, DATABASE_EXTENSIONS, DESIGN_EXTENSIONS, DOCKERFILE_EXTENSIONS, DOCUMENT_EXTENSIONS, EJS_EXTENSIONS, ELIXIR_EXTENSIONS, ERLANG_EXTENSIONS, EXCEL_EXTENSIONS, EXECUTABLE_EXTENSIONS, FILE_EXTENSIONS, FORTRAN_EXTENSIONS, FSHARP_EXTENSIONS, GO_EXTENSIONS, GROOVY_EXTENSIONS, HANDLEBARS_EXTENSIONS, HASKELL_EXTENSIONS, HTML_EXTENSIONS, IMAGE_EXTENSIONS, JAVA_EXTENSIONS, JAVASCRIPT_EXTENSIONS, JSON_EXTENSIONS, JULIA_EXTENSIONS, KOTLIN_EXTENSIONS, LESS_EXTENSIONS, LISP_EXTENSIONS, LUA_EXTENSIONS, MAKEFILE_EXTENSIONS, MARKDOWN_EXTENSIONS, NIM_EXTENSIONS, OBJECTIVE_C_EXTENSIONS, OCAML_EXTENSIONS, OPENDOCUMENT_EXTENSIONS, PASCAL_EXTENSIONS, PDF_EXTENSIONS, PERL_EXTENSIONS, PHP_EXTENSIONS, POWERPOINT_EXTENSIONS, POWERSHELL_EXTENSIONS, PUG_EXTENSIONS, PYTHON_EXTENSIONS, R_EXTENSIONS, RTF_EXTENSIONS, RUBY_EXTENSIONS, RUST_EXTENSIONS, SCALA_EXTENSIONS, SCHEME_EXTENSIONS, SCSS_EXTENSIONS, SHELL_EXTENSIONS, SOURCE_CODE_EXTENSIONS, SQL_EXTENSIONS, STYLUS_EXTENSIONS, SVELTE_EXTENSIONS, SWIFT_EXTENSIONS, TEXT_EXTENSIONS, TYPESCRIPT_EXTENSIONS, V_EXTENSIONS, VIDEO_EXTENSIONS, VUE_EXTENSIONS, WORD_EXTENSIONS, XML_EXTENSIONS, YAML_EXTENSIONS, ZIG_EXTENSIONS, } from "./fileExtensions.js";
|
|
31
31
|
export { detectLanguageFromFilename, EXACT_FILENAME_MAP, getLanguageIdentifier, getSupportedExtensions, getSupportedFilenames, isSourceCodeFile, LANGUAGE_MAP, } from "./languageMap.js";
|
|
32
32
|
export { ARCHIVE_LIMITS, bytesToMB, formatBytes, getSizeLimitForType, isWithinSizeLimit, mbToBytes, PROCESSING_LIMITS, SIZE_LIMITS, SIZE_LIMITS_BYTES, SIZE_LIMITS_MB, validateFileSize, YAML_LIMITS, } from "./sizeLimits.js";
|
|
@@ -36,7 +36,7 @@ EXTENSION_MIME_MAP, getMimeTypeForExtension,
|
|
|
36
36
|
IMAGE_MIME_TYPES,
|
|
37
37
|
// Types
|
|
38
38
|
// Combined MIME types
|
|
39
|
-
MIME_TYPES, SOURCE_CODE_MIME_TYPES, TEXT_MIME_TYPES, VIDEO_MIME_TYPES, } from "./
|
|
39
|
+
MIME_TYPES, SOURCE_CODE_MIME_TYPES, TEXT_MIME_TYPES, VIDEO_MIME_TYPES, } from "./mimeConstants.js";
|
|
40
40
|
// =============================================================================
|
|
41
41
|
// FILE EXTENSIONS
|
|
42
42
|
// =============================================================================
|
|
@@ -66,7 +66,7 @@ JSON_EXTENSIONS, JULIA_EXTENSIONS, KOTLIN_EXTENSIONS, LESS_EXTENSIONS, LISP_EXTE
|
|
|
66
66
|
// Text extensions
|
|
67
67
|
TEXT_EXTENSIONS, TYPESCRIPT_EXTENSIONS, V_EXTENSIONS,
|
|
68
68
|
// Multimedia extensions
|
|
69
|
-
VIDEO_EXTENSIONS, VUE_EXTENSIONS, WORD_EXTENSIONS, XML_EXTENSIONS, YAML_EXTENSIONS, ZIG_EXTENSIONS, } from "./
|
|
69
|
+
VIDEO_EXTENSIONS, VUE_EXTENSIONS, WORD_EXTENSIONS, XML_EXTENSIONS, YAML_EXTENSIONS, ZIG_EXTENSIONS, } from "./fileExtensions.js";
|
|
70
70
|
// =============================================================================
|
|
71
71
|
// LANGUAGE DETECTION
|
|
72
72
|
// =============================================================================
|
package/dist/processors/index.js
CHANGED
|
@@ -122,3 +122,11 @@ export { getProcessorForFile, getSupportedFileTypes, isFileTypeSupported, proces
|
|
|
122
122
|
// CLI HELPERS
|
|
123
123
|
// =============================================================================
|
|
124
124
|
export { detectMimeType, fileExists, getCliUsage, getFileExtension, getSupportedFileTypes as getCliSupportedFileTypes, listSupportedFileTypes, loadFileFromPath, processFileFromPath, } from "./cli/index.js";
|
|
125
|
+
// =============================================================================
|
|
126
|
+
// STANDALONE SAFETY UTILITIES (extracted from the former I/O processor system)
|
|
127
|
+
// =============================================================================
|
|
128
|
+
// PII detection, response validation, and tripwire evaluation are now
|
|
129
|
+
// standalone utilities in src/lib/utils/ and wired directly into
|
|
130
|
+
// generate() and stream() via native options (piiDetection, responseValidation,
|
|
131
|
+
// inputValidation). See src/lib/utils/piiDetector.ts, responseValidator.ts,
|
|
132
|
+
// and tripwireEvaluator.ts.
|
|
@@ -10,7 +10,7 @@ import { composeAbortSignals, createTimeoutController, TimeoutError, } from "../
|
|
|
10
10
|
import { withTimeout } from "../utils/async/index.js";
|
|
11
11
|
import { estimateTokens } from "../utils/tokenEstimation.js";
|
|
12
12
|
import { transformToolExecutions } from "../utils/transformationUtils.js";
|
|
13
|
-
import { buildGeminiResponseSchema, buildNativeConfig, buildNativeToolDeclarations, collectStreamChunks, collectStreamChunksIncremental, computeMaxSteps, createTextChannel, buildUserPartsWithMultimodal, executeNativeToolCalls, extractTextFromParts, extractThoughtSignature, handleMaxStepsTermination, prependConversationMessages, pushModelResponseToHistory, } from "./googleNativeGemini3.js";
|
|
13
|
+
import { buildGeminiResponseSchema, buildNativeConfig, buildNativeToolDeclarations, collectStreamChunks, collectStreamChunksIncremental, computeMaxSteps, createTextChannel, buildUserPartsWithMultimodal, executeNativeToolCalls, extractTextFromParts, extractThoughtSignature, handleMaxStepsTermination, prependConversationMessages, pushModelResponseToHistory, DedupExecuteMap, } from "./googleNativeGemini3.js";
|
|
14
14
|
import { createProxyFetch } from "../proxy/proxyFetch.js";
|
|
15
15
|
// Google AI Live API types now imported from ../types/providerSpecific.js
|
|
16
16
|
// Import proper types for multimodal message handling
|
|
@@ -521,7 +521,7 @@ export class GoogleAIStudioProvider extends BaseProvider {
|
|
|
521
521
|
});
|
|
522
522
|
// Convert tools
|
|
523
523
|
let toolsConfig;
|
|
524
|
-
let executeMap = new
|
|
524
|
+
let executeMap = new DedupExecuteMap();
|
|
525
525
|
let originalNameMap = new Map();
|
|
526
526
|
if (options.tools &&
|
|
527
527
|
Object.keys(options.tools).length > 0 &&
|
|
@@ -808,7 +808,7 @@ export class GoogleAIStudioProvider extends BaseProvider {
|
|
|
808
808
|
});
|
|
809
809
|
// Convert tools (a0269210: trust options.tools — already merged + filtered upstream)
|
|
810
810
|
let toolsConfig;
|
|
811
|
-
let executeMap = new
|
|
811
|
+
let executeMap = new DedupExecuteMap();
|
|
812
812
|
let originalNameMap = new Map();
|
|
813
813
|
const shouldUseTools = !options.disableTools;
|
|
814
814
|
if (shouldUseTools) {
|
|
@@ -10,6 +10,24 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import type { GenerateStopReason, ThinkingConfig, ChatMessage, CollectedChunkResult, MinimalChatMessage, NativeFunctionCall, NativeFunctionResponse, NativeToolDeclarationsResult, NativeToolsConfig, TextChannel, VertexNativePart, GeminiMultimodalInput } from "../types/index.js";
|
|
12
12
|
import type { Tool } from "../types/index.js";
|
|
13
|
+
/**
|
|
14
|
+
* A per-turn tool execute map that deduplicates identical tool calls.
|
|
15
|
+
*
|
|
16
|
+
* Gemini occasionally re-emits a tool call with identical arguments across
|
|
17
|
+
* agentic steps even though the prior result is already in the conversation
|
|
18
|
+
* history (BZ-3327). Re-executing produces duplicate side effects and
|
|
19
|
+
* duplicate reports for the user, plus wasted tokens. This map caches the
|
|
20
|
+
* result of each {tool name + args} executed within the turn and returns it
|
|
21
|
+
* for any identical re-request instead of running the tool again.
|
|
22
|
+
*
|
|
23
|
+
* Providers build a fresh executeMap per request, so the cache scope is
|
|
24
|
+
* exactly one turn. Only `.get()` is overridden (the sole access path used by
|
|
25
|
+
* the native agentic loops), so iteration still yields the raw executors.
|
|
26
|
+
*/
|
|
27
|
+
export declare class DedupExecuteMap extends Map<string, Tool["execute"]> {
|
|
28
|
+
private readonly resultCache;
|
|
29
|
+
get(name: string): Tool["execute"] | undefined;
|
|
30
|
+
}
|
|
13
31
|
export declare function sanitizeForGoogleFunctionName(name: string): string;
|
|
14
32
|
/**
|
|
15
33
|
* Resolve a sanitized Gemini tool name to one that is both unique within
|
|
@@ -17,6 +17,52 @@ import { convertZodToJsonSchema, ensureNestedSchemaTypes, inlineJsonSchema, isZo
|
|
|
17
17
|
import { createNativeThinkingConfig } from "../utils/thinkingConfig.js";
|
|
18
18
|
import { jsonSchema as aiJsonSchema, tool as createAISDKTool, } from "../utils/tool.js";
|
|
19
19
|
// ── Functions ──
|
|
20
|
+
/** Stable, key-order-independent serialization of tool args for the dedup key. */
|
|
21
|
+
function stableStringifyForDedup(value) {
|
|
22
|
+
return JSON.stringify(value, (_key, val) => val && typeof val === "object" && !Array.isArray(val)
|
|
23
|
+
? Object.keys(val)
|
|
24
|
+
.sort()
|
|
25
|
+
.reduce((acc, key) => {
|
|
26
|
+
acc[key] = val[key];
|
|
27
|
+
return acc;
|
|
28
|
+
}, {})
|
|
29
|
+
: val);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* A per-turn tool execute map that deduplicates identical tool calls.
|
|
33
|
+
*
|
|
34
|
+
* Gemini occasionally re-emits a tool call with identical arguments across
|
|
35
|
+
* agentic steps even though the prior result is already in the conversation
|
|
36
|
+
* history (BZ-3327). Re-executing produces duplicate side effects and
|
|
37
|
+
* duplicate reports for the user, plus wasted tokens. This map caches the
|
|
38
|
+
* result of each {tool name + args} executed within the turn and returns it
|
|
39
|
+
* for any identical re-request instead of running the tool again.
|
|
40
|
+
*
|
|
41
|
+
* Providers build a fresh executeMap per request, so the cache scope is
|
|
42
|
+
* exactly one turn. Only `.get()` is overridden (the sole access path used by
|
|
43
|
+
* the native agentic loops), so iteration still yields the raw executors.
|
|
44
|
+
*/
|
|
45
|
+
export class DedupExecuteMap extends Map {
|
|
46
|
+
resultCache = new Map();
|
|
47
|
+
get(name) {
|
|
48
|
+
const execute = super.get(name);
|
|
49
|
+
if (!execute) {
|
|
50
|
+
return execute;
|
|
51
|
+
}
|
|
52
|
+
const resultCache = this.resultCache;
|
|
53
|
+
const wrapped = async (args, options) => {
|
|
54
|
+
const key = `${name}::${stableStringifyForDedup(args)}`;
|
|
55
|
+
if (resultCache.has(key)) {
|
|
56
|
+
logger.warn(`[DedupExecuteMap] Tool "${name}" re-requested with identical arguments in the same turn — reusing the previous result instead of re-executing.`);
|
|
57
|
+
return resultCache.get(key);
|
|
58
|
+
}
|
|
59
|
+
const result = await execute(args, options);
|
|
60
|
+
resultCache.set(key, result);
|
|
61
|
+
return result;
|
|
62
|
+
};
|
|
63
|
+
return wrapped;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
20
66
|
/**
|
|
21
67
|
* Google's `function_declarations[].name` validator regex.
|
|
22
68
|
*
|
|
@@ -323,7 +369,7 @@ export function normalizeToolsForJsonSchemaProvider(tools) {
|
|
|
323
369
|
*/
|
|
324
370
|
export function buildNativeToolDeclarations(tools) {
|
|
325
371
|
const functionDeclarations = [];
|
|
326
|
-
const executeMap = new
|
|
372
|
+
const executeMap = new DedupExecuteMap();
|
|
327
373
|
const skippedTools = [];
|
|
328
374
|
const renamedTools = [];
|
|
329
375
|
// Disambiguate distinct originals that collapse onto the same sanitized
|
|
@@ -24,7 +24,7 @@ import { convertZodToJsonSchema, inlineJsonSchema, ensureNestedSchemaTypes, } fr
|
|
|
24
24
|
import { createNativeThinkingConfig } from "../utils/thinkingConfig.js";
|
|
25
25
|
import { TimeoutError, raceWithAbort, withTimeout, } from "../utils/async/index.js";
|
|
26
26
|
import { parseTimeout } from "../utils/timeout.js";
|
|
27
|
-
import { appendStepText, buildAbortedTurnMessage, buildContextCapMessage, buildToolLoopCapMessage, buildTurnStalledMessage, buildTurnTimeoutMessage, buildWrapupNudgeText, createContextGuard, createTextChannel, createTurnClock, extractThoughtSignature, isAbortError, mapGeminiFinishReason, prependConversationMessages, resolveTurnStopReason, } from "./googleNativeGemini3.js";
|
|
27
|
+
import { appendStepText, buildAbortedTurnMessage, buildContextCapMessage, buildToolLoopCapMessage, buildTurnStalledMessage, buildTurnTimeoutMessage, buildWrapupNudgeText, createContextGuard, createTextChannel, createTurnClock, extractThoughtSignature, isAbortError, mapGeminiFinishReason, prependConversationMessages, resolveTurnStopReason, DedupExecuteMap, } from "./googleNativeGemini3.js";
|
|
28
28
|
import { getContextWindowSize } from "../constants/contextWindows.js";
|
|
29
29
|
import { ATTR, LANGFUSE_ATTR, spanJsonAttribute, tracers, withClientSpan, withClientStreamSpan, withSpan, } from "../telemetry/index.js";
|
|
30
30
|
import { SpanKind, SpanStatusCode, context as otelContext, trace as otelTrace, } from "@opentelemetry/api";
|
|
@@ -1138,7 +1138,7 @@ export class GoogleVertexProvider extends BaseProvider {
|
|
|
1138
1138
|
});
|
|
1139
1139
|
// Convert Vercel AI SDK tools to @google/genai FunctionDeclarations
|
|
1140
1140
|
let tools;
|
|
1141
|
-
const executeMap = new
|
|
1141
|
+
const executeMap = new DedupExecuteMap();
|
|
1142
1142
|
if (options.tools &&
|
|
1143
1143
|
Object.keys(options.tools).length > 0 &&
|
|
1144
1144
|
!options.disableTools) {
|
|
@@ -2085,7 +2085,7 @@ export class GoogleVertexProvider extends BaseProvider {
|
|
|
2085
2085
|
const combinedTools = !options.disableTools ? options.tools || {} : {};
|
|
2086
2086
|
// Convert Vercel AI SDK tools to @google/genai FunctionDeclarations
|
|
2087
2087
|
let tools;
|
|
2088
|
-
const executeMap = new
|
|
2088
|
+
const executeMap = new DedupExecuteMap();
|
|
2089
2089
|
if (Object.keys(combinedTools).length > 0) {
|
|
2090
2090
|
const functionDeclarations = [];
|
|
2091
2091
|
for (const [name, tool] of Object.entries(combinedTools)) {
|
|
@@ -3116,7 +3116,7 @@ export class GoogleVertexProvider extends BaseProvider {
|
|
|
3116
3116
|
: userContentParts);
|
|
3117
3117
|
// Convert tools to Anthropic format if present
|
|
3118
3118
|
let tools;
|
|
3119
|
-
const executeMap = new
|
|
3119
|
+
const executeMap = new DedupExecuteMap();
|
|
3120
3120
|
if (options.tools &&
|
|
3121
3121
|
Object.keys(options.tools).length > 0 &&
|
|
3122
3122
|
!options.disableTools) {
|
|
@@ -4425,7 +4425,7 @@ export class GoogleVertexProvider extends BaseProvider {
|
|
|
4425
4425
|
: userContentParts);
|
|
4426
4426
|
// Convert tools to Anthropic format if present
|
|
4427
4427
|
let tools;
|
|
4428
|
-
const executeMap = new
|
|
4428
|
+
const executeMap = new DedupExecuteMap();
|
|
4429
4429
|
const toolExecutions = [];
|
|
4430
4430
|
// Defensive guard: Vertex generate() bypasses BaseProvider.generate(), so
|
|
4431
4431
|
// disableTools must be checked here before native tool declarations are
|