letta-nightly 0.6.2.dev20241210030340__py3-none-any.whl → 0.6.2.dev20241210104242__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/client/client.py CHANGED
@@ -3128,7 +3128,7 @@ class LocalClient(AbstractClient):
3128
3128
  return self.server.get_agent_recall_cursor(
3129
3129
  user_id=self.user_id,
3130
3130
  agent_id=agent_id,
3131
- cursor=cursor,
3131
+ before=cursor,
3132
3132
  limit=limit,
3133
3133
  reverse=True,
3134
3134
  )
@@ -2,7 +2,7 @@ from datetime import datetime
2
2
  from enum import Enum
3
3
  from typing import TYPE_CHECKING, List, Literal, Optional, Type
4
4
 
5
- from sqlalchemy import String, func, select
5
+ from sqlalchemy import String, desc, func, or_, select
6
6
  from sqlalchemy.exc import DBAPIError
7
7
  from sqlalchemy.orm import Mapped, Session, mapped_column
8
8
 
@@ -60,14 +60,25 @@ class SqlalchemyBase(CommonSqlalchemyMetaMixins, Base):
60
60
  end_date: Optional[datetime] = None,
61
61
  limit: Optional[int] = 50,
62
62
  query_text: Optional[str] = None,
63
+ ascending: bool = True,
63
64
  **kwargs,
64
65
  ) -> List[Type["SqlalchemyBase"]]:
65
- """List records with advanced filtering and pagination options."""
66
+ """
67
+ List records with cursor-based pagination, ordering by created_at.
68
+ Cursor is an ID, but pagination is based on the cursor object's created_at value.
69
+ """
66
70
  if start_date and end_date and start_date > end_date:
67
71
  raise ValueError("start_date must be earlier than or equal to end_date")
68
72
 
69
73
  logger.debug(f"Listing {cls.__name__} with kwarg filters {kwargs}")
70
74
  with db_session as session:
75
+ # If cursor provided, get the reference object
76
+ cursor_obj = None
77
+ if cursor:
78
+ cursor_obj = session.get(cls, cursor)
79
+ if not cursor_obj:
80
+ raise NoResultFound(f"No {cls.__name__} found with id {cursor}")
81
+
71
82
  query = select(cls)
72
83
 
73
84
  # Apply filtering logic
@@ -80,22 +91,38 @@ class SqlalchemyBase(CommonSqlalchemyMetaMixins, Base):
80
91
 
81
92
  # Date range filtering
82
93
  if start_date:
83
- query = query.filter(cls.created_at >= start_date)
94
+ query = query.filter(cls.created_at > start_date)
84
95
  if end_date:
85
- query = query.filter(cls.created_at <= end_date)
86
-
87
- # Cursor-based pagination
88
- if cursor:
89
- query = query.where(cls.id > cursor)
96
+ query = query.filter(cls.created_at < end_date)
97
+
98
+ # Cursor-based pagination using created_at
99
+ # TODO: There is a really nasty race condition issue here with Sqlite
100
+ # TODO: If they have the same created_at timestamp, this query does NOT match for whatever reason
101
+ if cursor_obj:
102
+ if ascending:
103
+ query = query.where(cls.created_at >= cursor_obj.created_at).where(
104
+ or_(cls.created_at > cursor_obj.created_at, cls.id > cursor_obj.id)
105
+ )
106
+ else:
107
+ query = query.where(cls.created_at <= cursor_obj.created_at).where(
108
+ or_(cls.created_at < cursor_obj.created_at, cls.id < cursor_obj.id)
109
+ )
90
110
 
91
111
  # Apply text search
92
112
  if query_text:
93
113
  query = query.filter(func.lower(cls.text).contains(func.lower(query_text)))
94
114
 
95
- # Handle ordering and soft deletes
115
+ # Handle soft deletes
96
116
  if hasattr(cls, "is_deleted"):
97
117
  query = query.where(cls.is_deleted == False)
98
- query = query.order_by(cls.id).limit(limit)
118
+
119
+ # Apply ordering by created_at
120
+ if ascending:
121
+ query = query.order_by(cls.created_at, cls.id)
122
+ else:
123
+ query = query.order_by(desc(cls.created_at), desc(cls.id))
124
+
125
+ query = query.limit(limit)
99
126
 
100
127
  return list(session.execute(query).scalars())
101
128
 
@@ -420,7 +420,7 @@ def get_agent_messages(
420
420
  return server.get_agent_recall_cursor(
421
421
  user_id=actor.id,
422
422
  agent_id=agent_id,
423
- cursor=before,
423
+ before=before,
424
424
  limit=limit,
425
425
  reverse=True,
426
426
  return_message_object=msg_object,
letta/server/server.py CHANGED
@@ -101,11 +101,6 @@ class Server(object):
101
101
  """List all available agents to a user"""
102
102
  raise NotImplementedError
103
103
 
104
- @abstractmethod
105
- def get_agent_messages(self, user_id: str, agent_id: str, start: int, count: int) -> list:
106
- """Paginated query of in-context messages in agent message queue"""
107
- raise NotImplementedError
108
-
109
104
  @abstractmethod
110
105
  def get_agent_memory(self, user_id: str, agent_id: str) -> dict:
111
106
  """Return the memory of an agent (core memory + non-core statistics)"""
@@ -1173,55 +1168,6 @@ class SyncServer(Server):
1173
1168
  message = agent.message_manager.get_message_by_id(id=message_id, actor=self.default_user)
1174
1169
  return message
1175
1170
 
1176
- def get_agent_messages(
1177
- self,
1178
- agent_id: str,
1179
- start: int,
1180
- count: int,
1181
- ) -> Union[List[Message], List[LettaMessage]]:
1182
- """Paginated query of all messages in agent message queue"""
1183
- # Get the agent object (loaded in memory)
1184
- letta_agent = self.load_agent(agent_id=agent_id)
1185
-
1186
- if start < 0 or count < 0:
1187
- raise ValueError("Start and count values should be non-negative")
1188
-
1189
- if start + count < len(letta_agent._messages): # messages can be returned from whats in memory
1190
- # Reverse the list to make it in reverse chronological order
1191
- reversed_messages = letta_agent._messages[::-1]
1192
- # Check if start is within the range of the list
1193
- if start >= len(reversed_messages):
1194
- raise IndexError("Start index is out of range")
1195
-
1196
- # Calculate the end index, ensuring it does not exceed the list length
1197
- end_index = min(start + count, len(reversed_messages))
1198
-
1199
- # Slice the list for pagination
1200
- messages = reversed_messages[start:end_index]
1201
-
1202
- else:
1203
- # need to access persistence manager for additional messages
1204
-
1205
- # get messages using message manager
1206
- page = letta_agent.message_manager.list_user_messages_for_agent(
1207
- agent_id=agent_id,
1208
- actor=self.default_user,
1209
- cursor=start,
1210
- limit=count,
1211
- )
1212
-
1213
- messages = page
1214
- assert all(isinstance(m, Message) for m in messages)
1215
-
1216
- ## Convert to json
1217
- ## Add a tag indicating in-context or not
1218
- # json_messages = [record.to_json() for record in messages]
1219
- # in_context_message_ids = [str(m.id) for m in letta_agent._messages]
1220
- # for d in json_messages:
1221
- # d["in_context"] = True if str(d["id"]) in in_context_message_ids else False
1222
-
1223
- return messages
1224
-
1225
1171
  def get_agent_archival(self, user_id: str, agent_id: str, start: int, count: int) -> List[Passage]:
1226
1172
  """Paginated query of all messages in agent archival memory"""
1227
1173
  if self.user_manager.get_user_by_id(user_id=user_id) is None:
@@ -1303,7 +1249,8 @@ class SyncServer(Server):
1303
1249
  self,
1304
1250
  user_id: str,
1305
1251
  agent_id: str,
1306
- cursor: Optional[str] = None,
1252
+ after: Optional[str] = None,
1253
+ before: Optional[str] = None,
1307
1254
  limit: Optional[int] = 100,
1308
1255
  reverse: Optional[bool] = False,
1309
1256
  return_message_object: bool = True,
@@ -1320,12 +1267,15 @@ class SyncServer(Server):
1320
1267
  letta_agent = self.load_agent(agent_id=agent_id)
1321
1268
 
1322
1269
  # iterate over records
1323
- # TODO: Check "order_by", "order"
1270
+ start_date = self.message_manager.get_message_by_id(after, actor=actor).created_at if after else None
1271
+ end_date = self.message_manager.get_message_by_id(before, actor=actor).created_at if before else None
1324
1272
  records = letta_agent.message_manager.list_messages_for_agent(
1325
1273
  agent_id=agent_id,
1326
1274
  actor=actor,
1327
- cursor=cursor,
1275
+ start_date=start_date,
1276
+ end_date=end_date,
1328
1277
  limit=limit,
1278
+ ascending=not reverse,
1329
1279
  )
1330
1280
 
1331
1281
  assert all(isinstance(m, Message) for m in records)
@@ -119,6 +119,7 @@ class MessageManager:
119
119
  limit: Optional[int] = 50,
120
120
  filters: Optional[Dict] = None,
121
121
  query_text: Optional[str] = None,
122
+ ascending: bool = True,
122
123
  ) -> List[PydanticMessage]:
123
124
  """List user messages with flexible filtering and pagination options.
124
125
 
@@ -159,6 +160,7 @@ class MessageManager:
159
160
  limit: Optional[int] = 50,
160
161
  filters: Optional[Dict] = None,
161
162
  query_text: Optional[str] = None,
163
+ ascending: bool = True,
162
164
  ) -> List[PydanticMessage]:
163
165
  """List messages with flexible filtering and pagination options.
164
166
 
@@ -188,6 +190,7 @@ class MessageManager:
188
190
  end_date=end_date,
189
191
  limit=limit,
190
192
  query_text=query_text,
193
+ ascending=ascending,
191
194
  **message_filters,
192
195
  )
