mcp-use 0.1.6 ā 0.1.8
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/README.md +196 -0
- package/dist/examples/ai_sdk_example.d.ts +23 -0
- package/dist/examples/ai_sdk_example.d.ts.map +1 -0
- package/dist/examples/ai_sdk_example.js +213 -0
- package/dist/examples/stream_example.d.ts +12 -0
- package/dist/examples/stream_example.d.ts.map +1 -0
- package/dist/examples/stream_example.js +198 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/src/agents/mcp_agent.d.ts +9 -3
- package/dist/src/agents/mcp_agent.d.ts.map +1 -1
- package/dist/src/agents/mcp_agent.js +175 -42
- package/dist/src/agents/utils/ai_sdk.d.ts +22 -0
- package/dist/src/agents/utils/ai_sdk.d.ts.map +1 -0
- package/dist/src/agents/utils/ai_sdk.js +62 -0
- package/dist/src/agents/utils/index.d.ts +2 -0
- package/dist/src/agents/utils/index.d.ts.map +1 -0
- package/dist/src/agents/utils/index.js +1 -0
- package/dist/tests/ai_sdk_compatibility.test.d.ts +13 -0
- package/dist/tests/ai_sdk_compatibility.test.d.ts.map +1 -0
- package/dist/tests/ai_sdk_compatibility.test.js +214 -0
- package/dist/tests/stream_events.test.d.ts +2 -0
- package/dist/tests/stream_events.test.d.ts.map +1 -0
- package/dist/tests/stream_events.test.js +306 -0
- package/dist/tests/stream_events_simple.test.d.ts +7 -0
- package/dist/tests/stream_events_simple.test.d.ts.map +1 -0
- package/dist/tests/stream_events_simple.test.js +179 -0
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +21 -0
- package/package.json +14 -4
package/dist/index.js
CHANGED
@@ -8,6 +8,8 @@ import { WebSocketConnector } from './src/connectors/websocket.js';
|
|
8
8
|
import { Logger, logger } from './src/logging.js';
|
9
9
|
import { MCPSession } from './src/session.js';
|
10
10
|
export { BaseAdapter, LangChainAdapter } from './src/adapters/index.js';
|
11
|
+
// Export AI SDK utilities
|
12
|
+
export * from './src/agents/utils/index.js';
|
11
13
|
export { ServerManager } from './src/managers/server_manager.js';
|
12
14
|
export * from './src/managers/tools/index.js';
|
13
15
|
// Export telemetry utilities
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import type { BaseLanguageModelInterface } from '@langchain/core/language_models/base';
|
2
2
|
import type { BaseMessage } from '@langchain/core/messages';
|
3
3
|
import type { StructuredToolInterface } from '@langchain/core/tools';
|
4
|
+
import type { StreamEvent } from '@langchain/core/tracers/log_stream';
|
4
5
|
import type { AgentStep } from 'langchain/agents';
|
5
6
|
import type { MCPClient } from '../client.js';
|
6
7
|
import type { BaseConnector } from '../connectors/base.js';
|
@@ -21,12 +22,12 @@ export declare class MCPAgent {
|
|
21
22
|
private systemPrompt?;
|
22
23
|
private systemPromptTemplateOverride?;
|
23
24
|
private additionalInstructions?;
|
24
|
-
private
|
25
|
+
private _initialized;
|
25
26
|
private conversationHistory;
|
26
|
-
private
|
27
|
+
private _agentExecutor;
|
27
28
|
private sessions;
|
28
29
|
private systemMessage;
|
29
|
-
private
|
30
|
+
private _tools;
|
30
31
|
private adapter;
|
31
32
|
private serverManager;
|
32
33
|
private telemetry;
|
@@ -69,5 +70,10 @@ export declare class MCPAgent {
|
|
69
70
|
*/
|
70
71
|
stream(query: string, maxSteps?: number, manageConnector?: boolean, externalHistory?: BaseMessage[]): AsyncGenerator<AgentStep, string, void>;
|
71
72
|
close(): Promise<void>;
|
73
|
+
/**
|
74
|
+
* Yields LangChain StreamEvent objects from the underlying streamEvents() method.
|
75
|
+
* This provides token-level streaming and fine-grained event updates.
|
76
|
+
*/
|
77
|
+
streamEvents(query: string, maxSteps?: number, manageConnector?: boolean, externalHistory?: BaseMessage[]): AsyncGenerator<StreamEvent, void, void>;
|
72
78
|
}
|
73
79
|
//# sourceMappingURL=mcp_agent.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"mcp_agent.d.ts","sourceRoot":"","sources":["../../../src/agents/mcp_agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAqB,MAAM,sCAAsC,CAAA;AACzG,OAAO,KAAK,EACV,WAAW,EACZ,MAAM,0BAA0B,CAAA;AACjC,OAAO,KAAK,EAAE,uBAAuB,EAAiB,MAAM,uBAAuB,CAAA;AACnF,OAAO,KAAK,EAAe,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAE1D,OAAO,EAGL,aAAa,EACd,MAAM,0BAA0B,CAAA;AAUjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAA;AAEnE,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAK7D,qBAAa,QAAQ;IACnB,OAAO,CAAC,GAAG,CAA4B;IACvC,OAAO,CAAC,MAAM,CAAC,CAAW;IAC1B,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,eAAe,CAA2B;IAClD,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,YAAY,CAAC,CAAe;IACpC,OAAO,CAAC,4BAA4B,CAAC,CAAe;IACpD,OAAO,CAAC,sBAAsB,CAAC,CAAe;IAE9C,OAAO,CAAC,
|
1
|
+
{"version":3,"file":"mcp_agent.d.ts","sourceRoot":"","sources":["../../../src/agents/mcp_agent.ts"],"names":[],"mappings":"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"}
|
@@ -22,12 +22,12 @@ export class MCPAgent {
|
|
22
22
|
systemPrompt;
|
23
23
|
systemPromptTemplateOverride;
|
24
24
|
additionalInstructions;
|
25
|
-
|
25
|
+
_initialized = false;
|
26
26
|
conversationHistory = [];
|
27
|
-
|
27
|
+
_agentExecutor = null;
|
28
28
|
sessions = {};
|
29
29
|
systemMessage = null;
|
30
|
-
|
30
|
+
_tools = [];
|
31
31
|
adapter;
|
32
32
|
serverManager = null;
|
33
33
|
telemetry;
|
@@ -67,6 +67,19 @@ export class MCPAgent {
|
|
67
67
|
const [provider, name] = extractModelInfo(this.llm);
|
68
68
|
this.modelProvider = provider;
|
69
69
|
this.modelName = name;
|
70
|
+
// Make getters configurable for test mocking
|
71
|
+
Object.defineProperty(this, 'agentExecutor', {
|
72
|
+
get: () => this._agentExecutor,
|
73
|
+
configurable: true,
|
74
|
+
});
|
75
|
+
Object.defineProperty(this, 'tools', {
|
76
|
+
get: () => this._tools,
|
77
|
+
configurable: true,
|
78
|
+
});
|
79
|
+
Object.defineProperty(this, 'initialized', {
|
80
|
+
get: () => this._initialized,
|
81
|
+
configurable: true,
|
82
|
+
});
|
70
83
|
}
|
71
84
|
async initialize() {
|
72
85
|
logger.info('š Initializing MCP agent and connecting to services...');
|
@@ -75,11 +88,11 @@ export class MCPAgent {
|
|
75
88
|
await this.serverManager.initialize();
|
76
89
|
// Get server management tools
|
77
90
|
const managementTools = this.serverManager.tools;
|
78
|
-
this.
|
79
|
-
this.
|
91
|
+
this._tools = managementTools;
|
92
|
+
this._tools.push(...this.additionalTools);
|
80
93
|
logger.info(`š§ Server manager mode active with ${managementTools.length} management tools`);
|
81
94
|
// Create the system message based on available tools
|
82
|
-
await this.createSystemMessageFromTools(this.
|
95
|
+
await this.createSystemMessageFromTools(this._tools);
|
83
96
|
}
|
84
97
|
else {
|
85
98
|
// Standard initialization - if using client, get or create sessions
|
@@ -94,9 +107,9 @@ export class MCPAgent {
|
|
94
107
|
logger.info(`ā
Created ${Object.keys(this.sessions).length} new sessions`);
|
95
108
|
}
|
96
109
|
// Create LangChain tools directly from the client using the adapter
|
97
|
-
this.
|
98
|
-
this.
|
99
|
-
logger.info(`š ļø Created ${this.
|
110
|
+
this._tools = await LangChainAdapter.createTools(this.client);
|
111
|
+
this._tools.push(...this.additionalTools);
|
112
|
+
logger.info(`š ļø Created ${this._tools.length} LangChain tools from client`);
|
100
113
|
}
|
101
114
|
else {
|
102
115
|
// Using direct connector - only establish connection
|
@@ -107,18 +120,18 @@ export class MCPAgent {
|
|
107
120
|
}
|
108
121
|
}
|
109
122
|
// Create LangChain tools using the adapter with connectors
|
110
|
-
this.
|
111
|
-
this.
|
112
|
-
logger.info(`š ļø Created ${this.
|
123
|
+
this._tools = await this.adapter.createToolsFromConnectors(this.connectors);
|
124
|
+
this._tools.push(...this.additionalTools);
|
125
|
+
logger.info(`š ļø Created ${this._tools.length} LangChain tools from connectors`);
|
113
126
|
}
|
114
127
|
// Get all tools for system message generation
|
115
|
-
logger.info(`š§° Found ${this.
|
128
|
+
logger.info(`š§° Found ${this._tools.length} tools across all connectors`);
|
116
129
|
// Create the system message based on available tools
|
117
|
-
await this.createSystemMessageFromTools(this.
|
130
|
+
await this.createSystemMessageFromTools(this._tools);
|
118
131
|
}
|
119
132
|
// Create the agent executor and mark initialized
|
120
|
-
this.
|
121
|
-
this.
|
133
|
+
this._agentExecutor = this.createAgent();
|
134
|
+
this._initialized = true;
|
122
135
|
logger.info('⨠Agent initialization complete');
|
123
136
|
}
|
124
137
|
async createSystemMessageFromTools(tools) {
|
@@ -142,12 +155,12 @@ export class MCPAgent {
|
|
142
155
|
]);
|
143
156
|
const agent = createToolCallingAgent({
|
144
157
|
llm: this.llm,
|
145
|
-
tools: this.
|
158
|
+
tools: this._tools,
|
146
159
|
prompt,
|
147
160
|
});
|
148
161
|
return new AgentExecutor({
|
149
162
|
agent,
|
150
|
-
tools: this.
|
163
|
+
tools: this._tools,
|
151
164
|
maxIterations: this.maxSteps,
|
152
165
|
verbose: this.verbose,
|
153
166
|
returnIntermediateSteps: true,
|
@@ -172,15 +185,15 @@ export class MCPAgent {
|
|
172
185
|
this.conversationHistory = this.conversationHistory.filter(m => !(m instanceof SystemMessage));
|
173
186
|
this.conversationHistory.unshift(this.systemMessage);
|
174
187
|
}
|
175
|
-
if (this.
|
176
|
-
this.
|
188
|
+
if (this._initialized && this._tools.length) {
|
189
|
+
this._agentExecutor = this.createAgent();
|
177
190
|
logger.debug('Agent recreated with new system message');
|
178
191
|
}
|
179
192
|
}
|
180
193
|
setDisallowedTools(disallowedTools) {
|
181
194
|
this.disallowedTools = disallowedTools;
|
182
195
|
this.adapter = new LangChainAdapter(this.disallowedTools);
|
183
|
-
if (this.
|
196
|
+
if (this._initialized) {
|
184
197
|
logger.debug('Agent already initialized. Changes will take effect on next initialization.');
|
185
198
|
}
|
186
199
|
}
|
@@ -216,19 +229,19 @@ export class MCPAgent {
|
|
216
229
|
let stepsTaken = 0;
|
217
230
|
let success = false;
|
218
231
|
try {
|
219
|
-
if (manageConnector && !this.
|
232
|
+
if (manageConnector && !this._initialized) {
|
220
233
|
await this.initialize();
|
221
234
|
initializedHere = true;
|
222
235
|
}
|
223
|
-
else if (!this.
|
236
|
+
else if (!this._initialized && this.autoInitialize) {
|
224
237
|
await this.initialize();
|
225
238
|
initializedHere = true;
|
226
239
|
}
|
227
|
-
if (!this.
|
240
|
+
if (!this._agentExecutor) {
|
228
241
|
throw new Error('MCP agent failed to initialize');
|
229
242
|
}
|
230
243
|
const steps = maxSteps ?? this.maxSteps;
|
231
|
-
this.
|
244
|
+
this._agentExecutor.maxIterations = steps;
|
232
245
|
const display_query = query.length > 50 ? `${query.slice(0, 50).replace(/\n/g, ' ')}...` : query.replace(/\n/g, ' ');
|
233
246
|
logger.info(`š¬ Received query: '${display_query}'`);
|
234
247
|
// āāā Record user message
|
@@ -244,30 +257,30 @@ export class MCPAgent {
|
|
244
257
|
}
|
245
258
|
const intermediateSteps = [];
|
246
259
|
const inputs = { input: query, chat_history: langchainHistory };
|
247
|
-
let nameToToolMap = Object.fromEntries(this.
|
260
|
+
let nameToToolMap = Object.fromEntries(this._tools.map(t => [t.name, t]));
|
248
261
|
logger.info(`š Starting agent execution with max_steps=${steps}`);
|
249
262
|
for (let stepNum = 0; stepNum < steps; stepNum++) {
|
250
263
|
stepsTaken = stepNum + 1;
|
251
264
|
if (this.useServerManager && this.serverManager) {
|
252
265
|
const currentTools = this.serverManager.tools;
|
253
266
|
const currentToolNames = new Set(currentTools.map(t => t.name));
|
254
|
-
const existingToolNames = new Set(this.
|
255
|
-
const changed = currentTools.length !== this.
|
267
|
+
const existingToolNames = new Set(this._tools.map(t => t.name));
|
268
|
+
const changed = currentTools.length !== this._tools.length
|
256
269
|
|| [...currentToolNames].some(n => !existingToolNames.has(n));
|
257
270
|
if (changed) {
|
258
271
|
logger.info(`š Tools changed before step ${stepNum + 1}, updating agent. New tools: ${[...currentToolNames].join(', ')}`);
|
259
|
-
this.
|
260
|
-
this.
|
261
|
-
await this.createSystemMessageFromTools(this.
|
262
|
-
this.
|
263
|
-
this.
|
264
|
-
nameToToolMap = Object.fromEntries(this.
|
272
|
+
this._tools = currentTools;
|
273
|
+
this._tools.push(...this.additionalTools);
|
274
|
+
await this.createSystemMessageFromTools(this._tools);
|
275
|
+
this._agentExecutor = this.createAgent();
|
276
|
+
this._agentExecutor.maxIterations = steps;
|
277
|
+
nameToToolMap = Object.fromEntries(this._tools.map(t => [t.name, t]));
|
265
278
|
}
|
266
279
|
}
|
267
280
|
logger.info(`š£ Step ${stepNum + 1}/${steps}`);
|
268
281
|
try {
|
269
282
|
logger.debug('Starting agent step execution');
|
270
|
-
const nextStepOutput = await this.
|
283
|
+
const nextStepOutput = await this._agentExecutor._takeNextStep(nameToToolMap, inputs, intermediateSteps);
|
271
284
|
if (nextStepOutput.returnValues) {
|
272
285
|
logger.info(`ā
Agent finished at step ${stepNum + 1}`);
|
273
286
|
result = nextStepOutput.returnValues?.output ?? 'No output generated';
|
@@ -280,7 +293,9 @@ export class MCPAgent {
|
|
280
293
|
const { action, observation } = step;
|
281
294
|
const toolName = action.tool;
|
282
295
|
toolsUsedNames.push(toolName);
|
283
|
-
let toolInputStr =
|
296
|
+
let toolInputStr = typeof action.toolInput === 'string'
|
297
|
+
? action.toolInput
|
298
|
+
: JSON.stringify(action.toolInput, null, 2);
|
284
299
|
if (toolInputStr.length > 100)
|
285
300
|
toolInputStr = `${toolInputStr.slice(0, 97)}...`;
|
286
301
|
logger.info(`š§ Tool call: ${toolName} with input: ${toolInputStr}`);
|
@@ -293,7 +308,7 @@ export class MCPAgent {
|
|
293
308
|
// Detect direct return
|
294
309
|
if (stepArray.length) {
|
295
310
|
const lastStep = stepArray[stepArray.length - 1];
|
296
|
-
const toolReturn = await this.
|
311
|
+
const toolReturn = await this._agentExecutor._getToolReturn(lastStep);
|
297
312
|
if (toolReturn) {
|
298
313
|
logger.info(`š Tool returned directly at step ${stepNum + 1}`);
|
299
314
|
result = toolReturn.returnValues?.output ?? 'No output generated';
|
@@ -352,8 +367,8 @@ export class MCPAgent {
|
|
352
367
|
modelName: this.modelName,
|
353
368
|
serverCount,
|
354
369
|
serverIdentifiers: this.connectors.map(connector => connector.publicIdentifier),
|
355
|
-
totalToolsAvailable: this.
|
356
|
-
toolsAvailableNames: this.
|
370
|
+
totalToolsAvailable: this._tools.length,
|
371
|
+
toolsAvailableNames: this._tools.map(t => t.name),
|
357
372
|
maxStepsConfigured: this.maxSteps,
|
358
373
|
memoryEnabled: this.memoryEnabled,
|
359
374
|
useServerManager: this.useServerManager,
|
@@ -377,8 +392,8 @@ export class MCPAgent {
|
|
377
392
|
async close() {
|
378
393
|
logger.info('š Closing MCPAgent resourcesā¦');
|
379
394
|
try {
|
380
|
-
this.
|
381
|
-
this.
|
395
|
+
this._agentExecutor = null;
|
396
|
+
this._tools = [];
|
382
397
|
if (this.client) {
|
383
398
|
logger.info('š Closing sessions through client');
|
384
399
|
await this.client.closeAllSessions();
|
@@ -395,8 +410,126 @@ export class MCPAgent {
|
|
395
410
|
}
|
396
411
|
}
|
397
412
|
finally {
|
398
|
-
this.
|
413
|
+
this._initialized = false;
|
399
414
|
logger.info('š Agent closed successfully');
|
400
415
|
}
|
401
416
|
}
|
417
|
+
/**
|
418
|
+
* Yields LangChain StreamEvent objects from the underlying streamEvents() method.
|
419
|
+
* This provides token-level streaming and fine-grained event updates.
|
420
|
+
*/
|
421
|
+
async *streamEvents(query, maxSteps, manageConnector = true, externalHistory) {
|
422
|
+
let initializedHere = false;
|
423
|
+
const startTime = Date.now();
|
424
|
+
let success = false;
|
425
|
+
let eventCount = 0;
|
426
|
+
let totalResponseLength = 0;
|
427
|
+
try {
|
428
|
+
// Initialize if needed
|
429
|
+
if (manageConnector && !this._initialized) {
|
430
|
+
await this.initialize();
|
431
|
+
initializedHere = true;
|
432
|
+
}
|
433
|
+
else if (!this._initialized && this.autoInitialize) {
|
434
|
+
await this.initialize();
|
435
|
+
initializedHere = true;
|
436
|
+
}
|
437
|
+
const agentExecutor = this.agentExecutor;
|
438
|
+
if (!agentExecutor) {
|
439
|
+
throw new Error('MCP agent failed to initialize');
|
440
|
+
}
|
441
|
+
// Set max iterations
|
442
|
+
const steps = maxSteps ?? this.maxSteps;
|
443
|
+
agentExecutor.maxIterations = steps;
|
444
|
+
const display_query = query.length > 50 ? `${query.slice(0, 50).replace(/\n/g, ' ')}...` : query.replace(/\n/g, ' ');
|
445
|
+
logger.info(`š¬ Received query for streamEvents: '${display_query}'`);
|
446
|
+
// Add user message to history if memory enabled
|
447
|
+
if (this.memoryEnabled) {
|
448
|
+
this.addToHistory(new HumanMessage(query));
|
449
|
+
}
|
450
|
+
// Prepare history
|
451
|
+
const historyToUse = externalHistory ?? this.conversationHistory;
|
452
|
+
const langchainHistory = [];
|
453
|
+
for (const msg of historyToUse) {
|
454
|
+
if (msg instanceof HumanMessage || msg instanceof AIMessage) {
|
455
|
+
langchainHistory.push(msg);
|
456
|
+
}
|
457
|
+
}
|
458
|
+
// Prepare inputs
|
459
|
+
const inputs = { input: query, chat_history: langchainHistory };
|
460
|
+
// Stream events from the agent executor
|
461
|
+
const eventStream = agentExecutor.streamEvents(inputs, { version: 'v2' });
|
462
|
+
// Yield each event
|
463
|
+
for await (const event of eventStream) {
|
464
|
+
eventCount++;
|
465
|
+
// Skip null or invalid events
|
466
|
+
if (!event || typeof event !== 'object') {
|
467
|
+
continue;
|
468
|
+
}
|
469
|
+
// Track response length for telemetry
|
470
|
+
if (event.event === 'on_chat_model_stream' && event.data?.chunk?.content) {
|
471
|
+
totalResponseLength += event.data.chunk.content.length;
|
472
|
+
}
|
473
|
+
yield event;
|
474
|
+
// Handle final message for history
|
475
|
+
if (event.event === 'on_chain_end' && event.data?.output) {
|
476
|
+
const output = event.data.output;
|
477
|
+
if (typeof output === 'string' && this.memoryEnabled) {
|
478
|
+
this.addToHistory(new AIMessage(output));
|
479
|
+
}
|
480
|
+
else if (output?.output && typeof output.output === 'string' && this.memoryEnabled) {
|
481
|
+
this.addToHistory(new AIMessage(output.output));
|
482
|
+
}
|
483
|
+
}
|
484
|
+
}
|
485
|
+
logger.info(`š StreamEvents complete - ${eventCount} events emitted`);
|
486
|
+
success = true;
|
487
|
+
}
|
488
|
+
catch (e) {
|
489
|
+
logger.error(`ā Error during streamEvents: ${e}`);
|
490
|
+
if (initializedHere && manageConnector) {
|
491
|
+
logger.info('š§¹ Cleaning up resources after initialization error in streamEvents');
|
492
|
+
await this.close();
|
493
|
+
}
|
494
|
+
throw e;
|
495
|
+
}
|
496
|
+
finally {
|
497
|
+
// Track telemetry
|
498
|
+
const executionTimeMs = Date.now() - startTime;
|
499
|
+
let serverCount = 0;
|
500
|
+
if (this.client) {
|
501
|
+
serverCount = Object.keys(await this.client.getAllActiveSessions()).length;
|
502
|
+
}
|
503
|
+
else if (this.connectors) {
|
504
|
+
serverCount = this.connectors.length;
|
505
|
+
}
|
506
|
+
const conversationHistoryLength = this.memoryEnabled ? this.conversationHistory.length : 0;
|
507
|
+
await this.telemetry.trackAgentExecution({
|
508
|
+
executionMethod: 'streamEvents',
|
509
|
+
query,
|
510
|
+
success,
|
511
|
+
modelProvider: this.modelProvider,
|
512
|
+
modelName: this.modelName,
|
513
|
+
serverCount,
|
514
|
+
serverIdentifiers: this.connectors.map(connector => connector.publicIdentifier),
|
515
|
+
totalToolsAvailable: this._tools.length,
|
516
|
+
toolsAvailableNames: this._tools.map(t => t.name),
|
517
|
+
maxStepsConfigured: this.maxSteps,
|
518
|
+
memoryEnabled: this.memoryEnabled,
|
519
|
+
useServerManager: this.useServerManager,
|
520
|
+
maxStepsUsed: maxSteps ?? null,
|
521
|
+
manageConnector,
|
522
|
+
externalHistoryUsed: externalHistory !== undefined,
|
523
|
+
response: `[STREAMED RESPONSE - ${totalResponseLength} chars]`,
|
524
|
+
executionTimeMs,
|
525
|
+
errorType: success ? null : 'streaming_error',
|
526
|
+
conversationHistoryLength,
|
527
|
+
});
|
528
|
+
// Clean up if needed
|
529
|
+
if (manageConnector && !this.client && initializedHere) {
|
530
|
+
logger.info('š§¹ Closing agent after streamEvents completion');
|
531
|
+
await this.close();
|
532
|
+
}
|
533
|
+
}
|
534
|
+
}
|
402
535
|
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
/**
|
2
|
+
* AI SDK Integration Utilities
|
3
|
+
*
|
4
|
+
* Utility functions for integrating MCPAgent's streamEvents with Vercel AI SDK.
|
5
|
+
* These utilities help convert stream events to AI SDK compatible formats.
|
6
|
+
*/
|
7
|
+
import type { StreamEvent } from '@langchain/core/tracers/log_stream';
|
8
|
+
/**
|
9
|
+
* Converts streamEvents to AI SDK compatible stream (basic version)
|
10
|
+
* Only yields the actual content tokens from chat model streams
|
11
|
+
*/
|
12
|
+
export declare function streamEventsToAISDK(streamEvents: AsyncGenerator<StreamEvent, void, void>): AsyncGenerator<string, void, void>;
|
13
|
+
/**
|
14
|
+
* Converts async generator to ReadableStream for AI SDK compatibility
|
15
|
+
*/
|
16
|
+
export declare function createReadableStreamFromGenerator(generator: AsyncGenerator<string, void, void>): ReadableStream<string>;
|
17
|
+
/**
|
18
|
+
* Enhanced adapter that includes tool information along with chat content
|
19
|
+
* Yields both content tokens and tool usage notifications
|
20
|
+
*/
|
21
|
+
export declare function streamEventsToAISDKWithTools(streamEvents: AsyncGenerator<StreamEvent, void, void>): AsyncGenerator<string, void, void>;
|
22
|
+
//# sourceMappingURL=ai_sdk.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"ai_sdk.d.ts","sourceRoot":"","sources":["../../../../src/agents/utils/ai_sdk.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAA;AAErE;;;GAGG;AACH,wBAAuB,mBAAmB,CACxC,YAAY,EAAE,cAAc,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,GACpD,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CASpC;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAC/C,SAAS,EAAE,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,GAC5C,cAAc,CAAC,MAAM,CAAC,CAcxB;AAED;;;GAGG;AACH,wBAAuB,4BAA4B,CACjD,YAAY,EAAE,cAAc,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,GACpD,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAqBpC"}
|
@@ -0,0 +1,62 @@
|
|
1
|
+
/**
|
2
|
+
* AI SDK Integration Utilities
|
3
|
+
*
|
4
|
+
* Utility functions for integrating MCPAgent's streamEvents with Vercel AI SDK.
|
5
|
+
* These utilities help convert stream events to AI SDK compatible formats.
|
6
|
+
*/
|
7
|
+
/**
|
8
|
+
* Converts streamEvents to AI SDK compatible stream (basic version)
|
9
|
+
* Only yields the actual content tokens from chat model streams
|
10
|
+
*/
|
11
|
+
export async function* streamEventsToAISDK(streamEvents) {
|
12
|
+
for await (const event of streamEvents) {
|
13
|
+
if (event.event === 'on_chat_model_stream' && event.data?.chunk?.text) {
|
14
|
+
const textContent = event.data.chunk.text;
|
15
|
+
if (typeof textContent === 'string' && textContent.length > 0) {
|
16
|
+
yield textContent;
|
17
|
+
}
|
18
|
+
}
|
19
|
+
}
|
20
|
+
}
|
21
|
+
/**
|
22
|
+
* Converts async generator to ReadableStream for AI SDK compatibility
|
23
|
+
*/
|
24
|
+
export function createReadableStreamFromGenerator(generator) {
|
25
|
+
return new ReadableStream({
|
26
|
+
async start(controller) {
|
27
|
+
try {
|
28
|
+
for await (const chunk of generator) {
|
29
|
+
controller.enqueue(chunk);
|
30
|
+
}
|
31
|
+
controller.close();
|
32
|
+
}
|
33
|
+
catch (error) {
|
34
|
+
controller.error(error);
|
35
|
+
}
|
36
|
+
},
|
37
|
+
});
|
38
|
+
}
|
39
|
+
/**
|
40
|
+
* Enhanced adapter that includes tool information along with chat content
|
41
|
+
* Yields both content tokens and tool usage notifications
|
42
|
+
*/
|
43
|
+
export async function* streamEventsToAISDKWithTools(streamEvents) {
|
44
|
+
for await (const event of streamEvents) {
|
45
|
+
switch (event.event) {
|
46
|
+
case 'on_chat_model_stream':
|
47
|
+
if (event.data?.chunk?.text) {
|
48
|
+
const textContent = event.data.chunk.text;
|
49
|
+
if (typeof textContent === 'string' && textContent.length > 0) {
|
50
|
+
yield textContent;
|
51
|
+
}
|
52
|
+
}
|
53
|
+
break;
|
54
|
+
case 'on_tool_start':
|
55
|
+
yield `\nš§ Using tool: ${event.name}\n`;
|
56
|
+
break;
|
57
|
+
case 'on_tool_end':
|
58
|
+
yield `\nā
Tool completed: ${event.name}\n`;
|
59
|
+
break;
|
60
|
+
}
|
61
|
+
}
|
62
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/agents/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,EACjC,mBAAmB,EACnB,4BAA4B,GAC7B,MAAM,aAAa,CAAA"}
|
@@ -0,0 +1 @@
|
|
1
|
+
export { createReadableStreamFromGenerator, streamEventsToAISDK, streamEventsToAISDKWithTools, } from './ai_sdk.js';
|
@@ -0,0 +1,13 @@
|
|
1
|
+
/**
|
2
|
+
* Tests for AI SDK compatibility with MCPAgent streamEvents()
|
3
|
+
*
|
4
|
+
* These tests verify that streamEvents() can be used with the AI SDK's
|
5
|
+
* LangChainAdapter for creating data stream responses compatible with
|
6
|
+
* Vercel AI SDK hooks like useCompletion and useChat.
|
7
|
+
*/
|
8
|
+
import type { StreamEvent } from '../index.js';
|
9
|
+
declare function streamEventsToAISDK(streamEvents: AsyncGenerator<StreamEvent, void, void>): AsyncGenerator<string, void, void>;
|
10
|
+
declare function streamEventsToCompleteContent(streamEvents: AsyncGenerator<StreamEvent, void, void>): AsyncGenerator<string, void, void>;
|
11
|
+
declare function createReadableStreamFromGenerator(generator: AsyncGenerator<string, void, void>): ReadableStream<string>;
|
12
|
+
export { createReadableStreamFromGenerator, streamEventsToAISDK, streamEventsToCompleteContent };
|
13
|
+
//# sourceMappingURL=ai_sdk_compatibility.test.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"ai_sdk_compatibility.test.d.ts","sourceRoot":"","sources":["../../tests/ai_sdk_compatibility.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAmD9C,iBAAgB,mBAAmB,CACjC,YAAY,EAAE,cAAc,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,GACpD,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAOpC;AAGD,iBAAgB,6BAA6B,CAC3C,YAAY,EAAE,cAAc,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,GACpD,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAoBpC;AAuJD,iBAAS,iCAAiC,CACxC,SAAS,EAAE,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,GAC5C,cAAc,CAAC,MAAM,CAAC,CAcxB;AAGD,OAAO,EAAE,iCAAiC,EAAE,mBAAmB,EAAE,6BAA6B,EAAE,CAAA"}
|