letta-nightly 0.4.1.dev20241014104152__py3-none-any.whl → 0.5.0.dev20241015014828__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_store/db.py +18 -7
- letta/agent_store/lancedb.py +2 -2
- letta/agent_store/milvus.py +1 -1
- letta/agent_store/qdrant.py +1 -1
- letta/agent_store/storage.py +12 -10
- letta/cli/cli_load.py +1 -1
- letta/client/client.py +51 -0
- letta/data_sources/connectors.py +124 -124
- letta/data_sources/connectors_helper.py +97 -0
- letta/llm_api/mistral.py +47 -0
- letta/metadata.py +58 -0
- letta/providers.py +44 -0
- letta/schemas/file.py +31 -0
- letta/schemas/job.py +1 -1
- letta/schemas/letta_request.py +3 -3
- letta/schemas/llm_config.py +1 -0
- letta/schemas/message.py +6 -2
- letta/schemas/passage.py +3 -3
- letta/schemas/source.py +2 -2
- letta/server/rest_api/routers/v1/agents.py +10 -16
- letta/server/rest_api/routers/v1/jobs.py +17 -1
- letta/server/rest_api/routers/v1/sources.py +7 -9
- letta/server/server.py +86 -13
- letta/server/static_files/assets/{index-9a9c449b.js → index-dc228d4a.js} +4 -4
- letta/server/static_files/index.html +1 -1
- {letta_nightly-0.4.1.dev20241014104152.dist-info → letta_nightly-0.5.0.dev20241015014828.dist-info}/METADATA +1 -1
- {letta_nightly-0.4.1.dev20241014104152.dist-info → letta_nightly-0.5.0.dev20241015014828.dist-info}/RECORD +31 -29
- letta/schemas/document.py +0 -21
- {letta_nightly-0.4.1.dev20241014104152.dist-info → letta_nightly-0.5.0.dev20241015014828.dist-info}/LICENSE +0 -0
- {letta_nightly-0.4.1.dev20241014104152.dist-info → letta_nightly-0.5.0.dev20241015014828.dist-info}/WHEEL +0 -0
- {letta_nightly-0.4.1.dev20241014104152.dist-info → letta_nightly-0.5.0.dev20241015014828.dist-info}/entry_points.txt +0 -0
letta/server/server.py
CHANGED
|
@@ -47,6 +47,7 @@ from letta.providers import (
|
|
|
47
47
|
AnthropicProvider,
|
|
48
48
|
AzureProvider,
|
|
49
49
|
GoogleAIProvider,
|
|
50
|
+
GroqProvider,
|
|
50
51
|
LettaProvider,
|
|
51
52
|
OllamaProvider,
|
|
52
53
|
OpenAIProvider,
|
|
@@ -63,16 +64,16 @@ from letta.schemas.block import (
|
|
|
63
64
|
CreatePersona,
|
|
64
65
|
UpdateBlock,
|
|
65
66
|
)
|
|
66
|
-
from letta.schemas.document import Document
|
|
67
67
|
from letta.schemas.embedding_config import EmbeddingConfig
|
|
68
68
|
|
|
69
69
|
# openai schemas
|
|
70
70
|
from letta.schemas.enums import JobStatus
|
|
71
|
+
from letta.schemas.file import FileMetadata
|
|
71
72
|
from letta.schemas.job import Job
|
|
72
73
|
from letta.schemas.letta_message import LettaMessage
|
|
73
74
|
from letta.schemas.llm_config import LLMConfig
|
|
74
75
|
from letta.schemas.memory import ArchivalMemorySummary, Memory, RecallMemorySummary
|
|
75
|
-
from letta.schemas.message import Message, UpdateMessage
|
|
76
|
+
from letta.schemas.message import Message, MessageCreate, MessageRole, UpdateMessage
|
|
76
77
|
from letta.schemas.openai.chat_completion_response import UsageStatistics
|
|
77
78
|
from letta.schemas.organization import Organization, OrganizationCreate
|
|
78
79
|
from letta.schemas.passage import Passage
|
|
@@ -141,6 +142,11 @@ class Server(object):
|
|
|
141
142
|
"""Process a message from the system, internally calls step"""
|
|
142
143
|
raise NotImplementedError
|
|
143
144
|
|
|
145
|
+
@abstractmethod
|
|
146
|
+
def send_messages(self, user_id: str, agent_id: str, messages: Union[MessageCreate, List[Message]]) -> None:
|
|
147
|
+
"""Send a list of messages to the agent"""
|
|
148
|
+
raise NotImplementedError
|
|
149
|
+
|
|
144
150
|
@abstractmethod
|
|
145
151
|
def run_command(self, user_id: str, agent_id: str, command: str) -> Union[str, None]:
|
|
146
152
|
"""Run a command on the agent, e.g. /memory
|
|
@@ -292,6 +298,12 @@ class SyncServer(Server):
|
|
|
292
298
|
base_url=model_settings.vllm_api_base,
|
|
293
299
|
)
|
|
294
300
|
)
|
|
301
|
+
if model_settings.groq_api_key:
|
|
302
|
+
self._enabled_providers.append(
|
|
303
|
+
GroqProvider(
|
|
304
|
+
api_key=model_settings.groq_api_key,
|
|
305
|
+
)
|
|
306
|
+
)
|
|
295
307
|
|
|
296
308
|
def save_agents(self):
|
|
297
309
|
"""Saves all the agents that are in the in-memory object store"""
|
|
@@ -725,6 +737,68 @@ class SyncServer(Server):
|
|
|
725
737
|
# Run the agent state forward
|
|
726
738
|
return self._step(user_id=user_id, agent_id=agent_id, input_messages=message)
|
|
727
739
|
|
|
740
|
+
def send_messages(
|
|
741
|
+
self,
|
|
742
|
+
user_id: str,
|
|
743
|
+
agent_id: str,
|
|
744
|
+
messages: Union[List[MessageCreate], List[Message]],
|
|
745
|
+
# whether or not to wrap user and system message as MemGPT-style stringified JSON
|
|
746
|
+
wrap_user_message: bool = True,
|
|
747
|
+
wrap_system_message: bool = True,
|
|
748
|
+
) -> LettaUsageStatistics:
|
|
749
|
+
"""Send a list of messages to the agent
|
|
750
|
+
|
|
751
|
+
If the messages are of type MessageCreate, we need to turn them into
|
|
752
|
+
Message objects first before sending them through step.
|
|
753
|
+
|
|
754
|
+
Otherwise, we can pass them in directly.
|
|
755
|
+
"""
|
|
756
|
+
if self.ms.get_user(user_id=user_id) is None:
|
|
757
|
+
raise ValueError(f"User user_id={user_id} does not exist")
|
|
758
|
+
if self.ms.get_agent(agent_id=agent_id, user_id=user_id) is None:
|
|
759
|
+
raise ValueError(f"Agent agent_id={agent_id} does not exist")
|
|
760
|
+
|
|
761
|
+
message_objects: List[Message] = []
|
|
762
|
+
|
|
763
|
+
if all(isinstance(m, MessageCreate) for m in messages):
|
|
764
|
+
for message in messages:
|
|
765
|
+
assert isinstance(message, MessageCreate)
|
|
766
|
+
|
|
767
|
+
# If wrapping is eanbled, wrap with metadata before placing content inside the Message object
|
|
768
|
+
if message.role == MessageRole.user and wrap_user_message:
|
|
769
|
+
message.text = system.package_user_message(user_message=message.text)
|
|
770
|
+
elif message.role == MessageRole.system and wrap_system_message:
|
|
771
|
+
message.text = system.package_system_message(system_message=message.text)
|
|
772
|
+
else:
|
|
773
|
+
raise ValueError(f"Invalid message role: {message.role}")
|
|
774
|
+
|
|
775
|
+
# Create the Message object
|
|
776
|
+
message_objects.append(
|
|
777
|
+
Message(
|
|
778
|
+
user_id=user_id,
|
|
779
|
+
agent_id=agent_id,
|
|
780
|
+
role=message.role,
|
|
781
|
+
text=message.text,
|
|
782
|
+
name=message.name,
|
|
783
|
+
# assigned later?
|
|
784
|
+
model=None,
|
|
785
|
+
# irrelevant
|
|
786
|
+
tool_calls=None,
|
|
787
|
+
tool_call_id=None,
|
|
788
|
+
)
|
|
789
|
+
)
|
|
790
|
+
|
|
791
|
+
elif all(isinstance(m, Message) for m in messages):
|
|
792
|
+
for message in messages:
|
|
793
|
+
assert isinstance(message, Message)
|
|
794
|
+
message_objects.append(message)
|
|
795
|
+
|
|
796
|
+
else:
|
|
797
|
+
raise ValueError(f"All messages must be of type Message or MessageCreate, got {type(messages)}")
|
|
798
|
+
|
|
799
|
+
# Run the agent state forward
|
|
800
|
+
return self._step(user_id=user_id, agent_id=agent_id, input_messages=message_objects)
|
|
801
|
+
|
|
728
802
|
# @LockingServer.agent_lock_decorator
|
|
729
803
|
def run_command(self, user_id: str, agent_id: str, command: str) -> LettaUsageStatistics:
|
|
730
804
|
"""Run a command on the agent"""
|
|
@@ -1596,7 +1670,7 @@ class SyncServer(Server):
|
|
|
1596
1670
|
# job.status = JobStatus.failed
|
|
1597
1671
|
# job.metadata_["error"] = error
|
|
1598
1672
|
# self.ms.update_job(job)
|
|
1599
|
-
# # TODO: delete any associated passages/
|
|
1673
|
+
# # TODO: delete any associated passages/files?
|
|
1600
1674
|
|
|
1601
1675
|
# # return failed job
|
|
1602
1676
|
# return job
|
|
@@ -1625,11 +1699,10 @@ class SyncServer(Server):
|
|
|
1625
1699
|
|
|
1626
1700
|
# get the data connectors
|
|
1627
1701
|
passage_store = StorageConnector.get_storage_connector(TableType.PASSAGES, self.config, user_id=user_id)
|
|
1628
|
-
|
|
1629
|
-
document_store = None # StorageConnector.get_storage_connector(TableType.DOCUMENTS, self.config, user_id=user_id)
|
|
1702
|
+
file_store = StorageConnector.get_storage_connector(TableType.FILES, self.config, user_id=user_id)
|
|
1630
1703
|
|
|
1631
1704
|
# load data into the document store
|
|
1632
|
-
passage_count, document_count = load_data(connector, source, passage_store,
|
|
1705
|
+
passage_count, document_count = load_data(connector, source, passage_store, file_store)
|
|
1633
1706
|
return passage_count, document_count
|
|
1634
1707
|
|
|
1635
1708
|
def attach_source_to_agent(
|
|
@@ -1686,14 +1759,14 @@ class SyncServer(Server):
|
|
|
1686
1759
|
# list all attached sources to an agent
|
|
1687
1760
|
return self.ms.list_attached_sources(agent_id)
|
|
1688
1761
|
|
|
1762
|
+
def list_files_from_source(self, source_id: str, limit: int = 1000, cursor: Optional[str] = None) -> List[FileMetadata]:
|
|
1763
|
+
# list all attached sources to an agent
|
|
1764
|
+
return self.ms.list_files_from_source(source_id=source_id, limit=limit, cursor=cursor)
|
|
1765
|
+
|
|
1689
1766
|
def list_data_source_passages(self, user_id: str, source_id: str) -> List[Passage]:
|
|
1690
1767
|
warnings.warn("list_data_source_passages is not yet implemented, returning empty list.", category=UserWarning)
|
|
1691
1768
|
return []
|
|
1692
1769
|
|
|
1693
|
-
def list_data_source_documents(self, user_id: str, source_id: str) -> List[Document]:
|
|
1694
|
-
warnings.warn("list_data_source_documents is not yet implemented, returning empty list.", category=UserWarning)
|
|
1695
|
-
return []
|
|
1696
|
-
|
|
1697
1770
|
def list_all_sources(self, user_id: str) -> List[Source]:
|
|
1698
1771
|
"""List all sources (w/ extra metadata) belonging to a user"""
|
|
1699
1772
|
|
|
@@ -1707,9 +1780,9 @@ class SyncServer(Server):
|
|
|
1707
1780
|
passage_conn = StorageConnector.get_storage_connector(TableType.PASSAGES, self.config, user_id=user_id)
|
|
1708
1781
|
num_passages = passage_conn.size({"source_id": source.id})
|
|
1709
1782
|
|
|
1710
|
-
# TODO: add when
|
|
1711
|
-
## count number of
|
|
1712
|
-
# document_conn = StorageConnector.get_storage_connector(TableType.
|
|
1783
|
+
# TODO: add when files table implemented
|
|
1784
|
+
## count number of files
|
|
1785
|
+
# document_conn = StorageConnector.get_storage_connector(TableType.FILES, self.config, user_id=user_id)
|
|
1713
1786
|
# num_documents = document_conn.size({"data_source": source.name})
|
|
1714
1787
|
num_documents = 0
|
|
1715
1788
|
|