okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
60cce3a
main
1// Proxy history and encoded provider-state IDs have malformed and truncated wire inputs the E2E flow cannot reliably generate. 2import albedo/harness/extensions/proxy/chat 3import albedo/openai_api/types 4import gleam/dynamic/decode 5import gleam/json 6import gleam/list 7import gleam/option .{ None , Some } 8import gleam/string 9 10fn parse ( body : String ) -> Result ( chat . Completion , String ) { 11chat . parse (<< body : utf8 >>) 12} 13 14fn inputs ( completion : chat . Completion ) -> List ( types . Input ) { 15list . map ( completion . history , fn ( entry ) { entry . input }) 16} 17 18pub fn tool_history_becomes_replay_and_tool_output_test () -> List ( types . Tool ) { 19let assert Ok ( completion ) = 20parse ( 21"{\"model\":\"p/m\",\"messages\":[{\"role\":\"user\",\"content\":\"go\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"c1\",\"type\":\"function\",\"function\":{\"name\":\"bash\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"c1\",\"content\":\"ok\"}],\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"bash\"}}]}" , 22) 23let assert [ 24types . User ( "go" ), 25types . Replay ( item ), 26types . ToolOutput ( "c1" , "ok" , []), 27] = inputs ( completion ) 28assert types . inspect_item ( 29item , 30decode . at ([ "tool_calls" ], decode . list ( decode . at ([ "id" ], decode . string ))), 31) 32== Ok ([ "c1" ]) 33let assert [ types . Tool ( "bash" , "" , _ , False )] = completion . request . tools 34} 35 36pub fn remote_images_are_refused_test () -> Nil { 37let assert Error ( message ) = 38parse ( 39"{\"model\":\"p/m\",\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"image_url\",\"image_url\":{\"url\":\"https://x/y.png\"}}]}]}" , 40) 41assert string . contains ( message , "data urls" ) 42} 43 44pub fn provider_state_rides_back_in_the_first_call_id_test () -> Nil { 45let carried = chat . carry ( responses_turn (), "cx" , types . Responses ) 46let assert [ first , second ] = carried . tool_calls 47assert string . starts_with ( first . id , "call_1__albedo__" ) 48assert second . id == "call_2" 49// Strict clients accept only [A-Za-z0-9_-] in ids. 50assert string . to_graphemes ( first . id ) 51|> list . all ( fn ( c ) { 52string . contains ( 53"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-" , 54c , 55) 56}) 57let assert Ok ( completion ) = parse ( echoed ( carried )) 58let assert [ _ , reasoning , call , first_result , second_result ] = 59completion . history 60// The native items return tagged with the profile that produced them. 61assert reasoning . provider == Some ( "cx" ) 62let assert types . Replay ( item ) = reasoning . input 63assert types . replay_protocol ( item ) == types . Responses 64assert types . inspect_item ( 65item , 66decode . at ([ "encrypted_content" ], decode . string ), 67) 68== Ok ( "opaque-state" ) 69assert call . provider == Some ( "cx" ) 70// Results point at the provider's own call ids again. 71assert first_result . input == types . ToolOutput ( "call_1" , "ok" , []) 72assert second_result . input == types . ToolOutput ( "call_2" , "ok" , []) 73} 74 75pub fn damaged_state_falls_back_to_portable_history_test () -> Nil { 76let assert Ok ( completion ) = 77parse ( 78"{\"model\":\"cx/m\",\"messages\":[{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"call_1__albedo__not-state\",\"type\":\"function\",\"function\":{\"name\":\"bash\",\"arguments\":\"{}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"call_1__albedo__not-state\",\"content\":\"ok\"}]}" , 79) 80let assert [ call , result ] = completion . history 81assert call . provider == None 82let assert types . Replay ( item ) = call . input 83assert types . inspect_item ( 84item , 85decode . at ([ "tool_calls" ], decode . list ( decode . at ([ "id" ], decode . string ))), 86) 87== Ok ([ "call_1" ]) 88assert result . input == types . ToolOutput ( "call_1" , "ok" , []) 89} 90 91/// Clients that normalize ids (LiteLLM #37849) must not corrupt a replay. 92/// Short cuts can remove only the zlib checksum and leave complete JSON, so 93/// every one replays portably instead of trusting unverified state. 94pub fn a_shortened_carried_id_replays_portably_test () -> Nil { 95let carried = chat . carry ( responses_turn (), "cx" , types . Responses ) 96let assert [ first , second ] = carried . tool_calls 97list . each ([ 1 , 2 , 3 , 4 , 5 , 6 ], fn ( n ) { 98let cut = string . drop_end ( first . id , n ) 99let shortened = 100types . Turn (.. carried , tool_calls : [ 101types . ToolCall (.. first , id : cut ), 102second , 103]) 104let assert Ok ( completion ) = parse ( echoed ( shortened )) 105let assert [ _ , call , first_result , _ ] = completion . history 106assert call . provider == None 107assert first_result . input == types . ToolOutput ( "call_1" , "ok" , []) 108}) 109} 110 111fn responses_turn () -> types . Turn { 112let assert Ok ( reasoning ) = 113json . parse ( 114"{\"type\":\"reasoning\",\"id\":\"rs_1\",\"summary\":[],\"encrypted_content\":\"opaque-state\"}" , 115types . replay_decoder ( types . Responses ), 116) 117let assert Ok ( call ) = 118json . parse ( 119"{\"type\":\"function_call\",\"call_id\":\"call_1\",\"name\":\"bash\",\"arguments\":\"{}\",\"status\":\"completed\"}" , 120types . replay_decoder ( types . Responses ), 121) 122types . Turn ( 123Some ( "r" ), 124[ reasoning , call ], 125[ 126types . ToolCall ( "call_1" , "bash" , "{}" ), 127types . ToolCall ( "call_2" , "bash" , "{}" ), 128], 129None , 130types . ToolCalls , 131None , 132[#( "call_1" , 0 ), #( "call_2" , 1 )], 133) 134} 135 136/// What a client sends back after this turn: plain chat with our ids. 137fn echoed ( turn : types . Turn ) -> String { 138let calls = 139turn . tool_calls 140|> list . map ( fn ( call ) { 141"{\"id\":\"" 142<> call . id 143<> "\",\"type\":\"function\",\"function\":{\"name\":\"bash\",\"arguments\":\"{}\"}}" 144}) 145|> string . join ( "," ) 146let results = 147turn . tool_calls 148|> list . map ( fn ( call ) { 149",{\"role\":\"tool\",\"tool_call_id\":\"" 150<> call . id 151<> "\",\"content\":\"ok\"}" 152}) 153|> string . concat 154"{\"model\":\"cx/m\",\"messages\":[{\"role\":\"user\",\"content\":\"go\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[" 155<> calls 156<> "]}" 157<> results 158<> "]}" 159}