8000 feat(chat): versions: regenerate, edit and switch in a conversation tree by adeelahmad · Pull Request #467 · adeelahmad/lense · GitHub
[go: up one dir, main page]

Skip to content

feat(chat): versions: regenerate, edit and switch in a conversation tree - #467

Merged
adeelahmad merged 1 commit into
mainfrom
claude/project-thread-r960xc-c2-versions
Oct 17, 2026
Merged

adeelahmad merged 1 commit into
mainfrom
claude/project-thread-r960xc-c2-versions

Conversation

@adeelahmad
Copy link
Copy Markdown
Owner

Requested by Adeel · project thread

Description

Before: a conversation was one line. Editing a question deleted it and everything after it, and "Ask again with" added the same question again at the end.

After: a conversation is a tree, and nothing in it is deleted. Through the API:

  • POST /api/v1/chats/{cid}/messages with regenerate: <answer id> writes a new answer to the same question beside the old one, with the same model or another (model).
  • edit: <question id> makes a new version of that question beside it and answers it. The old question keeps what followed it.
  • parent: <message id> goes on from any message instead of the version showing.
  • GET /api/v1/chats/{cid} gives the version showing as messages (same shape as before). Each message now carries parent and versions (index from 1, count, ids). The response also adds tree (every message of every version) and head.
  • PUT /api/v1/chats/{cid}/head {"message": id} switches to the version that message is in, down to its newest message.
  • The stream sends branch first when a new version is made.

The model reads only the version showing. A running summary covers the version it was written on. On another version the summary is ignored, and the next compaction writes one for that version. /clear and /compact act on the version they're typed on. Chat rooms and automations carry on from the head as before.

In the web app, Edit still looks the same: the new version shows in place of the old question. The switcher (‹ 2 / 3 ›) and the Regenerate button come in the next PR, and the docs label them as in progress.

How: chat_message.parent and chat.head hold the tree. chat.path walks the parents in Python after one query for the conversation's ids. chat.add saves under the head by default and moves the head. The upgrade step chat-tree turns existing conversations into one line each: every message gets the one before it as its parent, and the last becomes the head. It only touches conversations without a head, so it is safe to run twice. Until it has run, a conversation without a head is still read as one line.

Motivation and Context

Part of the chat gaps Adeel listed: regenerate, a response tree, and carrying on from any version. This is module C2 of the plan, backend part.

Screenshots (if appropriate):

n/a (API only; the web app's switcher is the next PR)

Steps to reproduce (if appropriate):

  1. Ask two questions in a conversation.
  2. POST /api/v1/chats/{cid}/messages {"regenerate": <first answer id>, "model": "<another model>"}. You get a branch event and then the new answer.
  3. GET /api/v1/chats/{cid}. The first answer now shows versions: {index: 2, count: 2}, and tree holds all 5 messages.
  4. PUT /api/v1/chats/{cid}/head {"message": <first answer id>} shows the first version again, down to its last answer.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change; ! in the title)

Checklist:

  • The title is a Conventional Commit.
  • My code follows the code style of this project (make hooks checks it on commit).
  • I added or updated tests.
  • My change requires documentation updates, and I have updated docs/ accordingly.
  • Users need more than the title to understand it, so I wrote it under ## Unreleased in CHANGELOG.md.

Done questions (AGENTS.md)

  • Goal: delivers what the user wanted, merged on green CI. The backend and API are done here. The web app's switcher and Regenerate button are the next PR.
  • Agents: everything goes through the API (regenerate, edit, parent, PUT /chats/{cid}/head, tree and versions in GET). C3's read_chat MCP tool will return the tree.
  • Zero setup: nothing to set up. Existing conversations upgrade on the next start.
  • Fewest clicks and keystrokes: nothing is deleted, so nothing needs confirming. Switching is one call.
  • Configurable: n/a, there are no new settings.
  • Light: n/a, no new dependency. Walking the tree is one query and a loop in Python.
  • Private and secure: conversations stay their owner's. parent, regenerate, edit and the head must be messages of that conversation, otherwise 404. There is no new attack surface, so the threat model is unchanged.
  • Cost: a regenerate is one more answer, logged like any other. Nothing else calls a model. A summary is rewritten only when a version leaves what it covers.
  • User decides: defaults are unchanged. Asking without the new fields goes on from the head, as before.
  • Upgrades: the upgrade step chat-tree is safe to run twice and tested twice. Reads stay right before it runs (docs/database.md › Upgrades).
  • Honest: the docs say the web app's switcher and Regenerate are in progress.
  • Tests, docs and generated files updated: test_chat_versions.py, plus updates to the compaction, chats and migrations tests. docs/assistant.md › Versions and docs/database.md › Upgrades are updated, and the client was regenerated with tooling.
  • Open standards: n/a, no new dependency.
  • Result reported with evidence; "refine later" items written down: deleting or naming a version, side-by-side compare, versions as preference pairs for fine-tuning, and keeping one summary per version so switching back doesn't rewrite it.

Generated by Claude Code

A conversation is now a tree: chat_message.parent and chat.head. Regenerate
writes a new answer beside the old one, edit makes a new version of a question
beside it instead of deleting what followed, and parent goes on from any
message. GET /chats/{cid} adds tree, head and each message's versions; PUT
/chats/{cid}/head switches. The model reads only the version showing; a
summary written on another version is ignored and rewritten for this one.
Upgrade step chat-tree lines existing conversations up, safe to run twice.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HXPWXcSCQb9hWPr7xkZu7B
@adeelahmad adeelahmad self-assigned this Oct 16, 2026
@adeelahmad
adeelahmad merged commit ab3f945 into main Oct 17, 2026
10 checks passed
@adeelahmad
adeelahmad deleted the claude/project-thread-r960xc-c2-versions branch October 17, 2026 00:11
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.

2 participants

0