Skip to content

[feature]: Chat V2 / Phase 1 / M3 — Edit, retry, per-conversation instructions (with branching) #147

@jackmusick

Description

@jackmusick

Goal

Ship M3 of the Chat V2 / Phase 1 Chat UX overhaul: edit, retry, and per-conversation instructions — built on top of message branching so edits and retries are non-destructive (matching Claude.ai / ChatGPT / LibreChat / Open WebUI).

Scope expanded vs. spec §12 M3: added branching infrastructure. Scope shrunk: dropped retry-with-different-model dropdown (regular retry only). Spec §1, §16.9, §16.10, and the "linear-only" non-goal are updated as part of this work.

What's in this milestone

Backend

  • Migration: Message.parent_message_id UUID NULL FK messages.id, Conversation.active_leaf_message_id UUID NULL FK messages.id, Conversation.instructions TEXT NULL. Backfill parent_message_id from sequence for existing rows; backfill active_leaf_message_id to the last message of each conversation.
  • agent_executor._build_message_history walks active_leaf_message_id → root via parent_message_id instead of ORDER BY sequence. Tool-call ID remap logic stays (operates on the resolved linear path).
  • New endpoint POST /api/conversations/{id}/messages/{msg_id}/edit — creates a sibling user message under the same parent, sets new active leaf, dispatches a turn.
  • New endpoint POST /api/conversations/{id}/messages/{msg_id}/retry — creates a sibling assistant message under the same parent, sets new active leaf, dispatches a turn.
  • New endpoint PATCH /api/conversations/{id}/active-leaf — switches active leaf (sibling navigation).
  • New endpoint PATCH /api/conversations/{id} accepts instructions field. System prompt assembly in _build_message_history appends conversation.instructions after agent prompt + workspace instructions.

Frontend

  • Pencil hover icon on user message bubbles → inline editable textarea + Save/Cancel. Save creates a sibling and switches active leaf.
  • RotateCcw hover icon on assistant message bubbles → single-click retry creates a sibling.
  • Sibling navigation: < 2/3 > arrows on any message that has siblings. Arrows update active leaf; chat re-renders the active path.
  • Conversation header overflow → "Customize this chat" Dialog with autosize textarea + live token cost preview. Save persists Conversation.instructions.
  • Chat store: branch-aware message rendering (flat array of the active path, derived from active_leaf_message_id), editMessage, retryMessage, switchBranch actions.

Spec updates (in this PR)

  • docs/superpowers/specs/2026-04-27-chat-ux-design.md:
    • §1.1: replace "no branching" with branching-on-edit semantics.
    • §1.2: drop "Switching models via retry sets the conversation's current model" + drop the model override dropdown.
    • §16.9: drop AlertDialog confirm.
    • §16.10: drop the Popover-with-ModelPicker; just a RotateCcw button.
    • Non-goals: remove "Branching/tree conversations (linear-only)."
  • docs/superpowers/plans/2026-04-27-chat-v2-master-plan.md: add a note in the decisions log.

Out of scope

  • Retry-with-different-model dropdown.
  • Compaction-aware branch handling (M5's problem).
  • Branch-aware export (v1 exports active branch only — already correct).

Tests

  • Unit: test_message_history_branching.py — parent-chain walk, sibling resolution, active-leaf switching, edit creates sibling, retry creates sibling.
  • E2E (api/tests/e2e/): edit creates new branch + dispatches turn; retry creates new branch + dispatches turn; PATCH instructions persists and shows up in next turn's system prompt; sibling switch endpoint.
  • Vitest: chatStore branch-aware path resolution; editMessage/retryMessage/switchBranch reducers; instructions dialog component.
  • Playwright: edit a user message and confirm both branches accessible via arrows; retry an assistant message and switch back; set per-conversation instructions and confirm next response reflects them.

Branching strategy

  • PR target: feature/chat-v2 (NOT main).
  • Worktree at .worktrees/<issue#>-m3-edit-retry-instructions/.
  • Branched from origin/feature/chat-v2, not main.

Closes

This issue closes when M3 ships into feature/chat-v2. The phase-1 tracking issue (#139) stays open.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions