fix: provide fallback items for Gemini array params#6150
fix: provide fallback items for Gemini array params#6150tsubasakong wants to merge 1 commit intoAstrBotDevs:masterfrom
Conversation
Summary of ChangesHello, 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 enhances the Highlights
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.
Hey - 我在这里给出了一些整体性的反馈:
- 新增的
target_type == "array"分支会把任何非字典或“假值”(falsy)的items都当成缺失处理,并且静默地用{ "type": "string" }替换;建议只在完全不存在"items"字段时才应用这个回退逻辑,或者至少对非字典类型的items保持原样传递,这样更复杂的 JSON Schema 结构(例如 tuple 校验)就不会被意外覆盖。 - 鉴于这段逻辑是 Gemini 特有的,或许可以把这个回退行为抽离到一个命名清晰的 helper 或某个后端专用的路径中,而不是直接写进通用的
convert_schema函数里,这样未来再做后端特定的调整时会更容易理解和维护。
给 AI Agent 的提示
Please address the comments from this code review:
## Overall Comments
- The new `target_type == "array"` branch treats any non-dict or falsy `items` value as missing and silently replaces it with `{ "type": "string" }`; consider only applying the fallback when `"items"` is absent entirely, or at least passing through non-dict `items` unchanged so more complex JSON Schema constructs (e.g. tuple validation) aren't unexpectedly overridden.
- Given this logic is Gemini-specific, it may be worth isolating the fallback into a clearly named helper or backend-specific path rather than embedding Gemini behavior directly into the generic `convert_schema` function, to keep future backend-specific tweaks easier to reason about.帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈持续改进评审质量。
Original comment in English
Hey - I've left some high level feedback:
- The new
target_type == "array"branch treats any non-dict or falsyitemsvalue as missing and silently replaces it with{ "type": "string" }; consider only applying the fallback when"items"is absent entirely, or at least passing through non-dictitemsunchanged so more complex JSON Schema constructs (e.g. tuple validation) aren't unexpectedly overridden. - Given this logic is Gemini-specific, it may be worth isolating the fallback into a clearly named helper or backend-specific path rather than embedding Gemini behavior directly into the generic
convert_schemafunction, to keep future backend-specific tweaks easier to reason about.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The new `target_type == "array"` branch treats any non-dict or falsy `items` value as missing and silently replaces it with `{ "type": "string" }`; consider only applying the fallback when `"items"` is absent entirely, or at least passing through non-dict `items` unchanged so more complex JSON Schema constructs (e.g. tuple validation) aren't unexpectedly overridden.
- Given this logic is Gemini-specific, it may be worth isolating the fallback into a clearly named helper or backend-specific path rather than embedding Gemini behavior directly into the generic `convert_schema` function, to keep future backend-specific tweaks easier to reason about.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Code Review
This pull request addresses an issue with serializing array parameters for Gemini tools. When an array parameter in a JSON schema omits the items property, Gemini's API rejects the request. The change introduces a fallback, defaulting to items: {"type": "string"} for such cases, ensuring the request doesn't fail. The change also correctly preserves existing items definitions. The fix is well-tested with new unit tests covering both the fallback and the explicit-items scenarios. The implementation is correct and the added tests are well-focused. I've suggested a minor refactoring to improve code readability.
| if isinstance(schema.get("items"), dict) and schema["items"]: | ||
| result["items"] = convert_schema(schema["items"]) | ||
| else: | ||
| result["items"] = {"type": "string"} |
There was a problem hiding this comment.
For better readability and to avoid multiple calls to schema.get("items"), it's good practice to store the result of schema.get("items") in a local variable. This also makes the subsequent logic clearer.
| if isinstance(schema.get("items"), dict) and schema["items"]: | |
| result["items"] = convert_schema(schema["items"]) | |
| else: | |
| result["items"] = {"type": "string"} | |
| items = schema.get("items") | |
| if isinstance(items, dict) and items: | |
| result["items"] = convert_schema(items) | |
| else: | |
| result["items"] = {"type": "string"} |
|
Related Documentation 1 document(s) may need updating based on files changed in this PR: AstrBotTeam's Space pr4697的改动View Suggested Changes@@ -468,11 +468,58 @@
- `on_task_canceled`:任务被取消时触发
- `on_task_result_ignored`:任务结果被忽略时触发(如状态已变化)
+#### Gemini 工具架构兼容性(PR #6150)
+
+[PR #6150](https://github.com/AstrBotDevs/AstrBot/pull/6150) 修复了工具架构转换系统在 Gemini API 下的兼容性问题,确保外部工具(如 MCP 工具)生成的不完整 JSON Schema 定义不会导致请求失败。
+
+**问题背景**
+
+Gemini API 严格要求数组类型参数必须包含 `items` 字段定义数组元素类型,否则会拒绝请求并返回 `items: missing field` 错误。然而,外部工具(特别是 MCP 工具)生成的 JSON Schema 定义有时会省略 `items` 字段,导致工具调用失败。
+
+**技术实现**
+
+工具架构转换系统(`FunctionTool.convert_schema()`)新增 Gemini 兼容性回退机制:
+
+1. **自动回退策略**:
+ - 当数组类型参数缺少 `items` 字段时,系统自动提供回退架构:`{"type": "string"}`
+ - 确保工具调用请求能够正常发送到 Gemini API,而非因架构不完整而失败
+
+2. **显式架构保留**:
+ - 如果数组参数已明确提供 `items` 架构,系统会完整保留原始定义
+ - 递归转换嵌套的 `items` 架构,确保复杂类型正确映射
+
+**技术细节**
+
+修复前,架构转换逻辑仅在 `schema` 中存在 `items` 字段时才处理,导致缺少 `items` 的数组参数被忽略。修复后,逻辑调整为:
+
+```python
+if target_type == "array":
+ if isinstance(schema.get("items"), dict) and schema["items"]:
+ result["items"] = convert_schema(schema["items"])
+ else:
+ result["items"] = {"type": "string"}
+```
+
+该修复确保所有数组类型参数在转换为 Gemini 架构时都包含有效的 `items` 定义。
+
+**影响范围**
+
+- **外部工具集成**:提升与 MCP 工具等外部工具源的兼容性,防止架构不完整导致的工具调用失败
+- **Gemini API 兼容性**:确保所有工具架构符合 Gemini API 规范,避免 `items: missing field` 错误
+- **架构正确性**:显式定义的数组元素类型得到完整保留,不影响已有的正确架构
+
+**用户收益**
+
+- 外部工具(如 MCP 工具)在 Gemini 模型下可正常使用,无需手动修复架构定义
+- 工具调用稳定性提升,减少因架构不完整导致的请求失败
+- 开发者无需关注外部工具架构的完整性,系统自动提供兼容性保障
+
#### 注意事项
- 工具需在对应 SubAgent/Persona 配置中声明
- 动态注册工具时需确保配置同步更新
- 后台任务需正确设置 `background_task: true` 参数
- 后台任务执行通过 `HandoffExecutor.execute_queued_task()` 方法完成,该方法从数据库中恢复任务上下文并执行
+- 外部工具(如 MCP 工具)生成的数组参数架构会自动获得回退 `items` 定义(`{"type": "string"}`),确保 Gemini API 兼容性
#### Neo 技能生命周期工具(PR #5028)
Note: You must be authenticated to accept/decline updates. |
|
already fixed in #6051, thanks! |
Fixes #6029.
Modifications / 改动点
add a Gemini schema compatibility fallback so array parameters without an explicit
itemsschema still serialize withitems: {"type": "string"}instead of failing the whole requestpreserve explicit array item schemas when they are already present
add focused unit coverage for both the fallback path and the explicit-items path
This is NOT a breaking change. / 这不是一个破坏性变更。
Screenshots or Test Results / 运行截图或测试结果
python3.11 -m ruff format astrbot/core/agent/tool.py tests/unit/test_tool_google_schema.pypython3.11 -m ruff check astrbot/core/agent/tool.py tests/unit/test_tool_google_schema.pypython3.11 -m pytest tests/unit/test_tool_google_schema.py -qgit diff --checkChecklist / 检查清单
requirements.txt和pyproject.toml文件相应位置。/ I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations inrequirements.txtandpyproject.toml.Summary by Sourcery
确保当数组参数省略
items定义时,Gemini 工具的模式依然保持有效。Bug Fixes:
items定义的 Gemini 数组参数提供默认的字符串类型元素模式,避免请求失败。Tests:
items时会应用默认元素模式,以及在存在显式数组元素模式时能够被正确保留。Original summary in English
Summary by Sourcery
Ensure Gemini tool schemas remain valid when array parameters omit item definitions.
Bug Fixes:
Tests: