feat(queue): Diagnostic spiegelt Pro-Kontext-Queue + Rueckfrage + Drafts
Diagnostic bekommt denselben Queue-Automaten wie die App: anstellen statt abbrechen, awaiting_reply pausiert die Queue (naechste Eingabe beantwortet die Rueckfrage), Queue-Banner mit loeschbaren Eintraegen ueber dem Eingabefeld, und Pro-Kontext-Textfeld-Entwuerfe (Feldinhalt bleibt beim Kontextwechsel erhalten). rvs_chat-Handler liest awaiting_reply aus der Bridge-Payload. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+89
-7
@@ -320,6 +320,7 @@
|
||||
</div>
|
||||
<div id="diag-pending-attachments" style="display:none;padding:6px 10px;background:#1E1E2E;border-radius:6px 6px 0 0;margin-bottom:-4px;display:flex;gap:6px;flex-wrap:wrap;align-items:center;">
|
||||
</div>
|
||||
<div id="diag-queue-banner" style="display:none;padding:6px 10px;background:#2A2410;border:1px solid #4A3F14;border-radius:6px;margin-bottom:6px;"></div>
|
||||
<div class="input-row">
|
||||
<label class="btn secondary" style="padding:6px 10px;cursor:pointer;font-size:14px;" title="Datei anhaengen">
|
||||
📎
|
||||
@@ -1425,6 +1426,12 @@
|
||||
let diagQueueStatus = {};
|
||||
let diagProjectsCache = [];
|
||||
let diagShowHiddenStrip = false; // versteckte Projekte im Streifen zeigen?
|
||||
// ── Pro-Kontext-Queue + Zustandsautomat (spiegelt die App) ──
|
||||
const diagCtxStates = {}; // pid → 'idle' | 'running' | 'awaiting_reply'
|
||||
const diagCtxQueues = {}; // pid → [{id,text}]
|
||||
const diagDrafts = JSON.parse(localStorage.getItem('diag_ctx_drafts') || '{}');
|
||||
let diagQid = 0;
|
||||
const diagState = (pid) => diagCtxStates[pid] || 'idle';
|
||||
|
||||
function updateChatVisibilityByFocus() {
|
||||
for (const box of [chatBox, document.getElementById('chat-box-fs')]) {
|
||||
@@ -1438,10 +1445,22 @@
|
||||
}
|
||||
|
||||
function switchDiagFocus(id) {
|
||||
focusedContextId = id || '';
|
||||
const nextId = id || '';
|
||||
// Pro-Kontext-Textfeld-Entwuerfe: Feldinhalt dem verlassenen Kontext
|
||||
// zuordnen, Entwurf des neuen laden.
|
||||
if (nextId !== focusedContextId) {
|
||||
const input = document.getElementById('chat-input');
|
||||
if (input) {
|
||||
diagDrafts[focusedContextId] = input.value;
|
||||
input.value = diagDrafts[nextId] || '';
|
||||
}
|
||||
localStorage.setItem('diag_ctx_drafts', JSON.stringify(diagDrafts));
|
||||
}
|
||||
focusedContextId = nextId;
|
||||
localStorage.setItem('diag_focused_context_id', focusedContextId);
|
||||
updateChatVisibilityByFocus();
|
||||
renderContextStrip();
|
||||
renderDiagQueue();
|
||||
}
|
||||
|
||||
function renderContextStrip() {
|
||||
@@ -1983,6 +2002,15 @@
|
||||
projectId: p.projectId || '',
|
||||
answeredBy: p.answeredBy || '',
|
||||
});
|
||||
// ── Pro-Kontext-Queue-Automat: auf ARIAs Antwort reagieren ──
|
||||
if (sender === 'aria') {
|
||||
const apid = p.projectId || '';
|
||||
const st = diagState(apid);
|
||||
if (st === 'running' || st === 'awaiting_reply') {
|
||||
if (p.awaiting_reply) { diagCtxStates[apid] = 'awaiting_reply'; renderDiagQueue(); }
|
||||
else advanceDiagQueue(apid);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (msg.type === 'chat_message_deleted') {
|
||||
@@ -2179,16 +2207,64 @@
|
||||
renderDiagPending();
|
||||
}
|
||||
|
||||
// ── Pro-Kontext-Queue: Helfer (spiegelt die App) ──
|
||||
function actuallySendDiag(pid, text) {
|
||||
addChat('sent', text, 'via RVS', { projectId: pid });
|
||||
send({ action: 'test_rvs', text, projectId: pid });
|
||||
diagCtxStates[pid] = 'running';
|
||||
renderDiagQueue();
|
||||
}
|
||||
function advanceDiagQueue(pid) {
|
||||
const q = diagCtxQueues[pid] || [];
|
||||
if (q.length === 0) { diagCtxStates[pid] = 'idle'; renderDiagQueue(); return; }
|
||||
const next = q.shift();
|
||||
actuallySendDiag(pid, next.text);
|
||||
}
|
||||
function enqueueOrSendDiag(pid, text) {
|
||||
if (diagState(pid) === 'running') {
|
||||
(diagCtxQueues[pid] = diagCtxQueues[pid] || []).push({ id: 'q' + (++diagQid), text });
|
||||
renderDiagQueue();
|
||||
} else {
|
||||
// idle ODER awaiting_reply → sofort (bei awaiting = Antwort auf Rueckfrage).
|
||||
actuallySendDiag(pid, text);
|
||||
}
|
||||
}
|
||||
function removeDiagQueuedFocused(id) {
|
||||
const pid = focusedContextId;
|
||||
diagCtxQueues[pid] = (diagCtxQueues[pid] || []).filter(it => it.id !== id);
|
||||
renderDiagQueue();
|
||||
}
|
||||
function renderDiagQueue() {
|
||||
const el = document.getElementById('diag-queue-banner');
|
||||
if (!el) return;
|
||||
const st = diagState(focusedContextId);
|
||||
const q = diagCtxQueues[focusedContextId] || [];
|
||||
if (st !== 'awaiting_reply' && q.length === 0) { el.style.display = 'none'; el.innerHTML = ''; return; }
|
||||
el.style.display = 'block';
|
||||
let html = '';
|
||||
if (st === 'awaiting_reply') {
|
||||
html += '<div style="color:#FFD60A;font-weight:600;margin-bottom:4px;">❓ ARIA fragt nach — deine Eingabe beantwortet das</div>';
|
||||
}
|
||||
if (q.length) {
|
||||
html += q.map(it =>
|
||||
'<span style="display:inline-block;background:#1E1E2E;border:1px solid #4A3F14;border-radius:10px;padding:2px 8px;margin:2px;font-size:12px;color:#FFD60A;">⏸ ' +
|
||||
escapeHtml(it.text.slice(0, 40)) +
|
||||
' <a href="#" style="color:#FF6B6B;text-decoration:none;" onclick="removeDiagQueuedFocused(\'' + it.id + '\');return false;">✕</a></span>'
|
||||
).join('');
|
||||
}
|
||||
el.innerHTML = html;
|
||||
}
|
||||
|
||||
function testRVS() {
|
||||
const input = document.getElementById('chat-input');
|
||||
const text = input.value.trim();
|
||||
if (!text && diagPendingFiles.length === 0) return;
|
||||
if (diagPendingFiles.length > 0) sendDiagAttachments();
|
||||
if (text) {
|
||||
// Multi-Threading: mit fokussierter Kontext-ID senden.
|
||||
// Bridge routet an /chat body.project_id — Brain queued per Kontext.
|
||||
addChat('sent', text, 'via RVS', { projectId: focusedContextId });
|
||||
send({ action: 'test_rvs', text, projectId: focusedContextId });
|
||||
// Draft dieses Kontexts leeren + Queue-Automat entscheidet senden/anstellen.
|
||||
diagDrafts[focusedContextId] = '';
|
||||
localStorage.setItem('diag_ctx_drafts', JSON.stringify(diagDrafts));
|
||||
enqueueOrSendDiag(focusedContextId, text);
|
||||
}
|
||||
input.value = '';
|
||||
}
|
||||
@@ -2675,8 +2751,8 @@
|
||||
const input = document.getElementById('chat-input-fs');
|
||||
const text = input.value.trim();
|
||||
if (!text) return;
|
||||
addChat('sent', text, 'via RVS');
|
||||
send({ action: 'test_rvs', text });
|
||||
// Ueber denselben Queue-Automaten wie der Haupt-Chat (fokussierter Kontext).
|
||||
enqueueOrSendDiag(focusedContextId, text);
|
||||
input.value = '';
|
||||
}
|
||||
// Escape schliesst Vollbild-Chat
|
||||
@@ -3650,6 +3726,12 @@
|
||||
}
|
||||
document.getElementById('chat-input').addEventListener('keydown', (e) => chatInputKeydown(e, testRVS));
|
||||
document.getElementById('chat-input-fs').addEventListener('keydown', (e) => chatInputKeydown(e, testRVSFS));
|
||||
// Entwurf des zuletzt fokussierten Kontexts ins Feld laden + Queue-Banner init.
|
||||
(function initDiagDraft() {
|
||||
const input = document.getElementById('chat-input');
|
||||
if (input && diagDrafts[focusedContextId]) input.value = diagDrafts[focusedContextId];
|
||||
renderDiagQueue();
|
||||
})();
|
||||
|
||||
// Escape schliesst Lightbox
|
||||
document.addEventListener('keydown', (e) => {
|
||||
|
||||
Reference in New Issue
Block a user