From d97608eecf2c0396a1aa0e60d8a72376b4217a4a Mon Sep 17 00:00:00 2001 From: Jessica Mulein Date: Wed, 10 Jun 2026 21:07:01 -0700 Subject: [PATCH] fix(tools): ReadRange resilience for weak model inputs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - is_provided() now rejects common junk values ('N/A', 'null', 'none') that small models pass instead of real text markers - ReadRange auto-fallback: when start_text/end_text are missing or junk but the file is already in editable or read-only context, show the whole file (@000 → 000@) instead of erroring. Files not in context still get the strict error. Reduces wasted turns on quantized local models (qwen3.6:27b-q4_K_M) that struggle with ReadRange's start_text/end_text contract. --- cecli/tools/read_range.py | 40 ++++++++++++++++++++++++------------ cecli/tools/utils/helpers.py | 2 +- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/cecli/tools/read_range.py b/cecli/tools/read_range.py index 413a111b61f..3c426215e70 100644 --- a/cecli/tools/read_range.py +++ b/cecli/tools/read_range.py @@ -128,20 +128,34 @@ def execute(cls, coder, show, **kwargs): # Validate arguments for this operation if not is_provided(start_text) or not is_provided(end_text): - error_outputs.append( - cls.format_error( - coder, - ( - f"Show operation {show_index + 1}: Provide both 'start_text' and" - " 'end_text'." - ), - file_path, - start_text, - end_text, - show_index, + # Auto-fallback: if the file is in editable context and markers are + # missing/junk, show the whole file instead of erroring. + abs_fnames = getattr(coder, "abs_fnames", set()) + abs_ro = getattr(coder, "abs_read_only_fnames", set()) + try: + abs_path_check = coder.abs_root_path(file_path) if file_path else None + except Exception: + abs_path_check = None + if abs_path_check and ( + abs_path_check in abs_fnames or abs_path_check in abs_ro + ): + start_text = "@000" + end_text = "000@" + else: + error_outputs.append( + cls.format_error( + coder, + ( + f"Show operation {show_index + 1}: Provide both 'start_text' and" + " 'end_text'." + ), + file_path, + start_text, + end_text, + show_index, + ) ) - ) - continue + continue if start_text.count("\n") > 4 or end_text.count("\n") > 4: error_outputs.append( diff --git a/cecli/tools/utils/helpers.py b/cecli/tools/utils/helpers.py index f05e2eda8f9..0839457ac9d 100644 --- a/cecli/tools/utils/helpers.py +++ b/cecli/tools/utils/helpers.py @@ -21,7 +21,7 @@ def is_provided(value, *, treat_zero_as_missing=False): """ if value is None: return False - if isinstance(value, str) and value == "": + if isinstance(value, str) and value.strip().lower() in ("", "n/a", "null", "none"): return False if treat_zero_as_missing and isinstance(value, (int, float)) and value == 0: return False