letta-nightly 0.6.6.dev20241221104005__py3-none-any.whl → 0.6.6.dev20241223104053__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 CHANGED
@@ -237,8 +237,8 @@ class Agent(BaseAgent):
237
237
  )
238
238
  function_response, updated_agent_state = sandbox_run_result.func_return, sandbox_run_result.agent_state
239
239
  assert orig_memory_str == self.agent_state.memory.compile(), "Memory should not be modified in a sandbox tool"
240
-
241
- self.update_memory_if_change(updated_agent_state.memory)
240
+ if updated_agent_state is not None:
241
+ self.update_memory_if_change(updated_agent_state.memory)
242
242
  except Exception as e:
243
243
  # Need to catch error here, or else trunction wont happen
244
244
  # TODO: modify to function execution error
@@ -251,7 +251,7 @@ class Agent(BaseAgent):
251
251
  def _get_ai_reply(
252
252
  self,
253
253
  message_sequence: List[Message],
254
- function_call: str = "auto",
254
+ function_call: Optional[str] = None,
255
255
  first_message: bool = False,
256
256
  stream: bool = False, # TODO move to config?
257
257
  empty_response_retry_limit: int = 3,
@@ -282,7 +282,6 @@ class Agent(BaseAgent):
282
282
  # Force a tool call if exactly one tool is specified
283
283
  elif step_count is not None and step_count > 0 and len(allowed_tool_names) == 1:
284
284
  force_tool_call = allowed_tool_names[0]
285
-
286
285
  for attempt in range(1, empty_response_retry_limit + 1):
287
286
  try:
288
287
  response = create(
@@ -314,7 +313,7 @@ class Agent(BaseAgent):
314
313
  except ValueError as ve:
315
314
  if attempt >= empty_response_retry_limit:
316
315
  warnings.warn(f"Retry limit reached. Final error: {ve}")
317
- break
316
+ raise Exception(f"Retries exhausted and no valid response received. Final error: {ve}")
318
317
  else:
319
318
  delay = min(backoff_factor * (2 ** (attempt - 1)), max_delay)
320
319
  warnings.warn(f"Attempt {attempt} failed: {ve}. Retrying in {delay} seconds...")
@@ -1043,6 +1042,7 @@ class Agent(BaseAgent):
1043
1042
  num_archival_memory=agent_manager_passage_size,
1044
1043
  num_recall_memory=message_manager_size,
1045
1044
  num_tokens_external_memory_summary=num_tokens_external_memory_summary,
1045
+ external_memory_summary=external_memory_summary,
1046
1046
  # top-level information
1047
1047
  context_window_size_max=self.agent_state.llm_config.context_window,
1048
1048
  context_window_size_current=num_tokens_used_total,
letta/llm_api/helpers.py CHANGED
@@ -250,6 +250,8 @@ def unpack_all_inner_thoughts_from_kwargs(
250
250
 
251
251
  def unpack_inner_thoughts_from_kwargs(choice: Choice, inner_thoughts_key: str) -> Choice:
252
252
  message = choice.message
253
+ rewritten_choice = choice # inner thoughts unpacked out of the function
254
+
253
255
  if message.role == "assistant" and message.tool_calls and len(message.tool_calls) >= 1:
254
256
  if len(message.tool_calls) > 1:
255
257
  warnings.warn(f"Unpacking inner thoughts from more than one tool call ({len(message.tool_calls)}) is not supported")
@@ -271,14 +273,18 @@ def unpack_inner_thoughts_from_kwargs(choice: Choice, inner_thoughts_key: str) -
271
273
  warnings.warn(f"Overwriting existing inner monologue ({new_choice.message.content}) with kwarg ({inner_thoughts})")
272
274
  new_choice.message.content = inner_thoughts
273
275
 
274
- return new_choice
276
+ # update the choice object
277
+ rewritten_choice = new_choice
275
278
  else:
276
279
  warnings.warn(f"Did not find inner thoughts in tool call: {str(tool_call)}")
277
- return choice
278
280
 
279
281
  except json.JSONDecodeError as e:
280
282
  warnings.warn(f"Failed to strip inner thoughts from kwargs: {e}")
281
283
  raise e
284
+ else:
285
+ warnings.warn(f"Did not find tool call in message: {str(message)}")
286
+
287
+ return rewritten_choice
282
288
 
283
289
 
284
290
  def is_context_overflow_error(exception: Union[requests.exceptions.RequestException, Exception]) -> bool:
@@ -110,7 +110,7 @@ def create(
110
110
  user_id: Optional[str] = None, # option UUID to associate request with
111
111
  functions: Optional[list] = None,
112
112
  functions_python: Optional[dict] = None,
113
- function_call: str = "auto",
113
+ function_call: Optional[str] = None, # see: https://platform.openai.com/docs/api-reference/chat/create#chat-create-tool_choice
114
114
  # hint
115
115
  first_message: bool = False,
116
116
  force_tool_call: Optional[str] = None, # Force a specific tool to be called
@@ -148,10 +148,19 @@ def create(
148
148
 
149
149
  # openai
150
150
  if llm_config.model_endpoint_type == "openai":
151
+
151
152
  if model_settings.openai_api_key is None and llm_config.model_endpoint == "https://api.openai.com/v1":
152
153
  # only is a problem if we are *not* using an openai proxy
153
154
  raise LettaConfigurationError(message="OpenAI key is missing from letta config file", missing_fields=["openai_api_key"])
154
155
 
156
+ if function_call is None and functions is not None and len(functions) > 0:
157
+ # force function calling for reliability, see https://platform.openai.com/docs/api-reference/chat/create#chat-create-tool_choice
158
+ # TODO(matt) move into LLMConfig
159
+ if llm_config.model_endpoint == "https://inference.memgpt.ai":
160
+ function_call = "auto" # TODO change to "required" once proxy supports it
161
+ else:
162
+ function_call = "required"
163
+
155
164
  data = build_openai_chat_completions_request(llm_config, messages, user_id, functions, function_call, use_tool_naming, max_tokens)
156
165
  if stream: # Client requested token streaming
157
166
  data.stream = True
@@ -255,12 +264,7 @@ def create(
255
264
 
256
265
  tool_call = None
257
266
  if force_tool_call is not None:
258
- tool_call = {
259
- "type": "function",
260
- "function": {
261
- "name": force_tool_call
262
- }
263
- }
267
+ tool_call = {"type": "function", "function": {"name": force_tool_call}}
264
268
  assert functions is not None
265
269
 
266
270
  return anthropic_chat_completions_request(
@@ -47,7 +47,7 @@ class LettaResponse(BaseModel):
47
47
  return f'<div class="content"><span class="function-name">{html.escape(msg.function_call.name)}</span>({args})</div>'
48
48
  elif msg.message_type == "tool_call_message":
49
49
  args = format_json(msg.tool_call.arguments)
50
- return f'<div class="content"><span class="function-name">{html.escape(msg.function_call.name)}</span>({args})</div>'
50
+ return f'<div class="content"><span class="function-name">{html.escape(msg.tool_call.name)}</span>({args})</div>'
51
51
  elif msg.message_type == "function_return":
52
52
  return_value = format_json(msg.function_return)
53
53
  # return f'<div class="status-line">Status: {html.escape(msg.status)}</div><div class="content">{return_value}</div>'
letta/schemas/memory.py CHANGED
@@ -30,6 +30,9 @@ class ContextWindowOverview(BaseModel):
30
30
  num_tokens_external_memory_summary: int = Field(
31
31
  ..., description="The number of tokens in the external memory summary (archival + recall metadata)."
32
32
  )
33
+ external_memory_summary: str = Field(
34
+ ..., description="The metadata summary of the external memory sources (archival + recall metadata)."
35
+ )
33
36
 
34
37
  # context window breakdown (in tokens)
35
38
  # this should all add up to context_window_size_current
@@ -1,8 +1,10 @@
1
1
  from typing import List, Optional
2
2
 
3
+ from composio.client import ComposioClientError, HTTPError, NoItemsFound
3
4
  from composio.client.collections import ActionModel, AppModel
4
5
  from composio.client.enums.base import EnumStringNotFound
5
- from composio.exceptions import ComposioSDKError
6
+ from composio.exceptions import ApiKeyNotProvidedError, ComposioSDKError
7
+ from composio.tools.base.abs import InvalidClassDefinition
6
8
  from fastapi import APIRouter, Body, Depends, Header, HTTPException
7
9
 
8
10
  from letta.errors import LettaToolCreateError
@@ -239,21 +241,66 @@ def add_composio_tool(
239
241
  try:
240
242
  tool_create = ToolCreate.from_composio(action_name=composio_action_name, api_key=composio_api_key)
241
243
  return server.tool_manager.create_or_update_tool(pydantic_tool=Tool(**tool_create.model_dump()), actor=actor)
242
- except EnumStringNotFound:
244
+ except EnumStringNotFound as e:
243
245
  raise HTTPException(
244
246
  status_code=400, # Bad Request
245
247
  detail={
246
248
  "code": "EnumStringNotFound",
247
- "message": f"Cannot find composio action with name `{composio_action_name}`.",
249
+ "message": str(e),
248
250
  "composio_action_name": composio_action_name,
249
251
  },
250
252
  )
251
- except ComposioSDKError:
253
+ except HTTPError as e:
254
+ raise HTTPException(
255
+ status_code=400, # Bad Request
256
+ detail={
257
+ "code": "HTTPError",
258
+ "message": str(e),
259
+ "composio_action_name": composio_action_name,
260
+ },
261
+ )
262
+ except NoItemsFound as e:
263
+ raise HTTPException(
264
+ status_code=400, # Bad Request
265
+ detail={
266
+ "code": "NoItemsFound",
267
+ "message": str(e),
268
+ "composio_action_name": composio_action_name,
269
+ },
270
+ )
271
+ except ComposioClientError as e:
272
+ raise HTTPException(
273
+ status_code=400, # Bad Request
274
+ detail={
275
+ "code": "ComposioClientError",
276
+ "message": str(e),
277
+ "composio_action_name": composio_action_name,
278
+ },
279
+ )
280
+ except ApiKeyNotProvidedError as e:
281
+ raise HTTPException(
282
+ status_code=400, # Bad Request
283
+ detail={
284
+ "code": "ApiKeyNotProvidedError",
285
+ "message": str(e),
286
+ "composio_action_name": composio_action_name,
287
+ },
288
+ )
289
+ except InvalidClassDefinition as e:
290
+ raise HTTPException(
291
+ status_code=400, # Bad Request
292
+ detail={
293
+ "code": "InvalidClassDefinition",
294
+ "message": str(e),
295
+ "composio_action_name": composio_action_name,
296
+ },
297
+ )
298
+ except ComposioSDKError as e:
252
299
  raise HTTPException(
253
300
  status_code=400, # Bad Request
254
301
  detail={
255
302
  "code": "ComposioSDKError",
256
- "message": f"No connected account found for tool `{composio_action_name}`. You need to connect the relevant app in Composio order to use the tool.",
303
+ "message": str(e),
257
304
  "composio_action_name": composio_action_name,
258
305
  },
259
306
  )
@@ -336,7 +336,7 @@ class AgentManager:
336
336
  curr_memory_str = agent_state.memory.compile()
337
337
  if curr_memory_str in curr_system_message_openai["content"] and not force:
338
338
  # NOTE: could this cause issues if a block is removed? (substring match would still work)
339
- logger.info(
339
+ logger.debug(
340
340
  f"Memory hasn't changed for agent id={agent_id} and actor=({actor.id}, {actor.name}), skipping system prompt rebuild"
341
341
  )
342
342
  return agent_state
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: letta-nightly
3
- Version: 0.6.6.dev20241221104005
3
+ Version: 0.6.6.dev20241223104053
4
4
  Summary: Create LLM agents with long-term memory and custom tools
5
5
  License: Apache License
6
6
  Author: Letta Team
@@ -1,6 +1,6 @@
1
1
  letta/__init__.py,sha256=kBJPc_H6xrNs2Y1U-Otm4HteKlgr6AfbLp8nRxMwfiQ,1014
2
2
  letta/__main__.py,sha256=6Hs2PV7EYc5Tid4g4OtcLXhqVHiNYTGzSBdoOnW2HXA,29
3
- letta/agent.py,sha256=4mkn4YzXv4e3DbQOOXcrBGTPDBhM9OlpRLVs_kY768s,54619
3
+ letta/agent.py,sha256=RBP9GB2ANk6VTZaTQ7zhwSb84zQ0cAK63745JcncpiA,54824
4
4
  letta/benchmark/benchmark.py,sha256=ebvnwfp3yezaXOQyGXkYCDYpsmre-b9hvNtnyx4xkG0,3701
5
5
  letta/benchmark/constants.py,sha256=aXc5gdpMGJT327VuxsT5FngbCK2J41PQYeICBO7g_RE,536
6
6
  letta/chat_only_agent.py,sha256=ECqJS7KzXOsNkJc9mv7reKbcxBI_PKP_PQyk95tsT1Y,4761
@@ -36,8 +36,8 @@ letta/llm_api/azure_openai.py,sha256=Y1HKPog1XzM_f7ujUK_Gv2zQkoy5pU-1bKiUnvSxSrs
36
36
  letta/llm_api/azure_openai_constants.py,sha256=oXtKrgBFHf744gyt5l1thILXgyi8NDNUrKEa2GGGpjw,278
37
37
  letta/llm_api/cohere.py,sha256=vDRd-SUGp1t_JUIdwC3RkIhwMl0OY7n-tAU9uPORYkY,14826
38
38
  letta/llm_api/google_ai.py,sha256=xKz9JDZs3m6yzSfcgCAAUD_rjI20BBIINoiSvlcnOw0,17621
39
- letta/llm_api/helpers.py,sha256=F8xZDZgDojWX5v-0vakyeUQyCyBr1HmzmsITRdOsmVg,13457
40
- letta/llm_api/llm_api_tools.py,sha256=Qb1NsOOLmgMzMZ_A1J0v2EoQPm444Z2kZ9d-5j-FL6c,17731
39
+ letta/llm_api/helpers.py,sha256=iP9EswPflaRzsmLqQuMGt1OCUQgPrPq1xTjrqmMKPiA,13675
40
+ letta/llm_api/llm_api_tools.py,sha256=ID3tTWyoNqq6yk7ezHWgUuWbF9QG-sQ73i4TZ1IgoxE,18244
41
41
  letta/llm_api/mistral.py,sha256=fHdfD9ug-rQIk2qn8tRKay1U6w9maF11ryhKi91FfXM,1593
42
42
  letta/llm_api/openai.py,sha256=4GEGROTv4vLawSgODnAHCI-DeIWDqrhuxtKrqYzHvso,24160
43
43
  letta/local_llm/README.md,sha256=hFJyw5B0TU2jrh9nb0zGZMgdH-Ei1dSRfhvPQG_NSoU,168
@@ -146,9 +146,9 @@ letta/schemas/job.py,sha256=vRVVpMCHTxot9uaalLS8RARnqzJWvcLB1XP5XRBioPc,1398
146
146
  letta/schemas/letta_base.py,sha256=v3OvpVFVUfcuK1lIyTjM0x4fmWeWQw1DdlhKXHBUCz8,3608
147
147
  letta/schemas/letta_message.py,sha256=SpAxAEFQa-JMzxIQ5cqz0TENB5S9WsdrTAHGUJBLCQQ,8040
148
148
  letta/schemas/letta_request.py,sha256=Hfb66FB1tXmrpEX4_yLQVfTrTSMbPYeEvZY-vqW9Tj8,981
149
- letta/schemas/letta_response.py,sha256=PSHnIzGAz1MP1ACA_f7zyt4zXDnYJhNfcDRbV1HJpo4,6940
149
+ letta/schemas/letta_response.py,sha256=Qx_OH8CttLeIT-BeiWE5huzxgLb6P6eNWadIiEZ2aQ0,6936
150
150
  letta/schemas/llm_config.py,sha256=zxygt_4imoEAgxMLO1nxNVAL-2ePGsOKEt-vQJOc0ow,4585
151
- letta/schemas/memory.py,sha256=iWEm15qMa4pWQQUMIt6mnlrBQvACII0MpfNX8QujGE8,10072
151
+ letta/schemas/memory.py,sha256=dWF1AWhQKEp1MJ6yz8wVYrWNsmA2ADREAz2lS3d8I6c,10229
152
152
  letta/schemas/message.py,sha256=Z_k8YpURh0Dbx4BaFbo6Z7YP9JIkItL1UKtDnmZfVHE,34149
153
153
  letta/schemas/openai/chat_completion_request.py,sha256=AOIwgbN3CZKVqkuXeMHeSa53u4h0wVq69t3T_LJ0vIE,3389
154
154
  letta/schemas/openai/chat_completion_response.py,sha256=ub-oVSyLpuJd-5_yzCSIRR8tD3GM83IeDO1c1uAATa4,3970
@@ -188,7 +188,7 @@ letta/server/rest_api/routers/v1/llms.py,sha256=TcyvSx6MEM3je5F4DysL7ligmssL_pFl
188
188
  letta/server/rest_api/routers/v1/organizations.py,sha256=tyqVzXTpMtk3sKxI3Iz4aS6RhbGEbXDzFBB_CpW18v4,2080
189
189
  letta/server/rest_api/routers/v1/sandbox_configs.py,sha256=pG3X3bYbmsq90kRc-06qfnM6yalvYEpVVEQnTuZVm0o,5134
190
190
  letta/server/rest_api/routers/v1/sources.py,sha256=shjy4gbKulKfbK94GF52EW4ZbiDatcNgnyBysONCBCA,9946
191
- letta/server/rest_api/routers/v1/tools.py,sha256=bWgI5SExyfwqPASLf8o9reFWInSuMYyyJRV1DTTATps,11266
191
+ letta/server/rest_api/routers/v1/tools.py,sha256=WpkM1UotqWyr61zBpEU3tAaoUfXIDMxJbjfPqpg1jpI,12720
192
192
  letta/server/rest_api/routers/v1/users.py,sha256=EBQe9IfCG3kzHpKmotz4yVGZioXz3SCSRy5yEhJK8hU,2293
193
193
  letta/server/rest_api/static_files.py,sha256=NG8sN4Z5EJ8JVQdj19tkFa9iQ1kBPTab9f_CUxd_u4Q,3143
194
194
  letta/server/rest_api/utils.py,sha256=78n6FMnCS7O3T_z1OXKmL8wKQVTnGnQ1LDlLTI-T5Kc,3952
@@ -206,7 +206,7 @@ letta/server/ws_api/interface.py,sha256=TWl9vkcMCnLsUtgsuENZ-ku2oMDA-OUTzLh_yNRo
206
206
  letta/server/ws_api/protocol.py,sha256=M_-gM5iuDBwa1cuN2IGNCG5GxMJwU2d3XW93XALv9s8,1821
207
207
  letta/server/ws_api/server.py,sha256=cBSzf-V4zT1bL_0i54OTI3cMXhTIIxqjSRF8pYjk7fg,5835
208
208
  letta/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
209
- letta/services/agent_manager.py,sha256=y8020VlCWvTtDmKfhaBxJ4XOi-9zwEXyh9q2oK6Tpwg,38935
209
+ letta/services/agent_manager.py,sha256=_-AzsHSClatNXk_cWlzdlaGvWsoBpIJOKaZGBVH3Ugc,38936
210
210
  letta/services/block_manager.py,sha256=HUj9HKW2LvAsENEsgCO3Pf3orvSy6XOimev38VKmRZ8,4929
211
211
  letta/services/helpers/agent_manager_helper.py,sha256=Q_nRk-eovoYTzLxOYvUbnsQVLWdRvFvjk8OcLUfjkJU,10568
212
212
  letta/services/job_manager.py,sha256=FrkSXloke48CZKuzlYdysxM5gKWoTu7FRigPrs_YW4A,3645
@@ -225,8 +225,8 @@ letta/streaming_interface.py,sha256=_FPUWy58j50evHcpXyd7zB1wWqeCc71NCFeWh_TBvnw,
225
225
  letta/streaming_utils.py,sha256=329fsvj1ZN0r0LpQtmMPZ2vSxkDBIUUwvGHZFkjm2I8,11745
226
226
  letta/system.py,sha256=buKYPqG5n2x41hVmWpu6JUpyd7vTWED9Km2_M7dLrvk,6960
227
227
  letta/utils.py,sha256=JZbKq-3KhbmilATo-SbY0OgOnwN-zkE40UD7dfAZMWI,33381
228
- letta_nightly-0.6.6.dev20241221104005.dist-info/LICENSE,sha256=mExtuZ_GYJgDEI38GWdiEYZizZS4KkVt2SF1g_GPNhI,10759
229
- letta_nightly-0.6.6.dev20241221104005.dist-info/METADATA,sha256=NjjF2UtUvzhYQzthHiAMd13gE9iWpiN76ruPjoOlDMk,21693
230
- letta_nightly-0.6.6.dev20241221104005.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
231
- letta_nightly-0.6.6.dev20241221104005.dist-info/entry_points.txt,sha256=2zdiyGNEZGV5oYBuS-y2nAAgjDgcC9yM_mHJBFSRt5U,40
232
- letta_nightly-0.6.6.dev20241221104005.dist-info/RECORD,,
228
+ letta_nightly-0.6.6.dev20241223104053.dist-info/LICENSE,sha256=mExtuZ_GYJgDEI38GWdiEYZizZS4KkVt2SF1g_GPNhI,10759
229
+ letta_nightly-0.6.6.dev20241223104053.dist-info/METADATA,sha256=N92E24my1TvWWRil2fDYjBNATWqRKLRMyHcuBZ_zbX4,21693
230
+ letta_nightly-0.6.6.dev20241223104053.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
231
+ letta_nightly-0.6.6.dev20241223104053.dist-info/entry_points.txt,sha256=2zdiyGNEZGV5oYBuS-y2nAAgjDgcC9yM_mHJBFSRt5U,40
232
+ letta_nightly-0.6.6.dev20241223104053.dist-info/RECORD,,