letta-nightly 0.6.28.dev20250220163833__tar.gz → 0.6.29.dev20250221104040__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 (265) hide show
  1. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/PKG-INFO +1 -1
  2. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/__init__.py +1 -1
  3. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/agent.py +6 -1
  4. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/llm_api/helpers.py +20 -10
  5. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/llm_api/llm_api_tools.py +4 -1
  6. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/llm_api/openai.py +3 -1
  7. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/__init__.py +1 -0
  8. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/agent.py +9 -11
  9. letta_nightly-0.6.29.dev20250221104040/letta/orm/identities_agents.py +13 -0
  10. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/identity.py +26 -5
  11. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/sqlalchemy_base.py +4 -0
  12. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/agent.py +3 -5
  13. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/identity.py +26 -3
  14. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/chat_completions_interface.py +45 -21
  15. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/routers/openai/chat_completions/chat_completions.py +98 -24
  16. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/routers/v1/agents.py +9 -4
  17. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/routers/v1/identities.py +20 -10
  18. letta_nightly-0.6.29.dev20250221104040/letta/server/rest_api/utils.py +309 -0
  19. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/server.py +10 -1
  20. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/services/agent_manager.py +8 -9
  21. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/services/helpers/agent_manager_helper.py +0 -15
  22. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/services/identity_manager.py +37 -21
  23. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/streaming_interface.py +6 -2
  24. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/pyproject.toml +1 -1
  25. letta_nightly-0.6.28.dev20250220163833/letta/server/rest_api/utils.py +0 -130
  26. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/LICENSE +0 -0
  27. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/README.md +0 -0
  28. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/__main__.py +0 -0
  29. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/benchmark/benchmark.py +0 -0
  30. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/benchmark/constants.py +0 -0
  31. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/chat_only_agent.py +0 -0
  32. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/cli/cli.py +0 -0
  33. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/cli/cli_config.py +0 -0
  34. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/cli/cli_load.py +0 -0
  35. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/client/__init__.py +0 -0
  36. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/client/client.py +0 -0
  37. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/client/streaming.py +0 -0
  38. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/client/utils.py +0 -0
  39. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/config.py +0 -0
  40. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/constants.py +0 -0
  41. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/data_sources/connectors.py +0 -0
  42. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/data_sources/connectors_helper.py +0 -0
  43. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/embeddings.py +0 -0
  44. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/errors.py +0 -0
  45. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/functions/__init__.py +0 -0
  46. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/functions/ast_parsers.py +0 -0
  47. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/functions/function_sets/base.py +0 -0
  48. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/functions/function_sets/extras.py +0 -0
  49. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/functions/function_sets/multi_agent.py +0 -0
  50. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/functions/functions.py +0 -0
  51. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/functions/helpers.py +0 -0
  52. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/functions/interface.py +0 -0
  53. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/functions/schema_generator.py +0 -0
  54. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/helpers/__init__.py +0 -0
  55. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/helpers/composio_helpers.py +0 -0
  56. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/helpers/converters.py +0 -0
  57. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/helpers/datetime_helpers.py +0 -0
  58. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/helpers/json_helpers.py +0 -0
  59. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/helpers/tool_rule_solver.py +0 -0
  60. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/humans/__init__.py +0 -0
  61. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/humans/examples/basic.txt +0 -0
  62. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/humans/examples/cs_phd.txt +0 -0
  63. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/interface.py +0 -0
  64. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/llm_api/__init__.py +0 -0
  65. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/llm_api/anthropic.py +0 -0
  66. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/llm_api/aws_bedrock.py +0 -0
  67. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/llm_api/azure_openai.py +0 -0
  68. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/llm_api/azure_openai_constants.py +0 -0
  69. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/llm_api/cohere.py +0 -0
  70. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/llm_api/deepseek.py +0 -0
  71. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/llm_api/google_ai.py +0 -0
  72. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/llm_api/google_constants.py +0 -0
  73. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/llm_api/google_vertex.py +0 -0
  74. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/llm_api/mistral.py +0 -0
  75. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/README.md +0 -0
  76. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/__init__.py +0 -0
  77. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/chat_completion_proxy.py +0 -0
  78. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/constants.py +0 -0
  79. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/function_parser.py +0 -0
  80. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/grammars/__init__.py +0 -0
  81. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/grammars/gbnf_grammar_generator.py +0 -0
  82. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/grammars/json.gbnf +0 -0
  83. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/grammars/json_func_calls_with_inner_thoughts.gbnf +0 -0
  84. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/json_parser.py +0 -0
  85. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/koboldcpp/api.py +0 -0
  86. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/koboldcpp/settings.py +0 -0
  87. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/llamacpp/api.py +0 -0
  88. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/llamacpp/settings.py +0 -0
  89. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/llm_chat_completion_wrappers/__init__.py +0 -0
  90. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/llm_chat_completion_wrappers/airoboros.py +0 -0
  91. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/llm_chat_completion_wrappers/chatml.py +0 -0
  92. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/llm_chat_completion_wrappers/configurable_wrapper.py +0 -0
  93. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/llm_chat_completion_wrappers/dolphin.py +0 -0
  94. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/llm_chat_completion_wrappers/llama3.py +0 -0
  95. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/llm_chat_completion_wrappers/simple_summary_wrapper.py +0 -0
  96. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/llm_chat_completion_wrappers/wrapper_base.py +0 -0
  97. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/llm_chat_completion_wrappers/zephyr.py +0 -0
  98. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/lmstudio/api.py +0 -0
  99. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/lmstudio/settings.py +0 -0
  100. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/ollama/api.py +0 -0
  101. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/ollama/settings.py +0 -0
  102. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/settings/__init__.py +0 -0
  103. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/settings/deterministic_mirostat.py +0 -0
  104. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/settings/settings.py +0 -0
  105. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/settings/simple.py +0 -0
  106. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/utils.py +0 -0
  107. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/vllm/api.py +0 -0
  108. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/webui/api.py +0 -0
  109. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/webui/legacy_api.py +0 -0
  110. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/webui/legacy_settings.py +0 -0
  111. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/local_llm/webui/settings.py +0 -0
  112. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/log.py +0 -0
  113. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/main.py +0 -0
  114. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/memory.py +0 -0
  115. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/offline_memory_agent.py +0 -0
  116. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/openai_backcompat/__init__.py +0 -0
  117. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/openai_backcompat/openai_object.py +0 -0
  118. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/__all__.py +0 -0
  119. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/agents_tags.py +0 -0
  120. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/base.py +0 -0
  121. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/block.py +0 -0
  122. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/blocks_agents.py +0 -0
  123. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/custom_columns.py +0 -0
  124. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/enums.py +0 -0
  125. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/errors.py +0 -0
  126. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/file.py +0 -0
  127. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/job.py +0 -0
  128. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/job_messages.py +0 -0
  129. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/message.py +0 -0
  130. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/mixins.py +0 -0
  131. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/organization.py +0 -0
  132. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/passage.py +0 -0
  133. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/provider.py +0 -0
  134. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/sandbox_config.py +0 -0
  135. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/source.py +0 -0
  136. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/sources_agents.py +0 -0
  137. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/sqlite_functions.py +0 -0
  138. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/step.py +0 -0
  139. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/tool.py +0 -0
  140. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/tools_agents.py +0 -0
  141. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/orm/user.py +0 -0
  142. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/personas/__init__.py +0 -0
  143. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/personas/examples/anna_pa.txt +0 -0
  144. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/personas/examples/google_search_persona.txt +0 -0
  145. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/personas/examples/memgpt_doc.txt +0 -0
  146. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/personas/examples/memgpt_starter.txt +0 -0
  147. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/personas/examples/o1_persona.txt +0 -0
  148. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/personas/examples/offline_memory_persona.txt +0 -0
  149. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/personas/examples/sam.txt +0 -0
  150. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/personas/examples/sam_pov.txt +0 -0
  151. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/personas/examples/sam_simple_pov_gpt35.txt +0 -0
  152. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/personas/examples/sqldb/test.db +0 -0
  153. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/prompts/__init__.py +0 -0
  154. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/prompts/gpt_summarize.py +0 -0
  155. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/prompts/gpt_system.py +0 -0
  156. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/prompts/system/memgpt_base.txt +0 -0
  157. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/prompts/system/memgpt_chat.txt +0 -0
  158. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/prompts/system/memgpt_chat_compressed.txt +0 -0
  159. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/prompts/system/memgpt_chat_fstring.txt +0 -0
  160. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/prompts/system/memgpt_convo_only.txt +0 -0
  161. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/prompts/system/memgpt_doc.txt +0 -0
  162. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/prompts/system/memgpt_gpt35_extralong.txt +0 -0
  163. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/prompts/system/memgpt_intuitive_knowledge.txt +0 -0
  164. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/prompts/system/memgpt_modified_chat.txt +0 -0
  165. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/prompts/system/memgpt_modified_o1.txt +0 -0
  166. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/prompts/system/memgpt_offline_memory.txt +0 -0
  167. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/prompts/system/memgpt_offline_memory_chat.txt +0 -0
  168. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/pytest.ini +0 -0
  169. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/block.py +0 -0
  170. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/embedding_config.py +0 -0
  171. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/embedding_config_overrides.py +0 -0
  172. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/enums.py +0 -0
  173. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/environment_variables.py +0 -0
  174. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/file.py +0 -0
  175. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/health.py +0 -0
  176. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/job.py +0 -0
  177. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/letta_base.py +0 -0
  178. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/letta_message.py +0 -0
  179. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/letta_request.py +0 -0
  180. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/letta_response.py +0 -0
  181. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/llm_config.py +0 -0
  182. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/llm_config_overrides.py +0 -0
  183. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/memory.py +0 -0
  184. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/message.py +0 -0
  185. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/openai/chat_completion_request.py +0 -0
  186. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/openai/chat_completion_response.py +0 -0
  187. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/openai/chat_completions.py +0 -0
  188. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/openai/embedding_response.py +0 -0
  189. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/openai/openai.py +0 -0
  190. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/organization.py +0 -0
  191. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/passage.py +0 -0
  192. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/providers.py +0 -0
  193. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/run.py +0 -0
  194. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/sandbox_config.py +0 -0
  195. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/source.py +0 -0
  196. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/step.py +0 -0
  197. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/tool.py +0 -0
  198. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/tool_rule.py +0 -0
  199. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/usage.py +0 -0
  200. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/schemas/user.py +0 -0
  201. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/serialize_schemas/__init__.py +0 -0
  202. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/serialize_schemas/agent.py +0 -0
  203. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/serialize_schemas/base.py +0 -0
  204. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/serialize_schemas/custom_fields.py +0 -0
  205. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/serialize_schemas/message.py +0 -0
  206. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/__init__.py +0 -0
  207. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/constants.py +0 -0
  208. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/db.py +0 -0
  209. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/generate_openapi_schema.sh +0 -0
  210. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/__init__.py +0 -0
  211. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/app.py +0 -0
  212. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/auth/__init__.py +0 -0
  213. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/auth/index.py +0 -0
  214. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/auth_token.py +0 -0
  215. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/interface.py +0 -0
  216. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/optimistic_json_parser.py +0 -0
  217. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/routers/__init__.py +0 -0
  218. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/routers/openai/chat_completions/__init__.py +0 -0
  219. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/routers/v1/__init__.py +0 -0
  220. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/routers/v1/blocks.py +0 -0
  221. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/routers/v1/health.py +0 -0
  222. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/routers/v1/jobs.py +0 -0
  223. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/routers/v1/llms.py +0 -0
  224. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/routers/v1/organizations.py +0 -0
  225. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/routers/v1/providers.py +0 -0
  226. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/routers/v1/runs.py +0 -0
  227. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/routers/v1/sandbox_configs.py +0 -0
  228. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/routers/v1/sources.py +0 -0
  229. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/routers/v1/steps.py +0 -0
  230. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/routers/v1/tags.py +0 -0
  231. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/routers/v1/tools.py +0 -0
  232. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/routers/v1/users.py +0 -0
  233. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/rest_api/static_files.py +0 -0
  234. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/startup.sh +0 -0
  235. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/static_files/assets/index-048c9598.js +0 -0
  236. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/static_files/assets/index-0e31b727.css +0 -0
  237. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/static_files/favicon.ico +0 -0
  238. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/static_files/index.html +0 -0
  239. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/static_files/memgpt_logo_transparent.png +0 -0
  240. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/utils.py +0 -0
  241. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/ws_api/__init__.py +0 -0
  242. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/ws_api/example_client.py +0 -0
  243. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/ws_api/interface.py +0 -0
  244. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/ws_api/protocol.py +0 -0
  245. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/server/ws_api/server.py +0 -0
  246. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/services/__init__.py +0 -0
  247. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/services/block_manager.py +0 -0
  248. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/services/helpers/tool_execution_helper.py +0 -0
  249. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/services/job_manager.py +0 -0
  250. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/services/message_manager.py +0 -0
  251. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/services/organization_manager.py +0 -0
  252. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/services/passage_manager.py +0 -0
  253. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/services/per_agent_lock_manager.py +0 -0
  254. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/services/provider_manager.py +0 -0
  255. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/services/sandbox_config_manager.py +0 -0
  256. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/services/source_manager.py +0 -0
  257. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/services/step_manager.py +0 -0
  258. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/services/tool_execution_sandbox.py +0 -0
  259. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/services/tool_manager.py +0 -0
  260. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/services/user_manager.py +0 -0
  261. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/settings.py +0 -0
  262. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/streaming_utils.py +0 -0
  263. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/system.py +0 -0
  264. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/tracing.py +0 -0
  265. {letta_nightly-0.6.28.dev20250220163833 → letta_nightly-0.6.29.dev20250221104040}/letta/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: letta-nightly
3
- Version: 0.6.28.dev20250220163833
3
+ Version: 0.6.29.dev20250221104040
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.28"
1
+ __version__ = "0.6.29"
2
2
 
3
3
  # import clients
4
4
  from letta.client.client import LocalClient, RESTClient, create_client
@@ -322,6 +322,7 @@ class Agent(BaseAgent):
322
322
  max_delay: float = 10.0, # max delay between retries
323
323
  step_count: Optional[int] = None,
324
324
  last_function_failed: bool = False,
325
+ put_inner_thoughts_first: bool = True,
325
326
  ) -> ChatCompletionResponse:
326
327
  """Get response from LLM API with robust retry mechanism."""
327
328
  log_telemetry(self.logger, "_get_ai_reply start")
@@ -367,6 +368,7 @@ class Agent(BaseAgent):
367
368
  force_tool_call=force_tool_call,
368
369
  stream=stream,
369
370
  stream_interface=self.interface,
371
+ put_inner_thoughts_first=put_inner_thoughts_first,
370
372
  )
371
373
  log_telemetry(self.logger, "_get_ai_reply create finish")
372
374
 
@@ -648,6 +650,7 @@ class Agent(BaseAgent):
648
650
  # additional args
649
651
  chaining: bool = True,
650
652
  max_chaining_steps: Optional[int] = None,
653
+ put_inner_thoughts_first: bool = True,
651
654
  **kwargs,
652
655
  ) -> LettaUsageStatistics:
653
656
  """Run Agent.step in a loop, handling chaining via heartbeat requests and function failures"""
@@ -662,6 +665,7 @@ class Agent(BaseAgent):
662
665
  kwargs["last_function_failed"] = function_failed
663
666
  step_response = self.inner_step(
664
667
  messages=next_input_message,
668
+ put_inner_thoughts_first=put_inner_thoughts_first,
665
669
  **kwargs,
666
670
  )
667
671
 
@@ -743,9 +747,9 @@ class Agent(BaseAgent):
743
747
  metadata: Optional[dict] = None,
744
748
  summarize_attempt_count: int = 0,
745
749
  last_function_failed: bool = False,
750
+ put_inner_thoughts_first: bool = True,
746
751
  ) -> AgentStepResponse:
747
752
  """Runs a single step in the agent loop (generates at most one LLM call)"""
748
-
749
753
  try:
750
754
 
751
755
  # Extract job_id from metadata if present
@@ -778,6 +782,7 @@ class Agent(BaseAgent):
778
782
  stream=stream,
779
783
  step_count=step_count,
780
784
  last_function_failed=last_function_failed,
785
+ put_inner_thoughts_first=put_inner_thoughts_first,
781
786
  )
782
787
  if not response:
783
788
  # EDGE CASE: Function call failed AND there's no tools left for agent to call -> return early
@@ -202,21 +202,29 @@ def add_inner_thoughts_to_functions(
202
202
  inner_thoughts_key: str,
203
203
  inner_thoughts_description: str,
204
204
  inner_thoughts_required: bool = True,
205
+ put_inner_thoughts_first: bool = True,
205
206
  ) -> List[dict]:
206
207
  """Add an inner_thoughts kwarg to every function in the provided list, ensuring it's the first parameter"""
207
208
  new_functions = []
208
209
  for function_object in functions:
209
210
  new_function_object = copy.deepcopy(function_object)
210
-
211
- # Create a new OrderedDict with inner_thoughts as the first item
212
211
  new_properties = OrderedDict()
213
- new_properties[inner_thoughts_key] = {
214
- "type": "string",
215
- "description": inner_thoughts_description,
216
- }
217
212
 
218
- # Add the rest of the properties
219
- new_properties.update(function_object["parameters"]["properties"])
213
+ # For chat completions, we want inner thoughts to come later
214
+ if put_inner_thoughts_first:
215
+ # Create with inner_thoughts as the first item
216
+ new_properties[inner_thoughts_key] = {
217
+ "type": "string",
218
+ "description": inner_thoughts_description,
219
+ }
220
+ # Add the rest of the properties
221
+ new_properties.update(function_object["parameters"]["properties"])
222
+ else:
223
+ new_properties.update(function_object["parameters"]["properties"])
224
+ new_properties[inner_thoughts_key] = {
225
+ "type": "string",
226
+ "description": inner_thoughts_description,
227
+ }
220
228
 
221
229
  # Cast OrderedDict back to a regular dict
222
230
  new_function_object["parameters"]["properties"] = dict(new_properties)
@@ -225,9 +233,11 @@ def add_inner_thoughts_to_functions(
225
233
  if inner_thoughts_required:
226
234
  required_params = new_function_object["parameters"].get("required", [])
227
235
  if inner_thoughts_key not in required_params:
228
- required_params.insert(0, inner_thoughts_key)
236
+ if put_inner_thoughts_first:
237
+ required_params.insert(0, inner_thoughts_key)
238
+ else:
239
+ required_params.append(inner_thoughts_key)
229
240
  new_function_object["parameters"]["required"] = required_params
230
-
231
241
  new_functions.append(new_function_object)
232
242
 
233
243
  return new_functions
@@ -140,6 +140,7 @@ def create(
140
140
  stream: bool = False,
141
141
  stream_interface: Optional[Union[AgentRefreshStreamingInterface, AgentChunkStreamingInterface]] = None,
142
142
  model_settings: Optional[dict] = None, # TODO: eventually pass from server
143
+ put_inner_thoughts_first: bool = True,
143
144
  ) -> ChatCompletionResponse:
144
145
  """Return response to chat completion with backoff"""
145
146
  from letta.utils import printd
@@ -185,7 +186,9 @@ def create(
185
186
  else:
186
187
  function_call = "required"
187
188
 
188
- data = build_openai_chat_completions_request(llm_config, messages, user_id, functions, function_call, use_tool_naming)
189
+ data = build_openai_chat_completions_request(
190
+ llm_config, messages, user_id, functions, function_call, use_tool_naming, put_inner_thoughts_first=put_inner_thoughts_first
191
+ )
189
192
  if stream: # Client requested token streaming
190
193
  data.stream = True
191
194
  assert isinstance(stream_interface, AgentChunkStreamingInterface) or isinstance(
@@ -94,6 +94,7 @@ def build_openai_chat_completions_request(
94
94
  functions: Optional[list],
95
95
  function_call: Optional[str],
96
96
  use_tool_naming: bool,
97
+ put_inner_thoughts_first: bool = True,
97
98
  ) -> ChatCompletionRequest:
98
99
  if functions and llm_config.put_inner_thoughts_in_kwargs:
99
100
  # Special case for LM Studio backend since it needs extra guidance to force out the thoughts first
@@ -105,6 +106,7 @@ def build_openai_chat_completions_request(
105
106
  functions=functions,
106
107
  inner_thoughts_key=INNER_THOUGHTS_KWARG,
107
108
  inner_thoughts_description=inner_thoughts_desc,
109
+ put_inner_thoughts_first=put_inner_thoughts_first,
108
110
  )
109
111
 
110
112
  openai_message_list = [
@@ -390,7 +392,7 @@ def openai_chat_completions_process_stream(
390
392
  chat_completion_response.usage.completion_tokens = n_chunks
391
393
  chat_completion_response.usage.total_tokens = prompt_tokens + n_chunks
392
394
 
393
- assert len(chat_completion_response.choices) > 0, chat_completion_response
395
+ assert len(chat_completion_response.choices) > 0, f"No response from provider {chat_completion_response}"
394
396
 
395
397
  # printd(chat_completion_response)
396
398
  return chat_completion_response
@@ -4,6 +4,7 @@ from letta.orm.base import Base
4
4
  from letta.orm.block import Block
5
5
  from letta.orm.blocks_agents import BlocksAgents
6
6
  from letta.orm.file import FileMetadata
7
+ from letta.orm.identities_agents import IdentitiesAgents
7
8
  from letta.orm.identity import Identity
8
9
  from letta.orm.job import Job
9
10
  from letta.orm.job_messages import JobMessage
@@ -1,7 +1,7 @@
1
1
  import uuid
2
2
  from typing import TYPE_CHECKING, List, Optional
3
3
 
4
- from sqlalchemy import JSON, Boolean, ForeignKey, Index, String
4
+ from sqlalchemy import JSON, Boolean, Index, String
5
5
  from sqlalchemy.orm import Mapped, mapped_column, relationship
6
6
 
7
7
  from letta.orm.block import Block
@@ -61,14 +61,6 @@ class Agent(SqlalchemyBase, OrganizationMixin):
61
61
  template_id: Mapped[Optional[str]] = mapped_column(String, nullable=True, doc="The id of the template the agent belongs to.")
62
62
  base_template_id: Mapped[Optional[str]] = mapped_column(String, nullable=True, doc="The base template id of the agent.")
63
63
 
64
- # Identity
65
- identity_id: Mapped[Optional[str]] = mapped_column(
66
- String, ForeignKey("identities.id", ondelete="CASCADE"), nullable=True, doc="The id of the identity the agent belongs to."
67
- )
68
- identifier_key: Mapped[Optional[str]] = mapped_column(
69
- String, nullable=True, doc="The identifier key of the identity the agent belongs to."
70
- )
71
-
72
64
  # Tool rules
73
65
  tool_rules: Mapped[Optional[List[ToolRule]]] = mapped_column(ToolRulesColumn, doc="the tool rules for this agent.")
74
66
 
@@ -79,7 +71,6 @@ class Agent(SqlalchemyBase, OrganizationMixin):
79
71
 
80
72
  # relationships
81
73
  organization: Mapped["Organization"] = relationship("Organization", back_populates="agents")
82
- identity: Mapped["Identity"] = relationship("Identity", back_populates="agents")
83
74
  tool_exec_environment_variables: Mapped[List["AgentEnvironmentVariable"]] = relationship(
84
75
  "AgentEnvironmentVariable",
85
76
  back_populates="agent",
@@ -130,7 +121,13 @@ class Agent(SqlalchemyBase, OrganizationMixin):
130
121
  viewonly=True, # Ensures SQLAlchemy doesn't attempt to manage this relationship
131
122
  doc="All passages derived created by this agent.",
132
123
  )
133
- identity: Mapped[Optional["Identity"]] = relationship("Identity", back_populates="agents")
124
+ identities: Mapped[List["Identity"]] = relationship(
125
+ "Identity",
126
+ secondary="identities_agents",
127
+ lazy="selectin",
128
+ back_populates="agents",
129
+ passive_deletes=True,
130
+ )
134
131
 
135
132
  def to_pydantic(self) -> PydanticAgentState:
136
133
  """converts to the basic pydantic model counterpart"""
@@ -160,6 +157,7 @@ class Agent(SqlalchemyBase, OrganizationMixin):
160
157
  "project_id": self.project_id,
161
158
  "template_id": self.template_id,
162
159
  "base_template_id": self.base_template_id,
160
+ "identity_ids": [identity.id for identity in self.identities],
163
161
  "message_buffer_autoclear": self.message_buffer_autoclear,
164
162
  }
165
163
 
@@ -0,0 +1,13 @@
1
+ from sqlalchemy import ForeignKey, String
2
+ from sqlalchemy.orm import Mapped, mapped_column
3
+
4
+ from letta.orm.base import Base
5
+
6
+
7
+ class IdentitiesAgents(Base):
8
+ """Identities may have one or many agents associated with them."""
9
+
10
+ __tablename__ = "identities_agents"
11
+
12
+ identity_id: Mapped[str] = mapped_column(String, ForeignKey("identities.id", ondelete="CASCADE"), primary_key=True)
13
+ agent_id: Mapped[str] = mapped_column(String, ForeignKey("agents.id", ondelete="CASCADE"), primary_key=True)
@@ -2,11 +2,13 @@ import uuid
2
2
  from typing import List, Optional
3
3
 
4
4
  from sqlalchemy import String, UniqueConstraint
5
+ from sqlalchemy.dialects.postgresql import JSONB
5
6
  from sqlalchemy.orm import Mapped, mapped_column, relationship
6
7
 
7
8
  from letta.orm.mixins import OrganizationMixin
8
9
  from letta.orm.sqlalchemy_base import SqlalchemyBase
9
10
  from letta.schemas.identity import Identity as PydanticIdentity
11
+ from letta.schemas.identity import IdentityProperty
10
12
 
11
13
 
12
14
  class Identity(SqlalchemyBase, OrganizationMixin):
@@ -14,17 +16,35 @@ class Identity(SqlalchemyBase, OrganizationMixin):
14
16
 
15
17
  __tablename__ = "identities"
16
18
  __pydantic_model__ = PydanticIdentity
17
- __table_args__ = (UniqueConstraint("identifier_key", "project_id", "organization_id", name="unique_identifier_pid_org_id"),)
19
+ __table_args__ = (
20
+ UniqueConstraint(
21
+ "identifier_key",
22
+ "project_id",
23
+ "organization_id",
24
+ name="unique_identifier_without_project",
25
+ postgresql_nulls_not_distinct=True,
26
+ ),
27
+ )
18
28
 
19
29
  id: Mapped[str] = mapped_column(String, primary_key=True, default=lambda: f"identity-{uuid.uuid4()}")
20
30
  identifier_key: Mapped[str] = mapped_column(nullable=False, doc="External, user-generated identifier key of the identity.")
21
31
  name: Mapped[str] = mapped_column(nullable=False, doc="The name of the identity.")
22
32
  identity_type: Mapped[str] = mapped_column(nullable=False, doc="The type of the identity.")
23
33
  project_id: Mapped[Optional[str]] = mapped_column(nullable=True, doc="The project id of the identity.")
34
+ properties: Mapped[List["IdentityProperty"]] = mapped_column(
35
+ JSONB, nullable=False, default=list, doc="List of properties associated with the identity"
36
+ )
24
37
 
25
38
  # relationships
26
39
  organization: Mapped["Organization"] = relationship("Organization", back_populates="identities")
27
- agents: Mapped[List["Agent"]] = relationship("Agent", lazy="selectin", back_populates="identity")
40
+ agents: Mapped[List["Agent"]] = relationship(
41
+ "Agent", secondary="identities_agents", lazy="selectin", passive_deletes=True, back_populates="identities"
42
+ )
43
+
44
+ @property
45
+ def agent_ids(self) -> List[str]:
46
+ """Get just the agent IDs without loading the full agent objects"""
47
+ return [agent.id for agent in self.agents]
28
48
 
29
49
  def to_pydantic(self) -> PydanticIdentity:
30
50
  state = {
@@ -33,7 +53,8 @@ class Identity(SqlalchemyBase, OrganizationMixin):
33
53
  "name": self.name,
34
54
  "identity_type": self.identity_type,
35
55
  "project_id": self.project_id,
36
- "agents": [agent.to_pydantic() for agent in self.agents],
56
+ "agent_ids": self.agent_ids,
57
+ "organization_id": self.organization_id,
58
+ "properties": self.properties,
37
59
  }
38
-
39
- return self.__pydantic_model__(**state)
60
+ return PydanticIdentity(**state)
@@ -68,6 +68,7 @@ class SqlalchemyBase(CommonSqlalchemyMetaMixins, Base):
68
68
  access_type: AccessType = AccessType.ORGANIZATION,
69
69
  join_model: Optional[Base] = None,
70
70
  join_conditions: Optional[Union[Tuple, List]] = None,
71
+ identifier_keys: Optional[List[str]] = None,
71
72
  **kwargs,
72
73
  ) -> List["SqlalchemyBase"]:
73
74
  """
@@ -143,6 +144,9 @@ class SqlalchemyBase(CommonSqlalchemyMetaMixins, Base):
143
144
  # Group by primary key and all necessary columns to avoid JSON comparison
144
145
  query = query.group_by(cls.id)
145
146
 
147
+ if identifier_keys and hasattr(cls, "identities"):
148
+ query = query.join(cls.identities).filter(cls.identities.property.mapper.class_.identifier_key.in_(identifier_keys))
149
+
146
150
  # Apply filtering logic from kwargs
147
151
  for key, value in kwargs.items():
148
152
  if "." in key:
@@ -83,9 +83,7 @@ class AgentState(OrmMetadataBase, validate_assignment=True):
83
83
  project_id: Optional[str] = Field(None, description="The id of the project the agent belongs to.")
84
84
  template_id: Optional[str] = Field(None, description="The id of the template the agent belongs to.")
85
85
  base_template_id: Optional[str] = Field(None, description="The base template id of the agent.")
86
-
87
- # Identity
88
- identifier_key: Optional[str] = Field(None, description="The identifier key belonging to the identity associated with this agent.")
86
+ identity_ids: List[str] = Field([], description="The ids of the identities associated with this agent.")
89
87
 
90
88
  # An advanced configuration that makes it so this agent does not remember any previous messages
91
89
  message_buffer_autoclear: bool = Field(
@@ -161,7 +159,7 @@ class CreateAgent(BaseModel, validate_assignment=True): #
161
159
  project_id: Optional[str] = Field(None, description="The id of the project the agent belongs to.")
162
160
  template_id: Optional[str] = Field(None, description="The id of the template the agent belongs to.")
163
161
  base_template_id: Optional[str] = Field(None, description="The base template id of the agent.")
164
- identifier_key: Optional[str] = Field(None, description="The identifier key belonging to the identity associated with this agent.")
162
+ identity_ids: Optional[List[str]] = Field(None, description="The ids of the identities associated with this agent.")
165
163
  message_buffer_autoclear: bool = Field(
166
164
  False,
167
165
  description="If set to True, the agent will not remember previous messages (though the agent will still retain state via core memory blocks and archival/recall memory). Not recommended unless you have an advanced use case.",
@@ -236,7 +234,7 @@ class UpdateAgent(BaseModel):
236
234
  project_id: Optional[str] = Field(None, description="The id of the project the agent belongs to.")
237
235
  template_id: Optional[str] = Field(None, description="The id of the template the agent belongs to.")
238
236
  base_template_id: Optional[str] = Field(None, description="The base template id of the agent.")
239
- identifier_key: Optional[str] = Field(None, description="The identifier key belonging to the identity associated with this agent.")
237
+ identity_ids: Optional[List[str]] = Field(None, description="The ids of the identities associated with this agent.")
240
238
  message_buffer_autoclear: Optional[bool] = Field(
241
239
  None,
242
240
  description="If set to True, the agent will not remember previous messages (though the agent will still retain state via core memory blocks and archival/recall memory). Not recommended unless you have an advanced use case.",
@@ -1,9 +1,8 @@
1
1
  from enum import Enum
2
- from typing import List, Optional
2
+ from typing import List, Optional, Union
3
3
 
4
4
  from pydantic import Field
5
5
 
6
- from letta.schemas.agent import AgentState
7
6
  from letta.schemas.letta_base import LettaBase
8
7
 
9
8
 
@@ -17,17 +16,38 @@ class IdentityType(str, Enum):
17
16
  other = "other"
18
17
 
19
18
 
19
+ class IdentityPropertyType(str, Enum):
20
+ """
21
+ Enum to represent the type of the identity property.
22
+ """
23
+
24
+ string = "string"
25
+ number = "number"
26
+ boolean = "boolean"
27
+ json = "json"
28
+
29
+
20
30
  class IdentityBase(LettaBase):
21
31
  __id_prefix__ = "identity"
22
32
 
23
33
 
34
+ class IdentityProperty(LettaBase):
35
+ """A property of an identity"""
36
+
37
+ key: str = Field(..., description="The key of the property")
38
+ value: Union[str, int, float, bool, dict] = Field(..., description="The value of the property")
39
+ type: IdentityPropertyType = Field(..., description="The type of the property")
40
+
41
+
24
42
  class Identity(IdentityBase):
25
43
  id: str = IdentityBase.generate_id_field()
26
44
  identifier_key: str = Field(..., description="External, user-generated identifier key of the identity.")
27
45
  name: str = Field(..., description="The name of the identity.")
28
46
  identity_type: IdentityType = Field(..., description="The type of the identity.")
29
47
  project_id: Optional[str] = Field(None, description="The project id of the identity, if applicable.")
30
- agents: List[AgentState] = Field(..., description="The agents associated with the identity.")
48
+ agent_ids: List[str] = Field(..., description="The IDs of the agents associated with the identity.")
49
+ organization_id: Optional[str] = Field(None, description="The organization id of the user")
50
+ properties: List[IdentityProperty] = Field(default_factory=list, description="List of properties associated with the identity")
31
51
 
32
52
 
33
53
  class IdentityCreate(LettaBase):
@@ -36,9 +56,12 @@ class IdentityCreate(LettaBase):
36
56
  identity_type: IdentityType = Field(..., description="The type of the identity.")
37
57
  project_id: Optional[str] = Field(None, description="The project id of the identity, if applicable.")
38
58
  agent_ids: Optional[List[str]] = Field(None, description="The agent ids that are associated with the identity.")
59
+ properties: Optional[List[IdentityProperty]] = Field(None, description="List of properties associated with the identity.")
39
60
 
40
61
 
41
62
  class IdentityUpdate(LettaBase):
63
+ identifier_key: Optional[str] = Field(None, description="External, user-generated identifier key of the identity.")
42
64
  name: Optional[str] = Field(None, description="The name of the identity.")
43
65
  identity_type: Optional[IdentityType] = Field(None, description="The type of the identity.")
44
66
  agent_ids: Optional[List[str]] = Field(None, description="The agent ids that are associated with the identity.")
67
+ properties: Optional[List[IdentityProperty]] = Field(None, description="List of properties associated with the identity.")
@@ -56,6 +56,7 @@ class ChatCompletionsStreamingInterface(AgentChunkStreamingInterface):
56
56
  self.current_function_name = ""
57
57
  self.current_function_arguments = []
58
58
  self.current_json_parse_result = {}
59
+ self._found_message_tool_kwarg = False
59
60
 
60
61
  # Internal chunk buffer and event for async notification
61
62
  self._chunks = deque()
@@ -153,12 +154,13 @@ class ChatCompletionsStreamingInterface(AgentChunkStreamingInterface):
153
154
  """No-op retained for interface compatibility."""
154
155
  return
155
156
 
156
- def process_chunk(self, chunk: ChatCompletionChunkResponse, message_id: str, message_date: datetime) -> None:
157
+ def process_chunk(
158
+ self, chunk: ChatCompletionChunkResponse, message_id: str, message_date: datetime, expect_reasoning_content: bool = False
159
+ ) -> None:
157
160
  """
158
161
  Called externally with a ChatCompletionChunkResponse. Transforms
159
162
  it if necessary, then enqueues partial messages for streaming back.
160
163
  """
161
- # print("RECEIVED CHUNK...")
162
164
  processed_chunk = self._process_chunk_to_openai_style(chunk)
163
165
  if processed_chunk is not None:
164
166
  self._push_to_buffer(processed_chunk)
@@ -197,6 +199,10 @@ class ChatCompletionsStreamingInterface(AgentChunkStreamingInterface):
197
199
  content (especially from a 'send_message' tool) is exposed as text
198
200
  deltas in 'content'. Otherwise, pass through or yield finish reasons.
199
201
  """
202
+ # If we've already sent the final chunk, ignore everything.
203
+ if self._found_message_tool_kwarg:
204
+ return None
205
+
200
206
  choice = chunk.choices[0]
201
207
  delta = choice.delta
202
208
 
@@ -219,25 +225,43 @@ class ChatCompletionsStreamingInterface(AgentChunkStreamingInterface):
219
225
  combined_args = "".join(self.current_function_arguments)
220
226
  parsed_args = OptimisticJSONParser().parse(combined_args)
221
227
 
222
- # If the parsed result is different
223
- # This is an edge case we need to consider. E.g. if the last streamed token is '}', we shouldn't stream that out
224
- if parsed_args != self.current_json_parse_result:
225
- self.current_json_parse_result = parsed_args
226
- # If we can see a "message" field, return it as partial content
227
- if self.assistant_message_tool_kwarg in parsed_args and parsed_args[self.assistant_message_tool_kwarg]:
228
- return ChatCompletionChunk(
229
- id=chunk.id,
230
- object=chunk.object,
231
- created=chunk.created.timestamp(),
232
- model=chunk.model,
233
- choices=[
234
- Choice(
235
- index=choice.index,
236
- delta=ChoiceDelta(content=self.current_function_arguments[-1], role=self.ASSISTANT_STR),
237
- finish_reason=None,
238
- )
239
- ],
240
- )
228
+ # TODO: Make this less brittle! This depends on `message` coming first!
229
+ # This is a heuristic we use to know if we're done with the `message` part of `send_message`
230
+ if len(parsed_args.keys()) > 1:
231
+ self._found_message_tool_kwarg = True
232
+ return ChatCompletionChunk(
233
+ id=chunk.id,
234
+ object=chunk.object,
235
+ created=chunk.created.timestamp(),
236
+ model=chunk.model,
237
+ choices=[
238
+ Choice(
239
+ index=choice.index,
240
+ delta=ChoiceDelta(),
241
+ finish_reason="stop",
242
+ )
243
+ ],
244
+ )
245
+ else:
246
+ # If the parsed result is different
247
+ # This is an edge case we need to consider. E.g. if the last streamed token is '}', we shouldn't stream that out
248
+ if parsed_args != self.current_json_parse_result:
249
+ self.current_json_parse_result = parsed_args
250
+ # If we can see a "message" field, return it as partial content
251
+ if self.assistant_message_tool_kwarg in parsed_args and parsed_args[self.assistant_message_tool_kwarg]:
252
+ return ChatCompletionChunk(
253
+ id=chunk.id,
254
+ object=chunk.object,
255
+ created=chunk.created.timestamp(),
256
+ model=chunk.model,
257
+ choices=[
258
+ Choice(
259
+ index=choice.index,
260
+ delta=ChoiceDelta(content=self.current_function_arguments[-1], role=self.ASSISTANT_STR),
261
+ finish_reason=None,
262
+ )
263
+ ],
264
+ )
241
265
 
242
266
  # If there's a finish reason, pass that along
243
267
  if choice.finish_reason is not None: