UNPKG

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
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 };