mirror of
https://github.com/multica-ai/multica.git
synced 2026-06-17 11:48:42 +02:00
State management - Pending task / live timeline are now Query-cache single source; Zustand mirror removed (fixes duplicate assistant render caused by the invalidate→refetch race window) - WS subscriptions moved from ChatWindow to global useRealtimeSync so pending state survives minimize and refresh - New GET /chat/sessions/:id/pending-task to recover live state on mount - Drafts persisted per-session (was per-workspace) Unread tracking - Migration 040: chat_session.unread_since (event-driven; old chats stay clean — no mass backfill) - POST /chat/sessions/:id/read clears unread; broadcasts chat:session_read so other devices sync - New GET /chat/pending-tasks aggregate for the FAB - ChatFab: brand-color impulse animation while running, brand-dot badge of unread session count - ChatWindow auto-marks read when user is viewing the session Header redesign - Two independent dropdowns: agent (avatar + name + My/Others grouping) at the input bottom-left; session (title + agent avatar) in the header - ⊕ new-chat button replaces the old + and history buttons - Session dropdown lists all sessions across agents with avatars - Empty state: 3 clickable starter prompts that send immediately - Mention link renderer falls through to default span on null — fixes @member/@agent/@all silently disappearing app-wide - User messages render through Markdown - Enter submits in chat input only (with IME guard + codeBlock skip); bubble menu hidden in chat Misc - Partial index on agent_task_queue for fast pending-task lookup - 2 new storage keys added to clearWorkspaceStorage - useMarkChatSessionRead has onError rollback - chat.* namespace logs across store, mutations, components, realtime Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
17 lines
912 B
SQL
17 lines
912 B
SQL
-- Event-driven unread tracking for chat sessions.
|
|
--
|
|
-- Semantics: unread_since is the timestamp of the first unread assistant
|
|
-- message. It stays NULL while the session has no unread. It's SET when
|
|
-- an assistant reply lands and the column was NULL. It's RESET to NULL
|
|
-- when the user marks the session as read. Existing rows start as NULL,
|
|
-- meaning "no unread to track" — historic chats are not mass-flagged.
|
|
ALTER TABLE chat_session ADD COLUMN unread_since TIMESTAMPTZ;
|
|
|
|
-- GetPendingChatTask runs on every session open / switch and filters by
|
|
-- chat_session_id + in-flight status + orders by created_at. A partial
|
|
-- index on the in-flight subset keeps that query cheap as the queue grows.
|
|
CREATE INDEX IF NOT EXISTS idx_agent_task_queue_chat_pending
|
|
ON agent_task_queue (chat_session_id, created_at DESC)
|
|
WHERE chat_session_id IS NOT NULL
|
|
AND status IN ('queued', 'dispatched', 'running');
|