Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[Bug] OpenAI-compatible Gemini 工具 schema const 导致 400

Open Beginner friendly
#10,720 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
77/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
python
Domain
ai, backend

Research direction

Read astrbot/core/agent/tool.py and inspect ToolSet.openai_schema(), where the issue says tool.parameters is passed through. Trace how nested tool schemas are built, then check the existing schema tests or add a focused regression case for nested const values. Done means OpenAI compatible tool parameters convert each const to a single value enum and the reported Gemini 400 is avoided.

Written by the indexing model from the issue text.

Description

bug
问题描述
问题

使用 OpenAI 兼容的 Gemini 网关时,只要工具(function declaration)的 JSON Schema 里出现 const,请求就会直接 400,导致所有聊天模型失败。

报错示例:

LLM 响应错误: All chat models failed: BadRequestError: Error code: 400 -
{'error': {'message': 'Invalid JSON payload received. Unknown name "const" ### at
\'***.tools[0].function_declarations[34].***.properties[0].***.properties[2].***.***.properties[10].***.properties[0].value\':
Cannot find field.', 'type': 'upstream_error', 'param': '', 'code': 400}}
Gemini 的 function calling schema 只支持 OpenAPI 3.0 Schema 的一个子集;const 是合法 JSON Schema,但不在 Gemini 支持的字段里。ToolSet.google_schema() 会过滤不支持的字段,但 OpenAI 兼容路径没有做同样的清洗。

期望行为 / Expected behavior
AstrBot 在把工具 schema 发给 OpenAI 兼容 provider 前,应做一次 provider-safe 清洗,至少把:
{ "const": "value" }
转换成:
{ "enum": ["value"] }
两者对“参数必须逐字等于该值”的约束等价,OpenAI、Anthropic、Gemini 兼容网关都能接受。
根因 / Root cause
astrbot/core/agent/tool.py 的 ToolSet.openai_schema() 目前直接透传 tool.parameters:
func_def["function"]["parameters"] = tool.parameters
我也检查了 v4.29.1 的同一文件,仍然没有 const 清洗逻辑;4.29.0 / 4.29.1 的更新日志也没有相关修复。
建议修复 / Suggested fix
在 openai_schema() 里递归转换 const:
def _provider_safe_schema(value):
    if isinstance(value, dict):
        result = {}
        for key, item in value.items():
            if key == "const":
                result["enum"] = [item]
            else:
                result[key] = _provider_safe_schema(item)
        return result
    if isinstance(value, list):
        return [_provider_safe_schema(item) for item in value]
    return value
func_def["function"]["parameters"] = _provider_safe_schema(tool.parameters)
如果担心影响非 Gemini provider,也可以只在模型名包含 gemini 时启用这个转换;不过 const -> enum 本身语义等价,通用转换也安全。
临时绕过 / Workaround
•  切换到非 Gemini 模型(DeepSeek / Claude / OpenAI 等)。
•  或使用原生 Gemini provider(googlegenai_chat_completion),它会走 google_schema() 的字段过滤。
•  或本地给 openai_schema() 打补丁。
环境 / Environment
•  Provider:[OpenAI-compatible Gemini gateway / gemini-3.8-flash]
•  相关插件:[astrbot_plugin_memory_companion, astrbot_plugin_private_companion]
补充 / Additional context
•  这个问题和 #7572(examples)、#7357(id)属于同一类 Gemini schema 严格校验问题。
•  修掉 const 后,如果 schema 里还有 oneOf / allOf,Gemini 可能继续报不支持的字段;长期看可能需要一个按 provider 维护的 schema 兼容层,但本 issue 先聚焦 const。
•  本地验证:把 Memory Companion v3 schema 过一遍转换后,const 数量为 0,enum 数量为 63,请求不再触发该 400。

### 如何复现?

1. 配置一个 OpenAI 兼容的 Gemini provider(例如 gemini-3.x 系列)。
2. 启用一个工具参数里带 const 的插件。例如 Memory Companion 的 memory_companion_query / memory_companion_events,其嵌套 schema 中有:
{
  "type": "object",
  "properties": {
    "time": {
      "oneOf": [
        {
          "type": "object",
          "properties": {
            "kind": { "const": "unknown" }
          }
        }
      ]
    }
  }
}
3. 发送一条会带上工具声明的消息。
4. 请求返回 400:Unknown name "const"。

### AstrBot 版本

4.28.2

### 操作系统

Linux

### 部署方式

Docker

### 使用的消息平台适配器

onebot v11

### 错误日志

```text
LLM 响应错误: All chat models failed: BadRequestError: Error code: 400 - {'error': {'message': 'Invalid JSON payload received. Unknown name "const" at \'***.tools[0].function_declarations[34].***.properties[0].***.properties[2].***.***.properties[10].***.properties[0].value\': Cannot find field.', 'type': 'upstream_error', 'param': '', 'code': 400}}
辅助信息

No response

检查清单
  • 我已在 Issue 列表中搜索过相关问题仍无法解决,或该问题从未被报告过。
  • 我已尝试过禁用所有插件,排除了可能是因插件导致的问题。
  • 我报告的问题与 AstrBot 本体相关,而非在报告某一插件的问题。
  • 我已阅读并同意本项目的贡献者行为准则。
  • (可选)我愿意提交 PR 以帮助修复该问题。
Dominant language
Python
Stars
42.1k
Forks
3.1k
Avg merge
1d 17m
Merged PRs (30d)
148

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from AstrBotDevs/AstrBot

All issues in AstrBotDevs/AstrBot

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.