614c38ea7c957eb7297513b5df107698f05c0c8c
7 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
| 22412d2fa3 |
feat: group tool calls per turn + session entity graph in chat rail
Two chat UX changes (share Chat.svelte, committed together). Tool-call grouping (ToolCallGroup.svelte): - Replaced the one-<details>-per-tool-call list with a single collapsible group per assistant turn, headed by tool count + a name preview and a status icon (spinning wrench in progress, check done, X on error). - The group auto-collapses the instant its turn finishes streaming, so a completed round shows as one compact pill; historical/loaded turns start collapsed. The auto-collapse fires once at the streaming→done transition, leaving manual toggles alone afterward. Session graph rail (SessionGraph.svelte) — replaces the old ContextRail (fleet health / pending approvals / live events), which is deleted: - A force-directed graph that starts empty (animated constellation empty state) and grows as the conversation references entities. Slugs are extracted from message text and tool *arguments* only — never bulk result rows, so a single get_health_summary doesn't dump all 168 entities — then validated against the backend via fetchGraph (cached) with check/execution probe entities excluded. Nodes are colored by health; edges appear once both endpoints are present. - Clicking a node highlights it and its neighbors and opens an inline detail panel below: slug/type/state, health + freshness, top attributes, in-graph relations (clickable to hop), and a Full detail button opening the entity sheet. - The rail is resizable via a drag handle (260–620px, persisted to localStorage). The header's global fleet-health dots are unchanged; only the right-rail content was replaced. Risk: reversible_low (UI-only). The slug extractor is scoped to focused mentions by design; edges may be slightly incomplete since only root-fetched entities contribute edges, which is acceptable for a session overview. Verification: verified in the browser preview — loading a real session built a 4-node graph (hubris/caddy/netbird-vps/strong) with the hubris→caddy relationship edge; clicking hubris showed "proxmox-host · active · healthy · checked 40s ago" with attributes and relations; dragging the handle resized 320→440px and persisted; a 34-tool historical turn renders as one collapsed pill that expands on click. tsc clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
|||
| 5686b9de40 |
fix: white favicon, sidebar active-state bug, app-wide pointer cursor
Three UI issues reported after the neutral-gray redesign: - favicon.svg was still filled #58a6ff (the pre-redesign accent blue); changed to white to match the sidebar logo mark. - Sidebar nav items all showed a filled background even when inactive. Root cause: sidebar-menu-button.svelte (and -sub-button) rendered `data-active="false"` as a literal attribute, but Tailwind's bare `data-active:` variant matches attribute *presence*, not value — so data-active:bg-sidebar-accent applied to every item regardless of state. Fixed by emitting the attribute only when active (`isActive || undefined`), a latent bug in the vendored shadcn component that read as intentional until flagged. - Tailwind's preflight resets <button> to cursor: default, so no button in the app showed a pointer. Added one base rule restoring cursor: pointer for buttons, [role=button], links, summary, and select (respecting :disabled / aria-disabled) rather than annotating each call site — covers new interactive elements automatically. Risk: reversible_low (UI-only). Verification: verified in the browser preview that inactive sidebar items are transparent (only the current page shows a background), nav buttons report cursor: pointer via computed styles, and the favicon renders white in the tab. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
|||
| aa6017e0ca |
fix: layout overflow regression + adopt true neutral gray theme
Problem: two issues surfaced after the dashboard-01 shell change ( |
|||
| cbfd09c5df |
feat: redesign toward shadcn-svelte dashboard-01 (inset sidebar, gradient stat cards)
Problem: requested visual alignment with the shadcn-svelte dashboard-01
reference block (shadcn-svelte.com/blocks#dashboard-01) — the app's
sidebar/header shell and Overview stat cards looked plain by comparison.
Change: pulled the actual reference source (app-sidebar.svelte,
nav-main.svelte, site-header.svelte, section-cards.svelte from
huntabyte/shadcn-svelte) rather than approximating from screenshots.
- App.svelte: Sidebar.Root now uses variant="inset" (the floating,
rounded, shadowed content panel — already fully built into the
existing Sidebar.Inset component via peer-data selectors, just never
enabled). Brand mark is now a proper Sidebar.MenuButton matching the
reference's padding/hover treatment; "New chat" uses the reference's
primary-colored button styling. Header matches the reference exactly:
h-(--header-height) (48px, was 44px), vertical separator after the
sidebar trigger, right-aligned actions group.
- Overview.svelte: stat cards rebuilt to match section-cards.svelte —
gradient background, Card.Action badge, Card.Footer with a bold line
+ muted context line, tabular-nums, responsive @container grid
(1/2/4 columns). Deliberately did NOT copy the reference's fake
trend-percentage badges (Oikos doesn't track historical trends, and
this project's whole thrust has been eliminating dishonest UI state —
see
|
|||
| 851b5dce67 |
feat: master-detail entity sheet, freshness in Entities table, live logo
Problem: the web UI felt dead and hard to navigate — the Entities table
had no health/freshness signal (just a meaningless row-mutation
timestamp), no way to see what was actually monitoring an entity,
sessions couldn't be reopened, and every drill-down was a full page
navigation that lost the list.
Change:
- Entities table: Updated column replaced with a health dot + relative
"checked Xm ago", sourced from the backend's new health/last_check_at
fields.
- New EntityDetailContent.svelte extracted from EntityDetail.svelte and
shared between the full #/entity/:slug page and a new EntitySheet.svelte
opened from the Entities table (master-detail, row click opens a panel
instead of navigating away). Adds a Monitoring card listing the
entity's check_defs (kind, interval, enabled/disabled with
click-to-toggle via the existing PatchCheck endpoint) and renders
attributes as key/value pairs instead of raw JSON.
- Sessions: fixed a bug where clicking a session loaded it into the
chat store but never navigated to the chat page, so nothing appeared
to happen. Added a SessionRail inside Chat so switching sessions
never leaves the chat surface.
- Fixed the local dev proxy (vite.config.ts): production Caddy strips
the /agent prefix before forwarding to nomos; the dev proxy didn't,
so every session/chat fetch 404'd locally while working in prod.
- Found and fixed a real latent bug while testing the session fix:
chat.ts's loadSessionMessages passed the persisted tool_calls array
straight through, but nomos stores the tool_use and tool_result as
two entries sharing one id. Chat.svelte's keyed {#each tool (tool.id)}
throws on the duplicate key, which silently blanked the entire
message list — invisible until sessions were actually clickable.
Fixed by merging tool_calls by id before rendering, matching the
shape the live-streaming path already produces.
- UI polish: sidebar logo is now just the omicron mark in white (was
icon+text in the accent color); removed the sheet overlay's
backdrop-blur (distracting per feedback); the Attributes/Relations/
Signals grids used viewport-based lg:/3xl: breakpoints, which forced
multi-column layouts based on browser width regardless of the sheet's
actual rendered width — switched to Tailwind v4 container queries
(@lg:/@2xl:/@3xl:) so layout responds to the real available width in
both the full page and the narrower sheet.
Risk: reversible_low (UI-only; no destructive operations; the tool_calls
merge and dev-proxy fix are corrections to broken paths, not behavior
changes to working ones).
Verification: npx tsc --noEmit clean (excluding pre-existing unrelated
.svelte type-resolution warnings). Manually verified in the browser
preview against the live dev API: Entities table health column renders
correctly; clicking a row opens the EntitySheet with a populated
Monitoring card (16 checks for host:hubris, verified via psql that
check_defs.target_id links them correctly); clicking a session now
loads its full transcript inline (was blank before the tool_calls fix);
sheet has no blur and lays out single/multi-column correctly at the
sheet's actual width.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
|||
| 2908b0a377 |
feat(ui): M4 — agent activity, knowledge search, audit, correlation grouping
Add three new pages completing the control-room web UI: - Agent activity: polls /agent-activity every 5s, filterable by type/agent - Knowledge search: FTS over /knowledge/search with snippet + entity links - Audit trail: browseable audit log with actor/action/entity filters Enhanced live events page with correlation-id clustering (Groups toggle). Added fetchAgentActivity/searchKnowledge/fetchAudit to the API client. 11 nav items now cover all planned control-room views. |
|||
| e8e230b4a5 |
nomos+web: streaming, provider routing, event gap-fill, embedded UI; fix approval FK & session context
Agent (cmd/nomos): - Stream LLM tokens via NewStreaming; emit text_delta then final text. - OpenRouter provider routing: data_collection=deny (ZDR) + require_parameters; NOMOS_PROVIDER_SORT opt-in; Exacto via model suffix. - Multi-turn: reload session history into context; UI passes session id. - Fix agent_activity logging (agent_id/session_id) and mcpClient data race. Events (live control-room feed): - approval.created (mcp), approval.decided (api), execution.completed/failed (approved-action path), signal.raised/resolved + health.changed (scheduler, transition-gated). Fixes: - createApproval FK violation (reuse execution entity) — the agent's only write path; log the previously-swallowed errors. Web UI: - Embed web/dist via //go:embed (single binary); Dockerfile builds SPA into the Go stage; committed .gitkeep placeholder keeps backend-only builds green. - Caddy: Authentik-gated /agent/* -> nomos so the UI reaches the agent same-origin in production. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |