Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions client/src/components/ToolsTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { TabsContent } from "@/components/ui/tabs";
import { Textarea } from "@/components/ui/textarea";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import DynamicJsonForm, { DynamicJsonFormRef } from "./DynamicJsonForm";
import type { JsonValue, JsonSchemaType } from "@/utils/jsonUtils";
import {
Expand Down Expand Up @@ -182,6 +189,42 @@ const ToolsTab = ({
{prop.description || "Toggle this option"}
</label>
</div>
) : prop.type === "string" && prop.enum ? (
<Select
value={
params[key] === undefined
? ""
: String(params[key])
}
onValueChange={(value) => {
if (value === "") {
setParams({
...params,
[key]: undefined,
});
} else {
setParams({
...params,
[key]: value,
});
}
}}
>
<SelectTrigger id={key} className="mt-1">
<SelectValue
placeholder={
prop.description || "Select an option"
}
/>
</SelectTrigger>
<SelectContent>
{prop.enum.map((option) => (
<SelectItem key={option} value={option}>
{option}
</SelectItem>
))}
</SelectContent>
</Select>
) : prop.type === "string" ? (
<Textarea
id={key}
Expand Down
58 changes: 58 additions & 0 deletions client/src/components/__tests__/ToolsTab.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,64 @@ describe("ToolsTab", () => {
});
});

describe("Enum Parameters", () => {
const toolWithEnumParam: Tool = {
name: "enumTool",
description: "Tool with enum parameter",
inputSchema: {
type: "object" as const,
properties: {
format: {
type: "string" as const,
enum: ["json", "xml", "csv", "yaml"],
description: "Output format",
},
},
},
};

beforeEach(() => {
// Mock scrollIntoView for Radix UI Select
Element.prototype.scrollIntoView = jest.fn();
});

it("should render enum parameter as dropdown", () => {
renderToolsTab({
tools: [toolWithEnumParam],
selectedTool: toolWithEnumParam,
});

// Should render a select button instead of textarea
const selectTrigger = screen.getByRole("combobox", { name: /format/i });
expect(selectTrigger).toBeInTheDocument();
});

it("should render non-enum string parameter as textarea", () => {
const toolWithStringParam: Tool = {
name: "stringTool",
description: "Tool with regular string parameter",
inputSchema: {
type: "object" as const,
properties: {
text: {
type: "string" as const,
description: "Some text input",
},
},
},
};

renderToolsTab({
tools: [toolWithStringParam],
selectedTool: toolWithStringParam,
});

// Should render textarea, not select
expect(screen.queryByRole("combobox")).not.toBeInTheDocument();
expect(screen.getByRole("textbox")).toBeInTheDocument();
});
});

describe("JSON Validation Integration", () => {
const toolWithJsonParams: Tool = {
name: "jsonTool",
Expand Down
Loading