letta-nightly 0.6.3.dev20241213104231__py3-none-any.whl → 0.6.4.dev20241214104034__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 +2 -2
- letta/agent.py +54 -45
- letta/chat_only_agent.py +6 -8
- letta/cli/cli.py +2 -10
- letta/client/client.py +121 -138
- letta/config.py +0 -161
- letta/main.py +3 -8
- letta/memory.py +3 -14
- letta/o1_agent.py +1 -5
- letta/offline_memory_agent.py +2 -6
- letta/orm/__init__.py +2 -0
- letta/orm/agent.py +109 -0
- letta/orm/agents_tags.py +10 -18
- letta/orm/block.py +29 -4
- letta/orm/blocks_agents.py +5 -11
- letta/orm/custom_columns.py +152 -0
- letta/orm/message.py +3 -38
- letta/orm/organization.py +2 -7
- letta/orm/passage.py +10 -32
- letta/orm/source.py +5 -25
- letta/orm/sources_agents.py +13 -0
- letta/orm/sqlalchemy_base.py +54 -30
- letta/orm/tool.py +1 -19
- letta/orm/tools_agents.py +7 -24
- letta/orm/user.py +3 -4
- letta/schemas/agent.py +48 -65
- letta/schemas/memory.py +2 -1
- letta/schemas/sandbox_config.py +12 -1
- letta/server/rest_api/app.py +0 -5
- letta/server/rest_api/routers/openai/chat_completions/chat_completions.py +1 -1
- letta/server/rest_api/routers/v1/agents.py +99 -78
- letta/server/rest_api/routers/v1/blocks.py +22 -25
- letta/server/rest_api/routers/v1/jobs.py +4 -4
- letta/server/rest_api/routers/v1/sandbox_configs.py +10 -10
- letta/server/rest_api/routers/v1/sources.py +12 -12
- letta/server/rest_api/routers/v1/tools.py +35 -15
- letta/server/rest_api/routers/v1/users.py +0 -46
- letta/server/server.py +172 -718
- letta/server/ws_api/server.py +0 -5
- letta/services/agent_manager.py +405 -0
- letta/services/block_manager.py +13 -21
- letta/services/helpers/agent_manager_helper.py +90 -0
- letta/services/organization_manager.py +0 -1
- letta/services/passage_manager.py +62 -62
- letta/services/sandbox_config_manager.py +3 -3
- letta/services/source_manager.py +22 -1
- letta/services/tool_execution_sandbox.py +4 -4
- letta/services/user_manager.py +11 -6
- letta/utils.py +2 -2
- {letta_nightly-0.6.3.dev20241213104231.dist-info → letta_nightly-0.6.4.dev20241214104034.dist-info}/METADATA +1 -1
- {letta_nightly-0.6.3.dev20241213104231.dist-info → letta_nightly-0.6.4.dev20241214104034.dist-info}/RECORD +54 -58
- letta/metadata.py +0 -407
- letta/schemas/agents_tags.py +0 -33
- letta/schemas/api_key.py +0 -21
- letta/schemas/blocks_agents.py +0 -32
- letta/schemas/tools_agents.py +0 -32
- letta/server/rest_api/routers/openai/assistants/threads.py +0 -338
- letta/services/agents_tags_manager.py +0 -64
- letta/services/blocks_agents_manager.py +0 -106
- letta/services/tools_agents_manager.py +0 -94
- {letta_nightly-0.6.3.dev20241213104231.dist-info → letta_nightly-0.6.4.dev20241214104034.dist-info}/LICENSE +0 -0
- {letta_nightly-0.6.3.dev20241213104231.dist-info → letta_nightly-0.6.4.dev20241214104034.dist-info}/WHEEL +0 -0
- {letta_nightly-0.6.3.dev20241213104231.dist-info → letta_nightly-0.6.4.dev20241214104034.dist-info}/entry_points.txt +0 -0
letta/schemas/agent.py
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
from datetime import datetime
|
|
2
1
|
from enum import Enum
|
|
3
2
|
from typing import Dict, List, Optional
|
|
4
3
|
|
|
5
4
|
from pydantic import BaseModel, Field, field_validator
|
|
6
5
|
|
|
7
|
-
from letta.constants import BASE_MEMORY_TOOLS, BASE_TOOLS
|
|
8
6
|
from letta.schemas.block import CreateBlock
|
|
9
7
|
from letta.schemas.embedding_config import EmbeddingConfig
|
|
10
|
-
from letta.schemas.letta_base import
|
|
8
|
+
from letta.schemas.letta_base import OrmMetadataBase
|
|
11
9
|
from letta.schemas.llm_config import LLMConfig
|
|
12
10
|
from letta.schemas.memory import Memory
|
|
13
11
|
from letta.schemas.message import Message, MessageCreate
|
|
@@ -15,15 +13,7 @@ from letta.schemas.openai.chat_completion_response import UsageStatistics
|
|
|
15
13
|
from letta.schemas.source import Source
|
|
16
14
|
from letta.schemas.tool import Tool
|
|
17
15
|
from letta.schemas.tool_rule import ToolRule
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class BaseAgent(LettaBase, validate_assignment=True):
|
|
21
|
-
__id_prefix__ = "agent"
|
|
22
|
-
description: Optional[str] = Field(None, description="The description of the agent.")
|
|
23
|
-
|
|
24
|
-
# metadata
|
|
25
|
-
metadata_: Optional[Dict] = Field(None, description="The metadata of the agent.", alias="metadata_")
|
|
26
|
-
user_id: Optional[str] = Field(None, description="The user id of the agent.")
|
|
16
|
+
from letta.utils import create_random_username
|
|
27
17
|
|
|
28
18
|
|
|
29
19
|
class AgentType(str, Enum):
|
|
@@ -38,37 +28,7 @@ class AgentType(str, Enum):
|
|
|
38
28
|
chat_only_agent = "chat_only_agent"
|
|
39
29
|
|
|
40
30
|
|
|
41
|
-
class
|
|
42
|
-
# NOTE: this has been changed to represent the data stored in the ORM, NOT what is passed around internally or returned to the user
|
|
43
|
-
id: str = BaseAgent.generate_id_field()
|
|
44
|
-
name: str = Field(..., description="The name of the agent.")
|
|
45
|
-
created_at: datetime = Field(..., description="The datetime the agent was created.", default_factory=datetime.now)
|
|
46
|
-
|
|
47
|
-
# in-context memory
|
|
48
|
-
message_ids: Optional[List[str]] = Field(default=None, description="The ids of the messages in the agent's in-context memory.")
|
|
49
|
-
# tools
|
|
50
|
-
# TODO: move to ORM mapping
|
|
51
|
-
tool_names: List[str] = Field(..., description="The tools used by the agent.")
|
|
52
|
-
|
|
53
|
-
# tool rules
|
|
54
|
-
tool_rules: Optional[List[ToolRule]] = Field(default=None, description="The list of tool rules.")
|
|
55
|
-
|
|
56
|
-
# system prompt
|
|
57
|
-
system: str = Field(..., description="The system prompt used by the agent.")
|
|
58
|
-
|
|
59
|
-
# agent configuration
|
|
60
|
-
agent_type: AgentType = Field(..., description="The type of agent.")
|
|
61
|
-
|
|
62
|
-
# llm information
|
|
63
|
-
llm_config: LLMConfig = Field(..., description="The LLM configuration used by the agent.")
|
|
64
|
-
embedding_config: EmbeddingConfig = Field(..., description="The embedding configuration used by the agent.")
|
|
65
|
-
|
|
66
|
-
class Config:
|
|
67
|
-
arbitrary_types_allowed = True
|
|
68
|
-
validate_assignment = True
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
class AgentState(PersistedAgentState):
|
|
31
|
+
class AgentState(OrmMetadataBase, validate_assignment=True):
|
|
72
32
|
"""
|
|
73
33
|
Representation of an agent's state. This is the state of the agent at a given time, and is persisted in the DB backend. The state has all the information needed to recreate a persisted agent.
|
|
74
34
|
|
|
@@ -85,43 +45,58 @@ class AgentState(PersistedAgentState):
|
|
|
85
45
|
|
|
86
46
|
"""
|
|
87
47
|
|
|
48
|
+
__id_prefix__ = "agent"
|
|
49
|
+
|
|
88
50
|
# NOTE: this is what is returned to the client and also what is used to initialize `Agent`
|
|
51
|
+
id: str = Field(..., description="The id of the agent. Assigned by the database.")
|
|
52
|
+
name: str = Field(..., description="The name of the agent.")
|
|
53
|
+
# tool rules
|
|
54
|
+
tool_rules: Optional[List[ToolRule]] = Field(default=None, description="The list of tool rules.")
|
|
55
|
+
|
|
56
|
+
# in-context memory
|
|
57
|
+
message_ids: Optional[List[str]] = Field(default=None, description="The ids of the messages in the agent's in-context memory.")
|
|
58
|
+
|
|
59
|
+
# system prompt
|
|
60
|
+
system: str = Field(..., description="The system prompt used by the agent.")
|
|
61
|
+
|
|
62
|
+
# agent configuration
|
|
63
|
+
agent_type: AgentType = Field(..., description="The type of agent.")
|
|
64
|
+
|
|
65
|
+
# llm information
|
|
66
|
+
llm_config: LLMConfig = Field(..., description="The LLM configuration used by the agent.")
|
|
67
|
+
embedding_config: EmbeddingConfig = Field(..., description="The embedding configuration used by the agent.")
|
|
89
68
|
|
|
90
69
|
# This is an object representing the in-process state of a running `Agent`
|
|
91
70
|
# Field in this object can be theoretically edited by tools, and will be persisted by the ORM
|
|
71
|
+
organization_id: Optional[str] = Field(None, description="The unique identifier of the organization associated with the agent.")
|
|
72
|
+
|
|
73
|
+
description: Optional[str] = Field(None, description="The description of the agent.")
|
|
74
|
+
metadata_: Optional[Dict] = Field(None, description="The metadata of the agent.", alias="metadata_")
|
|
75
|
+
|
|
92
76
|
memory: Memory = Field(..., description="The in-context memory of the agent.")
|
|
93
77
|
tools: List[Tool] = Field(..., description="The tools used by the agent.")
|
|
94
78
|
sources: List[Source] = Field(..., description="The sources used by the agent.")
|
|
95
79
|
tags: List[str] = Field(..., description="The tags associated with the agent.")
|
|
96
|
-
# TODO: add in context message objects
|
|
97
|
-
|
|
98
|
-
def to_persisted_agent_state(self) -> PersistedAgentState:
|
|
99
|
-
# turn back into persisted agent
|
|
100
|
-
data = self.model_dump()
|
|
101
|
-
del data["memory"]
|
|
102
|
-
del data["tools"]
|
|
103
|
-
del data["sources"]
|
|
104
|
-
del data["tags"]
|
|
105
|
-
return PersistedAgentState(**data)
|
|
106
80
|
|
|
107
81
|
|
|
108
|
-
class CreateAgent(
|
|
82
|
+
class CreateAgent(BaseModel, validate_assignment=True): #
|
|
109
83
|
# all optional as server can generate defaults
|
|
110
|
-
name:
|
|
111
|
-
message_ids: Optional[List[str]] = Field(None, description="The ids of the messages in the agent's in-context memory.")
|
|
84
|
+
name: str = Field(default_factory=lambda: create_random_username(), description="The name of the agent.")
|
|
112
85
|
|
|
113
86
|
# memory creation
|
|
114
87
|
memory_blocks: List[CreateBlock] = Field(
|
|
115
|
-
# [CreateHuman(), CreatePersona()], description="The blocks to create in the agent's in-context memory."
|
|
116
88
|
...,
|
|
117
89
|
description="The blocks to create in the agent's in-context memory.",
|
|
118
90
|
)
|
|
119
|
-
|
|
120
|
-
tools: List[str] = Field(
|
|
91
|
+
# TODO: This is a legacy field and should be removed ASAP to force `tool_ids` usage
|
|
92
|
+
tools: Optional[List[str]] = Field(None, description="The tools used by the agent.")
|
|
93
|
+
tool_ids: Optional[List[str]] = Field(None, description="The ids of the tools used by the agent.")
|
|
94
|
+
source_ids: Optional[List[str]] = Field(None, description="The ids of the sources used by the agent.")
|
|
95
|
+
block_ids: Optional[List[str]] = Field(None, description="The ids of the blocks used by the agent.")
|
|
121
96
|
tool_rules: Optional[List[ToolRule]] = Field(None, description="The tool rules governing the agent.")
|
|
122
97
|
tags: Optional[List[str]] = Field(None, description="The tags associated with the agent.")
|
|
123
98
|
system: Optional[str] = Field(None, description="The system prompt used by the agent.")
|
|
124
|
-
agent_type: AgentType = Field(AgentType.memgpt_agent, description="The type of agent.")
|
|
99
|
+
agent_type: AgentType = Field(default_factory=lambda: AgentType.memgpt_agent, description="The type of agent.")
|
|
125
100
|
llm_config: Optional[LLMConfig] = Field(None, description="The LLM configuration used by the agent.")
|
|
126
101
|
embedding_config: Optional[EmbeddingConfig] = Field(None, description="The embedding configuration used by the agent.")
|
|
127
102
|
# Note: if this is None, then we'll populate with the standard "more human than human" initial message sequence
|
|
@@ -129,6 +104,9 @@ class CreateAgent(BaseAgent): #
|
|
|
129
104
|
initial_message_sequence: Optional[List[MessageCreate]] = Field(
|
|
130
105
|
None, description="The initial set of messages to put in the agent's in-context memory."
|
|
131
106
|
)
|
|
107
|
+
include_base_tools: bool = Field(True, description="The LLM configuration used by the agent.")
|
|
108
|
+
description: Optional[str] = Field(None, description="The description of the agent.")
|
|
109
|
+
metadata_: Optional[Dict] = Field(None, description="The metadata of the agent.", alias="metadata_")
|
|
132
110
|
|
|
133
111
|
@field_validator("name")
|
|
134
112
|
@classmethod
|
|
@@ -156,17 +134,22 @@ class CreateAgent(BaseAgent): #
|
|
|
156
134
|
return name
|
|
157
135
|
|
|
158
136
|
|
|
159
|
-
class
|
|
160
|
-
id: str = Field(..., description="The id of the agent.")
|
|
137
|
+
class UpdateAgent(BaseModel):
|
|
161
138
|
name: Optional[str] = Field(None, description="The name of the agent.")
|
|
162
|
-
|
|
139
|
+
tool_ids: Optional[List[str]] = Field(None, description="The ids of the tools used by the agent.")
|
|
140
|
+
source_ids: Optional[List[str]] = Field(None, description="The ids of the sources used by the agent.")
|
|
141
|
+
block_ids: Optional[List[str]] = Field(None, description="The ids of the blocks used by the agent.")
|
|
163
142
|
tags: Optional[List[str]] = Field(None, description="The tags associated with the agent.")
|
|
164
143
|
system: Optional[str] = Field(None, description="The system prompt used by the agent.")
|
|
144
|
+
tool_rules: Optional[List[ToolRule]] = Field(None, description="The tool rules governing the agent.")
|
|
165
145
|
llm_config: Optional[LLMConfig] = Field(None, description="The LLM configuration used by the agent.")
|
|
166
146
|
embedding_config: Optional[EmbeddingConfig] = Field(None, description="The embedding configuration used by the agent.")
|
|
167
|
-
|
|
168
|
-
# TODO: determine if these should be editable via this schema?
|
|
169
147
|
message_ids: Optional[List[str]] = Field(None, description="The ids of the messages in the agent's in-context memory.")
|
|
148
|
+
description: Optional[str] = Field(None, description="The description of the agent.")
|
|
149
|
+
metadata_: Optional[Dict] = Field(None, description="The metadata of the agent.", alias="metadata_")
|
|
150
|
+
|
|
151
|
+
class Config:
|
|
152
|
+
extra = "ignore" # Ignores extra fields
|
|
170
153
|
|
|
171
154
|
|
|
172
155
|
class AgentStepResponse(BaseModel):
|
letta/schemas/memory.py
CHANGED
|
@@ -87,7 +87,7 @@ class Memory(BaseModel, validate_assignment=True):
|
|
|
87
87
|
Template(prompt_template)
|
|
88
88
|
|
|
89
89
|
# Validate compatibility with current memory structure
|
|
90
|
-
|
|
90
|
+
Template(prompt_template).render(blocks=self.blocks)
|
|
91
91
|
|
|
92
92
|
# If we get here, the template is valid and compatible
|
|
93
93
|
self.prompt_template = prompt_template
|
|
@@ -213,6 +213,7 @@ class ChatMemory(BasicBlockMemory):
|
|
|
213
213
|
human (str): The starter value for the human block.
|
|
214
214
|
limit (int): The character limit for each block.
|
|
215
215
|
"""
|
|
216
|
+
# TODO: Should these be CreateBlocks?
|
|
216
217
|
super().__init__(blocks=[Block(value=persona, limit=limit, label="persona"), Block(value=human, limit=limit, label="human")])
|
|
217
218
|
|
|
218
219
|
|
letta/schemas/sandbox_config.py
CHANGED
|
@@ -3,10 +3,11 @@ import json
|
|
|
3
3
|
from enum import Enum
|
|
4
4
|
from typing import Any, Dict, List, Optional, Union
|
|
5
5
|
|
|
6
|
-
from pydantic import BaseModel, Field
|
|
6
|
+
from pydantic import BaseModel, Field, model_validator
|
|
7
7
|
|
|
8
8
|
from letta.schemas.agent import AgentState
|
|
9
9
|
from letta.schemas.letta_base import LettaBase, OrmMetadataBase
|
|
10
|
+
from letta.settings import tool_settings
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
# Sandbox Config
|
|
@@ -45,6 +46,16 @@ class E2BSandboxConfig(BaseModel):
|
|
|
45
46
|
def type(self) -> "SandboxType":
|
|
46
47
|
return SandboxType.E2B
|
|
47
48
|
|
|
49
|
+
@model_validator(mode="before")
|
|
50
|
+
@classmethod
|
|
51
|
+
def set_default_template(cls, data: dict):
|
|
52
|
+
"""
|
|
53
|
+
Assign a default template value if the template field is not provided.
|
|
54
|
+
"""
|
|
55
|
+
if data.get("template") is None:
|
|
56
|
+
data["template"] = tool_settings.e2b_sandbox_template_id
|
|
57
|
+
return data
|
|
58
|
+
|
|
48
59
|
|
|
49
60
|
class SandboxConfigBase(OrmMetadataBase):
|
|
50
61
|
__id_prefix__ = "sandbox"
|
letta/server/rest_api/app.py
CHANGED
|
@@ -25,9 +25,6 @@ from letta.server.rest_api.interface import StreamingServerInterface
|
|
|
25
25
|
from letta.server.rest_api.routers.openai.assistants.assistants import (
|
|
26
26
|
router as openai_assistants_router,
|
|
27
27
|
)
|
|
28
|
-
from letta.server.rest_api.routers.openai.assistants.threads import (
|
|
29
|
-
router as openai_threads_router,
|
|
30
|
-
)
|
|
31
28
|
from letta.server.rest_api.routers.openai.chat_completions.chat_completions import (
|
|
32
29
|
router as openai_chat_completions_router,
|
|
33
30
|
)
|
|
@@ -215,7 +212,6 @@ def create_application() -> "FastAPI":
|
|
|
215
212
|
|
|
216
213
|
# openai
|
|
217
214
|
app.include_router(openai_assistants_router, prefix=OPENAI_API_PREFIX)
|
|
218
|
-
app.include_router(openai_threads_router, prefix=OPENAI_API_PREFIX)
|
|
219
215
|
app.include_router(openai_chat_completions_router, prefix=OPENAI_API_PREFIX)
|
|
220
216
|
|
|
221
217
|
# /api/auth endpoints
|
|
@@ -236,7 +232,6 @@ def create_application() -> "FastAPI":
|
|
|
236
232
|
@app.on_event("shutdown")
|
|
237
233
|
def on_shutdown():
|
|
238
234
|
global server
|
|
239
|
-
server.save_agents()
|
|
240
235
|
# server = None
|
|
241
236
|
|
|
242
237
|
return app
|
|
@@ -36,7 +36,7 @@ async def create_chat_completion(
|
|
|
36
36
|
The bearer token will be used to identify the user.
|
|
37
37
|
The 'user' field in the completion_request should be set to the agent ID.
|
|
38
38
|
"""
|
|
39
|
-
actor = server.get_user_or_default(user_id=user_id)
|
|
39
|
+
actor = server.user_manager.get_user_or_default(user_id=user_id)
|
|
40
40
|
|
|
41
41
|
agent_id = completion_request.user
|
|
42
42
|
if agent_id is None:
|