letta-nightly 0.1.7.dev20240930104151__tar.gz → 0.1.7.dev20241002104051__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 (189) hide show
  1. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/PKG-INFO +13 -9
  2. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/README.md +4 -4
  3. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/agent.py +19 -53
  4. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/cli/cli.py +0 -1
  5. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/cli/cli_load.py +0 -50
  6. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/client/client.py +1 -1
  7. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/config.py +3 -10
  8. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/functions/functions.py +1 -24
  9. letta_nightly-0.1.7.dev20241002104051/letta/functions/helpers.py +191 -0
  10. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/functions/schema_generator.py +2 -42
  11. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/tool.py +9 -9
  12. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/server.py +1 -18
  13. letta_nightly-0.1.7.dev20240930104151/letta/server/static_files/assets/index-0cbf7ad5.js → letta_nightly-0.1.7.dev20241002104051/letta/server/static_files/assets/index-4d08d8a3.js +75 -75
  14. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/static_files/index.html +1 -1
  15. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/pyproject.toml +6 -2
  16. letta_nightly-0.1.7.dev20240930104151/letta/server/static_files/assets/index-486e3228.js +0 -274
  17. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/LICENSE +0 -0
  18. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/__init__.py +0 -0
  19. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/__main__.py +0 -0
  20. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/agent_store/chroma.py +0 -0
  21. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/agent_store/db.py +0 -0
  22. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/agent_store/lancedb.py +0 -0
  23. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/agent_store/milvus.py +0 -0
  24. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/agent_store/qdrant.py +0 -0
  25. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/agent_store/storage.py +0 -0
  26. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/benchmark/benchmark.py +0 -0
  27. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/benchmark/constants.py +0 -0
  28. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/cli/cli_config.py +0 -0
  29. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/client/__init__.py +0 -0
  30. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/client/admin.py +0 -0
  31. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/client/streaming.py +0 -0
  32. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/client/utils.py +0 -0
  33. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/configs/anthropic.json +0 -0
  34. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/configs/letta_hosted.json +0 -0
  35. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/configs/openai.json +0 -0
  36. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/constants.py +0 -0
  37. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/credentials.py +0 -0
  38. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/data_sources/connectors.py +0 -0
  39. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/embeddings.py +0 -0
  40. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/errors.py +0 -0
  41. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/functions/__init__.py +0 -0
  42. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/functions/function_sets/base.py +0 -0
  43. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/functions/function_sets/extras.py +0 -0
  44. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/humans/__init__.py +0 -0
  45. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/humans/examples/basic.txt +0 -0
  46. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/humans/examples/cs_phd.txt +0 -0
  47. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/interface.py +0 -0
  48. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/llm_api/__init__.py +0 -0
  49. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/llm_api/anthropic.py +0 -0
  50. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/llm_api/azure_openai.py +0 -0
  51. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/llm_api/cohere.py +0 -0
  52. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/llm_api/google_ai.py +0 -0
  53. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/llm_api/llm_api_tools.py +0 -0
  54. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/llm_api/openai.py +0 -0
  55. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/README.md +0 -0
  56. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/__init__.py +0 -0
  57. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/chat_completion_proxy.py +0 -0
  58. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/constants.py +0 -0
  59. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/function_parser.py +0 -0
  60. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/grammars/__init__.py +0 -0
  61. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/grammars/gbnf_grammar_generator.py +0 -0
  62. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/grammars/json.gbnf +0 -0
  63. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/grammars/json_func_calls_with_inner_thoughts.gbnf +0 -0
  64. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/groq/api.py +0 -0
  65. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/json_parser.py +0 -0
  66. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/koboldcpp/api.py +0 -0
  67. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/koboldcpp/settings.py +0 -0
  68. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/llamacpp/api.py +0 -0
  69. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/llamacpp/settings.py +0 -0
  70. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/llm_chat_completion_wrappers/__init__.py +0 -0
  71. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/llm_chat_completion_wrappers/airoboros.py +0 -0
  72. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/llm_chat_completion_wrappers/chatml.py +0 -0
  73. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/llm_chat_completion_wrappers/configurable_wrapper.py +0 -0
  74. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/llm_chat_completion_wrappers/dolphin.py +0 -0
  75. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/llm_chat_completion_wrappers/llama3.py +0 -0
  76. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/llm_chat_completion_wrappers/simple_summary_wrapper.py +0 -0
  77. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/llm_chat_completion_wrappers/wrapper_base.py +0 -0
  78. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/llm_chat_completion_wrappers/zephyr.py +0 -0
  79. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/lmstudio/api.py +0 -0
  80. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/lmstudio/settings.py +0 -0
  81. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/ollama/api.py +0 -0
  82. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/ollama/settings.py +0 -0
  83. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/settings/__init__.py +0 -0
  84. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/settings/deterministic_mirostat.py +0 -0
  85. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/settings/settings.py +0 -0
  86. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/settings/simple.py +0 -0
  87. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/utils.py +0 -0
  88. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/vllm/api.py +0 -0
  89. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/webui/api.py +0 -0
  90. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/webui/legacy_api.py +0 -0
  91. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/webui/legacy_settings.py +0 -0
  92. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/local_llm/webui/settings.py +0 -0
  93. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/log.py +0 -0
  94. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/main.py +0 -0
  95. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/memory.py +0 -0
  96. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/metadata.py +0 -0
  97. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/openai_backcompat/__init__.py +0 -0
  98. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/openai_backcompat/openai_object.py +0 -0
  99. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/persistence_manager.py +0 -0
  100. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/personas/__init__.py +0 -0
  101. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/personas/examples/anna_pa.txt +0 -0
  102. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/personas/examples/google_search_persona.txt +0 -0
  103. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/personas/examples/memgpt_doc.txt +0 -0
  104. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/personas/examples/memgpt_starter.txt +0 -0
  105. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/personas/examples/sam.txt +0 -0
  106. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/personas/examples/sam_pov.txt +0 -0
  107. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/personas/examples/sam_simple_pov_gpt35.txt +0 -0
  108. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/personas/examples/sqldb/test.db +0 -0
  109. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/prompts/__init__.py +0 -0
  110. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/prompts/gpt_summarize.py +0 -0
  111. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/prompts/gpt_system.py +0 -0
  112. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/prompts/system/memgpt_base.txt +0 -0
  113. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/prompts/system/memgpt_chat.txt +0 -0
  114. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/prompts/system/memgpt_chat_compressed.txt +0 -0
  115. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/prompts/system/memgpt_chat_fstring.txt +0 -0
  116. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/prompts/system/memgpt_doc.txt +0 -0
  117. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/prompts/system/memgpt_gpt35_extralong.txt +0 -0
  118. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/prompts/system/memgpt_intuitive_knowledge.txt +0 -0
  119. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/prompts/system/memgpt_modified_chat.txt +0 -0
  120. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/pytest.ini +0 -0
  121. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/agent.py +0 -0
  122. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/api_key.py +0 -0
  123. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/block.py +0 -0
  124. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/document.py +0 -0
  125. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/embedding_config.py +0 -0
  126. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/enums.py +0 -0
  127. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/job.py +0 -0
  128. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/letta_base.py +0 -0
  129. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/letta_message.py +0 -0
  130. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/letta_request.py +0 -0
  131. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/letta_response.py +0 -0
  132. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/llm_config.py +0 -0
  133. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/memory.py +0 -0
  134. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/message.py +0 -0
  135. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/openai/chat_completion_request.py +0 -0
  136. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/openai/chat_completion_response.py +0 -0
  137. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/openai/chat_completions.py +0 -0
  138. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/openai/embedding_response.py +0 -0
  139. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/openai/openai.py +0 -0
  140. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/organization.py +0 -0
  141. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/passage.py +0 -0
  142. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/source.py +0 -0
  143. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/usage.py +0 -0
  144. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/schemas/user.py +0 -0
  145. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/__init__.py +0 -0
  146. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/constants.py +0 -0
  147. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/__init__.py +0 -0
  148. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/admin/__init__.py +0 -0
  149. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/admin/agents.py +0 -0
  150. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/admin/tools.py +0 -0
  151. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/admin/users.py +0 -0
  152. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/app.py +0 -0
  153. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/auth/__init__.py +0 -0
  154. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/auth/index.py +0 -0
  155. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/auth_token.py +0 -0
  156. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/interface.py +0 -0
  157. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/routers/__init__.py +0 -0
  158. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/routers/openai/__init__.py +0 -0
  159. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/routers/openai/assistants/__init__.py +0 -0
  160. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/routers/openai/assistants/assistants.py +0 -0
  161. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/routers/openai/assistants/schemas.py +0 -0
  162. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/routers/openai/assistants/threads.py +0 -0
  163. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/routers/openai/chat_completions/__init__.py +0 -0
  164. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/routers/openai/chat_completions/chat_completions.py +0 -0
  165. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/routers/v1/__init__.py +0 -0
  166. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/routers/v1/agents.py +0 -0
  167. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/routers/v1/blocks.py +0 -0
  168. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/routers/v1/jobs.py +0 -0
  169. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/routers/v1/llms.py +0 -0
  170. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/routers/v1/organizations.py +0 -0
  171. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/routers/v1/sources.py +0 -0
  172. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/routers/v1/tools.py +0 -0
  173. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/routers/v1/users.py +0 -0
  174. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/static_files.py +0 -0
  175. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/rest_api/utils.py +0 -0
  176. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/startup.sh +0 -0
  177. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/static_files/assets/index-156816da.css +0 -0
  178. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/static_files/favicon.ico +0 -0
  179. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/static_files/memgpt_logo_transparent.png +0 -0
  180. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/utils.py +0 -0
  181. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/ws_api/__init__.py +0 -0
  182. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/ws_api/example_client.py +0 -0
  183. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/ws_api/interface.py +0 -0
  184. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/ws_api/protocol.py +0 -0
  185. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/server/ws_api/server.py +0 -0
  186. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/settings.py +0 -0
  187. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/streaming_interface.py +0 -0
  188. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/system.py +0 -0
  189. {letta_nightly-0.1.7.dev20240930104151 → letta_nightly-0.1.7.dev20241002104051}/letta/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: letta-nightly
3
- Version: 0.1.7.dev20240930104151
3
+ Version: 0.1.7.dev20241002104051
4
4
  Summary: Create LLM agents with long-term memory and custom tools
5
5
  License: Apache License
6
6
  Author: Letta Team
@@ -12,21 +12,22 @@ Classifier: Programming Language :: Python :: 3.10
12
12
  Classifier: Programming Language :: Python :: 3.11
13
13
  Classifier: Programming Language :: Python :: 3.12
14
14
  Provides-Extra: autogen
15
- Provides-Extra: crewai-tools
16
15
  Provides-Extra: dev
16
+ Provides-Extra: external-tools
17
17
  Provides-Extra: milvus
18
18
  Provides-Extra: ollama
19
19
  Provides-Extra: postgres
20
20
  Provides-Extra: qdrant
21
21
  Provides-Extra: server
22
+ Provides-Extra: tests
22
23
  Requires-Dist: autoflake (>=2.3.0,<3.0.0) ; extra == "dev"
23
24
  Requires-Dist: black[jupyter] (>=24.2.0,<25.0.0) ; extra == "dev"
24
25
  Requires-Dist: chromadb (>=0.4.24,<0.5.0)
25
- Requires-Dist: crewai (>=0.41.1,<0.42.0) ; extra == "crewai-tools"
26
- Requires-Dist: crewai-tools (>=0.8.3,<0.9.0) ; extra == "crewai-tools"
26
+ Requires-Dist: crewai (>=0.41.1,<0.42.0) ; extra == "external-tools"
27
+ Requires-Dist: crewai-tools (>=0.8.3,<0.9.0) ; extra == "external-tools"
27
28
  Requires-Dist: datasets (>=2.14.6,<3.0.0) ; extra == "dev"
28
29
  Requires-Dist: demjson3 (>=3.0.6,<4.0.0)
29
- Requires-Dist: docker (>=7.1.0,<8.0.0) ; extra == "crewai-tools"
30
+ Requires-Dist: docker (>=7.1.0,<8.0.0) ; extra == "external-tools"
30
31
  Requires-Dist: docstring-parser (>=0.16,<0.17)
31
32
  Requires-Dist: docx2txt (>=0.8,<0.9)
32
33
  Requires-Dist: fastapi (>=0.104.1,<0.105.0) ; extra == "server"
@@ -35,6 +36,8 @@ Requires-Dist: httpx (>=0.27.2,<0.28.0)
35
36
  Requires-Dist: httpx-sse (>=0.4.0,<0.5.0)
36
37
  Requires-Dist: isort (>=5.13.2,<6.0.0) ; extra == "dev"
37
38
  Requires-Dist: jinja2 (>=3.1.4,<4.0.0)
39
+ Requires-Dist: langchain (>=0.2.16,<0.3.0) ; extra == "external-tools"
40
+ Requires-Dist: langchain-community (>=0.2.17,<0.3.0) ; extra == "external-tools"
38
41
  Requires-Dist: llama-index (>=0.11.9,<0.12.0)
39
42
  Requires-Dist: llama-index-embeddings-ollama (>=0.3.1,<0.4.0) ; extra == "ollama"
40
43
  Requires-Dist: llama-index-embeddings-openai (>=0.2.5,<0.3.0)
@@ -69,6 +72,7 @@ Requires-Dist: tqdm (>=4.66.1,<5.0.0)
69
72
  Requires-Dist: typer[all] (>=0.9.0,<0.10.0)
70
73
  Requires-Dist: uvicorn (>=0.24.0.post1,<0.25.0) ; extra == "server"
71
74
  Requires-Dist: websockets (>=12.0,<13.0) ; extra == "server"
75
+ Requires-Dist: wikipedia (>=1.4.0,<2.0.0) ; extra == "external-tools" or extra == "tests"
72
76
  Description-Content-Type: text/markdown
73
77
 
74
78
  # Letta (previously MemGPT)
@@ -77,13 +81,13 @@ Description-Content-Type: text/markdown
77
81
  [![arxiv 2310.08560](https://img.shields.io/badge/arXiv-2310.08560-B31B1B?logo=arxiv&style=flat-square)](https://arxiv.org/abs/2310.08560)
78
82
 
79
83
  > [!NOTE]
80
- > **Looking for MemGPT?**
84
+ > **Looking for MemGPT?** You're in the right place!
81
85
  >
82
- > The MemGPT package and Docker image have been renamed to `letta` to clarify the distinction between **MemGPT agents** and the API server / runtime that runs LLM agents as *services*.
86
+ > The MemGPT package and Docker image have been renamed to `letta` to clarify the distinction between MemGPT agents and the API server / runtime that runs LLM agents as *services*.
83
87
  >
84
- > You use the **Letta framework** to create **MemGPT agents**. Read more about the relationship between MemGPT and Letta [here](https://www.letta.com/blog/memgpt-and-letta).
88
+ > You use the **Letta _framework_** to create **MemGPT _agents_**. Read more about the relationship between MemGPT and Letta [here](https://www.letta.com/blog/memgpt-and-letta).
85
89
 
86
- See [documentation](https://docs.letta.com/introduction) for setup and usage.
90
+ Visit our [documentation page](https://docs.letta.com) for information on setup and usage.
87
91
 
88
92
  ## How to Get Involved
89
93
  * **Contribute to the Project**: Interested in contributing? Start by reading our [Contribution Guidelines](https://github.com/cpacker/MemGPT/tree/main/CONTRIBUTING.md).
@@ -4,13 +4,13 @@
4
4
  [![arxiv 2310.08560](https://img.shields.io/badge/arXiv-2310.08560-B31B1B?logo=arxiv&style=flat-square)](https://arxiv.org/abs/2310.08560)
5
5
 
6
6
  > [!NOTE]
7
- > **Looking for MemGPT?**
7
+ > **Looking for MemGPT?** You're in the right place!
8
8
  >
9
- > The MemGPT package and Docker image have been renamed to `letta` to clarify the distinction between **MemGPT agents** and the API server / runtime that runs LLM agents as *services*.
9
+ > The MemGPT package and Docker image have been renamed to `letta` to clarify the distinction between MemGPT agents and the API server / runtime that runs LLM agents as *services*.
10
10
  >
11
- > You use the **Letta framework** to create **MemGPT agents**. Read more about the relationship between MemGPT and Letta [here](https://www.letta.com/blog/memgpt-and-letta).
11
+ > You use the **Letta _framework_** to create **MemGPT _agents_**. Read more about the relationship between MemGPT and Letta [here](https://www.letta.com/blog/memgpt-and-letta).
12
12
 
13
- See [documentation](https://docs.letta.com/introduction) for setup and usage.
13
+ Visit our [documentation page](https://docs.letta.com) for information on setup and usage.
14
14
 
15
15
  ## How to Get Involved
16
16
  * **Contribute to the Project**: Interested in contributing? Start by reading our [Contribution Guidelines](https://github.com/cpacker/MemGPT/tree/main/CONTRIBUTING.md).
@@ -237,10 +237,8 @@ class Agent(BaseAgent):
237
237
  self.agent_state = agent_state
238
238
  assert isinstance(self.agent_state.memory, Memory), f"Memory object is not of type Memory: {type(self.agent_state.memory)}"
239
239
 
240
- try:
241
- self.link_tools(tools)
242
- except Exception as e:
243
- raise ValueError(f"Encountered an error while trying to link agent tools during initialization:\n{str(e)}")
240
+ # link tools
241
+ self.link_tools(tools)
244
242
 
245
243
  # gpt-4, gpt-3.5-turbo, ...
246
244
  self.model = self.agent_state.llm_config.model
@@ -345,13 +343,18 @@ class Agent(BaseAgent):
345
343
  env = {}
346
344
  env.update(globals())
347
345
  for tool in tools:
348
- # WARNING: name may not be consistent?
349
- if tool.module: # execute the whole module
350
- exec(tool.module, env)
351
- else:
352
- exec(tool.source_code, env)
353
- self.functions_python[tool.name] = env[tool.name]
354
- self.functions.append(tool.json_schema)
346
+ try:
347
+ # WARNING: name may not be consistent?
348
+ if tool.module: # execute the whole module
349
+ exec(tool.module, env)
350
+ else:
351
+ exec(tool.source_code, env)
352
+
353
+ self.functions_python[tool.json_schema["name"]] = env[tool.json_schema["name"]]
354
+ self.functions.append(tool.json_schema)
355
+ except Exception as e:
356
+ warnings.warn(f"WARNING: tool {tool.name} failed to link")
357
+ print(e)
355
358
  assert all([callable(f) for k, f in self.functions_python.items()]), self.functions_python
356
359
 
357
360
  def _load_messages_from_recall(self, message_ids: List[str]) -> List[Message]:
@@ -548,18 +551,19 @@ class Agent(BaseAgent):
548
551
  ) # extend conversation with assistant's reply
549
552
  printd(f"Function call message: {messages[-1]}")
550
553
 
551
- # The content if then internal monologue, not chat
552
- self.interface.internal_monologue(response_message.content, msg_obj=messages[-1])
554
+ if response_message.content:
555
+ # The content if then internal monologue, not chat
556
+ self.interface.internal_monologue(response_message.content, msg_obj=messages[-1])
553
557
 
554
558
  # Step 3: call the function
555
559
  # Note: the JSON response may not always be valid; be sure to handle errors
556
-
557
- # Failure case 1: function name is wrong
558
560
  function_call = (
559
561
  response_message.function_call if response_message.function_call is not None else response_message.tool_calls[0].function
560
562
  )
561
563
  function_name = function_call.name
562
564
  printd(f"Request to call function {function_name} with tool_call_id: {tool_call_id}")
565
+
566
+ # Failure case 1: function name is wrong
563
567
  try:
564
568
  function_to_call = self.functions_python[function_name]
565
569
  except KeyError:
@@ -1114,48 +1118,10 @@ class Agent(BaseAgent):
1114
1118
  def add_function(self, function_name: str) -> str:
1115
1119
  # TODO: refactor
1116
1120
  raise NotImplementedError
1117
- # if function_name in self.functions_python.keys():
1118
- # msg = f"Function {function_name} already loaded"
1119
- # printd(msg)
1120
- # return msg
1121
-
1122
- # available_functions = load_all_function_sets()
1123
- # if function_name not in available_functions.keys():
1124
- # raise ValueError(f"Function {function_name} not found in function library")
1125
-
1126
- # self.functions.append(available_functions[function_name]["json_schema"])
1127
- # self.functions_python[function_name] = available_functions[function_name]["python_function"]
1128
-
1129
- # msg = f"Added function {function_name}"
1130
- ## self.save()
1131
- # self.update_state()
1132
- # printd(msg)
1133
- # return msg
1134
1121
 
1135
1122
  def remove_function(self, function_name: str) -> str:
1136
1123
  # TODO: refactor
1137
1124
  raise NotImplementedError
1138
- # if function_name not in self.functions_python.keys():
1139
- # msg = f"Function {function_name} not loaded, ignoring"
1140
- # printd(msg)
1141
- # return msg
1142
-
1143
- ## only allow removal of user defined functions
1144
- # user_func_path = Path(USER_FUNCTIONS_DIR)
1145
- # func_path = Path(inspect.getfile(self.functions_python[function_name]))
1146
- # is_subpath = func_path.resolve().parts[: len(user_func_path.resolve().parts)] == user_func_path.resolve().parts
1147
-
1148
- # if not is_subpath:
1149
- # raise ValueError(f"Function {function_name} is not user defined and cannot be removed")
1150
-
1151
- # self.functions = [f_schema for f_schema in self.functions if f_schema["name"] != function_name]
1152
- # self.functions_python.pop(function_name)
1153
-
1154
- # msg = f"Removed function {function_name}"
1155
- ## self.save()
1156
- # self.update_state()
1157
- # printd(msg)
1158
- # return msg
1159
1125
 
1160
1126
  def update_state(self) -> AgentState:
1161
1127
  message_ids = [msg.id for msg in self._messages]
@@ -464,7 +464,6 @@ def run(
464
464
  # read user id from config
465
465
  ms = MetadataStore(config)
466
466
  client = create_client()
467
- client.user_id
468
467
 
469
468
  # determine agent to use, if not provided
470
469
  if not yes and not agent:
@@ -18,56 +18,6 @@ from letta.data_sources.connectors import DirectoryConnector
18
18
 
19
19
  app = typer.Typer()
20
20
 
21
- # NOTE: not supported due to llama-index breaking things (please reach out if you still need it)
22
- # @app.command("index")
23
- # def load_index(
24
- # name: Annotated[str, typer.Option(help="Name of dataset to load.")],
25
- # dir: Annotated[Optional[str], typer.Option(help="Path to directory containing index.")] = None,
26
- # user_id: Annotated[Optional[uuid.UUID], typer.Option(help="User ID to associate with dataset.")] = None,
27
- # ):
28
- # """Load a LlamaIndex saved VectorIndex into Letta"""
29
- # if user_id is None:
30
- # config = LettaConfig.load()
31
- # user_id = uuid.UUID(config.anon_clientid)
32
- #
33
- # try:
34
- # # load index data
35
- # storage_context = StorageContext.from_defaults(persist_dir=dir)
36
- # loaded_index = load_index_from_storage(storage_context)
37
- #
38
- # # hacky code to extract out passages/embeddings (thanks a lot, llama index)
39
- # embed_dict = loaded_index._vector_store._data.embedding_dict
40
- # node_dict = loaded_index._docstore.docs
41
- #
42
- # # create storage connector
43
- # config = LettaConfig.load()
44
- # if user_id is None:
45
- # user_id = uuid.UUID(config.anon_clientid)
46
- #
47
- # passages = []
48
- # for node_id, node in node_dict.items():
49
- # vector = embed_dict[node_id]
50
- # node.embedding = vector
51
- # # assume embedding are the same as config
52
- # passages.append(
53
- # Passage(
54
- # text=node.text,
55
- # embedding=np.array(vector),
56
- # embedding_dim=config.default_embedding_config.embedding_dim,
57
- # embedding_model=config.default_embedding_config.embedding_model,
58
- # )
59
- # )
60
- # assert config.default_embedding_config.embedding_dim == len(
61
- # vector
62
- # ), f"Expected embedding dimension {config.default_embedding_config.embedding_dim}, got {len(vector)}"
63
- #
64
- # if len(passages) == 0:
65
- # raise ValueError(f"No passages found in index {dir}")
66
- #
67
- # insert_passages_into_source(passages, name, user_id, config)
68
- # except ValueError as e:
69
- # typer.secho(f"Failed to load index from provided information.\n{e}", fg=typer.colors.RED)
70
-
71
21
 
72
22
  default_extensions = ".txt,.md,.pdf"
73
23
 
@@ -1562,7 +1562,7 @@ class LocalClient(AbstractClient):
1562
1562
 
1563
1563
  def get_agent(self, agent_id: str) -> AgentState:
1564
1564
  """
1565
- Get an agent's state by it's ID.
1565
+ Get an agent's state by its ID.
1566
1566
 
1567
1567
  Args:
1568
1568
  agent_id (str): ID of the agent
@@ -2,7 +2,6 @@ import configparser
2
2
  import inspect
3
3
  import json
4
4
  import os
5
- import uuid
6
5
  from dataclasses import dataclass
7
6
  from typing import Optional
8
7
 
@@ -14,6 +13,7 @@ from letta.constants import (
14
13
  DEFAULT_HUMAN,
15
14
  DEFAULT_PERSONA,
16
15
  DEFAULT_PRESET,
16
+ DEFAULT_USER_ID,
17
17
  LETTA_DIR,
18
18
  )
19
19
  from letta.log import get_logger
@@ -45,7 +45,7 @@ def set_field(config, section, field, value):
45
45
  @dataclass
46
46
  class LettaConfig:
47
47
  config_path: str = os.getenv("MEMGPT_CONFIG_PATH") or os.path.join(LETTA_DIR, "config")
48
- anon_clientid: str = str(uuid.UUID(int=0))
48
+ anon_clientid: str = DEFAULT_USER_ID
49
49
 
50
50
  # preset
51
51
  preset: str = DEFAULT_PRESET # TODO: rename to system prompt
@@ -100,10 +100,6 @@ class LettaConfig:
100
100
  # self.context_window = int(self.context_window)
101
101
  pass
102
102
 
103
- @staticmethod
104
- def generate_uuid() -> str:
105
- return uuid.UUID(int=uuid.getnode()).hex
106
-
107
103
  @classmethod
108
104
  def load(cls, llm_config: Optional[LLMConfig] = None, embedding_config: Optional[EmbeddingConfig] = None) -> "LettaConfig":
109
105
  # avoid circular import
@@ -199,8 +195,7 @@ class LettaConfig:
199
195
  # assert llm_config is not None, "LLM config must be provided if config does not exist"
200
196
 
201
197
  # create new config
202
- anon_clientid = LettaConfig.generate_uuid()
203
- config = cls(anon_clientid=anon_clientid, config_path=config_path)
198
+ config = cls(config_path=config_path)
204
199
 
205
200
  config.create_config_dir() # create dirs
206
201
 
@@ -284,8 +279,6 @@ class LettaConfig:
284
279
  set_field(config, "version", "letta_version", letta.__version__)
285
280
 
286
281
  # client
287
- if not self.anon_clientid:
288
- self.anon_clientid = self.generate_uuid()
289
282
  set_field(config, "client", "anon_clientid", self.anon_clientid)
290
283
 
291
284
  # always make sure all directories are present
@@ -1,17 +1,12 @@
1
1
  import importlib
2
2
  import inspect
3
3
  import os
4
- import sys
5
4
  from textwrap import dedent # remove indentation
6
5
  from types import ModuleType
7
6
 
8
- from letta.constants import CLI_WARNING_PREFIX, LETTA_DIR
7
+ from letta.constants import CLI_WARNING_PREFIX
9
8
  from letta.functions.schema_generator import generate_schema
10
9
 
11
- USER_FUNCTIONS_DIR = os.path.join(LETTA_DIR, "functions")
12
-
13
- sys.path.append(USER_FUNCTIONS_DIR)
14
-
15
10
 
16
11
  def parse_source_code(func) -> str:
17
12
  """Parse the source code of a function and remove indendation"""
@@ -68,24 +63,6 @@ def validate_function(module_name, module_full_path):
68
63
  return True, None
69
64
 
70
65
 
71
- def write_function(module_name: str, function_name: str, function_code: str):
72
- """Write a function to a file in the user functions directory"""
73
- # Create the user functions directory if it doesn't exist
74
- if not os.path.exists(USER_FUNCTIONS_DIR):
75
- os.makedirs(USER_FUNCTIONS_DIR)
76
-
77
- # Write the function to a file
78
- file_path = os.path.join(USER_FUNCTIONS_DIR, f"{module_name}.py")
79
- with open(file_path, "w", encoding="utf-8") as f:
80
- f.write(function_code)
81
- succ, error = validate_function(module_name, file_path)
82
-
83
- # raise error if function cannot be loaded
84
- if not succ:
85
- raise ValueError(error)
86
- return file_path
87
-
88
-
89
66
  def load_function_file(filepath: str) -> dict:
90
67
  file = os.path.basename(filepath)
91
68
  module_name = file[:-3] # Remove '.py' from filename
@@ -0,0 +1,191 @@
1
+ from typing import Any, Optional, Union
2
+
3
+ from pydantic import BaseModel
4
+
5
+
6
+ def generate_langchain_tool_wrapper(
7
+ tool: "LangChainBaseTool", additional_imports_module_attr_map: dict[str, str] = None
8
+ ) -> tuple[str, str]:
9
+ tool_name = tool.__class__.__name__
10
+ import_statement = f"from langchain_community.tools import {tool_name}"
11
+ extra_module_imports = generate_import_code(additional_imports_module_attr_map)
12
+
13
+ # Safety check that user has passed in all required imports:
14
+ assert_all_classes_are_imported(tool, additional_imports_module_attr_map)
15
+
16
+ tool_instantiation = f"tool = {generate_imported_tool_instantiation_call_str(tool)}"
17
+ run_call = f"return tool._run(**kwargs)"
18
+ func_name = f"run_{tool_name.lower()}"
19
+
20
+ # Combine all parts into the wrapper function
21
+ wrapper_function_str = f"""
22
+ def {func_name}(**kwargs):
23
+ if 'self' in kwargs:
24
+ del kwargs['self']
25
+ import importlib
26
+ {import_statement}
27
+ {extra_module_imports}
28
+ {tool_instantiation}
29
+ {run_call}
30
+ """
31
+ return func_name, wrapper_function_str
32
+
33
+
34
+ def generate_crewai_tool_wrapper(tool: "CrewAIBaseTool", additional_imports_module_attr_map: dict[str, str] = None) -> tuple[str, str]:
35
+ tool_name = tool.__class__.__name__
36
+ import_statement = f"from crewai_tools import {tool_name}"
37
+ extra_module_imports = generate_import_code(additional_imports_module_attr_map)
38
+
39
+ # Safety check that user has passed in all required imports:
40
+ assert_all_classes_are_imported(tool, additional_imports_module_attr_map)
41
+
42
+ tool_instantiation = f"tool = {generate_imported_tool_instantiation_call_str(tool)}"
43
+ run_call = f"return tool._run(**kwargs)"
44
+ func_name = f"run_{tool_name.lower()}"
45
+
46
+ # Combine all parts into the wrapper function
47
+ wrapper_function_str = f"""
48
+ def {func_name}(**kwargs):
49
+ if 'self' in kwargs:
50
+ del kwargs['self']
51
+ {import_statement}
52
+ {extra_module_imports}
53
+ {tool_instantiation}
54
+ {run_call}
55
+ """
56
+ return func_name, wrapper_function_str
57
+
58
+
59
+ def assert_all_classes_are_imported(
60
+ tool: Union["LangChainBaseTool", "CrewAIBaseTool"], additional_imports_module_attr_map: dict[str, str]
61
+ ) -> None:
62
+ # Safety check that user has passed in all required imports:
63
+ tool_name = tool.__class__.__name__
64
+ current_class_imports = {tool_name}
65
+ if additional_imports_module_attr_map:
66
+ current_class_imports.update(set(additional_imports_module_attr_map.values()))
67
+ required_class_imports = set(find_required_class_names_for_import(tool))
68
+
69
+ if not current_class_imports.issuperset(required_class_imports):
70
+ err_msg = f"[ERROR] You are missing module_attr pairs in `additional_imports_module_attr_map`. Currently, you have imports for {current_class_imports}, but the required classes for import are {required_class_imports}"
71
+ print(err_msg)
72
+ raise RuntimeError(err_msg)
73
+
74
+
75
+ def find_required_class_names_for_import(obj: Union["LangChainBaseTool", "CrewAIBaseTool", BaseModel]) -> list[str]:
76
+ """
77
+ Finds all the class names for required imports when instantiating the `obj`.
78
+ NOTE: This does not return the full import path, only the class name.
79
+
80
+ We accomplish this by running BFS and deep searching all the BaseModel objects in the obj parameters.
81
+ """
82
+ class_names = {obj.__class__.__name__}
83
+ queue = [obj]
84
+
85
+ while queue:
86
+ # Get the current object we are inspecting
87
+ curr_obj = queue.pop()
88
+
89
+ # Collect all possible candidates for BaseModel objects
90
+ candidates = []
91
+ if is_base_model(curr_obj):
92
+ # If it is a base model, we get all the values of the object parameters
93
+ # i.e., if obj('b' = <class A>), we would want to inspect <class A>
94
+ fields = dict(curr_obj)
95
+ # Generate code for each field, skipping empty or None values
96
+ candidates = list(fields.values())
97
+ elif isinstance(curr_obj, dict):
98
+ # If it is a dictionary, we get all the values
99
+ # i.e., if obj = {'a': 3, 'b': <class A>}, we would want to inspect <class A>
100
+ candidates = list(curr_obj.values())
101
+ elif isinstance(curr_obj, list):
102
+ # If it is a list, we inspect all the items in the list
103
+ # i.e., if obj = ['a', 3, None, <class A>], we would want to inspect <class A>
104
+ candidates = curr_obj
105
+
106
+ # Filter out all candidates that are not BaseModels
107
+ # In the list example above, ['a', 3, None, <class A>], we want to filter out 'a', 3, and None
108
+ candidates = filter(lambda x: is_base_model(x), candidates)
109
+
110
+ # Classic BFS here
111
+ for c in candidates:
112
+ c_name = c.__class__.__name__
113
+ if c_name not in class_names:
114
+ class_names.add(c_name)
115
+ queue.append(c)
116
+
117
+ return list(class_names)
118
+
119
+
120
+ def generate_imported_tool_instantiation_call_str(obj: Any) -> Optional[str]:
121
+ if isinstance(obj, (int, float, str, bool, type(None))):
122
+ # This is the base case
123
+ # If it is a basic Python type, we trivially return the string version of that value
124
+ # Handle basic types
125
+ return repr(obj)
126
+ elif is_base_model(obj):
127
+ # Otherwise, if it is a BaseModel
128
+ # We want to pull out all the parameters, and reformat them into strings
129
+ # e.g. {arg}={value}
130
+ # The reason why this is recursive, is because the value can be another BaseModel that we need to stringify
131
+ model_name = obj.__class__.__name__
132
+ fields = dict(obj)
133
+ # Generate code for each field, skipping empty or None values
134
+ field_assignments = []
135
+ for arg, value in fields.items():
136
+ python_string = generate_imported_tool_instantiation_call_str(value)
137
+ if python_string:
138
+ field_assignments.append(f"{arg}={python_string}")
139
+
140
+ assignments = ", ".join(field_assignments)
141
+ return f"{model_name}({assignments})"
142
+ elif isinstance(obj, dict):
143
+ # Inspect each of the items in the dict and stringify them
144
+ # This is important because the dictionary may contain other BaseModels
145
+ dict_items = []
146
+ for k, v in obj.items():
147
+ python_string = generate_imported_tool_instantiation_call_str(v)
148
+ if python_string:
149
+ dict_items.append(f"{repr(k)}: {python_string}")
150
+
151
+ joined_items = ", ".join(dict_items)
152
+ return f"{{{joined_items}}}"
153
+ elif isinstance(obj, list):
154
+ # Inspect each of the items in the list and stringify them
155
+ # This is important because the list may contain other BaseModels
156
+ list_items = [generate_imported_tool_instantiation_call_str(v) for v in obj]
157
+ filtered_list_items = list(filter(None, list_items))
158
+ list_items = ", ".join(filtered_list_items)
159
+ return f"[{list_items}]"
160
+ else:
161
+ # Otherwise, if it is none of the above, that usually means it is a custom Python class that is NOT a BaseModel
162
+ # Thus, we cannot get enough information about it to stringify it
163
+ # This may cause issues, but we are making the assumption that any of these custom Python types are handled correctly by the parent library, such as LangChain or CrewAI
164
+ # An example would be that WikipediaAPIWrapper has an argument that is a wikipedia (pip install wikipedia) object
165
+ # We cannot stringify this easily, but WikipediaAPIWrapper handles the setting of this parameter internally
166
+ # This assumption seems fair to me, since usually they are external imports, and LangChain and CrewAI should be bundling those as module-level imports within the tool
167
+ # We throw a warning here anyway and provide the class name
168
+ print(
169
+ f"[WARNING] Skipping parsing unknown class {obj.__class__.__name__} (does not inherit from the Pydantic BaseModel and is not a basic Python type)"
170
+ )
171
+ return None
172
+
173
+
174
+ def is_base_model(obj: Any):
175
+ from crewai_tools.tools.base_tool import BaseModel as CrewAiBaseModel
176
+ from langchain_core.pydantic_v1 import BaseModel as LangChainBaseModel
177
+
178
+ return isinstance(obj, BaseModel) or isinstance(obj, LangChainBaseModel) or isinstance(obj, CrewAiBaseModel)
179
+
180
+
181
+ def generate_import_code(module_attr_map: Optional[dict]):
182
+ if not module_attr_map:
183
+ return ""
184
+
185
+ code_lines = []
186
+ for module, attr in module_attr_map.items():
187
+ module_name = module.split(".")[-1]
188
+ code_lines.append(f"# Load the module\n {module_name} = importlib.import_module('{module}')")
189
+ code_lines.append(f" # Access the {attr} from the module")
190
+ code_lines.append(f" {attr} = getattr({module_name}, '{attr}')")
191
+ return "\n".join(code_lines)
@@ -1,6 +1,5 @@
1
1
  import inspect
2
- import typing
3
- from typing import Any, Dict, Optional, Type, get_args, get_origin
2
+ from typing import Any, Dict, Optional, Type, Union, get_args, get_origin
4
3
 
5
4
  from docstring_parser import parse
6
5
  from pydantic import BaseModel
@@ -8,7 +7,7 @@ from pydantic import BaseModel
8
7
 
9
8
  def is_optional(annotation):
10
9
  # Check if the annotation is a Union
11
- if getattr(annotation, "__origin__", None) is typing.Union:
10
+ if getattr(annotation, "__origin__", None) is Union:
12
11
  # Check if None is one of the options in the Union
13
12
  return type(None) in annotation.__args__
14
13
  return False
@@ -164,42 +163,3 @@ def generate_schema_from_args_schema(
164
163
  }
165
164
 
166
165
  return function_call_json
167
-
168
-
169
- def generate_langchain_tool_wrapper(tool_name: str) -> str:
170
- import_statement = f"from langchain_community.tools import {tool_name}"
171
-
172
- # NOTE: this will fail for tools like 'wikipedia = WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())' since it needs to pass an argument to the tool instantiation
173
- # https://python.langchain.com/v0.1/docs/integrations/tools/wikipedia/
174
- tool_instantiation = f"tool = {tool_name}()"
175
- run_call = f"return tool._run(**kwargs)"
176
- func_name = f"run_{tool_name.lower()}"
177
-
178
- # Combine all parts into the wrapper function
179
- wrapper_function_str = f"""
180
- def {func_name}(**kwargs):
181
- if 'self' in kwargs:
182
- del kwargs['self']
183
- {import_statement}
184
- {tool_instantiation}
185
- {run_call}
186
- """
187
- return func_name, wrapper_function_str
188
-
189
-
190
- def generate_crewai_tool_wrapper(tool_name: str) -> str:
191
- import_statement = f"from crewai_tools import {tool_name}"
192
- tool_instantiation = f"tool = {tool_name}()"
193
- run_call = f"return tool._run(**kwargs)"
194
- func_name = f"run_{tool_name.lower()}"
195
-
196
- # Combine all parts into the wrapper function
197
- wrapper_function_str = f"""
198
- def {func_name}(**kwargs):
199
- if 'self' in kwargs:
200
- del kwargs['self']
201
- {import_statement}
202
- {tool_instantiation}
203
- {run_call}
204
- """
205
- return func_name, wrapper_function_str