Files
Conflict_Checker/tests/test_llm_model_override.py
woogi f7e1b6bb7c
Docker Release / build-and-push (push) Successful in 1m0s
Docker Release / release (push) Skipped
Merge main: dual model dropdowns + richer job logs, adapted for agent-mode.
- llm.py: set_model_overrides(vision, text) replaces the single job override;
  UI picks still beat per-call agent model args, but never name the hybrid
  local model (avoids main's hybrid footgun); local->cloud fallback uses the
  text pick.
- jobs.py: timestamped line-split tee (job_log.py), in-memory log + log_tail
  polls, full log on terminal states (done/error/needs_review/finalization_error),
  log-only disk recovery, error email links to the run log, and failed runs now
  append the full traceback to job.log. Keeps pipeline_mode, job.json, and the
  review gate.
- models.py: vision/text split via architecture modalities, pricing kept;
  /models returns {vision, text, defaults}; /check takes vision_model/text_model
  (replacing model); /health adds text_model. models_catalog.py dropped.
- UI: two priced dropdowns (OpenRouter compute only) + live run-log panel.
- Tests updated for dual overrides and the /models shape; new coverage for
  traceback capture and local-model immunity.
2026-08-02 09:55:09 -05:00

45 lines
2.1 KiB
Python

from backend import config
from backend.llm import _resolve_backend, set_model_overrides, set_text_backend
def teardown_function():
set_model_overrides(None, None)
set_text_backend(False)
def test_vision_override_wins_for_vision_only():
set_model_overrides(vision="openai/gpt-4o", text=None)
assert _resolve_backend(has_images=True, model_override=None)["model"] == "openai/gpt-4o"
assert _resolve_backend(has_images=False, model_override=None)["model"] == config.TEXT_MODEL
def test_text_override_wins_for_text_only():
set_model_overrides(vision=None, text="anthropic/claude-sonnet-4")
assert _resolve_backend(has_images=False, model_override=None)["model"] == "anthropic/claude-sonnet-4"
assert _resolve_backend(has_images=True, model_override=None)["model"] == config.MODEL
def test_override_beats_per_call_model_arg():
set_model_overrides(vision="openai/gpt-4o", text="openai/gpt-4o-mini")
# Agents pass their AGENT_*_MODEL per call; the user's job pick wins.
assert _resolve_backend(has_images=True, model_override="other/model")["model"] == "openai/gpt-4o"
assert _resolve_backend(has_images=False, model_override="other/model")["model"] == "openai/gpt-4o-mini"
def test_no_override_keeps_defaults():
set_model_overrides(None, None)
assert _resolve_backend(has_images=True, model_override=None)["model"] == config.MODEL
assert _resolve_backend(has_images=False, model_override=None)["model"] == config.TEXT_MODEL
def test_ui_picks_never_name_the_local_model(monkeypatch):
"""Hybrid runs keep LOCAL_TEXT_MODEL; OpenRouter picks must not leak into
the local endpoint (a vLLM server won't serve OpenRouter model ids)."""
monkeypatch.setattr(config, "LOCAL_BASE_URL", "http://localhost:8000/v1")
monkeypatch.setattr(config, "LOCAL_TEXT_MODEL", "qwen/local-instruct")
set_text_backend(True)
set_model_overrides(vision="openai/gpt-4o", text="anthropic/claude-sonnet-4")
be = _resolve_backend(has_images=False, model_override=None)
assert be["local"] is True
assert be["model"] == "qwen/local-instruct"