Skip to content

Comments

feat: add ExitLoop API for tools to stop agent event loop#583

Open
GuyGoldenberg wants to merge 1 commit intogoogle:mainfrom
GuyGoldenberg:feat/exit-loop-api
Open

feat: add ExitLoop API for tools to stop agent event loop#583
GuyGoldenberg wants to merge 1 commit intogoogle:mainfrom
GuyGoldenberg:feat/exit-loop-api

Conversation

@GuyGoldenberg
Copy link

Adds ExitLoop() method to tool.Context - a clearer way for tools to signal they want to stop the agent loop.

The existing SkipSummarization field was confusingly named since it actually stops the event loop, not just "skips summarization". The new API makes the intent explicit.

Changes:

  • Add ExitLoop field to EventActions
  • Add ExitLoop() method to tool.Context
  • Deprecate SkipSummarization (kept for backward compat)
  • Migrate built-in tools to use new API

Test plan: All existing tests pass, added new test for ExitLoop().

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @GuyGoldenberg, 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 introduces a dedicated ExitLoop() API to clarify how tools signal an agent to stop its event loop. This change replaces the ambiguously named SkipSummarization field with a more explicit mechanism, improving the readability and maintainability of the codebase. The new API ensures that when a tool needs to halt the agent's execution, such as for user confirmation or when a final result is produced, the intent is clearly communicated.

Highlights

  • New API for Agent Loop Control: Introduced an ExitLoop() method in tool.Context to explicitly signal an agent to stop its event loop, providing a clearer mechanism than previous approaches.
  • Deprecation of SkipSummarization: The SkipSummarization field in session.EventActions has been deprecated, with ExitLoop now serving as its more semantically accurate replacement for halting the agent loop.
  • Migration of Built-in Tools: Several built-in tools, including agentTool and exitLoopTool, have been updated to utilize the new ExitLoop() API, ensuring consistent behavior across the system.
  • Enhanced Event Action Merging: The mergeEventActions logic in base_flow.go was updated to correctly propagate the ExitLoop signal, ensuring that loop termination requests are honored when combining event actions.
  • Updated Test Coverage: New tests were added specifically for the ExitLoop() functionality, and existing tests were modified to reflect the transition from SkipSummarization to ExitLoop.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • internal/llminternal/base_flow.go
    • Added logic to merge the new ExitLoop status within mergeEventActions.
  • internal/toolinternal/context.go
    • Implemented the ExitLoop() method to set the eventActions.ExitLoop flag.
    • Updated RequestConfirmation to call ExitLoop() instead of directly setting SkipSummarization.
  • internal/toolinternal/context_test.go
    • Renamed TestRequestConfirmation_SetsSkipSummarization to TestRequestConfirmation_SetsExitLoop.
    • Modified assertions in RequestConfirmation tests to check for ExitLoop instead of SkipSummarization.
    • Added a new test, TestExitLoop, to verify the functionality of the ExitLoop() method.
  • session/session.go
    • Added a new boolean field ExitLoop to the EventActions struct.
    • Marked the SkipSummarization field as deprecated with a comment.
    • Updated the IsFinalResponse method to consider Actions.ExitLoop when determining if an event is a final response.
  • tool/agenttool/agent_tool.go
    • Modified the Run method to call toolCtx.ExitLoop() when skipSummarization is true, replacing the direct assignment to SkipSummarization.
  • tool/agenttool/agent_tool_test.go
    • Updated test comments and assertions to reflect the use of ExitLoop instead of SkipSummarization.
  • tool/exitlooptool/tool.go
    • Updated the exitLoop function to use ctx.ExitLoop() instead of setting ctx.Actions().SkipSummarization.
  • tool/functiontool/function.go
    • Updated a comment in the Run method to clarify that RequestConfirmation internally calls ExitLoop().
  • tool/mcptoolset/tool.go
    • Updated a comment in the Run method to clarify that RequestConfirmation internally calls ExitLoop().
  • tool/tool.go
    • Added the ExitLoop() method to the tool.Context interface, along with its documentation.
Activity
  • No human activity (comments, reviews, etc.) has been recorded for this pull request yet.
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

The pull request introduces an ExitLoop API to explicitly signal the agent to stop its event loop, replacing the ambiguously named SkipSummarization field. This change improves clarity and maintainability. The modifications include adding the ExitLoop field to EventActions, creating an ExitLoop() method in tool.Context, deprecating SkipSummarization, and migrating existing tools to use the new API. The test cases have also been updated to reflect these changes. The overall change is positive for code clarity and intent.

Comment on lines +763 to +765
if other.ExitLoop {
base.ExitLoop = true
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The new ExitLoop logic is correctly integrated here. It's good that ExitLoop takes precedence or is handled alongside SkipSummarization during merging, ensuring the agent stops when intended.

Copy link
Author

Choose a reason for hiding this comment

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

Thanks Gemini :)

// This matches the behavior of the built-in RequireConfirmation path in
// functiontool (function.go).
c.eventActions.SkipSummarization = true
c.ExitLoop()
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Replacing the direct assignment to SkipSummarization with a call to c.ExitLoop() is a good refactoring. It centralizes the logic for exiting the loop and aligns with the new API.

Suggested change
c.ExitLoop()
c.ExitLoop()

Comment on lines 130 to 132
func (c *toolContext) ExitLoop() {
c.eventActions.ExitLoop = true
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The ExitLoop() method correctly sets the ExitLoop flag in eventActions. This provides a clear and explicit way for tools to signal the agent to stop its event loop.

Comment on lines +47 to +48
if !actions.ExitLoop {
t.Error("RequestConfirmation did not set ExitLoop to true")
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The assertion should be updated to check actions.ExitLoop instead of actions.SkipSummarization to align with the new API.

Suggested change
if !actions.ExitLoop {
t.Error("RequestConfirmation did not set ExitLoop to true")
if !actions.ExitLoop {
t.Error("RequestConfirmation did not set ExitLoop to true")

Comment on lines +77 to +78
if !actions.ExitLoop {
t.Error("ExitLoop should be set even with auto-generated function call ID")
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The assertion should be updated to check actions.ExitLoop instead of actions.SkipSummarization to align with the new API.

Suggested change
if !actions.ExitLoop {
t.Error("ExitLoop should be set even with auto-generated function call ID")
if !actions.ExitLoop {
t.Error("ExitLoop should be set even with auto-generated function call ID")

Comment on lines 93 to 107
func TestExitLoop(t *testing.T) {
inv := contextinternal.NewInvocationContext(t.Context(), contextinternal.InvocationContextParams{})
actions := &session.EventActions{}
toolCtx := NewToolContext(inv, "fn1", actions, nil)

if actions.ExitLoop {
t.Error("ExitLoop should be false initially")
}

toolCtx.ExitLoop()

if !actions.ExitLoop {
t.Error("ExitLoop should be true after calling ExitLoop()")
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This new test case for TestExitLoop is well-written and effectively verifies the functionality of the ExitLoop() method. It covers the initial state and the state after calling the method.

// multiple events with IsFinalResponse() as True, for each participating agent.
func (e *Event) IsFinalResponse() bool {
if (e.Actions.SkipSummarization) || len(e.LongRunningToolIDs) > 0 {
if e.Actions.ExitLoop || e.Actions.SkipSummarization || len(e.LongRunningToolIDs) > 0 {
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Adding e.Actions.ExitLoop to the IsFinalResponse() condition ensures that the agent correctly recognizes when it should stop its event loop, which is the intended behavior of the new API.

Suggested change
if e.Actions.ExitLoop || e.Actions.SkipSummarization || len(e.LongRunningToolIDs) > 0 {
if e.Actions.ExitLoop || e.Actions.SkipSummarization || len(e.LongRunningToolIDs) > 0 {

Comment on lines +153 to +156
// ExitLoop signals the agent to stop its event loop after processing this event.
// Use this when a tool needs to halt the agent's execution, such as when
// requiring user confirmation or when the tool's result is the final output.
ExitLoop bool
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The addition of the ExitLoop field with a clear and comprehensive comment explains its purpose and usage, which is crucial for maintainability and understanding the new API.

// requiring user confirmation or when the tool's result is the final output.
ExitLoop bool

// Deprecated: Use ExitLoop instead. SkipSummarization is kept for backward compatibility.
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Deprecating SkipSummarization and providing a clear comment to use ExitLoop instead is good practice for API evolution. It guides users to the new, clearer API while maintaining backward compatibility.

Suggested change
// Deprecated: Use ExitLoop instead. SkipSummarization is kept for backward compatibility.
// Deprecated: Use ExitLoop instead. SkipSummarization is kept for backward compatibility.

Comment on lines +91 to +94
// ExitLoop signals the agent to stop its event loop after processing this tool's response.
// Call this when the tool's result should be the final output, or when the agent should
// halt execution (e.g., waiting for user input, confirmation, or external action).
ExitLoop()
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The ExitLoop() method is a valuable addition to the tool.Context interface. Its clear documentation explains its purpose and when to use it, which enhances the usability and understanding of the API.

Add a clearer API for tools to signal they want to stop the agent's
event loop. The existing SkipSummarization field name was confusing
as it didn't describe the actual behavior (stopping the loop).

Changes:
- Add ExitLoop field to EventActions
- Add ExitLoop() method to tool.Context interface
- Update IsFinalResponse() to check ExitLoop
- Deprecate SkipSummarization (kept for backward compat)
- Update exitlooptool, agenttool, functiontool, mcptoolset to use new API
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