Summary
agentseek-api dev cannot load a graph manifest whose graph entry is an async factory. This blocks templates migrated from the LangGraph CLI when their graph must asynchronously initialize resources such as MCP clients and discovered tools.
Reproduction
A generated deepagents/mcp project declares a graph entry like:
{
"graphs": {
"mcp": "./src/agentseek_e2e_deepagents_mcp/agent.py:make_graph"
}
}
The factory is asynchronous:
async def make_graph() -> CompiledStateGraph:
# connect to stdio and Streamable HTTP MCP servers,
# discover tools, then build the deep agent
...
Start the project with agentseek dev (which launches uv run agentseek-api dev). The HTTP service and /health endpoint start successfully. On the first /runs/stream request, graph loading fails with:
GraphManifestError: Graph definition did not resolve to a compiled graph or compilable StateGraph.
Why this happens
The graph loader invokes the configured factory and immediately coerces the return value to a compiled graph or StateGraph. For an async factory, the immediate return value is a coroutine. Because the loader does not detect and await awaitable results, it validates the coroutine object instead of the graph it produces.
This is specifically a LangGraph CLI to AgentSeek API runtime migration issue: the same template can be served by the previous runtime, but fails when its lifecycle is changed to agentseek-api dev.
Impact
- The service can pass health checks while every first graph execution fails.
- MCP tool discovery cannot be performed during async graph construction.
- Async database or remote-resource initialization has the same risk.
doctor --live cannot detect the failure because it only checks HTTP readiness.
Proposed fix
In the graph loading path:
- Invoke the configured graph factory.
- Detect
inspect.isawaitable(result).
- Await the result in the async loading path.
- Validate and compile the resolved
StateGraph/compiled graph.
- Preserve checkpointer and store arguments.
- Keep the original factory exception as the error cause/context.
Regression coverage
Please add tests for:
- synchronous
StateGraph factory;
- synchronous compiled graph factory;
- asynchronous
StateGraph factory;
- asynchronous compiled graph factory;
- async factory exceptions;
- async factory with checkpointer/store arguments;
- a rendered MCP template loading its graph;
/runs/stream successfully invoking an MCP calculator tool.
Acceptance criteria
After the fix, agentseek-api dev followed by the first /runs/stream request must load the async MCP graph successfully, emit stream events, and allow multiple turns on the same thread.
Summary
agentseek-api devcannot load a graph manifest whose graph entry is an async factory. This blocks templates migrated from the LangGraph CLI when their graph must asynchronously initialize resources such as MCP clients and discovered tools.Reproduction
A generated
deepagents/mcpproject declares a graph entry like:{ "graphs": { "mcp": "./src/agentseek_e2e_deepagents_mcp/agent.py:make_graph" } }The factory is asynchronous:
Start the project with
agentseek dev(which launchesuv run agentseek-api dev). The HTTP service and/healthendpoint start successfully. On the first/runs/streamrequest, graph loading fails with:Why this happens
The graph loader invokes the configured factory and immediately coerces the return value to a compiled graph or
StateGraph. For an async factory, the immediate return value is a coroutine. Because the loader does not detect and await awaitable results, it validates the coroutine object instead of the graph it produces.This is specifically a LangGraph CLI to AgentSeek API runtime migration issue: the same template can be served by the previous runtime, but fails when its lifecycle is changed to
agentseek-api dev.Impact
doctor --livecannot detect the failure because it only checks HTTP readiness.Proposed fix
In the graph loading path:
inspect.isawaitable(result).StateGraph/compiled graph.Regression coverage
Please add tests for:
StateGraphfactory;StateGraphfactory;/runs/streamsuccessfully invoking an MCP calculator tool.Acceptance criteria
After the fix,
agentseek-api devfollowed by the first/runs/streamrequest must load the async MCP graph successfully, emit stream events, and allow multiple turns on the same thread.