mcp-use 1.1.8-canary.1 → 1.2.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/README.md +1 -1
- package/dist/.tsbuildinfo +1 -0
- package/dist/{chunk-4SWVHFJH.js → chunk-GKNOUQFQ.js} +284 -208
- package/dist/{chunk-2HFIPY7C.js → chunk-ZUEQQ6YK.js} +17 -2
- package/dist/index.cjs +315 -220
- package/dist/index.js +2 -2
- package/dist/{langfuse-YA2S23SM.js → langfuse-6AJGHMAV.js} +1 -1
- package/dist/src/agents/mcp_agent.d.ts +33 -8
- package/dist/src/agents/mcp_agent.d.ts.map +1 -1
- package/dist/src/agents/prompts/system_prompt_builder.d.ts +1 -1
- package/dist/src/agents/prompts/system_prompt_builder.d.ts.map +1 -1
- package/dist/src/browser.cjs +315 -220
- package/dist/src/browser.js +2 -2
- package/dist/src/managers/server_manager.d.ts +2 -1
- package/dist/src/managers/server_manager.d.ts.map +1 -1
- package/dist/src/managers/tools/acquire_active_mcp_server.d.ts +2 -2
- package/dist/src/managers/tools/acquire_active_mcp_server.d.ts.map +1 -1
- package/dist/src/managers/tools/add_server_from_config.d.ts +3 -3
- package/dist/src/managers/tools/add_server_from_config.d.ts.map +1 -1
- package/dist/src/managers/tools/base.d.ts +3 -3
- package/dist/src/managers/tools/base.d.ts.map +1 -1
- package/dist/src/managers/tools/connect_mcp_server.d.ts +2 -2
- package/dist/src/managers/tools/connect_mcp_server.d.ts.map +1 -1
- package/dist/src/managers/tools/list_mcp_servers.d.ts +2 -2
- package/dist/src/managers/tools/list_mcp_servers.d.ts.map +1 -1
- package/dist/src/managers/tools/release_mcp_server_connection.d.ts +2 -2
- package/dist/src/managers/tools/release_mcp_server_connection.d.ts.map +1 -1
- package/dist/src/managers/types.d.ts +14 -0
- package/dist/src/managers/types.d.ts.map +1 -0
- package/dist/src/observability/langfuse.d.ts.map +1 -1
- package/dist/src/observability/manager.d.ts +11 -0
- package/dist/src/observability/manager.d.ts.map +1 -1
- package/dist/tsup.config.d.ts.map +1 -1
- package/package.json +33 -13
- package/dist/tests/ai_sdk_compatibility.test.d.ts +0 -13
- package/dist/tests/ai_sdk_compatibility.test.d.ts.map +0 -1
- package/dist/tests/helpers/widget-generators.d.ts +0 -24
- package/dist/tests/helpers/widget-generators.d.ts.map +0 -1
- package/dist/tests/mcp-ui-adapter.test.d.ts +0 -8
- package/dist/tests/mcp-ui-adapter.test.d.ts.map +0 -1
- package/dist/tests/stream_events.test.d.ts +0 -12
- package/dist/tests/stream_events.test.d.ts.map +0 -1
- package/dist/tests/stream_events_simple.test.d.ts +0 -7
- package/dist/tests/stream_events_simple.test.d.ts.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
logger
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ZUEQQ6YK.js";
|
|
4
4
|
import {
|
|
5
5
|
__name
|
|
6
6
|
} from "./chunk-SHUYVCID.js";
|
|
@@ -212,7 +212,7 @@ var AcquireActiveMCPServerTool = class extends MCPServerTool {
|
|
|
212
212
|
};
|
|
213
213
|
|
|
214
214
|
// src/managers/tools/add_server_from_config.ts
|
|
215
|
-
import { StructuredTool as StructuredTool2 } from "langchain/tools";
|
|
215
|
+
import { StructuredTool as StructuredTool2 } from "@langchain/core/tools";
|
|
216
216
|
import { z as z3 } from "zod";
|
|
217
217
|
var AddMCPServerFromConfigTool = class extends StructuredTool2 {
|
|
218
218
|
static {
|
|
@@ -510,9 +510,9 @@ var ObservabilityManager = class {
|
|
|
510
510
|
return;
|
|
511
511
|
}
|
|
512
512
|
try {
|
|
513
|
-
const { langfuseHandler: langfuseHandler2, langfuseInitPromise: langfuseInitPromise2 } = await import("./langfuse-
|
|
513
|
+
const { langfuseHandler: langfuseHandler2, langfuseInitPromise: langfuseInitPromise2 } = await import("./langfuse-6AJGHMAV.js");
|
|
514
514
|
if (this.agentId || this.metadata || this.metadataProvider || this.tagsProvider) {
|
|
515
|
-
const { initializeLangfuse } = await import("./langfuse-
|
|
515
|
+
const { initializeLangfuse } = await import("./langfuse-6AJGHMAV.js");
|
|
516
516
|
await initializeLangfuse(this.agentId, this.metadata, this.metadataProvider, this.tagsProvider);
|
|
517
517
|
logger.debug(`ObservabilityManager: Reinitialized Langfuse with agent ID: ${this.agentId}, metadata: ${JSON.stringify(this.metadata)}`);
|
|
518
518
|
} else {
|
|
@@ -578,6 +578,23 @@ var ObservabilityManager = class {
|
|
|
578
578
|
const callbacks = await this.getCallbacks();
|
|
579
579
|
return callbacks.length > 0;
|
|
580
580
|
}
|
|
581
|
+
/**
|
|
582
|
+
* Get the current observability status including metadata and tags.
|
|
583
|
+
* @returns Object containing enabled status, callback count, handler names, metadata, and tags.
|
|
584
|
+
*/
|
|
585
|
+
async getStatus() {
|
|
586
|
+
const callbacks = await this.getCallbacks();
|
|
587
|
+
const handlerNames = await this.getHandlerNames();
|
|
588
|
+
const currentMetadata = this.metadataProvider ? this.metadataProvider() : this.metadata || {};
|
|
589
|
+
const currentTags = this.tagsProvider ? this.tagsProvider() : [];
|
|
590
|
+
return {
|
|
591
|
+
enabled: this.observe && callbacks.length > 0,
|
|
592
|
+
callbackCount: callbacks.length,
|
|
593
|
+
handlerNames,
|
|
594
|
+
metadata: currentMetadata,
|
|
595
|
+
tags: currentTags
|
|
596
|
+
};
|
|
597
|
+
}
|
|
581
598
|
/**
|
|
582
599
|
* Add a callback to the custom callbacks list.
|
|
583
600
|
* @param callback The callback to add.
|
|
@@ -1232,23 +1249,16 @@ Raw error: ${result}`
|
|
|
1232
1249
|
};
|
|
1233
1250
|
|
|
1234
1251
|
// src/agents/mcp_agent.ts
|
|
1235
|
-
import { CallbackManager } from "@langchain/core/callbacks/manager";
|
|
1236
1252
|
import {
|
|
1237
1253
|
AIMessage,
|
|
1238
1254
|
HumanMessage,
|
|
1239
|
-
SystemMessage as SystemMessage2,
|
|
1240
1255
|
ToolMessage
|
|
1241
1256
|
} from "@langchain/core/messages";
|
|
1242
|
-
import {
|
|
1243
|
-
import {
|
|
1244
|
-
ChatPromptTemplate,
|
|
1245
|
-
MessagesPlaceholder
|
|
1246
|
-
} from "@langchain/core/prompts";
|
|
1247
|
-
import { AgentExecutor, createToolCallingAgent } from "langchain/agents";
|
|
1257
|
+
import { createAgent, modelCallLimitMiddleware, SystemMessage as SystemMessage2 } from "langchain";
|
|
1248
1258
|
import { zodToJsonSchema as zodToJsonSchema2 } from "zod-to-json-schema";
|
|
1249
1259
|
|
|
1250
1260
|
// src/agents/prompts/system_prompt_builder.ts
|
|
1251
|
-
import { SystemMessage } from "
|
|
1261
|
+
import { SystemMessage } from "langchain";
|
|
1252
1262
|
function generateToolDescriptions(tools, disallowedTools) {
|
|
1253
1263
|
const disallowedSet = new Set(disallowedTools ?? []);
|
|
1254
1264
|
const descriptions = [];
|
|
@@ -1350,6 +1360,7 @@ var MCPAgent = class {
|
|
|
1350
1360
|
memoryEnabled;
|
|
1351
1361
|
disallowedTools;
|
|
1352
1362
|
additionalTools;
|
|
1363
|
+
toolsUsedNames = [];
|
|
1353
1364
|
useServerManager;
|
|
1354
1365
|
verbose;
|
|
1355
1366
|
observe;
|
|
@@ -1417,6 +1428,7 @@ var MCPAgent = class {
|
|
|
1417
1428
|
this.additionalInstructions = options.additionalInstructions ?? null;
|
|
1418
1429
|
this.disallowedTools = options.disallowedTools ?? [];
|
|
1419
1430
|
this.additionalTools = options.additionalTools ?? [];
|
|
1431
|
+
this.toolsUsedNames = options.toolsUsedNames ?? [];
|
|
1420
1432
|
this.useServerManager = options.useServerManager ?? false;
|
|
1421
1433
|
this.verbose = options.verbose ?? false;
|
|
1422
1434
|
this.observe = options.observe ?? true;
|
|
@@ -1540,25 +1552,17 @@ var MCPAgent = class {
|
|
|
1540
1552
|
throw new Error("LLM is required to create agent");
|
|
1541
1553
|
}
|
|
1542
1554
|
const systemContent = this.systemMessage?.content ?? "You are a helpful assistant.";
|
|
1543
|
-
const
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
]);
|
|
1549
|
-
const agent = createToolCallingAgent({
|
|
1550
|
-
llm: this.llm,
|
|
1551
|
-
tools: this._tools,
|
|
1552
|
-
prompt
|
|
1553
|
-
});
|
|
1554
|
-
return new AgentExecutor({
|
|
1555
|
-
agent,
|
|
1555
|
+
const toolNames = this._tools.map((tool) => tool.name);
|
|
1556
|
+
logger.info(`\u{1F9E0} Agent ready with tools: ${toolNames.join(", ")}`);
|
|
1557
|
+
const middleware = [modelCallLimitMiddleware({ runLimit: this.maxSteps })];
|
|
1558
|
+
const agent = createAgent({
|
|
1559
|
+
model: this.llm,
|
|
1556
1560
|
tools: this._tools,
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
returnIntermediateSteps: true,
|
|
1560
|
-
callbacks: this.callbacks
|
|
1561
|
+
systemPrompt: systemContent,
|
|
1562
|
+
middleware
|
|
1561
1563
|
});
|
|
1564
|
+
logger.debug(`Created agent with max_steps=${this.maxSteps} (via ModelCallLimitMiddleware) and ${this.callbacks.length} callbacks`);
|
|
1565
|
+
return agent;
|
|
1562
1566
|
}
|
|
1563
1567
|
getConversationHistory() {
|
|
1564
1568
|
return [...this.conversationHistory];
|
|
@@ -1726,6 +1730,42 @@ var MCPAgent = class {
|
|
|
1726
1730
|
}
|
|
1727
1731
|
return serverInfo;
|
|
1728
1732
|
}
|
|
1733
|
+
_normalizeOutput(value) {
|
|
1734
|
+
try {
|
|
1735
|
+
if (typeof value === "string") {
|
|
1736
|
+
return value;
|
|
1737
|
+
}
|
|
1738
|
+
if (value && typeof value === "object" && "content" in value) {
|
|
1739
|
+
return this._normalizeOutput(value.content);
|
|
1740
|
+
}
|
|
1741
|
+
if (Array.isArray(value)) {
|
|
1742
|
+
const parts = [];
|
|
1743
|
+
for (const item of value) {
|
|
1744
|
+
if (typeof item === "object" && item !== null) {
|
|
1745
|
+
if ("text" in item && typeof item.text === "string") {
|
|
1746
|
+
parts.push(item.text);
|
|
1747
|
+
} else if ("content" in item) {
|
|
1748
|
+
parts.push(this._normalizeOutput(item.content));
|
|
1749
|
+
} else {
|
|
1750
|
+
parts.push(String(item));
|
|
1751
|
+
}
|
|
1752
|
+
} else {
|
|
1753
|
+
const partText = item && typeof item === "object" && "text" in item ? item.text : null;
|
|
1754
|
+
if (typeof partText === "string") {
|
|
1755
|
+
parts.push(partText);
|
|
1756
|
+
} else {
|
|
1757
|
+
const partContent = item && typeof item === "object" && "content" in item ? item.content : item;
|
|
1758
|
+
parts.push(this._normalizeOutput(partContent));
|
|
1759
|
+
}
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
return parts.join("");
|
|
1763
|
+
}
|
|
1764
|
+
return String(value);
|
|
1765
|
+
} catch (error) {
|
|
1766
|
+
return String(value);
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1729
1769
|
async _consumeAndReturn(generator) {
|
|
1730
1770
|
while (true) {
|
|
1731
1771
|
const { done, value } = await generator.next();
|
|
@@ -1747,36 +1787,16 @@ var MCPAgent = class {
|
|
|
1747
1787
|
);
|
|
1748
1788
|
return this._consumeAndReturn(generator);
|
|
1749
1789
|
}
|
|
1750
|
-
/**
|
|
1751
|
-
* Runs the agent and yields intermediate steps as an async generator.
|
|
1752
|
-
* If outputSchema is provided, returns structured output of type T.
|
|
1753
|
-
*/
|
|
1754
1790
|
async *stream(query, maxSteps, manageConnector = true, externalHistory, outputSchema) {
|
|
1755
1791
|
if (this.isRemote && this.remoteAgent) {
|
|
1756
|
-
const
|
|
1757
|
-
return
|
|
1792
|
+
const result = await this.remoteAgent.run(query, maxSteps, manageConnector, externalHistory, outputSchema);
|
|
1793
|
+
return result;
|
|
1758
1794
|
}
|
|
1759
|
-
let result = "";
|
|
1760
1795
|
let initializedHere = false;
|
|
1761
1796
|
const startTime = Date.now();
|
|
1762
|
-
|
|
1797
|
+
let success = false;
|
|
1798
|
+
let finalOutput = null;
|
|
1763
1799
|
let stepsTaken = 0;
|
|
1764
|
-
const structuredOutputSuccess = false;
|
|
1765
|
-
const structuredOutputSuccessRef = { value: structuredOutputSuccess };
|
|
1766
|
-
let structuredLlm = null;
|
|
1767
|
-
let schemaDescription = "";
|
|
1768
|
-
if (outputSchema) {
|
|
1769
|
-
query = this._enhanceQueryWithSchema(query, outputSchema);
|
|
1770
|
-
logger.debug(`\u{1F504} Structured output requested, schema: ${JSON.stringify(zodToJsonSchema2(outputSchema), null, 2)}`);
|
|
1771
|
-
if (this.llm && "withStructuredOutput" in this.llm && typeof this.llm.withStructuredOutput === "function") {
|
|
1772
|
-
structuredLlm = this.llm.withStructuredOutput(outputSchema);
|
|
1773
|
-
} else if (this.llm) {
|
|
1774
|
-
structuredLlm = this.llm;
|
|
1775
|
-
} else {
|
|
1776
|
-
throw new Error("LLM is required for structured output");
|
|
1777
|
-
}
|
|
1778
|
-
schemaDescription = JSON.stringify(zodToJsonSchema2(outputSchema), null, 2);
|
|
1779
|
-
}
|
|
1780
1800
|
try {
|
|
1781
1801
|
if (manageConnector && !this._initialized) {
|
|
1782
1802
|
await this.initialize();
|
|
@@ -1788,12 +1808,19 @@ var MCPAgent = class {
|
|
|
1788
1808
|
if (!this._agentExecutor) {
|
|
1789
1809
|
throw new Error("MCP agent failed to initialize");
|
|
1790
1810
|
}
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1811
|
+
if (this.useServerManager && this.serverManager) {
|
|
1812
|
+
const currentTools = this.serverManager.tools;
|
|
1813
|
+
const currentToolNames = new Set(currentTools.map((t) => t.name));
|
|
1814
|
+
const existingToolNames = new Set(this._tools.map((t) => t.name));
|
|
1815
|
+
if (currentToolNames.size !== existingToolNames.size || [...currentToolNames].some((n) => !existingToolNames.has(n))) {
|
|
1816
|
+
logger.info(
|
|
1817
|
+
`\u{1F504} Tools changed before execution, updating agent. New tools: ${[...currentToolNames].join(", ")}`
|
|
1818
|
+
);
|
|
1819
|
+
this._tools = currentTools;
|
|
1820
|
+
this._tools.push(...this.additionalTools);
|
|
1821
|
+
await this.createSystemMessageFromTools(this._tools);
|
|
1822
|
+
this._agentExecutor = this.createAgent();
|
|
1823
|
+
}
|
|
1797
1824
|
}
|
|
1798
1825
|
const historyToUse = externalHistory ?? this.conversationHistory;
|
|
1799
1826
|
const langchainHistory = [];
|
|
@@ -1802,144 +1829,148 @@ var MCPAgent = class {
|
|
|
1802
1829
|
langchainHistory.push(msg);
|
|
1803
1830
|
}
|
|
1804
1831
|
}
|
|
1805
|
-
const
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
let
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
const currentToolNames = new Set(currentTools.map((t) => t.name));
|
|
1827
|
-
const existingToolNames = new Set(this._tools.map((t) => t.name));
|
|
1828
|
-
const changed = currentTools.length !== this._tools.length || [...currentToolNames].some((n) => !existingToolNames.has(n));
|
|
1829
|
-
if (changed) {
|
|
1830
|
-
logger.info(
|
|
1831
|
-
`\u{1F504} Tools changed before step ${stepNum + 1}, updating agent. New tools: ${[...currentToolNames].join(", ")}`
|
|
1832
|
-
);
|
|
1833
|
-
this._tools = currentTools;
|
|
1834
|
-
this._tools.push(...this.additionalTools);
|
|
1835
|
-
await this.createSystemMessageFromTools(this._tools);
|
|
1836
|
-
this._agentExecutor = this.createAgent();
|
|
1837
|
-
this._agentExecutor.maxIterations = steps;
|
|
1838
|
-
nameToToolMap = Object.fromEntries(this._tools.map((t) => [t.name, t]));
|
|
1832
|
+
const displayQuery = query.length > 50 ? `${query.slice(0, 50).replace(/\n/g, " ")}...` : query.replace(/\n/g, " ");
|
|
1833
|
+
logger.info(`\u{1F4AC} Received query: '${displayQuery}'`);
|
|
1834
|
+
logger.info("\u{1F3C1} Starting agent execution");
|
|
1835
|
+
const maxRestarts = 3;
|
|
1836
|
+
let restartCount = 0;
|
|
1837
|
+
const accumulatedMessages = [...langchainHistory, new HumanMessage(query)];
|
|
1838
|
+
while (restartCount <= maxRestarts) {
|
|
1839
|
+
const inputs = { messages: accumulatedMessages };
|
|
1840
|
+
let shouldRestart = false;
|
|
1841
|
+
const stream = await this._agentExecutor.stream(
|
|
1842
|
+
inputs,
|
|
1843
|
+
{
|
|
1844
|
+
streamMode: "updates",
|
|
1845
|
+
// Get updates as they happen
|
|
1846
|
+
callbacks: this.callbacks,
|
|
1847
|
+
metadata: this.getMetadata(),
|
|
1848
|
+
tags: this.getTags(),
|
|
1849
|
+
// Set trace name for LangChain/Langfuse
|
|
1850
|
+
runName: this.metadata.trace_name || "mcp-use-agent",
|
|
1851
|
+
// Pass sessionId for Langfuse if present in metadata
|
|
1852
|
+
...this.metadata.session_id && { sessionId: this.metadata.session_id }
|
|
1839
1853
|
}
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
result = nextStepOutput.returnValues?.output ?? "No output generated";
|
|
1853
|
-
runManager?.handleChainEnd({ output: result });
|
|
1854
|
-
if (outputSchema && structuredLlm) {
|
|
1855
|
-
logger.info("\u{1F527} Attempting structured output...");
|
|
1856
|
-
const currentResult = result;
|
|
1857
|
-
this._attemptStructuredOutput(
|
|
1858
|
-
currentResult,
|
|
1859
|
-
this.llm,
|
|
1860
|
-
outputSchema
|
|
1861
|
-
).then((structuredResult) => {
|
|
1862
|
-
if (this.memoryEnabled) {
|
|
1863
|
-
this.addToHistory(new AIMessage(`Structured result: ${JSON.stringify(structuredResult)}`));
|
|
1854
|
+
);
|
|
1855
|
+
for await (const chunk of stream) {
|
|
1856
|
+
for (const [nodeName, nodeOutput] of Object.entries(chunk)) {
|
|
1857
|
+
logger.debug(`\u{1F4E6} Node '${nodeName}' output: ${JSON.stringify(nodeOutput)}`);
|
|
1858
|
+
if (nodeOutput && typeof nodeOutput === "object" && "messages" in nodeOutput) {
|
|
1859
|
+
let messages = nodeOutput.messages;
|
|
1860
|
+
if (!Array.isArray(messages)) {
|
|
1861
|
+
messages = [messages];
|
|
1862
|
+
}
|
|
1863
|
+
for (const msg of messages) {
|
|
1864
|
+
if (!accumulatedMessages.includes(msg)) {
|
|
1865
|
+
accumulatedMessages.push(msg);
|
|
1864
1866
|
}
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1867
|
+
}
|
|
1868
|
+
for (const message of messages) {
|
|
1869
|
+
if ("tool_calls" in message && Array.isArray(message.tool_calls) && message.tool_calls.length > 0) {
|
|
1870
|
+
for (const toolCall of message.tool_calls) {
|
|
1871
|
+
const toolName = toolCall.name || "unknown";
|
|
1872
|
+
const toolInput = toolCall.args || {};
|
|
1873
|
+
this.toolsUsedNames.push(toolName);
|
|
1874
|
+
stepsTaken++;
|
|
1875
|
+
let toolInputStr = JSON.stringify(toolInput);
|
|
1876
|
+
if (toolInputStr.length > 100) {
|
|
1877
|
+
toolInputStr = `${toolInputStr.slice(0, 97)}...`;
|
|
1878
|
+
}
|
|
1879
|
+
logger.info(`\u{1F527} Tool call: ${toolName} with input: ${toolInputStr}`);
|
|
1880
|
+
yield {
|
|
1881
|
+
action: {
|
|
1882
|
+
tool: toolName,
|
|
1883
|
+
toolInput,
|
|
1884
|
+
log: `Calling tool ${toolName}`
|
|
1885
|
+
},
|
|
1886
|
+
observation: ""
|
|
1887
|
+
// Will be filled in by tool result
|
|
1888
|
+
};
|
|
1889
|
+
}
|
|
1884
1890
|
}
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1891
|
+
if (message instanceof ToolMessage || message && "type" in message && message.type === "tool") {
|
|
1892
|
+
const observation = message.content;
|
|
1893
|
+
let observationStr = String(observation);
|
|
1894
|
+
if (observationStr.length > 100) {
|
|
1895
|
+
observationStr = `${observationStr.slice(0, 97)}...`;
|
|
1896
|
+
}
|
|
1897
|
+
observationStr = observationStr.replace(/\n/g, " ");
|
|
1898
|
+
logger.info(`\u{1F4C4} Tool result: ${observationStr}`);
|
|
1899
|
+
if (this.useServerManager && this.serverManager) {
|
|
1900
|
+
const currentTools = this.serverManager.tools;
|
|
1901
|
+
const currentToolNames = new Set(currentTools.map((t) => t.name));
|
|
1902
|
+
const existingToolNames = new Set(this._tools.map((t) => t.name));
|
|
1903
|
+
if (currentToolNames.size !== existingToolNames.size || [...currentToolNames].some((n) => !existingToolNames.has(n))) {
|
|
1904
|
+
logger.info(
|
|
1905
|
+
`\u{1F504} Tools changed during execution. New tools: ${[...currentToolNames].join(", ")}`
|
|
1906
|
+
);
|
|
1907
|
+
this._tools = currentTools;
|
|
1908
|
+
this._tools.push(...this.additionalTools);
|
|
1909
|
+
await this.createSystemMessageFromTools(this._tools);
|
|
1910
|
+
this._agentExecutor = this.createAgent();
|
|
1911
|
+
shouldRestart = true;
|
|
1912
|
+
restartCount++;
|
|
1913
|
+
logger.info(
|
|
1914
|
+
`\u{1F503} Restarting execution with updated tools (restart ${restartCount}/${maxRestarts})`
|
|
1915
|
+
);
|
|
1916
|
+
break;
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
}
|
|
1920
|
+
if (message instanceof AIMessage && !("tool_calls" in message && Array.isArray(message.tool_calls) && message.tool_calls.length > 0)) {
|
|
1921
|
+
finalOutput = this._normalizeOutput(message.content);
|
|
1922
|
+
logger.info("\u2705 Agent finished with output");
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
if (shouldRestart) {
|
|
1913
1926
|
break;
|
|
1914
1927
|
}
|
|
1915
1928
|
}
|
|
1916
1929
|
}
|
|
1917
|
-
|
|
1918
|
-
if (e instanceof OutputParserException) {
|
|
1919
|
-
logger.error(`\u274C Output parsing error during step ${stepNum + 1}: ${e}`);
|
|
1920
|
-
result = `Agent stopped due to a parsing error: ${e}`;
|
|
1921
|
-
runManager?.handleChainError(result);
|
|
1930
|
+
if (shouldRestart) {
|
|
1922
1931
|
break;
|
|
1923
1932
|
}
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1933
|
+
}
|
|
1934
|
+
if (!shouldRestart) {
|
|
1935
|
+
break;
|
|
1936
|
+
}
|
|
1937
|
+
if (restartCount > maxRestarts) {
|
|
1938
|
+
logger.warn(`\u26A0\uFE0F Max restarts (${maxRestarts}) reached. Continuing with current tools.`);
|
|
1928
1939
|
break;
|
|
1929
1940
|
}
|
|
1930
1941
|
}
|
|
1931
|
-
if (
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1942
|
+
if (this.memoryEnabled) {
|
|
1943
|
+
this.addToHistory(new HumanMessage(query));
|
|
1944
|
+
if (finalOutput) {
|
|
1945
|
+
this.addToHistory(new AIMessage(finalOutput));
|
|
1946
|
+
}
|
|
1935
1947
|
}
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1948
|
+
if (outputSchema && finalOutput) {
|
|
1949
|
+
try {
|
|
1950
|
+
logger.info("\u{1F527} Attempting structured output...");
|
|
1951
|
+
const structuredResult = await this._attemptStructuredOutput(
|
|
1952
|
+
finalOutput,
|
|
1953
|
+
this.llm,
|
|
1954
|
+
outputSchema
|
|
1955
|
+
);
|
|
1956
|
+
if (this.memoryEnabled) {
|
|
1957
|
+
this.addToHistory(new AIMessage(`Structured result: ${JSON.stringify(structuredResult)}`));
|
|
1958
|
+
}
|
|
1959
|
+
logger.info("\u2705 Structured output successful");
|
|
1960
|
+
success = true;
|
|
1961
|
+
return structuredResult;
|
|
1962
|
+
} catch (e) {
|
|
1963
|
+
logger.error(`\u274C Structured output failed: ${e}`);
|
|
1964
|
+
throw new Error(`Failed to generate structured output: ${e instanceof Error ? e.message : String(e)}`);
|
|
1965
|
+
}
|
|
1966
|
+
}
|
|
1967
|
+
logger.info(`\u{1F389} Agent execution complete in ${((Date.now() - startTime) / 1e3).toFixed(2)} seconds`);
|
|
1968
|
+
success = true;
|
|
1969
|
+
return finalOutput || "No output generated";
|
|
1939
1970
|
} catch (e) {
|
|
1940
1971
|
logger.error(`\u274C Error running query: ${e}`);
|
|
1941
1972
|
if (initializedHere && manageConnector) {
|
|
1942
|
-
logger.info("\u{1F9F9} Cleaning up resources after
|
|
1973
|
+
logger.info("\u{1F9F9} Cleaning up resources after error");
|
|
1943
1974
|
await this.close();
|
|
1944
1975
|
}
|
|
1945
1976
|
throw e;
|
|
@@ -1952,16 +1983,17 @@ var MCPAgent = class {
|
|
|
1952
1983
|
serverCount = this.connectors.length;
|
|
1953
1984
|
}
|
|
1954
1985
|
const conversationHistoryLength = this.memoryEnabled ? this.conversationHistory.length : 0;
|
|
1986
|
+
const toolsAvailable = this._tools || [];
|
|
1955
1987
|
await this.telemetry.trackAgentExecution({
|
|
1956
1988
|
executionMethod: "stream",
|
|
1957
1989
|
query,
|
|
1958
|
-
success
|
|
1990
|
+
success,
|
|
1959
1991
|
modelProvider: this.modelProvider,
|
|
1960
1992
|
modelName: this.modelName,
|
|
1961
1993
|
serverCount,
|
|
1962
1994
|
serverIdentifiers: this.connectors.map((connector) => connector.publicIdentifier),
|
|
1963
|
-
totalToolsAvailable:
|
|
1964
|
-
toolsAvailableNames:
|
|
1995
|
+
totalToolsAvailable: toolsAvailable.length,
|
|
1996
|
+
toolsAvailableNames: toolsAvailable.map((t) => t.name),
|
|
1965
1997
|
maxStepsConfigured: this.maxSteps,
|
|
1966
1998
|
memoryEnabled: this.memoryEnabled,
|
|
1967
1999
|
useServerManager: this.useServerManager,
|
|
@@ -1969,19 +2001,30 @@ var MCPAgent = class {
|
|
|
1969
2001
|
manageConnector,
|
|
1970
2002
|
externalHistoryUsed: externalHistory !== void 0,
|
|
1971
2003
|
stepsTaken,
|
|
1972
|
-
toolsUsedCount: toolsUsedNames.length,
|
|
1973
|
-
toolsUsedNames,
|
|
1974
|
-
response:
|
|
2004
|
+
toolsUsedCount: this.toolsUsedNames.length,
|
|
2005
|
+
toolsUsedNames: this.toolsUsedNames,
|
|
2006
|
+
response: finalOutput || "",
|
|
1975
2007
|
executionTimeMs,
|
|
1976
|
-
errorType:
|
|
2008
|
+
errorType: success ? null : "execution_error",
|
|
1977
2009
|
conversationHistoryLength
|
|
1978
2010
|
});
|
|
1979
2011
|
if (manageConnector && !this.client && initializedHere) {
|
|
1980
|
-
logger.info("\u{1F9F9} Closing agent after
|
|
2012
|
+
logger.info("\u{1F9F9} Closing agent after stream completion");
|
|
1981
2013
|
await this.close();
|
|
1982
2014
|
}
|
|
1983
2015
|
}
|
|
1984
2016
|
}
|
|
2017
|
+
/**
|
|
2018
|
+
* Flush observability traces to the configured observability platform.
|
|
2019
|
+
* Important for serverless environments where traces need to be sent before function termination.
|
|
2020
|
+
*/
|
|
2021
|
+
async flush() {
|
|
2022
|
+
if (this.isRemote && this.remoteAgent) {
|
|
2023
|
+
return;
|
|
2024
|
+
}
|
|
2025
|
+
logger.debug("Flushing observability traces...");
|
|
2026
|
+
await this.observabilityManager.flush();
|
|
2027
|
+
}
|
|
1985
2028
|
async close() {
|
|
1986
2029
|
if (this.isRemote && this.remoteAgent) {
|
|
1987
2030
|
await this.remoteAgent.close();
|
|
@@ -2032,12 +2075,11 @@ var MCPAgent = class {
|
|
|
2032
2075
|
await this.initialize();
|
|
2033
2076
|
initializedHere = true;
|
|
2034
2077
|
}
|
|
2035
|
-
const agentExecutor = this.
|
|
2078
|
+
const agentExecutor = this._agentExecutor;
|
|
2036
2079
|
if (!agentExecutor) {
|
|
2037
2080
|
throw new Error("MCP agent failed to initialize");
|
|
2038
2081
|
}
|
|
2039
|
-
|
|
2040
|
-
agentExecutor.maxIterations = steps;
|
|
2082
|
+
this.maxSteps = maxSteps ?? this.maxSteps;
|
|
2041
2083
|
const display_query = query.length > 50 ? `${query.slice(0, 50).replace(/\n/g, " ")}...` : query.replace(/\n/g, " ");
|
|
2042
2084
|
logger.info(`\u{1F4AC} Received query for streamEvents: '${display_query}'`);
|
|
2043
2085
|
if (this.memoryEnabled) {
|
|
@@ -2053,13 +2095,20 @@ var MCPAgent = class {
|
|
|
2053
2095
|
logger.info(`\u26A0\uFE0F Skipped message of type: ${msg.constructor.name}`);
|
|
2054
2096
|
}
|
|
2055
2097
|
}
|
|
2056
|
-
const inputs =
|
|
2098
|
+
const inputs = [...langchainHistory, new HumanMessage(query)];
|
|
2057
2099
|
logger.info("callbacks", this.callbacks);
|
|
2058
2100
|
const eventStream = agentExecutor.streamEvents(
|
|
2059
|
-
inputs,
|
|
2101
|
+
{ messages: inputs },
|
|
2060
2102
|
{
|
|
2103
|
+
streamMode: "messages",
|
|
2061
2104
|
version: "v2",
|
|
2062
|
-
callbacks: this.callbacks
|
|
2105
|
+
callbacks: this.callbacks,
|
|
2106
|
+
metadata: this.getMetadata(),
|
|
2107
|
+
tags: this.getTags(),
|
|
2108
|
+
// Set trace name for LangChain/Langfuse
|
|
2109
|
+
runName: this.metadata.trace_name || "mcp-use-agent",
|
|
2110
|
+
// Pass sessionId for Langfuse if present in metadata
|
|
2111
|
+
...this.metadata.session_id && { sessionId: this.metadata.session_id }
|
|
2063
2112
|
}
|
|
2064
2113
|
);
|
|
2065
2114
|
for await (const event of eventStream) {
|
|
@@ -2070,8 +2119,20 @@ var MCPAgent = class {
|
|
|
2070
2119
|
if (event.event === "on_chat_model_stream" && event.data?.chunk?.content) {
|
|
2071
2120
|
totalResponseLength += event.data.chunk.content.length;
|
|
2072
2121
|
}
|
|
2122
|
+
if (event.event === "on_chat_model_stream" && event.data?.chunk) {
|
|
2123
|
+
logger.info("on_chat_model_stream", event.data.chunk);
|
|
2124
|
+
const chunk = event.data.chunk;
|
|
2125
|
+
if (chunk.content) {
|
|
2126
|
+
if (!finalResponse) {
|
|
2127
|
+
finalResponse = "";
|
|
2128
|
+
}
|
|
2129
|
+
const normalizedContent = this._normalizeOutput(chunk.content);
|
|
2130
|
+
finalResponse += normalizedContent;
|
|
2131
|
+
logger.debug(`\u{1F4DD} Accumulated response length: ${finalResponse.length}`);
|
|
2132
|
+
}
|
|
2133
|
+
}
|
|
2073
2134
|
yield event;
|
|
2074
|
-
if (event.event === "on_chain_end" && event.data?.output) {
|
|
2135
|
+
if (event.event === "on_chain_end" && event.data?.output && !finalResponse) {
|
|
2075
2136
|
const output = event.data.output;
|
|
2076
2137
|
if (Array.isArray(output) && output.length > 0 && output[0]?.text) {
|
|
2077
2138
|
finalResponse = output[0].text;
|
|
@@ -2088,7 +2149,7 @@ var MCPAgent = class {
|
|
|
2088
2149
|
let conversionCompleted = false;
|
|
2089
2150
|
let conversionResult = null;
|
|
2090
2151
|
let conversionError = null;
|
|
2091
|
-
|
|
2152
|
+
this._attemptStructuredOutput(
|
|
2092
2153
|
finalResponse,
|
|
2093
2154
|
this.llm,
|
|
2094
2155
|
outputSchema
|
|
@@ -2185,6 +2246,10 @@ var MCPAgent = class {
|
|
|
2185
2246
|
}
|
|
2186
2247
|
/**
|
|
2187
2248
|
* Attempt to create structured output from raw result with validation and retry logic.
|
|
2249
|
+
*
|
|
2250
|
+
* @param rawResult - The raw text result from the agent
|
|
2251
|
+
* @param llm - LLM to use for structured output
|
|
2252
|
+
* @param outputSchema - The Zod schema to validate against
|
|
2188
2253
|
*/
|
|
2189
2254
|
async _attemptStructuredOutput(rawResult, llm, outputSchema) {
|
|
2190
2255
|
logger.info(`\u{1F504} Attempting structured output with schema: ${outputSchema}`);
|
|
@@ -2199,7 +2264,9 @@ var MCPAgent = class {
|
|
|
2199
2264
|
} else {
|
|
2200
2265
|
throw new Error("LLM is required for structured output");
|
|
2201
2266
|
}
|
|
2202
|
-
|
|
2267
|
+
const jsonSchema = zodToJsonSchema2(outputSchema);
|
|
2268
|
+
const { $schema, additionalProperties, ...cleanSchema } = jsonSchema;
|
|
2269
|
+
schemaDescription = JSON.stringify(cleanSchema, null, 2);
|
|
2203
2270
|
logger.info(`\u{1F504} Schema description: ${schemaDescription}`);
|
|
2204
2271
|
let textContent = "";
|
|
2205
2272
|
if (typeof rawResult === "string") {
|
|
@@ -2207,6 +2274,7 @@ var MCPAgent = class {
|
|
|
2207
2274
|
} else if (rawResult && typeof rawResult === "object") {
|
|
2208
2275
|
textContent = JSON.stringify(rawResult);
|
|
2209
2276
|
}
|
|
2277
|
+
logger.info("rawResult", rawResult);
|
|
2210
2278
|
if (!textContent) {
|
|
2211
2279
|
textContent = JSON.stringify(rawResult);
|
|
2212
2280
|
}
|
|
@@ -2217,28 +2285,34 @@ var MCPAgent = class {
|
|
|
2217
2285
|
let formatPrompt = `
|
|
2218
2286
|
Please format the following information according to the EXACT schema specified below.
|
|
2219
2287
|
You must use the exact field names and types as shown in the schema.
|
|
2220
|
-
|
|
2288
|
+
|
|
2221
2289
|
Required schema format:
|
|
2222
2290
|
${schemaDescription}
|
|
2223
|
-
|
|
2291
|
+
|
|
2224
2292
|
Content to extract from:
|
|
2225
2293
|
${textContent}
|
|
2226
|
-
|
|
2227
|
-
IMPORTANT:
|
|
2294
|
+
|
|
2295
|
+
IMPORTANT:
|
|
2228
2296
|
- Use ONLY the field names specified in the schema
|
|
2229
2297
|
- Match the data types exactly (string, number, boolean, array, etc.)
|
|
2230
2298
|
- Include ALL required fields
|
|
2231
2299
|
- Return valid JSON that matches the schema structure exactly
|
|
2300
|
+
- For missing data: use null for nullable fields, omit optional fields entirely
|
|
2301
|
+
- Do NOT use empty strings ("") or zero (0) as placeholders for missing data
|
|
2232
2302
|
`;
|
|
2233
2303
|
if (attempt > 1) {
|
|
2234
2304
|
formatPrompt += `
|
|
2235
|
-
|
|
2305
|
+
|
|
2236
2306
|
PREVIOUS ATTEMPT FAILED with error: ${lastError}
|
|
2237
2307
|
Please fix the issues mentioned above and ensure the output matches the schema exactly.
|
|
2238
2308
|
`;
|
|
2239
2309
|
}
|
|
2240
2310
|
try {
|
|
2241
2311
|
logger.info(`\u{1F504} Structured output attempt ${attempt} - using streaming approach`);
|
|
2312
|
+
const contentPreview = textContent.length > 300 ? `${textContent.slice(0, 300)}...` : textContent;
|
|
2313
|
+
logger.info(`\u{1F504} Content being formatted (${textContent.length} chars): ${contentPreview}`);
|
|
2314
|
+
logger.info(`\u{1F504} Full format prompt (${formatPrompt.length} chars):
|
|
2315
|
+
${formatPrompt}`);
|
|
2242
2316
|
const stream = await structuredLlm.stream(formatPrompt);
|
|
2243
2317
|
let structuredResult = null;
|
|
2244
2318
|
let chunkCount = 0;
|
|
@@ -2314,14 +2388,16 @@ var MCPAgent = class {
|
|
|
2314
2388
|
*/
|
|
2315
2389
|
_enhanceQueryWithSchema(query, outputSchema) {
|
|
2316
2390
|
try {
|
|
2317
|
-
const
|
|
2391
|
+
const jsonSchema = zodToJsonSchema2(outputSchema);
|
|
2392
|
+
const { $schema, additionalProperties, ...cleanSchema } = jsonSchema;
|
|
2393
|
+
const schemaDescription = JSON.stringify(cleanSchema, null, 2);
|
|
2318
2394
|
const enhancedQuery = `
|
|
2319
2395
|
${query}
|
|
2320
|
-
|
|
2396
|
+
|
|
2321
2397
|
IMPORTANT: Your response must include sufficient information to populate the following structured output:
|
|
2322
|
-
|
|
2398
|
+
|
|
2323
2399
|
${schemaDescription}
|
|
2324
|
-
|
|
2400
|
+
|
|
2325
2401
|
Make sure you gather ALL the required information during your task execution.
|
|
2326
2402
|
If any required information is missing, continue working to find it.
|
|
2327
2403
|
`;
|