@@ -466,7 +466,7 @@ def _init_incremental_log(self, query: str) -> Optional[str]:
466466
467467 timestamp = datetime .datetime .now ().strftime ("%Y%m%d_%H%M%S" )
468468 filename = (f"local_sandbox_query_{ self ._query_count :03d} _"
469- f"{ timestamp } .json " )
469+ f"{ timestamp } .md " )
470470 filepath = os .path .join (self ._log_dir , filename )
471471 os .makedirs (self ._log_dir , exist_ok = True )
472472
@@ -481,7 +481,113 @@ def _init_incremental_log(self, query: str) -> Optional[str]:
481481
482482 def _flush_log (self , filepath : str ,
483483 response : List [Dict [str , Any ]]) -> None :
484- """Rewrite log file with current accumulated response."""
485- log_data = {** self ._current_log_meta , "response" : response }
486- with open (filepath , "w" ) as f :
487- json .dump (log_data , f , indent = 2 , default = str )
484+ """Write current conversation state as markdown to the log file."""
485+ try :
486+ meta = self ._current_log_meta
487+ lines : List [str ] = []
488+ lines .append ("# Local Sandbox Query\n " )
489+ lines .append (f"- **Query:** { meta .get ('query_number' , '?' )} " )
490+ lines .append (f"- **Timestamp:** { meta .get ('timestamp' , '?' )} " )
491+ lines .append (f"- **Session:** { meta .get ('session_id' , '?' )} " )
492+ lines .append ("" )
493+ lines .append ("## Prompt\n " )
494+ lines .append (meta .get ("query" , "" ))
495+ lines .append ("\n " )
496+ lines .append ("## Conversation\n " )
497+ turn_num = 0
498+ for entry in response :
499+ etype = entry .get ("type" , "" )
500+ if etype == "assistant" :
501+ turn_num += 1
502+ lines .append (f"### Turn { turn_num } \n " )
503+ for block in entry .get ("content" , []):
504+ btype = block .get ("type" , "" )
505+ if btype == "ThinkingBlock" :
506+ thinking = block .get ("thinking" , "" )
507+ if thinking :
508+ lines .append ("*[thinking]*" )
509+ for tline in thinking .splitlines ():
510+ lines .append (f"> { tline } " )
511+ lines .append ("" )
512+ elif btype == "text" :
513+ lines .append (
514+ f"**Assistant:** "
515+ f"{ block .get ('text' , '' )} \n " )
516+ elif btype == "tool_use" :
517+ name = block .get ("name" , "?" )
518+ tool_id = block .get ("id" , "" )
519+ inp = block .get ("input" , {})
520+ lines .append (
521+ f"**Tool Call:** `{ name } ` "
522+ f"(id: `{ tool_id } `)" )
523+ lines .append ("```json" )
524+ lines .append (json .dumps (
525+ inp , indent = 2 , default = str ))
526+ lines .append ("```\n " )
527+ else :
528+ lines .append (f"**{ btype } :**" )
529+ extra = {k : v for k , v in block .items ()
530+ if k != "type" and v is not None }
531+ if extra :
532+ lines .append ("```json" )
533+ lines .append (json .dumps (
534+ extra , indent = 2 , default = str ))
535+ lines .append ("```" )
536+ lines .append ("" )
537+ elif etype == "user" :
538+ for block in entry .get ("content" , []):
539+ btype = block .get ("type" , "" )
540+ if btype == "tool_result" :
541+ tool_use_id = block .get ("tool_use_id" , "" )
542+ content = block .get ("content" )
543+ is_error = block .get ("is_error" , False )
544+ label = ("Tool Error" if is_error
545+ else "Tool Result" )
546+ lines .append (
547+ f"**{ label } ** "
548+ f"(tool_use_id: `{ tool_use_id } `):" )
549+ if isinstance (content , list ):
550+ for item in content :
551+ if isinstance (item , dict ):
552+ lines .append ("```" )
553+ lines .append (
554+ item .get ("text" , str (item )))
555+ lines .append ("```" )
556+ else :
557+ lines .append ("```" )
558+ lines .append (str (item ))
559+ lines .append ("```" )
560+ elif content is not None :
561+ lines .append ("```" )
562+ lines .append (str (content ))
563+ lines .append ("```" )
564+ lines .append ("" )
565+ elif btype == "text" :
566+ lines .append (
567+ f"**User:** "
568+ f"{ block .get ('text' , '' )} \n " )
569+ else :
570+ lines .append (f"**{ btype } :**" )
571+ extra = {k : v for k , v in block .items ()
572+ if k != "type" and v is not None }
573+ if extra :
574+ lines .append ("```json" )
575+ lines .append (json .dumps (
576+ extra , indent = 2 , default = str ))
577+ lines .append ("```" )
578+ lines .append ("" )
579+ elif etype == "result" :
580+ turns = entry .get ("num_turns" , "?" )
581+ cost = entry .get ("total_cost_usd" )
582+ cost_str = (f"${ cost :.2f} " if cost is not None
583+ else "?" )
584+ lines .append (
585+ f"---\n \n **Result:** "
586+ f"{ turns } turns, { cost_str } \n " )
587+ elif etype == "error" :
588+ lines .append (
589+ f"**Error:** { entry .get ('error' , '' )} \n " )
590+ with open (filepath , "w" ) as lf :
591+ lf .write ("\n " .join (lines ))
592+ except Exception :
593+ pass # Don't let logging errors break the agent
0 commit comments