feat(llm): Koreferenz-Vorstufe + Tool-/Sonar-Metriken (Weg 2, Schritt 5)

Schliesst die im Tool-Calling-Eval isolierte Restkante (nl + Pronomen-aus-
History, z. B. "Leeft hij nog?" -> "Leeft Rutger Hauer nog?") und macht die
Web-Suche metrisch beobachtbar.

- Decontextualizer (app/pipeline/decontextualizer.py): loest Pronomen der
  letzten Aeusserung anhand des Verlaufs auf. Bewusst gegated (kurze
  Folgefrage MIT Pronomen UND History) -> kein Extra-Call im Normalfall;
  best effort (bei Fehler Original behalten).
- ToolCallingLLM nutzt die Vorstufe vor complete()/stream() und zaehlt
  tool_calls_total{tool=...}.
- SonarTool zaehlt sonar_calls_total{status=ok|error}.
- Verdrahtung: Registry openrouter-tools reicht den Decontextualizer durch.

Damit ist v1 von Weg 2 vollstaendig. Tests: 290 gruen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-06-29 21:43:24 +02:00
commit c36b884aab
4 changed files with 105 additions and 1 deletions

View file

@ -28,6 +28,7 @@ from app.providers.fallback import (
FallbackLLMProvider,
FallbackTTSProvider,
)
from app.pipeline.decontextualizer import Decontextualizer
from app.pipeline.input_cleaner import InputCleaner
from app.pipeline.spoken_response_adapter import SpokenResponseAdapter
from app.pipeline.tts_normalizer import TTSNormalizer
@ -63,6 +64,7 @@ LLM_REGISTRY = {
s.openrouter_api_key,
s.openrouter_llm_model,
tools=[SonarTool(s.openrouter_api_key)],
decontextualizer=Decontextualizer(s.openrouter_api_key, s.openrouter_llm_model),
),
"local-openai-compatible": lambda s: LocalOpenAICompatibleLLM(
s.local_llm_base_url,