mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-08 03:00:28 -04:00
fix(backend/copilot): address review — parallel fetch, None logging, failure tests
- Use asyncio.gather for parallel graph fetching instead of sequential loop - Cap graph fetches at 10 to prevent excessive DB calls on broad searches - Log warning when get_agent_as_json returns None (graph not found) - Add tests for exception and None return failure paths
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
from typing import TYPE_CHECKING, Literal
|
||||
|
||||
@@ -204,16 +205,25 @@ async def _search_library(
|
||||
)
|
||||
|
||||
|
||||
_MAX_GRAPH_FETCHES = 10
|
||||
|
||||
|
||||
async def _enrich_agents_with_graph(agents: list[AgentInfo], user_id: str) -> None:
|
||||
"""Fetch and attach full graph JSON (nodes + links) to each agent in-place."""
|
||||
for agent in agents:
|
||||
graph_id = agent.graph_id
|
||||
if not graph_id:
|
||||
continue
|
||||
fetchable = [a for a in agents if a.graph_id][:_MAX_GRAPH_FETCHES]
|
||||
if not fetchable:
|
||||
return
|
||||
|
||||
async def _fetch(agent: AgentInfo) -> None:
|
||||
try:
|
||||
agent.graph = await get_agent_as_json(graph_id, user_id)
|
||||
graph_json = await get_agent_as_json(agent.graph_id, user_id) # type: ignore[arg-type]
|
||||
if graph_json is None:
|
||||
logger.warning(f"Graph not found for agent {agent.graph_id}")
|
||||
agent.graph = graph_json
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to fetch graph for agent {graph_id}: {e}")
|
||||
logger.warning(f"Failed to fetch graph for agent {agent.graph_id}: {e}")
|
||||
|
||||
await asyncio.gather(*[_fetch(a) for a in fetchable])
|
||||
|
||||
|
||||
def _marketplace_agent_to_info(agent: StoreAgent | StoreAgentDetails) -> AgentInfo:
|
||||
|
||||
@@ -247,3 +247,67 @@ class TestLibraryUUIDLookup:
|
||||
assert isinstance(response, AgentsFoundResponse)
|
||||
assert response.agents[0].graph is None
|
||||
mock_get_json.assert_not_awaited()
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_include_graph_handles_fetch_failure(self):
|
||||
"""include_graph=True still returns agents when graph fetch fails."""
|
||||
agent_id = "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
|
||||
mock_agent = self._make_mock_library_agent(agent_id)
|
||||
|
||||
mock_lib_db = MagicMock()
|
||||
mock_lib_db.get_library_agent_by_graph_id = AsyncMock(return_value=mock_agent)
|
||||
|
||||
with (
|
||||
patch(
|
||||
"backend.copilot.tools.agent_search.library_db",
|
||||
return_value=mock_lib_db,
|
||||
),
|
||||
patch(
|
||||
"backend.copilot.tools.agent_search.get_agent_as_json",
|
||||
new_callable=AsyncMock,
|
||||
side_effect=Exception("DB connection failed"),
|
||||
),
|
||||
):
|
||||
response = await search_agents(
|
||||
query=agent_id,
|
||||
source="library",
|
||||
session_id="test-session",
|
||||
user_id=_TEST_USER_ID,
|
||||
include_graph=True,
|
||||
)
|
||||
|
||||
assert isinstance(response, AgentsFoundResponse)
|
||||
assert response.count == 1
|
||||
assert response.agents[0].graph is None
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_include_graph_handles_none_return(self):
|
||||
"""include_graph=True handles get_agent_as_json returning None."""
|
||||
agent_id = "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
|
||||
mock_agent = self._make_mock_library_agent(agent_id)
|
||||
|
||||
mock_lib_db = MagicMock()
|
||||
mock_lib_db.get_library_agent_by_graph_id = AsyncMock(return_value=mock_agent)
|
||||
|
||||
with (
|
||||
patch(
|
||||
"backend.copilot.tools.agent_search.library_db",
|
||||
return_value=mock_lib_db,
|
||||
),
|
||||
patch(
|
||||
"backend.copilot.tools.agent_search.get_agent_as_json",
|
||||
new_callable=AsyncMock,
|
||||
return_value=None,
|
||||
),
|
||||
):
|
||||
response = await search_agents(
|
||||
query=agent_id,
|
||||
source="library",
|
||||
session_id="test-session",
|
||||
user_id=_TEST_USER_ID,
|
||||
include_graph=True,
|
||||
)
|
||||
|
||||
assert isinstance(response, AgentsFoundResponse)
|
||||
assert response.count == 1
|
||||
assert response.agents[0].graph is None
|
||||
|
||||
Reference in New Issue
Block a user