Skip to content

Commit bb59111

Browse files
committed
feat: use a2a sdk
1 parent 6ba9a4a commit bb59111

File tree

20 files changed

+3454
-3445
lines changed

20 files changed

+3454
-3445
lines changed

openhands/a2a/A2AManager.py

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@
33
from abc import ABC
44
from typing import AsyncGenerator, List
55

6-
from openhands.a2a.client.card_resolver import A2ACardResolver
7-
from openhands.a2a.client.client import A2AClient
8-
from openhands.a2a.common.types import (
9-
A2AClientHTTPError,
10-
A2AClientJSONError,
6+
from a2a.client import A2ACardResolver, A2AClient
7+
from a2a.client.errors import A2AClientHTTPError, A2AClientJSONError
8+
from a2a.types import (
119
AgentCard,
1210
Message,
13-
SendTaskResponse,
14-
SendTaskStreamingResponse,
15-
TaskSendParams,
11+
MessageSendParams,
12+
SendMessageRequest,
13+
SendMessageResponse,
14+
SendStreamingMessageResponse,
1615
TextPart,
1716
)
17+
1818
from openhands.core.logger import openhands_logger as logger
1919

2020

@@ -73,9 +73,9 @@ def list_remote_agents(self):
7373
)
7474
return remote_agent_info
7575

76-
async def send_task(
77-
self, agent_name: str, message: str, sid: str
78-
) -> AsyncGenerator[SendTaskStreamingResponse | SendTaskResponse, None]:
76+
async def send_message(
77+
self, agent_name: str, message: str, sid: str, role: str = 'user'
78+
) -> AsyncGenerator[SendStreamingMessageResponse | SendMessageResponse, None]:
7979
"""Send a task to a remote agent and yield task responses.
8080
8181
Args:
@@ -91,25 +91,29 @@ async def send_task(
9191

9292
card = self.list_remote_agent_cards[agent_name]
9393
client = A2AClient(card)
94-
request: TaskSendParams = TaskSendParams(
95-
id=str(uuid.uuid4()),
94+
params: MessageSendParams = MessageSendParams(
9695
sessionId=sid,
9796
message=Message(
98-
role='user',
97+
role=role,
9998
parts=[TextPart(text=message)],
10099
metadata={},
101100
),
102101
acceptedOutputModes=['text', 'text/plain', 'image/png'],
103-
metadata={'conversation_id': sid},
102+
metadata={'conversation_id': sid, 'session_id': sid},
103+
)
104+
request: SendMessageRequest = SendMessageRequest(
105+
id=str(uuid.uuid4()),
106+
sessionId=sid,
107+
params=params,
104108
)
105109

106110
logger.info(f'Sending task to {agent_name} with message: {message}')
107111
logger.info(f'Card capabilities: {card.capabilities}')
108112
if card.capabilities.streaming:
109-
async for response in client.send_task_streaming(request):
113+
async for response in client.send_message_streaming(request=request):
110114
yield response
111115
else:
112-
response = await client.send_task(request)
116+
response = await client.send_message(request=request)
113117
yield response
114118

115119
# async def send_cancel_task(self, task_id: str, sid: str):

openhands/a2a/a2a.py

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22
import asyncio
33
from uuid import uuid4
44

5-
from openhands.a2a.client import A2ACardResolver, A2AClient
6-
from openhands.a2a.common.types import TaskState, TaskStatusUpdateEvent
5+
from a2a.client import A2ACardResolver, A2AClient
6+
from a2a.types import AgentCard, JSONRPCErrorResponse, TaskState, TaskStatusUpdateEvent
7+
8+
from containers.runtime.code.openhands.utils.async_utils import call_async_from_sync
9+
from openhands.core.logger import openhands_logger as logger
710
from openhands.core.message import TextContent
811

912

@@ -13,10 +16,7 @@ def __init__(self, a2a_server_url: str, session: str = None, history: bool = Fal
1316
self.history = history
1417

1518
self.card_resolver = A2ACardResolver(a2a_server_url)
16-
self.card = self.card_resolver.get_agent_card()
17-
18-
print('======= Agent Card ========')
19-
print(self.card.model_dump_json(exclude_none=True))
19+
self.card: AgentCard = call_async_from_sync(self.card_resolver.get_agent_card())
2020

2121
self.client = A2AClient(agent_card=self.card)
2222
if session:
@@ -61,21 +61,24 @@ async def completeTask(self, streaming, taskId, sessionId, messages: list[str]):
6161

6262
taskResult = None
6363
if streaming:
64-
response_stream = self.client.send_task_streaming(payload)
64+
response_stream = self.client.send_message_streaming(payload)
6565
async for result in response_stream:
6666
print(f'stream event => {result.model_dump_json(exclude_none=True)}')
6767
if (
68-
result.result
69-
and isinstance(result.result, TaskStatusUpdateEvent)
70-
and result.result.final
68+
result.root
69+
and isinstance(result.root.result, TaskStatusUpdateEvent)
70+
and result.root.result.final
7171
):
7272
return False
7373
else:
74-
taskResult = await self.client.send_task(payload)
74+
taskResult = await self.client.send_message(payload)
7575
print(f'\ntask result => {taskResult.model_dump_json(exclude_none=True)}')
7676
## if the result is that more input is required, loop again.
77-
state = TaskState(taskResult.result.status.state)
78-
if state.name == TaskState.INPUT_REQUIRED.name:
77+
if isinstance(taskResult.root, JSONRPCErrorResponse):
78+
logger.error(f'Error sending message to agent A2A: {taskResult.root}')
79+
return False
80+
state = TaskState(taskResult.root.result.status.state)
81+
if state.name == TaskState.input_required.name:
7982
return await self.completeTask(streaming, taskId, sessionId)
8083
else:
8184
## task is complete

openhands/a2a/client/__init__.py

Lines changed: 0 additions & 4 deletions
This file was deleted.

openhands/a2a/client/card_resolver.py

Lines changed: 0 additions & 50 deletions
This file was deleted.

openhands/a2a/client/client.py

Lines changed: 0 additions & 83 deletions
This file was deleted.

openhands/a2a/common/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)