The useAIStore hook manages the AI assistant panel, chat history, and API key configuration. This store enables the AI-powered game generation feature where users can describe scenes in natural language.
State interface
interface AIState {
messages: ChatMessage[];
isLoading: boolean;
error: string | null;
isOpen: boolean;
apiKey: string;
// Actions
addMessage: (role: ChatMessage['role'], content: string) => void;
setLoading: (loading: boolean) => void;
setError: (error: string | null) => void;
toggleOpen: () => void;
setOpen: (open: boolean) => void;
clearChat: () => void;
setApiKey: (key: string) => void;
updateLastAssistantMessage: (content: string) => void;
}
Types
ChatMessage
interface ChatMessage {
id: string;
role: 'user' | 'assistant' | 'system';
content: string;
timestamp: number;
isGenerating?: boolean; // true when AI is building game objects
}
Unique message identifier (UUID)
role
'user' | 'assistant' | 'system'
required
The role of the message sender
Unix timestamp when the message was created
Flag indicating the AI is actively generating game objects from this message
State properties
Array of all chat messages in chronological order
Whether the AI is currently processing a request
Error message if the last AI request failed
Whether the AI chat panel is currently visible
User’s API key for AI requests (stored in localStorage)
Actions
addMessage
Add a new message to the chat history.
addMessage(role: 'user' | 'assistant' | 'system', content: string): void
The role of the message sender
Example:
const aiStore = useAIStore();
// Add user message
aiStore.addMessage('user', 'Create a platformer with 3 platforms');
// Add assistant response
aiStore.addMessage('assistant', 'I created three platforms for you.');
setLoading
Set the loading state while waiting for AI response.
setLoading(loading: boolean): void
setError
Set or clear error messages.
setError(error: string | null): void
toggleOpen / setOpen
Control the visibility of the AI chat panel.
toggleOpen(): void
setOpen(open: boolean): void
Example:
// Toggle panel visibility
aiStore.toggleOpen();
// Explicitly show panel
aiStore.setOpen(true);
clearChat
Clear all messages from the chat history.
setApiKey
Update the user’s API key and persist to localStorage.
setApiKey(key: string): void
Example:
aiStore.setApiKey('sk-...');
updateLastAssistantMessage
Update the content of the most recent assistant message (for streaming responses).
updateLastAssistantMessage(content: string): void
Usage example
import { useAIStore } from '@/store/aiStore';
function AIChatPanel() {
const { messages, isLoading, isOpen, addMessage, setLoading } = useAIStore();
const handleSend = async (userInput: string) => {
// Add user message
addMessage('user', userInput);
setLoading(true);
try {
// Call AI API
const response = await fetch('/api/ai', {
method: 'POST',
body: JSON.stringify({ message: userInput }),
});
const data = await response.json();
// Add AI response
addMessage('assistant', data.message);
} catch (error) {
addMessage('system', 'Failed to get AI response');
} finally {
setLoading(false);
}
};
return (
<div>
{messages.map((msg) => (
<div key={msg.id}>
<strong>{msg.role}:</strong> {msg.content}
</div>
))}
</div>
);
}
Integration with game generator
The AI store works with the game generator to parse AI responses and execute game commands:
import { useAIStore } from '@/store/aiStore';
import { parseAIResponse, executeCommands } from '@/lib/gameGenerator';
// After receiving AI response
const aiResponse = await fetchAI(userInput);
const { commands, plainText } = parseAIResponse(aiResponse);
// Execute the commands
const log = executeCommands(commands);
// Add assistant message with execution log
addMessage('assistant', plainText + '\n\n' + log.join('\n'));
See also