Skip to content

Show how much subagent tool-call context ctx_reduce cannot reclaim #643

Open

Description

@dhaern

Short description

In long subagent tool loops, part of the tool-call context stays as skeleton_real arcs that ctx_reduce cannot drop, and neither the agent nor the user can see how large that part is. A subagent can sit above execute_threshold_tokens with nothing left to reduce. I suggest reporting the retained amount in /ctx-status and in the nudges. The numbers below may also help size what the signed-thinking harness listed in the v0.46.1 notes could recover.

What problem does this solve?

#619 fixed queued drops never being applied in subagent sessions. What remains is a floor the agent cannot lower. As I read shared/tag-transcript.ts (requiresToolArcSkeleton), tool calls in a message that carries native thinking blocks are kept as skeletons with their real arguments, which I assume is so the signed blocks stay valid. That fits Anthropic's rule that thinking blocks go back "alongside the tool_use block it accompanied", and that a tool-use loop is one assistant turn (Preserving thinking blocks). A subagent is usually one prompt followed by a long tool loop, so none of its history counts as an earlier turn.

I found nothing that separates this part from the rest: the Tool Calls row in shared/status-view.ts is a single total.

Numbers from my local context.db (Magic Context 0.46.1, OpenCode 1.18.35, execute_threshold_tokens: 262000). Across 111 subagent sessions with at least 20 dropped tool tags, the arguments kept by skeleton_real arcs were:

Percentile Tokens kept
p50 0
p75 ~4.5k
p90 ~24k
max ~165k

Three sessions keep more than 50k and two keep more than 100k. The largest is a Claude Opus 5.5 subagent with 1,008 skeleton tags and ~165k tokens of kept arguments. Its tool_call_tokens is ~225k, it has no pending ops left, and its last input was ~372k tokens against the 262k threshold.

Thinking does not explain every skeleton: across all subagent sessions in the database, 2,037 of 5,531 skeleton-dropped tool tags have no reasoning tokens recorded in tags. I don't know whether that means no thinking block or an unrecorded one.

Proposed solution

  • Split the retained part from the reclaimable part in the Tool Calls row of /ctx-status. When the retained part alone is above the execute threshold, say so in the ctx_reduce reply or the nudge, so the agent stops trying to reduce and the user can see why.
  • No change to what gets dropped is requested. The v0.46.1 notes list "A live test harness for Anthropic signed-thinking edits, seeded from a recorded request", which I read as you already looking at how the API treats edits to signed thinking. If it accepts removing a whole arc together with its thinking, subagent loops are where that would pay off most, and the table above gives a rough size. If it does not, the visible floor still helps choose a threshold.

Alternatives considered

  • Raising execute_threshold_tokens above the floor defeats the cap it was set for.
  • Starting a fresh subagent when the floor nears the threshold is the only workaround I have.

Area

OpenCode plugin

Additional context

The figures come from one local database, so they say nothing about how common this is.

Activity

  1. magic-alfonso commented on Oct 9, 2026

    @magic-alfonso

    Thanks, this is a valid finding and the numbers helped. Rather than only showing the retained part, we're going to reduce it.

    When a recent tool call is dropped, Magic Context keeps a small skeleton of it (the call with its real arguments, and the result replaced by a placeholder) so the model can still see what it did. That choice is made once, at drop time, and today it's replayed for the rest of the session. A skeleton is never turned into a full removal later, even after it's far from the end of the conversation. That's why skeletons accumulate in long tool loops.

    The change: on a pass that already rebuilds the cached prefix (crossing the execute threshold, a history fold, /ctx-flush, or the 85% force band), skeletons that are no longer among the newest 20 tool calls become full removals. Those passes rewrite the prefix anyway, so this costs no extra cache.

    Skeletons kept because their message carries Anthropic thinking blocks are a separate case. Anthropic only accepts certain edits to signed thinking, and a subagent's whole tool loop counts as one assistant turn, where thinking can't be modified at all. We're checking exactly which of those can be removed safely before changing anything there. Your observation that many skeletons have no recorded reasoning tokens is part of that check.

    I'll update this issue when the design is done and again when it ships.

  2. null-axiom commented on Oct 22, 2026

    @null-axiom

    Adding a data point from OpenCode 2 (Magic Context 0.49.13–0.49.16, OpenCode's own compaction.auto off as recommended).

    Long implementation subagents here peaked at 623K and 305K tokens of context in single runs. In the 623K run, ctx_reduce brought it back down only to about 200–350K, and it climbed again from there; most of that run's cost was cache reads of this context on every step.

    The skeleton change above should lower that floor. The other part is that a subagent has nothing that folds its history at all: on overflow Magic Context records "subagents cannot run historian" and returns, so with native compaction off, the only lever is ctx_reduce on individual items. Would either of these fit once the skeleton work lands?

    • a size-triggered, historian-free fold for subagents (oldest turns replaced with a short mechanical summary once context passes a threshold), or
    • a supported way to let OpenCode's native compaction run for subagent sessions only, while Magic Context keeps managing primary sessions.
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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions