5function App() {
6 const [messages, setMessages] = useState([
7 { role: 'assistant', content: "Hi! I'm Yukti, your friendly female AI assistant. I can help you chat or generate images! How can I assist you today? 👩💻" }
8 ]);
9 const [inputText, setInputText] = useState('');
10 const [isLoading, setIsLoading] = useState(false);
11 const [mode, setMode] = useState<'chat' | 'image'>('chat');
12 const [generatedImages, setGeneratedImages] = useState<string[]>([]);
13 const [imageStyle, setImageStyle] = useState<string>('photorealistic');
14 const [imageCount, setImageCount] = useState<number>(2);
15 const messagesEndRef = useRef(null);
16
43 setInputText('');
44 setIsLoading(true);
45 setGeneratedImages([]);
46
47 try {
48 const response = await fetch(mode === 'chat' ? '/chat' : '/generate-image', {
49 method: 'POST',
50 body: JSON.stringify({
51 messages: [...messages, newUserMessage],
52 prompt: inputText,
53 style: imageStyle,
54 count: imageCount
55 })
56 });
69 synthesizeSpeech(assistantResponse);
70 } else {
71 // Ensure imageUrls is always an array, even if undefined
72 const imageUrls = Array.isArray(data.imageUrls) ? data.imageUrls : [];
73 setGeneratedImages(imageUrls);
74 const imageMessage = {
75 role: 'assistant',
76 content: imageUrls.length > 0
77 ? `I've generated ${imageUrls.length} ${imageStyle} images for "${inputText}"`
78 : "Sorry, I couldn't generate any images."
79 };
80 setMessages(prev => [...prev, imageMessage]);
81 }
82 } catch (error) {
95
96 const toggleMode = () => {
97 setMode(prev => prev === 'chat' ? 'image' : 'chat');
98 setGeneratedImages([]);
99 };
100
101 const imageStyles = [
102 'photorealistic',
103 'digital art',
109 ];
110
111 const imageCountOptions = [1, 2, 3, 4];
112
113 return (
115 <div className="chat-header">
116 <h1>Yukti 👩💻</h1>
117 <p>{mode === 'chat' ? 'Chat Mode' : 'Image Generation Mode'}</p>
118 </div>
119
120 {mode === 'image' && (
121 <div className="image-controls">
122 <div className="style-selector">
123 <label>Image Style:</label>
124 <select
125 value={imageStyle}
126 onChange={(e) => setImageStyle(e.target.value)}
127 >
128 {imageStyles.map(style => (
129 <option key={style} value={style}>{style}</option>
130 ))}
132 </div>
133 <div className="count-selector">
134 <label>Number of Images:</label>
135 <select
136 value={imageCount}
137 onChange={(e) => setImageCount(Number(e.target.value))}
138 >
139 {imageCountOptions.map(count => (
140 <option key={count} value={count}>{count}</option>
141 ))}
154 </div>
155 ))}
156 {generatedImages.length > 0 && (
157 <div className="message assistant image-result">
158 <div className="image-gallery">
159 {generatedImages.map((imageUrl, index) => (
160 <img
161 key={index}
162 src={imageUrl}
163 alt={`Generated image ${index + 1}`}
164 className="generated-image"
165 />
166 ))}
180 onClick={toggleMode}
181 className="mode-toggle-inline"
182 title={mode === 'chat' ? 'Switch to Image Generation' : 'Switch to Chat'}
183 >
184 {mode === 'chat' ? '🖼️' : '💬'}
188 value={inputText}
189 onChange={(e) => setInputText(e.target.value)}
190 placeholder={mode === 'chat' ? "Talk to Yukti..." : "Describe the image you want..."}
191 disabled={isLoading}
192 />
257 }
258
259 if (url.pathname === '/generate-image') {
260 // Verify images method exists
261 if (!openai.images || !openai.images.generate) {
262 throw new Error("OpenAI object does not have the expected image generation method");
263 }
264
266 const { prompt, style, count } = body;
267
268 const imageResponse = await openai.images.generate({
269 model: "dall-e-3",
270 prompt: `A ${style} image of: ${prompt}.
271 High-quality, detailed, and visually appealing composition.`,
272 n: count,
274 });
275
276 const imageUrls = imageResponse.data?.map(img => img.url) || [];
277
278 return new Response(JSON.stringify({ imageUrls }), {
279 headers: { 'Content-Type': 'application/json' }
280 });
303 <html>
304 <head>
305 <title>Yukti - AI Assistant with Image Generation</title>
306 <style>${css}</style>
307 </head>
395}
396
397.image-gallery {
398 display: flex;
399 flex-wrap: wrap;
402}
403
404.generated-image {
405 max-width: 200px;
406 max-height: 200px;
409}
410
411.image-controls {
412 display: flex;
413 justify-content: space-around;