Spaces:
Running on Zero
Running on Zero
Download oev/convert_commands.py from divyanshudhruv/oev-demo: direct link, hf CLI and curl.
- Browser
- Download file 6.23 kB
-
https://huggingface.co/spaces/divyanshudhruv/oev-demo/resolve/main/oev/convert_commands.py
- Command line
-
hf download hf://spaces/divyanshudhruv/oev-demo/oev/convert_commands.py
-
curl -L -o convert_commands.py https://huggingface.co/spaces/divyanshudhruv/oev-demo/resolve/main/oev/convert_commands.py
6.23 kB
| """Synthetic command-intent dataset for the router specialist (seeded, no download). | |
| python -m oev.convert_commands | |
| """ | |
| import json | |
| import os | |
| import random | |
| INTENTS = ["music", "search", "note", "calculator", "app", "unknown"] | |
| INSTRUCTIONS_INTENT = ("What does the user want the computer to do? " | |
| "unknown covers partial commands, bare triggers and chat.") | |
| APPS = ["spotify", "chrome", "notepad", "calculator", "vs code", "discord", | |
| "steam", "explorer", "settings", "terminal"] | |
| SONGS = ["blinding lights", "bohemian rhapsody", "take five", "gimme shelter", | |
| "fly me to the moon", "dream on", "landslide", "redbone", | |
| "electric feel", "ain't no mountain high enough"] | |
| ARTISTS = ["the weeknd", "queen", "dave brubeck", "nina simone", "daft punk", | |
| "fleetwood mac", "tame impala", "miles davis", "chaka khan"] | |
| QUERIES = ["rust async programming", "latest nvidia drivers", "weather tomorrow", | |
| "best noise cancelling headphones", "python deque vs list", | |
| "how to fold a fitted sheet", "distance to the moon", | |
| "cheap flights to lisbon", "markdown table syntax", "is pluto a planet"] | |
| TASKS = ["finish the benchmark writeup", "call the dentist", "water the plants", | |
| "back up the laptop", "renew the domain", "ship the release notes"] | |
| ITEMS = ["oat milk", "printer paper", "a new mouse", "birthday candles", "coffee beans"] | |
| DAYS = ["saturday", "monday", "friday", "tomorrow"] | |
| PEOPLE = ["sam", "priya", "marco", "lena"] | |
| CHAT = ["hello", "hey there", "good morning", "how are you", "thanks a lot", | |
| "what time is it", "tell me a joke", "never mind", "actually stop"] | |
| MUSIC_T = ["play {song} on spotify", "open spotify and play {song}", | |
| "put on {artist}", "play some {artist} songs", "queue up {song}", | |
| "play {song} by {artist}", "start {artist} radio"] | |
| SEARCH_T = ["search the web for {query}", "search youtube for {query}", | |
| "google {query}", "look up {query}", "find {query} on the web"] | |
| NOTE_T = ["write in my notes that I need to {task}", "take a note: {task}", | |
| "remind me to {task}", "note that I have to {task}"] | |
| CALC_T = ["calculate {a} times {b}", "what is {a} plus {b}", "what is {a} minus {b}", | |
| "calculate {a} divided by {b}", "{a} times {b}"] | |
| APP_T = ["open {app}", "launch {app}", "start {app}", "switch to {app}", | |
| "open up {app}"] | |
| def _fill(templates, rng, **pools): | |
| t = rng.choice(templates) | |
| return t.format(**{k: rng.choice(v) for k, v in pools.items()}) | |
| def _full_command(rng): | |
| kind = rng.choice(["music", "search", "note", "calculator", "app"]) | |
| if kind == "music": | |
| return _fill(MUSIC_T, rng, song=SONGS, artist=ARTISTS), "music" | |
| if kind == "search": | |
| return _fill(SEARCH_T, rng, query=QUERIES), "search" | |
| if kind == "note": | |
| task = rng.choice(TASKS) + (" " + rng.choice(["today", "this week", "by friday"]) | |
| if rng.random() < 0.4 else "") | |
| return rng.choice(NOTE_T).format(task=task), "note" | |
| if kind == "calculator": | |
| a, b = rng.randint(2, 999), rng.randint(2, 99) | |
| return _fill(CALC_T, rng, a=[a], b=[b]), "calculator" | |
| return _fill(APP_T, rng, app=APPS), "app" | |
| def _partial(full, rng): | |
| words = full.split() | |
| cut = rng.randint(1, max(1, len(words) - 2)) | |
| return " ".join(words[:cut]) | |
| def _case(i, state, intent, complete, prefix): | |
| return { | |
| "id": f"{prefix}-{i:06d}", | |
| "domain": "commands", | |
| "state": state, | |
| "questions": [ | |
| {"name": "intent", "type": "choice", "instructions": INSTRUCTIONS_INTENT, | |
| "options": INTENTS, "answer": intent}, | |
| {"name": "complete", "type": "noul", "options": ["no", "yes"], | |
| "instructions": "Is this a finished command, or is the user still speaking?", | |
| "answer": "yes" if complete else "no"}, | |
| ], | |
| } | |
| def generate(n, seed, prefix): | |
| # balanced: equal intent quotas; the full/partial/trigger/chat mix inside | |
| # each class teaches the finished-vs-still-speaking split. repeats are | |
| # re-randomized rather than dropped so no class is starved by dedupe. | |
| rng = random.Random(seed) | |
| # one slot per case, cycling intent classes so every class gets n/len(INTENTS) | |
| slots = [INTENTS[i % len(INTENTS)] for i in range(n)] | |
| rng.shuffle(slots) | |
| out = [] | |
| for state_slot in slots: | |
| r = rng.random() | |
| if state_slot == "unknown": | |
| # unknown = partials, bare triggers, chat (never full commands) | |
| if r < 0.55: | |
| full, _ = _full_command(rng) | |
| state = _partial(full, rng) | |
| elif r < 0.8: | |
| state = rng.choice(["open", "play", "search", "write", "calculate", | |
| "can you", "hey", "um", "launch"]) | |
| else: | |
| state = rng.choice(CHAT) | |
| out.append(_case(len(out), state, "unknown", rng.random() < 0.3, prefix)) | |
| continue | |
| # a real intent: 60% full command, 25% partial, 15% bare trigger of that intent | |
| full, _ = _full_command(rng) | |
| # force the template family to match the slot | |
| for _ in range(50): | |
| full, kind = _full_command(rng) | |
| if kind == state_slot: | |
| break | |
| if r < 0.6: | |
| out.append(_case(len(out), full, state_slot, True, prefix)) | |
| elif r < 0.85: | |
| out.append(_case(len(out), _partial(full, rng), state_slot, False, prefix)) | |
| else: | |
| trigger = full.split()[0] | |
| out.append(_case(len(out), trigger, state_slot, False, prefix)) | |
| return out | |
| def main(out_dir="data/commands"): | |
| os.makedirs(out_dir, exist_ok=True) | |
| sizes = {"train": 8000, "valid": 1000, "test": 1000} | |
| seeds = {"train": 11, "valid": 22, "test": 33} | |
| for split, n in sizes.items(): | |
| path = os.path.join(out_dir, f"{split}.jsonl") | |
| with open(path, "w", encoding="utf-8") as f: | |
| f.writelines(json.dumps(c) + "\n" for c in generate(n, seeds[split], split[:2])) | |
| print(f"wrote {n} cases to {path} (intents: {', '.join(INTENTS)})") | |
| if __name__ == "__main__": | |
| main() | |