mcp-use
Version:
Opinionated MCP Framework for TypeScript (@modelcontextprotocol/sdk compatible) - Build MCP Agents, Clients and Servers with support for ChatGPT Apps, Code Mode, OAuth, Notifications, Sampling, Observability and more.
484 lines (481 loc) • 17.1 kB
JavaScript
import {
__name
} from "./chunk-3GQAWCBQ.js";
// src/agents/display.ts
var chalk = null;
var highlight = null;
var stripVTControlCharacters = null;
var displayPackagesWarned = false;
var isNode = typeof process !== "undefined" && process.versions?.node;
(async () => {
if (isNode) {
try {
const utilModule = await import("util");
stripVTControlCharacters = utilModule.stripVTControlCharacters;
} catch {
}
}
try {
const chalkModule = await import("chalk");
chalk = chalkModule.default;
} catch {
}
try {
const cliHighlightModule = await import("cli-highlight");
highlight = cliHighlightModule.highlight;
} catch {
}
if (isNode && (!chalk || !highlight)) {
if (!displayPackagesWarned) {
displayPackagesWarned = true;
console.warn(
"\n\u2728 For enhanced console output with colors and syntax highlighting, install:\n\n npm install chalk cli-highlight\n # or\n pnpm add chalk cli-highlight\n"
);
}
}
})();
var TERMINAL_WIDTH = process.stdout.columns || 120;
var chalkHelper = {
gray: /* @__PURE__ */ __name((str) => chalk?.gray(str) ?? str, "gray"),
bold: {
white: /* @__PURE__ */ __name((str) => chalk?.bold?.white(str) ?? str, "white")
},
bgGray: /* @__PURE__ */ __name((str) => chalk?.bgGray(str) ?? str, "bgGray"),
cyan: /* @__PURE__ */ __name((str) => chalk?.cyan(str) ?? str, "cyan"),
dim: /* @__PURE__ */ __name((str) => chalk?.dim(str) ?? str, "dim"),
red: /* @__PURE__ */ __name((str) => chalk?.red(str) ?? str, "red"),
green: /* @__PURE__ */ __name((str) => chalk?.green(str) ?? str, "green")
};
function highlightCode(content, language) {
if (!highlight) {
return content;
}
try {
return highlight(content, {
language: language ?? "javascript",
ignoreIllegals: true
});
} catch {
return content;
}
}
__name(highlightCode, "highlightCode");
function stripAnsi(str) {
if (stripVTControlCharacters) {
return stripVTControlCharacters(str);
}
return str.replace(/\x1b\[[0-9;]*m/g, "");
}
__name(stripAnsi, "stripAnsi");
function wrapAnsiLine(line, maxWidth) {
const stripped = stripAnsi(line);
if (stripped.length <= maxWidth) return [line];
const result = [];
let visibleCount = 0;
let current = "";
let i = 0;
while (i < line.length) {
const char = line[i];
if (char === "\x1B") {
let sequence = char;
i++;
while (i < line.length) {
const nextChar = line[i];
sequence += nextChar;
i++;
if (nextChar === "m") break;
}
current += sequence;
continue;
}
current += char;
visibleCount++;
i++;
if (visibleCount >= maxWidth) {
result.push(current);
current = "";
visibleCount = 0;
}
}
if (current) result.push(current);
return result;
}
__name(wrapAnsiLine, "wrapAnsiLine");
function printBox(content, title, language, bgColor = false) {
const width = TERMINAL_WIDTH;
let displayContent = content;
if (language) {
try {
displayContent = highlightCode(content, language);
} catch {
}
}
const lines = displayContent.split("\n").flatMap((line) => wrapAnsiLine(line, width - 4));
console.log(chalkHelper.gray("\u250C" + "\u2500".repeat(width - 2) + "\u2510"));
if (title) {
const stripped = stripAnsi(title);
const lineText = `${title} `;
const padding = Math.max(0, width - 4 - stripped.length - 2);
console.log(
chalkHelper.gray("\u2502 ") + chalkHelper.bold.white(lineText) + " ".repeat(padding) + chalkHelper.gray(" \u2502")
);
console.log(chalkHelper.gray("\u251C" + "\u2500".repeat(width - 2) + "\u2524"));
}
lines.forEach((line) => {
const stripped = stripAnsi(line);
const padding = Math.max(0, width - 4 - stripped.length);
const finalLine = bgColor ? chalkHelper.bgGray(line + " ".repeat(padding)) : line + " ".repeat(padding);
console.log(chalkHelper.gray("\u2502 ") + finalLine + chalkHelper.gray(" \u2502"));
});
console.log(chalkHelper.gray("\u2514" + "\u2500".repeat(width - 2) + "\u2518"));
}
__name(printBox, "printBox");
function extractCodeFromToolInput(input) {
if (typeof input === "object" && input !== null && "code" in input) {
const inputObj = input;
return typeof inputObj.code === "string" ? inputObj.code : null;
}
return null;
}
__name(extractCodeFromToolInput, "extractCodeFromToolInput");
function isExecuteCodeResult(obj) {
if (typeof obj !== "object" || obj === null) return false;
const result = obj;
return "result" in result && "logs" in result && Array.isArray(result.logs) && "execution_time" in result && typeof result.execution_time === "number" && "error" in result && (typeof result.error === "string" || result.error === null);
}
__name(isExecuteCodeResult, "isExecuteCodeResult");
function parseExecuteCodeResult(output) {
try {
if (typeof output === "string") {
const parsed = JSON.parse(output);
if (isExecuteCodeResult(parsed)) {
return parsed;
}
}
if (isExecuteCodeResult(output)) {
return output;
}
} catch (e) {
}
return null;
}
__name(parseExecuteCodeResult, "parseExecuteCodeResult");
function renderContent(content) {
if (content === null || content === void 0) {
return "null";
}
if (typeof content === "object") {
return JSON.stringify(content, null, 2);
}
return String(content);
}
__name(renderContent, "renderContent");
function unwrapToolInput(input) {
if (typeof input === "object" && input !== null && "input" in input) {
const inputObj = input;
if (typeof inputObj.input === "string") {
try {
return JSON.parse(inputObj.input);
} catch (e) {
return inputObj.input;
}
}
}
return input;
}
__name(unwrapToolInput, "unwrapToolInput");
function handleToolStart(event) {
const toolName = event.name || "unknown";
let input = event.data?.input || {};
input = unwrapToolInput(input);
const code = extractCodeFromToolInput(input);
if (code) {
printBox(code, `${toolName} - input`, "javascript", false);
const otherParams = { ...input };
delete otherParams.code;
if (Object.keys(otherParams).length > 0) {
printBox(renderContent(otherParams), "Other Parameters", "json", false);
}
} else {
printBox(renderContent(input), `${toolName} - input`, "json", false);
}
}
__name(handleToolStart, "handleToolStart");
function extractToolMessageContent(output) {
try {
if (typeof output === "object" && output !== null && "name" in output && "content" in output) {
const outputObj = output;
const toolName = (typeof outputObj.name === "string" ? outputObj.name : null) || "unknown";
const lcKwargs = outputObj.lc_kwargs;
const status = lcKwargs?.status || outputObj.status || "unknown";
let content = outputObj.content;
if (typeof content === "string") {
try {
content = JSON.parse(content);
} catch (e) {
}
}
return { toolName, status, content };
}
} catch (e) {
}
return null;
}
__name(extractToolMessageContent, "extractToolMessageContent");
function formatSearchToolsAsTree(tools, meta, query) {
const metaLines = [];
if (meta) {
if (meta.total_tools !== void 0) {
metaLines.push(`Total tools: ${meta.total_tools}`);
}
if (meta.namespaces && meta.namespaces.length > 0) {
metaLines.push(`Namespaces: ${meta.namespaces.join(", ")}`);
}
if (meta.result_count !== void 0) {
metaLines.push(`Results: ${meta.result_count}`);
}
}
if (!Array.isArray(tools) || tools.length === 0) {
const noResultsMsg = query ? `No tools found for query "${query}"` : "(no tools found)";
if (metaLines.length > 0) {
return `${metaLines.join("\n")}
${noResultsMsg}`;
}
return noResultsMsg;
}
const toolsByServer = {};
for (const tool of tools) {
const server = tool.server || "unknown";
if (!toolsByServer[server]) {
toolsByServer[server] = [];
}
toolsByServer[server].push(tool);
}
const lines = [];
if (meta) {
if (meta.total_tools !== void 0) {
lines.push(`Total tools: ${meta.total_tools}`);
}
if (meta.namespaces && meta.namespaces.length > 0) {
lines.push(`Namespaces: ${meta.namespaces.join(", ")}`);
}
if (meta.result_count !== void 0) {
lines.push(`Results: ${meta.result_count}`);
}
if (lines.length > 0) {
lines.push("");
}
}
const servers = Object.keys(toolsByServer).sort();
for (let i = 0; i < servers.length; i++) {
const server = servers[i];
const serverTools = toolsByServer[server];
const isLastServer = i === servers.length - 1;
const serverPrefix = isLastServer ? "\u2514\u2500" : "\u251C\u2500";
lines.push(
`${serverPrefix} ${chalkHelper.cyan(server)} (${serverTools.length} tools)`
);
for (let j = 0; j < serverTools.length; j++) {
const tool = serverTools[j];
const isLastTool = j === serverTools.length - 1;
const indent = isLastServer ? " " : "\u2502 ";
const toolPrefix = isLastTool ? "\u2514\u2500" : "\u251C\u2500";
const toolLine = `${indent}${toolPrefix} ${tool.name}`;
lines.push(toolLine);
if (tool.description) {
const descAlign = isLastTool ? " " : "\u2502 ";
const descriptionIndent = `${indent}${descAlign}`;
const indentLength = stripAnsi(descriptionIndent).length;
const availableWidth = Math.max(40, TERMINAL_WIDTH - indentLength - 4);
const words = tool.description.split(/(\s+)/);
const wrappedLines = [];
let currentLine = "";
for (const word of words) {
const testLine = currentLine + word;
if (stripAnsi(testLine).length <= availableWidth) {
currentLine = testLine;
} else {
if (currentLine) {
wrappedLines.push(currentLine.trimEnd());
}
currentLine = word.trimStart();
}
}
if (currentLine) {
wrappedLines.push(currentLine.trimEnd());
}
for (const descLine of wrappedLines) {
lines.push(`${descriptionIndent}${chalkHelper.dim(descLine)}`);
}
}
}
}
return lines.join("\n");
}
__name(formatSearchToolsAsTree, "formatSearchToolsAsTree");
function handleToolEnd(event) {
const output = event.data?.output;
const toolMessage = extractToolMessageContent(output);
if (toolMessage) {
const { toolName, status, content } = toolMessage;
if (toolName === "execute_code") {
let actualContent = content;
if (typeof content === "object" && content !== null && "content" in content) {
const innerContent = content.content;
if (Array.isArray(innerContent) && innerContent.length > 0) {
if (innerContent[0].type === "text" && innerContent[0].text) {
actualContent = innerContent[0].text;
}
}
}
const execResult2 = parseExecuteCodeResult(actualContent);
if (execResult2) {
const timeMs = execResult2.execution_time ? Math.round(execResult2.execution_time * 1e3) : 0;
const timeStr = `${timeMs}ms`;
const isError2 = execResult2.error !== null && execResult2.error !== void 0 && execResult2.error !== "";
const statusText = isError2 ? chalkHelper.red("error") : chalkHelper.green("success");
const title2 = `${toolName} - ${statusText} - ${timeStr}`;
if (execResult2.result !== null && execResult2.result !== void 0) {
const resultStr = renderContent(execResult2.result);
const language3 = typeof execResult2.result === "object" ? "json" : void 0;
printBox(resultStr, title2, language3, false);
} else {
printBox("(no result)", title2, void 0, false);
}
if (execResult2.logs && execResult2.logs.length > 0) {
printBox(execResult2.logs.join("\n"), `Logs`, void 0, false);
}
if (execResult2.error) {
printBox(
execResult2.error,
chalkHelper.red("Error"),
void 0,
false
);
}
return;
}
}
if (toolName === "search_tools") {
const toolInput = event.data?.input;
const query = toolInput?.query;
let actualContent = content;
if (typeof content === "object" && content !== null && !Array.isArray(content) && "content" in content) {
const innerContent = content.content;
if (Array.isArray(innerContent) && innerContent.length > 0) {
if (innerContent[0].type === "text" && innerContent[0].text) {
try {
actualContent = JSON.parse(innerContent[0].text);
} catch (e) {
actualContent = innerContent[0].text;
}
}
}
}
if (typeof actualContent === "object" && actualContent !== null && !Array.isArray(actualContent) && "results" in actualContent && Array.isArray(actualContent.results)) {
const results = actualContent.results;
const contentWithMeta = actualContent;
const meta = contentWithMeta.meta;
const treeStr = formatSearchToolsAsTree(results, meta, query);
const statusText = status === "success" ? chalk.green("Success") : chalk.red("Error");
const title2 = `${statusText}: ${toolName} - Result`;
printBox(treeStr, title2, void 0, false);
return;
}
if (Array.isArray(actualContent)) {
const treeStr = formatSearchToolsAsTree(
actualContent,
void 0,
query
);
const statusText = status === "success" ? chalk.green("Success") : chalk.red("Error");
const title2 = `${statusText}: ${toolName} - Result`;
printBox(treeStr, title2, void 0, false);
return;
}
}
const contentObj = typeof content === "object" && content !== null ? content : null;
const isError = contentObj && "isError" in contentObj && contentObj.isError === true || status === "error";
let displayContent = content;
if (typeof content === "object" && content !== null && "content" in content) {
displayContent = content.content;
if (Array.isArray(displayContent) && displayContent.length > 0) {
if (displayContent[0].type === "text" && displayContent[0].text) {
displayContent = displayContent[0].text;
}
}
}
const contentStr = renderContent(displayContent);
const language2 = typeof displayContent === "object" ? "json" : void 0;
const statusLabel = status === "success" ? chalkHelper.green("Success") : isError ? chalkHelper.red("Error") : "Result";
const title = `${statusLabel}: ${toolName} - Result`;
printBox(contentStr, title, language2, false);
return;
}
const execResult = parseExecuteCodeResult(output);
if (execResult) {
const timeMs = execResult.execution_time ? Math.round(execResult.execution_time * 1e3) : 0;
const timeStr = `${timeMs}ms`;
if (execResult.result !== null && execResult.result !== void 0) {
const resultStr = renderContent(execResult.result);
const language2 = typeof execResult.result === "object" ? "json" : void 0;
printBox(resultStr, `Result - ${timeStr}`, language2, false);
}
if (execResult.logs && execResult.logs.length > 0) {
printBox(execResult.logs.join("\n"), `Logs`, void 0, false);
}
if (execResult.error) {
printBox(execResult.error, chalkHelper.red("Error"), void 0, false);
}
return;
}
const outputStr = renderContent(output);
const language = typeof output === "object" ? "json" : void 0;
printBox(outputStr, "Result", language, false);
}
__name(handleToolEnd, "handleToolEnd");
async function* prettyStreamEvents(streamEventsGenerator) {
let finalResponse = "";
let isFirstTextChunk = true;
let hasStreamedText = false;
for await (const event of streamEventsGenerator) {
if (event.event === "on_tool_start") {
if (hasStreamedText) {
process.stdout.write("\n");
hasStreamedText = false;
isFirstTextChunk = true;
}
handleToolStart(event);
} else if (event.event === "on_tool_end") {
handleToolEnd(event);
} else if (event.event === "on_chat_model_stream") {
if (event.data?.chunk?.text) {
const text = event.data.chunk.text;
if (typeof text === "string" && text.length > 0) {
if (isFirstTextChunk) {
process.stdout.write("\n\u{1F916} ");
isFirstTextChunk = false;
}
process.stdout.write(text);
finalResponse += text;
hasStreamedText = true;
}
}
}
yield;
}
return finalResponse;
}
__name(prettyStreamEvents, "prettyStreamEvents");
export {
extractCodeFromToolInput,
extractToolMessageContent,
formatSearchToolsAsTree,
handleToolEnd,
handleToolStart,
parseExecuteCodeResult,
prettyStreamEvents,
printBox,
renderContent,
unwrapToolInput
};