feat: migrate agent core to pydantic-ai framework
This commit is contained in:
@@ -107,7 +107,7 @@ async def test_dispatch_planning_and_coding_phases(mock_planning_class: MagicMoc
|
||||
mock_client.issues.get_issue_comments.return_value = []
|
||||
|
||||
from gitea.models import UserModel
|
||||
mock_client.get_authenticated_user.return_value = UserModel(login="unknown-ai")
|
||||
mock_client.repos.get_authenticated_user.return_value = UserModel(login="unknown-ai")
|
||||
|
||||
mock_pr = PullRequestModel(
|
||||
number=42,
|
||||
|
||||
@@ -275,7 +275,13 @@ def _make_comment(login: str, body: str) -> CommentModel:
|
||||
def _make_dispatcher_for_reply_tests() -> AgentDispatcher:
|
||||
mock_client = MagicMock()
|
||||
mock_client.repos.get_authenticated_user.return_value = UserModel(login="unknown-ai")
|
||||
return AgentDispatcher(client=mock_client, tools=MagicMock())
|
||||
return AgentDispatcher(
|
||||
client=mock_client,
|
||||
issue_tools=MagicMock(),
|
||||
pr_tools=MagicMock(),
|
||||
file_tools=MagicMock(),
|
||||
git_tools=MagicMock(),
|
||||
)
|
||||
|
||||
|
||||
def test_is_awaiting_reply_no_comments() -> None:
|
||||
|
||||
+3
-7
@@ -8,11 +8,9 @@ pytestmark = pytest.mark.anyio
|
||||
@patch("main.load_dotenv")
|
||||
@patch("main.os.chdir")
|
||||
@patch("main.GiteaClient")
|
||||
@patch("main.GiteaTools")
|
||||
@patch("main.AgentOrchestrator")
|
||||
async def test_main_startup_success(
|
||||
mock_orchestrator_class: MagicMock,
|
||||
mock_tools_class: MagicMock,
|
||||
mock_client_class: MagicMock,
|
||||
mock_chdir: MagicMock,
|
||||
mock_load_dotenv: MagicMock
|
||||
@@ -21,7 +19,7 @@ async def test_main_startup_success(
|
||||
mock_client_class.return_value = mock_client
|
||||
mock_user = MagicMock()
|
||||
mock_user.login = "agent-test"
|
||||
mock_client.get_authenticated_user.return_value = mock_user
|
||||
mock_client.repos.get_authenticated_user.return_value = mock_user
|
||||
|
||||
mock_orchestrator = MagicMock()
|
||||
mock_orchestrator.poll_and_dispatch = AsyncMock(side_effect=KeyboardInterrupt())
|
||||
@@ -30,18 +28,16 @@ async def test_main_startup_success(
|
||||
# Run main; it should exit gracefully on KeyboardInterrupt
|
||||
await main()
|
||||
|
||||
mock_client.get_authenticated_user.assert_called_once()
|
||||
mock_client.repos.get_authenticated_user.assert_called_once()
|
||||
mock_orchestrator.poll_and_dispatch.assert_called_once()
|
||||
|
||||
|
||||
@patch("main.load_dotenv")
|
||||
@patch("main.os.chdir")
|
||||
@patch("main.GiteaClient")
|
||||
@patch("main.GiteaTools")
|
||||
@patch("main.AgentOrchestrator")
|
||||
async def test_main_startup_fails_no_authenticated_user(
|
||||
mock_orchestrator_class: MagicMock,
|
||||
mock_tools_class: MagicMock,
|
||||
mock_client_class: MagicMock,
|
||||
mock_chdir: MagicMock,
|
||||
mock_load_dotenv: MagicMock
|
||||
@@ -49,7 +45,7 @@ async def test_main_startup_fails_no_authenticated_user(
|
||||
mock_client = MagicMock()
|
||||
mock_client_class.return_value = mock_client
|
||||
# Simulate no user returned
|
||||
mock_client.get_authenticated_user.return_value = None
|
||||
mock_client.repos.get_authenticated_user.return_value = None
|
||||
|
||||
with pytest.raises(SystemExit) as exc_info:
|
||||
await main()
|
||||
|
||||
+19
-21
@@ -4,7 +4,6 @@ import pytest
|
||||
from unittest.mock import MagicMock, AsyncMock, patch
|
||||
|
||||
from core.orchestrator import AgentOrchestrator
|
||||
from gitea.client import GiteaClient
|
||||
from gitea.models import IssueModel, PullRequestModel, RepositoryModel
|
||||
|
||||
pytestmark = pytest.mark.anyio
|
||||
@@ -29,16 +28,17 @@ async def test_poll_and_dispatch_no_notifications(
|
||||
temp_state_file: Path
|
||||
) -> None:
|
||||
mock_get_path.return_value = temp_state_file
|
||||
mock_client = MagicMock(spec=GiteaClient)
|
||||
mock_tools = MagicMock()
|
||||
mock_client = MagicMock()
|
||||
|
||||
# Return no notifications
|
||||
mock_client.list_unread_notifications.return_value = []
|
||||
mock_client.notifications.list_unread_notifications.return_value = []
|
||||
|
||||
orchestrator = AgentOrchestrator(mock_client, mock_tools)
|
||||
orchestrator = AgentOrchestrator(
|
||||
mock_client, MagicMock(), MagicMock(), MagicMock(), MagicMock()
|
||||
)
|
||||
await orchestrator.poll_and_dispatch()
|
||||
|
||||
mock_client.list_unread_notifications.assert_called_once_with(since=None)
|
||||
mock_client.notifications.list_unread_notifications.assert_called_once_with(since=None)
|
||||
assert not temp_state_file.exists()
|
||||
|
||||
|
||||
@@ -66,8 +66,7 @@ async def test_poll_and_dispatch_with_notifications(
|
||||
return "Decided"
|
||||
mock_reader.decide_notification = AsyncMock(side_effect=mock_decide_notification)
|
||||
mock_notification_reader_class.return_value = mock_reader
|
||||
mock_client = MagicMock(spec=GiteaClient)
|
||||
mock_tools = MagicMock()
|
||||
mock_client = MagicMock()
|
||||
|
||||
# Set up mock Gitea notifications
|
||||
notifications = [
|
||||
@@ -98,13 +97,14 @@ async def test_poll_and_dispatch_with_notifications(
|
||||
}
|
||||
}
|
||||
]
|
||||
mock_client.list_unread_notifications.return_value = notifications
|
||||
mock_client.notifications.list_unread_notifications.return_value = notifications
|
||||
|
||||
# Mock issue and PR get methods
|
||||
# Mock issue and PR get methods on client
|
||||
issue_model = IssueModel(number=42, title="Bug issue", repository=RepositoryModel(name="repo1", full_name="meeks/repo1"))
|
||||
pr_model = PullRequestModel(number=10, title="Fix PR", repository=RepositoryModel(name="repo1", full_name="meeks/repo1"))
|
||||
mock_client.get_issue.return_value = issue_model
|
||||
mock_client.get_pull_request.return_value = pr_model
|
||||
|
||||
mock_client.issues.get_issue.return_value = issue_model
|
||||
mock_client.prs.get_pull_request.return_value = pr_model
|
||||
|
||||
# Mock dispatcher and workspace path
|
||||
mock_dispatcher_instance = MagicMock()
|
||||
@@ -116,15 +116,13 @@ async def test_poll_and_dispatch_with_notifications(
|
||||
mock_workspace_class.return_value = mock_workspace_instance
|
||||
|
||||
# Create orchestrator and poll
|
||||
orchestrator = AgentOrchestrator(mock_client, mock_tools)
|
||||
orchestrator = AgentOrchestrator(
|
||||
mock_client, MagicMock(), MagicMock(), MagicMock(), MagicMock()
|
||||
)
|
||||
await orchestrator.poll_and_dispatch()
|
||||
|
||||
# Assert notifications were checked with None (first execution)
|
||||
mock_client.list_unread_notifications.assert_called_once_with(since=None)
|
||||
|
||||
# Assert issue and PR details were fetched
|
||||
mock_client.get_issue.assert_called_once_with("meeks", "repo1", 42)
|
||||
mock_client.get_pull_request.assert_called_once_with("meeks", "repo1", 10)
|
||||
mock_client.notifications.list_unread_notifications.assert_called_once_with(since=None)
|
||||
|
||||
# Assert work was processed by dispatcher
|
||||
mock_dispatcher_instance.dispatch.assert_called_once()
|
||||
@@ -136,9 +134,9 @@ async def test_poll_and_dispatch_with_notifications(
|
||||
assert work_items[1].notification_id == 102
|
||||
|
||||
# Assert notifications were marked as read
|
||||
mock_client.mark_notification_as_read.assert_any_call(101)
|
||||
mock_client.mark_notification_as_read.assert_any_call(102)
|
||||
assert mock_client.mark_notification_as_read.call_count == 2
|
||||
mock_client.notifications.mark_notification_as_read.assert_any_call(101)
|
||||
mock_client.notifications.mark_notification_as_read.assert_any_call(102)
|
||||
assert mock_client.notifications.mark_notification_as_read.call_count == 2
|
||||
|
||||
# Assert checkpoint date was persisted
|
||||
assert temp_state_file.exists()
|
||||
|
||||
Reference in New Issue
Block a user