Compare commits
1 Commits
fix/1548-u
...
fix/1509
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
63b2d444d5 |
@@ -29,7 +29,7 @@ from typing import Any, Callable, Optional
|
||||
|
||||
import websockets
|
||||
|
||||
from bannerlord_trace import BannerlordTraceLogger
|
||||
from nexus.bannerlord_trace import BannerlordTraceLogger
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# CONFIGURATION
|
||||
|
||||
@@ -181,6 +181,63 @@ async def live_bridge(log_dir: str, ws_url: str, reconnect_delay: float = 5.0):
|
||||
await asyncio.gather(*tasks)
|
||||
|
||||
|
||||
|
||||
|
||||
def clean_lines(text: str) -> list[str]:
|
||||
"""Strip ANSI, normalize line endings, return non-empty lines."""
|
||||
text = strip_ansi(text).replace("\r", "")
|
||||
return [line.strip() for line in text.split("\n") if line.strip()]
|
||||
|
||||
|
||||
def parse_room_output(text: str) -> dict:
|
||||
"""Parse Evennia room text into structured data (title, desc, exits, objects)."""
|
||||
lines = clean_lines(text)
|
||||
if len(lines) < 2:
|
||||
return {"title": lines[0] if lines else "", "desc": "", "exits": [], "objects": []}
|
||||
title = lines[0]
|
||||
desc = lines[1]
|
||||
exits = []
|
||||
objects = []
|
||||
for line in lines[2:]:
|
||||
if line.startswith("Exits:"):
|
||||
raw = line.split(":", 1)[1].strip().replace(" and ", ", ")
|
||||
exits = [{"key": t.strip(), "destination_id": t.strip().title(), "destination_key": t.strip().title()} for t in raw.split(",") if t.strip()]
|
||||
elif line.startswith("You see:"):
|
||||
raw = line.split(":", 1)[1].strip().replace(" and ", ", ")
|
||||
parts = [t.strip() for t in raw.split(",") if t.strip()]
|
||||
objects = [{"id": p.removeprefix("a ").removeprefix("an "), "key": p.removeprefix("a ").removeprefix("an "), "short_desc": p} for p in parts]
|
||||
return {"title": title, "desc": desc, "exits": exits, "objects": objects}
|
||||
|
||||
|
||||
def normalize_event(raw: dict, hermes_session_id: str) -> list[dict]:
|
||||
"""Convert raw Evennia event dict into normalized Nexus events."""
|
||||
from nexus.evennia_event_adapter import (
|
||||
actor_located, command_issued, command_result,
|
||||
room_snapshot, session_bound,
|
||||
)
|
||||
out = []
|
||||
event = raw.get("event")
|
||||
actor = raw.get("actor", "Timmy")
|
||||
timestamp = raw.get("timestamp")
|
||||
if event == "connect":
|
||||
out.append(session_bound(hermes_session_id, evennia_account=actor, evennia_character=actor, timestamp=timestamp))
|
||||
parsed = parse_room_output(raw.get("output", ""))
|
||||
if parsed:
|
||||
out.append(actor_located(actor, parsed["title"], parsed["title"], timestamp=timestamp))
|
||||
out.append(room_snapshot(parsed["title"], parsed["title"], parsed["desc"], exits=parsed["exits"], objects=parsed["objects"], timestamp=timestamp))
|
||||
elif event == "command":
|
||||
cmd = raw.get("command", "")
|
||||
output = raw.get("output", "")
|
||||
out.append(command_issued(hermes_session_id, actor, cmd, timestamp=timestamp))
|
||||
success = not output.startswith("Command '") and not output.startswith("Could not find")
|
||||
out.append(command_result(hermes_session_id, actor, cmd, strip_ansi(output), success=success, timestamp=timestamp))
|
||||
parsed = parse_room_output(output)
|
||||
if parsed:
|
||||
out.append(actor_located(actor, parsed["title"], parsed["title"], timestamp=timestamp))
|
||||
out.append(room_snapshot(parsed["title"], parsed["title"], parsed["desc"], exits=parsed["exits"], objects=parsed["objects"], timestamp=timestamp))
|
||||
return out
|
||||
|
||||
|
||||
async def playback(log_path: Path, ws_url: str):
|
||||
"""Legacy mode: replay a telemetry JSONL file."""
|
||||
from nexus.evennia_event_adapter import (
|
||||
|
||||
@@ -9,28 +9,28 @@
|
||||
},
|
||||
"files": {
|
||||
"index.html": {
|
||||
"sha256": "562418d180da01b0eae320ee6604c33cf70aeee03d0ff918c27d0aa36509d6d5",
|
||||
"size": 20989
|
||||
"sha256": "71ba27afe8b6b42a09efe09d2b3017599392ddc3bc02543b31c2277dfb0b82cc",
|
||||
"size": 25933
|
||||
},
|
||||
"app.js": {
|
||||
"sha256": "df304e3d4d76ecca6f84a477d7729625fe51ff23ef3a24df554a61cf5b8f2d43",
|
||||
"size": 140652
|
||||
"sha256": "2b765a724a0fcda29abd40ba921bc621d2699f11d0ba14cf1579cbbdafdc5cd5",
|
||||
"size": 132902
|
||||
},
|
||||
"style.css": {
|
||||
"sha256": "a7228e516f8210bac580a1caa2f6223ec9ec533e46c58b585a7cbc53bc047fba",
|
||||
"size": 60727
|
||||
"sha256": "cd3068d03eed6f52a00bbc32cfae8fba4739b8b3cb194b3ec09fd747a075056d",
|
||||
"size": 44198
|
||||
},
|
||||
"gofai_worker.js": {
|
||||
"sha256": "01d1444b1e4c899a7579aa4e5624d5a0683e10b54a924005a7003534c607a500",
|
||||
"size": 1925
|
||||
"sha256": "d292f110aa12a8aa2b16b0c2d48e5b4ce24ee15b1cffb409ab846b1a05a91de2",
|
||||
"size": 969
|
||||
},
|
||||
"server.py": {
|
||||
"sha256": "79292dfd6955020f5d8ae368e8ce61a4831255dc1a935cbf8f51b35eaa2e4498",
|
||||
"size": 4389
|
||||
"sha256": "e963cc9715accfc8814e3fe5c44af836185d66740d5a65fd0365e9c629d38e05",
|
||||
"size": 4185
|
||||
},
|
||||
"portals.json": {
|
||||
"sha256": "82f91c3b8707d197e6295e594e616e92f9e215399a7181a130874e23381efa9f",
|
||||
"size": 6399
|
||||
"sha256": "889a5e0f724eb73a95f960bca44bca232150bddff7c1b11f253bd056f3683a08",
|
||||
"size": 3442
|
||||
},
|
||||
"vision.json": {
|
||||
"sha256": "0e3b5c06af98486bbcb2fc2dc627dc8b7b08aed4c3a4f9e10b57f91e1e8ca6ad",
|
||||
@@ -41,8 +41,8 @@
|
||||
"size": 495
|
||||
},
|
||||
"nexus/components/spatial-memory.js": {
|
||||
"sha256": "0945845828b3cfaac6060050bf138463b5108b6c135e4c396751da92a7376534",
|
||||
"size": 38272
|
||||
"sha256": "60170f6490ddd743acd6d285d3a1af6cad61fbf8aaef3f679ff4049108eac160",
|
||||
"size": 32782
|
||||
},
|
||||
"nexus/components/session-rooms.js": {
|
||||
"sha256": "9997a60dda256e38cb4645508bf9e98c15c3d963b696e0080e3170a9a7fa7cf1",
|
||||
|
||||
Reference in New Issue
Block a user