class CompactResponseFormatter
A formatter class that converts verbose LLM responses into compact, symbol-rich text optimized for e-ink displays by using Unicode symbols, mathematical notation, and abbreviated formatting.
/tf/active/vicechatdev/e-ink-llm/compact_formatter.py
22 - 437
moderate
Purpose
This class is designed to transform standard, verbose language model outputs into highly condensed formats suitable for e-ink displays with limited screen space. It replaces common phrases with symbols (e.g., 'â' for 'implies'), uses mathematical notation (e.g., 'â´' for 'therefore'), and structures content with emoji icons for quick visual scanning. The formatter can either work with pre-structured analysis dictionaries or parse raw LLM text to extract key components like insights, equations, action items, and verification steps.
Source Code
class CompactResponseFormatter:
"""Generates compact, symbol-rich responses for e-ink displays"""
def __init__(self):
# Symbol mapping for different content types
self.symbols = {
# Core symbols
'key_insight': 'đŻ',
'summary': 'đ',
'action': 'â
',
'warning': 'â ď¸',
'error': 'â',
'question': 'â',
'info': 'âšď¸',
# Subject-specific symbols
'math': 'đ',
'equation': 'đ§Ž',
'formula': 'â',
'calculation': 'đ˘',
'geometry': 'đ',
'graph': 'đ',
'text': 'đ',
'language': 'đŁď¸',
'translation': 'đ',
'grammar': 'đ',
'writing': 'âď¸',
'science': 'đŹ',
'chemistry': 'âď¸',
'physics': 'âď¸',
'biology': 'đ§Ź',
'medicine': 'đ',
'code': 'đť',
'algorithm': 'đ',
'data': 'đ',
'logic': 'đ§ ',
'design': 'đ¨',
'diagram': 'đ',
'flowchart': 'đ',
'sketch': 'âď¸',
# Process symbols
'step': 'â¤',
'next': 'â',
'result': '=',
'conclusion': 'â´',
'therefore': 'â´',
'because': 'âľ',
'check': 'â',
'cross': 'â',
'reference': 'đ',
'note': 'đĄ'
}
# Compact notation patterns
self.notation_patterns = {
'equals': ' = ',
'approximately': ' â ',
'not_equal': ' â ',
'less_than': ' < ',
'greater_than': ' > ',
'less_equal': ' ⤠',
'greater_equal': ' ⼠',
'plus_minus': ' Âą ',
'infinity': 'â',
'therefore': ' â´ ',
'because': ' âľ ',
'implies': ' â ',
'if_and_only_if': ' â ',
'for_all': 'â',
'exists': 'â',
'element_of': ' â ',
'subset': ' â ',
'union': ' ⪠',
'intersection': ' ⊠',
'degree': '°',
'squared': '²',
'cubed': 'Âł',
'sqrt': 'â',
'pi': 'Ď',
'alpha': 'Îą',
'beta': 'β',
'gamma': 'Îł',
'delta': 'Î',
'theta': 'θ',
'lambda': 'Îť',
'mu': 'Îź',
'sigma': 'ÎŁ'
}
def format_compact_response(self, analysis_result: Dict[str, Any]) -> str:
"""
Convert standard LLM response to compact format
Args:
analysis_result: Dictionary containing analysis from LLM
Returns:
Compact formatted response string
"""
sections = []
# 1. Key insight (always first)
if 'key_insight' in analysis_result:
sections.append(CompactSection(
icon=self.symbols['key_insight'],
title='',
content=analysis_result['key_insight'],
priority=1
))
# 2. Main content (bullets/steps)
if 'main_points' in analysis_result:
content = self._format_bullet_points(analysis_result['main_points'])
sections.append(CompactSection(
icon=self.symbols['summary'],
title='',
content=content,
priority=1
))
# 3. Mathematics (if present)
if 'equations' in analysis_result or 'calculations' in analysis_result:
math_content = self._format_mathematics(analysis_result)
if math_content:
sections.append(CompactSection(
icon=self.symbols['math'],
title='',
content=math_content,
priority=1
))
# 4. Action items
if 'actions' in analysis_result:
actions = ' | '.join(analysis_result['actions'])
sections.append(CompactSection(
icon=self.symbols['action'],
title='',
content=actions,
priority=2
))
# 5. Additional notes
if 'notes' in analysis_result:
sections.append(CompactSection(
icon=self.symbols['note'],
title='',
content=analysis_result['notes'],
priority=3
))
# 6. References/verification
if 'verification' in analysis_result:
sections.append(CompactSection(
icon=self.symbols['check'],
title='',
content=analysis_result['verification'],
priority=3
))
# Build final compact response
return self._build_compact_output(sections)
def _format_bullet_points(self, points: List[str]) -> str:
"""Format bullet points in compact style"""
if not points:
return ""
# Use compact bullets and abbreviations
formatted_points = []
for point in points:
# Apply compact notation
compact_point = self._apply_compact_notation(point)
formatted_points.append(f"⢠{compact_point}")
return '\n'.join(formatted_points)
def _format_mathematics(self, analysis: Dict[str, Any]) -> str:
"""Format mathematical content in compact notation"""
math_parts = []
# Handle equations
if 'equations' in analysis:
equations = analysis['equations']
if isinstance(equations, list):
# Chain equations with arrows
math_parts.append(' â '.join(equations))
else:
math_parts.append(str(equations))
# Handle calculations
if 'calculations' in analysis:
calc = analysis['calculations']
if isinstance(calc, dict):
for step, result in calc.items():
math_parts.append(f"{step} = {result}")
else:
math_parts.append(str(calc))
# Handle solutions
if 'solutions' in analysis:
solutions = analysis['solutions']
if isinstance(solutions, list):
math_parts.append('Solutions: ' + ', '.join(map(str, solutions)))
else:
math_parts.append(f"Solution: {solutions}")
result = ' | '.join(math_parts)
return self._apply_compact_notation(result)
def _apply_compact_notation(self, text: str) -> str:
"""Apply mathematical and logical compact notation"""
# Replace common phrases with symbols
replacements = {
'equals': '=',
'approximately': 'â',
'less than': '<',
'greater than': '>',
'less than or equal': 'â¤',
'greater than or equal': 'âĽ',
'plus or minus': 'Âą',
'therefore': 'â´',
'because': 'âľ',
'implies': 'â',
'degrees': '°',
'squared': '²',
'cubed': 'Âł',
'square root': 'â',
'pi': 'Ď',
'infinity': 'â',
'delta': 'Î',
'theta': 'θ',
'alpha': 'Îą',
'beta': 'β',
'gamma': 'Îł',
'sigma': 'ÎŁ'
}
result = text
for phrase, symbol in replacements.items():
result = re.sub(rf'\b{re.escape(phrase)}\b', symbol, result, flags=re.IGNORECASE)
# Remove redundant words
redundant_patterns = [
r'\bwe can see that\b',
r'\bit is clear that\b',
r'\bobviously\b',
r'\blet me\b',
r'\blet us\b',
r'\bI can\b',
r'\bI will\b',
r'\bfirst,?\s*',
r'\bsecond,?\s*',
r'\bthird,?\s*',
r'\bnext,?\s*',
r'\bfinally,?\s*'
]
for pattern in redundant_patterns:
result = re.sub(pattern, '', result, flags=re.IGNORECASE)
# Clean up extra spaces
result = re.sub(r'\s+', ' ', result).strip()
return result
def _build_compact_output(self, sections: List[CompactSection]) -> str:
"""Build final compact output from sections"""
# Sort by priority
sections.sort(key=lambda x: x.priority)
output_lines = []
for section in sections:
if section.content.strip():
if section.title:
line = f"{section.icon} {section.title}: {section.content}"
else:
line = f"{section.icon} {section.content}"
output_lines.append(line)
return '\n'.join(output_lines)
def parse_llm_response_to_compact(self, llm_response: str) -> str:
"""
Parse a standard verbose LLM response and convert to compact format
Args:
llm_response: Raw response from LLM
Returns:
Compact formatted version
"""
# Simple parsing strategy - look for key patterns
analysis = {
'key_insight': self._extract_key_insight(llm_response),
'main_points': self._extract_main_points(llm_response),
'equations': self._extract_equations(llm_response),
'solutions': self._extract_solutions(llm_response),
'actions': self._extract_actions(llm_response),
'verification': self._extract_verification(llm_response)
}
# Remove empty values
analysis = {k: v for k, v in analysis.items() if v}
return self.format_compact_response(analysis)
def _extract_key_insight(self, text: str) -> Optional[str]:
"""Extract the main insight/conclusion from text"""
patterns = [
r'(?:the main|key|primary|central)\s+(?:insight|finding|point|conclusion|result)(?:\s+is)?:?\s*(.+?)(?:\.|$)',
r'(?:in summary|to summarize|conclusion)[:,]?\s*(.+?)(?:\.|$)',
r'(?:this shows|this indicates|this means)(?:\s+that)?\s*(.+?)(?:\.|$)'
]
for pattern in patterns:
match = re.search(pattern, text, re.IGNORECASE | re.DOTALL)
if match:
return match.group(1).strip()[:100] # Limit length
# Fallback: first sentence
sentences = re.split(r'[.!?]', text)
if sentences:
return sentences[0].strip()[:100]
return None
def _extract_main_points(self, text: str) -> List[str]:
"""Extract bullet points or main ideas"""
points = []
# Look for numbered lists
numbered_pattern = r'^\d+[\.\)]\s*(.+?)(?=\n\d+[\.\)]|\n\n|\Z)'
numbered_matches = re.findall(numbered_pattern, text, re.MULTILINE | re.DOTALL)
if numbered_matches:
points.extend([p.strip() for p in numbered_matches])
# Look for bullet points
bullet_pattern = r'^[-*â˘]\s*(.+?)(?=\n[-*â˘]|\n\n|\Z)'
bullet_matches = re.findall(bullet_pattern, text, re.MULTILINE | re.DOTALL)
if bullet_matches:
points.extend([p.strip() for p in bullet_matches])
# If no lists found, split by sentences and take first few
if not points:
sentences = re.split(r'[.!?]', text)
points = [s.strip() for s in sentences[:3] if s.strip()]
# Clean up and limit
return [self._apply_compact_notation(p) for p in points[:5]]
def _extract_equations(self, text: str) -> List[str]:
"""Extract mathematical equations"""
equations = []
# Look for mathematical expressions
math_patterns = [
r'([a-zA-Z]\w*\s*[=â<>â¤âĽ]\s*[^.]+?)(?:\.|$)',
r'(\([^)]+\)\s*[=â]\s*[^.]+?)(?:\.|$)',
r'([xyz²³]\s*[+\-*/=]\s*[^.]+?)(?:\.|$)'
]
for pattern in math_patterns:
matches = re.findall(pattern, text)
equations.extend([m.strip() for m in matches])
return equations[:3] # Limit to first 3
def _extract_solutions(self, text: str) -> List[str]:
"""Extract solutions or answers"""
solution_patterns = [
r'(?:solution|answer|result)(?:s)?\s*(?:is|are)?:?\s*([^.]+)',
r'([xyz]\s*=\s*[^.]+)',
r'(?:therefore|thus|hence),?\s*([^.]+)'
]
solutions = []
for pattern in solution_patterns:
matches = re.findall(pattern, text, re.IGNORECASE)
solutions.extend([m.strip() for m in matches])
return solutions[:3]
def _extract_actions(self, text: str) -> List[str]:
"""Extract action items or next steps"""
action_patterns = [
r'(?:next step|action|recommendation|suggestion)(?:s)?:?\s*(.+?)(?:\.|$)',
r'(?:you should|recommended to|suggested to)\s*(.+?)(?:\.|$)',
r'(?:consider|try|attempt)\s*(.+?)(?:\.|$)'
]
actions = []
for pattern in action_patterns:
matches = re.findall(pattern, text, re.IGNORECASE)
actions.extend([m.strip() for m in matches])
return actions[:3]
def _extract_verification(self, text: str) -> Optional[str]:
"""Extract verification or check information"""
verify_patterns = [
r'(?:verify|check|confirm)(?:ing)?:?\s*(.+?)(?:\.|$)',
r'(?:proof|verification):\s*(.+?)(?:\.|$)'
]
for pattern in verify_patterns:
match = re.search(pattern, text, re.IGNORECASE)
if match:
return match.group(1).strip()[:80]
return None
Parameters
| Name | Type | Default | Kind |
|---|---|---|---|
bases |
- | - |
Parameter Details
__init__: No parameters required. The constructor initializes two dictionaries: 'symbols' containing emoji/icon mappings for different content types (math, science, actions, etc.) and 'notation_patterns' containing mathematical and logical symbols for compact notation.
Return Value
Instantiation returns a CompactResponseFormatter object. The main methods return strings: format_compact_response() and parse_llm_response_to_compact() both return compact formatted strings with symbols and abbreviated text. Helper methods return extracted components (lists of strings, optional strings, or formatted strings).
Class Interface
Methods
__init__(self)
Purpose: Initialize the formatter with symbol mappings and notation patterns
Returns: None - initializes instance with symbols and notation_patterns dictionaries
format_compact_response(self, analysis_result: Dict[str, Any]) -> str
Purpose: Convert a structured analysis dictionary into compact formatted text with symbols
Parameters:
analysis_result: Dictionary containing structured analysis with keys like 'key_insight', 'main_points', 'equations', 'calculations', 'solutions', 'actions', 'notes', 'verification'
Returns: Compact formatted string with emoji icons and abbreviated notation, organized by priority
parse_llm_response_to_compact(self, llm_response: str) -> str
Purpose: Parse raw verbose LLM text and convert it to compact format by extracting key components
Parameters:
llm_response: Raw text response from an LLM that needs to be condensed
Returns: Compact formatted string after extracting and structuring content from the raw text
_format_bullet_points(self, points: List[str]) -> str
Purpose: Format a list of points into compact bullet-point style with notation applied
Parameters:
points: List of text strings to format as bullet points
Returns: Newline-separated string of bullet points with compact notation applied
_format_mathematics(self, analysis: Dict[str, Any]) -> str
Purpose: Extract and format mathematical content (equations, calculations, solutions) in compact notation
Parameters:
analysis: Dictionary potentially containing 'equations', 'calculations', and 'solutions' keys
Returns: Pipe-separated string of mathematical expressions with compact notation
_apply_compact_notation(self, text: str) -> str
Purpose: Replace verbose phrases with mathematical/logical symbols and remove redundant words
Parameters:
text: Text string to be compacted
Returns: Compacted text with symbols replacing words (e.g., 'equals' â '=', 'therefore' â 'â´')
_build_compact_output(self, sections: List[CompactSection]) -> str
Purpose: Assemble final compact output from sorted sections with icons
Parameters:
sections: List of CompactSection objects containing icon, title, content, and priority
Returns: Newline-separated string of formatted sections sorted by priority
_extract_key_insight(self, text: str) -> Optional[str]
Purpose: Extract the main insight or conclusion from raw text using pattern matching
Parameters:
text: Raw text to extract insight from
Returns: Extracted insight string (max 100 chars) or None if not found
_extract_main_points(self, text: str) -> List[str]
Purpose: Extract bullet points, numbered lists, or main ideas from text
Parameters:
text: Raw text to extract points from
Returns: List of up to 5 extracted and compacted main points
_extract_equations(self, text: str) -> List[str]
Purpose: Extract mathematical equations and expressions from text
Parameters:
text: Raw text containing mathematical content
Returns: List of up to 3 extracted equation strings
_extract_solutions(self, text: str) -> List[str]
Purpose: Extract solutions, answers, or results from text
Parameters:
text: Raw text containing solutions
Returns: List of up to 3 extracted solution strings
_extract_actions(self, text: str) -> List[str]
Purpose: Extract action items, recommendations, or next steps from text
Parameters:
text: Raw text containing action items
Returns: List of up to 3 extracted action strings
_extract_verification(self, text: str) -> Optional[str]
Purpose: Extract verification or checking information from text
Parameters:
text: Raw text containing verification steps
Returns: Extracted verification string (max 80 chars) or None if not found
Attributes
| Name | Type | Description | Scope |
|---|---|---|---|
symbols |
Dict[str, str] | Dictionary mapping content type names to emoji/Unicode symbols for visual categorization (e.g., 'math': 'đ', 'action': 'â ') | instance |
notation_patterns |
Dict[str, str] | Dictionary mapping mathematical/logical terms to their compact symbol representations (e.g., 'equals': ' = ', 'therefore': ' â´ ') | instance |
Dependencies
rejsontypingdataclasses
Required Imports
import re
import json
from typing import Dict, List, Any, Optional
from dataclasses import dataclass
Usage Example
# Instantiate the formatter
formatter = CompactResponseFormatter()
# Method 1: Format pre-structured analysis
analysis = {
'key_insight': 'The equation has two real solutions',
'main_points': ['Factor the quadratic', 'Apply zero product property', 'Solve for x'],
'equations': ['x² - 5x + 6 = 0', '(x-2)(x-3) = 0'],
'solutions': ['x = 2', 'x = 3'],
'actions': ['Verify by substitution']
}
compact_output = formatter.format_compact_response(analysis)
print(compact_output)
# Output: đŻ The equation has two real solutions
# đ ⢠Factor the quadratic
# ⢠Apply zero product property
# ⢠Solve for x
# đ x² - 5x + 6 = 0 â (x-2)(x-3) = 0 | Solutions: x = 2, x = 3
# Method 2: Parse raw LLM response
llm_text = "The main conclusion is that x equals 5. First, we solve the equation x + 3 = 8. Therefore x = 5."
compact = formatter.parse_llm_response_to_compact(llm_text)
print(compact)
Best Practices
- The class is stateless after initialization - safe to reuse the same instance for multiple formatting operations
- Use format_compact_response() when you have structured data from your LLM (recommended for better control)
- Use parse_llm_response_to_compact() for quick conversion of raw LLM text, but expect less precise extraction
- The CompactSection dataclass must be defined before using this class (it's referenced but not included in the source)
- Compact output is optimized for readability on e-ink displays - test rendering on target device
- Symbol mappings can be customized by modifying self.symbols dictionary after instantiation
- The formatter limits extracted content (e.g., max 5 main points, 3 equations) to prevent overflow on small displays
- Text extraction uses regex patterns that may not capture all variations - consider pre-structuring LLM output for critical applications
- The _apply_compact_notation() method is aggressive in removing redundant words - review output to ensure meaning is preserved
Tags
Similar Components
AI-powered semantic similarity - components with related functionality:
-
function test_compact_formatter 74.6% similar
-
class PDFGenerator 63.6% similar
-
function demo_improvement_comparison 63.0% similar
-
function demo_hybrid_response 58.5% similar
-
class HybridPromptEnhancer 56.8% similar