Chat Interface Example

Learn how to build an interactive chat interface with streaming responses using Lumia AI.

Code

Complete implementation with comments

import { streamText } from 'ai';
import { Lumia } from '@ai-sdk/Lumia';
import { useState } from 'react';

export default function ChatInterface() {
  const [messages, setMessages] = useState([]);
  const [input, setInput] = useState('');
  const [isGenerating, setIsGenerating] = useState(false);
  
  async function handleSubmit(e) {
    e.preventDefault();
    if (!input.trim() || isGenerating) return;
    
    // Add user message
    const userMessage = { role: 'user', content: input };
    setMessages(prev => [...prev, userMessage]);
    setInput('');
    setIsGenerating(true);
    
    // Create placeholder for assistant's response
    const assistantMessage = { role: 'assistant', content: '' };
    setMessages(prev => [...prev, assistantMessage]);
    
    try {
      // Stream the response
      const result = streamText({
        model: Lumia('Lumia-V2-Pro'),
        prompt: input,
        system: 'You are a helpful assistant.',
        onChunk: ({ chunk }) => {
          if (chunk.type === 'text-delta') {
            setMessages(prev => {
              const newMessages = [...prev];
              const lastMessage = newMessages[newMessages.length - 1];
              lastMessage.content += chunk.text;
              return newMessages;
            });
          }
        }
      });
      
      await result.text;
    } catch (error) {
      console.error('Error:', error);
    } finally {
      setIsGenerating(false);
    }
  }
  
  return (
    <div className="flex flex-col h-[600px] max-w-2xl mx-auto">
      <div className="flex-1 overflow-y-auto p-4 space-y-4">
        {messages.map((message, i) => (
          <div key={i} className={`flex ${
            message.role === 'user' ? 'justify-end' : 'justify-start'
          }`}>
            <div className={`max-w-[80%] rounded-2xl px-4 py-2 ${
              message.role === 'user' 
                ? 'bg-blue-100 text-gray-800' 
                : 'bg-gray-100 text-gray-800'
            }`}>
              {message.content}
            </div>
          </div>
        ))}
      </div>
      
      <form onSubmit={handleSubmit} className="p-4 border-t">
        <div className="flex gap-2">
          <input
            type="text"
            value={input}
            onChange={(e) => setInput(e.target.value)}
            placeholder="Type a message..."
            className="flex-1 rounded-2xl px-4 py-2 bg-white"
            disabled={isGenerating}
          />
          <button
            type="submit"
            className="bg-white text-blue-600 rounded-2xl px-4 py-2"
            disabled={isGenerating}
          >
            {isGenerating ? 'Sending...' : 'Send'}
          </button>
        </div>
      </form>
    </div>
  );
}

Key Features

Understanding the main components and functionality

Real-time Streaming

Messages appear character by character as they're generated, providing a more engaging experience.

Message History

Maintains a conversation history with clear visual distinction between user and assistant messages.

Error Handling

Gracefully handles errors and loading states to ensure a smooth user experience.