Custom Formatting Example

This example demonstrates how to format and export conversation history.

  1#!/usr/bin/env python
  2"""
  343 Custom Formatting - Export Conversations
  4
  5Learn how to format and export conversations in various formats:
  6Markdown, HTML, JSON, plain text, and custom formats.
  7
  8Level: Expert Topic
  9"""
 10
 11from config_loader import get_chat_config, parse_args
 12
 13from lexilux import Chat, ChatHistory, ChatHistoryFormatter, Conversation
 14
 15
 16def main():
 17    """Demonstrate custom formatting features."""
 18    args = parse_args()
 19    try:
 20        config = get_chat_config(config_path=args.config)
 21    except (FileNotFoundError, KeyError) as e:
 22        print(f"Configuration error: {e}")
 23        print("\nUsing placeholder values. Please configure test_endpoints.json")
 24        config = {
 25            "base_url": "https://api.example.com/v1",
 26            "api_key": "your-api-key",
 27            "model": "gpt-4",
 28        }
 29
 30    chat = Chat(**config)
 31
 32    # Create a sample conversation
 33    print("Creating sample conversation...\n")
 34    conv = Conversation()
 35    conv.chat(chat, "What is Python?")
 36    conv.chat(chat, "Give me 3 key features")
 37    conv.chat(chat, "That's helpful, thanks!")
 38
 39    history = conv.to_history()
 40
 41    # Example 1: Markdown formatting
 42    print("=" * 50)
 43    print("Example 1: Markdown Format")
 44    print("=" * 50)
 45
 46    formatter = ChatHistoryFormatter()
 47    markdown = formatter.format_markdown(history)
 48
 49    print(markdown)
 50    print()
 51
 52    # Example 2: HTML formatting
 53    print("=" * 50)
 54    print("Example 2: HTML Format")
 55    print("=" * 50)
 56
 57    html = formatter.format_html(history, theme="light")
 58
 59    print(html[:300] + "...\n")
 60
 61    # Example 3: Plain text formatting
 62    print("=" * 50)
 63    print("Example 3: Plain Text Format")
 64    print("=" * 50)
 65
 66    text = formatter.format_text(history, width=60)
 67
 68    print(text)
 69    print()
 70
 71    # Example 4: JSON format
 72    print("=" * 50)
 73    print("Example 4: JSON Format")
 74    print("=" * 50)
 75
 76    json_str = formatter.format_json(history)
 77
 78    print(json_str[:200] + "...\n")
 79
 80    # Example 5: Custom formatting
 81    print("=" * 50)
 82    print("Example 5: Custom Formatter")
 83    print("=" * 50)
 84
 85    class CustomFormatter:
 86        """Custom conversation formatter."""
 87
 88        def format(self, history: ChatHistory) -> str:
 89            """Format as a chat log."""
 90            lines = ["=" * 60]
 91            lines.append("CONVERSATION LOG")
 92            lines.append("=" * 60)
 93            lines.append("")
 94
 95            for i, msg in enumerate(history.messages, 1):
 96                role = msg.role.upper()
 97                content = msg.content
 98
 99                lines.append(f"[{i}] {role}:")
100                lines.append("-" * 40)
101                lines.append(content)
102                lines.append("")
103
104            # Add summary
105            lines.append("=" * 60)
106            lines.append("SUMMARY")
107            lines.append("=" * 60)
108            lines.append(f"Total messages: {len(history.messages)}")
109            lines.append(f"Total tokens: {history.usage.total_tokens}")
110
111            return "\n".join(lines)
112
113    custom_formatter = CustomFormatter()
114    custom_output = custom_formatter.format(history)
115
116    print(custom_output)
117    print()
118
119    # Example 6: Save to file
120    print("=" * 50)
121    print("Example 6: Save to File")
122    print("=" * 50)
123
124    import tempfile
125    from pathlib import Path
126
127    # Create a temp directory for demo
128    temp_dir = Path(tempfile.mkdtemp())
129
130    # Save in different formats
131    files = {
132        "conversation.md": formatter.format_markdown(history),
133        "conversation.html": formatter.format_html(history),
134        "conversation.txt": formatter.format_text(history),
135        "conversation.json": formatter.format_json(history),
136    }
137
138    for filename, content in files.items():
139        filepath = temp_dir / filename
140        filepath.write_text(content)
141        print(f"✓ Saved: {filepath}")
142
143    print(f"\nAll files saved to: {temp_dir}\n")
144
145    # Example 7: Format with theme
146    print("=" * 50)
147    print("Example 7: HTML with Different Themes")
148    print("=" * 50)
149
150    themes = ["light", "dark", "auto"]
151
152    for theme in themes:
153        html = formatter.format_html(history, theme=theme)
154        # Count characters as a simple check
155        print(f"Theme '{theme}': {len(html)} characters")
156
157    print()
158
159    # Example 8: Format with/without round numbers
160    print("=" * 50)
161    print("Example 8: Markdown with/without Round Numbers")
162    print("=" * 50)
163
164    print("With round numbers:")
165    with_rounds = formatter.format_markdown(history, include_rounds=True)
166    print(with_rounds[:200] + "...\n")
167
168    print("Without round numbers:")
169    without_rounds = formatter.format_markdown(history, include_rounds=False)
170    print(without_rounds[:200] + "...\n")
171
172    # Example 9: Filtering before formatting
173    print("=" * 50)
174    print("Example 9: Filter Messages Before Formatting")
175    print("=" * 50)
176
177    from lexilux import filter_by_role
178
179    # Format only user messages
180    user_msgs = filter_by_role(history, "user")
181    user_history = ChatHistory(messages=user_msgs)
182
183    print("User messages only:")
184    print(formatter.format_markdown(user_history))
185
186    print("\n✓ Custom formatting completed!")
187
188
189if __name__ == "__main__":
190    main()