generative-ui/app/page.tsx (99 lines of code) (raw):

'use client' import Chat from '@/components/chat' import UIDisplay from '@/components/ui-display' import { PROMPT_SUGGESTIONS } from '@/lib/constants' import { FunctionCallItem, handleMessage } from '@/lib/handle-message' import React, { useState, useEffect } from 'react' import { parse } from 'partial-json' const MainInterface: React.FC = () => { const [functionCall, setFunctionCall] = useState<FunctionCallItem | null>( null ) const [suggestion, setSuggestion] = useState<string | undefined>(undefined) const [functionArguments, setFunctionArguments] = useState('') useEffect(() => { if (functionArguments.length > 0) { let parsedArguments = {} try { parsedArguments = parse(functionArguments) } catch (e) { console.error('Failed to parse arguments:', e) } setFunctionCall(prev => { if (prev) { return { ...prev, arguments: functionArguments, parsedArguments } } return null }) } }, [functionArguments]) const onMessage = async (data: any) => { const { event: eventType, data: eventData } = data if (eventType === 'function_arguments_delta') { // Accumulate arguments setFunctionArguments(prev => prev + eventData.arguments) // If functionCall doesn't exist, create it, otherwise update it setFunctionCall(prev => { if (!prev) { return { type: 'function_call', status: 'in_progress', id: eventData.callId, name: eventData.name, arguments: eventData.arguments, parsedArguments: {}, output: null } } else { return { ...prev, status: 'in_progress', name: eventData.name, id: eventData.callId, arguments: prev.arguments + eventData.arguments } } }) } else if (eventType === 'function_arguments_done') { setFunctionArguments(eventData.arguments) console.log('functionCall done', functionCall) setFunctionCall(prev => { if (prev) { return { ...prev, status: 'completed' } } return null }) } } const handleSendMessage = async (message: string) => { setFunctionArguments('') setFunctionCall(null) if (!message.trim()) return await handleMessage(message, onMessage) setSuggestion(undefined) } const applySuggestion = (sugg: string) => { setSuggestion(sugg) } return ( <div className="flex flex-col justify-bewtween gap-4 w-full h-screen pt-4 px-24 items-center"> <div className="w-full flex-1 md:w-2/3 flex flex-col items-center justify-center gap-2"> <Chat onSendMessage={handleSendMessage} suggestion={suggestion} /> <div className="flex items-center gap-2 py-2 px-4 text-sm overflow-x-scroll w-full pb-4"> {PROMPT_SUGGESTIONS.map((sugg: string, index: number) => ( <div key={index} className="hover:bg-gray-100 cursor-pointer text-sm text-nowrap px-2 py-1 rounded-full border border-gray-300 text-gray-400" onClick={() => applySuggestion(sugg)} > {sugg} </div> ))} </div> </div> <div className="h-[75vh] w-full bg-gray-50 rounded-t-lg shadow-md md:w-2/3 flex justify-center items-center"> <UIDisplay functionCall={functionCall} /> </div> </div> ) } export default MainInterface