Phase 1 run-control semantics and run_state events

This commit is contained in:
William Valentin
2026-02-25 10:22:44 -08:00
parent ae21681958
commit e4ee6acce8
13 changed files with 485 additions and 120 deletions
+21
View File
@@ -715,6 +715,10 @@ async function sendMessage(client, overrideText) {
scrollToBottom();
// Create placeholder for assistant response
const statusLine = document.createElement('div');
statusLine.className = 'px-1 text-[11px] leading-none text-zinc-500 select-none hidden';
statusLine.textContent = 'Run status: queued';
_elements.messages.appendChild(statusLine);
const placeholder = document.createElement('div');
placeholder.className = 'rounded-lg px-3.5 py-2.5 text-sm leading-relaxed break-words whitespace-pre-wrap bg-zinc-900 border border-zinc-800 text-zinc-50 streaming-cursor';
placeholder.innerHTML = '<span class="text-zinc-500">Thinking...</span>';
@@ -759,6 +763,22 @@ async function sendMessage(client, overrideText) {
scrollToBottom();
});
stream.on('run_state', (data) => {
if (!data || !data.state) {
return;
}
const labels = {
start: 'Run status: working',
cancel_requested: 'Run status: cancellation requested',
cancelled: 'Run status: cancelled',
complete: 'Run status: complete',
error: `Run status: error${data.message ? ` (${data.message})` : ''}`,
};
statusLine.textContent = labels[data.state] || `Run status: ${data.state}`;
statusLine.classList.remove('hidden');
scrollToBottom();
});
const done = await stream.result;
const content = done?.content ?? done?.text ?? '(no response)';
const assistantMessage = createMessageEl('assistant', content, Date.now());
@@ -771,6 +791,7 @@ async function sendMessage(client, overrideText) {
_cancelling = false;
updateSendButton();
clearPendingAttachments();
statusLine.remove();
scrollToBottom();
}
}