letta-nightly 0.5.0.dev20241018104142__tar.gz → 0.5.0.dev20241020104030__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 (195) hide show
  1. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/PKG-INFO +2 -2
  2. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/agent.py +28 -3
  3. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/client/client.py +41 -6
  4. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/llm_api/openai.py +28 -7
  5. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/utils.py +22 -6
  6. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/metadata.py +14 -5
  7. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/letta_message.py +8 -4
  8. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/memory.py +4 -0
  9. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/message.py +3 -0
  10. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/openai/chat_completion_request.py +2 -2
  11. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/app.py +1 -0
  12. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/interface.py +15 -2
  13. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/routers/v1/agents.py +14 -6
  14. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/routers/v1/tools.py +9 -6
  15. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/server.py +30 -5
  16. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/utils.py +3 -0
  17. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/pyproject.toml +2 -2
  18. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/LICENSE +0 -0
  19. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/README.md +0 -0
  20. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/__init__.py +0 -0
  21. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/__main__.py +0 -0
  22. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/agent_store/chroma.py +0 -0
  23. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/agent_store/db.py +0 -0
  24. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/agent_store/lancedb.py +0 -0
  25. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/agent_store/milvus.py +0 -0
  26. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/agent_store/qdrant.py +0 -0
  27. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/agent_store/storage.py +0 -0
  28. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/base.py +0 -0
  29. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/benchmark/benchmark.py +0 -0
  30. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/benchmark/constants.py +0 -0
  31. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/cli/cli.py +0 -0
  32. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/cli/cli_config.py +0 -0
  33. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/cli/cli_load.py +0 -0
  34. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/client/__init__.py +0 -0
  35. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/client/admin.py +0 -0
  36. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/client/streaming.py +0 -0
  37. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/client/utils.py +0 -0
  38. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/config.py +0 -0
  39. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/constants.py +0 -0
  40. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/credentials.py +0 -0
  41. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/data_sources/connectors.py +0 -0
  42. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/data_sources/connectors_helper.py +0 -0
  43. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/embeddings.py +0 -0
  44. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/errors.py +0 -0
  45. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/functions/__init__.py +0 -0
  46. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/functions/function_sets/base.py +0 -0
  47. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/functions/function_sets/extras.py +0 -0
  48. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/functions/functions.py +0 -0
  49. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/functions/helpers.py +0 -0
  50. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/functions/schema_generator.py +0 -0
  51. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/humans/__init__.py +0 -0
  52. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/humans/examples/basic.txt +0 -0
  53. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/humans/examples/cs_phd.txt +0 -0
  54. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/interface.py +0 -0
  55. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/llm_api/__init__.py +0 -0
  56. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/llm_api/anthropic.py +0 -0
  57. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/llm_api/azure_openai.py +0 -0
  58. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/llm_api/azure_openai_constants.py +0 -0
  59. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/llm_api/cohere.py +0 -0
  60. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/llm_api/google_ai.py +0 -0
  61. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/llm_api/helpers.py +0 -0
  62. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/llm_api/llm_api_tools.py +0 -0
  63. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/llm_api/mistral.py +0 -0
  64. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/README.md +0 -0
  65. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/__init__.py +0 -0
  66. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/chat_completion_proxy.py +0 -0
  67. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/constants.py +0 -0
  68. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/function_parser.py +0 -0
  69. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/grammars/__init__.py +0 -0
  70. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/grammars/gbnf_grammar_generator.py +0 -0
  71. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/grammars/json.gbnf +0 -0
  72. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/grammars/json_func_calls_with_inner_thoughts.gbnf +0 -0
  73. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/json_parser.py +0 -0
  74. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/koboldcpp/api.py +0 -0
  75. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/koboldcpp/settings.py +0 -0
  76. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/llamacpp/api.py +0 -0
  77. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/llamacpp/settings.py +0 -0
  78. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/llm_chat_completion_wrappers/__init__.py +0 -0
  79. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/llm_chat_completion_wrappers/airoboros.py +0 -0
  80. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/llm_chat_completion_wrappers/chatml.py +0 -0
  81. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/llm_chat_completion_wrappers/configurable_wrapper.py +0 -0
  82. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/llm_chat_completion_wrappers/dolphin.py +0 -0
  83. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/llm_chat_completion_wrappers/llama3.py +0 -0
  84. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/llm_chat_completion_wrappers/simple_summary_wrapper.py +0 -0
  85. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/llm_chat_completion_wrappers/wrapper_base.py +0 -0
  86. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/llm_chat_completion_wrappers/zephyr.py +0 -0
  87. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/lmstudio/api.py +0 -0
  88. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/lmstudio/settings.py +0 -0
  89. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/ollama/api.py +0 -0
  90. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/ollama/settings.py +0 -0
  91. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/settings/__init__.py +0 -0
  92. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/settings/deterministic_mirostat.py +0 -0
  93. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/settings/settings.py +0 -0
  94. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/settings/simple.py +0 -0
  95. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/vllm/api.py +0 -0
  96. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/webui/api.py +0 -0
  97. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/webui/legacy_api.py +0 -0
  98. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/webui/legacy_settings.py +0 -0
  99. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/local_llm/webui/settings.py +0 -0
  100. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/log.py +0 -0
  101. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/main.py +0 -0
  102. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/memory.py +0 -0
  103. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/o1_agent.py +0 -0
  104. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/openai_backcompat/__init__.py +0 -0
  105. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/openai_backcompat/openai_object.py +0 -0
  106. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/persistence_manager.py +0 -0
  107. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/personas/__init__.py +0 -0
  108. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/personas/examples/anna_pa.txt +0 -0
  109. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/personas/examples/google_search_persona.txt +0 -0
  110. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/personas/examples/memgpt_doc.txt +0 -0
  111. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/personas/examples/memgpt_starter.txt +0 -0
  112. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/personas/examples/o1_persona.txt +0 -0
  113. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/personas/examples/sam.txt +0 -0
  114. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/personas/examples/sam_pov.txt +0 -0
  115. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/personas/examples/sam_simple_pov_gpt35.txt +0 -0
  116. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/personas/examples/sqldb/test.db +0 -0
  117. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/prompts/__init__.py +0 -0
  118. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/prompts/gpt_summarize.py +0 -0
  119. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/prompts/gpt_system.py +0 -0
  120. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/prompts/system/memgpt_base.txt +0 -0
  121. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/prompts/system/memgpt_chat.txt +0 -0
  122. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/prompts/system/memgpt_chat_compressed.txt +0 -0
  123. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/prompts/system/memgpt_chat_fstring.txt +0 -0
  124. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/prompts/system/memgpt_doc.txt +0 -0
  125. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/prompts/system/memgpt_gpt35_extralong.txt +0 -0
  126. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/prompts/system/memgpt_intuitive_knowledge.txt +0 -0
  127. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/prompts/system/memgpt_modified_chat.txt +0 -0
  128. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/prompts/system/memgpt_modified_o1.txt +0 -0
  129. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/providers.py +0 -0
  130. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/pytest.ini +0 -0
  131. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/agent.py +0 -0
  132. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/api_key.py +0 -0
  133. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/block.py +0 -0
  134. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/embedding_config.py +0 -0
  135. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/enums.py +0 -0
  136. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/file.py +0 -0
  137. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/health.py +0 -0
  138. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/job.py +0 -0
  139. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/letta_base.py +0 -0
  140. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/letta_request.py +0 -0
  141. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/letta_response.py +0 -0
  142. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/llm_config.py +0 -0
  143. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/openai/chat_completion_response.py +0 -0
  144. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/openai/chat_completions.py +0 -0
  145. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/openai/embedding_response.py +0 -0
  146. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/openai/openai.py +0 -0
  147. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/organization.py +0 -0
  148. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/passage.py +0 -0
  149. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/source.py +0 -0
  150. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/tool.py +0 -0
  151. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/usage.py +0 -0
  152. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/schemas/user.py +0 -0
  153. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/__init__.py +0 -0
  154. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/constants.py +0 -0
  155. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/__init__.py +0 -0
  156. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/admin/__init__.py +0 -0
  157. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/admin/agents.py +0 -0
  158. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/admin/tools.py +0 -0
  159. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/admin/users.py +0 -0
  160. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/auth/__init__.py +0 -0
  161. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/auth/index.py +0 -0
  162. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/auth_token.py +0 -0
  163. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/routers/__init__.py +0 -0
  164. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/routers/openai/__init__.py +0 -0
  165. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/routers/openai/assistants/__init__.py +0 -0
  166. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/routers/openai/assistants/assistants.py +0 -0
  167. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/routers/openai/assistants/schemas.py +0 -0
  168. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/routers/openai/assistants/threads.py +0 -0
  169. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/routers/openai/chat_completions/__init__.py +0 -0
  170. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/routers/openai/chat_completions/chat_completions.py +0 -0
  171. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/routers/v1/__init__.py +0 -0
  172. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/routers/v1/blocks.py +0 -0
  173. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/routers/v1/health.py +0 -0
  174. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/routers/v1/jobs.py +0 -0
  175. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/routers/v1/llms.py +0 -0
  176. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/routers/v1/organizations.py +0 -0
  177. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/routers/v1/sources.py +0 -0
  178. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/routers/v1/users.py +0 -0
  179. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/static_files.py +0 -0
  180. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/rest_api/utils.py +0 -0
  181. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/startup.sh +0 -0
  182. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/static_files/assets/index-3ab03d5b.css +0 -0
  183. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/static_files/assets/index-d6b3669a.js +0 -0
  184. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/static_files/favicon.ico +0 -0
  185. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/static_files/index.html +0 -0
  186. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/static_files/memgpt_logo_transparent.png +0 -0
  187. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/utils.py +0 -0
  188. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/ws_api/__init__.py +0 -0
  189. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/ws_api/example_client.py +0 -0
  190. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/ws_api/interface.py +0 -0
  191. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/ws_api/protocol.py +0 -0
  192. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/server/ws_api/server.py +0 -0
  193. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/settings.py +0 -0
  194. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/streaming_interface.py +0 -0
  195. {letta_nightly-0.5.0.dev20241018104142 → letta_nightly-0.5.0.dev20241020104030}/letta/system.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: letta-nightly
3
- Version: 0.5.0.dev20241018104142
3
+ Version: 0.5.0.dev20241020104030
4
4
  Summary: Create LLM agents with long-term memory and custom tools
5
5
  License: Apache License
6
6
  Author: Letta Team
@@ -24,7 +24,7 @@ Requires-Dist: alembic (>=1.13.3,<2.0.0)
24
24
  Requires-Dist: autoflake (>=2.3.0,<3.0.0) ; extra == "dev"
25
25
  Requires-Dist: black[jupyter] (>=24.2.0,<25.0.0) ; extra == "dev"
26
26
  Requires-Dist: chromadb (>=0.4.24,<0.5.0)
27
- Requires-Dist: composio-core (>=0.5.28,<0.6.0) ; extra == "external-tools"
27
+ Requires-Dist: composio-core (>=0.5.34,<0.6.0) ; extra == "external-tools"
28
28
  Requires-Dist: composio-langchain (>=0.5.28,<0.6.0) ; extra == "external-tools"
29
29
  Requires-Dist: crewai (>=0.41.1,<0.42.0) ; extra == "external-tools"
30
30
  Requires-Dist: crewai-tools (>=0.8.3,<0.9.0) ; extra == "external-tools"
@@ -23,7 +23,7 @@ from letta.errors import LLMError
23
23
  from letta.interface import AgentInterface
24
24
  from letta.llm_api.helpers import is_context_overflow_error
25
25
  from letta.llm_api.llm_api_tools import create
26
- from letta.local_llm.utils import num_tokens_from_messages
26
+ from letta.local_llm.utils import num_tokens_from_functions, num_tokens_from_messages
27
27
  from letta.memory import ArchivalMemory, RecallMemory, summarize_messages
28
28
  from letta.metadata import MetadataStore
29
29
  from letta.persistence_manager import LocalStateManager
@@ -33,6 +33,9 @@ from letta.schemas.embedding_config import EmbeddingConfig
33
33
  from letta.schemas.enums import MessageRole
34
34
  from letta.schemas.memory import ContextWindowOverview, Memory
35
35
  from letta.schemas.message import Message, UpdateMessage
36
+ from letta.schemas.openai.chat_completion_request import (
37
+ Tool as ChatCompletionRequestTool,
38
+ )
36
39
  from letta.schemas.openai.chat_completion_response import ChatCompletionResponse
37
40
  from letta.schemas.openai.chat_completion_response import (
38
41
  Message as ChatCompletionMessage,
@@ -500,7 +503,7 @@ class Agent(BaseAgent):
500
503
  def _handle_ai_response(
501
504
  self,
502
505
  response_message: ChatCompletionMessage, # TODO should we eventually move the Message creation outside of this function?
503
- override_tool_call_id: bool = True,
506
+ override_tool_call_id: bool = False,
504
507
  # If we are streaming, we needed to create a Message ID ahead of time,
505
508
  # and now we want to use it in the creation of the Message object
506
509
  # TODO figure out a cleaner way to do this
@@ -527,6 +530,7 @@ class Agent(BaseAgent):
527
530
 
528
531
  # generate UUID for tool call
529
532
  if override_tool_call_id or response_message.function_call:
533
+ warnings.warn("Overriding the tool call can result in inconsistent tool call IDs during streaming")
530
534
  tool_call_id = get_tool_call_id() # needs to be a string for JSON
531
535
  response_message.tool_calls[0].id = tool_call_id
532
536
  else:
@@ -1458,6 +1462,24 @@ class Agent(BaseAgent):
1458
1462
  )
1459
1463
  num_tokens_external_memory_summary = count_tokens(external_memory_summary)
1460
1464
 
1465
+ # tokens taken up by function definitions
1466
+ if self.functions:
1467
+ available_functions_definitions = [ChatCompletionRequestTool(type="function", function=f) for f in self.functions]
1468
+ num_tokens_available_functions_definitions = num_tokens_from_functions(functions=self.functions, model=self.model)
1469
+ else:
1470
+ available_functions_definitions = []
1471
+ num_tokens_available_functions_definitions = 0
1472
+
1473
+ num_tokens_used_total = (
1474
+ num_tokens_system # system prompt
1475
+ + num_tokens_available_functions_definitions # function definitions
1476
+ + num_tokens_core_memory # core memory
1477
+ + num_tokens_external_memory_summary # metadata (statistics) about recall/archival
1478
+ + num_tokens_summary_memory # summary of ongoing conversation
1479
+ + num_tokens_messages # tokens taken by messages
1480
+ )
1481
+ assert isinstance(num_tokens_used_total, int)
1482
+
1461
1483
  return ContextWindowOverview(
1462
1484
  # context window breakdown (in messages)
1463
1485
  num_messages=len(self._messages),
@@ -1466,7 +1488,7 @@ class Agent(BaseAgent):
1466
1488
  num_tokens_external_memory_summary=num_tokens_external_memory_summary,
1467
1489
  # top-level information
1468
1490
  context_window_size_max=self.agent_state.llm_config.context_window,
1469
- context_window_size_current=num_tokens_system + num_tokens_core_memory + num_tokens_summary_memory + num_tokens_messages,
1491
+ context_window_size_current=num_tokens_used_total,
1470
1492
  # context window breakdown (in tokens)
1471
1493
  num_tokens_system=num_tokens_system,
1472
1494
  system_prompt=system_prompt,
@@ -1476,6 +1498,9 @@ class Agent(BaseAgent):
1476
1498
  summary_memory=summary_memory,
1477
1499
  num_tokens_messages=num_tokens_messages,
1478
1500
  messages=self._messages,
1501
+ # related to functions
1502
+ num_tokens_functions_definitions=num_tokens_available_functions_definitions,
1503
+ functions_definitions=available_functions_definitions,
1479
1504
  )
1480
1505
 
1481
1506
 
@@ -96,6 +96,9 @@ class AbstractClient(object):
96
96
  ):
97
97
  raise NotImplementedError
98
98
 
99
+ def get_tools_from_agent(self, agent_id: str):
100
+ raise NotImplementedError
101
+
99
102
  def add_tool_to_agent(self, agent_id: str, tool_id: str):
100
103
  raise NotImplementedError
101
104
 
@@ -197,7 +200,7 @@ class AbstractClient(object):
197
200
  ) -> Tool:
198
201
  raise NotImplementedError
199
202
 
200
- def list_tools(self) -> List[Tool]:
203
+ def list_tools(self, cursor: Optional[str] = None, limit: Optional[int] = 50) -> List[Tool]:
201
204
  raise NotImplementedError
202
205
 
203
206
  def get_tool(self, id: str) -> Tool:
@@ -480,6 +483,21 @@ class RESTClient(AbstractClient):
480
483
  raise ValueError(f"Failed to update agent: {response.text}")
481
484
  return AgentState(**response.json())
482
485
 
486
+ def get_tools_from_agent(self, agent_id: str) -> List[Tool]:
487
+ """
488
+ Get tools to an existing agent
489
+
490
+ Args:
491
+ agent_id (str): ID of the agent
492
+
493
+ Returns:
494
+ List[Tool]: A List of Tool objs
495
+ """
496
+ response = requests.get(f"{self.base_url}/{self.api_prefix}/agents/{agent_id}/tools", headers=self.headers)
497
+ if response.status_code != 200:
498
+ raise ValueError(f"Failed to get tools from agents: {response.text}")
499
+ return [Tool(**tool) for tool in response.json()]
500
+
483
501
  def add_tool_to_agent(self, agent_id: str, tool_id: str):
484
502
  """
485
503
  Add tool to an existing agent
@@ -1364,14 +1382,19 @@ class RESTClient(AbstractClient):
1364
1382
  # raise ValueError(f"Failed to create tool: {response.text}")
1365
1383
  # return ToolModel(**response.json())
1366
1384
 
1367
- def list_tools(self) -> List[Tool]:
1385
+ def list_tools(self, cursor: Optional[str] = None, limit: Optional[int] = 50) -> List[Tool]:
1368
1386
  """
1369
1387
  List available tools for the user.
1370
1388
 
1371
1389
  Returns:
1372
1390
  tools (List[Tool]): List of tools
1373
1391
  """
1374
- response = requests.get(f"{self.base_url}/{self.api_prefix}/tools", headers=self.headers)
1392
+ params = {}
1393
+ if cursor:
1394
+ params["cursor"] = str(cursor)
1395
+ if limit:
1396
+ params["limit"] = limit
1397
+ response = requests.get(f"{self.base_url}/{self.api_prefix}/tools", params=params, headers=self.headers)
1375
1398
  if response.status_code != 200:
1376
1399
  raise ValueError(f"Failed to list tools: {response.text}")
1377
1400
  return [Tool(**tool) for tool in response.json()]
@@ -1692,6 +1715,19 @@ class LocalClient(AbstractClient):
1692
1715
  )
1693
1716
  return agent_state
1694
1717
 
1718
+ def get_tools_from_agent(self, agent_id: str) -> List[Tool]:
1719
+ """
1720
+ Get tools from an existing agent.
1721
+
1722
+ Args:
1723
+ agent_id (str): ID of the agent
1724
+
1725
+ Returns:
1726
+ List[Tool]: A list of Tool objs
1727
+ """
1728
+ self.interface.clear()
1729
+ return self.server.get_tools_from_agent(agent_id=agent_id, user_id=self.user_id)
1730
+
1695
1731
  def add_tool_to_agent(self, agent_id: str, tool_id: str):
1696
1732
  """
1697
1733
  Add tool to an existing agent
@@ -2250,15 +2286,14 @@ class LocalClient(AbstractClient):
2250
2286
  ToolUpdate(id=id, source_type=source_type, source_code=source_code, tags=tags, name=name), self.user_id
2251
2287
  )
2252
2288
 
2253
- def list_tools(self):
2289
+ def list_tools(self, cursor: Optional[str] = None, limit: Optional[int] = 50) -> List[Tool]:
2254
2290
  """
2255
2291
  List available tools for the user.
2256
2292
 
2257
2293
  Returns:
2258
2294
  tools (List[Tool]): List of tools
2259
2295
  """
2260
- tools = self.server.list_tools(user_id=self.user_id)
2261
- return tools
2296
+ return self.server.list_tools(cursor=cursor, limit=limit, user_id=self.user_id)
2262
2297
 
2263
2298
  def get_tool(self, id: str) -> Optional[Tool]:
