okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
61c43ca
main
1"""Retrieval keeps exact counts, scoped pages, and Unicode text offsets through the daemon.""" 2 3import json 4import unittest 5 6from harness import Albedo ,Provider ,Reply ,python ,text 7 8 9class RetrievalTests (unittest .TestCase ): 10def setUp (self ): 11self .code = None 12self .tool = None 13self .arguments = None 14 15def script (request ): 16last = request ["input" ][- 1 ] 17if last .get ("type" )== "function_call_output" : 18return text ("done" ) 19if "<newly-evicted-history>" in str (last .get ("content" ,"" )): 20return text ("fold-only Café" ) 21if self .code is not None : 22return python (self .code ) 23if self .tool is not None : 24return Reply ( 25"python" ,tool_name = self .tool ,tool_arguments = self .arguments 26 ) 27return text ("done" ) 28 29self .provider = Provider (script ) 30self .addCleanup (self .provider .close ) 31self .app = Albedo (self .provider ,protocol = "responses" ) 32self .app .__enter__ () 33self .addCleanup (self .app .__exit__ ,None ,None ,None ) 34self .session = self .app .session () 35 36def turn (self ,session ,prompt ): 37before = len (self .provider .requests ) 38self .app .prompt (session ,prompt ).close () 39self .app .idle (session ) 40return [entry ["request" ]for entry in self .provider .requests [before :]] 41 42def retrieve (self ,name ,arguments ): 43self .tool ,self .arguments = name ,arguments 44requests = self .turn (self .session ,"retrieve fixture" ) 45output = next ( 46item ["output" ] 47for item in reversed (requests [- 1 ]["input" ]) 48if item .get ("type" )== "function_call_output" 49 ) 50return json .loads (output ) 51 52def test_transcript_pages_count_matches_and_preserve_grapheme_offsets (self ): 53target = self .app .session () 54for prompt in ["é👩💻tail Café\r" ,"second Café" ,"third Café" ]: 55self .turn (target ,prompt ) 56self .code = f""" 57agent = await agents.get( { target !r } ) 58found = await agent.search_messages('CAFÉ', limit=1) 59assert found.count == 3, found 60assert len(found.rows) == 1 and found.next_offset == 1, found 61seq = found.rows[0]['seq'] 62second = await agent.search_messages('CAFÉ', offset=1, limit=1) 63assert second.count == 3 and second.rows[0]['seq'] > seq, second 64end = await agent.search_messages('CAFÉ', offset=3, limit=1) 65assert end.count == 3 and end.rows == [] and end.next_offset is None, end 66prefix = len(f'[row #{{seq}}]\\n[user]\\n') 67accent = await agent.messages(seq=seq, offset=prefix, limit=1) 68assert accent.content == 'é', accent 69emoji = await agent.messages(seq=seq, offset=prefix+1, limit=1) 70assert emoji.content == '👩💻', emoji 71boundary = await agent.messages(seq=seq, offset=prefix+11, limit=1) 72assert boundary.content == '\\r\\n', boundary 73separator = await agent.messages(seq=seq, offset=prefix+12, limit=1) 74assert separator.content == '\\n', separator 75beyond = await agent.messages(seq=seq, offset=100000, limit=1) 76assert beyond.content == '' and beyond.next_offset is None, beyond 77try: 78await agent.messages(seq=seq, offset=-1) 79assert False, 'negative offset was accepted' 80except AgentsError as error: 81assert 'nonnegative' in str(error), error 82print('RETRIEVAL_PAGES_OK') 83""" 84requests = self .turn (self .session ,"verify source retrieval" ) 85output = next ( 86item ["output" ] 87for item in reversed (requests [- 1 ]["input" ]) 88if item .get ("type" )== "function_call_output" 89 ) 90self .assertIn ("RETRIEVAL_PAGES_OK" ,output ) 91 92def test_lcm_search_pages_sources_and_nodes_independently_inside_selected_range ( 93self , 94 ): 95for prompt in ["first Café" ,"second Café" ,"third Café" ,"fourth Café" ]: 96self .turn (self .session ,prompt ) 97with self .app .api ( 98f"/sessions/ { self . session } /compaction" , 99 {"strategy" :"lcm" }, 100 )as response : 101result = json .load (response ) 102self .assertEqual (result ["state" ],"compacted" ) 103self .app .idle (self .session ) 104listed = self .retrieve ("lcm_list" , {"limit" :1 }) 105self .assertGreater (listed ["total" ],0 ) 106self .assertEqual (len (listed ["folds" ]),1 ) 107node = listed ["folds" ][0 ] 108self .assertTrue (node ["frontier" ]) 109scoped = self .retrieve ( 110"lcm_grep" , {"pattern" :"CAFÉ" ,"summary_id" :node ["id" ],"limit" :1 } 111 ) 112self .assertGreater (scoped ["source_count" ],1 ) 113self .assertEqual (scoped ["node_count" ],1 ) 114self .assertEqual (len (scoped ["sources" ]),1 ) 115self .assertEqual (len (scoped ["nodes" ]),1 ) 116self .assertEqual (scoped ["next_offset" ],1 ) 117source = scoped ["sources" ][0 ] 118self .assertEqual (source ["node_id" ],node ["id" ]) 119self .assertGreaterEqual (source ["seq" ],node ["first_seq" ]) 120self .assertLessEqual (source ["seq" ],node ["last_seq" ]) 121second = self .retrieve ( 122"lcm_grep" , 123 {"pattern" :"CAFÉ" ,"summary_id" :node ["id" ],"limit" :1 ,"offset" :1 }, 124 ) 125self .assertEqual (second ["source_count" ],scoped ["source_count" ]) 126self .assertEqual (second ["node_count" ],1 ) 127self .assertEqual (len (second ["sources" ]),1 ) 128self .assertEqual (second ["nodes" ], []) 129self .assertEqual (second ["next_offset" ],2 ) 130summary_only = self .retrieve ( 131"lcm_grep" , {"pattern" :"fold-only" ,"summary_id" :node ["id" ],"limit" :1 } 132 ) 133self .assertEqual (summary_only ["source_count" ],0 ) 134self .assertEqual (summary_only ["node_count" ],1 ) 135self .assertEqual (summary_only ["sources" ], []) 136self .assertEqual (len (summary_only ["nodes" ]),1 ) 137self .assertIsNone (summary_only ["next_offset" ]) 138page = self .retrieve ("lcm_expand" , {"id" :node ["id" ],"limit" :1 }) 139self .assertEqual (page ["content" ],"[" ) 140self .assertEqual (page ["next_offset" ],1 ) 141continued = self .retrieve ( 142"lcm_expand" , {"id" :node ["id" ],"limit" :1 ,"offset" :1 } 143 ) 144self .assertEqual (continued ["content" ],"s" ) 145outside = self .retrieve ( 146"lcm_grep" , {"pattern" :"CAFÉ" ,"summary_id" :node ["id" ],"offset" :1000 } 147 ) 148self .assertEqual (outside ["source_count" ],scoped ["source_count" ]) 149self .assertEqual (outside ["sources" ], []) 150self .assertIsNone (outside ["next_offset" ])