Files
hope-voice-api/agent/dispatch_mcp.py
T
snowspeeder 321421e37f
Rebuild & Deploy / rebuild (push) Successful in 47s
fix: reliably dispatch and return background tasks
2026-08-29 07:29:38 -04:00

69 lines
2.3 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
import os
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
timeout_seconds = float(os.environ.get("TASK_TIMEOUT_SECONDS", "180"))
try:
await asyncio.wait_for(worker.run(), timeout=timeout_seconds)
except asyncio.TimeoutError:
message = f"Timed out after {timeout_seconds:g} seconds"
logger.error("Task %s %s", task_id, message.lower())
registry.fail(task_id, message)
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")