| """ |
| 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_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 |
|
|