Skip to content

[enhancement] Add side-effect-aware regeneration for the latest assistant response #21

Description

@lyrishark

Regenerate the latest assistant response without retaining poisoned context

Date: 2026-06-19
Status: Patched and verified locally; raised upstream for review

Suggested title:

[enhancement] Add side-effect-aware regeneration for the latest assistant response

Summary

Psycheros lets users edit a message, but editing does not rerun the turn or
remove the existing assistant response from active conversation context. When
an assistant response contains fabricated tool results or otherwise poisons
later context, the user currently has to start a new conversation to recover.

The local patch adds a Regenerate response action to the latest assistant
message. It preserves the latest user message and attachments, archives the
assistant/tool trace being replaced, clears its derived embeddings, metrics,
and context snapshots, then reuses the existing retry stream to generate a new
response in place.

Safety boundary

Tool effects are not generally reversible. Regeneration is therefore allowed
only when the replaced turn has no tools or uses known read-only tools. It is
refused for unknown or mutating tools, including memory writes, identity
changes, shell commands, image generation, Discord actions, and device actions.

The confirmation also states that external tool effects and memories already
consolidated outside the conversation database cannot be undone.

Local patch

  • Add message_revisions as an audit/recovery store for superseded rows.
  • Add a transactional database operation that validates the target is the
    latest assistant response, classifies tool calls, archives the replaced
    assistant/tool rows, removes derived records, and retains the user turn.
  • Extend POST /api/chat/retry with an optional assistantMessageId.
  • Add a latest-only circular-arrow action to server-rendered and streamed
    assistant messages.
  • Keep the old response visible when the server rejects regeneration.
  • Prevent paginated historical batches from rendering a regenerate action.
  • Keep message actions visible at mobile widths and hide regeneration while a
    replacement is streaming.

Files

  • packages/psycheros/src/db/schema.ts
  • packages/psycheros/src/db/client.ts
  • packages/psycheros/src/server/routes.ts
  • packages/psycheros/src/server/templates.ts
  • packages/psycheros/web/css/components.css
  • packages/psycheros/web/js/psycheros.js
  • packages/psycheros/tests/message_regeneration_test.ts

Verification

  • Focused suite: 24 passed, 0 failed.
  • Type checks and formatting checks passed.
  • Live Windows daemon restarted and returned HTTP 200 from /health.
  • Live regeneration archived the superseded assistant row while preserving the
    user turn, streamed a replacement, completed a real image tool call, and left
    exactly one regenerate action on the latest assistant response.
  • Desktop and 390px mobile browser checks found no horizontal overflow or
    console errors.

Upstream questions

  • Should consolidated entity-core memories eventually carry source-message
    lineage so a regeneration can retract unconsolidated or reviewable memory
    candidates precisely?
  • Should an archived revision restore action be exposed in the UI, or remain an
    audit/recovery mechanism only?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions