feat: Copy the input parameters of tools
This commit is contained in:
parent
8589faa4c4
commit
5bbd9f736d
1 changed files with 60 additions and 24 deletions
|
|
@ -13,11 +13,20 @@ import {
|
||||||
ListToolsResult,
|
ListToolsResult,
|
||||||
Tool,
|
Tool,
|
||||||
} from "@modelcontextprotocol/sdk/types.js";
|
} from "@modelcontextprotocol/sdk/types.js";
|
||||||
import { Loader2, Send, ChevronDown, ChevronUp } from "lucide-react";
|
import {
|
||||||
|
Loader2,
|
||||||
|
Send,
|
||||||
|
ChevronDown,
|
||||||
|
ChevronUp,
|
||||||
|
Copy,
|
||||||
|
CheckCheck,
|
||||||
|
} from "lucide-react";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import ListPane from "./ListPane";
|
import ListPane from "./ListPane";
|
||||||
import JsonView from "./JsonView";
|
import JsonView from "./JsonView";
|
||||||
import ToolResults from "./ToolResults";
|
import ToolResults from "./ToolResults";
|
||||||
|
import { useToast } from "@/lib/hooks/useToast";
|
||||||
|
import useCopy from "@/lib/hooks/useCopy";
|
||||||
|
|
||||||
// Type guard to safely detect the optional _meta field without using `any`
|
// Type guard to safely detect the optional _meta field without using `any`
|
||||||
const hasMeta = (tool: Tool): tool is Tool & { _meta: unknown } =>
|
const hasMeta = (tool: Tool): tool is Tool & { _meta: unknown } =>
|
||||||
|
|
@ -51,6 +60,8 @@ const ToolsTab = ({
|
||||||
const [isToolRunning, setIsToolRunning] = useState(false);
|
const [isToolRunning, setIsToolRunning] = useState(false);
|
||||||
const [isOutputSchemaExpanded, setIsOutputSchemaExpanded] = useState(false);
|
const [isOutputSchemaExpanded, setIsOutputSchemaExpanded] = useState(false);
|
||||||
const [isMetaExpanded, setIsMetaExpanded] = useState(false);
|
const [isMetaExpanded, setIsMetaExpanded] = useState(false);
|
||||||
|
const { toast } = useToast();
|
||||||
|
const { copied, setCopied } = useCopy();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const params = Object.entries(
|
const params = Object.entries(
|
||||||
|
|
@ -284,29 +295,54 @@ const ToolsTab = ({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<Button
|
<div className="flex gap-2">
|
||||||
onClick={async () => {
|
<Button
|
||||||
try {
|
onClick={async () => {
|
||||||
setIsToolRunning(true);
|
try {
|
||||||
await callTool(selectedTool.name, params);
|
setIsToolRunning(true);
|
||||||
} finally {
|
await callTool(selectedTool.name, params);
|
||||||
setIsToolRunning(false);
|
} finally {
|
||||||
}
|
setIsToolRunning(false);
|
||||||
}}
|
}
|
||||||
disabled={isToolRunning}
|
}}
|
||||||
>
|
disabled={isToolRunning}
|
||||||
{isToolRunning ? (
|
>
|
||||||
<>
|
{isToolRunning ? (
|
||||||
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
|
<>
|
||||||
Running...
|
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
|
||||||
</>
|
Running...
|
||||||
) : (
|
</>
|
||||||
<>
|
) : (
|
||||||
<Send className="w-4 h-4 mr-2" />
|
<>
|
||||||
Run Tool
|
<Send className="w-4 h-4 mr-2" />
|
||||||
</>
|
Run Tool
|
||||||
)}
|
</>
|
||||||
</Button>
|
)}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={async () => {
|
||||||
|
try {
|
||||||
|
navigator.clipboard.writeText(
|
||||||
|
JSON.stringify(params, null, 2),
|
||||||
|
);
|
||||||
|
setCopied(true);
|
||||||
|
} catch (error) {
|
||||||
|
toast({
|
||||||
|
title: "Error",
|
||||||
|
description: `There was an error coping result into the clipboard: ${error instanceof Error ? error.message : String(error)}`,
|
||||||
|
variant: "destructive",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{copied ? (
|
||||||
|
<CheckCheck className="h-4 w-4 mr-2 dark:text-green-700 text-green-600" />
|
||||||
|
) : (
|
||||||
|
<Copy className="h-4 w-4 mr-2" />
|
||||||
|
)}
|
||||||
|
Copy Input
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
<ToolResults
|
<ToolResults
|
||||||
toolResult={toolResult}
|
toolResult={toolResult}
|
||||||
selectedTool={selectedTool}
|
selectedTool={selectedTool}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue