letta-nightly 0.6.5.dev20241218213641__tar.gz → 0.6.5.dev20241220104040__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of letta-nightly might be problematic. Click here for more details.

Files changed (232) hide show
  1. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/PKG-INFO +1 -1
  2. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/agent.py +37 -6
  3. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/client/client.py +2 -2
  4. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/client/streaming.py +9 -9
  5. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/errors.py +60 -25
  6. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/functions/function_sets/base.py +0 -54
  7. letta_nightly-0.6.5.dev20241220104040/letta/helpers/tool_rule_solver.py +146 -0
  8. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/llm_api/llm_api_tools.py +2 -2
  9. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/custom_columns.py +5 -2
  10. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/message.py +2 -1
  11. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/passage.py +14 -15
  12. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/providers.py +2 -1
  13. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/enums.py +1 -0
  14. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/letta_message.py +76 -40
  15. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/letta_response.py +9 -1
  16. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/message.py +13 -13
  17. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/tool_rule.py +12 -2
  18. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/interface.py +48 -48
  19. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/openai/chat_completions/chat_completions.py +2 -2
  20. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/v1/agents.py +3 -0
  21. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/v1/tools.py +5 -20
  22. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/utils.py +23 -22
  23. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/server.py +12 -18
  24. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/services/agent_manager.py +32 -46
  25. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/services/message_manager.py +1 -0
  26. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/services/tool_manager.py +3 -3
  27. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/pyproject.toml +1 -1
  28. letta_nightly-0.6.5.dev20241218213641/letta/helpers/tool_rule_solver.py +0 -115
  29. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/LICENSE +0 -0
  30. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/README.md +0 -0
  31. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/__init__.py +0 -0
  32. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/__main__.py +0 -0
  33. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/benchmark/benchmark.py +0 -0
  34. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/benchmark/constants.py +0 -0
  35. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/chat_only_agent.py +0 -0
  36. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/cli/cli.py +0 -0
  37. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/cli/cli_config.py +0 -0
  38. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/cli/cli_load.py +0 -0
  39. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/client/__init__.py +0 -0
  40. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/client/utils.py +0 -0
  41. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/config.py +0 -0
  42. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/constants.py +0 -0
  43. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/credentials.py +0 -0
  44. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/data_sources/connectors.py +0 -0
  45. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/data_sources/connectors_helper.py +0 -0
  46. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/embeddings.py +0 -0
  47. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/functions/__init__.py +0 -0
  48. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/functions/function_sets/extras.py +0 -0
  49. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/functions/functions.py +0 -0
  50. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/functions/helpers.py +0 -0
  51. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/functions/schema_generator.py +0 -0
  52. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/helpers/__init__.py +0 -0
  53. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/humans/__init__.py +0 -0
  54. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/humans/examples/basic.txt +0 -0
  55. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/humans/examples/cs_phd.txt +0 -0
  56. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/interface.py +0 -0
  57. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/llm_api/__init__.py +0 -0
  58. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/llm_api/anthropic.py +0 -0
  59. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/llm_api/azure_openai.py +0 -0
  60. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/llm_api/azure_openai_constants.py +0 -0
  61. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/llm_api/cohere.py +0 -0
  62. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/llm_api/google_ai.py +0 -0
  63. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/llm_api/helpers.py +0 -0
  64. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/llm_api/mistral.py +0 -0
  65. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/llm_api/openai.py +0 -0
  66. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/README.md +0 -0
  67. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/__init__.py +0 -0
  68. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/chat_completion_proxy.py +0 -0
  69. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/constants.py +0 -0
  70. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/function_parser.py +0 -0
  71. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/grammars/__init__.py +0 -0
  72. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/grammars/gbnf_grammar_generator.py +0 -0
  73. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/grammars/json.gbnf +0 -0
  74. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/grammars/json_func_calls_with_inner_thoughts.gbnf +0 -0
  75. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/json_parser.py +0 -0
  76. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/koboldcpp/api.py +0 -0
  77. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/koboldcpp/settings.py +0 -0
  78. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/llamacpp/api.py +0 -0
  79. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/llamacpp/settings.py +0 -0
  80. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/llm_chat_completion_wrappers/__init__.py +0 -0
  81. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/llm_chat_completion_wrappers/airoboros.py +0 -0
  82. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/llm_chat_completion_wrappers/chatml.py +0 -0
  83. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/llm_chat_completion_wrappers/configurable_wrapper.py +0 -0
  84. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/llm_chat_completion_wrappers/dolphin.py +0 -0
  85. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/llm_chat_completion_wrappers/llama3.py +0 -0
  86. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/llm_chat_completion_wrappers/simple_summary_wrapper.py +0 -0
  87. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/llm_chat_completion_wrappers/wrapper_base.py +0 -0
  88. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/llm_chat_completion_wrappers/zephyr.py +0 -0
  89. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/lmstudio/api.py +0 -0
  90. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/lmstudio/settings.py +0 -0
  91. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/ollama/api.py +0 -0
  92. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/ollama/settings.py +0 -0
  93. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/settings/__init__.py +0 -0
  94. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/settings/deterministic_mirostat.py +0 -0
  95. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/settings/settings.py +0 -0
  96. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/settings/simple.py +0 -0
  97. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/utils.py +0 -0
  98. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/vllm/api.py +0 -0
  99. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/webui/api.py +0 -0
  100. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/webui/legacy_api.py +0 -0
  101. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/webui/legacy_settings.py +0 -0
  102. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/webui/settings.py +0 -0
  103. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/log.py +0 -0
  104. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/main.py +0 -0
  105. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/memory.py +0 -0
  106. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/o1_agent.py +0 -0
  107. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/offline_memory_agent.py +0 -0
  108. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/openai_backcompat/__init__.py +0 -0
  109. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/openai_backcompat/openai_object.py +0 -0
  110. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/__all__.py +0 -0
  111. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/__init__.py +0 -0
  112. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/agent.py +0 -0
  113. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/agents_tags.py +0 -0
  114. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/base.py +0 -0
  115. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/block.py +0 -0
  116. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/blocks_agents.py +0 -0
  117. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/enums.py +0 -0
  118. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/errors.py +0 -0
  119. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/file.py +0 -0
  120. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/job.py +0 -0
  121. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/mixins.py +0 -0
  122. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/organization.py +0 -0
  123. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/sandbox_config.py +0 -0
  124. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/source.py +0 -0
  125. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/sources_agents.py +0 -0
  126. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/sqlalchemy_base.py +0 -0
  127. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/sqlite_functions.py +0 -0
  128. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/tool.py +0 -0
  129. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/tools_agents.py +0 -0
  130. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/user.py +0 -0
  131. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/personas/__init__.py +0 -0
  132. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/personas/examples/anna_pa.txt +0 -0
  133. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/personas/examples/google_search_persona.txt +0 -0
  134. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/personas/examples/memgpt_doc.txt +0 -0
  135. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/personas/examples/memgpt_starter.txt +0 -0
  136. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/personas/examples/o1_persona.txt +0 -0
  137. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/personas/examples/offline_memory_persona.txt +0 -0
  138. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/personas/examples/sam.txt +0 -0
  139. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/personas/examples/sam_pov.txt +0 -0
  140. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/personas/examples/sam_simple_pov_gpt35.txt +0 -0
  141. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/personas/examples/sqldb/test.db +0 -0
  142. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/__init__.py +0 -0
  143. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/gpt_summarize.py +0 -0
  144. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/gpt_system.py +0 -0
  145. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/system/memgpt_base.txt +0 -0
  146. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/system/memgpt_chat.txt +0 -0
  147. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/system/memgpt_chat_compressed.txt +0 -0
  148. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/system/memgpt_chat_fstring.txt +0 -0
  149. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/system/memgpt_convo_only.txt +0 -0
  150. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/system/memgpt_doc.txt +0 -0
  151. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/system/memgpt_gpt35_extralong.txt +0 -0
  152. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/system/memgpt_intuitive_knowledge.txt +0 -0
  153. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/system/memgpt_modified_chat.txt +0 -0
  154. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/system/memgpt_modified_o1.txt +0 -0
  155. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/system/memgpt_offline_memory.txt +0 -0
  156. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/system/memgpt_offline_memory_chat.txt +0 -0
  157. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/pytest.ini +0 -0
  158. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/agent.py +0 -0
  159. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/block.py +0 -0
  160. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/embedding_config.py +0 -0
  161. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/file.py +0 -0
  162. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/health.py +0 -0
  163. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/job.py +0 -0
  164. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/letta_base.py +0 -0
  165. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/letta_request.py +0 -0
  166. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/llm_config.py +0 -0
  167. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/memory.py +0 -0
  168. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/openai/chat_completion_request.py +0 -0
  169. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/openai/chat_completion_response.py +0 -0
  170. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/openai/chat_completions.py +0 -0
  171. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/openai/embedding_response.py +0 -0
  172. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/openai/openai.py +0 -0
  173. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/organization.py +0 -0
  174. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/passage.py +0 -0
  175. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/sandbox_config.py +0 -0
  176. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/source.py +0 -0
  177. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/tool.py +0 -0
  178. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/usage.py +0 -0
  179. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/user.py +0 -0
  180. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/__init__.py +0 -0
  181. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/constants.py +0 -0
  182. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/generate_openapi_schema.sh +0 -0
  183. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/__init__.py +0 -0
  184. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/app.py +0 -0
  185. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/auth/__init__.py +0 -0
  186. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/auth/index.py +0 -0
  187. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/auth_token.py +0 -0
  188. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/__init__.py +0 -0
  189. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/openai/__init__.py +0 -0
  190. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/openai/assistants/__init__.py +0 -0
  191. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/openai/assistants/assistants.py +0 -0
  192. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/openai/assistants/schemas.py +0 -0
  193. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/openai/chat_completions/__init__.py +0 -0
  194. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/v1/__init__.py +0 -0
  195. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/v1/blocks.py +0 -0
  196. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/v1/health.py +0 -0
  197. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/v1/jobs.py +0 -0
  198. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/v1/llms.py +0 -0
  199. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/v1/organizations.py +0 -0
  200. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/v1/sandbox_configs.py +0 -0
  201. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/v1/sources.py +0 -0
  202. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/v1/users.py +0 -0
  203. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/static_files.py +0 -0
  204. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/startup.sh +0 -0
  205. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/static_files/assets/index-048c9598.js +0 -0
  206. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/static_files/assets/index-0e31b727.css +0 -0
  207. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/static_files/favicon.ico +0 -0
  208. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/static_files/index.html +0 -0
  209. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/static_files/memgpt_logo_transparent.png +0 -0
  210. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/utils.py +0 -0
  211. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/ws_api/__init__.py +0 -0
  212. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/ws_api/example_client.py +0 -0
  213. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/ws_api/interface.py +0 -0
  214. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/ws_api/protocol.py +0 -0
  215. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/server/ws_api/server.py +0 -0
  216. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/services/__init__.py +0 -0
  217. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/services/block_manager.py +0 -0
  218. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/services/helpers/agent_manager_helper.py +0 -0
  219. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/services/job_manager.py +0 -0
  220. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/services/organization_manager.py +0 -0
  221. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/services/passage_manager.py +0 -0
  222. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/services/per_agent_lock_manager.py +0 -0
  223. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/services/sandbox_config_manager.py +0 -0
  224. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/services/source_manager.py +0 -0
  225. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/services/tool_execution_sandbox.py +0 -0
  226. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/services/tool_sandbox_env/.gitkeep +0 -0
  227. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/services/user_manager.py +0 -0
  228. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/settings.py +0 -0
  229. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/streaming_interface.py +0 -0
  230. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/streaming_utils.py +0 -0
  231. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/system.py +0 -0
  232. {letta_nightly-0.6.5.dev20241218213641 → letta_nightly-0.6.5.dev20241220104040}/letta/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: letta-nightly
3
- Version: 0.6.5.dev20241218213641
3
+ Version: 0.6.5.dev20241220104040
4
4
  Summary: Create LLM agents with long-term memory and custom tools
5
5
  License: Apache License
6
6
  Author: Letta Team
@@ -1,5 +1,6 @@
1
1
  import datetime
2
2
  import inspect
3
+ import json
3
4
  import time
4
5
  import traceback
5
6
  import warnings
@@ -20,7 +21,7 @@ from letta.constants import (
20
21
  REQ_HEARTBEAT_MESSAGE,
21
22
  STRUCTURED_OUTPUT_MODELS,
22
23
  )
23
- from letta.errors import LLMError
24
+ from letta.errors import ContextWindowExceededError
24
25
  from letta.helpers import ToolRulesSolver
25
26
  from letta.interface import AgentInterface
26
27
  from letta.llm_api.helpers import is_context_overflow_error
@@ -371,6 +372,9 @@ class Agent(BaseAgent):
371
372
  self._append_to_messages(added_messages=init_messages_objs)
372
373
  self._validate_message_buffer_is_utc()
373
374
 
375
+ # Load last function response from message history
376
+ self.last_function_response = self.load_last_function_response()
377
+
374
378
  # Keep track of the total number of messages throughout all time
375
379
  self.messages_total = messages_total if messages_total is not None else (len(self._messages) - 1) # (-system)
376
380
  self.messages_total_init = len(self._messages) - 1
@@ -389,6 +393,19 @@ class Agent(BaseAgent):
389
393
  else:
390
394
  self.supports_structured_output = True
391
395
 
396
+ def load_last_function_response(self):
397
+ """Load the last function response from message history"""
398
+ for i in range(len(self._messages) - 1, -1, -1):
399
+ msg = self._messages[i]
400
+ if msg.role == MessageRole.tool and msg.text:
401
+ try:
402
+ response_json = json.loads(msg.text)
403
+ if response_json.get("message"):
404
+ return response_json["message"]
405
+ except (json.JSONDecodeError, KeyError):
406
+ raise ValueError(f"Invalid JSON format in message: {msg.text}")
407
+ return None
408
+
392
409
  def update_memory_if_change(self, new_memory: Memory) -> bool:
393
410
  """
394
411
  Update internal memory object and system prompt if there have been modifications.
@@ -586,7 +603,7 @@ class Agent(BaseAgent):
586
603
  ) -> ChatCompletionResponse:
587
604
  """Get response from LLM API with robust retry mechanism."""
588
605
 
589
- allowed_tool_names = self.tool_rules_solver.get_allowed_tool_names()
606
+ allowed_tool_names = self.tool_rules_solver.get_allowed_tool_names(last_function_response=self.last_function_response)
590
607
  agent_state_tool_jsons = [t.json_schema for t in self.agent_state.tools]
591
608
 
592
609
  allowed_functions = (
@@ -826,6 +843,7 @@ class Agent(BaseAgent):
826
843
  error_msg_user = f"{error_msg}\n{traceback.format_exc()}"
827
844
  printd(error_msg_user)
828
845
  function_response = package_function_response(False, error_msg)
846
+ self.last_function_response = function_response
829
847
  # TODO: truncate error message somehow
830
848
  messages.append(
831
849
  Message.dict_to_message(
@@ -861,6 +879,7 @@ class Agent(BaseAgent):
861
879
  ) # extend conversation with function response
862
880
  self.interface.function_message(f"Ran {function_name}({function_args})", msg_obj=messages[-1])
863
881
  self.interface.function_message(f"Success: {function_response_string}", msg_obj=messages[-1])
882
+ self.last_function_response = function_response
864
883
 
865
884
  else:
866
885
  # Standard non-function reply
@@ -1094,6 +1113,7 @@ class Agent(BaseAgent):
1094
1113
 
1095
1114
  # If we got a context alert, try trimming the messages length, then try again
1096
1115
  if is_context_overflow_error(e):
1116
+ printd(f"context window exceeded with limit {self.agent_state.llm_config.context_window}, running summarizer to trim messages")
1097
1117
  # A separate API call to run a summarizer
1098
1118
  self.summarize_messages_inplace()
1099
1119
 
@@ -1169,8 +1189,13 @@ class Agent(BaseAgent):
1169
1189
 
1170
1190
  # If at this point there's nothing to summarize, throw an error
1171
1191
  if len(candidate_messages_to_summarize) == 0:
1172
- raise LLMError(
1173
- f"Summarize error: tried to run summarize, but couldn't find enough messages to compress [len={len(self.messages)}, preserve_N={MESSAGE_SUMMARY_TRUNC_KEEP_N_LAST}]"
1192
+ raise ContextWindowExceededError(
1193
+ "Not enough messages to compress for summarization",
1194
+ details={
1195
+ "num_candidate_messages": len(candidate_messages_to_summarize),
1196
+ "num_total_messages": len(self.messages),
1197
+ "preserve_N": MESSAGE_SUMMARY_TRUNC_KEEP_N_LAST,
1198
+ },
1174
1199
  )
1175
1200
 
1176
1201
  # Walk down the message buffer (front-to-back) until we hit the target token count
@@ -1204,8 +1229,13 @@ class Agent(BaseAgent):
1204
1229
  message_sequence_to_summarize = self._messages[1:cutoff] # do NOT get rid of the system message
1205
1230
  if len(message_sequence_to_summarize) <= 1:
1206
1231
  # This prevents a potential infinite loop of summarizing the same message over and over
1207
- raise LLMError(
1208
- f"Summarize error: tried to run summarize, but couldn't find enough messages to compress [len={len(message_sequence_to_summarize)} <= 1]"
1232
+ raise ContextWindowExceededError(
1233
+ "Not enough messages to compress for summarization after determining cutoff",
1234
+ details={
1235
+ "num_candidate_messages": len(message_sequence_to_summarize),
1236
+ "num_total_messages": len(self.messages),
1237
+ "preserve_N": MESSAGE_SUMMARY_TRUNC_KEEP_N_LAST,
1238
+ },
1209
1239
  )
1210
1240
  else:
1211
1241
  printd(f"Attempting to summarize {len(message_sequence_to_summarize)} messages [1:{cutoff}] of {len(self._messages)}")
@@ -1218,6 +1248,7 @@ class Agent(BaseAgent):
1218
1248
  self.agent_state.llm_config.context_window = (
1219
1249
  LLM_MAX_TOKENS[self.model] if (self.model is not None and self.model in LLM_MAX_TOKENS) else LLM_MAX_TOKENS["DEFAULT"]
1220
1250
  )
1251
+
1221
1252
  summary = summarize_messages(agent_state=self.agent_state, message_sequence_to_summarize=message_sequence_to_summarize)
1222
1253
  printd(f"Got summary: {summary}")
1223
1254
 
@@ -233,7 +233,7 @@ class AbstractClient(object):
233
233
  def get_tool_id(self, name: str) -> Optional[str]:
234
234
  raise NotImplementedError
235
235
 
236
- def add_base_tools(self) -> List[Tool]:
236
+ def upsert_base_tools(self) -> List[Tool]:
237
237
  raise NotImplementedError
238
238
 
239
239
  def load_data(self, connector: DataConnector, source_name: str):
@@ -1466,7 +1466,7 @@ class RESTClient(AbstractClient):
1466
1466
  raise ValueError(f"Failed to get tool: {response.text}")
1467
1467
  return response.json()
1468
1468
 
1469
- def add_base_tools(self) -> List[Tool]:
1469
+ def upsert_base_tools(self) -> List[Tool]:
1470
1470
  response = requests.post(f"{self.base_url}/{self.api_prefix}/tools/add-base-tools/", headers=self.headers)
1471
1471
  if response.status_code != 200:
1472
1472
  raise ValueError(f"Failed to add base tools: {response.text}")
@@ -8,9 +8,9 @@ from letta.constants import OPENAI_CONTEXT_WINDOW_ERROR_SUBSTRING
8
8
  from letta.errors import LLMError
9
9
  from letta.schemas.enums import MessageStreamStatus
10
10
  from letta.schemas.letta_message import (
11
- FunctionCallMessage,
12
- FunctionReturn,
13
- InternalMonologue,
11
+ ToolCallMessage,
12
+ ToolReturnMessage,
13
+ ReasoningMessage,
14
14
  )
15
15
  from letta.schemas.letta_response import LettaStreamingResponse
16
16
  from letta.schemas.usage import LettaUsageStatistics
@@ -53,12 +53,12 @@ def _sse_post(url: str, data: dict, headers: dict) -> Generator[LettaStreamingRe
53
53
  yield MessageStreamStatus(sse.data)
54
54
  else:
55
55
  chunk_data = json.loads(sse.data)
56
- if "internal_monologue" in chunk_data:
57
- yield InternalMonologue(**chunk_data)
58
- elif "function_call" in chunk_data:
59
- yield FunctionCallMessage(**chunk_data)
60
- elif "function_return" in chunk_data:
61
- yield FunctionReturn(**chunk_data)
56
+ if "reasoning" in chunk_data:
57
+ yield ReasoningMessage(**chunk_data)
58
+ elif "tool_call" in chunk_data:
59
+ yield ToolCallMessage(**chunk_data)
60
+ elif "tool_return" in chunk_data:
61
+ yield ToolReturnMessage(**chunk_data)
62
62
  elif "usage" in chunk_data:
63
63
  yield LettaUsageStatistics(**chunk_data["usage"])
64
64
  else:
@@ -1,4 +1,5 @@
1
1
  import json
2
+ from enum import Enum
2
3
  from typing import TYPE_CHECKING, List, Optional, Union
3
4
 
4
5
  # Avoid circular imports
@@ -6,9 +7,31 @@ if TYPE_CHECKING:
6
7
  from letta.schemas.message import Message
7
8
 
8
9
 
10
+ class ErrorCode(Enum):
11
+ """Enum for error codes used by client."""
12
+
13
+ INTERNAL_SERVER_ERROR = "INTERNAL_SERVER_ERROR"
14
+ CONTEXT_WINDOW_EXCEEDED = "CONTEXT_WINDOW_EXCEEDED"
15
+ RATE_LIMIT_EXCEEDED = "RATE_LIMIT_EXCEEDED"
16
+
17
+
9
18
  class LettaError(Exception):
10
19
  """Base class for all Letta related errors."""
11
20
 
21
+ def __init__(self, message: str, code: Optional[ErrorCode] = None, details: dict = {}):
22
+ self.message = message
23
+ self.code = code
24
+ self.details = details
25
+ super().__init__(message)
26
+
27
+ def __str__(self) -> str:
28
+ if self.code:
29
+ return f"{self.code.value}: {self.message}"
30
+ return self.message
31
+
32
+ def __repr__(self) -> str:
33
+ return f"{self.__class__.__name__}(message='{self.message}', code='{self.code}', details={self.details})"
34
+
12
35
 
13
36
  class LettaToolCreateError(LettaError):
14
37
  """Error raised when a tool cannot be created."""
@@ -16,10 +39,7 @@ class LettaToolCreateError(LettaError):
16
39
  default_error_message = "Error creating tool."
17
40
 
18
41
  def __init__(self, message=None):
19
- if message is None:
20
- message = self.default_error_message
21
- self.message = message
22
- super().__init__(self.message)
42
+ super().__init__(message=message or self.default_error_message)
23
43
 
24
44
 
25
45
  class LettaConfigurationError(LettaError):
@@ -27,23 +47,17 @@ class LettaConfigurationError(LettaError):
27
47
 
28
48
  def __init__(self, message: str, missing_fields: Optional[List[str]] = None):
29
49
  self.missing_fields = missing_fields or []
30
- super().__init__(message)
50
+ super().__init__(message=message, details={"missing_fields": self.missing_fields})
31
51
 
32
52
 
33
53
  class LettaAgentNotFoundError(LettaError):
34
54
  """Error raised when an agent is not found."""
35
-
36
- def __init__(self, message: str):
37
- self.message = message
38
- super().__init__(self.message)
55
+ pass
39
56
 
40
57
 
41
58
  class LettaUserNotFoundError(LettaError):
42
59
  """Error raised when a user is not found."""
43
-
44
- def __init__(self, message: str):
45
- self.message = message
46
- super().__init__(self.message)
60
+ pass
47
61
 
48
62
 
49
63
  class LLMError(LettaError):
@@ -54,24 +68,45 @@ class LLMJSONParsingError(LettaError):
54
68
  """Exception raised for errors in the JSON parsing process."""
55
69
 
56
70
  def __init__(self, message="Error parsing JSON generated by LLM"):
57
- self.message = message
58
- super().__init__(self.message)
71
+ super().__init__(message=message)
59
72
 
60
73
 
61
74
  class LocalLLMError(LettaError):
62
75
  """Generic catch-all error for local LLM problems"""
63
76
 
64
77
  def __init__(self, message="Encountered an error while running local LLM"):
65
- self.message = message
66
- super().__init__(self.message)
78
+ super().__init__(message=message)
67
79
 
68
80
 
69
81
  class LocalLLMConnectionError(LettaError):
70
82
  """Error for when local LLM cannot be reached with provided IP/port"""
71
83
 
72
84
  def __init__(self, message="Could not connect to local LLM"):
73
- self.message = message
74
- super().__init__(self.message)
85
+ super().__init__(message=message)
86
+
87
+
88
+ class ContextWindowExceededError(LettaError):
89
+ """Error raised when the context window is exceeded but further summarization fails."""
90
+
91
+ def __init__(self, message: str, details: dict = {}):
92
+ error_message = f"{message} ({details})"
93
+ super().__init__(
94
+ message=error_message,
95
+ code=ErrorCode.CONTEXT_WINDOW_EXCEEDED,
96
+ details=details,
97
+ )
98
+
99
+
100
+ class RateLimitExceededError(LettaError):
101
+ """Error raised when the llm rate limiter throttles api requests."""
102
+
103
+ def __init__(self, message: str, max_retries: int):
104
+ error_message = f"{message} ({max_retries})"
105
+ super().__init__(
106
+ message=error_message,
107
+ code=ErrorCode.RATE_LIMIT_EXCEEDED,
108
+ details={"max_retries": max_retries},
109
+ )
75
110
 
76
111
 
77
112
  class LettaMessageError(LettaError):
@@ -96,16 +131,16 @@ class LettaMessageError(LettaError):
96
131
  return f"{error_msg}\n\n{message_json}"
97
132
 
98
133
 
99
- class MissingFunctionCallError(LettaMessageError):
100
- """Error raised when a message is missing a function call."""
134
+ class MissingToolCallError(LettaMessageError):
135
+ """Error raised when a message is missing a tool call."""
101
136
 
102
- default_error_message = "The message is missing a function call."
137
+ default_error_message = "The message is missing a tool call."
103
138
 
104
139
 
105
- class InvalidFunctionCallError(LettaMessageError):
106
- """Error raised when a message uses an invalid function call."""
140
+ class InvalidToolCallError(LettaMessageError):
141
+ """Error raised when a message uses an invalid tool call."""
107
142
 
108
- default_error_message = "The message uses an invalid function call or has improper usage of a function call."
143
+ default_error_message = "The message uses an invalid tool call or has improper usage of a tool call."
109
144
 
110
145
 
111
146
  class MissingInnerMonologueError(LettaMessageError):
@@ -61,60 +61,6 @@ def conversation_search(self: "Agent", query: str, page: Optional[int] = 0) -> O
61
61
  return results_str
62
62
 
63
63
 
64
- def conversation_search_date(self: "Agent", start_date: str, end_date: str, page: Optional[int] = 0) -> Optional[str]:
65
- """
66
- Search prior conversation history using a date range.
67
-
68
- Args:
69
- start_date (str): The start of the date range to search, in the format 'YYYY-MM-DD'.
70
- end_date (str): The end of the date range to search, in the format 'YYYY-MM-DD'.
71
- page (int): Allows you to page through results. Only use on a follow-up query. Defaults to 0 (first page).
72
-
73
- Returns:
74
- str: Query result string
75
- """
76
- import math
77
- from datetime import datetime
78
-
79
- from letta.constants import RETRIEVAL_QUERY_DEFAULT_PAGE_SIZE
80
- from letta.utils import json_dumps
81
-
82
- if page is None or (isinstance(page, str) and page.lower().strip() == "none"):
83
- page = 0
84
- try:
85
- page = int(page)
86
- if page < 0:
87
- raise ValueError
88
- except:
89
- raise ValueError(f"'page' argument must be an integer")
90
-
91
- # Convert date strings to datetime objects
92
- try:
93
- start_datetime = datetime.strptime(start_date, "%Y-%m-%d").replace(hour=0, minute=0, second=0, microsecond=0)
94
- end_datetime = datetime.strptime(end_date, "%Y-%m-%d").replace(hour=23, minute=59, second=59, microsecond=999999)
95
- except ValueError:
96
- raise ValueError("Dates must be in the format 'YYYY-MM-DD'")
97
-
98
- count = RETRIEVAL_QUERY_DEFAULT_PAGE_SIZE
99
- results = self.message_manager.list_user_messages_for_agent(
100
- # TODO: add paging by page number. currently cursor only works with strings.
101
- agent_id=self.agent_state.id,
102
- actor=self.user,
103
- start_date=start_datetime,
104
- end_date=end_datetime,
105
- limit=count,
106
- )
107
- total = len(results)
108
- num_pages = math.ceil(total / count) - 1 # 0 index
109
- if len(results) == 0:
110
- results_str = f"No results found."
111
- else:
112
- results_pref = f"Showing {len(results)} of {total} results (page {page}/{num_pages}):"
113
- results_formatted = [f"timestamp: {d['timestamp']}, {d['message']['role']} - {d['message']['content']}" for d in results]
114
- results_str = f"{results_pref} {json_dumps(results_formatted)}"
115
- return results_str
116
-
117
-
118
64
  def archival_memory_insert(self: "Agent", content: str) -> Optional[str]:
119
65
  """
120
66
  Add to archival memory. Make sure to phrase the memory contents such that it can be easily queried later.
@@ -0,0 +1,146 @@
1
+ import json
2
+ from typing import List, Optional, Union
3
+
4
+ from pydantic import BaseModel, Field
5
+
6
+ from letta.schemas.enums import ToolRuleType
7
+ from letta.schemas.tool_rule import (
8
+ BaseToolRule,
9
+ ChildToolRule,
10
+ ConditionalToolRule,
11
+ InitToolRule,
12
+ TerminalToolRule,
13
+ )
14
+
15
+
16
+ class ToolRuleValidationError(Exception):
17
+ """Custom exception for tool rule validation errors in ToolRulesSolver."""
18
+
19
+ def __init__(self, message: str):
20
+ super().__init__(f"ToolRuleValidationError: {message}")
21
+
22
+
23
+ class ToolRulesSolver(BaseModel):
24
+ init_tool_rules: List[InitToolRule] = Field(
25
+ default_factory=list, description="Initial tool rules to be used at the start of tool execution."
26
+ )
27
+ tool_rules: List[Union[ChildToolRule, ConditionalToolRule]] = Field(
28
+ default_factory=list, description="Standard tool rules for controlling execution sequence and allowed transitions."
29
+ )
30
+ terminal_tool_rules: List[TerminalToolRule] = Field(
31
+ default_factory=list, description="Terminal tool rules that end the agent loop if called."
32
+ )
33
+ last_tool_name: Optional[str] = Field(None, description="The most recent tool used, updated with each tool call.")
34
+
35
+ def __init__(self, tool_rules: List[BaseToolRule], **kwargs):
36
+ super().__init__(**kwargs)
37
+ # Separate the provided tool rules into init, standard, and terminal categories
38
+ for rule in tool_rules:
39
+ if rule.type == ToolRuleType.run_first:
40
+ assert isinstance(rule, InitToolRule)
41
+ self.init_tool_rules.append(rule)
42
+ elif rule.type == ToolRuleType.constrain_child_tools:
43
+ assert isinstance(rule, ChildToolRule)
44
+ self.tool_rules.append(rule)
45
+ elif rule.type == ToolRuleType.conditional:
46
+ assert isinstance(rule, ConditionalToolRule)
47
+ self.validate_conditional_tool(rule)
48
+ self.tool_rules.append(rule)
49
+ elif rule.type == ToolRuleType.exit_loop:
50
+ assert isinstance(rule, TerminalToolRule)
51
+ self.terminal_tool_rules.append(rule)
52
+
53
+
54
+ def update_tool_usage(self, tool_name: str):
55
+ """Update the internal state to track the last tool called."""
56
+ self.last_tool_name = tool_name
57
+
58
+ def get_allowed_tool_names(self, error_on_empty: bool = False, last_function_response: Optional[str] = None) -> List[str]:
59
+ """Get a list of tool names allowed based on the last tool called."""
60
+ if self.last_tool_name is None:
61
+ # Use initial tool rules if no tool has been called yet
62
+ return [rule.tool_name for rule in self.init_tool_rules]
63
+ else:
64
+ # Find a matching ToolRule for the last tool used
65
+ current_rule = next((rule for rule in self.tool_rules if rule.tool_name == self.last_tool_name), None)
66
+
67
+ if current_rule is None:
68
+ if error_on_empty:
69
+ raise ValueError(f"No tool rule found for {self.last_tool_name}")
70
+ return []
71
+
72
+ # If the current rule is a conditional tool rule, use the LLM response to
73
+ # determine which child tool to use
74
+ if isinstance(current_rule, ConditionalToolRule):
75
+ if not last_function_response:
76
+ raise ValueError("Conditional tool rule requires an LLM response to determine which child tool to use")
77
+ next_tool = self.evaluate_conditional_tool(current_rule, last_function_response)
78
+ return [next_tool] if next_tool else []
79
+
80
+ return current_rule.children if current_rule.children else []
81
+
82
+ def is_terminal_tool(self, tool_name: str) -> bool:
83
+ """Check if the tool is defined as a terminal tool in the terminal tool rules."""
84
+ return any(rule.tool_name == tool_name for rule in self.terminal_tool_rules)
85
+
86
+ def has_children_tools(self, tool_name):
87
+ """Check if the tool has children tools"""
88
+ return any(rule.tool_name == tool_name for rule in self.tool_rules)
89
+
90
+ def validate_conditional_tool(self, rule: ConditionalToolRule):
91
+ '''
92
+ Validate a conditional tool rule
93
+
94
+ Args:
95
+ rule (ConditionalToolRule): The conditional tool rule to validate
96
+
97
+ Raises:
98
+ ToolRuleValidationError: If the rule is invalid
99
+ '''
100
+ if len(rule.child_output_mapping) == 0:
101
+ raise ToolRuleValidationError("Conditional tool rule must have at least one child tool.")
102
+ return True
103
+
104
+ def evaluate_conditional_tool(self, tool: ConditionalToolRule, last_function_response: str) -> str:
105
+ '''
106
+ Parse function response to determine which child tool to use based on the mapping
107
+
108
+ Args:
109
+ tool (ConditionalToolRule): The conditional tool rule
110
+ last_function_response (str): The function response in JSON format
111
+
112
+ Returns:
113
+ str: The name of the child tool to use next
114
+ '''
115
+ json_response = json.loads(last_function_response)
116
+ function_output = json_response["message"]
117
+
118
+ # Try to match the function output with a mapping key
119
+ for key in tool.child_output_mapping:
120
+
121
+ # Convert function output to match key type for comparison
122
+ if isinstance(key, bool):
123
+ typed_output = function_output.lower() == "true"
124
+ elif isinstance(key, int):
125
+ try:
126
+ typed_output = int(function_output)
127
+ except (ValueError, TypeError):
128
+ continue
129
+ elif isinstance(key, float):
130
+ try:
131
+ typed_output = float(function_output)
132
+ except (ValueError, TypeError):
133
+ continue
134
+ else: # string
135
+ if function_output == "True" or function_output == "False":
136
+ typed_output = function_output.lower()
137
+ elif function_output == "None":
138
+ typed_output = None
139
+ else:
140
+ typed_output = function_output
141
+
142
+ if typed_output == key:
143
+ return tool.child_output_mapping[key]
144
+
145
+ # If no match found, use default
146
+ return tool.default_child
@@ -5,7 +5,7 @@ from typing import List, Optional, Union
5
5
  import requests
6
6
 
7
7
  from letta.constants import CLI_WARNING_PREFIX
8
- from letta.errors import LettaConfigurationError
8
+ from letta.errors import LettaConfigurationError, RateLimitExceededError
9
9
  from letta.llm_api.anthropic import anthropic_chat_completions_request
10
10
  from letta.llm_api.azure_openai import azure_openai_chat_completions_request
11
11
  from letta.llm_api.google_ai import (
@@ -80,7 +80,7 @@ def retry_with_exponential_backoff(
80
80
 
81
81
  # Check if max retries has been reached
82
82
  if num_retries > max_retries:
83
- raise Exception(f"Maximum number of retries ({max_retries}) exceeded.")
83
+ raise RateLimitExceededError("Maximum number of retries exceeded", max_retries=max_retries)
84
84
 
85
85
  # Increment the delay
86
86
  delay *= exponential_base * (1 + jitter * random.random())
@@ -9,7 +9,7 @@ from letta.schemas.embedding_config import EmbeddingConfig
9
9
  from letta.schemas.enums import ToolRuleType
10
10
  from letta.schemas.llm_config import LLMConfig
11
11
  from letta.schemas.openai.chat_completions import ToolCall, ToolCallFunction
12
- from letta.schemas.tool_rule import ChildToolRule, InitToolRule, TerminalToolRule
12
+ from letta.schemas.tool_rule import ChildToolRule, ConditionalToolRule, InitToolRule, TerminalToolRule
13
13
 
14
14
 
15
15
  class EmbeddingConfigColumn(TypeDecorator):
@@ -80,7 +80,7 @@ class ToolRulesColumn(TypeDecorator):
80
80
  return value
81
81
 
82
82
  @staticmethod
83
- def deserialize_tool_rule(data: dict) -> Union[ChildToolRule, InitToolRule, TerminalToolRule]:
83
+ def deserialize_tool_rule(data: dict) -> Union[ChildToolRule, InitToolRule, TerminalToolRule, ConditionalToolRule]:
84
84
  """Deserialize a dictionary to the appropriate ToolRule subclass based on the 'type'."""
85
85
  rule_type = ToolRuleType(data.get("type")) # Remove 'type' field if it exists since it is a class var
86
86
  if rule_type == ToolRuleType.run_first:
@@ -90,6 +90,9 @@ class ToolRulesColumn(TypeDecorator):
90
90
  elif rule_type == ToolRuleType.constrain_child_tools:
91
91
  rule = ChildToolRule(**data)
92
92
  return rule
93
+ elif rule_type == ToolRuleType.conditional:
94
+ rule = ConditionalToolRule(**data)
95
+ return rule
93
96
  else:
94
97
  raise ValueError(f"Unknown tool rule type: {rule_type}")
95
98
 
@@ -1,5 +1,6 @@
1
1
  from typing import Optional
2
2
 
3
+ from sqlalchemy import Index
3
4
  from sqlalchemy.orm import Mapped, mapped_column, relationship
4
5
 
5
6
  from letta.orm.custom_columns import ToolCallColumn
@@ -13,7 +14,7 @@ class Message(SqlalchemyBase, OrganizationMixin, AgentMixin):
13
14
  """Defines data model for storing Message objects"""
14
15
 
15
16
  __tablename__ = "messages"
16
- __table_args__ = {"extend_existing": True}
17
+ __table_args__ = (Index("ix_messages_agent_created_at", "agent_id", "created_at"),)
17
18
  __pydantic_model__ = PydanticMessage
18
19
 
19
20
  id: Mapped[str] = mapped_column(primary_key=True, doc="Unique message identifier")
@@ -1,26 +1,26 @@
1
1
  from typing import TYPE_CHECKING
2
- from sqlalchemy import Column, JSON, Index
3
- from sqlalchemy.orm import Mapped, mapped_column, relationship, declared_attr
4
2
 
5
- from letta.orm.mixins import FileMixin, OrganizationMixin
3
+ from sqlalchemy import JSON, Column, Index
4
+ from sqlalchemy.orm import Mapped, declared_attr, mapped_column, relationship
5
+
6
+ from letta.config import LettaConfig
7
+ from letta.constants import MAX_EMBEDDING_DIM
6
8
  from letta.orm.custom_columns import CommonVector, EmbeddingConfigColumn
7
- from letta.orm.sqlalchemy_base import SqlalchemyBase
8
9
  from letta.orm.mixins import AgentMixin, FileMixin, OrganizationMixin, SourceMixin
10
+ from letta.orm.sqlalchemy_base import SqlalchemyBase
9
11
  from letta.schemas.passage import Passage as PydanticPassage
10
12
  from letta.settings import settings
11
13
 
12
- from letta.config import LettaConfig
13
- from letta.constants import MAX_EMBEDDING_DIM
14
-
15
14
  config = LettaConfig()
16
15
 
17
16
  if TYPE_CHECKING:
18
- from letta.orm.organization import Organization
19
17
  from letta.orm.agent import Agent
18
+ from letta.orm.organization import Organization
20
19
 
21
20
 
22
21
  class BasePassage(SqlalchemyBase, OrganizationMixin):
23
22
  """Base class for all passage types with common fields"""
23
+
24
24
  __abstract__ = True
25
25
  __pydantic_model__ = PydanticPassage
26
26
 
@@ -45,17 +45,15 @@ class BasePassage(SqlalchemyBase, OrganizationMixin):
45
45
  @declared_attr
46
46
  def __table_args__(cls):
47
47
  if settings.letta_pg_uri_no_default:
48
- return (
49
- Index(f'{cls.__tablename__}_org_idx', 'organization_id'),
50
- {"extend_existing": True}
51
- )
48
+ return (Index(f"{cls.__tablename__}_org_idx", "organization_id"), {"extend_existing": True})
52
49
  return ({"extend_existing": True},)
53
50
 
54
51
 
55
52
  class SourcePassage(BasePassage, FileMixin, SourceMixin):
56
53
  """Passages derived from external files/sources"""
54
+
57
55
  __tablename__ = "source_passages"
58
-
56
+
59
57
  @declared_attr
60
58
  def file(cls) -> Mapped["FileMetadata"]:
61
59
  """Relationship to file"""
@@ -64,7 +62,7 @@ class SourcePassage(BasePassage, FileMixin, SourceMixin):
64
62
  @declared_attr
65
63
  def organization(cls) -> Mapped["Organization"]:
66
64
  return relationship("Organization", back_populates="source_passages", lazy="selectin")
67
-
65
+
68
66
  @declared_attr
69
67
  def source(cls) -> Mapped["Source"]:
70
68
  """Relationship to source"""
@@ -73,8 +71,9 @@ class SourcePassage(BasePassage, FileMixin, SourceMixin):
73
71
 
74
72
  class AgentPassage(BasePassage, AgentMixin):
75
73
  """Passages created by agents as archival memories"""
74
+
76
75
  __tablename__ = "agent_passages"
77
-
76
+
78
77
  @declared_attr
79
78
  def organization(cls) -> Mapped["Organization"]:
80
79
  return relationship("Organization", back_populates="agent_passages", lazy="selectin")