fix: normalize tool schemas for Kimi/Moonshot#2480
Closed
idling11 wants to merge 3 commits into
Closed
Conversation
Contributor
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
wavezhang
pushed a commit
to wavezhang/DeepSeek-TUI
that referenced
this pull request
Jun 1, 2026
5 tasks
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.
Summary
Normalize tool function schemas for Kimi Coding Plan: push
typefrom the parent object into each
anyOf/oneOfitem, matchingKimi's stricter JSON Schema validation.
Closes: #2438
Problem
Kimi's API rejects schemas where
typesits alongsideanyOfatthe root level. Every request — even "hi" — fails with HTTP 400:
type should be defined in anyOf items instead of the parent schema
Fix
schema_sanitize.rs: newsanitize_for_kimi()walks tool schemasand rewrites
{"type":"object", "anyOf":[...]}→{"anyOf":[ {"type":"object",...}, {"type":"object",...}]}chat.rs: auto-applies the normalization forApiProvider::Moonshotwhen serializing tools before each request
Files Changed
crates/tui/src/tools/schema_sanitize.rssanitize_for_kimi+ 2 testscrates/tui/src/client/chat.rsTests
kimi_sanitize_pushes_type_into_anyof_items✅kimi_sanitize_leaves_pure_object_untouched✅Greptile Summary
This PR adds a
sanitize_for_kimi()schema normalization pass that rewrites{\"type\": \"object\", \"anyOf\": [...]}into{\"anyOf\": [{\"type\": \"object\", ...}]}so Kimi/Moonshot's stricter JSON Schema validation accepts tool definitions. The fix is applied in bothcreate_message_chatandhandle_chat_completion_streamfor theMoonshotprovider.schema_sanitize.rsgainssanitize_for_kimi(): a recursive walk that stripstypefrom any parent carryinganyOf/oneOfand injects it into typeless child items.chat.rsapplies the sanitizer to every tool'sparametersfield before serializing the request body, in both the blocking and streaming code paths.Confidence Score: 4/5
Safe to merge for the common case; schemas with deeply nested anyOf items may not be fully normalized due to the top-down traversal order in sanitize_for_kimi().
The sanitizer walks schemas top-down, injecting type into anyOf items and then immediately recursing into those same items. An item that received an injected type but also carries its own nested anyOf will be re-processed by the recursive pass, which removes the freshly-injected type, leaving the item typeless so Kimi would still reject it.
crates/tui/src/tools/schema_sanitize.rs — the traversal order in sanitize_for_kimi() and the completeness of its tests warrant a second look before shipping to users with complex tool schemas.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A["Tool request (Moonshot provider)"] --> B["tool_to_chat_for_base_url()"] B --> C{"ApiProvider::Moonshot?"} C -- No --> E["body[tools] = chat_tools"] C -- Yes --> D["For each tool:\nget .function.parameters"] D --> F["sanitize_for_kimi(parameters)"] F --> G{"schema is Object\nwith type + anyOf/oneOf?"} G -- No --> H["Recurse into\nall child values"] G -- Yes --> I["Remove type from parent\nInject into typeless items"] I --> H H --> J{"Child is\nObject or Array?"} J -- Object --> G J -- Array --> K["Recurse into\neach element"] K --> G J -- Other --> L["Leaf - skip"] H --> EReviews (3): Last reviewed commit: "fix: collapse nested ifs to satisfy clip..." | Re-trigger Greptile