Spaces:
Sleeping
Sleeping
Fix: keep slow Text2OS/LASM/wallpaper generation off STATE_LOCK; deterministic keyword fast path before the LLM
Browse files
app.py
CHANGED
|
@@ -874,7 +874,11 @@ def keyword_intents(text):
|
|
| 874 |
|
| 875 |
|
| 876 |
def parse_intents(text):
|
| 877 |
-
"""Text2OS:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 878 |
eng = get_engine()
|
| 879 |
try:
|
| 880 |
raw = eng.text2text(
|
|
@@ -886,7 +890,7 @@ def parse_intents(text):
|
|
| 886 |
return data["ops"]
|
| 887 |
except Exception:
|
| 888 |
pass
|
| 889 |
-
return
|
| 890 |
|
| 891 |
|
| 892 |
# --------------------------------------------------------------------------- #
|
|
@@ -902,7 +906,7 @@ class Compositor:
|
|
| 902 |
self.last = None
|
| 903 |
self._memo = {} # signature -> raster, avoids per-frame realloc
|
| 904 |
self.metrics = {"frames": 0, "full": 0, "patch": 0, "idle": 0,
|
| 905 |
-
"
|
| 906 |
|
| 907 |
def _cached(self, sig, maker):
|
| 908 |
"""Return a stable raster for a content signature, so unchanged UI
|
|
@@ -1235,32 +1239,58 @@ def handle_client_message(msg, clients):
|
|
| 1235 |
elif t == "key":
|
| 1236 |
key = msg.get("key", "")
|
| 1237 |
if key == "Enter":
|
|
|
|
|
|
|
|
|
|
| 1238 |
text = KERNEL.text_buffer
|
| 1239 |
KERNEL.text_buffer = ""
|
| 1240 |
-
ops = parse_intents(text)
|
| 1241 |
-
for op in ops:
|
| 1242 |
-
if op.get("op") == "open" and op.get("app") in DEFAULT_SIZE:
|
| 1243 |
-
KERNEL.open(op["app"])
|
| 1244 |
-
elif op.get("op") == "close_all":
|
| 1245 |
-
for pid in list(KERNEL.windows):
|
| 1246 |
-
KERNEL.close(pid)
|
| 1247 |
KERNEL.log(f"Text2OS: {text[:40]}", ttl=6)
|
|
|
|
| 1248 |
elif key == "Backspace":
|
| 1249 |
KERNEL.text_buffer = KERNEL.text_buffer[:-1]
|
| 1250 |
elif len(key) == 1:
|
| 1251 |
KERNEL.text_buffer = (KERNEL.text_buffer + key)[-120:]
|
| 1252 |
elif t == "lasm":
|
| 1253 |
-
|
| 1254 |
-
vm = LatentVM(COMPOSITOR.stack, SPRITES)
|
| 1255 |
-
logs = vm.run(msg.get("program", []))
|
| 1256 |
-
for l in logs:
|
| 1257 |
-
KERNEL.log(l, ttl=5)
|
| 1258 |
elif t == "wallpaper":
|
| 1259 |
-
|
| 1260 |
-
msg.get("prompt", "abstract"), (FB, FB), seed=int(time.time()), steps=2))
|
| 1261 |
broadcast_dirty(clients)
|
| 1262 |
|
| 1263 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1264 |
def heartbeat(clients):
|
| 1265 |
"""Cursor/clock tick: small dirty rect, proves patch path."""
|
| 1266 |
while True:
|
|
|
|
| 874 |
|
| 875 |
|
| 876 |
def parse_intents(text):
|
| 877 |
+
"""Text2OS: deterministic keywords first (instant), LLM only for the
|
| 878 |
+
ambiguous remainder. Keeps common commands off the model entirely."""
|
| 879 |
+
kw = keyword_intents(text)
|
| 880 |
+
if not any(o.get("op") == "none" for o in kw):
|
| 881 |
+
return kw
|
| 882 |
eng = get_engine()
|
| 883 |
try:
|
| 884 |
raw = eng.text2text(
|
|
|
|
| 890 |
return data["ops"]
|
| 891 |
except Exception:
|
| 892 |
pass
|
| 893 |
+
return kw
|
| 894 |
|
| 895 |
|
| 896 |
# --------------------------------------------------------------------------- #
|
|
|
|
| 906 |
self.last = None
|
| 907 |
self._memo = {} # signature -> raster, avoids per-frame realloc
|
| 908 |
self.metrics = {"frames": 0, "full": 0, "patch": 0, "idle": 0,
|
| 909 |
+
"build_ms": 0.0, "frame_ms": 0.0, "tiles": 0, "bytes": 0}
|
| 910 |
|
| 911 |
def _cached(self, sig, maker):
|
| 912 |
"""Return a stable raster for a content signature, so unchanged UI
|
|
|
|
| 1239 |
elif t == "key":
|
| 1240 |
key = msg.get("key", "")
|
| 1241 |
if key == "Enter":
|
| 1242 |
+
# The intent parse may call the LLM for tens of seconds on CPU.
|
| 1243 |
+
# Never do that under STATE_LOCK: hand it to a worker thread so
|
| 1244 |
+
# the render loop and the heartbeat keep flowing.
|
| 1245 |
text = KERNEL.text_buffer
|
| 1246 |
KERNEL.text_buffer = ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1247 |
KERNEL.log(f"Text2OS: {text[:40]}", ttl=6)
|
| 1248 |
+
_spawn(apply_text2os, text)
|
| 1249 |
elif key == "Backspace":
|
| 1250 |
KERNEL.text_buffer = KERNEL.text_buffer[:-1]
|
| 1251 |
elif len(key) == 1:
|
| 1252 |
KERNEL.text_buffer = (KERNEL.text_buffer + key)[-120:]
|
| 1253 |
elif t == "lasm":
|
| 1254 |
+
_spawn(apply_lasm, msg.get("program", []))
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1255 |
elif t == "wallpaper":
|
| 1256 |
+
_spawn(apply_wallpaper, msg.get("prompt", "abstract"))
|
|
|
|
| 1257 |
broadcast_dirty(clients)
|
| 1258 |
|
| 1259 |
|
| 1260 |
+
def _spawn(fn, *args):
|
| 1261 |
+
"""Run slow, generation-bound work off the input/render critical path."""
|
| 1262 |
+
threading.Thread(target=fn, args=args, daemon=True).start()
|
| 1263 |
+
|
| 1264 |
+
|
| 1265 |
+
def apply_text2os(text):
|
| 1266 |
+
ops = parse_intents(text) # slow (LLM) -> done without the lock
|
| 1267 |
+
with STATE_LOCK:
|
| 1268 |
+
for op in ops:
|
| 1269 |
+
if op.get("op") == "open" and op.get("app") in DEFAULT_SIZE:
|
| 1270 |
+
KERNEL.open(op["app"])
|
| 1271 |
+
elif op.get("op") == "close_all":
|
| 1272 |
+
for pid in list(KERNEL.windows):
|
| 1273 |
+
KERNEL.close(pid)
|
| 1274 |
+
broadcast_dirty(CLIENTS)
|
| 1275 |
+
|
| 1276 |
+
|
| 1277 |
+
def apply_lasm(program):
|
| 1278 |
+
vm = LatentVM(COMPOSITOR.stack, SPRITES)
|
| 1279 |
+
logs = vm.run(program) # may run the model per opcode
|
| 1280 |
+
with STATE_LOCK:
|
| 1281 |
+
for l in logs:
|
| 1282 |
+
KERNEL.log(l, ttl=5)
|
| 1283 |
+
broadcast_dirty(CLIENTS)
|
| 1284 |
+
|
| 1285 |
+
|
| 1286 |
+
def apply_wallpaper(prompt):
|
| 1287 |
+
img = get_engine().text2img(prompt, (FB, FB), seed=int(time.time()), steps=2)
|
| 1288 |
+
STORE.put("chrome.wallpaper.v3", img)
|
| 1289 |
+
with STATE_LOCK:
|
| 1290 |
+
KERNEL.log("wallpaper regenerated", ttl=5)
|
| 1291 |
+
broadcast_dirty(CLIENTS)
|
| 1292 |
+
|
| 1293 |
+
|
| 1294 |
def heartbeat(clients):
|
| 1295 |
"""Cursor/clock tick: small dirty rect, proves patch path."""
|
| 1296 |
while True:
|