letta-nightly 0.7.2.dev20250423222439__py3-none-any.whl → 0.7.3.dev20250424054013__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
letta/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "0.7.2"
1
+ __version__ = "0.7.3"
2
2
 
3
3
  # import clients
4
4
  from letta.client.client import LocalClient, RESTClient, create_client
letta/agent.py CHANGED
@@ -332,13 +332,14 @@ class Agent(BaseAgent):
332
332
  log_telemetry(self.logger, "_get_ai_reply create start")
333
333
  # New LLM client flow
334
334
  llm_client = LLMClient.create(
335
- llm_config=self.agent_state.llm_config,
335
+ provider=self.agent_state.llm_config.model_endpoint_type,
336
336
  put_inner_thoughts_first=put_inner_thoughts_first,
337
337
  )
338
338
 
339
339
  if llm_client and not stream:
340
340
  response = llm_client.send_llm_request(
341
341
  messages=message_sequence,
342
+ llm_config=self.agent_state.llm_config,
342
343
  tools=allowed_functions,
343
344
  stream=stream,
344
345
  force_tool_call=force_tool_call,
@@ -66,7 +66,7 @@ class LettaAgent(BaseAgent):
66
66
  )
67
67
  tool_rules_solver = ToolRulesSolver(agent_state.tool_rules)
68
68
  llm_client = LLMClient.create(
69
- llm_config=agent_state.llm_config,
69
+ provider=agent_state.llm_config.model_endpoint_type,
70
70
  put_inner_thoughts_first=True,
71
71
  )
72
72
  for step in range(max_steps):
@@ -182,6 +182,7 @@ class LettaAgent(BaseAgent):
182
182
 
183
183
  response = await llm_client.send_llm_request_async(
184
184
  messages=in_context_messages,
185
+ llm_config=agent_state.llm_config,
185
186
  tools=allowed_tools,
186
187
  force_tool_call=force_tool_call,
187
188
  stream=stream,
@@ -156,7 +156,7 @@ class LettaAgentBatch:
156
156
 
157
157
  log_event(name="init_llm_client")
158
158
  llm_client = LLMClient.create(
159
- llm_config=agent_states[0].llm_config,
159
+ provider=agent_states[0].llm_config.model_endpoint_type,
160
160
  put_inner_thoughts_first=True,
161
161
  )
162
162
  agent_llm_config_mapping = {s.id: s.llm_config for s in agent_states}
@@ -272,9 +272,14 @@ class LettaAgentBatch:
272
272
  request_status_updates.append(RequestStatusUpdateInfo(llm_batch_id=llm_batch_id, agent_id=aid, request_status=status))
273
273
 
274
274
  # translate provider‑specific response → OpenAI‑style tool call (unchanged)
275
- llm_client = LLMClient.create(llm_config=item.llm_config, put_inner_thoughts_first=True)
275
+ llm_client = LLMClient.create(
276
+ provider=item.llm_config.model_endpoint_type,
277
+ put_inner_thoughts_first=True,
278
+ )
276
279
  tool_call = (
277
- llm_client.convert_response_to_chat_completion(response_data=pr.message.model_dump(), input_messages=[])
280
+ llm_client.convert_response_to_chat_completion(
281
+ response_data=pr.message.model_dump(), input_messages=[], llm_config=item.llm_config
282
+ )
278
283
  .choices[0]
279
284
  .message.tool_calls[0]
280
285
  )
@@ -90,7 +90,7 @@ class VoiceAgent(BaseAgent):
90
90
  # )
91
91
  self.message_buffer_limit = message_buffer_limit
92
92
  # self.message_buffer_min = message_buffer_min
93
- self.offline_memory_agent = EphemeralMemoryAgent(
93
+ self.sleeptime_memory_agent = EphemeralMemoryAgent(
94
94
  agent_id=agent_id, openai_client=openai_client, message_manager=message_manager, agent_manager=agent_manager, actor=actor
95
95
  )
96
96
 
@@ -372,7 +372,7 @@ class VoiceAgent(BaseAgent):
372
372
  return f"Failed to call tool. Error: {e}", False
373
373
 
374
374
  async def _recall_memory(self, query, agent_state: AgentState) -> None:
375
- results = await self.offline_memory_agent.step([MessageCreate(role="user", content=[TextContent(text=query)])])
375
+ results = await self.sleeptime_memory_agent.step([MessageCreate(role="user", content=[TextContent(text=query)])])
376
376
  target_block = next(b for b in agent_state.memory.blocks if b.label == self.summary_block_label)
377
377
  self.block_manager.update_block(
378
378
  block_id=target_block.id, block_update=BlockUpdate(value=results[0].content[0].text), actor=self.actor
letta/client/client.py CHANGED
@@ -85,6 +85,7 @@ class AbstractClient(object):
85
85
  description: Optional[str] = None,
86
86
  tags: Optional[List[str]] = None,
87
87
  message_buffer_autoclear: bool = False,
88
+ response_format: Optional[ResponseFormatUnion] = None,
88
89
  ) -> AgentState:
89
90
  raise NotImplementedError
90
91
 
@@ -2352,6 +2353,7 @@ class LocalClient(AbstractClient):
2352
2353
  initial_message_sequence: Optional[List[Message]] = None,
2353
2354
  tags: Optional[List[str]] = None,
2354
2355
  message_buffer_autoclear: bool = False,
2356
+ response_format: Optional[ResponseFormatUnion] = None,
2355
2357
  ) -> AgentState:
2356
2358
  """Create an agent
2357
2359
 
@@ -2405,6 +2407,7 @@ class LocalClient(AbstractClient):
2405
2407
  "initial_message_sequence": initial_message_sequence,
2406
2408
  "tags": tags,
2407
2409
  "message_buffer_autoclear": message_buffer_autoclear,
2410
+ "response_format": response_format,
2408
2411
  }
2409
2412
 
2410
2413
  # Only add name if it's not None
@@ -2,7 +2,7 @@ import importlib
2
2
  import inspect
3
3
  from textwrap import dedent # remove indentation
4
4
  from types import ModuleType
5
- from typing import Dict, List, Optional
5
+ from typing import Dict, List, Literal, Optional
6
6
 
7
7
  from letta.errors import LettaToolCreateError
8
8
  from letta.functions.schema_generator import generate_schema
@@ -20,6 +20,7 @@ def derive_openai_json_schema(source_code: str, name: Optional[str] = None) -> d
20
20
  "Optional": Optional,
21
21
  "List": List,
22
22
  "Dict": Dict,
23
+ "Literal": Literal,
23
24
  # To support Pydantic models
24
25
  # "BaseModel": BaseModel,
25
26
  # "Field": Field,
@@ -5,6 +5,7 @@ from typing import Any, Dict, List, Optional, Type, Union, get_args, get_origin
5
5
  from composio.client.collections import ActionParametersModel
6
6
  from docstring_parser import parse
7
7
  from pydantic import BaseModel
8
+ from typing_extensions import Literal
8
9
 
9
10
  from letta.functions.mcp_client.types import MCPTool
10
11
 
@@ -70,6 +71,10 @@ def type_to_json_schema_type(py_type) -> dict:
70
71
  "items": type_to_json_schema_type(args[0]),
71
72
  }
72
73
 
74
+ # Handle literals
75
+ if get_origin(py_type) is Literal:
76
+ return {"type": "string", "enum": get_args(py_type)}
77
+
73
78
  # Handle object types
74
79
  if py_type == dict or origin in (dict, Dict):
75
80
  args = get_args(py_type)
@@ -43,18 +43,18 @@ logger = get_logger(__name__)
43
43
 
44
44
  class AnthropicClient(LLMClientBase):
45
45
 
46
- def request(self, request_data: dict) -> dict:
46
+ def request(self, request_data: dict, llm_config: LLMConfig) -> dict:
47
47
  client = self._get_anthropic_client(async_client=False)
48
48
  response = client.beta.messages.create(**request_data, betas=["tools-2024-04-04"])
49
49
  return response.model_dump()
50
50
 
51
- async def request_async(self, request_data: dict) -> dict:
51
+ async def request_async(self, request_data: dict, llm_config: LLMConfig) -> dict:
52
52
  client = self._get_anthropic_client(async_client=True)
53
53
  response = await client.beta.messages.create(**request_data, betas=["tools-2024-04-04"])
54
54
  return response.model_dump()
55
55
 
56
56
  @trace_method
57
- async def stream_async(self, request_data: dict) -> AsyncStream[BetaRawMessageStreamEvent]:
57
+ async def stream_async(self, request_data: dict, llm_config: LLMConfig) -> AsyncStream[BetaRawMessageStreamEvent]:
58
58
  client = self._get_anthropic_client(async_client=True)
59
59
  request_data["stream"] = True
60
60
  return await client.beta.messages.create(**request_data, betas=["tools-2024-04-04"])
@@ -310,6 +310,7 @@ class AnthropicClient(LLMClientBase):
310
310
  self,
311
311
  response_data: dict,
312
312
  input_messages: List[PydanticMessage],
313
+ llm_config: LLMConfig,
313
314
  ) -> ChatCompletionResponse:
314
315
  """
315
316
  Example response from Claude 3:
@@ -411,7 +412,7 @@ class AnthropicClient(LLMClientBase):
411
412
  total_tokens=prompt_tokens + completion_tokens,
412
413
  ),
413
414
  )
414
- if self.llm_config.put_inner_thoughts_in_kwargs:
415
+ if llm_config.put_inner_thoughts_in_kwargs:
415
416
  chat_completion_response = unpack_all_inner_thoughts_from_kwargs(
416
417
  response=chat_completion_response, inner_thoughts_key=INNER_THOUGHTS_KWARG
417
418
  )
@@ -25,15 +25,15 @@ logger = get_logger(__name__)
25
25
 
26
26
  class GoogleAIClient(LLMClientBase):
27
27
 
28
- def request(self, request_data: dict) -> dict:
28
+ def request(self, request_data: dict, llm_config: LLMConfig) -> dict:
29
29
  """
30
30
  Performs underlying request to llm and returns raw response.
31
31
  """
32
32
  # print("[google_ai request]", json.dumps(request_data, indent=2))
33
33
 
34
34
  url, headers = get_gemini_endpoint_and_headers(
35
- base_url=str(self.llm_config.model_endpoint),
36
- model=self.llm_config.model,
35
+ base_url=str(llm_config.model_endpoint),
36
+ model=llm_config.model,
37
37
  api_key=str(model_settings.gemini_api_key),
38
38
  key_in_header=True,
39
39
  generate_content=True,
@@ -55,7 +55,7 @@ class GoogleAIClient(LLMClientBase):
55
55
  tool_objs = [Tool(**t) for t in tools]
56
56
  tool_names = [t.function.name for t in tool_objs]
57
57
  # Convert to the exact payload style Google expects
58
- tools = self.convert_tools_to_google_ai_format(tool_objs)
58
+ tools = self.convert_tools_to_google_ai_format(tool_objs, llm_config)
59
59
  else:
60
60
  tool_names = []
61
61
 
@@ -88,6 +88,7 @@ class GoogleAIClient(LLMClientBase):
88
88
  self,
89
89
  response_data: dict,
90
90
  input_messages: List[PydanticMessage],
91
+ llm_config: LLMConfig,
91
92
  ) -> ChatCompletionResponse:
92
93
  """
93
94
  Converts custom response format from llm client into an OpenAI
@@ -150,7 +151,7 @@ class GoogleAIClient(LLMClientBase):
150
151
  assert isinstance(function_args, dict), function_args
151
152
 
152
153
  # NOTE: this also involves stripping the inner monologue out of the function
153
- if self.llm_config.put_inner_thoughts_in_kwargs:
154
+ if llm_config.put_inner_thoughts_in_kwargs:
154
155
  from letta.local_llm.constants import INNER_THOUGHTS_KWARG
155
156
 
156
157
  assert INNER_THOUGHTS_KWARG in function_args, f"Couldn't find inner thoughts in function args:\n{function_call}"
@@ -259,49 +260,14 @@ class GoogleAIClient(LLMClientBase):
259
260
  return ChatCompletionResponse(
260
261
  id=response_id,
261
262
  choices=choices,
262
- model=self.llm_config.model, # NOTE: Google API doesn't pass back model in the response
263
+ model=llm_config.model, # NOTE: Google API doesn't pass back model in the response
263
264
  created=get_utc_time_int(),
264
265
  usage=usage,
265
266
  )
266
267
  except KeyError as e:
267
268
  raise e
268
269
 
269
- def _clean_google_ai_schema_properties(self, schema_part: dict):
270
- """Recursively clean schema parts to remove unsupported Google AI keywords."""
271
- if not isinstance(schema_part, dict):
272
- return
273
-
274
- # Per https://ai.google.dev/gemini-api/docs/function-calling?example=meeting#notes_and_limitations
275
- # * Only a subset of the OpenAPI schema is supported.
276
- # * Supported parameter types in Python are limited.
277
- unsupported_keys = ["default", "exclusiveMaximum", "exclusiveMinimum"]
278
- keys_to_remove_at_this_level = [key for key in unsupported_keys if key in schema_part]
279
- for key_to_remove in keys_to_remove_at_this_level:
280
- logger.warning(f"Removing unsupported keyword '{key_to_remove}' from schema part.")
281
- del schema_part[key_to_remove]
282
-
283
- if schema_part.get("type") == "string" and "format" in schema_part:
284
- allowed_formats = ["enum", "date-time"]
285
- if schema_part["format"] not in allowed_formats:
286
- logger.warning(f"Removing unsupported format '{schema_part['format']}' for string type. Allowed: {allowed_formats}")
287
- del schema_part["format"]
288
-
289
- # Check properties within the current level
290
- if "properties" in schema_part and isinstance(schema_part["properties"], dict):
291
- for prop_name, prop_schema in schema_part["properties"].items():
292
- self._clean_google_ai_schema_properties(prop_schema)
293
-
294
- # Check items within arrays
295
- if "items" in schema_part and isinstance(schema_part["items"], dict):
296
- self._clean_google_ai_schema_properties(schema_part["items"])
297
-
298
- # Check within anyOf, allOf, oneOf lists
299
- for key in ["anyOf", "allOf", "oneOf"]:
300
- if key in schema_part and isinstance(schema_part[key], list):
301
- for item_schema in schema_part[key]:
302
- self._clean_google_ai_schema_properties(item_schema)
303
-
304
- def convert_tools_to_google_ai_format(self, tools: List[Tool]) -> List[dict]:
270
+ def convert_tools_to_google_ai_format(self, tools: List[Tool], llm_config: LLMConfig) -> List[dict]:
305
271
  """
306
272
  OpenAI style:
307
273
  "tools": [{
@@ -365,7 +331,7 @@ class GoogleAIClient(LLMClientBase):
365
331
  self._clean_google_ai_schema_properties(func["parameters"])
366
332
 
367
333
  # Add inner thoughts
368
- if self.llm_config.put_inner_thoughts_in_kwargs:
334
+ if llm_config.put_inner_thoughts_in_kwargs:
369
335
  from letta.local_llm.constants import INNER_THOUGHTS_KWARG, INNER_THOUGHTS_KWARG_DESCRIPTION
370
336
 
371
337
  func["parameters"]["properties"][INNER_THOUGHTS_KWARG] = {
@@ -18,7 +18,7 @@ from letta.utils import get_tool_call_id
18
18
 
19
19
  class GoogleVertexClient(GoogleAIClient):
20
20
 
21
- def request(self, request_data: dict) -> dict:
21
+ def request(self, request_data: dict, llm_config: LLMConfig) -> dict:
22
22
  """
23
23
  Performs underlying request to llm and returns raw response.
24
24
  """
@@ -29,7 +29,7 @@ class GoogleVertexClient(GoogleAIClient):
29
29
  http_options={"api_version": "v1"},
30
30
  )
31
31
  response = client.models.generate_content(
32
- model=self.llm_config.model,
32
+ model=llm_config.model,
33
33
  contents=request_data["contents"],
34
34
  config=request_data["config"],
35
35
  )
@@ -45,7 +45,7 @@ class GoogleVertexClient(GoogleAIClient):
45
45
  """
46
46
  Constructs a request object in the expected data format for this client.
47
47
  """
48
- request_data = super().build_request_data(messages, self.llm_config, tools, force_tool_call)
48
+ request_data = super().build_request_data(messages, llm_config, tools, force_tool_call)
49
49
  request_data["config"] = request_data.pop("generation_config")
50
50
  request_data["config"]["tools"] = request_data.pop("tools")
51
51
 
@@ -75,6 +75,7 @@ class GoogleVertexClient(GoogleAIClient):
75
75
  self,
76
76
  response_data: dict,
77
77
  input_messages: List[PydanticMessage],
78
+ llm_config: LLMConfig,
78
79
  ) -> ChatCompletionResponse:
79
80
  """
80
81
  Converts custom response format from llm client into an OpenAI
@@ -136,7 +137,7 @@ class GoogleVertexClient(GoogleAIClient):
136
137
  assert isinstance(function_args, dict), function_args
137
138
 
138
139
  # NOTE: this also involves stripping the inner monologue out of the function
139
- if self.llm_config.put_inner_thoughts_in_kwargs:
140
+ if llm_config.put_inner_thoughts_in_kwargs:
140
141
  from letta.local_llm.constants import INNER_THOUGHTS_KWARG
141
142
 
142
143
  assert INNER_THOUGHTS_KWARG in function_args, f"Couldn't find inner thoughts in function args:\n{function_call}"
@@ -233,7 +234,7 @@ class GoogleVertexClient(GoogleAIClient):
233
234
  return ChatCompletionResponse(
234
235
  id=response_id,
235
236
  choices=choices,
236
- model=self.llm_config.model, # NOTE: Google API doesn't pass back model in the response
237
+ model=llm_config.model, # NOTE: Google API doesn't pass back model in the response
237
238
  created=get_utc_time_int(),
238
239
  usage=usage,
239
240
  )
@@ -1,7 +1,7 @@
1
1
  from typing import Optional
2
2
 
3
3
  from letta.llm_api.llm_client_base import LLMClientBase
4
- from letta.schemas.llm_config import LLMConfig
4
+ from letta.schemas.enums import ProviderType
5
5
 
6
6
 
7
7
  class LLMClient:
@@ -9,17 +9,15 @@ class LLMClient:
9
9
 
10
10
  @staticmethod
11
11
  def create(
12
- llm_config: LLMConfig,
12
+ provider: ProviderType,
13
13
  put_inner_thoughts_first: bool = True,
14
14
  ) -> Optional[LLMClientBase]:
15
15
  """
16
16
  Create an LLM client based on the model endpoint type.
17
17
 
18
18
  Args:
19
- llm_config: Configuration for the LLM model
19
+ provider: The model endpoint type
20
20
  put_inner_thoughts_first: Whether to put inner thoughts first in the response
21
- use_structured_output: Whether to use structured output
22
- use_tool_naming: Whether to use tool naming
23
21
 
24
22
  Returns:
25
23
  An instance of LLMClientBase subclass
@@ -27,33 +25,29 @@ class LLMClient:
27
25
  Raises:
28
26
  ValueError: If the model endpoint type is not supported
29
27
  """
30
- match llm_config.model_endpoint_type:
31
- case "google_ai":
28
+ match provider:
29
+ case ProviderType.google_ai:
32
30
  from letta.llm_api.google_ai_client import GoogleAIClient
33
31
 
34
32
  return GoogleAIClient(
35
- llm_config=llm_config,
36
33
  put_inner_thoughts_first=put_inner_thoughts_first,
37
34
  )
38
- case "google_vertex":
35
+ case ProviderType.google_vertex:
39
36
  from letta.llm_api.google_vertex_client import GoogleVertexClient
40
37
 
41
38
  return GoogleVertexClient(
42
- llm_config=llm_config,
43
39
  put_inner_thoughts_first=put_inner_thoughts_first,
44
40
  )
45
- case "anthropic":
41
+ case ProviderType.anthropic:
46
42
  from letta.llm_api.anthropic_client import AnthropicClient
47
43
 
48
44
  return AnthropicClient(
49
- llm_config=llm_config,
50
45
  put_inner_thoughts_first=put_inner_thoughts_first,
51
46
  )
52
- case "openai":
47
+ case ProviderType.openai:
53
48
  from letta.llm_api.openai_client import OpenAIClient
54
49
 
55
50
  return OpenAIClient(
56
- llm_config=llm_config,
57
51
  put_inner_thoughts_first=put_inner_thoughts_first,
58
52
  )
59
53
  case _:
@@ -20,17 +20,16 @@ class LLMClientBase:
20
20
 
21
21
  def __init__(
22
22
  self,
23
- llm_config: LLMConfig,
24
23
  put_inner_thoughts_first: Optional[bool] = True,
25
24
  use_tool_naming: bool = True,
26
25
  ):
27
- self.llm_config = llm_config
28
26
  self.put_inner_thoughts_first = put_inner_thoughts_first
29
27
  self.use_tool_naming = use_tool_naming
30
28
 
31
29
  def send_llm_request(
32
30
  self,
33
31
  messages: List[Message],
32
+ llm_config: LLMConfig,
34
33
  tools: Optional[List[dict]] = None, # TODO: change to Tool object
35
34
  stream: bool = False,
36
35
  force_tool_call: Optional[str] = None,
@@ -40,23 +39,24 @@ class LLMClientBase:
40
39
  If stream=True, returns a Stream[ChatCompletionChunk] that can be iterated over.
41
40
  Otherwise returns a ChatCompletionResponse.
42
41
  """
43
- request_data = self.build_request_data(messages, self.llm_config, tools, force_tool_call)
42
+ request_data = self.build_request_data(messages, llm_config, tools, force_tool_call)
44
43
 
45
44
  try:
46
45
  log_event(name="llm_request_sent", attributes=request_data)
47
46
  if stream:
48
- return self.stream(request_data)
47
+ return self.stream(request_data, llm_config)
49
48
  else:
50
- response_data = self.request(request_data)
49
+ response_data = self.request(request_data, llm_config)
51
50
  log_event(name="llm_response_received", attributes=response_data)
52
51
  except Exception as e:
53
52
  raise self.handle_llm_error(e)
54
53
 
55
- return self.convert_response_to_chat_completion(response_data, messages)
54
+ return self.convert_response_to_chat_completion(response_data, messages, llm_config)
56
55
 
57
56
  async def send_llm_request_async(
58
57
  self,
59
58
  messages: List[Message],
59
+ llm_config: LLMConfig,
60
60
  tools: Optional[List[dict]] = None, # TODO: change to Tool object
61
61
  stream: bool = False,
62
62
  force_tool_call: Optional[str] = None,
@@ -66,19 +66,19 @@ class LLMClientBase:
66
66
  If stream=True, returns an AsyncStream[ChatCompletionChunk] that can be async iterated over.
67
67
  Otherwise returns a ChatCompletionResponse.
68
68
  """
69
- request_data = self.build_request_data(messages, self.llm_config, tools, force_tool_call)
69
+ request_data = self.build_request_data(messages, llm_config, tools, force_tool_call)
70
70
 
71
71
  try:
72
72
  log_event(name="llm_request_sent", attributes=request_data)
73
73
  if stream:
74
- return await self.stream_async(request_data)
74
+ return await self.stream_async(request_data, llm_config)
75
75
  else:
76
- response_data = await self.request_async(request_data)
76
+ response_data = await self.request_async(request_data, llm_config)
77
77
  log_event(name="llm_response_received", attributes=response_data)
78
78
  except Exception as e:
79
79
  raise self.handle_llm_error(e)
80
80
 
81
- return self.convert_response_to_chat_completion(response_data, messages)
81
+ return self.convert_response_to_chat_completion(response_data, messages, llm_config)
82
82
 
83
83
  async def send_llm_batch_request_async(
84
84
  self,
@@ -102,14 +102,14 @@ class LLMClientBase:
102
102
  raise NotImplementedError
103
103
 
104
104
  @abstractmethod
105
- def request(self, request_data: dict) -> dict:
105
+ def request(self, request_data: dict, llm_config: LLMConfig) -> dict:
106
106
  """
107
107
  Performs underlying request to llm and returns raw response.
108
108
  """
109
109
  raise NotImplementedError
110
110
 
111
111
  @abstractmethod
112
- async def request_async(self, request_data: dict) -> dict:
112
+ async def request_async(self, request_data: dict, llm_config: LLMConfig) -> dict:
113
113
  """
114
114
  Performs underlying request to llm and returns raw response.
115
115
  """
@@ -120,6 +120,7 @@ class LLMClientBase:
120
120
  self,
121
121
  response_data: dict,
122
122
  input_messages: List[Message],
123
+ llm_config: LLMConfig,
123
124
  ) -> ChatCompletionResponse:
124
125
  """
125
126
  Converts custom response format from llm client into an OpenAI
@@ -128,18 +129,18 @@ class LLMClientBase:
128
129
  raise NotImplementedError
129
130
 
130
131
  @abstractmethod
131
- def stream(self, request_data: dict) -> Stream[ChatCompletionChunk]:
132
+ def stream(self, request_data: dict, llm_config: LLMConfig) -> Stream[ChatCompletionChunk]:
132
133
  """
133
134
  Performs underlying streaming request to llm and returns raw response.
134
135
  """
135
- raise NotImplementedError(f"Streaming is not supported for {self.llm_config.model_endpoint_type}")
136
+ raise NotImplementedError(f"Streaming is not supported for {llm_config.model_endpoint_type}")
136
137
 
137
138
  @abstractmethod
138
- async def stream_async(self, request_data: dict) -> AsyncStream[ChatCompletionChunk]:
139
+ async def stream_async(self, request_data: dict, llm_config: LLMConfig) -> AsyncStream[ChatCompletionChunk]:
139
140
  """
140
141
  Performs underlying streaming request to llm and returns raw response.
141
142
  """
142
- raise NotImplementedError(f"Streaming is not supported for {self.llm_config.model_endpoint_type}")
143
+ raise NotImplementedError(f"Streaming is not supported for {llm_config.model_endpoint_type}")
143
144
 
144
145
  @abstractmethod
145
146
  def handle_llm_error(self, e: Exception) -> Exception:
@@ -62,11 +62,11 @@ def supports_parallel_tool_calling(model: str) -> bool:
62
62
 
63
63
 
64
64
  class OpenAIClient(LLMClientBase):
65
- def _prepare_client_kwargs(self) -> dict:
65
+ def _prepare_client_kwargs(self, llm_config: LLMConfig) -> dict:
66
66
  api_key = model_settings.openai_api_key or os.environ.get("OPENAI_API_KEY")
67
67
  # supposedly the openai python client requires a dummy API key
68
68
  api_key = api_key or "DUMMY_API_KEY"
69
- kwargs = {"api_key": api_key, "base_url": self.llm_config.model_endpoint}
69
+ kwargs = {"api_key": api_key, "base_url": llm_config.model_endpoint}
70
70
 
71
71
  return kwargs
72
72
 
@@ -115,7 +115,7 @@ class OpenAIClient(LLMClientBase):
115
115
  # TODO(matt) move into LLMConfig
116
116
  # TODO: This vllm checking is very brittle and is a patch at most
117
117
  tool_choice = None
118
- if llm_config.model_endpoint == "https://inference.memgpt.ai" or (llm_config.handle and "vllm" in self.llm_config.handle):
118
+ if llm_config.model_endpoint == "https://inference.memgpt.ai" or (llm_config.handle and "vllm" in llm_config.handle):
119
119
  tool_choice = "auto" # TODO change to "required" once proxy supports it
120
120
  elif tools:
121
121
  # only set if tools is non-Null
@@ -152,20 +152,20 @@ class OpenAIClient(LLMClientBase):
152
152
 
153
153
  return data.model_dump(exclude_unset=True)
154
154
 
155
- def request(self, request_data: dict) -> dict:
155
+ def request(self, request_data: dict, llm_config: LLMConfig) -> dict:
156
156
  """
157
157
  Performs underlying synchronous request to OpenAI API and returns raw response dict.
158
158
  """
159
- client = OpenAI(**self._prepare_client_kwargs())
159
+ client = OpenAI(**self._prepare_client_kwargs(llm_config))
160
160
 
161
161
  response: ChatCompletion = client.chat.completions.create(**request_data)
162
162
  return response.model_dump()
163
163
 
164
- async def request_async(self, request_data: dict) -> dict:
164
+ async def request_async(self, request_data: dict, llm_config: LLMConfig) -> dict:
165
165
  """
166
166
  Performs underlying asynchronous request to OpenAI API and returns raw response dict.
167
167
  """
168
- client = AsyncOpenAI(**self._prepare_client_kwargs())
168
+ client = AsyncOpenAI(**self._prepare_client_kwargs(llm_config))
169
169
  response: ChatCompletion = await client.chat.completions.create(**request_data)
170
170
  return response.model_dump()
171
171
 
@@ -173,6 +173,7 @@ class OpenAIClient(LLMClientBase):
173
173
  self,
174
174
  response_data: dict,
175
175
  input_messages: List[PydanticMessage], # Included for consistency, maybe used later
176
+ llm_config: LLMConfig,
176
177
  ) -> ChatCompletionResponse:
177
178
  """
178
179
  Converts raw OpenAI response dict into the ChatCompletionResponse Pydantic model.
@@ -183,30 +184,30 @@ class OpenAIClient(LLMClientBase):
183
184
  chat_completion_response = ChatCompletionResponse(**response_data)
184
185
 
185
186
  # Unpack inner thoughts if they were embedded in function arguments
186
- if self.llm_config.put_inner_thoughts_in_kwargs:
187
+ if llm_config.put_inner_thoughts_in_kwargs:
187
188
  chat_completion_response = unpack_all_inner_thoughts_from_kwargs(
188
189
  response=chat_completion_response, inner_thoughts_key=INNER_THOUGHTS_KWARG
189
190
  )
190
191
 
191
192
  # If we used a reasoning model, create a content part for the ommitted reasoning
192
- if is_openai_reasoning_model(self.llm_config.model):
193
+ if is_openai_reasoning_model(llm_config.model):
193
194
  chat_completion_response.choices[0].message.ommitted_reasoning_content = True
194
195
 
195
196
  return chat_completion_response
196
197
 
197
- def stream(self, request_data: dict) -> Stream[ChatCompletionChunk]:
198
+ def stream(self, request_data: dict, llm_config: LLMConfig) -> Stream[ChatCompletionChunk]:
198
199
  """
199
200
  Performs underlying streaming request to OpenAI and returns the stream iterator.
200
201
  """
201
- client = OpenAI(**self._prepare_client_kwargs())
202
+ client = OpenAI(**self._prepare_client_kwargs(llm_config))
202
203
  response_stream: Stream[ChatCompletionChunk] = client.chat.completions.create(**request_data, stream=True)
203
204
  return response_stream
204
205
 
205
- async def stream_async(self, request_data: dict) -> AsyncStream[ChatCompletionChunk]:
206
+ async def stream_async(self, request_data: dict, llm_config: LLMConfig) -> AsyncStream[ChatCompletionChunk]:
206
207
  """
207
208
  Performs underlying asynchronous streaming request to OpenAI and returns the async stream iterator.
208
209
  """
209
- client = AsyncOpenAI(**self._prepare_client_kwargs())
210
+ client = AsyncOpenAI(**self._prepare_client_kwargs(llm_config))
210
211
  response_stream: AsyncStream[ChatCompletionChunk] = await client.chat.completions.create(**request_data, stream=True)
211
212
  return response_stream
212
213
 
letta/memory.py CHANGED
@@ -79,7 +79,7 @@ def summarize_messages(
79
79
  llm_config_no_inner_thoughts.put_inner_thoughts_in_kwargs = False
80
80
 
81
81
  llm_client = LLMClient.create(
82
- llm_config=llm_config_no_inner_thoughts,
82
+ provider=llm_config_no_inner_thoughts.model_endpoint_type,
83
83
  put_inner_thoughts_first=False,
84
84
  )
85
85
  # try to use new client, otherwise fallback to old flow
@@ -87,6 +87,7 @@ def summarize_messages(
87
87
  if llm_client:
88
88
  response = llm_client.send_llm_request(
89
89
  messages=message_sequence,
90
+ llm_config=llm_config_no_inner_thoughts,
90
91
  stream=False,
91
92
  )
92
93
  else:
@@ -0,0 +1,5 @@
1
+ I am an expert conversation memory agent that can do the following:
2
+ - Consolidate memories into more concise blocks
3
+ - Identify patterns in user behavior
4
+ - Make inferences based on the memory
5
+ I manage the memory blocks such that they contain everything that is important about the conversation.
letta/schemas/enums.py CHANGED
@@ -3,6 +3,9 @@ from enum import Enum
3
3
 
4
4
  class ProviderType(str, Enum):
5
5
  anthropic = "anthropic"
6
+ google_ai = "google_ai"
7
+ google_vertex = "google_vertex"
8
+ openai = "openai"
6
9
 
7
10
 
8
11
  class MessageRole(str, Enum):
letta/server/server.py CHANGED
@@ -766,12 +766,7 @@ class SyncServer(Server):
766
766
  memory_blocks=[
767
767
  CreateBlock(
768
768
  label="memory_persona",
769
- value=(
770
- "I am an expert conversation memory manager. "
771
- "I manage the memory blocks such that they "
772
- "contain everything that is important about "
773
- "the conversation."
774
- ),
769
+ value=get_persona_text("sleeptime_memory_persona"),
775
770
  ),
776
771
  ],
777
772
  llm_config=main_agent.llm_config,
@@ -236,6 +236,7 @@ class AgentManager:
236
236
  base_template_id=agent_create.base_template_id,
237
237
  message_buffer_autoclear=agent_create.message_buffer_autoclear,
238
238
  enable_sleeptime=agent_create.enable_sleeptime,
239
+ response_format=agent_create.response_format,
239
240
  created_by_id=actor.id,
240
241
  last_updated_by_id=actor.id,
241
242
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: letta-nightly
3
- Version: 0.7.2.dev20250423222439
3
+ Version: 0.7.3.dev20250424054013
4
4
  Summary: Create LLM agents with long-term memory and custom tools
5
5
  License: Apache License
6
6
  Author: Letta Team
@@ -1,21 +1,21 @@
1
- letta/__init__.py,sha256=Vn0bUZvcMtIJHa5k4fpXa2QL1Fd05BUjvVsE1nwn6Xw,917
1
+ letta/__init__.py,sha256=ShZtnPIM0QOgxGGKrq6VfF4qXaE6_ZDoAQ6zXI0RepM,917
2
2
  letta/__main__.py,sha256=6Hs2PV7EYc5Tid4g4OtcLXhqVHiNYTGzSBdoOnW2HXA,29
3
- letta/agent.py,sha256=FLb_4sYByecGSw38nmBdpb7qbJh6LZY-k-bC4HDQREU,72088
3
+ letta/agent.py,sha256=YmAkpFXHwZ0UhoatyIE-ZrV-kQDwg7f4A1o4cymoI-Y,72170
4
4
  letta/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  letta/agents/base_agent.py,sha256=yjB1Yz6L-9hTFinqkvyf6c-8dDX9O4u8VCrKrvA4G3s,2348
6
6
  letta/agents/ephemeral_agent.py,sha256=el-SUF_16vv_7OouIR-6z0pAE9Yc0PLibygvfCKwqfo,2736
7
7
  letta/agents/ephemeral_memory_agent.py,sha256=tVRsL18EvruNyrhzPkzLqiptfWa9jAC2GmSjUf5zKQo,4821
8
8
  letta/agents/helpers.py,sha256=sYfjJLCEQg0aaKDRIJ2Xm_fG1yivCB9wU6bSskZMPKg,2568
9
- letta/agents/letta_agent.py,sha256=hEcTc9RE9sim_P-Fj08cEPgT-6QvRfSAQB6zK_s_0a8,17751
10
- letta/agents/letta_agent_batch.py,sha256=TFOaWEodfhowylbcwK2Yz2mDe1pcduKZ9gW-eGckT1w,22750
11
- letta/agents/voice_agent.py,sha256=ywc6zsyEjeRxmhCwD1-opO9mAEhr2l9PRV3lf9y7HDc,17330
9
+ letta/agents/letta_agent.py,sha256=9kOJW8hU_UhRwaVujYBWxVxsOGbh367xfdymI81RdNI,17816
10
+ letta/agents/letta_agent_batch.py,sha256=YsuYKwanRAmSPwmT5NVG3oIyOjlOz08hrQgpgRNhXt0,22899
11
+ letta/agents/voice_agent.py,sha256=qzDw7MWQYwxsqOT4nIJ9OSl72n7b2Xy3ZUqc2_AEP5M,17334
12
12
  letta/benchmark/benchmark.py,sha256=ebvnwfp3yezaXOQyGXkYCDYpsmre-b9hvNtnyx4xkG0,3701
13
13
  letta/benchmark/constants.py,sha256=aXc5gdpMGJT327VuxsT5FngbCK2J41PQYeICBO7g_RE,536
14
14
  letta/cli/cli.py,sha256=zJz78-qDUz-depb7VQWkg87RBKiETQU4h9DI6ukQBa8,16477
15
15
  letta/cli/cli_config.py,sha256=MNMhIAAjXiAy2gX_gAtqiY0Ya6VNbzXJWjIcRVEZa-k,8597
16
16
  letta/cli/cli_load.py,sha256=vER0PwpHnsCZtCHcR2YjEXM-VVuO9jhfQibdo3gI3S0,2703
17
17
  letta/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
- letta/client/client.py,sha256=BzGlA6Z1FB0zi6-17x7eus5l_GPvmnnKiPFl4D-kGaE,138050
18
+ letta/client/client.py,sha256=nF2KxkTMp7JUx_ITLKhsU14z0e9Uwwkux3heskQmfeE,138224
19
19
  letta/client/streaming.py,sha256=UsDS_tDTsA3HgYryIDvGGmx_dWfnfQwtmEwLi4Z89Ik,4701
20
20
  letta/client/utils.py,sha256=VCGV-op5ZSmurd4yw7Vhf93XDQ0BkyBT8qsuV7EqfiU,2859
21
21
  letta/config.py,sha256=JFGY4TWW0Wm5fTbZamOwWqk5G8Nn-TXyhgByGoAqy2c,12375
@@ -29,7 +29,7 @@ letta/functions/ast_parsers.py,sha256=CQI0rUoIXcLKAev_GYrXcldRIGN5ZQtk5u4FLoHe5s
29
29
  letta/functions/function_sets/base.py,sha256=Z-trOG7dKbOWpJlsEBNSGlwcQnPuRXqnQ9NMed98nbY,16392
30
30
  letta/functions/function_sets/extras.py,sha256=mG7jCd2RUsf1w9G8mVcv26twJWpiDhbWI6VvnLZoEOk,4899
31
31
  letta/functions/function_sets/multi_agent.py,sha256=de2_wNVpWQviF1-XUkrliFvVresj6cOw7nOB61nGGW8,6899
32
- letta/functions/functions.py,sha256=NyWLh7a-f4mXti5vM1oWDwXzfA58VmVVqL03O9vosKY,5672
32
+ letta/functions/functions.py,sha256=No9DSb_BsXD3xwyODiEZRfmudKI3KoEK4bOtVQXFiJo,5713
33
33
  letta/functions/helpers.py,sha256=q-Ipwp4jB0zrw2slAVWBt2QsYbPoDkTq8PdFVoYYB6I,28043
34
34
  letta/functions/interface.py,sha256=pN1gpDnLISW44gRcic1IX6I6pDwOT9UbkST_4ICuMvQ,2936
35
35
  letta/functions/mcp_client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -38,7 +38,7 @@ letta/functions/mcp_client/exceptions.py,sha256=IE5SLCuMK7hK9V1QsJafPo6u0S0OwqRv
38
38
  letta/functions/mcp_client/sse_client.py,sha256=XOLnWIcrjBEkZ-IksgnHKSdVds3pC2E8OPkIhCNxloo,1470
39
39
  letta/functions/mcp_client/stdio_client.py,sha256=2oouLGphu4S15OrYj97n9_ZYZo-GMRWNLWwaw-U4TNs,4562
40
40
  letta/functions/mcp_client/types.py,sha256=nmcnQn2EpxXzXg5_pWPsHZobfxO6OucaUgz1bVvam7o,1411
41
- letta/functions/schema_generator.py,sha256=4hiDQpHemyfKWME-5X6xJuSiv7g9V_BgAPFegohHBIM,22327
41
+ letta/functions/schema_generator.py,sha256=OoXDHd5oZMNjljZJplEIMOMmKvxO_rfDFtAi-E9EHMA,22488
42
42
  letta/groups/dynamic_multi_agent.py,sha256=OLCxhICFLYyx8wjKGPr1INc6pniEuk4YGZyZhq2vkiY,12230
43
43
  letta/groups/helpers.py,sha256=Cof7vfZMOT2gApYpROpiAyKSKrofP1UPJxZQWFcZaqA,4336
44
44
  letta/groups/round_robin_multi_agent.py,sha256=uUJff0bO68udOREiKFWeS7eEQlk3bF7hcfLSFXMScqI,6999
@@ -67,22 +67,22 @@ letta/jobs/scheduler.py,sha256=nsXQTpW2YfVC8g6X35RUjguLVPV0NOku2Zt8SdDSnhg,2154
67
67
  letta/jobs/types.py,sha256=K8GKEnqEgAT6Kq4F2hUrBC4ZAFM9OkfOjVMStzxKuXQ,742
68
68
  letta/llm_api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
69
69
  letta/llm_api/anthropic.py,sha256=gF8IbHlNSjD2vSw7MukHEJqWAUr9h0kx5OzF-C0AG0s,44521
70
- letta/llm_api/anthropic_client.py,sha256=9xrto08r_uU9YV7_xtwMkrM8tqiDNmaFaXKhBNAouYc,24323
70
+ letta/llm_api/anthropic_client.py,sha256=9nQdoONlt_stvgX3hl30sgzv66_Yk_PeAnvOEO2Msgg,24418
71
71
  letta/llm_api/aws_bedrock.py,sha256=kAPpKPRe4ZUa6fkxFbo8xwQgq4fJf3QoZEAP1LOCfaw,4168
72
72
  letta/llm_api/azure_openai.py,sha256=YAkXwKyfnJFNhB45pkJVFsoxUNB_M74rQYchtw_CN6I,5099
73
73
  letta/llm_api/azure_openai_constants.py,sha256=ZaR2IasJThijG0uhLKJThrixdAxLPD2IojfeaJ-KQMQ,294
74
74
  letta/llm_api/cohere.py,sha256=IZ6LXyOFMYjWHTeNG9lvFxCdV_NIl0hY2q9SPFYXNkQ,14849
75
75
  letta/llm_api/deepseek.py,sha256=b1mSW8gnBrpAI8d2GcBpDyLYDnuC-P1UP6xJPalfQS4,12456
76
- letta/llm_api/google_ai_client.py,sha256=xkxPnUEJtcajV4ZsiHRr0y7caW8sQ586nnr1XOilejI,22694
76
+ letta/llm_api/google_ai_client.py,sha256=FGNmoMPV1ciZ6opeRcpSqgu_t9P66kM4aapaN0wfQpw,20792
77
77
  letta/llm_api/google_constants.py,sha256=1dqwt-YwdYGnAHV5rIPfGHfE3ybPzSn_48vlNYfd-bk,588
78
- letta/llm_api/google_vertex_client.py,sha256=YnDlqADuRdBoUCpsh_pj05UfpGybG71pEiaqsJxXJfk,11611
78
+ letta/llm_api/google_vertex_client.py,sha256=lTfAUTPSqwe-cuOoEgUehdwg2ZVHLqXRiu-sj6g8PJg,11645
79
79
  letta/llm_api/helpers.py,sha256=sLYv30UnKBRVPuhU_KDXfKFdbkUONiDAyVEwGr86l3A,16780
80
80
  letta/llm_api/llm_api_tools.py,sha256=s1n3YDGp-ShHOzxeuQ1BOje0oh7H_yGefRVwFXsc_A8,27547
81
- letta/llm_api/llm_client.py,sha256=PWnzdwD_7TMmbBuZnCWt10pJL4WXLCsQ3yS9-Y3Nh-c,2112
82
- letta/llm_api/llm_client_base.py,sha256=ea4YyfZQqmkm6IcG7U3nu86VX820eXbX9gWuw5hDdzg,5766
81
+ letta/llm_api/llm_client.py,sha256=JpSZWLoJsHdjlfavyhNyNf_j7N5Ks2DktDuA2PyQO70,1827
82
+ letta/llm_api/llm_client_base.py,sha256=-RSVo4986iNLbOyUR3IKggKL2zWD4IBsr8ZbF8p28Ac,5935
83
83
  letta/llm_api/mistral.py,sha256=fHdfD9ug-rQIk2qn8tRKay1U6w9maF11ryhKi91FfXM,1593
84
84
  letta/llm_api/openai.py,sha256=qTTOyI6qQA-KmS1atmy2giSyT1XpjysqkQZbbUY7eKs,23425
85
- letta/llm_api/openai_client.py,sha256=sM7sgYpqmqZHqbD3q9mDeB9N9RPTlf87bYhzPWGQWJA,13111
85
+ letta/llm_api/openai_client.py,sha256=qm9-zgJIlUnP9vmdfFBR2BCOenzf2aYGEsBVIBzKgB8,13277
86
86
  letta/local_llm/README.md,sha256=hFJyw5B0TU2jrh9nb0zGZMgdH-Ei1dSRfhvPQG_NSoU,168
87
87
  letta/local_llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
88
88
  letta/local_llm/chat_completion_proxy.py,sha256=gc5gaKoHP8QaWRulDeEYPk7Onl8KdCBmpF2l9znXKeQ,13853
@@ -122,7 +122,7 @@ letta/local_llm/webui/legacy_settings.py,sha256=BLmd3TSx5StnY3ibjwaxYATPt_Lvq-o1
122
122
  letta/local_llm/webui/settings.py,sha256=gmLHfiOl1u4JmlAZU2d2O8YKF9lafdakyjwR_ftVPh8,552
123
123
  letta/log.py,sha256=FbFwU9KEX7k0FBYhPl7fJ6uQ3NO3-ZbsnM2OpcTFXjo,2217
124
124
  letta/main.py,sha256=_agyaYPJq70OL0goNwO34zENL2KupnTgqlg-HVcNaTY,15379
125
- letta/memory.py,sha256=NC6YDx9OY-bUS_6GTyzpcjeNhxX-ZqssImvIQmeWHMg,4111
125
+ letta/memory.py,sha256=E3Xa_hiqnuHmsq0XOGUqUoxQm_es7EWYCtbOFAS23h0,4182
126
126
  letta/openai_backcompat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
127
127
  letta/openai_backcompat/openai_object.py,sha256=GSzeCTwLpLD2fH4X8wVqzwdmoTjKK2I4PnriBY453lc,13505
128
128
  letta/orm/__all__.py,sha256=2gh2MZTkA3Hw67VWVKK3JIStJOqTeLdpCvYSVYNeEDA,692
@@ -167,11 +167,11 @@ letta/personas/examples/google_search_persona.txt,sha256=RyObU80MIk2oeJJDWOK1aX5
167
167
  letta/personas/examples/memgpt_doc.txt,sha256=_McafHuYkJYAnBFwvu_LVEaSEQGbs0flCgJIIJYlZgc,425
168
168
  letta/personas/examples/memgpt_starter.txt,sha256=x-fEozRrfUVlCJUEjkwHDCGeBb2z50d0jd6QF78SHKQ,160
169
169
  letta/personas/examples/o1_persona.txt,sha256=VKSDXuMaiOg-fnaiMFnEauYy85q88LJKW0y8N7V5j3g,339
170
- letta/personas/examples/offline_memory_persona.txt,sha256=u2ZK9X72hxA7BbKRzkailEVisFaICdHhLi6hBNS4kC0,178
171
170
  letta/personas/examples/sam.txt,sha256=V1-3-x9gud_opkeNL3XPXyCyJySCp4sYi-XTFD26gnc,1223
172
171
  letta/personas/examples/sam_pov.txt,sha256=NUZOfkz91aBwnv2M3iDsPZYf8MlaGF0zQB0nFOUC56k,1171
173
172
  letta/personas/examples/sam_simple_pov_gpt35.txt,sha256=vP6R5GxPeO0QuMartRs3DBfSs1LFWW8CHNqo7II0BuA,1053
174
173
  letta/personas/examples/sleeptime_doc_persona.txt,sha256=vVlo5bifdpIc2phV0vgdKCWeDIpun_5vQYLDEaurJQk,351
174
+ letta/personas/examples/sleeptime_memory_persona.txt,sha256=ueMQ7ki7IEs-YUvuOH_F0dQoHJChw1w09B9kMBIM4dU,294
175
175
  letta/personas/examples/sqldb/test.db,sha256=MU5Di7exdYdtQH62Q8dfkM6YpckkcwHDiO1fed98XBY,8192
176
176
  letta/prompts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
177
177
  letta/prompts/gpt_summarize.py,sha256=sOUKcVrTRbX00yLOZVVhwKgduRRVCY64l80ptOY4Ghg,1125
@@ -197,7 +197,7 @@ letta/schemas/agent.py,sha256=PJIQJW5fx4EGD_3Q3wbl4scoISSXqMVqr7Yvgvk-ZTE,17263
197
197
  letta/schemas/block.py,sha256=rMWflyj982qW86dQK-9saXBHKaLCu3aUG2gQTckG3Ik,4984
198
198
  letta/schemas/embedding_config.py,sha256=ufboqW9ctSBJdhwzJRbrGtTzOTwSKfT0LY0mowpr6fs,3398
199
199
  letta/schemas/embedding_config_overrides.py,sha256=lkTa4y-EQ2RnaEKtKDM0sEAk7EwNa67REw8DGNNtGQY,84
200
- letta/schemas/enums.py,sha256=7Z4Wotyndp_eghhIvSdjFA3nMp_Vh_pcK1A_MrkBFRA,1357
200
+ letta/schemas/enums.py,sha256=443ybuOZZL963Vt0fYhtJ6AWkIetlOKNUMG0Nz7l2Ss,1443
201
201
  letta/schemas/environment_variables.py,sha256=VRtzOjdeQdHcSHXisk7oJUQlheruxhSWNS0xqlfGzbs,2429
202
202
  letta/schemas/file.py,sha256=ChN2CWzLI2TT9WLItcfElEH0E8b7kzPylF2OQBr6Beg,1550
203
203
  letta/schemas/group.py,sha256=aEO0_59TEozgRMjVk7S2U4Eq4RnCr3QnbnHt-36mILM,4328
@@ -278,7 +278,7 @@ letta/server/rest_api/routers/v1/users.py,sha256=G5DBHSkPfBgVHN2Wkm-rVYiLQAudwQc
278
278
  letta/server/rest_api/routers/v1/voice.py,sha256=0lerWjrKLkt4gXLhZl1cIcgstOz9Q2HZwc67L58BCXE,2451
279
279
  letta/server/rest_api/static_files.py,sha256=NG8sN4Z5EJ8JVQdj19tkFa9iQ1kBPTab9f_CUxd_u4Q,3143
280
280
  letta/server/rest_api/utils.py,sha256=OKUWg7u4vmROVweqRrs83bQvS958bZAoR_bUFDwwqsc,14861
281
- letta/server/server.py,sha256=K7GZsDTjvd2v14B04uPCfnfti-yrLhuUkZMa-XR64ak,79959
281
+ letta/server/server.py,sha256=XcZ_vrQkG2CVr_mgCKVAV6EMVjuR4lQVtU3FTAUJIIc,79726
282
282
  letta/server/startup.sh,sha256=MRXh1RKbS5lyA7XAsk7O6Q4LEKOqnv5B-dwe0SnTHeQ,2514
283
283
  letta/server/static_files/assets/index-048c9598.js,sha256=mR16XppvselwKCcNgONs4L7kZEVa4OEERm4lNZYtLSk,146819
284
284
  letta/server/static_files/assets/index-0e31b727.css,sha256=SBbja96uiQVLDhDOroHgM6NSl7tS4lpJRCREgSS_hA8,7672
@@ -292,7 +292,7 @@ letta/server/ws_api/interface.py,sha256=TWl9vkcMCnLsUtgsuENZ-ku2oMDA-OUTzLh_yNRo
292
292
  letta/server/ws_api/protocol.py,sha256=5mDgpfNZn_kNwHnpt5Dsuw8gdNH298sgxTGed3etzYg,1836
293
293
  letta/server/ws_api/server.py,sha256=cBSzf-V4zT1bL_0i54OTI3cMXhTIIxqjSRF8pYjk7fg,5835
294
294
  letta/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
295
- letta/services/agent_manager.py,sha256=yjML99WV91bDmVae8LjV8ZafO2dO1P6MJfIODxvgs4I,71057
295
+ letta/services/agent_manager.py,sha256=I893THGSJrwQt-NynuY2rUJxTOGVCetIlXdkEZALc7w,71123
296
296
  letta/services/block_manager.py,sha256=rphbpGBIEDFvCJ5GJt6A1OfbURGFQZ3WardljELQyAc,15225
297
297
  letta/services/group_manager.py,sha256=z1woWRRnjkWrGG_auSicXr2bJaJ653JV6PYl2N_AUfw,12224
298
298
  letta/services/helpers/agent_manager_helper.py,sha256=57ARg5TcmE_JdrWmhz5uaNHAt1NGlJ3wQH1tP2XOiAs,17825
@@ -327,8 +327,8 @@ letta/streaming_utils.py,sha256=jLqFTVhUL76FeOuYk8TaRQHmPTf3HSRc2EoJwxJNK6U,1194
327
327
  letta/system.py,sha256=dnOrS2FlRMwijQnOvfrky0Lg8wEw-FUq2zzfAJOUSKA,8477
328
328
  letta/tracing.py,sha256=RstWXpfWVF77nmb_ISORVWd9IQw2Ky3de40k_S70yKI,8258
329
329
  letta/utils.py,sha256=IZFvtj9WYcrxUbkoUUYGDxMYQYdn5SgfqsvnARGsAzc,32245
330
- letta_nightly-0.7.2.dev20250423222439.dist-info/LICENSE,sha256=mExtuZ_GYJgDEI38GWdiEYZizZS4KkVt2SF1g_GPNhI,10759
331
- letta_nightly-0.7.2.dev20250423222439.dist-info/METADATA,sha256=kByy0bUZbRDntWr776qN-8dzCs-8jvFLNKzd_yxKGaU,22282
332
- letta_nightly-0.7.2.dev20250423222439.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
333
- letta_nightly-0.7.2.dev20250423222439.dist-info/entry_points.txt,sha256=2zdiyGNEZGV5oYBuS-y2nAAgjDgcC9yM_mHJBFSRt5U,40
334
- letta_nightly-0.7.2.dev20250423222439.dist-info/RECORD,,
330
+ letta_nightly-0.7.3.dev20250424054013.dist-info/LICENSE,sha256=mExtuZ_GYJgDEI38GWdiEYZizZS4KkVt2SF1g_GPNhI,10759
331
+ letta_nightly-0.7.3.dev20250424054013.dist-info/METADATA,sha256=5LOq2K7liO_JkxDVOlEhu9MiKdT-qMyWdbZC5zQn5UE,22282
332
+ letta_nightly-0.7.3.dev20250424054013.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
333
+ letta_nightly-0.7.3.dev20250424054013.dist-info/entry_points.txt,sha256=2zdiyGNEZGV5oYBuS-y2nAAgjDgcC9yM_mHJBFSRt5U,40
334
+ letta_nightly-0.7.3.dev20250424054013.dist-info/RECORD,,
@@ -1,4 +0,0 @@
1
- I am an expert memory agent that can do the following:
2
- - Consolidate memories into more concise blocks
3
- - Identify patterns in user behavior
4
- - Make inferences based on the memory