mcp-use 1.3.0-canary.0 → 1.3.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/dist/.tsbuildinfo +1 -1
- package/dist/{chunk-73SH52J2.js → chunk-6EHM3S3M.js} +191 -8
- package/dist/index.cjs +189 -6
- package/dist/index.js +1 -1
- 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 +189 -6
- package/dist/src/browser.js +1 -1
- package/dist/src/server/index.cjs +34 -13
- package/dist/src/server/index.js +34 -13
- package/dist/src/server/mcp-server.d.ts +5 -0
- package/dist/src/server/mcp-server.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -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
|
@@ -3535,6 +3535,185 @@ var MCPAgent = class {
|
|
|
3535
3535
|
return String(value);
|
|
3536
3536
|
}
|
|
3537
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
|
+
}
|
|
3538
3717
|
async _consumeAndReturn(generator) {
|
|
3539
3718
|
while (true) {
|
|
3540
3719
|
const { done, value } = await generator.next();
|
|
@@ -3606,7 +3785,7 @@ var MCPAgent = class {
|
|
|
3606
3785
|
const historyToUse = externalHistory ?? this.conversationHistory;
|
|
3607
3786
|
const langchainHistory = [];
|
|
3608
3787
|
for (const msg of historyToUse) {
|
|
3609
|
-
if (msg
|
|
3788
|
+
if (this._isHumanMessageLike(msg) || this._isAIMessageLike(msg)) {
|
|
3610
3789
|
langchainHistory.push(msg);
|
|
3611
3790
|
}
|
|
3612
3791
|
}
|
|
@@ -3675,7 +3854,7 @@ var MCPAgent = class {
|
|
|
3675
3854
|
};
|
|
3676
3855
|
}
|
|
3677
3856
|
}
|
|
3678
|
-
if (
|
|
3857
|
+
if (this._isToolMessageLike(message)) {
|
|
3679
3858
|
const observation = message.content;
|
|
3680
3859
|
let observationStr = String(observation);
|
|
3681
3860
|
if (observationStr.length > 100) {
|
|
@@ -3710,8 +3889,10 @@ var MCPAgent = class {
|
|
|
3710
3889
|
}
|
|
3711
3890
|
}
|
|
3712
3891
|
}
|
|
3713
|
-
if (
|
|
3714
|
-
finalOutput = this._normalizeOutput(
|
|
3892
|
+
if (this._isAIMessageLike(message) && !this._messageHasToolCalls(message)) {
|
|
3893
|
+
finalOutput = this._normalizeOutput(
|
|
3894
|
+
this._getMessageContent(message)
|
|
3895
|
+
);
|
|
3715
3896
|
logger.info("\u2705 Agent finished with output");
|
|
3716
3897
|
}
|
|
3717
3898
|
}
|
|
@@ -3894,10 +4075,12 @@ var MCPAgent = class {
|
|
|
3894
4075
|
const historyToUse = externalHistory ?? this.conversationHistory;
|
|
3895
4076
|
const langchainHistory = [];
|
|
3896
4077
|
for (const msg of historyToUse) {
|
|
3897
|
-
if (msg
|
|
4078
|
+
if (this._isHumanMessageLike(msg) || this._isAIMessageLike(msg) || this._isToolMessageLike(msg)) {
|
|
3898
4079
|
langchainHistory.push(msg);
|
|
3899
4080
|
} else {
|
|
3900
|
-
logger.info(
|
|
4081
|
+
logger.info(
|
|
4082
|
+
`\u26A0\uFE0F Skipped message of type: ${msg.constructor?.name || typeof msg}`
|
|
4083
|
+
);
|
|
3901
4084
|
}
|
|
3902
4085
|
}
|
|
3903
4086
|
const inputs = [
|