fix(agent): connections.save 的 function-calling schema 去掉顶层 oneOf - #245
Merged
Merged
Conversation
现象:内置 AI 里让模型保存连接时,整个任务直接失败:
模型调用失败: Invalid request: OpenAI: Invalid schema for function
'connections_save': schema must have type 'object' and not have
'oneOf'/'anyOf'/'allOf'/'enum'/'const'/'not' at the top level
根因有两层:
1. `connections.save` 的工具参数 schema 用顶层 `oneOf` 表达「创建 or 更新」,
分支里还带 `not`。provider 要求工具参数 schema 顶层是纯 object,遇到这些
组合关键字会拒绝整个模型请求,而不是拒绝这一个工具——所以是任务级失败。
2. 本仓的 `validate_function_calling_schema` 当时只要求顶层是 object、组合
分支自身是 object,因此放行了这份 schema,直到请求发到 provider 才炸,且
报错只带函数名,很难定位到具体工具。
修复:
- `connections.save` 改为扁平 object schema,把「不带 id 即创建、带 id 即更新」
写进 schema/字段描述,二选一约束仍由运行时 `save` 按是否携带 `id` 分流,行为
与之前一致。
- `agent_runtime` 的 function-calling 校验新增顶层关键字拦截
(oneOf/anyOf/allOf/enum/const/not),本地就报错并带上工具名与指针;嵌套层
(如 `properties.*` 内的 anyOf)不受影响。
验证:
- `cargo test -p navop_runtime --lib connections::` → 46 passed
- `cargo test -p agent_runtime --lib tools::spec` → 10 passed
- `cargo test -p main --bin navop
agent_runtime_tool_schemas_convert_to_function_calling` → 1 passed
- 新增回归契约:连接工具 schema 顶层 provider-safe;LLM 边界上所有已暴露工具都
必须能转换成 llm-connector 工具定义(旧代码下该测试必红)。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes the task-level failure
Invalid request: OpenAI: Invalid schema for function 'connections_save': schema must have type 'object' and not have 'oneOf'/'anyOf'/'allOf'/'enum'/'const'/'not' at the top levelreported by the built-in AI assistant when it tries to save a connection.Root cause is two-fold:
connections.savetool schema used a top-leveloneOf(plus a nestednot) to express "create or update". Providers require the tool-parameter schema to be a plainobjectat the root; a combinator there makes them reject the whole model request, not just this one tool — hence a task-level failure.validate_function_calling_schemaonly checked that the root was an object and that combinator branches were objects, so it happily let this schema through and the error only surfaced at the provider, where the message names the function but not the tool.Changes:
crates/navop_runtime/src/connections.rs:connections.savenow exposes a flat object schema. The "omitidto create, passid+patchto update" contract moved into the schema/field descriptions; the actual either/or rule is still enforced at runtime byConnectionToolHandler::savebranching onid, so behaviour is unchanged.crates/agent_runtime/src/tools/spec.rs: the function-calling validator now rejects the provider-unsupported keywords at the root (oneOf/anyOf/allOf/enum/const/not) and reports the tool name plus a JSON pointer. Nested usage (e.g.anyOfinsideproperties.*) stays allowed.llm-connectortool definition (the new boundary test inmain/src/public_mcp_runtime/agent_db_registry_tests.rsis red on the old code).Screenshot
How to Test
Run the targeted tests (all green locally on this branch):
Manual check: rebuild the app, then in the built-in AI ask it to save a connection (for example a MySQL connection). The task previously failed immediately with the
Invalid schema for function 'connections_save'error; now the tool call is accepted and the connection is created or updated.Checklist
cargo runfor story tests related to the changes.