a digital person for bluesky

Improve reply thread display and reduce verbose logs

- Replace plain text reply thread with Rich panels for better formatting
- Hide verbose log messages by changing to debug level
- Filter out usage_statistics and stop_reason message types
- Clean up tool result displays for bluesky posts
- Skip archival_memory_insert result displays (always None)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

Changed files
+58 -32
+58 -32
bsky.py
··· 425 425 try: 426 426 args = json.loads(chunk.tool_call.arguments) 427 427 # Format based on tool type 428 - if tool_name == 'bluesky_reply': 429 - messages = args.get('messages', [args.get('message', '')]) 430 - lang = args.get('lang', 'en-US') 431 - if messages and isinstance(messages, list): 432 - preview = messages[0][:100] + "..." if len(messages[0]) > 100 else messages[0] 433 - msg_count = f" ({len(messages)} msgs)" if len(messages) > 1 else "" 428 + if tool_name in ['add_post_to_bluesky_reply_thread', 'bluesky_reply']: 429 + # Extract the text being posted 430 + text = args.get('text', '') 431 + if text: 434 432 if USE_RICH: 435 - tool_panel = Panel( 436 - f"\"{preview}\"{msg_count} [lang: {lang}]", 437 - title=f"Tool call: {tool_name}", 433 + post_panel = Panel( 434 + text, 435 + title="Bluesky Post", 438 436 title_align="left", 439 437 border_style="blue", 440 438 padding=(0, 1) 441 439 ) 442 - console.print(tool_panel) 440 + console.print(post_panel) 443 441 else: 444 - logger.info(f"Tool call: {tool_name} → \"{preview}\"{msg_count} [lang: {lang}]") 442 + print(f"\n{'='*60}") 443 + print("Bluesky Post") 444 + print('='*60) 445 + print(text) 446 + print('='*60 + "\n") 445 447 else: 446 448 log_with_panel(chunk.tool_call.arguments[:150] + "...", f"Tool call: {tool_name}", "blue") 447 449 elif tool_name == 'archival_memory_search': ··· 539 541 except Exception as e: 540 542 logger.error(f"Error formatting archival memory results: {e}") 541 543 log_with_panel(result_str[:100] + "...", f"Tool result: {tool_name} ✓", "green") 542 - elif tool_name == 'bluesky_reply': 543 - log_with_panel("Reply posted successfully", f"Tool result: {tool_name} ✓", "green") 544 + elif tool_name == 'add_post_to_bluesky_reply_thread': 545 + # Just show success for bluesky posts, the text was already shown in tool call 546 + log_with_panel("Post queued successfully", f"Bluesky Post ✓", "green") 547 + elif tool_name == 'archival_memory_insert': 548 + # Skip archival memory insert results (always returns None) 549 + pass 544 550 elif tool_name == 'update_block': 545 551 log_with_panel("Memory block updated", f"Tool result: {tool_name} ✓", "green") 546 552 else: ··· 551 557 log_with_panel("Success", f"Tool result: {tool_name} ✓", "green") 552 558 elif status == 'error': 553 559 # Show error details 554 - error_preview = "" 555 - if hasattr(chunk, 'tool_return') and chunk.tool_return: 556 - error_str = str(chunk.tool_return) 557 - error_preview = error_str[:100] + "..." if len(error_str) > 100 else error_str 558 - log_with_panel(f"Error: {error_preview}", f"Tool result: {tool_name} ✗", "red") 560 + if tool_name == 'add_post_to_bluesky_reply_thread': 561 + error_str = str(chunk.tool_return) if hasattr(chunk, 'tool_return') and chunk.tool_return else "Error occurred" 562 + log_with_panel(error_str, f"Bluesky Post ✗", "red") 563 + elif tool_name == 'archival_memory_insert': 564 + # Skip archival memory insert errors too 565 + pass 559 566 else: 560 - log_with_panel("Error occurred", f"Tool result: {tool_name} ✗", "red") 567 + error_preview = "" 568 + if hasattr(chunk, 'tool_return') and chunk.tool_return: 569 + error_str = str(chunk.tool_return) 570 + error_preview = error_str[:100] + "..." if len(error_str) > 100 else error_str 571 + log_with_panel(f"Error: {error_preview}", f"Tool result: {tool_name} ✗", "red") 572 + else: 573 + log_with_panel("Error occurred", f"Tool result: {tool_name} ✗", "red") 561 574 else: 562 575 logger.info(f"Tool result: {tool_name} - {status}") 563 576 elif chunk.message_type == 'assistant_message': ··· 579 592 print(f"{chunk.content}") 580 593 print('='*60 + "\n") 581 594 else: 582 - logger.info(f"{chunk.message_type}: {str(chunk)[:150]}...") 595 + # Filter out verbose message types 596 + if chunk.message_type not in ['usage_statistics', 'stop_reason']: 597 + logger.info(f"{chunk.message_type}: {str(chunk)[:150]}...") 583 598 else: 584 599 logger.info(f"📦 Stream status: {chunk}") 585 600 ··· 752 767 753 768 if reply_text: # Only add if there's actual content 754 769 reply_candidates.append((reply_text, reply_lang)) 755 - logger.info(f"Found successful add_post_to_bluesky_reply_thread candidate: {reply_text[:50]}... (lang: {reply_lang})") 770 + logger.debug(f"Found successful add_post_to_bluesky_reply_thread candidate: {reply_text[:50]}... (lang: {reply_lang})") 756 771 except json.JSONDecodeError as e: 757 772 logger.error(f"Failed to parse tool call arguments: {e}") 758 773 elif tool_status == 'error': 759 - logger.info(f"⚠️ Skipping failed add_post_to_bluesky_reply_thread tool call (status: error)") 774 + logger.debug(f"Skipping failed add_post_to_bluesky_reply_thread tool call (status: error)") 760 775 else: 761 776 logger.warning(f"⚠️ Skipping add_post_to_bluesky_reply_thread tool call with unknown status: {tool_status}") 762 777 ··· 779 794 # Use the first language for the entire thread (could be enhanced later) 780 795 reply_lang = reply_langs[0] if reply_langs else 'en-US' 781 796 782 - logger.info(f"Found {len(reply_candidates)} add_post_to_bluesky_reply_thread calls, building thread") 797 + logger.debug(f"Found {len(reply_candidates)} add_post_to_bluesky_reply_thread calls, building thread") 783 798 784 - # Print the generated reply for testing 785 - print(f"\n=== GENERATED REPLY THREAD ===") 786 - print(f"To: @{author_handle}") 799 + # Display the generated reply thread 787 800 if len(reply_messages) == 1: 788 - print(f"Reply: {reply_messages[0]}") 801 + content = reply_messages[0] 802 + title = f"Reply to @{author_handle}" 803 + else: 804 + content = "\n\n".join([f"{j}. {msg}" for j, msg in enumerate(reply_messages, 1)]) 805 + title = f"Reply Thread to @{author_handle} ({len(reply_messages)} messages)" 806 + 807 + if USE_RICH: 808 + reply_panel = Panel( 809 + content, 810 + title=title, 811 + title_align="left", 812 + border_style="green", 813 + padding=(0, 1) 814 + ) 815 + console.print(reply_panel) 789 816 else: 790 - print(f"Reply thread ({len(reply_messages)} messages):") 791 - for j, msg in enumerate(reply_messages, 1): 792 - print(f" {j}. {msg}") 793 - print(f"Language: {reply_lang}") 794 - print(f"======================\n") 817 + print(f"\n{title}") 818 + print("="*60) 819 + print(content) 820 + print("="*60 + "\n") 795 821 796 822 # Send the reply(s) with language (unless in testing mode) 797 823 if testing_mode: