|
160 | 160 | chatInput.value = ''; |
161 | 161 | addMessage('human', text); |
162 | 162 | chatHistory.push({ role: 'user', content: `Human operator: ${text}` }); |
163 | | - callGroq(); |
| 163 | + // Pause auto-conversation while human is talking, resume after response |
| 164 | + if (autoTimer) { clearTimeout(autoTimer); autoTimer = null; } |
| 165 | + callGroq(true); |
164 | 166 | }); |
165 | 167 |
|
166 | 168 | // --- Chat --- |
|
171 | 173 | let chatHistory: { role: string; content: string }[] = []; |
172 | 174 | let chatAbort: AbortController | null = null; |
173 | 175 | let chatBusy = false; |
| 176 | + let autoTimer: ReturnType<typeof setTimeout> | null = null; |
| 177 | + let autoStep = 0; |
| 178 | + const MAX_AUTO = 10; |
| 179 | + const BASE_DELAY = 5000; // 5s, then 6s, 7s... |
| 180 | + |
| 181 | + // Pre-written Director prompts for autonomous conversation |
| 182 | + const directorPrompts = [ |
| 183 | + (name: string) => `${name}, report your current status.`, |
| 184 | + (name: string) => `What's your progress percentage?`, |
| 185 | + (name: string) => `Any errors or warnings to report?`, |
| 186 | + (name: string) => `How many records have you processed so far?`, |
| 187 | + (name: string) => `What's your estimated time to completion?`, |
| 188 | + (name: string) => `Are there any dependencies blocking you?`, |
| 189 | + (name: string) => `Check your resource usage — CPU and memory.`, |
| 190 | + (name: string) => `Summarize your output so far.`, |
| 191 | + (name: string) => `Any anomalies detected in this batch?`, |
| 192 | + (name: string) => `Wrapping up. Final status before I move to the next AgentNode.`, |
| 193 | + ]; |
| 194 | + |
| 195 | + function scheduleAutoMessage() { |
| 196 | + if (autoTimer) clearTimeout(autoTimer); |
| 197 | + if (autoStep >= MAX_AUTO || !chatOpen || chatNodeIdx < 0) return; |
| 198 | + const delay = BASE_DELAY + autoStep * 1000; // 5s, 6s, 7s, ... |
| 199 | + autoTimer = setTimeout(() => { |
| 200 | + if (!chatOpen || chatNodeIdx < 0 || chatBusy) return; |
| 201 | + const info = nodeInfo[chatNodeIdx]; |
| 202 | + const prompt = directorPrompts[autoStep](info.name); |
| 203 | + autoStep++; |
| 204 | + addMessage('director', prompt); |
| 205 | + chatHistory.push({ role: 'user', content: `Director: ${prompt}` }); |
| 206 | + callGroq(true); |
| 207 | + }, delay); |
| 208 | + } |
174 | 209 |
|
175 | 210 | function openChat(idx: number) { |
176 | 211 | chatNodeIdx = idx; |
|
182 | 217 | chatMessages.innerHTML = ''; |
183 | 218 | chatHistory = []; |
184 | 219 | chatBusy = false; |
| 220 | + autoStep = 0; |
| 221 | + if (autoTimer) { clearTimeout(autoTimer); autoTimer = null; } |
185 | 222 | tooltip.style.opacity = '0'; |
186 | 223 |
|
187 | 224 | // Initial Director message |
188 | | - const directorMsg = idx === 0 |
189 | | - ? 'Orchestra "product-cleanup" is active. 3 AgentNodes running, 2 idle. Awaiting validator results.' |
190 | | - : `${info.name}, report your current status.`; |
191 | | - |
| 225 | + const directorMsg = directorPrompts[0](info.name); |
| 226 | + autoStep = 1; |
192 | 227 | addMessage('director', directorMsg); |
193 | 228 |
|
194 | | - // Set up system context and get first response |
195 | 229 | chatHistory = [ |
196 | | - { role: 'system', content: info.context + ' You are in a live orchestra chat. The AI Director just asked for your status. A human operator may also join the conversation. Respond concisely in 1-2 sentences.' }, |
197 | | - { role: 'user', content: directorMsg }, |
| 230 | + { role: 'system', content: info.context + ' You are in a live orchestra chat. The AI Director coordinates you. A human operator may also join. Always respond in character, concisely in 1-2 sentences. Vary your responses — mention specific numbers, progress, issues.' }, |
| 231 | + { role: 'user', content: `Director: ${directorMsg}` }, |
198 | 232 | ]; |
199 | | - callGroq(); |
| 233 | + callGroq(true); |
200 | 234 | } |
201 | 235 |
|
202 | 236 | function closeChat() { |
203 | 237 | chatOpen = false; |
204 | 238 | chatPanel.style.display = 'none'; |
205 | 239 | chatNodeIdx = -1; |
206 | 240 | chatBusy = false; |
| 241 | + if (autoTimer) { clearTimeout(autoTimer); autoTimer = null; } |
207 | 242 | if (chatAbort) { chatAbort.abort(); chatAbort = null; } |
208 | 243 | } |
209 | 244 |
|
|
229 | 264 |
|
230 | 265 | function esc(s: string) { return s.replace(/</g, '<').replace(/>/g, '>'); } |
231 | 266 |
|
232 | | - async function callGroq() { |
| 267 | + async function callGroq(continueAuto = false) { |
233 | 268 | if (chatBusy) return; |
234 | 269 | chatBusy = true; |
235 | 270 | if (chatAbort) chatAbort.abort(); |
|
253 | 288 | const reply = data.choices?.[0]?.message?.content || 'No response.'; |
254 | 289 | addMessage('agent', reply); |
255 | 290 | chatHistory.push({ role: 'assistant', content: reply }); |
| 291 | + // Schedule next autonomous Director message |
| 292 | + if (continueAuto) scheduleAutoMessage(); |
256 | 293 | } catch (e: any) { |
257 | 294 | typing.remove(); |
258 | 295 | if (e.name !== 'AbortError') addMessage('system', 'Connection error. Is the backend running?'); |
|
0 commit comments