-
-
Notifications
You must be signed in to change notification settings - Fork 676
Add Google Agent SDK Support #1639
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: master
Are you sure you want to change the base?
Conversation
…ipts Add Google Agent SDK provider
File-Level Changes (文件级别更改)
Tips and commands (提示和命令)Interacting with Sourcery (与 Sourcery 交互)
Customizing Your Experience (自定义您的体验)Access your dashboard to: (访问您的 dashboard 以:)
Getting Help (获取帮助)
Original review guide in EnglishReviewer's GuideThis PR integrates support for the Google Agent SDK by adding its configuration, registering and implementing a new provider adapter, updating documentation to reflect the new provider, and including the necessary dependency. Sequence Diagram: Chat Processing with Google Agent SDKsequenceDiagram
actor User
participant AstrBotCore as "AstrBot Core"
participant PGoogleAgentSDK as "ProviderGoogleAgentSDK"
participant GoogleAgentSvc as "Google Agent SDK (External Service)"
User->>AstrBotCore: Sends chat prompt
AstrBotCore->>PGoogleAgentSDK: text_chat(prompt, history, ...)
PGoogleAgentSDK->>GoogleAgentSvc: agent.chat(prompt, history)
GoogleAgentSvc-->>PGoogleAgentSDK: Receives agent_response
PGoogleAgentSDK->>AstrBotCore: Returns LLMResponse (with agent_response)
AstrBotCore-->>User: Delivers final response
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
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.
嘿 @HendricksJudy - 我已经审查了你的更改 - 这里有一些反馈:
- 在 default.py 中,顶层键 "Google Agent SDK" 使用空格—考虑使用一致的 snake_case 键(例如 google_agent_sdk)来匹配其他提供程序并避免 YAML 解析问题。
- 当前的 text_chat_stream 只是包装了非流式调用—如果 Google Agent SDK 提供了原生流式 API,那么最好使用它来实现真正的增量响应。
- 提供程序初始化忽略了配置的超时—考虑将 provider_config 中的
timeout
传递到 Agent SDK 调用中,以便尊重用户定义的超时。
以下是我在审查期间查看的内容
- 🟡 一般问题:发现 2 个问题
- 🟢 安全性:一切看起来都很好
- 🟢 测试:一切看起来都很好
- 🟢 复杂性:一切看起来都很好
- 🟢 文档:一切看起来都很好
帮助我更有用!请点击每个评论上的 👍 或 👎,我将使用反馈来改进您的评论。
Original comment in English
Hey @HendricksJudy - I've reviewed your changes - here's some feedback:
- In default.py the top-level key "Google Agent SDK" uses spaces—consider using a consistent snake_case key (e.g. google_agent_sdk) to match other providers and avoid YAML parsing issues.
- The current text_chat_stream just wraps the non-streaming call—if the Google Agent SDK offers a native streaming API, it’d be better to use that for true incremental responses.
- The provider initialization ignores the configured timeout—consider passing the
timeout
from provider_config into the Agent SDK calls so user-defined timeouts are respected.
Here's what I looked at during the review
- 🟡 General issues: 2 issues found
- 🟢 Security: all looks good
- 🟢 Testing: all looks good
- 🟢 Complexity: all looks good
- 🟢 Documentation: all looks good
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
history = contexts or [] | ||
if system_prompt: | ||
history = [{"role": "system", "content": system_prompt}, *history] | ||
# TODO: handle func_tool and tool_calls_result via ADK Tool API | ||
try: | ||
response = await self.agent.chat(prompt, history=history) # type: ignore[attr-defined] |
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.
建议: 警告何时提供 func_tool 或 tool_calls_result
如果提供了 func_tool 或 tool_calls_result,请考虑添加警告或异常,因为它们目前被忽略。
history = contexts or [] | |
if system_prompt: | |
history = [{"role": "system", "content": system_prompt}, *history] | |
# TODO: handle func_tool and tool_calls_result via ADK Tool API | |
try: | |
response = await self.agent.chat(prompt, history=history) # type: ignore[attr-defined] | |
history = contexts or [] | |
if system_prompt: | |
history = [{"role": "system", "content": system_prompt}, *history] | |
# TODO: handle func_tool and tool_calls_result via ADK Tool API | |
if kwargs.get("func_tool") is not None: | |
logger.warning("func_tool is provided but currently ignored by google_agent_sdk provider") | |
if tool_calls_result is not None: | |
logger.warning("tool_calls_result is provided but currently ignored by google_agent_sdk provider") | |
try: | |
response = await self.agent.chat(prompt, history=history) # type: ignore[attr-defined] |
Original comment in English
suggestion: Warn when func_tool or tool_calls_result is provided
Consider adding a warning or exception if func_tool or tool_calls_result is provided, since they are currently ignored.
history = contexts or [] | |
if system_prompt: | |
history = [{"role": "system", "content": system_prompt}, *history] | |
# TODO: handle func_tool and tool_calls_result via ADK Tool API | |
try: | |
response = await self.agent.chat(prompt, history=history) # type: ignore[attr-defined] | |
history = contexts or [] | |
if system_prompt: | |
history = [{"role": "system", "content": system_prompt}, *history] | |
# TODO: handle func_tool and tool_calls_result via ADK Tool API | |
if kwargs.get("func_tool") is not None: | |
logger.warning("func_tool is provided but currently ignored by google_agent_sdk provider") | |
if tool_calls_result is not None: | |
logger.warning("tool_calls_result is provided but currently ignored by google_agent_sdk provider") | |
try: | |
response = await self.agent.chat(prompt, history=history) # type: ignore[attr-defined] |
tool_calls_result=tool_calls_result, | ||
**kwargs, | ||
) | ||
yield llm_response |
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.
建议: 实施真正的流式传输或调整方法命名
由于 text_chat_stream 一次性产生完整响应,请实施分块流式传输或更新方法名称/文档,以明确不支持实时流式传输。
建议的实施方式:
async def text_chat_full_response(self, prompt, session_id=None, image_urls=None, func_tool=None, contexts=None, system_prompt=None, tool_calls_result=None, **kwargs):
"""
一次性返回完整的 LLM 响应。此方法不提供实时或分块流式传输。
"""
llm_response = await self.text_chat(
prompt,
session_id=session_id,
image_urls=image_urls,
func_tool=func_tool,
contexts=contexts,
system_prompt=system_prompt,
tool_calls_result=tool_calls_result,
**kwargs,
)
yield llm_response
- 在整个代码库中,将所有
text_chat_stream
的用法更新为text_chat_full_response
。 - 如果您有引用
text_chat_stream
的文档,请更新它以明确新的方法名称及其非流式传输行为。
Original comment in English
suggestion: Implement true streaming or adjust method naming
Since text_chat_stream yields the full response at once, please either implement chunked streaming or update the method name/documentation to clarify that real-time streaming is not supported.
Suggested implementation:
async def text_chat_full_response(self, prompt, session_id=None, image_urls=None, func_tool=None, contexts=None, system_prompt=None, tool_calls_result=None, **kwargs):
"""
Returns the full LLM response at once. This method does not provide real-time or chunked streaming.
"""
llm_response = await self.text_chat(
prompt,
session_id=session_id,
image_urls=image_urls,
func_tool=func_tool,
contexts=contexts,
system_prompt=system_prompt,
tool_calls_result=tool_calls_result,
**kwargs,
)
yield llm_response
- Update all usages of
text_chat_stream
totext_chat_full_response
throughout the codebase. - If you have documentation referencing
text_chat_stream
, update it to clarify the new method name and its non-streaming behavior.
try: | ||
response = await self.agent.chat(prompt, history=history) # type: ignore[attr-defined] | ||
except Exception as e: # pragma: no cover - runtime errors | ||
raise Exception(f"Google Agent SDK error: {e}") from e |
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.
问题(代码质量): 引发特定错误,而不是一般的 Exception
或 BaseException
(raise-specific-error
)
解释
如果一段代码引发特定异常类型,而不是通用的 [`BaseException`](https://docs.python.org/3/library/exceptions.html#BaseException) 或 [`Exception`](https://docs.python.org/3/library/exceptions.html#Exception),则调用代码可以:- 获取有关错误类型的更多信息
- 为其定义特定的异常处理
这样,代码的调用者可以适当地处理错误。
您如何解决这个问题?
因此,与其让代码引发 Exception
或 BaseException
,例如
if incorrect_input(value):
raise Exception("输入不正确")
您可以让代码引发特定错误,例如
if incorrect_input(value):
raise ValueError("输入不正确")
或者
class IncorrectInputError(Exception):
pass
if incorrect_input(value):
raise IncorrectInputError("输入不正确")
Original comment in English
issue (code-quality): Raise a specific error instead of the general Exception
or BaseException
(raise-specific-error
)
Explanation
If a piece of code raises a specific exception type rather than the generic [`BaseException`](https://docs.python.org/3/library/exceptions.html#BaseException) or [`Exception`](https://docs.python.org/3/library/exceptions.html#Exception), the calling code can:- get more information about what type of error it is
- define specific exception handling for it
This way, callers of the code can handle the error appropriately.
How can you solve this?
- Use one of the built-in exceptions of the standard library.
- Define your own error class that subclasses
Exception
.
So instead of having code raising Exception
or BaseException
like
if incorrect_input(value):
raise Exception("The input is incorrect")
you can have code raising a specific error like
if incorrect_input(value):
raise ValueError("The input is incorrect")
or
class IncorrectInputError(Exception):
pass
if incorrect_input(value):
raise IncorrectInputError("The input is incorrect")
keys = provider_config.get("key", []) | ||
if keys: |
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.
建议(代码质量): 使用命名表达式来简化赋值和条件 (use-named-expression
)
keys = provider_config.get("key", []) | |
if keys: | |
if keys := provider_config.get("key", []): |
Original comment in English
suggestion (code-quality): Use named expression to simplify assignment and conditional (use-named-expression
)
keys = provider_config.get("key", []) | |
if keys: | |
if keys := provider_config.get("key", []): |
llm_response = await self.text_chat( | ||
prompt, | ||
session_id=session_id, | ||
image_urls=image_urls, | ||
func_tool=func_tool, | ||
contexts=contexts, | ||
system_prompt=system_prompt, | ||
tool_calls_result=tool_calls_result, | ||
**kwargs, | ||
) |
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.
问题(代码质量): 内联立即产生的变量 (inline-immediately-yielded-variable
)
Original comment in English
issue (code-quality): Inline variable that is immediately yielded (inline-immediately-yielded-variable
)
No. The current code already works, so the suggestions are optional improvements rather than requirements. For instance, the configuration file stores the provider entry as "Google Agent SDK" with spaces, which works fine since keys are quoted and other providers use spaces or non‑ASCII names. The text_chat_stream method in the Google Agent provider forwards to text_chat and yields one result, so it isn't an accurate streaming implementation. This still delivers a response, just without incremental tokens. Adopting the suggestions (e.g., snake_case keys, native streaming support, honoring timeout) would improve consistency and functionality, but the existing implementation runs without them. They are functional enhancements, not strict necessities. |
Add image support for Google Chat
Hi, thank you for your contribution to adapting the Google Chat and Google Agent SDK! Can you provide a short tutorial about the configuration of Google Chat? |
Basic Setup Steps Once configured and running, AstrBot can receive messages from Google Chat spaces and send responses or images back to the webhook URL. This provides a basic integration using Google Chat’s HTTP webhook mechanism. |
Thanks for your response! I'm sorry but I haven't used Google Chat yet. Does it need a Google Workspace account? And what's the difference between the Google Agent SDK and Google Gen AI SDK? It seems like Google Gen AI SDK can handle all the model(such as gemini) API interactions. |
The README also distinguishes them in the provider support table, labeling “Google Gemini API” under “Text Generation” and “Google Agent SDK” under “Agent SDK”: Google GenAI SDK: For direct Gemini (text generation) calls—supports images, tool calls, and other model-specific options. Google Agent SDK: Wraps an “Agent” that can orchestrate interactions (chat history, potential tools, etc.) before using underlying models like Gemini. Thus, while the GenAI SDK handles raw model interactions, the Agent SDK provides a higher-level agent framework that relies on those models internally. |
解决了 #XYZ
Motivation
This pull request introduces support for the Google Agent SDK in AstrBot, enabling integration with Google's agent-based functionalities. The changes include updates to documentation, configuration, provider management, and the addition of a new provider adapter for the SDK.
Modifications
Documentation Updates:
README.md
andREADME_en.md
to include the Google Agent SDK in the list of supported providers, along with a link to its documentation. [1] [2] [3]Configuration Enhancements:
astrbot/core/config/default.py
, specifying its default settings such as model type, timeout, and API key support.Provider Management:
astrbot/core/provider/manager.py
to handle the newgoogle_agent_sdk
provider type, including its initialization logic.New Provider Adapter:
ProviderGoogleAgentSDK
inastrbot/core/provider/sources/google_agent_sdk_source.py
, which integrates with the Google Agent SDK for chat completions. This includes methods for initialization, API key management, and chat interactions.Dependency Addition:
google-agents>=0.1.0
topyproject.toml
as a new dependency to support the Google Agent SDK integration.Check
requirements.txt
和pyproject.toml
文件相应位置。好的,这是翻译成中文的 pull request 总结:
Sourcery 总结
添加对 Google Agent SDK 的支持,通过引入一个新的 provider adapter,更新配置和 provider 加载逻辑,更新文档,并添加所需的依赖项。
新特性:
ProviderGoogleAgentSDK
以支持通过 Google Agent SDK 进行聊天补全。增强:
构建:
pyproject.toml
中添加google-agents>=0.1.0
依赖项文档:
README
和README_en
中包含 Google Agent SDK,并附带文档链接。Original summary in English
Summary by Sourcery
Add support for the Google Agent SDK by introducing a new provider adapter, updating configuration and provider loading logic, updating documentation, and adding the required dependency.
New Features:
Enhancements:
Build:
Documentation: