letta-nightly 0.6.34.dev20250303230404__py3-none-any.whl → 0.6.36.dev20250305002337__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 CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "0.6.35"
1
+ __version__ = "0.6.36"
2
2
 
3
3
  # import clients
4
4
  from letta.client.client import LocalClient, RESTClient, create_client
letta/client/client.py CHANGED
@@ -1,4 +1,5 @@
1
1
  import logging
2
+ import sys
2
3
  import time
3
4
  from typing import Callable, Dict, Generator, List, Optional, Union
4
5
 
@@ -40,6 +41,16 @@ from letta.schemas.tool_rule import BaseToolRule
40
41
  from letta.server.rest_api.interface import QueuingInterface
41
42
  from letta.utils import get_human_text, get_persona_text
42
43
 
44
+ # Print deprecation notice in yellow when module is imported
45
+ print(
46
+ "\n\n\033[93m"
47
+ + "DEPRECATION WARNING: This legacy Python client has been deprecated and will be removed in a future release.\n"
48
+ + "Please migrate to the new official python SDK by running: pip install letta-client\n"
49
+ + "For further documentation, visit: https://docs.letta.com/api-reference/overview#python-sdk"
50
+ + "\033[0m\n\n",
51
+ file=sys.stderr,
52
+ )
53
+
43
54
 
44
55
  def create_client(base_url: Optional[str] = None, token: Optional[str] = None):
45
56
  if base_url is None:
letta/constants.py CHANGED
@@ -2,7 +2,7 @@ import os
2
2
  from logging import CRITICAL, DEBUG, ERROR, INFO, NOTSET, WARN, WARNING
3
3
 
4
4
  LETTA_DIR = os.path.join(os.path.expanduser("~"), ".letta")
5
- LETTA_DIR_TOOL_SANDBOX = os.path.join(LETTA_DIR, "tool_sandbox_dir")
5
+ LETTA_TOOL_EXECUTION_DIR = os.path.join(LETTA_DIR, "tool_execution_dir")
6
6
 
7
7
  ADMIN_PREFIX = "/v1/admin"
8
8
  API_PREFIX = "/v1"
@@ -146,6 +146,9 @@ MESSAGE_SUMMARY_WARNING_STR = " ".join(
146
146
  # "Remember to pass request_heartbeat = true if you would like to send a message immediately after.",
147
147
  ]
148
148
  )
149
+ DATA_SOURCE_ATTACH_ALERT = (
150
+ "[ALERT] New data was just uploaded to archival memory. You can view this data by calling the archival_memory_search tool."
151
+ )
149
152
 
150
153
  # The ackknowledgement message used in the summarize sequence
151
154
  MESSAGE_SUMMARY_REQUEST_ACK = "Understood, I will respond with a summary of the message (and only the summary, nothing else) once I receive the conversation history. I'm ready."
letta/log.py CHANGED
@@ -54,7 +54,7 @@ DEVELOPMENT_LOGGING = {
54
54
  "propagate": True, # Let logs bubble up to root
55
55
  },
56
56
  "uvicorn": {
57
- "level": "DEBUG",
57
+ "level": "INFO",
58
58
  "handlers": ["console"],
59
59
  "propagate": True,
60
60
  },
@@ -38,15 +38,15 @@ class LettaBase(BaseModel):
38
38
  description=cls._id_description(prefix),
39
39
  pattern=cls._id_regex_pattern(prefix),
40
40
  examples=[cls._id_example(prefix)],
41
- default_factory=cls._generate_id,
41
+ default_factory=cls.generate_id,
42
42
  )
43
43
 
44
44
  @classmethod
45
- def _generate_id(cls, prefix: Optional[str] = None) -> str:
45
+ def generate_id(cls, prefix: Optional[str] = None) -> str:
46
46
  prefix = prefix or cls.__id_prefix__
47
47
  return f"{prefix}-{uuid.uuid4()}"
48
48
 
49
- # def _generate_id(self) -> str:
49
+ # def generate_id(self) -> str:
50
50
  # return f"{self.__id_prefix__}-{uuid.uuid4()}"
51
51
 
52
52
  @classmethod
@@ -27,7 +27,7 @@ class Provider(ProviderBase):
27
27
 
28
28
  def resolve_identifier(self):
29
29
  if not self.id:
30
- self.id = ProviderBase._generate_id(prefix=ProviderBase.__id_prefix__)
30
+ self.id = ProviderBase.generate_id(prefix=ProviderBase.__id_prefix__)
31
31
 
32
32
  def list_llm_models(self) -> List[LLMConfig]:
33
33
  return []
@@ -6,6 +6,7 @@ from typing import Any, Dict, List, Literal, Optional, Union
6
6
 
7
7
  from pydantic import BaseModel, Field, model_validator
8
8
 
9
+ from letta.constants import LETTA_TOOL_EXECUTION_DIR
9
10
  from letta.schemas.agent import AgentState
10
11
  from letta.schemas.letta_base import LettaBase, OrmMetadataBase
11
12
  from letta.settings import tool_settings
@@ -71,7 +72,7 @@ class LocalSandboxConfig(BaseModel):
71
72
  if tool_settings.local_sandbox_dir:
72
73
  data["sandbox_dir"] = tool_settings.local_sandbox_dir
73
74
  else:
74
- data["sandbox_dir"] = "~/.letta"
75
+ data["sandbox_dir"] = LETTA_TOOL_EXECUTION_DIR
75
76
 
76
77
  return data
77
78
 
@@ -1,9 +1,16 @@
1
- from marshmallow import fields
1
+ from typing import Dict
2
+
3
+ from marshmallow import fields, post_dump
2
4
 
3
5
  from letta.orm import Agent
6
+ from letta.schemas.agent import AgentState as PydanticAgentState
7
+ from letta.schemas.user import User
4
8
  from letta.serialize_schemas.base import BaseSchema
9
+ from letta.serialize_schemas.block import SerializedBlockSchema
5
10
  from letta.serialize_schemas.custom_fields import EmbeddingConfigField, LLMConfigField, ToolRulesField
6
11
  from letta.serialize_schemas.message import SerializedMessageSchema
12
+ from letta.serialize_schemas.tool import SerializedToolSchema
13
+ from letta.server.db import SessionLocal
7
14
 
8
15
 
9
16
  class SerializedAgentSchema(BaseSchema):
@@ -12,25 +19,51 @@ class SerializedAgentSchema(BaseSchema):
12
19
  Excludes relational fields.
13
20
  """
14
21
 
22
+ __pydantic_model__ = PydanticAgentState
23
+
15
24
  llm_config = LLMConfigField()
16
25
  embedding_config = EmbeddingConfigField()
17
26
  tool_rules = ToolRulesField()
18
27
 
19
28
  messages = fields.List(fields.Nested(SerializedMessageSchema))
29
+ core_memory = fields.List(fields.Nested(SerializedBlockSchema))
30
+ tools = fields.List(fields.Nested(SerializedToolSchema))
31
+
32
+ def __init__(self, *args, session: SessionLocal, actor: User, **kwargs):
33
+ super().__init__(*args, actor=actor, **kwargs)
34
+ self.session = session
35
+
36
+ # Propagate session and actor to nested schemas automatically
37
+ for field in self.fields.values():
38
+ if isinstance(field, fields.List) and isinstance(field.inner, fields.Nested):
39
+ field.inner.schema.session = session
40
+ field.inner.schema.actor = actor
41
+ elif isinstance(field, fields.Nested):
42
+ field.schema.session = session
43
+ field.schema.actor = actor
44
+
45
+ @post_dump
46
+ def sanitize_ids(self, data: Dict, **kwargs):
47
+ data = super().sanitize_ids(data, **kwargs)
48
+
49
+ # Remap IDs of messages
50
+ # Need to do this in post, so we can correctly map the in-context message IDs
51
+ # TODO: Remap message_ids to reference objects, not just be a list
52
+ id_remapping = dict()
53
+ for message in data.get("messages"):
54
+ message_id = message.get("id")
55
+ if message_id not in id_remapping:
56
+ id_remapping[message_id] = SerializedMessageSchema.__pydantic_model__.generate_id()
57
+ message["id"] = id_remapping[message_id]
58
+ else:
59
+ raise ValueError(f"Duplicate message IDs in agent.messages: {message_id}")
20
60
 
21
- def __init__(self, *args, session=None, **kwargs):
22
- super().__init__(*args, **kwargs)
23
- if session:
24
- self.session = session
61
+ # Remap in context message ids
62
+ data["message_ids"] = [id_remapping[message_id] for message_id in data.get("message_ids")]
25
63
 
26
- # propagate session to nested schemas
27
- for field_name, field_obj in self.fields.items():
28
- if isinstance(field_obj, fields.List) and hasattr(field_obj.inner, "schema"):
29
- field_obj.inner.schema.session = session
30
- elif hasattr(field_obj, "schema"):
31
- field_obj.schema.session = session
64
+ return data
32
65
 
33
66
  class Meta(BaseSchema.Meta):
34
67
  model = Agent
35
68
  # TODO: Serialize these as well...
36
- exclude = ("tools", "sources", "core_memory", "tags", "source_passages", "agent_passages", "organization")
69
+ exclude = BaseSchema.Meta.exclude + ("sources", "tags", "source_passages", "agent_passages")
@@ -1,4 +1,10 @@
1
+ from typing import Dict, Optional
2
+
3
+ from marshmallow import post_dump, pre_load
1
4
  from marshmallow_sqlalchemy import SQLAlchemyAutoSchema
5
+ from sqlalchemy.inspection import inspect
6
+
7
+ from letta.schemas.user import User
2
8
 
3
9
 
4
10
  class BaseSchema(SQLAlchemyAutoSchema):
@@ -7,6 +13,41 @@ class BaseSchema(SQLAlchemyAutoSchema):
7
13
  This ensures all schemas share the same session.
8
14
  """
9
15
 
16
+ __pydantic_model__ = None
17
+ sensitive_ids = {"_created_by_id", "_last_updated_by_id"}
18
+ sensitive_relationships = {"organization"}
19
+ id_scramble_placeholder = "xxx"
20
+
21
+ def __init__(self, *args, actor: Optional[User] = None, **kwargs):
22
+ super().__init__(*args, **kwargs)
23
+ self.actor = actor
24
+
25
+ @post_dump
26
+ def sanitize_ids(self, data: Dict, **kwargs):
27
+ data["id"] = self.__pydantic_model__.generate_id()
28
+
29
+ for sensitive_id in BaseSchema.sensitive_ids.union(BaseSchema.sensitive_relationships):
30
+ if sensitive_id in data:
31
+ data[sensitive_id] = BaseSchema.id_scramble_placeholder
32
+
33
+ return data
34
+
35
+ @pre_load
36
+ def regenerate_ids(self, data: Dict, **kwargs):
37
+ if self.Meta.model:
38
+ mapper = inspect(self.Meta.model)
39
+ for sensitive_id in BaseSchema.sensitive_ids:
40
+ if sensitive_id in mapper.columns:
41
+ data[sensitive_id] = self.actor.id
42
+
43
+ for relationship in BaseSchema.sensitive_relationships:
44
+ if relationship in mapper.relationships:
45
+ data[relationship] = self.actor.organization_id
46
+
47
+ return data
48
+
10
49
  class Meta:
50
+ model = None
11
51
  include_relationships = True
12
52
  load_instance = True
53
+ exclude = ()
@@ -0,0 +1,15 @@
1
+ from letta.orm.block import Block
2
+ from letta.schemas.block import Block as PydanticBlock
3
+ from letta.serialize_schemas.base import BaseSchema
4
+
5
+
6
+ class SerializedBlockSchema(BaseSchema):
7
+ """
8
+ Marshmallow schema for serializing/deserializing Block objects.
9
+ """
10
+
11
+ __pydantic_model__ = PydanticBlock
12
+
13
+ class Meta(BaseSchema.Meta):
14
+ model = Block
15
+ exclude = BaseSchema.Meta.exclude + ("agents",)
@@ -1,4 +1,9 @@
1
+ from typing import Dict
2
+
3
+ from marshmallow import post_dump
4
+
1
5
  from letta.orm.message import Message
6
+ from letta.schemas.message import Message as PydanticMessage
2
7
  from letta.serialize_schemas.base import BaseSchema
3
8
  from letta.serialize_schemas.custom_fields import ToolCallField
4
9
 
@@ -8,8 +13,17 @@ class SerializedMessageSchema(BaseSchema):
8
13
  Marshmallow schema for serializing/deserializing Message objects.
9
14
  """
10
15
 
16
+ __pydantic_model__ = PydanticMessage
17
+
11
18
  tool_calls = ToolCallField()
12
19
 
20
+ @post_dump
21
+ def sanitize_ids(self, data: Dict, **kwargs):
22
+ # We don't want to remap here
23
+ # Because of the way that message_ids is just a JSON field on agents
24
+ # We need to wait for the agent dumps, and then keep track of all the message IDs we remapped
25
+ return data
26
+
13
27
  class Meta(BaseSchema.Meta):
14
28
  model = Message
15
- exclude = ("step", "job_message")
29
+ exclude = BaseSchema.Meta.exclude + ("step", "job_message", "agent")
@@ -0,0 +1,15 @@
1
+ from letta.orm import Tool
2
+ from letta.schemas.tool import Tool as PydanticTool
3
+ from letta.serialize_schemas.base import BaseSchema
4
+
5
+
6
+ class SerializedToolSchema(BaseSchema):
7
+ """
8
+ Marshmallow schema for serializing/deserializing Tool objects.
9
+ """
10
+
11
+ __pydantic_model__ = PydanticTool
12
+
13
+ class Meta(BaseSchema.Meta):
14
+ model = Tool
15
+ exclude = BaseSchema.Meta.exclude
@@ -42,6 +42,8 @@ def list_identities(
42
42
  )
43
43
  except HTTPException:
44
44
  raise
45
+ except NoResultFound as e:
46
+ raise HTTPException(status_code=404, detail=str(e))
45
47
  except Exception as e:
46
48
  raise HTTPException(status_code=500, detail=f"{e}")
47
49
  return identities
@@ -75,11 +77,11 @@ def create_identity(
75
77
  except UniqueConstraintViolationError:
76
78
  if identity.project_id:
77
79
  raise HTTPException(
78
- status_code=400,
80
+ status_code=409,
79
81
  detail=f"An identity with identifier key {identity.identifier_key} already exists for project {identity.project_id}",
80
82
  )
81
83
  else:
82
- raise HTTPException(status_code=400, detail=f"An identity with identifier key {identity.identifier_key} already exists")
84
+ raise HTTPException(status_code=409, detail=f"An identity with identifier key {identity.identifier_key} already exists")
83
85
  except Exception as e:
84
86
  raise HTTPException(status_code=500, detail=f"{e}")
85
87
 
@@ -96,6 +98,8 @@ def upsert_identity(
96
98
  return server.identity_manager.upsert_identity(identity=identity, actor=actor)
97
99
  except HTTPException:
98
100
  raise
101
+ except NoResultFound as e:
102
+ raise HTTPException(status_code=404, detail=str(e))
99
103
  except Exception as e:
100
104
  raise HTTPException(status_code=500, detail=f"{e}")
101
105
 
@@ -112,6 +116,8 @@ def modify_identity(
112
116
  return server.identity_manager.update_identity(identity_id=identity_id, identity=identity, actor=actor)
113
117
  except HTTPException:
114
118
  raise
119
+ except NoResultFound as e:
120
+ raise HTTPException(status_code=404, detail=str(e))
115
121
  except Exception as e:
116
122
  raise HTTPException(status_code=500, detail=f"{e}")
117
123
 
@@ -125,5 +131,12 @@ def delete_identity(
125
131
  """
126
132
  Delete an identity by its identifier key
