diff --git a/ui/desktop/src/components/GooseResponseForm.tsx b/ui/desktop/src/components/GooseResponseForm.tsx index 76f7ecc6e..7024f2d44 100644 --- a/ui/desktop/src/components/GooseResponseForm.tsx +++ b/ui/desktop/src/components/GooseResponseForm.tsx @@ -4,6 +4,20 @@ import ReactMarkdown from 'react-markdown'; import { Button } from './ui/button'; import { cn } from '../utils'; +interface FormField { + label: string; + type: 'text' | 'textarea'; + name: string; + placeholder: string; + required: boolean; +} + +interface DynamicForm { + title: string; + description: string; + fields: FormField[]; +} + interface GooseResponseFormProps { message: string; metadata: any; @@ -12,11 +26,13 @@ interface GooseResponseFormProps { export default function GooseResponseForm({ message: _message, metadata, append }: GooseResponseFormProps) { const [selectedOption, setSelectedOption] = useState(null); + const [formValues, setFormValues] = useState>({}); const prevStatusRef = useRef(null); let isQuestion = false; let isOptions = false; - let options = []; + let options: Array<{ optionTitle: string; optionDescription: string }> = []; + let dynamicForm: DynamicForm | null = null; if (metadata) { window.electron.logInfo('metadata:'+ JSON.stringify(metadata, null, 2)); @@ -27,6 +43,16 @@ export default function GooseResponseForm({ message: _message, metadata, append isQuestion = currentStatus === "QUESTION"; isOptions = metadata?.[1] === "OPTIONS"; + // Parse dynamic form data if it exists in metadata[3] + if (metadata?.[3]) { + try { + dynamicForm = JSON.parse(metadata[3]); + } catch (err) { + console.error("Failed to parse form data:", err); + dynamicForm = null; + } + } + if (isQuestion && isOptions && metadata?.[2]) { try { let optionsData = metadata[2]; @@ -92,13 +118,35 @@ export default function GooseResponseForm({ message: _message, metadata, append } }; + const handleFormSubmit = (e: React.FormEvent) => { + e.preventDefault(); + if (dynamicForm) { + const message = { + content: JSON.stringify(formValues), + role: "user", + }; + append(message); + } + }; + + const handleFormChange = (name: string, value: string) => { + setFormValues(prev => ({ + ...prev, + [name]: value + })); + }; + if (!metadata) { return null; } + function isForm(f: DynamicForm) { + return f && f.title && f.description && f.fields && Array.isArray(f.fields) && f.fields.length > 0; + } + return (
- {isQuestion && !isOptions && ( + {isQuestion && !isOptions && !isForm(dynamicForm) && (
)} - {isQuestion && isOptions && options.length > 0 && ( + {isQuestion && isOptions && Array.isArray(options) && options.length > 0 && (
{options.map((opt, index) => (
)} + {isForm(dynamicForm) && !isOptions && ( +
+

{dynamicForm.title}

+

{dynamicForm.description}

+ + {dynamicForm.fields.map((field) => ( +
+ + {field.type === 'textarea' ? ( +