-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Implement dynamic agent updates for the Runner and AdkWebServer #4468
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
Response from ADK Triaging Agent Hello @jayy-77, thank you for creating this PR! To help us review your contribution, could you please fill out the pull request template in the description? Specifically, we need:
This information is crucial for our reviewers to understand and verify your work efficiently. You can find more details in our contribution guidelines. Thanks! |
Summary of ChangesHello @jayy-77, 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 significant improvements for dynamic agent management within the system. It enables agents to be reloaded and updated at runtime without service interruption, which is crucial for scenarios where agent configurations, such as instructions or tools, change frequently. These changes enhance the flexibility and responsiveness of the agent execution environment, particularly for live interaction sessions. Highlights
🧠 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
Activity
Using Gemini Code AssistThe 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
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 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
|
There was a problem hiding this 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 introduces a valuable feature for dynamically updating agents in the Runner and AdkWebServer for hot-reloading configurations. However, it introduces a critical path traversal vulnerability where user-provided input from the WebSocket URL is used to construct file paths without sanitization, potentially leading to Remote Code Execution (RCE). Additionally, there's a critical issue in adk_web_server.py that will cause a runtime error and a potential consistency issue in runners.py. Detailed comments and suggestions have been provided to address these points and prevent the vulnerability.
| if self.reload_agents: | ||
| try: | ||
| # Force reload the agent from disk | ||
| self.agent_loader.remove_agent_from_cache(app_name) | ||
| agent_or_app = self.agent_loader.load_agent(app_name) | ||
|
|
||
| if isinstance(agent_or_app, App): | ||
| reloaded_agent = agent_or_app.root_agent | ||
| else: | ||
| reloaded_agent = agent_or_app | ||
|
|
||
| logger.info( | ||
| 'Reloaded agent %s for live session (instructions may have updated)', | ||
| app_name | ||
| ) | ||
| except Exception as e: | ||
| logger.warning( | ||
| 'Failed to reload agent %s, using cached version: %s', | ||
| app_name, e | ||
| ) | ||
| reloaded_agent = None | ||
| else: | ||
| reloaded_agent = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The run_agent_live WebSocket endpoint accepts an app_name parameter from the URL which is used to dynamically reload agent configurations. This app_name is passed directly to self.agent_loader.remove_agent_from_cache() and self.agent_loader.load_agent() without proper sanitization, leading to a critical Path Traversal vulnerability and potential Remote Code Execution (RCE). Additionally, the AdkWebServer class lacks a reload_agents attribute, which will cause an AttributeError at runtime. The agent reloading logic could also be simplified.
import os
import re
# Perform security check for app_name to prevent path traversal.
if not re.match(r'^[a-zA-Z0-9_]+$', app_name):
await websocket.close(code=1008, reason='Invalid app_name format')
return
# More robust path validation
agent_path = os.path.abspath(os.path.join(self.agents_dir, app_name))
if not agent_path.startswith(os.path.abspath(self.agents_dir)):
await websocket.close(code=1008, reason='Path traversal detected')
return| self.agent = agent | ||
| # Re-infer agent origin for the new agent | ||
| self._agent_origin_app_name, self._agent_origin_dir = ( | ||
| self._infer_agent_origin(agent) | ||
| ) | ||
| self._enforce_app_name_alignment() | ||
| logger.info('Updated runner agent to: %s', agent.name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When update_agent is called, it updates self.agent but does not update self.app.root_agent if an App instance was provided to the Runner. This can lead to inconsistent behavior, as other parts of the Runner, like event compaction, might still use the old agent from self.app. To ensure consistency, you should also update self.app.root_agent.
self.agent = agent
if self.app:
self.app.root_agent = agent
# Re-infer agent origin for the new agent
self._agent_origin_app_name, self._agent_origin_dir = (
self._infer_agent_origin(agent)
)
self._enforce_app_name_alignment()
logger.info('Updated runner agent to: %s', agent.name)
Please ensure you have read the contribution guide before creating a pull request.
Link to Issue or Description of Change
1. Link to an existing issue (if applicable):
2. Or, if no issue exists, describe the change:
If applicable, please follow the issue templates to provide as much detail as
possible.
Problem:
A clear and concise description of what the problem is.
Solution:
A clear and concise description of what you want to happen and why you choose
this solution.
Testing Plan
Please describe the tests that you ran to verify your changes. This is required
for all PRs that are not small documentation or typo fixes.
Unit Tests:
Please include a summary of passed
pytestresults.Manual End-to-End (E2E) Tests:
Please provide instructions on how to manually test your changes, including any
necessary setup or configuration. Please provide logs or screenshots to help
reviewers better understand the fix.
Checklist
Additional context
Add any other context or screenshots about the feature request here.