diff --git a/clients/web/src/components/elements/MessageBubble/MessageBubble.tsx b/clients/web/src/components/elements/MessageBubble/MessageBubble.tsx index 68465ed6..951369f9 100644 --- a/clients/web/src/components/elements/MessageBubble/MessageBubble.tsx +++ b/clients/web/src/components/elements/MessageBubble/MessageBubble.tsx @@ -78,6 +78,7 @@ const BubbleContainer = Paper.withProps({ const RoleLabel = Text.withProps({ size: "xs", c: "dimmed", + ff: "monospace", }); const PreviewImage = Image.withProps({ diff --git a/clients/web/src/components/groups/PromptArgumentsForm/PromptArgumentsForm.stories.tsx b/clients/web/src/components/groups/PromptArgumentsForm/PromptArgumentsForm.stories.tsx index 74c85e00..3cc01bac 100644 --- a/clients/web/src/components/groups/PromptArgumentsForm/PromptArgumentsForm.stories.tsx +++ b/clients/web/src/components/groups/PromptArgumentsForm/PromptArgumentsForm.stories.tsx @@ -1,4 +1,5 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; +import type { Prompt } from "@modelcontextprotocol/sdk/types.js"; import { fn } from "storybook/test"; import { PromptArgumentsForm } from "./PromptArgumentsForm"; @@ -14,64 +15,73 @@ const meta: Meta = { export default meta; type Story = StoryObj; +const summarizePrompt: Prompt = { + name: "summarize", + description: "Summarize the given text into key points", +}; + +const translatePrompt: Prompt = { + name: "translate", + description: "Translate text from one language to another", + arguments: [ + { name: "text", required: true, description: "The text to translate" }, + { + name: "targetLanguage", + required: true, + description: "The language to translate into", + }, + ], +}; + +const summarizeWithArgsPrompt: Prompt = { + name: "summarize", + description: "Summarize the given text into key points", + arguments: [ + { name: "text", required: true, description: "The text to summarize" }, + { + name: "maxLength", + required: true, + description: "Maximum length of summary in words", + }, + { + name: "format", + required: false, + description: "Output format (bullets or paragraph)", + }, + ], +}; + +const codeReviewPrompt: Prompt = { + name: "code-review", + arguments: [ + { name: "code", required: true, description: "The code to review" }, + ], +}; + export const NoArguments: Story = { args: { - name: "summarize", - description: "Summarize the given text into key points", - arguments: [], + prompt: summarizePrompt, argumentValues: {}, }, }; export const WithArguments: Story = { args: { - name: "translate", - description: "Translate text from one language to another", - arguments: [ - { name: "text", required: true, description: "The text to translate" }, - { - name: "targetLanguage", - required: true, - description: "The language to translate into", - }, - ], + prompt: translatePrompt, argumentValues: {}, }, }; export const WithRequiredAndOptional: Story = { args: { - name: "summarize", - description: "Summarize the given text into key points", - arguments: [ - { name: "text", required: true, description: "The text to summarize" }, - { - name: "maxLength", - required: true, - description: "Maximum length of summary in words", - }, - { - name: "format", - required: false, - description: "Output format (bullets or paragraph)", - }, - ], + prompt: summarizeWithArgsPrompt, argumentValues: {}, }, }; export const AllFilled: Story = { args: { - name: "translate", - description: "Translate text from one language to another", - arguments: [ - { name: "text", required: true, description: "The text to translate" }, - { - name: "targetLanguage", - required: true, - description: "The language to translate into", - }, - ], + prompt: translatePrompt, argumentValues: { text: "Hello, how are you?", targetLanguage: "Spanish", @@ -81,10 +91,7 @@ export const AllFilled: Story = { export const NoDescription: Story = { args: { - name: "code-review", - arguments: [ - { name: "code", required: true, description: "The code to review" }, - ], + prompt: codeReviewPrompt, argumentValues: {}, }, }; diff --git a/clients/web/src/components/groups/PromptArgumentsForm/PromptArgumentsForm.tsx b/clients/web/src/components/groups/PromptArgumentsForm/PromptArgumentsForm.tsx index a75ba8d4..bd3e7252 100644 --- a/clients/web/src/components/groups/PromptArgumentsForm/PromptArgumentsForm.tsx +++ b/clients/web/src/components/groups/PromptArgumentsForm/PromptArgumentsForm.tsx @@ -1,20 +1,19 @@ import { Button, Group, Stack, Text, TextInput, Title } from "@mantine/core"; - -export interface PromptArgument { - name: string; - required: boolean; - description?: string; -} +import type { Prompt } from "@modelcontextprotocol/sdk/types.js"; export interface PromptArgumentsFormProps { - name: string; - description?: string; - arguments: PromptArgument[]; + prompt: Prompt; argumentValues: Record; onArgumentChange: (name: string, value: string) => void; onGetPrompt: () => void; } +const PromptTitle = Text.withProps({ + fw: 700, + size: "lg", + truncate: "end", +}); + const DescriptionText = Text.withProps({ size: "sm", c: "dimmed", @@ -25,32 +24,36 @@ function formatPlaceholder(name: string): string { } export function PromptArgumentsForm({ - description, - arguments: promptArguments, + prompt, argumentValues, onArgumentChange, onGetPrompt, }: PromptArgumentsFormProps) { + const { name, title, description, arguments: promptArguments } = prompt; + return ( - Prompt Arguments + {title ?? name} {description && {description}} - {promptArguments.length > 0 && ( - - {promptArguments.map((arg) => ( - - onArgumentChange(arg.name, event.currentTarget.value) - } - /> - ))} - + {promptArguments && promptArguments.length > 0 && ( + <> + Arguments + + {promptArguments.map((arg) => ( + + onArgumentChange(arg.name, event.currentTarget.value) + } + /> + ))} + + )}