193
196
 
@@ -459,7 +459,7 @@ class ToolExecutionSandbox:
459
459
  Generate the code string to call the function.
460
460
 
461
461
  Args:
462
- inject_agent_state (bool): Whether to inject the agent's state as an input into the tool
462
+ inject_agent_state (bool): Whether to inject the axgent's state as an input into the tool
463
463
 
464
464
  Returns:
465
465
  str: Generated code string for calling the tool
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: letta-nightly
3
- Version: 0.6.2.dev20241210030340
3
+ Version: 0.6.2.dev20241210104242
4
4
  Summary: Create LLM agents with long-term memory and custom tools
5
5
  License: Apache License
6
6
  Author: Letta Team
@@ -13,7 +13,7 @@ letta/cli/cli.py,sha256=yjopYQj6DrYcRAg9FjD974zOqPUlCjzanD1EsSIRFXE,16832
13
13
  letta/cli/cli_config.py,sha256=tB0Wgz3O9j6KiCsU1HWfsKmhNM9RqLsAxzxEDFQFGnM,8565
14
14
  letta/cli/cli_load.py,sha256=xFw-CuzjChcIptaqQ1XpDROENt0JSjyPeiQ0nmEeO1k,2706
15
15
  letta/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
- letta/client/client.py,sha256=hhCn2cA52O2lGjxv0zKYtABKQYBhG_F_SEasKEK5lII,127092
16
+ letta/client/client.py,sha256=mO9m6bktXYzF_QSkWiVDnKdxiHGQhWEgBnVHt9dMSiQ,127092
17
17
  letta/client/streaming.py,sha256=Hh5pjlyrdCuO2V75ZCxSSOCPd3BmHdKFGaIUJC6fBp0,4775
18
18
  letta/client/utils.py,sha256=OJlAKWrldc4I6M1WpcTWNtPJ4wfxlzlZqWLfCozkFtI,2872
19
19
  letta/config.py,sha256=AF4XY6grcu87OLjrWXh1ufnyKWsCL0qER-_9jQCAlU0,18947
@@ -105,7 +105,7 @@ letta/orm/mixins.py,sha256=TpP5dFAcGu2VvHZQSt8ymc0UjQhcVp5-Fc2C4v_nUTM,1508
105
105
  letta/orm/organization.py,sha256=ZoHow3Tpdh9TXDvB4VZbArbUCgbErFTSQMriYAzulqA,2397
106
106
  letta/orm/sandbox_config.py,sha256=PCMHE-eJPzBT-90OYtXjEMRF4f9JB8AJIGETE7bu-f0,2870
107
107
  letta/orm/source.py,sha256=Ib0XHCMt345RjBSC30A398rZ21W5mA4PXX00XNXyd24,2021
108
- letta/orm/sqlalchemy_base.py,sha256=Wgmy9QAiLW1sS7jm3rtow8HWtdwkPLvRJpDEp1VN4LE,13878
108
+ letta/orm/sqlalchemy_base.py,sha256=fGoFtBMwt6qZDsSj1jwr8gNttp2kyOHZqo1OxywJVpc,15133
109
109
  letta/orm/tool.py,sha256=seND1kw-GvdtIumGDrsUH0EtE7F59YUzK-XYenOZ4vE,3070
110
110
  letta/orm/tools_agents.py,sha256=mBMGQsTEx_ckfhZb2-2nqbxHBEMhvDXim6w6tFHHWBQ,1195
111
111
  letta/orm/user.py,sha256=bUZzyBQXfR0w7mZAkThPAQE6kKx6W--Rw6uAiPEUW3s,1133
@@ -186,7 +186,7 @@ letta/server/rest_api/routers/openai/assistants/threads.py,sha256=g8iu98__tQEMY9
186
186
  letta/server/rest_api/routers/openai/chat_completions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
187
187
  letta/server/rest_api/routers/openai/chat_completions/chat_completions.py,sha256=qFMpxfYIlJ-PW08IQt09RW44u6hwkssdsUT-h_GuOvE,4836
188
188
  letta/server/rest_api/routers/v1/__init__.py,sha256=RZc0fIHNN4BGretjU6_TGK7q49RyV4jfYNudoiK_sUo,762
189
- letta/server/rest_api/routers/v1/agents.py,sha256=18x44MxYBvGQHmSKF1HQ-dlETQEOyetPFC1yoxEqObw,27891
189
+ letta/server/rest_api/routers/v1/agents.py,sha256=_1rRBIaCMQT5hpyNRWfTetBEB00JHS4vwJL9ExMz3kw,27891
190
190
  letta/server/rest_api/routers/v1/blocks.py,sha256=hLGwm56xCA09KdEi8P0V3s__pD_yyl07p17cdSfDj8g,4878
191
191
  letta/server/rest_api/routers/v1/health.py,sha256=pKCuVESlVOhGIb4VC4K-H82eZqfghmT6kvj2iOkkKuc,401
192
192
  letta/server/rest_api/routers/v1/jobs.py,sha256=gnu__rjcd9SpKdQkSD_sci-xJYH0fw828PuHMcYwsCw,2678
@@ -198,7 +198,7 @@ letta/server/rest_api/routers/v1/tools.py,sha256=ajYUo_cgUBDfm4Ja_EufxSdhBWoAb5N
198
198
  letta/server/rest_api/routers/v1/users.py,sha256=M1wEr2IyHzuRwINYxLXTkrbAH3osLe_cWjzrWrzR1aw,3729
199
199
  letta/server/rest_api/static_files.py,sha256=NG8sN4Z5EJ8JVQdj19tkFa9iQ1kBPTab9f_CUxd_u4Q,3143
200
200
  letta/server/rest_api/utils.py,sha256=6Z0T0kHIwDAgTIFh38Q1JQ_nhANgdqXcSlsuY41pL6M,3158
201
- letta/server/server.py,sha256=3sgoeetKRww5gPZyWiKhbMkvhyWPLAnI6A1NYBoW-YI,81922
201
+ letta/server/server.py,sha256=db4lkuXS0JVhakRrCBumte3NZ7jKVk6z2Is_PbD7aYg,80019
202
202
  letta/server/startup.sh,sha256=722uKJWB2C4q3vjn39De2zzPacaZNw_1fN1SpLGjKIo,1569
203
203
  letta/server/static_files/assets/index-43ab4d62.css,sha256=Q6tNYu7XNRgkTZau1dVwCQTT4YpLGLF7VgTNzLcMaQI,7613
204
204
  letta/server/static_files/assets/index-4848e3d7.js,sha256=XkoX-NW0x1Hb7uTWslfpuPP73MnNDthOdJLHLID9EhM,146806
@@ -216,12 +216,12 @@ letta/services/agents_tags_manager.py,sha256=zNqeXDpaf4dQ77jrRHiQfITdk4FawBzcND-
216
216
  letta/services/block_manager.py,sha256=BmuK0k3yl9byT703syGtZNfjUdM2FkOwlE6bQYIQtjI,5448
