forked from Rockachopa/Timmy-time-dashboard
The chat WebSocket return path was broken by two bugs that prevented
Timmy's responses from appearing in the live chat feed:
1. Frontend checked msg.type instead of msg.event for 'timmy_response'
events — the WSEvent dataclass uses 'event' as the field name.
2. Frontend accessed msg.response instead of msg.data.response — the
response payload is nested in the data field.
Additional fixes:
- Queue acknowledgment ("Message queued...") no longer logged as an
agent message in chat history; the real response is logged by the
task processor when it completes, eliminating duplicate messages.
- Chat message template now carries data-task-id so the WS handler
can find and replace the placeholder with the actual response.
- appendMessage() uses DOM APIs (textContent) instead of innerHTML
for safer content insertion before markdown rendering.
- Fixed chat_message.html script targeting when queue-status div is
present between the agent message and the inline script.
https://claude.ai/code/session_011cJfexqBBuGhSRQU8qwKcR
Co-authored-by: Claude <noreply@anthropic.com>
36 lines
1.4 KiB
HTML
36 lines
1.4 KiB
HTML
<div class="chat-message user">
|
|
<div class="msg-meta">YOU // {{ timestamp }}</div>
|
|
<div class="msg-body">{{ user_message | e }}</div>
|
|
</div>
|
|
{% if response %}
|
|
<div class="chat-message agent"{% if task_id %} data-task-id="{{ task_id }}"{% endif %}>
|
|
<div class="msg-meta">TIMMY // {{ timestamp }}</div>
|
|
<div class="msg-body timmy-md">{{ response | e }}</div>
|
|
</div>
|
|
{% if queue_info %}
|
|
<div class="queue-status" data-task-id="{{ task_id }}" data-position="{{ queue_info.position }}" data-total="{{ queue_info.total }}">
|
|
<small class="text-muted">Position in queue: {{ queue_info.position }}/{{ queue_info.total }}</small>
|
|
</div>
|
|
{% endif %}
|
|
<script>
|
|
(function() {
|
|
var script = document.currentScript;
|
|
var prev = script.previousElementSibling;
|
|
// Skip queue-status div to find the agent message div
|
|
if (prev && prev.classList.contains('queue-status')) prev = prev.previousElementSibling;
|
|
var el = prev ? prev.querySelector('.timmy-md') : null;
|
|
if (el && typeof marked !== 'undefined' && typeof DOMPurify !== 'undefined') {
|
|
el.innerHTML = DOMPurify.sanitize(marked.parse(el.textContent));
|
|
if (typeof hljs !== 'undefined') {
|
|
el.querySelectorAll('pre code').forEach(function(block) { hljs.highlightElement(block); });
|
|
}
|
|
}
|
|
})();
|
|
</script>
|
|
{% elif error %}
|
|
<div class="chat-message error-msg">
|
|
<div class="msg-meta">SYSTEM // {{ timestamp }}</div>
|
|
<div class="msg-body">{{ error | e }}</div>
|
|
</div>
|
|
{% endif %}
|