letta-nightly 0.4.1.dev20241008104105__tar.gz → 0.4.1.dev20241010104112__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.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/PKG-INFO +1 -1
  2. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/agent.py +18 -2
  3. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/agent_store/db.py +23 -7
  4. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/cli/cli.py +2 -1
  5. letta_nightly-0.4.1.dev20241010104112/letta/cli/cli_config.py +228 -0
  6. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/client/client.py +8 -1
  7. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/client/utils.py +7 -2
  8. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/credentials.py +2 -2
  9. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/embeddings.py +3 -0
  10. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/functions/schema_generator.py +1 -1
  11. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/interface.py +6 -2
  12. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/llm_api/anthropic.py +3 -24
  13. letta_nightly-0.4.1.dev20241010104112/letta/llm_api/azure_openai.py +100 -0
  14. letta_nightly-0.4.1.dev20241010104112/letta/llm_api/azure_openai_constants.py +10 -0
  15. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/llm_api/google_ai.py +38 -63
  16. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/llm_api/helpers.py +64 -2
  17. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/llm_api/llm_api_tools.py +6 -15
  18. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/llm_api/openai.py +6 -49
  19. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/constants.py +3 -0
  20. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/main.py +1 -1
  21. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/metadata.py +2 -0
  22. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/providers.py +165 -31
  23. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/agent.py +14 -0
  24. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/llm_config.py +0 -3
  25. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/openai/chat_completion_response.py +3 -0
  26. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/tool.py +3 -3
  27. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/routers/openai/assistants/threads.py +5 -5
  28. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/routers/openai/chat_completions/chat_completions.py +2 -2
  29. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/routers/v1/agents.py +11 -11
  30. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/routers/v1/blocks.py +2 -2
  31. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/routers/v1/jobs.py +2 -2
  32. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/routers/v1/sources.py +12 -12
  33. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/routers/v1/tools.py +6 -6
  34. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/server.py +26 -7
  35. letta_nightly-0.4.1.dev20241010104112/letta/settings.py +89 -0
  36. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/streaming_interface.py +8 -4
  37. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/pyproject.toml +2 -1
  38. letta_nightly-0.4.1.dev20241008104105/letta/cli/cli_config.py +0 -1325
  39. letta_nightly-0.4.1.dev20241008104105/letta/configs/anthropic.json +0 -13
  40. letta_nightly-0.4.1.dev20241008104105/letta/configs/letta_hosted.json +0 -11
  41. letta_nightly-0.4.1.dev20241008104105/letta/configs/openai.json +0 -12
  42. letta_nightly-0.4.1.dev20241008104105/letta/llm_api/azure_openai.py +0 -151
  43. letta_nightly-0.4.1.dev20241008104105/letta/settings.py +0 -198
  44. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/LICENSE +0 -0
  45. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/README.md +0 -0
  46. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/__init__.py +0 -0
  47. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/__main__.py +0 -0
  48. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/agent_store/chroma.py +0 -0
  49. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/agent_store/lancedb.py +0 -0
  50. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/agent_store/milvus.py +0 -0
  51. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/agent_store/qdrant.py +0 -0
  52. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/agent_store/storage.py +0 -0
  53. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/benchmark/benchmark.py +0 -0
  54. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/benchmark/constants.py +0 -0
  55. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/cli/cli_load.py +0 -0
  56. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/client/__init__.py +0 -0
  57. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/client/admin.py +0 -0
  58. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/client/streaming.py +0 -0
  59. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/config.py +0 -0
  60. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/constants.py +0 -0
  61. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/data_sources/connectors.py +0 -0
  62. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/errors.py +0 -0
  63. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/functions/__init__.py +0 -0
  64. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/functions/function_sets/base.py +0 -0
  65. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/functions/function_sets/extras.py +0 -0
  66. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/functions/functions.py +0 -0
  67. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/functions/helpers.py +0 -0
  68. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/humans/__init__.py +0 -0
  69. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/humans/examples/basic.txt +0 -0
  70. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/humans/examples/cs_phd.txt +0 -0
  71. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/llm_api/__init__.py +0 -0
  72. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/llm_api/cohere.py +0 -0
  73. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/README.md +0 -0
  74. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/__init__.py +0 -0
  75. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/chat_completion_proxy.py +0 -0
  76. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/function_parser.py +0 -0
  77. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/grammars/__init__.py +0 -0
  78. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/grammars/gbnf_grammar_generator.py +0 -0
  79. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/grammars/json.gbnf +0 -0
  80. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/grammars/json_func_calls_with_inner_thoughts.gbnf +0 -0
  81. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/json_parser.py +0 -0
  82. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/koboldcpp/api.py +0 -0
  83. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/koboldcpp/settings.py +0 -0
  84. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/llamacpp/api.py +0 -0
  85. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/llamacpp/settings.py +0 -0
  86. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/llm_chat_completion_wrappers/__init__.py +0 -0
  87. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/llm_chat_completion_wrappers/airoboros.py +0 -0
  88. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/llm_chat_completion_wrappers/chatml.py +0 -0
  89. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/llm_chat_completion_wrappers/configurable_wrapper.py +0 -0
  90. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/llm_chat_completion_wrappers/dolphin.py +0 -0
  91. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/llm_chat_completion_wrappers/llama3.py +0 -0
  92. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/llm_chat_completion_wrappers/simple_summary_wrapper.py +0 -0
  93. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/llm_chat_completion_wrappers/wrapper_base.py +0 -0
  94. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/llm_chat_completion_wrappers/zephyr.py +0 -0
  95. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/lmstudio/api.py +0 -0
  96. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/lmstudio/settings.py +0 -0
  97. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/ollama/api.py +0 -0
  98. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/ollama/settings.py +0 -0
  99. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/settings/__init__.py +0 -0
  100. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/settings/deterministic_mirostat.py +0 -0
  101. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/settings/settings.py +0 -0
  102. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/settings/simple.py +0 -0
  103. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/utils.py +0 -0
  104. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/vllm/api.py +0 -0
  105. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/webui/api.py +0 -0
  106. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/webui/legacy_api.py +0 -0
  107. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/webui/legacy_settings.py +0 -0
  108. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/local_llm/webui/settings.py +0 -0
  109. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/log.py +0 -0
  110. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/memory.py +0 -0
  111. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/openai_backcompat/__init__.py +0 -0
  112. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/openai_backcompat/openai_object.py +0 -0
  113. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/persistence_manager.py +0 -0
  114. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/personas/__init__.py +0 -0
  115. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/personas/examples/anna_pa.txt +0 -0
  116. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/personas/examples/google_search_persona.txt +0 -0
  117. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/personas/examples/memgpt_doc.txt +0 -0
  118. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/personas/examples/memgpt_starter.txt +0 -0
  119. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/personas/examples/sam.txt +0 -0
  120. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/personas/examples/sam_pov.txt +0 -0
  121. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/personas/examples/sam_simple_pov_gpt35.txt +0 -0
  122. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/personas/examples/sqldb/test.db +0 -0
  123. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/prompts/__init__.py +0 -0
  124. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/prompts/gpt_summarize.py +0 -0
  125. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/prompts/gpt_system.py +0 -0
  126. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/prompts/system/memgpt_base.txt +0 -0
  127. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/prompts/system/memgpt_chat.txt +0 -0
  128. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/prompts/system/memgpt_chat_compressed.txt +0 -0
  129. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/prompts/system/memgpt_chat_fstring.txt +0 -0
  130. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/prompts/system/memgpt_doc.txt +0 -0
  131. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/prompts/system/memgpt_gpt35_extralong.txt +0 -0
  132. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/prompts/system/memgpt_intuitive_knowledge.txt +0 -0
  133. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/prompts/system/memgpt_modified_chat.txt +0 -0
  134. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/pytest.ini +0 -0
  135. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/api_key.py +0 -0
  136. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/block.py +0 -0
  137. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/document.py +0 -0
  138. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/embedding_config.py +0 -0
  139. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/enums.py +0 -0
  140. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/health.py +0 -0
  141. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/job.py +0 -0
  142. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/letta_base.py +0 -0
  143. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/letta_message.py +0 -0
  144. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/letta_request.py +0 -0
  145. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/letta_response.py +0 -0
  146. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/memory.py +0 -0
  147. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/message.py +0 -0
  148. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/openai/chat_completion_request.py +0 -0
  149. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/openai/chat_completions.py +0 -0
  150. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/openai/embedding_response.py +0 -0
  151. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/openai/openai.py +0 -0
  152. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/organization.py +0 -0
  153. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/passage.py +0 -0
  154. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/source.py +0 -0
  155. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/usage.py +0 -0
  156. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/schemas/user.py +0 -0
  157. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/__init__.py +0 -0
  158. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/constants.py +0 -0
  159. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/__init__.py +0 -0
  160. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/admin/__init__.py +0 -0
  161. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/admin/agents.py +0 -0
  162. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/admin/tools.py +0 -0
  163. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/admin/users.py +0 -0
  164. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/app.py +0 -0
  165. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/auth/__init__.py +0 -0
  166. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/auth/index.py +0 -0
  167. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/auth_token.py +0 -0
  168. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/interface.py +0 -0
  169. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/routers/__init__.py +0 -0
  170. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/routers/openai/__init__.py +0 -0
  171. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/routers/openai/assistants/__init__.py +0 -0
  172. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/routers/openai/assistants/assistants.py +0 -0
  173. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/routers/openai/assistants/schemas.py +0 -0
  174. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/routers/openai/chat_completions/__init__.py +0 -0
  175. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/routers/v1/__init__.py +0 -0
  176. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/routers/v1/health.py +0 -0
  177. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/routers/v1/llms.py +0 -0
  178. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/routers/v1/organizations.py +0 -0
  179. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/routers/v1/users.py +0 -0
  180. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/static_files.py +0 -0
  181. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/rest_api/utils.py +0 -0
  182. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/startup.sh +0 -0
  183. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/static_files/assets/index-3ab03d5b.css +0 -0
  184. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/static_files/assets/index-9a9c449b.js +0 -0
  185. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/static_files/favicon.ico +0 -0
  186. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/static_files/index.html +0 -0
  187. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/static_files/memgpt_logo_transparent.png +0 -0
  188. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/utils.py +0 -0
  189. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/ws_api/__init__.py +0 -0
  190. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/ws_api/example_client.py +0 -0
  191. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/ws_api/interface.py +0 -0
  192. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/ws_api/protocol.py +0 -0
  193. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/server/ws_api/server.py +0 -0
  194. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/system.py +0 -0
  195. {letta_nightly-0.4.1.dev20241008104105 → letta_nightly-0.4.1.dev20241010104112}/letta/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: letta-nightly
3
- Version: 0.4.1.dev20241008104105
3
+ Version: 0.4.1.dev20241010104112
4
4
  Summary: Create LLM agents with long-term memory and custom tools
5
5
  License: Apache License
6
6
  Author: Letta Team
@@ -239,6 +239,7 @@ class Agent(BaseAgent):
239
239
  assert isinstance(self.agent_state.memory, Memory), f"Memory object is not of type Memory: {type(self.agent_state.memory)}"
240
240
 
241
241
  # link tools
242
+ self.tools = tools
242
243
  self.link_tools(tools)
243
244
 
244
245
  # gpt-4, gpt-3.5-turbo, ...
@@ -338,6 +339,9 @@ class Agent(BaseAgent):
338
339
  for tool_name in self.agent_state.tools:
339
340
  assert tool_name in [tool.name for tool in tools], f"Tool name {tool_name} not included in agent tool list"
340
341
 
342
+ # Update tools
343
+ self.tools = tools
344
+
341
345
  # Store the functions schemas (this is passed as an argument to ChatCompletion)
342
346
  self.functions = []
343
347
  self.functions_python = {}
@@ -482,7 +486,7 @@ class Agent(BaseAgent):
482
486
  inner_thoughts_in_kwargs_option=inner_thoughts_in_kwargs_option,
483
487
  )
484
488
 
485
- if len(response.choices) == 0:
489
+ if len(response.choices) == 0 or response.choices[0] is None:
486
490
  raise Exception(f"API call didn't return a message: {response}")
487
491
 
488
492
  # special case for 'length'
@@ -552,9 +556,12 @@ class Agent(BaseAgent):
552
556
  ) # extend conversation with assistant's reply
553
557
  printd(f"Function call message: {messages[-1]}")
554
558
 
559
+ nonnull_content = False
555
560
  if response_message.content:
556
561
  # The content if then internal monologue, not chat
557
562
  self.interface.internal_monologue(response_message.content, msg_obj=messages[-1])
563
+ # Flag to avoid printing a duplicate if inner thoughts get popped from the function call
564
+ nonnull_content = True
558
565
 
559
566
  # Step 3: call the function
560
567
  # Note: the JSON response may not always be valid; be sure to handle errors
@@ -615,12 +622,17 @@ class Agent(BaseAgent):
615
622
  if "inner_thoughts" in function_args:
616
623
  response_message.content = function_args.pop("inner_thoughts")
617
624
  # The content if then internal monologue, not chat
618
- if response_message.content:
625
+ if response_message.content and not nonnull_content:
619
626
  self.interface.internal_monologue(response_message.content, msg_obj=messages[-1])
620
627
 
621
628
  # (Still parsing function args)
622
629
  # Handle requests for immediate heartbeat
623
630
  heartbeat_request = function_args.pop("request_heartbeat", None)
631
+
632
+ # Edge case: heartbeat_request is returned as a stringified boolean, we will attempt to parse:
633
+ if isinstance(heartbeat_request, str) and heartbeat_request.lower().strip() == "true":
634
+ heartbeat_request = True
635
+
624
636
  if not isinstance(heartbeat_request, bool) or heartbeat_request is None:
