Add multi-model panel with Fusion mode
Panel agents answer the user prompt in parallel (read-only, non-streaming); their responses are merged into the worker's last user message as a <panel_responses> block, and the session agent synthesizes one final streamed answer. The RunPanel engine is built layer-ready for future MoA. - New session fields: multi_model_mode (off/fusion), panel_agent_ids (CSV) with idempotent column migration - New partial Services/AnthropicService.Panel.cs holding the RunPanel engine - Provider-agnostic members: Anthropic RunNonStreamingToolLoop / OpenAI CompleteText / CLI plan-mode; all forced read-only, persisted with Tag=panel - SSE events: panel_start, panel_member_start, panel_member_done, panel_done - Frontend: multi-agent picker, live panel bubbles, history rendering - Graceful degradation: panel errors fall back to worker-only Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
b23eba32b4
commit
268f11fa6d
20 files changed
+647
-35
No files matched your search
@@ -205,3 +205,42 @@ function finalizeReviewBubble(type, data, agentType) {
|
||||
_currentReviewToolBox = null;
|
||||
scrollDown();
|
||||
}
|
||||
|
||||
// ── Panel Bubbles (Fusion: mehrere Member parallel, non-streaming) ──
|
||||
// Member liefern ihren Text gesammelt bei panel_member_done → pro Member eine eigene
|
||||
// Bubble (keyed by index), kein Konflikt mit dem Single-_reviewBubble-State.
|
||||
|
||||
let _panelBubbles = {};
|
||||
|
||||
function startPanel(data) {
|
||||
endStreamBubble();
|
||||
_panelBubbles = {};
|
||||
}
|
||||
|
||||
function addPanelMemberBubble(data) {
|
||||
var bubble = document.createElement('div');
|
||||
bubble.className = 'msg review-bubble panel-bubble streamed';
|
||||
var model = (typeof prettyModelName === 'function') ? prettyModelName(data.model) : data.model;
|
||||
bubble.appendChild(_createSubAgentHeader('panel', data.name, { model: model }));
|
||||
var content = document.createElement('div');
|
||||
content.className = 'review-content markdown';
|
||||
content.innerHTML = '<span class="tool-spinner"><i class="fa fa-hourglass-half"></i></span> denkt nach…';
|
||||
bubble.appendChild(content);
|
||||
bubble._panelContent = content;
|
||||
_panelBubbles[data.index] = bubble;
|
||||
chatEl().appendChild(bubble);
|
||||
scrollDown();
|
||||
}
|
||||
|
||||
function finalizePanelMember(data) {
|
||||
var bubble = _panelBubbles[data.index];
|
||||
if (!bubble) return;
|
||||
var text = (data.text && data.text.trim()) ? data.text : '_(keine Antwort)_';
|
||||
bubble._panelContent.innerHTML = renderMarkdown(text);
|
||||
delete _panelBubbles[data.index];
|
||||
scrollDown();
|
||||
}
|
||||
|
||||
function endPanel(data) {
|
||||
_panelBubbles = {};
|
||||
}
|
||||
Reference in new issue
Block a user