Add job run logs, OpenRouter model picker, and discipline grouping.
Docker Release / build-and-push (push) Successful in 55s
Docker Release / release (push) Skipped

- Job logs: each job's stdout/stderr is teed into outputs/<id>/job.log
  (survives restarts) and served at GET /jobs/{id}/log as text/plain, so
  full run logs can be shared for debugging and refinement.
- Model picker: GET /models proxies OpenRouter's public model list with
  per-1M-token pricing (1h cache, 502 on failure); the UI shows a model
  dropdown with costs when OpenRouter compute is selected, and the pick
  overrides vision+text models for that job (Classic and Agent modes).
- Conflicts in the report view are grouped by discipline pair
  (collapsible sections, severity-ordered within groups) instead of one
  flat severity-only list.
This commit is contained in:
John Wilganowski
2026-07-28 21:23:42 +00:00
parent 4ecc7c5cef
commit afa1089311
8 changed files with 441 additions and 55 deletions
+26
View File
@@ -0,0 +1,26 @@
from backend import config
from backend.llm import _resolve_backend, set_model_override
def test_override_wins_for_vision_and_text():
set_model_override("openai/gpt-4o")
try:
assert _resolve_backend(has_images=True, model_override=None)["model"] == "openai/gpt-4o"
assert _resolve_backend(has_images=False, model_override=None)["model"] == "openai/gpt-4o"
finally:
set_model_override(None)
def test_override_beats_per_call_model_arg():
set_model_override("openai/gpt-4o")
try:
# Agents pass their AGENT_*_MODEL per call; the user's job pick wins.
assert _resolve_backend(has_images=False, model_override="other/model")["model"] == "openai/gpt-4o"
finally:
set_model_override(None)
def test_no_override_keeps_defaults():
set_model_override(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