letta-nightly 0.1.7.dev20240924104148__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.

Files changed (189) hide show
  1. letta/__init__.py +24 -0
  2. letta/__main__.py +3 -0
  3. letta/agent.py +1427 -0
  4. letta/agent_store/chroma.py +295 -0
  5. letta/agent_store/db.py +546 -0
  6. letta/agent_store/lancedb.py +177 -0
  7. letta/agent_store/milvus.py +198 -0
  8. letta/agent_store/qdrant.py +201 -0
  9. letta/agent_store/storage.py +188 -0
  10. letta/benchmark/benchmark.py +96 -0
  11. letta/benchmark/constants.py +14 -0
  12. letta/cli/cli.py +689 -0
  13. letta/cli/cli_config.py +1282 -0
  14. letta/cli/cli_load.py +166 -0
  15. letta/client/__init__.py +0 -0
  16. letta/client/admin.py +171 -0
  17. letta/client/client.py +2360 -0
  18. letta/client/streaming.py +90 -0
  19. letta/client/utils.py +61 -0
  20. letta/config.py +484 -0
  21. letta/configs/anthropic.json +13 -0
  22. letta/configs/letta_hosted.json +11 -0
  23. letta/configs/openai.json +12 -0
  24. letta/constants.py +134 -0
  25. letta/credentials.py +140 -0
  26. letta/data_sources/connectors.py +247 -0
  27. letta/embeddings.py +218 -0
  28. letta/errors.py +26 -0
  29. letta/functions/__init__.py +0 -0
  30. letta/functions/function_sets/base.py +174 -0
  31. letta/functions/function_sets/extras.py +132 -0
  32. letta/functions/functions.py +105 -0
  33. letta/functions/schema_generator.py +205 -0
  34. letta/humans/__init__.py +0 -0
  35. letta/humans/examples/basic.txt +1 -0
  36. letta/humans/examples/cs_phd.txt +9 -0
  37. letta/interface.py +314 -0
  38. letta/llm_api/__init__.py +0 -0
  39. letta/llm_api/anthropic.py +383 -0
  40. letta/llm_api/azure_openai.py +155 -0
  41. letta/llm_api/cohere.py +396 -0
  42. letta/llm_api/google_ai.py +468 -0
  43. letta/llm_api/llm_api_tools.py +485 -0
  44. letta/llm_api/openai.py +470 -0
  45. letta/local_llm/README.md +3 -0
  46. letta/local_llm/__init__.py +0 -0
  47. letta/local_llm/chat_completion_proxy.py +279 -0
  48. letta/local_llm/constants.py +31 -0
  49. letta/local_llm/function_parser.py +68 -0
  50. letta/local_llm/grammars/__init__.py +0 -0
  51. letta/local_llm/grammars/gbnf_grammar_generator.py +1324 -0
  52. letta/local_llm/grammars/json.gbnf +26 -0
  53. letta/local_llm/grammars/json_func_calls_with_inner_thoughts.gbnf +32 -0
  54. letta/local_llm/groq/api.py +97 -0
  55. letta/local_llm/json_parser.py +202 -0
  56. letta/local_llm/koboldcpp/api.py +62 -0
  57. letta/local_llm/koboldcpp/settings.py +23 -0
  58. letta/local_llm/llamacpp/api.py +58 -0
  59. letta/local_llm/llamacpp/settings.py +22 -0
  60. letta/local_llm/llm_chat_completion_wrappers/__init__.py +0 -0
  61. letta/local_llm/llm_chat_completion_wrappers/airoboros.py +452 -0
  62. letta/local_llm/llm_chat_completion_wrappers/chatml.py +470 -0
  63. letta/local_llm/llm_chat_completion_wrappers/configurable_wrapper.py +387 -0
  64. letta/local_llm/llm_chat_completion_wrappers/dolphin.py +246 -0
  65. letta/local_llm/llm_chat_completion_wrappers/llama3.py +345 -0
  66. letta/local_llm/llm_chat_completion_wrappers/simple_summary_wrapper.py +156 -0
  67. letta/local_llm/llm_chat_completion_wrappers/wrapper_base.py +11 -0
  68. letta/local_llm/llm_chat_completion_wrappers/zephyr.py +345 -0
  69. letta/local_llm/lmstudio/api.py +100 -0
  70. letta/local_llm/lmstudio/settings.py +29 -0
  71. letta/local_llm/ollama/api.py +88 -0
  72. letta/local_llm/ollama/settings.py +32 -0
  73. letta/local_llm/settings/__init__.py +0 -0
  74. letta/local_llm/settings/deterministic_mirostat.py +45 -0
  75. letta/local_llm/settings/settings.py +72 -0
  76. letta/local_llm/settings/simple.py +28 -0
  77. letta/local_llm/utils.py +265 -0
  78. letta/local_llm/vllm/api.py +63 -0
  79. letta/local_llm/webui/api.py +60 -0
  80. letta/local_llm/webui/legacy_api.py +58 -0
  81. letta/local_llm/webui/legacy_settings.py +23 -0
  82. letta/local_llm/webui/settings.py +24 -0
  83. letta/log.py +76 -0
  84. letta/main.py +437 -0
  85. letta/memory.py +440 -0
  86. letta/metadata.py +884 -0
  87. letta/openai_backcompat/__init__.py +0 -0
  88. letta/openai_backcompat/openai_object.py +437 -0
  89. letta/persistence_manager.py +148 -0
  90. letta/personas/__init__.py +0 -0
  91. letta/personas/examples/anna_pa.txt +13 -0
  92. letta/personas/examples/google_search_persona.txt +15 -0
  93. letta/personas/examples/memgpt_doc.txt +6 -0
  94. letta/personas/examples/memgpt_starter.txt +4 -0
  95. letta/personas/examples/sam.txt +14 -0
  96. letta/personas/examples/sam_pov.txt +14 -0
  97. letta/personas/examples/sam_simple_pov_gpt35.txt +13 -0
  98. letta/personas/examples/sqldb/test.db +0 -0
  99. letta/prompts/__init__.py +0 -0
  100. letta/prompts/gpt_summarize.py +14 -0
  101. letta/prompts/gpt_system.py +26 -0
  102. letta/prompts/system/memgpt_base.txt +49 -0
  103. letta/prompts/system/memgpt_chat.txt +58 -0
  104. letta/prompts/system/memgpt_chat_compressed.txt +13 -0
  105. letta/prompts/system/memgpt_chat_fstring.txt +51 -0
  106. letta/prompts/system/memgpt_doc.txt +50 -0
  107. letta/prompts/system/memgpt_gpt35_extralong.txt +53 -0
  108. letta/prompts/system/memgpt_intuitive_knowledge.txt +31 -0
  109. letta/prompts/system/memgpt_modified_chat.txt +23 -0
  110. letta/pytest.ini +0 -0
  111. letta/schemas/agent.py +117 -0
  112. letta/schemas/api_key.py +21 -0
  113. letta/schemas/block.py +135 -0
  114. letta/schemas/document.py +21 -0
  115. letta/schemas/embedding_config.py +54 -0
  116. letta/schemas/enums.py +35 -0
  117. letta/schemas/job.py +38 -0
  118. letta/schemas/letta_base.py +80 -0
  119. letta/schemas/letta_message.py +175 -0
  120. letta/schemas/letta_request.py +23 -0
  121. letta/schemas/letta_response.py +28 -0
  122. letta/schemas/llm_config.py +54 -0
  123. letta/schemas/memory.py +224 -0
  124. letta/schemas/message.py +727 -0
  125. letta/schemas/openai/chat_completion_request.py +123 -0
  126. letta/schemas/openai/chat_completion_response.py +136 -0
  127. letta/schemas/openai/chat_completions.py +123 -0
  128. letta/schemas/openai/embedding_response.py +11 -0
  129. letta/schemas/openai/openai.py +157 -0
  130. letta/schemas/organization.py +20 -0
  131. letta/schemas/passage.py +80 -0
  132. letta/schemas/source.py +62 -0
  133. letta/schemas/tool.py +143 -0
  134. letta/schemas/usage.py +18 -0
  135. letta/schemas/user.py +33 -0
  136. letta/server/__init__.py +0 -0
  137. letta/server/constants.py +6 -0
  138. letta/server/rest_api/__init__.py +0 -0
  139. letta/server/rest_api/admin/__init__.py +0 -0
  140. letta/server/rest_api/admin/agents.py +21 -0
  141. letta/server/rest_api/admin/tools.py +83 -0
  142. letta/server/rest_api/admin/users.py +98 -0
  143. letta/server/rest_api/app.py +193 -0
  144. letta/server/rest_api/auth/__init__.py +0 -0
  145. letta/server/rest_api/auth/index.py +43 -0
  146. letta/server/rest_api/auth_token.py +22 -0
  147. letta/server/rest_api/interface.py +726 -0
  148. letta/server/rest_api/routers/__init__.py +0 -0
  149. letta/server/rest_api/routers/openai/__init__.py +0 -0
  150. letta/server/rest_api/routers/openai/assistants/__init__.py +0 -0
  151. letta/server/rest_api/routers/openai/assistants/assistants.py +115 -0
  152. letta/server/rest_api/routers/openai/assistants/schemas.py +121 -0
  153. letta/server/rest_api/routers/openai/assistants/threads.py +336 -0
  154. letta/server/rest_api/routers/openai/chat_completions/__init__.py +0 -0
  155. letta/server/rest_api/routers/openai/chat_completions/chat_completions.py +131 -0
  156. letta/server/rest_api/routers/v1/__init__.py +15 -0
  157. letta/server/rest_api/routers/v1/agents.py +543 -0
  158. letta/server/rest_api/routers/v1/blocks.py +73 -0
  159. letta/server/rest_api/routers/v1/jobs.py +46 -0
  160. letta/server/rest_api/routers/v1/llms.py +28 -0
  161. letta/server/rest_api/routers/v1/organizations.py +61 -0
  162. letta/server/rest_api/routers/v1/sources.py +199 -0
  163. letta/server/rest_api/routers/v1/tools.py +103 -0
  164. letta/server/rest_api/routers/v1/users.py +109 -0
  165. letta/server/rest_api/static_files.py +74 -0
  166. letta/server/rest_api/utils.py +69 -0
  167. letta/server/server.py +1995 -0
  168. letta/server/startup.sh +8 -0
  169. letta/server/static_files/assets/index-0cbf7ad5.js +274 -0
  170. letta/server/static_files/assets/index-156816da.css +1 -0
  171. letta/server/static_files/assets/index-486e3228.js +274 -0
  172. letta/server/static_files/favicon.ico +0 -0
  173. letta/server/static_files/index.html +39 -0
  174. letta/server/static_files/memgpt_logo_transparent.png +0 -0
  175. letta/server/utils.py +46 -0
  176. letta/server/ws_api/__init__.py +0 -0
  177. letta/server/ws_api/example_client.py +104 -0
  178. letta/server/ws_api/interface.py +108 -0
  179. letta/server/ws_api/protocol.py +100 -0
  180. letta/server/ws_api/server.py +145 -0
  181. letta/settings.py +165 -0
  182. letta/streaming_interface.py +396 -0
  183. letta/system.py +207 -0
  184. letta/utils.py +1065 -0
  185. letta_nightly-0.1.7.dev20240924104148.dist-info/LICENSE +190 -0
  186. letta_nightly-0.1.7.dev20240924104148.dist-info/METADATA +98 -0
  187. letta_nightly-0.1.7.dev20240924104148.dist-info/RECORD +189 -0
  188. letta_nightly-0.1.7.dev20240924104148.dist-info/WHEEL +4 -0
  189. letta_nightly-0.1.7.dev20240924104148.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,188 @@
