- Remove Docker-based microservices (docker-compose.yml, Makefile, Dockerfiles) - Update start-dev.sh to use backend.app:app entry point - Add shared schema and client modules for service communication - Add team coordination modules (messenger, registry, task_delegator, coordinator) - Add evaluation hooks and skill adaptation hooks - Add skill template and gateway server - Update frontend WebSocket URL configuration - Add explain components for insider and technical analysis Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
189 lines
5.0 KiB
Python
189 lines
5.0 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""AgentRegistry - Agent registration and lookup by role.
|
|
|
|
Provides register(), unregister(), and get_by_role() for agent
|
|
discovery and management.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
from typing import Any, Dict, List, Optional
|
|
|
|
from agentscope.message import Msg
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class AgentRegistry:
|
|
"""Registry for agent instances with role-based lookup.
|
|
|
|
Supports:
|
|
- register(): Add agent with roles
|
|
- unregister(): Remove agent
|
|
- get_by_role(): Find agents by role
|
|
- get_by_id(): Get specific agent
|
|
|
|
Each agent can have multiple roles for flexible dispatch.
|
|
"""
|
|
|
|
def __init__(self):
|
|
self._agents: Dict[str, Any] = {}
|
|
self._roles: Dict[str, List[str]] = {}
|
|
self._agent_roles: Dict[str, List[str]] = {}
|
|
|
|
def register(
|
|
self,
|
|
agent_id: str,
|
|
agent: Any,
|
|
roles: Optional[List[str]] = None,
|
|
) -> None:
|
|
"""Register an agent with optional roles.
|
|
|
|
Args:
|
|
agent_id: Unique agent identifier
|
|
agent: Agent instance
|
|
roles: Optional list of role strings
|
|
"""
|
|
self._agents[agent_id] = agent
|
|
self._agent_roles[agent_id] = roles or []
|
|
|
|
for role in self._agent_roles[agent_id]:
|
|
if role not in self._roles:
|
|
self._roles[role] = []
|
|
if agent_id not in self._roles[role]:
|
|
self._roles[role].append(agent_id)
|
|
|
|
logger.info(
|
|
"Registered agent %s with roles %s",
|
|
agent_id,
|
|
self._agent_roles[agent_id],
|
|
)
|
|
|
|
def unregister(self, agent_id: str) -> bool:
|
|
"""Unregister an agent.
|
|
|
|
Args:
|
|
agent_id: Agent identifier to remove
|
|
|
|
Returns:
|
|
True if agent was removed
|
|
"""
|
|
if agent_id not in self._agents:
|
|
return False
|
|
|
|
roles = self._agent_roles.pop(agent_id, [])
|
|
for role in roles:
|
|
if role in self._roles:
|
|
try:
|
|
self._roles[role].remove(agent_id)
|
|
except ValueError:
|
|
pass
|
|
|
|
del self._agents[agent_id]
|
|
logger.info("Unregistered agent: %s", agent_id)
|
|
return True
|
|
|
|
def get_by_id(self, agent_id: str) -> Optional[Any]:
|
|
"""Get agent by ID.
|
|
|
|
Args:
|
|
agent_id: Agent identifier
|
|
|
|
Returns:
|
|
Agent instance or None
|
|
"""
|
|
return self._agents.get(agent_id)
|
|
|
|
def get_by_role(self, role: str) -> List[Any]:
|
|
"""Get all agents with a given role.
|
|
|
|
Args:
|
|
role: Role string to search for
|
|
|
|
Returns:
|
|
List of agent instances with the role
|
|
"""
|
|
agent_ids = self._roles.get(role, [])
|
|
return [self._agents[aid] for aid in agent_ids if aid in self._agents]
|
|
|
|
def get_by_roles(self, roles: List[str]) -> List[Any]:
|
|
"""Get agents matching ANY of the given roles.
|
|
|
|
Args:
|
|
roles: List of role strings
|
|
|
|
Returns:
|
|
List of unique agent instances matching any role
|
|
"""
|
|
seen = set()
|
|
result = []
|
|
for role in roles:
|
|
for agent in self.get_by_role(role):
|
|
if id(agent) not in seen:
|
|
seen.add(id(agent))
|
|
result.append(agent)
|
|
return result
|
|
|
|
def list_agents(self) -> List[str]:
|
|
"""List all registered agent IDs.
|
|
|
|
Returns:
|
|
List of agent identifiers
|
|
"""
|
|
return list(self._agents.keys())
|
|
|
|
def list_roles(self) -> List[str]:
|
|
"""List all registered roles.
|
|
|
|
Returns:
|
|
List of role strings
|
|
"""
|
|
return list(self._roles.keys())
|
|
|
|
def list_roles_for_agent(self, agent_id: str) -> List[str]:
|
|
"""List roles for specific agent.
|
|
|
|
Args:
|
|
agent_id: Agent identifier
|
|
|
|
Returns:
|
|
List of role strings
|
|
"""
|
|
return list(self._agent_roles.get(agent_id, []))
|
|
|
|
def update_roles(self, agent_id: str, roles: List[str]) -> None:
|
|
"""Update roles for an existing agent.
|
|
|
|
Args:
|
|
agent_id: Agent identifier
|
|
roles: New list of roles
|
|
"""
|
|
if agent_id not in self._agents:
|
|
raise KeyError(f"Agent not registered: {agent_id}")
|
|
|
|
old_roles = self._agent_roles.get(agent_id, [])
|
|
for role in old_roles:
|
|
if role in self._roles:
|
|
try:
|
|
self._roles[role].remove(agent_id)
|
|
except ValueError:
|
|
pass
|
|
|
|
self._agent_roles[agent_id] = roles
|
|
for role in roles:
|
|
if role not in self._roles:
|
|
self._roles[role] = []
|
|
if agent_id not in self._roles[role]:
|
|
self._roles[role].append(agent_id)
|
|
|
|
logger.info("Updated roles for agent %s: %s", agent_id, roles)
|
|
|
|
@property
|
|
def agents(self) -> Dict[str, Any]:
|
|
"""Get copy of registered agents dict."""
|
|
return dict(self._agents)
|
|
|
|
|
|
__all__ = ["AgentRegistry"]
|