Summary
Every rendered route (CLI route or MCP tool) runs inside a render session bounded by DEFAULT_AGENT_RENDER_LIMITS.maxElapsedMs = 60_000 (packages/rsc-runtime/src/agent-document.ts). The CLI runtime and the MCP projector construct the dispatcher with no limit overrides, and neither CliRouteConfig nor ToolConfig has a field to raise it. A route whose legitimate work exceeds a minute — a long-poll such as cargo-hauler's hauler_await — throws elapsed-time-exceeded at emit time, after the wait has already succeeded, and the caller loses the result.
Observed downstream as ScriptedAlchemy/cargo-hauler#32: hauler await cc-N --max-wait-ms 90000 waited 91 s, then printed only Agent render elapsed time exceeds 60000ms and exited 1. The daemon had the result; the render session refused to deliver it.
Workaround in place
cargo-hauler now clamps one await call to 55 s (schema ceiling, guidance text, README) and tells the agent to call again. That is a caller-visible regression in ergonomics purely to stay under a framework constant, and every long-polling plugin will have to rediscover it.
Request
Let a route declare its render budget, e.g.
export const config = {
description: '…',
render: { maxElapsedMs: 7_200_000 }, // or `limits: Partial<AgentRenderLimits>`
} satisfies ToolConfig;
- Validated at build time (positive safe integer; perhaps an upper bound per host, since Claude/Codex/Cursor tool timeouts are the real ceiling and
AB… could warn when the route's budget exceeds the host's tool timeout).
- Applied by both the CLI runtime and the MCP projector when they create the render dispatcher for that route.
- Surfaced in
agent-bundle inspect output.
Alternatively (smaller): treat a streamed Agent.Progress update as keep-alive and only count elapsed time since the last emitted event, so a route that is visibly making progress is not killed by a wall-clock cap.
Version
agent-bundle preview 4edbd493b (main); also present at 9bb5d0dc (DEFAULT_AGENT_RENDER_LIMITS unchanged, no config surface for limits — rg "AgentRenderLimits" packages/agent-bundle/src matches only test/render.ts).
Summary
Every rendered route (CLI route or MCP tool) runs inside a render session bounded by
DEFAULT_AGENT_RENDER_LIMITS.maxElapsedMs = 60_000(packages/rsc-runtime/src/agent-document.ts). The CLI runtime and the MCP projector construct the dispatcher with no limit overrides, and neitherCliRouteConfignorToolConfighas a field to raise it. A route whose legitimate work exceeds a minute — a long-poll such as cargo-hauler'shauler_await— throwselapsed-time-exceededat emit time, after the wait has already succeeded, and the caller loses the result.Observed downstream as ScriptedAlchemy/cargo-hauler#32:
hauler await cc-N --max-wait-ms 90000waited 91 s, then printed onlyAgent render elapsed time exceeds 60000msand exited 1. The daemon had the result; the render session refused to deliver it.Workaround in place
cargo-hauler now clamps one
awaitcall to 55 s (schema ceiling, guidance text, README) and tells the agent to call again. That is a caller-visible regression in ergonomics purely to stay under a framework constant, and every long-polling plugin will have to rediscover it.Request
Let a route declare its render budget, e.g.
AB…could warn when the route's budget exceeds the host's tool timeout).agent-bundle inspectoutput.Alternatively (smaller): treat a streamed
Agent.Progressupdate as keep-alive and only count elapsed time since the last emitted event, so a route that is visibly making progress is not killed by a wall-clock cap.Version
agent-bundle preview
4edbd493b(main); also present at9bb5d0dc(DEFAULT_AGENT_RENDER_LIMITSunchanged, no config surface for limits —rg "AgentRenderLimits" packages/agent-bundle/srcmatches onlytest/render.ts).