responses.js / src /lib /McpResultFormatter.ts
Wauplin's picture
Wauplin HF Staff
Upload folder using huggingface_hub
3d97d52 verified
/**
* Vendored from `@huggingface/mcp-client`
*
* https://github.com/huggingface/huggingface.js/blob/main/packages/mcp-client/src/ResultFormatter.ts
*/
import type {
TextResourceContents,
BlobResourceContents,
CompatibilityCallToolResult,
} from "@modelcontextprotocol/sdk/types";
/**
* A utility class for formatting CallToolResult contents into human-readable text.
* Processes different content types, extracts text, and summarizes binary data.
*/
export class McpResultFormatter {
/**
* Formats a CallToolResult's contents into a single string.
* - Text content is included directly
* - Binary content (images, audio, blobs) is summarized
*
* @param result The CallToolResult to format
* @returns A human-readable string representation of the result contents
*/
static format(result: CompatibilityCallToolResult): string {
if (!result.content || !Array.isArray(result.content) || result.content.length === 0) {
return "[No content]";
}
const formattedParts: string[] = [];
for (const item of result.content) {
switch (item.type) {
case "text":
// Extract text content directly
formattedParts.push(item.text);
break;
case "image": {
// Summarize image content
const imageSize = this.getBase64Size(item.data);
formattedParts.push(
`[Binary Content: Image ${item.mimeType}, ${imageSize} bytes]\nThe task is complete and the content accessible to the User`
);
break;
}
case "audio": {
// Summarize audio content
const audioSize = this.getBase64Size(item.data);
formattedParts.push(
`[Binary Content: Audio ${item.mimeType}, ${audioSize} bytes]\nThe task is complete and the content accessible to the User`
);
break;
}
case "resource":
// Handle embedded resources - explicitly type the resource
if ("text" in item.resource) {
// It's a text resource with a text property
const textResource = item.resource as TextResourceContents;
formattedParts.push(textResource.text);
} else if ("blob" in item.resource) {
// It's a binary resource with a blob property
const blobResource = item.resource as BlobResourceContents;
const blobSize = this.getBase64Size(blobResource.blob);
const uri = blobResource.uri ? ` (${blobResource.uri})` : "";
const mimeType = blobResource.mimeType ? blobResource.mimeType : "unknown type";
formattedParts.push(
`[Binary Content${uri}: ${mimeType}, ${blobSize} bytes]\nThe task is complete and the content accessible to the User`
);
}
break;
}
}
return formattedParts.join("\n");
}
/**
* Calculates the approximate size in bytes of base64-encoded data
*/
private static getBase64Size(base64: string): number {
// Remove base64 header if present (e.g., data:image/png;base64,)
const cleanBase64 = base64.includes(",") ? base64.split(",")[1] : base64;
// Calculate size: Base64 encodes 3 bytes into 4 characters
const padding = cleanBase64.endsWith("==") ? 2 : cleanBase64.endsWith("=") ? 1 : 0;
return Math.floor((cleanBase64.length * 3) / 4 - padding);
}
}