fix(proxy): Kimi-provider-fix. inline local $ref siblings in chat tool parameters / 内联 chat 工具参数中携带 sibling 的本地 $ref - #2106
Merged
BigPizzaV3 merged 1 commit intoSep 9, 2026
Conversation
Strict chat backends such as Kimi For Coding reject or ignore JSON Schema $ref values that carry sibling keys. When converting Responses API tool definitions to Chat Completions, resolve local #/$defs/ references and merge siblings over the resolved definition; cycle detection falls back to the original schema. Bare $ref parameter schemas no longer receive synthetic type/properties/required defaults.
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.
中文
背景
Codex 客户端发送的工具定义中,会出现 JSON Schema
$ref携带 sibling 关键字的形式,例如$defs里的{"$ref": "#/$defs/__schema2", "type": "string", "format": "uuid", "minLength": 1}。按 JSON Schema draft-07 及更早版本的语义,$ref的 sibling 会被直接忽略;严格的 OpenAI 兼容上游(如 Kimi For Coding)会拒绝或静默丢弃这类 schema,导致工具参数校验异常。同时,
normalize_chat_tool_parameters此前会无条件为 parameters 补type/properties/required默认值。当 parameters 本身是裸$ref时,补默认值反而人为制造了$refsibling。改动
$ref(对象仅含$ref一个键)时不再补type/properties/required默认值,避免人为制造 siblinginline_ref_siblings:递归遍历参数 schema,将携带 sibling 的本地#/$defs/引用展开为目标定义的副本,sibling 键覆盖定义中的同名键$defs别名链(裸$ref指向另一个$ref),内置循环检测;一旦发现环,整体回退为原 schema,不做任何内联(行为由测试锚定)测试
crates/codex-plus-core/tests/protocol_proxy.rs新增 10 个测试,覆盖:sibling 内联与覆盖优先级、别名链解析顺序、嵌套properties/items中的引用、循环引用不死循环、外部 / 未知 / 非对象目标保留、裸$ref不再被补默认值等。本地
cargo test -p codex-plus-core --test protocol_proxy87/87 通过;cargo fmt --check与cargo clippy对本次改动无新增告警。cargo test -p codex-plus-core全量中仅launcher的 1 个用例在本机失败(a_busy_floating_helper_port_fails_immediately_without_waiting,改动未触及 launcher 代码,为预存问题)。English
Background
Tool definitions sent by the Codex client may contain JSON Schema
$refvalues carrying sibling keys, e.g. inside$defs:{"$ref": "#/$defs/__schema2", "type": "string", "format": "uuid", "minLength": 1}. Under JSON Schema draft-07 and earlier, siblings of$refare ignored entirely; strict OpenAI-compatible upstreams (such as Kimi For Coding) reject or silently drop such schemas, which breaks tool-parameter validation.In addition,
normalize_chat_tool_parameterspreviously injectedtype/properties/requireddefaults unconditionally. Whenparametersitself is a bare$ref, those defaults create$refsiblings that never existed in the original schema.Changes
$refparameter schemas (objects whose only key is$ref) no longer receive synthetictype/properties/requireddefaults, so normalization never manufactures$refsiblings.inline_ref_siblings: recursively walks the parameter schema and expands local#/$defs/references that carry siblings into a copy of the resolved definition, with sibling keys overriding same-named definition keys.$defs(a bare$refpointing at another$ref) with cycle detection; if a cycle is found, the whole schema is returned untouched (behaviour pinned by tests).Testing
10 new tests in
crates/codex-plus-core/tests/protocol_proxy.rs, covering: sibling inlining and override precedence, alias-chain resolution order, refs nested insideproperties/items, cycle safety, preservation of external / unknown / non-object targets, and bare$refschemas staying default-free.Local
cargo test -p codex-plus-core --test protocol_proxypasses 87/87;cargo fmt --checkandcargo clippyreport no new warnings for this change. In the fullcargo test -p codex-plus-corerun, one pre-existinglaunchertest fails on this machine (a_busy_floating_helper_port_fails_immediately_without_waiting); the change does not touch launcher code.