""" Generates synthetic fine-tuning examples in the format. Each adapter needs examples where the assistant emits a valid ui_spec wrapped in tags followed by a prose explanation. Usage: python training/generate_examples.py --mode support --n 50 -o data/support.jsonl python training/generate_examples.py --mode analytics --n 50 -o data/analytics.jsonl python training/generate_examples.py --mode form --n 50 -o data/form.jsonl python training/generate_examples.py --all -o data/ """ import argparse import json import random from pathlib import Path from typing import Callable # ── support examples ────────────────────────────────────────────────────────── _SUPPORT_ISSUES = [ ("login fails with 401", "Authentication error — token may be expired."), ("page not loading", "Possible network timeout or server error."), ("export button missing", "Feature may be behind a permission flag."), ("data not syncing", "Background sync may be paused or failing silently."), ("slow performance", "Cache may be stale — clearing it often helps."), ] def _support_example() -> dict: issue, summary = random.choice(_SUPPORT_ISSUES) steps = ["Check console for error codes", "Clear cache and retry", "Verify account permissions", "Contact support with error ID"] spec = { "component": "card", "props": { "title": f"Troubleshooting: {issue}", "body": summary, "items": [{"label": f"Step {i+1}", "value": s} for i, s in enumerate(steps)], }, } user = f"I have an issue: {issue}" assist = f"{json.dumps(spec)}\n\n{summary} Here are the recommended steps." return {"messages": [{"role": "user", "content": user}, {"role": "assistant", "content": assist}]} # ── analytics examples ──────────────────────────────────────────────────────── _METRICS = ["revenue", "active users", "churn rate", "conversion", "page views"] _PERIODS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"] def _analytics_example() -> dict: metric = random.choice(_METRICS) values = [random.randint(100, 900) for _ in _PERIODS] spec = { "component": "chart", "props": { "title": f"{metric.title()} — Last 6 Months", "type": "bar", "data": { "labels": _PERIODS, "datasets": [{"label": metric.title(), "data": values}], }, }, } user = f"Show me {metric} trends over the last 6 months" insight = f"Peak was {_PERIODS[values.index(max(values))]} at {max(values)}." assist = f"{json.dumps(spec)}\n\n{insight}" return {"messages": [{"role": "user", "content": user}, {"role": "assistant", "content": assist}]} # ── form examples ───────────────────────────────────────────────────────────── _FORMS = [ { "title": "Contact Support", "submitLabel": "Send Request", "fields": [ {"name": "name", "label": "Full Name", "type": "text", "required": True}, {"name": "email", "label": "Email", "type": "email", "required": True}, {"name": "subject", "label": "Subject", "type": "text"}, {"name": "message", "label": "Message", "type": "textarea", "required": True}, ], }, { "title": "Account Registration", "submitLabel": "Create Account", "fields": [ {"name": "username", "label": "Username", "type": "text", "required": True}, {"name": "email", "label": "Email", "type": "email", "required": True}, {"name": "password", "label": "Password", "type": "password", "required": True}, {"name": "plan", "label": "Plan", "type": "select", "options": ["Free", "Pro", "Enterprise"]}, ], }, { "title": "Export Data", "submitLabel": "Export", "fields": [ {"name": "format", "label": "Format", "type": "select", "options": ["CSV", "JSON", "Excel"]}, {"name": "date_from", "label": "From", "type": "date", "required": True}, {"name": "date_to", "label": "To", "type": "date", "required": True}, ], }, ] def _form_example() -> dict: form_def = random.choice(_FORMS) spec = {"component": "form", "props": form_def} user = f"I need to {form_def['submitLabel'].lower()}" assist = (f"{json.dumps(spec)}\n\n" f"Please fill in the {form_def['title']} form below.") return {"messages": [{"role": "user", "content": user}, {"role": "assistant", "content": assist}]} # ── generator dispatch ──────────────────────────────────────────────────────── _GENERATORS: dict[str, Callable[[], dict]] = { "support": _support_example, "analytics": _analytics_example, "form": _form_example, } def generate(mode: str, n: int) -> list[dict]: fn = _GENERATORS[mode] return [fn() for _ in range(n)] def write_jsonl(examples: list[dict], path: Path) -> None: path.parent.mkdir(parents=True, exist_ok=True) with open(path, "w", encoding="utf-8") as f: for ex in examples: f.write(json.dumps(ex, ensure_ascii=False) + "\n") print(f"Wrote {len(examples)} examples → {path}") # ── CLI ─────────────────────────────────────────────────────────────────────── def main() -> None: p = argparse.ArgumentParser(description="Generate synthetic adapter training data") p.add_argument("--mode", choices=list(_GENERATORS.keys()), help="Adapter mode to generate for") p.add_argument("--all", action="store_true", help="Generate for all modes (saves to /.jsonl)") p.add_argument("--n", type=int, default=50, help="Examples per mode") p.add_argument("-o", "--output", default="data", help="Output path or directory") args = p.parse_args() modes = list(_GENERATORS.keys()) if args.all else ([args.mode] if args.mode else []) if not modes: p.error("Specify --mode or --all") out = Path(args.output) for mode in modes: dest = (out / f"{mode}.jsonl") if args.all or out.suffix != ".jsonl" else out write_jsonl(generate(mode, args.n), dest) if __name__ == "__main__": main()