feat: Vorbereiter-Agent (Preparer) für Sessions

- Neues optionales Session-Feld 'preparerAgentId' (DB + Model + API)
- PreparerContext im ChatContext für Agent-Konfiguration
- RunPreparer() in AnthropicService: führt Preparer vor dem Worker aus
  - [FORWARD] → aufbereiteter Prompt wird an Session-Agent weitergegeben
  - Ohne [FORWARD] → Rückfrage an User, Flow stoppt (preparer_query)
- Preparer-System-Prompt: erklärt Rolle, [FORWARD]-Mechanismus, Vorarbeit
- Preparer kann eigene Tools + Fähigkeiten aktiv nutzen
- ChatEndpoint: Preparer-Phase vor StreamChat integriert
- Frontend: SSE-Events (preparer_start/text/tool_use/done)
- Preparer-Bubble (Info-Farbe) mit Status Weitergeleitet/Rückfrage
- [Preparer: Name] → hübscher Header, [FORWARD] ausgeblendet
- [Vorbereitet von Name] → dezenter Header in User-Bubble
- Agent-Picker im Session-Form (vor Review-Agent)
This commit is contained in:
Meleki committed 2026-03-07 15:23:22 +01:00
1 parent f12fbfdc3e
commit 494f431963
12 files changed
+306 -8

No files matched your search

+19
View File
@@ -21,6 +21,8 @@ registerPage('session', {
const workspaceEl = document.getElementById('sessionWorkspace');
const agentSelect = document.getElementById('agentSelect');
const agentSelectCard = document.getElementById('agentSelectCard');
const preparerAgentSelect = document.getElementById('preparerAgentSelect');
const preparerAgentSelectCard = document.getElementById('preparerAgentSelectCard');
const reviewAgentSelect = document.getElementById('reviewAgentSelect');
const reviewAgentSelectCard = document.getElementById('reviewAgentSelectCard');
const reviewIterationsRow = document.getElementById('reviewIterationsRow');
@@ -115,6 +117,14 @@ registerPage('session', {
renderAgentInCard(agentSelectCard, null, 'fa-user-circle-o', 'Kein Agent ausgewählt');
}
// Initiale Anzeige – Preparer-Agent
if (session && session.preparerAgentId) {
preparerAgentSelect.value = session.preparerAgentId;
renderAgentInCard(preparerAgentSelectCard, agentMap[session.preparerAgentId] || null, 'fa-filter', 'Kein Vorbereiter-Agent');
} else {
renderAgentInCard(preparerAgentSelectCard, null, 'fa-filter', 'Kein Vorbereiter-Agent');
}
// Initiale Anzeige – Review-Agent
if (session && session.reviewAgentId) {
reviewAgentSelect.value = session.reviewAgentId;
@@ -141,6 +151,14 @@ registerPage('session', {
});
});
// Klick auf Preparer-Agent-Card → Modal öffnen
preparerAgentSelectCard.addEventListener('click', () => {
openAgentPickerModal(agents, agentSkillsMap, preparerAgentSelect.value, (selectedId) => {
preparerAgentSelect.value = selectedId || '';
renderAgentInCard(preparerAgentSelectCard, selectedId ? agentMap[selectedId] : null, 'fa-filter', 'Kein Vorbereiter-Agent');
});
});
// Klick auf Review-Agent-Card → Modal öffnen
reviewAgentSelectCard.addEventListener('click', () => {
openAgentPickerModal(agents, agentSkillsMap, reviewAgentSelect.value, (selectedId) => {
@@ -208,6 +226,7 @@ registerPage('session', {
reviewAgentId: reviewAgentSelect.value || null,
maxReviewIterations: parseInt(maxReviewIterationsEl.value) || 3,
finalizerAgentId: finalizerAgentSelect.value || null,
preparerAgentId: preparerAgentSelect.value || null,
context: _sessionContextMde.value().trim() || null,
workspace: workspaceEl.value.trim() || null,
customCommands: commands,