Add MCP delegation bridge and diagram tools
**Features Added**: 1. **Agent Registry (agent_registry.py)** - Thread-safe global singleton for MCP tool access to Agent instance - Enables MCP tools to call Agent.delegate() without circular imports - Registered at bot startup in bot_runner.py 2. **Sub-Agent Manager (sub_agent_manager.py)** - Watchdog system monitoring sub-agent lifecycle - Detects hung agents (5min timeout, 30s check interval) - Auto-cleanup and status tracking 3. **delegate_task MCP Tool (mcp_tools.py)** - Exposes Agent.delegate() to Claude via MCP protocol - Enables parallel sub-agent execution via tool calls - Supports specialist prompts and agent ID caching 4. **Memory Write Locks (memory_system.py)** - Thread-safe writes to prevent file corruption - Protects write_memory(), update_soul(), update_user() 5. **Diagram Tools** - Mermaid MCP server (flowcharts, sequence diagrams, etc.) - Excalidraw MCP server (hand-drawn style diagrams) - Config files in config/ directory 6. **Adapter Improvements** - Enhanced error handling across all adapters - Unified logging patterns **Testing**: Ready for parallel sub-agent testing Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -306,6 +306,58 @@ class TelegramAdapter(BaseAdapter):
|
||||
except TelegramError as e:
|
||||
print(f"[Telegram] Error sending typing indicator: {e}")
|
||||
|
||||
async def send_file(
|
||||
self,
|
||||
channel_id: str,
|
||||
file_path: str,
|
||||
caption: Optional[str] = None,
|
||||
thread_id: Optional[str] = None
|
||||
) -> Dict[str, Any]:
|
||||
"""Send a file (image or document) to Telegram."""
|
||||
if not self.bot:
|
||||
return {"success": False, "error": "Bot not started"}
|
||||
|
||||
try:
|
||||
from pathlib import Path
|
||||
path = Path(file_path)
|
||||
|
||||
if not path.exists():
|
||||
return {"success": False, "error": f"File not found: {file_path}"}
|
||||
|
||||
chat_id = int(channel_id)
|
||||
reply_to = int(thread_id) if thread_id else None
|
||||
ext = path.suffix.lower()
|
||||
|
||||
# Send as photo for images, document for others
|
||||
if ext in [".png", ".jpg", ".jpeg", ".gif", ".webp"]:
|
||||
with open(path, "rb") as photo:
|
||||
sent = await self.bot.send_photo(
|
||||
chat_id=chat_id,
|
||||
photo=photo,
|
||||
caption=caption,
|
||||
reply_to_message_id=reply_to,
|
||||
)
|
||||
else:
|
||||
with open(path, "rb") as document:
|
||||
sent = await self.bot.send_document(
|
||||
chat_id=chat_id,
|
||||
document=document,
|
||||
caption=caption,
|
||||
reply_to_message_id=reply_to,
|
||||
)
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"message_id": sent.message_id,
|
||||
"file_path": file_path,
|
||||
}
|
||||
except TelegramError as e:
|
||||
print(f"[Telegram] Error sending file: {e}")
|
||||
return {"success": False, "error": str(e)}
|
||||
except Exception as e:
|
||||
print(f"[Telegram] Unexpected error sending file: {e}")
|
||||
return {"success": False, "error": str(e)}
|
||||
|
||||
async def health_check(self) -> Dict[str, Any]:
|
||||
"""Perform health check."""
|
||||
base_health = await super().health_check()
|
||||
|
||||
Reference in New Issue
Block a user