neuro-simulator 0.3.0__py3-none-any.whl → 0.3.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21,8 +21,6 @@ from ..services.letta import LettaAgent
21
21
  from ..services.builtin import BuiltinAgentWrapper
22
22
 
23
23
  # --- API Routers ---
24
- from ..api.agent import router as agent_router
25
- from ..api.stream import router as stream_router
26
24
  from ..api.system import router as system_router
27
25
 
28
26
  # --- Services and Utilities ---
@@ -60,8 +58,6 @@ app.add_middleware(
60
58
  expose_headers=["X-API-Token"],
61
59
  )
62
60
 
63
- app.include_router(agent_router)
64
- app.include_router(stream_router)
65
61
  app.include_router(system_router)
66
62
 
67
63
  # --- Background Task Definitions ---
@@ -167,7 +163,7 @@ async def neuro_response_cycle():
167
163
  if not selected_chats:
168
164
  continue
169
165
 
170
- response_result = await asyncio.wait_for(agent.process_messages(selected_chats), timeout=20.0)
166
+ response_result = await asyncio.wait_for(agent.process_and_respond(selected_chats), timeout=20.0)
171
167
 
172
168
  response_text = response_result.get("final_response", "").strip()
173
169
  if not response_text:
@@ -280,7 +276,10 @@ async def websocket_stream_endpoint(websocket: WebSocket):
280
276
  @app.websocket("/ws/admin")
281
277
  async def websocket_admin_endpoint(websocket: WebSocket):
282
278
  await websocket.accept()
279
+ # Add the new admin client to a dedicated list
280
+ connection_manager.admin_connections.append(websocket)
283
281
  try:
282
+ # Send initial state
284
283
  for log_entry in list(server_log_queue): await websocket.send_json({"type": "server_log", "data": log_entry})
285
284
  for log_entry in list(agent_log_queue): await websocket.send_json({"type": "agent_log", "data": log_entry})
286
285
 
@@ -288,15 +287,208 @@ async def websocket_admin_endpoint(websocket: WebSocket):
288
287
  initial_context = await agent.get_message_history()
289
288
  await websocket.send_json({"type": "agent_context", "action": "update", "messages": initial_context})
290
289
 
290
+ # Send initial stream status
291
+ status = {"is_running": process_manager.is_running, "backend_status": "running" if process_manager.is_running else "stopped"}
292
+ await websocket.send_json({"type": "stream_status", "payload": status})
293
+
294
+ # Main loop for receiving messages from the client and pushing log updates
291
295
  while websocket.client_state == WebSocketState.CONNECTED:
296
+ # Check for incoming messages
297
+ try:
298
+ raw_data = await asyncio.wait_for(websocket.receive_text(), timeout=0.01)
299
+ data = json.loads(raw_data)
300
+ await handle_admin_ws_message(websocket, data)
301
+ except asyncio.TimeoutError:
302
+ pass # No message received, continue to push logs
303
+
304
+ # Push log updates
292
305
  if server_log_queue: await websocket.send_json({"type": "server_log", "data": server_log_queue.popleft()})
293
306
  if agent_log_queue: await websocket.send_json({"type": "agent_log", "data": agent_log_queue.popleft()})
294
307
  await asyncio.sleep(0.1)
308
+
295
309
  except WebSocketDisconnect:
296
310
  pass
297
311
  finally:
312
+ connection_manager.admin_connections.remove(websocket)
298
313
  logger.info("Admin WebSocket client disconnected.")
299
314
 
315
+ async def handle_admin_ws_message(websocket: WebSocket, data: dict):
316
+ """Handles incoming messages from the admin WebSocket."""
317
+ action = data.get("action")
318
+ payload = data.get("payload", {})
319
+ request_id = data.get("request_id")
320
+
321
+ agent = await create_agent()
322
+ response = {"type": "response", "request_id": request_id, "payload": {}}
323
+
324
+ try:
325
+ # Core Memory Actions
326
+ if action == "get_core_memory_blocks":
327
+ blocks = await agent.get_memory_blocks()
328
+ response["payload"] = blocks
329
+
330
+ elif action == "create_core_memory_block":
331
+ block_id = await agent.create_memory_block(**payload)
332
+ response["payload"] = {"status": "success", "block_id": block_id}
333
+ # Broadcast the update to all admins
334
+ updated_blocks = await agent.get_memory_blocks()
335
+ from ..utils.websocket import connection_manager
336
+ await connection_manager.broadcast_to_admins({"type": "core_memory_updated", "payload": updated_blocks})
337
+
338
+ elif action == "update_core_memory_block":
339
+ await agent.update_memory_block(**payload)
340
+ response["payload"] = {"status": "success"}
341
+ # Broadcast the update to all admins
342
+ updated_blocks = await agent.get_memory_blocks()
343
+ from ..utils.websocket import connection_manager
344
+ await connection_manager.broadcast_to_admins({"type": "core_memory_updated", "payload": updated_blocks})
345
+
346
+ elif action == "delete_core_memory_block":
347
+ await agent.delete_memory_block(**payload)
348
+ response["payload"] = {"status": "success"}
349
+ # Broadcast the update to all admins
350
+ updated_blocks = await agent.get_memory_blocks()
351
+ from ..utils.websocket import connection_manager
352
+ await connection_manager.broadcast_to_admins({"type": "core_memory_updated", "payload": updated_blocks})
353
+
354
+ # Temp Memory Actions
355
+ elif action == "get_temp_memory":
356
+ temp_mem = await agent.get_temp_memory()
357
+ response["payload"] = temp_mem
358
+
359
+ elif action == "add_temp_memory":
360
+ await agent.add_temp_memory(**payload)
361
+ response["payload"] = {"status": "success"}
362
+ updated_temp_mem = await agent.get_temp_memory()
363
+ from ..utils.websocket import connection_manager
364
+ await connection_manager.broadcast_to_admins({"type": "temp_memory_updated", "payload": updated_temp_mem})
365
+
366
+ elif action == "clear_temp_memory":
367
+ await agent.clear_temp_memory()
368
+ response["payload"] = {"status": "success"}
369
+ updated_temp_mem = await agent.get_temp_memory()
370
+ await connection_manager.broadcast_to_admins({"type": "temp_memory_updated", "payload": updated_temp_mem})
371
+
372
+ # Init Memory Actions
373
+ elif action == "get_init_memory":
374
+ init_mem = await agent.get_init_memory()
375
+ response["payload"] = init_mem
376
+
377
+ elif action == "update_init_memory":
378
+ await agent.update_init_memory(**payload)
379
+ response["payload"] = {"status": "success"}
380
+ updated_init_mem = await agent.get_init_memory()
381
+ from ..utils.websocket import connection_manager
382
+ await connection_manager.broadcast_to_admins({"type": "init_memory_updated", "payload": updated_init_mem})
383
+
384
+ # Tool Actions
385
+ elif action == "get_tools":
386
+ tools = await agent.get_available_tools()
387
+ response["payload"] = {"tools": tools}
388
+
389
+ elif action == "execute_tool":
390
+ result = await agent.execute_tool(**payload)
391
+ response["payload"] = {"result": result}
392
+
393
+ # Stream Control Actions
394
+ elif action == "start_stream":
395
+ if not process_manager.is_running:
396
+ process_manager.start_live_processes()
397
+ response["payload"] = {"status": "success", "message": "Stream started"}
398
+ # Broadcast stream status update
399
+ from ..utils.websocket import connection_manager
400
+ status = {"is_running": process_manager.is_running, "backend_status": "running" if process_manager.is_running else "stopped"}
401
+ await connection_manager.broadcast_to_admins({"type": "stream_status", "payload": status})
402
+
403
+ elif action == "stop_stream":
404
+ if process_manager.is_running:
405
+ await process_manager.stop_live_processes()
406
+ response["payload"] = {"status": "success", "message": "Stream stopped"}
407
+ # Broadcast stream status update
408
+ from ..utils.websocket import connection_manager
409
+ status = {"is_running": process_manager.is_running, "backend_status": "running" if process_manager.is_running else "stopped"}
410
+ await connection_manager.broadcast_to_admins({"type": "stream_status", "payload": status})
411
+
412
+ elif action == "restart_stream":
413
+ await process_manager.stop_live_processes()
414
+ await asyncio.sleep(1)
415
+ process_manager.start_live_processes()
416
+ response["payload"] = {"status": "success", "message": "Stream restarted"}
417
+ # Broadcast stream status update
418
+ from ..utils.websocket import connection_manager
419
+ status = {"is_running": process_manager.is_running, "backend_status": "running" if process_manager.is_running else "stopped"}
420
+ await connection_manager.broadcast_to_admins({"type": "stream_status", "payload": status})
421
+
422
+ elif action == "get_stream_status":
423
+ status = {"is_running": process_manager.is_running, "backend_status": "running" if process_manager.is_running else "stopped"}
424
+ response["payload"] = status
425
+
426
+ # Config Management Actions
427
+ elif action == "get_configs":
428
+ from ..api.system import filter_config_for_frontend
429
+ configs = filter_config_for_frontend(config_manager.settings)
430
+ response["payload"] = configs
431
+
432
+ elif action == "update_configs":
433
+ from ..api.system import filter_config_for_frontend
434
+ await config_manager.update_settings(payload)
435
+ updated_configs = filter_config_for_frontend(config_manager.settings)
436
+ response["payload"] = updated_configs
437
+ await connection_manager.broadcast_to_admins({"type": "config_updated", "payload": updated_configs})
438
+
439
+ elif action == "reload_configs":
440
+ await config_manager.update_settings({})
441
+ response["payload"] = {"status": "success", "message": "Configuration reloaded"}
442
+ from ..api.system import filter_config_for_frontend
443
+ updated_configs = filter_config_for_frontend(config_manager.settings)
444
+ await connection_manager.broadcast_to_admins({"type": "config_updated", "payload": updated_configs})
445
+
446
+ # Other Agent Actions
447
+ elif action == "get_agent_context":
448
+ context = await agent.get_message_history()
449
+ response["payload"] = context
450
+
451
+ elif action == "get_last_prompt":
452
+ # Check if the agent supports prompt generation introspection
453
+ agent_instance = getattr(agent, 'agent_instance', None) if hasattr(agent, 'agent_instance') else agent
454
+ if not hasattr(agent_instance, 'memory_manager') or not hasattr(agent_instance.memory_manager, 'get_recent_chat') or not hasattr(agent_instance, '_build_neuro_prompt'):
455
+ response["payload"] = {"status": "error", "message": "The active agent does not support prompt generation introspection."}
456
+ else:
457
+ recent_history = await agent_instance.memory_manager.get_recent_chat(entries=10)
458
+ messages_for_prompt = []
459
+ for entry in recent_history:
460
+ if entry.get('role') == 'user':
461
+ parts = entry.get('content', '').split(':', 1)
462
+ if len(parts) == 2:
463
+ messages_for_prompt.append({'username': parts[0].strip(), 'text': parts[1].strip()})
464
+ else:
465
+ messages_for_prompt.append({'username': 'user', 'text': entry.get('content', '')})
466
+ prompt = await agent_instance._build_neuro_prompt(messages_for_prompt)
467
+ response["payload"] = {"prompt": prompt}
468
+
469
+ elif action == "reset_agent_memory":
470
+ await agent.reset_memory()
471
+ response["payload"] = {"status": "success"}
472
+ # Broadcast updates for all memory types
473
+ await connection_manager.broadcast_to_admins({"type": "core_memory_updated", "payload": await agent.get_memory_blocks()})
474
+ await connection_manager.broadcast_to_admins({"type": "temp_memory_updated", "payload": await agent.get_temp_memory()})
475
+ await connection_manager.broadcast_to_admins({"type": "init_memory_updated", "payload": await agent.get_init_memory()})
476
+ await connection_manager.broadcast_to_admins({"type": "agent_context", "action": "update", "messages": await agent.get_message_history()})
477
+
478
+ else:
479
+ response["payload"] = {"status": "error", "message": f"Unknown action: {action}"}
480
+
481
+ # Send the direct response to the requesting client
482
+ if request_id:
483
+ await websocket.send_json(response)
484
+
485
+ except Exception as e:
486
+ logger.error(f"Error handling admin WS message (action: {action}): {e}", exc_info=True)
487
+ if request_id:
488
+ response["payload"] = {"status": "error", "message": str(e)}
489
+ await websocket.send_json(response)
490
+
491
+
300
492
  # --- Server Entrypoint ---
