Skip to content

fix(sidequest): rebuild_cursors only scans ToolOutput, misses ToolResult from native tool-use providers #2114

@bug-ops

Description

@bug-ops

Summary

SidequestState::rebuild_cursors scans for MessagePart::ToolOutput but the native tool execution path stores results as MessagePart::ToolResult. This means SideQuest eviction silently does nothing when using OpenAI, Claude, or any provider with supports_tool_use() == true.

Root cause

crates/zeph-core/src/agent/tool_execution/legacy.rs:20-26 dispatches to native or legacy based on provider.supports_tool_use():

  • Native path (native.rs): stores tool results as MessagePart::ToolResult { tool_use_id, content, is_error }
  • Legacy path (legacy.rs): stores tool results as MessagePart::ToolOutput { tool_name, body, compacted_at }

SidequestState::rebuild_cursors (crates/zeph-core/src/agent/sidequest.rs:106) pattern-matches only MessagePart::ToolOutput. With native providers, all tool outputs are stored as ToolResult — so the cursor list is always empty.

Evidence

CI-75 live test with OpenAI router + [memory.sidequest] enabled = true, interval_turns = 2:

2026-03-22T12:02:04.826488Z DEBUG zeph_core::agent: sidequest: no eligible cursors
2026-03-22T12:03:01.225734Z DEBUG zeph_core::agent: sidequest: no eligible cursors

The tick() fires correctly at turn 2 and 4, but rebuild_cursors finds zero matching parts.

Severity

MEDIUM — SideQuest is disabled by default (enabled = false). No production impact today. But functionally broken for the most common providers (OpenAI, Claude). Works only with Ollama legacy path.

Fix

rebuild_cursors must also scan MessagePart::ToolResult entries. The eviction logic (apply_eviction) needs to handle the ToolResult variant alongside ToolOutput. The compacted_at concept (used in ToolOutput) needs an equivalent for ToolResult — either add a evicted flag to ToolResult or replace its content with a tombstone like [evicted by sidequest].

Alternatively, unify the two message part variants into a single ToolResult with an optional compacted_at field.

Filed

CI-75, 2026-03-22

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions