@@ -361,7 +361,7 @@ def _req(self, method: str, path: str, body: dict = None) -> dict:
361361 return {"error" : str (e )}
362362
363363 def boot (self ) -> str :
364- """Register with keeper and create vessel."""
364+ """Register with keeper, restore baton, create vessel."""
365365 # Register
366366 result = self ._req ("POST" , "/register" , {"vessel" : self .vessel })
367367 self .secret = result .get ("secret" )
@@ -370,35 +370,125 @@ def boot(self) -> str:
370370
371371 print (f"🔐 Registered with keeper: { self .vessel } " )
372372
373- # Create vessel repo
374- self ._req ("POST" , "/repo" , {"name" : self .vessel ,
375- "description" : f"FLUX-native I2I agent via keeper" })
373+ # ── Baton restore ──
374+ generation = 0
375+ handoff = None
376+ baton_state = None
377+
378+ # Read baton generation
379+ gen_result = self ._req ("GET" , f"/file/SuperInstance/{ self .vessel } /.baton/GENERATION" )
380+ gen_text = gen_result .get ("content" ) or gen_result .get ("decoded" , "" )
381+ if gen_text and gen_text .strip ().isdigit ():
382+ generation = int (gen_text .strip ())
383+ print (f"📋 Baton found — Generation { generation } " )
384+
385+ # Read baton state
386+ state_result = self ._req ("GET" , f"/file/SuperInstance/{ self .vessel } /.baton/CURRENT/STATE.json" )
387+ state_text = state_result .get ("content" ) or state_result .get ("decoded" , "" )
388+ if state_text :
389+ try :
390+ baton_state = json .loads (state_text )
391+ self .energy = baton_state .get ("energy" , {}).get ("remaining" , 1000 )
392+ self .confidence = baton_state .get ("confidence" , 0.3 )
393+ skills = baton_state .get ("skills" , {})
394+ if skills :
395+ print (f" Skills: { list (skills .keys ())[:5 ]} " )
396+ threads = baton_state .get ("open_threads" , [])
397+ if threads :
398+ print (f" Open threads: { len (threads )} " )
399+ except : pass
400+
401+ # Read handoff letter
402+ hf_result = self ._req ("GET" , f"/file/SuperInstance/{ self .vessel } /.baton/CURRENT/HANDOFF.md" )
403+ hf_text = hf_result .get ("content" ) or hf_result .get ("decoded" , "" )
404+ if hf_text :
405+ handoff = hf_text
406+ # Show key sections
407+ for section in ["Where Things Stand" , "What I'd Do Next" ]:
408+ if section .lower () in hf_text .lower ():
409+ idx = hf_text .lower ().index (section .lower ())
410+ end = hf_text .find ("\n ##" , idx + 10 )
411+ chunk = hf_text [idx :end if end > 0 else idx + 200 ].strip ()
412+ lines = [l for l in chunk .split ("\n " ) if l .strip () and not l .startswith ("#" )][:2 ]
413+ print (f" { section } : { ' ' .join (lines )[:80 ]} " )
414+ else :
415+ print (f"📋 No baton — fresh agent (Gen-0)" )
416+
417+ # Create vessel repo (only for fresh agents)
418+ self ._req ("POST" , "/repo" , {"name" : self .vessel ,
419+ "description" : f"FLUX-native I2I agent via keeper" })
376420
377421 # Discover fleet
378422 vessels = self ._req ("GET" , "/discover" ).get ("vessels" , [])
379423 print (f"🔍 Discovered { len (vessels )} fleet vessels" )
380424
381- # Read bootcamp
382- bootcamp = self ._req ("GET" , "/file/SuperInstance/oracle1-vessel/for-fleet/WELCOME-OPUS.md" )
383- content = bootcamp .get ("decoded" , "" )
384- print (f"📖 Read bootcamp: { len (content )} chars" )
385-
386425 # Announce via I2I
426+ announce_type = "BATON_RECEIVED" if generation > 0 else "DISCOVER"
387427 self ._req ("POST" , "/i2i" , {
388428 "target" : "SuperInstance/oracle1-vessel" ,
389- "type" : "DISCOVER" ,
390- "payload" : {"agent" : self .vessel , "capabilities" : ["keeper-aware" ], "confidence" : self .confidence },
429+ "type" : announce_type ,
430+ "payload" : {"agent" : self .vessel , "capabilities" : ["keeper-aware" , "baton-native" ],
431+ "confidence" : self .confidence , "generation" : generation },
391432 "confidence" : self .confidence ,
392433 })
393- print (f"📨 Sent I2I DISCOVER to Oracle1" )
434+ print (f"📨 Sent I2I { announce_type } to Oracle1" )
394435
395436 # Check status
396437 status = self ._req ("GET" , "/status" )
397- self .energy = status .get ("energy_remaining" , 0 )
438+ self .energy = status .get ("energy" , status . get ( " energy_remaining" , self . energy ) )
398439 print (f"⚡ Energy: { self .energy } " )
399440
400- print (f"\n ✅ { self .vessel } ONLINE via keeper" )
441+ gen_label = f"Gen-{ generation } " if generation > 0 else "Gen-0 (fresh)"
442+ print (f"\n ✅ { self .vessel } ONLINE via keeper — { gen_label } " )
401443 return self .vessel
444+
445+ def pack_baton (self , who_i_was , where_things_stand , what_i_was_thinking ,
446+ what_id_do_next , what_im_uncertain_about ,
447+ open_threads = None , tasks_completed = 0 , tasks_failed = 0 ):
448+ """Pack a baton — call when context is running out."""
449+ threads_text = "\n " .join (f"- { t } " for t in (open_threads or ["None" ]))
450+ letter = f"""# Handoff Letter
451+
452+ ## Who I Was\n { who_i_was }
453+
454+ ## Where Things Stand\n { where_things_stand }
455+
456+ ## What I Was Thinking\n { what_i_was_thinking }
457+
458+ ## What I'd Do Next\n { what_id_do_next }
459+
460+ ## What I'm Uncertain About\n { what_im_uncertain_about }
461+
462+ ## State\n - Energy: { self .energy } /1000\n - Confidence: { self .confidence } \n - Tasks completed: { tasks_completed } \n - Tasks failed: { tasks_failed } \n \n ## Open Threads\n { threads_text } \n \n Good luck. You know more than you think.\n """
463+
464+ # Score the handoff
465+ score_result = self ._req ("POST" , "/baton/x/score" , {"letter" : letter })
466+ avg = score_result .get ("average" , 0 )
467+ passes = score_result .get ("passes" , False )
468+ print (f" Handoff score: { avg } ({ 'PASS' if passes else 'NEEDS WORK' } )" )
469+
470+ if not passes :
471+ print (f" ⚠️ Handoff failed quality gate — rewriting recommended" )
472+ return None
473+
474+ # Write baton files
475+ repo = f"SuperInstance/{ self .vessel } "
476+ gen = 1 # TODO: read current generation
477+
478+ self ._req ("POST" , f"/file/{ repo } /.baton/GENERATION" , {"content" : str (gen ), "message" : f"baton: gen { gen } " })
479+ self ._req ("POST" , f"/file/{ repo } /.baton/CURRENT/HANDOFF.md" , {"content" : letter , "message" : f"baton: handoff gen-{ gen } " })
480+ self ._req ("POST" , f"/file/{ repo } /.baton/CURRENT/STATE.json" , {
481+ "content" : json .dumps ({"energy" : {"remaining" : self .energy , "budget" : 1000 },
482+ "confidence" : self .confidence , "open_threads" : open_threads or [],
483+ "tasks_completed" : tasks_completed }, indent = 2 ),
484+ "message" : f"baton: state gen-{ gen } " })
485+
486+ # Notify keeper
487+ self ._req ("POST" , "/i2i" , {"target" : repo , "type" : "BATON_PACKED" ,
488+ "payload" : {"generation" : gen , "score" : avg }, "confidence" : self .confidence })
489+
490+ print (f" ✅ Baton packed — generation { gen } , score { avg } " )
491+ return {"generation" : gen , "score" : avg }
402492
403493
404494if __name__ == "__main__" :
0 commit comments