distributed-a2a 0.1.6rc8__tar.gz → 0.1.9rc0__tar.gz
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.
- {distributed_a2a-0.1.6rc8/distributed_a2a.egg-info → distributed_a2a-0.1.9rc0}/PKG-INFO +12 -11
- {distributed_a2a-0.1.6rc8 → distributed_a2a-0.1.9rc0}/distributed_a2a/agent.py +1 -1
- distributed_a2a-0.1.9rc0/distributed_a2a/registry.py +55 -0
- {distributed_a2a-0.1.6rc8 → distributed_a2a-0.1.9rc0}/distributed_a2a/server.py +9 -1
- {distributed_a2a-0.1.6rc8 → distributed_a2a-0.1.9rc0/distributed_a2a.egg-info}/PKG-INFO +12 -11
- distributed_a2a-0.1.9rc0/distributed_a2a.egg-info/requires.txt +11 -0
- {distributed_a2a-0.1.6rc8 → distributed_a2a-0.1.9rc0}/pyproject.toml +1 -1
- distributed_a2a-0.1.9rc0/requirements.txt +11 -0
- distributed_a2a-0.1.6rc8/distributed_a2a/registry.py +0 -18
- distributed_a2a-0.1.6rc8/distributed_a2a.egg-info/requires.txt +0 -10
- distributed_a2a-0.1.6rc8/requirements.txt +0 -10
- {distributed_a2a-0.1.6rc8 → distributed_a2a-0.1.9rc0}/LICENSE +0 -0
- {distributed_a2a-0.1.6rc8 → distributed_a2a-0.1.9rc0}/MANIFEST.in +0 -0
- {distributed_a2a-0.1.6rc8 → distributed_a2a-0.1.9rc0}/README.md +0 -0
- {distributed_a2a-0.1.6rc8 → distributed_a2a-0.1.9rc0}/distributed_a2a/__init__.py +0 -0
- {distributed_a2a-0.1.6rc8 → distributed_a2a-0.1.9rc0}/distributed_a2a/client.py +0 -0
- {distributed_a2a-0.1.6rc8 → distributed_a2a-0.1.9rc0}/distributed_a2a/executors.py +0 -0
- {distributed_a2a-0.1.6rc8 → distributed_a2a-0.1.9rc0}/distributed_a2a/model.py +0 -0
- {distributed_a2a-0.1.6rc8 → distributed_a2a-0.1.9rc0}/distributed_a2a/router.py +0 -0
- {distributed_a2a-0.1.6rc8 → distributed_a2a-0.1.9rc0}/distributed_a2a.egg-info/SOURCES.txt +0 -0
- {distributed_a2a-0.1.6rc8 → distributed_a2a-0.1.9rc0}/distributed_a2a.egg-info/dependency_links.txt +0 -0
- {distributed_a2a-0.1.6rc8 → distributed_a2a-0.1.9rc0}/distributed_a2a.egg-info/top_level.txt +0 -0
- {distributed_a2a-0.1.6rc8 → distributed_a2a-0.1.9rc0}/setup.cfg +0 -0
- {distributed_a2a-0.1.6rc8 → distributed_a2a-0.1.9rc0}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: distributed_a2a
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.9rc0
|
|
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
|
|
@@ -19,16 +19,17 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
19
19
|
Requires-Python: >=3.10
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
License-File: LICENSE
|
|
22
|
-
Requires-Dist: langchain
|
|
23
|
-
Requires-Dist: langchain-core
|
|
24
|
-
Requires-Dist: langchain-openai
|
|
25
|
-
Requires-Dist: langgraph
|
|
26
|
-
Requires-Dist: langgraph-dynamodb-checkpoint
|
|
27
|
-
Requires-Dist: pydantic
|
|
28
|
-
Requires-Dist: boto3
|
|
29
|
-
Requires-Dist: a2a
|
|
30
|
-
Requires-Dist:
|
|
31
|
-
Requires-Dist:
|
|
22
|
+
Requires-Dist: langchain==1.2.3
|
|
23
|
+
Requires-Dist: langchain-core==1.2.7
|
|
24
|
+
Requires-Dist: langchain-openai==1.1.7
|
|
25
|
+
Requires-Dist: langgraph==1.0.5
|
|
26
|
+
Requires-Dist: langgraph-dynamodb-checkpoint==0.2.6.4
|
|
27
|
+
Requires-Dist: pydantic==2.12.5
|
|
28
|
+
Requires-Dist: boto3==1.42.25
|
|
29
|
+
Requires-Dist: a2a-sdk==0.3.22
|
|
30
|
+
Requires-Dist: a2a-types==0.1.0
|
|
31
|
+
Requires-Dist: build==1.4.0
|
|
32
|
+
Requires-Dist: twine==6.2.0
|
|
32
33
|
Dynamic: author
|
|
33
34
|
Dynamic: home-page
|
|
34
35
|
Dynamic: license-file
|
|
@@ -11,7 +11,7 @@ from .model import get_model, LLMConfig
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class AgentResponse(BaseModel):
|
|
14
|
-
status: Literal[TaskState.rejected, TaskState.completed, TaskState.
|
|
14
|
+
status: Literal[TaskState.rejected, TaskState.completed, TaskState.failed] = Field(
|
|
15
15
|
description=(
|
|
16
16
|
f'You should select status as {TaskState.rejected} for requests that fall outside your area of expertise.'
|
|
17
17
|
f'You should select status as {TaskState.completed} if the request is fully addressed and no further input is needed. '
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import asyncio
|
|
3
|
+
import boto3
|
|
4
|
+
import requests
|
|
5
|
+
from langchain_core.tools import StructuredTool
|
|
6
|
+
from a2a.types import AgentCard
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
async def registry_heart_beat(name: str, registry_url: str, agent_card: AgentCard, interval_sec: int,
|
|
10
|
+
get_expire_at: callable) -> None:
|
|
11
|
+
registry = AgentRegistryLookup(registry_url=registry_url)
|
|
12
|
+
while True:
|
|
13
|
+
try:
|
|
14
|
+
registry.put_agent_card(name=name, agent_card=agent_card.model_dump(), expire_at=get_expire_at())
|
|
15
|
+
except Exception as e:
|
|
16
|
+
print(f"Failed to send heart beat to registry: {e}")
|
|
17
|
+
await asyncio.sleep(interval_sec)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class AgentRegistryLookup:
|
|
21
|
+
def __init__(self, registry_url: str):
|
|
22
|
+
self.registry_url = registry_url
|
|
23
|
+
|
|
24
|
+
def get_agent_cards(self) -> list[dict]:
|
|
25
|
+
response = requests.get(url=f"{self.registry_url}/agent-cards", timeout=30)
|
|
26
|
+
response.raise_for_status()
|
|
27
|
+
return response.json()
|
|
28
|
+
|
|
29
|
+
def put_agent_card(self, name: str, agent_card: dict, expire_at: int) -> None:
|
|
30
|
+
response = requests.put(
|
|
31
|
+
url=f"{self.registry_url}/agent-card/{name}",
|
|
32
|
+
params={"expire_at": str(expire_at)},
|
|
33
|
+
json=agent_card,
|
|
34
|
+
timeout=30
|
|
35
|
+
)
|
|
36
|
+
response.raise_for_status()
|
|
37
|
+
|
|
38
|
+
def as_tool(self) -> StructuredTool:
|
|
39
|
+
return StructuredTool.from_function(func=lambda: self.get_agent_cards(), name="agent_card_lookup",
|
|
40
|
+
description="Gets all available agent cards")
|
|
41
|
+
|
|
42
|
+
class DynamoDbRegistryLookup:
|
|
43
|
+
def __init__(self, agent_card_tabel: str):
|
|
44
|
+
dynamo = boto3.resource("dynamodb", region_name="eu-central-1")
|
|
45
|
+
self.table = dynamo.Table(agent_card_tabel)
|
|
46
|
+
|
|
47
|
+
def get_agent_cards(self) -> list[dict]:
|
|
48
|
+
|
|
49
|
+
items = self.table.scan().get("Items", [])
|
|
50
|
+
cards: list[dict] = [json.loads(it["card"]) for it in items]
|
|
51
|
+
return cards
|
|
52
|
+
|
|
53
|
+
def as_tool(self) -> StructuredTool:
|
|
54
|
+
return StructuredTool.from_function(func=lambda: self.get_agent_cards(), name="agent_card_lookup",
|
|
55
|
+
description="Gets all available agent cards")
|
|
@@ -13,7 +13,7 @@ from fastapi import FastAPI
|
|
|
13
13
|
|
|
14
14
|
from .executors import RoutingAgentExecutor
|
|
15
15
|
from .model import AgentConfig
|
|
16
|
-
from .registry import DynamoDbRegistryLookup
|
|
16
|
+
from .registry import DynamoDbRegistryLookup, registry_heart_beat
|
|
17
17
|
|
|
18
18
|
CAPABILITIES = AgentCapabilities(streaming=False, push_notifications=False)
|
|
19
19
|
|
|
@@ -25,6 +25,8 @@ AGENT_CARD_TABLE = "agent-cards"
|
|
|
25
25
|
def get_expire_at() -> int:
|
|
26
26
|
return int(time.time() + MAX_HEART_BEAT_MISSES * HEART_BEAT_INTERVAL_SEC)
|
|
27
27
|
|
|
28
|
+
|
|
29
|
+
|
|
28
30
|
async def heart_beat(name: str, agent_card_table: str, agent_card: AgentCard) -> None:
|
|
29
31
|
table = boto3.resource("dynamodb", region_name="eu-central-1").Table(agent_card_table)
|
|
30
32
|
table.put_item(Item={"id": name, "card": agent_card.model_dump_json(), "expireAt": get_expire_at()})
|
|
@@ -75,6 +77,12 @@ def load_app(agent_config: Any) -> FastAPI:
|
|
|
75
77
|
@asynccontextmanager
|
|
76
78
|
async def lifespan(_: FastAPI) -> AsyncGenerator[None, Any]:
|
|
77
79
|
asyncio.create_task(heart_beat(name=agent_card.name, agent_card_table=AGENT_CARD_TABLE, agent_card=agent_card))
|
|
80
|
+
import os
|
|
81
|
+
registry_url = os.getenv("REGISTRY_URL")
|
|
82
|
+
if registry_url:
|
|
83
|
+
asyncio.create_task(registry_heart_beat(name=agent_card.name, registry_url=registry_url,
|
|
84
|
+
agent_card=agent_card, interval_sec=HEART_BEAT_INTERVAL_SEC,
|
|
85
|
+
get_expire_at=get_expire_at))
|
|
78
86
|
yield
|
|
79
87
|
|
|
80
88
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: distributed_a2a
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.9rc0
|
|
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
|
|
@@ -19,16 +19,17 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
19
19
|
Requires-Python: >=3.10
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
License-File: LICENSE
|
|
22
|
-
Requires-Dist: langchain
|
|
23
|
-
Requires-Dist: langchain-core
|
|
24
|
-
Requires-Dist: langchain-openai
|
|
25
|
-
Requires-Dist: langgraph
|
|
26
|
-
Requires-Dist: langgraph-dynamodb-checkpoint
|
|
27
|
-
Requires-Dist: pydantic
|
|
28
|
-
Requires-Dist: boto3
|
|
29
|
-
Requires-Dist: a2a
|
|
30
|
-
Requires-Dist:
|
|
31
|
-
Requires-Dist:
|
|
22
|
+
Requires-Dist: langchain==1.2.3
|
|
23
|
+
Requires-Dist: langchain-core==1.2.7
|
|
24
|
+
Requires-Dist: langchain-openai==1.1.7
|
|
25
|
+
Requires-Dist: langgraph==1.0.5
|
|
26
|
+
Requires-Dist: langgraph-dynamodb-checkpoint==0.2.6.4
|
|
27
|
+
Requires-Dist: pydantic==2.12.5
|
|
28
|
+
Requires-Dist: boto3==1.42.25
|
|
29
|
+
Requires-Dist: a2a-sdk==0.3.22
|
|
30
|
+
Requires-Dist: a2a-types==0.1.0
|
|
31
|
+
Requires-Dist: build==1.4.0
|
|
32
|
+
Requires-Dist: twine==6.2.0
|
|
32
33
|
Dynamic: author
|
|
33
34
|
Dynamic: home-page
|
|
34
35
|
Dynamic: license-file
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import boto3
|
|
2
|
-
from langchain_core.tools import StructuredTool
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class DynamoDbRegistryLookup:
|
|
6
|
-
def __init__(self, agent_card_tabel: str):
|
|
7
|
-
dynamo = boto3.resource("dynamodb", region_name="eu-central-1")
|
|
8
|
-
self.table = dynamo.Table(agent_card_tabel)
|
|
9
|
-
|
|
10
|
-
def get_agent_cards(self) -> list[str]:
|
|
11
|
-
|
|
12
|
-
items = self.table.scan().get("Items", [])
|
|
13
|
-
cards: list[str] = [it["card"] for it in items]
|
|
14
|
-
return cards
|
|
15
|
-
|
|
16
|
-
def as_tool(self) -> StructuredTool:
|
|
17
|
-
return StructuredTool.from_function(func=lambda: self.get_agent_cards(), name="agent_card_lookup",
|
|
18
|
-
description="Gets all available agent cards")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{distributed_a2a-0.1.6rc8 → distributed_a2a-0.1.9rc0}/distributed_a2a.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{distributed_a2a-0.1.6rc8 → distributed_a2a-0.1.9rc0}/distributed_a2a.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|