Conversation
Message Branches
Switch between regenerated answers and edited prompts — arrows, a mini branch map, and direction-aware swaps.
2 variantsMIT
Preview
Cache resized images by content hash in
.pressd/cache. On each build, hash the source file and the resize options; if the key exists, copy the cached output instead of running sharp again.1 / 1
Original · sonnet-5.5Version 1 of 1, Original
Installation
Copies the component into components/ui and installs its dependencies and theme tokens.
pnpm dlx shadcn@latest add https://tuffui.com/r/message-branches.jsonUsage
Pass your own data and wire the callbacks to your agent runtime.
import { useState } from "react";
import { MessageBranches } from "@/components/ui/message-branches";
export function AssistantTurn({ turn }: { turn: Turn }) {
const [index, setIndex] = useState(turn.versions.length - 1);
return (
<MessageBranches
data={{
turnsBefore: turn.position,
versions: turn.versions.map((v) => ({
id: v.id,
kind: v.editedPrompt ? "edited" : v.parentId ? "regenerated" : "original",
prompt: v.editedPrompt,
meta: v.model,
turnsAfter: v.followUps,
content: <Markdown>{v.text}</Markdown>,
})),
}}
index={index}
onIndexChange={(next, version) => {
setIndex(next);
thread.checkout(version.id); // later turns follow the chosen branch
}}
onRegenerate={() => thread.regenerate(turn.id)}
/>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
| data* | { versions: MessageVersion[]; turnsBefore?: number } | — | Every version of this answer, oldest first. `turnsBefore` is how many turns precede the fork, drawn as dots in the map. |
| index | number | — | Controlled index of the visible version. Leave it out to let the component track it. |
| defaultIndex | number | last version | Initial version when uncontrolled. |
| onIndexChange | (index: number, version: MessageVersion) => void | — | Called when the user switches with the arrows, the map or ←/→. Switch the thread to that branch here. |
| onRegenerate | () => void | — | Shows a regenerate button next to the switcher. |
| variant | "inline" | "map" | "inline" | A ‹ 2 / 3 › switcher under the message, or a branch map with one row per version. |
| className | string | — | Extra classes for the root element. |
type MessageVersion = {
id: string;
kind: "original" | "regenerated" | "edited";
content: ReactNode;
label?: string; // overrides "Original" / "Regenerated" / "Edited prompt"
meta?: string; // e.g. the model, "opus-5.5"
prompt?: string; // the edited prompt, for kind "edited"
turnsAfter?: number; // follow-up turns on this branch, for the map
};