okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
61c43ca
main
1"""The model's own notes survive each compaction and lead every later request.""" 2 3import json 4import unittest 5 6from harness import Albedo ,Provider ,error ,text 7 8MARKER = "keeping notes for yourself" 9EVICTED = "<newly-evicted-history>" 10 11 12def last_user (request ): 13return next ( 14 ( 15str (item .get ("content" ,"" )) 16for item in reversed (request ["input" ]) 17if item .get ("role" )== "user" 18 ), 19"" , 20 ) 21 22 23class NotesTests (unittest .TestCase ): 24def setUp (self ): 25self .written = [] 26self .notes_fail = False 27 28def reply (request ): 29if MARKER in request .get ("instructions" ,"" ): 30if self .notes_fail : 31return error (500 ) 32return text (self .written .pop (0 )) 33if EVICTED in last_user (request ): 34return text ("rolling summary" ) 35return text ("done" ) 36 37self .provider = Provider (reply ) 38self .addCleanup (self .provider .close ) 39self .app = Albedo (self .provider ,protocol = "responses" ) 40self .app .__enter__ () 41self .addCleanup (self .app .__exit__ ,None ,None ,None ) 42self .session = self .app .session () 43 44def say (self ,* prompts ): 45for prompt in prompts : 46self .app .prompt (self .session ,prompt ).close () 47self .app .idle (self .session ) 48 49def compact (self ): 50with self .app .api (f"/sessions/ { self . session } /compaction" , {})as response : 51self .assertEqual (json .load (response )["state" ],"compacted" ) 52self .app .idle (self .session ) 53 54def note_calls (self ): 55return [ 56item ["request" ] 57for item in self .provider .requests 58if MARKER in item ["request" ].get ("instructions" ,"" ) 59 ] 60 61def head_of_next_request (self ): 62self .say ("next" ) 63return self .provider .requests [- 1 ]["request" ]["input" ][0 ]["content" ] 64 65def test_notes_are_rewritten_from_the_previous_ones_and_lead_each_request (self ): 66self .written = ["NOTES-ONE commit abc123" ,"NOTES-TWO" ] 67self .say ("first question" ,"second question" ,"third question" ) 68self .compact () 69 70 (first ,)= self .note_calls () 71self .assertIn ("at most 2000 tokens" ,first ["instructions" ]) 72self .assertIn ("(none)" ,last_user (first )) 73self .assertIn ("first question" ,last_user (first )) 74self .assertIn ("[assistant]\ndone" ,last_user (first )) 75self .assertNotIn ("provider item" ,last_user (first )) 76head = self .head_of_next_request () 77self .assertIn ("compaction notes" ,head ) 78self .assertIn ("NOTES-ONE commit abc123" ,head ) 79 80self .say ("fourth question" ,"fifth question" ) 81self .compact () 82 83second = self .note_calls ()[1 ] 84previous ,evicted = last_user (second ).split (EVICTED ) 85self .assertIn ("NOTES-ONE commit abc123" ,previous ) 86self .assertIn ("fourth question" ,evicted ) 87self .assertNotIn ("first question" ,evicted ) 88head = self .head_of_next_request () 89self .assertIn ("NOTES-TWO" ,head ) 90self .assertNotIn ("NOTES-ONE" ,head ) 91 92def test_a_failed_rewrite_keeps_the_old_notes_and_the_compaction (self ): 93self .written = ["NOTES-ONE" ] 94self .say ("first question" ,"second question" ,"third question" ) 95self .compact () 96self .say ("fourth question" ,"fifth question" ) 97self .notes_fail = True 98self .compact () 99 100self .assertEqual (len (self .note_calls ()),2 ) 101head = self .head_of_next_request () 102self .assertIn ("NOTES-ONE" ,head ) 103request = self .provider .requests [- 1 ]["request" ] 104self .assertIn ("rolling summary" ,json .dumps (request ["input" ])) 105 106 107if __name__ == "__main__" : 108unittest .main ()