feat: ask_user_choice Tool – interaktive Auswahlmöglichkeiten im Chat
Neues Tool 'ask_user_choice' analog zum AskUserQuestion aus dem Claude Agent SDK. Claude kann dem User Multiple-Choice-Fragen stellen, wenn es mehrere sinnvolle Wege gibt. Der User wählt per Button, Claude arbeitet mit der Antwort weiter. Backend: - ToolService: ask_user_choice Tool-Definition (question + choices[2-5]) - AnthropicService/ProcessStream: Tool wird NICHT ausgeführt, sondern als SSE-Event 'user_choice' an den Client gesendet. stopReason wird auf 'awaiting_user_choice' gesetzt (mit Guard gegen Überschreibung durch message_delta) - ChatEndpoint: Erkennung von Choice-Responses (choiceToolCallId + choiceResult), tool_result wird in die korrekte Chain gespeichert (wo der tool_use liegt), toolChoice wird auf 'auto' gesetzt damit Claude frei antworten kann - ChatService: FindChainWithToolCall() zum Auffinden der richtigen Chain, BuildHistoryFromDb() erweitert um Choice-Chain-Erkennung (wenn letzte Chain leer/nur tool_result → vorletzte Chain vollständig rekonstruieren) - ChatModels: ChatRequest um ChoiceToolCallId + ChoiceResult erweitert Frontend: - api.js: apiChatChoice() für Choice-Responses - chat.js: handleStreamEvent() als shared Handler extrahiert (sendMessage + handleChoiceClick nutzen denselben Code), handleChoiceClick() startet neuen Stream nach Button-Klick - ui.js: addChoiceBubble() (live/interaktiv) + addChoiceBubbleStatic() (History) - history.js: Choice-Bubbles in _renderMessagesIntoFragment + renderMessages, Voraus-Suche nach zugehörigem tool_result, unbeantwortet = klickbare Buttons - chat.css: Styling für Choice-Bubbles (Primary-Color-Outline-Buttons, Hover, Selected/Unselected States) Robustheit: - Backend-Fallback wenn Claude choices als String statt Array sendet - Frontend-Guard: Array.isArray(choices) an allen 4 Render-Stellen - Page-Refresh mit offener Choice → aktive Buttons werden korrekt gerendert
This commit is contained in:
1 parent
72347ed2f5
commit
5f3e308975
10 files changed
+628
-140
No files matched your search
@@ -50,6 +50,15 @@ async function apiChat(content, sessionId, signal) {
|
||||
});
|
||||
}
|
||||
|
||||
async function apiChatChoice(sessionId, choiceToolCallId, choiceResult, signal) {
|
||||
return fetch('/api/chat', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ sessionId, choiceToolCallId, choiceResult }),
|
||||
signal
|
||||
});
|
||||
}
|
||||
|
||||
// ── Agent API ──
|
||||
|
||||
async function apiGetAgents() {
|
||||
|
||||
Reference in new issue
Block a user