Class: OllamaAgent::DiffPathValidator
- Inherits:
-
Object
- Object
- OllamaAgent::DiffPathValidator
- Defined in:
- lib/ollama_agent/diff_path_validator.rb
Overview
Validates unified diffs: hunk headers and path alignment with edit_file (applyability is patch –dry-run). rubocop:disable Metrics/ClassLength – normalization helpers live alongside validation
Constant Summary collapse
- CONTEXT_DIFF_HUNK =
Legacy context-diff hunks (‘— N,M —-`) are not unified diffs; models sometimes emit them by mistake.
/^\s*---\s+\d+\s*,\s*\d+\s*----\s*$/m
Class Method Summary collapse
- .call(diff, root, target_path) ⇒ Object
- .ensure_trailing_newline(diff) ⇒ Object
- .expand_escaped_newlines_when_no_real_newlines(diff) ⇒ Object
-
.normalize_diff(diff) ⇒ Object
Normalizes newlines and escaped “\n” sequences models sometimes send in tool args.
- .normalize_newlines(diff) ⇒ Object
- .split_glued_hunk_headers(diff) ⇒ Object
- .strip_cursor_patch_markers(diff) ⇒ Object
- .strip_trailing_commas_on_headers(diff) ⇒ Object
Instance Method Summary collapse
-
#initialize(diff, root, target_path) ⇒ DiffPathValidator
constructor
A new instance of DiffPathValidator.
-
#validate ⇒ String?
Error message, or nil if the diff is acceptable.
Constructor Details
#initialize(diff, root, target_path) ⇒ DiffPathValidator
Returns a new instance of DiffPathValidator.
56 57 58 59 60 |
# File 'lib/ollama_agent/diff_path_validator.rb', line 56 def initialize(diff, root, target_path) @diff = self.class.normalize_diff(diff) @root = File.(root) @target_path = target_path end |
Class Method Details
.call(diff, root, target_path) ⇒ Object
12 13 14 |
# File 'lib/ollama_agent/diff_path_validator.rb', line 12 def self.call(diff, root, target_path) new(diff, root, target_path).validate end |
.ensure_trailing_newline(diff) ⇒ Object
44 45 46 47 48 |
# File 'lib/ollama_agent/diff_path_validator.rb', line 44 def self.ensure_trailing_newline(diff) return diff if diff.empty? || diff.end_with?("\n") "#{diff}\n" end |
.expand_escaped_newlines_when_no_real_newlines(diff) ⇒ Object
30 31 32 33 34 |
# File 'lib/ollama_agent/diff_path_validator.rb', line 30 def self.(diff) return diff unless diff.include?("\\n") && !diff.include?("\n") diff.gsub("\\\\n", "\n").gsub("\\n", "\n") end |
.normalize_diff(diff) ⇒ Object
Normalizes newlines and escaped “\n” sequences models sometimes send in tool args.
17 18 19 20 21 22 23 24 |
# File 'lib/ollama_agent/diff_path_validator.rb', line 17 def self.normalize_diff(diff) d = normalize_newlines(diff.to_s) d = (d) d = strip_cursor_patch_markers(d) d = strip_trailing_commas_on_headers(d) d = split_glued_hunk_headers(d) ensure_trailing_newline(d) end |
.normalize_newlines(diff) ⇒ Object
26 27 28 |
# File 'lib/ollama_agent/diff_path_validator.rb', line 26 def self.normalize_newlines(diff) diff.gsub("\r\n", "\n").gsub("\r", "\n") end |
.split_glued_hunk_headers(diff) ⇒ Object
40 41 42 |
# File 'lib/ollama_agent/diff_path_validator.rb', line 40 def self.split_glued_hunk_headers(diff) diff.gsub(/(\S)\s(@@ -\d[^\n]*)/, "\\1\n\\2") end |
.strip_cursor_patch_markers(diff) ⇒ Object
50 51 52 53 54 |
# File 'lib/ollama_agent/diff_path_validator.rb', line 50 def self.strip_cursor_patch_markers(diff) # Multiline `/m` so `^` matches each line; strips Cursor-style trailers that are not valid patch input. diff.gsub(/^\s*\*\*\*\s*(?:Begin|End)\s+Patch\s*$/im, "") .gsub(/^\s*(?:Begin|End)\s+Patch\s*$/im, "") end |
.strip_trailing_commas_on_headers(diff) ⇒ Object
36 37 38 |
# File 'lib/ollama_agent/diff_path_validator.rb', line 36 def self.strip_trailing_commas_on_headers(diff) diff.gsub(/^((?:---|\+\+\+)[^\n]+),\s*$/m, "\\1") end |
Instance Method Details
#validate ⇒ String?
Returns error message, or nil if the diff is acceptable.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/ollama_agent/diff_path_validator.rb', line 63 def validate return "Diff is empty." if @diff.strip.empty? return "edit_file path is missing or empty." if @target_path.nil? || @target_path.to_s.strip.empty? err = context_diff_hunk_error return err if err err = header_order_error return err if err err = structure_error return err if err path_alignment_error end |