Files
oikos/plans/2026-07-14-tool-timeline-sidebar.md
dtoro cc6bcdceaa
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
Desktop App / Build Linux (amd64) (push) Has been cancelled
Desktop App / Attach to Release (push) Has been cancelled
scroll fixes + activity bar position
- Activity bar moved to bottom of message list (before messagesEnd)
- Smart scroll: auto-scroll only during streaming or when near bottom
- Scrolling up pauses auto-scroll until next send
- Removed duplicate $effect block
- Plan: tool timeline in sidebar (plans/2026-07-14-tool-timeline-sidebar.md)
2026-07-14 11:37:52 +02:00

4.4 KiB
Raw Blame History

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.