fix: ask_user_choice Short-Poll, Freitext-Option, Stop-Kontext-Fix

- Long-Poll durch Short-Poll ersetzt (MCP-Server pollt jede Sekunde statt einer blockierenden HTTP-Anfrage)
- Expliziter Lambda-Rückgabetyp Task<IResult> für ASP.NET Minimal API Endpoints (behebt 200 empty body Bug)
- Freitext-Option bei Choice-Buttons ("Eigene Antwort…") für freie User-Eingabe
- Stop während ask_user_choice markiert Chain als awaiting_user_choice statt stopped (Kontext bleibt erhalten)
- ask_user_choice System-Prompt-Instruktion breiter formuliert (Quiz, Multiple-Choice etc.)
- Text wird jetzt immer in DB gespeichert, auch bei ask_user_choice
- Key-Check Model auf claude-haiku-4-5 geändert

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
MelekiandClaude Opus 4.6 committed 2026-03-18 11:32:25 +01:00
1 parent 3e0a69e7a4
commit 92ecaf9dac
8 files changed
+184 -66

No files matched your search

+74
View File
@@ -1280,6 +1280,80 @@
color: var(--muted);
}
/* Freitext-Option */
.choice-custom {
margin-top: var(--badge-spacing);
}
.choice-custom-toggle {
font-size: 0.85em;
color: var(--muted);
text-decoration: none;
}
.choice-custom-toggle:hover {
color: var(--primary);
}
.choice-custom-row {
display: none;
gap: var(--badge-spacing);
align-items: center;
margin-top: var(--badge-spacing);
}
.choice-custom-open .choice-custom-toggle {
display: none;
}
.choice-custom-open .choice-custom-row {
display: flex;
}
.choice-custom-input {
flex: 1;
border: var(--border-width) solid var(--f1-border);
border-radius: var(--border-radius);
background: var(--f1-bg);
color: var(--f1-text);
padding: 0.3em 0.6em;
font-size: 0.9em;
}
.choice-custom-input:focus {
border-color: var(--primary);
outline: none;
}
.choice-custom-send {
border: var(--border-width) solid var(--primary);
border-radius: var(--border-radius);
background: transparent;
color: var(--primary);
cursor: pointer;
padding: 0.3em 0.6em;
font-size: 0.9em;
}
.choice-custom-send:hover {
background: var(--primary);
color: var(--f1-bg);
}
.choice-answered .choice-custom {
display: none;
}
.choice-answered .choice-custom.has-answer {
display: block;
}
.choice-custom-answer {
font-size: 0.85em;
color: var(--primary);
font-style: italic;
}
.inline-choice-block {
margin: var(--gap) 0;
padding: var(--gap);
+42
View File
@@ -215,6 +215,48 @@ function _createChoiceBubble(opts) {
}
div.appendChild(buttonsDiv);
// Freitext-Option (nur wenn noch nicht beantwortet)
if (!answered) {
const customDiv = document.createElement('div');
customDiv.className = 'choice-custom';
const toggleLink = document.createElement('a');
toggleLink.className = 'choice-custom-toggle';
toggleLink.href = '#';
toggleLink.textContent = 'Eigene Antwort…';
toggleLink.addEventListener('click', function(e) {
e.preventDefault();
customDiv.classList.add('choice-custom-open');
customDiv.querySelector('.choice-custom-input').focus();
});
customDiv.appendChild(toggleLink);
const inputRow = document.createElement('div');
inputRow.className = 'choice-custom-row';
const input = document.createElement('input');
input.type = 'text';
input.className = 'choice-custom-input';
input.placeholder = 'Eigene Antwort eingeben…';
var sendCustom = function() {
var text = input.value.trim();
if (!text) return;
handleChoiceClick(opts.toolCallId, text, div);
};
input.addEventListener('keydown', function(e) { if (e.key === 'Enter') sendCustom(); });
var sendBtn = document.createElement('button');
sendBtn.className = 'choice-custom-send';
sendBtn.textContent = '↵';
sendBtn.addEventListener('click', sendCustom);
inputRow.appendChild(input);
inputRow.appendChild(sendBtn);
customDiv.appendChild(inputRow);
div.appendChild(customDiv);
}
if (opts.timestamp) _addTimestamp(div, opts.timestamp);
return div;
}
+14
View File
@@ -415,14 +415,28 @@ async function sendMessageDirect(text) {
async function handleChoiceClick(toolCallId, choice, bubbleDiv) {
// Buttons deaktivieren und gewählte Option markieren
const buttons = bubbleDiv.querySelectorAll('.choice-btn');
var matchedButton = false;
buttons.forEach(btn => {
btn.disabled = true;
if (btn.textContent === choice) {
btn.classList.add('choice-selected');
matchedButton = true;
} else {
btn.classList.add('choice-unselected');
}
});
// Freitext-Antwort: Keine der Buttons matched → Antwort als Text anzeigen
if (!matchedButton) {
var customDiv = bubbleDiv.querySelector('.choice-custom');
if (customDiv) {
customDiv.innerHTML = '';
customDiv.classList.add('has-answer');
var answerSpan = document.createElement('span');
answerSpan.className = 'choice-custom-answer';
answerSpan.textContent = '↳ ' + choice;
customDiv.appendChild(answerSpan);
}
}
bubbleDiv.classList.add('choice-answered');
// CLI-Modus: Antwort über internen Endpoint an MCP-Server weiterleiten (CLI läuft weiter)