2026-04-21 17:12:58 -04:00
|
|
|
"""Tests for browser_tool._get_vision_model() — Gemma 4 default (Issue #816).
|
|
|
|
|
|
|
|
|
|
Covers acceptance criteria from issue #816:
|
|
|
|
|
- Browser screenshots use Gemma 4 by default.
|
|
|
|
|
- BROWSER_VISION_MODEL env var overrides the model for browser vision only.
|
|
|
|
|
- AUXILIARY_VISION_MODEL env var still works as a global override.
|
|
|
|
|
- auxiliary.browser_vision.model in config.yaml overrides the default.
|
|
|
|
|
- Priority: BROWSER_VISION_MODEL > config.yaml > AUXILIARY_VISION_MODEL > default.
|
|
|
|
|
"""
|
2026-04-21 12:49:46 -04:00
|
|
|
|
2026-04-21 20:48:15 -04:00
|
|
|
import os
|
2026-04-21 12:49:46 -04:00
|
|
|
import sys
|
|
|
|
|
from unittest.mock import patch, MagicMock
|
|
|
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TestGetVisionModelDefault:
|
|
|
|
|
def test_default_is_gemma4(self, monkeypatch):
|
|
|
|
|
monkeypatch.delenv("BROWSER_VISION_MODEL", raising=False)
|
|
|
|
|
monkeypatch.delenv("AUXILIARY_VISION_MODEL", raising=False)
|
|
|
|
|
import tools.browser_tool as bt
|
2026-04-21 18:16:58 -04:00
|
|
|
with patch("hermes_cli.config.load_config", return_value={}):
|
|
|
|
|
model = bt._get_vision_model()
|
2026-04-21 12:49:46 -04:00
|
|
|
assert model == "google/gemma-4-27b-it"
|
|
|
|
|
|
|
|
|
|
def test_default_constant(self):
|
|
|
|
|
import tools.browser_tool as bt
|
|
|
|
|
assert bt._BROWSER_VISION_DEFAULT_MODEL == "google/gemma-4-27b-it"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TestGetVisionModelEnvOverrides:
|
|
|
|
|
def test_browser_vision_model_env_takes_priority(self, monkeypatch):
|
|
|
|
|
monkeypatch.setenv("BROWSER_VISION_MODEL", "openai/gpt-4o")
|
|
|
|
|
monkeypatch.setenv("AUXILIARY_VISION_MODEL", "google/gemini-3-flash-preview")
|
|
|
|
|
import tools.browser_tool as bt
|
|
|
|
|
assert bt._get_vision_model() == "openai/gpt-4o"
|
|
|
|
|
|
|
|
|
|
def test_auxiliary_vision_model_fallback(self, monkeypatch):
|
|
|
|
|
monkeypatch.delenv("BROWSER_VISION_MODEL", raising=False)
|
|
|
|
|
monkeypatch.setenv("AUXILIARY_VISION_MODEL", "google/gemini-3-flash-preview")
|
|
|
|
|
import tools.browser_tool as bt
|
2026-04-21 18:16:58 -04:00
|
|
|
with patch("hermes_cli.config.load_config", return_value={}):
|
|
|
|
|
assert bt._get_vision_model() == "google/gemini-3-flash-preview"
|
2026-04-21 12:49:46 -04:00
|
|
|
|
|
|
|
|
def test_browser_vision_model_empty_falls_through(self, monkeypatch):
|
|
|
|
|
"""Empty BROWSER_VISION_MODEL should fall through to next step."""
|
|
|
|
|
monkeypatch.setenv("BROWSER_VISION_MODEL", "")
|
|
|
|
|
monkeypatch.delenv("AUXILIARY_VISION_MODEL", raising=False)
|
|
|
|
|
import tools.browser_tool as bt
|
2026-04-21 18:16:58 -04:00
|
|
|
with patch("hermes_cli.config.load_config", return_value={}):
|
|
|
|
|
# Should reach the default
|
|
|
|
|
assert bt._get_vision_model() == "google/gemma-4-27b-it"
|
2026-04-21 12:49:46 -04:00
|
|
|
|
|
|
|
|
def test_auxiliary_vision_model_empty_falls_through(self, monkeypatch):
|
|
|
|
|
monkeypatch.delenv("BROWSER_VISION_MODEL", raising=False)
|
|
|
|
|
monkeypatch.setenv("AUXILIARY_VISION_MODEL", "")
|
|
|
|
|
import tools.browser_tool as bt
|
2026-04-21 18:16:58 -04:00
|
|
|
with patch("hermes_cli.config.load_config", return_value={}):
|
|
|
|
|
assert bt._get_vision_model() == "google/gemma-4-27b-it"
|
2026-04-21 12:49:46 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class TestGetVisionModelConfig:
|
|
|
|
|
def test_config_overrides_default(self, monkeypatch):
|
|
|
|
|
monkeypatch.delenv("BROWSER_VISION_MODEL", raising=False)
|
|
|
|
|
monkeypatch.delenv("AUXILIARY_VISION_MODEL", raising=False)
|
|
|
|
|
cfg = {"auxiliary": {"browser_vision": {"model": "anthropic/claude-3-5-haiku"}}}
|
|
|
|
|
with patch("hermes_cli.config.load_config", return_value=cfg):
|
|
|
|
|
import tools.browser_tool as bt
|
|
|
|
|
assert bt._get_vision_model() == "anthropic/claude-3-5-haiku"
|
|
|
|
|
|
|
|
|
|
def test_config_empty_string_falls_through_to_default(self, monkeypatch):
|
|
|
|
|
monkeypatch.delenv("BROWSER_VISION_MODEL", raising=False)
|
|
|
|
|
monkeypatch.delenv("AUXILIARY_VISION_MODEL", raising=False)
|
|
|
|
|
cfg = {"auxiliary": {"browser_vision": {"model": ""}}}
|
|
|
|
|
with patch("hermes_cli.config.load_config", return_value=cfg):
|
|
|
|
|
import tools.browser_tool as bt
|
|
|
|
|
assert bt._get_vision_model() == "google/gemma-4-27b-it"
|
|
|
|
|
|
|
|
|
|
def test_config_load_error_falls_through_to_default(self, monkeypatch):
|
|
|
|
|
monkeypatch.delenv("BROWSER_VISION_MODEL", raising=False)
|
|
|
|
|
monkeypatch.delenv("AUXILIARY_VISION_MODEL", raising=False)
|
|
|
|
|
with patch("hermes_cli.config.load_config", side_effect=Exception("config error")):
|
|
|
|
|
import tools.browser_tool as bt
|
|
|
|
|
assert bt._get_vision_model() == "google/gemma-4-27b-it"
|
|
|
|
|
|
|
|
|
|
def test_env_beats_config(self, monkeypatch):
|
|
|
|
|
monkeypatch.setenv("BROWSER_VISION_MODEL", "openai/gpt-4o")
|
|
|
|
|
cfg = {"auxiliary": {"browser_vision": {"model": "anthropic/claude-3-5-haiku"}}}
|
|
|
|
|
with patch("hermes_cli.config.load_config", return_value=cfg):
|
|
|
|
|
import tools.browser_tool as bt
|
|
|
|
|
assert bt._get_vision_model() == "openai/gpt-4o"
|
2026-04-21 17:12:58 -04:00
|
|
|
|
|
|
|
|
def test_config_beats_auxiliary_vision_model(self, monkeypatch):
|
|
|
|
|
"""Config should override AUXILIARY_VISION_MODEL when BROWSER_VISION_MODEL unset."""
|
|
|
|
|
monkeypatch.delenv("BROWSER_VISION_MODEL", raising=False)
|
|
|
|
|
monkeypatch.setenv("AUXILIARY_VISION_MODEL", "global-override")
|
|
|
|
|
cfg = {"auxiliary": {"browser_vision": {"model": "config-model"}}}
|
|
|
|
|
with patch("hermes_cli.config.load_config", return_value=cfg):
|
|
|
|
|
import tools.browser_tool as bt
|
|
|
|
|
assert bt._get_vision_model() == "config-model"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TestBackwardCompatibility:
|
|
|
|
|
"""AUXILIARY_VISION_MODEL must still work for users who already have it configured."""
|
|
|
|
|
|
|
|
|
|
def test_existing_auxiliary_vision_model_not_broken(self, monkeypatch):
|
|
|
|
|
"""Users who set AUXILIARY_VISION_MODEL must not be broken by this change."""
|
|
|
|
|
monkeypatch.delenv("BROWSER_VISION_MODEL", raising=False)
|
|
|
|
|
monkeypatch.setenv("AUXILIARY_VISION_MODEL", "openai/gpt-4o")
|
|
|
|
|
import tools.browser_tool as bt
|
|
|
|
|
with patch("hermes_cli.config.load_config", return_value={}):
|
|
|
|
|
model = bt._get_vision_model()
|
|
|
|
|
assert model == "openai/gpt-4o"
|
|
|
|
|
assert model != "google/gemma-4-27b-it"
|