Skip to content

fix(agent): prevent session context poisoning on interrupted turns - #29265

Open
rahuldevlab wants to merge 2 commits into
google-gemini:mainfrom
rahuldevlab:fix/clean-interrupted-agent-turns
Open

fix(agent): prevent session context poisoning on interrupted turns#29265
rahuldevlab wants to merge 2 commits into
google-gemini:mainfrom
rahuldevlab:fix/clean-interrupted-agent-turns

Conversation

@rahuldevlab

Copy link
Copy Markdown

Summary

This PR resolves a critical issue where interrupting an agentic stream (via SIGINT, timeout, or aborted tool executions) poisons the active chat session history and breaks subsequent prompt execution.

Details

  • The Issue: When an active model generation or tool execution is interrupted, closeUnansweredToolResponseTurn() appends [The previous response was interrupted before it completed.] (defined as INTERRUPTED_RESPONSE_PLACEHOLDER) to the history to close the dangling turn and prevent adjacent user turns from coalescing (which would otherwise fuse user chat input into previous tool responses, violating API turn invariants). However, sending this synthetic placeholder to the model in subsequent prompts causes severe context poisoning—the model treats it as a few-shot completion pattern and parrots it back, breaking the agentic loop.
  • The Solution: In packages/core/src/core/geminiChat.ts's extractCuratedHistory (which compiles the history payload sent to the Gemini API), any model turns containing INTERRUPTED_RESPONSE_PLACEHOLDER are intercepted and mapped to a benign model turn "Continuing.".
    • For the User: The UI still records and displays the clear warning notification: ✦ [The previous response was interrupted before it completed.].
    • For the Model: The model only sees a natural "Continuing." transition. If it mimics this phrase in its next response, it is perfectly harmless and does not disrupt the loop.

Related Issues

Closes #29264

How to Validate

  1. Run a tool-calling prompt (e.g. search the codebase for all API handlers).
  2. Trigger an interruption (SIGINT/Ctrl+C or abort). The CLI outputs the warning nicely.
  3. Submit a subsequent prompt (e.g. list files). The agent now executes and completes normally instead of outputting ✦ [The previous response was interrupted before it completed.].
  4. Run vitest: npm test -w @google/gemini-cli-core -- src/core/geminiChat.test.ts. All tests (including the new suite covering mapped interruption placeholders) pass with 100% success.

Pre-Merge Checklist

  • Added/updated tests (if needed)
  • Validated on required platforms/methods:
    • Windows
      • npm run

@rahuldevlab
rahuldevlab requested a review from a team as a code owner September 9, 2026 07:10
@google-cla

google-cla Bot commented Sep 9, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@github-actions github-actions Bot added the size/m A medium sized PR label Sep 9, 2026
@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown

📊 PR Size: size/M

  • Lines changed: 69
  • Additions: +67
  • Deletions: -2
  • Files changed: 2

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical issue where interrupting an agentic stream caused the model to receive an interruption warning in its context window, leading to 'context poisoning' where the model would repeat the warning in subsequent turns. By intercepting these placeholders during history compilation and mapping them to a neutral transition phrase, the agent can now recover gracefully from interruptions without disrupting the chat loop.

Highlights

  • Context Poisoning Prevention: Modified the history extraction logic to replace the 'INTERRUPTED_RESPONSE_PLACEHOLDER' with a benign 'Continuing.' message when sending chat history to the Gemini API.
  • Turn Integrity: Ensured that interrupted turns are still correctly closed to prevent turn fusion, while simultaneously avoiding the model's tendency to parrot the interruption warning.
  • Test Coverage: Added a new test suite in 'geminiChat.test.ts' to verify that interruption placeholders are correctly mapped and that the resulting chat history maintains the expected turn structure.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

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.

Code Review

This pull request introduces interruption handling in getHistoryTurns within packages/core/src/core/geminiChat.ts by replacing INTERRUPTED_RESPONSE_PLACEHOLDER with a benign 'Continuing.' message in the curated history, preventing turn fusion and poisoning. A corresponding unit test has been added to verify this behavior. The review feedback highlights a potential runtime TypeError where part could be undefined when accessing part.text, and suggests using optional chaining (part?.text) to safely handle these cases.

Comment thread packages/core/src/core/geminiChat.ts
@gemini-cli gemini-cli Bot added priority/p2 Important but can be addressed in a future release. area/agent Issues related to Core Agent, Tools, Memory, Sub-Agents, Hooks, Agent Quality labels Sep 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/agent Issues related to Core Agent, Tools, Memory, Sub-Agents, Hooks, Agent Quality priority/p2 Important but can be addressed in a future release. size/m A medium sized PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(agent): prevent session context poisoning and infinite loops on interrupted turns

1 participant