(options = {})
| 1376 | }; |
| 1377 | |
| 1378 | const sendMessage = async (options = {}) => { |
| 1379 | const msg = String(options.message || inputEl?.value || '').trim(); |
| 1380 | if (!msg) return; |
| 1381 | if (!options.message && inputEl) { |
| 1382 | inputEl.value = ''; |
| 1383 | } |
| 1384 | appendMessage('user', msg); |
| 1385 | |
| 1386 | try { |
| 1387 | const requestPayload = { |
| 1388 | message: msg, |
| 1389 | workspace: workspace(), |
| 1390 | currentSourceId: normalizeSourceId(currentChatLocation().sourceId), |
| 1391 | currentFolderPath: normalizeFolderPath(currentChatLocation().rootPath), |
| 1392 | recipeId: String(options.recipeId || ''), |
| 1393 | copilotProfile, |
| 1394 | ...buildAnalysisPayload() |
| 1395 | }; |
| 1396 | if (copilotContextPacket && typeof copilotContextPacket === 'object') { |
| 1397 | requestPayload.contextPacket = copilotContextPacket; |
| 1398 | } |
| 1399 | const res = await apiPost('/api/pro/ai/chat.php', requestPayload); |
| 1400 | lastRecipeDraft = { |
| 1401 | prompt: msg, |
| 1402 | meta: (res && typeof res.meta === 'object') ? res.meta : null |
| 1403 | }; |
| 1404 | let assistantHandle = null; |
| 1405 | let assistantWorkflow = (res?.workflow && typeof res.workflow === 'object') ? { ...res.workflow } : null; |
| 1406 | if (assistantWorkflow && res?.job?.id) { |
| 1407 | assistantWorkflow.jobId = Number(res.job.id || 0); |
| 1408 | assistantWorkflow.pending = false; |
| 1409 | assistantWorkflow.confirmed = false; |
| 1410 | assistantWorkflow.queued = true; |
| 1411 | assistantWorkflow.running = false; |
| 1412 | assistantWorkflow.status = 'queued'; |
| 1413 | } |
| 1414 | if (res?.assistant) { |
| 1415 | assistantHandle = appendMessage('assistant', String(res.assistant), { workflow: assistantWorkflow }); |
| 1416 | } else { |
| 1417 | assistantHandle = appendMessage('assistant', 'No response text returned.', { workflow: assistantWorkflow }); |
| 1418 | } |
| 1419 | refreshVisibleFolderForToolResult(res?.tool, res?.workspace); |
| 1420 | refreshVisibleFolderForWorkflowResult(res?.refresh, res?.workspace); |
| 1421 | if (res?.job?.id) { |
| 1422 | showToast(`AI job queued (#${res.job.id})`); |
| 1423 | watchJob(res.job.id, { |
| 1424 | messageHandle: assistantHandle, |
| 1425 | workflow: assistantWorkflow |
| 1426 | }); |
| 1427 | } |
| 1428 | if (options.recipeId) { |
| 1429 | loadRecipes(); |
| 1430 | } |
| 1431 | } catch (err) { |
| 1432 | appendMessage('assistant', `Error: ${err?.message || 'Request failed'}`); |
| 1433 | } |
| 1434 | }; |
| 1435 |
no test coverage detected