Skip to content

fix(agent): connections.save 的 function-calling schema 去掉顶层 oneOf - #245

Merged
feigeCode merged 2 commits into
mainfrom
fix/connections-save-llm-schema
Sep 20, 2026
Merged

feigeCode merged 2 commits into
mainfrom
fix/connections-save-llm-schema

Conversation

@feigeCode

Copy link
Copy Markdown
Owner

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 level reported by the built-in AI assistant when it tries to save a connection.

Root cause is two-fold:

  1. The connections.save tool schema used a top-level oneOf (plus a nested not) to express "create or update". Providers require the tool-parameter schema to be a plain object at the root; a combinator there makes them reject the whole model request, not just this one tool — hence a task-level failure.
  2. Our own validate_function_calling_schema only 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.save now exposes a flat object schema. The "omit id to create, pass id + patch to update" contract moved into the schema/field descriptions; the actual either/or rule is still enforced at runtime by ConnectionToolHandler::save branching on id, 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. anyOf inside properties.*) stays allowed.
  • Regression tests: connection tool schemas must be provider-safe at the root, and every tool exposed to the model must convert to an llm-connector tool definition (the new boundary test in main/src/public_mcp_runtime/agent_db_registry_tests.rs is red on the old code).

Screenshot

Before After
N/A (no UI change, only the tool schema sent to the model) N/A

How to Test

Run the targeted tests (all green locally on this branch):

cargo test -p navop_runtime --lib connections::
cargo test -p agent_runtime --lib tools::spec
cargo test -p main --bin navop agent_runtime_tool_schemas_convert_to_function_calling

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

  • I have read the CONTRIBUTING document and followed the guidelines.
  • Reviewed the changes in this PR and confirmed AI generated code (If any) is accurate.
  • Passed cargo run for story tests related to the changes.
  • Tested macOS, Windows and Linux platforms performance (if the change is platform-specific)

feigeCode and others added 2 commits September 20, 2026 14:52
现象:内置 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 工具定义(旧代码下该测试必红)。
@feigeCode
feigeCode merged commit bd7a8dd into main Sep 20, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant