Skip to content

feat(context): prune historical verbose tool results with tool protection and turn filtering #2078

Description

@Cobies

Before submitting

  • I searched open and closed issues and did not find a request for this feature.
  • I reviewed this request and removed credentials, tokens, private paths, hostnames, and other sensitive data.

Problem or opportunity

In long-running or exploratory sessions in Gentle Pi / Gentle Shell, terminal tools (bash, grep, find) often produce large outputs (such as multi-hundred-line git diff outputs, test failure dumps, or directory listings).

Because Pi retransmits the full conversation history to the model on every turn, older verbose tool results accumulate in context. This can inflate context size to 80k-120k+ tokens, significantly increasing API latency and per-turn token costs, while adding unnecessary noise to model reasoning on later unrelated turns.

Proposed outcome

Introduce non-destructive rolling-window tool result pruning via the native pi.on("context") hook:

  1. Recent Turn Preservation: The most recent turns (default recentTurnsToKeep = 2) preserve 100% of their raw tool results intact.
  2. Conservative 4,000-Char Threshold: In older turns, only verbose terminal tool outputs exceeding DEFAULT_MAX_RETAINED_CHARS = 4_000 are pruned to a concise placeholder ([Output omitted from LLM context: X chars, Y lines. Preserved in session history.]).
  3. Protected Tool Names (PROTECTED_TOOL_NAMES): Critical orchestration, lifecycle, memory, and review tools are strictly exempt from pruning regardless of size or age:
    • Subagents: subagent_run, subagent_result, subagent_status, subagent_list_tasks, subagent_continue
    • Review authority: gentle_review, gentle_review_capture, gentle_review_capture_group, gentle_review_scope
    • Memory & Decisions: mem_save, mem_get_observation, mem_search, mem_context, mem_timeline, todo, ask_user_choice, ask_user_question
  4. Synthetic Subagent Notification Filtering: Background subagent notifications arriving as synthetic role: "user" messages (Subagent <agent> (task <id>, ...) finished.) are excluded from human turn counting, preventing subagent completions from prematurely displacing the human user's active window.
  5. Opt-out & Non-Destructive Design: Disk transcripts and UI logs are never modified (only the transient array passed to the model API is filtered), and pruning can be completely disabled via GENTLE_PI_CONTEXT_PRUNING=off.

Alternatives considered

Relying solely on session_before_compact waits until the conversation hits maximum context limits. A rolling window on older bulky terminal tool outputs keeps active context lean without forcing full session compaction.

Additional context

Accompanied by a dedicated unit test suite covering tool protection, turn window preservation, idempotency, and synthetic notification filtering.

Activity

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