Skip to content

Conversation

@bzqzheng
Copy link
Contributor

@bzqzheng bzqzheng commented Aug 1, 2025

Add Message Editing Functionality

Overview

This PR introduces message editing, allowing users to revise their prior inputs and view regenerated AI responses. It enables iterative prompt refinement and A/B testing of message variations.

Key Features

  • Edit Button: Hover-to-reveal button on user messages
  • Inline Editing: Seamless textarea interface with smooth transitions
  • Save/Cancel: Save changes or discard edits with intuitive controls
  • Cmd+Enter Shortcut: Instantly saves and re-prompts the AI
  • AI Re-response: Triggers new AI response after edits
  • Message Pruning: Editing any message (e.g. message 2 of 5) prunes all subsequent messages
  • Visual Feedback: Loading indicators, edit mode, and “edited” labels
  • Context Preservation: Maintains coherent conversation flow after edit-triggered regeneration

References

  • Previous PR

Adds the ability for users to edit their messages directly in the chat view. When a message is edited, the conversation history is truncated and a new AI response is generated from the updated text.
@bzqzheng
Copy link
Contributor Author

bzqzheng commented Aug 1, 2025

Screenshot 2025-08-01 at 5 49 24 PM Goose UI in editing mode.

@zanesq zanesq self-requested a review August 1, 2025 22:47
@spencrmartin
Copy link
Collaborator

Can we eventually aim to just re-emulate the chat input section within this component? @zanesq I can add it to the backlog if you want to push out

@DOsinga
Copy link
Collaborator

DOsinga commented Aug 2, 2025

I like this. I wonder if we should prune though and not create a new conversation?

@bzqzheng
Copy link
Contributor Author

bzqzheng commented Aug 4, 2025

I like this. I wonder if we should prune though and not create a new conversation?

Can you clarify what you meant by "prune through" a conversation?
I may not haven' been clear in the PR description: when a message is edited and saved, all preceding messages are preserved, and all subsequent messages are deleted/pruned.
This differs slightly from ChatGPT's behavior, which preserves subsequent messages even after edits.

@DOsinga
Copy link
Collaborator

DOsinga commented Aug 4, 2025

yeah, I meant and alternative is to start a new conversation with the messages before and the new edited message -

Copy link
Collaborator

@zanesq zanesq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I tried it locally and was able to edit a previous message and continue.

// Create the new message with the edited content.
const updatedMessage = createUserMessage(newContent);

// Set the new history. This is a two-step process to ensure React state updates correctly.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of a two-step process with setTimout that can lead to race conditions can you try something like this instead?

import { useState, useCallback, useEffect } from 'react';

// Add state to track pending edited message
const [pendingEdit, setPendingEdit] = useState<{ id: string; content: string } | null>(null);

const onMessageUpdate = useCallback(
  (messageId: string, newContent: string) => {
    const messageIndex = messages.findIndex((msg) => msg.id === messageId);
    if (messageIndex !== -1) {
      // Truncate history up to the message to edit
      const history = messages.slice(0, messageIndex);
      setMessages(history);
      // Instead of setTimeout, set pendingEdit which will be handled in useEffect
      setPendingEdit({ id: messageId, content: newContent });
    }
  },
  [messages, setMessages]
);

// Listen for pending edit and append message after messages updated
useEffect(() => {
  if (pendingEdit) {
    const updatedMessage = createUserMessage(pendingEdit.content);
    append(updatedMessage);
    setPendingEdit(null); // Reset after processing
  }
}, [pendingEdit, append]);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated!

(messageId: string, newContent: string) => {
const messageIndex = messages.findIndex((msg) => msg.id === messageId);

if (messageIndex !== -1) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On edit all messages after (and including) the edited one are removed, and a new message is appended. Seems like some people might expect the following bot responses to still be there so we should warn of this destructive behavior (could be some small text at the bottom of the edit textarea?)

Copy link
Contributor Author

@bzqzheng bzqzheng Aug 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is actually the intended behavior and follows the (almost) same UX pattern used by ChatGPT and Grok.

  • ChatGPT/Grok also supports conversation branching; the latest branch will not have any messages after the edited message
  • Gemini only supports editing the latest message

The reasoning behind this approach is that editing a message fundamentally changes the context of the conversation, and the LLM's responses that followed the original message may not be relevant or accurate given the new context. By removing subsequent messages, we ensure the convo flows naturally from the edited point and prevents context confusion.

@jamadeo
Copy link
Collaborator

jamadeo commented Aug 14, 2025

Hey @bzqzheng , still interested in getting this in? Seems useful!

@bzqzheng
Copy link
Contributor Author

Hey @bzqzheng , still interested in getting this in? Seems useful!

yes, will update this PR this upcoming weekend.

@zanesq
Copy link
Collaborator

zanesq commented Aug 19, 2025

Thanks taking a look will pull in main also

@zanesq zanesq merged commit e5075ea into block:main Aug 19, 2025
10 checks passed
zanesq added a commit that referenced this pull request Aug 19, 2025
…npm-cacheing

* 'main' of github.com:block/goose:
  Unlist figma tutorial (#4186)
  feat(ui): Implement in-place message editing with re-response (#3798)
  Retry all 500 codes (#4160)
  blog: Transforming AI Assistance with Goose Mentor Mode (#4151)
  upgraded all npm packages and fixed related issues (#4072)
  Docs: @-mentions in goosehints (#4171)
  fix: consistent font sizing in ToolCallWithResponse (#4167)
  Temporarily disable TODO Tool (#4158)
  docs: add integrated MCP server config to jetbrains tutorial  (#4120)
  docs: remove figma MCP from suggested servers (#4123)
  Blog: The AI Skeptic’s Guide to Context Windows (#4152)
  Docs: Auto-compact context (#4116)
  chore(deps): bump brace-expansion from 1.1.11 to 1.1.12 in /documentation (#4149)
  Recipe config to limit tool availability (#4020)
  docs: fix warning message (#4148)
  feat: adds cursor-agent as a cli provider (#4101)
  chore: remove vector search tool selection strategy (#3933)
  docs: add streamable_http install links (#4130)
zanesq added a commit that referenced this pull request Aug 19, 2025
* 'main' of github.com:block/goose: (51 commits)
  Fix tests from upstream changes and add testing to lint staged and ci (#4127)
  Unlist figma tutorial (#4186)
  feat(ui): Implement in-place message editing with re-response (#3798)
  Retry all 500 codes (#4160)
  blog: Transforming AI Assistance with Goose Mentor Mode (#4151)
  upgraded all npm packages and fixed related issues (#4072)
  Docs: @-mentions in goosehints (#4171)
  fix: consistent font sizing in ToolCallWithResponse (#4167)
  Temporarily disable TODO Tool (#4158)
  docs: add integrated MCP server config to jetbrains tutorial  (#4120)
  docs: remove figma MCP from suggested servers (#4123)
  Blog: The AI Skeptic’s Guide to Context Windows (#4152)
  Docs: Auto-compact context (#4116)
  chore(deps): bump brace-expansion from 1.1.11 to 1.1.12 in /documentation (#4149)
  Recipe config to limit tool availability (#4020)
  docs: fix warning message (#4148)
  feat: adds cursor-agent as a cli provider (#4101)
  chore: remove vector search tool selection strategy (#3933)
  docs: add streamable_http install links (#4130)
  feat: iterating on summarize oneshot prompt (#4113)
  ...

# Conflicts:
#	ui/desktop/src/App.test.tsx
zanesq added a commit that referenced this pull request Aug 19, 2025
* 'main' of github.com:block/goose:
  Remove unused extension stuff (#4166)
  Added tests for extensions functionality (#3794)
  chore(release): release version 1.5.0 (#4169)
  Fix tests from upstream changes and add testing to lint staged and ci (#4127)
  Unlist figma tutorial (#4186)
  feat(ui): Implement in-place message editing with re-response (#3798)
zanesq added a commit that referenced this pull request Aug 19, 2025
…-visual-improvements

* 'main' of github.com:block/goose: (21 commits)
  Custom providers update (#4099)
  docs: goose_terminal env var (#4205)
  Desktop alerts when suspicious unicode characters found in Recipe (#4080)
  chore: remove the google drive built-in extension (#4187)
  Move out app init (#4185)
  Remove unused extension stuff (#4166)
  Added tests for extensions functionality (#3794)
  chore(release): release version 1.5.0 (#4169)
  Fix tests from upstream changes and add testing to lint staged and ci (#4127)
  Unlist figma tutorial (#4186)
  feat(ui): Implement in-place message editing with re-response (#3798)
  Retry all 500 codes (#4160)
  blog: Transforming AI Assistance with Goose Mentor Mode (#4151)
  upgraded all npm packages and fixed related issues (#4072)
  Docs: @-mentions in goosehints (#4171)
  fix: consistent font sizing in ToolCallWithResponse (#4167)
  Temporarily disable TODO Tool (#4158)
  docs: add integrated MCP server config to jetbrains tutorial  (#4120)
  docs: remove figma MCP from suggested servers (#4123)
  Blog: The AI Skeptic’s Guide to Context Windows (#4152)
  ...
ayax79 pushed a commit to ayax79/goose that referenced this pull request Aug 21, 2025
@alexhancock alexhancock mentioned this pull request Aug 22, 2025
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.

5 participants