letta-nightly 0.6.5.dev20241219104153__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.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/PKG-INFO +1 -1
  2. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/agent.py +20 -1
  3. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/client/streaming.py +9 -9
  4. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/errors.py +6 -6
  5. letta_nightly-0.6.5.dev20241220104040/letta/helpers/tool_rule_solver.py +146 -0
  6. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/custom_columns.py +5 -2
  7. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/providers.py +2 -1
  8. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/enums.py +1 -0
  9. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/letta_message.py +76 -40
  10. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/letta_response.py +9 -1
  11. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/message.py +13 -13
  12. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/tool_rule.py +12 -2
  13. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/interface.py +48 -48
  14. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/openai/chat_completions/chat_completions.py +2 -2
  15. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/v1/agents.py +0 -8
  16. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/v1/tools.py +2 -2
  17. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/server.py +9 -42
  18. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/services/message_manager.py +1 -0
  19. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/pyproject.toml +1 -1
  20. letta_nightly-0.6.5.dev20241219104153/letta/helpers/tool_rule_solver.py +0 -115
  21. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/LICENSE +0 -0
  22. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/README.md +0 -0
  23. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/__init__.py +0 -0
  24. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/__main__.py +0 -0
  25. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/benchmark/benchmark.py +0 -0
  26. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/benchmark/constants.py +0 -0
  27. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/chat_only_agent.py +0 -0
  28. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/cli/cli.py +0 -0
  29. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/cli/cli_config.py +0 -0
  30. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/cli/cli_load.py +0 -0
  31. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/client/__init__.py +0 -0
  32. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/client/client.py +0 -0
  33. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/client/utils.py +0 -0
  34. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/config.py +0 -0
  35. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/constants.py +0 -0
  36. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/credentials.py +0 -0
  37. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/data_sources/connectors.py +0 -0
  38. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/data_sources/connectors_helper.py +0 -0
  39. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/embeddings.py +0 -0
  40. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/functions/__init__.py +0 -0
  41. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/functions/function_sets/base.py +0 -0
  42. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/functions/function_sets/extras.py +0 -0
  43. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/functions/functions.py +0 -0
  44. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/functions/helpers.py +0 -0
  45. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/functions/schema_generator.py +0 -0
  46. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/helpers/__init__.py +0 -0
  47. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/humans/__init__.py +0 -0
  48. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/humans/examples/basic.txt +0 -0
  49. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/humans/examples/cs_phd.txt +0 -0
  50. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/interface.py +0 -0
  51. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/llm_api/__init__.py +0 -0
  52. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/llm_api/anthropic.py +0 -0
  53. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/llm_api/azure_openai.py +0 -0
  54. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/llm_api/azure_openai_constants.py +0 -0
  55. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/llm_api/cohere.py +0 -0
  56. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/llm_api/google_ai.py +0 -0
  57. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/llm_api/helpers.py +0 -0
  58. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/llm_api/llm_api_tools.py +0 -0
  59. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/llm_api/mistral.py +0 -0
  60. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/llm_api/openai.py +0 -0
  61. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/README.md +0 -0
  62. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/__init__.py +0 -0
  63. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/chat_completion_proxy.py +0 -0
  64. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/constants.py +0 -0
  65. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/function_parser.py +0 -0
  66. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/grammars/__init__.py +0 -0
  67. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/grammars/gbnf_grammar_generator.py +0 -0
  68. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/grammars/json.gbnf +0 -0
  69. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/grammars/json_func_calls_with_inner_thoughts.gbnf +0 -0
  70. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/json_parser.py +0 -0
  71. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/koboldcpp/api.py +0 -0
  72. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/koboldcpp/settings.py +0 -0
  73. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/llamacpp/api.py +0 -0
  74. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/llamacpp/settings.py +0 -0
  75. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/llm_chat_completion_wrappers/__init__.py +0 -0
  76. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/llm_chat_completion_wrappers/airoboros.py +0 -0
  77. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/llm_chat_completion_wrappers/chatml.py +0 -0
  78. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/llm_chat_completion_wrappers/configurable_wrapper.py +0 -0
  79. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/llm_chat_completion_wrappers/dolphin.py +0 -0
  80. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/llm_chat_completion_wrappers/llama3.py +0 -0
  81. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/llm_chat_completion_wrappers/simple_summary_wrapper.py +0 -0
  82. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/llm_chat_completion_wrappers/wrapper_base.py +0 -0
  83. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/llm_chat_completion_wrappers/zephyr.py +0 -0
  84. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/lmstudio/api.py +0 -0
  85. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/lmstudio/settings.py +0 -0
  86. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/ollama/api.py +0 -0
  87. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/ollama/settings.py +0 -0
  88. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/settings/__init__.py +0 -0
  89. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/settings/deterministic_mirostat.py +0 -0
  90. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/settings/settings.py +0 -0
  91. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/settings/simple.py +0 -0
  92. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/utils.py +0 -0
  93. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/vllm/api.py +0 -0
  94. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/webui/api.py +0 -0
  95. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/webui/legacy_api.py +0 -0
  96. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/webui/legacy_settings.py +0 -0
  97. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/local_llm/webui/settings.py +0 -0
  98. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/log.py +0 -0
  99. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/main.py +0 -0
  100. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/memory.py +0 -0
  101. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/o1_agent.py +0 -0
  102. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/offline_memory_agent.py +0 -0
  103. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/openai_backcompat/__init__.py +0 -0
  104. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/openai_backcompat/openai_object.py +0 -0
  105. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/__all__.py +0 -0
  106. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/__init__.py +0 -0
  107. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/agent.py +0 -0
  108. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/agents_tags.py +0 -0
  109. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/base.py +0 -0
  110. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/block.py +0 -0
  111. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/blocks_agents.py +0 -0
  112. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/enums.py +0 -0
  113. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/errors.py +0 -0
  114. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/file.py +0 -0
  115. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/job.py +0 -0
  116. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/message.py +0 -0
  117. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/mixins.py +0 -0
  118. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/organization.py +0 -0
  119. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/passage.py +0 -0
  120. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/sandbox_config.py +0 -0
  121. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/source.py +0 -0
  122. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/sources_agents.py +0 -0
  123. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/sqlalchemy_base.py +0 -0
  124. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/sqlite_functions.py +0 -0
  125. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/tool.py +0 -0
  126. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/tools_agents.py +0 -0
  127. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/orm/user.py +0 -0
  128. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/personas/__init__.py +0 -0
  129. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/personas/examples/anna_pa.txt +0 -0
  130. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/personas/examples/google_search_persona.txt +0 -0
  131. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/personas/examples/memgpt_doc.txt +0 -0
  132. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/personas/examples/memgpt_starter.txt +0 -0
  133. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/personas/examples/o1_persona.txt +0 -0
  134. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/personas/examples/offline_memory_persona.txt +0 -0
  135. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/personas/examples/sam.txt +0 -0
  136. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/personas/examples/sam_pov.txt +0 -0
  137. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/personas/examples/sam_simple_pov_gpt35.txt +0 -0
  138. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/personas/examples/sqldb/test.db +0 -0
  139. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/__init__.py +0 -0
  140. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/gpt_summarize.py +0 -0
  141. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/gpt_system.py +0 -0
  142. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/system/memgpt_base.txt +0 -0
  143. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/system/memgpt_chat.txt +0 -0
  144. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/system/memgpt_chat_compressed.txt +0 -0
  145. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/system/memgpt_chat_fstring.txt +0 -0
  146. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/system/memgpt_convo_only.txt +0 -0
  147. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/system/memgpt_doc.txt +0 -0
  148. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/system/memgpt_gpt35_extralong.txt +0 -0
  149. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/system/memgpt_intuitive_knowledge.txt +0 -0
  150. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/system/memgpt_modified_chat.txt +0 -0
  151. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/system/memgpt_modified_o1.txt +0 -0
  152. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/system/memgpt_offline_memory.txt +0 -0
  153. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/prompts/system/memgpt_offline_memory_chat.txt +0 -0
  154. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/pytest.ini +0 -0
  155. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/agent.py +0 -0
  156. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/block.py +0 -0
  157. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/embedding_config.py +0 -0
  158. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/file.py +0 -0
  159. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/health.py +0 -0
  160. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/job.py +0 -0
  161. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/letta_base.py +0 -0
  162. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/letta_request.py +0 -0
  163. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/llm_config.py +0 -0
  164. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/memory.py +0 -0
  165. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/openai/chat_completion_request.py +0 -0
  166. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/openai/chat_completion_response.py +0 -0
  167. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/openai/chat_completions.py +0 -0
  168. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/openai/embedding_response.py +0 -0
  169. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/openai/openai.py +0 -0
  170. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/organization.py +0 -0
  171. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/passage.py +0 -0
  172. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/sandbox_config.py +0 -0
  173. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/source.py +0 -0
  174. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/tool.py +0 -0
  175. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/usage.py +0 -0
  176. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/schemas/user.py +0 -0
  177. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/__init__.py +0 -0
  178. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/constants.py +0 -0
  179. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/generate_openapi_schema.sh +0 -0
  180. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/__init__.py +0 -0
  181. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/app.py +0 -0
  182. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/auth/__init__.py +0 -0
  183. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/auth/index.py +0 -0
  184. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/auth_token.py +0 -0
  185. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/__init__.py +0 -0
  186. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/openai/__init__.py +0 -0
  187. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/openai/assistants/__init__.py +0 -0
  188. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/openai/assistants/assistants.py +0 -0
  189. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/openai/assistants/schemas.py +0 -0
  190. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/openai/chat_completions/__init__.py +0 -0
  191. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/v1/__init__.py +0 -0
  192. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/v1/blocks.py +0 -0
  193. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/v1/health.py +0 -0
  194. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/v1/jobs.py +0 -0
  195. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/v1/llms.py +0 -0
  196. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/v1/organizations.py +0 -0
  197. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/v1/sandbox_configs.py +0 -0
  198. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/v1/sources.py +0 -0
  199. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/routers/v1/users.py +0 -0
  200. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/static_files.py +0 -0
  201. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/rest_api/utils.py +0 -0
  202. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/startup.sh +0 -0
  203. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/static_files/assets/index-048c9598.js +0 -0
  204. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/static_files/assets/index-0e31b727.css +0 -0
  205. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/static_files/favicon.ico +0 -0
  206. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/static_files/index.html +0 -0
  207. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/static_files/memgpt_logo_transparent.png +0 -0
  208. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/utils.py +0 -0
  209. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/ws_api/__init__.py +0 -0
  210. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/ws_api/example_client.py +0 -0
  211. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/ws_api/interface.py +0 -0
  212. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/ws_api/protocol.py +0 -0
  213. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/server/ws_api/server.py +0 -0
  214. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/services/__init__.py +0 -0
  215. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/services/agent_manager.py +0 -0
  216. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/services/block_manager.py +0 -0
  217. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/services/helpers/agent_manager_helper.py +0 -0
  218. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/services/job_manager.py +0 -0
  219. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/services/organization_manager.py +0 -0
  220. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/services/passage_manager.py +0 -0
  221. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/services/per_agent_lock_manager.py +0 -0
  222. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/services/sandbox_config_manager.py +0 -0
  223. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/services/source_manager.py +0 -0
  224. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/services/tool_execution_sandbox.py +0 -0
  225. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/services/tool_manager.py +0 -0
  226. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/services/tool_sandbox_env/.gitkeep +0 -0
  227. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/services/user_manager.py +0 -0
  228. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/settings.py +0 -0
  229. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/streaming_interface.py +0 -0
  230. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/streaming_utils.py +0 -0
  231. {letta_nightly-0.6.5.dev20241219104153 → letta_nightly-0.6.5.dev20241220104040}/letta/system.py +0 -0
  232. {letta_nightly-0.6.5.dev20241219104153 → 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.dev20241219104153
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
@@ -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
@@ -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:
@@ -131,16 +131,16 @@ class LettaMessageError(LettaError):
131
131
  return f"{error_msg}\n\n{message_json}"
132
132
 
133
133
 
134
- class MissingFunctionCallError(LettaMessageError):
135
- """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."""
136
136
 
137
- default_error_message = "The message is missing a function call."
137
+ default_error_message = "The message is missing a tool call."
138
138
 
139
139
 
140
- class InvalidFunctionCallError(LettaMessageError):
141
- """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."""
142
142
 
143
- 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."
144
144
 
145
145
 
146
146
  class MissingInnerMonologueError(LettaMessageError):
@@ -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
@@ -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
 
@@ -482,7 +482,8 @@ class GoogleAIProvider(Provider):
482
482
  model_options = [mo[len("models/") :] if mo.startswith("models/") else mo for mo in model_options]
483
483
 
484
484
  # TODO remove manual filtering for gemini-pro
485
- model_options = [mo for mo in model_options if str(mo).startswith("gemini") and "-pro" in str(mo)]
485
+ # Add support for all gemini models
486
+ model_options = [mo for mo in model_options if str(mo).startswith("gemini-")]
486
487
 
487
488
  configs = []
488
489
  for model in model_options:
@@ -45,5 +45,6 @@ class ToolRuleType(str, Enum):
45
45
  run_first = "InitToolRule"
46
46
  exit_loop = "TerminalToolRule" # reasoning loop should exit
47
47
  continue_loop = "continue_loop" # reasoning loop should continue
48
+ conditional = "conditional"
48
49
  constrain_child_tools = "ToolRule"
49
50
  require_parent_tools = "require_parent_tools"
@@ -9,7 +9,7 @@ from pydantic import BaseModel, Field, field_serializer, field_validator
9
9
 
10
10
  class LettaMessage(BaseModel):
11
11
  """
12
- Base class for simplified Letta message response type. This is intended to be used for developers who want the internal monologue, function calls, and function returns in a simplified format that does not include additional information other than the content and timestamp.
12
+ Base class for simplified Letta message response type. This is intended to be used for developers who want the internal monologue, tool calls, and tool returns in a simplified format that does not include additional information other than the content and timestamp.
13
13
 
14
14
  Attributes:
15
15
  id (str): The ID of the message
@@ -60,32 +60,32 @@ class UserMessage(LettaMessage):
60
60
  message: str
61
61
 
62
62
 
63
- class InternalMonologue(LettaMessage):
63
+ class ReasoningMessage(LettaMessage):
64
64
  """
65
- Representation of an agent's internal monologue.
65
+ Representation of an agent's internal reasoning.
66
66
 
67
67
  Attributes:
68
- internal_monologue (str): The internal monologue of the agent
68
+ reasoning (str): The internal reasoning of the agent
69
69
  id (str): The ID of the message
70
70
  date (datetime): The date the message was created in ISO format
71
71
  """
72
72
 
73
- message_type: Literal["internal_monologue"] = "internal_monologue"
74
- internal_monologue: str
73
+ message_type: Literal["reasoning_message"] = "reasoning_message"
74
+ reasoning: str
75
75
 
76
76
 
77
- class FunctionCall(BaseModel):
77
+ class ToolCall(BaseModel):
78
78
 
79
79
  name: str
80
80
  arguments: str
81
- function_call_id: str
81
+ tool_call_id: str
82
82
 
83
83
 
84
- class FunctionCallDelta(BaseModel):
84
+ class ToolCallDelta(BaseModel):
85
85
 
86
86
  name: Optional[str]
87
87
  arguments: Optional[str]
88
- function_call_id: Optional[str]
88
+ tool_call_id: Optional[str]
89
89
 
90
90
  # NOTE: this is a workaround to exclude None values from the JSON dump,
91
91
  # since the OpenAI style of returning chunks doesn't include keys with null values
@@ -97,50 +97,84 @@ class FunctionCallDelta(BaseModel):
97
97
  return json.dumps(self.model_dump(exclude_none=True), *args, **kwargs)
98
98
 
99
99
 
100
- class FunctionCallMessage(LettaMessage):
100
+ class ToolCallMessage(LettaMessage):
101
101
  """
102
- A message representing a request to call a function (generated by the LLM to trigger function execution).
102
+ A message representing a request to call a tool (generated by the LLM to trigger tool execution).
103
103
 
104
104
  Attributes:
105
- function_call (Union[FunctionCall, FunctionCallDelta]): The function call
105
+ tool_call (Union[ToolCall, ToolCallDelta]): The tool call
106
106
  id (str): The ID of the message
107
107
  date (datetime): The date the message was created in ISO format
108
108
  """
109
109
 
110
- message_type: Literal["function_call"] = "function_call"
111
- function_call: Union[FunctionCall, FunctionCallDelta]
110
+ message_type: Literal["tool_call_message"] = "tool_call_message"
111
+ tool_call: Union[ToolCall, ToolCallDelta]
112
112
 
113
- # NOTE: this is required for the FunctionCallDelta exclude_none to work correctly
113
+ # NOTE: this is required for the ToolCallDelta exclude_none to work correctly
114
114
  def model_dump(self, *args, **kwargs):
115
115
  kwargs["exclude_none"] = True
116
116
  data = super().model_dump(*args, **kwargs)
117
- if isinstance(data["function_call"], dict):
118
- data["function_call"] = {k: v for k, v in data["function_call"].items() if v is not None}
117
+ if isinstance(data["tool_call"], dict):
118
+ data["tool_call"] = {k: v for k, v in data["tool_call"].items() if v is not None}
119
119
  return data
120
120
 
121
121
  class Config:
122
122
  json_encoders = {
123
- FunctionCallDelta: lambda v: v.model_dump(exclude_none=True),
124
- FunctionCall: lambda v: v.model_dump(exclude_none=True),
123
+ ToolCallDelta: lambda v: v.model_dump(exclude_none=True),
124
+ ToolCall: lambda v: v.model_dump(exclude_none=True),
125
125
  }
126
126
 
127
- # NOTE: this is required to cast dicts into FunctionCallMessage objects
127
+ # NOTE: this is required to cast dicts into ToolCallMessage objects
128
128
  # Without this extra validator, Pydantic will throw an error if 'name' or 'arguments' are None
129
- # (instead of properly casting to FunctionCallDelta instead of FunctionCall)
130
- @field_validator("function_call", mode="before")
129
+ # (instead of properly casting to ToolCallDelta instead of ToolCall)
130
+ @field_validator("tool_call", mode="before")
131
131
  @classmethod
132
- def validate_function_call(cls, v):
132
+ def validate_tool_call(cls, v):
133
133
  if isinstance(v, dict):
134
- if "name" in v and "arguments" in v and "function_call_id" in v:
135
- return FunctionCall(name=v["name"], arguments=v["arguments"], function_call_id=v["function_call_id"])
136
- elif "name" in v or "arguments" in v or "function_call_id" in v:
137
- return FunctionCallDelta(name=v.get("name"), arguments=v.get("arguments"), function_call_id=v.get("function_call_id"))
134
+ if "name" in v and "arguments" in v and "tool_call_id" in v:
135
+ return ToolCall(name=v["name"], arguments=v["arguments"], tool_call_id=v["tool_call_id"])
136
+ elif "name" in v or "arguments" in v or "tool_call_id" in v:
137
+ return ToolCallDelta(name=v.get("name"), arguments=v.get("arguments"), tool_call_id=v.get("tool_call_id"))
138
138
  else:
139
- raise ValueError("function_call must contain either 'name' or 'arguments'")
139
+ raise ValueError("tool_call must contain either 'name' or 'arguments'")
140
140
  return v
141
141
 
142
142
 
143
- class FunctionReturn(LettaMessage):
143
+ class ToolReturnMessage(LettaMessage):
144
+ """
145
+ A message representing the return value of a tool call (generated by Letta executing the requested tool).
146
+
147
+ Attributes:
148
+ tool_return (str): The return value of the tool
149
+ status (Literal["success", "error"]): The status of the tool call
150
+ id (str): The ID of the message
151
+ date (datetime): The date the message was created in ISO format
152
+ tool_call_id (str): A unique identifier for the tool call that generated this message
153
+ stdout (Optional[List(str)]): Captured stdout (e.g. prints, logs) from the tool invocation
154
+ stderr (Optional[List(str)]): Captured stderr from the tool invocation
155
+ """
156
+
157
+ message_type: Literal["tool_return_message"] = "tool_return_message"
158
+ tool_return: str
159
+ status: Literal["success", "error"]
160
+ tool_call_id: str
161
+ stdout: Optional[List[str]] = None
162
+ stderr: Optional[List[str]] = None
163
+
164
+
165
+ # Legacy Letta API had an additional type "assistant_message" and the "function_call" was a formatted string
166
+
167
+
168
+ class AssistantMessage(LettaMessage):
169
+ message_type: Literal["assistant_message"] = "assistant_message"
170
+ assistant_message: str
171
+
172
+
173
+ class LegacyFunctionCallMessage(LettaMessage):
174
+ function_call: str
175
+
176
+
177
+ class LegacyFunctionReturn(LettaMessage):
144
178
  """
145
179
  A message representing the return value of a function call (generated by Letta executing the requested function).
146
180
 
@@ -162,22 +196,24 @@ class FunctionReturn(LettaMessage):
162
196
  stderr: Optional[List[str]] = None
163
197
 
164
198
 
165
- # Legacy Letta API had an additional type "assistant_message" and the "function_call" was a formatted string
166
-
167
-
168
- class AssistantMessage(LettaMessage):
169
- message_type: Literal["assistant_message"] = "assistant_message"
170
- assistant_message: str
199
+ class LegacyInternalMonologue(LettaMessage):
200
+ """
201
+ Representation of an agent's internal monologue.
171
202
 
203
+ Attributes:
204
+ internal_monologue (str): The internal monologue of the agent
205
+ id (str): The ID of the message
206
+ date (datetime): The date the message was created in ISO format
207
+ """
172
208
 
173
- class LegacyFunctionCallMessage(LettaMessage):
174
- function_call: str
209
+ message_type: Literal["internal_monologue"] = "internal_monologue"
210
+ internal_monologue: str
175
211
 
176
212
 
177
- LegacyLettaMessage = Union[InternalMonologue, AssistantMessage, LegacyFunctionCallMessage, FunctionReturn]
213
+ LegacyLettaMessage = Union[LegacyInternalMonologue, AssistantMessage, LegacyFunctionCallMessage, LegacyFunctionReturn]
178
214
 
179
215
 
180
216
  LettaMessageUnion = Annotated[
181
- Union[SystemMessage, UserMessage, InternalMonologue, FunctionCallMessage, FunctionReturn, AssistantMessage],
217
+ Union[SystemMessage, UserMessage, ReasoningMessage, ToolCallMessage, ToolReturnMessage, AssistantMessage],
182
218
  Field(discriminator="message_type"),
183
219
  ]
@@ -40,14 +40,22 @@ class LettaResponse(BaseModel):
40
40
  def get_formatted_content(msg):
41
41
  if msg.message_type == "internal_monologue":
42
42
  return f'<div class="content"><span class="internal-monologue">{html.escape(msg.internal_monologue)}</span></div>'
43
+ if msg.message_type == "reasoning_message":
44
+ return f'<div class="content"><span class="internal-monologue">{html.escape(msg.reasoning)}</span></div>'
43
45
  elif msg.message_type == "function_call":
44
46
  args = format_json(msg.function_call.arguments)
45
47
  return f'<div class="content"><span class="function-name">{html.escape(msg.function_call.name)}</span>({args})</div>'
48
+ elif msg.message_type == "tool_call_message":
49
+ args = format_json(msg.tool_call.arguments)
50
+ return f'<div class="content"><span class="function-name">{html.escape(msg.function_call.name)}</span>({args})</div>'
46
51
  elif msg.message_type == "function_return":
47
-
48
52
  return_value = format_json(msg.function_return)
49
53
  # return f'<div class="status-line">Status: {html.escape(msg.status)}</div><div class="content">{return_value}</div>'
50
54
  return f'<div class="content">{return_value}</div>'
55
+ elif msg.message_type == "tool_return_message":
56
+ return_value = format_json(msg.tool_return)
57
+ # return f'<div class="status-line">Status: {html.escape(msg.status)}</div><div class="content">{return_value}</div>'
58
+ return f'<div class="content">{return_value}</div>'
51
59
  elif msg.message_type == "user_message":
52
60
  if is_json(msg.message):
53
61
  return f'<div class="content">{format_json(msg.message)}</div>'
@@ -16,10 +16,10 @@ from letta.schemas.enums import MessageRole
16
16
  from letta.schemas.letta_base import OrmMetadataBase
17
17
  from letta.schemas.letta_message import (
18
18
  AssistantMessage,
19
- FunctionCall,
20
- FunctionCallMessage,
21
- FunctionReturn,
22
- InternalMonologue,
19
+ ToolCall as LettaToolCall,
20
+ ToolCallMessage,
21
+ ToolReturnMessage,
22
+ ReasoningMessage,
23
23
  LettaMessage,
24
24
  SystemMessage,
25
25
  UserMessage,
@@ -145,10 +145,10 @@ class Message(BaseMessage):
145
145
  if self.text is not None:
146
146
  # This is type InnerThoughts
147
147
  messages.append(
148
- InternalMonologue(
148
+ ReasoningMessage(
149
149
  id=self.id,
150
150
  date=self.created_at,
151
- internal_monologue=self.text,
151
+ reasoning=self.text,
152
152
  )
153
153
  )
154
154
  if self.tool_calls is not None:
@@ -172,18 +172,18 @@ class Message(BaseMessage):
172
172
  )
173
173
  else:
174
174
  messages.append(
175
- FunctionCallMessage(
175
+ ToolCallMessage(
176
176
  id=self.id,
177
177
  date=self.created_at,
178
- function_call=FunctionCall(
178
+ tool_call=LettaToolCall(
179
179
  name=tool_call.function.name,
180
180
  arguments=tool_call.function.arguments,
181
- function_call_id=tool_call.id,
181
+ tool_call_id=tool_call.id,
182
182
  ),
183
183
  )
184
184
  )
185
185
  elif self.role == MessageRole.tool:
186
- # This is type FunctionReturn
186
+ # This is type ToolReturnMessage
187
187
  # Try to interpret the function return, recall that this is how we packaged:
188
188
  # def package_function_response(was_success, response_string, timestamp=None):
189
189
  # formatted_time = get_local_time() if timestamp is None else timestamp
@@ -208,12 +208,12 @@ class Message(BaseMessage):
208
208
  messages.append(
209
209
  # TODO make sure this is what the API returns
210
210
  # function_return may not match exactly...
211
- FunctionReturn(
211
+ ToolReturnMessage(
212
212
  id=self.id,
213
213
  date=self.created_at,
214
- function_return=self.text,
214
+ tool_return=self.text,
215
215
  status=status_enum,
216
- function_call_id=self.tool_call_id,
216
+ tool_call_id=self.tool_call_id,
217
217
  )
218
218
  )
219
219
  elif self.role == MessageRole.user:
@@ -1,4 +1,4 @@
1
- from typing import List, Union
1
+ from typing import Any, Dict, List, Optional, Union
2
2
 
3
3
  from pydantic import Field
4
4
 
@@ -21,6 +21,16 @@ class ChildToolRule(BaseToolRule):
21
21
  children: List[str] = Field(..., description="The children tools that can be invoked.")
22
22
 
23
23
 
24
+ class ConditionalToolRule(BaseToolRule):
25
+ """
26
+ A ToolRule that conditionally maps to different child tools based on the output.
27
+ """
28
+ type: ToolRuleType = ToolRuleType.conditional
29
+ default_child: Optional[str] = Field(None, description="The default child tool to be called. If None, any tool can be called.")
30
+ child_output_mapping: Dict[Any, str] = Field(..., description="The output case to check for mapping")
31
+ require_output_mapping: bool = Field(default=False, description="Whether to throw an error when output doesn't match any case")
32
+
33
+
24
34
  class InitToolRule(BaseToolRule):
25
35
  """
26
36
  Represents the initial tool rule configuration.
@@ -37,4 +47,4 @@ class TerminalToolRule(BaseToolRule):
37
47
  type: ToolRuleType = ToolRuleType.exit_loop
38
48
 
39
49
 
40
- ToolRule = Union[ChildToolRule, InitToolRule, TerminalToolRule]
50
+ ToolRule = Union[ChildToolRule, InitToolRule, TerminalToolRule, ConditionalToolRule]