77 lines
1.9 KiB
Python
77 lines
1.9 KiB
Python
|
|
"""Agent Registry - Thread-safe global singleton for MCP tool access.
|
||
|
|
|
||
|
|
MCP tools are module-level functions that cannot access the Agent instance
|
||
|
|
directly. This registry provides a thread-safe bridge so that tools like
|
||
|
|
delegate_task can call Agent.delegate() without circular imports.
|
||
|
|
|
||
|
|
Usage:
|
||
|
|
# At bot startup (bot_runner.py):
|
||
|
|
from agent_registry import register_agent
|
||
|
|
agent = Agent(...)
|
||
|
|
register_agent(agent)
|
||
|
|
|
||
|
|
# In MCP tools (mcp_tools.py):
|
||
|
|
from agent_registry import get_agent
|
||
|
|
agent = get_agent()
|
||
|
|
if agent:
|
||
|
|
result = agent.delegate(task, specialist_prompt)
|
||
|
|
"""
|
||
|
|
|
||
|
|
import threading
|
||
|
|
from typing import Optional, TYPE_CHECKING
|
||
|
|
|
||
|
|
if TYPE_CHECKING:
|
||
|
|
from agent import Agent
|
||
|
|
|
||
|
|
# Module-level singleton state
|
||
|
|
_agent: Optional['Agent'] = None
|
||
|
|
_lock = threading.Lock()
|
||
|
|
|
||
|
|
|
||
|
|
def register_agent(agent: 'Agent') -> None:
|
||
|
|
"""Register the main Agent instance for MCP tool access.
|
||
|
|
|
||
|
|
Must be called exactly once at bot startup, after Agent is initialized.
|
||
|
|
Thread-safe.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
agent: The main Agent instance (not a sub-agent).
|
||
|
|
|
||
|
|
Raises:
|
||
|
|
ValueError: If agent is None or is a sub-agent.
|
||
|
|
"""
|
||
|
|
global _agent
|
||
|
|
|
||
|
|
if agent is None:
|
||
|
|
raise ValueError("Cannot register None as the main agent")
|
||
|
|
if getattr(agent, 'is_sub_agent', False):
|
||
|
|
raise ValueError("Cannot register a sub-agent as the main agent")
|
||
|
|
|
||
|
|
with _lock:
|
||
|
|
_agent = agent
|
||
|
|
print(f"[AgentRegistry] Main agent registered (provider={agent.llm.provider})")
|
||
|
|
|
||
|
|
|
||
|
|
def get_agent() -> Optional['Agent']:
|
||
|
|
"""Get the registered main Agent instance.
|
||
|
|
|
||
|
|
Thread-safe. Returns None if no agent has been registered yet.
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
The main Agent instance, or None.
|
||
|
|
"""
|
||
|
|
with _lock:
|
||
|
|
return _agent
|
||
|
|
|
||
|
|
|
||
|
|
def clear_agent() -> None:
|
||
|
|
"""Clear the registered agent (for testing or shutdown).
|
||
|
|
|
||
|
|
Thread-safe.
|
||
|
|
"""
|
||
|
|
global _agent
|
||
|
|
|
||
|
|
with _lock:
|
||
|
|
_agent = None
|
||
|
|
print("[AgentRegistry] Agent registry cleared")
|