Skip to content

feat: implement Fork thread branching, Archive, Branch, Resend, and English menu labels#270

Open
Copilot wants to merge 3 commits into
mainfrom
copilot/fix-three-dots-menu
Open

feat: implement Fork thread branching, Archive, Branch, Resend, and English menu labels#270
Copilot wants to merge 3 commits into
mainfrom
copilot/fix-three-dots-menu

Conversation

Copilot AI commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Several chat context menu items were stubbed with "coming soon" and labels were in Chinese. Fork needed proper DB-level tree branching — not text copying — so that forked threads inherit parent context structurally at query time.

DB

  • Migration 023: chat_thread_forks(user_id, forked_session_id, parent_session_id, fork_message_id, fork_write_seq) — UNIQUE on (user_id, forked_session_id)

Backend

  • forkThread(): creates a new session and inserts a fork record pinning the branch point by write_seq
  • listSessionMessagesForModel: when assembling LLM context for a forked session, walks the fork chain and prepends ancestor messages up to fork_write_seq — no content duplication, purely relational
  • POST /fork: accepts sessionId, messageId, channelId; returns forkedSessionId

Flutter

  • forkThread() API client + ChatForkResult in chat_history_api_service.dart
  • MessageList: onMoveToThreadonFork; adds onBranch / onResend callbacks; all labels translated to English; (coming soon) removed
  • chat_screen.dart — five handlers now implemented:
    • _handleArchiveRound — archives AI reply + its preceding user message (single-pass reverse scan)
    • _handleArchiveReply — archives AI reply only
    • _handleFork — calls POST /fork, navigates to new thread with inherited context
    • _handleBranch — same as Fork but triggered from a user message
    • _handleResend — re-sends message text in current thread
  • _archivedMessageIds.clear() added at all 7 _messages.clear() call sites so archive state resets on scope change

@vercel

vercel Bot commented Jun 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
bricks Ready Ready Preview, Comment Jun 3, 2026 2:51pm

Request Review

@crazygo crazygo marked this pull request as ready for review June 3, 2026 06:46
Copilot AI review requested due to automatic review settings June 3, 2026 06:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes the assistant message “⋯” action menu in ChatScreen by wiring the previously-missing callbacks into MessageList, ensuring the menu can open and handle user taps (currently via placeholder snackbars).

Changes:

  • Add _handleArchiveRound, _handleArchiveReply, and _handleMoveToThread handlers in ChatScreen.
  • Pass the new handlers to MessageList so _showAssistantMessageActionMenu no longer early-returns due to all-null callbacks.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}
}

void _handleArchiveRound(ChatMessage message) {
.showSnackBar(const SnackBar(content: Text('Coming soon')));
}

void _handleArchiveReply(ChatMessage message) {
.showSnackBar(const SnackBar(content: Text('Coming soon')));
}

void _handleMoveToThread(ChatMessage message) {
Copilot AI added 2 commits June 3, 2026 14:46
- Add migration 023: chat_thread_forks table for DB-level branching
- Backend: forkThread() service, listSessionMessagesForModel fork context assembly
- Backend: POST /fork endpoint
- Flutter: ChatForkResult + forkThread() API client method
- Flutter: MessageList - rename onMoveToThread→onFork, add onBranch/onResend, translate all labels to English
- Flutter: chat_screen.dart - implement _handleArchiveRound, _handleArchiveReply, _handleFork, _handleBranch, _handleResend
- Flutter: clear _archivedMessageIds at all _messages.clear() call sites
- Test: update message_list_test.dart for renamed onFork callback and Fork label
Copilot AI changed the title fix: wire assistant message action menu in ChatScreen feat: implement Fork thread branching, Archive, Branch, Resend, and English menu labels Jun 3, 2026
Copilot AI requested a review from crazygo June 3, 2026 14:48
@crazygo crazygo requested a review from Copilot June 4, 2026 02:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

if (msgResult.rows.length === 0) {
throw new Error(`Fork message not found: ${forkMessageId}`);
}
const forkWriteSeq = Number(msgResult.rows[0].write_seq);
Comment on lines +369 to +373
// Check if this session is a fork; if so, prepend parent context first.
const fork = await getThreadFork(userId, sessionId);

// Fetch own messages (newest-first so we can apply the char budget).
const ownResult = await pool.query<ChatMessageRow>(
Comment on lines +1846 to +1854
const body = req.body ?? {};
const parentSessionId = parseSessionId(body.parentSessionId);
const forkMessageId = parseSessionId(body.forkMessageId);
const newThreadId = parseSessionId(body.newThreadId);

if (!parentSessionId || !forkMessageId || !newThreadId) {
res.status(400).json({
error: "parentSessionId, forkMessageId, and newThreadId are required",
});
Comment on lines +21 to +22
CREATE INDEX IF NOT EXISTS idx_chat_thread_forks_forked_session
ON chat_thread_forks(user_id, forked_session_id);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants