@@ -76,16 +76,49 @@ pub fn parse_text(text: &str, options: &ParseOptions<'_>) -> ParseOutcome {
7676 let diagnostics = scan. diagnostics ;
7777
7878 if calls. is_empty ( ) {
79- let joined = parts. join ( "\n " ) ;
80- let ( cleaned, glm_calls) = grammar:: glm:: parse_and_strip ( & joined) ;
79+ let ( cleaned, glm_calls) = parse_unprotected_glm ( text, & scan. kept ) ;
8180 if !glm_calls. is_empty ( ) {
8281 calls = glm_calls;
83- return finalize ( cleaned. trim ( ) . to_string ( ) , calls, diagnostics, options) ;
82+ return finalize ( cleaned, calls, diagnostics, options) ;
8483 }
8584 }
8685 finalize ( parts. join ( "\n " ) , calls, diagnostics, options)
8786}
8887
88+ /// Parses GLM calls outside fences and keeps fenced examples in the narrative.
89+ fn parse_unprotected_glm ( text : & str , kept : & [ Range < usize > ] ) -> ( String , Vec < ParsedToolCall > ) {
90+ let protected = protected:: fence_ranges ( text) ;
91+ let mut parts = Vec :: new ( ) ;
92+ let mut calls = Vec :: new ( ) ;
93+ for range in kept {
94+ let mut cursor = range. start ;
95+ let mut cleaned = String :: new ( ) ;
96+ for fence in & protected {
97+ if fence. end <= cursor || fence. start >= range. end {
98+ continue ;
99+ }
100+ if cursor < fence. start {
101+ let ( part, parsed) = grammar:: glm:: parse_and_strip ( & text[ cursor..fence. start ] ) ;
102+ cleaned. push_str ( & part) ;
103+ calls. extend ( parsed) ;
104+ }
105+ let end = fence. end . min ( range. end ) ;
106+ cleaned. push_str ( & text[ cursor. max ( fence. start ) ..end] ) ;
107+ cursor = end;
108+ }
109+ if cursor < range. end {
110+ let ( part, parsed) = grammar:: glm:: parse_and_strip ( & text[ cursor..range. end ] ) ;
111+ cleaned. push_str ( & part) ;
112+ calls. extend ( parsed) ;
113+ }
114+ let cleaned = cleaned. trim ( ) ;
115+ if !cleaned. is_empty ( ) {
116+ parts. push ( cleaned. to_string ( ) ) ;
117+ }
118+ }
119+ ( parts. join ( "\n " ) , calls)
120+ }
121+
89122/// Name resolution and the diagnostics it produces.
90123fn finalize (
91124 text : String ,
0 commit comments