AI conversation history
ai-ui specs/ai-ui/conversation-history.kmd
Sidebar of past AI conversations: date-grouped (Today / Yesterday / Last 7 days / Older), search (literal + semantic), pin/archive/delete, auto-titulation, cross-device sync. Standard pattern in ChatGPT/Claude/ Gemini desktop apps.
When this spec applies
Primary triggers
- Display list of past AI conversations
All triggers
- Build chat product with multi-conversation memory
- Implement Kortex/Talk left sidebar
- Audit right-to-erasure cascade for conversations
Specification body
Spec — AI conversation history
Companion:
memory-drawer.kmd(#117) — sibling persistence surface. Cascade-delete contract peridentity-data-retention.kmdR5.
Princípios
- Date-grouped natural — Today / Yesterday / Last 7 days / Older.
- Search dual mode — literal + semantic (via
services/ai/memoryourag). - Actions standard — pin / archive / delete / rename / export.
- Auto-titulation — AI-generated title from first messages; user can override.
- Multi-tenant scope — sidebar shows only current workspace conversations.
R1 — Anatomia
┌────────────────────────────────────┐
│ [🔍 Search] [+ New] │
├────────────────────────────────────┤
│ Pinned │
│ ⭐ Stack architecture (...) │
├────────────────────────────────────┤
│ Today │
│ • Kortex deploy review (12:30) │
│ • Quick math question (10:15) │
├────────────────────────────────────┤
│ Yesterday │
│ • Spec review session (...) │
├────────────────────────────────────┤
│ Last 7 days │
│ • ... │
├────────────────────────────────────┤
│ Older │
│ • ... │
└────────────────────────────────────┘
Slots:
| Slot | Content |
|---|---|
| Search bar | live filter; semantic toggle |
| New button | start new conversation |
| Groups | Pinned / Today / Yesterday / Last 7 days / Older (collapsible) |
| Item | title + relative timestamp + last assistant snippet (optional) |
Item context menu: pin / archive / delete / rename / export markdown.
R2 — Auto-titulation
When conversation has ≥ 2 messages, gateway emits auto-title via small/fast model:
gateway.complete({
prompt: "Title this conversation in <= 6 words: ${first_user_msg} | ${first_assistant_msg}",
model: "haiku-fast", // cheap fast model
})
User can override (long-press → rename). Override persisted; re-generation NOT auto unless user explicitly requests.
R3 — Search modes
| Mode | Trigger |
|---|---|
| Literal | Default; substring match on title + message content |
| Semantic | Toggle button; query services/ai/memory embedding similarity |
Search debounce: 250ms.
Semantic results ranked by similarity; show score badge optional.
R4 — Pin / archive / delete
- Pin: max 5 pinned per workspace; sticky top group.
- Archive: removes from main list; available in "Archived" filter.
- Delete: soft-delete with 24h grace (per
identity-data-retention.kmdR5); during grace, "Undo" toast visible; after grace, hard-delete cascade (messages + memory items referenced + uploads).
R5 — Export
Export as markdown bundle:
# Conversation: Stack architecture review
- Created: 2026-05-14 09:00
- Last activity: 2026-05-14 12:30
- Messages: 24
## Messages
### User · 09:00
...
### Assistant · 09:01
...
Download .md or share via Hub (private/public).
R6 — Sync cross-device
Backed by Koder ID session; conversation list syncs across devices via:
- Conversation index table (kdb-kv) scoped per
(koder_user_id, workspace_id). - Real-time updates via WebSocket from
services/ai/chat-adapter. - Conflict resolution: last-write-wins per item field; new conversation always wins (no merge).
R7 — Surface bindings
| Surface | API |
|---|---|
| Flutter | KoderConversationList({onSelect, onArchive, onDelete, onPin, onRename}) em koder_kit/lib/src/ai/conversation_list.dart |
| Web | <koder-conversation-list> |
| Compose/SwiftUI | futuro |
| CLI / TUI | koder conv list + koder conv switch <id> + koder conv pin/archive/delete <id> |
R8 — Acessibilidade
- Sidebar:
role="navigation" aria-label="Conversation history". - Groups:
role="group" aria-labelledby="<date-header>". - Items:
<button>with aria-label "Conversation:, last activity - Search:
role="searchbox". - Context menu: keyboard accessible.
R9 — i18n
| Key | en-US | pt-BR |
|---|---|---|
ai.history.group.pinned |
"Pinned" | "Fixadas" |
ai.history.group.today |
"Today" | "Hoje" |
ai.history.group.yesterday |
"Yesterday" | "Ontem" |
ai.history.group.last7days |
"Last 7 days" | "Últimos 7 dias" |
ai.history.group.older |
"Older" | "Mais antigas" |
ai.history.action.pin |
"Pin" | "Fixar" |
ai.history.action.archive |
"Archive" | "Arquivar" |
ai.history.action.delete |
"Delete" | "Excluir" |
ai.history.action.rename |
"Rename" | "Renomear" |
ai.history.action.export |
"Export markdown" | "Exportar markdown" |
ai.history.action.new |
"New conversation" | "Nova conversa" |
ai.history.search.placeholder |
"Search conversations..." | "Buscar conversas..." |
ai.history.search.semantic_toggle |
"Semantic search" | "Busca semântica" |
ai.history.delete.confirm |
"Delete this conversation?" | "Excluir esta conversa?" |
ai.history.delete.undo_toast |
"Conversation deleted · Undo" | "Conversa excluída · Desfazer" |
R10 — Multi-tenant
- Conversation index scope per
(koder_user_id, workspace_id). - Cross-workspace: each workspace has own sidebar; no cross-workspace search by default.
- Shared workspace (multi-user): admin-controlled visibility — default own-only.
T-suite
- T1 Mount: render groups with conversations populated.
- T2 Date grouping correct: timestamps map to right group.
- T3 Pin: max 5 enforced.
- T4 Archive: removes from main; visible in archive filter.
- T5 Delete + undo: tap delete → toast 24h undo; tap undo → restored.
- T6 Hard-delete after grace: advance clock 25h → conversation gone; messages cascade-deleted.
- T7 Auto-title: after 2 messages → title auto-set.
- T8 Rename overrides: user renames → persisted; auto-title NOT triggered again.
- T9 Search literal: type "deploy" → filters list.
- T10 Search semantic: toggle → query embedding; results ranked.
- T11 Sync cross-device: edit on device A → visible on device B after WebSocket roundtrip.
- T12 Multi-tenant: workspace switch → list reloads with new scope.
- T13 A11y: keyboard nav full; aria announce group transitions.
- N1 Cross-tenant access: workspace B tries to load conversation A → 404.
Cross-link
- Companion:
memory-drawer.kmd(#117 — sibling persistence) - Backend:
services/ai/chat-adapter/,services/ai/memory/ - Policies:
multi-tenant-by-default.kmd,identity-data-retention.kmdR5 - Refs: ChatGPT sidebar, Claude conversations, Gemini sidebar
References
meta/docs/stack/specs/ai-ui/memory-drawer.kmdmeta/docs/stack/specs/ai-ui/chat-message-bubble.kmdmeta/docs/stack/policies/identity-data-retention.kmdmeta/docs/stack/policies/multi-tenant-by-default.kmd