sidebar activity timeline replaces tool display in chat
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

- New ActivityTimeline: unified timeline in sidebar showing all agent actions
  (goal, plan steps, tool calls, knowledge, completion) in reverse chron order
- activityLog derived store merges messages + planSteps + currentTask
- AgentIndicator stays in chat (thinking/working indicator), simplified props
- ToolCallGroup removed from chat — tools visible only in sidebar timeline
- SessionDigest replaced by ActivityTimeline
- PlanProgress restored in sidebar (conceptual steps, separate from timeline)
This commit is contained in:
2026-07-14 12:19:26 +02:00
parent cc266c238e
commit b414722fc7
7 changed files with 394 additions and 76 deletions

View File

@@ -1,10 +1,10 @@
<script lang="ts">
import type { ToolCallResult } from '$lib/stores/chat'
import type { ActivityEntry } from '$lib/stores/chat'
import LoaderCircleIcon from '@lucide/svelte/icons/loader-circle'
import CheckIcon from '@lucide/svelte/icons/check'
import XIcon from '@lucide/svelte/icons/x'
let { active = false, lastTool = null as ToolCallResult | null, error = '' }: { active?: boolean; lastTool?: ToolCallResult | null; error?: string } = $props()
let { active = false, lastActivity = null as ActivityEntry | null, error = '' }: { active?: boolean; lastActivity?: ActivityEntry | null; error?: string } = $props()
let done = $state(false)
let wasActive = $state(false)
@@ -13,7 +13,6 @@
if (active) { done = false; wasActive = true }
if (!active && wasActive) {
done = true
// Fade out after 3s
const t = setTimeout(() => { done = false; wasActive = false }, 3000)
return () => clearTimeout(t)
}
@@ -22,33 +21,8 @@
const label = $derived.by(() => {
if (error) return error
if (!active && done) return 'Done'
if (!lastTool) return 'Agent is thinking…'
const args = lastTool.args ?? {}
switch (lastTool.name) {
case 'set_goal': return 'Setting goal…'
case 'propose_plan': return 'Building plan…'
case 'search_knowledge': return `Researching: ${args.query ?? ''}`
case 'get_entity': return `Looking up ${args.slug_or_id ?? ''}`
case 'get_entity_knowledge': return `Checking prior knowledge…`
case 'get_relations': return `Checking relationships…`
case 'list_lxcs': return 'Listing containers…'
case 'list_entities': return 'Listing entities…'
case 'get_health_summary': return 'Checking fleet health…'
case 'run': {
const purpose = args.purpose ?? ''
const target = args.target ?? ''
if (purpose) return purpose
if (target) return `Running on ${target}…`
return 'Running command…'
}
case 'get_execution_status': return 'Checking execution status…'
case 'update_plan_step': return 'Updating progress…'
case 'upsert_knowledge': return 'Recording knowledge…'
case 'complete_task': return 'Wrapping up…'
case 'ping_service': return 'Checking service…'
case 'ask_operator': return 'Asking operator…'
default: return `${lastTool.name}…`
}
if (lastActivity) return lastActivity.description
return 'Agent is thinking…'
})
</script>