Skip to content

Commit

Permalink
feat: working inspector connect
Browse files Browse the repository at this point in the history
  • Loading branch information
jrriehl committed Dec 11, 2024
1 parent a273642 commit 68752e1
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 74 deletions.
12 changes: 2 additions & 10 deletions python/examples/11-mailbox-agents/alice.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,11 @@ class Message(Model):
message: str


# First generate a secure seed phrase (e.g. https://pypi.org/project/mnemonic/)
SEED_PHRASE = "put_your_seed_phrase_here"

# Now your agent is ready to join the agentverse!
agent = Agent(
name="alice",
seed=SEED_PHRASE,
port=8000,
endpoint="http://agentverse.ai/v1/submit",
)
agent = Agent(name="alice", port=8008, mailbox=True)


@agent.on_message(model=Message, replies={Message})
@agent.on_message(model=Message, replies=Message)
async def handle_message(ctx: Context, sender: str, msg: Message):
ctx.logger.info(f"Received message from {sender}: {msg.message}")

Expand Down
9 changes: 1 addition & 8 deletions python/examples/11-mailbox-agents/bob.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,9 @@ class Message(Model):
# Copy ALICE_ADDRESS generated in alice.py
ALICE_ADDRESS = "paste_alice_address_here"

# Generate a second seed phrase (e.g. https://pypi.org/project/mnemonic/)
SEED_PHRASE = "put_your_seed_phrase_here"

# Now your agent is ready to join the agentverse!
agent = Agent(
name="bob",
seed=SEED_PHRASE,
port=8001,
endpoint="http://agentverse.ai/v1/submit",
)
agent = Agent(name="bob", port=8009, mailbox=True)


