letta-nightly 0.6.7.dev20250108225500__tar.gz → 0.6.8.dev20250109011239__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 (236) hide show
  1. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/PKG-INFO +2 -2
  2. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/__init__.py +2 -2
  3. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/agent.py +2 -0
  4. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/client/client.py +3 -2
  5. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/constants.py +2 -0
  6. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/functions/helpers.py +11 -4
  7. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/functions/schema_generator.py +0 -1
  8. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/llm_api/llm_api_tools.py +5 -1
  9. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/orm/__init__.py +2 -1
  10. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/orm/organization.py +2 -0
  11. letta_nightly-0.6.8.dev20250109011239/letta/orm/provider.py +23 -0
  12. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/providers.py +21 -2
  13. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/agent.py +9 -1
  14. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/letta_request.py +4 -0
  15. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/routers/v1/agents.py +6 -2
  16. letta_nightly-0.6.8.dev20250109011239/letta/server/rest_api/routers/v1/providers.py +72 -0
  17. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/server.py +11 -2
  18. letta_nightly-0.6.8.dev20250109011239/letta/server/static_files/assets/index-0e31b727.css +1 -0
  19. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/static_files/index.html +2 -2
  20. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/services/agent_manager.py +24 -5
  21. letta_nightly-0.6.8.dev20250109011239/letta/services/provider_manager.py +63 -0
  22. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/services/tool_execution_sandbox.py +12 -5
  23. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/pyproject.toml +3 -3
  24. letta_nightly-0.6.7.dev20250108225500/letta/server/static_files/assets/index-0e31b727.css +0 -1
  25. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/LICENSE +0 -0
  26. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/README.md +0 -0
  27. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/__main__.py +0 -0
  28. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/benchmark/benchmark.py +0 -0
  29. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/benchmark/constants.py +0 -0
  30. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/chat_only_agent.py +0 -0
  31. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/cli/cli.py +0 -0
  32. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/cli/cli_config.py +0 -0
  33. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/cli/cli_load.py +0 -0
  34. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/client/__init__.py +0 -0
  35. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/client/streaming.py +0 -0
  36. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/client/utils.py +0 -0
  37. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/config.py +0 -0
  38. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/credentials.py +0 -0
  39. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/data_sources/connectors.py +0 -0
  40. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/data_sources/connectors_helper.py +0 -0
  41. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/embeddings.py +0 -0
  42. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/errors.py +0 -0
  43. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/functions/__init__.py +0 -0
  44. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/functions/function_sets/base.py +0 -0
  45. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/functions/function_sets/extras.py +0 -0
  46. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/functions/functions.py +0 -0
  47. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/helpers/__init__.py +0 -0
  48. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/helpers/tool_rule_solver.py +0 -0
  49. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/humans/__init__.py +0 -0
  50. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/humans/examples/basic.txt +0 -0
  51. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/humans/examples/cs_phd.txt +0 -0
  52. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/interface.py +0 -0
  53. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/llm_api/__init__.py +0 -0
  54. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/llm_api/anthropic.py +0 -0
  55. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/llm_api/azure_openai.py +0 -0
  56. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/llm_api/azure_openai_constants.py +0 -0
  57. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/llm_api/cohere.py +0 -0
  58. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/llm_api/google_ai.py +0 -0
  59. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/llm_api/helpers.py +0 -0
  60. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/llm_api/mistral.py +0 -0
  61. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/llm_api/openai.py +0 -0
  62. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/README.md +0 -0
  63. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/__init__.py +0 -0
  64. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/chat_completion_proxy.py +0 -0
  65. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/constants.py +0 -0
  66. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/function_parser.py +0 -0
  67. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/grammars/__init__.py +0 -0
  68. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/grammars/gbnf_grammar_generator.py +0 -0
  69. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/grammars/json.gbnf +0 -0
  70. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/grammars/json_func_calls_with_inner_thoughts.gbnf +0 -0
  71. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/json_parser.py +0 -0
  72. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/koboldcpp/api.py +0 -0
  73. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/koboldcpp/settings.py +0 -0
  74. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/llamacpp/api.py +0 -0
  75. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/llamacpp/settings.py +0 -0
  76. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/llm_chat_completion_wrappers/__init__.py +0 -0
  77. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/llm_chat_completion_wrappers/airoboros.py +0 -0
  78. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/llm_chat_completion_wrappers/chatml.py +0 -0
  79. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/llm_chat_completion_wrappers/configurable_wrapper.py +0 -0
  80. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/llm_chat_completion_wrappers/dolphin.py +0 -0
  81. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/llm_chat_completion_wrappers/llama3.py +0 -0
  82. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/llm_chat_completion_wrappers/simple_summary_wrapper.py +0 -0
  83. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/llm_chat_completion_wrappers/wrapper_base.py +0 -0
  84. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/llm_chat_completion_wrappers/zephyr.py +0 -0
  85. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/lmstudio/api.py +0 -0
  86. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/lmstudio/settings.py +0 -0
  87. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/ollama/api.py +0 -0
  88. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/ollama/settings.py +0 -0
  89. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/settings/__init__.py +0 -0
  90. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/settings/deterministic_mirostat.py +0 -0
  91. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/settings/settings.py +0 -0
  92. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/settings/simple.py +0 -0
  93. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/utils.py +0 -0
  94. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/vllm/api.py +0 -0
  95. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/webui/api.py +0 -0
  96. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/webui/legacy_api.py +0 -0
  97. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/webui/legacy_settings.py +0 -0
  98. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/local_llm/webui/settings.py +0 -0
  99. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/log.py +0 -0
  100. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/main.py +0 -0
  101. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/memory.py +0 -0
  102. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/o1_agent.py +0 -0
  103. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/offline_memory_agent.py +0 -0
  104. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/openai_backcompat/__init__.py +0 -0
  105. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/openai_backcompat/openai_object.py +0 -0
  106. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/orm/__all__.py +0 -0
  107. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/orm/agent.py +0 -0
  108. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/orm/agents_tags.py +0 -0
  109. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/orm/base.py +0 -0
  110. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/orm/block.py +0 -0
  111. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/orm/blocks_agents.py +0 -0
  112. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/orm/custom_columns.py +0 -0
  113. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/orm/enums.py +0 -0
  114. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/orm/errors.py +0 -0
  115. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/orm/file.py +0 -0
  116. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/orm/job.py +0 -0
  117. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/orm/message.py +0 -0
  118. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/orm/mixins.py +0 -0
  119. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/orm/passage.py +0 -0
  120. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/orm/sandbox_config.py +0 -0
  121. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/orm/source.py +0 -0
  122. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/orm/sources_agents.py +0 -0
  123. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/orm/sqlalchemy_base.py +0 -0
  124. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/orm/sqlite_functions.py +0 -0
  125. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/orm/tool.py +0 -0
  126. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/orm/tools_agents.py +0 -0
  127. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/orm/user.py +0 -0
  128. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/personas/__init__.py +0 -0
  129. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/personas/examples/anna_pa.txt +0 -0
  130. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/personas/examples/google_search_persona.txt +0 -0
  131. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/personas/examples/memgpt_doc.txt +0 -0
  132. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/personas/examples/memgpt_starter.txt +0 -0
  133. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/personas/examples/o1_persona.txt +0 -0
  134. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/personas/examples/offline_memory_persona.txt +0 -0
  135. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/personas/examples/sam.txt +0 -0
  136. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/personas/examples/sam_pov.txt +0 -0
  137. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/personas/examples/sam_simple_pov_gpt35.txt +0 -0
  138. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/personas/examples/sqldb/test.db +0 -0
  139. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/prompts/__init__.py +0 -0
  140. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/prompts/gpt_summarize.py +0 -0
  141. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/prompts/gpt_system.py +0 -0
  142. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/prompts/system/memgpt_base.txt +0 -0
  143. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/prompts/system/memgpt_chat.txt +0 -0
  144. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/prompts/system/memgpt_chat_compressed.txt +0 -0
  145. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/prompts/system/memgpt_chat_fstring.txt +0 -0
  146. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/prompts/system/memgpt_convo_only.txt +0 -0
  147. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/prompts/system/memgpt_doc.txt +0 -0
  148. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/prompts/system/memgpt_gpt35_extralong.txt +0 -0
  149. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/prompts/system/memgpt_intuitive_knowledge.txt +0 -0
  150. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/prompts/system/memgpt_modified_chat.txt +0 -0
  151. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/prompts/system/memgpt_modified_o1.txt +0 -0
  152. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/prompts/system/memgpt_offline_memory.txt +0 -0
  153. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/prompts/system/memgpt_offline_memory_chat.txt +0 -0
  154. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/pytest.ini +0 -0
  155. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/block.py +0 -0
  156. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/embedding_config.py +0 -0
  157. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/enums.py +0 -0
  158. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/environment_variables.py +0 -0
  159. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/file.py +0 -0
  160. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/health.py +0 -0
  161. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/job.py +0 -0
  162. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/letta_base.py +0 -0
  163. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/letta_message.py +0 -0
  164. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/letta_response.py +0 -0
  165. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/llm_config.py +0 -0
  166. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/memory.py +0 -0
  167. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/message.py +0 -0
  168. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/openai/chat_completion_request.py +0 -0
  169. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/openai/chat_completion_response.py +0 -0
  170. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/openai/chat_completions.py +0 -0
  171. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/openai/embedding_response.py +0 -0
  172. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/openai/openai.py +0 -0
  173. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/organization.py +0 -0
  174. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/passage.py +0 -0
  175. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/sandbox_config.py +0 -0
  176. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/source.py +0 -0
  177. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/tool.py +0 -0
  178. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/tool_rule.py +0 -0
  179. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/usage.py +0 -0
  180. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/schemas/user.py +0 -0
  181. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/__init__.py +0 -0
  182. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/constants.py +0 -0
  183. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/generate_openapi_schema.sh +0 -0
  184. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/__init__.py +0 -0
  185. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/app.py +0 -0
  186. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/auth/__init__.py +0 -0
  187. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/auth/index.py +0 -0
  188. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/auth_token.py +0 -0
  189. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/interface.py +0 -0
  190. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/routers/__init__.py +0 -0
  191. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/routers/openai/__init__.py +0 -0
  192. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/routers/openai/assistants/__init__.py +0 -0
  193. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/routers/openai/assistants/assistants.py +0 -0
  194. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/routers/openai/assistants/schemas.py +0 -0
  195. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/routers/openai/chat_completions/__init__.py +0 -0
  196. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/routers/openai/chat_completions/chat_completions.py +0 -0
  197. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/routers/v1/__init__.py +0 -0
  198. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/routers/v1/blocks.py +0 -0
  199. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/routers/v1/health.py +0 -0
  200. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/routers/v1/jobs.py +0 -0
  201. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/routers/v1/llms.py +0 -0
  202. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/routers/v1/organizations.py +0 -0
  203. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/routers/v1/sandbox_configs.py +0 -0
  204. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/routers/v1/sources.py +0 -0
  205. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/routers/v1/tools.py +0 -0
  206. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/routers/v1/users.py +0 -0
  207. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/static_files.py +0 -0
  208. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/rest_api/utils.py +0 -0
  209. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/startup.sh +0 -0
  210. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/static_files/assets/index-048c9598.js +0 -0
  211. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/static_files/favicon.ico +0 -0
  212. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/static_files/memgpt_logo_transparent.png +0 -0
  213. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/utils.py +0 -0
  214. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/ws_api/__init__.py +0 -0
  215. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/ws_api/example_client.py +0 -0
  216. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/ws_api/interface.py +0 -0
  217. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/ws_api/protocol.py +0 -0
  218. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/server/ws_api/server.py +0 -0
  219. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/services/__init__.py +0 -0
  220. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/services/block_manager.py +0 -0
  221. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/services/helpers/agent_manager_helper.py +0 -0
  222. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/services/job_manager.py +0 -0
  223. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/services/message_manager.py +0 -0
  224. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/services/organization_manager.py +0 -0
  225. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/services/passage_manager.py +0 -0
  226. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/services/per_agent_lock_manager.py +0 -0
  227. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/services/sandbox_config_manager.py +0 -0
  228. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/services/source_manager.py +0 -0
  229. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/services/tool_manager.py +0 -0
  230. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/services/tool_sandbox_env/.gitkeep +0 -0
  231. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/services/user_manager.py +0 -0
  232. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/settings.py +0 -0
  233. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/streaming_interface.py +0 -0
  234. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/streaming_utils.py +0 -0
  235. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/system.py +0 -0
  236. {letta_nightly-0.6.7.dev20250108225500 → letta_nightly-0.6.8.dev20250109011239}/letta/utils.py +0 -0
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: letta-nightly
3
- Version: 0.6.7.dev20250108225500
3
+ Version: 0.6.8.dev20250109011239
4
4
  Summary: Create LLM agents with long-term memory and custom tools
5
5
  License: Apache License
6
6
  Author: Letta Team
7
7
  Author-email: contact@letta.com
8
- Requires-Python: >=3.10,<4.0
8
+ Requires-Python: >=3.10,<3.14
9
9
  Classifier: License :: Other/Proprietary License
10
10
  Classifier: Programming Language :: Python :: 3
11
11
  Classifier: Programming Language :: Python :: 3.10
@@ -1,9 +1,9 @@
1
- __version__ = "0.6.7"
1
+ __version__ = "0.6.8"
2
2
 
3
3
  # import clients
4
4
  from letta.client.client import LocalClient, RESTClient, create_client
5
5
 
6
- # imports for easier access
6
+ # # imports for easier access
7
7
  from letta.schemas.agent import AgentState
8
8
  from letta.schemas.block import Block
9
9
  from letta.schemas.embedding_config import EmbeddingConfig
@@ -1075,6 +1075,8 @@ def save_agent(agent: Agent):
1075
1075
  message_ids=agent_state.message_ids,
1076
1076
  description=agent_state.description,
1077
1077
  metadata_=agent_state.metadata_,
1078
+ # TODO: Add this back in later
1079
+ # tool_exec_environment_variables=agent_state.get_agent_env_vars_as_dict(),
1078
1080
  )
1079
1081
  agent_manager.update_agent(agent_id=agent_state.id, agent_update=update_agent, actor=agent.user)
1080
1082
 
@@ -35,7 +35,6 @@ from letta.schemas.source import Source, SourceCreate, SourceUpdate
35
35
  from letta.schemas.tool import Tool, ToolCreate, ToolUpdate
36
36
  from letta.schemas.tool_rule import BaseToolRule
37
37
  from letta.server.rest_api.interface import QueuingInterface
38
- from letta.server.server import SyncServer
39
38
  from letta.utils import get_human_text, get_persona_text
40
39
 
41
40
 
@@ -1033,7 +1032,7 @@ class RESTClient(AbstractClient):
1033
1032
  ) -> Block: #
1034
1033
  request_kwargs = dict(label=label, value=value, template=is_template, template_name=template_name)
1035
1034
  if limit:
1036
- request_kwargs['limit'] = limit
1035
+ request_kwargs["limit"] = limit
1037
1036
  request = CreateBlock(**request_kwargs)
1038
1037
  response = requests.post(f"{self.base_url}/{self.api_prefix}/blocks", json=request.model_dump(), headers=self.headers)
1039
1038
  if response.status_code != 200:
@@ -2011,6 +2010,8 @@ class LocalClient(AbstractClient):
2011
2010
  debug (bool): Whether to print debug information.
2012
2011
  """
2013
2012
 
2013
+ from letta.server.server import SyncServer
2014
+
2014
2015
  # set logging levels
2015
2016
  letta.utils.DEBUG = debug
2016
2017
  logging.getLogger().setLevel(logging.CRITICAL)
@@ -7,6 +7,8 @@ ADMIN_PREFIX = "/v1/admin"
7
7
  API_PREFIX = "/v1"
8
8
  OPENAI_API_PREFIX = "/openai"
9
9
 
10
+ COMPOSIO_ENTITY_ENV_VAR_KEY = "COMPOSIO_ENTITY"
11
+
10
12
  # String in the error message for when the context window is too large
11
13
  # Example full message:
12
14
  # This model's maximum context length is 8192 tokens. However, your messages resulted in 8198 tokens (7450 in the messages, 748 in the functions). Please reduce the length of the messages or functions.
@@ -1,8 +1,11 @@
1
1
  from typing import Any, Optional, Union
2
2
 
3
3
  import humps
4
+ from composio.constants import DEFAULT_ENTITY_ID
4
5
  from pydantic import BaseModel
5
6
 
7
+ from letta.constants import COMPOSIO_ENTITY_ENV_VAR_KEY
8
+
6
9
 
7
10
  def generate_composio_tool_wrapper(action_name: str) -> tuple[str, str]:
8
11
  # Instantiate the object
@@ -13,12 +16,16 @@ def generate_composio_tool_wrapper(action_name: str) -> tuple[str, str]:
13
16
 
14
17
  wrapper_function_str = f"""
15
18
  def {func_name}(**kwargs):
16
- from composio import Action, App, Tag
17
19
  from composio_langchain import ComposioToolSet
20
+ import os
21
+
22
+ entity_id = os.getenv('{COMPOSIO_ENTITY_ENV_VAR_KEY}', '{DEFAULT_ENTITY_ID}')
23
+ composio_toolset = ComposioToolSet(entity_id=entity_id)
24
+ response = composio_toolset.execute_action(action='{action_name}', params=kwargs)
18
25
 
19
- composio_toolset = ComposioToolSet()
20
- tool = {tool_instantiation_str}
21
- return tool.func(**kwargs)['data']
26
+ if response["error"]:
27
+ raise RuntimeError(response["error"])
28
+ return response["data"]
22
29
  """
23
30
 
24
31
  # Compile safety check
@@ -3,7 +3,6 @@ from typing import Any, Dict, List, Optional, Type, Union, get_args, get_origin
3
3
 
4
4
  from docstring_parser import parse
5
5
  from pydantic import BaseModel
6
- from pydantic.v1 import BaseModel as V1BaseModel
7
6
 
8
7
 
9
8
  def is_optional(annotation):
@@ -22,6 +22,7 @@ from letta.schemas.llm_config import LLMConfig
22
22
  from letta.schemas.message import Message
23
23
  from letta.schemas.openai.chat_completion_request import ChatCompletionRequest, Tool, cast_message_to_subtype
24
24
  from letta.schemas.openai.chat_completion_response import ChatCompletionResponse
25
+ from letta.services.provider_manager import ProviderManager
25
26
  from letta.settings import ModelSettings
26
27
  from letta.streaming_interface import AgentChunkStreamingInterface, AgentRefreshStreamingInterface
27
28
 
@@ -251,9 +252,12 @@ def create(
251
252
  tool_call = {"type": "function", "function": {"name": force_tool_call}}
252
253
  assert functions is not None
253
254
 
255
+ # load anthropic key from db in case a custom key has been stored
256
+ anthropic_key_override = ProviderManager().get_anthropic_key_override()
257
+
254
258
  return anthropic_chat_completions_request(
255
259
  url=llm_config.model_endpoint,
256
- api_key=model_settings.anthropic_api_key,
260
+ api_key=anthropic_key_override if anthropic_key_override else model_settings.anthropic_api_key,
257
261
  data=ChatCompletionRequest(
258
262
  model=llm_config.model,
259
263
  messages=[cast_message_to_subtype(m.to_openai_dict()) for m in messages],
@@ -8,7 +8,8 @@ from letta.orm.job import Job
8
8
  from letta.orm.message import Message
9
9
  from letta.orm.organization import Organization
10
10
  from letta.orm.passage import AgentPassage, BasePassage, SourcePassage
11
- from letta.orm.sandbox_config import SandboxConfig, SandboxEnvironmentVariable
11
+ from letta.orm.provider import Provider
12
+ from letta.orm.sandbox_config import AgentEnvironmentVariable, SandboxConfig, SandboxEnvironmentVariable
12
13
  from letta.orm.source import Source
13
14
  from letta.orm.sources_agents import SourcesAgents
14
15
  from letta.orm.tool import Tool
@@ -9,6 +9,7 @@ if TYPE_CHECKING:
9
9
 
10
10
  from letta.orm.agent import Agent
11
11
  from letta.orm.file import FileMetadata
12
+ from letta.orm.provider import Provider
12
13
  from letta.orm.sandbox_config import AgentEnvironmentVariable
13
14
  from letta.orm.tool import Tool
14
15
  from letta.orm.user import User
@@ -45,6 +46,7 @@ class Organization(SqlalchemyBase):
45
46
  "SourcePassage", back_populates="organization", cascade="all, delete-orphan"
46
47
  )
47
48
  agent_passages: Mapped[List["AgentPassage"]] = relationship("AgentPassage", back_populates="organization", cascade="all, delete-orphan")
49
+ providers: Mapped[List["Provider"]] = relationship("Provider", back_populates="organization", cascade="all, delete-orphan")
48
50
 
49
51
  @property
50
52
  def passages(self) -> List[Union["SourcePassage", "AgentPassage"]]:
@@ -0,0 +1,23 @@
1
+ from typing import TYPE_CHECKING
2
+
3
+ from sqlalchemy.orm import Mapped, mapped_column, relationship
4
+
5
+ from letta.orm.mixins import OrganizationMixin
6
+ from letta.orm.sqlalchemy_base import SqlalchemyBase
7
+ from letta.providers import Provider as PydanticProvider
8
+
9
+ if TYPE_CHECKING:
10
+ from letta.orm.organization import Organization
11
+
12
+
13
+ class Provider(SqlalchemyBase, OrganizationMixin):
14
+ """Provider ORM class"""
15
+
16
+ __tablename__ = "providers"
17
+ __pydantic_model__ = PydanticProvider
18
+
19
+ name: Mapped[str] = mapped_column(nullable=False, doc="The name of the provider")
20
+ api_key: Mapped[str] = mapped_column(nullable=True, doc="API key used for requests to the provider.")
21
+
22
+ # relationships
23
+ organization: Mapped["Organization"] = relationship("Organization", back_populates="providers")
@@ -1,16 +1,24 @@
1
1
  from typing import List, Optional
2
2
 
3
- from pydantic import BaseModel, Field, model_validator
3
+ from pydantic import Field, model_validator
4
4
 
5
5
  from letta.constants import LLM_MAX_TOKENS, MIN_CONTEXT_WINDOW
6
6
  from letta.llm_api.azure_openai import get_azure_chat_completions_endpoint, get_azure_embeddings_endpoint
7
7
  from letta.llm_api.azure_openai_constants import AZURE_MODEL_TO_CONTEXT_LENGTH
8
8
  from letta.schemas.embedding_config import EmbeddingConfig
9
+ from letta.schemas.letta_base import LettaBase
9
10
  from letta.schemas.llm_config import LLMConfig
11
+ from letta.services.organization_manager import OrganizationManager
10
12
 
11
13
 
12
- class Provider(BaseModel):
14
+ class ProviderBase(LettaBase):
15
+ __id_prefix__ = "provider"
16
+
17
+
18
+ class Provider(ProviderBase):
13
19
  name: str = Field(..., description="The name of the provider")
20
+ api_key: Optional[str] = Field(None, description="API key used for requests to the provider.")
21
+ organization_id: Optional[str] = Field(OrganizationManager.DEFAULT_ORG_ID, description="The organization id of the user")
14
22
 
15
23
  def list_llm_models(self) -> List[LLMConfig]:
16
24
  return []
@@ -29,6 +37,17 @@ class Provider(BaseModel):
29
37
  return f"{self.name}/{model_name}"
30
38
 
31
39
 
40
+ class ProviderCreate(ProviderBase):
41
+ name: str = Field(..., description="The name of the provider.")
42
+ api_key: str = Field(..., description="API key used for requests to the provider.")
43
+ organization_id: str = Field(..., description="The organization id that this provider information pertains to.")
44
+
45
+
46
+ class ProviderUpdate(ProviderBase):
47
+ id: str = Field(..., description="The id of the provider to update.")
48
+ api_key: str = Field(..., description="API key used for requests to the provider.")
49
+
50
+
32
51
  class LettaProvider(Provider):
33
52
 
34
53
  name: str = "letta"
@@ -80,9 +80,16 @@ class AgentState(OrmMetadataBase, validate_assignment=True):
80
80
  sources: List[Source] = Field(..., description="The sources used by the agent.")
81
81
  tags: List[str] = Field(..., description="The tags associated with the agent.")
82
82
  tool_exec_environment_variables: List[AgentEnvironmentVariable] = Field(
83
- ..., description="The environment variables for tool execution specific to this agent."
83
+ default_factory=list, description="The environment variables for tool execution specific to this agent."
84
84
  )
85
85
 
86
+ def get_agent_env_vars_as_dict(self) -> Dict[str, str]:
87
+ # Get environment variables for this agent specifically
88
+ per_agent_env_vars = {}
89
+ for agent_env_var_obj in self.tool_exec_environment_variables:
90
+ per_agent_env_vars[agent_env_var_obj.key] = agent_env_var_obj.value
91
+ return per_agent_env_vars
92
+
86
93
 
87
94
  class CreateAgent(BaseModel, validate_assignment=True): #
88
95
  # all optional as server can generate defaults
@@ -127,6 +134,7 @@ class CreateAgent(BaseModel, validate_assignment=True): #
127
134
  tool_exec_environment_variables: Optional[Dict[str, str]] = Field(
128
135
  None, description="The environment variables for tool execution specific to this agent."
129
136
  )
137
+ variables: Optional[Dict[str, str]] = Field(None, description="The variables that should be set for the agent.")
130
138
 
131
139
  @field_validator("name")
132
140
  @classmethod
@@ -11,6 +11,10 @@ class LettaRequest(BaseModel):
11
11
 
12
12
  # Flags to support the use of AssistantMessage message types
13
13
 
14
+ use_assistant_message: bool = Field(
15
+ default=True,
16
+ description="Whether the server should parse specific tool call arguments (default `send_message`) as `AssistantMessage` objects.",
17
+ )
14
18
  assistant_message_tool_name: str = Field(
15
19
  default=DEFAULT_MESSAGE_TOOL,
16
20
  description="The name of the designated message tool.",
@@ -46,6 +46,8 @@ def list_agents(
46
46
  ),
47
47
  server: "SyncServer" = Depends(get_letta_server),
48
48
  user_id: Optional[str] = Header(None, alias="user_id"),
49
+ cursor: Optional[int] = Query(None, description="Cursor for pagination"),
50
+ limit: Optional[int] = Query(None, description="Limit for pagination"),
49
51
  # Extract user_id from header, default to None if not present
50
52
  ):
51
53
  """
@@ -66,7 +68,7 @@ def list_agents(
66
68
  }
67
69
 
68
70
  # Call list_agents with the dynamic kwargs
69
- agents = server.agent_manager.list_agents(actor=actor, **kwargs)
71
+ agents = server.agent_manager.list_agents(actor=actor, cursor=cursor, limit=limit, **kwargs)
70
72
  return agents
71
73
 
72
74
 
@@ -491,6 +493,7 @@ async def send_message(
491
493
  stream_steps=False,
492
494
  stream_tokens=False,
493
495
  # Support for AssistantMessage
496
+ use_assistant_message=request.use_assistant_message,
494
497
  assistant_message_tool_name=request.assistant_message_tool_name,
495
498
  assistant_message_tool_kwarg=request.assistant_message_tool_kwarg,
496
499
  )
@@ -636,6 +639,7 @@ async def send_message_to_agent(
636
639
  chat_completion_mode: bool = False,
637
640
  timestamp: Optional[datetime] = None,
638
641
  # Support for AssistantMessage
642
+ use_assistant_message: bool = True,
639
643
  assistant_message_tool_name: str = DEFAULT_MESSAGE_TOOL,
640
644
  assistant_message_tool_kwarg: str = DEFAULT_MESSAGE_TOOL_KWARG,
641
645
  ) -> Union[StreamingResponse, LettaResponse]:
@@ -666,7 +670,7 @@ async def send_message_to_agent(
666
670
  stream_tokens = False
667
671
 
668
672
  # Create a new interface per request
669
- letta_agent.interface = StreamingServerInterface()
673
+ letta_agent.interface = StreamingServerInterface(use_assistant_message)
670
674
  streaming_interface = letta_agent.interface
671
675
  if not isinstance(streaming_interface, StreamingServerInterface):
672
676
  raise ValueError(f"Agent has wrong type of interface: {type(streaming_interface)}")
@@ -0,0 +1,72 @@
1
+ from fastapi import APIRouter, Depends
2
+
3
+ from letta.providers import Provider, ProviderCreate, ProviderUpdate
4
+ from letta.server.rest_api.utils import get_letta_server
5
+
6
+ if TYPE_CHECKING:
7
+ from letta.server.server import SyncServer
8
+
9
+ router = APIRouter(prefix="/providers", tags=["providers", "admin"])
10
+
11
+
12
+ @router.get("/", tags=["admin"], response_model=List[Provider], operation_id="list_providers")
13
+ def list_providers(
14
+ cursor: Optional[str] = Query(None),
15
+ limit: Optional[int] = Query(50),
16
+ server: "SyncServer" = Depends(get_letta_server),
17
+ ):
18
+ """
19
+ Get a list of all custom providers in the database
20
+ """
21
+ try:
22
+ providers = server.provider_manager.list_providers(cursor=cursor, limit=limit)
23
+ except HTTPException:
24
+ raise
25
+ except Exception as e:
26
+ raise HTTPException(status_code=500, detail=f"{e}")
27
+ return providers
28
+
29
+
30
+ @router.post("/", tags=["admin"], response_model=Provider, operation_id="create_provider")
31
+ def create_provider(
32
+ request: ProviderCreate = Body(...),
33
+ server: "SyncServer" = Depends(get_letta_server),
34
+ ):
35
+ """
36
+ Create a new custom provider
37
+ """
38
+ provider = Provider(**request.model_dump())
39
+ provider = server.provider_manager.create_provider(provider)
40
+ return provider
41
+
42
+
43
+ @router.put("/", tags=["admin"], response_model=Provider, operation_id="update_provider")
44
+ def update_provider(
45
+ request: ProviderUpdate = Body(...),
46
+ server: "SyncServer" = Depends(get_letta_server),
47
+ ):
48
+ """
49
+ Update an existing custom provider
50
+ """
51
+ provider = server.provider_manager.update_provider(request)
52
+ return provider
53
+
54
+
55
+ @router.delete("/", tags=["admin"], response_model=Provider, operation_id="delete_provider")
56
+ def delete_provider(
57
+ provider_id: str = Query(..., description="The provider_id key to be deleted."),
58
+ server: "SyncServer" = Depends(get_letta_server),
59
+ ):
60
+ """
61
+ Delete an existing custom provider
62
+ """
63
+ try:
64
+ provider = server.provider_manager.get_provider_by_id(provider_id=provider_id)
65
+ if provider is None:
66
+ raise HTTPException(status_code=404, detail=f"Provider does not exist")
67
+ server.provider_manager.delete_provider_by_id(provider_id=provider_id)
68
+ except HTTPException:
69
+ raise
70
+ except Exception as e:
71
+ raise HTTPException(status_code=500, detail=f"{e}")
72
+ return user
@@ -66,6 +66,7 @@ from letta.services.message_manager import MessageManager
66
66
  from letta.services.organization_manager import OrganizationManager
67
67
  from letta.services.passage_manager import PassageManager
68
68
  from letta.services.per_agent_lock_manager import PerAgentLockManager
69
+ from letta.services.provider_manager import ProviderManager
69
70
  from letta.services.sandbox_config_manager import SandboxConfigManager
70
71
  from letta.services.source_manager import SourceManager
71
72
  from letta.services.tool_execution_sandbox import ToolExecutionSandbox
@@ -180,6 +181,7 @@ def db_error_handler():
180
181
  exit(1)
181
182
 
182
183
 
184
+ print("Creating engine", settings.letta_pg_uri)
183
185
  if settings.letta_pg_uri_no_default:
184
186
  config.recall_storage_type = "postgres"
185
187
  config.recall_storage_uri = settings.letta_pg_uri_no_default
@@ -289,6 +291,7 @@ class SyncServer(Server):
289
291
  self.message_manager = MessageManager()
290
292
  self.job_manager = JobManager()
291
293
  self.agent_manager = AgentManager()
294
+ self.provider_manager = ProviderManager()
292
295
 
293
296
  # Managers that interface with parallelism
294
297
  self.per_agent_lock_manager = PerAgentLockManager()
@@ -1029,7 +1032,7 @@ class SyncServer(Server):
1029
1032
  """List available models"""
1030
1033
 
1031
1034
  llm_models = []
1032
- for provider in self._enabled_providers:
1035
+ for provider in self.get_enabled_providers():
1033
1036
  try:
1034
1037
  llm_models.extend(provider.list_llm_models())
1035
1038
  except Exception as e:
@@ -1039,13 +1042,19 @@ class SyncServer(Server):
1039
1042
  def list_embedding_models(self) -> List[EmbeddingConfig]:
1040
1043
  """List available embedding models"""
1041
1044
  embedding_models = []
1042
- for provider in self._enabled_providers:
1045
+ for provider in self.get_enabled_providers():
1043
1046
  try:
1044
1047
  embedding_models.extend(provider.list_embedding_models())
1045
1048
  except Exception as e:
1046
1049
  warnings.warn(f"An error occurred while listing embedding models for provider {provider}: {e}")
1047
1050
  return embedding_models
1048
1051
 
1052
+ def get_enabled_providers(self):
1053
+ providers_from_env = {p.name: p for p in self._enabled_providers}
1054
+ providers_from_db = {p.name: p for p in self.provider_manager.list_providers()}
1055
+ # Merge the two dictionaries, keeping the values from providers_from_db where conflicts occur
1056
+ return {**providers_from_env, **providers_from_db}.values()
1057
+
1049
1058
  def get_llm_config_from_handle(self, handle: str, context_window_limit: Optional[int] = None) -> LLMConfig:
1050
1059
  provider_name, model_name = handle.split("/", 1)
1051
1060
  provider = self.get_provider_from_name(provider_name)
@@ -0,0 +1 @@
1
+ *,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}:root{--background: 210, 10%, 92%;--background-lighter: 0, 0%, 100%;--background-darker: 210, 6%, 86%;--foreground: 224 71.4% 4.1%;--card: 0 0% 100%;--card-foreground: 224 71.4% 4.1%;--popover: 0 0% 100%;--popover-foreground: 224 71.4% 4.1%;--brand: 220.9 39.3% 11%;--brand-foreground: 210 20% 98%;--primary: 240, 92%, 35%;--primary-foreground: 0, 0%, 100%;--muted: 220 14.3% 95.9%;--muted-foreground: 220 8.9% 46.1%;--accent: 220 14.3% 95.9%;--accent-foreground: 220.9 39.3% 11%;--destructive: 0 84.2% 60.2%;--destructive-foreground: 210 20% 98%;--border: 210, 6%, 86%;--input: 210, 6%, 86%;--ring: 224 71.4% 4.1%;--radius: .5rem}.dark{--background: 224 71.4% 4.1%;--background-lighter: 224 71.4% 4.1%;--background-darker: 224 71.4% 4.1%;--foreground: 210 20% 98%;--card: 224 71.4% 4.1%;--card-foreground: 210 20% 98%;--popover: 224 71.4% 4.1%;--popover-foreground: 210 20% 98%;--brand: 210 20% 98%;--brand-foreground: 220.9 39.3% 11%;--primary: 10, 100%, 60%;--primary-foreground: 210 20% 98%;--muted: 215 27.9% 16.9%;--muted-foreground: 217.9 10.6% 64.9%;--accent: 215 27.9% 16.9%;--accent-foreground: 210 20% 98%;--destructive: 0 62.8% 30.6%;--destructive-foreground: 210 20% 98%;--border: 215 27.9% 16.9%;--input: 215 27.9% 16.9%;--ring: 216 12.2% 83.9%}*{border-color:hsl(var(--border))}html{height:100%}body{height:100%;width:100%;background-color:hsl(var(--background));color:hsl(var(--foreground));-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}input::file-selector-button{color:hsl(var(--foreground))}*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.fixed{position:fixed}.mt-10{margin-top:2.5rem}.mt-3{margin-top:.75rem}.flex{display:flex}.h-\[100dvh\]{height:100dvh}.h-full{height:100%}.w-\[100dvw\]{width:100dvw}.w-full{width:100%}.max-w-\[600px\]{max-width:600px}.max-w-\[893px\]{max-width:893px}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-center{justify-content:center}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-5{gap:1.25rem}.border{border-width:1px}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity))}.p-0{padding:0}.p-10{padding:2.5rem}.px-4{padding-left:1rem;padding-right:1rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.font-semibold{font-weight:600}.text-black{--tw-text-opacity: 1;color:rgb(0 0 0 / var(--tw-text-opacity))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity))}@keyframes enter{0%{opacity:var(--tw-enter-opacity, 1);transform:translate3d(var(--tw-enter-translate-x, 0),var(--tw-enter-translate-y, 0),0) scale3d(var(--tw-enter-scale, 1),var(--tw-enter-scale, 1),var(--tw-enter-scale, 1)) rotate(var(--tw-enter-rotate, 0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity, 1);transform:translate3d(var(--tw-exit-translate-x, 0),var(--tw-exit-translate-y, 0),0) scale3d(var(--tw-exit-scale, 1),var(--tw-exit-scale, 1),var(--tw-exit-scale, 1)) rotate(var(--tw-exit-rotate, 0))}}.PopoverContent{width:var(--radix-popover-trigger-width);max-height:var(--radix-popover-content-available-height)}
@@ -7,7 +7,7 @@
7
7
 
8
8
  <meta name="viewport" content="width=device-width, initial-scale=1" />
9
9
  <link rel="icon" type="image/x-icon" href="/favicon.ico" />
10
-
10
+
11
11
  <script>
12
12
  if (localStorage.theme === 'dark') {
13
13
  if (document && document.documentElement) {
@@ -34,6 +34,6 @@
34
34
  </head>
35
35
  <body>
36
36
  <div class="h-full w-full" id="root"></div>
37
-
37
+
38
38
  </body>
39
39
  </html>
@@ -338,11 +338,30 @@ class AgentManager:
338
338
  # Retrieve the agent
339
339
  agent = AgentModel.read(db_session=session, identifier=agent_id, actor=actor)
340
340
 
341
- # Replace the environment variables
342
- agent.tool_exec_environment_variables = [
343
- AgentEnvironmentVariableModel(key=key, value=value, agent_id=agent_id, organization_id=actor.organization_id)
344
- for key, value in env_vars.items()
345
- ]
341
+ # Fetch existing environment variables as a dictionary
342
+ existing_vars = {var.key: var for var in agent.tool_exec_environment_variables}
343
+
344
+ # Update or create environment variables
345
+ updated_vars = []
346
+ for key, value in env_vars.items():
347
+ if key in existing_vars:
348
+ # Update existing variable
349
+ existing_vars[key].value = value
350
+ updated_vars.append(existing_vars[key])
351
+ else:
352
+ # Create new variable
353
+ updated_vars.append(
354
+ AgentEnvironmentVariableModel(
355
+ key=key,
356
+ value=value,
357
+ agent_id=agent_id,
358
+ organization_id=actor.organization_id,
359
+ )
360
+ )
361
+
362
+ # Remove stale variables
363
+ stale_keys = set(existing_vars) - set(env_vars)
364
+ agent.tool_exec_environment_variables = [var for var in updated_vars if var.key not in stale_keys]
346
365
 
347
366
  # Update the agent in the database
348
367
  agent.update(session, actor=actor)
@@ -0,0 +1,63 @@
1
+ from typing import List, Optional
2
+
3
+ from letta.orm.provider import Provider as ProviderModel
4
+ from letta.providers import Provider as PydanticProvider
5
+ from letta.providers import ProviderUpdate
6
+ from letta.utils import enforce_types
7
+
8
+
9
+ class ProviderManager:
10
+
11
+ def __init__(self):
12
+ from letta.server.server import db_context
13
+
14
+ self.session_maker = db_context
15
+
16
+ @enforce_types
17
+ def create_provider(self, provider: PydanticProvider) -> PydanticProvider:
18
+ """Create a new provider if it doesn't already exist."""
19
+ with self.session_maker() as session:
20
+ new_provider = ProviderModel(**provider.model_dump())
21
+ new_provider.create(session)
22
+ return new_provider.to_pydantic()
23
+
24
+ @enforce_types
25
+ def update_provider(self, provider_update: ProviderUpdate) -> PydanticProvider:
26
+ """Update provider details."""
27
+ with self.session_maker() as session:
28
+ # Retrieve the existing provider by ID
29
+ existing_provider = ProviderModel.read(db_session=session, identifier=provider_update.id)
30
+
31
+ # Update only the fields that are provided in ProviderUpdate
32
+ update_data = provider_update.model_dump(exclude_unset=True, exclude_none=True)
33
+ for key, value in update_data.items():
34
+ setattr(existing_provider, key, value)
35
+
36
+ # Commit the updated provider
37
+ existing_provider.update(session)
38
+ return existing_provider.to_pydantic()
39
+
40
+ @enforce_types
41
+ def delete_provider_by_id(self, provider_id: str):
42
+ """Delete a provider."""
43
+ with self.session_maker() as session:
44
+ # Delete from provider table
45
+ provider = ProviderModel.read(db_session=session, identifier=provider_id)
46
+ provider.hard_delete(session)
47
+
48
+ session.commit()
49
+
50
+ @enforce_types
51
+ def list_providers(self, cursor: Optional[str] = None, limit: Optional[int] = 50) -> List[PydanticProvider]:
52
+ """List providers with pagination using cursor (id) and limit."""
53
+ with self.session_maker() as session:
54
+ results = ProviderModel.list(db_session=session, cursor=cursor, limit=limit)
55
+ return [provider.to_pydantic() for provider in results]
56
+
57
+ @enforce_types
58
+ def get_anthropic_key_override(self) -> Optional[str]:
59
+ """Helper function to fetch custom anthropic key for v0 BYOK feature"""
60
+ providers = self.list_providers(limit=1)
61
+ if len(providers) == 1 and providers[0].name == "anthropic":
62
+ return providers[0].api_key
63
+ return None
@@ -98,7 +98,7 @@ class ToolExecutionSandbox:
98
98
  os.environ.clear()
99
99
  os.environ.update(original_env) # Restore original environment variables
100
100
 
101
- def run_local_dir_sandbox(self, agent_state: AgentState) -> SandboxRunResult:
101
+ def run_local_dir_sandbox(self, agent_state: Optional[AgentState] = None) -> SandboxRunResult:
102
102
  sbx_config = self.sandbox_config_manager.get_or_create_default_sandbox_config(sandbox_type=SandboxType.LOCAL, actor=self.user)
103
103
  local_configs = sbx_config.get_local_config()
104
104
 
@@ -107,6 +107,10 @@ class ToolExecutionSandbox:
107
107
  env = os.environ.copy()
108
108
  env.update(env_vars)
109
109
 
110
+ # Get environment variables for this agent specifically
111
+ if agent_state:
112
+ env.update(agent_state.get_agent_env_vars_as_dict())
113
+
110
114
  # Safety checks
111
115
  if not os.path.isdir(local_configs.sandbox_dir):
112
116
  raise FileNotFoundError(f"Sandbox directory does not exist: {local_configs.sandbox_dir}")
@@ -273,7 +277,7 @@ class ToolExecutionSandbox:
273
277
 
274
278
  # e2b sandbox specific functions
275
279
 
276
- def run_e2b_sandbox(self, agent_state: AgentState) -> SandboxRunResult:
280
+ def run_e2b_sandbox(self, agent_state: Optional[AgentState] = None) -> SandboxRunResult:
277
281
  sbx_config = self.sandbox_config_manager.get_or_create_default_sandbox_config(sandbox_type=SandboxType.E2B, actor=self.user)
278
282
  sbx = self.get_running_e2b_sandbox_with_same_state(sbx_config)
279
283
  if not sbx or self.force_recreate:
@@ -292,15 +296,18 @@ class ToolExecutionSandbox:
292
296
  # Get environment variables for the sandbox
293
297
  # TODO: We set limit to 100 here, but maybe we want it uncapped? Realistically this should be fine.
294
298
  env_vars = self.sandbox_config_manager.get_sandbox_env_vars_as_dict(sandbox_config_id=sbx_config.id, actor=self.user, limit=100)
299
+ # Get environment variables for this agent specifically
300
+ if agent_state:
301
+ env_vars.update(agent_state.get_agent_env_vars_as_dict())
302
+
295
303
  code = self.generate_execution_script(agent_state=agent_state)
296
304
  execution = sbx.run_code(code, envs=env_vars)
297
305
 
298
306
  if execution.results:
299
307
  func_return, agent_state = self.parse_best_effort(execution.results[0].text)
300
308
  elif execution.error:
301
- logger.error(f"Executing tool {self.tool_name} failed with {execution.error}")
302
- logger.error(f"E2B Sandbox configurations: {sbx_config}")
303
- logger.error(f"E2B Sandbox ID: {sbx.sandbox_id}")
309
+ logger.error(f"Executing tool {self.tool_name} raised a {execution.error.name} with message: \n{execution.error.value}")
310
+ logger.error(f"Traceback from e2b sandbox: \n{execution.error.traceback}")
304
311
  func_return = get_friendly_error_msg(
305
312
  function_name=self.tool_name, exception_name=execution.error.name, exception_message=execution.error.value
306
313
  )
@@ -1,8 +1,8 @@
1
1
  [tool.poetry]
2
2
  name = "letta-nightly"
3
- version = "0.6.7.dev20250108225500"
3
+ version = "0.6.8.dev20250109011239"
4
4
  packages = [
5
- {include = "letta"}
5
+ {include = "letta"},
6
6
  ]
7
7
  description = "Create LLM agents with long-term memory and custom tools"
8
8
  authors = [
@@ -15,7 +15,7 @@ readme = "README.md"
15
15
  letta = "letta.main:app"
16
16
 
17
17
  [tool.poetry.dependencies]
18
- python = "<4.0,>=3.10"
18
+ python = "<3.14,>=3.10"
19
19
  typer = {extras = ["all"], version = "^0.9.0"}
20
20
  questionary = "^2.0.1"
21
21
  pytz = "^2023.3.post1"