File size: 2,907 Bytes
63bc467
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
"""Coin source-item classifier v2.8. Proposals require human review."""
import re

LABELS=["shadowboxing","bag_work","partner_work","footwork","strength","conditioning","mobility","recovery","unknown"]
LETTER_TO_LABEL={"A":"shadowboxing","B":"footwork","C":"conditioning","D":"unknown","E":"bag_work","F":"partner_work"}
SYSTEM_PROMPT=("Classify one boxing workout source item using its immutable parent section only as context. " "A = solo boxing practice, punches, or defense without a partner. " "B = footwork, steps, or agility without punches. " "C = physical conditioning or strength. D = unclear, a heading, or a prescription. " "E = heavy-bag work. F = partner work or sparring. Return one letter only.")

def explicit_activity(text, kind="boxing", allow_kind_fallback=True):
    if re.search(r"\bpush[ -]?ups?\b",text,re.I) and re.search(r"\b(?:jumps?|squats?)\b",text,re.I): return "strength",re.search(r"\bpush[ -]?ups?\b",text,re.I).group(0)
    if re.search(r"\b(?:frontal|fighting) stance\b",text,re.I) and re.search(r"\battack\b",text,re.I): return "shadowboxing",re.search(r"\battack\b",text,re.I).group(0)
    patterns=[("recovery",r"\b(?:rest day|active recovery|recovery day)\b"),("conditioning",r"\b(?:conditioning|running|sprints?|jump rope)\b"),("shadowboxing",r"\b(?:virtual|virual) sparring\b"),("partner_work",r"\b(?:partner work|sparring|partner drill)\b"),("bag_work",r"\bbag work\b"),("shadowboxing",r"\b(?:shadowboxing|shadow boxing|virtual pad work|punch(?:es)?|jab|hooks?|uppercuts?|combos?|combinations?|defen[cs]e|slips?|rolls?)\b"),("strength",r"\b(?:squats?|push[ -]?ups?|pull[ -]?ups?|burpees?|mountain climbers?|leg raises?|tucks?|medicine ball|med ball|dumbbell|kettlebell|deadlift|bench press|snatch|inverted row)\b"),("mobility",r"\b(?:stretches|stretching|stretch|mobility)\b")]
    for activity,pattern in patterns:
        match=re.search(pattern,text,re.I)
        if match:return activity,match.group(0)
    if allow_kind_fallback and kind=="recovery":return "recovery",text.splitlines()[0][:200]
    return None

def explicit_parent_activity(text):
    lines=[line.strip() for line in text.splitlines() if line.strip()]
    heading=" ".join(lines[:2])
    for activity,pattern in (("bag_work",r"\bBAG WORK\b"),("partner_work",r"\b(?:PARTNER WORK|(?<!VIRTUAL )(?<!VIRUAL )SPARRING)\b")):
        match=re.search(pattern,heading,re.I)
        if match:return activity,match.group(0).strip()
    return None

def model_request(source_text,parent_section):
    return {"messages":[{"role":"system","content":SYSTEM_PROMPT},{"role":"user","content":__import__("json").dumps({"item":source_text,"parent_section":parent_section},sort_keys=True,separators=(",",":"))}],"max_tokens":1,"temperature":0,"logprobs":True,"top_logprobs":10,"chat_template_kwargs":{"enable_thinking":False}}

def decode_choice(choice):
    return LETTER_TO_LABEL.get(choice.strip(),"unknown")