@@ -554,6 +554,44 @@ const extract_all_code_block_patches = (params: {
554554
555555 code_blocks . sort ( ( a , b ) => a . start - b . start )
556556
557+ const xml_blocks : typeof code_blocks = [ ]
558+ const xml_file_tag_start_regex =
559+ / ^ \s * < ( [ \w - ] + ) \s + p a t h = (?: [ " ' ] ( [ ^ " ' ] + ) [ " ' ] | ( [ ^ > \s ] + ) ) /
560+ let in_xml_block = false
561+ let xml_start = - 1
562+ let xml_tag_name = ''
563+ for ( let i = 0 ; i < lines . length ; i ++ ) {
564+ const trimmed_line = lines [ i ] . trim ( )
565+
566+ const is_inside_markdown_block = code_blocks . some (
567+ ( b ) => i >= b . start && i < b . end
568+ )
569+ if ( is_inside_markdown_block ) continue
570+
571+ if ( ! in_xml_block ) {
572+ const match = trimmed_line . match ( xml_file_tag_start_regex )
573+ if ( match ) {
574+ in_xml_block = true
575+ xml_start = i
576+ xml_tag_name = match [ 1 ]
577+ }
578+ } else {
579+ const xml_file_tag_end_regex = new RegExp ( `^\\s*<\\/${ xml_tag_name } >` )
580+ if ( xml_file_tag_end_regex . test ( trimmed_line ) ) {
581+ xml_blocks . push ( { start : xml_start , end : i , type : 'xml_file' } )
582+ in_xml_block = false
583+ }
584+ }
585+ }
586+ if ( in_xml_block ) {
587+ xml_blocks . push ( {
588+ start : xml_start ,
589+ end : lines . length - 1 ,
590+ type : 'xml_file'
591+ } )
592+ }
593+ code_blocks . push ( ...xml_blocks )
594+ code_blocks . sort ( ( a , b ) => a . start - b . start )
557595 // First, identify all files that have explicit diff blocks.
558596 const files_with_diffs = new Set < string > ( )
559597 const diff_block_patches = new Map < number , Diff [ ] > ( )
@@ -620,7 +658,10 @@ const extract_all_code_block_patches = (params: {
620658 // Process each found code block in order of appearance.
621659 for ( let i = 0 ; i < code_blocks . length ; i ++ ) {
622660 const block = code_blocks [ i ]
623- const block_lines = lines . slice ( block . start + 1 , block . end )
661+ const block_lines =
662+ block . type == 'xml_file'
663+ ? lines . slice ( block . start , block . end + 1 )
664+ : lines . slice ( block . start + 1 , block . end )
624665
625666 if ( block . type != 'diff' && block . type != 'patch' ) {
626667 const has_truncation_comment = block_lines . some ( ( line ) => {
@@ -639,7 +680,13 @@ const extract_all_code_block_patches = (params: {
639680 }
640681 }
641682
642- const text_before = lines . slice ( last_block_end + 1 , block . start ) . join ( '\n' )
683+ const text_before = lines
684+ . slice ( last_block_end + 1 , block . start )
685+ . filter ( ( line ) => {
686+ const trimmed = line . trim ( )
687+ return trimmed != '<files>' && trimmed != '</files>'
688+ } )
689+ . join ( '\n' )
643690
644691 if ( block . type == 'diff' || block . type == 'patch' ) {
645692 if ( text_before . trim ( ) ) {
@@ -729,7 +776,13 @@ const extract_all_code_block_patches = (params: {
729776 }
730777
731778 if ( last_block_end < lines . length - 1 ) {
732- const text_after = lines . slice ( last_block_end + 1 ) . join ( '\n' )
779+ const text_after = lines
780+ . slice ( last_block_end + 1 )
781+ . filter ( ( line ) => {
782+ const trimmed = line . trim ( )
783+ return trimmed != '<files>' && trimmed != '</files>'
784+ } )
785+ . join ( '\n' )
733786 if ( text_after . trim ( ) ) {
734787 items . push ( { type : 'text' , content : text_after . trim ( ) } )
735788 }
@@ -810,40 +863,23 @@ export const extract_diffs = (params: {
810863 code_block_regex . test ( line . trim ( ) )
811864 )
812865
813- if ( uses_code_blocks ) {
866+ const xml_file_tag_start_regex =
867+ / ^ \s * < ( [ \w - ] + ) \s + p a t h = (?: [ " ' ] ( [ ^ " ' ] + ) [ " ' ] | ( [ ^ > \s ] + ) ) /
868+ const uses_xml_blocks = lines . some ( ( line ) =>
869+ xml_file_tag_start_regex . test ( line . trim ( ) )
870+ )
871+
872+ if ( uses_code_blocks || uses_xml_blocks ) {
814873 return extract_all_code_block_patches ( {
815874 normalized_text,
816875 is_single_root : params . is_single_root
817876 } )
818- } else {
819- const xml_file_tag_start_regex =
820- / ^ \s * < ( [ \w - ] + ) \s + p a t h = (?: [ " ' ] ( [ ^ " ' ] + ) [ " ' ] | ( [ ^ > \s ] + ) ) /
821- const start_match =
822- lines . length > 0 ? lines [ 0 ] . trim ( ) . match ( xml_file_tag_start_regex ) : null
823-
824- if ( start_match ) {
825- const tag_name = start_match [ 1 ]
826- const xml_file_tag_end_regex = new RegExp ( `^\\s*<\\/${ tag_name } >` )
827- if (
828- lines . length >= 2 &&
829- xml_file_tag_end_regex . test ( lines [ lines . length - 1 ] . trim ( ) ) &&
830- lines . some ( ( l ) => l . trim ( ) . startsWith ( '@@' ) )
831- ) {
832- const result = convert_code_block_to_new_file_diff ( {
833- lines : lines ,
834- is_single_root : params . is_single_root
835- } )
836- if ( result ) {
837- return [ result ]
838- }
839- }
840- }
841-
842- return parse_multiple_raw_patches ( {
843- all_lines : lines ,
844- is_single_root : params . is_single_root
845- } )
846877 }
878+
879+ return parse_multiple_raw_patches ( {
880+ all_lines : lines ,
881+ is_single_root : params . is_single_root
882+ } )
847883}
848884
849885export const extract_paths_from_lines = (
0 commit comments