retry a turn the agent restart cut off

the cut-off notice is its own event now rather than an error: nothing is broken
and nothing is lost but the turn, so the row says what happened and offers the
one action that fixes it. the conversation is already durable — the claude
session id is written through to disk and passed back as resume: — so retry
just resends the prompt on a session the fresh agent picks up with full
context. read back out of the transcript, so a second window on the same
session can offer it too.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-07 02:00:16 +00:00
co-authored by Claude Opus 5
parent 876b39b301
commit 66fca28927
7 changed files with 83 additions and 10 deletions
+6
View File
@@ -156,6 +156,12 @@ export type ServerMessage =
| {
type: 'stopped';
}
| {
// The agent process went away mid-turn (almost always `pm2 restart officer-agent`). Its own type
// rather than an `error` because it is recoverable and the recovery is one click: the conversation
// is on disk and the next turn resumes it, so the UI offers to send the same prompt again.
type: 'cut-off';
}
| {
// Ack for a client 'disconnect': the session was torn down server-side.
type: 'disconnected';
+1 -4
View File
@@ -622,10 +622,7 @@ async function endTurnIfAgentIsGone(
const session = sessionManager.getSession(sessionId);
if (session) session.isGenerating = false;
const event: ServerMessage = {
type: 'error',
message: 'The agent restarted while this turn was running, so it was cut off. The conversation is intact.',
};
const event: ServerMessage = { type: 'cut-off' };
try {
const seq = await appendChatEvent(sessionId, event);
sendToClient(ws, event, seq);