@@ -22,22 +22,30 @@ type TestResult = std::result::Result<(), Box<dyn std::error::Error + Send + Syn
2222fn fragmented_chat_tool_names_are_complete_in_cross_format_streams ( ) -> TestResult {
2323 let engine = TranslationEngine :: default ( ) ;
2424 for target in [ WireFormat :: AnthropicMessages , WireFormat :: OpenAiResponses ] {
25- for arguments in [ "{}" , "" ] {
25+ for ( early_arguments , arguments) in [ ( "{" , "}" ) , ( "" , "{}" ) , ( "" , "" ) ] {
2626 let mut state = StreamTranslationState :: new ( WireFormat :: OpenAiChat , target) ;
2727 let mut events = Vec :: new ( ) ;
2828 for event in [
2929 json ! ( { "choices" : [ { "delta" : { "tool_calls" : [ { "index" : 0 ,
3030 "id" : "call_weather" , "function" : { "name" : "wea" , "arguments" : "" } } ] } } ] } ) ,
31+ json ! ( { "choices" : [ { "delta" : { "tool_calls" : [ { "index" : 0 ,
32+ "function" : { "arguments" : early_arguments} } ] } } ] } ) ,
3133 json ! ( { "choices" : [ { "delta" : { "tool_calls" : [ { "index" : 0 ,
3234 "function" : { "name" : "ther" , "arguments" : arguments} } ] } } ] } ) ,
3335 json ! ( { "choices" : [ { "delta" : { } , "finish_reason" : "tool_calls" } ] } ) ,
3436 ] {
35- events. extend ( engine. translate_event (
36- & mut state,
37- WireFormat :: OpenAiChat ,
38- target,
39- & event,
40- ) ?) ;
37+ let translated =
38+ engine. translate_event ( & mut state, WireFormat :: OpenAiChat , target, & event) ?;
39+ if event[ "choices" ] [ 0 ] [ "finish_reason" ] . is_null ( ) {
40+ assert ! (
41+ translated. iter( ) . all( |event| {
42+ event[ "type" ] != "content_block_start"
43+ && event[ "type" ] != "response.output_item.added"
44+ } ) ,
45+ "tool name must not be announced before completion"
46+ ) ;
47+ }
48+ events. extend ( translated) ;
4149 }
4250 events. extend ( engine. finish_stream ( & mut state, target) ?) ;
4351 let names: Vec < _ > = events
@@ -56,6 +64,17 @@ fn fragmented_chat_tool_names_are_complete_in_cross_format_streams() -> TestResu
5664 vec ! [ "weather" , "weather" ]
5765 } ;
5866 assert_eq ! ( names, expected, "{target:?}, arguments={arguments:?}" ) ;
67+ let emitted_arguments: String = events
68+ . iter ( )
69+ . filter_map ( |event| {
70+ if event[ "type" ] == "response.function_call_arguments.delta" {
71+ event[ "delta" ] . as_str ( )
72+ } else {
73+ event[ "delta" ] [ "partial_json" ] . as_str ( )
74+ }
75+ } )
76+ . collect ( ) ;
77+ assert_eq ! ( emitted_arguments, format!( "{early_arguments}{arguments}" ) ) ;
5978 }
6079 }
6180 Ok ( ( ) )
@@ -2114,24 +2133,28 @@ fn translated_responses_text_and_tool_events_keep_item_identity_until_done() ->
21142133 . iter ( )
21152134 . filter ( |event| event[ "output_index" ] == index)
21162135 . collect :: < Vec < _ > > ( ) ;
2136+ let mut expected_types = vec ! [
2137+ "response.output_item.added" ,
2138+ "response.function_call_arguments.delta" ,
2139+ "response.function_call_arguments.done" ,
2140+ "response.output_item.done" ,
2141+ ] ;
2142+ if source == WireFormat :: AnthropicMessages {
2143+ expected_types. insert ( 2 , "response.function_call_arguments.delta" ) ;
2144+ }
21172145 assert_eq ! (
21182146 tool_events
21192147 . iter( )
21202148 . map( |event| event[ "type" ] . as_str( ) . unwrap_or_default( ) )
21212149 . collect:: <Vec <_>>( ) ,
2122- [
2123- "response.output_item.added" ,
2124- "response.function_call_arguments.delta" ,
2125- "response.function_call_arguments.delta" ,
2126- "response.function_call_arguments.done" ,
2127- "response.output_item.done"
2128- ]
2150+ expected_types
21292151 ) ;
2130- let done = tool_events[ 3 ] ;
2152+ let done = tool_events[ tool_events . len ( ) - 2 ] ;
21312153 assert_eq ! ( done[ "name" ] , name) ;
21322154 assert_eq ! ( done[ "arguments" ] , arguments) ;
2133- assert_eq ! ( tool_events[ 4 ] [ "item" ] [ "id" ] , items[ & index] [ "id" ] ) ;
2134- assert_eq ! ( tool_events[ 4 ] [ "item" ] [ "call_id" ] , call_id) ;
2155+ let item_done = tool_events[ tool_events. len ( ) - 1 ] ;
2156+ assert_eq ! ( item_done[ "item" ] [ "id" ] , items[ & index] [ "id" ] ) ;
2157+ assert_eq ! ( item_done[ "item" ] [ "call_id" ] , call_id) ;
21352158 }
21362159 let completed = events. last ( ) . ok_or ( "missing response completion" ) ?;
21372160 assert_eq ! ( completed[ "type" ] , "response.completed" ) ;
0 commit comments