fix(camofox): honor auxiliary vision temperature\n\n- forward auxiliary.vision.temperature in camofox screenshot analysis\n- add regression tests for configured and default behavior
This commit is contained in:
@@ -260,6 +260,72 @@ class TestCamofoxGetImages:
|
|||||||
assert result["images"][0]["src"] == "https://x.com/img.png"
|
assert result["images"][0]["src"] == "https://x.com/img.png"
|
||||||
|
|
||||||
|
|
||||||
|
class TestCamofoxVisionConfig:
|
||||||
|
@patch("tools.browser_camofox.requests.post")
|
||||||
|
@patch("tools.browser_camofox._get")
|
||||||
|
@patch("tools.browser_camofox._get_raw")
|
||||||
|
def test_camofox_vision_uses_configured_temperature_and_timeout(self, mock_get_raw, mock_get, mock_post, monkeypatch):
|
||||||
|
monkeypatch.setenv("CAMOFOX_URL", "http://localhost:9377")
|
||||||
|
mock_post.return_value = _mock_response(json_data={"tabId": "tab11", "url": "https://x.com"})
|
||||||
|
camofox_navigate("https://x.com", task_id="t11")
|
||||||
|
|
||||||
|
snapshot_text = '- button "Submit"\n'
|
||||||
|
raw_resp = MagicMock()
|
||||||
|
raw_resp.content = b"fakepng"
|
||||||
|
mock_get_raw.return_value = raw_resp
|
||||||
|
mock_get.return_value = {"snapshot": snapshot_text}
|
||||||
|
|
||||||
|
mock_response = MagicMock()
|
||||||
|
mock_choice = MagicMock()
|
||||||
|
mock_choice.message.content = "Camofox screenshot analysis"
|
||||||
|
mock_response.choices = [mock_choice]
|
||||||
|
|
||||||
|
with (
|
||||||
|
patch("tools.browser_camofox.open", create=True) as mock_open,
|
||||||
|
patch("agent.auxiliary_client.call_llm", return_value=mock_response) as mock_llm,
|
||||||
|
patch("hermes_cli.config.load_config", return_value={"auxiliary": {"vision": {"temperature": 1, "timeout": 45}}}),
|
||||||
|
):
|
||||||
|
mock_open.return_value.__enter__.return_value.read.return_value = b"fakepng"
|
||||||
|
result = json.loads(camofox_vision("what is on the page?", annotate=True, task_id="t11"))
|
||||||
|
|
||||||
|
assert result["success"] is True
|
||||||
|
assert result["analysis"] == "Camofox screenshot analysis"
|
||||||
|
assert mock_llm.call_args.kwargs["temperature"] == 1.0
|
||||||
|
assert mock_llm.call_args.kwargs["timeout"] == 45.0
|
||||||
|
|
||||||
|
@patch("tools.browser_camofox.requests.post")
|
||||||
|
@patch("tools.browser_camofox._get")
|
||||||
|
@patch("tools.browser_camofox._get_raw")
|
||||||
|
def test_camofox_vision_defaults_temperature_when_config_omits_it(self, mock_get_raw, mock_get, mock_post, monkeypatch):
|
||||||
|
monkeypatch.setenv("CAMOFOX_URL", "http://localhost:9377")
|
||||||
|
mock_post.return_value = _mock_response(json_data={"tabId": "tab12", "url": "https://x.com"})
|
||||||
|
camofox_navigate("https://x.com", task_id="t12")
|
||||||
|
|
||||||
|
snapshot_text = '- button "Submit"\n'
|
||||||
|
raw_resp = MagicMock()
|
||||||
|
raw_resp.content = b"fakepng"
|
||||||
|
mock_get_raw.return_value = raw_resp
|
||||||
|
mock_get.return_value = {"snapshot": snapshot_text}
|
||||||
|
|
||||||
|
mock_response = MagicMock()
|
||||||
|
mock_choice = MagicMock()
|
||||||
|
mock_choice.message.content = "Default camofox screenshot analysis"
|
||||||
|
mock_response.choices = [mock_choice]
|
||||||
|
|
||||||
|
with (
|
||||||
|
patch("tools.browser_camofox.open", create=True) as mock_open,
|
||||||
|
patch("agent.auxiliary_client.call_llm", return_value=mock_response) as mock_llm,
|
||||||
|
patch("hermes_cli.config.load_config", return_value={"auxiliary": {"vision": {}}}),
|
||||||
|
):
|
||||||
|
mock_open.return_value.__enter__.return_value.read.return_value = b"fakepng"
|
||||||
|
result = json.loads(camofox_vision("what is on the page?", annotate=True, task_id="t12"))
|
||||||
|
|
||||||
|
assert result["success"] is True
|
||||||
|
assert result["analysis"] == "Default camofox screenshot analysis"
|
||||||
|
assert mock_llm.call_args.kwargs["temperature"] == 0.1
|
||||||
|
assert mock_llm.call_args.kwargs["timeout"] == 120.0
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Routing integration — verify browser_tool routes to camofox
|
# Routing integration — verify browser_tool routes to camofox
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -545,9 +545,12 @@ def camofox_vision(question: str, annotate: bool = False,
|
|||||||
try:
|
try:
|
||||||
from hermes_cli.config import load_config
|
from hermes_cli.config import load_config
|
||||||
_cfg = load_config()
|
_cfg = load_config()
|
||||||
_vision_timeout = int(_cfg.get("auxiliary", {}).get("vision", {}).get("timeout", 120))
|
_vision_cfg = _cfg.get("auxiliary", {}).get("vision", {})
|
||||||
|
_vision_timeout = float(_vision_cfg.get("timeout", 120))
|
||||||
|
_vision_temperature = float(_vision_cfg.get("temperature", 0.1))
|
||||||
except Exception:
|
except Exception:
|
||||||
_vision_timeout = 120
|
_vision_timeout = 120.0
|
||||||
|
_vision_temperature = 0.1
|
||||||
|
|
||||||
response = call_llm(
|
response = call_llm(
|
||||||
messages=[{
|
messages=[{
|
||||||
@@ -563,6 +566,7 @@ def camofox_vision(question: str, annotate: bool = False,
|
|||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
task="vision",
|
task="vision",
|
||||||
|
temperature=_vision_temperature,
|
||||||
timeout=_vision_timeout,
|
timeout=_vision_timeout,
|
||||||
)
|
)
|
||||||
analysis = (response.choices[0].message.content or "").strip() if response.choices else ""
|
analysis = (response.choices[0].message.content or "").strip() if response.choices else ""
|
||||||
|
|||||||
Reference in New Issue
Block a user