#!/usr/bin/env python3 """ AgentLiving Bridge Server 连接 Godot 前端和 OpenClaw 后端 """ import asyncio import websockets import json import sys from datetime import datetime # 简单的状态存储 agent_states = { "val": { "location": "客厅", "energy": 80, "mood": "开心", "activity": "idle", "position": [400, 300] } } class AgentLivingBridge: def __init__(self): self.clients = set() async def register(self, websocket): self.clients.add(websocket) print(f"Client connected. Total: {len(self.clients)}") async def unregister(self, websocket): self.clients.discard(websocket) print(f"Client disconnected. Total: {len(self.clients)}") async def handle_client(self, websocket, path): await self.register(websocket) try: async for message in websocket: await self.process_message(websocket, message) except websockets.exceptions.ConnectionClosed: pass finally: await self.unregister(websocket) async def process_message(self, websocket, message): try: data = json.loads(message) msg_type = data.get("type", "") print(f"[{datetime.now().isoformat()}] Received: {msg_type}") if msg_type == "hello": # 新客户端连接 await websocket.send(json.dumps({ "type": "state_sync", "state": agent_states["val"] })) elif msg_type == "user_command": # 处理用户指令 command = data.get("command", "") print(f"User command: {command}") # 解析指令并生成动作序列 actions = self._parse_command(command) await websocket.send(json.dumps({ "type": "action_sequence", "actions": actions })) elif msg_type == "furniture_clicked": # 处理家具点击 furniture = data.get("furniture", "") print(f"Furniture clicked: {furniture}") # 生成走过去+交互的动作序列 actions = [ {"cmd": "show_thought", "text": f"要去{furniture}那边...", "duration": 1.0}, {"cmd": "walk_to", "pos": data.get("position", [0, 0])}, {"cmd": "play_anim", "anim": "interact"}, {"cmd": "show_thought", "text": f"正在使用{furniture}", "duration": 2.0} ] await websocket.send(json.dumps({ "type": "action_sequence", "actions": actions })) elif msg_type == "room_changed": # 更新房间状态 room = data.get("room", "") agent_states["val"]["location"] = room print(f"Val moved to: {room}") elif msg_type == "request_state_sync": # 请求状态同步 await websocket.send(json.dumps({ "type": "state_sync", "state": agent_states["val"] })) elif msg_type == "heartbeat_ack": # 心跳响应,忽略 pass else: print(f"Unknown message type: {msg_type}") except json.JSONDecodeError: print(f"Invalid JSON: {message}") except Exception as e: print(f"Error processing message: {e}") await websocket.send(json.dumps({ "type": "error", "error": str(e) })) def _parse_command(self, command: str) -> list: """解析用户指令为动作序列""" command = command.lower() actions = [] # 简单指令映射 if "沙发" in command or "坐" in command: actions = [ {"cmd": "show_thought", "text": "去沙发上休息...", "duration": 1.0}, {"cmd": "walk_to", "pos": [280, 200]}, {"cmd": "play_anim", "anim": "interact"}, {"cmd": "show_thought", "text": "真舒服~", "duration": 2.0} ] elif "冰箱" in command or "水" in command or "喝" in command: actions = [ {"cmd": "show_thought", "text": "去倒杯水...", "duration": 1.0}, {"cmd": "walk_to", "pos": [280, 440]}, {"cmd": "play_anim", "anim": "interact"}, {"cmd": "show_thought", "text": "解渴了~", "duration": 2.0} ] elif "床" in command or "睡" in command or "休息" in command: actions = [ {"cmd": "show_thought", "text": "去睡一会儿...", "duration": 1.0}, {"cmd": "walk_to", "pos": [760, 200]}, {"cmd": "play_anim", "anim": "interact"}, {"cmd": "show_thought", "text": "Zzz...", "duration": 3.0} ] elif "书桌" in command or "工作" in command or "学习" in command: actions = [ {"cmd": "show_thought", "text": "去工作...", "duration": 1.0}, {"cmd": "walk_to", "pos": [840, 200]}, {"cmd": "play_anim", "anim": "think"}, {"cmd": "show_thought", "text": "正在思考...", "duration": 3.0} ] elif "客厅" in command: actions = [ {"cmd": "show_thought", "text": "去客厅...", "duration": 1.0}, {"cmd": "walk_to", "pos": [320, 240]} ] elif "厨房" in command: actions = [ {"cmd": "show_thought", "text": "去厨房...", "duration": 1.0}, {"cmd": "walk_to", "pos": [320, 480]} ] elif "卧室" in command: actions = [ {"cmd": "show_thought", "text": "去卧室...", "duration": 1.0}, {"cmd": "walk_to", "pos": [800, 240]} ] else: # 默认:显示思考 actions = [ {"cmd": "show_thought", "text": f"收到指令:{command}", "duration": 2.0}, {"cmd": "play_anim", "anim": "think"} ] return actions async def main(): bridge = AgentLivingBridge() host = "localhost" port = 8765 print(f"Starting AgentLiving Bridge Server on ws://{host}:{port}") print("Press Ctrl+C to stop") async with websockets.serve( bridge.handle_client, host, port, ping_interval=20, ping_timeout=10 ): await asyncio.Future() # 永久运行 if __name__ == "__main__": try: asyncio.run(main()) except KeyboardInterrupt: print("\nShutting down...") sys.exit(0)