Skip to content

fix: restrict token deletion to agents, subcommands, and tools#305888

Closed
swematheus wants to merge 6 commits intomicrosoft:mainfrom
swematheus:main
Closed

fix: restrict token deletion to agents, subcommands, and tools#305888
swematheus wants to merge 6 commits intomicrosoft:mainfrom
swematheus:main

Conversation

@swematheus
Copy link
Copy Markdown

This PR fixes the issue reported in #305366 by extracting the token deletion filtering logic into a new helper function isDeletableToken. This function identifies deletable tokens as ChatRequestAgentPart, ChatRequestAgentSubcommandPart, and ChatRequestToolPart, centralizing the logic for better maintainability and ensuring consistent behavior during chat input editing.

Previously, slash commands were deleted as whole tokens, which could be disruptive, now they behave like regular text, deleting character by character.

To test: Run the project. Open a chat, type any commands starting with / and press backspace. You'll see that now we delete char by char instead of the whole command.

Copilot AI review requested due to automatic review settings April 2, 2026 13:14
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adjusts chat input backspace behavior so that only agent, agent-subcommand, and tool parts are treated as atomic “tokens” for deletion, preventing standalone slash commands/prompts from being deleted as a whole.

Changes:

  • Introduces an isDeletableToken helper to centralize which parsed parts should be deleted atomically.
  • Updates ChatTokenDeleter to use the helper, excluding slash command/prompt parts from token deletion behavior.

Comment on lines 485 to 489
const previousParsedValue = parser.parseChatRequestWithReferences(getDynamicVariablesForWidget(this.widget), getSelectedToolAndToolSetsForWidget(this.widget), previousInputValue, this.widget.location, { selectedAgent: previousSelectedAgent, mode: this.widget.input.currentModeKind, attachmentCapabilities });

// For dynamic variables, this has to happen in ChatDynamicVariableModel with the other bookkeeping
const deletableTokens = previousParsedValue.parts.filter(p => p instanceof ChatRequestAgentPart || p instanceof ChatRequestAgentSubcommandPart || p instanceof ChatRequestSlashCommandPart || p instanceof ChatRequestSlashPromptPart || p instanceof ChatRequestToolPart);
const deletableTokens = previousParsedValue.parts.filter(isDeletableToken);
deletableTokens.forEach(token => {
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

The token-deletion behavior is being changed (slash commands/prompts are no longer treated as atomic tokens for backspace), but there’s no automated coverage to prevent regressions. Consider adding a browser unit test that instantiates a chat input editor and verifies: (1) backspace inside /con deletes a single character rather than removing the whole token, and (2) backspace over agent/subcommand/tool tokens still deletes the whole token.

Copilot uses AI. Check for mistakes.
@swematheus swematheus closed this Apr 3, 2026
@swematheus swematheus reopened this Apr 3, 2026
@swematheus swematheus closed this Apr 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants