# 2026-07-14 — Tool timeline in sidebar + session analysis **Status:** Planned ## Session analysis: `1d614a1f` (2026-07-14T09:21) "Audit all homelab hosts and active LXCs for pending apt updates" ### What went well - `list_lxcs(state="active")` worked — only returned live LXCs (our Phase 5 fix) - Agent discovered that `apt-get update` on host targets gets classified as `config_mutation` (modifies apt cache) — all 9 needed approval, user bulk-approved - 162 tool calls across 4 turns: 30 + 78 + 0 (auto-resume fail) + 54 = legitimate fleet audit - Our Phase 1 fix worked: 3 auto-resume failures persisted "task is paused" notes instead of auto-failing ### What failed - **Agent never called `complete_task`.** Session status stuck at `"planning"` despite: - `set_goal` called in first turn - 162 tool calls executed - Final message has full audit text - But `propose_plan` never cleared the gate — the agent entered planning and never left - The 3 auto-resume failures filled the transcript with `[System: auto-resume failed…]` noise ### Root cause: `apt-get update` triggers `config_mutation` classification - The command classifier correctly treats `apt-get update` as state-changing (it writes to the apt cache) - But the agent just wanted to READ package lists. The audit batch of 9 `apt-get update` calls all needed approval - Lesson: `apt-get update` should be in a separate audit/update pair where the audit phase uses a read-only inspection command (e.g. `apt list --upgradable` doesn't mutate cache) ### Tool usage pattern - 30 tool calls in turn 1 (set_goal, propose_plan, list_lxcs, run × 9 for apt update on hosts, update_plan_step × 8, ask_operator) - 78 tool calls in turn 3 (run × 25+ for apt audits, get_execution_status × 10+, update_plan_step × 10) - 54 tool calls in turn 7 (final result synthesis) These 162 tool calls are ALL rendered inline in chat today. The operator sees a massive wall of collapsed ToolCallGroup entries. --- ## Plan ### 1. Scroll fixes (DONE above) - Activity bar moved to bottom of messages (before messagesEnd) - Smart scroll: auto-scroll only during streaming OR when user is near bottom - Scrolling up pauses auto-scroll until user sends a new message ### 2. Tool timeline in sidebar **Goal:** Decouple tool execution noise from conversation. Chat shows agent's thinking; sidebar shows what it's doing. #### 2.1 — Chat: compact tool indicator Replace the full ToolCallGroup in chat with a single compact line: ``` [N tools used — view in Activity] ``` - Clicking it opens/highlights the sidebar timeline - Pending approvals still show inline in chat (InlineApproval stays) - Inline tool renderers (entity cards, health summary, etc.) stay — they're informational, not noise #### 2.2 — Sidebar: live tool timeline The "This session" section (SessionDigest) becomes a live tool timeline: - Each agent turn gets a timestamp header - Within each turn: tool calls shown as a compact list with status icons (running spinner / done check / failed X) - Tool names are the same compact format from ToolCallGroup - Results stay collapsible (click to expand) - Auto-scrolls to latest, but doesn't force-follow if user is reading history - UPDATEs live (no reload needed) — same polling mechanism as SessionDigest #### 2.3 — Sidebar: merge plan steps PlanProgress and SessionDigest merge into one "Activity" panel: - Top: plan steps with progress bar (from PlanProgress) - Middle: live tool timeline (from SessionDigest) - Bottom: knowledge created this session (from SessionDigest) ### 3. `complete_task` enforcement (session finding) The agent called `set_goal` and then the task entered `planning` status. But the flow is: - `set_goal` → status changes to `planning` - `propose_plan` → status changes to `executing` The agent called `set_goal` but never `propose_plan` that clears `planning`. Looking at the code: `setGoal` in store.go sets `status = 'planning'`, and `proposePlan` sets `status = 'executing'`. So the agent must have called `set_goal` but the subsequent `propose_plan` failed or the agent skipped it. **Fix:** In `setGoal`, if the agent has enough information to propose a plan, auto-transition to `executing` when the first tool call is made (not when `set_goal` is called — that's too early). The status `planning` should only stick if the agent explicitly calls `ask_operator` for more info. Otherwise, status `planning` is indistinguishable from `active` — it just means the agent never formalized the transition.