mcp-use 1.2.5-dev.5 → 1.3.0-canary.1
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/dist/.tsbuildinfo +1 -1
- package/dist/{chunk-73SH52J2.js → chunk-6EHM3S3M.js} +191 -8
- package/dist/{chunk-37MPZ3D6.js → chunk-TIUSJAAE.js} +12 -0
- package/dist/{chunk-X2HJQBDI.js → chunk-VNEGDXZO.js} +26 -1
- package/dist/index.cjs +226 -6
- package/dist/index.js +3 -3
- package/dist/src/agents/index.cjs +189 -6
- package/dist/src/agents/index.js +1 -1
- package/dist/src/agents/mcp_agent.d.ts +90 -2
- package/dist/src/agents/mcp_agent.d.ts.map +1 -1
- package/dist/src/browser.cjs +201 -6
- package/dist/src/browser.js +2 -2
- package/dist/src/connectors/base.d.ts +11 -0
- package/dist/src/connectors/base.d.ts.map +1 -1
- package/dist/src/react/index.cjs +37 -0
- package/dist/src/react/index.js +2 -2
- package/dist/src/react/types.d.ts +7 -0
- package/dist/src/react/types.d.ts.map +1 -1
- package/dist/src/react/useMcp.d.ts.map +1 -1
- package/dist/src/server/index.cjs +108 -58
- package/dist/src/server/index.js +108 -58
- package/dist/src/server/mcp-server.d.ts +5 -0
- package/dist/src/server/mcp-server.d.ts.map +1 -1
- package/package.json +41 -44
|
@@ -2464,6 +2464,185 @@ var MCPAgent = class {
|
|
|
2464
2464
|
return String(value);
|
|
2465
2465
|
}
|
|
2466
2466
|
}
|
|
2467
|
+
/**
|
|
2468
|
+
* Check if a message is AI/assistant-like regardless of whether it's a class instance.
|
|
2469
|
+
* Handles version mismatches, serialization boundaries, and different message formats.
|
|
2470
|
+
*
|
|
2471
|
+
* This method solves the issue where messages from LangChain agents may be plain JavaScript
|
|
2472
|
+
* objects (e.g., `{ type: 'ai', content: '...' }`) instead of AIMessage instances due to
|
|
2473
|
+
* serialization/deserialization across module boundaries or version mismatches.
|
|
2474
|
+
*
|
|
2475
|
+
* @example
|
|
2476
|
+
* // Real AIMessage instance (standard case)
|
|
2477
|
+
* _isAIMessageLike(new AIMessage("hello")) // => true
|
|
2478
|
+
*
|
|
2479
|
+
* @example
|
|
2480
|
+
* // Plain object after serialization (fixes issue #446)
|
|
2481
|
+
* _isAIMessageLike({ type: "ai", content: "hello" }) // => true
|
|
2482
|
+
*
|
|
2483
|
+
* @example
|
|
2484
|
+
* // OpenAI-style format with role
|
|
2485
|
+
* _isAIMessageLike({ role: "assistant", content: "hello" }) // => true
|
|
2486
|
+
*
|
|
2487
|
+
* @example
|
|
2488
|
+
* // Object with getType() method
|
|
2489
|
+
* _isAIMessageLike({ getType: () => "ai", content: "hello" }) // => true
|
|
2490
|
+
*
|
|
2491
|
+
* @param message - The message object to check
|
|
2492
|
+
* @returns true if the message represents an AI/assistant message
|
|
2493
|
+
*/
|
|
2494
|
+
_isAIMessageLike(message) {
|
|
2495
|
+
if (message instanceof import_langchain2.AIMessage) {
|
|
2496
|
+
return true;
|
|
2497
|
+
}
|
|
2498
|
+
if (typeof message !== "object" || message === null) {
|
|
2499
|
+
return false;
|
|
2500
|
+
}
|
|
2501
|
+
const msg = message;
|
|
2502
|
+
if (typeof msg.getType === "function") {
|
|
2503
|
+
try {
|
|
2504
|
+
const type = msg.getType();
|
|
2505
|
+
if (type === "ai" || type === "assistant") {
|
|
2506
|
+
return true;
|
|
2507
|
+
}
|
|
2508
|
+
} catch (error) {
|
|
2509
|
+
}
|
|
2510
|
+
}
|
|
2511
|
+
if (typeof msg._getType === "function") {
|
|
2512
|
+
try {
|
|
2513
|
+
const type = msg._getType();
|
|
2514
|
+
if (type === "ai" || type === "assistant") {
|
|
2515
|
+
return true;
|
|
2516
|
+
}
|
|
2517
|
+
} catch (error) {
|
|
2518
|
+
}
|
|
2519
|
+
}
|
|
2520
|
+
if ("type" in msg) {
|
|
2521
|
+
return msg.type === "ai" || msg.type === "assistant";
|
|
2522
|
+
}
|
|
2523
|
+
if ("role" in msg) {
|
|
2524
|
+
return msg.role === "ai" || msg.role === "assistant";
|
|
2525
|
+
}
|
|
2526
|
+
return false;
|
|
2527
|
+
}
|
|
2528
|
+
/**
|
|
2529
|
+
* Check if a message has tool calls, handling both class instances and plain objects.
|
|
2530
|
+
* Safely checks for tool_calls array presence.
|
|
2531
|
+
*
|
|
2532
|
+
* @example
|
|
2533
|
+
* // AIMessage with tool calls
|
|
2534
|
+
* const msg = new AIMessage({ content: "", tool_calls: [{ name: "add", args: {} }] });
|
|
2535
|
+
* _messageHasToolCalls(msg) // => true
|
|
2536
|
+
*
|
|
2537
|
+
* @example
|
|
2538
|
+
* // Plain object with tool calls
|
|
2539
|
+
* _messageHasToolCalls({ type: "ai", tool_calls: [{ name: "add" }] }) // => true
|
|
2540
|
+
*
|
|
2541
|
+
* @example
|
|
2542
|
+
* // Message without tool calls
|
|
2543
|
+
* _messageHasToolCalls({ type: "ai", content: "hello" }) // => false
|
|
2544
|
+
*
|
|
2545
|
+
* @param message - The message object to check
|
|
2546
|
+
* @returns true if the message has non-empty tool_calls array
|
|
2547
|
+
*/
|
|
2548
|
+
_messageHasToolCalls(message) {
|
|
2549
|
+
if (typeof message === "object" && message !== null && "tool_calls" in message && Array.isArray(message.tool_calls)) {
|
|
2550
|
+
return message.tool_calls.length > 0;
|
|
2551
|
+
}
|
|
2552
|
+
return false;
|
|
2553
|
+
}
|
|
2554
|
+
/**
|
|
2555
|
+
* Check if a message is a HumanMessage-like object.
|
|
2556
|
+
* Handles both class instances and plain objects from serialization.
|
|
2557
|
+
*
|
|
2558
|
+
* @example
|
|
2559
|
+
* _isHumanMessageLike(new HumanMessage("hello")) // => true
|
|
2560
|
+
* _isHumanMessageLike({ type: "human", content: "hello" }) // => true
|
|
2561
|
+
*
|
|
2562
|
+
* @param message - The message object to check
|
|
2563
|
+
* @returns true if the message represents a human message
|
|
2564
|
+
*/
|
|
2565
|
+
_isHumanMessageLike(message) {
|
|
2566
|
+
if (message instanceof import_langchain2.HumanMessage) {
|
|
2567
|
+
return true;
|
|
2568
|
+
}
|
|
2569
|
+
if (typeof message !== "object" || message === null) {
|
|
2570
|
+
return false;
|
|
2571
|
+
}
|
|
2572
|
+
const msg = message;
|
|
2573
|
+
if (typeof msg.getType === "function") {
|
|
2574
|
+
try {
|
|
2575
|
+
const type = msg.getType();
|
|
2576
|
+
if (type === "human" || type === "user") {
|
|
2577
|
+
return true;
|
|
2578
|
+
}
|
|
2579
|
+
} catch (error) {
|
|
2580
|
+
}
|
|
2581
|
+
}
|
|
2582
|
+
if ("type" in msg && (msg.type === "human" || msg.type === "user")) {
|
|
2583
|
+
return true;
|
|
2584
|
+
}
|
|
2585
|
+
if ("role" in msg && (msg.role === "human" || msg.role === "user")) {
|
|
2586
|
+
return true;
|
|
2587
|
+
}
|
|
2588
|
+
return false;
|
|
2589
|
+
}
|
|
2590
|
+
/**
|
|
2591
|
+
* Check if a message is a ToolMessage-like object.
|
|
2592
|
+
* Handles both class instances and plain objects from serialization.
|
|
2593
|
+
*
|
|
2594
|
+
* @example
|
|
2595
|
+
* _isToolMessageLike(new ToolMessage({ content: "result", tool_call_id: "123" })) // => true
|
|
2596
|
+
* _isToolMessageLike({ type: "tool", content: "result" }) // => true
|
|
2597
|
+
*
|
|
2598
|
+
* @param message - The message object to check
|
|
2599
|
+
* @returns true if the message represents a tool message
|
|
2600
|
+
*/
|
|
2601
|
+
_isToolMessageLike(message) {
|
|
2602
|
+
if (message instanceof import_langchain2.ToolMessage) {
|
|
2603
|
+
return true;
|
|
2604
|
+
}
|
|
2605
|
+
if (typeof message !== "object" || message === null) {
|
|
2606
|
+
return false;
|
|
2607
|
+
}
|
|
2608
|
+
const msg = message;
|
|
2609
|
+
if (typeof msg.getType === "function") {
|
|
2610
|
+
try {
|
|
2611
|
+
const type = msg.getType();
|
|
2612
|
+
if (type === "tool") {
|
|
2613
|
+
return true;
|
|
2614
|
+
}
|
|
2615
|
+
} catch (error) {
|
|
2616
|
+
}
|
|
2617
|
+
}
|
|
2618
|
+
if ("type" in msg && msg.type === "tool") {
|
|
2619
|
+
return true;
|
|
2620
|
+
}
|
|
2621
|
+
return false;
|
|
2622
|
+
}
|
|
2623
|
+
/**
|
|
2624
|
+
* Extract content from a message, handling both AIMessage instances and plain objects.
|
|
2625
|
+
*
|
|
2626
|
+
* @example
|
|
2627
|
+
* // From AIMessage instance
|
|
2628
|
+
* _getMessageContent(new AIMessage("hello")) // => "hello"
|
|
2629
|
+
*
|
|
2630
|
+
* @example
|
|
2631
|
+
* // From plain object
|
|
2632
|
+
* _getMessageContent({ type: "ai", content: "hello" }) // => "hello"
|
|
2633
|
+
*
|
|
2634
|
+
* @param message - The message object to extract content from
|
|
2635
|
+
* @returns The content of the message, or undefined if not present
|
|
2636
|
+
*/
|
|
2637
|
+
_getMessageContent(message) {
|
|
2638
|
+
if (message instanceof import_langchain2.AIMessage) {
|
|
2639
|
+
return message.content;
|
|
2640
|
+
}
|
|
2641
|
+
if (message && typeof message === "object" && "content" in message) {
|
|
2642
|
+
return message.content;
|
|
2643
|
+
}
|
|
2644
|
+
return void 0;
|
|
2645
|
+
}
|
|
2467
2646
|
async _consumeAndReturn(generator) {
|
|
2468
2647
|
while (true) {
|
|
2469
2648
|
const { done, value } = await generator.next();
|
|
@@ -2535,7 +2714,7 @@ var MCPAgent = class {
|
|
|
2535
2714
|
const historyToUse = externalHistory ?? this.conversationHistory;
|
|
2536
2715
|
const langchainHistory = [];
|
|
2537
2716
|
for (const msg of historyToUse) {
|
|
2538
|
-
if (msg
|
|
2717
|
+
if (this._isHumanMessageLike(msg) || this._isAIMessageLike(msg)) {
|
|
2539
2718
|
langchainHistory.push(msg);
|
|
2540
2719
|
}
|
|
2541
2720
|
}
|
|
@@ -2604,7 +2783,7 @@ var MCPAgent = class {
|
|
|
2604
2783
|
};
|
|
2605
2784
|
}
|
|
2606
2785
|
}
|
|
2607
|
-
if (
|
|
2786
|
+
if (this._isToolMessageLike(message)) {
|
|
2608
2787
|
const observation = message.content;
|
|
2609
2788
|
let observationStr = String(observation);
|
|
2610
2789
|
if (observationStr.length > 100) {
|
|
@@ -2639,8 +2818,10 @@ var MCPAgent = class {
|
|
|
2639
2818
|
}
|
|
2640
2819
|
}
|
|
2641
2820
|
}
|
|
2642
|
-
if (
|
|
2643
|
-
finalOutput = this._normalizeOutput(
|
|
2821
|
+
if (this._isAIMessageLike(message) && !this._messageHasToolCalls(message)) {
|
|
2822
|
+
finalOutput = this._normalizeOutput(
|
|
2823
|
+
this._getMessageContent(message)
|
|
2824
|
+
);
|
|
2644
2825
|
logger.info("\u2705 Agent finished with output");
|
|
2645
2826
|
}
|
|
2646
2827
|
}
|
|
@@ -2823,10 +3004,12 @@ var MCPAgent = class {
|
|
|
2823
3004
|
const historyToUse = externalHistory ?? this.conversationHistory;
|
|
2824
3005
|
const langchainHistory = [];
|
|
2825
3006
|
for (const msg of historyToUse) {
|
|
2826
|
-
if (msg
|
|
3007
|
+
if (this._isHumanMessageLike(msg) || this._isAIMessageLike(msg) || this._isToolMessageLike(msg)) {
|
|
2827
3008
|
langchainHistory.push(msg);
|
|
2828
3009
|
} else {
|
|
2829
|
-
logger.info(
|
|
3010
|
+
logger.info(
|
|
3011
|
+
`\u26A0\uFE0F Skipped message of type: ${msg.constructor?.name || typeof msg}`
|
|
3012
|
+
);
|
|
2830
3013
|
}
|
|
2831
3014
|
}
|
|
2832
3015
|
const inputs = [
|
package/dist/src/agents/index.js
CHANGED
|
@@ -2,11 +2,11 @@ import type { BaseCallbackHandler } from "@langchain/core/callbacks/base";
|
|
|
2
2
|
import type { BaseLanguageModelInterface, LanguageModelLike } from "@langchain/core/language_models/base";
|
|
3
3
|
import type { StructuredToolInterface } from "@langchain/core/tools";
|
|
4
4
|
import type { StreamEvent } from "@langchain/core/tracers/log_stream";
|
|
5
|
+
import { SystemMessage } from "langchain";
|
|
5
6
|
import type { ZodSchema } from "zod";
|
|
7
|
+
import { LangChainAdapter } from "../adapters/langchain_adapter.js";
|
|
6
8
|
import type { MCPClient } from "../client.js";
|
|
7
9
|
import type { BaseConnector } from "../connectors/base.js";
|
|
8
|
-
import { SystemMessage } from "langchain";
|
|
9
|
-
import { LangChainAdapter } from "../adapters/langchain_adapter.js";
|
|
10
10
|
import { ServerManager } from "../managers/server_manager.js";
|
|
11
11
|
import { ObservabilityManager } from "../observability/index.js";
|
|
12
12
|
import type { BaseMessage } from "./types.js";
|
|
@@ -130,6 +130,94 @@ export declare class MCPAgent {
|
|
|
130
130
|
*/
|
|
131
131
|
private getMCPServerInfo;
|
|
132
132
|
private _normalizeOutput;
|
|
133
|
+
/**
|
|
134
|
+
* Check if a message is AI/assistant-like regardless of whether it's a class instance.
|
|
135
|
+
* Handles version mismatches, serialization boundaries, and different message formats.
|
|
136
|
+
*
|
|
137
|
+
* This method solves the issue where messages from LangChain agents may be plain JavaScript
|
|
138
|
+
* objects (e.g., `{ type: 'ai', content: '...' }`) instead of AIMessage instances due to
|
|
139
|
+
* serialization/deserialization across module boundaries or version mismatches.
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* // Real AIMessage instance (standard case)
|
|
143
|
+
* _isAIMessageLike(new AIMessage("hello")) // => true
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* // Plain object after serialization (fixes issue #446)
|
|
147
|
+
* _isAIMessageLike({ type: "ai", content: "hello" }) // => true
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* // OpenAI-style format with role
|
|
151
|
+
* _isAIMessageLike({ role: "assistant", content: "hello" }) // => true
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* // Object with getType() method
|
|
155
|
+
* _isAIMessageLike({ getType: () => "ai", content: "hello" }) // => true
|
|
156
|
+
*
|
|
157
|
+
* @param message - The message object to check
|
|
158
|
+
* @returns true if the message represents an AI/assistant message
|
|
159
|
+
*/
|
|
160
|
+
private _isAIMessageLike;
|
|
161
|
+
/**
|
|
162
|
+
* Check if a message has tool calls, handling both class instances and plain objects.
|
|
163
|
+
* Safely checks for tool_calls array presence.
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* // AIMessage with tool calls
|
|
167
|
+
* const msg = new AIMessage({ content: "", tool_calls: [{ name: "add", args: {} }] });
|
|
168
|
+
* _messageHasToolCalls(msg) // => true
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* // Plain object with tool calls
|
|
172
|
+
* _messageHasToolCalls({ type: "ai", tool_calls: [{ name: "add" }] }) // => true
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
* // Message without tool calls
|
|
176
|
+
* _messageHasToolCalls({ type: "ai", content: "hello" }) // => false
|
|
177
|
+
*
|
|
178
|
+
* @param message - The message object to check
|
|
179
|
+
* @returns true if the message has non-empty tool_calls array
|
|
180
|
+
*/
|
|
181
|
+
private _messageHasToolCalls;
|
|
182
|
+
/**
|
|
183
|
+
* Check if a message is a HumanMessage-like object.
|
|
184
|
+
* Handles both class instances and plain objects from serialization.
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* _isHumanMessageLike(new HumanMessage("hello")) // => true
|
|
188
|
+
* _isHumanMessageLike({ type: "human", content: "hello" }) // => true
|
|
189
|
+
*
|
|
190
|
+
* @param message - The message object to check
|
|
191
|
+
* @returns true if the message represents a human message
|
|
192
|
+
*/
|
|
193
|
+
private _isHumanMessageLike;
|
|
194
|
+
/**
|
|
195
|
+
* Check if a message is a ToolMessage-like object.
|
|
196
|
+
* Handles both class instances and plain objects from serialization.
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* _isToolMessageLike(new ToolMessage({ content: "result", tool_call_id: "123" })) // => true
|
|
200
|
+
* _isToolMessageLike({ type: "tool", content: "result" }) // => true
|
|
201
|
+
*
|
|
202
|
+
* @param message - The message object to check
|
|
203
|
+
* @returns true if the message represents a tool message
|
|
204
|
+
*/
|
|
205
|
+
private _isToolMessageLike;
|
|
206
|
+
/**
|
|
207
|
+
* Extract content from a message, handling both AIMessage instances and plain objects.
|
|
208
|
+
*
|
|
209
|
+
* @example
|
|
210
|
+
* // From AIMessage instance
|
|
211
|
+
* _getMessageContent(new AIMessage("hello")) // => "hello"
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* // From plain object
|
|
215
|
+
* _getMessageContent({ type: "ai", content: "hello" }) // => "hello"
|
|
216
|
+
*
|
|
217
|
+
* @param message - The message object to extract content from
|
|
218
|
+
* @returns The content of the message, or undefined if not present
|
|
219
|
+
*/
|
|
220
|
+
private _getMessageContent;
|
|
133
221
|
private _consumeAndReturn;
|
|
134
222
|
/**
|
|
135
223
|
* Runs the agent and returns a promise for the final result.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp_agent.d.ts","sourceRoot":"","sources":["../../../src/agents/mcp_agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,KAAK,EACV,0BAA0B,EAC1B,iBAAiB,EAClB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,
|
|
1
|
+
{"version":3,"file":"mcp_agent.d.ts","sourceRoot":"","sources":["../../../src/agents/mcp_agent.ts"],"names":[],"mappings":"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"}
|
package/dist/src/browser.cjs
CHANGED
|
@@ -814,6 +814,7 @@ var BaseConnector = class {
|
|
|
814
814
|
connectionManager = null;
|
|
815
815
|
toolsCache = null;
|
|
816
816
|
capabilitiesCache = null;
|
|
817
|
+
serverInfoCache = null;
|
|
817
818
|
connected = false;
|
|
818
819
|
opts;
|
|
819
820
|
constructor(opts = {}) {
|
|
@@ -848,6 +849,8 @@ var BaseConnector = class {
|
|
|
848
849
|
logger.debug("Caching server capabilities & tools");
|
|
849
850
|
const capabilities = this.client.getServerCapabilities();
|
|
850
851
|
this.capabilitiesCache = capabilities;
|
|
852
|
+
const serverInfo = this.client.getServerVersion();
|
|
853
|
+
this.serverInfoCache = serverInfo || null;
|
|
851
854
|
const listToolsRes = await this.client.listTools(
|
|
852
855
|
void 0,
|
|
853
856
|
defaultRequestOptions
|
|
@@ -855,6 +858,7 @@ var BaseConnector = class {
|
|
|
855
858
|
this.toolsCache = listToolsRes.tools ?? [];
|
|
856
859
|
logger.debug(`Fetched ${this.toolsCache.length} tools from server`);
|
|
857
860
|
logger.debug("Server capabilities:", capabilities);
|
|
861
|
+
logger.debug("Server info:", serverInfo);
|
|
858
862
|
return capabilities;
|
|
859
863
|
}
|
|
860
864
|
/** Lazily expose the cached tools list. */
|
|
@@ -864,6 +868,14 @@ var BaseConnector = class {
|
|
|
864
868
|
}
|
|
865
869
|
return this.toolsCache;
|
|
866
870
|
}
|
|
871
|
+
/** Expose cached server capabilities. */
|
|
872
|
+
get serverCapabilities() {
|
|
873
|
+
return this.capabilitiesCache;
|
|
874
|
+
}
|
|
875
|
+
/** Expose cached server info. */
|
|
876
|
+
get serverInfo() {
|
|
877
|
+
return this.serverInfoCache;
|
|
878
|
+
}
|
|
867
879
|
/** Call a tool on the server. */
|
|
868
880
|
async callTool(name, args, options) {
|
|
869
881
|
if (!this.client) {
|
|
@@ -3523,6 +3535,185 @@ var MCPAgent = class {
|
|
|
3523
3535
|
return String(value);
|
|
3524
3536
|
}
|
|
3525
3537
|
}
|
|
3538
|
+
/**
|
|
3539
|
+
* Check if a message is AI/assistant-like regardless of whether it's a class instance.
|
|
3540
|
+
* Handles version mismatches, serialization boundaries, and different message formats.
|
|
3541
|
+
*
|
|
3542
|
+
* This method solves the issue where messages from LangChain agents may be plain JavaScript
|
|
3543
|
+
* objects (e.g., `{ type: 'ai', content: '...' }`) instead of AIMessage instances due to
|
|
3544
|
+
* serialization/deserialization across module boundaries or version mismatches.
|
|
3545
|
+
*
|
|
3546
|
+
* @example
|
|
3547
|
+
* // Real AIMessage instance (standard case)
|
|
3548
|
+
* _isAIMessageLike(new AIMessage("hello")) // => true
|
|
3549
|
+
*
|
|
3550
|
+
* @example
|
|
3551
|
+
* // Plain object after serialization (fixes issue #446)
|
|
3552
|
+
* _isAIMessageLike({ type: "ai", content: "hello" }) // => true
|
|
3553
|
+
*
|
|
3554
|
+
* @example
|
|
3555
|
+
* // OpenAI-style format with role
|
|
3556
|
+
* _isAIMessageLike({ role: "assistant", content: "hello" }) // => true
|
|
3557
|
+
*
|
|
3558
|
+
* @example
|
|
3559
|
+
* // Object with getType() method
|
|
3560
|
+
* _isAIMessageLike({ getType: () => "ai", content: "hello" }) // => true
|
|
3561
|
+
*
|
|
3562
|
+
* @param message - The message object to check
|
|
3563
|
+
* @returns true if the message represents an AI/assistant message
|
|
3564
|
+
*/
|
|
3565
|
+
_isAIMessageLike(message) {
|
|
3566
|
+
if (message instanceof import_langchain2.AIMessage) {
|
|
3567
|
+
return true;
|
|
3568
|
+
}
|
|
3569
|
+
if (typeof message !== "object" || message === null) {
|
|
3570
|
+
return false;
|
|
3571
|
+
}
|
|
3572
|
+
const msg = message;
|
|
3573
|
+
if (typeof msg.getType === "function") {
|
|
3574
|
+
try {
|
|
3575
|
+
const type = msg.getType();
|
|
3576
|
+
if (type === "ai" || type === "assistant") {
|
|
3577
|
+
return true;
|
|
3578
|
+
}
|
|
3579
|
+
} catch (error) {
|
|
3580
|
+
}
|
|
3581
|
+
}
|
|
3582
|
+
if (typeof msg._getType === "function") {
|
|
3583
|
+
try {
|
|
3584
|
+
const type = msg._getType();
|
|
3585
|
+
if (type === "ai" || type === "assistant") {
|
|
3586
|
+
return true;
|
|
3587
|
+
}
|
|
3588
|
+
} catch (error) {
|
|
3589
|
+
}
|
|
3590
|
+
}
|
|
3591
|
+
if ("type" in msg) {
|
|
3592
|
+
return msg.type === "ai" || msg.type === "assistant";
|
|
3593
|
+
}
|
|
3594
|
+
if ("role" in msg) {
|
|
3595
|
+
return msg.role === "ai" || msg.role === "assistant";
|
|
3596
|
+
}
|
|
3597
|
+
return false;
|
|
3598
|
+
}
|
|
3599
|
+
/**
|
|
3600
|
+
* Check if a message has tool calls, handling both class instances and plain objects.
|
|
3601
|
+
* Safely checks for tool_calls array presence.
|
|
3602
|
+
*
|
|
3603
|
+
* @example
|
|
3604
|
+
* // AIMessage with tool calls
|
|
3605
|
+
* const msg = new AIMessage({ content: "", tool_calls: [{ name: "add", args: {} }] });
|
|
3606
|
+
* _messageHasToolCalls(msg) // => true
|
|
3607
|
+
*
|
|
3608
|
+
* @example
|
|
3609
|
+
* // Plain object with tool calls
|
|
3610
|
+
* _messageHasToolCalls({ type: "ai", tool_calls: [{ name: "add" }] }) // => true
|
|
3611
|
+
*
|
|
3612
|
+
* @example
|
|
3613
|
+
* // Message without tool calls
|
|
3614
|
+
* _messageHasToolCalls({ type: "ai", content: "hello" }) // => false
|
|
3615
|
+
*
|
|
3616
|
+
* @param message - The message object to check
|
|
3617
|
+
* @returns true if the message has non-empty tool_calls array
|
|
3618
|
+
*/
|
|
3619
|
+
_messageHasToolCalls(message) {
|
|
3620
|
+
if (typeof message === "object" && message !== null && "tool_calls" in message && Array.isArray(message.tool_calls)) {
|
|
3621
|
+
return message.tool_calls.length > 0;
|
|
3622
|
+
}
|
|
3623
|
+
return false;
|
|
3624
|
+
}
|
|
3625
|
+
/**
|
|
3626
|
+
* Check if a message is a HumanMessage-like object.
|
|
3627
|
+
* Handles both class instances and plain objects from serialization.
|
|
3628
|
+
*
|
|
3629
|
+
* @example
|
|
3630
|
+
* _isHumanMessageLike(new HumanMessage("hello")) // => true
|
|
3631
|
+
* _isHumanMessageLike({ type: "human", content: "hello" }) // => true
|
|
3632
|
+
*
|
|
3633
|
+
* @param message - The message object to check
|
|
3634
|
+
* @returns true if the message represents a human message
|
|
3635
|
+
*/
|
|
3636
|
+
_isHumanMessageLike(message) {
|
|
3637
|
+
if (message instanceof import_langchain2.HumanMessage) {
|
|
3638
|
+
return true;
|
|
3639
|
+
}
|
|
3640
|
+
if (typeof message !== "object" || message === null) {
|
|
3641
|
+
return false;
|
|
3642
|
+
}
|
|
3643
|
+
const msg = message;
|
|
3644
|
+
if (typeof msg.getType === "function") {
|
|
3645
|
+
try {
|
|
3646
|
+
const type = msg.getType();
|
|
3647
|
+
if (type === "human" || type === "user") {
|
|
3648
|
+
return true;
|
|
3649
|
+
}
|
|
3650
|
+
} catch (error) {
|
|
3651
|
+
}
|
|
3652
|
+
}
|
|
3653
|
+
if ("type" in msg && (msg.type === "human" || msg.type === "user")) {
|
|
3654
|
+
return true;
|
|
3655
|
+
}
|
|
3656
|
+
if ("role" in msg && (msg.role === "human" || msg.role === "user")) {
|
|
3657
|
+
return true;
|
|
3658
|
+
}
|
|
3659
|
+
return false;
|
|
3660
|
+
}
|
|
3661
|
+
/**
|
|
3662
|
+
* Check if a message is a ToolMessage-like object.
|
|
3663
|
+
* Handles both class instances and plain objects from serialization.
|
|
3664
|
+
*
|
|
3665
|
+
* @example
|
|
3666
|
+
* _isToolMessageLike(new ToolMessage({ content: "result", tool_call_id: "123" })) // => true
|
|
3667
|
+
* _isToolMessageLike({ type: "tool", content: "result" }) // => true
|
|
3668
|
+
*
|
|
3669
|
+
* @param message - The message object to check
|
|
3670
|
+
* @returns true if the message represents a tool message
|
|
3671
|
+
*/
|
|
3672
|
+
_isToolMessageLike(message) {
|
|
3673
|
+
if (message instanceof import_langchain2.ToolMessage) {
|
|
3674
|
+
return true;
|
|
3675
|
+
}
|
|
3676
|
+
if (typeof message !== "object" || message === null) {
|
|
3677
|
+
return false;
|
|
3678
|
+
}
|
|
3679
|
+
const msg = message;
|
|
3680
|
+
if (typeof msg.getType === "function") {
|
|
3681
|
+
try {
|
|
3682
|
+
const type = msg.getType();
|
|
3683
|
+
if (type === "tool") {
|
|
3684
|
+
return true;
|
|
3685
|
+
}
|
|
3686
|
+
} catch (error) {
|
|
3687
|
+
}
|
|
3688
|
+
}
|
|
3689
|
+
if ("type" in msg && msg.type === "tool") {
|
|
3690
|
+
return true;
|
|
3691
|
+
}
|
|
3692
|
+
return false;
|
|
3693
|
+
}
|
|
3694
|
+
/**
|
|
3695
|
+
* Extract content from a message, handling both AIMessage instances and plain objects.
|
|
3696
|
+
*
|
|
3697
|
+
* @example
|
|
3698
|
+
* // From AIMessage instance
|
|
3699
|
+
* _getMessageContent(new AIMessage("hello")) // => "hello"
|
|
3700
|
+
*
|
|
3701
|
+
* @example
|
|
3702
|
+
* // From plain object
|
|
3703
|
+
* _getMessageContent({ type: "ai", content: "hello" }) // => "hello"
|
|
3704
|
+
*
|
|
3705
|
+
* @param message - The message object to extract content from
|
|
3706
|
+
* @returns The content of the message, or undefined if not present
|
|
3707
|
+
*/
|
|
3708
|
+
_getMessageContent(message) {
|
|
3709
|
+
if (message instanceof import_langchain2.AIMessage) {
|
|
3710
|
+
return message.content;
|
|
3711
|
+
}
|
|
3712
|
+
if (message && typeof message === "object" && "content" in message) {
|
|
3713
|
+
return message.content;
|
|
3714
|
+
}
|
|
3715
|
+
return void 0;
|
|
3716
|
+
}
|
|
3526
3717
|
async _consumeAndReturn(generator) {
|
|
3527
3718
|
while (true) {
|
|
3528
3719
|
const { done, value } = await generator.next();
|
|
@@ -3594,7 +3785,7 @@ var MCPAgent = class {
|
|
|
3594
3785
|
const historyToUse = externalHistory ?? this.conversationHistory;
|
|
3595
3786
|
const langchainHistory = [];
|
|
3596
3787
|
for (const msg of historyToUse) {
|
|
3597
|
-
if (msg
|
|
3788
|
+
if (this._isHumanMessageLike(msg) || this._isAIMessageLike(msg)) {
|
|
3598
3789
|
langchainHistory.push(msg);
|
|
3599
3790
|
}
|
|
3600
3791
|
}
|
|
@@ -3663,7 +3854,7 @@ var MCPAgent = class {
|
|
|
3663
3854
|
};
|
|
3664
3855
|
}
|
|
3665
3856
|
}
|
|
3666
|
-
if (
|
|
3857
|
+
if (this._isToolMessageLike(message)) {
|
|
3667
3858
|
const observation = message.content;
|
|
3668
3859
|
let observationStr = String(observation);
|
|
3669
3860
|
if (observationStr.length > 100) {
|
|
@@ -3698,8 +3889,10 @@ var MCPAgent = class {
|
|
|
3698
3889
|
}
|
|
3699
3890
|
}
|
|
3700
3891
|
}
|
|
3701
|
-
if (
|
|
3702
|
-
finalOutput = this._normalizeOutput(
|
|
3892
|
+
if (this._isAIMessageLike(message) && !this._messageHasToolCalls(message)) {
|
|
3893
|
+
finalOutput = this._normalizeOutput(
|
|
3894
|
+
this._getMessageContent(message)
|
|
3895
|
+
);
|
|
3703
3896
|
logger.info("\u2705 Agent finished with output");
|
|
3704
3897
|
}
|
|
3705
3898
|
}
|
|
@@ -3882,10 +4075,12 @@ var MCPAgent = class {
|
|
|
3882
4075
|
const historyToUse = externalHistory ?? this.conversationHistory;
|
|
3883
4076
|
const langchainHistory = [];
|
|
3884
4077
|
for (const msg of historyToUse) {
|
|
3885
|
-
if (msg
|
|
4078
|
+
if (this._isHumanMessageLike(msg) || this._isAIMessageLike(msg) || this._isToolMessageLike(msg)) {
|
|
3886
4079
|
langchainHistory.push(msg);
|
|
3887
4080
|
} else {
|
|
3888
|
-
logger.info(
|
|
4081
|
+
logger.info(
|
|
4082
|
+
`\u26A0\uFE0F Skipped message of type: ${msg.constructor?.name || typeof msg}`
|
|
4083
|
+
);
|
|
3889
4084
|
}
|
|
3890
4085
|
}
|
|
3891
4086
|
const inputs = [
|
package/dist/src/browser.js
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
MCPAgent,
|
|
10
10
|
ObservabilityManager,
|
|
11
11
|
RemoteAgent
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-6EHM3S3M.js";
|
|
13
13
|
import {
|
|
14
14
|
BaseConnector,
|
|
15
15
|
BrowserMCPClient,
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
MCPSession,
|
|
19
19
|
WebSocketConnector,
|
|
20
20
|
onMcpAuthorization
|
|
21
|
-
} from "../chunk-
|
|
21
|
+
} from "../chunk-TIUSJAAE.js";
|
|
22
22
|
import "../chunk-YURRUCIM.js";
|
|
23
23
|
import {
|
|
24
24
|
Logger,
|
|
@@ -25,6 +25,10 @@ export declare abstract class BaseConnector {
|
|
|
25
25
|
protected connectionManager: ConnectionManager<any> | null;
|
|
26
26
|
protected toolsCache: Tool[] | null;
|
|
27
27
|
protected capabilitiesCache: any;
|
|
28
|
+
protected serverInfoCache: {
|
|
29
|
+
name: string;
|
|
30
|
+
version?: string;
|
|
31
|
+
} | null;
|
|
28
32
|
protected connected: boolean;
|
|
29
33
|
protected readonly opts: ConnectorInitOptions;
|
|
30
34
|
constructor(opts?: ConnectorInitOptions);
|
|
@@ -46,6 +50,13 @@ export declare abstract class BaseConnector {
|
|
|
46
50
|
initialize(defaultRequestOptions?: RequestOptions): Promise<ReturnType<Client["getServerCapabilities"]>>;
|
|
47
51
|
/** Lazily expose the cached tools list. */
|
|
48
52
|
get tools(): Tool[];
|
|
53
|
+
/** Expose cached server capabilities. */
|
|
54
|
+
get serverCapabilities(): any;
|
|
55
|
+
/** Expose cached server info. */
|
|
56
|
+
get serverInfo(): {
|
|
57
|
+
name: string;
|
|
58
|
+
version?: string;
|
|
59
|
+
} | null;
|
|
49
60
|
/** Call a tool on the server. */
|
|
50
61
|
callTool(name: string, args: Record<string, any>, options?: RequestOptions): Promise<CallToolResult>;
|
|
51
62
|
/**
|