Skip to content

feat(patch): add 'did you mean?' feedback when patch fails to match - #13435

Merged
teknium1 merged 2 commits into
mainfrom
hermes/hermes-860394f5
Apr 21, 2026
Merged

feat(patch): add 'did you mean?' feedback when patch fails to match#13435
teknium1 merged 2 commits into
mainfrom
hermes/hermes-860394f5

Conversation

@teknium1

Copy link
Copy Markdown
Collaborator

Salvage of #2505 by @teyrebaz33, onto current main.

Summary

When the fuzzy patch engine can't find old_string, the error now includes a line-numbered snippet of the closest matching section(s) in the file — so the model can self-correct without a separate read_file round-trip.

Phase 1 of #536 (Aider-style self-correction reflection loop).

Changes

  • tools/fuzzy_match.py: new find_closest_lines() (SequenceMatcher, >0.3 threshold, top-3 with context) + format_no_match_hint() shared helper that only fires on genuine no-match errors (gates on startswith('Could not find') + match_count == 0).
  • tools/file_operations.py: patch_replace uses the helper.
  • tools/file_tools.py: legacy generic [Hint: old_string not found...] suppressed when the rich snippet is already attached — no double-hint.
  • tools/patch_parser.py: V4A patch mode (_validate_operations + _apply_update) now surfaces the same hint.
  • tools/skill_manager_tool.py: skill_manage patching uses the same helper.
  • 5 original tests + 7 new gating tests (ambiguous, drift, identical, non-zero count, None, no-similar, happy path).

Validation

Result
tests/tools/test_fuzzy_match.py 34/34
test_file_tools + test_patch_parser + test_skill_manager_tool 96/96
E2E (4 scenarios: no-match+similar, no-match+no-similar, ambiguous, success) OK
E2E V4A mode with non-matching hunk OK

Credit

Original work by @teyrebaz33 (#2505). Their commit is preserved with authorship intact. Closes #2505.

teyrebaz33 and others added 2 commits April 21, 2026 01:56
When patch_replace() cannot find old_string in a file, the error message
now includes the closest matching lines from the file with line numbers
and context. This helps the LLM self-correct without a separate read_file
call.

Implements Phase 1 of #536: enhanced patch error feedback with no
architectural changes.

- tools/fuzzy_match.py: new find_closest_lines() using SequenceMatcher
- tools/file_operations.py: attach closest-lines hint to patch errors
- tests/tools/test_fuzzy_match.py: 5 new tests for find_closest_lines
…nage

Follow-ups on top of @teyrebaz33's cherry-picked commit:

1. New shared helper format_no_match_hint() in fuzzy_match.py with a
   startswith('Could not find') gate so the snippet only appends to
   genuine no-match errors — not to 'Found N matches' (ambiguous),
   'Escape-drift detected', or 'identical strings' errors, which would
   all mislead the model.

2. file_tools.patch_tool suppresses the legacy generic '[Hint: old_string
   not found...]' string when the rich 'Did you mean?' snippet is
   already attached — no more double-hint.

3. Wire the same helper into patch_parser.py (V4A patch mode, both
   _validate_operations and _apply_update) and skill_manager_tool.py so
   all three fuzzy callers surface the hint consistently.

Tests: 7 new gating tests in TestFormatNoMatchHint cover every error
class (ambiguous, drift, identical, non-zero match count, None error,
no similar content, happy path). 34/34 test_fuzzy_match, 96/96
test_file_tools + test_patch_parser + test_skill_manager_tool pass.
E2E verified across all four scenarios: no-match-with-similar,
no-match-no-similar, ambiguous, success. V4A mode confirmed
end-to-end with a non-matching hunk.
@teknium1
teknium1 merged commit 5e6427a into main Apr 21, 2026
5 of 7 checks passed
@teknium1
teknium1 deleted the hermes/hermes-860394f5 branch April 21, 2026 09:03
@github-actions

Copy link
Copy Markdown
Contributor

🚨 CRITICAL Supply Chain Risk Detected

This PR contains a pattern that has been used in real supply chain attacks. A maintainer must review the flagged code carefully before merging.

🚨 CRITICAL: Install-hook file added or modified

These files can execute code during package installation or interpreter startup.

Files:

hermes_cli/setup.py

Scanner only fires on high-signal indicators: .pth files, base64+exec/eval combos, subprocess with encoded commands, or install-hook files. Low-signal warnings were removed intentionally — if you're seeing this comment, the finding is worth inspecting.

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.

2 participants