mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 03:14:56 +07:00
Transform JSON schemas for Google AI tools to use `nullable: true` instead of `type: ["type", "null"]`, which is not supported by the Gemini API. Additionally, convert multi-type arrays (e.g., `type: ["string", "number"]`) to `anyOf` constraints, as Gemini expects a single string for the `type` field. This handles recursive transformation of properties, items, definitions, and logical operators, safely merging conflicting `anyOf` and `allOf` constraints. Closes https://github.com/zed-industries/zed/issues/44875 Closes https://github.com/zed-industries/zed/issues/32429 Release Notes: - Fixed a bug where using Gemini with certain tools (especially via MCP) resulted in "Invalid JSON payload received" errors due to incompatible JSON schema formats. ## Testing Added unit tests in `crates/language_model/src/tool_schema.rs` covering nullability, multi-types, and `oneOf` conversions. ### Manual Testing with MCP Test Server The [MCP Test Server](https://github.com/dastrobu/mcp-test-server) was used to verify these edge cases with Gemini 3 Flash. #### Setup 1. Install the test server: `cargo install --git https://github.com/dastrobu/mcp-test-server` 2. Add to Zed `settings.json`: ```json "context_servers": [ { "command": "mcp-test-server" } ] ``` Use the following pattern in a chat window: ``` call the add_tool function to create a new tool: weather with input schema: { "type": "object", "properties": { "city": { "type": ["string", "null"] } } } ``` Afterwards: ... ``` call it ``` Without fix: <img width="671" height="448" alt="image" src="https://github.com/user-attachments/assets/e8b6e7bd-d431-4a7e-8c9a-fff73d82127d" /> With fix: <img width="729" height="334" alt="image" src="https://github.com/user-attachments/assets/eb758765-4c34-4915-a8cf-dd4bfb993619" /> #### Cases verified manually: **1. Nullability in properties** - **Input:** ```json { "type": "object", "properties": { "city": { "type": ["string", "null"] } } } ``` - **Converted:** ```json { "type": "object", "properties": { "city": { "type": "string", "nullable": true } } } ``` **2. Multi-type properties** - **Input:** ```json { "type": "object", "properties": { "city": { "type": ["string", "number"] } } } ``` - **Converted:** ```json { "type": "object", "properties": { "city": { "anyOf": [ { "type": "string" }, { "type": "number" } ] } } } ``` **3. Explicit `anyOf` with nullability** - **Input:** ```json { "type": "object", "properties": { "city": { "anyOf": [ { "type": "string" }, { "type": "null" } ] } } } ``` - **Converted:** ```json { "type": "object", "properties": { "city": { "anyOf": [ { "type": "string" }, { "nullable": true } ] } } } ``` **4. Conflicting `anyOf` sources (Multi-type + existing `anyOf`)** - **Input:** ```json { "type": "object", "properties": { "city": { "type": ["string", "number"], "anyOf": [ { "minLength": 5 } ] } } } ``` - **Converted:** ```json { "type": "object", "properties": { "city": { "allOf": [ { "anyOf": [{ "minLength": 5 }] }, { "anyOf": [{ "type": "string" }, { "type": "number" }] } ] } } } ``` Co-authored-by: Richard Feldman <richard@zed.dev>
28 lines
597 B
TOML
28 lines
597 B
TOML
[package]
|
|
name = "language_model_core"
|
|
version = "0.1.0"
|
|
edition.workspace = true
|
|
publish.workspace = true
|
|
license = "GPL-3.0-or-later"
|
|
|
|
[lints]
|
|
workspace = true
|
|
|
|
[lib]
|
|
path = "src/language_model_core.rs"
|
|
doctest = false
|
|
|
|
[dependencies]
|
|
anyhow.workspace = true
|
|
async-lock.workspace = true
|
|
cloud_llm_client.workspace = true
|
|
futures.workspace = true
|
|
gpui_shared_string.workspace = true
|
|
http_client.workspace = true
|
|
log.workspace = true
|
|
partial-json-fixer.workspace = true
|
|
schemars.workspace = true
|
|
serde.workspace = true
|
|
serde_json.workspace = true
|
|
strum.workspace = true
|
|
thiserror.workspace = true
|