Skip to content

fix(patch-tool): advertise per-mode required params in schema descriptions#15673

Closed
briandevans wants to merge 1 commit into
NousResearch:mainfrom
briandevans:fix/patch-tool-conditional-required-schema-15524
Closed

fix(patch-tool): advertise per-mode required params in schema descriptions#15673
briandevans wants to merge 1 commit into
NousResearch:mainfrom
briandevans:fix/patch-tool-conditional-required-schema-15524

Conversation

@briandevans

Copy link
Copy Markdown
Contributor

Problem

Strict LLM backends (e.g. kimi-k2.x, reported in #15524) omit conditionally-required parameters like old_string/new_string for replace mode because the PATCH_SCHEMA only declares required: ["mode"]. The model sees every other parameter as optional and skips them, resulting in runtime errors.

Root cause

JSON Schema has no standard way to express "required if another field equals X" that all providers accept. The obvious fix—anyOf at the parameters level—breaks at least three providers:

  • Anthropic API rejects anyOf/oneOf/allOf on tool parameter schemas (documented in tests/honcho_plugin/test_session.py:376)
  • Fireworks rejects the same
  • Kimi/Moonshot: agent/moonshot_schema.py has a sanitizer bug where anyOf causes it to strip type then re-add it, resulting in a schema Kimi rejects

Fix

Add explicit guidance in the descriptions — the only universally-accepted signalling mechanism:

  1. Top-level description restructured with REPLACE MODE and PATCH MODE sections, each listing REQUIRED PARAMETERS: ...
  2. Per-property description prefixed with REQUIRED when mode='replace' / REQUIRED when mode='patch' for the conditionally-required fields
  3. required array stays ["mode"] — no anyOf / oneOf

Tests

Added TestPatchSchemaShape (9 assertions) to tests/tools/test_file_tools.py that lock the schema shape and guard against regressions:

  • Verifies top-level description documents required params for both modes
  • Verifies each conditionally-required property has REQUIRED when mode= in its description
  • Verifies no anyOf/oneOf at parameters level
  • Verifies required == ["mode"]

All 32 tests pass.

Closes #15524

Copilot AI review requested due to automatic review settings April 25, 2026 14:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Improves the patch tool’s schema guidance for strict tool-calling LLM backends by explicitly documenting which parameters are required for each mode, without using conditional JSON Schema constructs that are rejected by some providers.

Changes:

  • Restructures PATCH_SCHEMA["description"] to clearly list required parameters for replace vs patch mode.
  • Prefixes conditionally-required parameter descriptions with REQUIRED when mode='…'.
  • Adds regression tests to lock the schema shape and ensure provider-compatibility constraints (e.g., no anyOf/oneOf, required == ["mode"]).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
tools/file_tools.py Updates PATCH_SCHEMA descriptions to advertise per-mode required parameters without changing validation structure.
tests/tools/test_file_tools.py Adds TestPatchSchemaShape to prevent regressions in schema wording/shape and to enforce provider-compat constraints.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/tools Tool registry, model_tools, toolsets tool/file File tools (read, write, patch, search) labels Apr 25, 2026
…tions

Models that enforce required-only constraints (e.g. kimi-k2.x) were
omitting old_string/new_string for replace mode and patch for patch mode
because the schema only declared required: ["mode"].

Add explicit "REQUIRED when mode='X'" markers to each conditionally-required
property description and a top-level "REQUIRED PARAMETERS: ..." summary for
each mode. Avoids anyOf/oneOf which break Anthropic, Fireworks, and
Kimi/Moonshot providers. Add TestPatchSchemaShape to lock the shape.

Fixes NousResearch#15524

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@briandevans briandevans force-pushed the fix/patch-tool-conditional-required-schema-15524 branch from 47c581b to 0826b4d Compare April 29, 2026 15:14
@briandevans

Copy link
Copy Markdown
Contributor Author

Rebased onto current origin/main (13c238327) — was 96h stale on a base from before the file-tools dedup fixes (a32d07529, ced8f44cd, 977d5f56c, a32b325d0) landed. Clean rebase, no conflicts; touched files are orthogonal to the dedup-cache changes.

Re-ran focused tests on the rebased head (0826b4d53):

  • tests/tools/test_file_tools.py::TestPatchSchemaShape — 9/9 pass
  • tests/tools/test_file_tools.py (full file) — 32/32 pass

The fix is unchanged from review: PATCH_SCHEMA still uses required: ["mode"] (provider-compatible) and the per-mode requirements are advertised in description strings so strict tool-calling backends (kimi-k2.x, Anthropic, Fireworks) don't silently omit old_string/new_string for replace mode or patch for patch mode.

@teknium1

teknium1 commented May 8, 2026

Copy link
Copy Markdown
Contributor

Salvaged onto current main in #22143 — merged as commit 8e4f3ba with your authorship preserved via rebase-merge (branch was 1198 commits behind). Trimmed the schema-shape test block from 9 assertions to 2 invariants per Teknium's direction; the actual schema change is exactly as you wrote it. Thanks @briandevans!

@alang166668-ui

Copy link
Copy Markdown

⚠️ File-mutation verifier: 3 file(s) were NOT modified this turn despite any wording above that may suggest otherwise. Run git status or read_file to confirm.
• concepts/automatic-organization.md — [patch] Could not find match for old_string
• concepts/lora.md — [patch] Could not find match for old_string
• concepts/rag-pipeline.md — [patch] Could not find match for old_string

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/tools Tool registry, model_tools, toolsets P2 Medium — degraded but workaround exists tool/file File tools (read, write, patch, search) type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: patch tool conditionally required parameters are systematically omitted

5 participants