301
493
 
302
494
  def run_server(host: str = None, port: int = None):
@@ -37,8 +37,8 @@ class BuiltinAgentWrapper(BaseAgent):
37
37
  async def reset_memory(self):
38
38
  await self.agent_instance.reset_all_memory()
39
39
 
40
- async def process_messages(self, messages: List[Dict[str, str]]) -> Dict[str, Any]:
41
- return await self.agent_instance.process_messages(messages)
40
+ async def process_and_respond(self, messages: List[Dict[str, str]]) -> Dict[str, Any]:
41
+ return await self.agent_instance.process_and_respond(messages)
42
42
 
43
43
  # Memory Block Management
44
44
  async def get_memory_blocks(self) -> List[Dict[str, Any]]:
@@ -50,13 +50,25 @@ class BuiltinAgentWrapper(BaseAgent):
50
50
 
51
51
  async def create_memory_block(self, title: str, description: str, content: List[str]) -> Dict[str, str]:
52
52
  block_id = await self.agent_instance.memory_manager.create_core_memory_block(title, description, content)
53
+ # Broadcast core_memory_updated event
54
+ updated_blocks = await self.get_memory_blocks()
55
+ from ..utils.websocket import connection_manager
56
+ await connection_manager.broadcast_to_admins({"type": "core_memory_updated", "payload": updated_blocks})
53
57
  return {"block_id": block_id}
54
58
 
55
59
  async def update_memory_block(self, block_id: str, title: Optional[str], description: Optional[str], content: Optional[List[str]]):
56
60
  await self.agent_instance.memory_manager.update_core_memory_block(block_id, title, description, content)
61
+ # Broadcast core_memory_updated event
62
+ updated_blocks = await self.get_memory_blocks()
63
+ from ..utils.websocket import connection_manager
64
+ await connection_manager.broadcast_to_admins({"type": "core_memory_updated", "payload": updated_blocks})
57
65
 
58
66
  async def delete_memory_block(self, block_id: str):
59
67
  await self.agent_instance.memory_manager.delete_core_memory_block(block_id)
68
+ # Broadcast core_memory_updated event
69
+ updated_blocks = await self.get_memory_blocks()
70
+ from ..utils.websocket import connection_manager
71
+ await connection_manager.broadcast_to_admins({"type": "core_memory_updated", "payload": updated_blocks})
60
72
 
61
73
  # Init Memory Management
62
74
  async def get_init_memory(self) -> Dict[str, Any]:
@@ -64,6 +76,10 @@ class BuiltinAgentWrapper(BaseAgent):
64
76
 
65
77
  async def update_init_memory(self, memory: Dict[str, Any]):
66
78
  await self.agent_instance.memory_manager.update_init_memory(memory)
79
+ # Broadcast init_memory_updated event
80
+ updated_init_mem = await self.get_init_memory()
81
+ from ..utils.websocket import connection_manager
82
+ await connection_manager.broadcast_to_admins({"type": "init_memory_updated", "payload": updated_init_mem})
67
83
 
68
84
  # Temp Memory Management
69
85
  async def get_temp_memory(self) -> List[Dict[str, Any]]:
@@ -71,17 +87,31 @@ class BuiltinAgentWrapper(BaseAgent):
71
87
 
72
88
  async def add_temp_memory(self, content: str, role: str):
73
89
  await self.agent_instance.memory_manager.add_temp_memory(content, role)
90
+ # Broadcast temp_memory_updated event
91
+ updated_temp_mem = await self.get_temp_memory()
92
+ from ..utils.websocket import connection_manager
93
+ await connection_manager.broadcast_to_admins({"type": "temp_memory_updated", "payload": updated_temp_mem})
74
94
 
75
95
  async def clear_temp_memory(self):
76
96
  await self.agent_instance.memory_manager.reset_temp_memory()
97
+ # Broadcast temp_memory_updated event
98
+ updated_temp_mem = await self.get_temp_memory()
99
+ from ..utils.websocket import connection_manager
100
+ await connection_manager.broadcast_to_admins({"type": "temp_memory_updated", "payload": updated_temp_mem})
77
101
 
78
102
  # Tool Management
79
103
  async def get_available_tools(self) -> str:
80
104
  return self.agent_instance.tool_manager.get_tool_descriptions()
81
105
 
82
106
  async def execute_tool(self, tool_name: str, params: Dict[str, Any]) -> Any:
83
- return await self.agent_instance.execute_tool(tool_name, params)
107
+ result = await self.agent_instance.execute_tool(tool_name, params)
108
+ # If the tool was add_temp_memory, broadcast temp_memory_updated event
109
+ if tool_name == "add_temp_memory":
110
+ updated_temp_mem = await self.get_temp_memory()
111
+ from ..utils.websocket import connection_manager
112
+ await connection_manager.broadcast_to_admins({"type": "temp_memory_updated", "payload": updated_temp_mem})
113
+ return result
84
114
 
85
115
  # Context/Message History
86
116
  async def get_message_history(self, limit: int = 20) -> List[Dict[str, Any]]:
87
- return await self.agent_instance.memory_manager.get_recent_context(limit)
117
+ return await self.agent_instance.memory_manager.get_recent_chat(limit)
@@ -33,6 +33,7 @@ class ProcessManager:
33
33
  from ..core.application import generate_audience_chat_task, neuro_response_cycle, broadcast_events_task
34
34
  from ..utils.queue import clear_all_queues
35
35
  from ..core.agent_factory import create_agent
36
+ from ..utils.websocket import connection_manager
36
37
 
37
38
  asyncio.create_task(create_agent())
38
39
 
@@ -45,6 +46,9 @@ class ProcessManager:
45
46
  self._tasks.append(asyncio.create_task(neuro_response_cycle()))
46
47
 
47
48
  self._is_running = True
49
+ # Broadcast stream status update
50
+ status = {"is_running": self._is_running, "backend_status": "running" if self._is_running else "stopped"}
51
+ asyncio.create_task(connection_manager.broadcast_to_admins({"type": "stream_status", "payload": status}))
48
52
  logger.info(f"Core processes started: {len(self._tasks)} tasks.")
49
53
 
50
54
  async def stop_live_processes(self):
@@ -66,6 +70,10 @@ class ProcessManager:
66
70
 
67
71
  live_stream_manager.reset_stream_state()
68
72
 
73
+ # Broadcast stream status update
74
+ status = {"is_running": self._is_running, "backend_status": "running" if self._is_running else "stopped"}
75
+ await connection_manager.broadcast_to_admins({"type": "stream_status", "payload": status})
76
+
69
77
  logger.info("All core tasks have been stopped.")
70
78
 
71
79
  # Global singleton instance
@@ -12,7 +12,8 @@ logger = logging.getLogger(__name__.replace("neuro_simulator", "server", 1))
12
12
  class WebSocketManager:
