Skip to content

feat: add regenerate button to re‑send last prompt#700

Open
hankkyy wants to merge 1 commit into
fathah:mainfrom
hankkyy:feat/regenerate-response
Open

feat: add regenerate button to re‑send last prompt#700
hankkyy wants to merge 1 commit into
fathah:mainfrom
hankkyy:feat/regenerate-response

Conversation

@hankkyy

@hankkyy hankkyy commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Feature

Add a 'Regenerate' button below the last agent response. Clicking it re-sends the last user message to get a new response from the agent, matching the common 'regenerate' pattern in AI chat apps.

Changes

MessageList.tsx

  • Added onRegenerate prop
  • New RegenerateBar component with RefreshCw icon and localized 'Regenerate' label
  • Shown when: not loading, last message is from agent, and at least one user message exists

Chat.tsx

  • Added handleRegenerate callback: finds the last user message and calls handleSendRef.current() with its content and attachments

main.css

  • .chat-regenerate-bar — thin bar below messages, aligned to the message column (margin-left: 42px to clear the avatar)
  • .chat-regenerate-btn — inline-flex button with border, hover effect

i18n

  • Added copyMessage and regenerate keys to all 10 supported locales

Behavior

  • After agent finishes responding, a 'Regenerate' button appears below the response
  • Click → re-sends the last user message → agent generates a fresh response
  • Not shown while loading or when no user message exists

Add a 'Regenerate' button below the last agent response so users can
re-run their last prompt without retyping.

Changes:
- MessageList: add onRegenerate prop + RegenerateBar component with
  RefreshCw icon, shown when agent has finished and a user message exists
- Chat: add handleRegenerate that finds the last user message and
  re-sends it via handleSendRef
- main.css: .chat-regenerate-bar + .chat-regenerate-btn styles
- i18n: add copyMessage and regenerate strings to all 10 locales
@greptile-apps

greptile-apps Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a "Regenerate" button below the last agent response that re-sends the last user message. The UI, CSS, and i18n wiring are clean, but the core regenerate logic has a correctness issue.

  • Chat.tsx: handleRegenerate calls handleSend, which always calls pushUser to append a new user bubble — so every regenerate adds a duplicate of the original user message to the transcript instead of reusing it.
  • MessageList.tsx: RegenerateBar component and showRegenerate visibility conditions are well-structured; a trailing newline was accidentally removed.
  • i18n: regenerate key added correctly across all 10 locales; copyMessage is also added but has no corresponding usage in this PR.

Confidence Score: 3/5

The regenerate button will visibly duplicate the user's message in the transcript on every click, making the conversation history incorrect.

The central behavior of the feature — re-sending without adding a redundant user bubble — is broken. handleSend unconditionally appends a new user message via pushUser, so the transcript grows incorrectly with each regenerate. The UI shell (button rendering, visibility logic, CSS, i18n) is solid, but the core callback needs to bypass pushUser before this can ship.

src/renderer/src/screens/Chat/Chat.tsx — specifically the handleRegenerate callback and how it interacts with handleSend/pushUser.

Important Files Changed

Filename Overview
src/renderer/src/screens/Chat/Chat.tsx Adds handleRegenerate, but it delegates to handleSend which calls pushUser internally — this appends a duplicate user bubble on every regenerate instead of reusing the existing one.
src/renderer/src/screens/Chat/MessageList.tsx Adds RegenerateBar component and showRegenerate logic; visibility conditions are correct. Minor: trailing newline was removed.
src/renderer/src/assets/main.css Adds clean CSS for .chat-regenerate-bar and .chat-regenerate-btn with appropriate design token usage.
src/shared/i18n/locales/en/chat.ts Adds regenerate (used) and copyMessage (unused in this PR) keys; the orphan key is shipped across all 10 locales.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant User
    participant MessageList
    participant Chat
    participant handleSend
    participant pushUser
    participant Agent

    Note over MessageList: isLoading=false, lastMessage=agent, hasUserMsg=true
    MessageList->>User: Show RegenerateBar
    User->>MessageList: Click Regenerate
    MessageList->>Chat: onRegenerate()
    Chat->>Chat: find lastUser message in messages[]
    Chat->>handleSend: handleSendRef.current(lastUser.content, attachments)
    handleSend->>pushUser: pushUser(text, "user", attachments)
    Note over pushUser: ⚠️ Appends NEW user bubble (duplicate)
    pushUser-->>Chat: messages updated with duplicate
    handleSend->>Agent: sendToAgent(text, attachments)
    Agent-->>Chat: new response streamed
    Chat-->>MessageList: messages updated
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant User
    participant MessageList
    participant Chat
    participant handleSend
    participant pushUser
    participant Agent

    Note over MessageList: isLoading=false, lastMessage=agent, hasUserMsg=true
    MessageList->>User: Show RegenerateBar
    User->>MessageList: Click Regenerate
    MessageList->>Chat: onRegenerate()
    Chat->>Chat: find lastUser message in messages[]
    Chat->>handleSend: handleSendRef.current(lastUser.content, attachments)
    handleSend->>pushUser: pushUser(text, "user", attachments)
    Note over pushUser: ⚠️ Appends NEW user bubble (duplicate)
    pushUser-->>Chat: messages updated with duplicate
    handleSend->>Agent: sendToAgent(text, attachments)
    Agent-->>Chat: new response streamed
    Chat-->>MessageList: messages updated
Loading

Reviews (1): Last reviewed commit: "feat: add regenerate button to re-send l..." | Re-trigger Greptile

Comment on lines +472 to +480
const handleRegenerate = useCallback(() => {
const lastUser = [...messages]
.reverse()
.find((m) => m.role === "user") as
| import("./types").ChatBubbleMessage
| undefined;
if (!lastUser?.content) return;
void handleSendRef.current(lastUser.content, lastUser.attachments || []);
}, [messages]);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Regenerate duplicates the last user message

handleRegenerate calls handleSendRef.current(...), which internally calls pushUser(text, "user", attachments) — that appends a brand-new user bubble to the messages array. As a result, every regenerate produces an extra copy of the original user message in the transcript: the conversation grows as […, user: "hello", agent: "resp1", user: "hello" (duplicate), agent: "resp2"].

The standard "regenerate" pattern strips the last agent turn (and optionally the duplicate user turn) before re-sending. At a minimum, handleSend should not push another user bubble when regenerating — consider passing sendToAgent directly, or adding a noUserBubble flag to handleSend/handleSendRef.

Comment on lines +135 to +136
copyMessage: "Copy message",
regenerate: "Regenerate",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 The copyMessage key is added here and to all 10 locale files, but there is no reference to t("chat.copyMessage") anywhere in the PR. Shipping unused i18n keys adds translation overhead without benefit; consider removing it if the copy-message feature is not yet implemented.

Suggested change
copyMessage: "Copy message",
regenerate: "Regenerate",
regenerate: "Regenerate",

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines 204 to +205
);
});
}); No newline at end of file

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Missing newline at end of file. The original file ended with a newline after });; this edit dropped it.

Suggested change
);
});
});
);
});

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

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.

1 participant