@@ -5,10 +5,7 @@ use crate::{
5
5
use anyhow:: Context as _;
6
6
use std:: {
7
7
collections:: { HashMap , HashSet } ,
8
- sync:: {
9
- atomic:: { AtomicBool , Ordering } ,
10
- Arc ,
11
- } ,
8
+ sync:: Arc ,
12
9
vec,
13
10
} ;
14
11
@@ -92,7 +89,6 @@ pub struct HarmonyEncoding {
92
89
pub ( crate ) format_token_mapping : HashMap < FormattingToken , String > ,
93
90
pub ( crate ) stop_formatting_tokens : HashSet < FormattingToken > ,
94
91
pub ( crate ) stop_formatting_tokens_for_assistant_actions : HashSet < FormattingToken > ,
95
- pub ( crate ) conversation_has_function_tools : Arc < AtomicBool > ,
96
92
}
97
93
98
94
impl std:: fmt:: Debug for HarmonyEncoding {
@@ -191,8 +187,9 @@ impl HarmonyEncoding {
191
187
}
192
188
} )
193
189
} ) ;
194
- self . conversation_has_function_tools
195
- . store ( has_function_tools, Ordering :: Relaxed ) ;
190
+ let render_options = RenderOptions {
191
+ conversation_has_function_tools : has_function_tools,
192
+ } ;
196
193
let last_assistant_is_final = messages
197
194
. iter ( )
198
195
. rev ( )
@@ -217,9 +214,7 @@ impl HarmonyEncoding {
217
214
&& first_final_idx. is_some_and ( |first| * idx < first)
218
215
&& msg. channel . as_deref ( ) == Some ( "analysis" ) )
219
216
} )
220
- . try_for_each ( |( _, msg) | self . render_into ( msg, into) ) ;
221
- self . conversation_has_function_tools
222
- . store ( false , Ordering :: Relaxed ) ;
217
+ . try_for_each ( |( _, msg) | self . render_into ( msg, into, Some ( & render_options) ) ) ;
223
218
result?;
224
219
Ok ( ( ) )
225
220
}
@@ -305,18 +300,27 @@ impl HarmonyEncoding {
305
300
}
306
301
307
302
/// Render a single message into tokens.
308
- pub fn render ( & self , message : & Message ) -> anyhow:: Result < Vec < Rank > > {
303
+ pub fn render (
304
+ & self ,
305
+ message : & Message ,
306
+ render_options : Option < & RenderOptions > ,
307
+ ) -> anyhow:: Result < Vec < Rank > > {
309
308
let mut out = vec ! [ ] ;
310
- Render :: < Message > :: render ( self , message, & mut out) ?;
309
+ Render :: < Message > :: render ( self , message, & mut out, render_options ) ?;
311
310
Ok ( out)
312
311
}
313
312
314
313
/// Render a single message into the provided buffer.
315
- pub fn render_into < B > ( & self , message : & Message , into : & mut B ) -> anyhow:: Result < ( ) >
314
+ pub fn render_into < B > (
315
+ & self ,
316
+ message : & Message ,
317
+ into : & mut B ,
318
+ render_options : Option < & RenderOptions > ,
319
+ ) -> anyhow:: Result < ( ) >
316
320
where
317
321
B : Extend < Rank > ,
318
322
{
319
- Render :: < Message > :: render ( self , message, into)
323
+ Render :: < Message > :: render ( self , message, into, render_options )
320
324
}
321
325
}
322
326
@@ -772,14 +776,29 @@ impl HarmonyEncoding {
772
776
}
773
777
}
774
778
779
+ #[ derive( Clone , Copy , Debug , Default ) ]
780
+ pub struct RenderOptions {
781
+ pub conversation_has_function_tools : bool ,
782
+ }
783
+
775
784
trait Render < T : ?Sized > {
776
- fn render < B > ( & self , item : & T , into : & mut B ) -> anyhow:: Result < ( ) >
785
+ fn render < B > (
786
+ & self ,
787
+ item : & T ,
788
+ into : & mut B ,
789
+ render_options : Option < & RenderOptions > ,
790
+ ) -> anyhow:: Result < ( ) >
777
791
where
778
792
B : Extend < Rank > ;
779
793
}
780
794
781
795
impl Render < Message > for HarmonyEncoding {
782
- fn render < B > ( & self , message : & Message , into : & mut B ) -> anyhow:: Result < ( ) >
796
+ fn render < B > (
797
+ & self ,
798
+ message : & Message ,
799
+ into : & mut B ,
800
+ render_options : Option < & RenderOptions > ,
801
+ ) -> anyhow:: Result < ( ) >
783
802
where
784
803
B : Extend < Rank > ,
785
804
{
@@ -836,7 +855,7 @@ impl Render<Message> for HarmonyEncoding {
836
855
message. author. role
837
856
) ;
838
857
}
839
- Render :: < Content > :: render ( self , content, into) ?;
858
+ Render :: < Content > :: render ( self , content, into, render_options ) ?;
840
859
}
841
860
842
861
// If there is a tool call we should render a tool call token
@@ -851,23 +870,35 @@ impl Render<Message> for HarmonyEncoding {
851
870
852
871
// Dispatch Content variants to their specific Render implementations
853
872
impl Render < Content > for HarmonyEncoding {
854
- fn render < B > ( & self , content : & Content , into : & mut B ) -> anyhow:: Result < ( ) >
873
+ fn render < B > (
874
+ & self ,
875
+ content : & Content ,
876
+ into : & mut B ,
877
+ render_options : Option < & RenderOptions > ,
878
+ ) -> anyhow:: Result < ( ) >
855
879
where
856
880
B : Extend < Rank > ,
857
881
{
858
882
match content {
859
- Content :: Text ( text) => Render :: < TextContent > :: render ( self , text, into) ,
860
- Content :: SystemContent ( sys) => Render :: < SystemContent > :: render ( self , sys, into) ,
883
+ Content :: Text ( text) => Render :: < TextContent > :: render ( self , text, into, render_options) ,
884
+ Content :: SystemContent ( sys) => {
885
+ Render :: < SystemContent > :: render ( self , sys, into, render_options)
886
+ }
861
887
Content :: DeveloperContent ( dev) => {
862
- Render :: < crate :: chat:: DeveloperContent > :: render ( self , dev, into)
888
+ Render :: < crate :: chat:: DeveloperContent > :: render ( self , dev, into, render_options )
863
889
}
864
890
}
865
891
}
866
892
}
867
893
868
894
// Render plain text content
869
895
impl Render < TextContent > for HarmonyEncoding {
870
- fn render < B > ( & self , text : & TextContent , into : & mut B ) -> anyhow:: Result < ( ) >
896
+ fn render < B > (
897
+ & self ,
898
+ text : & TextContent ,
899
+ into : & mut B ,
900
+ _render_options : Option < & RenderOptions > ,
901
+ ) -> anyhow:: Result < ( ) >
871
902
where
872
903
B : Extend < Rank > ,
873
904
{
@@ -877,7 +908,12 @@ impl Render<TextContent> for HarmonyEncoding {
877
908
878
909
// Render system-specific content (model identity, instructions, effort)
879
910
impl Render < SystemContent > for HarmonyEncoding {
880
- fn render < B > ( & self , sys : & SystemContent , into : & mut B ) -> anyhow:: Result < ( ) >
911
+ fn render < B > (
912
+ & self ,
913
+ sys : & SystemContent ,
914
+ into : & mut B ,
915
+ render_options : Option < & RenderOptions > ,
916
+ ) -> anyhow:: Result < ( ) >
881
917
where
882
918
B : Extend < Rank > ,
883
919
{
@@ -923,7 +959,7 @@ impl Render<SystemContent> for HarmonyEncoding {
923
959
if channel_config. channel_required {
924
960
channels_header. push_str ( " Channel must be included for every message." ) ;
925
961
}
926
- if self . conversation_has_function_tools . load ( Ordering :: Relaxed ) {
962
+ if render_options . is_some_and ( |o| o . conversation_has_function_tools ) {
927
963
channels_header. push ( '\n' ) ;
928
964
channels_header. push_str (
929
965
"Calls to these tools must go to the commentary channel: 'functions'." ,
@@ -940,7 +976,12 @@ impl Render<SystemContent> for HarmonyEncoding {
940
976
941
977
// Render developer-specific content (instructions, tools)
942
978
impl Render < crate :: chat:: DeveloperContent > for HarmonyEncoding {
943
- fn render < B > ( & self , dev : & crate :: chat:: DeveloperContent , into : & mut B ) -> anyhow:: Result < ( ) >
979
+ fn render < B > (
980
+ & self ,
981
+ dev : & crate :: chat:: DeveloperContent ,
982
+ into : & mut B ,
983
+ _render_options : Option < & RenderOptions > ,
984
+ ) -> anyhow:: Result < ( ) >
944
985
where
945
986
B : Extend < Rank > ,
946
987
{
0 commit comments