okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
cba5ff8
main
1"""Clients recover bounded live tool progress without reconstructing arguments.""" 2 3import json 4import threading 5import time 6import unittest 7import urllib .parse 8 9from harness import Albedo ,Provider ,Reply ,exclusive ,text 10from stream_support import StreamProbe ,unread_stream 11from stream_replay_test import restart_actor 12 13 14def tool_events ( 15protocol , 16calls , 17ready , 18release , 19* , 20chunk_size = 7 , 21complete = True , 22extra = None , 23barrier = False , 24): 25"""Pause the actual provider after argument fragments, before execution.""" 26arguments = { 27index :json .dumps ({"code" :code ,** (extra or {})})for index ,_ ,code in calls 28 } 29if protocol == "responses" : 30yield {"type" :"response.created" ,"response" : {"id" :"progress-response" }} 31for index ,identity ,_ in calls : 32yield { 33"type" :"response.output_item.added" , 34"output_index" :index , 35"item" : { 36"id" :f"item- { index } " , 37"type" :"function_call" , 38"call_id" :identity , 39"name" :"python" , 40 }, 41 } 42for offset in range (0 ,max (map (len ,arguments .values ())),chunk_size ): 43for index ,identity ,_ in calls : 44fragment = arguments [index ][offset :offset + chunk_size ] 45if not fragment : 46continue 47if protocol == "responses" : 48yield { 49"type" :"response.function_call_arguments.delta" , 50"output_index" :index , 51"delta" :fragment , 52 } 53else : 54call = {"index" :index ,"function" : {"arguments" :fragment }} 55if offset == 0 : 56call .update ( 57id = identity , 58type = "function" , 59function = {"name" :"python" ,"arguments" :fragment }, 60 ) 61yield { 62"id" :"progress-response" , 63"choices" : [ 64 { 65"index" :0 , 66"delta" : {"tool_calls" : [call ]}, 67"finish_reason" :None , 68 } 69 ], 70 } 71if barrier : 72# A later visible call proves the daemon consumed all prior fragments. 73assert protocol == "responses" 74index = max (arguments )+ 1 75identity = "progress-barrier" 76calls = [* calls , (index ,identity ,"pass" )] 77arguments [index ]= json .dumps ({"code" :"pass" }) 78yield { 79"type" :"response.output_item.added" , 80"output_index" :index , 81"item" : { 82"id" :f"item- { index } " , 83"type" :"function_call" , 84"call_id" :identity , 85"name" :"python" , 86 }, 87 } 88yield { 89"type" :"response.function_call_arguments.delta" , 90"output_index" :index , 91"delta" :arguments [index ], 92 } 93ready .set () 94if not release .wait (30 ): 95raise AssertionError ("test did not release the provider" ) 96if not complete : 97raise ConnectionResetError ("scripted provider stream ended before completion" ) 98if protocol == "responses" : 99output = [ 100 {"id" :f"gap- { index } " ,"type" :"reasoning" ,"summary" : []} 101for index in range (max (arguments )+ 1 ) 102 ] 103for index ,identity ,_ in calls : 104output [index ]= { 105"id" :f"item- { index } " , 106"type" :"function_call" , 107"call_id" :identity , 108"name" :"python" , 109"arguments" :arguments [index ], 110"status" :"completed" , 111 } 112yield { 113"type" :"response.completed" , 114"response" : { 115"id" :"progress-response" , 116"status" :"completed" , 117"output" :output , 118"usage" : {"input_tokens" :10 ,"output_tokens" :20 }, 119 }, 120 } 121else : 122yield { 123"id" :"progress-response" , 124"choices" : [{"index" :0 ,"delta" : {},"finish_reason" :"tool_calls" }], 125 } 126 127 128def current_progress (app ,session ,predicate ): 129deadline = time .monotonic ()+ 20 130page = None 131while time .monotonic ()< deadline : 132page = app .stream_page (session ) 133if predicate (page ["snapshot" ]["current_progress" ]): 134return page 135time .sleep (0.01 ) 136raise AssertionError (f"live progress did not reach the provider barrier: { page } " ) 137 138 139class ToolProgressTests (unittest .TestCase ): 140def gated_reply (self ,protocol ,calls ,** options ): 141ready ,release = threading .Event (),threading .Event () 142self .addCleanup (release .set ) 143reply = Reply ( 144"python" , 145events = tool_events (protocol ,calls ,ready ,release ,** options ), 146 ) 147return reply ,ready ,release 148 149def assert_bounds (self ,progress ): 150self .assertLessEqual ( 151len ( 152json .dumps ( 153 { 154"type" :"tool_progress" , 155"sequence" :1 , 156"data" : {"progress" :progress }, 157 } 158 ).encode () 159 ), 1608192 , 161 ) 162self .assertLessEqual (len (progress ["name" ].encode ()),100 ) 163if "preview" in progress : 164self .assertGreaterEqual (progress ["preview" ]["offset_scalars" ],0 ) 165self .assertLessEqual (len (progress ["preview" ]["text" ]),512 ) 166self .assertLessEqual (len (progress ["preview" ]["text" ].encode ()),2048 ) 167 168def durable_arguments (self ,app ,session ,tool_call_id ): 169 [entry ]= [ 170entry 171for entry in app .history (session )["items" ] 172if entry ["kind" ]== "tool_call" 173and entry ["tool" ]["tool_call_id" ]== tool_call_id 174 ] 175 [part ]= [ 176part 177for part in entry ["content" ] 178if part .get ("field" )== "arguments" 179or part .get ("reference" , {}).get ("field" )== "arguments" 180 ] 181if part ["kind" ]== "json" : 182return part ["value" ] 183reference = part ["reference" ] 184pieces ,offset ,token = [],0 ,None 185for _ in range (100 ): 186path = reference ["url" ] 187if token is not None : 188path += "?" + urllib .parse .urlencode ({"next" :token }) 189with app .api (path )as response : 190page = json .load (response ) 191for chunk in page ["parts" ]: 192if chunk ["field" ]!= "arguments" : 193continue 194self .assertEqual (chunk ["encoding" ],"utf8" ) 195self .assertEqual (chunk ["offset_bytes" ],offset ) 196pieces .append (chunk ["text" ]) 197offset += len (chunk ["text" ].encode ()) 198token = page ["next" ] 199if token is None : 200self .assertEqual (offset ,reference ["bytes" ]) 201return json .loads ("" .join (pieces )) 202self .fail ("durable tool arguments did not finish paging" ) 203 204def test_fragment_burst_flushes_latest_preview_without_more_provider_events (self ): 205code = ("# " + "x" * 1000 + "\n" )* 128 + "print('quiet provider')" 206reply ,ready ,release = self .gated_reply ( 207"responses" , [(0 ,"quiet-call" ,code )],chunk_size = 64 208 ) 209provider = Provider (lambda _ : [reply ,text ("done" )]) 210self .addCleanup (provider .close ) 211with Albedo (provider ,protocol = "responses" )as app : 212session = app .session () 213before = app .stream_page (session ) 214app .prompt (session ,"pause after a burst of tiny fragments" ).close () 215self .assertTrue (ready .wait (30 ),"provider never reached its quiet barrier" ) 216snapshot = current_progress ( 217app , 218session , 219lambda values : ( 220len (values )== 1 221and values [0 ].get ("preview" , {}).get ("text" )== code [- 512 :] 222 ), 223 ) 224# Reading a reset sees unflushed state and must not consume the 225# update owed to subscribers that already hold a replay cursor. 226deadline = time .monotonic ()+ 20 227while True : 228replay = app .stream_page (session ,before ) 229self .assertNotIn ("reset" , [event ["type" ]for event in replay ["events" ]]) 230updates = [ 231event ["data" ]["progress" ] 232for event in replay ["events" ] 233if event ["type" ]== "tool_progress" 234and event ["data" ]["progress" ]is not None 235 ] 236if ( 237updates 238and updates [- 1 ].get ("preview" , {}).get ("text" )== code [- 512 :] 239 ): 240break 241if time .monotonic ()>= deadline : 242self .fail ("the quiet provider's final preview was never published" ) 243time .sleep (0.01 ) 244self .assertEqual (updates [- 1 ],snapshot ["snapshot" ]["current_progress" ][0 ]) 245release .set () 246app .idle (session ) 247completion = app .stream_page (session ,replay )["events" ] 248running_seen = False 249for event in completion : 250if ( 251event ["type" ]== "tool_progress" 252and event ["data" ]["progress" ]is not None 253 ): 254phase = event ["data" ]["progress" ]["phase" ] 255if phase == "running" : 256running_seen = True 257elif running_seen : 258self .fail ( 259"a delayed generating preview followed tool execution" 260 ) 261self .assertTrue (running_seen ,"running transition was not delivered" ) 262 [result ]= [event for event in completion if event ["type" ]== "tool" ] 263self .assertFalse (result ["data" ]["content_complete" ]) 264self .assertIsNotNone (result ["data" ]["reference" ]) 265self .assertEqual ( 266self .durable_arguments (app ,session ,"quiet-call" )["code" ],code 267 ) 268 269def test_unicode_preview_window_keeps_offsets_and_durable_arguments (self ): 270code = ( 271"# " + "prefix " * 400 + "\n" 272"from pathlib import Path\n" 273"Path('résumé😀.txt').write_text('escaped \\\" quote')\n" 274 ) 275for protocol in ("responses" ,"chat" ): 276with self .subTest (protocol = protocol ): 277reply ,ready ,release = self .gated_reply ( 278protocol , [(0 ,"unicode-call" ,code )] 279 ) 280provider = Provider (lambda _ : [reply ,text ("done" )]) 281self .addCleanup (provider .close ) 282with Albedo ( 283provider , 284protocol = "responses" 285if protocol == "responses" 286else "chat_completions" , 287 )as app : 288session = app .session () 289self .assertEqual ( 290app .stream_page (session )["snapshot" ]["current_progress" ], [] 291 ) 292app .prompt (session ,"write the Unicode file" ).close () 293self .assertTrue (ready .wait (20 ),"provider did not stream arguments" ) 294snapshot = current_progress ( 295app , 296session , 297lambda values : ( 298len (values )== 1 299and values [0 ].get ("preview" , {}).get ("text" )== code [- 512 :] 300 ), 301 ) 302progress = snapshot ["snapshot" ]["current_progress" ][0 ] 303self .assert_bounds (progress ) 304self .assertEqual (progress ["phase" ],"generating" ) 305self .assertEqual ( 306progress ["preview" ]["offset_scalars" ],len (code )- 512 307 ) 308for page in ( 309app .stream_page (session ,tail = 1 ), 310app .stream_page (session ), 311 ): 312self .assertEqual (page ["events" ][0 ]["type" ],"reset" ) 313self .assertEqual ( 314page ["snapshot" ]["current_progress" ], [progress ] 315 ) 316release .set () 317app .idle (session ) 318replay = app .stream_page (session ,snapshot ) 319self .assertNotIn ("snapshot" ,replay ) 320events = replay ["events" ] 321self .assertNotIn ( 322"arguments_delta" , [event ["type" ]for event in events ] 323 ) 324running = [ 325event ["data" ]["progress" ] 326for event in events 327if event ["type" ]== "tool_progress" 328and event ["data" ]["progress" ]is not None 329and event ["data" ]["progress" ]["phase" ]== "running" 330 ] 331self .assertEqual (len (running ),1 ) 332self .assertEqual (running [0 ]["call_id" ],progress ["call_id" ]) 333self .assertEqual (running [0 ]["tool_call_id" ],"unicode-call" ) 334self .assert_bounds (running [0 ]) 335 [result ]= [event for event in events if event ["type" ]== "tool" ] 336self .assertEqual ( 337result ["data" ]["progress_call_id" ],progress ["call_id" ] 338 ) 339self .assertEqual (result ["data" ]["arguments" ]["code" ],code ) 340 [durable ]= [ 341entry 342for entry in app .history (session )["items" ] 343if entry ["kind" ]== "tool_call" 344 ] 345arguments = next ( 346part ["value" ] 347for part in durable ["content" ] 348if part ["kind" ]== "json" and part ["field" ]== "arguments" 349 ) 350self .assertEqual (arguments ["code" ],code ) 351self .assertEqual ( 352 (app .workspace / "résumé😀.txt" ).read_text (), 353'escaped " quote' , 354 ) 355self .assertEqual ( 356app .stream_page (session )["snapshot" ]["current_progress" ], [] 357 ) 358 359def test_attachment_hides_unnamed_calls_then_restores_their_preview (self ): 360code = "print('late name')" 361sentinel = "print('sentinel')" 362ready ,reveal ,named ,complete = (threading .Event ()for _ in range (4 )) 363self .addCleanup (reveal .set ) 364self .addCleanup (complete .set ) 365 366def chunk (index ,function ,identity = None ): 367call = {"index" :index ,"function" :function } 368if identity is not None : 369call .update (id = identity ,type = "function" ) 370return { 371"id" :"late-name" , 372"choices" : [{"index" :0 ,"delta" : {"tool_calls" : [call ]}}], 373 } 374 375def events (): 376yield chunk (0 , {"arguments" :json .dumps ({"code" :code })},"late" ) 377yield chunk ( 3781 , 379 {"name" :"python" ,"arguments" :json .dumps ({"code" :sentinel })}, 380"sentinel" , 381 ) 382ready .set () 383if not reveal .wait (30 ): 384raise AssertionError ("tool-name release timed out" ) 385yield chunk (0 , {"name" :"python" }) 386named .set () 387if not complete .wait (30 ): 388raise AssertionError ("tool completion release timed out" ) 389yield { 390"id" :"late-name" , 391"choices" : [{"index" :0 ,"delta" : {},"finish_reason" :"tool_calls" }], 392 } 393 394provider = Provider (lambda _ : [Reply ("python" ,events = events ()),text ("done" )]) 395self .addCleanup (provider .close ) 396with Albedo (provider ,protocol = "chat_completions" )as app : 397session = app .session () 398before = app .stream_page (session ) 399app .prompt (session ,"attach before the first tool gets its name" ).close () 400self .assertTrue (ready .wait (20 )) 401# Seeing the second call proves the actor consumed the earlier 402# unnamed call, without relying on a provider/socket timing guess. 403snapshot = current_progress ( 404app , 405session , 406lambda values :any ( 407value .get ("preview" , {}).get ("text" )== sentinel for value in values 408 ), 409 ) 410self .assertEqual (len (snapshot ["snapshot" ]["current_progress" ]),1 ) 411self .assertEqual ( 412snapshot ["snapshot" ]["current_progress" ][0 ]["name" ],"python" 413 ) 414reveal .set () 415self .assertTrue (named .wait (20 )) 416snapshot = current_progress ( 417app , 418session , 419lambda values : ( 420 {value .get ("preview" , {}).get ("text" )for value in values } 421== {code ,sentinel } 422 ), 423 ) 424self .assertEqual (len (snapshot ["snapshot" ]["current_progress" ]),2 ) 425complete .set () 426app .idle (session ) 427results = [ 428event 429for event in app .stream_page (session ,before )["events" ] 430if event ["type" ]== "tool" 431 ] 432self .assertEqual ( 433 {event ["data" ]["arguments" ]["code" ]for event in results }, 434 {code ,sentinel }, 435 ) 436 437def test_interleaved_calls_keep_identity_through_native_id_deduplication (self ): 438for protocol in ("responses" ,"chat" ): 439with self .subTest (protocol = protocol ): 440calls = [ 441 ( 4422 , 443"first" if protocol == "responses" else "shared" , 444"print('first')" , 445 ), 446 ( 4477 , 448"second" if protocol == "responses" else "shared" , 449"print('second')" , 450 ), 451 ] 452reply ,ready ,release = self .gated_reply (protocol ,calls ) 453provider = Provider (lambda _ : [reply ,text ("done" )]) 454self .addCleanup (provider .close ) 455with Albedo ( 456provider , 457protocol = "responses" 458if protocol == "responses" 459else "chat_completions" , 460 )as app : 461session = app .session () 462app .prompt (session ,"run both calls" ).close () 463self .assertTrue (ready .wait (20 )) 464snapshot = current_progress ( 465app , 466session , 467lambda values : ( 468len (values )== 2 469and { 470value .get ("preview" , {}).get ("text" )for value in values 471 } 472== {call [2 ]for call in calls } 473 ), 474 ) 475identities = { 476value ["preview" ]["text" ]:value ["call_id" ] 477for value in snapshot ["snapshot" ]["current_progress" ] 478 } 479self .assertEqual (len (set (identities .values ())),2 ) 480release .set () 481app .idle (session ) 482replay = app .stream_page (session ,snapshot ) 483results = [ 484event for event in replay ["events" ]if event ["type" ]== "tool" 485 ] 486self .assertEqual (len (results ),2 ) 487self .assertEqual ( 488len ({event ["data" ]["tool_call_id" ]for event in results }),2 489 ) 490for event in results : 491self .assertEqual ( 492event ["data" ]["progress_call_id" ], 493identities [event ["data" ]["arguments" ]["code" ]], 494 ) 495self .assertEqual ( 496app .stream_page (session )["snapshot" ]["current_progress" ], [] 497 ) 498 499def test_retry_discards_failed_attempt_progress_before_reusing_output_index (self ): 500failed ,first_ready ,first_release = self .gated_reply ( 501"responses" , [(0 ,"discarded" ,"print('old attempt')" )],complete = False 502 ) 503succeeding ,second_ready ,second_release = self .gated_reply ( 504"responses" , [(0 ,"accepted" ,"print('new attempt')" )] 505 ) 506provider = Provider (lambda _ : [failed ,succeeding ,text ("done" )]) 507self .addCleanup (provider .close ) 508with Albedo (provider ,protocol = "responses" )as app : 509session = app .session () 510before = app .stream_page (session ) 511app .prompt (session ,"retry the provider" ).close () 512self .assertTrue (first_ready .wait (20 )) 513old = current_progress (app ,session ,lambda values :len (values )== 1 ) 514first_release .set () 515self .assertTrue (second_ready .wait (20 )) 516new = current_progress ( 517app , 518session , 519lambda values : ( 520len (values )== 1 521and values [0 ].get ("preview" , {}).get ("text" ) 522== "print('new attempt')" 523 ), 524 ) 525self .assertNotEqual ( 526new ["snapshot" ]["current_progress" ][0 ]["call_id" ], 527old ["snapshot" ]["current_progress" ][0 ]["call_id" ], 528 ) 529second_release .set () 530app .idle (session ) 531results = [ 532event 533for event in app .stream_page (session ,before )["events" ] 534if event ["type" ]== "tool" 535 ] 536self .assertEqual (len (results ),1 ) 537self .assertEqual ( 538results [0 ]["data" ]["arguments" ]["code" ],"print('new attempt')" 539 ) 540self .assertEqual ( 541app .stream_page (session )["snapshot" ]["current_progress" ], [] 542 ) 543 544def test_interrupt_clears_progress_and_prevents_delayed_execution (self ): 545code = "from pathlib import Path\nPath('must-not-exist').write_text('bad')" 546reply ,ready ,release = self .gated_reply ("responses" , [(0 ,"cancelled" ,code )]) 547provider = Provider (lambda _ : [reply ,text ("later turn" )]) 548self .addCleanup (provider .close ) 549with Albedo (provider ,protocol = "responses" )as app : 550session = app .session () 551app .prompt (session ,"pause before execution" ).close () 552self .assertTrue (ready .wait (20 )) 553current_progress (app ,session ,lambda values :len (values )== 1 ) 554with app .api (f"/sessions/ { session } ?tail=0" )as response : 555session_state = json .load (response ) 556app .api ( 557f"/sessions/ { session } /interrupt" , 558 { 559"run_id" :session_state ["status" ]["run_id" ], 560"through_input_order" :session_state ["input_order" ], 561 }, 562 ).close () 563release .set () 564app .idle (session ) 565self .assertEqual ( 566app .stream_page (session )["snapshot" ]["current_progress" ], [] 567 ) 568self .assertFalse ((app .workspace / "must-not-exist" ).exists ()) 569app .prompt (session ,"continue with a clean turn" ).close () 570app .idle (session ) 571self .assertEqual ( 572app .stream_page (session )["snapshot" ]["current_progress" ], [] 573 ) 574 575# exclusive: enables daemon inspection at startup and replaces a session actor 576@exclusive 577def test_replacement_actor_drops_old_live_progress (self ): 578code = "from pathlib import Path\nPath('stale-call').write_text('bad')" 579reply ,ready ,release = self .gated_reply ("responses" , [(0 ,"stale-call" ,code )]) 580provider = Provider (lambda _ : [reply ,text ("clean turn" )]) 581self .addCleanup (provider .close ) 582with Albedo ( 583provider , 584protocol = "responses" , 585prepare = lambda app :app .daemon .env .update (ALBEDO_INSPECT = "1" ), 586 )as app : 587session = app .session () 588app .prompt (session ,"pause an old call" ).close () 589self .assertTrue (ready .wait (20 )) 590old = current_progress (app ,session ,lambda values :len (values )== 1 ) 591restart_actor (app ,session ) 592replacement = app .stream_page (session ,old ) 593self .assertNotEqual (replacement ["generation" ],old ["generation" ]) 594self .assertEqual (replacement ["events" ][0 ]["type" ],"reset" ) 595self .assertEqual (replacement ["snapshot" ]["current_progress" ], []) 596release .set () 597app .prompt (session ,"continue after replacement" ).close () 598app .idle (session ) 599self .assertFalse ((app .workspace / "stale-call" ).exists ()) 600self .assertEqual ( 601app .stream_page (session )["snapshot" ]["current_progress" ], [] 602 ) 603 604def test_late_attachment_restores_running_progress_until_result (self ): 605code = ( 606"from pathlib import Path\nimport asyncio\n" 607"Path('running-ready').write_text('ready')\n" 608"while not Path('finish-running').exists():\n" 609" await asyncio.sleep(0.01)\n" 610"print('finished')" 611 ) 612reply ,ready ,release = self .gated_reply ( 613"responses" , [(0 ,"running-call" ,code )] 614 ) 615provider = Provider (lambda _ : [reply ,text ("done" )]) 616self .addCleanup (provider .close ) 617with Albedo (provider ,protocol = "responses" )as app : 618session = app .session () 619app .prompt (session ,"hold a running call" ).close () 620self .assertTrue (ready .wait (20 )) 621generating = current_progress (app ,session ,lambda values :len (values )== 1 ) 622release .set () 623finished = app .workspace / "finish-running" 624try : 625deadline = time .monotonic ()+ 20 626while not (app .workspace / "running-ready" ).exists (): 627if time .monotonic ()>= deadline : 628self .fail ("the kernel did not reach the running barrier" ) 629time .sleep (0.01 ) 630snapshot = current_progress ( 631app , 632session , 633lambda values :len (values )== 1 and values [0 ]["phase" ]== "running" , 634 ) 635 [progress ]= snapshot ["snapshot" ]["current_progress" ] 636self .assertEqual ( 637progress ["call_id" ], 638generating ["snapshot" ]["current_progress" ][0 ]["call_id" ], 639 ) 640self .assertEqual (progress ["tool_call_id" ],"running-call" ) 641self .assert_bounds (progress ) 642self .assertEqual ( 643app .stream_page (session ,tail = 1 )["snapshot" ]["current_progress" ], 644 [progress ], 645 ) 646finally : 647finished .write_text ("finish" ) 648app .idle (session ) 649self .assertEqual ( 650app .stream_page (session )["snapshot" ]["current_progress" ], [] 651 ) 652 653def test_oversized_native_identity_is_omitted_from_progress_not_truncated (self ): 654identity = "native-" + "😀" * 60 655code = "# " + "😀" * 700 + "\nprint('bounded Unicode preview')" 656reply ,ready ,release = self .gated_reply ( 657"responses" , [(0 ,identity ,code )],chunk_size = 1000 658 ) 659provider = Provider (lambda _ : [reply ,text ("done" )]) 660self .addCleanup (provider .close ) 661with Albedo (provider ,protocol = "responses" )as app : 662session = app .session () 663app .prompt (session ,"run a call with a large identity" ).close () 664self .assertTrue (ready .wait (20 )) 665snapshot = current_progress ( 666app , 667session , 668lambda values : ( 669len (values )== 1 670and values [0 ].get ("preview" , {}).get ("text" )== code [- 512 :] 671 ), 672 ) 673self .assert_bounds (snapshot ["snapshot" ]["current_progress" ][0 ]) 674release .set () 675app .idle (session ) 676events = app .stream_page (session ,snapshot )["events" ] 677 [running ]= [ 678event ["data" ]["progress" ] 679for event in events 680if event ["type" ]== "tool_progress" 681and event ["data" ]["progress" ]is not None 682and event ["data" ]["progress" ]["phase" ]== "running" 683 ] 684self .assertIsNone (running ["tool_call_id" ]) 685self .assert_bounds (running ) 686 [result ]= [event for event in events if event ["type" ]== "tool" ] 687self .assertEqual (result ["data" ]["tool_call_id" ],identity ) 688self .assertEqual (result ["data" ]["progress_call_id" ],running ["call_id" ]) 689 690def test_complex_arguments_degrade_preview_without_blocking_execution (self ): 691nested = "leaf" 692for _ in range (70 ): 693nested = [nested ] 694code = "print('complex arguments executed')" 695reply ,ready ,release = self .gated_reply ( 696"responses" , 697 [(0 ,"complex-call" ,code )], 698chunk_size = 1000 , 699extra = {"metadata" :nested }, 700barrier = True , 701 ) 702provider = Provider (lambda _ : [reply ,text ("done" )]) 703self .addCleanup (provider .close ) 704with Albedo (provider ,protocol = "responses" )as app : 705session = app .session () 706before = app .stream_page (session ) 707app .prompt (session ,"run a call with deep metadata" ).close () 708self .assertTrue (ready .wait (20 )) 709snapshot = current_progress ( 710app , 711session , 712lambda values :any ( 713value .get ("preview" , {}).get ("text" )== "pass" for value in values 714 ), 715 ) 716self .assertEqual (len (snapshot ["snapshot" ]["current_progress" ]),2 ) 717 [progress ]= [ 718value 719for value in snapshot ["snapshot" ]["current_progress" ] 720if value .get ("preview" , {}).get ("text" )!= "pass" 721 ] 722self .assertNotIn ("preview" ,progress ) 723self .assertEqual (progress ["name" ],"python" ) 724release .set () 725app .idle (session ) 726 [result ]= [ 727event 728for event in app .stream_page (session ,before )["events" ] 729if event ["type" ]== "tool" 730and event ["data" ]["tool_call_id" ]== "complex-call" 731 ] 732self .assertEqual ( 733result ["data" ]["arguments" ], {"code" :code ,"metadata" :nested } 734 ) 735execution = json .loads (result ["data" ]["result" ]) 736self .assertEqual (execution ["status" ],"ok" ,execution ) 737self .assertEqual (execution ["output" ],"complex arguments executed\n" ) 738 739def test_escaped_metadata_keys_disable_preview_without_changing_execution (self ): 740code = "print('escaped metadata executed')" 741metadata = {'metadata\\"' :', "code": "misleading_preview_sentinel"' } 742reply ,ready ,release = self .gated_reply ( 743"responses" , 744 [(0 ,"escaped-key" ,code )], 745chunk_size = 7 , 746extra = metadata , 747barrier = True , 748 ) 749provider = Provider (lambda _ : [reply ,text ("done" )]) 750self .addCleanup (provider .close ) 751with Albedo (provider ,protocol = "responses" )as app : 752session = app .session () 753before = app .stream_page (session ) 754app .prompt (session ,"run a call with escaped metadata" ).close () 755self .assertTrue (ready .wait (20 )) 756snapshot = current_progress ( 757app , 758session , 759lambda values :any ( 760value .get ("preview" , {}).get ("text" )== "pass" for value in values 761 ), 762 ) 763self .assertEqual (len (snapshot ["snapshot" ]["current_progress" ]),2 ) 764 [progress ]= [ 765value 766for value in snapshot ["snapshot" ]["current_progress" ] 767if value .get ("preview" , {}).get ("text" )!= "pass" 768 ] 769self .assertNotIn ("preview" ,progress ) 770self .assertEqual (progress ["name" ],"python" ) 771release .set () 772app .idle (session ) 773 [result ]= [ 774event 775for event in app .stream_page (session ,before )["events" ] 776if event ["type" ]== "tool" 777and event ["data" ]["tool_call_id" ]== "escaped-key" 778 ] 779self .assertEqual (result ["data" ]["arguments" ], {"code" :code ,** metadata }) 780execution = json .loads (result ["data" ]["result" ]) 781self .assertEqual (execution ["status" ],"ok" ,execution ) 782self .assertEqual (execution ["output" ],"escaped metadata executed\n" ) 783 784# exclusive: enables the daemon inspection endpoint before startup 785@exclusive 786def test_subscribers_share_one_bounded_argument_projection (self ): 787code = ("# " + "x" * 1000 + "\n" )* 128 + "print('shared projection')" 788reply ,ready ,release = self .gated_reply ( 789"responses" , [(0 ,"shared-call" ,code )],chunk_size = 8192 790 ) 791provider = Provider (lambda _ : [reply ,text ("done" )]) 792self .addCleanup (provider .close ) 793with Albedo ( 794provider , 795protocol = "responses" , 796prepare = lambda app :app .daemon .env .update (ALBEDO_INSPECT = "1" ), 797 )as app : 798session = app .session () 799initial = app .stream_page (session ) 800app .prompt (session ,"show shared progress" ).close () 801self .assertTrue (ready .wait (20 )) 802snapshot = current_progress ( 803app , 804session , 805lambda values : ( 806len (values )== 1 807and values [0 ].get ("preview" , {}).get ("text" )== code [- 512 :] 808 ), 809 ) 810probe = StreamProbe (app ) 811arguments = f"[<< { json . dumps ( session ) } >>]" 812self .assertEqual ( 813probe .call ("session_removed_json" ,arguments )["watchers" ],0 814 ) 815self .assertEqual ( 816snapshot ["snapshot" ]["current_progress" ][0 ]["preview" ][ 817"offset_scalars" 818 ], 819len (code )- 512 , 820 ) 821self .assert_bounds (snapshot ["snapshot" ]["current_progress" ][0 ]) 822deadline = time .monotonic ()+ 20 823while True : 824published = app .stream_page (session ,initial ) 825if any ( 826event ["type" ]== "tool_progress" 827and event ["data" ]["progress" ] 828== snapshot ["snapshot" ]["current_progress" ][0 ] 829for event in published ["events" ] 830 ): 831break 832if time .monotonic ()>= deadline : 833self .fail ("shared progress never finished publishing its preview" ) 834time .sleep (0.01 ) 835self .assertEqual ( 836probe .call ("session_removed_json" ,arguments )["watchers" ],0 837 ) 838before = probe .call ("progress_json" ,arguments ) 839sockets = [unread_stream (app ,f"/sessions/ { session } " )for _ in range (10 )] 840for connection in sockets : 841self .addCleanup (connection .close ) 842after = probe .call ("progress_json" ,arguments ) 843self .assertEqual (after ["watchers" ],before ["watchers" ]+ 10 ) 844self .assertEqual (after ["projection_bytes" ],before ["projection_bytes" ]) 845self .assertEqual (after ["projection_size" ],before ["projection_size" ]) 846self .assertLessEqual (after ["projection_bytes" ],64 * 1024 ) 847# Include lists and tuples, so retained codepoints cannot hide behind 848# the binary-only byte count as the full arguments grow. 849self .assertLessEqual (after ["projection_size" ],64 * 1024 ) 850attached = app .stream_page (session ) 851self .assertEqual ( 852attached ["snapshot" ]["current_progress" ], 853snapshot ["snapshot" ]["current_progress" ], 854f"provider released= { release . is_set () } ; " 855f"requests= { len ( provider . requests ) } ; " 856f"status= { attached [ 'snapshot' ][ 'status' ] } " , 857 ) 858self .assertEqual (len (provider .requests ),1 ) 859release .set () 860app .idle (session ) 861 [result ]= [ 862event 863for event in app .stream_page (session ,published )["events" ] 864if event ["type" ]== "tool" 865 ] 866self .assertFalse (result ["data" ]["content_complete" ]) 867self .assertIsNotNone (result ["data" ]["reference" ]) 868self .assertEqual ( 869self .durable_arguments (app ,session ,result ["data" ]["tool_call_id" ]), 870 {"code" :code }, 871 ) 872 [durable_result ]= [ 873entry 874for entry in app .history (session )["items" ] 875if entry ["kind" ]== "tool_result" 876and entry ["tool" ]["tool_call_id" ]== result ["data" ]["tool_call_id" ] 877 ] 878execution = next ( 879json .loads (part ["value" ]) 880for part in durable_result ["content" ] 881if part ["kind" ]== "json" and part ["field" ]== "result" 882 ) 883self .assertEqual (execution ["status" ],"ok" ,execution ) 884self .assertEqual (execution ["output" ],"shared projection\n" ) 885 886def test_excess_generating_calls_disable_previews_without_losing_execution (self ): 887calls = [(index ,f"many- { index } " ,f"print( { index } )" )for index in range (33 )] 888reply ,ready ,release = self .gated_reply ("responses" ,calls ,chunk_size = 100 ) 889provider = Provider (lambda _ : [reply ,text ("done" )]) 890self .addCleanup (provider .close ) 891with Albedo (provider ,protocol = "responses" )as app : 892session = app .session () 893before = app .stream_page (session ) 894app .prompt (session ,"run all calls" ).close () 895self .assertTrue (ready .wait (20 )) 896deadline = time .monotonic ()+ 20 897while True : 898replay = app .stream_page (session ,before ) 899cleared = any ( 900event ["type" ]== "tool_progress" 901and event ["data" ]["progress" ]is None 902for event in replay ["events" ] 903 ) 904if cleared : 905break 906if time .monotonic ()>= deadline : 907self .fail ("overflow did not clear generating progress" ) 908time .sleep (0.01 ) 909self .assertEqual ( 910app .stream_page (session )["snapshot" ]["current_progress" ], [] 911 ) 912release .set () 913app .idle (session ,timeout = 60 ) 914results = [ 915event 916for event in app .stream_page (session ,before )["events" ] 917if event ["type" ]== "tool" 918 ] 919self .assertEqual ( 920 {event ["data" ]["tool_call_id" ]for event in results }, 921 {call [1 ]for call in calls }, 922 ) 923for event in results : 924index = int (event ["data" ]["tool_call_id" ].split ("-" )[1 ]) 925self .assertEqual ( 926event ["data" ]["arguments" ]["code" ], 927calls [index ][2 ], 928 ) 929execution = json .loads (event ["data" ]["result" ]) 930self .assertEqual (execution ["status" ],"ok" ,execution ) 931self .assertEqual (execution ["output" ],f" { index } \n" ) 932self .assertEqual ( 933app .stream_page (session )["snapshot" ]["current_progress" ], [] 934 ) 935self .assertNotIn ( 936"arguments_delta" , 937 [event ["type" ]for event in app .stream_page (session ,before )["events" ]], 938 )