tinyworld / router.py
sush0401's picture
TinyWorld + Crisis Mode, ZeroGPU in-process inference
d3a7a1c verified
Raw
History Blame Contribute Delete
3.88 kB
import re
COMMAND_VERBS = {
"go", "head", "walk", "run", "visit", "check", "rest", "help",
"tell", "make", "ask", "send", "move", "bring", "look",
}
BASE_LOCATION_ALIASES = {
"clinic": "nia_clinic",
"hospital": "nia_clinic",
"nurse": "nia_clinic",
"cafe": "cafe",
"café": "cafe",
"coffee": "cafe",
"school": "school",
"class": "school",
"park": "park",
"fountain": "fountain",
"square": "square",
"plaza": "square",
"office": "priya_office",
"city hall": "priya_office",
"shop": "shop",
"store": "shop",
}
def classify(text, world):
raw = (text or "").strip()
if not raw:
return {"type": "noop", "text": raw, "addressees": [], "instruction": "", "goto": None}
if not re.search(r"[A-Za-z0-9]", raw):
return {"type": "ambient", "text": raw, "addressees": [], "instruction": raw, "goto": None}
cast = world.get("cast", [])
names = _matched_names(raw, cast)
lowered = raw.lower()
looks_command = bool(names) and (
_starts_with_name_command(lowered, names)
or lowered.startswith("tell ")
or lowered.startswith("make ")
or lowered.startswith("ask ")
or any(re.search(rf"\b{verb}\b", lowered) for verb in COMMAND_VERBS)
)
if looks_command:
instruction = _strip_command_prefix(raw, names)
goto = resolve_location(instruction, world, cast, names)
return {
"type": "directed_command",
"text": raw,
"addressees": names,
"instruction": instruction,
"goto": goto,
}
return {"type": "world_event", "text": raw, "addressees": [], "instruction": raw, "goto": None}
def resolve_location(text, world, cast=None, addressees=None):
lowered = (text or "").lower()
hotspots = ((world.get("board", {}) or {}).get("hotspots_tile") or {})
if "home" in lowered and cast and addressees and len(addressees) == 1:
char = next((c for c in cast if c["name"] == addressees[0]), None)
home = char.get("home") if char else None
if home in hotspots:
return home
aliases = dict(BASE_LOCATION_ALIASES)
if "nurse_office" in hotspots:
aliases["clinic"] = "nurse_office"
aliases["nurse"] = "nurse_office"
aliases["nurse office"] = "nurse_office"
if "quad" in hotspots:
aliases["quad"] = "quad"
aliases["campus"] = "quad"
if "riverside_walk" in hotspots:
aliases["river"] = "riverside_walk"
aliases["riverside"] = "riverside_walk"
for key in hotspots:
aliases[key] = key
aliases[key.replace("_", " ")] = key
aliases[key.replace("_", "")] = key
for phrase, hotspot in sorted(aliases.items(), key=lambda item: len(item[0]), reverse=True):
if phrase in lowered and hotspot in hotspots:
return hotspot
return None
def _matched_names(text, cast):
lowered = text.lower()
matches = []
for char in cast:
first = char["name"].split()[0].lower()
if re.search(rf"\b{re.escape(first)}\b", lowered):
matches.append(char["name"])
return matches
def _starts_with_name_command(lowered, names):
first_names = [name.split()[0].lower() for name in names]
for first in first_names:
if re.match(rf"^\s*{re.escape(first)}\s*[,:\-]\s*", lowered):
return True
return False
def _strip_command_prefix(text, names):
instruction = text.strip()
first_names = "|".join(re.escape(name.split()[0]) for name in names)
patterns = [
rf"^\s*(?:tell|ask|make|send)\s+(?:{first_names})\s+(?:to\s+)?",
rf"^\s*(?:{first_names})\s*[,:\-]\s*",
]
for pattern in patterns:
instruction = re.sub(pattern, "", instruction, flags=re.IGNORECASE).strip()
return instruction or text.strip()