Skip to content

Commit fd3a131

Browse files
author
Alex Lavaee
committed
fix: correct agent.run() API usage and update test mocks
- Fix mypy type errors by using agent.run() instead of client.run() - Retrieve agent by ID using client.create_agent(agent_id=...) - Update all test mocks to mock agent.run() instead of client.run() - Add explicit str() cast for response.text to satisfy type checker - Add ruff to dev dependencies for linting
1 parent 112a18a commit fd3a131

File tree

3 files changed

+33
-41
lines changed

3 files changed

+33
-41
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ dev = [
5555
"mypy>=1.18.2",
5656
"pyright>=1.1.406",
5757
"pytest-asyncio>=1.2.0",
58+
"ruff>=0.14.3",
5859
"types-pytz>=2025.2.0.20250809",
5960
]
6061

src/spec_to_agents/tools/bing_search.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,16 @@ async def web_search(
117117
# Get the persistent agent ID
118118
agent_id = await _get_or_create_web_search_agent_id()
119119

120-
# Use context manager for client - retrieve existing agent by ID
121-
async with create_agent_client(agent_id=agent_id) as client:
122-
# Client is now connected to the persistent agent
123-
response = await client.run(f"Perform a web search for: {query}")
124-
return response.text
120+
# Use context manager for client - agent persists on service
121+
async with create_agent_client() as client:
122+
# Retrieve the persistent agent by ID
123+
agent = client.create_agent(
124+
agent_id=agent_id,
125+
tools=[HostedWebSearchTool(description="Search the web for current information using Bing")],
126+
store=True,
127+
)
128+
response = await agent.run(f"Perform a web search for: {query}")
129+
return str(response.text)
125130

126131
except Exception as e:
127132
# Handle API errors gracefully

tests/test_tools_bing_search.py

Lines changed: 22 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ async def test_web_search_success():
4646
mock_response.text = 'Found 2 results for "Microsoft Agent Framework"\n\n1. Microsoft Agent Framework\n Build intelligent multi-agent systems.\n URL: https://github.com/microsoft/agent-framework' # noqa: E501
4747

4848
mock_client.create_agent.return_value = mock_agent
49-
mock_client.run = AsyncMock(return_value=mock_response)
49+
mock_agent.run = AsyncMock(return_value=mock_response)
5050
mock_client.__aenter__ = AsyncMock(return_value=mock_client)
5151
mock_client.__aexit__ = AsyncMock(return_value=None)
5252
mock_client_factory.return_value = mock_client
@@ -83,7 +83,7 @@ async def test_web_search_no_results():
8383
mock_response.text = "No results found for query: xyzabc123nonexistent"
8484

8585
mock_client.create_agent.return_value = mock_agent
86-
mock_client.run = AsyncMock(return_value=mock_response)
86+
mock_agent.run = AsyncMock(return_value=mock_response)
8787
mock_client.__aenter__ = AsyncMock(return_value=mock_client)
8888
mock_client.__aexit__ = AsyncMock(return_value=None)
8989
mock_client_factory.return_value = mock_client
@@ -118,7 +118,7 @@ async def test_web_search_with_custom_count():
118118
mock_response.text = "Found 2 results"
119119

120120
mock_client.create_agent.return_value = mock_agent
121-
mock_client.run = AsyncMock(return_value=mock_response)
121+
mock_agent.run = AsyncMock(return_value=mock_response)
122122
mock_client.__aenter__ = AsyncMock(return_value=mock_client)
123123
mock_client.__aexit__ = AsyncMock(return_value=None)
124124
mock_client_factory.return_value = mock_client
@@ -149,8 +149,8 @@ async def test_web_search_api_error():
149149
mock_client = Mock()
150150
mock_agent = Mock()
151151
mock_agent.id = "test-agent-id"
152-
# Make client.run() raise an exception (not agent.run())
153-
mock_client.run = AsyncMock(side_effect=Exception("API rate limit exceeded"))
152+
# Make agent.run() raise an exception
153+
mock_agent.run = AsyncMock(side_effect=Exception("API rate limit exceeded"))
154154
mock_client.create_agent.return_value = mock_agent
155155
# Mock context manager
156156
mock_client.__aenter__ = AsyncMock(return_value=mock_client)
@@ -194,7 +194,7 @@ async def test_web_search_formatting():
194194
)
195195

196196
mock_client.create_agent.return_value = mock_agent
197-
mock_client.run = AsyncMock(return_value=mock_response)
197+
mock_agent.run = AsyncMock(return_value=mock_response)
198198
mock_client.__aenter__ = AsyncMock(return_value=mock_client)
199199
mock_client.__aexit__ = AsyncMock(return_value=None)
200200
mock_client_factory.return_value = mock_client
@@ -233,7 +233,7 @@ async def test_web_search_empty_results_list():
233233
mock_response.text = "No results found for query: empty query"
234234

235235
mock_client.create_agent.return_value = mock_agent
236-
mock_client.run = AsyncMock(return_value=mock_response)
236+
mock_agent.run = AsyncMock(return_value=mock_response)
237237
mock_client.__aenter__ = AsyncMock(return_value=mock_client)
238238
mock_client.__aexit__ = AsyncMock(return_value=None)
239239
mock_client_factory.return_value = mock_client
@@ -274,7 +274,7 @@ async def test_web_search_result_numbering():
274274
)
275275

276276
mock_client.create_agent.return_value = mock_agent
277-
mock_client.run = AsyncMock(return_value=mock_response)
277+
mock_agent.run = AsyncMock(return_value=mock_response)
278278
mock_client.__aenter__ = AsyncMock(return_value=mock_client)
279279
mock_client.__aexit__ = AsyncMock(return_value=None)
280280
mock_client_factory.return_value = mock_client
@@ -300,6 +300,7 @@ async def test_web_search_result_numbering():
300300
)
301301
async def test_web_search_agent_persistence():
302302
"""Test that agent ID is stored and agent is retrieved by ID on subsequent calls."""
303+
import spec_to_agents.tools.bing_search as bing_search_module
303304
from spec_to_agents.tools.bing_search import web_search
304305

305306
# Note: autouse fixture automatically resets _web_search_agent_id before this test
@@ -308,9 +309,7 @@ async def test_web_search_agent_persistence():
308309
patch("spec_to_agents.tools.bing_search.create_agent_client") as mock_client_factory,
309310
patch("spec_to_agents.tools.bing_search.HostedWebSearchTool"),
310311
):
311-
# Mock two different clients - one for creation, one for retrieval
312-
mock_create_client = Mock()
313-
mock_retrieve_client = Mock()
312+
mock_client = Mock()
314313
mock_agent = Mock()
315314

316315
# Set the agent ID that will be stored
@@ -321,24 +320,14 @@ async def test_web_search_agent_persistence():
321320
response2 = Mock()
322321
response2.text = "Second search result"
323322

324-
# First client creates agent
325-
mock_create_client.create_agent.return_value = mock_agent
326-
mock_create_client.__aenter__ = AsyncMock(return_value=mock_create_client)
327-
mock_create_client.__aexit__ = AsyncMock(return_value=None)
328-
329-
# Second client retrieves agent by ID and runs queries
330-
mock_retrieve_client.run = AsyncMock(side_effect=[response1, response2])
331-
mock_retrieve_client.__aenter__ = AsyncMock(return_value=mock_retrieve_client)
332-
mock_retrieve_client.__aexit__ = AsyncMock(return_value=None)
333-
334-
# Track calls to verify correct parameters
335-
calls = []
336-
337-
def mock_factory(agent_id=None):
338-
calls.append(agent_id)
339-
return mock_create_client if agent_id is None else mock_retrieve_client
323+
# Mock agent to return different results for each call
324+
mock_agent.run = AsyncMock(side_effect=[response1, response2])
340325

341-
mock_client_factory.side_effect = mock_factory
326+
# Mock client to always return the same agent
327+
mock_client.create_agent.return_value = mock_agent
328+
mock_client.__aenter__ = AsyncMock(return_value=mock_client)
329+
mock_client.__aexit__ = AsyncMock(return_value=None)
330+
mock_client_factory.return_value = mock_client
342331

343332
# First call - should create agent and store ID
344333
result1 = await web_search("query 1")
@@ -351,14 +340,11 @@ def mock_factory(agent_id=None):
351340
# Agent ID should still be the same
352341
assert bing_search_module._web_search_agent_id == "test-agent-123"
353342

354-
# Verify create_agent_client was called with correct parameters
355-
assert len(calls) == 3 # One for creation, two for retrieval
356-
# First call creates (agent_id is None)
357-
assert calls[0] is None
358-
# Second call retrieves by ID
359-
assert calls[1] == "test-agent-123"
360-
# Third call retrieves by ID
361-
assert calls[2] == "test-agent-123"
343+
# Verify create_agent was called 3 times:
344+
# - Once to create the initial agent (in _get_or_create_web_search_agent_id)
345+
# - Once to retrieve it for first query
346+
# - Once to retrieve it for second query
347+
assert mock_client.create_agent.call_count == 3
362348

363349

364350
@pytest.mark.asyncio

0 commit comments

Comments
 (0)