- Accueil
- Plugins
- Sessions et messages
- dsh-conversation-retry
dsh-conversation-retry
zhao0335/dsh-conversation-retry
Edits a message you already sent and re-runs from that point by forking the session, and retries a completed turn, in the DeepSeek Harness Web UI.
Installer
dsh plugin --profile web add github:zhao0335/dsh-conversation-retryREADME
dsh-conversation-retry
Edit a message you already sent and re-run from there — plus retry a turn — in the DeepSeek Harness Web UI.
The stock Harness only lets you append another message when something goes wrong. A prompt you already sent is frozen: the bad answer stays in the history and keeps costing context. This plugin makes the conversation editable.
| Action | Where | What it does |
|---|---|---|
| Edit | on your own message | Rewrite a prompt you already sent and re-run from that point. |
| Retry | in the assistant action strip | Re-send the turn's prompt unchanged and let the model answer again. |
Both actions produce a real, separate session: nothing is rewritten in place and nothing is lost. The original conversation is untouched, and the new branch appears in the sidebar like any other session.
Branching a turn is not part of this plugin — the Chat footer already ships a branch button, so there is nothing to add.
Why forks instead of in-place rewriting
A Harness session is an append-only event log — that is what makes replay, inspection, and export trustworthy. Deleting the tail of a log would break that guarantee, so "edit and re-run" is expressed as a fork of an exact event-sequence prefix: the child is a complete, self-contained session whose history ends just before the message you edited. This is the same primitive the sidebar's Fork session action uses, cut at message granularity instead of at the session's end.
That also means an edit is non-destructive: the branch you abandoned is still there if you want it back.
Install
dsh plugin --profile web add github:Zhao0335/dsh-conversation-retry
Then reload the Web UI once so the browser picks up the new client module.
To install from a local checkout instead, point the Harness at the directory:
plugin_manager install_bundle target: <absolute path to this directory>
Requirements: a Harness build that exposes ctx.sessions.fork with an atSeq
boundary, the conversation.chat.user.before chain slot, and the
conversation.chat.assistant-actions slot (0.2.x and later).
Usage
Edit a message. Hover one of your own messages; a pencil button appears
beside it. Click it and the message opens in a dialog, pre-filled. Change it and
press Fork and send (Ctrl/Cmd+Enter). A new session opens with the
edited prompt already running; everything before that message is carried over,
and the old answer and everything after it are gone from the new history.
Retry a turn. The retry button sits in the assistant message's own action strip, next to copy and branch, and uses the same 28px geometry, tertiary colour, and hover treatment as the shipped buttons. It re-asks the turn's prompt on a history without that turn.
The child session inherits the title with an incremented suffix, so branches of the same conversation stay recognisable in the sidebar.
How it works
conversation.chat.user.before— a chain slot rendered inside the user row. Its selector elects the entry only for rows whose durable message source carries a browser prompt identity (source.rpcId), so only messages you actually typed get the pencil; synthetic context injections do not. Placement needs one subtlety: the user row stacks its children in a column (message-source seat, bubble, action row), and every slot render sits in adisplay: contentswrapper. The row is therefore reached through that wrapper's stabledata-slotattribute, the control leaves the column flow, and the shipped action row reserves its width — which is what puts the pencil on the copy icon's line instead of on a row of its own.conversation.chat.assistant-actions— the shipped action strip. The entry's component renders inside it, so the retry button inherits the row's layout and hover behaviour. It maps itsmessageIdback to the owning turn throughuseChatand that turn'sturn-taildata.- The edit affordance resolves its message through a per-session index of
rpcId→ sequence and text, rebuilt only when the published event-window revision moves. Scanning the log once per rendered row would make a long conversation quadratic in its own history. shell.overlay— the frame-wide layer that hosts the single edit dialog. The open edit target lives in a small module-level store shared by both entries.ctx.sessions.fork({ sessionId, atSeq })— cuts an exact inclusive prefix. Edit forks atuserMessage.seq - 1; retry forks atturnStart.seq - 1.ctx.sessions.using(childId, …)→SessionBinding.session.prompt([…], 'queue')— sends the prompt into the child once its initial open settles.ctx.uiWorkspace.openSession(childId)— retains the child as the main view (so it outlives the plugin's own reference) and navigates to it.
The Host half is an empty apply(); the whole feature is browser-side.
Limitations
- Retry re-sends the turn's first user message. A turn opened by a synthetic context injection (goal continuation, file-change notice) will re-send that injected text rather than a human prompt.
- Edit is offered only for messages whose source carries an
rpcId— prompts submitted from this browser. Messages restored from an older log format without that identity are not editable. - Messages whose events have scrolled out of the loaded history are skipped; the buttons are hidden for them.
- Attachments are not carried over — the prompt is re-sent as text.
License
MIT — see LICENSE.
Plugins associés
billion-context
ranxianglei/billion-context
dsh-web-ui (dsh-chat-recovery)
zhu1090093659/dsh-web-ui
dsh-synapse
liangmianya/dsh-synapse
dsh-archive-manager
michengai/dsh-archive-manager