a digital person for bluesky

Simplify logging format to use plain text with underscores

Replace Rich panel formatting with simple text output using underscores
for titles. This provides a cleaner, more minimal logging style without
external dependencies.

Changes:
- Remove all Rich imports (Panel, Console, Table, Text)
- Replace panel displays with title + underscores format
- Remove --rich command line option
- Update log_with_panel to use simple print statements
- Remove USE_RICH and console global variables

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

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

+45 -154
+45 -154
bsky.py
··· 1 - from rich import print # pretty printing tools 2 - from rich.console import Console 3 - from rich.table import Table 4 - from rich.panel import Panel 5 - from rich.text import Text 1 + # Rich imports removed - using simple text formatting 6 2 from time import sleep 7 3 from letta_client import Letta 8 4 from bsky_utils import thread_to_yaml_string ··· 48 44 # Logging will be configured after argument parsing 49 45 logger = None 50 46 prompt_logger = None 51 - console = None 52 - USE_RICH = False 47 + # Simple text formatting (Rich no longer used) 53 48 SHOW_REASONING = False 54 49 last_archival_query = "archival memory search" 55 50 56 51 def log_with_panel(message, title=None, border_color="white"): 57 - """Log a message with Rich panel if USE_RICH is enabled, otherwise use regular logger""" 58 - if USE_RICH and console: 59 - if title: 60 - panel = Panel( 61 - message, 62 - title=title, 63 - title_align="left", 64 - border_style=border_color, 65 - padding=(0, 1) 66 - ) 67 - console.print(panel) 68 - else: 69 - console.print(message) 52 + """Log a message with simple text format""" 53 + if title: 54 + print(f"\n{title}") 55 + print("_" * len(title)) 56 + print(message) 70 57 else: 71 - logger.info(message) 58 + print(message) 72 59 73 60 74 61 # Create a client with extended timeout for LLM operations ··· 348 335 # Continue without user blocks rather than failing completely 349 336 350 337 # Get response from Letta agent 351 - if USE_RICH: 352 - # Create and print Rich panel directly 353 - mention_panel = Panel( 354 - mention_text, 355 - title=f"MENTION FROM @{author_handle}", 356 - title_align="left", 357 - border_style="cyan", 358 - padding=(0, 1) 359 - ) 360 - console.print(mention_panel) 361 - else: 362 - # Simple text format when Rich is disabled 363 - print(f"\n{'='*60}") 364 - print(f"MENTION FROM @{author_handle}") 365 - print('='*60) 366 - print(f"{mention_text}") 367 - print('='*60 + "\n") 338 + # Simple text format with underscores 339 + title = f"MENTION FROM @{author_handle}" 340 + print(f"\n{title}") 341 + print("_" * len(title)) 342 + print(mention_text) 368 343 369 344 # Log prompt details to separate logger 370 345 prompt_logger.debug(f"Full prompt being sent:\n{prompt}") ··· 389 364 if hasattr(chunk, 'message_type'): 390 365 if chunk.message_type == 'reasoning_message': 391 366 # Show full reasoning without truncation 392 - if SHOW_REASONING and USE_RICH: 393 - # Create and print Rich panel for reasoning 394 - reasoning_panel = Panel( 395 - chunk.reasoning, 396 - title="Reasoning", 397 - title_align="left", 398 - border_style="yellow", 399 - padding=(0, 1) 400 - ) 401 - console.print(reasoning_panel) 402 - elif SHOW_REASONING: 403 - # Simple text format when Rich is disabled but reasoning is enabled 404 - print(f"\n{'='*60}") 405 - print("Reasoning") 406 - print('='*60) 407 - print(f"{chunk.reasoning}") 408 - print('='*60 + "\n") 367 + if SHOW_REASONING: 368 + # Simple text format with underscores 369 + print("\nReasoning") 370 + print("_________") 371 + print(chunk.reasoning) 409 372 else: 410 373 # Default log format (only when --reasoning is used due to log level) 411 - if USE_RICH: 412 - reasoning_panel = Panel( 413 - chunk.reasoning, 414 - title="Reasoning", 415 - title_align="left", 416 - border_style="yellow", 417 - padding=(0, 1) 418 - ) 419 - console.print(reasoning_panel) 420 - else: 421 - logger.info(f"Reasoning: {chunk.reasoning}") 374 + # Simple text format with underscores 375 + print("\nReasoning") 376 + print("_________") 377 + print(chunk.reasoning) 422 378 elif chunk.message_type == 'tool_call_message': 423 379 # Parse tool arguments for better display 424 380 tool_name = chunk.tool_call.name ··· 429 385 # Extract the text being posted 430 386 text = args.get('text', '') 431 387 if text: 432 - if USE_RICH: 433 - post_panel = Panel( 434 - text, 435 - title="Bluesky Post", 436 - title_align="left", 437 - border_style="blue", 438 - padding=(0, 1) 439 - ) 440 - console.print(post_panel) 441 - else: 442 - print(f"\n{'='*60}") 443 - print("Bluesky Post") 444 - print('='*60) 445 - print(text) 446 - print('='*60 + "\n") 388 + # Simple text format with underscores 389 + print("\nBluesky Post") 390 + print("____________") 391 + print(text) 447 392 else: 448 393 log_with_panel(chunk.tool_call.arguments[:150] + "...", f"Tool call: {tool_name}", "blue") 449 394 elif tool_name == 'archival_memory_search': 450 395 query = args.get('query', 'unknown') 451 396 global last_archival_query 452 397 last_archival_query = query 453 - if USE_RICH: 454 - tool_panel = Panel( 455 - f"query: \"{query}\"", 456 - title=f"Tool call: {tool_name}", 457 - title_align="left", 458 - border_style="blue", 459 - padding=(0, 1) 460 - ) 461 - console.print(tool_panel) 462 - else: 463 - log_with_panel(f"query: \"{query}\"", f"Tool call: {tool_name}", "blue") 398 + log_with_panel(f"query: \"{query}\"", f"Tool call: {tool_name}", "blue") 464 399 elif tool_name == 'archival_memory_insert': 465 400 content = args.get('content', '') 466 401 # Show the full content being inserted 467 - if USE_RICH: 468 - tool_panel = Panel( 469 - content, 470 - title=f"Tool call: {tool_name}", 471 - title_align="left", 472 - border_style="blue", 473 - padding=(0, 1) 474 - ) 475 - console.print(tool_panel) 476 - else: 477 - log_with_panel(content, f"Tool call: {tool_name}", "blue") 402 + log_with_panel(content, f"Tool call: {tool_name}", "blue") 478 403 elif tool_name == 'update_block': 479 404 label = args.get('label', 'unknown') 480 405 value_preview = str(args.get('value', ''))[:50] + "..." if len(str(args.get('value', ''))) > 50 else str(args.get('value', '')) ··· 535 460 content = entry.get('content', '') 536 461 content_text += f"[{i}/{len(results)}] {timestamp}\n{content}\n\n" 537 462 538 - if USE_RICH: 539 - # Create and print Rich panel directly 540 - memory_panel = Panel( 541 - content_text.strip(), 542 - title=f"{search_query} ({len(results)} results)", 543 - title_align="left", 544 - border_style="blue", 545 - padding=(0, 1) 546 - ) 547 - console.print(memory_panel) 548 - else: 549 - # Use simple text format when Rich is disabled 550 - print(f"\n{search_query} ({len(results)} results)") 551 - print("="*80) 552 - print(content_text.strip()) 553 - print("="*80 + "\n") 463 + # Simple text format with underscores 464 + title = f"{search_query} ({len(results)} results)" 465 + print(f"\n{title}") 466 + print("_" * len(title)) 467 + print(content_text.strip()) 554 468 555 469 except Exception as e: 556 470 logger.error(f"Error formatting archival memory results: {e}") ··· 588 502 else: 589 503 logger.info(f"Tool result: {tool_name} - {status}") 590 504 elif chunk.message_type == 'assistant_message': 591 - if USE_RICH: 592 - # Create and print Rich panel directly 593 - response_panel = Panel( 594 - chunk.content, 595 - title="Assistant Response", 596 - title_align="left", 597 - border_style="green", 598 - padding=(0, 1) 599 - ) 600 - console.print(response_panel) 601 - else: 602 - # Simple text format when Rich is disabled 603 - print(f"\n{'='*60}") 604 - print("Assistant Response") 605 - print('='*60) 606 - print(f"{chunk.content}") 607 - print('='*60 + "\n") 505 + # Simple text format with underscores 506 + print("\nAssistant Response") 507 + print("__________________") 508 + print(chunk.content) 608 509 else: 609 510 # Filter out verbose message types 610 511 if chunk.message_type not in ['usage_statistics', 'stop_reason']: ··· 818 719 content = "\n\n".join([f"{j}. {msg}" for j, msg in enumerate(reply_messages, 1)]) 819 720 title = f"Reply Thread to @{author_handle} ({len(reply_messages)} messages)" 820 721 821 - if USE_RICH: 822 - reply_panel = Panel( 823 - content, 824 - title=title, 825 - title_align="left", 826 - border_style="green", 827 - padding=(0, 1) 828 - ) 829 - console.print(reply_panel) 830 - else: 831 - print(f"\n{title}") 832 - print("="*60) 833 - print(content) 834 - print("="*60 + "\n") 722 + # Simple text format with underscores 723 + print(f"\n{title}") 724 + print("_" * len(title)) 725 + print(content) 835 726 836 727 # Send the reply(s) with language (unless in testing mode) 837 728 if testing_mode: ··· 1265 1156 parser.add_argument('--test', action='store_true', help='Run in testing mode (no messages sent, queue files preserved)') 1266 1157 parser.add_argument('--no-git', action='store_true', help='Skip git operations when exporting agent state') 1267 1158 parser.add_argument('--simple-logs', action='store_true', help='Use simplified log format (void - LEVEL - message)') 1268 - parser.add_argument('--rich', action='store_true', help='Enable Rich formatting for archival memory display') 1159 + # --rich option removed as we now use simple text formatting 1269 1160 parser.add_argument('--reasoning', action='store_true', help='Display reasoning in panels and set reasoning log level to INFO') 1270 1161 args = parser.parse_args() 1271 1162 ··· 1295 1186 logging.getLogger("httpx").setLevel(logging.CRITICAL) 1296 1187 1297 1188 # Create Rich console for pretty printing 1298 - console = Console() 1189 + # Console no longer used - simple text formatting 1299 1190 1300 - global TESTING_MODE, SKIP_GIT, USE_RICH, SHOW_REASONING 1191 + global TESTING_MODE, SKIP_GIT, SHOW_REASONING 1301 1192 TESTING_MODE = args.test 1302 1193 1303 1194 # Store no-git flag globally for use in export_agent_state calls 1304 1195 SKIP_GIT = args.no_git 1305 1196 1306 1197 # Store rich flag globally 1307 - USE_RICH = args.rich 1198 + # Rich formatting no longer used 1308 1199 1309 1200 # Store reasoning flag globally 1310 1201 SHOW_REASONING = args.reasoning