127
133
  """
128
- actor = server.user_manager.get_user_or_default(user_id=actor_id)
129
- server.identity_manager.delete_identity(identity_id=identity_id, actor=actor)
134
+ try:
135
+ actor = server.user_manager.get_user_or_default(user_id=actor_id)
136
+ server.identity_manager.delete_identity(identity_id=identity_id, actor=actor)
137
+ except HTTPException:
138
+ raise
139
+ except NoResultFound as e:
140
+ raise HTTPException(status_code=404, detail=str(e))
141
+ except Exception as e:
142
+ raise HTTPException(status_code=500, detail=f"{e}")
letta/server/startup.sh CHANGED
@@ -38,6 +38,15 @@ if ! alembic upgrade head; then
38
38
  fi
39
39
  echo "Database migration completed successfully."
40
40
 
41
+ # Set permissions for tool execution directory if configured
42
+ if [ -n "$LETTA_SANDBOX_MOUNT_PATH" ]; then
43
+ if ! chmod 777 "$LETTA_SANDBOX_MOUNT_PATH"; then
44
+ echo "ERROR: Failed to set permissions for tool execution directory at: $LETTA_SANDBOX_MOUNT_PATH"
45
+ echo "Please check that the directory exists and is accessible"
46
+ exit 1
47
+ fi
48
+ fi
49
+
41
50
  # If ADE is enabled, add the --ade flag to the command
42
51
  CMD="letta server --host $HOST --port $PORT"
43
52
  if [ "${SECURE:-false}" = "true" ]; then
@@ -4,7 +4,7 @@ from typing import Dict, List, Optional
4
4
  import numpy as np
5
5
  from sqlalchemy import Select, and_, func, literal, or_, select, union_all
6
6
 
7
- from letta.constants import BASE_MEMORY_TOOLS, BASE_TOOLS, MAX_EMBEDDING_DIM, MULTI_AGENT_TOOLS
7
+ from letta.constants import BASE_MEMORY_TOOLS, BASE_TOOLS, DATA_SOURCE_ATTACH_ALERT, MAX_EMBEDDING_DIM, MULTI_AGENT_TOOLS
8
8
  from letta.embeddings import embedding_model
9
9
  from letta.helpers.datetime_helpers import get_utc_time
10
10
  from letta.log import get_logger
@@ -35,6 +35,7 @@ from letta.schemas.tool_rule import TerminalToolRule as PydanticTerminalToolRule
35
35
  from letta.schemas.tool_rule import ToolRule as PydanticToolRule
36
36
  from letta.schemas.user import User as PydanticUser
37
37
  from letta.serialize_schemas import SerializedAgentSchema
38
+ from letta.serialize_schemas.tool import SerializedToolSchema
38
39
  from letta.services.block_manager import BlockManager
39
40
  from letta.services.helpers.agent_manager_helper import (
40
41
  _process_relationship,
@@ -394,18 +395,28 @@ class AgentManager:
394
395
  with self.session_maker() as session:
395
396
  # Retrieve the agent
396
397
  agent = AgentModel.read(db_session=session, identifier=agent_id, actor=actor)
397
- schema = SerializedAgentSchema(session=session)
398
+ schema = SerializedAgentSchema(session=session, actor=actor)
398
399
  return schema.dump(agent)
399
400
 
400
401
  @enforce_types
401
- def deserialize(self, serialized_agent: dict, actor: PydanticUser) -> PydanticAgentState:
402
- # TODO: Use actor to override fields
402
+ def deserialize(self, serialized_agent: dict, actor: PydanticUser, mark_as_copy: bool = True) -> PydanticAgentState:
403
+ tool_data_list = serialized_agent.pop("tools", [])
404
+
403
405
  with self.session_maker() as session:
404
- schema = SerializedAgentSchema(session=session)
406
+ schema = SerializedAgentSchema(session=session, actor=actor)
405
407
  agent = schema.load(serialized_agent, session=session)
406
- agent.organization_id = actor.organization_id
407
- agent = agent.create(session, actor=actor)
408
- return agent.to_pydantic()
408
+ if mark_as_copy:
409
+ agent.name += "_copy"
410
+ agent.create(session, actor=actor)
411
+ pydantic_agent = agent.to_pydantic()
412
+
413
+ # Need to do this separately as there's some fancy upsert logic that SqlAlchemy cannot handle
414
+ for tool_data in tool_data_list:
415
+ pydantic_tool = SerializedToolSchema(actor=actor).load(tool_data, transient=True).to_pydantic()
416
+ pydantic_tool = self.tool_manager.create_or_update_tool(pydantic_tool, actor=actor)
417
+ pydantic_agent = self.attach_tool(agent_id=pydantic_agent.id, tool_id=pydantic_tool.id, actor=actor)
418
+
419
+ return pydantic_agent
409
420
 
410
421
  # ======================================================================================================================
411
422
  # Per Agent Environment Variable Management
@@ -670,6 +681,7 @@ class AgentManager:
670
681
  ValueError: If either agent or source doesn't exist
671
682
  IntegrityError: If the source is already attached to the agent
672
683
  """
684
+
673
685
  with self.session_maker() as session:
674
686
  # Verify both agent and source exist and user has permission to access them
675
687
  agent = AgentModel.read(db_session=session, identifier=agent_id, actor=actor)
@@ -687,7 +699,27 @@ class AgentManager:
687
699
 
688
700
  # Commit the changes
689
701
  agent.update(session, actor=actor)