217
217
  letta/services/blocks_agents_manager.py,sha256=mfO3EMW9os_E1_r4SRlC2wmBFFLpt8p-yhdOH_Iotaw,5627
218
218
  letta/services/job_manager.py,sha256=FrkSXloke48CZKuzlYdysxM5gKWoTu7FRigPrs_YW4A,3645
219
- letta/services/message_manager.py,sha256=DjxD4CtyLsJjsOQt-3znslR8htQBqOOuYNvK6RJCrsE,7581
219
+ letta/services/message_manager.py,sha256=ucFJLbK835YSfEENoxdKB3wPZgO-NYFO9EvDV0W-sc0,7682
220
220
  letta/services/organization_manager.py,sha256=B7BgHkZcAOP1fzbg2fFF8eTfKmqOiGvoojQ8ys7JVY4,3412
221
221
  letta/services/per_agent_lock_manager.py,sha256=porM0cKKANQ1FvcGXOO_qM7ARk5Fgi1HVEAhXsAg9-4,546
222
222
  letta/services/sandbox_config_manager.py,sha256=PqlS47FAYYmiUFd9bUV4W1t4FjhMqiDoh3Blw_1tiCM,13269
223
223
  letta/services/source_manager.py,sha256=8TILbVvJx1bopgDbIJCiIguZBw7uyYDFkasZxVos_G8,6560
224
- letta/services/tool_execution_sandbox.py,sha256=GTWdfAKIMIuODEFbmReyEYkOnE62uzDF-3FHWee1s3A,21295
224
+ letta/services/tool_execution_sandbox.py,sha256=NIadt_Rct5WrVfQSdWlRc095ihUGc0-QvF_dH5qZXOM,21296
225
225
  letta/services/tool_manager.py,sha256=lfrfWyxiFUWcEf-nATHs7r76XWutMYbOPyePs543ZOo,7681
226
226
  letta/services/tool_sandbox_env/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
227
227
  letta/services/tools_agents_manager.py,sha256=kF6yIsUO154_Q3l-cEeSU56QW-VUr_M6B-9csqhHBkg,4847
@@ -231,8 +231,8 @@ letta/streaming_interface.py,sha256=_FPUWy58j50evHcpXyd7zB1wWqeCc71NCFeWh_TBvnw,
231
231
  letta/streaming_utils.py,sha256=329fsvj1ZN0r0LpQtmMPZ2vSxkDBIUUwvGHZFkjm2I8,11745
232
232
  letta/system.py,sha256=buKYPqG5n2x41hVmWpu6JUpyd7vTWED9Km2_M7dLrvk,6960
233
233
  letta/utils.py,sha256=L8c6S77gyMYFgVP6ncGRaNbGjWtg6BOU_whI1vjt9Ts,32915
234
- letta_nightly-0.6.2.dev20241210030340.dist-info/LICENSE,sha256=mExtuZ_GYJgDEI38GWdiEYZizZS4KkVt2SF1g_GPNhI,10759
235
- letta_nightly-0.6.2.dev20241210030340.dist-info/METADATA,sha256=rDMf6d3sIU9YD69kVu5go6wdd9J2Zb77t05v3Vu7fho,11459
236
- letta_nightly-0.6.2.dev20241210030340.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
237
- letta_nightly-0.6.2.dev20241210030340.dist-info/entry_points.txt,sha256=2zdiyGNEZGV5oYBuS-y2nAAgjDgcC9yM_mHJBFSRt5U,40
238
- letta_nightly-0.6.2.dev20241210030340.dist-info/RECORD,,
234
+ letta_nightly-0.6.2.dev20241210104242.dist-info/LICENSE,sha256=mExtuZ_GYJgDEI38GWdiEYZizZS4KkVt2SF1g_GPNhI,10759
235
+ letta_nightly-0.6.2.dev20241210104242.dist-info/METADATA,sha256=_Srlq9gfn8M6NvP9C7JZ2YHGX7Ss782h0o4JeYtlm1Q,11459
236
+ letta_nightly-0.6.2.dev20241210104242.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
237
+ letta_nightly-0.6.2.dev20241210104242.dist-info/entry_points.txt,sha256=2zdiyGNEZGV5oYBuS-y2nAAgjDgcC9yM_mHJBFSRt5U,40
238
+ letta_nightly-0.6.2.dev20241210104242.dist-info/RECORD,,