Skip to content

Add byte caps to orchestration MCP outputs and closed-agent tombstones #373

Closed

Description

@Juliusolsson05

Problem

The built-in MCP/orchestration audit found that orchestration output paths are mostly count-capped but not byte-capped. A single huge child answer can be JSON-stringified into a tool response, retained in a parent transcript/tool result, duplicated in renderer runtime state, and stored again in closed-agent tombstones.

This is separate from the live child leak in #369: even correctly closed agents can leave large text payloads in MCP/tool-result paths.

Findings

  • orchestration_read_agent, orchestration_read_run_outputs, and orchestration_wait_agents return toolText(JSON.stringify(...)); message counts are capped but message bytes are not.
  • Renderer visibleMessageSummary caps message count, not messages[].text, latestAssistantText, or finalAssistantText.
  • OrchestrationBridge.noteClosed stores closed-agent output for up to 24h with count caps but no byte caps.
  • Parent tool results can retain the huge orchestration output through normal provider transcript/feed paths.
  • latestAssistantText and finalAssistantText duplicate the same large payload in several output shapes.

Proposed Fix

  • Add MCP params/defaults: maxCharsPerMessage, maxCharsPerAgent, and maxTotalChars.
  • Make wait/run outputs summary-first by default: statuses, lifecycle, counts, and bounded excerpts.
  • Apply caps before renderer IPC response construction and before main stores closed-agent tombstones.
  • Return truncated, original counts, and original byte/char estimates so callers know they got excerpts.
  • Cap mirrored latestAssistantText / finalAssistantText fields, or make them aliases computed only at API boundary.
  • Fix transcript tail streaming so tail rings truncate before storing raw projected items.

Acceptance

  • One huge child output cannot create an unbounded orchestration MCP response.
  • Closed-agent tombstones are byte-bounded, not just count-bounded.
  • Parent transcripts receive bounded orchestration excerpts by default.
  • Full output retrieval remains possible through explicit capped reads or disk-backed transcript access.

Related: #327, #365, #369

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions