letta-nightly 0.6.19.dev20250130104029__tar.gz → 0.6.20.dev20250131222205__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 (244) hide show
  1. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/PKG-INFO +1 -1
  2. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/__init__.py +1 -1
  3. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/llm_api/anthropic.py +3 -26
  4. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/llm_api/azure_openai_constants.py +1 -1
  5. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/llm_api/llm_api_tools.py +21 -21
  6. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/llm_api/openai.py +12 -15
  7. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/agent.py +6 -0
  8. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/custom_columns.py +3 -0
  9. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/agent.py +3 -0
  10. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/sandbox_config.py +43 -1
  11. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/tool_rule.py +9 -6
  12. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/app.py +4 -1
  13. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/__init__.py +2 -0
  14. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/sandbox_configs.py +78 -1
  15. letta_nightly-0.6.20.dev20250131222205/letta/server/rest_api/routers/v1/steps.py +78 -0
  16. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/tools.py +23 -9
  17. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/server.py +0 -3
  18. letta_nightly-0.6.20.dev20250131222205/letta/services/helpers/tool_execution_helper.py +155 -0
  19. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/services/step_manager.py +55 -0
  20. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/services/tool_execution_sandbox.py +25 -36
  21. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/settings.py +1 -1
  22. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/system.py +14 -1
  23. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/pyproject.toml +1 -1
  24. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/LICENSE +0 -0
  25. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/README.md +0 -0
  26. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/__main__.py +0 -0
  27. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/agent.py +0 -0
  28. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/benchmark/benchmark.py +0 -0
  29. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/benchmark/constants.py +0 -0
  30. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/chat_only_agent.py +0 -0
  31. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/cli/cli.py +0 -0
  32. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/cli/cli_config.py +0 -0
  33. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/cli/cli_load.py +0 -0
  34. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/client/__init__.py +0 -0
  35. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/client/client.py +0 -0
  36. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/client/streaming.py +0 -0
  37. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/client/utils.py +0 -0
  38. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/config.py +0 -0
  39. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/constants.py +0 -0
  40. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/data_sources/connectors.py +0 -0
  41. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/data_sources/connectors_helper.py +0 -0
  42. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/embeddings.py +0 -0
  43. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/errors.py +0 -0
  44. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/functions/__init__.py +0 -0
  45. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/functions/ast_parsers.py +0 -0
  46. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/functions/function_sets/base.py +0 -0
  47. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/functions/function_sets/extras.py +0 -0
  48. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/functions/function_sets/multi_agent.py +0 -0
  49. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/functions/functions.py +0 -0
  50. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/functions/helpers.py +0 -0
  51. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/functions/schema_generator.py +0 -0
  52. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/helpers/__init__.py +0 -0
  53. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/helpers/tool_rule_solver.py +0 -0
  54. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/humans/__init__.py +0 -0
  55. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/humans/examples/basic.txt +0 -0
  56. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/humans/examples/cs_phd.txt +0 -0
  57. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/interface.py +0 -0
  58. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/llm_api/__init__.py +0 -0
  59. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/llm_api/aws_bedrock.py +0 -0
  60. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/llm_api/azure_openai.py +0 -0
  61. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/llm_api/cohere.py +0 -0
  62. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/llm_api/google_ai.py +0 -0
  63. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/llm_api/helpers.py +0 -0
  64. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/llm_api/mistral.py +0 -0
  65. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/README.md +0 -0
  66. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/__init__.py +0 -0
  67. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/chat_completion_proxy.py +0 -0
  68. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/constants.py +0 -0
  69. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/function_parser.py +0 -0
  70. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/grammars/__init__.py +0 -0
  71. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/grammars/gbnf_grammar_generator.py +0 -0
  72. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/grammars/json.gbnf +0 -0
  73. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/grammars/json_func_calls_with_inner_thoughts.gbnf +0 -0
  74. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/json_parser.py +0 -0
  75. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/koboldcpp/api.py +0 -0
  76. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/koboldcpp/settings.py +0 -0
  77. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/llamacpp/api.py +0 -0
  78. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/llamacpp/settings.py +0 -0
  79. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/llm_chat_completion_wrappers/__init__.py +0 -0
  80. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/llm_chat_completion_wrappers/airoboros.py +0 -0
  81. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/llm_chat_completion_wrappers/chatml.py +0 -0
  82. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/llm_chat_completion_wrappers/configurable_wrapper.py +0 -0
  83. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/llm_chat_completion_wrappers/dolphin.py +0 -0
  84. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/llm_chat_completion_wrappers/llama3.py +0 -0
  85. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/llm_chat_completion_wrappers/simple_summary_wrapper.py +0 -0
  86. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/llm_chat_completion_wrappers/wrapper_base.py +0 -0
  87. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/llm_chat_completion_wrappers/zephyr.py +0 -0
  88. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/lmstudio/api.py +0 -0
  89. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/lmstudio/settings.py +0 -0
  90. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/ollama/api.py +0 -0
  91. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/ollama/settings.py +0 -0
  92. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/settings/__init__.py +0 -0
  93. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/settings/deterministic_mirostat.py +0 -0
  94. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/settings/settings.py +0 -0
  95. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/settings/simple.py +0 -0
  96. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/utils.py +0 -0
  97. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/vllm/api.py +0 -0
  98. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/webui/api.py +0 -0
  99. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/webui/legacy_api.py +0 -0
  100. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/webui/legacy_settings.py +0 -0
  101. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/local_llm/webui/settings.py +0 -0
  102. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/log.py +0 -0
  103. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/main.py +0 -0
  104. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/memory.py +0 -0
  105. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/offline_memory_agent.py +0 -0
  106. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/openai_backcompat/__init__.py +0 -0
  107. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/openai_backcompat/openai_object.py +0 -0
  108. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/__all__.py +0 -0
  109. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/__init__.py +0 -0
  110. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/agents_tags.py +0 -0
  111. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/base.py +0 -0
  112. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/block.py +0 -0
  113. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/blocks_agents.py +0 -0
  114. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/enums.py +0 -0
  115. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/errors.py +0 -0
  116. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/file.py +0 -0
  117. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/job.py +0 -0
  118. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/job_messages.py +0 -0
  119. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/message.py +0 -0
  120. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/mixins.py +0 -0
  121. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/organization.py +0 -0
  122. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/passage.py +0 -0
  123. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/provider.py +0 -0
  124. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/sandbox_config.py +0 -0
  125. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/source.py +0 -0
  126. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/sources_agents.py +0 -0
  127. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/sqlalchemy_base.py +0 -0
  128. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/sqlite_functions.py +0 -0
  129. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/step.py +0 -0
  130. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/tool.py +0 -0
  131. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/tools_agents.py +0 -0
  132. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/orm/user.py +0 -0
  133. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/personas/__init__.py +0 -0
  134. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/personas/examples/anna_pa.txt +0 -0
  135. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/personas/examples/google_search_persona.txt +0 -0
  136. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/personas/examples/memgpt_doc.txt +0 -0
  137. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/personas/examples/memgpt_starter.txt +0 -0
  138. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/personas/examples/o1_persona.txt +0 -0
  139. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/personas/examples/offline_memory_persona.txt +0 -0
  140. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/personas/examples/sam.txt +0 -0
  141. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/personas/examples/sam_pov.txt +0 -0
  142. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/personas/examples/sam_simple_pov_gpt35.txt +0 -0
  143. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/personas/examples/sqldb/test.db +0 -0
  144. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/__init__.py +0 -0
  145. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/gpt_summarize.py +0 -0
  146. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/gpt_system.py +0 -0
  147. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/system/memgpt_base.txt +0 -0
  148. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/system/memgpt_chat.txt +0 -0
  149. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/system/memgpt_chat_compressed.txt +0 -0
  150. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/system/memgpt_chat_fstring.txt +0 -0
  151. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/system/memgpt_convo_only.txt +0 -0
  152. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/system/memgpt_doc.txt +0 -0
  153. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/system/memgpt_gpt35_extralong.txt +0 -0
  154. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/system/memgpt_intuitive_knowledge.txt +0 -0
  155. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/system/memgpt_modified_chat.txt +0 -0
  156. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/system/memgpt_modified_o1.txt +0 -0
  157. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/system/memgpt_offline_memory.txt +0 -0
  158. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/prompts/system/memgpt_offline_memory_chat.txt +0 -0
  159. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/pytest.ini +0 -0
  160. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/block.py +0 -0
  161. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/embedding_config.py +0 -0
  162. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/embedding_config_overrides.py +0 -0
  163. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/enums.py +0 -0
  164. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/environment_variables.py +0 -0
  165. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/file.py +0 -0
  166. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/health.py +0 -0
  167. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/job.py +0 -0
  168. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/letta_base.py +0 -0
  169. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/letta_message.py +0 -0
  170. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/letta_request.py +0 -0
  171. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/letta_response.py +0 -0
  172. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/llm_config.py +0 -0
  173. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/llm_config_overrides.py +0 -0
  174. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/memory.py +0 -0
  175. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/message.py +0 -0
  176. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/openai/chat_completion_request.py +0 -0
  177. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/openai/chat_completion_response.py +0 -0
  178. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/openai/chat_completions.py +0 -0
  179. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/openai/embedding_response.py +0 -0
  180. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/openai/openai.py +0 -0
  181. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/organization.py +0 -0
  182. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/passage.py +0 -0
  183. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/providers.py +0 -0
  184. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/run.py +0 -0
  185. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/source.py +0 -0
  186. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/step.py +0 -0
  187. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/tool.py +0 -0
  188. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/usage.py +0 -0
  189. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/schemas/user.py +0 -0
  190. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/__init__.py +0 -0
  191. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/constants.py +0 -0
  192. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/generate_openapi_schema.sh +0 -0
  193. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/__init__.py +0 -0
  194. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/auth/__init__.py +0 -0
  195. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/auth/index.py +0 -0
  196. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/auth_token.py +0 -0
  197. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/chat_completions_interface.py +0 -0
  198. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/interface.py +0 -0
  199. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/optimistic_json_parser.py +0 -0
  200. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/__init__.py +0 -0
  201. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/openai/chat_completions/__init__.py +0 -0
  202. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/openai/chat_completions/chat_completions.py +0 -0
  203. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/agents.py +0 -0
  204. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/blocks.py +0 -0
  205. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/health.py +0 -0
  206. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/jobs.py +0 -0
  207. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/llms.py +0 -0
  208. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/organizations.py +0 -0
  209. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/providers.py +0 -0
  210. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/runs.py +0 -0
  211. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/sources.py +0 -0
  212. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/tags.py +0 -0
  213. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/routers/v1/users.py +0 -0
  214. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/static_files.py +0 -0
  215. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/rest_api/utils.py +0 -0
  216. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/startup.sh +0 -0
  217. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/static_files/assets/index-048c9598.js +0 -0
  218. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/static_files/assets/index-0e31b727.css +0 -0
  219. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/static_files/favicon.ico +0 -0
  220. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/static_files/index.html +0 -0
  221. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/static_files/memgpt_logo_transparent.png +0 -0
  222. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/utils.py +0 -0
  223. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/ws_api/__init__.py +0 -0
  224. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/ws_api/example_client.py +0 -0
  225. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/ws_api/interface.py +0 -0
  226. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/ws_api/protocol.py +0 -0
  227. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/server/ws_api/server.py +0 -0
  228. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/services/__init__.py +0 -0
  229. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/services/agent_manager.py +0 -0
  230. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/services/block_manager.py +0 -0
  231. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/services/helpers/agent_manager_helper.py +0 -0
  232. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/services/job_manager.py +0 -0
  233. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/services/message_manager.py +0 -0
  234. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/services/organization_manager.py +0 -0
  235. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/services/passage_manager.py +0 -0
  236. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/services/per_agent_lock_manager.py +0 -0
  237. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/services/provider_manager.py +0 -0
  238. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/services/sandbox_config_manager.py +0 -0
  239. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/services/source_manager.py +0 -0
  240. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/services/tool_manager.py +0 -0
  241. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/services/user_manager.py +0 -0
  242. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/streaming_interface.py +0 -0
  243. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/streaming_utils.py +0 -0
  244. {letta_nightly-0.6.19.dev20250130104029 → letta_nightly-0.6.20.dev20250131222205}/letta/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: letta-nightly
3
- Version: 0.6.19.dev20250130104029
3
+ Version: 0.6.20.dev20250131222205
4
4
  Summary: Create LLM agents with long-term memory and custom tools
5
5
  License: Apache License
6
6
  Author: Letta Team
@@ -1,4 +1,4 @@
1
- __version__ = "0.6.19"
1
+ __version__ = "0.6.20"
2
2
 
3
3
 
4
4
  # import clients
@@ -1,7 +1,8 @@
1
1
  import json
2
2
  import re
3
3
  import time
4
- from typing import Generator, List, Optional, Tuple, Union
4
+ import warnings
5
+ from typing import Generator, List, Optional, Union
5
6
 
6
7
  import anthropic
7
8
  from anthropic import PermissionDeniedError
@@ -36,7 +37,7 @@ from letta.schemas.openai.chat_completion_response import MessageDelta, ToolCall
36
37
  from letta.services.provider_manager import ProviderManager
37
38
  from letta.settings import model_settings
38
39
  from letta.streaming_interface import AgentChunkStreamingInterface, AgentRefreshStreamingInterface
39
- from letta.utils import get_utc_time, smart_urljoin
40
+ from letta.utils import get_utc_time
40
41
 
41
42
  BASE_URL = "https://api.anthropic.com/v1"
42
43
 
@@ -567,30 +568,6 @@ def _prepare_anthropic_request(
567
568
  return data
568
569
 
569
570
 
570
- def get_anthropic_endpoint_and_headers(
571
- base_url: str,
572
- api_key: str,
573
- version: str = "2023-06-01",
574
- beta: Optional[str] = "tools-2024-04-04",
575
- ) -> Tuple[str, dict]:
576
- """
577
- Dynamically generate the Anthropic endpoint and headers.
578
- """
579
- url = smart_urljoin(base_url, "messages")
580
-
581
- headers = {
582
- "Content-Type": "application/json",
583
- "x-api-key": api_key,
584
- "anthropic-version": version,
585
- }
586
-
587
- # Add beta header if specified
588
- if beta:
589
- headers["anthropic-beta"] = beta
590
-
591
- return url, headers
592
-
593
-
594
571
  def anthropic_chat_completions_request(
595
572
  data: ChatCompletionRequest,
596
573
  inner_thoughts_xml_tag: Optional[str] = "thinking",
@@ -6,5 +6,5 @@ AZURE_MODEL_TO_CONTEXT_LENGTH = {
6
6
  "gpt-35-turbo-0125": 16385,
7
7
  "gpt-4-0613": 8192,
8
8
  "gpt-4o-mini-2024-07-18": 128000,
9
- "gpt-4o-2024-08-06": 128000,
9
+ "gpt-4o": 128000,
10
10
  }
@@ -29,7 +29,6 @@ from letta.schemas.openai.chat_completion_request import ChatCompletionRequest,
29
29
  from letta.schemas.openai.chat_completion_response import ChatCompletionResponse
30
30
  from letta.settings import ModelSettings
31
31
  from letta.streaming_interface import AgentChunkStreamingInterface, AgentRefreshStreamingInterface
32
- from letta.utils import run_async_task
33
32
 
34
33
  LLM_API_PROVIDER_OPTIONS = ["openai", "azure", "anthropic", "google_ai", "cohere", "local", "groq"]
35
34
 
@@ -57,7 +56,9 @@ def retry_with_exponential_backoff(
57
56
  while True:
58
57
  try:
59
58
  return func(*args, **kwargs)
60
-
59
+ except KeyboardInterrupt:
60
+ # Stop retrying if user hits Ctrl-C
61
+ raise KeyboardInterrupt("User intentionally stopped thread. Stopping...")
61
62
  except requests.exceptions.HTTPError as http_err:
62
63
 
63
64
  if not hasattr(http_err, "response") or not http_err.response:
@@ -142,6 +143,11 @@ def create(
142
143
  if model_settings.openai_api_key is None and llm_config.model_endpoint == "https://api.openai.com/v1":
143
144
  # only is a problem if we are *not* using an openai proxy
144
145
  raise LettaConfigurationError(message="OpenAI key is missing from letta config file", missing_fields=["openai_api_key"])
146
+ elif model_settings.openai_api_key is None:
147
+ # the openai python client requires a dummy API key
148
+ api_key = "DUMMY_API_KEY"
149
+ else:
150
+ api_key = model_settings.openai_api_key
145
151
 
146
152
  if function_call is None and functions is not None and len(functions) > 0:
147
153
  # force function calling for reliability, see https://platform.openai.com/docs/api-reference/chat/create#chat-create-tool_choice
@@ -157,25 +163,21 @@ def create(
157
163
  assert isinstance(stream_interface, AgentChunkStreamingInterface) or isinstance(
158
164
  stream_interface, AgentRefreshStreamingInterface
159
165
  ), type(stream_interface)
160
- response = run_async_task(
161
- openai_chat_completions_process_stream(
162
- url=llm_config.model_endpoint,
163
- api_key=model_settings.openai_api_key,
164
- chat_completion_request=data,
165
- stream_interface=stream_interface,
166
- )
166
+ response = openai_chat_completions_process_stream(
167
+ url=llm_config.model_endpoint,
168
+ api_key=api_key,
169
+ chat_completion_request=data,
170
+ stream_interface=stream_interface,
167
171
  )
168
172
  else: # Client did not request token streaming (expect a blocking backend response)
169
173
  data.stream = False
170
174
  if isinstance(stream_interface, AgentChunkStreamingInterface):
171
175
  stream_interface.stream_start()
172
176
  try:
173
- response = run_async_task(
174
- openai_chat_completions_request(
175
- url=llm_config.model_endpoint,
176
- api_key=model_settings.openai_api_key,
177
- chat_completion_request=data,
178
- )
177
+ response = openai_chat_completions_request(
178
+ url=llm_config.model_endpoint,
179
+ api_key=api_key,
180
+ chat_completion_request=data,
179
181
  )
180
182
  finally:
181
183
  if isinstance(stream_interface, AgentChunkStreamingInterface):
@@ -349,12 +351,10 @@ def create(
349
351
  stream_interface.stream_start()
350
352
  try:
351
353
  # groq uses the openai chat completions API, so this component should be reusable
352
- response = run_async_task(
353
- openai_chat_completions_request(
354
- url=llm_config.model_endpoint,
355
- api_key=model_settings.groq_api_key,
356
- chat_completion_request=data,
357
- )
354
+ response = openai_chat_completions_request(
355
+ url=llm_config.model_endpoint,
356
+ api_key=model_settings.groq_api_key,
357
+ chat_completion_request=data,
358
358
  )
359
359
  finally:
360
360
  if isinstance(stream_interface, AgentChunkStreamingInterface):
@@ -1,8 +1,8 @@
1
1
  import warnings
2
- from typing import AsyncGenerator, List, Optional, Union
2
+ from typing import Generator, List, Optional, Union
3
3
 
4
4
  import requests
5
- from openai import AsyncOpenAI
5
+ from openai import OpenAI
6
6
 
7
7
  from letta.llm_api.helpers import add_inner_thoughts_to_functions, convert_to_structured_output, make_post_request
8
8
  from letta.local_llm.constants import INNER_THOUGHTS_KWARG, INNER_THOUGHTS_KWARG_DESCRIPTION, INNER_THOUGHTS_KWARG_DESCRIPTION_GO_FIRST
@@ -158,7 +158,7 @@ def build_openai_chat_completions_request(
158
158
  return data
159
159
 
160
160
 
161
- async def openai_chat_completions_process_stream(
161
+ def openai_chat_completions_process_stream(
162
162
  url: str,
163
163
  api_key: str,
164
164
  chat_completion_request: ChatCompletionRequest,
@@ -231,7 +231,7 @@ async def openai_chat_completions_process_stream(
231
231
  n_chunks = 0 # approx == n_tokens
232
232
  chunk_idx = 0
233
233
  try:
234
- async for chat_completion_chunk in openai_chat_completions_request_stream(
234
+ for chat_completion_chunk in openai_chat_completions_request_stream(
235
235
  url=url, api_key=api_key, chat_completion_request=chat_completion_request
236
236
  ):
237
237
  assert isinstance(chat_completion_chunk, ChatCompletionChunkResponse), type(chat_completion_chunk)
@@ -382,24 +382,21 @@ async def openai_chat_completions_process_stream(
382
382
  return chat_completion_response
383
383
 
384
384
 
385
- async def openai_chat_completions_request_stream(
385
+ def openai_chat_completions_request_stream(
386
386
  url: str,
387
387
  api_key: str,
388
388
  chat_completion_request: ChatCompletionRequest,
389
- ) -> AsyncGenerator[ChatCompletionChunkResponse, None]:
389
+ ) -> Generator[ChatCompletionChunkResponse, None, None]:
390
390
  data = prepare_openai_payload(chat_completion_request)
391
391
  data["stream"] = True
392
- client = AsyncOpenAI(
393
- api_key=api_key,
394
- base_url=url,
395
- )
396
- stream = await client.chat.completions.create(**data)
397
- async for chunk in stream:
392
+ client = OpenAI(api_key=api_key, base_url=url, max_retries=0)
393
+ stream = client.chat.completions.create(**data)
394
+ for chunk in stream:
398
395
  # TODO: Use the native OpenAI objects here?
399
396
  yield ChatCompletionChunkResponse(**chunk.model_dump(exclude_none=True))
400
397
 
401
398
 
402
- async def openai_chat_completions_request(
399
+ def openai_chat_completions_request(
403
400
  url: str,
404
401
  api_key: str,
405
402
  chat_completion_request: ChatCompletionRequest,
@@ -412,8 +409,8 @@ async def openai_chat_completions_request(
412
409
  https://platform.openai.com/docs/guides/text-generation?lang=curl
413
410
  """
414
411
  data = prepare_openai_payload(chat_completion_request)
415
- client = AsyncOpenAI(api_key=api_key, base_url=url)
416
- chat_completion = await client.chat.completions.create(**data)
412
+ client = OpenAI(api_key=api_key, base_url=url, max_retries=0)
413
+ chat_completion = client.chat.completions.create(**data)
417
414
  return ChatCompletionResponse(**chat_completion.model_dump())
418
415
 
419
416
 
@@ -56,6 +56,9 @@ class Agent(SqlalchemyBase, OrganizationMixin):
56
56
  embedding_config: Mapped[Optional[EmbeddingConfig]] = mapped_column(
57
57
  EmbeddingConfigColumn, doc="the embedding configuration object for this agent."
58
58
  )
59
+ project_id: Mapped[Optional[str]] = mapped_column(String, nullable=True, doc="The id of the project the agent belongs to.")
60
+ template_id: Mapped[Optional[str]] = mapped_column(String, nullable=True, doc="The id of the template the agent belongs to.")
61
+ base_template_id: Mapped[Optional[str]] = mapped_column(String, nullable=True, doc="The base template id of the agent.")
59
62
 
60
63
  # Tool rules
61
64
  tool_rules: Mapped[Optional[List[ToolRule]]] = mapped_column(ToolRulesColumn, doc="the tool rules for this agent.")
@@ -146,6 +149,9 @@ class Agent(SqlalchemyBase, OrganizationMixin):
146
149
  "created_at": self.created_at,
147
150
  "updated_at": self.updated_at,
148
151
  "tool_exec_environment_variables": self.tool_exec_environment_variables,
152
+ "project_id": self.project_id,
153
+ "template_id": self.template_id,
154
+ "base_template_id": self.base_template_id,
149
155
  }
150
156
 
151
157
  return self.__pydantic_model__(**state)
@@ -85,10 +85,13 @@ class ToolRulesColumn(TypeDecorator):
85
85
  """Deserialize a dictionary to the appropriate ToolRule subclass based on the 'type'."""
86
86
  rule_type = ToolRuleType(data.get("type")) # Remove 'type' field if it exists since it is a class var
87
87
  if rule_type == ToolRuleType.run_first or rule_type == "InitToolRule":
88
+ data["type"] = ToolRuleType.run_first
88
89
  return InitToolRule(**data)
89
90
  elif rule_type == ToolRuleType.exit_loop or rule_type == "TerminalToolRule":
91
+ data["type"] = ToolRuleType.exit_loop
90
92
  return TerminalToolRule(**data)
91
93
  elif rule_type == ToolRuleType.constrain_child_tools or rule_type == "ToolRule":
94
+ data["type"] = ToolRuleType.constrain_child_tools
92
95
  rule = ChildToolRule(**data)
93
96
  return rule
94
97
  elif rule_type == ToolRuleType.conditional:
@@ -81,6 +81,9 @@ class AgentState(OrmMetadataBase, validate_assignment=True):
81
81
  tool_exec_environment_variables: List[AgentEnvironmentVariable] = Field(
82
82
  default_factory=list, description="The environment variables for tool execution specific to this agent."
83
83
  )
84
+ project_id: Optional[str] = Field(None, description="The id of the project the agent belongs to.")
85
+ template_id: Optional[str] = Field(None, description="The id of the template the agent belongs to.")
86
+ base_template_id: Optional[str] = Field(None, description="The base template id of the agent.")
84
87
 
85
88
  def get_agent_env_vars_as_dict(self) -> Dict[str, str]:
86
89
  # Get environment variables for this agent specifically
@@ -1,5 +1,6 @@
1
1
  import hashlib
2
2
  import json
3
+ import re
3
4
  from enum import Enum
4
5
  from typing import Any, Dict, List, Literal, Optional, Union
5
6
 
@@ -25,18 +26,55 @@ class SandboxRunResult(BaseModel):
25
26
  sandbox_config_fingerprint: str = Field(None, description="The fingerprint of the config for the sandbox")
26
27
 
27
28
 
29
+ class PipRequirement(BaseModel):
30
+ name: str = Field(..., min_length=1, description="Name of the pip package.")
31
+ version: Optional[str] = Field(None, description="Optional version of the package, following semantic versioning.")
32
+
33
+ @classmethod
34
+ def validate_version(cls, version: Optional[str]) -> Optional[str]:
35
+ if version is None:
36
+ return None
37
+ semver_pattern = re.compile(r"^\d+(\.\d+){0,2}(-[a-zA-Z0-9.]+)?$")
38
+ if not semver_pattern.match(version):
39
+ raise ValueError(f"Invalid version format: {version}. Must follow semantic versioning (e.g., 1.2.3, 2.0, 1.5.0-alpha).")
40
+ return version
41
+
42
+ def __init__(self, **data):
43
+ super().__init__(**data)
44
+ self.version = self.validate_version(self.version)
45
+
46
+
28
47
  class LocalSandboxConfig(BaseModel):
29
- sandbox_dir: str = Field(..., description="Directory for the sandbox environment.")
48
+ sandbox_dir: Optional[str] = Field(None, description="Directory for the sandbox environment.")
30
49
  use_venv: bool = Field(False, description="Whether or not to use the venv, or run directly in the same run loop.")
31
50
  venv_name: str = Field(
32
51
  "venv",
33
52
  description="The name for the venv in the sandbox directory. We first search for an existing venv with this name, otherwise, we make it from the requirements.txt.",
34
53
  )
54
+ pip_requirements: List[PipRequirement] = Field(
55
+ default_factory=list,
56
+ description="List of pip packages to install with mandatory name and optional version following semantic versioning. This only is considered when use_venv is True.",
57
+ )
35
58
 
36
59
  @property
37
60
  def type(self) -> "SandboxType":
38
61
  return SandboxType.LOCAL
39
62
 
63
+ @model_validator(mode="before")
64
+ @classmethod
65
+ def set_default_sandbox_dir(cls, data):
66
+ # If `data` is not a dict (e.g., it's another Pydantic model), just return it
67
+ if not isinstance(data, dict):
68
+ return data
69
+
70
+ if data.get("sandbox_dir") is None:
71
+ if tool_settings.local_sandbox_dir:
72
+ data["sandbox_dir"] = tool_settings.local_sandbox_dir
73
+ else:
74
+ data["sandbox_dir"] = "~/.letta"
75
+
76
+ return data
77
+
40
78
 
41
79
  class E2BSandboxConfig(BaseModel):
42
80
  timeout: int = Field(5 * 60, description="Time limit for the sandbox (in seconds).")
@@ -53,6 +91,10 @@ class E2BSandboxConfig(BaseModel):
53
91
  """
54
92
  Assign a default template value if the template field is not provided.
55
93
  """
94
+ # If `data` is not a dict (e.g., it's another Pydantic model), just return it
95
+ if not isinstance(data, dict):
96
+ return data
97
+
56
98
  if data.get("template") is None:
57
99
  data["template"] = tool_settings.e2b_sandbox_template_id
58
100
  return data
@@ -1,4 +1,4 @@
1
- from typing import Any, Dict, List, Optional, Union
1
+ from typing import Annotated, Any, Dict, List, Literal, Optional, Union
2
2
 
3
3
  from pydantic import Field
4
4
 
@@ -17,7 +17,7 @@ class ChildToolRule(BaseToolRule):
17
17
  A ToolRule represents a tool that can be invoked by the agent.
18
18
  """
19
19
 
20
- type: ToolRuleType = ToolRuleType.constrain_child_tools
20
+ type: Literal[ToolRuleType.constrain_child_tools] = ToolRuleType.constrain_child_tools
21
21
  children: List[str] = Field(..., description="The children tools that can be invoked.")
22
22
 
23
23
 
@@ -26,7 +26,7 @@ class ConditionalToolRule(BaseToolRule):
26
26
  A ToolRule that conditionally maps to different child tools based on the output.
27
27
  """
28
28
 
29
- type: ToolRuleType = ToolRuleType.conditional
29
+ type: Literal[ToolRuleType.conditional] = ToolRuleType.conditional
30
30
  default_child: Optional[str] = Field(None, description="The default child tool to be called. If None, any tool can be called.")
31
31
  child_output_mapping: Dict[Any, str] = Field(..., description="The output case to check for mapping")
32
32
  require_output_mapping: bool = Field(default=False, description="Whether to throw an error when output doesn't match any case")
@@ -37,7 +37,7 @@ class InitToolRule(BaseToolRule):
37
37
  Represents the initial tool rule configuration.
38
38
  """
39
39
 
40
- type: ToolRuleType = ToolRuleType.run_first
40
+ type: Literal[ToolRuleType.run_first] = ToolRuleType.run_first
41
41
 
42
42
 
43
43
  class TerminalToolRule(BaseToolRule):
@@ -45,7 +45,10 @@ class TerminalToolRule(BaseToolRule):
45
45
  Represents a terminal tool rule configuration where if this tool gets called, it must end the agent loop.
46
46
  """
47
47
 
48
- type: ToolRuleType = ToolRuleType.exit_loop
48
+ type: Literal[ToolRuleType.exit_loop] = ToolRuleType.exit_loop
49
49
 
50
50
 
51
- ToolRule = Union[ChildToolRule, InitToolRule, TerminalToolRule, ConditionalToolRule]
51
+ ToolRule = Annotated[
52
+ Union[ChildToolRule, InitToolRule, TerminalToolRule, ConditionalToolRule],
53
+ Field(discriminator="type"),
54
+ ]
@@ -97,7 +97,10 @@ class CheckPasswordMiddleware(BaseHTTPMiddleware):
97
97
  if request.url.path == "/v1/health/" or request.url.path == "/latest/health/":
98
98
  return await call_next(request)
99
99
 
100
- if request.headers.get("X-BARE-PASSWORD") == f"password {random_password}":
100
+ if (
101
+ request.headers.get("X-BARE-PASSWORD") == f"password {random_password}"
102
+ or request.headers.get("Authorization") == f"Bearer {random_password}"
103
+ ):
101
104
  return await call_next(request)
102
105
 
103
106
  return JSONResponse(
@@ -7,6 +7,7 @@ from letta.server.rest_api.routers.v1.providers import router as providers_route
7
7
  from letta.server.rest_api.routers.v1.runs import router as runs_router
8
8
  from letta.server.rest_api.routers.v1.sandbox_configs import router as sandbox_configs_router
9
9
  from letta.server.rest_api.routers.v1.sources import router as sources_router
10
+ from letta.server.rest_api.routers.v1.steps import router as steps_router
10
11
  from letta.server.rest_api.routers.v1.tags import router as tags_router
11
12
  from letta.server.rest_api.routers.v1.tools import router as tools_router
12
13
 
@@ -21,5 +22,6 @@ ROUTERS = [
21
22
  sandbox_configs_router,
22
23
  providers_router,
23
24
  runs_router,
25
+ steps_router,
24
26
  tags_router,
25
27
  ]
@@ -1,16 +1,22 @@
1
+ import os
2
+ import shutil
1
3
  from typing import List, Optional
2
4
 
3
- from fastapi import APIRouter, Depends, Query
5
+ from fastapi import APIRouter, Depends, HTTPException, Query
4
6
 
7
+ from letta.log import get_logger
5
8
  from letta.schemas.environment_variables import SandboxEnvironmentVariable as PydanticEnvVar
6
9
  from letta.schemas.environment_variables import SandboxEnvironmentVariableCreate, SandboxEnvironmentVariableUpdate
10
+ from letta.schemas.sandbox_config import LocalSandboxConfig
7
11
  from letta.schemas.sandbox_config import SandboxConfig as PydanticSandboxConfig
8
12
  from letta.schemas.sandbox_config import SandboxConfigCreate, SandboxConfigUpdate, SandboxType
9
13
  from letta.server.rest_api.utils import get_letta_server, get_user_id
10
14
  from letta.server.server import SyncServer
15
+ from letta.services.helpers.tool_execution_helper import create_venv_for_local_sandbox, install_pip_requirements_for_sandbox
11
16
 
12
17
  router = APIRouter(prefix="/sandbox-config", tags=["sandbox-config"])
13
18
 
19
+ logger = get_logger(__name__)
14
20
 
15
21
  ### Sandbox Config Routes
16
22
 
@@ -44,6 +50,34 @@ def create_default_local_sandbox_config(
44
50
  return server.sandbox_config_manager.get_or_create_default_sandbox_config(sandbox_type=SandboxType.LOCAL, actor=actor)
45
51
 
46
52
 
53
+ @router.post("/local", response_model=PydanticSandboxConfig)
54
+ def create_custom_local_sandbox_config(
55
+ local_sandbox_config: LocalSandboxConfig,
56
+ server: SyncServer = Depends(get_letta_server),
57
+ user_id: str = Depends(get_user_id),
58
+ ):
59
+ """
60
+ Create or update a custom LocalSandboxConfig, including pip_requirements.
61
+ """
62
+ # Ensure the incoming config is of type LOCAL
63
+ if local_sandbox_config.type != SandboxType.LOCAL:
64
+ raise HTTPException(
65
+ status_code=400,
66
+ detail=f"Provided config must be of type '{SandboxType.LOCAL.value}'.",
67
+ )
68
+
69
+ # Retrieve the user (actor)
70
+ actor = server.user_manager.get_user_or_default(user_id=user_id)
71
+
72
+ # Wrap the LocalSandboxConfig into a SandboxConfigCreate
73
+ sandbox_config_create = SandboxConfigCreate(config=local_sandbox_config)
74
+
75
+ # Use the manager to create or update the sandbox config
76
+ sandbox_config = server.sandbox_config_manager.create_or_update_sandbox_config(sandbox_config_create, actor=actor)
77
+
78
+ return sandbox_config
79
+
80
+
47
81
  @router.patch("/{sandbox_config_id}", response_model=PydanticSandboxConfig)
48
82
  def update_sandbox_config(
49
83
  sandbox_config_id: str,
@@ -77,6 +111,49 @@ def list_sandbox_configs(
77
111
  return server.sandbox_config_manager.list_sandbox_configs(actor, limit=limit, after=after, sandbox_type=sandbox_type)
78
112
 
79
113
 
114
+ @router.post("/local/recreate-venv", response_model=PydanticSandboxConfig)
115
+ def force_recreate_local_sandbox_venv(
116
+ server: SyncServer = Depends(get_letta_server),
117
+ user_id: str = Depends(get_user_id),
118
+ ):
119
+ """
120
+ Forcefully recreate the virtual environment for the local sandbox.
121
+ Deletes and recreates the venv, then reinstalls required dependencies.
122
+ """
123
+ actor = server.user_manager.get_user_or_default(user_id=user_id)
124
+
125
+ # Retrieve the local sandbox config
126
+ sbx_config = server.sandbox_config_manager.get_or_create_default_sandbox_config(sandbox_type=SandboxType.LOCAL, actor=actor)
127
+
128
+ local_configs = sbx_config.get_local_config()
129
+ sandbox_dir = os.path.expanduser(local_configs.sandbox_dir) # Expand tilde
130
+ venv_path = os.path.join(sandbox_dir, local_configs.venv_name)
131
+
132
+ # Check if venv exists, and delete if necessary
133
+ if os.path.isdir(venv_path):
134
+ try:
135
+ shutil.rmtree(venv_path)
136
+ logger.info(f"Deleted existing virtual environment at: {venv_path}")
137
+ except Exception as e:
138
+ raise HTTPException(status_code=500, detail=f"Failed to delete existing venv: {e}")
139
+
140
+ # Recreate the virtual environment
141
+ try:
142
+ create_venv_for_local_sandbox(sandbox_dir_path=sandbox_dir, venv_path=str(venv_path), env=os.environ.copy(), force_recreate=True)
143
+ logger.info(f"Successfully recreated virtual environment at: {venv_path}")
144
+ except Exception as e:
145
+ raise HTTPException(status_code=500, detail=f"Failed to recreate venv: {e}")
146
+
147
+ # Install pip requirements
148
+ try:
149
+ install_pip_requirements_for_sandbox(local_configs=local_configs, env=os.environ.copy())
150
+ logger.info(f"Successfully installed pip requirements for venv at: {venv_path}")
151
+ except Exception as e:
152
+ raise HTTPException(status_code=500, detail=f"Failed to install pip requirements: {e}")
153
+
154
+ return sbx_config
155
+
156
+
80
157
  ### Sandbox Environment Variable Routes
81
158
 
82
159
 
@@ -0,0 +1,78 @@
1
+ from datetime import datetime
2
+ from typing import List, Optional
3
+
4
+ from fastapi import APIRouter, Depends, Header, HTTPException, Query
5
+
6
+ from letta.orm.errors import NoResultFound
7
+ from letta.schemas.step import Step
8
+ from letta.server.rest_api.utils import get_letta_server
9
+ from letta.server.server import SyncServer
10
+
11
+ router = APIRouter(prefix="/steps", tags=["steps"])
12
+
13
+
14
+ @router.get("", response_model=List[Step], operation_id="list_steps")
15
+ def list_steps(
16
+ before: Optional[str] = Query(None, description="Return steps before this step ID"),
17
+ after: Optional[str] = Query(None, description="Return steps after this step ID"),
18
+ limit: Optional[int] = Query(50, description="Maximum number of steps to return"),
19
+ order: Optional[str] = Query("desc", description="Sort order (asc or desc)"),
20
+ start_date: Optional[str] = Query(None, description='Return steps after this ISO datetime (e.g. "2025-01-29T15:01:19-08:00")'),
21
+ end_date: Optional[str] = Query(None, description='Return steps before this ISO datetime (e.g. "2025-01-29T15:01:19-08:00")'),
22
+ model: Optional[str] = Query(None, description="Filter by the name of the model used for the step"),
23
+ server: SyncServer = Depends(get_letta_server),
24
+ user_id: Optional[str] = Header(None, alias="user_id"),
25
+ ):
26
+ """
27
+ List steps with optional pagination and date filters.
28
+ Dates should be provided in ISO 8601 format (e.g. 2025-01-29T15:01:19-08:00)
29
+ """
30
+ actor = server.user_manager.get_user_or_default(user_id=user_id)
31
+
32
+ # Convert ISO strings to datetime objects if provided
33
+ start_dt = datetime.fromisoformat(start_date) if start_date else None
34
+ end_dt = datetime.fromisoformat(end_date) if end_date else None
35
+
36
+ return server.step_manager.list_steps(
37
+ actor=actor,
38
+ before=before,
39
+ after=after,
40
+ start_date=start_dt,
41
+ end_date=end_dt,
42
+ limit=limit,
43
+ order=order,
44
+ model=model,
45
+ )
46
+
47
+
48
+ @router.get("/{step_id}", response_model=Step, operation_id="retrieve_step")
49
+ def retrieve_step(
50
+ step_id: str,
51
+ user_id: Optional[str] = Header(None, alias="user_id"),
52
+ server: SyncServer = Depends(get_letta_server),
53
+ ):
54
+ """
55
+ Get a step by ID.
56
+ """
57
+ try:
58
+ return server.step_manager.get_step(step_id=step_id)
59
+ except NoResultFound:
60
+ raise HTTPException(status_code=404, detail="Step not found")
61
+
62
+
63
+ @router.patch("/{step_id}/transaction/{transaction_id}", response_model=Step, operation_id="update_step_transaction_id")
64
+ def update_step_transaction_id(
65
+ step_id: str,
66
+ transaction_id: str,
67
+ user_id: Optional[str] = Header(None, alias="user_id"),
68
+ server: SyncServer = Depends(get_letta_server),
69
+ ):
70
+ """
71
+ Update the transaction ID for a step.
72
+ """
73
+ actor = server.user_manager.get_user_or_default(user_id=user_id)
74
+
75
+ try:
76
+ return server.step_manager.update_step_transaction_id(actor, step_id=step_id, transaction_id=transaction_id)
77
+ except NoResultFound:
78
+ raise HTTPException(status_code=404, detail="Step not found")