"""
Agent and Tool Registry for Praval Framework.
Provides a global registry for tracking agents and tools across the system,
enabling better coordination and discovery in multi-agent applications.
Thread-safe for concurrent agent registration and lookup.
"""
import threading
from typing import Dict, List, Any, Optional
from .agent import Agent
[docs]
class PravalRegistry:
"""Global registry for agents and tools in Praval applications.
Thread-safe for concurrent agent registration and lookup.
Uses RLock to allow reentrant locking (same thread can acquire multiple times).
"""
[docs]
def __init__(self):
self._agents: Dict[str, Agent] = {}
self._tools: Dict[str, Dict[str, Any]] = {}
self._lock = threading.RLock()
[docs]
def register_agent(self, agent: Agent) -> Agent:
"""
Register an agent in the global registry (thread-safe).
Args:
agent: Agent instance to register
Returns:
The registered agent
"""
with self._lock:
self._agents[agent.name] = agent
# Also register all tools from this agent
for tool_name, tool_info in agent.tools.items():
full_tool_name = f"{agent.name}.{tool_name}"
self._tools[full_tool_name] = {
**tool_info,
"agent": agent.name
}
return agent
[docs]
def get_agent(self, name: str) -> Optional[Agent]:
"""Get an agent by name from the registry (thread-safe)."""
with self._lock:
return self._agents.get(name)
[docs]
def get_all_agents(self) -> Dict[str, Agent]:
"""Get all registered agents (thread-safe, returns copy)."""
with self._lock:
return self._agents.copy()
[docs]
def list_agents(self) -> List[str]:
"""List names of all registered agents (thread-safe)."""
with self._lock:
return list(self._agents.keys())
[docs]
def clear(self):
"""Clear all registered agents and tools (thread-safe)."""
with self._lock:
self._agents.clear()
self._tools.clear()
# Global registry instance
_global_registry = PravalRegistry()
[docs]
def register_agent(agent: Agent) -> Agent:
"""Register an agent in the global registry."""
return _global_registry.register_agent(agent)
[docs]
def get_registry() -> PravalRegistry:
"""Get the global registry instance."""
return _global_registry
[docs]
def reset_registry() -> None:
"""
Reset the global registry to a clean state.
This is primarily used for testing to ensure test isolation.
"""
_global_registry.clear()