AI providers: correlation decision and transcript correction move to OpenAI gpt-4o-mini

One funded account (OpenAI) now covers extraction, embeddings, summaries,
the ambiguous-scene correlation call and transcript correction; Groq stays
optional for STT. New app/internal/llm.py picks the provider from the model
name, so setting either model back to a gemini-* ID needs no code change.
Usage accounting for replay runs now covers both providers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Logan Cusano
2026-11-08 01:25:21 -05:00
co-authored by Claude Opus 5.5
parent 3e9ca4be06
commit 0060ccde75
12 changed files with 180 additions and 50 deletions
@@ -253,11 +253,11 @@ def build_context_block(context: dict, talkgroup_name: Optional[str]) -> str:
def _sync_gemini(model_name: str, prompt: str) -> dict:
from app.internal import gemini
from app.internal import llm
# Correction rewrites text against vocabulary; keep a little reasoning
# ("low") rather than the correlator's "minimal" until a replay shows
# minimal doesn't hurt it.
return gemini.generate_json(model_name, prompt, purpose="correction", thinking_level="low")
return llm.generate_json(model_name, prompt, purpose="correction", thinking_level="low")
async def correct(
@@ -282,7 +282,8 @@ async def correct(
so a correction that only fixed the joined transcript would never reach the
model on exactly the multi-transmission calls that carry the most content.
"""
if not settings.gemini_api_key or not settings.transcript_correction_enabled:
from app.internal import llm
if not llm.available(settings.transcript_correction_model) or not settings.transcript_correction_enabled:
return None, None, False
if len((text or "").split()) < MIN_WORDS_FOR_CORRECTION: