The model reliably tacked a filler question ("Möchtest du...?", "Gefällt
dir...?") onto nearly every reply regardless of "Stelle bei Bedarf eine
kurze Rückfrage." Verified against live Ollama across several prompts:
sharpened the instruction to end with a statement unless a concrete
piece of information is actually missing.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVgSHNHdRx3UNTBodFmhRA
Auf Wunsch: wie ein Tool funktioniert (wann aufrufen, wie mit dem
Ergebnis umgehen) gehört ausschließlich in seine FunctionSchema.description,
nie in den globalen SYSTEM_PROMPT. SYSTEM_PROMPT enthält jetzt nur noch
Astras Persona, Sprachausgabe-Formatierung und eine generische
"nutze Werkzeuge statt zu erfinden"-Zeile, die kein einzelnes Tool nennt.
Gemessener Preis dieser saubereren Trennung: read_news-Zuverlässigkeit
sinkt von ca. 60-75% (Tool-Regeln zusätzlich im System-Prompt dupliziert)
auf ca. 20-50% (Regeln nur noch in der Tool-Description). generate_image
bleibt bei ~100%, vermutlich weil es die einzige naheliegende Aktion für
Bild-Anfragen ist, während read_news mit generate_image um die
Modell-Aufmerksamkeit konkurriert. Bewusst so gebaut trotz der Zahlen —
Architekturentscheidung, keine Regression, die ich für einen Fehler halte.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVgSHNHdRx3UNTBodFmhRA
Neues Werkzeug read_news, gleiche Trennung wie ComfyUI:
- astra/feeds.py: kuratierte deutsche Feed-Liste nach Thema (tech,
nachrichten, wirtschaft) — 11 Feeds, alle live gegen die echten
Endpunkte verifiziert (heise, Golem, t3n, netzpolitik.org,
tagesschau.de, Zeit Online, Spiegel, SZ, Handelsblatt, WiWo,
manager magazin).
- astra/rss.py: async Feed-Client (feedparser), holt Feeds eines
Themas parallel ab, überspringt einzelne nicht erreichbare Feeds
statt komplett zu scheitern.
- astra/tools.py: read_news als natives Ollama-Tool, gleiches
tool_start/tool_result/tool_error-UI-Muster wie generate_image.
Mit zwei Tools gleichzeitig verfügbar sank die Zuverlässigkeit des
lokalen 9.7B-Modells spürbar (0/8 Tool-Aufrufe mit dem ursprünglichen,
langen System-Prompt) — reproduzierbar isoliert über direkte
Ollama-Requests. Ursache: Instruction-Dilution bei mehreren
Tool-Regeln in einem langen Prompt. Behoben durch gestrafften,
Tool-Regeln-zuerst-Prompt und Temperatur 0.6→0.4: Bildgenerierung
bleibt ~100% zuverlässig, Nachrichten-Tool bei ~60–75% je nach
Formulierung. Per echtem Browser-Test mit synthetisierter Sprache
verifiziert: echte aktuelle Schlagzeilen erscheinen im Transkript.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVgSHNHdRx3UNTBodFmhRA
Pipecat stores a tool call's assistant message OpenAI-style, with
function.arguments as a JSON string. Ollama's native /api/chat wants an
object there and rejects the follow-up request with 400 ("Value looks
like object, but can't find closing '}' symbol") — reproduced verbatim
against real Ollama, then fixed with astra/core.py::normalize_tool_calls,
applied in build_request. Verified end-to-end with a real browser test
(synthesized speech as the fake mic): "erzeuge ein Bild von einer Katze
im Weltraum" now completes the full round trip — tool call, ComfyUI
image, and Astra's follow-up reply — with no error.
Also: an assistant turn interrupted before producing any text showed
nothing at all in the transcript. astra/server.py's assistant_turn
handler now notifies on interruption even with empty content, so an
early interruption (e.g. mic picking up noise during the slightly
longer vision-augmented responses) is visible instead of silent.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVgSHNHdRx3UNTBodFmhRA
Zwei neue, sauber getrennte Fähigkeiten, jede in ihrem eigenen Modul:
- astra/comfyui.py: async HTTP-Client für einen lokalen ComfyUI-Server
(z-image-turbo-Workflow), kennt nichts von der Pipeline.
- astra/documents.py: PDF-Textextraktion via pypdf, keine Netzwerkzugriffe.
- astra/tools.py: verdrahtet generate_image als natives Ollama-Tool-Call —
Qwen 3.5 unterstützt Tools und Vision bereits nativ laut `ollama show`.
Dafür wurde astra/services.py so erweitert, dass NativeOllamaService
Ollamas native tool_calls im Streaming-Response erkennt und als
ChatCompletionChunk-Deltas an Pipecats bereits vorhandene, generische
Function-Calling-Maschinerie (_process_context/run_function_calls)
weiterreicht — die musste dafür nicht angefasst werden. trim_messages in
core.py bewahrt jetzt Tool-Roundtrips und Bild-Anhänge vollständig statt
sie auf role/content zu reduzieren.
Neuer Upload-Button im UI (Bild oder PDF, während eines laufenden
Gesprächs): PDFs gehen als Text, Bilder als Base64 über Qwens Vision in
den Gesprächskontext ein. Generierte Bilder werden über /api/media/<id>
ausgeliefert und per Datenkanal im Transkript angezeigt.
Kompletter Function-Calling-Roundtrip end-to-end gegen echtes Ollama und
echtes ComfyUI verifiziert (Modell ruft generate_image korrekt auf,
Bild wird erzeugt und im media_store abgelegt).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVgSHNHdRx3UNTBodFmhRA
Stimmen werden jetzt lazy pro Name geladen und gecacht statt einer
fest verdrahteten Default-Stimme; das UI bekommt ein Dropdown mit
allen 26 deutschen Pocket-TTS-Stimmen (/api/voices), Auswahl wird im
Browser gemerkt und ist während eines laufenden Gesprächs gesperrt.
Zusätzlich ein optionaler ASTRA_TAILNET_HOST, damit die App über
`tailscale serve` auch von einem anderen Gerät im selben Tailnet
erreichbar ist, ohne die Loopback-only-Härtung für alle anderen
Hosts aufzuweichen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVgSHNHdRx3UNTBodFmhRA
Lokaler deutscher Sprachagent für Apple Silicon: Pipecat-Pipeline mit
Nemotron-ASR (MLX), Qwen über natives Ollama /api/chat, und Pocket TTS.
Loopback-only WebRTC-Server mit Origin/Host-Härtung.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVgSHNHdRx3UNTBodFmhRA