690
- return agent.to_pydantic()
702
+
703
+ # Add system messsage alert to agent
704
+ self.append_system_message(
705
+ agent_id=agent_id,
706
+ content=DATA_SOURCE_ATTACH_ALERT,
707
+ actor=actor,
708
+ )
709
+
710
+ return agent.to_pydantic()
711
+
712
+ @enforce_types
713
+ def append_system_message(self, agent_id: str, content: str, actor: PydanticUser):
714
+
715
+ # get the agent
716
+ agent = self.get_agent_by_id(agent_id=agent_id, actor=actor)
717
+ message = PydanticMessage.dict_to_message(
718
+ agent_id=agent.id, user_id=actor.id, model=agent.llm_config.model, openai_message_dict={"role": "system", "content": content}
719
+ )
720
+
721
+ # update agent in-context message IDs
722
+ self.append_to_in_context_messages(messages=[message], agent_id=agent_id, actor=actor)
691
723
 
692
724
  @enforce_types
693
725
  def list_attached_sources(self, agent_id: str, actor: PydanticUser) -> List[PydanticSource]:
@@ -46,7 +46,7 @@ class MessageManager:
46
46
 
47
47
  # Sort results directly based on message_ids
48
48
  result_dict = {msg.id: msg.to_pydantic() for msg in results}
49
- return [result_dict[msg_id] for msg_id in message_ids]
49
+ return list(filter(lambda x: x is not None, [result_dict.get(msg_id, None) for msg_id in message_ids]))
50
50
 
51
51
  @enforce_types
52
52
  def create_message(self, pydantic_msg: PydanticMessage, actor: PydanticUser) -> PydanticMessage:
@@ -1,6 +1,6 @@
1
1
  from typing import Dict, List, Optional
2
2
 
3
- from letta.constants import LETTA_DIR_TOOL_SANDBOX
3
+ from letta.constants import LETTA_TOOL_EXECUTION_DIR
4
4
  from letta.log import get_logger
5
5
  from letta.orm.errors import NoResultFound
6
6
  from letta.orm.sandbox_config import SandboxConfig as SandboxConfigModel
@@ -35,7 +35,7 @@ class SandboxConfigManager:
35
35
  default_config = {} # Empty
36
36
  else:
37
37
  # TODO: May want to move this to environment variables v.s. persisting in database
38
- default_local_sandbox_path = LETTA_DIR_TOOL_SANDBOX
38
+ default_local_sandbox_path = LETTA_TOOL_EXECUTION_DIR
39
39
  default_config = LocalSandboxConfig(sandbox_dir=default_local_sandbox_path).model_dump(exclude_none=True)
40
40
 
41
41
  sandbox_config = self.create_or_update_sandbox_config(SandboxConfigCreate(config=default_config), actor=actor)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: letta-nightly
3
- Version: 0.6.34.dev20250303230404
3
+ Version: 0.6.36.dev20250305002337
4
4
  Summary: Create LLM agents with long-term memory and custom tools
5
5
  License: Apache License
6
6
  Author: Letta Team
@@ -1,4 +1,4 @@
1
- letta/__init__.py,sha256=4ym40mjr7-1tSGCMdgCrprX97F8XePgils4ZWFvEFxM,918
1
+ letta/__init__.py,sha256=3laFXdFab_elN6Et2nVUFuVgXonpAuR0CntCKlRqyPI,918
2
2
  letta/__main__.py,sha256=6Hs2PV7EYc5Tid4g4OtcLXhqVHiNYTGzSBdoOnW2HXA,29
3
3
  letta/agent.py,sha256=VljWPlG9bh22cF0o0s9lGw0Qi5Ua2O2JLSOiFtH1SfE,62823
4
4
  letta/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -11,11 +11,11 @@ letta/cli/cli.py,sha256=zJz78-qDUz-depb7VQWkg87RBKiETQU4h9DI6ukQBa8,16477
11
11
  letta/cli/cli_config.py,sha256=MNMhIAAjXiAy2gX_gAtqiY0Ya6VNbzXJWjIcRVEZa-k,8597
12
12
  letta/cli/cli_load.py,sha256=xFw-CuzjChcIptaqQ1XpDROENt0JSjyPeiQ0nmEeO1k,2706
13
13
  letta/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
- letta/client/client.py,sha256=7RQjZ-3yn_Hc9QsZoNCFRilyvfTq-Xie2sNbs1Lmbh4,138697
14
+ letta/client/client.py,sha256=G2X1QBXOQORzVwViRNax2EPSYwzdxw_L2RiTFS-SS9Q,139150
15
15
  letta/client/streaming.py,sha256=lN9vamc07sfQlRbFif327GvURLUPhx-4AC_oUOPvs6w,4543
16
16
  letta/client/utils.py,sha256=VCGV-op5ZSmurd4yw7Vhf93XDQ0BkyBT8qsuV7EqfiU,2859
17
17
  letta/config.py,sha256=JFGY4TWW0Wm5fTbZamOwWqk5G8Nn-TXyhgByGoAqy2c,12375
18
- letta/constants.py,sha256=Dl_MEUMMSLorS-hVRnbAMzOUAtC8UbW969c2jGy1iLU,7512
18
+ letta/constants.py,sha256=MvctT-wAIq4CKlYn3XerWAYsqiJj7ydJqqCCuwJLQa0,7675
19
19
  letta/data_sources/connectors.py,sha256=R2AssXpqS7wN6VI8AfxvqaZs5S1ZACc4E_FewmR9iZI,7022
20
20
  letta/data_sources/connectors_helper.py,sha256=2TQjCt74fCgT5sw1AP8PalDEk06jPBbhrPG4HVr-WLs,3371
21
21
  letta/embeddings.py,sha256=zqlfbN3aCgSOlNd9M2NW9zrwx4WwQzketb8oa5BzzE8,10831
@@ -94,7 +94,7 @@ letta/local_llm/webui/api.py,sha256=kkxncdCFq1vjgvaHOoQ__j7rcDPgC1F64KcEm94Y6Rs,
94
94
  letta/local_llm/webui/legacy_api.py,sha256=k3H3y4qp2Fs-XmP24iSIEyvq6wjWFWBzklY3-wRAJNI,2335
95
95
  letta/local_llm/webui/legacy_settings.py,sha256=BLmd3TSx5StnY3ibjwaxYATPt_Lvq-o1rlcc_-Q1JcU,538
96
96
  letta/local_llm/webui/settings.py,sha256=gmLHfiOl1u4JmlAZU2d2O8YKF9lafdakyjwR_ftVPh8,552
97
- letta/log.py,sha256=spiTumfM4Ayk9-pmyKs_jyLvMTyzbQDZay1Vg0ROoZ8,2214
97
+ letta/log.py,sha256=p8tJmoPNBg6CJ5PBWjzad1kkQLBjftHvoBUMYXlyL8k,2213
98
98
  letta/main.py,sha256=_agyaYPJq70OL0goNwO34zENL2KupnTgqlg-HVcNaTY,15379
99
99
  letta/memory.py,sha256=Jqh6Uz4mMAC1aAO2sH8zw4TuMWZr1OI-ZgkSUDh2TQI,3353
100
100
  letta/offline_memory_agent.py,sha256=P_rm6GmKAH6lg7-njuv7dK29f7v5-tAQy-rMOwcPfwk,7499
@@ -167,7 +167,7 @@ letta/schemas/file.py,sha256=ChN2CWzLI2TT9WLItcfElEH0E8b7kzPylF2OQBr6Beg,1550
167
167
  letta/schemas/health.py,sha256=zT6mYovvD17iJRuu2rcaQQzbEEYrkwvAE9TB7iU824c,139
168
168
  letta/schemas/identity.py,sha256=028DseEyCErZ_fifQdFp4ON5QKlDWp-6hrrlekqko_g,2883
169
169
  letta/schemas/job.py,sha256=MX9EiLDDIeHm3q52ImOjp7UzXEdYTXAWWobRCAxwV0w,2225
170
- letta/schemas/letta_base.py,sha256=HTnSHJ2YSyhEdpY-vg9Y7ywqS1zzTjb9j5iVPYsuVSk,3991
170
+ letta/schemas/letta_base.py,sha256=DuMqiNFmYwTAsXUHYdX--EWgtFUVzph5ptLZvu7aguI,3988
171
171
  letta/schemas/letta_message.py,sha256=QHzIEwnEJEkE02biCwyQo5IvL2fVq_whBRQD3vPYO48,9837
172
172
  letta/schemas/letta_request.py,sha256=dzy3kwb5j2QLaSV0sDlwISEMt2xxH3IiK-vR9xJV65k,1123
173
173
  letta/schemas/letta_response.py,sha256=pq-SxXQy5yZo1-DiAwV2mMURlUvz1Uu7HHR_tB1hMho,7139
@@ -182,9 +182,9 @@ letta/schemas/openai/embedding_response.py,sha256=WKIZpXab1Av7v6sxKG8feW3ZtpQUNo
182
182
  letta/schemas/openai/openai.py,sha256=Hilo5BiLAGabzxCwnwfzK5QrWqwYD8epaEKFa4Pwndk,7970
183
183
  letta/schemas/organization.py,sha256=_RR8jlOOdJyG31q53IDdIvBVvIfAZrQWAGuvc5HmW24,788
184
184
  letta/schemas/passage.py,sha256=RG0vkaewEu4a_NAZM-FVyMammHjqpPP0RDYAdu27g6A,3723
185
- letta/schemas/providers.py,sha256=k02mAFMn9F8zW6vjHSIL-OfBlfFharJQM43SrJfdmbs,43666
185
+ letta/schemas/providers.py,sha256=2Ijzjj1gPETiFyl8yb4ZbwaTljw5WSCdGayAgCsBeYE,43665
186
186
  letta/schemas/run.py,sha256=SRqPRziINIiPunjOhE_NlbnQYgxTvqmbauni_yfBQRA,2085
187
- letta/schemas/sandbox_config.py,sha256=Nz8K5brqe6jpf66KnTJ0-E7ZeFdPoBFGN-XOI35OeaY,5926
187
+ letta/schemas/sandbox_config.py,sha256=SZCo3FSMz-DIBMKGu0atT4tsVFXGsqMFPaJnjrxpkX4,5993
188
188
  letta/schemas/source.py,sha256=-BQVolcXA2ziCu2ztR6cbTdGUc8G7vGJy7rvpdf1hpg,2880
189
189
  letta/schemas/step.py,sha256=8rfOW4gbEIB7yp05pqmZn4P3U3XrvXeUd9lPg9yh6x8,2122
190
190
  letta/schemas/tool.py,sha256=3K3csZrk0m9e1lg05tNrO5WCTBiCT9lS-WCVL8jM7mk,11201
@@ -192,10 +192,12 @@ letta/schemas/tool_rule.py,sha256=2YQZba4fXS3u4j8pIk7BDujfq8rnxSVMwJSyaVgApH4,21
192
192
  letta/schemas/usage.py,sha256=8oYRH-JX0PfjIu2zkT5Uu3UWQ7Unnz_uHiO8hRGI4m0,912
193
193
  letta/schemas/user.py,sha256=V32Tgl6oqB3KznkxUz12y7agkQicjzW7VocSpj78i6Q,1526
194
194
  letta/serialize_schemas/__init__.py,sha256=mflGEZvM3NuMG9Q6dccEdVk73BUHoX-v7hmfk025Gmc,64
195
- letta/serialize_schemas/agent.py,sha256=sa59t30C6HegMhsilolMZBW2dblFkAvi8iUAMnY4-H8,1366
196
- letta/serialize_schemas/base.py,sha256=QMSl1HajcopfNd-iw51wUdE6_Cb8IhIyNTQnGibsVDU,293
195
+ letta/serialize_schemas/agent.py,sha256=XQiLmve761rqktUNNjMYNyuxn1xHq0wtJeZVD9UV11c,2817
196
+ letta/serialize_schemas/base.py,sha256=gH3LyWn7EbiDSJ5T6vUhTf6dilTSfM_TJMIsfQ1Wu_E,1682
197
+ letta/serialize_schemas/block.py,sha256=BeZ2FZO59IWUHiPMSNKlZMi9dH9Gbys0rJpsoCFBjdg,420
197
198
  letta/serialize_schemas/custom_fields.py,sha256=HPonsK5DIU9EezXmQG0vAq2CWZVucld6Fqm3-VcJBg8,2101
198
- letta/serialize_schemas/message.py,sha256=VAw39wVxrdQt2-aCylwYzNGJNuLK6inuRGVRkzFy9Ss,419
199
+ letta/serialize_schemas/message.py,sha256=Tdj_ixjjqM2j29gqxLgrdWpTgh5mR3YF5wTbPTnSsHY,920
200
+ letta/serialize_schemas/tool.py,sha256=x13LlwOvbAwnS7Jf5M1nOQCUnDhm4oTFY_mYJu3aJhM,392
199
201
  letta/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
200
202
  letta/server/constants.py,sha256=yAdGbLkzlOU_dLTx0lKDmAnj0ZgRXCEaIcPJWO69eaE,92
201
203
  letta/server/db.py,sha256=cA1MHpMCTTC1MX7VWppJ-cKq1XW93Vws_vTV0-bKmTE,3642
@@ -215,7 +217,7 @@ letta/server/rest_api/routers/v1/__init__.py,sha256=Zi2th-okqT_RWAjB8MYGHX8CpHt1
215
217
  letta/server/rest_api/routers/v1/agents.py,sha256=I5V06th-lpUZ2fX2wtlYLD8SC2W1AkEIHRR4lr098YM,26658
216
218
  letta/server/rest_api/routers/v1/blocks.py,sha256=0j7JX2BQzk31RyhvPZeEb-zh9ImXsVU4_8y5XMiR_WA,3900
217
219
  letta/server/rest_api/routers/v1/health.py,sha256=MoOjkydhGcJXTiuJrKIB0etVXiRMdTa51S8RQ8-50DQ,399
218
- letta/server/rest_api/routers/v1/identities.py,sha256=yqehnyLCRMetPHXu1Hfb9DqqiRLnlryR7_VF6t_HUm4,5449
220
+ letta/server/rest_api/routers/v1/identities.py,sha256=gRTcOXxbpiTzQzzVA_I1Sc9aUSKhW6YcQcJb__HxOX4,5957
219
221
  letta/server/rest_api/routers/v1/jobs.py,sha256=4oeJfI2odNGubU_g7WSORJhn_usFsbRaD-qm86rve1E,2746
220
222
  letta/server/rest_api/routers/v1/llms.py,sha256=lYp5URXtZk1yu_Pe-p1Wq1uQ0qeb6aWtx78rXSB7N_E,881
221
223
  letta/server/rest_api/routers/v1/organizations.py,sha256=8n-kA9LHtKImdY2xL-v7m6nYAbFWqH1vjBCJhQbv7Is,2077
@@ -231,7 +233,7 @@ letta/server/rest_api/routers/v1/voice.py,sha256=0Yk-2c4Ec_viqMLMAn_9kZPAYeUgLQo
231
233
  letta/server/rest_api/static_files.py,sha256=NG8sN4Z5EJ8JVQdj19tkFa9iQ1kBPTab9f_CUxd_u4Q,3143
232
234
  letta/server/rest_api/utils.py,sha256=TlVzgtsg0jmaXzvGubtzOE9WSyvRe6_DFoIBK9EDYt8,13820
233
235
  letta/server/server.py,sha256=LrIVbKJeEhSTbbiUQdg0gGvpXveY6ITJINWZ9gqehEA,58118
234
- letta/server/startup.sh,sha256=qEi6dQHJRzEzDIgnIODj-RYp-O1XstfFpc6cFLkUzVs,1576
236
+ letta/server/startup.sh,sha256=eo7zz4HGu5ryOshfbOSGbXpUDDyoaP7fTq4z8269uaw,1939
235
237
  letta/server/static_files/assets/index-048c9598.js,sha256=mR16XppvselwKCcNgONs4L7kZEVa4OEERm4lNZYtLSk,146819
236
238
  letta/server/static_files/assets/index-0e31b727.css,sha256=SBbja96uiQVLDhDOroHgM6NSl7tS4lpJRCREgSS_hA8,7672
237
239
  letta/server/static_files/favicon.ico,sha256=DezhLdFSbM8o81wCOZcV3riq7tFUOGQD4h6-vr-HuU0,342
@@ -244,18 +246,18 @@ letta/server/ws_api/interface.py,sha256=TWl9vkcMCnLsUtgsuENZ-ku2oMDA-OUTzLh_yNRo
244
246
  letta/server/ws_api/protocol.py,sha256=5mDgpfNZn_kNwHnpt5Dsuw8gdNH298sgxTGed3etzYg,1836
