diff --git a/tests/tools/test_browser_camofox.py b/tests/tools/test_browser_camofox.py index 81d69967de..8cf24bdafd 100644 --- a/tests/tools/test_browser_camofox.py +++ b/tests/tools/test_browser_camofox.py @@ -260,6 +260,72 @@ class TestCamofoxGetImages: 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 # --------------------------------------------------------------------------- diff --git a/tools/browser_camofox.py b/tools/browser_camofox.py index 88f486f196..0efeb16e9b 100644 --- a/tools/browser_camofox.py +++ b/tools/browser_camofox.py @@ -545,9 +545,12 @@ def camofox_vision(question: str, annotate: bool = False, try: from hermes_cli.config import 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: - _vision_timeout = 120 + _vision_timeout = 120.0 + _vision_temperature = 0.1 response = call_llm( messages=[{ @@ -563,6 +566,7 @@ def camofox_vision(question: str, annotate: bool = False, ], }], task="vision", + temperature=_vision_temperature, timeout=_vision_timeout, ) analysis = (response.choices[0].message.content or "").strip() if response.choices else ""