2264
2299
  """
@@ -18,8 +18,13 @@ from letta.local_llm.utils import num_tokens_from_functions, num_tokens_from_mes
18
18
  from letta.schemas.llm_config import LLMConfig
19
19
  from letta.schemas.message import Message as _Message
20
20
  from letta.schemas.message import MessageRole as _MessageRole
21
+ from letta.schemas.openai.chat_completion_request import ChatCompletionRequest
21
22
  from letta.schemas.openai.chat_completion_request import (
22
- ChatCompletionRequest,
23
+ FunctionCall as ToolFunctionChoiceFunctionCall,
24
+ )
25
+ from letta.schemas.openai.chat_completion_request import (
26
+ Tool,
27
+ ToolFunctionChoice,
23
28
  cast_message_to_subtype,
24
29
  )
25
30
  from letta.schemas.openai.chat_completion_response import (
@@ -36,7 +41,7 @@ from letta.streaming_interface import (
36
41
  AgentChunkStreamingInterface,
37
42
  AgentRefreshStreamingInterface,
38
43
  )
39
- from letta.utils import smart_urljoin
44
+ from letta.utils import get_tool_call_id, smart_urljoin
40
45
 
41
46
  OPENAI_SSE_DONE = "[DONE]"
42
47
 
@@ -100,10 +105,10 @@ def openai_get_model_list(
100
105
 
101
106
  def build_openai_chat_completions_request(
102
107
  llm_config: LLMConfig,
103
- messages: List[Message],
108
+ messages: List[_Message],
104
109
  user_id: Optional[str],
105
110
  functions: Optional[list],
106
- function_call: str,
111
+ function_call: Optional[str],
107
112
  use_tool_naming: bool,
108
113
  max_tokens: Optional[int],
109
114
  ) -> ChatCompletionRequest:
@@ -124,11 +129,17 @@ def build_openai_chat_completions_request(
124
129
  model = None
125
130
 
126
131
  if use_tool_naming:
132
+ if function_call is None:
133
+ tool_choice = None
134
+ elif function_call not in ["none", "auto", "required"]:
135
+ tool_choice = ToolFunctionChoice(type="function", function=ToolFunctionChoiceFunctionCall(name=function_call))
136
+ else:
137
+ tool_choice = function_call
127
138
  data = ChatCompletionRequest(
128
139
  model=model,
129
140
  messages=openai_message_list,
130
- tools=[{"type": "function", "function": f} for f in functions] if functions else None,
131
- tool_choice=function_call,
141
+ tools=[Tool(type="function", function=f) for f in functions] if functions else None,
142
+ tool_choice=tool_choice,
132
143
  user=str(user_id),
133
144
  max_tokens=max_tokens,
134
145
  )
@@ -163,6 +174,7 @@ def openai_chat_completions_process_stream(
163
174
  stream_interface: Optional[Union[AgentChunkStreamingInterface, AgentRefreshStreamingInterface]] = None,
164
175
  create_message_id: bool = True,
165
176
  create_message_datetime: bool = True,
177
+ override_tool_call_id: bool = True,
166
178
  ) -> ChatCompletionResponse:
167
179
  """Process a streaming completion response, and return a ChatCompletionRequest at the end.
168
180
 
@@ -233,6 +245,14 @@ def openai_chat_completions_process_stream(
233
245
  ):
234
246
  assert isinstance(chat_completion_chunk, ChatCompletionChunkResponse), type(chat_completion_chunk)
235
247
 
248
+ # NOTE: this assumes that the tool call ID will only appear in one of the chunks during the stream
249
+ if override_tool_call_id:
250
+ for choice in chat_completion_chunk.choices:
251
+ if choice.delta.tool_calls and len(choice.delta.tool_calls) > 0:
252
+ for tool_call in choice.delta.tool_calls:
253
+ if tool_call.id is not None:
254
+ tool_call.id = get_tool_call_id()
255
+
236
256
  if stream_interface:
237
257
  if isinstance(stream_interface, AgentChunkStreamingInterface):
238
258
  stream_interface.process_chunk(
@@ -279,6 +299,7 @@ def openai_chat_completions_process_stream(
279
299
  else:
280
300
  accum_message.content += content_delta
281
301
 
302
+ # TODO(charles) make sure this works for parallel tool calling?
282
303
  if message_delta.tool_calls is not None:
283
304
  tool_calls_delta = message_delta.tool_calls
284
305
 
@@ -329,7 +350,7 @@ def openai_chat_completions_process_stream(
329
350
  assert all([c.finish_reason != TEMP_STREAM_FINISH_REASON for c in chat_completion_response.choices])
330
351
  assert all(
331
352
  [
332
- all([tc != TEMP_STREAM_TOOL_CALL_ID for tc in c.message.tool_calls]) if c.message.tool_calls else True
353
+ all([tc.id != TEMP_STREAM_TOOL_CALL_ID for tc in c.message.tool_calls]) if c.message.tool_calls else True
333
354
  for c in chat_completion_response.choices
334
355
  ]
335
356
  )
@@ -1,6 +1,6 @@
1
1
  import os
2
2
  import warnings
3
- from typing import List
3
+ from typing import List, Union
4
4
 
5
5
  import requests
6
6
  import tiktoken
@@ -11,6 +11,7 @@ import letta.local_llm.llm_chat_completion_wrappers.configurable_wrapper as conf
11
11
  import letta.local_llm.llm_chat_completion_wrappers.dolphin as dolphin
12
12
  import letta.local_llm.llm_chat_completion_wrappers.llama3 as llama3
13
13
  import letta.local_llm.llm_chat_completion_wrappers.zephyr as zephyr
14
+ from letta.schemas.openai.chat_completion_request import Tool, ToolCall
14
15
 
15
16
 
16
17
  def post_json_auth_request(uri, json_payload, auth_type, auth_key):
@@ -123,7 +124,7 @@ def num_tokens_from_functions(functions: List[dict], model: str = "gpt-4"):
123
124
  return num_tokens
124
125
 
125
126
 
126
- def num_tokens_from_tool_calls(tool_calls: List[dict], model: str = "gpt-4"):
127
+ def num_tokens_from_tool_calls(tool_calls: Union[List[dict], List[ToolCall]], model: str = "gpt-4"):
127
128
  """Based on above code (num_tokens_from_functions).
128
129
 
129
130
  Example to encode:
@@ -144,10 +145,25 @@ def num_tokens_from_tool_calls(tool_calls: List[dict], model: str = "gpt-4"):
144
145
 
145
146
  num_tokens = 0
146
147
  for tool_call in tool_calls:
147
- function_tokens = len(encoding.encode(tool_call["id"]))
148
- function_tokens += 2 + len(encoding.encode(tool_call["type"]))
149
- function_tokens += 2 + len(encoding.encode(tool_call["function"]["name"]))
150
- function_tokens += 2 + len(encoding.encode(tool_call["function"]["arguments"]))
148
+ if isinstance(tool_call, dict):
149
+ tool_call_id = tool_call["id"]
150
+ tool_call_type = tool_call["type"]
151
+ tool_call_function = tool_call["function"]
152
+ tool_call_function_name = tool_call_function["name"]
153
+ tool_call_function_arguments = tool_call_function["arguments"]
154
+ elif isinstance(tool_call, Tool):
155
+ tool_call_id = tool_call.id
156
+ tool_call_type = tool_call.type
157
+ tool_call_function = tool_call.function
158
+ tool_call_function_name = tool_call_function.name
159
+ tool_call_function_arguments = tool_call_function.arguments
160
+ else:
161
+ raise ValueError(f"Unknown tool call type: {type(tool_call)}")
162
+
163
+ function_tokens = len(encoding.encode(tool_call_id))
164
+ function_tokens += 2 + len(encoding.encode(tool_call_type))
165
+ function_tokens += 2 + len(encoding.encode(tool_call_function_name))
166
+ function_tokens += 2 + len(encoding.encode(tool_call_function_arguments))
151
167
 
152
168
  num_tokens += function_tokens
153
169
 
@@ -14,7 +14,9 @@ from sqlalchemy import (
14
14
  Integer,
15
15
  String,
16
16
  TypeDecorator,
17
+ asc,
17
18
  desc,
19
+ or_,
18
20
  )
19
21
  from sqlalchemy.sql import func
20
22
 
@@ -707,12 +709,19 @@ class MetadataStore:
707
709
  session.commit()
708
710
 
709
711
  @enforce_types
710
- # def list_tools(self, user_id: str) -> List[ToolModel]: # TODO: add when users can creat tools
711
- def list_tools(self, user_id: Optional[str] = None) -> List[ToolModel]:
712
+ def list_tools(self, cursor: Optional[str] = None, limit: Optional[int] = 50, user_id: Optional[str] = None) -> List[ToolModel]:
712
713
  with self.session_maker() as session:
713
- results = session.query(ToolModel).filter(ToolModel.user_id == None).all()
714
- if user_id:
715
- results += session.query(ToolModel).filter(ToolModel.user_id == user_id).all()
714
+ # Query for public tools or user-specific tools
715
+ query = session.query(ToolModel).filter(or_(ToolModel.user_id == None, ToolModel.user_id == user_id))
716
+
717
+ # Apply cursor if provided (assuming cursor is an ID)
718
+ if cursor:
719
+ query = query.filter(ToolModel.id > cursor)
720
+
721
+ # Order by ID and apply limit
722
+ results = query.order_by(asc(ToolModel.id)).limit(limit).all()
723
+
724
+ # Convert to records
716
725
  res = [r.to_record() for r in results]
717
726
  return res
718
727
 
@@ -78,12 +78,14 @@ class FunctionCall(BaseModel):
78
78
 
79
79
  name: str
80
80
  arguments: str
81
+ function_call_id: str
81
82
 
82
83
 
83
84
  class FunctionCallDelta(BaseModel):
84
85
 
85
86
  name: Optional[str]
86
87
  arguments: Optional[str]
88
+ function_call_id: Optional[str]
87
89
 
88
90
  # NOTE: this is a workaround to exclude None values from the JSON dump,
89
91
  # since the OpenAI style of returning chunks doesn't include keys with null values
@@ -129,10 +131,10 @@ class FunctionCallMessage(LettaMessage):
129
131
  @classmethod
130
132
  def validate_function_call(cls, v):
131
133
  if isinstance(v, dict):
132
- if "name" in v and "arguments" in v:
133
- return FunctionCall(name=v["name"], arguments=v["arguments"])
134
- elif "name" in v or "arguments" in v:
135
- return FunctionCallDelta(name=v.get("name"), arguments=v.get("arguments"))
134
+ if "name" in v and "arguments" in v and "function_call_id" in v:
135
+ return FunctionCall(name=v["name"], arguments=v["arguments"], function_call_id=v["function_call_id"])
136
+ elif "name" in v or "arguments" in v or "function_call_id" in v:
137
+ return FunctionCallDelta(name=v.get("name"), arguments=v.get("arguments"), function_call_id=v.get("function_call_id"))
136
138
  else:
137
139
  raise ValueError("function_call must contain either 'name' or 'arguments'")
138
140
  return v
@@ -147,11 +149,13 @@ class FunctionReturn(LettaMessage):
147
149
  status (Literal["success", "error"]): The status of the function call
148
150
  id (str): The ID of the message
149
151
  date (datetime): The date the message was created in ISO format
152
+ function_call_id (str): A unique identifier for the function call that generated this message
150
153
  """
151
154
 
152
155
  message_type: Literal["function_return"] = "function_return"
153
156
  function_return: str
154
157
  status: Literal["success", "error"]
158
+ function_call_id: str
155
159
 
156
160
 
157
161
  # Legacy Letta API had an additional type "assistant_message" and the "function_call" was a formatted string
@@ -9,6 +9,7 @@ if TYPE_CHECKING:
9
9
 
10
10
  from letta.schemas.block import Block
11
11
  from letta.schemas.message import Message
12
+ from letta.schemas.openai.chat_completion_request import Tool
12
13
 
13
14
 
14
15
  class ContextWindowOverview(BaseModel):
@@ -41,6 +42,9 @@ class ContextWindowOverview(BaseModel):
41
42
  num_tokens_summary_memory: int = Field(..., description="The number of tokens in the summary memory.")
42
43
  summary_memory: Optional[str] = Field(None, description="The content of the summary memory.")
43
44
 
45
+ num_tokens_functions_definitions: int = Field(..., description="The number of tokens in the functions definitions.")
46
+ functions_definitions: Optional[List[Tool]] = Field(..., description="The content of the functions definitions.")
47
+
44
48
  num_tokens_messages: int = Field(..., description="The number of tokens in the messages list.")
45
49
  # TODO make list of messages?
46
50
  # messages: List[dict] = Field(..., description="The messages in the context window.")
@@ -178,6 +178,7 @@ class Message(BaseMessage):
178
178
  function_call=FunctionCall(
179
179
  name=tool_call.function.name,
180
180
  arguments=tool_call.function.arguments,
181
+ function_call_id=tool_call.id,
181
182
  ),
182
183
  )
183
184
  )
@@ -203,6 +204,7 @@ class Message(BaseMessage):
203
204
  raise ValueError(f"Invalid status: {status}")
204
205
  except json.JSONDecodeError:
205
206
  raise ValueError(f"Failed to decode function return: {self.text}")
207
+ assert self.tool_call_id is not None
206
208
  messages.append(
207
209
  # TODO make sure this is what the API returns
208
210
  # function_return may not match exactly...
@@ -211,6 +213,7 @@ class Message(BaseMessage):
211
213
  date=self.created_at,
212
214
  function_return=self.text,
213
215
  status=status_enum,
216
+ function_call_id=self.tool_call_id,
214
217
  )
215
218
  )
216
219
  elif self.role == MessageRole.user:
@@ -74,7 +74,7 @@ class ToolFunctionChoice(BaseModel):
74
74
  function: FunctionCall
75
75
 
76
76
 
77
- ToolChoice = Union[Literal["none", "auto"], ToolFunctionChoice]
77
+ ToolChoice = Union[Literal["none", "auto", "required"], ToolFunctionChoice]
78
78
 
79
79
 
80
80
  ## tools ##
@@ -117,7 +117,7 @@ class ChatCompletionRequest(BaseModel):
117
117
 
118
118
  # function-calling related
119
119
  tools: Optional[List[Tool]] = None
120
- tool_choice: Optional[ToolChoice] = "none"
120
+ tool_choice: Optional[ToolChoice] = None # "none" means don't call a tool
121
121
  # deprecated scheme
122
122
  functions: Optional[List[FunctionSchema]] = None
123
123
  function_call: Optional[FunctionCallChoice] = None
@@ -70,6 +70,7 @@ def create_application() -> "FastAPI":
70
70
  title="Letta",
71
71
  summary="Create LLM agents with long-term memory and custom tools 📚🦙",
72
72
  version="1.0.0", # TODO wire this up to the version in the package
73
+ debug=True,
73
74
  )
74
75
 
75
76
  if "--ade" in sys.argv:
@@ -531,7 +531,11 @@ class StreamingServerInterface(AgentChunkStreamingInterface):
531
531
  processed_chunk = FunctionCallMessage(
532
532
  id=message_id,
533
533
  date=message_date,
534
- function_call=FunctionCallDelta(name=tool_call_delta.get("name"), arguments=tool_call_delta.get("arguments")),
534
+ function_call=FunctionCallDelta(
535
+ name=tool_call_delta.get("name"),
536
+ arguments=tool_call_delta.get("arguments"),
537
+ function_call_id=tool_call_delta.get("id"),
538
+ ),
535
539
  )
536
540
 
537
541
  else:
@@ -548,7 +552,11 @@ class StreamingServerInterface(AgentChunkStreamingInterface):
548
552
  processed_chunk = FunctionCallMessage(
549
553
  id=message_id,
550
554
  date=message_date,
551
- function_call=FunctionCallDelta(name=tool_call_delta.get("name"), arguments=tool_call_delta.get("arguments")),
555
+ function_call=FunctionCallDelta(
556
+ name=tool_call_delta.get("name"),
557
+ arguments=tool_call_delta.get("arguments"),
558
+ function_call_id=tool_call_delta.get("id"),
559
+ ),
552
560
  )
553
561
 
554
562
  elif choice.finish_reason is not None:
