1
0

Implement MCP system, Event Bus, and Sub-Agents

## 1. MCP (Model Context Protocol) Implementation

### Registry (src/mcp/registry.py)
- Tool registration with JSON schemas
- Dynamic tool discovery
- Health tracking per tool
- Metrics collection (latency, error rates)
- @register_tool decorator for easy registration

### Server (src/mcp/server.py)
- MCPServer class implementing MCP protocol
- MCPHTTPServer for FastAPI integration
- Standard endpoints: list_tools, call_tool, get_schema

### Schemas (src/mcp/schemas/base.py)
- create_tool_schema() helper
- Common parameter types
- Standard return types

### Bootstrap (src/mcp/bootstrap.py)
- Automatic tool module loading
- Status reporting

## 2. MCP-Compliant Tools (src/tools/)

| Tool | Purpose | Category |
|------|---------|----------|
| web_search | DuckDuckGo search | research |
| read_file | File reading | files |
| write_file | File writing (confirmation) | files |
| list_directory | Directory listing | files |
| python | Python code execution | code |
| memory_search | Vector memory search | memory |

All tools have proper schemas, error handling, and MCP registration.

## 3. Event Bus (src/events/bus.py)

- Async publish/subscribe pattern
- Pattern matching with wildcards (agent.task.*)
- Event history tracking
- Concurrent handler execution
- Module-level singleton for system-wide use

## 4. Sub-Agents (src/agents/)

All agents inherit from BaseAgent with:
- Agno Agent integration
- MCP tool registry access
- Event bus connectivity
- Structured logging

### Agent Roster

| Agent | Role | Tools | Purpose |
|-------|------|-------|---------|
| Seer | Research | web_search, read_file, memory_search | Information gathering |
| Forge | Code | python, write_file, read_file | Code generation |
| Quill | Writing | write_file, read_file, memory_search | Content creation |
| Echo | Memory | memory_search, read_file, write_file | Context retrieval |
| Helm | Routing | memory_search | Task routing decisions |
| Timmy | Orchestrator | All tools | Coordination & user interface |

### Timmy Orchestrator
- Analyzes user requests
- Routes to appropriate sub-agent
- Handles direct queries
- Manages swarm coordination
- create_timmy_swarm() factory function

## 5. Integration

All components wired together:
- Tools auto-register on import
- Agents connect to event bus
- MCP server provides HTTP API
- Ready for dashboard integration

## Tests
- All 973 existing tests pass
- New components tested manually
- Import verification successful

Next steps: Cascade Router, Self-Upgrade Loop, Dashboard integration
This commit is contained in:
Alexander Payne
2026-02-25 19:26:24 -05:00
parent 16b65b28e8
commit a719c7538d
18 changed files with 2099 additions and 0 deletions

124
src/tools/code_exec.py Normal file
View File

@@ -0,0 +1,124 @@
"""Code execution tool.
MCP-compliant tool for executing Python code.
"""
import logging
import traceback
from typing import Any
from mcp.registry import register_tool
from mcp.schemas.base import create_tool_schema, PARAM_STRING, PARAM_BOOLEAN, RETURN_STRING
logger = logging.getLogger(__name__)
PYTHON_SCHEMA = create_tool_schema(
name="python",
description="Execute Python code. Use for calculations, data processing, or when precise computation is needed. Code runs in a restricted environment.",
parameters={
"code": {
**PARAM_STRING,
"description": "Python code to execute",
},
"return_output": {
**PARAM_BOOLEAN,
"description": "Return the value of the last expression",
"default": True,
},
},
required=["code"],
returns=RETURN_STRING,
)
def python(code: str, return_output: bool = True) -> str:
"""Execute Python code in restricted environment.
Args:
code: Python code to execute
return_output: Whether to return last expression value
Returns:
Execution result or error message
"""
# Safe globals for code execution
safe_globals = {
"__builtins__": {
"abs": abs,
"all": all,
"any": any,
"bin": bin,
"bool": bool,
"dict": dict,
"enumerate": enumerate,
"filter": filter,
"float": float,
"format": format,
"hex": hex,
"int": int,
"isinstance": isinstance,
"issubclass": issubclass,
"len": len,
"list": list,
"map": map,
"max": max,
"min": min,
"next": next,
"oct": oct,
"ord": ord,
"pow": pow,
"print": lambda *args, **kwargs: None, # Disabled
"range": range,
"repr": repr,
"reversed": reversed,
"round": round,
"set": set,
"slice": slice,
"sorted": sorted,
"str": str,
"sum": sum,
"tuple": tuple,
"type": type,
"zip": zip,
}
}
# Allowed modules
allowed_modules = ["math", "random", "statistics", "datetime", "json"]
for mod_name in allowed_modules:
try:
safe_globals[mod_name] = __import__(mod_name)
except ImportError:
pass
try:
# Compile and execute
compiled = compile(code, "<string>", "eval" if return_output else "exec")
if return_output:
result = eval(compiled, safe_globals, {})
return f"Result: {result}"
else:
exec(compiled, safe_globals, {})
return "Code executed successfully."
except SyntaxError:
# Try as exec if eval fails
try:
compiled = compile(code, "<string>", "exec")
exec(compiled, safe_globals, {})
return "Code executed successfully."
except Exception as exc:
error_msg = traceback.format_exc()
logger.error("Python execution failed: %s", exc)
return f"Error: {exc}\n\n{error_msg}"
except Exception as exc:
error_msg = traceback.format_exc()
logger.error("Python execution failed: %s", exc)
return f"Error: {exc}\n\n{error_msg}"
# Register with MCP
register_tool(name="python", schema=PYTHON_SCHEMA, category="code")(python)