@agent.on_interval(period=2.0)
Expand Down
62 changes: 13 additions & 49 deletions python/src/uagents/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,7 @@ class Agent(Sink):
identifier (str): The Agent Identifier, including network prefix and address.
wallet (LocalWallet): The agent's wallet for transacting on the ledger.
storage (KeyValueStore): The key-value store for storage operations.
mailbox (Dict[str, str]): The mailbox configuration for the agent.
agentverse (Dict[str, str]): The agentverse configuration for the agent.
agentverse (AgentverseConfig): The agentverse configuration for the agent.
mailbox_client (MailboxClient): The client for interacting with the agentverse mailbox.
protocols (Dict[str, Protocol]): Dictionary mapping all supported protocol digests to their
corresponding protocols.
Expand All @@ -273,7 +272,8 @@ def __init__(
seed: Optional[str] = None,
endpoint: Optional[Union[str, List[str], Dict[str, dict]]] = None,
agentverse: Optional[Union[str, Dict[str, str]]] = None,
mailbox: Optional[Union[str, Dict[str, str]]] = None,
mailbox: bool = False,
proxy: bool = False,
resolve: Optional[Resolver] = None,
registration_policy: Optional[AgentRegistrationPolicy] = None,
enable_wallet_messaging: Union[bool, Dict[str, str]] = False,
Expand All @@ -295,7 +295,8 @@ def __init__(
seed (Optional[str]): The seed for generating keys.
endpoint (Optional[Union[str, List[str], Dict[str, dict]]]): The endpoint configuration.
agentverse (Optional[Union[str, Dict[str, str]]]): The agentverse configuration.
mailbox (Optional[Union[str, Dict[str, str]]]): The mailbox configuration.
mailbox (bool): True if the agent will receive messages via an Agentverse mailbox.
proxy (bool): True if the agent will receive messages via an Agentverse proxy endpoint.
resolve (Optional[Resolver]): The resolver to use for agent communication.
enable_wallet_messaging (Optional[Union[bool, Dict[str, str]]]): Whether to enable
wallet messaging. If '{"chain_id": CHAIN_ID}' is provided, this sets the chain ID for
Expand All @@ -319,29 +320,12 @@ def __init__(
self._initialize_wallet_and_identity(seed, name, wallet_key_derivation_index)
self._logger = get_logger(self.name, level=log_level)

# configure endpoints and mailbox
self._endpoints = parse_endpoint_config(endpoint)
self._use_mailbox = False

if mailbox:
# agentverse config overrides mailbox config
# but mailbox is kept for backwards compatibility
if agentverse:
self._logger.warning(
"Ignoring the provided 'mailbox' configuration since 'agentverse' overrides it"
)
else:
agentverse = mailbox
self._agentverse = parse_agentverse_config(agentverse)

# support legacy method of setting mailbox configuration if no endpoint is provided
if endpoint is None and mailbox:
self._logger.info(
f"Setting endpoint to mailbox: {self._agentverse.url}/v1/submit"
)
self._endpoints = [
AgentEndpoint(url=f"{self._agentverse.url}/v1/submit", weight=1)
]
# configure endpoints and mailbox
self._endpoints = parse_endpoint_config(
endpoint, self._agentverse, mailbox, proxy, self._logger
)

self._use_mailbox = is_mailbox_agent(self._endpoints, self._agentverse)
if self._use_mailbox:
Expand Down Expand Up @@ -613,17 +597,6 @@ def storage(self) -> KeyValueStore:
"""
return self._storage

@property
def mailbox(self) -> AgentverseConfig:
"""
Get the mailbox configuration of the agent.
Agentverse overrides it but mailbox is kept for backwards compatibility.
Returns:
Dict[str, str]: The mailbox configuration.
"""
return self._agentverse

@property
def agentverse(self) -> AgentverseConfig:
"""
Expand Down Expand Up @@ -680,17 +653,6 @@ def metadata(self) -> Dict[str, Any]:
"""
return self._metadata

@mailbox.setter
def mailbox(self, config: Union[str, Dict[str, str]]):
"""
Set the mailbox configuration for the agent.
Agentverse overrides it but mailbox is kept for backwards compatibility.
Args:
config (Union[str, Dict[str, str]]): The new mailbox configuration.
"""
self._agentverse = parse_agentverse_config(config)

@agentverse.setter
def agentverse(self, config: Union[str, Dict[str, str]]):
"""
Expand Down Expand Up @@ -937,7 +899,7 @@ def _on_rest(
return lambda func: func

def decorator_on_rest(func: RestHandler):
@functools.wraps(RestGetHandler if method == "GET" else RestPostHandler)
@functools.wraps(RestGetHandler if method == "GET" else RestPostHandler) # type: ignore
def handler(*args, **kwargs):
return func(*args, **kwargs)

Expand Down Expand Up @@ -1412,7 +1374,6 @@ def __init__(
"""
self._loop = loop or asyncio.get_event_loop_policy().get_event_loop()
self._agents: List[Agent] = []
self._endpoints = parse_endpoint_config(endpoint)
self._port = port or 8000
self._queries: Dict[str, asyncio.Future] = {}
self._logger = get_logger("bureau", log_level)
Expand All @@ -1423,6 +1384,9 @@ def __init__(
logger=self._logger,
)
self._agentverse = parse_agentverse_config(agentverse)
self._endpoints = parse_endpoint_config(
endpoint, self._agentverse, False, False, self._logger
)
self._use_mailbox = any(
[
is_mailbox_agent(agent._endpoints, self._agentverse)
Expand Down
20 changes: 14 additions & 6 deletions python/src/uagents/asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,19 +133,27 @@ async def _asgi_send(
body: Optional[Union[Dict[str, Any], ErrorWrapper]] = None,
):
header = (
[[k.encode(), v.encode()] for k, v in headers.items()] if headers else None
[[k.encode(), v.encode()] for k, v in headers.items()]
if headers is not None
else [[b"content-type", b"application/json"]]
)
if body is None:
body = {}

await send(
{
"type": "http.response.start",
"status": status_code,
"headers": header or [[b"content-type", b"application/json"]],
"headers": header,
}
)
await send({"type": "http.response.body", "body": json.dumps(body).encode()})

if body is None:
encoded_body = (
b"{}" if [[b"content-type", b"application/json"]] in header else b""
)
else:
encoded_body = json.dumps(body).encode()

await send({"type": "http.response.body", "body": encoded_body})

async def handle_readiness_probe(self, headers: CaseInsensitiveDict, send):
"""
Expand Down Expand Up @@ -296,7 +304,7 @@ async def __call__(self, scope, receive, send): # pylint: disable=too-many-bra

# Handle OPTIONS preflight request for CORS
if request_method == "OPTIONS":
await self._asgi_send(send, 204)
await self._asgi_send(send, 204, headers={})
return

# check if the request is for a REST endpoint
Expand Down
33 changes: 32 additions & 1 deletion python/src/uagents/config.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import logging
from typing import Dict, List, Literal, Optional, Union

from pydantic import BaseModel

from uagents.types import AgentEndpoint
from uagents.utils import get_logger

AGENT_PREFIX = "agent"
LEDGER_PREFIX = "fetch"
Expand Down Expand Up @@ -60,13 +62,38 @@ def url(self) -> str:

def parse_endpoint_config(
endpoint: Optional[Union[str, List[str], Dict[str, dict]]],
agentverse: AgentverseConfig,
mailbox: bool = False,
proxy: bool = False,
logger: Optional[logging.Logger] = None,
) -> List[AgentEndpoint]:
"""
Parse the user-provided endpoint configuration.
Args:
endpoint (Optional[Union[str, List[str], Dict[str, dict]]]): The endpoint configuration.
agentverse (AgentverseConfig): The agentverse configuration.
mailbox (bool): Whether to use the mailbox endpoint.
proxy (bool): Whether to use the proxy endpoint.
logger (Optional[logging.Logger]): The logger to use.
Returns:
Optional[List[Dict[str, Any]]]: The parsed endpoint configuration.
Optional[List[AgentEndpoint]: The parsed endpoint configuration.
"""

logger = logger or get_logger("config")

if endpoint:
if mailbox:
logger.warning("Endpoint configuration overrides mailbox setting.")
if proxy:
logger.warning("Endpoint configuration overrides proxy setting.")
elif mailbox and proxy:
logger.warning(
"Mailbox and proxy settings are mutually exclusive. "
"Defaulting to mailbox."
)

if isinstance(endpoint, dict):
endpoints = [
AgentEndpoint.model_validate(
Expand All @@ -80,6 +107,10 @@ def parse_endpoint_config(
]
elif isinstance(endpoint, str):
endpoints = [AgentEndpoint.model_validate({"url": endpoint, "weight": 1})]
elif mailbox:
endpoints = [AgentEndpoint(url=f"{agentverse.url}/v1/submit", weight=1)]
elif proxy:
endpoints = [AgentEndpoint(url=f"{agentverse.url}/v1/proxy/submit", weight=1)]
else:
endpoints = []
return endpoints
Expand Down

0 comments on commit 68752e1

Please sign in to comment.