245
247
  letta/server/ws_api/server.py,sha256=cBSzf-V4zT1bL_0i54OTI3cMXhTIIxqjSRF8pYjk7fg,5835
246
248
  letta/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
247
- letta/services/agent_manager.py,sha256=6faeX7u5CCF5qfwUPNNbQfDNUcIMNcNMV0dGTzM-Aj8,55684
249
+ letta/services/agent_manager.py,sha256=VksHRO4kTYbymJhds9im5w2g9kfpIcCjG9X8ON9eWG0,57077
248
250
  letta/services/block_manager.py,sha256=PkbiO59VimLyK6PolWR5O29uHxksCH6pP6K4Vkov3NA,5573
249
251
  letta/services/helpers/agent_manager_helper.py,sha256=uvQsmk2ZCAvG4AuI9r3Cs3IDe3Ra8X-qP3B3RbBVMtg,11179
250
252
  letta/services/helpers/tool_execution_helper.py,sha256=lLoebs1kZKjw62y1PxHbIDkHq_heJN2ZT0gKje-R8oo,6941
251
253
  letta/services/identity_manager.py,sha256=o1XMd5NG2gZ_YWrPOmisfFN0i-2ohoq8n1GM8F49Lf4,7144
252
254
  letta/services/job_manager.py,sha256=ejcv_nMljByimiWJjvj7aqUFQktL1kK-vx_cra2L2cs,16317
253
- letta/services/message_manager.py,sha256=miGZ24h6NC16wHiTP95ooo-M-o2x1rxRnj67p8vQyOY,10702
255
+ letta/services/message_manager.py,sha256=rRd3eMpW_SWbAU_dHAzsX6om9E2yfXno4FwmUEOnZCk,10751
254
256
  letta/services/organization_manager.py,sha256=dhQ3cFPXWNYLfMjdahr2HsOAMJ1JtCEWj1G8Nei5MQc,3388
255
257
  letta/services/passage_manager.py,sha256=mwShFO_xRaTi82fvANb_ngO0TmGaZPA9FPu8KuZ6Gd8,8643
256
258
  letta/services/per_agent_lock_manager.py,sha256=porM0cKKANQ1FvcGXOO_qM7ARk5Fgi1HVEAhXsAg9-4,546
257
259
  letta/services/provider_manager.py,sha256=QOKMSZOM6eAWa2-nANWQc1frKBh8N3gqDq0V87fnSuc,3748
258
- letta/services/sandbox_config_manager.py,sha256=AlZFtESHfEQf3T6WEpn7-B4nZgmnoO_-FxB5FCxSqpY,13357
260
+ letta/services/sandbox_config_manager.py,sha256=ATgZNWNpkdIQDUPy4ABsguHQba2PZf51-c4Ji60MzLE,13361
259
261
  letta/services/source_manager.py,sha256=SE24AiPPhpvZMGDD047H3_ZDD7OM4zHbTW1JXjPEv7U,7672
260
262
  letta/services/step_manager.py,sha256=5wAxv3OzoYwW9aDcg26hC3foQqOl5qA0tno3vg_Ai5U,5107
261
263
  letta/services/summarizer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -270,8 +272,8 @@ letta/streaming_utils.py,sha256=jLqFTVhUL76FeOuYk8TaRQHmPTf3HSRc2EoJwxJNK6U,1194
270
272
  letta/system.py,sha256=dnOrS2FlRMwijQnOvfrky0Lg8wEw-FUq2zzfAJOUSKA,8477
271
273
  letta/tracing.py,sha256=h_-c2lIKHmA7yCLOvgaHijMabmRC__FAl2rZtVKufUM,8017
272
274
  letta/utils.py,sha256=AdHrQ2OQ3V4XhJ1LtYwbLUO71j2IJY37cIUxXPgaaRY,32125
273
- letta_nightly-0.6.34.dev20250303230404.dist-info/LICENSE,sha256=mExtuZ_GYJgDEI38GWdiEYZizZS4KkVt2SF1g_GPNhI,10759
274
- letta_nightly-0.6.34.dev20250303230404.dist-info/METADATA,sha256=K-eqyoyQyayfEK3uVLC_MjRfH40CN7hzrgwdayVxPss,22627
275
- letta_nightly-0.6.34.dev20250303230404.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
276
- letta_nightly-0.6.34.dev20250303230404.dist-info/entry_points.txt,sha256=2zdiyGNEZGV5oYBuS-y2nAAgjDgcC9yM_mHJBFSRt5U,40
277
- letta_nightly-0.6.34.dev20250303230404.dist-info/RECORD,,
275
+ letta_nightly-0.6.36.dev20250305002337.dist-info/LICENSE,sha256=mExtuZ_GYJgDEI38GWdiEYZizZS4KkVt2SF1g_GPNhI,10759
276
+ letta_nightly-0.6.36.dev20250305002337.dist-info/METADATA,sha256=Tz_fOWZtclmqoKIa_WOGDAxKZBbcYl8CPNAmC0G6ZWE,22627
277
+ letta_nightly-0.6.36.dev20250305002337.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
278
+ letta_nightly-0.6.36.dev20250305002337.dist-info/entry_points.txt,sha256=2zdiyGNEZGV5oYBuS-y2nAAgjDgcC9yM_mHJBFSRt5U,40
279
+ letta_nightly-0.6.36.dev20250305002337.dist-info/RECORD,,