The FastMCP server never started listening on stdio because the file was missing 'if __name__ == "__main__": mcp.run(transport="stdio")'. The LiveKit agent's MCP client got 'Connection closed' during initialize, which killed the entire toolset setup — ALL tools (weather, memory, skills, dispatch) were unavailable. This is why Hope could hear you but never called any tools.
63 lines
2.0 KiB
Python
63 lines
2.0 KiB
Python
"""Dispatch MCP server — lets Hope spawn background tasks.
|
|
|
|
The main agent calls dispatch_task(description) when the user asks for
|
|
something long-running. The tool returns immediately with a task ID; the
|
|
actual work runs in a background asyncio task via TaskWorker.
|
|
|
|
Communication with the main agent process happens via /tmp/tasks/events.jsonl
|
|
(the file-based registry).
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
import logging
|
|
|
|
from mcp.server.fastmcp import FastMCP
|
|
|
|
logger = logging.getLogger("voice-agent.dispatch")
|
|
|
|
mcp = FastMCP("dispatch")
|
|
|
|
|
|
@mcp.tool()
|
|
async def dispatch_task(description: str) -> str:
|
|
"""Spawn a background task to research or look something up.
|
|
|
|
Use this when the user asks you to do something that will take more than
|
|
a few seconds (research, look up news, multi-step investigation). The task
|
|
runs in parallel while you continue the conversation. When it completes,
|
|
the result will be delivered back to you automatically — you can tell the
|
|
user "I'll let you know when I find out."
|
|
|
|
Returns a short confirmation with the task ID.
|
|
"""
|
|
try:
|
|
from agent.task_registry import registry
|
|
from agent.task_worker import TaskWorker
|
|
except ImportError:
|
|
from task_registry import registry
|
|
from task_worker import TaskWorker
|
|
|
|
task = registry.create(description)
|
|
worker = TaskWorker(task.id, description)
|
|
asyncio.create_task(_run_worker(worker, task.id))
|
|
logger.info("Dispatched task %s: %s", task.id, description)
|
|
return f"Task {task.id} started. I'll report back when it's done."
|
|
|
|
|
|
async def _run_worker(worker: "TaskWorker", task_id: str):
|
|
try:
|
|
from agent.task_registry import registry
|
|
except ImportError:
|
|
from task_registry import registry
|
|
|
|
try:
|
|
await worker.run()
|
|
except Exception as e:
|
|
logger.exception("Task %s crashed: %s", task_id, e)
|
|
registry.fail(task_id, str(e))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
mcp.run(transport="stdio")
|