Merge pull request #193 from seuros/main

feat: Add utility function to escape Unicode characters in tool results
This commit is contained in:
Ola Hungerford
2025-03-22 19:14:16 -07:00
committed by GitHub
5 changed files with 52 additions and 7 deletions

View File

@@ -8,15 +8,15 @@ import { Textarea } from "@/components/ui/textarea";
import DynamicJsonForm, { JsonSchemaType, JsonValue } from "./DynamicJsonForm";
import { generateDefaultValue } from "@/utils/schemaUtils";
import {
CallToolResultSchema,
CompatibilityCallToolResult,
ListToolsResult,
Tool,
CallToolResultSchema,
} from "@modelcontextprotocol/sdk/types.js";
import { AlertCircle, Send } from "lucide-react";
import { useEffect, useState } from "react";
import ListPane from "./ListPane";
import { CompatibilityCallToolResult } from "@modelcontextprotocol/sdk/types.js";
import { escapeUnicode } from "@/utils/escapeUnicode";
const ToolsTab = ({
tools,
@@ -54,7 +54,7 @@ const ToolsTab = ({
<>
<h4 className="font-semibold mb-2">Invalid Tool Result:</h4>
<pre className="bg-gray-50 dark:bg-gray-800 dark:text-gray-100 p-4 rounded text-sm overflow-auto max-h-64">
{JSON.stringify(toolResult, null, 2)}
{escapeUnicode(toolResult)}
</pre>
<h4 className="font-semibold mb-2">Errors:</h4>
{parsedResult.error.errors.map((error, idx) => (
@@ -62,7 +62,7 @@ const ToolsTab = ({
key={idx}
className="bg-gray-50 dark:bg-gray-800 dark:text-gray-100 p-4 rounded text-sm overflow-auto max-h-64"
>
{JSON.stringify(error, null, 2)}
{escapeUnicode(error)}
</pre>
))}
</>
@@ -101,7 +101,7 @@ const ToolsTab = ({
</audio>
) : (
<pre className="bg-gray-50 dark:bg-gray-800 dark:text-gray-100 whitespace-pre-wrap break-words p-4 rounded text-sm overflow-auto max-h-64">
{JSON.stringify(item.resource, null, 2)}
{escapeUnicode(item.resource)}
</pre>
))}
</div>
@@ -113,7 +113,7 @@ const ToolsTab = ({
<>
<h4 className="font-semibold mb-2">Tool Result (Legacy):</h4>
<pre className="bg-gray-50 dark:bg-gray-800 dark:text-gray-100 p-4 rounded text-sm overflow-auto max-h-64">
{JSON.stringify(toolResult.toolResult, null, 2)}
{escapeUnicode(toolResult.toolResult)}
</pre>
</>
);

View File

@@ -0,0 +1,27 @@
import { escapeUnicode } from "../escapeUnicode";
describe("escapeUnicode", () => {
it("should escape Unicode characters in a string", () => {
const input = { text: "你好世界" };
const expected = '{\n "text": "\\\\u4f60\\\\u597d\\\\u4e16\\\\u754c"\n}';
expect(escapeUnicode(input)).toBe(expected);
});
it("should handle empty strings", () => {
const input = { text: "" };
const expected = '{\n "text": ""\n}';
expect(escapeUnicode(input)).toBe(expected);
});
it("should handle null and undefined values", () => {
const input = { text: null, value: undefined };
const expected = '{\n "text": null\n}';
expect(escapeUnicode(input)).toBe(expected);
});
it("should handle numbers and booleans", () => {
const input = { number: 123, boolean: true };
const expected = '{\n "number": 123,\n "boolean": true\n}';
expect(escapeUnicode(input)).toBe(expected);
});
});

View File

@@ -0,0 +1,16 @@
// Utility function to escape Unicode characters
export function escapeUnicode(obj: unknown): string {
return JSON.stringify(
obj,
(_key: string, value) => {
if (typeof value === "string") {
// Replace non-ASCII characters with their Unicode escape sequences
return value.replace(/[^\0-\x7F]/g, (char) => {
return "\\u" + ("0000" + char.charCodeAt(0).toString(16)).slice(-4);
});
}
return value;
},
2,
);
}

1
package-lock.json generated
View File

@@ -24,6 +24,7 @@
"mcp-inspector": "bin/cli.js"
},
"devDependencies": {
"@types/jest": "^29.5.14",
"@types/node": "^22.7.5",
"@types/shell-quote": "^1.7.5",
"prettier": "3.3.3"

View File

@@ -42,6 +42,7 @@
"ts-node": "^10.9.2"
},
"devDependencies": {
"@types/jest": "^29.5.14",
"@types/node": "^22.7.5",
"@types/shell-quote": "^1.7.5",
"prettier": "3.3.3"