package tui import ( "context" "strings" tea "github.com/charmbracelet/bubbletea" ) // askRequest kommt vom question-Tool über Model.askCh. Anders als eine // Permission-Rückfrage (bool, Tastendruck) ist die Antwort hier Freitext — // die Antwort läuft deshalb über das normale Eingabefeld: submit() prüft // zuerst, ob eine Frage offen ist, und behandelt den getippten Text als // Antwort statt als neue Chat-Nachricht/Slash-Command (siehe submit in // model.go). type askRequest struct { question string options []string resp chan string } type askRequestMsg struct{ req askRequest } func listenAskRequests(ch <-chan askRequest) tea.Cmd { return func() tea.Msg { req, ok := <-ch if !ok { return nil } return askRequestMsg{req: req} } } // askUser ist der Hook, den loop.AskUser aufruft (siehe New()). Läuft auf // dem Goroutine des Backend-Loops, nicht dem der TUI. func (m *Model) askUser(ctx context.Context, question string, options []string) (string, error) { resp := make(chan string, 1) req := askRequest{question: question, options: options, resp: resp} select { case m.askCh <- req: case <-ctx.Done(): return "", ctx.Err() } select { case answer := <-resp: return answer, nil case <-ctx.Done(): return "", ctx.Err() } } // answerQuestion schließt die offene Frage ab und schickt answer an den // wartenden Loop-Goroutine zurück. resp ist mit Cap 1 gepuffert, der Send // blockiert also nie. Die Bestätigung im Transkript kommt bewusst nicht von // hier, sondern aus dem regulären ToolCallOutput-Event (renderToolResult, // builtin.QuestionResult) — sonst erschiene die Antwort doppelt. func (m *Model) answerQuestion(answer string) { req := m.askReq m.askReq = nil m.textarea.Placeholder = defaultInputPlaceholder req.resp <- answer } // renderAskRequest baut den Transkript-Block für eine offene Frage — wie // bei Permissions kein Vollbild-Overlay, sondern ein Eintrag im normalen // Nachrichtenfluss (siehe renderPermissionRequest). func renderAskRequest(question string, options []string) string { var b strings.Builder b.WriteString("❓ Rückfrage: " + question) if len(options) > 0 { b.WriteString("\nVorschläge: " + strings.Join(options, " · ")) } b.WriteString("\n\nAntwort eingeben und Enter drücken.") return styleAskBox.Render(b.String()) }