letta-nightly 0.4.1.dev20241011104054__py3-none-any.whl → 0.4.1.dev20241013104006__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/agent.py +1 -1
- letta/agent_store/db.py +8 -2
- letta/base.py +3 -0
- letta/cli/cli.py +2 -18
- letta/llm_api/azure_openai.py +1 -1
- letta/llm_api/helpers.py +1 -0
- letta/llm_api/llm_api_tools.py +17 -13
- letta/llm_api/openai.py +21 -17
- letta/local_llm/chat_completion_proxy.py +1 -3
- letta/local_llm/vllm/api.py +1 -1
- letta/metadata.py +3 -4
- letta/providers.py +93 -9
- letta/schemas/embedding_config.py +7 -0
- letta/schemas/llm_config.py +7 -0
- letta/server/server.py +51 -40
- letta/settings.py +12 -3
- {letta_nightly-0.4.1.dev20241011104054.dist-info → letta_nightly-0.4.1.dev20241013104006.dist-info}/METADATA +2 -1
- {letta_nightly-0.4.1.dev20241011104054.dist-info → letta_nightly-0.4.1.dev20241013104006.dist-info}/RECORD +21 -20
- {letta_nightly-0.4.1.dev20241011104054.dist-info → letta_nightly-0.4.1.dev20241013104006.dist-info}/LICENSE +0 -0
- {letta_nightly-0.4.1.dev20241011104054.dist-info → letta_nightly-0.4.1.dev20241013104006.dist-info}/WHEEL +0 -0
- {letta_nightly-0.4.1.dev20241011104054.dist-info → letta_nightly-0.4.1.dev20241013104006.dist-info}/entry_points.txt +0 -0
letta/agent.py
CHANGED
|
@@ -481,7 +481,7 @@ class Agent(BaseAgent):
|
|
|
481
481
|
first_message=first_message,
|
|
482
482
|
# streaming
|
|
483
483
|
stream=stream,
|
|
484
|
-
|
|
484
|
+
stream_interface=self.interface,
|
|
485
485
|
# putting inner thoughts in func args or not
|
|
486
486
|
inner_thoughts_in_kwargs_option=inner_thoughts_in_kwargs_option,
|
|
487
487
|
)
|
letta/agent_store/db.py
CHANGED
|
@@ -18,13 +18,14 @@ from sqlalchemy import (
|
|
|
18
18
|
select,
|
|
19
19
|
text,
|
|
20
20
|
)
|
|
21
|
-
from sqlalchemy.orm import
|
|
21
|
+
from sqlalchemy.orm import mapped_column
|
|
22
22
|
from sqlalchemy.orm.session import close_all_sessions
|
|
23
23
|
from sqlalchemy.sql import func
|
|
24
24
|
from sqlalchemy_json import MutableJson
|
|
25
25
|
from tqdm import tqdm
|
|
26
26
|
|
|
27
27
|
from letta.agent_store.storage import StorageConnector, TableType
|
|
28
|
+
from letta.base import Base
|
|
28
29
|
from letta.config import LettaConfig
|
|
29
30
|
from letta.constants import MAX_EMBEDDING_DIM
|
|
30
31
|
from letta.metadata import EmbeddingConfigColumn, ToolCallColumn
|
|
@@ -35,7 +36,6 @@ from letta.schemas.openai.chat_completions import ToolCall
|
|
|
35
36
|
from letta.schemas.passage import Passage
|
|
36
37
|
from letta.settings import settings
|
|
37
38
|
|
|
38
|
-
Base = declarative_base()
|
|
39
39
|
config = LettaConfig()
|
|
40
40
|
|
|
41
41
|
|
|
@@ -560,3 +560,9 @@ class SQLLiteStorageConnector(SQLStorageConnector):
|
|
|
560
560
|
|
|
561
561
|
# Commit the changes to the database
|
|
562
562
|
session.commit()
|
|
563
|
+
|
|
564
|
+
|
|
565
|
+
def attach_base():
|
|
566
|
+
# This should be invoked in server.py to make sure Base gets initialized properly
|
|
567
|
+
# DO NOT REMOVE
|
|
568
|
+
print("Initializing database...")
|
letta/base.py
ADDED
letta/cli/cli.py
CHANGED
|
@@ -14,9 +14,7 @@ from letta.constants import CLI_WARNING_PREFIX, LETTA_DIR
|
|
|
14
14
|
from letta.local_llm.constants import ASSISTANT_MESSAGE_CLI_SYMBOL
|
|
15
15
|
from letta.log import get_logger
|
|
16
16
|
from letta.metadata import MetadataStore
|
|
17
|
-
from letta.schemas.embedding_config import EmbeddingConfig
|
|
18
17
|
from letta.schemas.enums import OptionState
|
|
19
|
-
from letta.schemas.llm_config import LLMConfig
|
|
20
18
|
from letta.schemas.memory import ChatMemory, Memory
|
|
21
19
|
from letta.server.server import logger as server_logger
|
|
22
20
|
|
|
@@ -235,12 +233,7 @@ def run(
|
|
|
235
233
|
# choose from list of llm_configs
|
|
236
234
|
llm_configs = client.list_llm_configs()
|
|
237
235
|
llm_options = [llm_config.model for llm_config in llm_configs]
|
|
238
|
-
|
|
239
|
-
# TODO move into LLMConfig as a class method?
|
|
240
|
-
def prettify_llm_config(llm_config: LLMConfig) -> str:
|
|
241
|
-
return f"{llm_config.model}" + f" ({llm_config.model_endpoint})" if llm_config.model_endpoint else ""
|
|
242
|
-
|
|
243
|
-
llm_choices = [questionary.Choice(title=prettify_llm_config(llm_config), value=llm_config) for llm_config in llm_configs]
|
|
236
|
+
llm_choices = [questionary.Choice(title=llm_config.pretty_print(), value=llm_config) for llm_config in llm_configs]
|
|
244
237
|
|
|
245
238
|
# select model
|
|
246
239
|
if len(llm_options) == 0:
|
|
@@ -255,17 +248,8 @@ def run(
|
|
|
255
248
|
embedding_configs = client.list_embedding_configs()
|
|
256
249
|
embedding_options = [embedding_config.embedding_model for embedding_config in embedding_configs]
|
|
257
250
|
|
|
258
|
-
# TODO move into EmbeddingConfig as a class method?
|
|
259
|
-
def prettify_embed_config(embedding_config: EmbeddingConfig) -> str:
|
|
260
|
-
return (
|
|
261
|
-
f"{embedding_config.embedding_model}" + f" ({embedding_config.embedding_endpoint})"
|
|
262
|
-
if embedding_config.embedding_endpoint
|
|
263
|
-
else ""
|
|
264
|
-
)
|
|
265
|
-
|
|
266
251
|
embedding_choices = [
|
|
267
|
-
questionary.Choice(title=
|
|
268
|
-
for embedding_config in embedding_configs
|
|
252
|
+
questionary.Choice(title=embedding_config.pretty_print(), value=embedding_config) for embedding_config in embedding_configs
|
|
269
253
|
]
|
|
270
254
|
|
|
271
255
|
# select model
|
letta/llm_api/azure_openai.py
CHANGED
|
@@ -79,7 +79,7 @@ def azure_openai_chat_completions_request(
|
|
|
79
79
|
data.pop("tools")
|
|
80
80
|
data.pop("tool_choice", None) # extra safe, should exist always (default="auto")
|
|
81
81
|
|
|
82
|
-
url = get_azure_chat_completions_endpoint(model_settings.azure_base_url, llm_config.model, model_settings.
|
|
82
|
+
url = get_azure_chat_completions_endpoint(model_settings.azure_base_url, llm_config.model, model_settings.azure_api_version)
|
|
83
83
|
response_json = make_post_request(url, headers, data)
|
|
84
84
|
# NOTE: azure openai does not include "content" in the response when it is None, so we need to add it
|
|
85
85
|
if "content" not in response_json["choices"][0].get("message"):
|
letta/llm_api/helpers.py
CHANGED
|
@@ -153,6 +153,7 @@ def unpack_inner_thoughts_from_kwargs(choice: Choice, inner_thoughts_key: str) -
|
|
|
153
153
|
return new_choice
|
|
154
154
|
else:
|
|
155
155
|
warnings.warn(f"Did not find inner thoughts in tool call: {str(tool_call)}")
|
|
156
|
+
return choice
|
|
156
157
|
|
|
157
158
|
except json.JSONDecodeError as e:
|
|
158
159
|
warnings.warn(f"Failed to strip inner thoughts from kwargs: {e}")
|
letta/llm_api/llm_api_tools.py
CHANGED
|
@@ -70,6 +70,10 @@ def retry_with_exponential_backoff(
|
|
|
70
70
|
return func(*args, **kwargs)
|
|
71
71
|
|
|
72
72
|
except requests.exceptions.HTTPError as http_err:
|
|
73
|
+
|
|
74
|
+
if not hasattr(http_err, "response") or not http_err.response:
|
|
75
|
+
raise
|
|
76
|
+
|
|
73
77
|
# Retry on specified errors
|
|
74
78
|
if http_err.response.status_code in error_codes:
|
|
75
79
|
# Increment retries
|
|
@@ -115,7 +119,7 @@ def create(
|
|
|
115
119
|
use_tool_naming: bool = True,
|
|
116
120
|
# streaming?
|
|
117
121
|
stream: bool = False,
|
|
118
|
-
|
|
122
|
+
stream_interface: Optional[Union[AgentRefreshStreamingInterface, AgentChunkStreamingInterface]] = None,
|
|
119
123
|
# TODO move to llm_config?
|
|
120
124
|
# if unspecified (None), default to something we've tested
|
|
121
125
|
inner_thoughts_in_kwargs_option: OptionState = OptionState.DEFAULT,
|
|
@@ -149,19 +153,19 @@ def create(
|
|
|
149
153
|
|
|
150
154
|
if stream: # Client requested token streaming
|
|
151
155
|
data.stream = True
|
|
152
|
-
assert isinstance(
|
|
153
|
-
|
|
154
|
-
), type(
|
|
156
|
+
assert isinstance(stream_interface, AgentChunkStreamingInterface) or isinstance(
|
|
157
|
+
stream_interface, AgentRefreshStreamingInterface
|
|
158
|
+
), type(stream_interface)
|
|
155
159
|
response = openai_chat_completions_process_stream(
|
|
156
160
|
url=llm_config.model_endpoint, # https://api.openai.com/v1 -> https://api.openai.com/v1/chat/completions
|
|
157
161
|
api_key=model_settings.openai_api_key,
|
|
158
162
|
chat_completion_request=data,
|
|
159
|
-
|
|
163
|
+
stream_interface=stream_interface,
|
|
160
164
|
)
|
|
161
165
|
else: # Client did not request token streaming (expect a blocking backend response)
|
|
162
166
|
data.stream = False
|
|
163
|
-
if isinstance(
|
|
164
|
-
|
|
167
|
+
if isinstance(stream_interface, AgentChunkStreamingInterface):
|
|
168
|
+
stream_interface.stream_start()
|
|
165
169
|
try:
|
|
166
170
|
response = openai_chat_completions_request(
|
|
167
171
|
url=llm_config.model_endpoint, # https://api.openai.com/v1 -> https://api.openai.com/v1/chat/completions
|
|
@@ -169,8 +173,8 @@ def create(
|
|
|
169
173
|
chat_completion_request=data,
|
|
170
174
|
)
|
|
171
175
|
finally:
|
|
172
|
-
if isinstance(
|
|
173
|
-
|
|
176
|
+
if isinstance(stream_interface, AgentChunkStreamingInterface):
|
|
177
|
+
stream_interface.stream_end()
|
|
174
178
|
|
|
175
179
|
if inner_thoughts_in_kwargs:
|
|
176
180
|
response = unpack_all_inner_thoughts_from_kwargs(response=response, inner_thoughts_key=INNER_THOUGHTS_KWARG)
|
|
@@ -317,8 +321,8 @@ def create(
|
|
|
317
321
|
# They mention that none of the messages can have names, but it seems to not error out (for now)
|
|
318
322
|
|
|
319
323
|
data.stream = False
|
|
320
|
-
if isinstance(
|
|
321
|
-
|
|
324
|
+
if isinstance(stream_interface, AgentChunkStreamingInterface):
|
|
325
|
+
stream_interface.stream_start()
|
|
322
326
|
try:
|
|
323
327
|
# groq uses the openai chat completions API, so this component should be reusable
|
|
324
328
|
assert model_settings.groq_api_key is not None, "Groq key is missing"
|
|
@@ -328,8 +332,8 @@ def create(
|
|
|
328
332
|
chat_completion_request=data,
|
|
329
333
|
)
|
|
330
334
|
finally:
|
|
331
|
-
if isinstance(
|
|
332
|
-
|
|
335
|
+
if isinstance(stream_interface, AgentChunkStreamingInterface):
|
|
336
|
+
stream_interface.stream_end()
|
|
333
337
|
|
|
334
338
|
if inner_thoughts_in_kwargs:
|
|
335
339
|
response = unpack_all_inner_thoughts_from_kwargs(response=response, inner_thoughts_key=INNER_THOUGHTS_KWARG)
|
letta/llm_api/openai.py
CHANGED
|
@@ -61,6 +61,7 @@ def openai_get_model_list(
|
|
|
61
61
|
headers["Authorization"] = f"Bearer {api_key}"
|
|
62
62
|
|
|
63
63
|
printd(f"Sending request to {url}")
|
|
64
|
+
response = None
|
|
64
65
|
try:
|
|
65
66
|
# TODO add query param "tool" to be true
|
|
66
67
|
response = requests.get(url, headers=headers, params=extra_params)
|
|
@@ -71,7 +72,8 @@ def openai_get_model_list(
|
|
|
71
72
|
except requests.exceptions.HTTPError as http_err:
|
|
72
73
|
# Handle HTTP errors (e.g., response 4XX, 5XX)
|
|
73
74
|
try:
|
|
74
|
-
|
|
75
|
+
if response:
|
|
76
|
+
response = response.json()
|
|
75
77
|
except:
|
|
76
78
|
pass
|
|
77
79
|
printd(f"Got HTTPError, exception={http_err}, response={response}")
|
|
@@ -79,7 +81,8 @@ def openai_get_model_list(
|
|
|
79
81
|
except requests.exceptions.RequestException as req_err:
|
|
80
82
|
# Handle other requests-related errors (e.g., connection error)
|
|
81
83
|
try:
|
|
82
|
-
|
|
84
|
+
if response:
|
|
85
|
+
response = response.json()
|
|
83
86
|
except:
|
|
84
87
|
pass
|
|
85
88
|
printd(f"Got RequestException, exception={req_err}, response={response}")
|
|
@@ -87,7 +90,8 @@ def openai_get_model_list(
|
|
|
87
90
|
except Exception as e:
|
|
88
91
|
# Handle other potential errors
|
|
89
92
|
try:
|
|
90
|
-
|
|
93
|
+
if response:
|
|
94
|
+
response = response.json()
|
|
91
95
|
except:
|
|
92
96
|
pass
|
|
93
97
|
printd(f"Got unknown Exception, exception={e}, response={response}")
|
|
@@ -157,7 +161,7 @@ def openai_chat_completions_process_stream(
|
|
|
157
161
|
url: str,
|
|
158
162
|
api_key: str,
|
|
159
163
|
chat_completion_request: ChatCompletionRequest,
|
|
160
|
-
|
|
164
|
+
stream_interface: Optional[Union[AgentChunkStreamingInterface, AgentRefreshStreamingInterface]] = None,
|
|
161
165
|
create_message_id: bool = True,
|
|
162
166
|
create_message_datetime: bool = True,
|
|
163
167
|
) -> ChatCompletionResponse:
|
|
@@ -167,7 +171,7 @@ def openai_chat_completions_process_stream(
|
|
|
167
171
|
on the chunks received from the OpenAI-compatible server POST SSE response.
|
|
168
172
|
"""
|
|
169
173
|
assert chat_completion_request.stream == True
|
|
170
|
-
assert
|
|
174
|
+
assert stream_interface is not None, "Required"
|
|
171
175
|
|
|
172
176
|
# Count the prompt tokens
|
|
173
177
|
# TODO move to post-request?
|
|
@@ -220,8 +224,8 @@ def openai_chat_completions_process_stream(
|
|
|
220
224
|
),
|
|
221
225
|
)
|
|
222
226
|
|
|
223
|
-
if
|
|
224
|
-
|
|
227
|
+
if stream_interface:
|
|
228
|
+
stream_interface.stream_start()
|
|
225
229
|
|
|
226
230
|
n_chunks = 0 # approx == n_tokens
|
|
227
231
|
try:
|
|
@@ -230,17 +234,17 @@ def openai_chat_completions_process_stream(
|
|
|
230
234
|
):
|
|
231
235
|
assert isinstance(chat_completion_chunk, ChatCompletionChunkResponse), type(chat_completion_chunk)
|
|
232
236
|
|
|
233
|
-
if
|
|
234
|
-
if isinstance(
|
|
235
|
-
|
|
237
|
+
if stream_interface:
|
|
238
|
+
if isinstance(stream_interface, AgentChunkStreamingInterface):
|
|
239
|
+
stream_interface.process_chunk(
|
|
236
240
|
chat_completion_chunk,
|
|
237
241
|
message_id=chat_completion_response.id if create_message_id else chat_completion_chunk.id,
|
|
238
242
|
message_date=chat_completion_response.created if create_message_datetime else chat_completion_chunk.created,
|
|
239
243
|
)
|
|
240
|
-
elif isinstance(
|
|
241
|
-
|
|
244
|
+
elif isinstance(stream_interface, AgentRefreshStreamingInterface):
|
|
245
|
+
stream_interface.process_refresh(chat_completion_response)
|
|
242
246
|
else:
|
|
243
|
-
raise TypeError(
|
|
247
|
+
raise TypeError(stream_interface)
|
|
244
248
|
|
|
245
249
|
if chunk_idx == 0:
|
|
246
250
|
# initialize the choice objects which we will increment with the deltas
|
|
@@ -314,13 +318,13 @@ def openai_chat_completions_process_stream(
|
|
|
314
318
|
n_chunks += 1
|
|
315
319
|
|
|
316
320
|
except Exception as e:
|
|
317
|
-
if
|
|
318
|
-
|
|
321
|
+
if stream_interface:
|
|
322
|
+
stream_interface.stream_end()
|
|
319
323
|
print(f"Parsing ChatCompletion stream failed with error:\n{str(e)}")
|
|
320
324
|
raise e
|
|
321
325
|
finally:
|
|
322
|
-
if
|
|
323
|
-
|
|
326
|
+
if stream_interface:
|
|
327
|
+
stream_interface.stream_end()
|
|
324
328
|
|
|
325
329
|
# make sure we didn't leave temp stuff in
|
|
326
330
|
assert all([c.finish_reason != TEMP_STREAM_FINISH_REASON for c in chat_completion_response.choices])
|
|
@@ -85,9 +85,7 @@ def get_chat_completion(
|
|
|
85
85
|
elif wrapper is None:
|
|
86
86
|
# Warn the user that we're using the fallback
|
|
87
87
|
if not has_shown_warning:
|
|
88
|
-
print(
|
|
89
|
-
f"{CLI_WARNING_PREFIX}no wrapper specified for local LLM, using the default wrapper (you can remove this warning by specifying the wrapper with --model-wrapper)"
|
|
90
|
-
)
|
|
88
|
+
print(f"{CLI_WARNING_PREFIX}no prompt formatter specified for local LLM, using the default formatter")
|
|
91
89
|
has_shown_warning = True
|
|
92
90
|
|
|
93
91
|
llm_wrapper = DEFAULT_WRAPPER()
|
letta/local_llm/vllm/api.py
CHANGED
|
@@ -3,7 +3,7 @@ from urllib.parse import urljoin
|
|
|
3
3
|
from letta.local_llm.settings.settings import get_completions_settings
|
|
4
4
|
from letta.local_llm.utils import count_tokens, post_json_auth_request
|
|
5
5
|
|
|
6
|
-
WEBUI_API_SUFFIX = "/
|
|
6
|
+
WEBUI_API_SUFFIX = "/completions"
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
def get_vllm_completion(endpoint, auth_type, auth_key, model, prompt, context_window, user, grammar=None):
|
letta/metadata.py
CHANGED
|
@@ -14,11 +14,10 @@ from sqlalchemy import (
|
|
|
14
14
|
String,
|
|
15
15
|
TypeDecorator,
|
|
16
16
|
desc,
|
|
17
|
-
func,
|
|
18
17
|
)
|
|
19
|
-
from sqlalchemy.orm import declarative_base
|
|
20
18
|
from sqlalchemy.sql import func
|
|
21
19
|
|
|
20
|
+
from letta.base import Base
|
|
22
21
|
from letta.config import LettaConfig
|
|
23
22
|
from letta.schemas.agent import AgentState
|
|
24
23
|
from letta.schemas.api_key import APIKey
|
|
@@ -28,6 +27,8 @@ from letta.schemas.enums import JobStatus
|
|
|
28
27
|
from letta.schemas.job import Job
|
|
29
28
|
from letta.schemas.llm_config import LLMConfig
|
|
30
29
|
from letta.schemas.memory import Memory
|
|
30
|
+
|
|
31
|
+
# from letta.schemas.message import Message, Passage, Record, RecordType, ToolCall
|
|
31
32
|
from letta.schemas.openai.chat_completions import ToolCall, ToolCallFunction
|
|
32
33
|
from letta.schemas.organization import Organization
|
|
33
34
|
from letta.schemas.source import Source
|
|
@@ -36,8 +37,6 @@ from letta.schemas.user import User
|
|
|
36
37
|
from letta.settings import settings
|
|
37
38
|
from letta.utils import enforce_types, get_utc_time, printd
|
|
38
39
|
|
|
39
|
-
Base = declarative_base()
|
|
40
|
-
|
|
41
40
|
|
|
42
41
|
class LLMConfigColumn(TypeDecorator):
|
|
43
42
|
"""Custom type for storing LLMConfig as JSON"""
|
letta/providers.py
CHANGED
|
@@ -14,14 +14,18 @@ from letta.schemas.llm_config import LLMConfig
|
|
|
14
14
|
|
|
15
15
|
class Provider(BaseModel):
|
|
16
16
|
|
|
17
|
-
def list_llm_models(self):
|
|
17
|
+
def list_llm_models(self) -> List[LLMConfig]:
|
|
18
18
|
return []
|
|
19
19
|
|
|
20
|
-
def list_embedding_models(self):
|
|
20
|
+
def list_embedding_models(self) -> List[EmbeddingConfig]:
|
|
21
21
|
return []
|
|
22
22
|
|
|
23
|
-
def get_model_context_window(self, model_name: str):
|
|
24
|
-
|
|
23
|
+
def get_model_context_window(self, model_name: str) -> Optional[int]:
|
|
24
|
+
raise NotImplementedError
|
|
25
|
+
|
|
26
|
+
def provider_tag(self) -> str:
|
|
27
|
+
"""String representation of the provider for display purposes"""
|
|
28
|
+
raise NotImplementedError
|
|
25
29
|
|
|
26
30
|
|
|
27
31
|
class LettaProvider(Provider):
|
|
@@ -136,9 +140,17 @@ class AnthropicProvider(Provider):
|
|
|
136
140
|
|
|
137
141
|
|
|
138
142
|
class OllamaProvider(OpenAIProvider):
|
|
143
|
+
"""Ollama provider that uses the native /api/generate endpoint
|
|
144
|
+
|
|
145
|
+
See: https://github.com/ollama/ollama/blob/main/docs/api.md#generate-a-completion
|
|
146
|
+
"""
|
|
147
|
+
|
|
139
148
|
name: str = "ollama"
|
|
140
149
|
base_url: str = Field(..., description="Base URL for the Ollama API.")
|
|
141
150
|
api_key: Optional[str] = Field(None, description="API key for the Ollama API (default: `None`).")
|
|
151
|
+
default_prompt_formatter: str = Field(
|
|
152
|
+
..., description="Default prompt formatter (aka model wrapper) to use on a /completions style API."
|
|
153
|
+
)
|
|
142
154
|
|
|
143
155
|
def list_llm_models(self) -> List[LLMConfig]:
|
|
144
156
|
# https://github.com/ollama/ollama/blob/main/docs/api.md#list-local-models
|
|
@@ -152,17 +164,21 @@ class OllamaProvider(OpenAIProvider):
|
|
|
152
164
|
configs = []
|
|
153
165
|
for model in response_json["models"]:
|
|
154
166
|
context_window = self.get_model_context_window(model["name"])
|
|
167
|
+
if context_window is None:
|
|
168
|
+
print(f"Ollama model {model['name']} has no context window")
|
|
169
|
+
continue
|
|
155
170
|
configs.append(
|
|
156
171
|
LLMConfig(
|
|
157
172
|
model=model["name"],
|
|
158
173
|
model_endpoint_type="ollama",
|
|
159
174
|
model_endpoint=self.base_url,
|
|
175
|
+
model_wrapper=self.default_prompt_formatter,
|
|
160
176
|
context_window=context_window,
|
|
161
177
|
)
|
|
162
178
|
)
|
|
163
179
|
return configs
|
|
164
180
|
|
|
165
|
-
def get_model_context_window(self, model_name: str):
|
|
181
|
+
def get_model_context_window(self, model_name: str) -> Optional[int]:
|
|
166
182
|
|
|
167
183
|
import requests
|
|
168
184
|
|
|
@@ -188,6 +204,10 @@ class OllamaProvider(OpenAIProvider):
|
|
|
188
204
|
# ]
|
|
189
205
|
# max_position_embeddings
|
|
190
206
|
# parse model cards: nous, dolphon, llama
|
|
207
|
+
if "model_info" not in response_json:
|
|
208
|
+
if "error" in response_json:
|
|
209
|
+
print(f"Ollama fetch model info error for {model_name}: {response_json['error']}")
|
|
210
|
+
return None
|
|
191
211
|
for key, value in response_json["model_info"].items():
|
|
192
212
|
if "context_length" in key:
|
|
193
213
|
return value
|
|
@@ -198,6 +218,10 @@ class OllamaProvider(OpenAIProvider):
|
|
|
198
218
|
|
|
199
219
|
response = requests.post(f"{self.base_url}/api/show", json={"name": model_name, "verbose": True})
|
|
200
220
|
response_json = response.json()
|
|
221
|
+
if "model_info" not in response_json:
|
|
222
|
+
if "error" in response_json:
|
|
223
|
+
print(f"Ollama fetch model info error for {model_name}: {response_json['error']}")
|
|
224
|
+
return None
|
|
201
225
|
for key, value in response_json["model_info"].items():
|
|
202
226
|
if "embedding_length" in key:
|
|
203
227
|
return value
|
|
@@ -216,6 +240,7 @@ class OllamaProvider(OpenAIProvider):
|
|
|
216
240
|
for model in response_json["models"]:
|
|
217
241
|
embedding_dim = self.get_model_embedding_dim(model["name"])
|
|
218
242
|
if not embedding_dim:
|
|
243
|
+
print(f"Ollama model {model['name']} has no embedding dimension")
|
|
219
244
|
continue
|
|
220
245
|
configs.append(
|
|
221
246
|
EmbeddingConfig(
|
|
@@ -310,7 +335,7 @@ class GoogleAIProvider(Provider):
|
|
|
310
335
|
)
|
|
311
336
|
return configs
|
|
312
337
|
|
|
313
|
-
def get_model_context_window(self, model_name: str):
|
|
338
|
+
def get_model_context_window(self, model_name: str) -> Optional[int]:
|
|
314
339
|
from letta.llm_api.google_ai import google_ai_get_model_context_window
|
|
315
340
|
|
|
316
341
|
return google_ai_get_model_context_window(self.base_url, self.api_key, model_name)
|
|
@@ -371,16 +396,75 @@ class AzureProvider(Provider):
|
|
|
371
396
|
)
|
|
372
397
|
return configs
|
|
373
398
|
|
|
374
|
-
def get_model_context_window(self, model_name: str):
|
|
399
|
+
def get_model_context_window(self, model_name: str) -> Optional[int]:
|
|
375
400
|
"""
|
|
376
401
|
This is hardcoded for now, since there is no API endpoints to retrieve metadata for a model.
|
|
377
402
|
"""
|
|
378
403
|
return AZURE_MODEL_TO_CONTEXT_LENGTH.get(model_name, 4096)
|
|
379
404
|
|
|
380
405
|
|
|
381
|
-
class
|
|
406
|
+
class VLLMChatCompletionsProvider(Provider):
|
|
407
|
+
"""vLLM provider that treats vLLM as an OpenAI /chat/completions proxy"""
|
|
408
|
+
|
|
382
409
|
# NOTE: vLLM only serves one model at a time (so could configure that through env variables)
|
|
383
|
-
|
|
410
|
+
name: str = "vllm"
|
|
411
|
+
base_url: str = Field(..., description="Base URL for the vLLM API.")
|
|
412
|
+
|
|
413
|
+
def list_llm_models(self) -> List[LLMConfig]:
|
|
414
|
+
# not supported with vLLM
|
|
415
|
+
from letta.llm_api.openai import openai_get_model_list
|
|
416
|
+
|
|
417
|
+
assert self.base_url, "base_url is required for vLLM provider"
|
|
418
|
+
response = openai_get_model_list(self.base_url, api_key=None)
|
|
419
|
+
|
|
420
|
+
configs = []
|
|
421
|
+
print(response)
|
|
422
|
+
for model in response["data"]:
|
|
423
|
+
configs.append(
|
|
424
|
+
LLMConfig(
|
|
425
|
+
model=model["id"],
|
|
426
|
+
model_endpoint_type="openai",
|
|
427
|
+
model_endpoint=self.base_url,
|
|
428
|
+
context_window=model["max_model_len"],
|
|
429
|
+
)
|
|
430
|
+
)
|
|
431
|
+
return configs
|
|
432
|
+
|
|
433
|
+
def list_embedding_models(self) -> List[EmbeddingConfig]:
|
|
434
|
+
# not supported with vLLM
|
|
435
|
+
return []
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
class VLLMCompletionsProvider(Provider):
|
|
439
|
+
"""This uses /completions API as the backend, not /chat/completions, so we need to specify a model wrapper"""
|
|
440
|
+
|
|
441
|
+
# NOTE: vLLM only serves one model at a time (so could configure that through env variables)
|
|
442
|
+
name: str = "vllm"
|
|
443
|
+
base_url: str = Field(..., description="Base URL for the vLLM API.")
|
|
444
|
+
default_prompt_formatter: str = Field(..., description="Default prompt formatter (aka model wrapper) to use on vLLM /completions API.")
|
|
445
|
+
|
|
446
|
+
def list_llm_models(self) -> List[LLMConfig]:
|
|
447
|
+
# not supported with vLLM
|
|
448
|
+
from letta.llm_api.openai import openai_get_model_list
|
|
449
|
+
|
|
450
|
+
response = openai_get_model_list(self.base_url, api_key=None)
|
|
451
|
+
|
|
452
|
+
configs = []
|
|
453
|
+
for model in response["data"]:
|
|
454
|
+
configs.append(
|
|
455
|
+
LLMConfig(
|
|
456
|
+
model=model["id"],
|
|
457
|
+
model_endpoint_type="vllm",
|
|
458
|
+
model_endpoint=self.base_url,
|
|
459
|
+
model_wrapper=self.default_prompt_formatter,
|
|
460
|
+
context_window=model["max_model_len"],
|
|
461
|
+
)
|
|
462
|
+
)
|
|
463
|
+
return configs
|
|
464
|
+
|
|
465
|
+
def list_embedding_models(self) -> List[EmbeddingConfig]:
|
|
466
|
+
# not supported with vLLM
|
|
467
|
+
return []
|
|
384
468
|
|
|
385
469
|
|
|
386
470
|
class CohereProvider(OpenAIProvider):
|
|
@@ -52,3 +52,10 @@ class EmbeddingConfig(BaseModel):
|
|
|
52
52
|
)
|
|
53
53
|
else:
|
|
54
54
|
raise ValueError(f"Model {model_name} not supported.")
|
|
55
|
+
|
|
56
|
+
def pretty_print(self) -> str:
|
|
57
|
+
return (
|
|
58
|
+
f"{self.embedding_model}"
|
|
59
|
+
+ (f" [type={self.embedding_endpoint_type}]" if self.embedding_endpoint_type else "")
|
|
60
|
+
+ (f" [ip={self.embedding_endpoint}]" if self.embedding_endpoint else "")
|
|
61
|
+
)
|
letta/schemas/llm_config.py
CHANGED
|
@@ -68,3 +68,10 @@ class LLMConfig(BaseModel):
|
|
|
68
68
|
)
|
|
69
69
|
else:
|
|
70
70
|
raise ValueError(f"Model {model_name} not supported.")
|
|
71
|
+
|
|
72
|
+
def pretty_print(self) -> str:
|
|
73
|
+
return (
|
|
74
|
+
f"{self.model}"
|
|
75
|
+
+ (f" [type={self.model_endpoint_type}]" if self.model_endpoint_type else "")
|
|
76
|
+
+ (f" [ip={self.model_endpoint}]" if self.model_endpoint else "")
|
|
77
|
+
)
|
letta/server/server.py
CHANGED
|
@@ -14,8 +14,8 @@ import letta.constants as constants
|
|
|
14
14
|
import letta.server.utils as server_utils
|
|
15
15
|
import letta.system as system
|
|
16
16
|
from letta.agent import Agent, save_agent
|
|
17
|
+
from letta.agent_store.db import attach_base
|
|
17
18
|
from letta.agent_store.storage import StorageConnector, TableType
|
|
18
|
-
from letta.config import LettaConfig
|
|
19
19
|
from letta.credentials import LettaCredentials
|
|
20
20
|
from letta.data_sources.connectors import DataConnector, load_data
|
|
21
21
|
|
|
@@ -41,7 +41,7 @@ from letta.interface import AgentInterface # abstract
|
|
|
41
41
|
from letta.interface import CLIInterface # for printing to terminal
|
|
42
42
|
from letta.log import get_logger
|
|
43
43
|
from letta.memory import get_memory_functions
|
|
44
|
-
from letta.metadata import MetadataStore
|
|
44
|
+
from letta.metadata import Base, MetadataStore
|
|
45
45
|
from letta.prompts import gpt_system
|
|
46
46
|
from letta.providers import (
|
|
47
47
|
AnthropicProvider,
|
|
@@ -51,7 +51,8 @@ from letta.providers import (
|
|
|
51
51
|
OllamaProvider,
|
|
52
52
|
OpenAIProvider,
|
|
53
53
|
Provider,
|
|
54
|
-
|
|
54
|
+
VLLMChatCompletionsProvider,
|
|
55
|
+
VLLMCompletionsProvider,
|
|
55
56
|
)
|
|
56
57
|
from letta.schemas.agent import AgentState, AgentType, CreateAgent, UpdateAgentState
|
|
57
58
|
from letta.schemas.api_key import APIKey, APIKeyCreate
|
|
@@ -150,23 +151,11 @@ class Server(object):
|
|
|
150
151
|
|
|
151
152
|
|
|
152
153
|
from sqlalchemy import create_engine
|
|
153
|
-
from sqlalchemy.orm import
|
|
154
|
+
from sqlalchemy.orm import sessionmaker
|
|
154
155
|
|
|
155
|
-
from letta.agent_store.db import MessageModel, PassageModel
|
|
156
156
|
from letta.config import LettaConfig
|
|
157
157
|
|
|
158
158
|
# NOTE: hack to see if single session management works
|
|
159
|
-
from letta.metadata import (
|
|
160
|
-
AgentModel,
|
|
161
|
-
AgentSourceMappingModel,
|
|
162
|
-
APIKeyModel,
|
|
163
|
-
BlockModel,
|
|
164
|
-
JobModel,
|
|
165
|
-
OrganizationModel,
|
|
166
|
-
SourceModel,
|
|
167
|
-
ToolModel,
|
|
168
|
-
UserModel,
|
|
169
|
-
)
|
|
170
159
|
from letta.settings import model_settings, settings
|
|
171
160
|
|
|
172
161
|
config = LettaConfig.load()
|
|
@@ -183,24 +172,12 @@ else:
|
|
|
183
172
|
# TODO: don't rely on config storage
|
|
184
173
|
engine = create_engine("sqlite:///" + os.path.join(config.recall_storage_path, "sqlite.db"))
|
|
185
174
|
|
|
186
|
-
|
|
175
|
+
|
|
187
176
|
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
AgentModel.__table__,
|
|
193
|
-
SourceModel.__table__,
|
|
194
|
-
AgentSourceMappingModel.__table__,
|
|
195
|
-
APIKeyModel.__table__,
|
|
196
|
-
BlockModel.__table__,
|
|
197
|
-
ToolModel.__table__,
|
|
198
|
-
JobModel.__table__,
|
|
199
|
-
PassageModel.__table__,
|
|
200
|
-
MessageModel.__table__,
|
|
201
|
-
OrganizationModel.__table__,
|
|
202
|
-
],
|
|
203
|
-
)
|
|
177
|
+
|
|
178
|
+
attach_base()
|
|
179
|
+
|
|
180
|
+
Base.metadata.create_all(bind=engine)
|
|
204
181
|
|
|
205
182
|
|
|
206
183
|
# Dependency
|
|
@@ -223,7 +200,7 @@ class SyncServer(Server):
|
|
|
223
200
|
def __init__(
|
|
224
201
|
self,
|
|
225
202
|
chaining: bool = True,
|
|
226
|
-
max_chaining_steps: bool = None,
|
|
203
|
+
max_chaining_steps: Optional[bool] = None,
|
|
227
204
|
default_interface_factory: Callable[[], AgentInterface] = lambda: CLIInterface(),
|
|
228
205
|
# default_interface: AgentInterface = CLIInterface(),
|
|
229
206
|
# default_persistence_manager_cls: PersistenceManager = LocalStateManager,
|
|
@@ -264,16 +241,34 @@ class SyncServer(Server):
|
|
|
264
241
|
# collect providers (always has Letta as a default)
|
|
265
242
|
self._enabled_providers: List[Provider] = [LettaProvider()]
|
|
266
243
|
if model_settings.openai_api_key:
|
|
267
|
-
self._enabled_providers.append(
|
|
244
|
+
self._enabled_providers.append(
|
|
245
|
+
OpenAIProvider(
|
|
246
|
+
api_key=model_settings.openai_api_key,
|
|
247
|
+
base_url=model_settings.openai_api_base,
|
|
248
|
+
)
|
|
249
|
+
)
|
|
268
250
|
if model_settings.anthropic_api_key:
|
|
269
|
-
self._enabled_providers.append(
|
|
251
|
+
self._enabled_providers.append(
|
|
252
|
+
AnthropicProvider(
|
|
253
|
+
api_key=model_settings.anthropic_api_key,
|
|
254
|
+
)
|
|
255
|
+
)
|
|
270
256
|
if model_settings.ollama_base_url:
|
|
271
|
-
self._enabled_providers.append(
|
|
272
|
-
|
|
273
|
-
|
|
257
|
+
self._enabled_providers.append(
|
|
258
|
+
OllamaProvider(
|
|
259
|
+
base_url=model_settings.ollama_base_url,
|
|
260
|
+
api_key=None,
|
|
261
|
+
default_prompt_formatter=model_settings.default_prompt_formatter,
|
|
262
|
+
)
|
|
263
|
+
)
|
|
274
264
|
if model_settings.gemini_api_key:
|
|
275
|
-
self._enabled_providers.append(
|
|
265
|
+
self._enabled_providers.append(
|
|
266
|
+
GoogleAIProvider(
|
|
267
|
+
api_key=model_settings.gemini_api_key,
|
|
268
|
+
)
|
|
269
|
+
)
|
|
276
270
|
if model_settings.azure_api_key and model_settings.azure_base_url:
|
|
271
|
+
assert model_settings.azure_api_version, "AZURE_API_VERSION is required"
|
|
277
272
|
self._enabled_providers.append(
|
|
278
273
|
AzureProvider(
|
|
279
274
|
api_key=model_settings.azure_api_key,
|
|
@@ -281,6 +276,22 @@ class SyncServer(Server):
|
|
|
281
276
|
api_version=model_settings.azure_api_version,
|
|
282
277
|
)
|
|
283
278
|
)
|
|
279
|
+
if model_settings.vllm_api_base:
|
|
280
|
+
# vLLM exposes both a /chat/completions and a /completions endpoint
|
|
281
|
+
self._enabled_providers.append(
|
|
282
|
+
VLLMCompletionsProvider(
|
|
283
|
+
base_url=model_settings.vllm_api_base,
|
|
284
|
+
default_prompt_formatter=model_settings.default_prompt_formatter,
|
|
285
|
+
)
|
|
286
|
+
)
|
|
287
|
+
# NOTE: to use the /chat/completions endpoint, you need to specify extra flags on vLLM startup
|
|
288
|
+
# see: https://docs.vllm.ai/en/latest/getting_started/examples/openai_chat_completion_client_with_tools.html
|
|
289
|
+
# e.g. "... --enable-auto-tool-choice --tool-call-parser hermes"
|
|
290
|
+
self._enabled_providers.append(
|
|
291
|
+
VLLMChatCompletionsProvider(
|
|
292
|
+
base_url=model_settings.vllm_api_base,
|
|
293
|
+
)
|
|
294
|
+
)
|
|
284
295
|
|
|
285
296
|
def save_agents(self):
|
|
286
297
|
"""Saves all the agents that are in the in-memory object store"""
|
letta/settings.py
CHANGED
|
@@ -4,14 +4,20 @@ from typing import Optional
|
|
|
4
4
|
from pydantic import Field
|
|
5
5
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
6
6
|
|
|
7
|
+
from letta.local_llm.constants import DEFAULT_WRAPPER_NAME
|
|
8
|
+
|
|
7
9
|
|
|
8
10
|
class ModelSettings(BaseSettings):
|
|
9
11
|
|
|
10
12
|
# env_prefix='my_prefix_'
|
|
11
13
|
|
|
14
|
+
# when we use /completions APIs (instead of /chat/completions), we need to specify a model wrapper
|
|
15
|
+
# the "model wrapper" is responsible for prompt formatting and function calling parsing
|
|
16
|
+
default_prompt_formatter: str = DEFAULT_WRAPPER_NAME
|
|
17
|
+
|
|
12
18
|
# openai
|
|
13
19
|
openai_api_key: Optional[str] = None
|
|
14
|
-
openai_api_base:
|
|
20
|
+
openai_api_base: str = "https://api.openai.com/v1"
|
|
15
21
|
|
|
16
22
|
# groq
|
|
17
23
|
groq_api_key: Optional[str] = None
|
|
@@ -25,13 +31,16 @@ class ModelSettings(BaseSettings):
|
|
|
25
31
|
# azure
|
|
26
32
|
azure_api_key: Optional[str] = None
|
|
27
33
|
azure_base_url: Optional[str] = None
|
|
28
|
-
|
|
34
|
+
# We provide a default here, since usually people will want to be on the latest API version.
|
|
35
|
+
azure_api_version: Optional[str] = (
|
|
36
|
+
"2024-09-01-preview" # https://learn.microsoft.com/en-us/azure/ai-services/openai/api-version-deprecation
|
|
37
|
+
)
|
|
29
38
|
|
|
30
39
|
# google ai
|
|
31
40
|
gemini_api_key: Optional[str] = None
|
|
32
41
|
|
|
33
42
|
# vLLM
|
|
34
|
-
|
|
43
|
+
vllm_api_base: Optional[str] = None
|
|
35
44
|
|
|
36
45
|
# openllm
|
|
37
46
|
openllm_auth_type: Optional[str] = None
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: letta-nightly
|
|
3
|
-
Version: 0.4.1.
|
|
3
|
+
Version: 0.4.1.dev20241013104006
|
|
4
4
|
Summary: Create LLM agents with long-term memory and custom tools
|
|
5
5
|
License: Apache License
|
|
6
6
|
Author: Letta Team
|
|
@@ -20,6 +20,7 @@ Provides-Extra: postgres
|
|
|
20
20
|
Provides-Extra: qdrant
|
|
21
21
|
Provides-Extra: server
|
|
22
22
|
Provides-Extra: tests
|
|
23
|
+
Requires-Dist: alembic (>=1.13.3,<2.0.0)
|
|
23
24
|
Requires-Dist: autoflake (>=2.3.0,<3.0.0) ; extra == "dev"
|
|
24
25
|
Requires-Dist: black[jupyter] (>=24.2.0,<25.0.0) ; extra == "dev"
|
|
25
26
|
Requires-Dist: chromadb (>=0.4.24,<0.5.0)
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
letta/__init__.py,sha256=btKRPdyhkpIyHlCPRLwwz-SCSVcEGNBeheYA-XNesiI,996
|
|
2
2
|
letta/__main__.py,sha256=6Hs2PV7EYc5Tid4g4OtcLXhqVHiNYTGzSBdoOnW2HXA,29
|
|
3
|
-
letta/agent.py,sha256=
|
|
3
|
+
letta/agent.py,sha256=pdsd1M_AF3uF-AgJrMmxj8uB0Rkt5AXKBxHNw9mMaP4,66559
|
|
4
4
|
letta/agent_store/chroma.py,sha256=upR5zGnGs6I6btulEYbiZdGG87BgKjxUJOQZ4Y-RQ_M,12492
|
|
5
|
-
letta/agent_store/db.py,sha256=
|
|
5
|
+
letta/agent_store/db.py,sha256=TAQ1rcqS8zuC1hT_BaiXn6tSz5aKHAb-YQxr4QLKgz4,22724
|
|
6
6
|
letta/agent_store/lancedb.py,sha256=8RWmqVjowm5g0cc6DNRcb6f1FHGEqFnccnuekhWY39U,5101
|
|
7
7
|
letta/agent_store/milvus.py,sha256=VxEKz9XR7_3QTY59K_38NtJCCQvi41rhHoFibfzW7yw,8469
|
|
8
8
|
letta/agent_store/qdrant.py,sha256=qIEJhXJb6GzcT4wp8iV5Ox5W1CFMvcPViTI4HLSh59E,7879
|
|
9
9
|
letta/agent_store/storage.py,sha256=QWrPdIEJCnsPg1xnPrG1xbOXmbjpz37ZNhvuH52M7A8,6642
|
|
10
|
+
letta/base.py,sha256=Ba-wt8p59bLmeUONkYSo5MhrkH-_HdT4zE1Y9MVGrSQ,83
|
|
10
11
|
letta/benchmark/benchmark.py,sha256=ebvnwfp3yezaXOQyGXkYCDYpsmre-b9hvNtnyx4xkG0,3701
|
|
11
12
|
letta/benchmark/constants.py,sha256=aXc5gdpMGJT327VuxsT5FngbCK2J41PQYeICBO7g_RE,536
|
|
12
|
-
letta/cli/cli.py,sha256=
|
|
13
|
+
letta/cli/cli.py,sha256=XZDF7EfBYqdYEyDbENVp-tTyGcdvd9Wa1PNk70D-MGs,16195
|
|
13
14
|
letta/cli/cli_config.py,sha256=G7QqPNTtlQ4TdrXZrrFFGblZEhnkyrqN1Cl5z415C-g,8689
|
|
14
15
|
letta/cli/cli_load.py,sha256=aVlGWiNEUs_eG793HLl7cES-dEIuA1CJfZpT1Cm8Uo4,4591
|
|
15
16
|
letta/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -35,16 +36,16 @@ letta/humans/examples/cs_phd.txt,sha256=9C9ZAV_VuG7GB31ksy3-_NAyk8rjE6YtVOkhp08k
|
|
|
35
36
|
letta/interface.py,sha256=QI4hFP0WrNsgM5qX6TbnhH1ZZxsLYr5DaccuxpEQ8S4,12768
|
|
36
37
|
letta/llm_api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
38
|
letta/llm_api/anthropic.py,sha256=bAb9PVrpYjo2QN51_SJbW7Vry2_Sf55B05UoruHXb7A,12932
|
|
38
|
-
letta/llm_api/azure_openai.py,sha256=
|
|
39
|
+
letta/llm_api/azure_openai.py,sha256=C-fuuholudcLJDWjqnXJwpXsfmGWfNugEVWyj6YCrpg,4572
|
|
39
40
|
letta/llm_api/azure_openai_constants.py,sha256=oXtKrgBFHf744gyt5l1thILXgyi8NDNUrKEa2GGGpjw,278
|
|
40
41
|
letta/llm_api/cohere.py,sha256=vDRd-SUGp1t_JUIdwC3RkIhwMl0OY7n-tAU9uPORYkY,14826
|
|
41
42
|
letta/llm_api/google_ai.py,sha256=3xZ074nSOCC22c15yerA5ngWzh0ex4wxeI-6faNbHPE,17708
|
|
42
|
-
letta/llm_api/helpers.py,sha256=
|
|
43
|
-
letta/llm_api/llm_api_tools.py,sha256=
|
|
44
|
-
letta/llm_api/openai.py,sha256=
|
|
43
|
+
letta/llm_api/helpers.py,sha256=LjUtCjvPzSP3-3Ak0J--2RqUXOO6Of8287mm1L1LAMU,9549
|
|
44
|
+
letta/llm_api/llm_api_tools.py,sha256=Z3eiYUtvZKBVBcmKI2l4qWkKM4hgvLN9Y1aSxXc7y-k,15344
|
|
45
|
+
letta/llm_api/openai.py,sha256=EXpktSI_TYjsCDEXBxdNXsY5uE9Rzb7BPF1F6cz8bkg,21689
|
|
45
46
|
letta/local_llm/README.md,sha256=hFJyw5B0TU2jrh9nb0zGZMgdH-Ei1dSRfhvPQG_NSoU,168
|
|
46
47
|
letta/local_llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
47
|
-
letta/local_llm/chat_completion_proxy.py,sha256=
|
|
48
|
+
letta/local_llm/chat_completion_proxy.py,sha256=SiohxsjGTku4vOryOZx7I0t0xoO_sUuhXgoe62fKq3c,12995
|
|
48
49
|
letta/local_llm/constants.py,sha256=GIu0184EIiOLEqGeupLUYQvkgT_imIjLg3T-KM9TcFM,1125
|
|
49
50
|
letta/local_llm/function_parser.py,sha256=BlNsGo1VzyfY5KdF_RwjRQNOWIsaudo7o37u1W5eg0s,2626
|
|
50
51
|
letta/local_llm/grammars/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -74,7 +75,7 @@ letta/local_llm/settings/deterministic_mirostat.py,sha256=kgRikcxYHfIbPFydHW6W7I
|
|
|
74
75
|
letta/local_llm/settings/settings.py,sha256=ZAbzDpu2WsBXjVGXJ-TKUpS99VTI__3EoZml9KqYef0,2971
|
|
75
76
|
letta/local_llm/settings/simple.py,sha256=HAO2jBJ_hJCEsXWIJcD0sckR0tI0zs3x2CPdf6ORQLs,719
|
|
76
77
|
letta/local_llm/utils.py,sha256=DTv8S0lIpFBZlY6fjprtAU3n06eOPDKT6EXwnOgexLo,11363
|
|
77
|
-
letta/local_llm/vllm/api.py,sha256=
|
|
78
|
+
letta/local_llm/vllm/api.py,sha256=2kAGZjc_GH9ILJnVRq-45yfsfKELVfbC9VEl_cIC6vg,2590
|
|
78
79
|
letta/local_llm/webui/api.py,sha256=kkxncdCFq1vjgvaHOoQ__j7rcDPgC1F64KcEm94Y6Rs,2639
|
|
79
80
|
letta/local_llm/webui/legacy_api.py,sha256=k3H3y4qp2Fs-XmP24iSIEyvq6wjWFWBzklY3-wRAJNI,2335
|
|
80
81
|
letta/local_llm/webui/legacy_settings.py,sha256=BLmd3TSx5StnY3ibjwaxYATPt_Lvq-o1rlcc_-Q1JcU,538
|
|
@@ -82,7 +83,7 @@ letta/local_llm/webui/settings.py,sha256=gmLHfiOl1u4JmlAZU2d2O8YKF9lafdakyjwR_ft
|
|
|
82
83
|
letta/log.py,sha256=QHquDnL7oUAvdKlAwUlCK9zXKDMUjrU9WA0bxnMsP0Y,2101
|
|
83
84
|
letta/main.py,sha256=7uuiFv8TeOd3K92WwfYkls7l7KXJ5P0l2zgK9AfmD08,18502
|
|
84
85
|
letta/memory.py,sha256=6q1x3-PY-PeXzAt6hvP-UF1ajvroPZ7XW-5nLy-JhMo,17657
|
|
85
|
-
letta/metadata.py,sha256
|
|
86
|
+
letta/metadata.py,sha256=50pEJ5BuNKT8dPv34-H_Id9an3ql45Ze7BKqn7DGQ6s,33256
|
|
86
87
|
letta/openai_backcompat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
87
88
|
letta/openai_backcompat/openai_object.py,sha256=Y1ZS1sATP60qxJiOsjOP3NbwSzuzvkNAvb3DeuhM5Uk,13490
|
|
88
89
|
letta/persistence_manager.py,sha256=LlLgEDpSafCPAiyKmuq0NvVAnfBkZo6TWbGIKYQjQBs,5200
|
|
@@ -106,13 +107,13 @@ letta/prompts/system/memgpt_doc.txt,sha256=AsT55NOORoH-K-p0fxklrDRZ3qHs4MIKMuR-M
|
|
|
106
107
|
letta/prompts/system/memgpt_gpt35_extralong.txt,sha256=FheNhYoIzNz6qnJKhVquZVSMj3HduC48reFaX7Pf7ig,5046
|
|
107
108
|
letta/prompts/system/memgpt_intuitive_knowledge.txt,sha256=sA7c3urYqREVnSBI81nTGImXAekqC0Fxc7RojFqud1g,2966
|
|
108
109
|
letta/prompts/system/memgpt_modified_chat.txt,sha256=HOaPVurEftD8KsuwsclDgE2afIfklMjxhuSO96q1-6I,4656
|
|
109
|
-
letta/providers.py,sha256=
|
|
110
|
+
letta/providers.py,sha256=e4jWshGMu4UQ9B0yEzcHP1bDxNHEo_mgpO5M0txuOIo,17978
|
|
110
111
|
letta/pytest.ini,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
111
112
|
letta/schemas/agent.py,sha256=ztnUqdhY9V3g0jsbTjF1ypKPC1tZx4QVFaRuLAOXNSA,6230
|
|
112
113
|
letta/schemas/api_key.py,sha256=u07yzzMn-hBAHZIIKbWY16KsgiFjSNR8lAghpMUo3_4,682
|
|
113
114
|
letta/schemas/block.py,sha256=1_GwFtfykloYU4Mp2DV3-DqkvsKo79Mu3LAzVYOgMzk,3998
|
|
114
115
|
letta/schemas/document.py,sha256=JpvU0YkvOVLvHaDNcg-ihFzpeHC2zqsWBgyJ6zHnfNw,745
|
|
115
|
-
letta/schemas/embedding_config.py,sha256=
|
|
116
|
+
letta/schemas/embedding_config.py,sha256=1kD6NpiXeH4roVumxqDAKk7xt8SpXGWNhZs_XXUSlEU,2855
|
|
116
117
|
letta/schemas/enums.py,sha256=WfRYpLh_pD-VyhEnp3Y6pPfx063zq2o4jky6PulqO8w,629
|
|
117
118
|
letta/schemas/health.py,sha256=zT6mYovvD17iJRuu2rcaQQzbEEYrkwvAE9TB7iU824c,139
|
|
118
119
|
letta/schemas/job.py,sha256=bYDrjbJm2B4LUTSkLUdQR_HDhL2E23g0EHf7E23ezYU,1547
|
|
@@ -120,7 +121,7 @@ letta/schemas/letta_base.py,sha256=4QXFgyjCHqIagi8B6_4nmqb9eoJ52Y6aCxBxQpGX48M,2
|
|
|
120
121
|
letta/schemas/letta_message.py,sha256=Slgxa59qZfdvqXuCVHOt03u-7JL456ZY-WLaK5UYYKU,6234
|
|
121
122
|
letta/schemas/letta_request.py,sha256=Fv4hZKLMefCISwxuElXB0vsGDjqnzZuCbCbHPUPTirQ,1852
|
|
122
123
|
letta/schemas/letta_response.py,sha256=_UJoO3UtC3F5DtQCHzdiGM1SHNPYPKvopIWqg8t5YZw,1564
|
|
123
|
-
letta/schemas/llm_config.py,sha256=
|
|
124
|
+
letta/schemas/llm_config.py,sha256=xwHBO_sY-Kahtwxt_0Qz4j2CRSeJ0pGAIxpqyK_2Exk,2930
|
|
124
125
|
letta/schemas/memory.py,sha256=mDJbe9mzTw0HSn6tiouC3z32r-8Fc_EaeqxDy_hXf0U,9327
|
|
125
126
|
letta/schemas/message.py,sha256=1C6lz4yvMTusE8zORKbi_BKnb_X_-RuUvdpM5YeZ21o,33409
|
|
126
127
|
letta/schemas/openai/chat_completion_request.py,sha256=Fa7xnSnG7WUQounJhnDu0fTSxoR6xOAh2bODuqmfypI,3345
|
|
@@ -166,7 +167,7 @@ letta/server/rest_api/routers/v1/tools.py,sha256=MEhxu-zMS2ff_wwcRpMuQyWA71w_3BJ
|
|
|
166
167
|
letta/server/rest_api/routers/v1/users.py,sha256=Y2rDvHOG1B5FLSOjutY3R22vt48IngbZ-9h8CohG5rc,3378
|
|
167
168
|
letta/server/rest_api/static_files.py,sha256=NG8sN4Z5EJ8JVQdj19tkFa9iQ1kBPTab9f_CUxd_u4Q,3143
|
|
168
169
|
letta/server/rest_api/utils.py,sha256=Fc2ZGKzLaBa2sEtSTVjJ8D5M0xIwsWC0CVAOIJaD3rY,2176
|
|
169
|
-
letta/server/server.py,sha256=
|
|
170
|
+
letta/server/server.py,sha256=txNgf3AIraK-kTV4PLwzROfgfBTIul_Y74hPygFtOHw,82687
|
|
170
171
|
letta/server/startup.sh,sha256=jeGV7B_PS0hS-tT6o6GpACrUbV9WV1NI2L9aLoUDDtc,311
|
|
171
172
|
letta/server/static_files/assets/index-3ab03d5b.css,sha256=OrA9W4iKJ5h2Wlr7GwdAT4wow0CM8hVit1yOxEL49Qw,54295
|
|
172
173
|
letta/server/static_files/assets/index-9a9c449b.js,sha256=qoWUq6_kuLhE9NFkNeCBptgq-oERW46r0tB3JlWe_qc,1818951
|
|
@@ -179,12 +180,12 @@ letta/server/ws_api/example_client.py,sha256=95AA5UFgTlNJ0FUQkLxli8dKNx48MNm3eWG
|
|
|
179
180
|
letta/server/ws_api/interface.py,sha256=TWl9vkcMCnLsUtgsuENZ-ku2oMDA-OUTzLh_yNRoMa4,4120
|
|
180
181
|
letta/server/ws_api/protocol.py,sha256=M_-gM5iuDBwa1cuN2IGNCG5GxMJwU2d3XW93XALv9s8,1821
|
|
181
182
|
letta/server/ws_api/server.py,sha256=C2Kv48PCwl46DQFb0ZP30s86KJLQ6dZk2AhWQEZn9pY,6004
|
|
182
|
-
letta/settings.py,sha256=
|
|
183
|
+
letta/settings.py,sha256=6VWC3vtTa8vqj6dqos4p_xHTMJNJS_8LRGJmqvaU1-o,3219
|
|
183
184
|
letta/streaming_interface.py,sha256=_FPUWy58j50evHcpXyd7zB1wWqeCc71NCFeWh_TBvnw,15736
|
|
184
185
|
letta/system.py,sha256=buKYPqG5n2x41hVmWpu6JUpyd7vTWED9Km2_M7dLrvk,6960
|
|
185
186
|
letta/utils.py,sha256=neUs7mxNfndzRL5XUxerr8Lic6w7qnyyvf8FBwMnyWw,30852
|
|
186
|
-
letta_nightly-0.4.1.
|
|
187
|
-
letta_nightly-0.4.1.
|
|
188
|
-
letta_nightly-0.4.1.
|
|
189
|
-
letta_nightly-0.4.1.
|
|
190
|
-
letta_nightly-0.4.1.
|
|
187
|
+
letta_nightly-0.4.1.dev20241013104006.dist-info/LICENSE,sha256=mExtuZ_GYJgDEI38GWdiEYZizZS4KkVt2SF1g_GPNhI,10759
|
|
188
|
+
letta_nightly-0.4.1.dev20241013104006.dist-info/METADATA,sha256=L5hOlFIaGT5BnE945CxaUdQEoKsOLrysrrL_bD9MjVU,6008
|
|
189
|
+
letta_nightly-0.4.1.dev20241013104006.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
|
190
|
+
letta_nightly-0.4.1.dev20241013104006.dist-info/entry_points.txt,sha256=2zdiyGNEZGV5oYBuS-y2nAAgjDgcC9yM_mHJBFSRt5U,40
|
|
191
|
+
letta_nightly-0.4.1.dev20241013104006.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|