@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/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [9.84.0](https://github.com/juspay/neurolink/compare/v9.83.0...v9.84.0) (2026-07-08)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
- **(agents):** add multi-agent network system with orchestration and message bus ([73c88dc](https://github.com/juspay/neurolink/commit/73c88dcf7185b01620947defd6e8763acd15d77b))
|
|
6
|
+
- **(safety):** add native PII detection and response validation to generate/stream ([db2b38f](https://github.com/juspay/neurolink/commit/db2b38fbb2210f0ef718e18cb60c30965594d1e8))
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- **(providers):** dedupe identical Gemini tool calls within a turn (BZ-3327) ([bfdb0a7](https://github.com/juspay/neurolink/commit/bfdb0a7c2c09d8c3fb2a1e1cbfa9e5fadcb86e5f))
|
|
11
|
+
- **(providers):** resolve engineering practice violations (Rules 6, 7, 8) ([664f0a3](https://github.com/juspay/neurolink/commit/664f0a3c45634172cfac5f287db74318a9e4a70c))
|
|
12
|
+
|
|
1
13
|
## [9.83.0](https://github.com/juspay/neurolink/compare/v9.82.0...v9.83.0) (2026-07-08)
|
|
2
14
|
|
|
3
15
|
### Features
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent - Core agent implementation for NeuroLink
|
|
3
|
+
*
|
|
4
|
+
* An Agent wraps a NeuroLink instance with specialized behavior, instructions,
|
|
5
|
+
* and tool restrictions. Agents can be composed into networks for multi-agent
|
|
6
|
+
* orchestration using the agents-as-tools pattern.
|
|
7
|
+
*/
|
|
8
|
+
import type { z } from "zod";
|
|
9
|
+
import type { NeuroLink } from "../neurolink.js";
|
|
10
|
+
import type { AgentDefinition, AgentExecutionOptions, AgentInput, AgentInstance, AgentResult, AgentStatus, AgentStreamChunk } from "../types/index.js";
|
|
11
|
+
/**
|
|
12
|
+
* Agent - Wraps a NeuroLink instance with specialized behavior
|
|
13
|
+
*
|
|
14
|
+
* Features:
|
|
15
|
+
* - Custom instructions and persona
|
|
16
|
+
* - Tool restrictions per agent (via toolFilter on generate/stream)
|
|
17
|
+
* - Input/output schema validation
|
|
18
|
+
* - Streaming support
|
|
19
|
+
* - Execution metrics tracking
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const agent = new Agent({
|
|
24
|
+
* id: 'researcher',
|
|
25
|
+
* name: 'Research Agent',
|
|
26
|
+
* description: 'Searches and analyzes information',
|
|
27
|
+
* instructions: 'You are a research assistant...',
|
|
28
|
+
* tools: ['websearchGrounding', 'readFile'],
|
|
29
|
+
* }, neurolink);
|
|
30
|
+
*
|
|
31
|
+
* const result = await agent.execute('Find information about quantum computing');
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare class Agent implements AgentInstance {
|
|
35
|
+
readonly id: string;
|
|
36
|
+
readonly name: string;
|
|
37
|
+
readonly description: string;
|
|
38
|
+
readonly instructions: string;
|
|
39
|
+
readonly provider?: string;
|
|
40
|
+
readonly model?: string;
|
|
41
|
+
readonly tools?: string[];
|
|
42
|
+
readonly inputSchema?: z.ZodSchema;
|
|
43
|
+
readonly outputSchema?: z.ZodSchema;
|
|
44
|
+
readonly maxSteps: number;
|
|
45
|
+
readonly temperature: number;
|
|
46
|
+
readonly canDelegate: boolean;
|
|
47
|
+
readonly metadata?: Record<string, unknown>;
|
|
48
|
+
private neurolink;
|
|
49
|
+
private emitter;
|
|
50
|
+
private executionCount;
|
|
51
|
+
private lastExecutionTime?;
|
|
52
|
+
private totalExecutionTime;
|
|
53
|
+
constructor(definition: AgentDefinition, neurolink: NeuroLink);
|
|
54
|
+
/**
|
|
55
|
+
* Execute the agent with given input
|
|
56
|
+
*
|
|
57
|
+
* @param input - Text input or structured data
|
|
58
|
+
* @param options - Execution options
|
|
59
|
+
* @returns Agent result with content and metadata
|
|
60
|
+
*/
|
|
61
|
+
execute(input: AgentInput, options?: AgentExecutionOptions): Promise<AgentResult>;
|
|
62
|
+
/**
|
|
63
|
+
* Stream execution results
|
|
64
|
+
*
|
|
65
|
+
* @param input - Text input or structured data
|
|
66
|
+
* @param options - Execution options
|
|
67
|
+
* @yields Agent stream chunks
|
|
68
|
+
*/
|
|
69
|
+
stream(input: AgentInput, options?: AgentExecutionOptions): AsyncIterable<AgentStreamChunk>;
|
|
70
|
+
/**
|
|
71
|
+
* Get agent status
|
|
72
|
+
*/
|
|
73
|
+
getStatus(): AgentStatus;
|
|
74
|
+
/**
|
|
75
|
+
* Get average execution time
|
|
76
|
+
*/
|
|
77
|
+
getAverageExecutionTime(): number;
|
|
78
|
+
/**
|
|
79
|
+
* Subscribe to agent events
|
|
80
|
+
*/
|
|
81
|
+
on(event: string, handler: (...args: unknown[]) => void): void;
|
|
82
|
+
/**
|
|
83
|
+
* Unsubscribe from agent events
|
|
84
|
+
*/
|
|
85
|
+
off(event: string, handler: (...args: unknown[]) => void): void;
|
|
86
|
+
/**
|
|
87
|
+
* Build prompt from input and context
|
|
88
|
+
*/
|
|
89
|
+
private buildPrompt;
|
|
90
|
+
/**
|
|
91
|
+
* Build generation options for NeuroLink.generate()
|
|
92
|
+
*
|
|
93
|
+
* Uses toolFilter to delegate tool restriction to BaseProvider.applyToolFiltering()
|
|
94
|
+
* rather than pre-filtering tools manually.
|
|
95
|
+
*/
|
|
96
|
+
private buildGenerateOptions;
|
|
97
|
+
/**
|
|
98
|
+
* Build stream options for NeuroLink.stream()
|
|
99
|
+
*
|
|
100
|
+
* Uses toolFilter to delegate tool restriction to BaseProvider.applyToolFiltering()
|
|
101
|
+
* rather than pre-filtering tools manually.
|
|
102
|
+
*/
|
|
103
|
+
private buildStreamOptions;
|
|
104
|
+
}
|
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent - Core agent implementation for NeuroLink
|
|
3
|
+
*
|
|
4
|
+
* An Agent wraps a NeuroLink instance with specialized behavior, instructions,
|
|
5
|
+
* and tool restrictions. Agents can be composed into networks for multi-agent
|
|
6
|
+
* orchestration using the agents-as-tools pattern.
|
|
7
|
+
*/
|
|
8
|
+
import { EventEmitter } from "events";
|
|
9
|
+
import { ErrorFactory } from "../utils/errorHandling.js";
|
|
10
|
+
import { logger } from "../utils/logger.js";
|
|
11
|
+
/**
|
|
12
|
+
* Agent - Wraps a NeuroLink instance with specialized behavior
|
|
13
|
+
*
|
|
14
|
+
* Features:
|
|
15
|
+
* - Custom instructions and persona
|
|
16
|
+
* - Tool restrictions per agent (via toolFilter on generate/stream)
|
|
17
|
+
* - Input/output schema validation
|
|
18
|
+
* - Streaming support
|
|
19
|
+
* - Execution metrics tracking
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const agent = new Agent({
|
|
24
|
+
* id: 'researcher',
|
|
25
|
+
* name: 'Research Agent',
|
|
26
|
+
* description: 'Searches and analyzes information',
|
|
27
|
+
* instructions: 'You are a research assistant...',
|
|
28
|
+
* tools: ['websearchGrounding', 'readFile'],
|
|
29
|
+
* }, neurolink);
|
|
30
|
+
*
|
|
31
|
+
* const result = await agent.execute('Find information about quantum computing');
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export class Agent {
|
|
35
|
+
id;
|
|
36
|
+
name;
|
|
37
|
+
description;
|
|
38
|
+
instructions;
|
|
39
|
+
provider;
|
|
40
|
+
model;
|
|
41
|
+
tools;
|
|
42
|
+
inputSchema;
|
|
43
|
+
outputSchema;
|
|
44
|
+
maxSteps;
|
|
45
|
+
temperature;
|
|
46
|
+
canDelegate;
|
|
47
|
+
metadata;
|
|
48
|
+
neurolink;
|
|
49
|
+
emitter;
|
|
50
|
+
executionCount = 0;
|
|
51
|
+
lastExecutionTime;
|
|
52
|
+
totalExecutionTime = 0;
|
|
53
|
+
constructor(definition, neurolink) {
|
|
54
|
+
// Validate required fields
|
|
55
|
+
if (!definition.id || typeof definition.id !== "string") {
|
|
56
|
+
throw ErrorFactory.invalidConfiguration("AgentDefinition.id", "Agent definition must have a valid id");
|
|
57
|
+
}
|
|
58
|
+
if (!definition.name || typeof definition.name !== "string") {
|
|
59
|
+
throw ErrorFactory.invalidConfiguration("AgentDefinition.name", "Agent definition must have a valid name");
|
|
60
|
+
}
|
|
61
|
+
if (!definition.description || typeof definition.description !== "string") {
|
|
62
|
+
throw ErrorFactory.invalidConfiguration("AgentDefinition.description", "Agent definition must have a valid description");
|
|
63
|
+
}
|
|
64
|
+
if (!definition.instructions ||
|
|
65
|
+
typeof definition.instructions !== "string") {
|
|
66
|
+
throw ErrorFactory.invalidConfiguration("AgentDefinition.instructions", "Agent definition must have valid instructions");
|
|
67
|
+
}
|
|
68
|
+
this.id = definition.id;
|
|
69
|
+
this.name = definition.name;
|
|
70
|
+
this.description = definition.description;
|
|
71
|
+
this.instructions = definition.instructions;
|
|
72
|
+
this.provider = definition.provider;
|
|
73
|
+
this.model = definition.model;
|
|
74
|
+
this.tools = definition.tools;
|
|
75
|
+
this.inputSchema = definition.inputSchema;
|
|
76
|
+
this.outputSchema = definition.outputSchema;
|
|
77
|
+
this.maxSteps = definition.maxSteps ?? 10;
|
|
78
|
+
this.temperature = definition.temperature ?? 0.7;
|
|
79
|
+
this.canDelegate = definition.canDelegate ?? false;
|
|
80
|
+
this.metadata = definition.metadata;
|
|
81
|
+
this.neurolink = neurolink;
|
|
82
|
+
this.emitter = new EventEmitter();
|
|
83
|
+
logger.debug(`[Agent:${this.id}] Created agent: ${this.name}`, {
|
|
84
|
+
tools: this.tools?.length || 0,
|
|
85
|
+
maxSteps: this.maxSteps,
|
|
86
|
+
canDelegate: this.canDelegate,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Execute the agent with given input
|
|
91
|
+
*
|
|
92
|
+
* @param input - Text input or structured data
|
|
93
|
+
* @param options - Execution options
|
|
94
|
+
* @returns Agent result with content and metadata
|
|
95
|
+
*/
|
|
96
|
+
async execute(input, options) {
|
|
97
|
+
const startTime = Date.now();
|
|
98
|
+
this.executionCount++;
|
|
99
|
+
const traceId = options?.traceId ?? `agent-${this.id}-${Date.now()}`;
|
|
100
|
+
logger.debug(`[Agent:${this.id}] Starting execution`, {
|
|
101
|
+
traceId,
|
|
102
|
+
input: typeof input === "string" ? input.slice(0, 100) : "structured",
|
|
103
|
+
executionCount: this.executionCount,
|
|
104
|
+
});
|
|
105
|
+
this.emitter.emit("agent:start", {
|
|
106
|
+
agentId: this.id,
|
|
107
|
+
traceId,
|
|
108
|
+
timestamp: startTime,
|
|
109
|
+
});
|
|
110
|
+
try {
|
|
111
|
+
// Validate input if schema provided
|
|
112
|
+
if (this.inputSchema && typeof input !== "string") {
|
|
113
|
+
const validation = this.inputSchema.safeParse(input);
|
|
114
|
+
if (!validation.success) {
|
|
115
|
+
throw new Error(`Input validation failed: ${validation.error.message}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Build the prompt with agent context
|
|
119
|
+
const prompt = this.buildPrompt(input, options?.context);
|
|
120
|
+
// Build generation options
|
|
121
|
+
const generateOptions = this.buildGenerateOptions(prompt, options, traceId);
|
|
122
|
+
// Execute via NeuroLink
|
|
123
|
+
const result = await this.neurolink.generate(generateOptions);
|
|
124
|
+
const duration = Date.now() - startTime;
|
|
125
|
+
this.lastExecutionTime = duration;
|
|
126
|
+
this.totalExecutionTime += duration;
|
|
127
|
+
// Parse output if schema provided
|
|
128
|
+
let parsedOutput;
|
|
129
|
+
if (this.outputSchema && result.content) {
|
|
130
|
+
try {
|
|
131
|
+
const parsed = JSON.parse(result.content);
|
|
132
|
+
const validation = this.outputSchema.safeParse(parsed);
|
|
133
|
+
if (validation.success) {
|
|
134
|
+
parsedOutput = validation.data;
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
logger.warn(`[Agent:${this.id}] Output schema validation failed`, {
|
|
138
|
+
error: validation.error.message,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
logger.warn(`[Agent:${this.id}] Failed to parse output as JSON`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
logger.debug(`[Agent:${this.id}] Execution completed`, {
|
|
147
|
+
traceId,
|
|
148
|
+
duration,
|
|
149
|
+
contentLength: result.content?.length || 0,
|
|
150
|
+
toolsUsed: result.toolsUsed?.length || 0,
|
|
151
|
+
});
|
|
152
|
+
// Pass through toolExecutions, adding duration (not provided by generate())
|
|
153
|
+
const toolExecutions = result.toolExecutions?.map((te) => ({
|
|
154
|
+
name: te.name,
|
|
155
|
+
input: te.input,
|
|
156
|
+
output: te.output,
|
|
157
|
+
duration: 0,
|
|
158
|
+
}));
|
|
159
|
+
const agentResult = {
|
|
160
|
+
content: result.content || "",
|
|
161
|
+
object: parsedOutput,
|
|
162
|
+
usage: result.usage,
|
|
163
|
+
toolsUsed: result.toolsUsed,
|
|
164
|
+
toolExecutions,
|
|
165
|
+
duration,
|
|
166
|
+
status: "success",
|
|
167
|
+
agentId: this.id,
|
|
168
|
+
};
|
|
169
|
+
this.emitter.emit("agent:complete", {
|
|
170
|
+
agentId: this.id,
|
|
171
|
+
traceId,
|
|
172
|
+
duration,
|
|
173
|
+
result: agentResult,
|
|
174
|
+
});
|
|
175
|
+
return agentResult;
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
const duration = Date.now() - startTime;
|
|
179
|
+
this.lastExecutionTime = duration;
|
|
180
|
+
logger.error(`[Agent:${this.id}] Execution failed`, {
|
|
181
|
+
traceId,
|
|
182
|
+
error: error instanceof Error ? error.message : String(error),
|
|
183
|
+
duration,
|
|
184
|
+
});
|
|
185
|
+
this.emitter.emit("agent:error", {
|
|
186
|
+
agentId: this.id,
|
|
187
|
+
traceId,
|
|
188
|
+
error,
|
|
189
|
+
duration,
|
|
190
|
+
});
|
|
191
|
+
return {
|
|
192
|
+
content: "",
|
|
193
|
+
error: error instanceof Error ? error.message : String(error),
|
|
194
|
+
duration,
|
|
195
|
+
status: "error",
|
|
196
|
+
agentId: this.id,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Stream execution results
|
|
202
|
+
*
|
|
203
|
+
* @param input - Text input or structured data
|
|
204
|
+
* @param options - Execution options
|
|
205
|
+
* @yields Agent stream chunks
|
|
206
|
+
*/
|
|
207
|
+
async *stream(input, options) {
|
|
208
|
+
const startTime = Date.now();
|
|
209
|
+
const traceId = options?.traceId ?? `agent-${this.id}-${Date.now()}`;
|
|
210
|
+
this.emitter.emit("agent:start", {
|
|
211
|
+
agentId: this.id,
|
|
212
|
+
traceId,
|
|
213
|
+
timestamp: startTime,
|
|
214
|
+
});
|
|
215
|
+
yield {
|
|
216
|
+
type: "agent-start",
|
|
217
|
+
agentId: this.id,
|
|
218
|
+
timestamp: startTime,
|
|
219
|
+
traceId,
|
|
220
|
+
};
|
|
221
|
+
try {
|
|
222
|
+
// Validate input if schema provided
|
|
223
|
+
if (this.inputSchema && typeof input !== "string") {
|
|
224
|
+
const validation = this.inputSchema.safeParse(input);
|
|
225
|
+
if (!validation.success) {
|
|
226
|
+
throw new Error(`Input validation failed: ${validation.error.message}`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
const prompt = this.buildPrompt(input, options?.context);
|
|
230
|
+
const streamOptions = this.buildStreamOptions(prompt, options, traceId);
|
|
231
|
+
// Execute via NeuroLink
|
|
232
|
+
const streamResult = await this.neurolink.stream(streamOptions);
|
|
233
|
+
let fullContent = "";
|
|
234
|
+
for await (const chunk of streamResult.stream) {
|
|
235
|
+
// Handle different chunk types from the stream
|
|
236
|
+
if ("content" in chunk && typeof chunk.content === "string") {
|
|
237
|
+
fullContent += chunk.content;
|
|
238
|
+
yield {
|
|
239
|
+
type: "agent-text",
|
|
240
|
+
agentId: this.id,
|
|
241
|
+
content: chunk.content,
|
|
242
|
+
isPartial: true,
|
|
243
|
+
timestamp: Date.now(),
|
|
244
|
+
traceId,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
// Handle tool calls if present
|
|
248
|
+
if ("toolCall" in chunk && chunk.toolCall) {
|
|
249
|
+
const toolCall = chunk.toolCall;
|
|
250
|
+
yield {
|
|
251
|
+
type: "agent-tool-call",
|
|
252
|
+
agentId: this.id,
|
|
253
|
+
toolName: toolCall.toolName || "unknown",
|
|
254
|
+
args: toolCall.args,
|
|
255
|
+
toolCallId: toolCall.toolCallId || `tool-${Date.now()}`,
|
|
256
|
+
timestamp: Date.now(),
|
|
257
|
+
traceId,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
// Handle tool results if present
|
|
261
|
+
if ("toolResult" in chunk && chunk.toolResult) {
|
|
262
|
+
const toolResult = chunk.toolResult;
|
|
263
|
+
yield {
|
|
264
|
+
type: "agent-tool-result",
|
|
265
|
+
agentId: this.id,
|
|
266
|
+
toolName: toolResult.toolName || "unknown",
|
|
267
|
+
toolCallId: toolResult.toolCallId || `tool-${Date.now()}`,
|
|
268
|
+
result: toolResult.result,
|
|
269
|
+
success: toolResult.success ?? true,
|
|
270
|
+
timestamp: Date.now(),
|
|
271
|
+
traceId,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
const duration = Date.now() - startTime;
|
|
276
|
+
this.lastExecutionTime = duration;
|
|
277
|
+
this.executionCount++;
|
|
278
|
+
this.totalExecutionTime += duration;
|
|
279
|
+
this.emitter.emit("agent:complete", {
|
|
280
|
+
agentId: this.id,
|
|
281
|
+
traceId,
|
|
282
|
+
duration,
|
|
283
|
+
content: fullContent,
|
|
284
|
+
});
|
|
285
|
+
yield {
|
|
286
|
+
type: "agent-complete",
|
|
287
|
+
agentId: this.id,
|
|
288
|
+
content: fullContent,
|
|
289
|
+
usage: streamResult.usage,
|
|
290
|
+
duration,
|
|
291
|
+
timestamp: Date.now(),
|
|
292
|
+
traceId,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
catch (error) {
|
|
296
|
+
this.emitter.emit("agent:error", {
|
|
297
|
+
agentId: this.id,
|
|
298
|
+
traceId,
|
|
299
|
+
error,
|
|
300
|
+
});
|
|
301
|
+
yield {
|
|
302
|
+
type: "agent-error",
|
|
303
|
+
agentId: this.id,
|
|
304
|
+
error: error instanceof Error ? error.message : String(error),
|
|
305
|
+
timestamp: Date.now(),
|
|
306
|
+
traceId,
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Get agent status
|
|
312
|
+
*/
|
|
313
|
+
getStatus() {
|
|
314
|
+
return {
|
|
315
|
+
id: this.id,
|
|
316
|
+
name: this.name,
|
|
317
|
+
executionCount: this.executionCount,
|
|
318
|
+
lastExecutionTime: this.lastExecutionTime,
|
|
319
|
+
available: true,
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Get average execution time
|
|
324
|
+
*/
|
|
325
|
+
getAverageExecutionTime() {
|
|
326
|
+
if (this.executionCount === 0) {
|
|
327
|
+
return 0;
|
|
328
|
+
}
|
|
329
|
+
return this.totalExecutionTime / this.executionCount;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Subscribe to agent events
|
|
333
|
+
*/
|
|
334
|
+
on(event, handler) {
|
|
335
|
+
this.emitter.on(event, handler);
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Unsubscribe from agent events
|
|
339
|
+
*/
|
|
340
|
+
off(event, handler) {
|
|
341
|
+
this.emitter.off(event, handler);
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Build prompt from input and context
|
|
345
|
+
*/
|
|
346
|
+
buildPrompt(input, context) {
|
|
347
|
+
let prompt = typeof input === "string" ? input : JSON.stringify(input);
|
|
348
|
+
if (context && Object.keys(context).length > 0) {
|
|
349
|
+
prompt = `Context: ${JSON.stringify(context)}\n\nTask: ${prompt}`;
|
|
350
|
+
}
|
|
351
|
+
return prompt;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Build generation options for NeuroLink.generate()
|
|
355
|
+
*
|
|
356
|
+
* Uses toolFilter to delegate tool restriction to BaseProvider.applyToolFiltering()
|
|
357
|
+
* rather than pre-filtering tools manually.
|
|
358
|
+
*/
|
|
359
|
+
buildGenerateOptions(prompt, options, traceId) {
|
|
360
|
+
return {
|
|
361
|
+
input: { text: prompt },
|
|
362
|
+
provider: this.provider,
|
|
363
|
+
model: this.model,
|
|
364
|
+
temperature: this.temperature,
|
|
365
|
+
systemPrompt: this.instructions,
|
|
366
|
+
// toolFilter delegates to BaseProvider.applyToolFiltering() natively
|
|
367
|
+
...(this.tools && this.tools.length > 0 && { toolFilter: this.tools }),
|
|
368
|
+
maxSteps: options?.maxSteps ?? this.maxSteps,
|
|
369
|
+
requestId: traceId,
|
|
370
|
+
context: {
|
|
371
|
+
agentId: this.id,
|
|
372
|
+
agentName: this.name,
|
|
373
|
+
...options?.context,
|
|
374
|
+
},
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Build stream options for NeuroLink.stream()
|
|
379
|
+
*
|
|
380
|
+
* Uses toolFilter to delegate tool restriction to BaseProvider.applyToolFiltering()
|
|
381
|
+
* rather than pre-filtering tools manually.
|
|
382
|
+
*/
|
|
383
|
+
buildStreamOptions(prompt, options, traceId) {
|
|
384
|
+
return {
|
|
385
|
+
input: { text: prompt },
|
|
386
|
+
provider: this.provider,
|
|
387
|
+
model: this.model,
|
|
388
|
+
temperature: this.temperature,
|
|
389
|
+
systemPrompt: this.instructions,
|
|
390
|
+
// toolFilter delegates to BaseProvider.applyToolFiltering() natively
|
|
391
|
+
...(this.tools && this.tools.length > 0 && { toolFilter: this.tools }),
|
|
392
|
+
maxSteps: options?.maxSteps ?? this.maxSteps,
|
|
393
|
+
context: {
|
|
394
|
+
agentId: this.id,
|
|
395
|
+
agentName: this.name,
|
|
396
|
+
traceId,
|
|
397
|
+
...options?.context,
|
|
398
|
+
},
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentNetwork - Multi-Agent Orchestration for NeuroLink
|
|
3
|
+
*
|
|
4
|
+
* Uses the ai SDK's built-in tool loop: each agent is wrapped as an ai SDK
|
|
5
|
+
* tool, and the network's router is a single neurolink.generate() call with
|
|
6
|
+
* maxSteps. The SDK iterates automatically (tool call → execute → feed result
|
|
7
|
+
* → next call) until the model stops or maxSteps is reached.
|
|
8
|
+
*/
|
|
9
|
+
import type { NeuroLink } from "../neurolink.js";
|
|
10
|
+
import type { AgentNetworkConfig, NetworkExecutionInput, NetworkExecutionOptions, NetworkExecutionResult, NetworkStreamChunk, Primitive } from "../types/index.js";
|
|
11
|
+
import { Agent } from "./agent.js";
|
|
12
|
+
/**
|
|
13
|
+
* AgentNetwork - Multi-agent orchestration using the ai SDK tool loop
|
|
14
|
+
*
|
|
15
|
+
* Each agent in the network is registered as an ai SDK `tool()`. A single
|
|
16
|
+
* `neurolink.generate()` call with `maxSteps` acts as the router: the model
|
|
17
|
+
* picks which agent tool(s) to call, the SDK executes them and feeds results
|
|
18
|
+
* back, and the loop continues until the model emits `finishReason: "stop"` or
|
|
19
|
+
* maxSteps is exhausted.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const network = neurolink.createNetwork({
|
|
24
|
+
* name: 'Content Team',
|
|
25
|
+
* agents: [researchAgent, writerAgent, reviewerAgent],
|
|
26
|
+
* router: { model: 'gpt-4o' }
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* const result = await network.execute({
|
|
30
|
+
* message: 'Write an article about AI trends'
|
|
31
|
+
* });
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare class AgentNetwork {
|
|
35
|
+
readonly id: string;
|
|
36
|
+
readonly name: string;
|
|
37
|
+
readonly description?: string;
|
|
38
|
+
private neurolink;
|
|
39
|
+
private agents;
|
|
40
|
+
private workflows;
|
|
41
|
+
private primitives;
|
|
42
|
+
private emitter;
|
|
43
|
+
private config;
|
|
44
|
+
private toolsInitialized;
|
|
45
|
+
private toolsInitPromise;
|
|
46
|
+
constructor(config: AgentNetworkConfig, neurolink: NeuroLink);
|
|
47
|
+
private initializeAgents;
|
|
48
|
+
private initializeWorkflows;
|
|
49
|
+
private initializeTools;
|
|
50
|
+
private ensureToolsInitialized;
|
|
51
|
+
/**
|
|
52
|
+
* Build a Record of ai SDK tools — one per agent in the network.
|
|
53
|
+
* The router model calls these tools to delegate subtasks.
|
|
54
|
+
*/
|
|
55
|
+
private buildAgentTools;
|
|
56
|
+
/**
|
|
57
|
+
* Build the router system prompt that describes all available agents and
|
|
58
|
+
* instructs the model to delegate tasks via agent tools.
|
|
59
|
+
*/
|
|
60
|
+
private buildRouterSystemPrompt;
|
|
61
|
+
/**
|
|
62
|
+
* Build NetworkExecutionTrace steps from generate() toolExecutions.
|
|
63
|
+
*/
|
|
64
|
+
private buildTrace;
|
|
65
|
+
/**
|
|
66
|
+
* Execute the network with intelligent routing via the ai SDK tool loop.
|
|
67
|
+
*
|
|
68
|
+
* A single `neurolink.generate()` call is issued. The model decides which
|
|
69
|
+
* agent tool(s) to call; the SDK executes them and loops until `stop` or
|
|
70
|
+
* `maxSteps` is reached.
|
|
71
|
+
*/
|
|
72
|
+
execute(input: NetworkExecutionInput, options?: NetworkExecutionOptions): Promise<NetworkExecutionResult>;
|
|
73
|
+
/**
|
|
74
|
+
* Stream network execution using the ai SDK tool loop.
|
|
75
|
+
*
|
|
76
|
+
* Calls `neurolink.stream()` with agent tools. Text chunks, tool calls, and
|
|
77
|
+
* tool results are forwarded as typed NetworkStreamChunk events.
|
|
78
|
+
*/
|
|
79
|
+
stream(input: NetworkExecutionInput, options?: NetworkExecutionOptions): AsyncIterable<NetworkStreamChunk>;
|
|
80
|
+
getAgent(id: string): Agent | undefined;
|
|
81
|
+
getAllAgents(): Agent[];
|
|
82
|
+
getAllPrimitives(): Primitive[];
|
|
83
|
+
on(event: string, handler: (...args: unknown[]) => void): void;
|
|
84
|
+
off(event: string, handler: (...args: unknown[]) => void): void;
|
|
85
|
+
private extractMessageContent;
|
|
86
|
+
private emit;
|
|
87
|
+
}
|