""" TD Lang Errors — Clear, helpful error messages. Milan is 11 — errors should say what went wrong and where, not dump cryptic stack traces. """ class TDLangError(Exception): """Base error for all td_lang errors.""" def __init__(self, message: str, line: int | None = None, hint: str | None = None): self.line = line self.hint = hint if line is not None: full = f"Line {line}: {message}" else: full = message if hint: full += f"\n Hint: {hint}" super().__init__(full) class TDSyntaxError(TDLangError): """Bad .td syntax — couldn't understand the file.""" pass class TDCompileError(TDLangError): """Valid syntax but impossible plan — e.g., merging into a model that doesn't exist.""" pass class TDGateError(TDLangError): """Gates failed during execution.""" def __init__(self, failed_gates: list[str], message: str = ""): self.failed_gates = failed_gates msg = message or f"Gates failed: {', '.join(failed_gates)}" super().__init__(msg, hint="Check eval results — the model may have regressed.") class TDBudgetError(TDLangError): """Budget would be exceeded — compiler refuses to run.""" def __init__(self, field: str, limit: float, requested: float): self.field = field self.limit = limit self.requested = requested super().__init__( f"Budget exceeded: {field} limit is {limit}, but plan needs ~{requested}", hint="Reduce steps, use fewer merges, or increase the budget.", ) class TDContractError(TDLangError): """Data or reward contract violation — training data doesn't match spec.""" def __init__(self, contract_type: str, violations: list[str]): self.contract_type = contract_type self.violations = violations msg = f"{contract_type} contract failed with {len(violations)} violation(s)" if violations: msg += f": {violations[0]}" if len(violations) > 1: msg += f" (and {len(violations)-1} more)" super().__init__( msg, hint="Check your training data matches the contract spec.", ) # ============================================================================ # COMMON MISTAKE SUGGESTIONS (Phase 5) # ============================================================================ COMMON_FIXES = { "load": 'Did you forget quotes? Correct: load "model/path" as name', "merge": 'Format: merge "source" into target using method [strength 0.5]', "edit": "Format: edit target layers 16-28 using lora [lr 1e-4]", "prune": "Format: prune target using wanda [aggressiveness 0.2]", "fork": "Format: fork source as new_name", "reset": 'Format: reset target to "checkpoint_path"', "train": 'Format: train target on "dataset" using grpo [steps 64]', "synth": "Format: synth target from source [filter cherry_llm]", "snapshot": "Format: snapshot target [-> output_dir]", "report": "Format: report [-> economics.json]", "fuse": 'Format: fuse ["model1", "model2"] into target [strategy equal]', "absorb": 'Format: absorb "model" into target [strength 0.5]', "schedule": 'Format: schedule "every 6h" { commands... } or schedule "at 02:00" { ... }', "download": 'Format: download "dataset_name" as alias [split train]', "log": 'Format: log "output.txt" (place before commands to capture output)', "compare": 'Format: compare target vs "source_model" [questions 50] [-> output.json]', "verify": 'Format: verify target on "dataset" [questions 100] [-> output.json]', "vote": 'Format: vote target "question" [samples 5] [-> output.json]', "prompt": 'Format: prompt target "Think step by step before answering."', "distill": 'Format: distill target into "small_model" [steps 200] [-> output_dir]', "rollback": "Format: rollback target (reverts to most recent snapshot)", "curriculum": 'Format: curriculum target on "dataset" using grpo [levels 3] [steps 64]', "star": 'Format: star target on "dataset" [rounds 3] [samples 8]', "best_of": 'Format: best_of target on "dataset" [n 8] [steps 32]', "exploit": 'Format: exploit target on "dataset" [samples 16] [steps 32] [-> output.jsonl]', "arena": 'Format: arena target on "dataset" [rounds 5] [episodes 50] [steps 64] [curiosity 0.3] [-> log.json]', "research_arena": 'Format: research_arena target topic "subject" [sources "pubmed"|"web"|"arxiv"] [rounds 5] [episodes 30] [-> log.json]', } def suggest_fix(token: str) -> str | None: """Given a failed token, suggest the correct syntax.""" token_lower = token.lower().strip() for keyword, fix in COMMON_FIXES.items(): if keyword in token_lower: return fix return None