import unittest from app.agents.browser_decision import _fallback_browser_decision from app.agents.browser_tools import ( _normalize_points, execute_browser_tool_call, parse_browser_json_response, ) from app.agents.graph.state import AgentState from app.agents.llm_client import _parse_openrouter_responses_api from app.agents.tooling import ToolCall, tool @tool(description="Add two numbers together") def add_numbers(left: int, right: int, note: str = "") -> dict: return {"sum": left + right, "note": note} class ToolingTests(unittest.TestCase): def test_tool_schema_marks_required_and_optional_fields(self): schema = add_numbers.schema self.assertEqual(schema.name, "add_numbers") self.assertEqual(schema.parameters["required"], ["left", "right"]) self.assertEqual(schema.parameters["properties"]["note"]["type"], "string") self.assertEqual(schema.parameters["properties"]["left"]["type"], "integer") def test_execute_browser_tool_call_normalizes_search_decision(self): result = execute_browser_tool_call( ToolCall( id="call_search", name="search_web", arguments={ "query": "latest groq models", "reason": "current page lacks the answer", "known_facts": ["Groq exposes an OpenAI-compatible API"], }, ) ) self.assertEqual(result["action"], "SEARCH") self.assertEqual(result["value"], "latest groq models") self.assertEqual(result["reason"], "current page lacks the answer") self.assertEqual(result["known_facts"], ["Groq exposes an OpenAI-compatible API"]) def test_parse_browser_json_response_maps_legacy_fields(self): parsed = parse_browser_json_response( """ { "action": "navigate", "url": "https://example.com/page", "reason": "This looks like the source page", "missing_points": ["exact launch date"] } """ ) self.assertEqual(parsed["action"], "NAVIGATE") self.assertEqual(parsed["value"], "https://example.com/page") self.assertEqual(parsed["reason"], "This looks like the source page") self.assertEqual(parsed["missing_points"], ["exact launch date"]) def test_parse_browser_json_response_rejects_scroll_when_mode_disallows_it(self): with self.assertRaises(ValueError) as ctx: parse_browser_json_response('{"action":"scroll"}', allow_scroll=False) self.assertIn("SCROLL", str(ctx.exception)) def test_normalize_points_treats_plain_string_as_single_item(self): self.assertEqual( _normalize_points("trump age still missing"), ["trump age still missing"], ) def test_agent_state_update_research_progress_does_not_split_string_into_chars(self): state = AgentState(task="qual idade do trump?") state.update_research_progress(missing_points="trump age still missing") self.assertEqual(state.missing_points, ["trump age still missing"]) def test_fallback_browser_decision_does_not_leak_reasoning_as_done(self): decision = _fallback_browser_decision( task="qual idade do trump?", current_url="https://en.wikipedia.org/wiki/Donald_Trump", blocked=False, allow_scroll=True, links=[], raw_text="We are on the Wikipedia page and should think step by step...", ) self.assertNotEqual(decision["action"], "DONE") self.assertEqual(decision["action"], "SCROLL") def test_fallback_browser_decision_uses_unseen_link_when_available(self): decision = _fallback_browser_decision( task="qual idade do trump?", current_url="https://html.duckduckgo.com/html/?q=qual+idade+do+trump", blocked=False, allow_scroll=False, links=["https://en.wikipedia.org/wiki/Donald_Trump"], raw_text="Let us think carefully first...", ) self.assertEqual(decision["action"], "NAVIGATE") self.assertEqual(decision["value"], "https://en.wikipedia.org/wiki/Donald_Trump") def test_parse_openrouter_responses_api_separates_reasoning_from_content_and_tools(self): parsed = _parse_openrouter_responses_api( { "model": "nvidia/nemotron-3-super-120b-a12b:free", "status": "completed", "output": [ { "type": "reasoning", "summary": [ "Need the current age", "Should inspect the canonical page first", ], }, { "type": "function_call", "id": "fc_1", "call_id": "call_1", "name": "navigate_to_url", "arguments": "{\"url\":\"https://en.wikipedia.org/wiki/Donald_Trump\"}", }, { "type": "message", "role": "assistant", "content": [ { "type": "output_text", "text": "Vou abrir a página principal.", } ], }, ], } ) self.assertEqual(parsed.reasoning, [ "Need the current age", "Should inspect the canonical page first", ]) self.assertEqual(parsed.content, "Vou abrir a página principal.") self.assertEqual(len(parsed.tool_calls), 1) self.assertEqual(parsed.tool_calls[0].name, "navigate_to_url") self.assertEqual( parsed.tool_calls[0].arguments, {"url": "https://en.wikipedia.org/wiki/Donald_Trump"}, ) if __name__ == "__main__": unittest.main()