625
637
  printd(
626
638
  f"{CLI_WARNING_PREFIX}'request_heartbeat' arg parsed was not a bool or None, type={type(heartbeat_request)}, value={heartbeat_request}"
@@ -1353,6 +1365,10 @@ def save_agent(agent: Agent, ms: MetadataStore):
1353
1365
  else:
1354
1366
  ms.create_agent(agent_state)
1355
1367
 
1368
+ for tool in agent.tools:
1369
+ if ms.get_tool(tool_name=tool.name, user_id=tool.user_id) is None:
1370
+ ms.create_tool(tool)
1371
+
1356
1372
  agent.agent_state = ms.get_agent(agent_id=agent_id)
1357
1373
  assert isinstance(agent.agent_state.memory, Memory), f"Memory is not a Memory object: {type(agent_state.memory)}"
1358
1374
 
@@ -398,8 +398,6 @@ class PostgresStorageConnector(SQLStorageConnector):
398
398
  return records
399
399
 
400
400
  def insert_many(self, records, exists_ok=True, show_progress=False):
401
- pass
402
-
403
401
  # TODO: this is terrible, should eventually be done the same way for all types (migrate to SQLModel)
404
402
  if len(records) == 0:
405
403
  return
@@ -506,18 +504,36 @@ class SQLLiteStorageConnector(SQLStorageConnector):
506
504
  # sqlite3.register_converter("UUID", lambda b: uuid.UUID(bytes_le=b))
507
505
 
508
506
  def insert_many(self, records, exists_ok=True, show_progress=False):
509
- pass
510
-
511
507
  # TODO: this is terrible, should eventually be done the same way for all types (migrate to SQLModel)
512
508
  if len(records) == 0:
513
509
  return
510
+
511
+ added_ids = [] # avoid adding duplicates
512
+ # NOTE: this has not great performance due to the excessive commits
514
513
  with self.session_maker() as session:
515
514
  iterable = tqdm(records) if show_progress else records
516
515
  for record in iterable:
517
516
  # db_record = self.db_model(**vars(record))
518
- db_record = self.db_model(**record.dict())
519
- session.add(db_record)
520
- session.commit()
517
+
518
+ if record.id in added_ids:
519
+ continue
520
+
521
+ existing_record = session.query(self.db_model).filter_by(id=record.id).first()
522
+ if existing_record:
523
+ if exists_ok:
524
+ fields = record.model_dump()
525
+ fields.pop("id")
526
+ session.query(self.db_model).filter(self.db_model.id == record.id).update(fields)
527
+ session.commit()
528
+ else:
529
+ raise ValueError(f"Record with id {record.id} already exists.")
530
+
531
+ else:
532
+ db_record = self.db_model(**record.dict())
533
+ session.add(db_record)
534
+ session.commit()
535
+
536
+ added_ids.append(record.id)
521
537
 
522
538
  def insert(self, record, exists_ok=True):
523
539
  self.insert_many([record], exists_ok=exists_ok)
@@ -11,6 +11,7 @@ from letta import create_client
11
11
  from letta.agent import Agent, save_agent
12
12
  from letta.config import LettaConfig
13
13
  from letta.constants import CLI_WARNING_PREFIX, LETTA_DIR
14
+ from letta.local_llm.constants import ASSISTANT_MESSAGE_CLI_SYMBOL
14
15
  from letta.log import get_logger
15
16
  from letta.metadata import MetadataStore
16
17
  from letta.schemas.enums import OptionState
@@ -276,7 +277,7 @@ def run(
276
277
  memory = ChatMemory(human=human_obj.value, persona=persona_obj.value, limit=core_memory_limit)
277
278
  metadata = {"human": human_obj.name, "persona": persona_obj.name}
278
279
 
279
- typer.secho(f"-> 🤖 Using persona profile: '{persona_obj.name}'", fg=typer.colors.WHITE)
280
+ typer.secho(f"-> {ASSISTANT_MESSAGE_CLI_SYMBOL} Using persona profile: '{persona_obj.name}'", fg=typer.colors.WHITE)
280
281
  typer.secho(f"-> 🧑 Using human profile: '{human_obj.name}'", fg=typer.colors.WHITE)
281
282
 
282
283
  # add tools
@@ -0,0 +1,228 @@
1
+ import ast
2
+ import os
3
+ from enum import Enum
4
+ from typing import Annotated, List, Optional
5
+
6
+ import questionary
7
+ import typer
8
+ from prettytable.colortable import ColorTable, Themes
9
+ from tqdm import tqdm
10
+
11
+ from letta import utils
12
+
13
+ app = typer.Typer()
14
+
15
+
16
+ @app.command()
17
+ def configure():
18
+ """Updates default Letta configurations
19
+
20
+ This function and quickstart should be the ONLY place where LettaConfig.save() is called
21
+ """
22
+ print("`letta configure` has been deprecated. Please see documentation on configuration, and run `letta run` instead.")
23
+
24
+
25
+ class ListChoice(str, Enum):
26
+ agents = "agents"
27
+ humans = "humans"
28
+ personas = "personas"
29
+ sources = "sources"
30
+
31
+
32
+ @app.command()
33
+ def list(arg: Annotated[ListChoice, typer.Argument]):
34
+ from letta.client.client import create_client
35
+
36
+ client = create_client()
37
+ table = ColorTable(theme=Themes.OCEAN)
38
+ if arg == ListChoice.agents:
39
+ """List all agents"""
40
+ table.field_names = ["Name", "LLM Model", "Embedding Model", "Embedding Dim", "Persona", "Human", "Data Source", "Create Time"]
41
+ for agent in tqdm(client.list_agents()):
42
+ # TODO: add this function
43
+ sources = client.list_attached_sources(agent_id=agent.id)
44
+ source_names = [source.name for source in sources if source is not None]
45
+ table.add_row(
46
+ [
47
+ agent.name,
48
+ agent.llm_config.model,
49
+ agent.embedding_config.embedding_model,
50
+ agent.embedding_config.embedding_dim,
51
+ agent.memory.get_block("persona").value[:100] + "...",
52
+ agent.memory.get_block("human").value[:100] + "...",
53
+ ",".join(source_names),
54
+ utils.format_datetime(agent.created_at),
55
+ ]
56
+ )
57
+ print(table)
58
+ elif arg == ListChoice.humans:
59
+ """List all humans"""
60
+ table.field_names = ["Name", "Text"]
61
+ for human in client.list_humans():
62
+ table.add_row([human.name, human.value.replace("\n", "")[:100]])
63
+ print(table)
64
+ elif arg == ListChoice.personas:
65
+ """List all personas"""
66
+ table.field_names = ["Name", "Text"]
67
+ for persona in client.list_personas():
68
+ table.add_row([persona.name, persona.value.replace("\n", "")[:100]])
69
+ print(table)
70
+ elif arg == ListChoice.sources:
71
+ """List all data sources"""
72
+
73
+ # create table
74
+ table.field_names = ["Name", "Description", "Embedding Model", "Embedding Dim", "Created At"]
75
+ # TODO: eventually look accross all storage connections
76
+ # TODO: add data source stats
77
+ # TODO: connect to agents
78
+
79
+ # get all sources
80
+ for source in client.list_sources():
81
+ # get attached agents
82
+ table.add_row(
83
+ [
84
+ source.name,
85
+ source.description,
86
+ source.embedding_config.embedding_model,
87
+ source.embedding_config.embedding_dim,
88
+ utils.format_datetime(source.created_at),
89
+ ]
90
+ )
91
+
92
+ print(table)
93
+ else:
94
+ raise ValueError(f"Unknown argument {arg}")
95
+ return table
96
+
97
+
98
+ @app.command()
99
+ def add_tool(
100
+ filename: str = typer.Option(..., help="Path to the Python file containing the function"),
101
+ name: Optional[str] = typer.Option(None, help="Name of the tool"),
102
+ update: bool = typer.Option(True, help="Update the tool if it already exists"),
103
+ tags: Optional[List[str]] = typer.Option(None, help="Tags for the tool"),
104
+ ):
105
+ """Add or update a tool from a Python file."""
106
+ from letta.client.client import create_client
107
+
108
+ client = create_client(base_url=os.getenv("MEMGPT_BASE_URL"), token=os.getenv("MEMGPT_SERVER_PASS"))
109
+
110
+ # 1. Parse the Python file
111
+ with open(filename, "r", encoding="utf-8") as file:
112
+ source_code = file.read()
113
+
114
+ # 2. Parse the source code to extract the function
115
+ # Note: here we assume it is one function only in the file.
116
+ module = ast.parse(source_code)
117
+ func_def = None
118
+ for node in module.body:
119
+ if isinstance(node, ast.FunctionDef):
120
+ func_def = node
121
+ break
122
+
123
+ if not func_def:
124
+ raise ValueError("No function found in the provided file")
125
+
126
+ # 3. Compile the function to make it callable
127
+ # Explanation courtesy of GPT-4:
128
+ # Compile the AST (Abstract Syntax Tree) node representing the function definition into a code object
129
+ # ast.Module creates a module node containing the function definition (func_def)
130
+ # compile converts the AST into a code object that can be executed by the Python interpreter
131
+ # The exec function executes the compiled code object in the current context,
132
+ # effectively defining the function within the current namespace
133
+ exec(compile(ast.Module([func_def], []), filename, "exec"))
134
+ # Retrieve the function object by evaluating its name in the current namespace
135
+ # eval looks up the function name in the current scope and returns the function object
136
+ func = eval(func_def.name)
137
+
138
+ # 4. Add or update the tool
139
+ tool = client.create_tool(func=func, name=name, tags=tags, update=update)
140
+ print(f"Tool {tool.name} added successfully")
141
+
142
+
143
+ @app.command()
144
+ def list_tools():
145
+ """List all available tools."""
146
+ from letta.client.client import create_client
147
+
148
+ client = create_client(base_url=os.getenv("MEMGPT_BASE_URL"), token=os.getenv("MEMGPT_SERVER_PASS"))
149
+
150
+ tools = client.list_tools()
151
+ for tool in tools:
152
+ print(f"Tool: {tool.name}")
153
+
154
+
155
+ @app.command()
156
+ def add(
157
+ option: str, # [human, persona]
158
+ name: Annotated[str, typer.Option(help="Name of human/persona")],
159
+ text: Annotated[Optional[str], typer.Option(help="Text of human/persona")] = None,
160
+ filename: Annotated[Optional[str], typer.Option("-f", help="Specify filename")] = None,
161
+ ):
162
+ """Add a person/human"""
163
+ from letta.client.client import create_client
164
+
165
+ client = create_client(base_url=os.getenv("MEMGPT_BASE_URL"), token=os.getenv("MEMGPT_SERVER_PASS"))
166
+ if filename: # read from file
167
+ assert text is None, "Cannot specify both text and filename"
168
+ with open(filename, "r", encoding="utf-8") as f:
169
+ text = f.read()
170
+ else:
171
+ assert text is not None, "Must specify either text or filename"
172
+ if option == "persona":
173
+ persona_id = client.get_persona_id(name)
174
+ if persona_id:
175
+ client.get_persona(persona_id)
176
+ # config if user wants to overwrite
177
+ if not questionary.confirm(f"Persona {name} already exists. Overwrite?").ask():
178
+ return
179
+ client.update_persona(persona_id, text=text)
180
+ else:
181
+ client.create_persona(name=name, text=text)
182
+
183
+ elif option == "human":
184
+ human_id = client.get_human_id(name)
185
+ if human_id:
186
+ human = client.get_human(human_id)
187
+ # config if user wants to overwrite
188
+ if not questionary.confirm(f"Human {name} already exists. Overwrite?").ask():
189
+ return
190
+ client.update_human(human_id, text=text)
191
+ else:
192
+ human = client.create_human(name=name, text=text)
193
+ else:
194
+ raise ValueError(f"Unknown kind {option}")
195
+
196
+
197
+ @app.command()
198
+ def delete(option: str, name: str):
199
+ """Delete a source from the archival memory."""
200
+ from letta.client.client import create_client
201
+
202
+ client = create_client(base_url=os.getenv("MEMGPT_BASE_URL"), token=os.getenv("MEMGPT_API_KEY"))
203
+ try:
204
+ # delete from metadata
205
+ if option == "source":
206
+ # delete metadata
207
+ source_id = client.get_source_id(name)
208
+ assert source_id is not None, f"Source {name} does not exist"
209
+ client.delete_source(source_id)
210
+ elif option == "agent":
211
+ agent_id = client.get_agent_id(name)
212
+ assert agent_id is not None, f"Agent {name} does not exist"
213
+ client.delete_agent(agent_id=agent_id)
214
+ elif option == "human":
215
+ human_id = client.get_human_id(name)
216
+ assert human_id is not None, f"Human {name} does not exist"
217
+ client.delete_human(human_id)
218
+ elif option == "persona":
219
+ persona_id = client.get_persona_id(name)
220
+ assert persona_id is not None, f"Persona {name} does not exist"
221
+ client.delete_persona(persona_id)
222
+ else:
223
+ raise ValueError(f"Option {option} not implemented")
224
+
225
+ typer.secho(f"Deleted {option} '{name}'", fg=typer.colors.GREEN)
226
+
227
+ except Exception as e:
228
+ typer.secho(f"Failed to delete {option}'{name}'\n{e}", fg=typer.colors.RED)
@@ -9,7 +9,7 @@ from letta.constants import BASE_TOOLS, DEFAULT_HUMAN, DEFAULT_PERSONA
9
9
  from letta.data_sources.connectors import DataConnector
10
10
  from letta.functions.functions import parse_source_code
11
11
  from letta.memory import get_memory_functions
12
- from letta.schemas.agent import AgentState, CreateAgent, UpdateAgentState
12
+ from letta.schemas.agent import AgentState, AgentType, CreateAgent, UpdateAgentState
13
13
  from letta.schemas.block import (
14
14
  Block,
15
15
  CreateBlock,
@@ -68,6 +68,7 @@ class AbstractClient(object):
68
68
  def create_agent(
69
69
  self,
70
70
  name: Optional[str] = None,
71
+ agent_type: Optional[AgentType] = AgentType.memgpt_agent,
71
72
  embedding_config: Optional[EmbeddingConfig] = None,
72
73
  llm_config: Optional[LLMConfig] = None,
73
74
  memory: Memory = ChatMemory(human=get_human_text(DEFAULT_HUMAN), persona=get_persona_text(DEFAULT_PERSONA)),
@@ -319,6 +320,8 @@ class RESTClient(AbstractClient):
319
320
  def create_agent(
320
321
  self,
321
322
  name: Optional[str] = None,
323
+ # agent config
324
+ agent_type: Optional[AgentType] = AgentType.memgpt_agent,
322
325
  # model configs
323
326
  embedding_config: EmbeddingConfig = None,
324
327
  llm_config: LLMConfig = None,
@@ -381,6 +384,7 @@ class RESTClient(AbstractClient):
381
384
  memory=memory,
382
385
  tools=tool_names,
383
386
  system=system,
387
+ agent_type=agent_type,
384
388
  llm_config=llm_config if llm_config else self._default_llm_config,
385
389
  embedding_config=embedding_config if embedding_config else self._default_embedding_config,
386
390
  )
@@ -1462,6 +1466,8 @@ class LocalClient(AbstractClient):
1462
1466
  def create_agent(
1463
1467
  self,
1464
1468
  name: Optional[str] = None,
1469
+ # agent config
1470
+ agent_type: Optional[AgentType] = AgentType.memgpt_agent,
1465
1471
  # model configs
1466
1472
  embedding_config: EmbeddingConfig = None,
1467
1473
  llm_config: LLMConfig = None,
@@ -1524,6 +1530,7 @@ class LocalClient(AbstractClient):
1524
1530
  memory=memory,
1525
1531
  tools=tool_names,
1526
1532
  system=system,
1533
+ agent_type=agent_type,
1527
1534
  llm_config=llm_config if llm_config else self._default_llm_config,
1528
1535
  embedding_config=embedding_config if embedding_config else self._default_embedding_config,
1529
1536
  ),
@@ -2,6 +2,11 @@ from datetime import datetime
2
2
 
3
3
  from IPython.display import HTML, display
4
4
 
5
+ from letta.local_llm.constants import (
6
+ ASSISTANT_MESSAGE_CLI_SYMBOL,
7
+ INNER_THOUGHTS_CLI_SYMBOL,
8
+ )
9
+
5
10
 
6
11
  def pprint(messages):
7
12
  """Utility function for pretty-printing the output of client.send_message in notebooks"""
@@ -47,13 +52,13 @@ def pprint(messages):
47
52
  html_content += f"<p><strong>🛠️ [{date_formatted}] Function Return ({return_status}):</strong></p>"
48
53
  html_content += f"<p class='function-return'>{return_string}</p>"
49
54
  elif "internal_monologue" in message:
50
- html_content += f"<p><strong>💭 [{date_formatted}] Internal Monologue:</strong></p>"
55
+ html_content += f"<p><strong>{INNER_THOUGHTS_CLI_SYMBOL} [{date_formatted}] Internal Monologue:</strong></p>"
51
56
  html_content += f"<p class='internal-monologue'>{message['internal_monologue']}</p>"
52
57
  elif "function_call" in message:
53
58
  html_content += f"<p><strong>🛠️ [[{date_formatted}] Function Call:</strong></p>"
54
59
  html_content += f"<p class='function-call'>{message['function_call']}</p>"
55
60
  elif "assistant_message" in message:
56
- html_content += f"<p><strong>🤖 [{date_formatted}] Assistant Message:</strong></p>"
61
+ html_content += f"<p><strong>{ASSISTANT_MESSAGE_CLI_SYMBOL} [{date_formatted}] Assistant Message:</strong></p>"
57
62
  html_content += f"<p class='assistant-message'>{message['assistant_message']}</p>"
58
63
  html_content += "<br>"
59
64
  html_content += "</div>"
@@ -76,7 +76,7 @@ class LettaCredentials:
76
76
  "azure_embedding_deployment": get_field(config, "azure", "embedding_deployment"),
77
77
  # gemini
78
78
  "google_ai_key": get_field(config, "google_ai", "key"),
79
- "google_ai_service_endpoint": get_field(config, "google_ai", "service_endpoint"),
79
+ # "google_ai_service_endpoint": get_field(config, "google_ai", "service_endpoint"),
80
80
  # anthropic
81
81
  "anthropic_key": get_field(config, "anthropic", "key"),
82
82
  # cohere
@@ -117,7 +117,7 @@ class LettaCredentials:
117
117
 
118
118
  # gemini
119
119
  set_field(config, "google_ai", "key", self.google_ai_key)
120
- set_field(config, "google_ai", "service_endpoint", self.google_ai_service_endpoint)
120
+ # set_field(config, "google_ai", "service_endpoint", self.google_ai_service_endpoint)
121
121
 
122
122
  # anthropic
123
123
  set_field(config, "anthropic", "key", self.anthropic_key)
@@ -91,6 +91,9 @@ class EmbeddingEndpoint:
91
91
  raise ValueError(
92
92
  f"Embeddings endpoint was provided an invalid URL (set to: '{base_url}'). Make sure embedding_endpoint is set correctly in your Letta config."
93
93
  )
94
+ # TODO: find a neater solution - re-mapping for letta endpoint
95
+ if model == "letta-free":
96
+ model = "BAAI/bge-large-en-v1.5"
94
97
  self.model_name = model
95
98
  self._user = user
96
99
  self._base_url = base_url
@@ -130,7 +130,7 @@ def generate_schema(function, name: Optional[str] = None, description: Optional[
130
130
  if function.__name__ not in ["send_message", "pause_heartbeats"]:
131
131
  schema["parameters"]["properties"]["request_heartbeat"] = {
132
132
  "type": "boolean",
133
- "description": "Request an immediate heartbeat after function execution. Set to 'true' if you want to send a follow-up message or run a follow-up function.",
133
+ "description": "Request an immediate heartbeat after function execution. Set to `True` if you want to send a follow-up message or run a follow-up function.",
134
134
  }
135
135
  schema["parameters"]["required"].append("request_heartbeat")
136
136
 
@@ -5,6 +5,10 @@ from typing import List, Optional
5
5
  from colorama import Fore, Style, init
6
6
 
7
7
  from letta.constants import CLI_WARNING_PREFIX
8
+ from letta.local_llm.constants import (
9
+ ASSISTANT_MESSAGE_CLI_SYMBOL,
10
+ INNER_THOUGHTS_CLI_SYMBOL,
11
+ )
8
12
  from letta.schemas.message import Message
9
13
  from letta.utils import json_loads, printd
10
14
 
@@ -79,14 +83,14 @@ class CLIInterface(AgentInterface):
79
83
  @staticmethod
80
84
  def internal_monologue(msg: str, msg_obj: Optional[Message] = None):
81
85
  # ANSI escape code for italic is '\x1B[3m'
82
- fstr = f"\x1B[3m{Fore.LIGHTBLACK_EX}💭 {{msg}}{Style.RESET_ALL}"
86
+ fstr = f"\x1B[3m{Fore.LIGHTBLACK_EX}{INNER_THOUGHTS_CLI_SYMBOL} {{msg}}{Style.RESET_ALL}"
83
87
  if STRIP_UI:
84
88
  fstr = "{msg}"
85
89
  print(fstr.format(msg=msg))
86
90
 
87
91
  @staticmethod
88
92
  def assistant_message(msg: str, msg_obj: Optional[Message] = None):
89
- fstr = f"{Fore.YELLOW}{Style.BRIGHT}🤖 {Fore.YELLOW}{{msg}}{Style.RESET_ALL}"
93
+ fstr = f"{Fore.YELLOW}{Style.BRIGHT}{ASSISTANT_MESSAGE_CLI_SYMBOL} {Fore.YELLOW}{{msg}}{Style.RESET_ALL}"
90
94
  if STRIP_UI:
91
95
  fstr = "{msg}"
92
96
  print(fstr.format(msg=msg))
@@ -2,8 +2,7 @@ import json
2
2
  import re
3
3
  from typing import List, Optional, Union
4
4
 
5
- import requests
6
-
5
+ from letta.llm_api.helpers import make_post_request
7
6
  from letta.schemas.message import Message
8
7
  from letta.schemas.openai.chat_completion_request import ChatCompletionRequest, Tool
9
8
  from letta.schemas.openai.chat_completion_response import (
@@ -295,7 +294,6 @@ def anthropic_chat_completions_request(
295
294
  inner_thoughts_xml_tag: Optional[str] = "thinking",
296
295
  ) -> ChatCompletionResponse:
297
296
  """https://docs.anthropic.com/claude/docs/tool-use"""
298
- from letta.utils import printd
299
297
 
300
298
  url = smart_urljoin(url, "messages")
301
299
  headers = {
@@ -360,24 +358,5 @@ def anthropic_chat_completions_request(
360
358
  data.pop("user", None)
361
359
  data.pop("tool_choice", None)
362
360
 
363
- printd(f"Sending request to {url}")
364
- try:
365
- response = requests.post(url, headers=headers, json=data)
366
- printd(f"response = {response}")
367
- response.raise_for_status() # Raises HTTPError for 4XX/5XX status
368
- response = response.json() # convert to dict from string
369
- printd(f"response.json = {response}")
370
- response = convert_anthropic_response_to_chatcompletion(response_json=response, inner_thoughts_xml_tag=inner_thoughts_xml_tag)
371
- return response
372
- except requests.exceptions.HTTPError as http_err:
373
- # Handle HTTP errors (e.g., response 4XX, 5XX)
374
- printd(f"Got HTTPError, exception={http_err}, payload={data}")
375
- raise http_err
376
- except requests.exceptions.RequestException as req_err:
377
- # Handle other requests-related errors (e.g., connection error)
378
- printd(f"Got RequestException, exception={req_err}")
379
- raise req_err
380
- except Exception as e:
381
- # Handle other potential errors
382
- printd(f"Got unknown Exception, exception={e}")
383
- raise e
361
+ response_json = make_post_request(url, headers, data)
362
+ return convert_anthropic_response_to_chatcompletion(response_json=response_json, inner_thoughts_xml_tag=inner_thoughts_xml_tag)
@@ -0,0 +1,100 @@
1
+ import requests
2
+
3
+ from letta.llm_api.helpers import make_post_request
4
+ from letta.schemas.llm_config import LLMConfig
5
+ from letta.schemas.openai.chat_completion_response import ChatCompletionResponse
6
+ from letta.schemas.openai.chat_completions import ChatCompletionRequest
7
+ from letta.schemas.openai.embedding_response import EmbeddingResponse
8
+ from letta.settings import ModelSettings
9
+
10
+
11
+ def get_azure_chat_completions_endpoint(base_url: str, model: str, api_version: str):
12
+ return f"{base_url}/openai/deployments/{model}/chat/completions?api-version={api_version}"
13
+
14
+
15
+ def get_azure_embeddings_endpoint(base_url: str, model: str, api_version: str):
16
+ return f"{base_url}/openai/deployments/{model}/embeddings?api-version={api_version}"
17
+
18
+
19
+ def get_azure_model_list_endpoint(base_url: str, api_version: str):
20
+ return f"{base_url}/openai/models?api-version={api_version}"
21
+
22
+
23
+ def azure_openai_get_model_list(base_url: str, api_key: str, api_version: str) -> list:
24
+ """https://learn.microsoft.com/en-us/rest/api/azureopenai/models/list?view=rest-azureopenai-2023-05-15&tabs=HTTP"""
25
+
26
+ # https://xxx.openai.azure.com/openai/models?api-version=xxx
27
+ headers = {"Content-Type": "application/json"}
28
+ if api_key is not None:
29
+ headers["api-key"] = f"{api_key}"
30
+
31
+ url = get_azure_model_list_endpoint(base_url, api_version)
32
+ try:
33
+ response = requests.get(url, headers=headers)
34
+ response.raise_for_status()
35
+ except requests.RequestException as e:
36
+ raise RuntimeError(f"Failed to retrieve model list: {e}")
37
+
38
+ return response.json().get("data", [])
39
+
40
+
41
+ def azure_openai_get_chat_completion_model_list(base_url: str, api_key: str, api_version: str) -> list:
42
+ model_list = azure_openai_get_model_list(base_url, api_key, api_version)
43
+ # Extract models that support text generation
44
+ model_options = [m for m in model_list if m.get("capabilities").get("chat_completion") == True]
45
+ return model_options
46
+
47
+
48
+ def azure_openai_get_embeddings_model_list(base_url: str, api_key: str, api_version: str, require_embedding_in_name: bool = True) -> list:
49
+ def valid_embedding_model(m: dict):
50
+ valid_name = True
51
+ if require_embedding_in_name:
52
+ valid_name = "embedding" in m["id"]
53
+
54
+ return m.get("capabilities").get("embeddings") == True and valid_name
55
+
56
+ model_list = azure_openai_get_model_list(base_url, api_key, api_version)
57
+ # Extract models that support embeddings
58
+
59
+ model_options = [m for m in model_list if valid_embedding_model(m)]
60
+ return model_options
61
+
62
+
63
+ def azure_openai_chat_completions_request(
64
+ model_settings: ModelSettings, llm_config: LLMConfig, api_key: str, chat_completion_request: ChatCompletionRequest
65
+ ) -> ChatCompletionResponse:
66
+ """https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#chat-completions"""
67
+
68
+ assert api_key is not None, "Missing required field when calling Azure OpenAI"
69
+
70
+ headers = {"Content-Type": "application/json", "api-key": f"{api_key}"}
71
+ data = chat_completion_request.model_dump(exclude_none=True)
72
+
73
+ # If functions == None, strip from the payload
74
+ if "functions" in data and data["functions"] is None:
75
+ data.pop("functions")
76
+ data.pop("function_call", None) # extra safe, should exist always (default="auto")
77
+
78
+ if "tools" in data and data["tools"] is None:
79
+ data.pop("tools")
80
+ data.pop("tool_choice", None) # extra safe, should exist always (default="auto")
81
+
82
+ url = get_azure_chat_completions_endpoint(model_settings.azure_base_url, llm_config.model, model_settings.api_version)
83
+ response_json = make_post_request(url, headers, data)
84
+ # NOTE: azure openai does not include "content" in the response when it is None, so we need to add it
85
+ if "content" not in response_json["choices"][0].get("message"):
86
+ response_json["choices"][0]["message"]["content"] = None
87
+ response = ChatCompletionResponse(**response_json) # convert to 'dot-dict' style which is the openai python client default
88
+ return response
89
+
90
+
91
+ def azure_openai_embeddings_request(
92
+ resource_name: str, deployment_id: str, api_version: str, api_key: str, data: dict
93
+ ) -> EmbeddingResponse:
94
+ """https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#embeddings"""
95
+
96
+ url = f"https://{resource_name}.openai.azure.com/openai/deployments/{deployment_id}/embeddings?api-version={api_version}"
97
+ headers = {"Content-Type": "application/json", "api-key": f"{api_key}"}
98
+
99
+ response_json = make_post_request(url, headers, data)
100
+ return EmbeddingResponse(**response_json)