letta-nightly 0.6.4.dev20241217104233__tar.gz → 0.6.5.dev20241218055539__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 (231) hide show
  1. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/PKG-INFO +1 -1
  2. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/__init__.py +1 -1
  3. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/agent.py +68 -65
  4. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/client/client.py +1 -0
  5. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/constants.py +6 -1
  6. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/embeddings.py +3 -9
  7. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/functions/function_sets/base.py +9 -57
  8. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/functions/schema_generator.py +1 -1
  9. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/llm_api/anthropic.py +38 -13
  10. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/llm_api/llm_api_tools.py +12 -1
  11. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/function_parser.py +1 -1
  12. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/orm/errors.py +8 -0
  13. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/orm/sqlalchemy_base.py +24 -17
  14. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/providers.py +2 -0
  15. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/agent.py +35 -0
  16. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/sandbox_config.py +2 -1
  17. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/app.py +32 -7
  18. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/routers/v1/tools.py +1 -1
  19. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/server.py +81 -57
  20. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/services/agent_manager.py +3 -0
  21. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/services/tool_execution_sandbox.py +54 -45
  22. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/settings.py +9 -4
  23. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/utils.py +8 -0
  24. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/pyproject.toml +1 -1
  25. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/LICENSE +0 -0
  26. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/README.md +0 -0
  27. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/__main__.py +0 -0
  28. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/benchmark/benchmark.py +0 -0
  29. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/benchmark/constants.py +0 -0
  30. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/chat_only_agent.py +0 -0
  31. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/cli/cli.py +0 -0
  32. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/cli/cli_config.py +0 -0
  33. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/cli/cli_load.py +0 -0
  34. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/client/__init__.py +0 -0
  35. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/client/streaming.py +0 -0
  36. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/client/utils.py +0 -0
  37. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/config.py +0 -0
  38. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/credentials.py +0 -0
  39. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/data_sources/connectors.py +0 -0
  40. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/data_sources/connectors_helper.py +0 -0
  41. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/errors.py +0 -0
  42. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/functions/__init__.py +0 -0
  43. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/functions/function_sets/extras.py +0 -0
  44. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/functions/functions.py +0 -0
  45. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/functions/helpers.py +0 -0
  46. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/helpers/__init__.py +0 -0
  47. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/helpers/tool_rule_solver.py +0 -0
  48. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/humans/__init__.py +0 -0
  49. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/humans/examples/basic.txt +0 -0
  50. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/humans/examples/cs_phd.txt +0 -0
  51. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/interface.py +0 -0
  52. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/llm_api/__init__.py +0 -0
  53. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/llm_api/azure_openai.py +0 -0
  54. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/llm_api/azure_openai_constants.py +0 -0
  55. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/llm_api/cohere.py +0 -0
  56. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/llm_api/google_ai.py +0 -0
  57. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/llm_api/helpers.py +0 -0
  58. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/llm_api/mistral.py +0 -0
  59. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/llm_api/openai.py +0 -0
  60. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/README.md +0 -0
  61. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/__init__.py +0 -0
  62. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/chat_completion_proxy.py +0 -0
  63. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/constants.py +0 -0
  64. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/grammars/__init__.py +0 -0
  65. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/grammars/gbnf_grammar_generator.py +0 -0
  66. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/grammars/json.gbnf +0 -0
  67. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/grammars/json_func_calls_with_inner_thoughts.gbnf +0 -0
  68. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/json_parser.py +0 -0
  69. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/koboldcpp/api.py +0 -0
  70. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/koboldcpp/settings.py +0 -0
  71. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/llamacpp/api.py +0 -0
  72. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/llamacpp/settings.py +0 -0
  73. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/llm_chat_completion_wrappers/__init__.py +0 -0
  74. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/llm_chat_completion_wrappers/airoboros.py +0 -0
  75. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/llm_chat_completion_wrappers/chatml.py +0 -0
  76. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/llm_chat_completion_wrappers/configurable_wrapper.py +0 -0
  77. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/llm_chat_completion_wrappers/dolphin.py +0 -0
  78. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/llm_chat_completion_wrappers/llama3.py +0 -0
  79. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/llm_chat_completion_wrappers/simple_summary_wrapper.py +0 -0
  80. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/llm_chat_completion_wrappers/wrapper_base.py +0 -0
  81. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/llm_chat_completion_wrappers/zephyr.py +0 -0
  82. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/lmstudio/api.py +0 -0
  83. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/lmstudio/settings.py +0 -0
  84. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/ollama/api.py +0 -0
  85. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/ollama/settings.py +0 -0
  86. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/settings/__init__.py +0 -0
  87. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/settings/deterministic_mirostat.py +0 -0
  88. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/settings/settings.py +0 -0
  89. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/settings/simple.py +0 -0
  90. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/utils.py +0 -0
  91. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/vllm/api.py +0 -0
  92. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/webui/api.py +0 -0
  93. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/webui/legacy_api.py +0 -0
  94. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/webui/legacy_settings.py +0 -0
  95. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/local_llm/webui/settings.py +0 -0
  96. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/log.py +0 -0
  97. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/main.py +0 -0
  98. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/memory.py +0 -0
  99. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/o1_agent.py +0 -0
  100. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/offline_memory_agent.py +0 -0
  101. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/openai_backcompat/__init__.py +0 -0
  102. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/openai_backcompat/openai_object.py +0 -0
  103. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/orm/__all__.py +0 -0
  104. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/orm/__init__.py +0 -0
  105. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/orm/agent.py +0 -0
  106. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/orm/agents_tags.py +0 -0
  107. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/orm/base.py +0 -0
  108. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/orm/block.py +0 -0
  109. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/orm/blocks_agents.py +0 -0
  110. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/orm/custom_columns.py +0 -0
  111. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/orm/enums.py +0 -0
  112. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/orm/file.py +0 -0
  113. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/orm/job.py +0 -0
  114. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/orm/message.py +0 -0
  115. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/orm/mixins.py +0 -0
  116. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/orm/organization.py +0 -0
  117. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/orm/passage.py +0 -0
  118. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/orm/sandbox_config.py +0 -0
  119. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/orm/source.py +0 -0
  120. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/orm/sources_agents.py +0 -0
  121. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/orm/sqlite_functions.py +0 -0
  122. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/orm/tool.py +0 -0
  123. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/orm/tools_agents.py +0 -0
  124. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/orm/user.py +0 -0
  125. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/personas/__init__.py +0 -0
  126. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/personas/examples/anna_pa.txt +0 -0
  127. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/personas/examples/google_search_persona.txt +0 -0
  128. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/personas/examples/memgpt_doc.txt +0 -0
  129. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/personas/examples/memgpt_starter.txt +0 -0
  130. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/personas/examples/o1_persona.txt +0 -0
  131. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/personas/examples/offline_memory_persona.txt +0 -0
  132. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/personas/examples/sam.txt +0 -0
  133. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/personas/examples/sam_pov.txt +0 -0
  134. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/personas/examples/sam_simple_pov_gpt35.txt +0 -0
  135. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/personas/examples/sqldb/test.db +0 -0
  136. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/prompts/__init__.py +0 -0
  137. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/prompts/gpt_summarize.py +0 -0
  138. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/prompts/gpt_system.py +0 -0
  139. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/prompts/system/memgpt_base.txt +0 -0
  140. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/prompts/system/memgpt_chat.txt +0 -0
  141. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/prompts/system/memgpt_chat_compressed.txt +0 -0
  142. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/prompts/system/memgpt_chat_fstring.txt +0 -0
  143. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/prompts/system/memgpt_convo_only.txt +0 -0
  144. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/prompts/system/memgpt_doc.txt +0 -0
  145. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/prompts/system/memgpt_gpt35_extralong.txt +0 -0
  146. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/prompts/system/memgpt_intuitive_knowledge.txt +0 -0
  147. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/prompts/system/memgpt_modified_chat.txt +0 -0
  148. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/prompts/system/memgpt_modified_o1.txt +0 -0
  149. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/prompts/system/memgpt_offline_memory.txt +0 -0
  150. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/prompts/system/memgpt_offline_memory_chat.txt +0 -0
  151. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/pytest.ini +0 -0
  152. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/block.py +0 -0
  153. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/embedding_config.py +0 -0
  154. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/enums.py +0 -0
  155. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/file.py +0 -0
  156. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/health.py +0 -0
  157. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/job.py +0 -0
  158. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/letta_base.py +0 -0
  159. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/letta_message.py +0 -0
  160. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/letta_request.py +0 -0
  161. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/letta_response.py +0 -0
  162. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/llm_config.py +0 -0
  163. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/memory.py +0 -0
  164. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/message.py +0 -0
  165. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/openai/chat_completion_request.py +0 -0
  166. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/openai/chat_completion_response.py +0 -0
  167. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/openai/chat_completions.py +0 -0
  168. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/openai/embedding_response.py +0 -0
  169. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/openai/openai.py +0 -0
  170. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/organization.py +0 -0
  171. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/passage.py +0 -0
  172. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/source.py +0 -0
  173. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/tool.py +0 -0
  174. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/tool_rule.py +0 -0
  175. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/usage.py +0 -0
  176. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/schemas/user.py +0 -0
  177. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/__init__.py +0 -0
  178. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/constants.py +0 -0
  179. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/generate_openapi_schema.sh +0 -0
  180. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/__init__.py +0 -0
  181. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/auth/__init__.py +0 -0
  182. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/auth/index.py +0 -0
  183. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/auth_token.py +0 -0
  184. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/interface.py +0 -0
  185. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/routers/__init__.py +0 -0
  186. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/routers/openai/__init__.py +0 -0
  187. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/routers/openai/assistants/__init__.py +0 -0
  188. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/routers/openai/assistants/assistants.py +0 -0
  189. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/routers/openai/assistants/schemas.py +0 -0
  190. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/routers/openai/chat_completions/__init__.py +0 -0
  191. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/routers/openai/chat_completions/chat_completions.py +0 -0
  192. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/routers/v1/__init__.py +0 -0
  193. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/routers/v1/agents.py +0 -0
  194. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/routers/v1/blocks.py +0 -0
  195. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/routers/v1/health.py +0 -0
  196. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/routers/v1/jobs.py +0 -0
  197. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/routers/v1/llms.py +0 -0
  198. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/routers/v1/organizations.py +0 -0
  199. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/routers/v1/sandbox_configs.py +0 -0
  200. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/routers/v1/sources.py +0 -0
  201. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/routers/v1/users.py +0 -0
  202. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/static_files.py +0 -0
  203. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/rest_api/utils.py +0 -0
  204. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/startup.sh +0 -0
  205. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/static_files/assets/index-048c9598.js +0 -0
  206. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/static_files/assets/index-0e31b727.css +0 -0
  207. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/static_files/favicon.ico +0 -0
  208. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/static_files/index.html +0 -0
  209. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/static_files/memgpt_logo_transparent.png +0 -0
  210. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/utils.py +0 -0
  211. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/ws_api/__init__.py +0 -0
  212. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/ws_api/example_client.py +0 -0
  213. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/ws_api/interface.py +0 -0
  214. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/ws_api/protocol.py +0 -0
  215. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/server/ws_api/server.py +0 -0
  216. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/services/__init__.py +0 -0
  217. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/services/block_manager.py +0 -0
  218. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/services/helpers/agent_manager_helper.py +0 -0
  219. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/services/job_manager.py +0 -0
  220. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/services/message_manager.py +0 -0
  221. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/services/organization_manager.py +0 -0
  222. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/services/passage_manager.py +0 -0
  223. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/services/per_agent_lock_manager.py +0 -0
  224. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/services/sandbox_config_manager.py +0 -0
  225. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/services/source_manager.py +0 -0
  226. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/services/tool_manager.py +0 -0
  227. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/services/tool_sandbox_env/.gitkeep +0 -0
  228. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/services/user_manager.py +0 -0
  229. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/streaming_interface.py +0 -0
  230. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/streaming_utils.py +0 -0
  231. {letta_nightly-0.6.4.dev20241217104233 → letta_nightly-0.6.5.dev20241218055539}/letta/system.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: letta-nightly
3
- Version: 0.6.4.dev20241217104233
3
+ Version: 0.6.5.dev20241218055539
4
4
  Summary: Create LLM agents with long-term memory and custom tools
5
5
  License: Apache License
6
6
  Author: Letta Team
@@ -1,4 +1,4 @@
1
- __version__ = "0.6.4"
1
+ __version__ = "0.6.5"
2
2
 
3
3
  # import clients
4
4
  from letta.client.client import LocalClient, RESTClient, create_client
@@ -18,6 +18,7 @@ from letta.constants import (
18
18
  MESSAGE_SUMMARY_WARNING_FRAC,
19
19
  O1_BASE_TOOLS,
20
20
  REQ_HEARTBEAT_MESSAGE,
21
+ STRUCTURED_OUTPUT_MODELS,
21
22
  )
22
23
  from letta.errors import LLMError
23
24
  from letta.helpers import ToolRulesSolver
@@ -63,6 +64,7 @@ from letta.system import (
63
64
  )
64
65
  from letta.utils import (
65
66
  count_tokens,
67
+ get_friendly_error_msg,
66
68
  get_local_time,
67
69
  get_tool_call_id,
68
70
  get_utc_time,
@@ -258,9 +260,6 @@ class Agent(BaseAgent):
258
260
 
259
261
  self.user = user
260
262
 
261
- # link tools
262
- self.link_tools(agent_state.tools)
263
-
264
263
  # initialize a tool rules solver
265
264
  if agent_state.tool_rules:
266
265
  # if there are tool rules, print out a warning
@@ -276,6 +275,7 @@ class Agent(BaseAgent):
276
275
 
277
276
  # gpt-4, gpt-3.5-turbo, ...
278
277
  self.model = self.agent_state.llm_config.model
278
+ self.check_tool_rules()
279
279
 
280
280
  # state managers
281
281
  self.block_manager = BlockManager()
@@ -295,8 +295,6 @@ class Agent(BaseAgent):
295
295
  self.agent_manager = AgentManager()
296
296
 
297
297
  # State needed for heartbeat pausing
298
- self.pause_heartbeats_start = None
299
- self.pause_heartbeats_minutes = 0
300
298
 
301
299
  self.first_message_verify_mono = first_message_verify_mono
302
300
 
@@ -381,6 +379,16 @@ class Agent(BaseAgent):
381
379
  # Create the agent in the DB
382
380
  self.update_state()
383
381
 
382
+ def check_tool_rules(self):
383
+ if self.model not in STRUCTURED_OUTPUT_MODELS:
384
+ if len(self.tool_rules_solver.init_tool_rules) > 1:
385
+ raise ValueError(
386
+ "Multiple initial tools are not supported for non-structured models. Please use only one initial tool rule."
387
+ )
388
+ self.supports_structured_output = False
389
+ else:
390
+ self.supports_structured_output = True
391
+
384
392
  def update_memory_if_change(self, new_memory: Memory) -> bool:
385
393
  """
386
394
  Update internal memory object and system prompt if there have been modifications.
@@ -415,11 +423,21 @@ class Agent(BaseAgent):
415
423
  return True
416
424
  return False
417
425
 
418
- def execute_tool_and_persist_state(self, function_name, function_to_call, function_args):
426
+ def execute_tool_and_persist_state(self, function_name: str, function_args: dict, target_letta_tool: Tool):
419
427
  """
420
428
  Execute tool modifications and persist the state of the agent.
421
429
  Note: only some agent state modifications will be persisted, such as data in the AgentState ORM and block data
422
430
  """
431
+ # TODO: Get rid of this. This whole piece is pretty shady, that we exec the function to just get the type hints for args.
432
+ env = {}
433
+ env.update(globals())
434
+ exec(target_letta_tool.source_code, env)
435
+ callable_func = env[target_letta_tool.json_schema["name"]]
436
+ spec = inspect.getfullargspec(callable_func).annotations
437
+ for name, arg in function_args.items():
438
+ if isinstance(function_args[name], dict):
439
+ function_args[name] = spec[name](**function_args[name])
440
+
423
441
  # TODO: add agent manager here
424
442
  orig_memory_str = self.agent_state.memory.compile()
425
443
 
@@ -432,11 +450,11 @@ class Agent(BaseAgent):
432
450
  if function_name in BASE_TOOLS or function_name in O1_BASE_TOOLS:
433
451
  # base tools are allowed to access the `Agent` object and run on the database
434
452
  function_args["self"] = self # need to attach self to arg since it's dynamically linked
435
- function_response = function_to_call(**function_args)
453
+ function_response = callable_func(**function_args)
436
454
  else:
437
455
  # execute tool in a sandbox
438
456
  # TODO: allow agent_state to specify which sandbox to execute tools in
439
- sandbox_run_result = ToolExecutionSandbox(function_name, function_args, self.agent_state.created_by_id).run(
457
+ sandbox_run_result = ToolExecutionSandbox(function_name, function_args, self.user).run(
440
458
  agent_state=self.agent_state.__deepcopy__()
441
459
  )
442
460
  function_response, updated_agent_state = sandbox_run_result.func_return, sandbox_run_result.agent_state
@@ -446,12 +464,9 @@ class Agent(BaseAgent):
446
464
  except Exception as e:
447
465
  # Need to catch error here, or else trunction wont happen
448
466
  # TODO: modify to function execution error
449
- from letta.constants import MAX_ERROR_MESSAGE_CHAR_LIMIT
450
-
451
- error_msg = f"Error executing tool {function_name}: {e}"
452
- if len(error_msg) > MAX_ERROR_MESSAGE_CHAR_LIMIT:
453
- error_msg = error_msg[:MAX_ERROR_MESSAGE_CHAR_LIMIT]
454
- raise ValueError(error_msg)
467
+ function_response = get_friendly_error_msg(
468
+ function_name=function_name, exception_name=type(e).__name__, exception_message=str(e)
469
+ )
455
470
 
456
471
  return function_response
457
472
 
@@ -464,27 +479,6 @@ class Agent(BaseAgent):
464
479
  def messages(self, value):
465
480
  raise Exception("Modifying message list directly not allowed")
466
481
 
467
- def link_tools(self, tools: List[Tool]):
468
- """Bind a tool object (schema + python function) to the agent object"""
469
-
470
- # Store the functions schemas (this is passed as an argument to ChatCompletion)
471
- self.functions = []
472
- self.functions_python = {}
473
- env = {}
474
- env.update(globals())
475
- for tool in tools:
476
- try:
477
- # WARNING: name may not be consistent?
478
- # if tool.module: # execute the whole module
479
- # exec(tool.module, env)
480
- # else:
481
- exec(tool.source_code, env)
482
- self.functions_python[tool.json_schema["name"]] = env[tool.json_schema["name"]]
483
- self.functions.append(tool.json_schema)
484
- except Exception:
485
- warnings.warn(f"WARNING: tool {tool.name} failed to link")
486
- assert all([callable(f) for k, f in self.functions_python.items()]), self.functions_python
487
-
488
482
  def _load_messages_from_recall(self, message_ids: List[str]) -> List[Message]:
489
483
  """Load a list of messages from recall storage"""
490
484
 
@@ -588,14 +582,32 @@ class Agent(BaseAgent):
588
582
  empty_response_retry_limit: int = 3,
589
583
  backoff_factor: float = 0.5, # delay multiplier for exponential backoff
590
584
  max_delay: float = 10.0, # max delay between retries
585
+ step_count: Optional[int] = None,
591
586
  ) -> ChatCompletionResponse:
592
587
  """Get response from LLM API with robust retry mechanism."""
593
588
 
594
589
  allowed_tool_names = self.tool_rules_solver.get_allowed_tool_names()
590
+ agent_state_tool_jsons = [t.json_schema for t in self.agent_state.tools]
591
+
595
592
  allowed_functions = (
596
- self.functions if not allowed_tool_names else [func for func in self.functions if func["name"] in allowed_tool_names]
593
+ agent_state_tool_jsons
594
+ if not allowed_tool_names
595
+ else [func for func in agent_state_tool_jsons if func["name"] in allowed_tool_names]
597
596
  )
598
597
 
598
+ # For the first message, force the initial tool if one is specified
599
+ force_tool_call = None
600
+ if (
601
+ step_count is not None
602
+ and step_count == 0
603
+ and not self.supports_structured_output
604
+ and len(self.tool_rules_solver.init_tool_rules) > 0
605
+ ):
606
+ force_tool_call = self.tool_rules_solver.init_tool_rules[0].tool_name
607
+ # Force a tool call if exactly one tool is specified
608
+ elif step_count is not None and step_count > 0 and len(allowed_tool_names) == 1:
609
+ force_tool_call = allowed_tool_names[0]
610
+
599
611
  for attempt in range(1, empty_response_retry_limit + 1):
600
612
  try:
601
613
  response = create(
@@ -603,9 +615,10 @@ class Agent(BaseAgent):
603
615
  messages=message_sequence,
604
616
  user_id=self.agent_state.created_by_id,
605
617
  functions=allowed_functions,
606
- functions_python=self.functions_python,
618
+ # functions_python=self.functions_python, do we need this?
607
619
  function_call=function_call,
608
620
  first_message=first_message,
621
+ force_tool_call=force_tool_call,
609
622
  stream=stream,
610
623
  stream_interface=self.interface,
611
624
  )
@@ -711,10 +724,13 @@ class Agent(BaseAgent):
711
724
  function_name = function_call.name
712
725
  printd(f"Request to call function {function_name} with tool_call_id: {tool_call_id}")
713
726
 
714
- # Failure case 1: function name is wrong
715
- try:
716
- function_to_call = self.functions_python[function_name]
717
- except KeyError:
727
+ # Failure case 1: function name is wrong (not in agent_state.tools)
728
+ target_letta_tool = None
729
+ for t in self.agent_state.tools:
730
+ if t.name == function_name:
731
+ target_letta_tool = t
732
+
733
+ if not target_letta_tool:
718
734
  error_msg = f"No function named {function_name}"
719
735
  function_response = package_function_response(False, error_msg)
720
736
  messages.append(
@@ -782,14 +798,8 @@ class Agent(BaseAgent):
782
798
  # this is because the function/tool role message is only created once the function/tool has executed/returned
783
799
  self.interface.function_message(f"Running {function_name}({function_args})", msg_obj=messages[-1])
784
800
  try:
785
- spec = inspect.getfullargspec(function_to_call).annotations
786
-
787
- for name, arg in function_args.items():
788
- if isinstance(function_args[name], dict):
789
- function_args[name] = spec[name](**function_args[name])
790
-
791
801
  # handle tool execution (sandbox) and state updates
792
- function_response = self.execute_tool_and_persist_state(function_name, function_to_call, function_args)
802
+ function_response = self.execute_tool_and_persist_state(function_name, function_args, target_letta_tool)
793
803
 
794
804
  # handle trunction
795
805
  if function_name in ["conversation_search", "conversation_search_date", "archival_memory_search"]:
@@ -801,8 +811,7 @@ class Agent(BaseAgent):
801
811
  truncate = True
802
812
 
803
813
  # get the function response limit
804
- tool_obj = [tool for tool in self.agent_state.tools if tool.name == function_name][0]
805
- return_char_limit = tool_obj.return_char_limit
814
+ return_char_limit = target_letta_tool.return_char_limit
806
815
  function_response_string = validate_function_response(
807
816
  function_response, return_char_limit=return_char_limit, truncate=truncate
808
817
  )
@@ -897,6 +906,7 @@ class Agent(BaseAgent):
897
906
  step_count = 0
898
907
  while True:
899
908
  kwargs["first_message"] = False
909
+ kwargs["step_count"] = step_count
900
910
  step_response = self.inner_step(
901
911
  messages=next_input_message,
902
912
  **kwargs,
@@ -972,6 +982,7 @@ class Agent(BaseAgent):
972
982
  first_message_retry_limit: int = FIRST_MESSAGE_ATTEMPTS,
973
983
  skip_verify: bool = False,
974
984
  stream: bool = False, # TODO move to config?
985
+ step_count: Optional[int] = None,
975
986
  ) -> AgentStepResponse:
976
987
  """Runs a single step in the agent loop (generates at most one LLM call)"""
977
988
 
@@ -1014,7 +1025,9 @@ class Agent(BaseAgent):
1014
1025
  else:
1015
1026
  response = self._get_ai_reply(
1016
1027
  message_sequence=input_message_sequence,
1028
+ first_message=first_message,
1017
1029
  stream=stream,
1030
+ step_count=step_count,
1018
1031
  )
1019
1032
 
1020
1033
  # Step 3: check if LLM wanted to call a function
@@ -1235,17 +1248,6 @@ class Agent(BaseAgent):
1235
1248
 
1236
1249
  printd(f"Ran summarizer, messages length {prior_len} -> {len(self.messages)}")
1237
1250
 
1238
- def heartbeat_is_paused(self):
1239
- """Check if there's a requested pause on timed heartbeats"""
1240
-
1241
- # Check if the pause has been initiated
1242
- if self.pause_heartbeats_start is None:
1243
- return False
1244
-
1245
- # Check if it's been more than pause_heartbeats_minutes since pause_heartbeats_start
1246
- elapsed_time = get_utc_time() - self.pause_heartbeats_start
1247
- return elapsed_time.total_seconds() < self.pause_heartbeats_minutes * 60
1248
-
1249
1251
  def _swap_system_message_in_buffer(self, new_system_message: str):
1250
1252
  """Update the system message (NOT prompt) of the Agent (requires updating the internal buffer)"""
1251
1253
  assert isinstance(new_system_message, str)
@@ -1370,7 +1372,7 @@ class Agent(BaseAgent):
1370
1372
  agent_manager: AgentManager,
1371
1373
  ):
1372
1374
  """Attach a source to the agent using the SourcesAgents ORM relationship.
1373
-
1375
+
1374
1376
  Args:
1375
1377
  user: User performing the action
1376
1378
  source_id: ID of the source to attach
@@ -1553,9 +1555,10 @@ class Agent(BaseAgent):
1553
1555
  num_tokens_external_memory_summary = count_tokens(external_memory_summary)
1554
1556
 
1555
1557
  # tokens taken up by function definitions
1556
- if self.functions:
1557
- available_functions_definitions = [ChatCompletionRequestTool(type="function", function=f) for f in self.functions]
1558
- num_tokens_available_functions_definitions = num_tokens_from_functions(functions=self.functions, model=self.model)
1558
+ agent_state_tool_jsons = [t.json_schema for t in self.agent_state.tools]
1559
+ if agent_state_tool_jsons:
1560
+ available_functions_definitions = [ChatCompletionRequestTool(type="function", function=f) for f in agent_state_tool_jsons]
1561
+ num_tokens_available_functions_definitions = num_tokens_from_functions(functions=agent_state_tool_jsons, model=self.model)
1559
1562
  else:
1560
1563
  available_functions_definitions = []
1561
1564
  num_tokens_available_functions_definitions = 0
@@ -2156,6 +2156,7 @@ class LocalClient(AbstractClient):
2156
2156
  "block_ids": [b.id for b in memory.get_blocks()] + block_ids,
2157
2157
  "tool_ids": tool_ids,
2158
2158
  "tool_rules": tool_rules,
2159
+ "include_base_tools": include_base_tools,
2159
2160
  "system": system,
2160
2161
  "agent_type": agent_type,
2161
2162
  "llm_config": llm_config if llm_config else self._default_llm_config,
@@ -23,6 +23,7 @@ MIN_CONTEXT_WINDOW = 4096
23
23
 
24
24
  # embeddings
25
25
  MAX_EMBEDDING_DIM = 4096 # maximum supported embeding size - do NOT change or else DBs will need to be reset
26
+ DEFAULT_EMBEDDING_CHUNK_SIZE = 300
26
27
 
27
28
  # tokenizers
28
29
  EMBEDDING_TO_TOKENIZER_MAP = {
@@ -37,7 +38,8 @@ DEFAULT_HUMAN = "basic"
37
38
  DEFAULT_PRESET = "memgpt_chat"
38
39
 
39
40
  # Base tools that cannot be edited, as they access agent state directly
40
- BASE_TOOLS = ["send_message", "conversation_search", "conversation_search_date", "archival_memory_insert", "archival_memory_search"]
41
+ # Note that we don't include "conversation_search_date" for now
42
+ BASE_TOOLS = ["send_message", "conversation_search", "archival_memory_insert", "archival_memory_search"]
41
43
  O1_BASE_TOOLS = ["send_thinking_message", "send_final_message"]
42
44
  # Base memory tools CAN be edited, and are added by default by the server
43
45
  BASE_MEMORY_TOOLS = ["core_memory_append", "core_memory_replace"]
@@ -48,6 +50,9 @@ BASE_MEMORY_TOOLS = ["core_memory_append", "core_memory_replace"]
48
50
  DEFAULT_MESSAGE_TOOL = "send_message"
49
51
  DEFAULT_MESSAGE_TOOL_KWARG = "message"
50
52
 
53
+ # Structured output models
54
+ STRUCTURED_OUTPUT_MODELS = {"gpt-4o", "gpt-4o-mini"}
55
+
51
56
  # LOGGER_LOG_LEVEL is use to convert Text to Logging level value for logging mostly for Cli input to setting level
52
57
  LOGGER_LOG_LEVELS = {"CRITICAL": CRITICAL, "ERROR": ERROR, "WARN": WARN, "WARNING": WARNING, "INFO": INFO, "DEBUG": DEBUG, "NOTSET": NOTSET}
53
58
 
@@ -234,16 +234,10 @@ def embedding_model(config: EmbeddingConfig, user_id: Optional[uuid.UUID] = None
234
234
  )
235
235
  elif endpoint_type == "ollama":
236
236
 
237
- from llama_index.embeddings.ollama import OllamaEmbedding
238
-
239
- ollama_additional_kwargs = {}
240
- callback_manager = None
241
-
242
- model = OllamaEmbedding(
243
- model_name=config.embedding_model,
237
+ model = OllamaEmbeddings(
238
+ model=config.embedding_model,
244
239
  base_url=config.embedding_endpoint,
245
- ollama_additional_kwargs=ollama_additional_kwargs or {},
246
- callback_manager=callback_manager or None,
240
+ ollama_additional_kwargs={},
247
241
  )
248
242
  return model
249
243
 
@@ -1,16 +1,6 @@
1
- from datetime import datetime
2
1
  from typing import Optional
3
2
 
4
3
  from letta.agent import Agent
5
- from letta.constants import MAX_PAUSE_HEARTBEATS
6
- from letta.services.agent_manager import AgentManager
7
-
8
- # import math
9
- # from letta.utils import json_dumps
10
-
11
- ### Functions / tools the agent can use
12
- # All functions should return a response string (or None)
13
- # If the function fails, throw an exception
14
4
 
15
5
 
16
6
  def send_message(self: "Agent", message: str) -> Optional[str]:
@@ -28,36 +18,6 @@ def send_message(self: "Agent", message: str) -> Optional[str]:
28
18
  return None
29
19
 
30
20
 
31
- # Construct the docstring dynamically (since it should use the external constants)
32
- pause_heartbeats_docstring = f"""
33
- Temporarily ignore timed heartbeats. You may still receive messages from manual heartbeats and other events.
34
-
35
- Args:
36
- minutes (int): Number of minutes to ignore heartbeats for. Max value of {MAX_PAUSE_HEARTBEATS} minutes ({MAX_PAUSE_HEARTBEATS // 60} hours).
37
-
38
- Returns:
39
- str: Function status response
40
- """
41
-
42
-
43
- def pause_heartbeats(self: "Agent", minutes: int) -> Optional[str]:
44
- import datetime
45
-
46
- from letta.constants import MAX_PAUSE_HEARTBEATS
47
-
48
- minutes = min(MAX_PAUSE_HEARTBEATS, minutes)
49
-
50
- # Record the current time
51
- self.pause_heartbeats_start = datetime.datetime.now(datetime.timezone.utc)
52
- # And record how long the pause should go for
53
- self.pause_heartbeats_minutes = int(minutes)
54
-
55
- return f"Pausing timed heartbeats for {minutes} min"
56
-
57
-
58
- pause_heartbeats.__doc__ = pause_heartbeats_docstring
59
-
60
-
61
21
  def conversation_search(self: "Agent", query: str, page: Optional[int] = 0) -> Optional[str]:
62
22
  """
63
23
  Search prior conversation history using case-insensitive string matching.
@@ -84,19 +44,19 @@ def conversation_search(self: "Agent", query: str, page: Optional[int] = 0) -> O
84
44
  count = RETRIEVAL_QUERY_DEFAULT_PAGE_SIZE
85
45
  # TODO: add paging by page number. currently cursor only works with strings.
86
46
  # original: start=page * count
87
- results = self.message_manager.list_user_messages_for_agent(
47
+ messages = self.message_manager.list_user_messages_for_agent(
88
48
  agent_id=self.agent_state.id,
89
49
  actor=self.user,
90
50
  query_text=query,
91
51
  limit=count,
92
52
  )
93
- total = len(results)
53
+ total = len(messages)
94
54
  num_pages = math.ceil(total / count) - 1 # 0 index
95
- if len(results) == 0:
55
+ if len(messages) == 0:
96
56
  results_str = f"No results found."
97
57
  else:
98
- results_pref = f"Showing {len(results)} of {total} results (page {page}/{num_pages}):"
99
- results_formatted = [f"timestamp: {d['timestamp']}, {d['message']['role']} - {d['message']['content']}" for d in results]
58
+ results_pref = f"Showing {len(messages)} of {total} results (page {page}/{num_pages}):"
59
+ results_formatted = [message.text for message in messages]
100
60
  results_str = f"{results_pref} {json_dumps(results_formatted)}"
101
61
  return results_str
102
62
 
@@ -114,6 +74,7 @@ def conversation_search_date(self: "Agent", start_date: str, end_date: str, page
114
74
  str: Query result string
115
75
  """
116
76
  import math
77
+ from datetime import datetime
117
78
 
118
79
  from letta.constants import RETRIEVAL_QUERY_DEFAULT_PAGE_SIZE
119
80
  from letta.utils import json_dumps
@@ -142,7 +103,6 @@ def conversation_search_date(self: "Agent", start_date: str, end_date: str, page
142
103
  start_date=start_datetime,
143
104
  end_date=end_datetime,
144
105
  limit=count,
145
- # start_date=start_date, end_date=end_date, limit=count, start=page * count
146
106
  )
147
107
  total = len(results)
148
108
  num_pages = math.ceil(total / count) - 1 # 0 index
@@ -186,10 +146,8 @@ def archival_memory_search(self: "Agent", query: str, page: Optional[int] = 0, s
186
146
  Returns:
187
147
  str: Query result string
188
148
  """
189
- import math
190
149
 
191
150
  from letta.constants import RETRIEVAL_QUERY_DEFAULT_PAGE_SIZE
192
- from letta.utils import json_dumps
193
151
 
194
152
  if page is None or (isinstance(page, str) and page.lower().strip() == "none"):
195
153
  page = 0
@@ -198,7 +156,7 @@ def archival_memory_search(self: "Agent", query: str, page: Optional[int] = 0, s
198
156
  except:
199
157
  raise ValueError(f"'page' argument must be an integer")
200
158
  count = RETRIEVAL_QUERY_DEFAULT_PAGE_SIZE
201
-
159
+
202
160
  try:
203
161
  # Get results using passage manager
204
162
  all_results = self.agent_manager.list_passages(
@@ -207,7 +165,7 @@ def archival_memory_search(self: "Agent", query: str, page: Optional[int] = 0, s
207
165
  query_text=query,
208
166
  limit=count + start, # Request enough results to handle offset
209
167
  embedding_config=self.agent_state.embedding_config,
210
- embed_query=True
168
+ embed_query=True,
211
169
  )
212
170
 
213
171
  # Apply pagination
@@ -215,13 +173,7 @@ def archival_memory_search(self: "Agent", query: str, page: Optional[int] = 0, s
215
173
  paged_results = all_results[start:end]
216
174
 
217
175
  # Format results to match previous implementation
218
- formatted_results = [
219
- {
220
- "timestamp": str(result.created_at),
221
- "content": result.text
222
- }
223
- for result in paged_results
224
- ]
176
+ formatted_results = [{"timestamp": str(result.created_at), "content": result.text} for result in paged_results]
225
177
 
226
178
  return formatted_results, len(formatted_results)
227
179
 
@@ -386,7 +386,7 @@ def generate_schema(function, name: Optional[str] = None, description: Optional[
386
386
  # append the heartbeat
387
387
  # TODO: don't hard-code
388
388
  # TODO: if terminal, don't include this
389
- if function.__name__ not in ["send_message", "pause_heartbeats"]:
389
+ if function.__name__ not in ["send_message"]:
390
390
  schema["parameters"]["properties"]["request_heartbeat"] = {
391
391
  "type": "boolean",
392
392
  "description": "Request an immediate heartbeat after function execution. Set to `True` if you want to send a follow-up message or run a follow-up function.",
@@ -99,16 +99,20 @@ def convert_tools_to_anthropic_format(tools: List[Tool]) -> List[dict]:
99
99
  - 1 level less of nesting
100
100
  - "parameters" -> "input_schema"
101
101
  """
102
- tools_dict_list = []
102
+ formatted_tools = []
103
103
  for tool in tools:
104
- tools_dict_list.append(
105
- {
106
- "name": tool.function.name,
107
- "description": tool.function.description,
108
- "input_schema": tool.function.parameters,
104
+ formatted_tool = {
105
+ "name" : tool.function.name,
106
+ "description" : tool.function.description,
107
+ "input_schema" : tool.function.parameters or {
108
+ "type": "object",
109
+ "properties": {},
110
+ "required": []
109
111
  }
110
- )
111
- return tools_dict_list
112
+ }
113
+ formatted_tools.append(formatted_tool)
114
+
115
+ return formatted_tools
112
116
 
113
117
 
114
118
  def merge_tool_results_into_user_messages(messages: List[dict]):
@@ -258,10 +262,24 @@ def convert_anthropic_response_to_chatcompletion(
258
262
  ),
259
263
  )
260
264
  ]
261
- else:
262
- # Just inner mono
263
- content = strip_xml_tags(string=response_json["content"][0]["text"], tag=inner_thoughts_xml_tag)
264
- tool_calls = None
265
+ elif len(response_json["content"]) == 1:
266
+ if response_json["content"][0]["type"] == "tool_use":
267
+ # function call only
268
+ content = None
269
+ tool_calls = [
270
+ ToolCall(
271
+ id=response_json["content"][0]["id"],
272
+ type="function",
273
+ function=FunctionCall(
274
+ name=response_json["content"][0]["name"],
275
+ arguments=json.dumps(response_json["content"][0]["input"], indent=2),
276
+ ),
277
+ )
278
+ ]
279
+ else:
280
+ # inner mono only
281
+ content = strip_xml_tags(string=response_json["content"][0]["text"], tag=inner_thoughts_xml_tag)
282
+ tool_calls = None
265
283
  else:
266
284
  raise RuntimeError("Unexpected type for content in response_json.")
267
285
 
@@ -323,6 +341,14 @@ def anthropic_chat_completions_request(
323
341
  if anthropic_tools is not None:
324
342
  data["tools"] = anthropic_tools
325
343
 
344
+ # TODO: Add support for other tool_choice options like "auto", "any"
345
+ if len(anthropic_tools) == 1:
346
+ data["tool_choice"] = {
347
+ "type": "tool", # Changed from "function" to "tool"
348
+ "name": anthropic_tools[0]["name"], # Directly specify name without nested "function" object
349
+ "disable_parallel_tool_use": True # Force single tool use
350
+ }
351
+
326
352
  # Move 'system' to the top level
327
353
  # 'messages: Unexpected role "system". The Messages API accepts a top-level `system` parameter, not "system" as an input message role.'
328
354
  assert data["messages"][0]["role"] == "system", f"Expected 'system' role in messages[0]:\n{data['messages'][0]}"
@@ -358,7 +384,6 @@ def anthropic_chat_completions_request(
358
384
  data.pop("top_p", None)
359
385
  data.pop("presence_penalty", None)
360
386
  data.pop("user", None)
361
- data.pop("tool_choice", None)
362
387
 
363
388
  response_json = make_post_request(url, headers, data)
364
389
  return convert_anthropic_response_to_chatcompletion(response_json=response_json, inner_thoughts_xml_tag=inner_thoughts_xml_tag)
@@ -113,6 +113,7 @@ def create(
113
113
  function_call: str = "auto",
114
114
  # hint
115
115
  first_message: bool = False,
116
+ force_tool_call: Optional[str] = None, # Force a specific tool to be called
116
117
  # use tool naming?
117
118
  # if false, will use deprecated 'functions' style
118
119
  use_tool_naming: bool = True,
@@ -252,6 +253,16 @@ def create(
252
253
  if not use_tool_naming:
253
254
  raise NotImplementedError("Only tool calling supported on Anthropic API requests")
254
255
 
256
+ tool_call = None
257
+ if force_tool_call is not None:
258
+ tool_call = {
259
+ "type": "function",
260
+ "function": {
261
+ "name": force_tool_call
262
+ }
263
+ }
264
+ assert functions is not None
265
+
255
266
  return anthropic_chat_completions_request(
256
267
  url=llm_config.model_endpoint,
257
268
  api_key=model_settings.anthropic_api_key,
@@ -259,7 +270,7 @@ def create(
259
270
  model=llm_config.model,
260
271
  messages=[cast_message_to_subtype(m.to_openai_dict()) for m in messages],
261
272
  tools=[{"type": "function", "function": f} for f in functions] if functions else None,
262
- # tool_choice=function_call,
273
+ tool_choice=tool_call,
263
274
  # user=str(user_id),
264
275
  # NOTE: max_tokens is required for Anthropic API
265
276
  max_tokens=1024, # TODO make dynamic
@@ -3,7 +3,7 @@ import json
3
3
 
4
4
  from letta.utils import json_dumps, json_loads
5
5
 
6
- NO_HEARTBEAT_FUNCS = ["send_message", "pause_heartbeats"]
6
+ NO_HEARTBEAT_FUNCS = ["send_message"]
7
7
 
8
8
 
9
9
  def insert_heartbeat(message):
@@ -12,3 +12,11 @@ class UniqueConstraintViolationError(ValueError):
12
12
 
13
13
  class ForeignKeyConstraintViolationError(ValueError):
14
14
  """Custom exception for foreign key constraint violations."""
15
+
16
+
17
+ class DatabaseTimeoutError(Exception):
18
+ """Custom exception for database timeout issues."""
19
+
20
+ def __init__(self, message="Database operation timed out", original_exception=None):
21
+ super().__init__(message)
22
+ self.original_exception = original_exception