import json import pytest from letta.streaming_utils import JSONInnerThoughtsExtractor @pytest.mark.parametrize("wait_for_first_key", [True, False]) def test_inner_thoughts_in_args_simple(wait_for_first_key): """Test case where the function_delta.arguments contains inner_thoughts Correct output should be inner_thoughts VALUE (not KEY) being written to one buffer And everything else (omiting inner_thoughts KEY) being written to the other buffer """ print("Running Test Case 1: With 'inner_thoughts'") handler1 = JSONInnerThoughtsExtractor(inner_thoughts_key="inner_thoughts", wait_for_first_key=wait_for_first_key) fragments1 = [ "{", """"inner_thoughts":"Chad's x2 tradition""", " is going strong! 😂 I love the enthusiasm!", " Time to delve into something imaginative:", """ If you could swap lives with any fictional character for a day, who would it be?\"""", ",", """"message":"Here we are again, with 'x2'!""", " 🎉 Let's take this chance: If you could swap", " lives with any fictional character for a day,", ''' who would it be?"''', "}", ] print("Basic inner thoughts testcase:", fragments1, "".join(fragments1)) # Make sure the string is valid JSON _ = json.loads("".join(fragments1)) if wait_for_first_key: # If we're waiting for the first key, then the first opening brace should be buffered/held back # until after the inner thoughts are finished expected_updates1 = [ {"main_json_update": "", "inner_thoughts_update": ""}, # Fragment 1 (NOTE: different) {"main_json_update": "", "inner_thoughts_update": "Chad's x2 tradition"}, # Fragment 2 {"main_json_update": "", "inner_thoughts_update": " is going strong! 😂 I love the enthusiasm!"}, # Fragment 3 {"main_json_update": "", "inner_thoughts_update": " Time to delve into something imaginative:"}, # Fragment 4 { "main_json_update": "", "inner_thoughts_update": " If you could swap lives with any fictional character for a day, who would it be?", }, # Fragment 5 {"main_json_update": "", "inner_thoughts_update": ""}, # Fragment 6 (comma after inner_thoughts) { "main_json_update": '{"message":"Here we are again, with \'x2\'!', "inner_thoughts_update": "", }, # Fragment 7 (NOTE: the brace is included here, instead of at the beginning) {"main_json_update": " 🎉 Let's take this chance: If you could swap", "inner_thoughts_update": ""}, # Fragment 8 {"main_json_update": " lives with any fictional character for a day,", "inner_thoughts_update": ""}, # Fragment 9 {"main_json_update": ' who would it be?"', "inner_thoughts_update": ""}, # Fragment 10 {"main_json_update": "}", "inner_thoughts_update": ""}, # Fragment 11 ] else: # If we're not waiting for the first key, then the first opening brace should be written immediately expected_updates1 = [ {"main_json_update": "{", "inner_thoughts_update": ""}, # Fragment 1 {"main_json_update": "", "inner_thoughts_update": "Chad's x2 tradition"}, # Fragment 2 {"main_json_update": "", "inner_thoughts_update": " is going strong! 😂 I love the enthusiasm!"}, # Fragment 3 {"main_json_update": "", "inner_thoughts_update": " Time to delve into something imaginative:"}, # Fragment 4 { "main_json_update": "", "inner_thoughts_update": " If you could swap lives with any fictional character for a day, who would it be?", }, # Fragment 5 {"main_json_update": "", "inner_thoughts_update": ""}, # Fragment 6 (comma after inner_thoughts) {"main_json_update": '"message":"Here we are again, with \'x2\'!', "inner_thoughts_update": ""}, # Fragment 7 {"main_json_update": " 🎉 Let's take this chance: If you could swap", "inner_thoughts_update": ""}, # Fragment 8 {"main_json_update": " lives with any fictional character for a day,", "inner_thoughts_update": ""}, # Fragment 9 {"main_json_update": ' who would it be?"', "inner_thoughts_update": ""}, # Fragment 10 {"main_json_update": "}", "inner_thoughts_update": ""}, # Fragment 11 ] for idx, (fragment, expected) in enumerate(zip(fragments1, expected_updates1)): updates_main_json, updates_inner_thoughts = handler1.process_fragment(fragment) # Assertions assert ( updates_main_json == expected["main_json_update"] ), f"Test Case 1, Fragment {idx+1}: Main JSON update mismatch.\nExpected: '{expected['main_json_update']}'\nGot: '{updates_main_json}'" assert ( updates_inner_thoughts == expected["inner_thoughts_update"] ), f"Test Case 1, Fragment {idx+1}: Inner Thoughts update mismatch.\nExpected: '{expected['inner_thoughts_update']}'\nGot: '{updates_inner_thoughts}'" @pytest.mark.parametrize("wait_for_first_key", [True, False]) def test_inner_thoughts_in_args_trailing_quote(wait_for_first_key): # Another test case where there's a function call that has a chunk that ends with a double quote print("Running Test Case: chunk ends with double quote") handler1 = JSONInnerThoughtsExtractor(inner_thoughts_key="inner_thoughts", wait_for_first_key=wait_for_first_key) fragments1 = [ # 1 "{", # 2 """\"inner_thoughts\":\"User wants to add 'banana' again for a fourth time; I'll track another addition.""", # 3 '",', # 4 """\"content\":\"banana""", # 5 """\",\"""", # 6 """request_heartbeat\":\"""", # 7 """true\"""", # 8 "}", ] print("Double quote test case:", fragments1, "".join(fragments1)) # Make sure the string is valid JSON _ = json.loads("".join(fragments1)) if wait_for_first_key: # If we're waiting for the first key, then the first opening brace should be buffered/held back # until after the inner thoughts are finished expected_updates1 = [ {"main_json_update": "", "inner_thoughts_update": ""}, # Fragment 1 (NOTE: different) { "main_json_update": "", "inner_thoughts_update": "User wants to add 'banana' again for a fourth time; I'll track another addition.", }, # Fragment 2 {"main_json_update": "", "inner_thoughts_update": ""}, # Fragment 3 { "main_json_update": '{"content":"banana', "inner_thoughts_update": "", }, # Fragment 4 { # "main_json_update": '","', "main_json_update": '",', "inner_thoughts_update": "", }, # Fragment 5 { # "main_json_update": 'request_heartbeat":"', "main_json_update": '"request_heartbeat":"', "inner_thoughts_update": "", }, # Fragment 6 { "main_json_update": 'true"', "inner_thoughts_update": "", }, # Fragment 7 { "main_json_update": "}", "inner_thoughts_update": "", }, # Fragment 8 ] else: pass # If we're not waiting for the first key, then the first opening brace should be written immediately expected_updates1 = [ {"main_json_update": "{", "inner_thoughts_update": ""}, # Fragment 1 (NOTE: different) { "main_json_update": "", "inner_thoughts_update": "User wants to add 'banana' again for a fourth time; I'll track another addition.", }, # Fragment 2 {"main_json_update": "", "inner_thoughts_update": ""}, # Fragment 3 { "main_json_update": '"content":"banana', "inner_thoughts_update": "", }, # Fragment 4 { # "main_json_update": '","', "main_json_update": '",', "inner_thoughts_update": "", }, # Fragment 5 { # "main_json_update": 'request_heartbeat":"', "main_json_update": '"request_heartbeat":"', "inner_thoughts_update": "", }, # Fragment 6 { "main_json_update": 'true"', "inner_thoughts_update": "", }, # Fragment 7 { "main_json_update": "}", "inner_thoughts_update": "", }, # Fragment 8 ] current_inner_thoughts = "" current_main_json = "" for idx, (fragment, expected) in enumerate(zip(fragments1, expected_updates1)): updates_main_json, updates_inner_thoughts = handler1.process_fragment(fragment) # Assertions assert ( updates_main_json == expected["main_json_update"] ), f"Test Case 1, Fragment {idx+1}: Main JSON update mismatch.\nFragment: '{fragment}'\nExpected: '{expected['main_json_update']}'\nGot: '{updates_main_json}'\nCurrent JSON: '{current_main_json}'\nCurrent Inner Thoughts: '{current_inner_thoughts}'" assert ( updates_inner_thoughts == expected["inner_thoughts_update"] ), f"Test Case 1, Fragment {idx+1}: Inner Thoughts update mismatch.\nExpected: '{expected['inner_thoughts_update']}'\nGot: '{updates_inner_thoughts}'\nCurrent JSON: '{current_main_json}'\nCurrent Inner Thoughts: '{current_inner_thoughts}'" current_main_json += updates_main_json current_inner_thoughts += updates_inner_thoughts print(f"Final JSON: '{current_main_json}'") print(f"Final Inner Thoughts: '{current_inner_thoughts}'") _ = json.loads(current_main_json) def test_inner_thoughts_not_in_args(): """Test case where the function_delta.arguments does not contain inner_thoughts Correct output should be everything being written to the main_json buffer """ print("Running Test Case 2: Without 'inner_thoughts'") handler2 = JSONInnerThoughtsExtractor(inner_thoughts_key="inner_thoughts") fragments2 = [ "{", """"message":"Here we are again, with 'x2'!""", " 🎉 Let's take this chance: If you could swap", " lives with any fictional character for a day,", ''' who would it be?"''', "}", ] print("Basic inner thoughts not in kwargs testcase:", fragments2, "".join(fragments2)) # Make sure the string is valid JSON _ = json.loads("".join(fragments2)) expected_updates2 = [ {"main_json_update": "{", "inner_thoughts_update": ""}, # Fragment 1 {"main_json_update": '"message":"Here we are again, with \'x2\'!', "inner_thoughts_update": ""}, # Fragment 2 {"main_json_update": " 🎉 Let's take this chance: If you could swap", "inner_thoughts_update": ""}, # Fragment 3 {"main_json_update": " lives with any fictional character for a day,", "inner_thoughts_update": ""}, # Fragment 4 {"main_json_update": ' who would it be?"', "inner_thoughts_update": ""}, # Fragment 5 {"main_json_update": "}", "inner_thoughts_update": ""}, # Fragment 6 ] for idx, (fragment, expected) in enumerate(zip(fragments2, expected_updates2)): updates_main_json, updates_inner_thoughts = handler2.process_fragment(fragment) # Assertions assert ( updates_main_json == expected["main_json_update"] ), f"Test Case 2, Fragment {idx+1}: Main JSON update mismatch.\nExpected: '{expected['main_json_update']}'\nGot: '{updates_main_json}'" assert ( updates_inner_thoughts == expected["inner_thoughts_update"] ), f"Test Case 2, Fragment {idx+1}: Inner Thoughts update mismatch.\nExpected: '{expected['inner_thoughts_update']}'\nGot: '{updates_inner_thoughts}'" # Final assertions for Test Case 2 expected_final_main_json2 = '{"message":"Here we are again, with \'x2\'! 🎉 Let\'s take this chance: If you could swap lives with any fictional character for a day, who would it be?"}' expected_final_inner_thoughts2 = "" assert ( handler2.main_json == expected_final_main_json2 ), f"Test Case 2: Final main_json mismatch.\nExpected: '{expected_final_main_json2}'\nGot: '{handler2.main_json}'" assert ( handler2.inner_thoughts == expected_final_inner_thoughts2 ), f"Test Case 2: Final inner_thoughts mismatch.\nExpected: '{expected_final_inner_thoughts2}'\nGot: '{handler2.inner_thoughts}'"