neuro-simulator 0.0.4__py3-none-any.whl → 0.1.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.
- neuro_simulator/__init__.py +10 -1
- neuro_simulator/agent/__init__.py +8 -0
- neuro_simulator/agent/api.py +737 -0
- neuro_simulator/agent/core.py +471 -0
- neuro_simulator/agent/llm.py +104 -0
- neuro_simulator/agent/memory/__init__.py +4 -0
- neuro_simulator/agent/memory/manager.py +370 -0
- neuro_simulator/agent/memory.py +137 -0
- neuro_simulator/agent/tools/__init__.py +4 -0
- neuro_simulator/agent/tools/core.py +112 -0
- neuro_simulator/agent/tools.py +69 -0
- neuro_simulator/builtin_agent.py +83 -0
- neuro_simulator/cli.py +45 -0
- neuro_simulator/config.py +217 -79
- neuro_simulator/config.yaml.example +16 -2
- neuro_simulator/letta.py +71 -45
- neuro_simulator/log_handler.py +30 -16
- neuro_simulator/main.py +167 -30
- neuro_simulator/process_manager.py +5 -2
- neuro_simulator/stream_manager.py +6 -0
- {neuro_simulator-0.0.4.dist-info → neuro_simulator-0.1.2.dist-info}/METADATA +1 -1
- neuro_simulator-0.1.2.dist-info/RECORD +31 -0
- neuro_simulator-0.0.4.dist-info/RECORD +0 -20
- {neuro_simulator-0.0.4.dist-info → neuro_simulator-0.1.2.dist-info}/WHEEL +0 -0
- {neuro_simulator-0.0.4.dist-info → neuro_simulator-0.1.2.dist-info}/entry_points.txt +0 -0
- {neuro_simulator-0.0.4.dist-info → neuro_simulator-0.1.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,737 @@
|
|
1
|
+
# agent/api.py
|
2
|
+
"""Unified API endpoints for agent management"""
|
3
|
+
|
4
|
+
from fastapi import APIRouter, Depends, HTTPException, status, Request
|
5
|
+
from typing import Dict, Any, List, Optional
|
6
|
+
from pydantic import BaseModel
|
7
|
+
import asyncio
|
8
|
+
|
9
|
+
from ..config import config_manager
|
10
|
+
|
11
|
+
# Dynamically import the appropriate agent based on config
|
12
|
+
agent_type = config_manager.settings.agent_type
|
13
|
+
|
14
|
+
if agent_type == "builtin":
|
15
|
+
# We'll import the module, not the variable, to avoid import-time issues
|
16
|
+
import neuro_simulator.builtin_agent as builtin_agent_module
|
17
|
+
else:
|
18
|
+
from ..letta import letta_client, config_manager
|
19
|
+
|
20
|
+
router = APIRouter(prefix="/api/agent", tags=["Agent Management"])
|
21
|
+
|
22
|
+
# Security dependency
|
23
|
+
async def get_api_token(request: Request):
|
24
|
+
"""检查API token是否有效"""
|
25
|
+
password = config_manager.settings.server.panel_password
|
26
|
+
if not password:
|
27
|
+
# No password set, allow access
|
28
|
+
return True
|
29
|
+
|
30
|
+
# 检查header中的token
|
31
|
+
header_token = request.headers.get("X-API-Token")
|
32
|
+
if header_token and header_token == password:
|
33
|
+
return True
|
34
|
+
|
35
|
+
raise HTTPException(
|
36
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
37
|
+
detail="Invalid API token",
|
38
|
+
headers={"WWW-Authenticate": "Bearer"},
|
39
|
+
)
|
40
|
+
|
41
|
+
class MessageItem(BaseModel):
|
42
|
+
username: str
|
43
|
+
text: str
|
44
|
+
role: str = "user"
|
45
|
+
|
46
|
+
class ToolExecutionRequest(BaseModel):
|
47
|
+
tool_name: str
|
48
|
+
params: Dict[str, Any]
|
49
|
+
|
50
|
+
class MemoryUpdateRequest(BaseModel):
|
51
|
+
block_id: str
|
52
|
+
title: Optional[str] = None
|
53
|
+
description: Optional[str] = None
|
54
|
+
content: Optional[List[str]] = None
|
55
|
+
|
56
|
+
class MemoryCreateRequest(BaseModel):
|
57
|
+
title: str
|
58
|
+
description: str
|
59
|
+
content: List[str]
|
60
|
+
|
61
|
+
class InitMemoryUpdateRequest(BaseModel):
|
62
|
+
memory: Dict[str, Any]
|
63
|
+
|
64
|
+
class TempMemoryItem(BaseModel):
|
65
|
+
content: str
|
66
|
+
role: str = "system"
|
67
|
+
|
68
|
+
# Agent message APIs
|
69
|
+
@router.get("/messages", dependencies=[Depends(get_api_token)])
|
70
|
+
async def get_agent_messages():
|
71
|
+
"""Get agent's detailed message processing history"""
|
72
|
+
if agent_type == "builtin":
|
73
|
+
# Check if local_agent is initialized
|
74
|
+
if builtin_agent_module.local_agent is None:
|
75
|
+
# Try to initialize it
|
76
|
+
try:
|
77
|
+
await builtin_agent_module.initialize_builtin_agent()
|
78
|
+
except Exception as e:
|
79
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize builtin agent: {str(e)}")
|
80
|
+
|
81
|
+
if builtin_agent_module.local_agent is None:
|
82
|
+
raise HTTPException(status_code=500, detail="Builtin agent not initialized")
|
83
|
+
|
84
|
+
# Return temp memory which contains the message history with processing details
|
85
|
+
all_messages = builtin_agent_module.local_agent.memory_manager.temp_memory
|
86
|
+
# Filter to only include messages with processing details (marked by having 'processing_details' key)
|
87
|
+
detailed_messages = [msg for msg in all_messages if 'processing_details' in msg]
|
88
|
+
return detailed_messages
|
89
|
+
else:
|
90
|
+
# For Letta agent, we need to get messages from the Letta API
|
91
|
+
if letta_client is None:
|
92
|
+
# Try to initialize letta client
|
93
|
+
try:
|
94
|
+
from ..letta import initialize_letta_client
|
95
|
+
initialize_letta_client()
|
96
|
+
except Exception as e:
|
97
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize Letta client: {str(e)}")
|
98
|
+
|
99
|
+
if letta_client is None:
|
100
|
+
raise HTTPException(status_code=500, detail="Letta client not initialized")
|
101
|
+
|
102
|
+
try:
|
103
|
+
agent_id = config_manager.settings.api_keys.neuro_agent_id
|
104
|
+
if not agent_id:
|
105
|
+
raise HTTPException(status_code=500, detail="Letta agent ID not configured")
|
106
|
+
|
107
|
+
messages = letta_client.agents.messages.list(agent_id=agent_id)
|
108
|
+
return messages
|
109
|
+
except Exception as e:
|
110
|
+
raise HTTPException(status_code=500, detail=f"Error getting messages: {str(e)}")
|
111
|
+
|
112
|
+
@router.get("/context", dependencies=[Depends(get_api_token)])
|
113
|
+
async def get_agent_context():
|
114
|
+
"""Get agent's conversation context"""
|
115
|
+
if agent_type == "builtin":
|
116
|
+
# Check if local_agent is initialized
|
117
|
+
if builtin_agent_module.local_agent is None:
|
118
|
+
# Try to initialize it
|
119
|
+
try:
|
120
|
+
await builtin_agent_module.initialize_builtin_agent()
|
121
|
+
except Exception as e:
|
122
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize builtin agent: {str(e)}")
|
123
|
+
|
124
|
+
if builtin_agent_module.local_agent is None:
|
125
|
+
raise HTTPException(status_code=500, detail="Builtin agent not initialized")
|
126
|
+
|
127
|
+
# Return conversation context
|
128
|
+
context_messages = await builtin_agent_module.local_agent.memory_manager.get_recent_context()
|
129
|
+
return context_messages
|
130
|
+
else:
|
131
|
+
# For Letta agent, we need to get messages from the Letta API
|
132
|
+
if letta_client is None:
|
133
|
+
# Try to initialize letta client
|
134
|
+
try:
|
135
|
+
from ..letta import initialize_letta_client
|
136
|
+
initialize_letta_client()
|
137
|
+
except Exception as e:
|
138
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize Letta client: {str(e)}")
|
139
|
+
|
140
|
+
if letta_client is None:
|
141
|
+
raise HTTPException(status_code=500, detail="Letta client not initialized")
|
142
|
+
|
143
|
+
try:
|
144
|
+
agent_id = config_manager.settings.api_keys.neuro_agent_id
|
145
|
+
if not agent_id:
|
146
|
+
raise HTTPException(status_code=500, detail="Letta agent ID not configured")
|
147
|
+
|
148
|
+
messages = letta_client.agents.messages.list(agent_id=agent_id)
|
149
|
+
return messages
|
150
|
+
except Exception as e:
|
151
|
+
raise HTTPException(status_code=500, detail=f"Error getting messages: {str(e)}")
|
152
|
+
|
153
|
+
@router.delete("/messages", dependencies=[Depends(get_api_token)])
|
154
|
+
async def clear_agent_messages():
|
155
|
+
"""Clear agent's message history"""
|
156
|
+
if agent_type == "builtin":
|
157
|
+
# Check if local_agent is initialized
|
158
|
+
if builtin_agent_module.local_agent is None:
|
159
|
+
# Try to initialize it
|
160
|
+
try:
|
161
|
+
await builtin_agent_module.initialize_builtin_agent()
|
162
|
+
except Exception as e:
|
163
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize builtin agent: {str(e)}")
|
164
|
+
|
165
|
+
if builtin_agent_module.local_agent is None:
|
166
|
+
raise HTTPException(status_code=500, detail="Builtin agent not initialized")
|
167
|
+
|
168
|
+
# For builtin agent, we need to filter out messages with processing details
|
169
|
+
manager = builtin_agent_module.local_agent.memory_manager
|
170
|
+
manager.temp_memory = [msg for msg in manager.temp_memory if 'processing_details' not in msg]
|
171
|
+
await manager._save_temp_memory()
|
172
|
+
return {"status": "success", "message": "Messages cleared successfully"}
|
173
|
+
else:
|
174
|
+
# For Letta agent, we need to reset messages via the Letta API
|
175
|
+
if letta_client is None:
|
176
|
+
# Try to initialize letta client
|
177
|
+
try:
|
178
|
+
from ..letta import initialize_letta_client
|
179
|
+
initialize_letta_client()
|
180
|
+
except Exception as e:
|
181
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize Letta client: {str(e)}")
|
182
|
+
|
183
|
+
if letta_client is None:
|
184
|
+
raise HTTPException(status_code=500, detail="Letta client not initialized")
|
185
|
+
|
186
|
+
try:
|
187
|
+
agent_id = config_manager.settings.api_keys.neuro_agent_id
|
188
|
+
if not agent_id:
|
189
|
+
raise HTTPException(status_code=500, detail="Letta agent ID not configured")
|
190
|
+
|
191
|
+
# Reset messages
|
192
|
+
letta_client.agents.messages.reset(agent_id=agent_id)
|
193
|
+
return {"status": "success", "message": "Messages cleared successfully"}
|
194
|
+
except Exception as e:
|
195
|
+
raise HTTPException(status_code=500, detail=f"Error clearing messages: {str(e)}")
|
196
|
+
|
197
|
+
@router.delete("/messages/{message_id}", dependencies=[Depends(get_api_token)])
|
198
|
+
async def delete_agent_message(message_id: str):
|
199
|
+
"""Delete a specific message from agent's history"""
|
200
|
+
if agent_type == "builtin":
|
201
|
+
# Check if local_agent is initialized
|
202
|
+
if builtin_agent_module.local_agent is None:
|
203
|
+
# Try to initialize it
|
204
|
+
try:
|
205
|
+
await builtin_agent_module.initialize_builtin_agent()
|
206
|
+
except Exception as e:
|
207
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize builtin agent: {str(e)}")
|
208
|
+
|
209
|
+
if builtin_agent_module.local_agent is None:
|
210
|
+
raise HTTPException(status_code=500, detail="Builtin agent not initialized")
|
211
|
+
|
212
|
+
# For builtin agent, we don't have a direct way to delete a specific message
|
213
|
+
# We'll return a not supported error
|
214
|
+
raise HTTPException(status_code=400, detail="Deleting specific messages not supported for builtin agent")
|
215
|
+
else:
|
216
|
+
# For Letta agent, we need to delete a specific message via the Letta API
|
217
|
+
if letta_client is None:
|
218
|
+
# Try to initialize letta client
|
219
|
+
try:
|
220
|
+
from ..letta import initialize_letta_client
|
221
|
+
initialize_letta_client()
|
222
|
+
except Exception as e:
|
223
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize Letta client: {str(e)}")
|
224
|
+
|
225
|
+
if letta_client is None:
|
226
|
+
raise HTTPException(status_code=500, detail="Letta client not initialized")
|
227
|
+
|
228
|
+
try:
|
229
|
+
agent_id = config_manager.settings.api_keys.neuro_agent_id
|
230
|
+
if not agent_id:
|
231
|
+
raise HTTPException(status_code=500, detail="Letta agent ID not configured")
|
232
|
+
|
233
|
+
# Delete specific message
|
234
|
+
letta_client.agents.messages.delete(agent_id=agent_id, message_id=message_id)
|
235
|
+
return {"status": "success", "message": f"Message {message_id} deleted successfully"}
|
236
|
+
except Exception as e:
|
237
|
+
raise HTTPException(status_code=500, detail=f"Error deleting message: {str(e)}")
|
238
|
+
|
239
|
+
@router.post("/messages", dependencies=[Depends(get_api_token)])
|
240
|
+
async def send_message_to_agent(message: MessageItem):
|
241
|
+
"""Send a message to the agent"""
|
242
|
+
if agent_type == "builtin":
|
243
|
+
# Check if local_agent is initialized
|
244
|
+
if builtin_agent_module.local_agent is None:
|
245
|
+
# Try to initialize it
|
246
|
+
try:
|
247
|
+
await builtin_agent_module.initialize_builtin_agent()
|
248
|
+
except Exception as e:
|
249
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize builtin agent: {str(e)}")
|
250
|
+
|
251
|
+
if builtin_agent_module.local_agent is None:
|
252
|
+
raise HTTPException(status_code=500, detail="Builtin agent not initialized")
|
253
|
+
|
254
|
+
response = await builtin_agent_module.local_agent.process_messages([message.dict()])
|
255
|
+
return {"response": response}
|
256
|
+
else:
|
257
|
+
# For Letta agent, we need to send the message via the Letta API
|
258
|
+
if letta_client is None:
|
259
|
+
# Try to initialize letta client
|
260
|
+
try:
|
261
|
+
from ..letta import initialize_letta_client
|
262
|
+
initialize_letta_client()
|
263
|
+
except Exception as e:
|
264
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize Letta client: {str(e)}")
|
265
|
+
|
266
|
+
if letta_client is None:
|
267
|
+
raise HTTPException(status_code=500, detail="Letta client not initialized")
|
268
|
+
|
269
|
+
try:
|
270
|
+
agent_id = config_manager.settings.api_keys.neuro_agent_id
|
271
|
+
if not agent_id:
|
272
|
+
raise HTTPException(status_code=500, detail="Letta agent ID not configured")
|
273
|
+
|
274
|
+
from letta_client import MessageCreate
|
275
|
+
response = letta_client.agents.messages.create(
|
276
|
+
agent_id=agent_id,
|
277
|
+
messages=[MessageCreate(role=message.role, content=f"{message.username}: {message.text}")]
|
278
|
+
)
|
279
|
+
|
280
|
+
# Extract the response text
|
281
|
+
ai_response_text = ""
|
282
|
+
if response and response.messages:
|
283
|
+
last_message = response.messages[-1]
|
284
|
+
if hasattr(last_message, 'content'):
|
285
|
+
if isinstance(last_message.content, str):
|
286
|
+
ai_response_text = last_message.content
|
287
|
+
elif isinstance(last_message.content, list) and last_message.content:
|
288
|
+
first_part = last_message.content[0]
|
289
|
+
if hasattr(first_part, 'text'):
|
290
|
+
ai_response_text = first_part.text
|
291
|
+
|
292
|
+
return {"response": ai_response_text}
|
293
|
+
except Exception as e:
|
294
|
+
raise HTTPException(status_code=500, detail=f"Error sending message: {str(e)}")
|
295
|
+
|
296
|
+
# Agent memory APIs
|
297
|
+
@router.get("/memory/init", dependencies=[Depends(get_api_token)])
|
298
|
+
async def get_init_memory():
|
299
|
+
"""Get initialization memory content"""
|
300
|
+
if agent_type == "builtin":
|
301
|
+
# Check if local_agent is initialized
|
302
|
+
if builtin_agent_module.local_agent is None:
|
303
|
+
# Try to initialize it
|
304
|
+
try:
|
305
|
+
await builtin_agent_module.initialize_builtin_agent()
|
306
|
+
except Exception as e:
|
307
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize builtin agent: {str(e)}")
|
308
|
+
|
309
|
+
if builtin_agent_module.local_agent is None:
|
310
|
+
raise HTTPException(status_code=500, detail="Builtin agent not initialized")
|
311
|
+
|
312
|
+
# Return init memory
|
313
|
+
return builtin_agent_module.local_agent.memory_manager.init_memory
|
314
|
+
else:
|
315
|
+
# For Letta agent, init memory concept doesn't directly apply
|
316
|
+
raise HTTPException(status_code=400, detail="Getting init memory not supported for Letta agent")
|
317
|
+
|
318
|
+
@router.put("/memory/init", dependencies=[Depends(get_api_token)])
|
319
|
+
async def update_init_memory(request: InitMemoryUpdateRequest):
|
320
|
+
"""Update initialization memory content"""
|
321
|
+
if agent_type == "builtin":
|
322
|
+
# Check if local_agent is initialized
|
323
|
+
if builtin_agent_module.local_agent is None:
|
324
|
+
# Try to initialize it
|
325
|
+
try:
|
326
|
+
await builtin_agent_module.initialize_builtin_agent()
|
327
|
+
except Exception as e:
|
328
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize builtin agent: {str(e)}")
|
329
|
+
|
330
|
+
if builtin_agent_module.local_agent is None:
|
331
|
+
raise HTTPException(status_code=500, detail="Builtin agent not initialized")
|
332
|
+
|
333
|
+
# Update init memory
|
334
|
+
manager = builtin_agent_module.local_agent.memory_manager
|
335
|
+
manager.init_memory.update(request.memory)
|
336
|
+
await manager._save_init_memory()
|
337
|
+
|
338
|
+
return {"status": "success", "message": "Initialization memory updated"}
|
339
|
+
else:
|
340
|
+
# For Letta agent, init memory concept doesn't directly apply
|
341
|
+
raise HTTPException(status_code=400, detail="Updating init memory not supported for Letta agent")
|
342
|
+
|
343
|
+
@router.get("/memory/temp", dependencies=[Depends(get_api_token)])
|
344
|
+
async def get_temp_memory():
|
345
|
+
"""Get all temporary memory content"""
|
346
|
+
if agent_type == "builtin":
|
347
|
+
# Check if local_agent is initialized
|
348
|
+
if builtin_agent_module.local_agent is None:
|
349
|
+
# Try to initialize it
|
350
|
+
try:
|
351
|
+
await builtin_agent_module.initialize_builtin_agent()
|
352
|
+
except Exception as e:
|
353
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize builtin agent: {str(e)}")
|
354
|
+
|
355
|
+
if builtin_agent_module.local_agent is None:
|
356
|
+
raise HTTPException(status_code=500, detail="Builtin agent not initialized")
|
357
|
+
|
358
|
+
# Return all temp memory
|
359
|
+
return builtin_agent_module.local_agent.memory_manager.temp_memory
|
360
|
+
else:
|
361
|
+
# For Letta agent, temp memory concept doesn't directly apply
|
362
|
+
raise HTTPException(status_code=400, detail="Getting temp memory not supported for Letta agent")
|
363
|
+
|
364
|
+
@router.get("/memory/blocks", dependencies=[Depends(get_api_token)])
|
365
|
+
async def get_memory_blocks():
|
366
|
+
"""Get all memory blocks"""
|
367
|
+
if agent_type == "builtin":
|
368
|
+
# Check if local_agent is initialized
|
369
|
+
if builtin_agent_module.local_agent is None:
|
370
|
+
# Try to initialize it
|
371
|
+
try:
|
372
|
+
await builtin_agent_module.initialize_builtin_agent()
|
373
|
+
except Exception as e:
|
374
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize builtin agent: {str(e)}")
|
375
|
+
|
376
|
+
if builtin_agent_module.local_agent is None:
|
377
|
+
raise HTTPException(status_code=500, detail="Builtin agent not initialized")
|
378
|
+
|
379
|
+
blocks = await builtin_agent_module.local_agent.memory_manager.get_core_memory_blocks()
|
380
|
+
return blocks
|
381
|
+
else:
|
382
|
+
# For Letta agent, we need to get memory blocks from the Letta API
|
383
|
+
if letta_client is None:
|
384
|
+
# Try to initialize letta client
|
385
|
+
try:
|
386
|
+
from ..letta import initialize_letta_client
|
387
|
+
initialize_letta_client()
|
388
|
+
except Exception as e:
|
389
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize Letta client: {str(e)}")
|
390
|
+
|
391
|
+
if letta_client is None:
|
392
|
+
raise HTTPException(status_code=500, detail="Letta client not initialized")
|
393
|
+
|
394
|
+
try:
|
395
|
+
agent_id = config_manager.settings.api_keys.neuro_agent_id
|
396
|
+
if not agent_id:
|
397
|
+
raise HTTPException(status_code=500, detail="Letta agent ID not configured")
|
398
|
+
|
399
|
+
blocks = letta_client.agents.blocks.list(agent_id=agent_id)
|
400
|
+
return blocks
|
401
|
+
except Exception as e:
|
402
|
+
raise HTTPException(status_code=500, detail=f"Error getting memory blocks: {str(e)}")
|
403
|
+
|
404
|
+
@router.get("/memory/blocks/{block_id}", dependencies=[Depends(get_api_token)])
|
405
|
+
async def get_memory_block(block_id: str):
|
406
|
+
"""Get a specific memory block"""
|
407
|
+
if agent_type == "builtin":
|
408
|
+
# Check if local_agent is initialized
|
409
|
+
if builtin_agent_module.local_agent is None:
|
410
|
+
# Try to initialize it
|
411
|
+
try:
|
412
|
+
await builtin_agent_module.initialize_builtin_agent()
|
413
|
+
except Exception as e:
|
414
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize builtin agent: {str(e)}")
|
415
|
+
|
416
|
+
if builtin_agent_module.local_agent is None:
|
417
|
+
raise HTTPException(status_code=500, detail="Builtin agent not initialized")
|
418
|
+
|
419
|
+
block = await builtin_agent_module.local_agent.memory_manager.get_core_memory_block(block_id)
|
420
|
+
if block is None:
|
421
|
+
raise HTTPException(status_code=404, detail="Memory block not found")
|
422
|
+
return block
|
423
|
+
else:
|
424
|
+
# For Letta agent
|
425
|
+
if letta_client is None:
|
426
|
+
# Try to initialize letta client
|
427
|
+
try:
|
428
|
+
from ..letta import initialize_letta_client
|
429
|
+
initialize_letta_client()
|
430
|
+
except Exception as e:
|
431
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize Letta client: {str(e)}")
|
432
|
+
|
433
|
+
if letta_client is None:
|
434
|
+
raise HTTPException(status_code=500, detail="Letta client not initialized")
|
435
|
+
|
436
|
+
try:
|
437
|
+
agent_id = config_manager.settings.api_keys.neuro_agent_id
|
438
|
+
if not agent_id:
|
439
|
+
raise HTTPException(status_code=500, detail="Letta agent ID not configured")
|
440
|
+
|
441
|
+
block = letta_client.agents.blocks.retrieve(agent_id=agent_id, block_id=block_id)
|
442
|
+
return block
|
443
|
+
except Exception as e:
|
444
|
+
raise HTTPException(status_code=500, detail=f"Error getting memory block: {str(e)}")
|
445
|
+
|
446
|
+
@router.post("/memory/blocks", dependencies=[Depends(get_api_token)])
|
447
|
+
async def create_memory_block(request: MemoryCreateRequest):
|
448
|
+
"""Create a new memory block"""
|
449
|
+
if agent_type == "builtin":
|
450
|
+
# Check if local_agent is initialized
|
451
|
+
if builtin_agent_module.local_agent is None:
|
452
|
+
# Try to initialize it
|
453
|
+
try:
|
454
|
+
await builtin_agent_module.initialize_builtin_agent()
|
455
|
+
except Exception as e:
|
456
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize builtin agent: {str(e)}")
|
457
|
+
|
458
|
+
if builtin_agent_module.local_agent is None:
|
459
|
+
raise HTTPException(status_code=500, detail="Builtin agent not initialized")
|
460
|
+
|
461
|
+
block_id = await builtin_agent_module.local_agent.memory_manager.create_core_memory_block(
|
462
|
+
title=request.title,
|
463
|
+
description=request.description,
|
464
|
+
content=request.content
|
465
|
+
)
|
466
|
+
return {"block_id": block_id}
|
467
|
+
else:
|
468
|
+
# For Letta agent
|
469
|
+
if letta_client is None:
|
470
|
+
# Try to initialize letta client
|
471
|
+
try:
|
472
|
+
from ..letta import initialize_letta_client
|
473
|
+
initialize_letta_client()
|
474
|
+
except Exception as e:
|
475
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize Letta client: {str(e)}")
|
476
|
+
|
477
|
+
if letta_client is None:
|
478
|
+
raise HTTPException(status_code=500, detail="Letta client not initialized")
|
479
|
+
|
480
|
+
try:
|
481
|
+
agent_id = config_manager.settings.api_keys.neuro_agent_id
|
482
|
+
if not agent_id:
|
483
|
+
raise HTTPException(status_code=500, detail="Letta agent ID not configured")
|
484
|
+
|
485
|
+
block = letta_client.agents.blocks.create(
|
486
|
+
agent_id=agent_id,
|
487
|
+
name=request.title, # Using title as name for Letta
|
488
|
+
content="\n".join(request.content), # Join content as a single string
|
489
|
+
limit=1000 # Default limit
|
490
|
+
)
|
491
|
+
|
492
|
+
return {"block_id": block.id}
|
493
|
+
except Exception as e:
|
494
|
+
raise HTTPException(status_code=500, detail=f"Error creating memory block: {str(e)}")
|
495
|
+
|
496
|
+
@router.put("/memory/blocks/{block_id}", dependencies=[Depends(get_api_token)])
|
497
|
+
async def update_memory_block(block_id: str, request: MemoryUpdateRequest):
|
498
|
+
"""Update a memory block"""
|
499
|
+
if agent_type == "builtin":
|
500
|
+
# Check if local_agent is initialized
|
501
|
+
if builtin_agent_module.local_agent is None:
|
502
|
+
# Try to initialize it
|
503
|
+
try:
|
504
|
+
await builtin_agent_module.initialize_builtin_agent()
|
505
|
+
except Exception as e:
|
506
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize builtin agent: {str(e)}")
|
507
|
+
|
508
|
+
if builtin_agent_module.local_agent is None:
|
509
|
+
raise HTTPException(status_code=500, detail="Builtin agent not initialized")
|
510
|
+
|
511
|
+
try:
|
512
|
+
await builtin_agent_module.local_agent.memory_manager.update_core_memory_block(
|
513
|
+
block_id=block_id,
|
514
|
+
title=request.title,
|
515
|
+
description=request.description,
|
516
|
+
content=request.content
|
517
|
+
)
|
518
|
+
return {"status": "success"}
|
519
|
+
except Exception as e:
|
520
|
+
raise HTTPException(status_code=500, detail=f"Error updating memory block: {str(e)}")
|
521
|
+
else:
|
522
|
+
# For Letta agent
|
523
|
+
if letta_client is None:
|
524
|
+
# Try to initialize letta client
|
525
|
+
try:
|
526
|
+
from ..letta import initialize_letta_client
|
527
|
+
initialize_letta_client()
|
528
|
+
except Exception as e:
|
529
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize Letta client: {str(e)}")
|
530
|
+
|
531
|
+
if letta_client is None:
|
532
|
+
raise HTTPException(status_code=500, detail="Letta client not initialized")
|
533
|
+
|
534
|
+
try:
|
535
|
+
agent_id = config_manager.settings.api_keys.neuro_agent_id
|
536
|
+
if not agent_id:
|
537
|
+
raise HTTPException(status_code=500, detail="Letta agent ID not configured")
|
538
|
+
|
539
|
+
# Prepare update parameters
|
540
|
+
update_params = {}
|
541
|
+
if request.title:
|
542
|
+
update_params["name"] = request.title
|
543
|
+
if request.content:
|
544
|
+
update_params["content"] = "\n".join(request.content)
|
545
|
+
if request.description:
|
546
|
+
update_params["description"] = request.description
|
547
|
+
|
548
|
+
letta_client.agents.blocks.modify(
|
549
|
+
agent_id=agent_id,
|
550
|
+
block_id=block_id,
|
551
|
+
**update_params
|
552
|
+
)
|
553
|
+
|
554
|
+
return {"status": "success"}
|
555
|
+
except Exception as e:
|
556
|
+
raise HTTPException(status_code=500, detail=f"Error updating memory block: {str(e)}")
|
557
|
+
|
558
|
+
@router.delete("/memory/blocks/{block_id}", dependencies=[Depends(get_api_token)])
|
559
|
+
async def delete_memory_block(block_id: str):
|
560
|
+
"""Delete a memory block"""
|
561
|
+
if agent_type == "builtin":
|
562
|
+
# Check if local_agent is initialized
|
563
|
+
if builtin_agent_module.local_agent is None:
|
564
|
+
# Try to initialize it
|
565
|
+
try:
|
566
|
+
await builtin_agent_module.initialize_builtin_agent()
|
567
|
+
except Exception as e:
|
568
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize builtin agent: {str(e)}")
|
569
|
+
|
570
|
+
if builtin_agent_module.local_agent is None:
|
571
|
+
raise HTTPException(status_code=500, detail="Builtin agent not initialized")
|
572
|
+
|
573
|
+
try:
|
574
|
+
await builtin_agent_module.local_agent.memory_manager.delete_core_memory_block(block_id)
|
575
|
+
return {"status": "success"}
|
576
|
+
except Exception as e:
|
577
|
+
raise HTTPException(status_code=500, detail=f"Error deleting memory block: {str(e)}")
|
578
|
+
else:
|
579
|
+
# For Letta agent
|
580
|
+
if letta_client is None:
|
581
|
+
# Try to initialize letta client
|
582
|
+
try:
|
583
|
+
from ..letta import initialize_letta_client
|
584
|
+
initialize_letta_client()
|
585
|
+
except Exception as e:
|
586
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize Letta client: {str(e)}")
|
587
|
+
|
588
|
+
if letta_client is None:
|
589
|
+
raise HTTPException(status_code=500, detail="Letta client not initialized")
|
590
|
+
|
591
|
+
try:
|
592
|
+
agent_id = config_manager.settings.api_keys.neuro_agent_id
|
593
|
+
if not agent_id:
|
594
|
+
raise HTTPException(status_code=500, detail="Letta agent ID not configured")
|
595
|
+
|
596
|
+
letta_client.agents.blocks.delete(agent_id=agent_id, block_id=block_id)
|
597
|
+
return {"status": "success"}
|
598
|
+
except Exception as e:
|
599
|
+
raise HTTPException(status_code=500, detail=f"Error deleting memory block: {str(e)}")
|
600
|
+
|
601
|
+
@router.post("/memory/temp", dependencies=[Depends(get_api_token)])
|
602
|
+
async def add_temp_memory_item(request: TempMemoryItem):
|
603
|
+
"""Add an item to temporary memory"""
|
604
|
+
if agent_type == "builtin":
|
605
|
+
# Check if local_agent is initialized
|
606
|
+
if builtin_agent_module.local_agent is None:
|
607
|
+
# Try to initialize it
|
608
|
+
try:
|
609
|
+
await builtin_agent_module.initialize_builtin_agent()
|
610
|
+
except Exception as e:
|
611
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize builtin agent: {str(e)}")
|
612
|
+
|
613
|
+
if builtin_agent_module.local_agent is None:
|
614
|
+
raise HTTPException(status_code=500, detail="Builtin agent not initialized")
|
615
|
+
|
616
|
+
# Add item to temp memory
|
617
|
+
await builtin_agent_module.local_agent.memory_manager.add_temp_memory(request.content, request.role)
|
618
|
+
|
619
|
+
return {"status": "success", "message": "Item added to temporary memory"}
|
620
|
+
else:
|
621
|
+
# For Letta agent, we don't have a direct way to add temp memory items
|
622
|
+
raise HTTPException(status_code=400, detail="Adding items to temporary memory not supported for Letta agent")
|
623
|
+
|
624
|
+
@router.delete("/memory/temp", dependencies=[Depends(get_api_token)])
|
625
|
+
async def clear_temp_memory():
|
626
|
+
"""Clear temporary memory"""
|
627
|
+
if agent_type == "builtin":
|
628
|
+
# Check if local_agent is initialized
|
629
|
+
if builtin_agent_module.local_agent is None:
|
630
|
+
# Try to initialize it
|
631
|
+
try:
|
632
|
+
await builtin_agent_module.initialize_builtin_agent()
|
633
|
+
except Exception as e:
|
634
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize builtin agent: {str(e)}")
|
635
|
+
|
636
|
+
if builtin_agent_module.local_agent is None:
|
637
|
+
raise HTTPException(status_code=500, detail="Builtin agent not initialized")
|
638
|
+
|
639
|
+
# Reset only temp memory
|
640
|
+
await builtin_agent_module.local_agent.memory_manager.reset_temp_memory()
|
641
|
+
return {"status": "success", "message": "Temporary memory cleared"}
|
642
|
+
else:
|
643
|
+
# For Letta agent, we don't have a direct way to clear temp memory
|
644
|
+
raise HTTPException(status_code=400, detail="Clearing temporary memory not supported for Letta agent")
|
645
|
+
|
646
|
+
@router.post("/reset_memory", dependencies=[Depends(get_api_token)])
|
647
|
+
async def reset_agent_memory():
|
648
|
+
"""Reset all agent memory types"""
|
649
|
+
if agent_type == "builtin":
|
650
|
+
# Check if local_agent is initialized
|
651
|
+
if builtin_agent_module.local_agent is None:
|
652
|
+
# Try to initialize it
|
653
|
+
try:
|
654
|
+
await builtin_agent_module.initialize_builtin_agent()
|
655
|
+
except Exception as e:
|
656
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize builtin agent: {str(e)}")
|
657
|
+
|
658
|
+
if builtin_agent_module.local_agent is None:
|
659
|
+
raise HTTPException(status_code=500, detail="Builtin agent not initialized")
|
660
|
+
|
661
|
+
try:
|
662
|
+
await builtin_agent_module.reset_builtin_agent_memory()
|
663
|
+
return {"status": "success", "message": "All agent memory reset successfully"}
|
664
|
+
except Exception as e:
|
665
|
+
raise HTTPException(status_code=500, detail=f"Error resetting agent memory: {str(e)}")
|
666
|
+
else:
|
667
|
+
# For Letta agent, we need to handle memory reset differently
|
668
|
+
if letta_client is None:
|
669
|
+
# Try to initialize letta client
|
670
|
+
try:
|
671
|
+
from ..letta import initialize_letta_client
|
672
|
+
initialize_letta_client()
|
673
|
+
except Exception as e:
|
674
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize Letta client: {str(e)}")
|
675
|
+
|
676
|
+
if letta_client is None:
|
677
|
+
raise HTTPException(status_code=500, detail="Letta client not initialized")
|
678
|
+
|
679
|
+
try:
|
680
|
+
agent_id = config_manager.settings.api_keys.neuro_agent_id
|
681
|
+
if not agent_id:
|
682
|
+
raise HTTPException(status_code=500, detail="Letta agent ID not configured")
|
683
|
+
|
684
|
+
# For Letta, we might need to recreate the agent or reset its state
|
685
|
+
# This is a simplified implementation - you might need to adjust based on Letta's API
|
686
|
+
return {"status": "success", "message": "Letta agent memory reset functionality to be implemented"}
|
687
|
+
except Exception as e:
|
688
|
+
raise HTTPException(status_code=500, detail=f"Error resetting Letta agent memory: {str(e)}")
|
689
|
+
|
690
|
+
# Agent tool APIs
|
691
|
+
@router.get("/tools", dependencies=[Depends(get_api_token)])
|
692
|
+
async def get_available_tools():
|
693
|
+
"""Get list of available tools"""
|
694
|
+
if agent_type == "builtin":
|
695
|
+
# Check if local_agent is initialized
|
696
|
+
if builtin_agent_module.local_agent is None:
|
697
|
+
# Try to initialize it
|
698
|
+
try:
|
699
|
+
await builtin_agent_module.initialize_builtin_agent()
|
700
|
+
except Exception as e:
|
701
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize builtin agent: {str(e)}")
|
702
|
+
|
703
|
+
if builtin_agent_module.local_agent is None:
|
704
|
+
raise HTTPException(status_code=500, detail="Builtin agent not initialized")
|
705
|
+
|
706
|
+
# Get tool descriptions from the tool manager
|
707
|
+
tool_descriptions = builtin_agent_module.local_agent.tool_manager.get_tool_descriptions()
|
708
|
+
return {"tools": tool_descriptions}
|
709
|
+
else:
|
710
|
+
# For Letta agent, tools are managed differently
|
711
|
+
# Returning a generic response for now
|
712
|
+
return {"tools": "Letta agent tools are managed through the Letta platform"}
|
713
|
+
|
714
|
+
@router.post("/tools/execute", dependencies=[Depends(get_api_token)])
|
715
|
+
async def execute_tool(request: ToolExecutionRequest):
|
716
|
+
"""Execute a tool with given parameters"""
|
717
|
+
if agent_type == "builtin":
|
718
|
+
# Check if local_agent is initialized
|
719
|
+
if builtin_agent_module.local_agent is None:
|
720
|
+
# Try to initialize it
|
721
|
+
try:
|
722
|
+
await builtin_agent_module.initialize_builtin_agent()
|
723
|
+
except Exception as e:
|
724
|
+
raise HTTPException(status_code=500, detail=f"Failed to initialize builtin agent: {str(e)}")
|
725
|
+
|
726
|
+
if builtin_agent_module.local_agent is None:
|
727
|
+
raise HTTPException(status_code=500, detail="Builtin agent not initialized")
|
728
|
+
|
729
|
+
try:
|
730
|
+
result = await builtin_agent_module.local_agent.execute_tool(request.tool_name, request.params)
|
731
|
+
return {"result": result}
|
732
|
+
except Exception as e:
|
733
|
+
raise HTTPException(status_code=500, detail=f"Error executing tool: {str(e)}")
|
734
|
+
else:
|
735
|
+
# For Letta agent, tool execution is handled internally
|
736
|
+
raise HTTPException(status_code=400, detail="Tool execution not supported for Letta agent through this API")
|
737
|
+
|