Parses the LLM response content (containing the patch) into a list of tuples, where each tuple contains the file path and the PatchAction object.
(self)
| 218 | gpt_prompts = PatchPrompts() |
| 219 | |
| 220 | def get_edits(self) -> List[EditResult]: |
| 221 | """ |
| 222 | Parses the LLM response content (containing the patch) into a list of |
| 223 | tuples, where each tuple contains the file path and the PatchAction object. |
| 224 | """ |
| 225 | content = self.partial_response_content |
| 226 | if not content or not content.strip(): |
| 227 | return [] |
| 228 | |
| 229 | # Check for patch sentinels |
| 230 | lines = content.splitlines() |
| 231 | if ( |
| 232 | len(lines) < 2 |
| 233 | or not _norm(lines[0]).startswith("*** Begin Patch") |
| 234 | # Allow flexible end, might be EOF or just end of stream |
| 235 | # or _norm(lines[-1]) != "*** End Patch" |
| 236 | ): |
| 237 | # Tolerate missing sentinels if content looks like a patch action |
| 238 | is_patch_like = any( |
| 239 | _norm(line).startswith( |
| 240 | ("@@", "*** Update File:", "*** Add File:", "*** Delete File:") |
| 241 | ) |
| 242 | for line in lines |
| 243 | ) |
| 244 | if not is_patch_like: |
| 245 | # If it doesn't even look like a patch, return empty |
| 246 | self.io.tool_warning("Response does not appear to be in patch format.") |
| 247 | return [] |
| 248 | # If it looks like a patch but lacks sentinels, try parsing anyway but warn. |
| 249 | self.io.tool_warning( |
| 250 | "Patch format warning: Missing '*** Begin Patch'/'*** End Patch' sentinels." |
| 251 | ) |
| 252 | start_index = 0 |
| 253 | else: |
| 254 | start_index = 1 # Skip "*** Begin Patch" |
| 255 | |
| 256 | # Identify files needed for context lookups during parsing |
| 257 | needed_paths = identify_files_needed(content) |
| 258 | current_files: Dict[str, str] = {} |
| 259 | for rel_path in needed_paths: |
| 260 | abs_path = self.abs_root_path(rel_path) |
| 261 | try: |
| 262 | # Use io.read_text to handle potential errors/encodings |
| 263 | file_content = self.io.read_text(abs_path) |
| 264 | if file_content is None: |
| 265 | raise DiffError( |
| 266 | f"File referenced in patch not found or could not be read: {rel_path}" |
| 267 | ) |
| 268 | current_files[rel_path] = file_content |
| 269 | except FileNotFoundError: |
| 270 | raise DiffError(f"File referenced in patch not found: {rel_path}") |
| 271 | except IOError as e: |
| 272 | raise DiffError(f"Error reading file {rel_path}: {e}") |
| 273 | |
| 274 | try: |
| 275 | # Parse the patch text using adapted logic |
| 276 | patch_obj = self._parse_patch_text(lines, start_index, current_files) |
| 277 | # Convert Patch object actions dict to a list of tuples (path, action) |
nothing calls this directly
no test coverage detected