@nuwa-ai/ui-kit gives you a React hook (useNuwa) and a context provider (NuwaProvider) to talk to the Nuwa Client from your Cap UI. With it you can send prompts, persist UI state per chat thread, stream AI output, add selections, and manage iframe height/theme.
Wrap your UI with NuwaProvider, then call useNuwa() inside to access the nuwa client instance and connection state.For all props and return types, see: NuwaProvider and useNuwa
import { NuwaProvider, useNuwa } from '@nuwa-ai/ui-kit';function MyCapUI() { const { nuwa, connected, theme } = useNuwa(); const run = async () => { // Persist local UI state to the current chat thread await nuwa.saveState({ step: 'started' }); // Send a prompt to the active conversation await nuwa.sendPrompt('Please analyze the selected notes.'); }; return ( <div className={theme === 'dark' ? 'dark' : ''}> <button onClick={run} disabled={!connected}>Run</button> </div> );}export default function App() { return ( <NuwaProvider onConnected={() => console.log('Nuwa connected')} onError={console.error}> <MyCapUI /> </NuwaProvider> );}
Persist and retrieve UI state per chat thread with nuwa.saveState() and nuwa.getState(). You can save UI state at any time, as any object types. When the user returns to the same chat thread, your latest saved state is delivered back to the UI.See full method signature
You can save any object types as UI state but you need to make sure your UI can handle the state object. For example, if you save a state object with a property title, you need to make sure your UI can handle the title property.
import { useEffect, useState } from 'react';function ThreadStateExample() { const { nuwa } = useNuwa(); const [title, setTitle] = useState(''); // Load previously saved state for this chat thread useEffect(() => { let mounted = true; (async () => { const prev = await nuwa.getState<{ title?: string } | null>(); if (mounted && prev?.title) setTitle(prev.title); })(); return () => { mounted = false; }; }, [nuwa]); // Save on change const onChange = async (e: React.ChangeEvent<HTMLInputElement>) => { const v = e.target.value; setTitle(v); await nuwa.saveState({ title: v }); }; return <input value={title} onChange={onChange} placeholder="Title" />;}
Add a selection (label + message) to parent UI. The selection message is provided to the AI as part of the system prompt. You can set it with the prompt variable{{artifact_selections}} in the Cap’s prompt field.