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>
|
||||||
<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 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>
|
||||||
|
<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">
|
<div class="input-row">
|
||||||
<label class="btn secondary" style="padding:6px 10px;cursor:pointer;font-size:14px;" title="Datei anhaengen">
|
<label class="btn secondary" style="padding:6px 10px;cursor:pointer;font-size:14px;" title="Datei anhaengen">
|
||||||
📎
|
📎
|
||||||
@@ -1425,6 +1426,12 @@
|
|||||||
let diagQueueStatus = {};
|
let diagQueueStatus = {};
|
||||||
let diagProjectsCache = [];
|
let diagProjectsCache = [];
|
||||||
let diagShowHiddenStrip = false; // versteckte Projekte im Streifen zeigen?
|
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() {
|
function updateChatVisibilityByFocus() {
|
||||||
for (const box of [chatBox, document.getElementById('chat-box-fs')]) {
|
for (const box of [chatBox, document.getElementById('chat-box-fs')]) {
|
||||||
@@ -1438,10 +1445,22 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function switchDiagFocus(id) {
|
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);
|
localStorage.setItem('diag_focused_context_id', focusedContextId);
|
||||||
updateChatVisibilityByFocus();
|
updateChatVisibilityByFocus();
|
||||||
renderContextStrip();
|
renderContextStrip();
|
||||||
|
renderDiagQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderContextStrip() {
|
function renderContextStrip() {
|
||||||
@@ -1983,6 +2002,15 @@
|
|||||||
projectId: p.projectId || '',
|
projectId: p.projectId || '',
|
||||||
answeredBy: p.answeredBy || '',
|
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;
|
return;
|
||||||
}
|
}
|
||||||
if (msg.type === 'chat_message_deleted') {
|
if (msg.type === 'chat_message_deleted') {
|
||||||
@@ -2179,16 +2207,64 @@
|
|||||||
renderDiagPending();
|
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() {
|
function testRVS() {
|
||||||
const input = document.getElementById('chat-input');
|
const input = document.getElementById('chat-input');
|
||||||
const text = input.value.trim();
|
const text = input.value.trim();
|
||||||
if (!text && diagPendingFiles.length === 0) return;
|
if (!text && diagPendingFiles.length === 0) return;
|
||||||
if (diagPendingFiles.length > 0) sendDiagAttachments();
|
if (diagPendingFiles.length > 0) sendDiagAttachments();
|
||||||
if (text) {
|
if (text) {
|
||||||
// Multi-Threading: mit fokussierter Kontext-ID senden.
|
// Draft dieses Kontexts leeren + Queue-Automat entscheidet senden/anstellen.
|
||||||
// Bridge routet an /chat body.project_id — Brain queued per Kontext.
|
diagDrafts[focusedContextId] = '';
|
||||||
addChat('sent', text, 'via RVS', { projectId: focusedContextId });
|
localStorage.setItem('diag_ctx_drafts', JSON.stringify(diagDrafts));
|
||||||
send({ action: 'test_rvs', text, projectId: focusedContextId });
|
enqueueOrSendDiag(focusedContextId, text);
|
||||||
}
|
}
|
||||||
input.value = '';
|
input.value = '';
|
||||||
}
|
}
|
||||||
@@ -2675,8 +2751,8 @@
|
|||||||
const input = document.getElementById('chat-input-fs');
|
const input = document.getElementById('chat-input-fs');
|
||||||
const text = input.value.trim();
|
const text = input.value.trim();
|
||||||
if (!text) return;
|
if (!text) return;
|
||||||
addChat('sent', text, 'via RVS');
|
// Ueber denselben Queue-Automaten wie der Haupt-Chat (fokussierter Kontext).
|
||||||
send({ action: 'test_rvs', text });
|
enqueueOrSendDiag(focusedContextId, text);
|
||||||
input.value = '';
|
input.value = '';
|
||||||
}
|
}
|
||||||
// Escape schliesst Vollbild-Chat
|
// Escape schliesst Vollbild-Chat
|
||||||
@@ -3650,6 +3726,12 @@
|
|||||||
}
|
}
|
||||||
document.getElementById('chat-input').addEventListener('keydown', (e) => chatInputKeydown(e, testRVS));
|
document.getElementById('chat-input').addEventListener('keydown', (e) => chatInputKeydown(e, testRVS));
|
||||||
document.getElementById('chat-input-fs').addEventListener('keydown', (e) => chatInputKeydown(e, testRVSFS));
|
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
|
// Escape schliesst Lightbox
|
||||||
document.addEventListener('keydown', (e) => {
|
document.addEventListener('keydown', (e) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user