Address review feedback: the routed-agent /clear path bypassed the
public ContextManager.Clear contract via an unexported hook. Restore
the single Clear call in the command path and resolve the session's
owning agent inside the built-in implementations instead:
- legacy: Clear resolves the owning agent via agentForSession instead
of assuming the default agent
- seahorse: drop ClearContextStore; Clear wipes the engine state and
the owning agent's session store
- command path: persist session scope metadata before Clear so
ownership resolves even when /clear is the session's first message
- add coverage that a custom ContextManager receives Clear for routed
agents
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Previously when io.Copy to the base64 encoder failed, encoder.Close()
was skipped. This left the encoder's internal buffer unflushed.
Now always call Close() and handle both copy and close errors
explicitly.
Two bugs prevented the usage block from ever reaching the wire:
1. CallLLM read turnStateFromContext(ctx), but the raw ctx is not seeded
with the turn state (only turnCtx is), so SetLastUsage/SetLastFinishReason
were dropped — GetLastUsage() returned nil at finalize. Set them on the
ts parameter directly, which is also what the streaming publisher reads.
2. The manager wraps the channel streamer in finalizeHookStreamer /
splitMarkerStreamer, neither of which forwarded SetTurnUsage (it is not
part of the bus.Streamer interface), so the type assertion in the
publisher's Finalize failed silently. Mirror the existing SetModelName
forwarding: add a turnUsageStreamer interface + setStreamerTurnUsage
helper and SetTurnUsage methods on both wrappers (splitMarker also stores
and re-applies usage to each freshly-begun part streamer).
Adds regression tests asserting both wrappers forward SetTurnUsage.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
When the Brave Search API returns HTTP 200 with zero results, log a
warning with the response body preview to help diagnose silent failures.
This addresses cases where the API response format has changed or a
non-standard error response is misinterpreted as a successful empty
result, leaving the LLM with a misleading "No results" message.
Previously, empty results were silently returned to the LLM as "No
results for: <query>", making it impossible to distinguish between
genuinely empty results and API format mismatches or silent errors.
Closes#3125