distributed-a2a 0.1.1__py3-none-any.whl → 0.1.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,7 @@
1
+ from .client import RoutingA2AClient
1
2
  from .server import load_app
2
3
 
3
4
  __all__ = [
4
- "load_app"
5
+ "load_app",
6
+ "RoutingA2AClient"
5
7
  ]
@@ -0,0 +1,110 @@
1
+ import json
2
+ import time
3
+ from uuid import uuid4
4
+
5
+ import httpx
6
+ from a2a.client import ClientConfig, ClientFactory, A2ACardResolver, ClientEvent
7
+ from a2a.client import create_text_message_object
8
+ from a2a.types import (
9
+ AgentCard,
10
+ Message, TaskQueryParams, Task, Artifact, Part, TextPart
11
+ )
12
+ from a2a.types import TaskState
13
+
14
+
15
+ class RemoteAgentConnection:
16
+ """A class to hold the connections to the remote agents."""
17
+
18
+ def __init__(self, agent_card: AgentCard, client: httpx.AsyncClient):
19
+ client_config = ClientConfig(
20
+ httpx_client=client,
21
+ supported_transports=[agent_card.preferred_transport],
22
+ streaming=agent_card.capabilities.streaming,
23
+ polling=True
24
+ )
25
+ client_factory = ClientFactory(config=client_config)
26
+ self.agent_client = client_factory.create(agent_card)
27
+
28
+ async def _send_message_to_agent(self, message_request: Message) -> Task:
29
+
30
+ responses: list[ClientEvent] = []
31
+ async for response in self.agent_client.send_message(message_request):
32
+ responses.append(response)
33
+
34
+ task_response: Task | None = None
35
+ match responses:
36
+ case [(task, _)]:
37
+ task_response = task
38
+ case _:
39
+ raise Exception("Wrong response format")
40
+ return task_response
41
+
42
+ async def _get_task(self, task_id: str) -> Task:
43
+ query_params: TaskQueryParams = TaskQueryParams(id=task_id)
44
+ response: Task = await self.agent_client.get_task(query_params)
45
+ return response
46
+
47
+ async def send_message(self, message_to_send: str, context_id, task_id: None | str = None,
48
+ count=0) -> str | AgentCard:
49
+ message: Message = create_text_message_object(content=message_to_send)
50
+ message.message_id = str(uuid4())
51
+ message.context_id = context_id
52
+
53
+ response: Task
54
+ if task_id is None:
55
+ response = await self._send_message_to_agent(message)
56
+ else:
57
+ response = await self._get_task(task_id)
58
+
59
+ task_state = response.status.state
60
+ if task_state == TaskState.working or task_state == TaskState.submitted:
61
+ if count < 20:
62
+ time.sleep(1)
63
+ return await self.send_message(message_to_send, context_id, response.id, count + 1)
64
+ else:
65
+ raise Exception("Timeout waiting for agent to respond")
66
+
67
+ if task_state == TaskState.failed:
68
+ raise Exception("A2ATaskFailed")
69
+ elif task_state == TaskState.auth_required:
70
+ raise Exception("A2ATaskAuthRequired")
71
+
72
+ match response.artifacts:
73
+ case [Artifact(name='target_agent', parts=[Part(root=TextPart(text=agent_card))])]:
74
+ return AgentCard(**json.loads(agent_card))
75
+ case [Artifact(name='current_result', parts=[Part(root=TextPart(text=result))])]:
76
+ return result
77
+ case _:
78
+ raise Exception("Wrong response format")
79
+
80
+
81
+ MAX_RECURSION_DEPTH = 10
82
+
83
+
84
+ class RoutingA2AClient:
85
+ def __init__(self, initial_url: str):
86
+ self.url = initial_url
87
+ self.client = httpx.AsyncClient()
88
+ self.current_card: AgentCard | None = None
89
+
90
+ async def fetch_current_card(self):
91
+ card_resolver = A2ACardResolver(
92
+ self.client, self.url
93
+ )
94
+ self.current_card = (
95
+ await card_resolver.get_agent_card()
96
+ )
97
+
98
+ async def send_message(self, message: str, context_id: str, depth: int = 0) -> str:
99
+ if depth > MAX_RECURSION_DEPTH:
100
+ raise Exception("Maximum recursion depth exceeded. This is likely due to an infinite loop in your agent.")
101
+ if self.current_card is None:
102
+ await self.fetch_current_card()
103
+
104
+ agent_connection = RemoteAgentConnection(self.current_card, self.client)
105
+
106
+ agent_response: str | AgentCard = await agent_connection.send_message(message, context_id)
107
+ if isinstance(agent_response, AgentCard):
108
+ self.current_card = agent_response
109
+ return await self.send_message(message, context_id, depth + 1)
110
+ return agent_response
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: distributed_a2a
3
- Version: 0.1.1
3
+ Version: 0.1.3
4
4
  Summary: A library for building A2A agents with routing capabilities
5
5
  Home-page: https://github.com/Barra-Technologies/distributed-a2a
6
6
  Author: Fabian Bell
@@ -1,11 +1,12 @@
1
- distributed_a2a/__init__.py,sha256=fff-M86h-bxXMrtmNoHhL7mY-5vTx9ED1VJ9s2HVoXE,59
1
+ distributed_a2a/__init__.py,sha256=1q_7gRfBCGe-7sF_9YKzevyS97XQhtuFnZiYHIqaU-0,120
2
2
  distributed_a2a/agent.py,sha256=dv4EBN70E4PoW9XxErwUEievDB7X-gyz8bmbG0Z-05U,2376
3
+ distributed_a2a/client.py,sha256=2974Uw8YUuyBytwxxJJKYsWXCpEaIbGmMUHDraITxJ0,4149
3
4
  distributed_a2a/executors.py,sha256=xXiJydbb4modTdn7XmDflJ4QZ6v_SBeiIrLlcNErc9M,3951
4
5
  distributed_a2a/model.py,sha256=I-e0V1cqxbRNi2LdSZW8XPkgqncy9zX_dOXAusuqPrQ,331
5
6
  distributed_a2a/registry.py,sha256=197eZVR6TW0isOUE0VjWSWs7aCqbWqnBzcV8EVXAxrI,677
6
7
  distributed_a2a/server.py,sha256=C83rt-T3_EGQbDfPmncSvpa9PYbJxweHc5tKFmTOnvI,2601
7
- distributed_a2a-0.1.1.dist-info/licenses/LICENSE,sha256=Btzdu2kIoMbdSp6OyCLupB1aRgpTCJ_szMimgEnpkkE,1056
8
- distributed_a2a-0.1.1.dist-info/METADATA,sha256=SlsxcSx3Rjn5PfclsQ_6LE1MNojGVAo41bG0MBbgCtY,3604
9
- distributed_a2a-0.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
10
- distributed_a2a-0.1.1.dist-info/top_level.txt,sha256=23qJ8n5k7796BHDK7a58uuO-X4GV0EgUWcGi8NIn-0k,16
11
- distributed_a2a-0.1.1.dist-info/RECORD,,
8
+ distributed_a2a-0.1.3.dist-info/licenses/LICENSE,sha256=Btzdu2kIoMbdSp6OyCLupB1aRgpTCJ_szMimgEnpkkE,1056
9
+ distributed_a2a-0.1.3.dist-info/METADATA,sha256=D0xe5WxwE8nfTlR8ZDoIP_b2FEFlkJDcqpKe6apr09c,3604
10
+ distributed_a2a-0.1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
11
+ distributed_a2a-0.1.3.dist-info/top_level.txt,sha256=23qJ8n5k7796BHDK7a58uuO-X4GV0EgUWcGi8NIn-0k,16
12
+ distributed_a2a-0.1.3.dist-info/RECORD,,