letta-nightly 0.6.20.dev20250204104033__py3-none-any.whl → 0.6.21.dev20250205051348__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.
Potentially problematic release.
This version of letta-nightly might be problematic. Click here for more details.
- letta/__init__.py +1 -1
- letta/agent.py +81 -68
- letta/client/client.py +2 -9
- letta/functions/helpers.py +1 -3
- letta/local_llm/utils.py +7 -1
- letta/orm/agent.py +1 -7
- letta/orm/enums.py +1 -0
- letta/schemas/agent.py +6 -0
- letta/schemas/providers.py +1 -1
- letta/schemas/tool.py +1 -1
- letta/server/rest_api/routers/v1/agents.py +16 -4
- letta/server/rest_api/routers/v1/tools.py +2 -2
- letta/server/server.py +3 -3
- letta/server/startup.sh +1 -1
- letta/services/agent_manager.py +22 -1
- letta/services/passage_manager.py +21 -2
- letta/services/step_manager.py +1 -1
- letta/services/tool_manager.py +11 -4
- {letta_nightly-0.6.20.dev20250204104033.dist-info → letta_nightly-0.6.21.dev20250205051348.dist-info}/METADATA +1 -1
- {letta_nightly-0.6.20.dev20250204104033.dist-info → letta_nightly-0.6.21.dev20250205051348.dist-info}/RECORD +23 -23
- {letta_nightly-0.6.20.dev20250204104033.dist-info → letta_nightly-0.6.21.dev20250205051348.dist-info}/LICENSE +0 -0
- {letta_nightly-0.6.20.dev20250204104033.dist-info → letta_nightly-0.6.21.dev20250205051348.dist-info}/WHEEL +0 -0
- {letta_nightly-0.6.20.dev20250204104033.dist-info → letta_nightly-0.6.21.dev20250205051348.dist-info}/entry_points.txt +0 -0
letta/__init__.py
CHANGED
letta/agent.py
CHANGED
|
@@ -38,6 +38,7 @@ from letta.schemas.message import Message
|
|
|
38
38
|
from letta.schemas.openai.chat_completion_response import ChatCompletionResponse
|
|
39
39
|
from letta.schemas.openai.chat_completion_response import Message as ChatCompletionMessage
|
|
40
40
|
from letta.schemas.openai.chat_completion_response import UsageStatistics
|
|
41
|
+
from letta.schemas.sandbox_config import SandboxRunResult
|
|
41
42
|
from letta.schemas.tool import Tool
|
|
42
43
|
from letta.schemas.tool_rule import TerminalToolRule
|
|
43
44
|
from letta.schemas.usage import LettaUsageStatistics
|
|
@@ -198,7 +199,9 @@ class Agent(BaseAgent):
|
|
|
198
199
|
return True
|
|
199
200
|
return False
|
|
200
201
|
|
|
201
|
-
def execute_tool_and_persist_state(
|
|
202
|
+
def execute_tool_and_persist_state(
|
|
203
|
+
self, function_name: str, function_args: dict, target_letta_tool: Tool
|
|
204
|
+
) -> tuple[str, Optional[SandboxRunResult]]:
|
|
202
205
|
"""
|
|
203
206
|
Execute tool modifications and persist the state of the agent.
|
|
204
207
|
Note: only some agent state modifications will be persisted, such as data in the AgentState ORM and block data
|
|
@@ -242,6 +245,7 @@ class Agent(BaseAgent):
|
|
|
242
245
|
assert orig_memory_str == self.agent_state.memory.compile(), "Memory should not be modified in a sandbox tool"
|
|
243
246
|
if updated_agent_state is not None:
|
|
244
247
|
self.update_memory_if_changed(updated_agent_state.memory)
|
|
248
|
+
return function_response, sandbox_run_result
|
|
245
249
|
except Exception as e:
|
|
246
250
|
# Need to catch error here, or else trunction wont happen
|
|
247
251
|
# TODO: modify to function execution error
|
|
@@ -249,7 +253,44 @@ class Agent(BaseAgent):
|
|
|
249
253
|
function_name=function_name, exception_name=type(e).__name__, exception_message=str(e)
|
|
250
254
|
)
|
|
251
255
|
|
|
252
|
-
return function_response
|
|
256
|
+
return function_response, None
|
|
257
|
+
|
|
258
|
+
def _handle_function_error_response(
|
|
259
|
+
self,
|
|
260
|
+
error_msg: str,
|
|
261
|
+
tool_call_id: str,
|
|
262
|
+
function_name: str,
|
|
263
|
+
function_response: str,
|
|
264
|
+
messages: List[Message],
|
|
265
|
+
include_function_failed_message: bool = False,
|
|
266
|
+
) -> List[Message]:
|
|
267
|
+
"""
|
|
268
|
+
Handle error from function call response
|
|
269
|
+
"""
|
|
270
|
+
# Update tool rules
|
|
271
|
+
self.last_function_response = function_response
|
|
272
|
+
self.tool_rules_solver.update_tool_usage(function_name)
|
|
273
|
+
|
|
274
|
+
# Extend conversation with function response
|
|
275
|
+
function_response = package_function_response(False, error_msg)
|
|
276
|
+
new_message = Message.dict_to_message(
|
|
277
|
+
agent_id=self.agent_state.id,
|
|
278
|
+
user_id=self.agent_state.created_by_id,
|
|
279
|
+
model=self.model,
|
|
280
|
+
openai_message_dict={
|
|
281
|
+
"role": "tool",
|
|
282
|
+
"name": function_name,
|
|
283
|
+
"content": function_response,
|
|
284
|
+
"tool_call_id": tool_call_id,
|
|
285
|
+
},
|
|
286
|
+
)
|
|
287
|
+
messages.append(new_message)
|
|
288
|
+
self.interface.function_message(f"Error: {error_msg}", msg_obj=new_message)
|
|
289
|
+
if include_function_failed_message:
|
|
290
|
+
self.interface.function_message(f"Ran {function_name}({function_args})", msg_obj=new_message)
|
|
291
|
+
|
|
292
|
+
# Return updated messages
|
|
293
|
+
return messages
|
|
253
294
|
|
|
254
295
|
def _get_ai_reply(
|
|
255
296
|
self,
|
|
@@ -261,6 +302,7 @@ class Agent(BaseAgent):
|
|
|
261
302
|
backoff_factor: float = 0.5, # delay multiplier for exponential backoff
|
|
262
303
|
max_delay: float = 10.0, # max delay between retries
|
|
263
304
|
step_count: Optional[int] = None,
|
|
305
|
+
last_function_failed: bool = False,
|
|
264
306
|
) -> ChatCompletionResponse:
|
|
265
307
|
"""Get response from LLM API with robust retry mechanism."""
|
|
266
308
|
|
|
@@ -273,6 +315,12 @@ class Agent(BaseAgent):
|
|
|
273
315
|
else [func for func in agent_state_tool_jsons if func["name"] in allowed_tool_names]
|
|
274
316
|
)
|
|
275
317
|
|
|
318
|
+
# Don't allow a tool to be called if it failed last time
|
|
319
|
+
if last_function_failed and self.tool_rules_solver.last_tool_name:
|
|
320
|
+
allowed_functions = [f for f in allowed_functions if f["name"] != self.tool_rules_solver.last_tool_name]
|
|
321
|
+
if not allowed_functions:
|
|
322
|
+
return None
|
|
323
|
+
|
|
276
324
|
# For the first message, force the initial tool if one is specified
|
|
277
325
|
force_tool_call = None
|
|
278
326
|
if (
|
|
@@ -285,6 +333,7 @@ class Agent(BaseAgent):
|
|
|
285
333
|
# Force a tool call if exactly one tool is specified
|
|
286
334
|
elif step_count is not None and step_count > 0 and len(allowed_tool_names) == 1:
|
|
287
335
|
force_tool_call = allowed_tool_names[0]
|
|
336
|
+
|
|
288
337
|
for attempt in range(1, empty_response_retry_limit + 1):
|
|
289
338
|
try:
|
|
290
339
|
response = create(
|
|
@@ -409,21 +458,8 @@ class Agent(BaseAgent):
|
|
|
409
458
|
|
|
410
459
|
if not target_letta_tool:
|
|
411
460
|
error_msg = f"No function named {function_name}"
|
|
412
|
-
function_response =
|
|
413
|
-
messages.
|
|
414
|
-
Message.dict_to_message(
|
|
415
|
-
agent_id=self.agent_state.id,
|
|
416
|
-
user_id=self.agent_state.created_by_id,
|
|
417
|
-
model=self.model,
|
|
418
|
-
openai_message_dict={
|
|
419
|
-
"role": "tool",
|
|
420
|
-
"name": function_name,
|
|
421
|
-
"content": function_response,
|
|
422
|
-
"tool_call_id": tool_call_id,
|
|
423
|
-
},
|
|
424
|
-
)
|
|
425
|
-
) # extend conversation with function response
|
|
426
|
-
self.interface.function_message(f"Error: {error_msg}", msg_obj=messages[-1])
|
|
461
|
+
function_response = "None" # more like "never ran?"
|
|
462
|
+
messages = self._handle_function_error_response(error_msg, tool_call_id, function_name, function_response, messages)
|
|
427
463
|
return messages, False, True # force a heartbeat to allow agent to handle error
|
|
428
464
|
|
|
429
465
|
# Failure case 2: function name is OK, but function args are bad JSON
|
|
@@ -432,21 +468,8 @@ class Agent(BaseAgent):
|
|
|
432
468
|
function_args = parse_json(raw_function_args)
|
|
433
469
|
except Exception:
|
|
434
470
|
error_msg = f"Error parsing JSON for function '{function_name}' arguments: {function_call.arguments}"
|
|
435
|
-
function_response =
|
|
436
|
-
messages.
|
|
437
|
-
Message.dict_to_message(
|
|
438
|
-
agent_id=self.agent_state.id,
|
|
439
|
-
user_id=self.agent_state.created_by_id,
|
|
440
|
-
model=self.model,
|
|
441
|
-
openai_message_dict={
|
|
442
|
-
"role": "tool",
|
|
443
|
-
"name": function_name,
|
|
444
|
-
"content": function_response,
|
|
445
|
-
"tool_call_id": tool_call_id,
|
|
446
|
-
},
|
|
447
|
-
)
|
|
448
|
-
) # extend conversation with function response
|
|
449
|
-
self.interface.function_message(f"Error: {error_msg}", msg_obj=messages[-1])
|
|
471
|
+
function_response = "None" # more like "never ran?"
|
|
472
|
+
messages = self._handle_function_error_response(error_msg, tool_call_id, function_name, function_response, messages)
|
|
450
473
|
return messages, False, True # force a heartbeat to allow agent to handle error
|
|
451
474
|
|
|
452
475
|
# Check if inner thoughts is in the function call arguments (possible apparently if you are using Azure)
|
|
@@ -479,7 +502,12 @@ class Agent(BaseAgent):
|
|
|
479
502
|
self.interface.function_message(f"Running {function_name}({function_args})", msg_obj=messages[-1])
|
|
480
503
|
try:
|
|
481
504
|
# handle tool execution (sandbox) and state updates
|
|
482
|
-
function_response = self.execute_tool_and_persist_state(function_name, function_args, target_letta_tool)
|
|
505
|
+
function_response, sandbox_run_result = self.execute_tool_and_persist_state(function_name, function_args, target_letta_tool)
|
|
506
|
+
|
|
507
|
+
if sandbox_run_result and sandbox_run_result.status == "error":
|
|
508
|
+
error_msg = f"Error calling function {function_name} with args {function_args}: {sandbox_run_result.stderr}"
|
|
509
|
+
messages = self._handle_function_error_response(error_msg, tool_call_id, function_name, function_response, messages)
|
|
510
|
+
return messages, False, True # force a heartbeat to allow agent to handle error
|
|
483
511
|
|
|
484
512
|
# handle trunction
|
|
485
513
|
if function_name in ["conversation_search", "conversation_search_date", "archival_memory_search"]:
|
|
@@ -505,45 +533,17 @@ class Agent(BaseAgent):
|
|
|
505
533
|
error_msg = get_friendly_error_msg(function_name=function_name, exception_name=type(e).__name__, exception_message=str(e))
|
|
506
534
|
error_msg_user = f"{error_msg}\n{traceback.format_exc()}"
|
|
507
535
|
self.logger.error(error_msg_user)
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
messages.append(
|
|
512
|
-
Message.dict_to_message(
|
|
513
|
-
agent_id=self.agent_state.id,
|
|
514
|
-
user_id=self.agent_state.created_by_id,
|
|
515
|
-
model=self.model,
|
|
516
|
-
openai_message_dict={
|
|
517
|
-
"role": "tool",
|
|
518
|
-
"name": function_name,
|
|
519
|
-
"content": function_response,
|
|
520
|
-
"tool_call_id": tool_call_id,
|
|
521
|
-
},
|
|
522
|
-
)
|
|
523
|
-
) # extend conversation with function response
|
|
524
|
-
self.interface.function_message(f"Ran {function_name}({function_args})", msg_obj=messages[-1])
|
|
525
|
-
self.interface.function_message(f"Error: {error_msg}", msg_obj=messages[-1])
|
|
536
|
+
messages = self._handle_function_error_response(
|
|
537
|
+
error_msg, tool_call_id, function_name, function_response, messages, include_function_failed_message=True
|
|
538
|
+
)
|
|
526
539
|
return messages, False, True # force a heartbeat to allow agent to handle error
|
|
527
540
|
|
|
528
541
|
# Step 4: check if function response is an error
|
|
529
542
|
if function_response_string.startswith(ERROR_MESSAGE_PREFIX):
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
agent_id=self.agent_state.id,
|
|
535
|
-
user_id=self.agent_state.created_by_id,
|
|
536
|
-
model=self.model,
|
|
537
|
-
openai_message_dict={
|
|
538
|
-
"role": "tool",
|
|
539
|
-
"name": function_name,
|
|
540
|
-
"content": function_response,
|
|
541
|
-
"tool_call_id": tool_call_id,
|
|
542
|
-
},
|
|
543
|
-
)
|
|
544
|
-
) # extend conversation with function response
|
|
545
|
-
self.interface.function_message(f"Ran {function_name}({function_args})", msg_obj=messages[-1])
|
|
546
|
-
self.interface.function_message(f"Error: {function_response_string}", msg_obj=messages[-1])
|
|
543
|
+
error_msg = function_response_string
|
|
544
|
+
messages = self._handle_function_error_response(
|
|
545
|
+
error_msg, tool_call_id, function_name, function_response, messages, include_function_failed_message=True
|
|
546
|
+
)
|
|
547
547
|
return messages, False, True # force a heartbeat to allow agent to handle error
|
|
548
548
|
|
|
549
549
|
# If no failures happened along the way: ...
|
|
@@ -607,9 +607,11 @@ class Agent(BaseAgent):
|
|
|
607
607
|
counter = 0
|
|
608
608
|
total_usage = UsageStatistics()
|
|
609
609
|
step_count = 0
|
|
610
|
+
function_failed = False
|
|
610
611
|
while True:
|
|
611
612
|
kwargs["first_message"] = False
|
|
612
613
|
kwargs["step_count"] = step_count
|
|
614
|
+
kwargs["last_function_failed"] = function_failed
|
|
613
615
|
step_response = self.inner_step(
|
|
614
616
|
messages=next_input_message,
|
|
615
617
|
**kwargs,
|
|
@@ -689,6 +691,7 @@ class Agent(BaseAgent):
|
|
|
689
691
|
step_count: Optional[int] = None,
|
|
690
692
|
metadata: Optional[dict] = None,
|
|
691
693
|
summarize_attempt_count: int = 0,
|
|
694
|
+
last_function_failed: bool = False,
|
|
692
695
|
) -> AgentStepResponse:
|
|
693
696
|
"""Runs a single step in the agent loop (generates at most one LLM call)"""
|
|
694
697
|
|
|
@@ -723,7 +726,17 @@ class Agent(BaseAgent):
|
|
|
723
726
|
first_message=first_message,
|
|
724
727
|
stream=stream,
|
|
725
728
|
step_count=step_count,
|
|
729
|
+
last_function_failed=last_function_failed,
|
|
726
730
|
)
|
|
731
|
+
if not response:
|
|
732
|
+
# EDGE CASE: Function call failed AND there's no tools left for agent to call -> return early
|
|
733
|
+
return AgentStepResponse(
|
|
734
|
+
messages=input_message_sequence,
|
|
735
|
+
heartbeat_request=False,
|
|
736
|
+
function_failed=False, # NOTE: this is different from other function fails. We force to return early
|
|
737
|
+
in_context_memory_warning=False,
|
|
738
|
+
usage=UsageStatistics(),
|
|
739
|
+
)
|
|
727
740
|
|
|
728
741
|
# Step 3: check if LLM wanted to call a function
|
|
729
742
|
# (if yes) Step 4: call the function
|
letta/client/client.py
CHANGED
|
@@ -2950,18 +2950,11 @@ class LocalClient(AbstractClient):
|
|
|
2950
2950
|
langchain_tool=langchain_tool,
|
|
2951
2951
|
additional_imports_module_attr_map=additional_imports_module_attr_map,
|
|
2952
2952
|
)
|
|
2953
|
-
return self.server.tool_manager.
|
|
2954
|
-
|
|
2955
|
-
def load_crewai_tool(self, crewai_tool: "CrewAIBaseTool", additional_imports_module_attr_map: dict[str, str] = None) -> Tool:
|
|
2956
|
-
tool_create = ToolCreate.from_crewai(
|
|
2957
|
-
crewai_tool=crewai_tool,
|
|
2958
|
-
additional_imports_module_attr_map=additional_imports_module_attr_map,
|
|
2959
|
-
)
|
|
2960
|
-
return self.server.tool_manager.create_or_update_tool(pydantic_tool=Tool(**tool_create.model_dump()), actor=self.user)
|
|
2953
|
+
return self.server.tool_manager.create_or_update_langchain_tool(tool_create=tool_create, actor=self.user)
|
|
2961
2954
|
|
|
2962
2955
|
def load_composio_tool(self, action: "ActionType") -> Tool:
|
|
2963
2956
|
tool_create = ToolCreate.from_composio(action_name=action.name)
|
|
2964
|
-
return self.server.tool_manager.create_or_update_composio_tool(
|
|
2957
|
+
return self.server.tool_manager.create_or_update_composio_tool(tool_create=tool_create, actor=self.user)
|
|
2965
2958
|
|
|
2966
2959
|
def create_tool(
|
|
2967
2960
|
self,
|
letta/functions/helpers.py
CHANGED
|
@@ -230,9 +230,7 @@ def generate_imported_tool_instantiation_call_str(obj: Any) -> Optional[str]:
|
|
|
230
230
|
|
|
231
231
|
|
|
232
232
|
def is_base_model(obj: Any):
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
return isinstance(obj, BaseModel) or isinstance(obj, LangChainBaseModel)
|
|
233
|
+
return isinstance(obj, BaseModel)
|
|
236
234
|
|
|
237
235
|
|
|
238
236
|
def generate_import_code(module_attr_map: Optional[dict]):
|
letta/local_llm/utils.py
CHANGED
|
@@ -11,8 +11,11 @@ import letta.local_llm.llm_chat_completion_wrappers.configurable_wrapper as conf
|
|
|
11
11
|
import letta.local_llm.llm_chat_completion_wrappers.dolphin as dolphin
|
|
12
12
|
import letta.local_llm.llm_chat_completion_wrappers.llama3 as llama3
|
|
13
13
|
import letta.local_llm.llm_chat_completion_wrappers.zephyr as zephyr
|
|
14
|
+
from letta.log import get_logger
|
|
14
15
|
from letta.schemas.openai.chat_completion_request import Tool, ToolCall
|
|
15
16
|
|
|
17
|
+
logger = get_logger(__name__)
|
|
18
|
+
|
|
16
19
|
|
|
17
20
|
def post_json_auth_request(uri, json_payload, auth_type, auth_key):
|
|
18
21
|
"""Send a POST request with a JSON payload and optional authentication"""
|
|
@@ -126,8 +129,11 @@ def num_tokens_from_functions(functions: List[dict], model: str = "gpt-4"):
|
|
|
126
129
|
function_tokens += 2
|
|
127
130
|
if isinstance(v["items"], dict) and "type" in v["items"]:
|
|
128
131
|
function_tokens += len(encoding.encode(v["items"]["type"]))
|
|
132
|
+
elif field == "default":
|
|
133
|
+
function_tokens += 2
|
|
134
|
+
function_tokens += len(encoding.encode(str(v["default"])))
|
|
129
135
|
else:
|
|
130
|
-
|
|
136
|
+
logger.warning(f"num_tokens_from_functions: Unsupported field {field} in function {function}")
|
|
131
137
|
function_tokens += 11
|
|
132
138
|
|
|
133
139
|
num_tokens += function_tokens
|
letta/orm/agent.py
CHANGED
|
@@ -4,7 +4,6 @@ from typing import TYPE_CHECKING, List, Optional
|
|
|
4
4
|
from sqlalchemy import JSON, Index, String
|
|
5
5
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
6
6
|
|
|
7
|
-
from letta.constants import MULTI_AGENT_TOOLS
|
|
8
7
|
from letta.orm.block import Block
|
|
9
8
|
from letta.orm.custom_columns import EmbeddingConfigColumn, LLMConfigColumn, ToolRulesColumn
|
|
10
9
|
from letta.orm.message import Message
|
|
@@ -121,12 +120,7 @@ class Agent(SqlalchemyBase, OrganizationMixin):
|
|
|
121
120
|
# add default rule for having send_message be a terminal tool
|
|
122
121
|
tool_rules = self.tool_rules
|
|
123
122
|
if not tool_rules:
|
|
124
|
-
tool_rules = [
|
|
125
|
-
TerminalToolRule(tool_name="send_message"),
|
|
126
|
-
]
|
|
127
|
-
|
|
128
|
-
for tool_name in MULTI_AGENT_TOOLS:
|
|
129
|
-
tool_rules.append(TerminalToolRule(tool_name=tool_name))
|
|
123
|
+
tool_rules = [TerminalToolRule(tool_name="send_message"), TerminalToolRule(tool_name="send_message_to_agent_async")]
|
|
130
124
|
|
|
131
125
|
state = {
|
|
132
126
|
"id": self.id,
|
letta/orm/enums.py
CHANGED
letta/schemas/agent.py
CHANGED
|
@@ -143,6 +143,9 @@ class CreateAgent(BaseModel, validate_assignment=True): #
|
|
|
143
143
|
None, description="The environment variables for tool execution specific to this agent."
|
|
144
144
|
)
|
|
145
145
|
memory_variables: Optional[Dict[str, str]] = Field(None, description="The variables that should be set for the agent.")
|
|
146
|
+
project_id: Optional[str] = Field(None, description="The id of the project the agent belongs to.")
|
|
147
|
+
template_id: Optional[str] = Field(None, description="The id of the template the agent belongs to.")
|
|
148
|
+
base_template_id: Optional[str] = Field(None, description="The base template id of the agent.")
|
|
146
149
|
|
|
147
150
|
@field_validator("name")
|
|
148
151
|
@classmethod
|
|
@@ -210,6 +213,9 @@ class UpdateAgent(BaseModel):
|
|
|
210
213
|
tool_exec_environment_variables: Optional[Dict[str, str]] = Field(
|
|
211
214
|
None, description="The environment variables for tool execution specific to this agent."
|
|
212
215
|
)
|
|
216
|
+
project_id: Optional[str] = Field(None, description="The id of the project the agent belongs to.")
|
|
217
|
+
template_id: Optional[str] = Field(None, description="The id of the template the agent belongs to.")
|
|
218
|
+
base_template_id: Optional[str] = Field(None, description="The base template id of the agent.")
|
|
213
219
|
|
|
214
220
|
class Config:
|
|
215
221
|
extra = "ignore" # Ignores extra fields
|
letta/schemas/providers.py
CHANGED
|
@@ -279,7 +279,7 @@ class LMStudioOpenAIProvider(OpenAIProvider):
|
|
|
279
279
|
from letta.llm_api.openai import openai_get_model_list
|
|
280
280
|
|
|
281
281
|
# For LMStudio, we want to hit 'GET /api/v0/models' instead of 'GET /v1/models'
|
|
282
|
-
MODEL_ENDPOINT_URL = f"{self.base_url}/api/v0"
|
|
282
|
+
MODEL_ENDPOINT_URL = f"{self.base_url.strip('/v1')}/api/v0"
|
|
283
283
|
response = openai_get_model_list(MODEL_ENDPOINT_URL)
|
|
284
284
|
|
|
285
285
|
"""
|
letta/schemas/tool.py
CHANGED
|
@@ -79,7 +79,7 @@ class Tool(BaseTool):
|
|
|
79
79
|
self.json_schema = get_json_schema_from_module(module_name=LETTA_MULTI_AGENT_TOOL_MODULE_NAME, function_name=self.name)
|
|
80
80
|
elif self.tool_type == ToolType.EXTERNAL_COMPOSIO:
|
|
81
81
|
# If it is a composio tool, we generate both the source code and json schema on the fly here
|
|
82
|
-
# TODO:
|
|
82
|
+
# TODO: Deriving the composio action name is brittle, need to think long term about how to improve this
|
|
83
83
|
try:
|
|
84
84
|
composio_action = generate_composio_action_from_func_name(self.name)
|
|
85
85
|
tool_create = ToolCreate.from_composio(composio_action)
|
|
@@ -47,6 +47,9 @@ def list_agents(
|
|
|
47
47
|
after: Optional[str] = Query(None, description="Cursor for pagination"),
|
|
48
48
|
limit: Optional[int] = Query(None, description="Limit for pagination"),
|
|
49
49
|
query_text: Optional[str] = Query(None, description="Search agents by name"),
|
|
50
|
+
project_id: Optional[str] = Query(None, description="Search agents by project id"),
|
|
51
|
+
template_id: Optional[str] = Query(None, description="Search agents by template id"),
|
|
52
|
+
base_template_id: Optional[str] = Query(None, description="Search agents by base template id"),
|
|
50
53
|
):
|
|
51
54
|
"""
|
|
52
55
|
List all agents associated with a given user.
|
|
@@ -58,16 +61,25 @@ def list_agents(
|
|
|
58
61
|
kwargs = {
|
|
59
62
|
key: value
|
|
60
63
|
for key, value in {
|
|
61
|
-
"tags": tags,
|
|
62
|
-
"match_all_tags": match_all_tags,
|
|
63
64
|
"name": name,
|
|
64
|
-
"
|
|
65
|
+
"project_id": project_id,
|
|
66
|
+
"template_id": template_id,
|
|
67
|
+
"base_template_id": base_template_id,
|
|
65
68
|
}.items()
|
|
66
69
|
if value is not None
|
|
67
70
|
}
|
|
68
71
|
|
|
69
72
|
# Call list_agents with the dynamic kwargs
|
|
70
|
-
agents = server.agent_manager.list_agents(
|
|
73
|
+
agents = server.agent_manager.list_agents(
|
|
74
|
+
actor=actor,
|
|
75
|
+
before=before,
|
|
76
|
+
after=after,
|
|
77
|
+
limit=limit,
|
|
78
|
+
query_text=query_text,
|
|
79
|
+
tags=tags,
|
|
80
|
+
match_all_tags=match_all_tags,
|
|
81
|
+
**kwargs,
|
|
82
|
+
)
|
|
71
83
|
return agents
|
|
72
84
|
|
|
73
85
|
|
|
@@ -66,7 +66,7 @@ def list_tools(
|
|
|
66
66
|
try:
|
|
67
67
|
actor = server.user_manager.get_user_or_default(user_id=user_id)
|
|
68
68
|
if name is not None:
|
|
69
|
-
tool = server.tool_manager.get_tool_by_name(
|
|
69
|
+
tool = server.tool_manager.get_tool_by_name(tool_name=name, actor=actor)
|
|
70
70
|
return [tool] if tool else []
|
|
71
71
|
return server.tool_manager.list_tools(actor=actor, after=after, limit=limit)
|
|
72
72
|
except Exception as e:
|
|
@@ -231,7 +231,7 @@ def add_composio_tool(
|
|
|
231
231
|
|
|
232
232
|
try:
|
|
233
233
|
tool_create = ToolCreate.from_composio(action_name=composio_action_name)
|
|
234
|
-
return server.tool_manager.create_or_update_composio_tool(
|
|
234
|
+
return server.tool_manager.create_or_update_composio_tool(tool_create=tool_create, actor=actor)
|
|
235
235
|
except EnumStringNotFound as e:
|
|
236
236
|
raise HTTPException(
|
|
237
237
|
status_code=400, # Bad Request
|
letta/server/server.py
CHANGED
|
@@ -189,7 +189,7 @@ def db_error_handler():
|
|
|
189
189
|
|
|
190
190
|
|
|
191
191
|
if settings.letta_pg_uri_no_default:
|
|
192
|
-
print("Creating postgres engine"
|
|
192
|
+
print("Creating postgres engine")
|
|
193
193
|
config.recall_storage_type = "postgres"
|
|
194
194
|
config.recall_storage_uri = settings.letta_pg_uri_no_default
|
|
195
195
|
config.archival_storage_type = "postgres"
|
|
@@ -1000,8 +1000,8 @@ class SyncServer(Server):
|
|
|
1000
1000
|
return passage_count, document_count
|
|
1001
1001
|
|
|
1002
1002
|
def list_data_source_passages(self, user_id: str, source_id: str) -> List[Passage]:
|
|
1003
|
-
|
|
1004
|
-
return
|
|
1003
|
+
# TODO: move this query into PassageManager
|
|
1004
|
+
return self.agent_manager.list_passages(actor=self.user_manager.get_user_or_default(user_id=user_id), source_id=source_id)
|
|
1005
1005
|
|
|
1006
1006
|
def list_all_sources(self, actor: User) -> List[Source]:
|
|
1007
1007
|
"""List all sources (w/ extra metadata) belonging to a user"""
|
letta/server/startup.sh
CHANGED
|
@@ -14,7 +14,7 @@ wait_for_postgres() {
|
|
|
14
14
|
|
|
15
15
|
# Check if we're configured for external Postgres
|
|
16
16
|
if [ -n "$LETTA_PG_URI" ]; then
|
|
17
|
-
echo "External Postgres configuration detected, using
|
|
17
|
+
echo "External Postgres configuration detected, using env var LETTA_PG_URI"
|
|
18
18
|
else
|
|
19
19
|
echo "No external Postgres configuration detected, starting internal PostgreSQL..."
|
|
20
20
|
# Start PostgreSQL using the base image's entrypoint script
|
letta/services/agent_manager.py
CHANGED
|
@@ -120,6 +120,9 @@ class AgentManager:
|
|
|
120
120
|
metadata=agent_create.metadata,
|
|
121
121
|
tool_rules=agent_create.tool_rules,
|
|
122
122
|
actor=actor,
|
|
123
|
+
project_id=agent_create.project_id,
|
|
124
|
+
template_id=agent_create.template_id,
|
|
125
|
+
base_template_id=agent_create.base_template_id,
|
|
123
126
|
)
|
|
124
127
|
|
|
125
128
|
# If there are provided environment variables, add them in
|
|
@@ -179,6 +182,9 @@ class AgentManager:
|
|
|
179
182
|
description: Optional[str] = None,
|
|
180
183
|
metadata: Optional[Dict] = None,
|
|
181
184
|
tool_rules: Optional[List[PydanticToolRule]] = None,
|
|
185
|
+
project_id: Optional[str] = None,
|
|
186
|
+
template_id: Optional[str] = None,
|
|
187
|
+
base_template_id: Optional[str] = None,
|
|
182
188
|
) -> PydanticAgentState:
|
|
183
189
|
"""Create a new agent."""
|
|
184
190
|
with self.session_maker() as session:
|
|
@@ -193,6 +199,9 @@ class AgentManager:
|
|
|
193
199
|
"description": description,
|
|
194
200
|
"metadata_": metadata,
|
|
195
201
|
"tool_rules": tool_rules,
|
|
202
|
+
"project_id": project_id,
|
|
203
|
+
"template_id": template_id,
|
|
204
|
+
"base_template_id": base_template_id,
|
|
196
205
|
}
|
|
197
206
|
|
|
198
207
|
# Create the new agent using SqlalchemyBase.create
|
|
@@ -242,7 +251,19 @@ class AgentManager:
|
|
|
242
251
|
agent = AgentModel.read(db_session=session, identifier=agent_id, actor=actor)
|
|
243
252
|
|
|
244
253
|
# Update scalar fields directly
|
|
245
|
-
scalar_fields = {
|
|
254
|
+
scalar_fields = {
|
|
255
|
+
"name",
|
|
256
|
+
"system",
|
|
257
|
+
"llm_config",
|
|
258
|
+
"embedding_config",
|
|
259
|
+
"message_ids",
|
|
260
|
+
"tool_rules",
|
|
261
|
+
"description",
|
|
262
|
+
"metadata",
|
|
263
|
+
"project_id",
|
|
264
|
+
"template_id",
|
|
265
|
+
"base_template_id",
|
|
266
|
+
}
|
|
246
267
|
for field in scalar_fields:
|
|
247
268
|
value = getattr(agent_update, field, None)
|
|
248
269
|
if value is not None:
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
from datetime import datetime
|
|
2
2
|
from typing import List, Optional
|
|
3
3
|
|
|
4
|
+
from openai import OpenAI
|
|
5
|
+
|
|
4
6
|
from letta.embeddings import embedding_model, parse_and_chunk_text
|
|
5
7
|
from letta.orm.errors import NoResultFound
|
|
6
8
|
from letta.orm.passage import AgentPassage, SourcePassage
|
|
@@ -86,14 +88,31 @@ class PassageManager:
|
|
|
86
88
|
"""Insert passage(s) into archival memory"""
|
|
87
89
|
|
|
88
90
|
embedding_chunk_size = agent_state.embedding_config.embedding_chunk_size
|
|
89
|
-
|
|
91
|
+
|
|
92
|
+
# TODO eventually migrate off of llama-index for embeddings?
|
|
93
|
+
# Already causing pain for OpenAI proxy endpoints like LM Studio...
|
|
94
|
+
if agent_state.embedding_config.embedding_endpoint_type != "openai":
|
|
95
|
+
embed_model = embedding_model(agent_state.embedding_config)
|
|
90
96
|
|
|
91
97
|
passages = []
|
|
92
98
|
|
|
93
99
|
try:
|
|
94
100
|
# breakup string into passages
|
|
95
101
|
for text in parse_and_chunk_text(text, embedding_chunk_size):
|
|
96
|
-
|
|
102
|
+
|
|
103
|
+
if agent_state.embedding_config.embedding_endpoint_type != "openai":
|
|
104
|
+
embedding = embed_model.get_text_embedding(text)
|
|
105
|
+
else:
|
|
106
|
+
# TODO should have the settings passed in via the server call
|
|
107
|
+
from letta.settings import model_settings
|
|
108
|
+
|
|
109
|
+
# Simple OpenAI client code
|
|
110
|
+
client = OpenAI(
|
|
111
|
+
api_key=model_settings.openai_api_key, base_url=agent_state.embedding_config.embedding_endpoint, max_retries=0
|
|
112
|
+
)
|
|
113
|
+
response = client.embeddings.create(input=text, model=agent_state.embedding_config.embedding_model)
|
|
114
|
+
embedding = response.data[0].embedding
|
|
115
|
+
|
|
97
116
|
if isinstance(embedding, dict):
|
|
98
117
|
try:
|
|
99
118
|
embedding = embedding["data"][0]["embedding"]
|
letta/services/step_manager.py
CHANGED
letta/services/tool_manager.py
CHANGED
|
@@ -11,7 +11,7 @@ from letta.orm.enums import ToolType
|
|
|
11
11
|
from letta.orm.errors import NoResultFound
|
|
12
12
|
from letta.orm.tool import Tool as ToolModel
|
|
13
13
|
from letta.schemas.tool import Tool as PydanticTool
|
|
14
|
-
from letta.schemas.tool import ToolUpdate
|
|
14
|
+
from letta.schemas.tool import ToolCreate, ToolUpdate
|
|
15
15
|
from letta.schemas.user import User as PydanticUser
|
|
16
16
|
from letta.utils import enforce_types, printd
|
|
17
17
|
|
|
@@ -57,9 +57,16 @@ class ToolManager:
|
|
|
57
57
|
return tool
|
|
58
58
|
|
|
59
59
|
@enforce_types
|
|
60
|
-
def create_or_update_composio_tool(self,
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
def create_or_update_composio_tool(self, tool_create: ToolCreate, actor: PydanticUser) -> PydanticTool:
|
|
61
|
+
return self.create_or_update_tool(
|
|
62
|
+
PydanticTool(tool_type=ToolType.EXTERNAL_COMPOSIO, name=tool_create.json_schema["name"], **tool_create.model_dump()), actor
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
@enforce_types
|
|
66
|
+
def create_or_update_langchain_tool(self, tool_create: ToolCreate, actor: PydanticUser) -> PydanticTool:
|
|
67
|
+
return self.create_or_update_tool(
|
|
68
|
+
PydanticTool(tool_type=ToolType.EXTERNAL_LANGCHAIN, name=tool_create.json_schema["name"], **tool_create.model_dump()), actor
|
|
69
|
+
)
|
|
63
70
|
|
|
64
71
|
@enforce_types
|
|
65
72
|
def create_tool(self, pydantic_tool: PydanticTool, actor: PydanticUser) -> PydanticTool:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
letta/__init__.py,sha256=
|
|
1
|
+
letta/__init__.py,sha256=bjhntPdDAWCs4iINZfoEzpfEiEU32NSYtCmSvdcL3gk,919
|
|
2
2
|
letta/__main__.py,sha256=6Hs2PV7EYc5Tid4g4OtcLXhqVHiNYTGzSBdoOnW2HXA,29
|
|
3
|
-
letta/agent.py,sha256=
|
|
3
|
+
letta/agent.py,sha256=Ds5-t_Ge1ZJf8wbQ2LbpK9LHEs6XNu0xLow3iXoZpd8,56980
|
|
4
4
|
letta/benchmark/benchmark.py,sha256=ebvnwfp3yezaXOQyGXkYCDYpsmre-b9hvNtnyx4xkG0,3701
|
|
5
5
|
letta/benchmark/constants.py,sha256=aXc5gdpMGJT327VuxsT5FngbCK2J41PQYeICBO7g_RE,536
|
|
6
6
|
letta/chat_only_agent.py,sha256=71Lf-df8y3nsE9IFKpEigaZaWHoWnXnhVChkp1L-83I,4760
|
|
@@ -8,7 +8,7 @@ letta/cli/cli.py,sha256=_uGKM-RvGLGf7y8iWjkLgLTxIw7uWrdCdL5ETUOCkUs,16472
|
|
|
8
8
|
letta/cli/cli_config.py,sha256=2oo4vui1GXQarAD6Ru4SRzPvcW4eX2mCXOBusfYGvJw,8533
|
|
9
9
|
letta/cli/cli_load.py,sha256=xFw-CuzjChcIptaqQ1XpDROENt0JSjyPeiQ0nmEeO1k,2706
|
|
10
10
|
letta/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
-
letta/client/client.py,sha256
|
|
11
|
+
letta/client/client.py,sha256=Vzjq3a5dx9W5R96FvKkohHf2Yf0NV4XG0VWTH2h0624,138315
|
|
12
12
|
letta/client/streaming.py,sha256=DzE86XJTg_0j9eC45Hrpy9vPt-Wfo1F-sIv_B7iNV6I,5509
|
|
13
13
|
letta/client/utils.py,sha256=VCGV-op5ZSmurd4yw7Vhf93XDQ0BkyBT8qsuV7EqfiU,2859
|
|
14
14
|
letta/config.py,sha256=JFGY4TWW0Wm5fTbZamOwWqk5G8Nn-TXyhgByGoAqy2c,12375
|
|
@@ -23,7 +23,7 @@ letta/functions/function_sets/base.py,sha256=bOiitkhzqYKwZBiRYrx29AlordiA5IrXw25
|
|
|
23
23
|
letta/functions/function_sets/extras.py,sha256=Z9yEdBpQFtTjpxkgbtkWMA8GtDWC6ai2bdsRpnv0H_w,4837
|
|
24
24
|
letta/functions/function_sets/multi_agent.py,sha256=2tu7A_eMwkfXldZWpfwwnq0OXPFTjROo-NjXvuhxOhc,5357
|
|
25
25
|
letta/functions/functions.py,sha256=NyWLh7a-f4mXti5vM1oWDwXzfA58VmVVqL03O9vosKY,5672
|
|
26
|
-
letta/functions/helpers.py,sha256=
|
|
26
|
+
letta/functions/helpers.py,sha256=5f4ua21fffqU-M24ha2xNGrqIhqLWh0-sTNFOHbu18Q,19700
|
|
27
27
|
letta/functions/schema_generator.py,sha256=qosgp3p27QRTqOCPLrSkCGVdyQsyTTZunXQ_g-YaTkw,20138
|
|
28
28
|
letta/helpers/__init__.py,sha256=p0luQ1Oe3Skc6sH4O58aHHA3Qbkyjifpuq0DZ1GAY0U,59
|
|
29
29
|
letta/helpers/tool_rule_solver.py,sha256=VnJfqb5L1Lcipc_tBVGj0om60GKQkMkNLgg6X9VZl2c,6210
|
|
@@ -73,7 +73,7 @@ letta/local_llm/settings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
|
|
|
73
73
|
letta/local_llm/settings/deterministic_mirostat.py,sha256=kgRikcxYHfIbPFydHW6W7IO9jmp6NeA7JNAhnI3DPsc,1221
|
|
74
74
|
letta/local_llm/settings/settings.py,sha256=QBuuOLl3OFxN6koBGxFuXSllf4EryQuJCHB5_0IttFU,2962
|
|
75
75
|
letta/local_llm/settings/simple.py,sha256=HAO2jBJ_hJCEsXWIJcD0sckR0tI0zs3x2CPdf6ORQLs,719
|
|
76
|
-
letta/local_llm/utils.py,sha256=
|
|
76
|
+
letta/local_llm/utils.py,sha256=jvJIhAH0qOXpV5dCqA2jI_3GxcaV6VT-chP7OxihEOU,13735
|
|
77
77
|
letta/local_llm/vllm/api.py,sha256=2kAGZjc_GH9ILJnVRq-45yfsfKELVfbC9VEl_cIC6vg,2590
|
|
78
78
|
letta/local_llm/webui/api.py,sha256=kkxncdCFq1vjgvaHOoQ__j7rcDPgC1F64KcEm94Y6Rs,2639
|
|
79
79
|
letta/local_llm/webui/legacy_api.py,sha256=k3H3y4qp2Fs-XmP24iSIEyvq6wjWFWBzklY3-wRAJNI,2335
|
|
@@ -87,13 +87,13 @@ letta/openai_backcompat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
|
|
|
87
87
|
letta/openai_backcompat/openai_object.py,sha256=Y1ZS1sATP60qxJiOsjOP3NbwSzuzvkNAvb3DeuhM5Uk,13490
|
|
88
88
|
letta/orm/__all__.py,sha256=2gh2MZTkA3Hw67VWVKK3JIStJOqTeLdpCvYSVYNeEDA,692
|
|
89
89
|
letta/orm/__init__.py,sha256=wPokP-EvOri2LhKLjmYVtI_FWchaxgFvJeF_NAfqJIo,842
|
|
90
|
-
letta/orm/agent.py,sha256=
|
|
90
|
+
letta/orm/agent.py,sha256=sFUzzFf8SPJetHP50DuiRss7YmMFh_gEqcFr6tTmBKg,7245
|
|
91
91
|
letta/orm/agents_tags.py,sha256=dYSnHz4IWBjyOiQ4RJomX3P0QN76JTlEZEw5eJM6Emg,925
|
|
92
92
|
letta/orm/base.py,sha256=VjvxF9TwKF9Trf8BJkDgf7D6KrWWopOkUiF18J3IElk,3071
|
|
93
93
|
letta/orm/block.py,sha256=EjH8lXexHtFIHJ8G-RjNo2oAH834x0Hbn4CER9S4U74,3880
|
|
94
94
|
letta/orm/blocks_agents.py,sha256=W0dykl9OchAofSuAYZD5zNmhyMabPr9LTJrz-I3A0m4,983
|
|
95
95
|
letta/orm/custom_columns.py,sha256=APR3ylle9hUutQoy8m-toTV53F1mpcQhEcnf32XTmQA,5447
|
|
96
|
-
letta/orm/enums.py,sha256=
|
|
96
|
+
letta/orm/enums.py,sha256=g4qbX_6a1NQpCt3rScAySbwSbkwqGmnOEaNbkMmCWF4,474
|
|
97
97
|
letta/orm/errors.py,sha256=Se0Guz-gqi-D36NUWSh7AP9zTVCSph9KgZh_trwng4o,734
|
|
98
98
|
letta/orm/file.py,sha256=7_p7LxityP3NQZVURQYG0kgcZhEkVuMN0Fj4h9YOe1w,1780
|
|
99
99
|
letta/orm/job.py,sha256=G2P-xUpTapD4lhU2FwMZET1b5QR4ju9WOB3uiTKD_mw,2157
|
|
@@ -139,7 +139,7 @@ letta/prompts/system/memgpt_modified_o1.txt,sha256=objnDgnxpF3-MmU28ZqZ7-TOG8UlH
|
|
|
139
139
|
letta/prompts/system/memgpt_offline_memory.txt,sha256=rWEJeF-6aiinjkJM9hgLUYCmlEcC_HekYB1bjEUYq6M,2460
|
|
140
140
|
letta/prompts/system/memgpt_offline_memory_chat.txt,sha256=ituh7gDuio7nC2UKFB7GpBq6crxb8bYedQfJ0ADoPgg,3949
|
|
141
141
|
letta/pytest.ini,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
142
|
-
letta/schemas/agent.py,sha256=
|
|
142
|
+
letta/schemas/agent.py,sha256=9Utvls2nMlwixoWaBn6gf5VlgQTnTZxhexK1j2CuSD0,12707
|
|
143
143
|
letta/schemas/block.py,sha256=FYYmRWjH4d4QHMUx_nmIXjv_qJna_l-Ip_4i51wDBPA,5942
|
|
144
144
|
letta/schemas/embedding_config.py,sha256=RkLbUorFkMWr1tPkn6c2aHrnICjWTbhPY86tIncwXyA,3373
|
|
145
145
|
letta/schemas/embedding_config_overrides.py,sha256=lkTa4y-EQ2RnaEKtKDM0sEAk7EwNa67REw8DGNNtGQY,84
|
|
@@ -163,12 +163,12 @@ letta/schemas/openai/embedding_response.py,sha256=WKIZpXab1Av7v6sxKG8feW3ZtpQUNo
|
|
|
163
163
|
letta/schemas/openai/openai.py,sha256=Hilo5BiLAGabzxCwnwfzK5QrWqwYD8epaEKFa4Pwndk,7970
|
|
164
164
|
letta/schemas/organization.py,sha256=WWbUWVSp_VQRFwWN4fdHg1yObiV6x9rZnvIY8x5BPs0,746
|
|
165
165
|
letta/schemas/passage.py,sha256=pdCLZgOn0gWK1gB6aFHLS0gfdWCBqLaiHDA0iQ12Zd8,3704
|
|
166
|
-
letta/schemas/providers.py,sha256=
|
|
166
|
+
letta/schemas/providers.py,sha256=1Sc7gWI6n9RkR4kOY4g3xGLVo6VCSwpiJySp3Pm3MQw,34903
|
|
167
167
|
letta/schemas/run.py,sha256=SRqPRziINIiPunjOhE_NlbnQYgxTvqmbauni_yfBQRA,2085
|
|
168
168
|
letta/schemas/sandbox_config.py,sha256=Nz8K5brqe6jpf66KnTJ0-E7ZeFdPoBFGN-XOI35OeaY,5926
|
|
169
169
|
letta/schemas/source.py,sha256=-BQVolcXA2ziCu2ztR6cbTdGUc8G7vGJy7rvpdf1hpg,2880
|
|
170
170
|
letta/schemas/step.py,sha256=cCmDChQMndy7aMJGH0Z19VbzJkAeFTYuA0cJpzjW2g0,1928
|
|
171
|
-
letta/schemas/tool.py,sha256=
|
|
171
|
+
letta/schemas/tool.py,sha256=dDyzvLZ_gw9DdcFplGTHoH9aFQnF2ez-ApYLRtxAfys,11051
|
|
172
172
|
letta/schemas/tool_rule.py,sha256=tS7ily6NJD8E4n7Hla38jMUe6OIdhdc1ckq0AiRpu5Y,1893
|
|
173
173
|
letta/schemas/usage.py,sha256=8oYRH-JX0PfjIu2zkT5Uu3UWQ7Unnz_uHiO8hRGI4m0,912
|
|
174
174
|
letta/schemas/user.py,sha256=V32Tgl6oqB3KznkxUz12y7agkQicjzW7VocSpj78i6Q,1526
|
|
@@ -187,7 +187,7 @@ letta/server/rest_api/routers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5N
|
|
|
187
187
|
letta/server/rest_api/routers/openai/chat_completions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
188
188
|
letta/server/rest_api/routers/openai/chat_completions/chat_completions.py,sha256=TjeiyEMkpWR3PBazUWs4W2XVwGVEW5NRTOFXWag62oU,6657
|
|
189
189
|
letta/server/rest_api/routers/v1/__init__.py,sha256=tzD8Oh6ynPkg8ULcITWcwalLL81SIh6eztPqV9l7VGk,1162
|
|
190
|
-
letta/server/rest_api/routers/v1/agents.py,sha256
|
|
190
|
+
letta/server/rest_api/routers/v1/agents.py,sha256=AkoJWxn-cJEURGXBarJtasTJsldPe6vv9TFOiGpJRlY,25473
|
|
191
191
|
letta/server/rest_api/routers/v1/blocks.py,sha256=oJYOpGUTd4AhKwVolVlZPIXO2EoOrBHkyi2PdrmbtmA,3888
|
|
192
192
|
letta/server/rest_api/routers/v1/health.py,sha256=pKCuVESlVOhGIb4VC4K-H82eZqfghmT6kvj2iOkkKuc,401
|
|
193
193
|
letta/server/rest_api/routers/v1/jobs.py,sha256=pKihW12hQdFwt6tHQXs94yOMv6xotlhBB3Vl7Q5ASKQ,2738
|
|
@@ -199,12 +199,12 @@ letta/server/rest_api/routers/v1/sandbox_configs.py,sha256=_6WcwgKrgRfnTEC_EgoN-
|
|
|
199
199
|
letta/server/rest_api/routers/v1/sources.py,sha256=g7NKgbZkS7y1vlukJHZ_yoWrk3AxyoWKTVGszp0Ky18,8414
|
|
200
200
|
letta/server/rest_api/routers/v1/steps.py,sha256=SuZmneaeSSAHjOMatMt_QILLzkNpkbwuVgKiMYr52cE,3038
|
|
201
201
|
letta/server/rest_api/routers/v1/tags.py,sha256=45G0cmcP-ER0OO5OanT_fGtGQfl9ZjRKU97mFwtwyfo,878
|
|
202
|
-
letta/server/rest_api/routers/v1/tools.py,sha256=
|
|
202
|
+
letta/server/rest_api/routers/v1/tools.py,sha256=Ft1wnS7RJT3TOfwSGMJ0_gfTpXnVArZUtPCXT3osI-0,12615
|
|
203
203
|
letta/server/rest_api/routers/v1/users.py,sha256=G5DBHSkPfBgVHN2Wkm-rVYiLQAudwQczIq2Z3YLdbVo,2277
|
|
204
204
|
letta/server/rest_api/static_files.py,sha256=NG8sN4Z5EJ8JVQdj19tkFa9iQ1kBPTab9f_CUxd_u4Q,3143
|
|
205
205
|
letta/server/rest_api/utils.py,sha256=dsjkZzgo9Rk3fjUf1ajjiiql1eeO5DAzmXprttI7bJU,3993
|
|
206
|
-
letta/server/server.py,sha256=
|
|
207
|
-
letta/server/startup.sh,sha256=
|
|
206
|
+
letta/server/server.py,sha256=8tRXPLta26ARQSThMDnKDAxTGx39j8Zw-41kgEgSpoQ,59850
|
|
207
|
+
letta/server/startup.sh,sha256=qEi6dQHJRzEzDIgnIODj-RYp-O1XstfFpc6cFLkUzVs,1576
|
|
208
208
|
letta/server/static_files/assets/index-048c9598.js,sha256=mR16XppvselwKCcNgONs4L7kZEVa4OEERm4lNZYtLSk,146819
|
|
209
209
|
letta/server/static_files/assets/index-0e31b727.css,sha256=SBbja96uiQVLDhDOroHgM6NSl7tS4lpJRCREgSS_hA8,7672
|
|
210
210
|
letta/server/static_files/favicon.ico,sha256=DezhLdFSbM8o81wCOZcV3riq7tFUOGQD4h6-vr-HuU0,342
|
|
@@ -217,29 +217,29 @@ letta/server/ws_api/interface.py,sha256=TWl9vkcMCnLsUtgsuENZ-ku2oMDA-OUTzLh_yNRo
|
|
|
217
217
|
letta/server/ws_api/protocol.py,sha256=M_-gM5iuDBwa1cuN2IGNCG5GxMJwU2d3XW93XALv9s8,1821
|
|
218
218
|
letta/server/ws_api/server.py,sha256=cBSzf-V4zT1bL_0i54OTI3cMXhTIIxqjSRF8pYjk7fg,5835
|
|
219
219
|
letta/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
220
|
-
letta/services/agent_manager.py,sha256=
|
|
220
|
+
letta/services/agent_manager.py,sha256=FLb6Y3_aZSNGTIfUrKJbRTXTMHJBlf8OGH-Ahf0moY0,50958
|
|
221
221
|
letta/services/block_manager.py,sha256=u56TXG46QDMbQZadDGCO7fY1vreJ69Xr_0MUF53xw4k,5519
|
|
222
222
|
letta/services/helpers/agent_manager_helper.py,sha256=RH0MXLZASkP2LVbVNUfSYHrcBYZnVxFd9ejGjRK90Hw,11283
|
|
223
223
|
letta/services/helpers/tool_execution_helper.py,sha256=q8uSiQcX6VH_iNg5VNloZgC2JkH9lIOXBKCXYPx2Yac,6097
|
|
224
224
|
letta/services/job_manager.py,sha256=7awEHraoEmqlDQvcQTEkb_dcZsG9eIYGWYct8exzm2E,13117
|
|
225
225
|
letta/services/message_manager.py,sha256=w6-B9Zz5z9UXcd6mKhinsaCINTsmxDsH9JJsV2_qlH4,8878
|
|
226
226
|
letta/services/organization_manager.py,sha256=h3hrknBhA3YQt90OeBzFnqjYM9NWKnk8jDKzXGm4AUg,3392
|
|
227
|
-
letta/services/passage_manager.py,sha256=
|
|
227
|
+
letta/services/passage_manager.py,sha256=oyTFguEa5Z1JgciKHSmQkgC3kV4Q4fV-4NgUQxfxafU,8647
|
|
228
228
|
letta/services/per_agent_lock_manager.py,sha256=porM0cKKANQ1FvcGXOO_qM7ARk5Fgi1HVEAhXsAg9-4,546
|
|
229
229
|
letta/services/provider_manager.py,sha256=jEal0A0XWobWH5CVfmzPtcFhsflI-sanqyg26FqpDKk,3575
|
|
230
230
|
letta/services/sandbox_config_manager.py,sha256=eWDNTscRG9Gt_Ixho3-daOOno_9KcebxeA9v_CbzYu0,13371
|
|
231
231
|
letta/services/source_manager.py,sha256=0JLKIv405oS5wc6bY5k2bxxZpS9O-VwUGHVdGPbJ3e4,7676
|
|
232
|
-
letta/services/step_manager.py,sha256=
|
|
232
|
+
letta/services/step_manager.py,sha256=dvGFeobB7TjXBENG6pGrEr6tEil3Am7GyTzv2IjQifA,4885
|
|
233
233
|
letta/services/tool_execution_sandbox.py,sha256=4XBYkCEBLG6GqijxgqeLIQQJ9zRbsJa8vZ4dZG04Pq8,22080
|
|
234
|
-
letta/services/tool_manager.py,sha256=
|
|
234
|
+
letta/services/tool_manager.py,sha256=9Y15q0GqnADk-tnUeWDFFsDOt_ZjwsPU2oteDVtHAF4,9572
|
|
235
235
|
letta/services/user_manager.py,sha256=1U8BQ_-MBkEW2wnSFV_OsTwBmRAZLN8uHLFjnDjK3hA,4308
|
|
236
236
|
letta/settings.py,sha256=r9KUE1YU2VfLPsdjTRvv5OfyEhV6CqXwqkeeT6NMznI,6090
|
|
237
237
|
letta/streaming_interface.py,sha256=lo2VAQRUJOdWTijwnXuKOC9uejqr2siUAEmZiQUXkj8,15710
|
|
238
238
|
letta/streaming_utils.py,sha256=jLqFTVhUL76FeOuYk8TaRQHmPTf3HSRc2EoJwxJNK6U,11946
|
|
239
239
|
letta/system.py,sha256=S_0cod77iEttkFd1bSh2wenLCKA8YL487AuVenIDUng,8425
|
|
240
240
|
letta/utils.py,sha256=lgBDWKmrQrmJGPxcgamFC2aJyi6I0dX7bzLBt3YC6j0,34051
|
|
241
|
-
letta_nightly-0.6.
|
|
242
|
-
letta_nightly-0.6.
|
|
243
|
-
letta_nightly-0.6.
|
|
244
|
-
letta_nightly-0.6.
|
|
245
|
-
letta_nightly-0.6.
|
|
241
|
+
letta_nightly-0.6.21.dev20250205051348.dist-info/LICENSE,sha256=mExtuZ_GYJgDEI38GWdiEYZizZS4KkVt2SF1g_GPNhI,10759
|
|
242
|
+
letta_nightly-0.6.21.dev20250205051348.dist-info/METADATA,sha256=frAZ25QAcs_U__UpdBap5HwnrO-07Bp7zjmEiYL-HHM,22156
|
|
243
|
+
letta_nightly-0.6.21.dev20250205051348.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
|
244
|
+
letta_nightly-0.6.21.dev20250205051348.dist-info/entry_points.txt,sha256=2zdiyGNEZGV5oYBuS-y2nAAgjDgcC9yM_mHJBFSRt5U,40
|
|
245
|
+
letta_nightly-0.6.21.dev20250205051348.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|