feat: Learning page — capability timeline + trend, built on real data
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled

The plan's "learning view" (runbook success-rate trends, promoted
skills, capability timeline) assumes the patterns/skills/feedback
pipeline is populated. It isn't: all three tables are empty in
production and nothing in the codebase ever writes to feedback, so
building the UI against them today would ship a permanently-empty
page. Scoped instead around data that's real and growing —
executions — while still wiring up /patterns and /skills so the page
needs no rework once that pipeline exists.

New /api/v1/learning/timeline (per-verb first-success date + success
rate, parsed via the existing splitAction helper) and
/api/v1/learning/trend (30-day daily success/fail counts), both
read-only queries against executions. Patterns and skills sections
call the existing (untouched) ListPatterns/ListSkills endpoints and
render an explanatory empty state instead of nothing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-10 21:28:19 +02:00
parent 6192c35c10
commit 52e16e04ca
5 changed files with 380 additions and 0 deletions

View File

@@ -10,6 +10,7 @@
import EntityDetail from './pages/EntityDetail.svelte'
import Agent from './pages/Agent.svelte'
import Knowledge from './pages/Knowledge.svelte'
import Learning from './pages/Learning.svelte'
import Audit from './pages/Audit.svelte'
import { newChat } from '$lib/stores/chat'
import { summary, subscribeContext, openSignalCount } from '$lib/stores/context'
@@ -33,6 +34,7 @@
import BotIcon from '@lucide/svelte/icons/bot'
import SearchIcon from '@lucide/svelte/icons/search'
import ScrollTextIcon from '@lucide/svelte/icons/scroll-text'
import TrendingUpIcon from '@lucide/svelte/icons/trending-up'
let page = $state('chat')
let routeParam = $state('')
@@ -71,6 +73,7 @@
{ id: 'events', label: 'Events', icon: ActivityIcon },
{ id: 'agent', label: 'Agent', icon: BotIcon },
{ id: 'knowledge', label: 'Knowledge', icon: SearchIcon },
{ id: 'learning', label: 'Learning', icon: TrendingUpIcon },
{ id: 'audit', label: 'Audit', icon: ScrollTextIcon }
]
</script>
@@ -210,6 +213,8 @@
<Agent />
{:else if page === 'knowledge'}
<Knowledge />
{:else if page === 'learning'}
<Learning />
{:else if page === 'audit'}
<Audit />
{:else}