letta-nightly 0.11.0.dev20250808104456__py3-none-any.whl → 0.11.2.dev20250809104224__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.
- letta/__init__.py +1 -1
- letta/schemas/llm_config.py +6 -6
- letta/serialize_schemas/marshmallow_agent.py +101 -11
- letta/server/rest_api/routers/v1/agents.py +2 -1
- letta/services/agent_manager.py +2 -2
- {letta_nightly-0.11.0.dev20250808104456.dist-info → letta_nightly-0.11.2.dev20250809104224.dist-info}/METADATA +1 -1
- {letta_nightly-0.11.0.dev20250808104456.dist-info → letta_nightly-0.11.2.dev20250809104224.dist-info}/RECORD +10 -10
- {letta_nightly-0.11.0.dev20250808104456.dist-info → letta_nightly-0.11.2.dev20250809104224.dist-info}/LICENSE +0 -0
- {letta_nightly-0.11.0.dev20250808104456.dist-info → letta_nightly-0.11.2.dev20250809104224.dist-info}/WHEEL +0 -0
- {letta_nightly-0.11.0.dev20250808104456.dist-info → letta_nightly-0.11.2.dev20250809104224.dist-info}/entry_points.txt +0 -0
letta/__init__.py
CHANGED
letta/schemas/llm_config.py
CHANGED
@@ -187,9 +187,12 @@ class LLMConfig(BaseModel):
|
|
187
187
|
|
188
188
|
@classmethod
|
189
189
|
def apply_reasoning_setting_to_config(cls, config: "LLMConfig", reasoning: bool):
|
190
|
-
if reasoning:
|
191
|
-
config.
|
190
|
+
if not reasoning:
|
191
|
+
config.put_inner_thoughts_in_kwargs = False
|
192
|
+
config.enable_reasoner = False
|
192
193
|
|
194
|
+
else:
|
195
|
+
config.enable_reasoner = True
|
193
196
|
if (
|
194
197
|
config.model_endpoint_type == "anthropic"
|
195
198
|
and ("claude-opus-4" in config.model or "claude-sonnet-4" in config.model or "claude-3-7-sonnet" in config.model)
|
@@ -207,9 +210,6 @@ class LLMConfig(BaseModel):
|
|
207
210
|
config.reasoning_effort = "medium"
|
208
211
|
else:
|
209
212
|
config.put_inner_thoughts_in_kwargs = True
|
210
|
-
|
211
|
-
else:
|
212
|
-
config.enable_reasoner = False
|
213
|
-
config.put_inner_thoughts_in_kwargs = False
|
213
|
+
config.enable_reasoner = False
|
214
214
|
|
215
215
|
return config
|
@@ -1,6 +1,7 @@
|
|
1
|
-
from typing import Dict
|
1
|
+
from typing import Dict, Optional
|
2
2
|
|
3
3
|
from marshmallow import fields, post_dump, pre_load
|
4
|
+
from sqlalchemy import func
|
4
5
|
from sqlalchemy.orm import sessionmaker
|
5
6
|
|
6
7
|
import letta
|
@@ -15,6 +16,7 @@ from letta.serialize_schemas.marshmallow_custom_fields import EmbeddingConfigFie
|
|
15
16
|
from letta.serialize_schemas.marshmallow_message import SerializedMessageSchema
|
16
17
|
from letta.serialize_schemas.marshmallow_tag import SerializedAgentTagSchema
|
17
18
|
from letta.serialize_schemas.marshmallow_tool import SerializedToolSchema
|
19
|
+
from letta.settings import DatabaseChoice, settings
|
18
20
|
|
19
21
|
|
20
22
|
class MarshmallowAgentSchema(BaseSchema):
|
@@ -41,9 +43,10 @@ class MarshmallowAgentSchema(BaseSchema):
|
|
41
43
|
tool_exec_environment_variables = fields.List(fields.Nested(SerializedAgentEnvironmentVariableSchema))
|
42
44
|
tags = fields.List(fields.Nested(SerializedAgentTagSchema))
|
43
45
|
|
44
|
-
def __init__(self, *args, session: sessionmaker, actor: User, **kwargs):
|
46
|
+
def __init__(self, *args, session: sessionmaker, actor: User, max_steps: Optional[int] = None, **kwargs):
|
45
47
|
super().__init__(*args, actor=actor, **kwargs)
|
46
48
|
self.session = session
|
49
|
+
self.max_steps = max_steps
|
47
50
|
|
48
51
|
# Propagate session and actor to nested schemas automatically
|
49
52
|
for field in self.fields.values():
|
@@ -64,16 +67,103 @@ class MarshmallowAgentSchema(BaseSchema):
|
|
64
67
|
|
65
68
|
with db_registry.session() as session:
|
66
69
|
agent_id = data.get("id")
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
MessageModel
|
70
|
+
|
71
|
+
if self.max_steps is not None:
|
72
|
+
# first, always get the system message
|
73
|
+
system_msg = (
|
74
|
+
session.query(MessageModel)
|
75
|
+
.filter(
|
76
|
+
MessageModel.agent_id == agent_id,
|
77
|
+
MessageModel.organization_id == self.actor.organization_id,
|
78
|
+
MessageModel.role == "system",
|
79
|
+
)
|
80
|
+
.order_by(MessageModel.sequence_id.asc())
|
81
|
+
.first()
|
82
|
+
)
|
83
|
+
|
84
|
+
if settings.database_engine is DatabaseChoice.POSTGRES:
|
85
|
+
# efficient PostgreSQL approach using subquery
|
86
|
+
user_msg_subquery = (
|
87
|
+
session.query(MessageModel.sequence_id)
|
88
|
+
.filter(
|
89
|
+
MessageModel.agent_id == agent_id,
|
90
|
+
MessageModel.organization_id == self.actor.organization_id,
|
91
|
+
MessageModel.role == "user",
|
92
|
+
)
|
93
|
+
.order_by(MessageModel.sequence_id.desc())
|
94
|
+
.limit(self.max_steps)
|
95
|
+
.subquery()
|
96
|
+
)
|
97
|
+
|
98
|
+
# get the minimum sequence_id from the subquery
|
99
|
+
cutoff_sequence_id = session.query(func.min(user_msg_subquery.c.sequence_id)).scalar()
|
100
|
+
|
101
|
+
if cutoff_sequence_id:
|
102
|
+
# get messages from cutoff, excluding system message to avoid duplicates
|
103
|
+
step_msgs = (
|
104
|
+
session.query(MessageModel)
|
105
|
+
.filter(
|
106
|
+
MessageModel.agent_id == agent_id,
|
107
|
+
MessageModel.organization_id == self.actor.organization_id,
|
108
|
+
MessageModel.sequence_id >= cutoff_sequence_id,
|
109
|
+
MessageModel.role != "system",
|
110
|
+
)
|
111
|
+
.order_by(MessageModel.sequence_id.asc())
|
112
|
+
.all()
|
113
|
+
)
|
114
|
+
# combine system message with step messages
|
115
|
+
msgs = [system_msg] + step_msgs if system_msg else step_msgs
|
116
|
+
else:
|
117
|
+
# no user messages, just return system message
|
118
|
+
msgs = [system_msg] if system_msg else []
|
119
|
+
else:
|
120
|
+
# sqlite approach: get all user messages first, then get messages from cutoff
|
121
|
+
user_messages = (
|
122
|
+
session.query(MessageModel.sequence_id)
|
123
|
+
.filter(
|
124
|
+
MessageModel.agent_id == agent_id,
|
125
|
+
MessageModel.organization_id == self.actor.organization_id,
|
126
|
+
MessageModel.role == "user",
|
127
|
+
)
|
128
|
+
.order_by(MessageModel.sequence_id.desc())
|
129
|
+
.limit(self.max_steps)
|
130
|
+
.all()
|
131
|
+
)
|
132
|
+
|
133
|
+
if user_messages:
|
134
|
+
# get the minimum sequence_id
|
135
|
+
cutoff_sequence_id = min(msg.sequence_id for msg in user_messages)
|
136
|
+
|
137
|
+
# get messages from cutoff, excluding system message to avoid duplicates
|
138
|
+
step_msgs = (
|
139
|
+
session.query(MessageModel)
|
140
|
+
.filter(
|
141
|
+
MessageModel.agent_id == agent_id,
|
142
|
+
MessageModel.organization_id == self.actor.organization_id,
|
143
|
+
MessageModel.sequence_id >= cutoff_sequence_id,
|
144
|
+
MessageModel.role != "system",
|
145
|
+
)
|
146
|
+
.order_by(MessageModel.sequence_id.asc())
|
147
|
+
.all()
|
148
|
+
)
|
149
|
+
# combine system message with step messages
|
150
|
+
msgs = [system_msg] + step_msgs if system_msg else step_msgs
|
151
|
+
else:
|
152
|
+
# no user messages, just return system message
|
153
|
+
msgs = [system_msg] if system_msg else []
|
154
|
+
else:
|
155
|
+
# if no limit, get all messages in ascending order
|
156
|
+
msgs = (
|
157
|
+
session.query(MessageModel)
|
158
|
+
.filter(
|
159
|
+
MessageModel.agent_id == agent_id,
|
160
|
+
MessageModel.organization_id == self.actor.organization_id,
|
161
|
+
)
|
162
|
+
.order_by(MessageModel.sequence_id.asc())
|
163
|
+
.all()
|
72
164
|
)
|
73
|
-
|
74
|
-
|
75
|
-
)
|
76
|
-
# overwrite the “messages” key with a fully serialized list
|
165
|
+
|
166
|
+
# overwrite the "messages" key with a fully serialized list
|
77
167
|
data[self.FIELD_MESSAGES] = [SerializedMessageSchema(session=self.session, actor=self.actor).dump(m) for m in msgs]
|
78
168
|
|
79
169
|
return data
|
@@ -146,6 +146,7 @@ class IndentedORJSONResponse(Response):
|
|
146
146
|
@router.get("/{agent_id}/export", response_class=IndentedORJSONResponse, operation_id="export_agent_serialized")
|
147
147
|
def export_agent_serialized(
|
148
148
|
agent_id: str,
|
149
|
+
max_steps: int = 100,
|
149
150
|
server: "SyncServer" = Depends(get_letta_server),
|
150
151
|
actor_id: str | None = Header(None, alias="user_id"),
|
151
152
|
# do not remove, used to autogeneration of spec
|
@@ -158,7 +159,7 @@ def export_agent_serialized(
|
|
158
159
|
actor = server.user_manager.get_user_or_default(user_id=actor_id)
|
159
160
|
|
160
161
|
try:
|
161
|
-
agent = server.agent_manager.serialize(agent_id=agent_id, actor=actor)
|
162
|
+
agent = server.agent_manager.serialize(agent_id=agent_id, actor=actor, max_steps=max_steps)
|
162
163
|
return agent.model_dump()
|
163
164
|
except NoResultFound:
|
164
165
|
raise HTTPException(status_code=404, detail=f"Agent with id={agent_id} not found for user_id={actor.id}.")
|
letta/services/agent_manager.py
CHANGED
@@ -1446,10 +1446,10 @@ class AgentManager:
|
|
1446
1446
|
|
1447
1447
|
@enforce_types
|
1448
1448
|
@trace_method
|
1449
|
-
def serialize(self, agent_id: str, actor: PydanticUser) -> AgentSchema:
|
1449
|
+
def serialize(self, agent_id: str, actor: PydanticUser, max_steps: Optional[int] = None) -> AgentSchema:
|
1450
1450
|
with db_registry.session() as session:
|
1451
1451
|
agent = AgentModel.read(db_session=session, identifier=agent_id, actor=actor)
|
1452
|
-
schema = MarshmallowAgentSchema(session=session, actor=actor)
|
1452
|
+
schema = MarshmallowAgentSchema(session=session, actor=actor, max_steps=max_steps)
|
1453
1453
|
data = schema.dump(agent)
|
1454
1454
|
return AgentSchema(**data)
|
1455
1455
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
letta/__init__.py,sha256=
|
1
|
+
letta/__init__.py,sha256=psvi_LC5TMlxXPWuIwlSeUPhOZJHv6RJJQfvghPf9Zo,1321
|
2
2
|
letta/agent.py,sha256=o591CrbxIepAfmVdZv7OVBCQsfAvKqv_HTd89LYPgu8,89462
|
3
3
|
letta/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
4
|
letta/agents/base_agent.py,sha256=-hrG_4iNba2e68LF8nzfPKeCviBdoWZ6jODd798ryt0,7796
|
@@ -260,7 +260,7 @@ letta/schemas/letta_request.py,sha256=GF7tSVjoAXukl1SXN2FBi8ZMaWOVRvuJuXPgEwbV7H
|
|
260
260
|
letta/schemas/letta_response.py,sha256=e6FcAhRX3heB0FoWAAozB3RJboMwi_JpelTdc5JupVA,8188
|
261
261
|
letta/schemas/letta_stop_reason.py,sha256=4t39UKMMsLuNM-9a0BG7Mi-zZ7YhYLFSEpTWc8_OyrQ,2035
|
262
262
|
letta/schemas/llm_batch_job.py,sha256=xr7RmMc9ItmL344vcIn1MJaT2nOf0F7qEHrsXkQNFQI,3136
|
263
|
-
letta/schemas/llm_config.py,sha256
|
263
|
+
letta/schemas/llm_config.py,sha256=SLjJRc1trV8fgZoTyBPC9hsgNONWQKfmf8SE97qFfmo,9462
|
264
264
|
letta/schemas/llm_config_overrides.py,sha256=E6qJuVA8TwAAy3VjGitJ5jSQo5PbN-6VPcZOF5qhP9A,1815
|
265
265
|
letta/schemas/mcp.py,sha256=_FKUSIoTLfx64buKqye-9fPET8-1_e2h9uYByNwTVio,10440
|
266
266
|
letta/schemas/memory.py,sha256=45j0akHGSrShd8v8wW-7lJhFRNWi9rWEvFp8w6f1PUk,14142
|
@@ -309,7 +309,7 @@ letta/schemas/tool_rule.py,sha256=e9pWC2kZvdnohQuCTAxm96UjczrPnSB_lEeVkBEBPN4,97
|
|
309
309
|
letta/schemas/usage.py,sha256=9SSTH5kUliwiVF14b-yKbDcmxQBOLg4YH5xhXDbW9UU,1281
|
310
310
|
letta/schemas/user.py,sha256=GanbgD80N33FBjWKkv-MvUO01C0GHzrYmJ-o80wgLLI,1481
|
311
311
|
letta/serialize_schemas/__init__.py,sha256=cosMjvWz7cubC1azbUofzYrcDBTuSgjJImUdsrSs3p0,77
|
312
|
-
letta/serialize_schemas/marshmallow_agent.py,sha256=
|
312
|
+
letta/serialize_schemas/marshmallow_agent.py,sha256=FrIz3XD-XR29tZio1Ji0588XPP4CJNE17sDTC0HHaKk,10370
|
313
313
|
letta/serialize_schemas/marshmallow_agent_environment_variable.py,sha256=9RYJkaNH2UiRoIFzrNklVAGl3uMmu3n6NwzFdviPPVA,653
|
314
314
|
letta/serialize_schemas/marshmallow_base.py,sha256=GP0ImCRfJ-BqNKe-T44Feal18pmFQG-p8JllOsSSNRk,1379
|
315
315
|
letta/serialize_schemas/marshmallow_block.py,sha256=qV17pbztsb9MD-632aC66aBJ5m-HK780ifOO9YnoKoo,1043
|
@@ -337,7 +337,7 @@ letta/server/rest_api/routers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5N
|
|
337
337
|
letta/server/rest_api/routers/openai/chat_completions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
338
338
|
letta/server/rest_api/routers/openai/chat_completions/chat_completions.py,sha256=QBWab1fn2LXVDMtc6li3gOzmrNzDiUw5WUJsMeeMZII,5076
|
339
339
|
letta/server/rest_api/routers/v1/__init__.py,sha256=HlL-WoRMz39NLyHhFugHbdIho66ZVK5VG2YRNYIiMZU,1866
|
340
|
-
letta/server/rest_api/routers/v1/agents.py,sha256=
|
340
|
+
letta/server/rest_api/routers/v1/agents.py,sha256=xb78slGGlPsceL6rrHDssoR128tVbJSbkroSnXvu9FE,64603
|
341
341
|
letta/server/rest_api/routers/v1/blocks.py,sha256=jICprv_qKlS1H9xOwzXVnGG41l9D9WR6RpKPAKljrhk,7459
|
342
342
|
letta/server/rest_api/routers/v1/embeddings.py,sha256=PRaQlrmEXPiIdWsTbadrFsv3Afyv5oEFUdhgHA8FTi8,989
|
343
343
|
letta/server/rest_api/routers/v1/folders.py,sha256=ikC1oYkWZXafDlFDv1hOkuGkOnUCAU3XqNmZG6PsqS4,21646
|
@@ -376,7 +376,7 @@ letta/server/ws_api/protocol.py,sha256=5mDgpfNZn_kNwHnpt5Dsuw8gdNH298sgxTGed3etz
|
|
376
376
|
letta/server/ws_api/server.py,sha256=_16TQafm509rqRztZYqo0HKKZoe8ccBrNftd_kbIJTE,5833
|
377
377
|
letta/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
378
378
|
letta/services/agent_file_manager.py,sha256=bgYTyQA90Iqo3W-LprPtyyOKf2itoqivcRhh4EOUXss,30847
|
379
|
-
letta/services/agent_manager.py,sha256=
|
379
|
+
letta/services/agent_manager.py,sha256=6CUnFBGoC42im08I10ZG8hIWYw-gq35iQ-sAmK0EYQM,151364
|
380
380
|
letta/services/agent_serialization_manager.py,sha256=YrpeY1SQavEKr9IjlwNp0MD8iwq5U_Deh9-B57ghCzQ,39640
|
381
381
|
letta/services/archive_manager.py,sha256=a_EDb0agJAze1oOELfnHmPUQB0k9fG1xBK5p_o2zsis,9427
|
382
382
|
letta/services/block_manager.py,sha256=sSbNpsbk62-qBtOmhIp3YlOQKTpWQ3gXlVrFpF1vY50,33491
|
@@ -456,8 +456,8 @@ letta/templates/summary_request_text.j2,sha256=ZttQwXonW2lk4pJLYzLK0pmo4EO4EtUUI
|
|
456
456
|
letta/templates/template_helper.py,sha256=HkG3zwRc5NVGmSTQu5PUTpz7LevK43bzXVaQuN8urf0,1634
|
457
457
|
letta/types/__init__.py,sha256=hokKjCVFGEfR7SLMrtZsRsBfsC7yTIbgKPLdGg4K1eY,147
|
458
458
|
letta/utils.py,sha256=Fwwe2imHRamc_kucAATo8NXhwDG5NBoOIYmBaERXUhM,38384
|
459
|
-
letta_nightly-0.11.
|
460
|
-
letta_nightly-0.11.
|
461
|
-
letta_nightly-0.11.
|
462
|
-
letta_nightly-0.11.
|
463
|
-
letta_nightly-0.11.
|
459
|
+
letta_nightly-0.11.2.dev20250809104224.dist-info/LICENSE,sha256=mExtuZ_GYJgDEI38GWdiEYZizZS4KkVt2SF1g_GPNhI,10759
|
460
|
+
letta_nightly-0.11.2.dev20250809104224.dist-info/METADATA,sha256=ZUP9pUGfSAJE5ES3S_3m6Bp6MmSYNXr9BvjSaXIhgws,23281
|
461
|
+
letta_nightly-0.11.2.dev20250809104224.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
462
|
+
letta_nightly-0.11.2.dev20250809104224.dist-info/entry_points.txt,sha256=2zdiyGNEZGV5oYBuS-y2nAAgjDgcC9yM_mHJBFSRt5U,40
|
463
|
+
letta_nightly-0.11.2.dev20250809104224.dist-info/RECORD,,
|
File without changes
|
File without changes
|