1
+ """ These classes define storage connectors.
2
+
3
+ We originally tried to use Llama Index VectorIndex, but their limited API was extremely problematic.
4
+ """
5
+
6
+ import uuid
7
+ from abc import abstractmethod
8
+ from typing import Dict, List, Optional, Tuple, Type, Union
9
+
10
+ from pydantic import BaseModel
11
+
12
+ from letta.config import LettaConfig
13
+ from letta.schemas.document import Document
14
+ from letta.schemas.message import Message
15
+ from letta.schemas.passage import Passage
16
+ from letta.utils import printd
17
+
18
+
19
+ # ENUM representing table types in Letta
20
+ # each table corresponds to a different table schema (specified in data_types.py)
21
+ class TableType:
22
+ ARCHIVAL_MEMORY = "archival_memory" # recall memory table: letta_agent_{agent_id}
23
+ RECALL_MEMORY = "recall_memory" # archival memory table: letta_agent_recall_{agent_id}
24
+ PASSAGES = "passages" # TODO
25
+ DOCUMENTS = "documents" # TODO
26
+
27
+
28
+ # table names used by Letta
29
+
30
+ # agent tables
31
+ RECALL_TABLE_NAME = "letta_recall_memory_agent" # agent memory
32
+ ARCHIVAL_TABLE_NAME = "letta_archival_memory_agent" # agent memory
33
+
34
+ # external data source tables
35
+ PASSAGE_TABLE_NAME = "letta_passages" # chunked/embedded passages (from source)
36
+ DOCUMENT_TABLE_NAME = "letta_documents" # original documents (from source)
37
+
38
+
39
+ class StorageConnector:
40
+ """Defines a DB connection that is user-specific to access data: Documents, Passages, Archival/Recall Memory"""
41
+
42
+ type: Type[BaseModel]
43
+
44
+ def __init__(
45
+ self,
46
+ table_type: Union[TableType.ARCHIVAL_MEMORY, TableType.RECALL_MEMORY, TableType.PASSAGES, TableType.DOCUMENTS],
47
+ config: LettaConfig,
48
+ user_id,
49
+ agent_id=None,
50
+ ):
51
+ self.user_id = user_id
52
+ self.agent_id = agent_id
53
+ self.table_type = table_type
54
+
55
+ # get object type
56
+ if table_type == TableType.ARCHIVAL_MEMORY:
57
+ self.type = Passage
58
+ self.table_name = ARCHIVAL_TABLE_NAME
59
+ elif table_type == TableType.RECALL_MEMORY:
60
+ self.type = Message
61
+ self.table_name = RECALL_TABLE_NAME
62
+ elif table_type == TableType.DOCUMENTS:
63
+ self.type = Document
64
+ self.table_name == DOCUMENT_TABLE_NAME
65
+ elif table_type == TableType.PASSAGES:
66
+ self.type = Passage
67
+ self.table_name = PASSAGE_TABLE_NAME
68
+ else:
69
+ raise ValueError(f"Table type {table_type} not implemented")
70
+ printd(f"Using table name {self.table_name}")
71
+
72
+ # setup base filters for agent-specific tables
73
+ if self.table_type == TableType.ARCHIVAL_MEMORY or self.table_type == TableType.RECALL_MEMORY:
74
+ # agent-specific table
75
+ assert agent_id is not None, "Agent ID must be provided for agent-specific tables"
76
+ self.filters = {"user_id": self.user_id, "agent_id": self.agent_id}
77
+ elif self.table_type == TableType.PASSAGES or self.table_type == TableType.DOCUMENTS:
78
+ # setup base filters for user-specific tables
79
+ assert agent_id is None, "Agent ID must not be provided for user-specific tables"
80
+ self.filters = {"user_id": self.user_id}
81
+ else:
82
+ raise ValueError(f"Table type {table_type} not implemented")
83
+
84
+ @staticmethod
85
+ def get_storage_connector(
86
+ table_type: Union[TableType.ARCHIVAL_MEMORY, TableType.RECALL_MEMORY, TableType.PASSAGES, TableType.DOCUMENTS],
87
+ config: LettaConfig,
88
+ user_id,
89
+ agent_id=None,
90
+ ):
91
+ if table_type == TableType.ARCHIVAL_MEMORY or table_type == TableType.PASSAGES:
92
+ storage_type = config.archival_storage_type
93
+ elif table_type == TableType.RECALL_MEMORY:
94
+ storage_type = config.recall_storage_type
95
+ else:
96
+ raise ValueError(f"Table type {table_type} not implemented")
97
+
98
+ if storage_type == "postgres":
99
+ from letta.agent_store.db import PostgresStorageConnector
100
+
101
+ return PostgresStorageConnector(table_type, config, user_id, agent_id)
102
+ elif storage_type == "chroma":
103
+ from letta.agent_store.chroma import ChromaStorageConnector
104
+
105
+ return ChromaStorageConnector(table_type, config, user_id, agent_id)
106
+
107
+ elif storage_type == "qdrant":
108
+ from letta.agent_store.qdrant import QdrantStorageConnector
109
+
110
+ return QdrantStorageConnector(table_type, config, user_id, agent_id)
111
+ # TODO: add back
112
+ # elif storage_type == "lancedb":
113
+ # from letta.agent_store.db import LanceDBConnector
114
+
115
+ # return LanceDBConnector(agent_config=agent_config, table_type=table_type)
116
+
117
+ elif storage_type == "sqlite":
118
+ from letta.agent_store.db import SQLLiteStorageConnector
119
+
120
+ return SQLLiteStorageConnector(table_type, config, user_id, agent_id)
121
+ elif storage_type == "milvus":
122
+ from letta.agent_store.milvus import MilvusStorageConnector
123
+
124
+ return MilvusStorageConnector(table_type, config, user_id, agent_id)
125
+ else:
126
+ raise NotImplementedError(f"Storage type {storage_type} not implemented")
127
+
128
+ @staticmethod
129
+ def get_archival_storage_connector(user_id, agent_id):
130
+ config = LettaConfig.load()
131
+ return StorageConnector.get_storage_connector(TableType.ARCHIVAL_MEMORY, config, user_id, agent_id)
132
+
133
+ @staticmethod
134
+ def get_recall_storage_connector(user_id, agent_id):
135
+ config = LettaConfig.load()
136
+ return StorageConnector.get_storage_connector(TableType.RECALL_MEMORY, config, user_id, agent_id)
137
+
138
+ @abstractmethod
139
+ def get_filters(self, filters: Optional[Dict] = {}) -> Union[Tuple[list, dict], dict]:
140
+ pass
141
+
142
+ @abstractmethod
143
+ def get_all_paginated(self, filters: Optional[Dict] = {}, page_size: int = 1000):
144
+ pass
145
+
146
+ @abstractmethod
147
+ def get_all(self, filters: Optional[Dict] = {}, limit=10):
148
+ pass
149
+
150
+ @abstractmethod
151
+ def get(self, id: uuid.UUID):
152
+ pass
153
+
154
+ @abstractmethod
155
+ def size(self, filters: Optional[Dict] = {}) -> int:
156
+ pass
157
+
158
+ @abstractmethod
159
+ def insert(self, record):
160
+ pass
161
+
162
+ @abstractmethod
163
+ def insert_many(self, records, show_progress=False):
164
+ pass
165
+
166
+ @abstractmethod
167
+ def query(self, query: str, query_vec: List[float], top_k: int = 10, filters: Optional[Dict] = {}):
168
+ pass
169
+
170
+ @abstractmethod
171
+ def query_date(self, start_date, end_date):
172
+ pass
173
+
174
+ @abstractmethod
175
+ def query_text(self, query):
176
+ pass
177
+
178
+ @abstractmethod
179
+ def delete_table(self):
180
+ pass
181
+
182
+ @abstractmethod
183
+ def delete(self, filters: Optional[Dict] = {}):
184
+ pass
185
+
186
+ @abstractmethod
187
+ def save(self):
188
+ pass
@@ -0,0 +1,96 @@
1
+ # type: ignore
2
+
3
+ import time
4
+ import uuid
5
+ from typing import Annotated
6
+
7
+ import typer
8
+
9
+ from letta import create_client
10
+ from letta.benchmark.constants import HUMAN, PERSONA, PROMPTS, TRIES
11
+ from letta.config import LettaConfig
12
+
13
+ # from letta.agent import Agent
14
+ from letta.errors import LLMJSONParsingError
15
+ from letta.utils import get_human_text, get_persona_text
16
+
17
+ app = typer.Typer()
18
+
19
+
20
+ def send_message(message: str, agent_id, turn: int, fn_type: str, print_msg: bool = False, n_tries: int = TRIES):
21
+ try:
22
+ print_msg = f"\t-> Now running {fn_type}. Progress: {turn}/{n_tries}"
23
+ print(print_msg, end="\r", flush=True)
24
+ response = client.user_message(agent_id=agent_id, message=message, return_token_count=True)
25
+
26
+ if turn + 1 == n_tries:
27
+ print(" " * len(print_msg), end="\r", flush=True)
28
+
29
+ for r in response:
30
+ if "function_call" in r and fn_type in r["function_call"] and any("assistant_message" in re for re in response):
31
+ return True, r["function_call"]
32
+
33
+ return False, "No function called."
34
+ except LLMJSONParsingError as e:
35
+ print(f"Error in parsing Letta JSON: {e}")
36
+ return False, "Failed to decode valid Letta JSON from LLM output."
37
+ except Exception as e:
38
+ print(f"An unexpected error occurred: {e}")
39
+ return False, "An unexpected error occurred."
40
+
41
+
42
+ @app.command()
43
+ def bench(
44
+ print_messages: Annotated[bool, typer.Option("--messages", help="Print functions calls and messages from the agent.")] = False,
45
+ n_tries: Annotated[int, typer.Option("--n-tries", help="Number of benchmark tries to perform for each function.")] = TRIES,
46
+ ):
47
+ client = create_client()
48
+ print(f"\nDepending on your hardware, this may take up to 30 minutes. This will also create {n_tries * len(PROMPTS)} new agents.\n")
49
+ config = LettaConfig.load()
50
+ print(f"version = {config.letta_version}")
51
+
52
+ total_score, total_tokens_accumulated, elapsed_time = 0, 0, 0
53
+
54
+ for fn_type, message in PROMPTS.items():
55
+ score = 0
56
+ start_time_run = time.time()
57
+ bench_id = uuid.uuid4()
58
+
59
+ for i in range(n_tries):
60
+ agent = client.create_agent(
61
+ name=f"benchmark_{bench_id}_agent_{i}",
62
+ persona=get_persona_text(PERSONA),
63
+ human=get_human_text(HUMAN),
64
+ )
65
+
66
+ agent_id = agent.id
67
+ result, msg = send_message(
68
+ message=message, agent_id=agent_id, turn=i, fn_type=fn_type, print_msg=print_messages, n_tries=n_tries
69
+ )
70
+
71
+ if print_messages:
72
+ print(f"\t{msg}")
73
+
74
+ if result:
75
+ score += 1
76
+
77
+ # TODO: add back once we start tracking usage via the client
78
+ # total_tokens_accumulated += tokens_accumulated
79
+
80
+ elapsed_time_run = round(time.time() - start_time_run, 2)
81
+ print(f"Score for {fn_type}: {score}/{n_tries}, took {elapsed_time_run} seconds")
82
+
83
+ elapsed_time += elapsed_time_run
84
+ total_score += score
85
+
86
+ print(f"\nMEMGPT VERSION: {config.letta_version}")
87
+ print(f"CONTEXT WINDOW: {config.default_llm_config.context_window}")
88
+ print(f"MODEL WRAPPER: {config.default_llm_config.model_wrapper}")
89
+ print(f"PRESET: {config.preset}")
90
+ print(f"PERSONA: {config.persona}")
91
+ print(f"HUMAN: {config.human}")
92
+
93
+ print(
94
+ # f"\n\t-> Total score: {total_score}/{len(PROMPTS) * n_tries}, took {elapsed_time} seconds at average of {round(total_tokens_accumulated/elapsed_time, 2)} t/s\n"
95
+ f"\n\t-> Total score: {total_score}/{len(PROMPTS) * n_tries}, took {elapsed_time} seconds\n"
96
+ )
@@ -0,0 +1,14 @@
1
+ # Basic
2
+ TRIES = 3
3
+ AGENT_NAME = "benchmark"
4
+ PERSONA = "sam_pov"
5
+ HUMAN = "cs_phd"
6
+
7
+ # Prompts
8
+ PROMPTS = {
9
+ "core_memory_replace": "Hey there, my name is John, what is yours?",
10
+ "core_memory_append": "I want you to remember that I like soccers for later.",
11
+ "conversation_search": "Do you remember when I talked about bananas?",
12
+ "archival_memory_insert": "Can you make sure to remember that I like programming for me so you can look it up later?",
13
+ "archival_memory_search": "Can you retrieve information about the war?",
14
+ }