13
13
  """Manages all active WebSocket connections and provides broadcasting capabilities."""
14
14
  def __init__(self):
15
- self.active_connections: deque[WebSocket] = deque()
15
+ self.active_connections: list[WebSocket] = []
16
+ self.admin_connections: list[WebSocket] = []
16
17
  logger.info("WebSocketManager initialized.")
17
18
 
18
19
  async def connect(self, websocket: WebSocket):
@@ -37,19 +38,15 @@ class WebSocketManager:
37
38
  self.disconnect(websocket)
38
39
 
39
40
  async def broadcast(self, message: dict):
40
- disconnected_sockets = []
41
- for connection in list(self.active_connections):
42
- if connection.client_state == WebSocketState.CONNECTED:
43
- try:
44
- await connection.send_json(message)
45
- except Exception as e:
46
- logger.warning(f"Could not broadcast message to client {connection}, it may have disconnected: {e}")
47
- disconnected_sockets.append(connection)
48
- else:
49
- disconnected_sockets.append(connection)
50
-
51
- for disconnected_socket in disconnected_sockets:
52
- self.disconnect(disconnected_socket)
41
+ for connection in self.active_connections:
42
+ await connection.send_json(message)
43
+
44
+ async def broadcast_to_admins(self, message: dict):
45
+ for connection in self.admin_connections:
46
+ try:
47
+ await connection.send_json(message)
48
+ except Exception as e:
49
+ logger.error(f"Failed to send message to admin connection: {e}")
53
50
 
54
51
  # Global singleton instance
55
52
  connection_manager = WebSocketManager()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: neuro_simulator
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: Neuro Simulator Server
5
5
  Author-email: Moha-Master <hongkongreporter@outlook.com>
6
6
  License-Expression: MIT
@@ -69,7 +69,7 @@ neuro_simulator/
69
69
  │ ├── memory/ # 记忆管理模块
70
70
  │ │ ├── __init__.py
71
71
  │ │ ├── manager.py # 记忆管理器
72
- │ │ ├── context.json # 上下文记忆文件
72
+ │ │ ├── chat_history.json # 上下文记忆文件
73
73
  │ │ ├── core_memory.json # 核心记忆文件
74
74
  │ │ ├── init_memory.json # 初始化记忆文件
75
75
  │ │ └── temp_memory.json # 临时记忆文件
@@ -109,7 +109,7 @@ working_dir_example/ # 工作目录结构,请将这个目录重命名和
109
109
  ├── config.yaml.example # 自动生成的配置文件模板,必须手动重命名和填写
110
110
  └── agent/ # Agent相关文件夹
111
111
  └── memory/ # Agent记忆文件夹
112
- ├── context.json # 上下文记忆文件
112
+ ├── chat_history.json # 上下文记忆文件
113
113
  ├── core_memory.json # 核心记忆文件
114
114
  ├── init_memory.json # 初始化记忆文件
115
115
  └── temp_memory.json # 临时记忆文件
@@ -191,7 +191,6 @@ neuro -D /path/to/your/config -H 0.0.0.0 -P 8080
191
191
  - `/api/configs/*` - 配置管理接口(获取/更新/重载配置)
192
192
  - `api_keys` `server` 等敏感配置项无法从接口获取和修改
193
193
  - `/api/logs` - 日志获取接口
194
- - `/api/tts/synthesize` - TTS 合成接口
195
194
  - `/api/system/health` - 健康检查接口
196
195
  - `/ws/stream` - 客户端使用的直播接口
197
196
  - `/ws/admin` - 日志和内建 Agent的 Context 流接口
@@ -1,37 +1,36 @@
1
1
  neuro_simulator/__init__.py,sha256=-tposzyvg6UckPcfSvtc03UjxBa9oCe_zRvlKf8splk,31
2
- neuro_simulator/cli.py,sha256=p2jSNbMsQ2HYau-EX3ygmTRhECU9dbSg0v53xgYjOZ4,3894
2
+ neuro_simulator/cli.py,sha256=Nc-udO0jdRVZjlbebKBjDVOIUzd6tJr13ApBGeBEg2k,3967
3
3
  neuro_simulator/agent/__init__.py,sha256=t52CZlyTGWqcGjMs90qvpFpRckY2WSSlO7r_H3K_mSY,32
4
4
  neuro_simulator/agent/base.py,sha256=6v2ZO5UpGCwJEkJ23Oe96Rs510tK4ZOEpZ2DB49IZmM,1262
5
- neuro_simulator/agent/core.py,sha256=CJv0We7ZjW_EKQB54Xq-y3wDu2a2HmoaOAdYR057HOg,8941
5
+ neuro_simulator/agent/core.py,sha256=2mPVCcNKZDRsyYd6L8RzQYlm8LwzoKoP9FJg0W4qcbc,10702
6
6
  neuro_simulator/agent/factory.py,sha256=e0IBnqJQM7OuKtglrf-pWwqwmg98wh7tOq5LxF2rV-w,1146
7
7
  neuro_simulator/agent/llm.py,sha256=vLz8hp2h2R0JaNfS1RLGYGkri_YoUdlEdNfFVbxeEuI,4261
8
8
  neuro_simulator/agent/memory/__init__.py,sha256=YJ7cynQJI6kD7vjyv3rKc-CZqmoYSuGQtRZl_XdGEps,39
9
- neuro_simulator/agent/memory/manager.py,sha256=z5ZI1agkuOev5gtuGA_g6MS3atB7ufdPRVNZZ89yg1w,9259
9
+ neuro_simulator/agent/memory/manager.py,sha256=UiUJgjiTV7SHCmb3V5sc4OUa_ksEeXBOyvl-WBQviqs,9266
10
10
  neuro_simulator/agent/tools/__init__.py,sha256=1WZy6PADfi6o1avyy1y-ThWBFAPJ_bBqtkobyYpf5ao,38
11
11
  neuro_simulator/agent/tools/core.py,sha256=o6Oyis-HFD-g6Z_u3T--tkmr9ylKJvybKqMRSMUwi1Q,5555
12
12
  neuro_simulator/api/__init__.py,sha256=5LWyDSayPGdQS8Rv13nmAKLyhPnMVPyTYDdvoMPB4xw,56
13
- neuro_simulator/api/agent.py,sha256=ABl_JoIxB4wW_J2J52bWndmTXkfGJBS5LZmbGuh7zv8,6343
14
- neuro_simulator/api/stream.py,sha256=Yg-cwjVI2HTLAt7moWbDQ1ZbbP6QE1ZB8LrW6A3tcQk,2081
15
- neuro_simulator/api/system.py,sha256=hXznMcThuFhwopYWgpzrRxwtBuFnF_b_vinkOaE5XOs,3712
13
+ neuro_simulator/api/stream.py,sha256=hM66flSUygpE-NH9X-ZOV6SiGipBzN1-wjd_wZRpQm4,94
14
+ neuro_simulator/api/system.py,sha256=W05Q41BYAFrw-MTnJ5YJrBG2S1SmTcByoex77GfUaFQ,1787
16
15
  neuro_simulator/core/__init__.py,sha256=-ojq25c8XA0CU25b0OxcGjH4IWFEDHR-HXSRSZIuKe8,57
17
16
  neuro_simulator/core/agent_factory.py,sha256=qMFidwT5IrOkyNHwmpO8_fRv20KLbaIBfWF-VTFCLNA,1742
18
- neuro_simulator/core/agent_interface.py,sha256=r58Opcgs7SWVovYTjMWuxF8AiTy9QfRz276_YGmSei0,2791
19
- neuro_simulator/core/application.py,sha256=fM9XgYBvx-mNB173rYDezbKdLJRTJ5Mr0nOtxNlSfSc,13365
17
+ neuro_simulator/core/agent_interface.py,sha256=ZXUCtkQUvsBQ5iCb0gTILJaShn5KmSrEgKhd7PK18HE,2794
18
+ neuro_simulator/core/application.py,sha256=zQ6QRUU-dyFW2GDKyBxiTO1BKh-Yt6j169YS-MLpalk,23734
20
19
  neuro_simulator/core/config.py,sha256=brA8kiekV_995mpz04JiGj1swIWbZZuWWLNYtbroMyE,14884
21
20
  neuro_simulator/services/__init__.py,sha256=s3ZrAHg5TpJakadAAGY1h0wDw_xqN4Je4aJwJyRBmk4,61
22
21
  neuro_simulator/services/audience.py,sha256=0phlhsujh_GMXm_UMiyOntY-ZMtoseRa_FroIfc5A6w,5028
23
22
  neuro_simulator/services/audio.py,sha256=ZscQA25wVYpm9FUl4Hya7tKH8t0TjR3th9-OEZ0G7xk,2934
24
- neuro_simulator/services/builtin.py,sha256=7ePxEom5HIK6wGto_H5M8JOnAjyiHqUuE381DEGgzjE,3821
23
+ neuro_simulator/services/builtin.py,sha256=nn3sJFPy09JxQkw35icdyGU9hzLTXXazAJkNpdcz6Zs,5848
25
24
  neuro_simulator/services/letta.py,sha256=6jBvOTsLMlRILDv-fvX9fhHMONSYeu-ImJGFcKU00kc,11067
26
25
  neuro_simulator/services/stream.py,sha256=dG7RuNI_ICohPkqKZ-zlBppo54BgWm_KYBs-ezzc73E,5907
27
26
  neuro_simulator/utils/__init__.py,sha256=xSEFzjT827W81mNyQ_DLtr00TgFlttqfFgpz9pSxFXQ,58
28
27
  neuro_simulator/utils/logging.py,sha256=BO-q_cCcoeamsc8eJqq2-L3Z8nhApze_v6LnmD-O8Ww,3411
29
- neuro_simulator/utils/process.py,sha256=9w2JQH59Wy6L8ADrig2QF88iajdykGPZIYJVJe6Al2Y,2603
28
+ neuro_simulator/utils/process.py,sha256=9OYWx8fzaJZqmFUcjQX37AnBhl7YWvrLxDWBa30vqwU,3192
30
29
  neuro_simulator/utils/queue.py,sha256=vSkh-BrgfsGN_gDAx2mfK44ydmMapdVyLsDG-7LIJZQ,1643
31
30
  neuro_simulator/utils/state.py,sha256=DdBqSAYfjOFtJfB1hEGhYPh32r1ZvFuVlN_-29_-luA,664
32
- neuro_simulator/utils/websocket.py,sha256=yOdFvJzbNhcUn5EAuyS55G_R8q-snas5OvkOtS8g19E,2292
33
- neuro_simulator-0.3.0.dist-info/METADATA,sha256=PELlUyyTi3i1u1_EOLIntPwd7-FAXAoy6uiSs2QA2uE,8676
34
- neuro_simulator-0.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
35
- neuro_simulator-0.3.0.dist-info/entry_points.txt,sha256=qVd5ypnRRgU8Cw7rWfZ7o0OXyS9P9hgY-cRoN_mgz9g,51
36
- neuro_simulator-0.3.0.dist-info/top_level.txt,sha256=V8awSKpcrFnjJDiJxSfy7jtOrnuE2BgAR9hLmfMDWK8,16
37
- neuro_simulator-0.3.0.dist-info/RECORD,,
31
+ neuro_simulator/utils/websocket.py,sha256=1gtVoH1hafBUfVYmwkVDAbjwETeqyC3sWx706nQzSRo,2085
32
+ neuro_simulator-0.3.2.dist-info/METADATA,sha256=HBAqQoRRJmPcm1IxQwderrq7cTO-UhF-ulzqixLNPh8,8643
33
+ neuro_simulator-0.3.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
34
+ neuro_simulator-0.3.2.dist-info/entry_points.txt,sha256=qVd5ypnRRgU8Cw7rWfZ7o0OXyS9P9hgY-cRoN_mgz9g,51
35
+ neuro_simulator-0.3.2.dist-info/top_level.txt,sha256=V8awSKpcrFnjJDiJxSfy7jtOrnuE2BgAR9hLmfMDWK8,16
36
+ neuro_simulator-0.3.2.dist-info/RECORD,,
@@ -1,163 +0,0 @@
1
- # neuro_simulator/api/agent.py
2
- """Unified API endpoints for agent management, decoupled from implementation."""
3
-
4
- from fastapi import APIRouter, Depends, HTTPException, status, Request
5
- from typing import Dict, Any, List, Optional
6
- from pydantic import BaseModel
7
-
8
- # Imports for the new structure
9
- from ..core.config import config_manager
10
- from ..core.agent_factory import create_agent
11
- from ..core.agent_interface import BaseAgent
12
-
13
- router = APIRouter(prefix="/api/agent", tags=["Agent Management"])
14
-
15
- # Security dependency (remains the same)
16
- async def get_api_token(request: Request):
17
- password = config_manager.settings.server.panel_password
18
- if not password:
19
- return True
20
- header_token = request.headers.get("X-API-Token")
21
- if header_token and header_token == password:
22
- return True
23
- raise HTTPException(
24
- status_code=status.HTTP_401_UNAUTHORIZED,
25
- detail="Invalid API token",
26
- headers={"WWW-Authenticate": "Bearer"},
27
- )
28
-
29
- # Pydantic models (remains the same)
30
- class MessageItem(BaseModel):
31
- username: str
32
- text: str
33
- role: str = "user"
34
-
35
- class ToolExecutionRequest(BaseModel):
36
- tool_name: str
37
- params: Dict[str, Any]
38
-
39
- class MemoryUpdateRequest(BaseModel):
40
- title: Optional[str] = None
41
- description: Optional[str] = None
42
- content: Optional[List[str]] = None
43
-
44
- class MemoryCreateRequest(BaseModel):
45
- title: str
46
- description: str
47
- content: List[str]
48
-
49
- class InitMemoryUpdateRequest(BaseModel):
50
- memory: Dict[str, Any]
51
-
52
- class TempMemoryItem(BaseModel):
53
- content: str
54
- role: str = "system"
55
-
56
- # Dependency to get the agent instance, making endpoints cleaner
57
- async def get_agent() -> BaseAgent:
58
- return await create_agent()
59
-
60
- # A single dependency for both auth and agent instance
61
- class AgentDeps:
62
- def __init__(self, token: bool = Depends(get_api_token), agent: BaseAgent = Depends(get_agent)):
63
- self.agent = agent
64
-
65
- # --- Refactored Agent Endpoints ---
66
-
67
- @router.get("/messages", response_model=List[Dict[str, Any]])
68
- async def get_agent_messages(deps: AgentDeps = Depends()):
69
- """Get agent's detailed message processing history."""
70
- return await deps.agent.get_message_history()
71
-
72
- @router.get("/context", response_model=List[Dict[str, Any]])
73
- async def get_agent_context(deps: AgentDeps = Depends()):
74
- """Get agent's recent conversation context (last 20 entries)."""
75
- return await deps.agent.get_message_history(limit=20)
76
-
77
- @router.delete("/messages")
78
- async def clear_agent_messages(deps: AgentDeps = Depends()):
79
- """Clear agent's message history."""
80
- await deps.agent.reset_memory()
81
- return {"status": "success", "message": "Agent memory reset successfully"}
82
-
83
- @router.post("/messages")
84
- async def send_message_to_agent(message: MessageItem, deps: AgentDeps = Depends()):
85
- """Send a message to the agent."""
86
- response = await deps.agent.process_messages([message.dict()])
87
- return {"response": response}
88
-
89
- @router.get("/memory/init", response_model=Dict[str, Any])
90
- async def get_init_memory(deps: AgentDeps = Depends()):
91
- """Get initialization memory content."""
92
- return await deps.agent.get_init_memory()
93
-
94
- @router.put("/memory/init")
95
- async def update_init_memory(request: InitMemoryUpdateRequest, deps: AgentDeps = Depends()):
96
- """Update initialization memory content."""
97
- await deps.agent.update_init_memory(request.memory)
98
- return {"status": "success", "message": "Initialization memory updated"}
99
-
100
- @router.get("/memory/temp", response_model=List[Dict[str, Any]])
101
- async def get_temp_memory(deps: AgentDeps = Depends()):
102
- """Get all temporary memory content."""
103
- return await deps.agent.get_temp_memory()
104
-
105
- @router.post("/memory/temp")
106
- async def add_temp_memory_item(request: TempMemoryItem, deps: AgentDeps = Depends()):
107
- """Add an item to temporary memory."""
108
- await deps.agent.add_temp_memory(request.content, request.role)
109
- return {"status": "success", "message": "Item added to temporary memory"}
110
-
111
- @router.delete("/memory/temp")
112
- async def clear_temp_memory(deps: AgentDeps = Depends()):
113
- """Clear temporary memory."""
114
- await deps.agent.clear_temp_memory()
115
- return {"status": "success", "message": "Temporary memory cleared"}
116
-
117
- @router.get("/memory/blocks", response_model=List[Dict[str, Any]])
118
- async def get_memory_blocks(deps: AgentDeps = Depends()):
119
- """Get all memory blocks."""
120
- return await deps.agent.get_memory_blocks()
121
-
122
- @router.get("/memory/blocks/{block_id}", response_model=Dict[str, Any])
123
- async def get_memory_block(block_id: str, deps: AgentDeps = Depends()):
124
- """Get a specific memory block."""
125
- block = await deps.agent.get_memory_block(block_id)
126
- if block is None:
127
- raise HTTPException(status_code=404, detail="Memory block not found")
128
- return block
129
-
130
- @router.post("/memory/blocks", response_model=Dict[str, str])
131
- async def create_memory_block(request: MemoryCreateRequest, deps: AgentDeps = Depends()):
132
- """Create a new memory block."""
133
- return await deps.agent.create_memory_block(request.title, request.description, request.content)
134
-
135
- @router.put("/memory/blocks/{block_id}")
136
- async def update_memory_block(block_id: str, request: MemoryUpdateRequest, deps: AgentDeps = Depends()):
137
- """Update a memory block."""
138
- await deps.agent.update_memory_block(block_id, request.title, request.description, request.content)
139
- return {"status": "success"}
140
-
141
- @router.delete("/memory/blocks/{block_id}")
142
- async def delete_memory_block(block_id: str, deps: AgentDeps = Depends()):
143
- """Delete a memory block."""
144
- await deps.agent.delete_memory_block(block_id)
145
- return {"status": "success"}
146
-
147
- @router.post("/reset_memory")
148
- async def reset_agent_memory(deps: AgentDeps = Depends()):
149
- """Reset all agent memory types."""
150
- await deps.agent.reset_memory()
151
- return {"status": "success", "message": "Agent memory reset successfully"}
152
-
153
- @router.get("/tools")
154
- async def get_available_tools(deps: AgentDeps = Depends()):
155
- """Get list of available tools."""
156
- # Return in the format expected by the frontend
157
- return {"tools": await deps.agent.get_available_tools()}
158
-
159
- @router.post("/tools/execute")
160
- async def execute_tool(request: ToolExecutionRequest, deps: AgentDeps = Depends()):
161
- """Execute a tool with given parameters."""
162
- result = await deps.agent.execute_tool(request.tool_name, request.params)
163
- return {"result": result}