AI conversation history

mandatory

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.

Companion: memory-drawer.kmd (#117) — sibling persistence surface. Cascade-delete contract per identity-data-retention.kmd R5.

Princípios

  1. Date-grouped natural — Today / Yesterday / Last 7 days / Older.
  2. Search dual mode — literal + semantic (via services/ai/memory ou rag).
  3. Actions standard — pin / archive / delete / rename / export.
  4. Auto-titulation — AI-generated title from first messages; user can override.
  5. 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.kmd R5); 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: title, last activity time".
  • 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.
  • Companion: memory-drawer.kmd (#117 — sibling persistence)
  • Backend: services/ai/chat-adapter/, services/ai/memory/
  • Policies: multi-tenant-by-default.kmd, identity-data-retention.kmd R5
  • Refs: ChatGPT sidebar, Claude conversations, Gemini sidebar