@@ -759,6 +767,7 @@ class StreamingServerInterface(AgentChunkStreamingInterface):
759
767
  function_call=FunctionCall(
760
768
  name=function_call.function.name,
761
769
  arguments=function_call.function.arguments,
770
+ function_call_id=function_call.id,
762
771
  ),
763
772
  )
764
773
 
@@ -786,21 +795,25 @@ class StreamingServerInterface(AgentChunkStreamingInterface):
786
795
  elif msg.startswith("Success: "):
787
796
  msg = msg.replace("Success: ", "")
788
797
  # new_message = {"function_return": msg, "status": "success"}
798
+ assert msg_obj.tool_call_id is not None
789
799
  new_message = FunctionReturn(
790
800
  id=msg_obj.id,
791
801
  date=msg_obj.created_at,
792
802
  function_return=msg,
793
803
  status="success",
804
+ function_call_id=msg_obj.tool_call_id,
794
805
  )
795
806
 
796
807
  elif msg.startswith("Error: "):
797
808
  msg = msg.replace("Error: ", "")
798
809
  # new_message = {"function_return": msg, "status": "error"}
810
+ assert msg_obj.tool_call_id is not None
799
811
  new_message = FunctionReturn(
800
812
  id=msg_obj.id,
801
813
  date=msg_obj.created_at,
802
814
  function_return=msg,
803
815
  status="error",
816
+ function_call_id=msg_obj.tool_call_id,
804
817
  )
805
818
 
806
819
  else:
@@ -27,6 +27,7 @@ from letta.schemas.memory import (
27
27
  from letta.schemas.message import Message, MessageCreate, UpdateMessage
28
28
  from letta.schemas.passage import Passage
29
29
  from letta.schemas.source import Source
30
+ from letta.schemas.tool import Tool
30
31
  from letta.server.rest_api.interface import StreamingServerInterface
31
32
  from letta.server.rest_api.utils import get_letta_server, sse_async_generator
32
33
  from letta.server.server import SyncServer
@@ -100,6 +101,17 @@ def update_agent(
100
101
  return server.update_agent(update_agent, user_id=actor.id)
101
102
 
102
103
 
104
+ @router.get("/{agent_id}/tools", response_model=List[Tool], operation_id="get_tools_from_agent")
105
+ def get_tools_from_agent(
106
+ agent_id: str,
107
+ server: "SyncServer" = Depends(get_letta_server),
108
+ user_id: Optional[str] = Header(None, alias="user_id"), # Extract user_id from header, default to None if not present
109
+ ):
110
+ """Get tools from an existing agent"""
111
+ actor = server.get_user_or_default(user_id=user_id)
112
+ return server.get_tools_from_agent(agent_id=agent_id, user_id=actor.id)
113
+
114
+
103
115
  @router.patch("/{agent_id}/add-tool/{tool_id}", response_model=AgentState, operation_id="add_tool_to_agent")
104
116
  def add_tool_to_agent(
105
117
  agent_id: str,
@@ -107,10 +119,8 @@ def add_tool_to_agent(
107
119
  server: "SyncServer" = Depends(get_letta_server),
108
120
  user_id: Optional[str] = Header(None, alias="user_id"), # Extract user_id from header, default to None if not present
109
121
  ):
110
- """Add tools to an exsiting agent"""
122
+ """Add tools to an existing agent"""
111
123
  actor = server.get_user_or_default(user_id=user_id)
112
-
113
- update_agent.id = agent_id
114
124
  return server.add_tool_to_agent(agent_id=agent_id, tool_id=tool_id, user_id=actor.id)
115
125
 
116
126
 
@@ -121,10 +131,8 @@ def remove_tool_from_agent(
121
131
  server: "SyncServer" = Depends(get_letta_server),
122
132
  user_id: Optional[str] = Header(None, alias="user_id"), # Extract user_id from header, default to None if not present
123
133
  ):
124
- """Add tools to an exsiting agent"""
134
+ """Add tools to an existing agent"""
125
135
  actor = server.get_user_or_default(user_id=user_id)
126
-
127
- update_agent.id = agent_id
128
136
  return server.remove_tool_from_agent(agent_id=agent_id, tool_id=tool_id, user_id=actor.id)
129
137
 
130
138
 
@@ -59,18 +59,21 @@ def get_tool_id(
59
59
 
60
60
  @router.get("/", response_model=List[Tool], operation_id="list_tools")
61
61
  def list_all_tools(
62
+ cursor: Optional[str] = None,
63
+ limit: Optional[int] = 50,
62
64
  server: SyncServer = Depends(get_letta_server),
63
65
  user_id: Optional[str] = Header(None, alias="user_id"), # Extract user_id from header, default to None if not present
64
66
  ):
65
67
  """
66
68
  Get a list of all tools available to agents created by a user
67
69
  """
68
- actor = server.get_user_or_default(user_id=user_id)
69
- actor.id
70
-
71
- # TODO: add back when user-specific
72
- return server.list_tools(user_id=actor.id)
73
- # return server.ms.list_tools(user_id=None)
70
+ try:
71
+ actor = server.get_user_or_default(user_id=user_id)
72
+ return server.list_tools(cursor=cursor, limit=limit, user_id=actor.id)
73
+ except Exception as e:
74
+ # Log or print the full exception here for debugging
75
+ print(f"Error occurred: {e}")
76
+ raise HTTPException(status_code=500, detail=str(e))
74
77
 
75
78
 
76
79
  @router.post("/", response_model=Tool, operation_id="create_tool")