42 lines
1.2 KiB
Python
42 lines
1.2 KiB
Python
"""Default narration theme: icons per stage, green facts, blue paths."""
|
|
|
|
from . import register_theme
|
|
|
|
ICONS = [
|
|
('loading/', '⬇ '),
|
|
('dataset ready', '📦 '),
|
|
('few-shot', '✳ '),
|
|
('checkpoint', '◷ '),
|
|
('generation skipped', '⏭ '),
|
|
('generating', '🤖 '),
|
|
('generation complete', '✓ '),
|
|
('scoring', '★ '),
|
|
('writing', '📝 '),
|
|
('endpoint', '🔗 '),
|
|
]
|
|
|
|
FACT_COLOR = 'green' # numbers/phrases/scores
|
|
PATH_COLOR = 'blue' # filesystem locations
|
|
|
|
|
|
@register_theme('default')
|
|
def narrate(msg: str) -> str:
|
|
import re
|
|
|
|
low = msg.lower()
|
|
icon = next((i for k, i in ICONS if k in low), '')
|
|
|
|
def fact(text):
|
|
return re.sub(r'(?<![\w/%.])(\d+(?:/\d+)?(?:\s+[a-z-]+){0,4})(?=[\s,.]|$)',
|
|
rf'[{FACT_COLOR}]\1[/{FACT_COLOR}]', text)
|
|
|
|
m = re.search(r'[:·] ([a-zA-Z_@]+ [0-9.]+%)(?=\s|$)', msg)
|
|
if m:
|
|
head = f'{icon}{msg[:m.start()]}: [bold {FACT_COLOR}]{m.group(1)}[/{FACT_COLOR}]'
|
|
return head + fact(msg[m.end():])
|
|
for sep in ('-> ', 'to '):
|
|
head, _, tail = msg.rpartition(sep)
|
|
if head and tail.startswith('/'):
|
|
return f'{icon}{head}{sep}[{PATH_COLOR}]{tail}[/{PATH_COLOR}]'
|
|
return f'{icon}{fact(msg)}'
|