[Bug] Gemini functionResponse 未正确保留 name/id,导致 cpa-Antigravity 工具调用失败
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 78/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- python
- Domain
- ai, backend-api-design
Research direction
Start in astrbot/core/provider/sources/gemini_source.py, focusing on the role == "tool" handling and its construction of function responses. Reproduce the callback through a CPA Gemini provider, then verify that the response preserves the original function name and tool call ID and no longer produces the reported HTTP 400.
Written by the indexing model from the issue text.
Description
问题描述
问题描述
使用 AstrBot 通过 CLIProxyAPI 的 Antigravity 后端调用 gemini-3.7-flash-high 时,模型可以正常触发工具调用,AstrBot 也能正常执行工具,但在将工具结果回传给模型时会报 HTTP 400。
调用链路:
AstrBot
-> CLIProxyAPI (gemini模式 v1beta)
-> Antigravity
-> gemini-3.7-flash-high
本次触发的工具名是:
gemini_search
AstrBot 日志中可以看到 gemini_search 已经被成功调用并返回结果,但后续请求报错:
HTTP 400
antigravity executor: invalid Gemini function call history:
request.contents[4].parts[0]: functionResponse.name "call_176130"
does not match functionCall.name "gemini_search"
at request.contents[3].parts[1]
初步分析
Gemini 第一轮返回的工具调用实际上包含两个字段:
{
"functionCall": {
"name": "gemini_search",
"id": "call_176130",
"args": {
"query": "..."
}
}
}
但是 AstrBot 回传工具结果时,最终变成了类似:
{
"functionResponse": {
"name": "call_176130",
"response": {
...
}
}
}
这里似乎把 tool_call_id 当成了 functionResponse.name。
预期应该是:
{
"functionResponse": {
"name": "gemini_search",
"id": "call_176130",
"response": {
...
}
}
}
也就是:
functionResponse.name == functionCall.name
functionResponse.id == functionCall.id
AstrBot 相关源码
查看 astrbot/core/provider/sources/gemini_source.py 后,发现处理 role == "tool" 时有类似逻辑:
elif role == "tool":
func_name = message.get("name", message["tool_call_id"])
part = types.Part.from_function_response(
name=func_name,
response={
"name": func_name,
"content": message["content"],
},
)
这里如果 tool message 中没有 name 字段:
message.get("name", message["tool_call_id"])
就会直接 fallback 到:
message["tool_call_id"]
于是:
func_name = call_176130
最后生成:
functionResponse.name = call_176130
这和实际报错完全一致。
另外,这里似乎也没有把 tool_call_id 回填到:
functionResponse.id
最小化测试
为了排除 CLIProxyAPI 本身的问题,我又绕过 AstrBot,直接使用 Python 手工请求 CLIProxyAPI。
第一轮模型正常返回:
{
"functionCall": {
"name": "get_weather",
"args": {
"city": "Beijing"
},
"id": "call_128917"
}
}
然后我故意只回传:
{
"functionResponse": {
"name": "get_weather",
"response": {
"temperature": "30°C",
"condition": "Sunny"
}
}
}
CLIProxyAPI / Antigravity 返回:
HTTP 400
antigravity executor: invalid Gemini function call history:
request.contents[2].parts[0]: missing functionResponse.id
for request.contents[1].parts[0]
说明 Antigravity 会严格校验:
functionResponse.name == functionCall.name
functionResponse.id == functionCall.id
所以目前看起来,更像是 AstrBot 在 Gemini tool result 序列化时没有正确保留:
function name
tool call id
这两个字段。
额外现象
比较奇怪的是,同样的 AstrBot 工具调用流程:
AstrBot
-> NewAPI (gemini模式 v1beta)
-> Google AI Studio Gemini API Key
是可以正常工作的。
猜测可能是 Google AI Studio 的 Gemini API 对旧格式或缺失 functionResponse.id 的情况更宽容,而 Antigravity 会严格校验 function call history,所以这个问题在 Antigravity 路径下才暴露出来。
期望行为
对于:
{
"functionCall": {
"name": "gemini_search",
"id": "call_176130"
}
}
AstrBot 回传工具结果时应该保留:
{
"functionResponse": {
"name": "gemini_search",
"id": "call_176130",
"response": {
...
}
}
}
不知道这里是否可以在 Gemini provider 中同时保留原始 function name 和 tool_call_id?
如何复现?
provider对接cpa,然后触发一次工具回调就能重现
AstrBot 版本
4.26.4
操作系统
Windows
部署方式
AstrbotLauncher
使用的消息平台适配器
napcat
错误日志
[2026-08-20 15:39:13.784] [Core]
[INFO]
[core.event_bus:74]: [default] [napcat(aiocqhttp)] 平生/9xxxxx6: /昨天七夕发生过什么比较大的社会新闻吗
[2026-08-20 15:39:20.489] [Core]
[INFO]
[runners.tool_loop_agent_runner:985]: Agent 使用工具: ['gemini_search']
[2026-08-20 15:39:20.489] [Core]
[INFO]
[runners.tool_loop_agent_runner:1038]: 使用工具:gemini_search,参数:{'query': '2026年8月19日 七夕 新闻 热点 社会新闻'}
[2026-08-20 15:39:27.640] [Core]
[INFO]
[runners.tool_loop_agent_runner:1235]: Tool `gemini_search` Result: 2026年8月19日(星期三)为中国传统节日**七夕节**(农历七月初七)。当日社会热点主要围绕节日文化传承、文旅消费体验及文明婚俗倡导展开。
### 关键要点摘要
* **节日氛围与文旅消费:**
* 各地通过“传统节日IP”赋能文旅,打造沉浸式消费场景。例如,宁夏银川举办“贺兰山日出之约”与“阅海湖落日大合唱”;杭州推出“跟着爱情故事游杭州”主题线路;广西玉林举办“南宋香市”游园会。
* 游客更倾向于追求体验感与情绪价值,传统景区通过全时段文旅体验(如“日间沉浸+夜间狂欢”)实现业态升级。
* **文明婚俗与社会实践:**
* 多地将七夕与移风易俗、家风建设深度结合,举办集体婚礼与集体颁证活动。例如,山东多地开展中式集体婚礼,倡导简约庄重的婚俗新风;湖北郧西举办“天河作证·情定郧西”集体婚礼大典。
* 江苏宜兴举办全国“我们的节日·七夕”主题文化活动,采用“传统文化+AI数字呈现”模式,展示非遗民俗并联动长三角地区开展文明实践。
* **文化传承与公益活动:**
* 七夕节不仅是“中国情人节”,也是传统的“乞巧节”。各地博物馆与社区开展了手工制作(如巧果、香囊)、非遗展示及家风宣讲等活动,引导年轻人了解传统文化内涵。
* 此外,8月19日恰逢第九个“中国医师节”,部分地区(如青海乐都)将七夕民俗与医师节康养体验相结合,开展中医药文化惠民活动。
### 参考来源
1. **网络中国节|“浪漫经济”点燃七夕消费热潮 - 新浪新闻**
https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHr-GJdZ6acU5vILbsCiVg-F5LLDJ1yRZA_IQqyGofPw_hHsc80fFzHre46fF2p0U5XMl7gsrVh0vZaE02u0_PjrK19MBQpXgeBGpr7is4KxjuLdb8oslrtyxqePpQpKju1WJi0uSSGkFtx_DebTsCIey6_c7HrdBxq
2. **财经聚焦丨七夕:传统节日IP赋能催生消费新体验 - 新华网**
https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQH3Dr5m8L3sZMq0aegbdDWs3yFA6YYSZXEvqVrzhPeRhkG6ok2LlCmKDIWpGPYx3cnxMbBOxqBGBY1hbUin4DuwxlamG1f2e889mPbRLbgCUTzUg91ZgAevqrOpFKaWhudEMisqbmWdlsyLDsWP26EMTDh60zad55DjLX7cdyaazFSZ
3. **“我们的节日·七夕”主题文化活动在宜兴举办 - 中共江苏省委新闻网**
https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQE88R0TGmkJGTdYUF3jF9PsuMEOHQDfzoXYMUTcbQY9399D08FtYSPgRE7DcB4IR6ykzb54x9yXtZyHxfZS95o61RsGt7hkj3Tt91rujZ0Cr8HAhlPbQM9c-eAYNI5X9ddBvumiPpRNfYel54T_7MyuyjAOpyGzuhQxcsd7J3-4bjXzBLk=
4. **缘定七夕!山东送上文明实践幸福“礼包” - 大众日报**
https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFygkeaQn7TRLmnc5tHbzG_E3pJNZnyI1lcmelGHTaP-UeNPPjXskbN8u8XfEArxDQoteEHePADgB_XTxNF0jyTPr0CF-i-8fpyfWqFsxhfMdyTeIIKSwC_ZlOXwEVF5LUHfvVZ863smVvcVkcG5VY3sXkKig==
5. **青海乐都举办“8·19”中国医师节康养体验活动 - 科技日报**
https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGb5iHnNEML9eG-9afAYOM6ASPObn-nNmQ-fZcVyx239L5E4gryWbVI_3-6bKrYV9dV5Z3uqrcT5PRdyMQHVSgFx6otKbaWaCguaxkXtFZZ5BtDrzWutQ8jRL9Dyu6SncZZupzhJPyjj_2XL_F9YB52VDiaoNE=
[2026-08-20 15:39:28.359] [Core]
[WARN]
[v4.26.4] [runners.tool_loop_agent_runner:556]: Chat Model cpa-gemini/gemini-3.7-flash-high request error: 400 None. {'error': {'message': 'antigravity executor: invalid Gemini function call history: request.contents[4].parts[0]: functionResponse.name "call_176130" does not match functionCall.name "gemini_search" at request.contents[3].parts[1]', 'type': 'invalid_request_error'}}
辅助信息
No response
检查清单
- Dominant language
- Python
- Stars
- 40.7k
- Forks
- 2.9k
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 114
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from AstrBotDevs/AstrBot
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
AstrBotDevs/AstrBot#10033 · 3 comments ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
AstrBotDevs/AstrBot#9999 ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
AstrBotDevs/AstrBot#9945 · 2 comments ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
AstrBotDevs/AstrBot#9938 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
AstrBotDevs/AstrBot#9929 · 2 comments ·
All issues in AstrBotDevs/AstrBot
Similar issues
-
documentation help wanted
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
simonw/sqlite-utils#872 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100