fix(llm): System-Nachrichten zu einer fuehrenden zusammenfuehren (Qwen3-Template)

Qwen3 verlangt genau eine System-Nachricht ganz am Anfang. Sobald ein Nutzer
Erinnerungen hatte, injizierte das Gateway eine zweite System-Nachricht zusaetzlich
zum Sprach-System-Prompt -> 400 "System message must be at the beginning".
Der lokale Provider fuehrt jetzt Sprach-Prompt + System-Inhalte aus der History
(z. B. Nutzer-Erinnerungen) zu einer einzigen System-Nachricht zusammen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-06-18 04:45:21 +02:00
commit d59afa4dd9
2 changed files with 49 additions and 6 deletions

View file

@ -25,13 +25,26 @@ class LocalOpenAICompatibleLLM(LLMProvider):
self.temperature = temperature
def _build_messages(self, text: str, history: list[dict] | None) -> list[dict]:
messages: list[dict] = []
# Sprach-System-Prompt zuerst (knappe, vorlesbare Antworten). Etwaige
# System-Nachrichten aus der History (z. B. Nutzer-Erinnerungen) bleiben erhalten.
# Manche Chat-Templates (z. B. Qwen3) erlauben nur EINE System-Nachricht,
# ganz am Anfang. Daher den Sprach-System-Prompt und etwaige System-
# Nachrichten aus der History (z. B. Nutzer-Erinnerungen) zu einer einzigen
# fuehrenden System-Nachricht zusammenfuehren.
system_parts: list[str] = []
if self.system_prompt:
messages.append({"role": "system", "content": self.system_prompt})
if history:
messages.extend(history)
system_parts.append(self.system_prompt)
rest: list[dict] = []
for msg in history or []:
if msg.get("role") == "system":
content = (msg.get("content") or "").strip()
if content:
system_parts.append(content)
else:
rest.append(msg)
messages: list[dict] = []
if system_parts:
messages.append({"role": "system", "content": "\n\n".join(system_parts)})
messages.extend(rest)
messages.append({"role": "user", "content": text})
return messages