okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
61c43ca
main
1//// A refused retrieval call answers with an error payload the model can 2//// correct, instead of ending the turn: subagents died whole on 3//// "run failed: LCM node not found in this session" after handing a 4//// transcript row seq to an LCM node tool. 5 6import albedo/daemon/conversation 7import albedo/daemon/family 8import albedo/harness/extensions 9import albedo/harness/extensions/lcm/memory as lcm_memory 10import albedo/harness/runtime 11import albedo/openai_api/types 12import gleam/dynamic/decode 13import gleam/json 14import gleam/option .{ None } 15import gleam/string 16import gleeunit/should 17 18fn host () -> #( runtime . Runtime , runtime . Session ) { 19let assert Ok ( host ) = 20runtime . start_with_config ( 21":memory:" , 22extensions . Config ([ lcm_memory . extension ()], [ "lcm-memory" ]), 23) 24let ledger = runtime . ledger ( host ) 25let assert Ok ( _ ) = conversation . initialise ( ledger ) 26let assert Ok ( _ ) = family . initialise ( ledger ) 27let assert Ok ( _ ) = 28conversation . create ( 29ledger , 30conversation . Info ( 31"tool-error-test" , 32"new session" , 33"/tmp" , 34"provider" , 35"model" , 36types . Responses , 37conversation . Idle , 38None , 39None , 40), 41) 42let assert Ok ( session ) = runtime . open_session ( host , "tool-error-test" , "/tmp" ) 43#( host , session ) 44} 45 46fn answer ( 47host : runtime . Runtime , 48session : runtime . Session , 49name : String , 50arguments : String , 51) -> String { 52// The regression is Ok against Error: a refused read must not fail the run. 53let assert Ok ( output ) = 54runtime . invoke ( 55host , 56session , 57types . ToolCall ( "call_1" , name , arguments ), 58types . any_images , 59) 60let assert types . ToolOutput ( _ , body , []) = output 61body 62} 63 64pub fn missing_lcm_node_answers_as_tool_output_test () -> Nil { 65let #( host , session ) = host () 66// 35049 is a transcript row seq, the exact confusion that killed a child. 67let body = answer ( host , session , "lcm_describe" , "{\"id\":35049}" ) 68let assert Ok ( reason ) = 69json . parse ( body , decode . field ( "error" , decode . string , decode . success )) 70string . contains ( reason , "LCM node 35049 not found" ) |> should . be_true 71string . contains ( reason , "transcript_read" ) |> should . be_true 72runtime . stop ( host ) 73} 74 75pub fn missing_summary_scope_answers_as_tool_output_test () -> Nil { 76let #( host , session ) = host () 77let body = 78answer ( 79host , 80session , 81"lcm_grep" , 82"{\"pattern\":\"needle\",\"summary_id\":7}" , 83) 84let assert Ok ( reason ) = 85json . parse ( body , decode . field ( "error" , decode . string , decode . success )) 86string . contains ( reason , "LCM node 7 not found" ) |> should . be_true 87runtime . stop ( host ) 88} 89 90pub fn answering_tools_still_answer_normally_test () -> Nil { 91let #( host , session ) = host () 92let body = answer ( host , session , "lcm_list" , "{}" ) 93let assert Ok ( total ) = 94json . parse ( body , decode . field ( "total" , decode . int , decode . success )) 95total |> should . equal ( 0 ) 96runtime . stop ( host ) 97}