Skip to content

Save transcript to file before function call is performed#17996

Closed
laurentsimon wants to merge 3 commits intogoogle-gemini:mainfrom
laurentsimon:feat/hook-transcript
Closed

Save transcript to file before function call is performed#17996
laurentsimon wants to merge 3 commits intogoogle-gemini:mainfrom
laurentsimon:feat/hook-transcript

Conversation

@laurentsimon
Copy link
Contributor

Summary

This PR closes #17922.

It flushes transcript to disk to ensure it's available in a BeforeTool hook.

Details

Before this PR, transcript contains:

{
  "messages": [
    {
      "type": "user",
      "content": "analyze code test.py"
    }
  ]
}

After this PR:

{
   "messages": [
      {
       "type": "user",
       "content": "analyze code test.py"
      },
      {
       "type": "gemini",
       "content": "I'm calling the function...",
       "thoughts": [
        {
          "subject": "Initiating Code Exploration",
          "description": "I'm starting by examining the code located at `test.py`. My immediate plan is to use the `read_file` tool. This will help me acquire the content of the file so I can provide a comprehensive explanation.",
        }
       ]
     }
  ]
}

Related Issues

How to Validate

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
      • npm run
      • npx
      • Docker
    • Linux
      • npm run
      • npx
      • Docker

@laurentsimon laurentsimon requested a review from a team as a code owner January 30, 2026 21:44
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @laurentsimon, 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 an issue where the chat transcript might not be fully available to BeforeTool hooks, particularly when the Gemini model provides internal 'thoughts' alongside or instead of direct text responses. By modifying the GeminiChat logic, it now explicitly tracks and records these 'thoughts' to the transcript, ensuring a complete and accurate record is persisted to disk before any subsequent tool executions.

Highlights

  • Transcript Persistence: The pull request ensures that the full chat transcript, including the Gemini model's internal 'thoughts', is flushed to disk before any function calls are performed. This guarantees that BeforeTool hooks have access to the complete interaction history.
  • New hasThoughts Flag: A new boolean flag, hasThoughts, has been introduced in GeminiChat to explicitly track whether a model's streamed response contains 'thought' parts.
  • Updated Transcript Recording Logic: The condition for recording model responses to the chat transcript has been updated. Messages are now recorded if they contain either explicit responseText or if the hasThoughts flag is true, ensuring 'thoughts' are always captured.
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 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 counter productive. 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.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

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.

Copy link
Contributor

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

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 updates the chat recording logic to save the transcript to a file even when the model's response contains only thoughts and no text, which is useful for BeforeTool hooks. The changes involve adding a hasThoughts flag that is checked before recording the message.

My main feedback is regarding a redundant check for thoughts being added, which could be consolidated with an existing check to improve efficiency and maintainability. Otherwise, the logic seems correct and addresses the intended issue.

@gemini-cli gemini-cli bot added the area/agent Issues related to Core Agent, Tools, Memory, Sub-Agents, Hooks, Agent Quality label Jan 30, 2026
@gemini-cli
Copy link
Contributor

gemini-cli bot commented Jan 31, 2026

Hi there! Thank you for your contribution to Gemini CLI. We really appreciate the time and effort you've put into this pull request.

To keep our backlog manageable and ensure we're focusing on current priorities, we are closing pull requests that haven't seen maintainer activity for 30 days. Currently, the team is prioritizing work associated with 🔒 maintainer only or help wanted issues.

If you believe this change is still critical, please feel free to comment with updated details. Otherwise, we encourage contributors to focus on open issues labeled as help wanted. Thank you for your understanding!

@gemini-cli gemini-cli bot closed this Jan 31, 2026
@bdmorgan bdmorgan added help wanted We will accept PRs from all issues marked as "help wanted". Thanks for your support! priority/p1 Important and should be addressed in the near term. labels Jan 31, 2026
@bdmorgan bdmorgan reopened this Jan 31, 2026
@bdmorgan
Copy link
Collaborator

Fixes #17922

@laurentsimon
Copy link
Contributor Author

Hi there! Thank you for your contribution to Gemini CLI. We really appreciate the time and effort you've put into this pull request.

To keep our backlog manageable and ensure we're focusing on current priorities, we are closing pull requests that haven't seen maintainer activity for 30 days. Currently, the team is prioritizing work associated with 🔒 maintainer only or help wanted issues.

If you believe this change is still critical, please feel free to comment with updated details. Otherwise, we encourage contributors to focus on open issues labeled as help wanted. Thank you for your understanding!

yes this change is "critical"

@theshloksschauhan
Copy link

theshloksschauhan commented Feb 23, 2026 via email

@laurentsimon
Copy link
Contributor Author

@theshloksschauhan
where is your code? How does it differ from this PR?

@theshloksschauhan
Copy link

theshloksschauhan commented Feb 23, 2026 via email

@krishdef7
Copy link
Contributor

Hi @bdmorgan @laurentsimon,

This change looks useful, especially for ensuring BeforeTool hooks have access to the latest transcript state.

One thing I was thinking about while reading this — currently the flush happens when handling model output (including thoughts). For cases where tool calls are triggered asynchronously, would it make sense to explicitly flush the transcript at the point where a tool call is dispatched as well?

That could ensure consistency even when execution paths diverge (e.g., streaming responses vs tool-triggered execution).

Happy to explore this further or help test edge cases if useful.

Thanks!
Krish

@laurentsimon
Copy link
Contributor Author

Hi @bdmorgan @laurentsimon,

This change looks useful, especially for ensuring BeforeTool hooks have access to the latest transcript state.

One thing I was thinking about while reading this — currently the flush happens when handling model output (including thoughts). For cases where tool calls are triggered asynchronously, would it make sense to explicitly flush the transcript at the point where a tool call is dispatched as well?

That could ensure consistency even when execution paths diverge (e.g., streaming responses vs tool-triggered execution).

Happy to explore this further or help test edge cases if useful.

Thanks! Krish

Help greatly appreciated. I'm not super familiar with the codebase so I did the best I could to make it work, but like you say there are likely edge cases this PR does not cover

@krishdef7
Copy link
Contributor

Hi @laurentsimon — thanks, that makes sense.

I’ll take a closer look at the tool dispatch path and how it interacts with transcript persistence, especially in async and streaming scenarios.

Initial thought: it might help to explicitly flush the transcript right before tool execution is dispatched, so BeforeTool hooks always see the latest state (including thoughts), even if the execution path diverges.

I’ll validate this against:

  • tool failures mid-stream
  • multiple tool calls in a session
  • partial/streaming responses

If it holds, I’ll follow up with a concrete PR + tests shortly.

Does this direction align with what you had in mind?

@laurentsimon
Copy link
Contributor Author

laurentsimon commented Feb 25, 2026

Hi @laurentsimon — thanks, that makes sense.

I’ll take a closer look at the tool dispatch path and how it interacts with transcript persistence, especially in async and streaming scenarios.

Initial thought: it might help to explicitly flush the transcript right before tool execution is dispatched, so BeforeTool hooks always see the latest state (including thoughts), even if the execution path diverges.

Makes sense, in particular for thoughts. Tool execution metadata is available in BeforeTool inputs, so having the tool info in the transcript is less critical

I’ll validate this against:

  • tool failures mid-stream
  • multiple tool calls in a session
  • partial/streaming responses

If it holds, I’ll follow up with a concrete PR + tests shortly.

Does this direction align with what you had in mind?

That makes sense, yes.

Really appreciate the help, thank you for taking the time.

krishdef7 added a commit to krishdef7/gemini-cli that referenced this pull request Feb 26, 2026
…esponses

Extends the fix in google-gemini#17996: when the model emits a functionCall with no
response text and no thoughts, recordMessage was not called, leaving
BeforeTool hooks with no gemini entry in the transcript at dispatch time.

- Add hasThoughts flag (from google-gemini#17996) to track thought-only responses
- Add hasToolCall to flush condition so pure tool calls also trigger a
  transcript write before tool execution
- Add regression test verifying gemini entry is written on pure tool call

Fixes the edge case noted in PR google-gemini#17996 discussion.
krishdef7 added a commit to krishdef7/gemini-cli that referenced this pull request Feb 26, 2026
…esponses

Extends the fix in google-gemini#17996: when the model emits a functionCall with no
response text and no thoughts, recordMessage was not called, leaving
BeforeTool hooks with no gemini entry in the transcript at dispatch time.

- Add hasThoughts flag (from google-gemini#17996) to track thought-only responses
- Add hasToolCall to flush condition so pure tool calls also trigger a
  transcript write before tool execution
- Add regression test verifying gemini entry is written on pure tool call

Fixes the edge case noted in PR google-gemini#17996 discussion.
krishdef7 added a commit to krishdef7/gemini-cli that referenced this pull request Feb 26, 2026
…esponses

Extends the fix in google-gemini#17996: when the model emits a functionCall with no
response text and no thoughts, recordMessage was not called, leaving
BeforeTool hooks with no gemini entry in the transcript at dispatch time.

- Add hasThoughts flag (from google-gemini#17996) to track thought-only responses
- Add hasToolCall to flush condition so pure tool calls also trigger a
  transcript write before tool execution
- Add regression test verifying gemini entry is written on pure tool call

Fixes the edge case noted in PR google-gemini#17996 discussion.
@krishdef7
Copy link
Contributor

Hi @laurentsimon — I've opened a follow-up PR (#20419) that addresses the remaining edge case. When the model emits a pure functionCall with no text and no thoughts, recordMessage was still not called, so BeforeTool hooks saw no gemini entry at dispatch time. The fix extends the flush condition to responseText || hasThoughts || hasToolCall — a 3-line change in processStreamResponse, no new dependencies. Includes a regression test. Happy to rebase onto your branch if you'd prefer to land both together.

@laurentsimon
Copy link
Contributor Author

Hi @laurentsimon — I've opened a follow-up PR (#20419) that addresses the remaining edge case. When the model emits a pure functionCall with no text and no thoughts, recordMessage was still not called, so BeforeTool hooks saw no gemini entry at dispatch time. The fix extends the flush condition to responseText || hasThoughts || hasToolCall — a 3-line change in processStreamResponse, no new dependencies. Includes a regression test. Happy to rebase onto your branch if you'd prefer to land both together.

Great. Let me close this PR then. Thank you!

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 help wanted We will accept PRs from all issues marked as "help wanted". Thanks for your support! priority/p1 Important and should be addressed in the near term.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Context of chat agent not available in safety checker BeforeTool hook

4 participants