Skip to content

feat: add /undo slash command and keep replay in sync#277

Merged
kermanx merged 10 commits into
mainfrom
feat/undo-command
Jun 2, 2026
Merged

feat: add /undo slash command and keep replay in sync#277
kermanx merged 10 commits into
mainfrom
feat/undo-command

Conversation

@kermanx
Copy link
Copy Markdown
Collaborator

@kermanx kermanx commented Jun 1, 2026

Related Issue

N/A – this is a quick feature/fix combination.

Problem

  1. Users need a way to withdraw the last prompt from the conversation history without clearing the entire session.
  2. When a prompt is undone, the replay builder was not notified, so session resume would still render the removed messages in the TUI timeline.

What changed

  • Added /undo slash command (apps/kimi-code) that pops the last user prompt and its subsequent assistant/tool exchange from the transcript.
  • Added ReplayBuilder.removeLastMessages (packages/agent-core) so the replay record set can be trimmed to match the undone history.
  • Wired ContextMemory.undo to call the new replay-builder method, keeping in-memory history and replay records consistent.
  • Added a resume test that replays persisted records containing context.undo and asserts both context history and replay messages are correctly trimmed.

Checklist

  • I have read the CONTRIBUTING document.
  • I have explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Jun 1, 2026

🦋 Changeset detected

Latest commit: fd6bd63

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@moonshot-ai/agent-core Minor
@moonshot-ai/kimi-code Minor
@moonshot-ai/migration-legacy Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Jun 1, 2026

pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@fd6bd63
npx https://pkg.pr.new/@moonshot-ai/kimi-code@fd6bd63

commit: fd6bd63

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4c373a7819

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +93 to +95
if (message.role === 'user') {
removedUserCount++;
if (removedUserCount >= count) break;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Count only real user prompts when undoing

When a non-user-origin role: 'user' message is at the end of history, such as a background task completion notification appended with origin.kind === 'background_task', this condition treats it as the prompt to undo and stops before removing the actual last visible user prompt. The TUI removes the last TranscriptEntry with kind === 'user', so after /undo in that scenario the prompt disappears from the transcript but remains in the model context and persisted history.

Useful? React with 👍 / 👎.

Comment thread packages/agent-core/src/agent/replay/index.ts Outdated
Comment thread apps/kimi-code/src/tui/kimi-tui.ts Outdated
Comment on lines +912 to +913
const entries = this.state.transcriptEntries;
const lastUserIndex = entries.findLastIndex((e) => e.kind === 'user');
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Treat skill activations as undoable turns

When the last turn was a user-slash skill activation, the transcript entry is kind: 'skill_activation', not kind: 'user', so this search either reports “Nothing to undo” or selects an earlier prompt. In the latter case the TUI removes the earlier prompt while core context.undo(1) removes the skill activation from history, leaving the visible transcript and model context out of sync.

Useful? React with 👍 / 👎.

Comment thread packages/agent-core/src/agent/index.ts
Comment thread .changeset/feat-undo-command.md
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 421adaf23d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/kimi-code/src/tui/kimi-tui.ts Outdated

this.state.ui.requestRender();

void session.undoHistory(1);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Handle undo RPC failures before mutating the transcript

If session.undoHistory(1) rejects here (for example because the core/session RPC is gone or persistence fails), the TUI has already spliced the visible transcript and requested a render, while the core context and persisted history still contain the prompt. Other send paths attach a .catch(...) and call failSessionRequest/show an error; this path leaves the UI and model history out of sync with no user-visible failure.

Useful? React with 👍 / 👎.

Comment on lines +107 to +108
undoHistory({ agentId, ...payload }: AgentScopedPayload<UndoHistoryPayload>) {
return this.getAgent(agentId).undoHistory(payload);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Refresh session metadata after undoing main-agent prompts

When /undo removes a main-agent prompt, this method only forwards to the agent and never mirrors the metadata maintenance done by prompt()/activateSkill(). After undoing the last or only prompt, SessionMeta.lastPrompt (and the auto-generated title for an untitled session) can still point at text that is no longer in context, so the session picker/continued session metadata advertises an undone prompt.

Useful? React with 👍 / 👎.


this.agent.replayBuilder.removeLastMessages(removedCount);

this.openSteps.clear();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reset injection bookkeeping after removing injected reminders

When the undone turn contained dynamic injections added in beforeStep (for example plugin session-start, plan-mode, or auto-permission reminders), this loop removes those origin.kind === 'injection' messages from history but leaves each injector's bookkeeping untouched. On the next turn the injectors can still think the reminder exists (or that the permission mode was already announced), so the model proceeds without required session/plan/permission instructions that were just removed from context.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5e0675eac7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

'context.append_loop_event': { event: LoopRecordedEvent };
'context.clear': {};
'context.apply_compaction': CompactionResult;
'context.undo': { count: number };
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Apply undo records in the vis context projector

When sessions containing this new persisted context.undo record are opened in the visual debugger, apps/vis/server/src/lib/context-projector.ts still falls through default for this record type (I checked the switch: it handles append/clear/apply_compaction but not undo). As a result, the projected context shown by the vis /context endpoint keeps prompts and assistant/tool messages that agent-core removed during replay, so debugging an undone session displays stale conversation state.

Useful? React with 👍 / 👎.

Comment thread packages/agent-core/src/agent/context/index.ts
Comment thread packages/agent-core/src/agent/context/index.ts
@kermanx
Copy link
Copy Markdown
Collaborator Author

kermanx commented Jun 1, 2026

@codex

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5e0675eac7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/agent-core/src/agent/context/index.ts
Comment thread apps/kimi-code/src/tui/kimi-tui.ts Outdated
Comment thread apps/kimi-code/src/tui/kimi-tui.ts Outdated
Comment thread packages/agent-core/src/agent/index.ts
Comment thread packages/agent-core/src/agent/context/index.ts
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e296ec1dad

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/agent-core/src/agent/context/index.ts
Comment thread apps/kimi-code/src/tui/kimi-tui.ts Outdated
Comment thread packages/agent-core/src/agent/context/index.ts
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2ebc40722c

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/kimi-code/src/tui/commands/undo.ts
Comment thread apps/kimi-code/src/tui/commands/undo.ts
@kermanx kermanx merged commit a217ff0 into main Jun 2, 2026
8 checks passed
@kermanx kermanx deleted the feat/undo-command branch June 2, 2026 04:49
@github-actions github-actions Bot mentioned this pull request Jun 2, 2026
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