letta-nightly 0.5.1.dev20241103104102__tar.gz → 0.5.1.dev20241105104128__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.
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/PKG-INFO +3 -1
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/agent.py +33 -5
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/cli/cli.py +3 -3
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/cli/cli_config.py +2 -2
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/client/client.py +25 -13
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/functions/schema_generator.py +48 -7
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/metadata.py +10 -10
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/agent.py +6 -2
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/block.py +1 -1
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/letta_base.py +2 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/organization.py +2 -1
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/tool.py +9 -5
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/user.py +2 -2
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/server.py +18 -9
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/services/tool_manager.py +2 -2
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/pyproject.toml +4 -2
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/LICENSE +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/README.md +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/__init__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/__main__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/agent_store/chroma.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/agent_store/db.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/agent_store/lancedb.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/agent_store/milvus.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/agent_store/qdrant.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/agent_store/storage.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/benchmark/benchmark.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/benchmark/constants.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/cli/cli_load.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/client/__init__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/client/streaming.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/client/utils.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/config.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/constants.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/credentials.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/data_sources/connectors.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/data_sources/connectors_helper.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/embeddings.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/errors.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/functions/__init__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/functions/function_sets/base.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/functions/function_sets/extras.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/functions/functions.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/functions/helpers.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/helpers/__init__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/helpers/tool_rule_solver.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/humans/__init__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/humans/examples/basic.txt +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/humans/examples/cs_phd.txt +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/interface.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/llm_api/__init__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/llm_api/anthropic.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/llm_api/azure_openai.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/llm_api/azure_openai_constants.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/llm_api/cohere.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/llm_api/google_ai.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/llm_api/helpers.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/llm_api/llm_api_tools.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/llm_api/mistral.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/llm_api/openai.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/README.md +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/__init__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/chat_completion_proxy.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/constants.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/function_parser.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/grammars/__init__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/grammars/gbnf_grammar_generator.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/grammars/json.gbnf +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/grammars/json_func_calls_with_inner_thoughts.gbnf +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/json_parser.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/koboldcpp/api.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/koboldcpp/settings.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/llamacpp/api.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/llamacpp/settings.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/llm_chat_completion_wrappers/__init__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/llm_chat_completion_wrappers/airoboros.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/llm_chat_completion_wrappers/chatml.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/llm_chat_completion_wrappers/configurable_wrapper.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/llm_chat_completion_wrappers/dolphin.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/llm_chat_completion_wrappers/llama3.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/llm_chat_completion_wrappers/simple_summary_wrapper.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/llm_chat_completion_wrappers/wrapper_base.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/llm_chat_completion_wrappers/zephyr.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/lmstudio/api.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/lmstudio/settings.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/ollama/api.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/ollama/settings.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/settings/__init__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/settings/deterministic_mirostat.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/settings/settings.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/settings/simple.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/utils.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/vllm/api.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/webui/api.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/webui/legacy_api.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/webui/legacy_settings.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/local_llm/webui/settings.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/log.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/main.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/memory.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/o1_agent.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/openai_backcompat/__init__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/openai_backcompat/openai_object.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/orm/__all__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/orm/__init__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/orm/base.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/orm/enums.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/orm/errors.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/orm/mixins.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/orm/organization.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/orm/sqlalchemy_base.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/orm/tool.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/orm/user.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/persistence_manager.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/personas/__init__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/personas/examples/anna_pa.txt +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/personas/examples/google_search_persona.txt +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/personas/examples/memgpt_doc.txt +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/personas/examples/memgpt_starter.txt +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/personas/examples/o1_persona.txt +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/personas/examples/sam.txt +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/personas/examples/sam_pov.txt +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/personas/examples/sam_simple_pov_gpt35.txt +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/personas/examples/sqldb/test.db +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/prompts/__init__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/prompts/gpt_summarize.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/prompts/gpt_system.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/prompts/system/memgpt_base.txt +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/prompts/system/memgpt_chat.txt +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/prompts/system/memgpt_chat_compressed.txt +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/prompts/system/memgpt_chat_fstring.txt +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/prompts/system/memgpt_doc.txt +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/prompts/system/memgpt_gpt35_extralong.txt +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/prompts/system/memgpt_intuitive_knowledge.txt +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/prompts/system/memgpt_modified_chat.txt +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/prompts/system/memgpt_modified_o1.txt +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/providers.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/pytest.ini +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/api_key.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/embedding_config.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/enums.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/file.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/health.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/job.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/letta_message.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/letta_request.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/letta_response.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/llm_config.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/memory.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/message.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/openai/chat_completion_request.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/openai/chat_completion_response.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/openai/chat_completions.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/openai/embedding_response.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/openai/openai.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/passage.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/source.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/tool_rule.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/schemas/usage.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/__init__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/constants.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/__init__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/app.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/auth/__init__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/auth/index.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/auth_token.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/interface.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/routers/__init__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/routers/openai/__init__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/routers/openai/assistants/__init__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/routers/openai/assistants/assistants.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/routers/openai/assistants/schemas.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/routers/openai/assistants/threads.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/routers/openai/chat_completions/__init__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/routers/openai/chat_completions/chat_completions.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/routers/v1/__init__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/routers/v1/agents.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/routers/v1/blocks.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/routers/v1/health.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/routers/v1/jobs.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/routers/v1/llms.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/routers/v1/organizations.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/routers/v1/sources.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/routers/v1/tools.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/routers/v1/users.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/static_files.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/rest_api/utils.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/startup.sh +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/static_files/assets/index-3ab03d5b.css +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/static_files/assets/index-9fa459a2.js +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/static_files/favicon.ico +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/static_files/index.html +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/static_files/memgpt_logo_transparent.png +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/utils.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/ws_api/__init__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/ws_api/example_client.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/ws_api/interface.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/ws_api/protocol.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/server/ws_api/server.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/services/__init__.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/services/organization_manager.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/services/user_manager.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/settings.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/streaming_interface.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/streaming_utils.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/system.py +0 -0
- {letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: letta-nightly
|
|
3
|
-
Version: 0.5.1.
|
|
3
|
+
Version: 0.5.1.dev20241105104128
|
|
4
4
|
Summary: Create LLM agents with long-term memory and custom tools
|
|
5
5
|
License: Apache License
|
|
6
6
|
Author: Letta Team
|
|
@@ -52,6 +52,8 @@ Requires-Dist: pg8000 (>=1.30.3,<2.0.0) ; extra == "postgres"
|
|
|
52
52
|
Requires-Dist: pgvector (>=0.2.3,<0.3.0) ; extra == "postgres"
|
|
53
53
|
Requires-Dist: pre-commit (>=3.5.0,<4.0.0) ; extra == "dev"
|
|
54
54
|
Requires-Dist: prettytable (>=3.9.0,<4.0.0)
|
|
55
|
+
Requires-Dist: psycopg2 (>=2.9.10,<3.0.0) ; extra == "postgres"
|
|
56
|
+
Requires-Dist: psycopg2-binary (>=2.9.10,<3.0.0) ; extra == "postgres"
|
|
55
57
|
Requires-Dist: pyautogen (==0.2.22) ; extra == "autogen"
|
|
56
58
|
Requires-Dist: pydantic (>=2.7.4,<3.0.0)
|
|
57
59
|
Requires-Dist: pydantic-settings (>=2.2.1,<3.0.0)
|
{letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/agent.py
RENAMED
|
@@ -235,6 +235,7 @@ class Agent(BaseAgent):
|
|
|
235
235
|
# extras
|
|
236
236
|
messages_total: Optional[int] = None, # TODO remove?
|
|
237
237
|
first_message_verify_mono: bool = True, # TODO move to config?
|
|
238
|
+
initial_message_sequence: Optional[List[Message]] = None,
|
|
238
239
|
):
|
|
239
240
|
assert isinstance(agent_state.memory, Memory), f"Memory object is not of type Memory: {type(agent_state.memory)}"
|
|
240
241
|
# Hold a copy of the state that was used to init the agent
|
|
@@ -294,6 +295,7 @@ class Agent(BaseAgent):
|
|
|
294
295
|
|
|
295
296
|
else:
|
|
296
297
|
printd(f"Agent.__init__ :: creating, state={agent_state.message_ids}")
|
|
298
|
+
assert self.agent_state.id is not None and self.agent_state.user_id is not None
|
|
297
299
|
|
|
298
300
|
# Generate a sequence of initial messages to put in the buffer
|
|
299
301
|
init_messages = initialize_message_sequence(
|
|
@@ -306,14 +308,40 @@ class Agent(BaseAgent):
|
|
|
306
308
|
include_initial_boot_message=True,
|
|
307
309
|
)
|
|
308
310
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
311
|
+
if initial_message_sequence is not None:
|
|
312
|
+
# We always need the system prompt up front
|
|
313
|
+
system_message_obj = Message.dict_to_message(
|
|
314
|
+
agent_id=self.agent_state.id,
|
|
315
|
+
user_id=self.agent_state.user_id,
|
|
316
|
+
model=self.model,
|
|
317
|
+
openai_message_dict=init_messages[0],
|
|
318
|
+
)
|
|
319
|
+
# Don't use anything else in the pregen sequence, instead use the provided sequence
|
|
320
|
+
init_messages = [system_message_obj] + initial_message_sequence
|
|
321
|
+
|
|
322
|
+
else:
|
|
323
|
+
# Basic "more human than human" initial message sequence
|
|
324
|
+
init_messages = initialize_message_sequence(
|
|
325
|
+
model=self.model,
|
|
326
|
+
system=self.system,
|
|
327
|
+
memory=self.memory,
|
|
328
|
+
archival_memory=None,
|
|
329
|
+
recall_memory=None,
|
|
330
|
+
memory_edit_timestamp=get_utc_time(),
|
|
331
|
+
include_initial_boot_message=True,
|
|
332
|
+
)
|
|
333
|
+
# Cast to Message objects
|
|
334
|
+
init_messages = [
|
|
313
335
|
Message.dict_to_message(
|
|
314
336
|
agent_id=self.agent_state.id, user_id=self.agent_state.user_id, model=self.model, openai_message_dict=msg
|
|
315
337
|
)
|
|
316
|
-
|
|
338
|
+
for msg in init_messages
|
|
339
|
+
]
|
|
340
|
+
|
|
341
|
+
# Cast the messages to actual Message objects to be synced to the DB
|
|
342
|
+
init_messages_objs = []
|
|
343
|
+
for msg in init_messages:
|
|
344
|
+
init_messages_objs.append(msg)
|
|
317
345
|
assert all([isinstance(msg, Message) for msg in init_messages_objs]), (init_messages_objs, init_messages)
|
|
318
346
|
|
|
319
347
|
# Put the messages inside the message buffer
|
{letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/cli/cli.py
RENAMED
|
@@ -282,10 +282,10 @@ def run(
|
|
|
282
282
|
system_prompt = system if system else None
|
|
283
283
|
|
|
284
284
|
memory = ChatMemory(human=human_obj.value, persona=persona_obj.value, limit=core_memory_limit)
|
|
285
|
-
metadata = {"human": human_obj.
|
|
285
|
+
metadata = {"human": human_obj.template_name, "persona": persona_obj.template_name}
|
|
286
286
|
|
|
287
|
-
typer.secho(f"-> {ASSISTANT_MESSAGE_CLI_SYMBOL} Using persona profile: '{persona_obj.
|
|
288
|
-
typer.secho(f"-> 🧑 Using human profile: '{human_obj.
|
|
287
|
+
typer.secho(f"-> {ASSISTANT_MESSAGE_CLI_SYMBOL} Using persona profile: '{persona_obj.template_name}'", fg=typer.colors.WHITE)
|
|
288
|
+
typer.secho(f"-> 🧑 Using human profile: '{human_obj.template_name}'", fg=typer.colors.WHITE)
|
|
289
289
|
|
|
290
290
|
# add tools
|
|
291
291
|
agent_state = client.create_agent(
|
|
@@ -59,13 +59,13 @@ def list(arg: Annotated[ListChoice, typer.Argument]):
|
|
|
59
59
|
"""List all humans"""
|
|
60
60
|
table.field_names = ["Name", "Text"]
|
|
61
61
|
for human in client.list_humans():
|
|
62
|
-
table.add_row([human.
|
|
62
|
+
table.add_row([human.template_name, human.value.replace("\n", "")[:100]])
|
|
63
63
|
print(table)
|
|
64
64
|
elif arg == ListChoice.personas:
|
|
65
65
|
"""List all personas"""
|
|
66
66
|
table.field_names = ["Name", "Text"]
|
|
67
67
|
for persona in client.list_personas():
|
|
68
|
-
table.add_row([persona.
|
|
68
|
+
table.add_row([persona.template_name, persona.value.replace("\n", "")[:100]])
|
|
69
69
|
print(table)
|
|
70
70
|
elif arg == ListChoice.sources:
|
|
71
71
|
"""List all data sources"""
|
|
@@ -376,6 +376,7 @@ class RESTClient(AbstractClient):
|
|
|
376
376
|
# metadata
|
|
377
377
|
metadata: Optional[Dict] = {"human:": DEFAULT_HUMAN, "persona": DEFAULT_PERSONA},
|
|
378
378
|
description: Optional[str] = None,
|
|
379
|
+
initial_message_sequence: Optional[List[Message]] = None,
|
|
379
380
|
) -> AgentState:
|
|
380
381
|
"""Create an agent
|
|
381
382
|
|
|
@@ -428,9 +429,18 @@ class RESTClient(AbstractClient):
|
|
|
428
429
|
agent_type=agent_type,
|
|
429
430
|
llm_config=llm_config if llm_config else self._default_llm_config,
|
|
430
431
|
embedding_config=embedding_config if embedding_config else self._default_embedding_config,
|
|
432
|
+
initial_message_sequence=initial_message_sequence,
|
|
433
|
+
)
|
|
434
|
+
|
|
435
|
+
# Use model_dump_json() instead of model_dump()
|
|
436
|
+
# If we use model_dump(), the datetime objects will not be serialized correctly
|
|
437
|
+
# response = requests.post(f"{self.base_url}/{self.api_prefix}/agents", json=request.model_dump(), headers=self.headers)
|
|
438
|
+
response = requests.post(
|
|
439
|
+
f"{self.base_url}/{self.api_prefix}/agents",
|
|
440
|
+
data=request.model_dump_json(), # Use model_dump_json() instead of json=model_dump()
|
|
441
|
+
headers={"Content-Type": "application/json", **self.headers},
|
|
431
442
|
)
|
|
432
443
|
|
|
433
|
-
response = requests.post(f"{self.base_url}/{self.api_prefix}/agents", json=request.model_dump(), headers=self.headers)
|
|
434
444
|
if response.status_code != 200:
|
|
435
445
|
raise ValueError(f"Status {response.status_code} - Failed to create agent: {response.text}")
|
|
436
446
|
return AgentState(**response.json())
|
|
@@ -859,8 +869,8 @@ class RESTClient(AbstractClient):
|
|
|
859
869
|
else:
|
|
860
870
|
return [Block(**block) for block in response.json()]
|
|
861
871
|
|
|
862
|
-
def create_block(self, label: str, text: str,
|
|
863
|
-
request = CreateBlock(label=label, value=text, template=template,
|
|
872
|
+
def create_block(self, label: str, text: str, template_name: Optional[str] = None, template: bool = False) -> Block: #
|
|
873
|
+
request = CreateBlock(label=label, value=text, template=template, template_name=template_name)
|
|
864
874
|
response = requests.post(f"{self.base_url}/{self.api_prefix}/blocks", json=request.model_dump(), headers=self.headers)
|
|
865
875
|
if response.status_code != 200:
|
|
866
876
|
raise ValueError(f"Failed to create block: {response.text}")
|
|
@@ -872,7 +882,7 @@ class RESTClient(AbstractClient):
|
|
|
872
882
|
return Block(**response.json())
|
|
873
883
|
|
|
874
884
|
def update_block(self, block_id: str, name: Optional[str] = None, text: Optional[str] = None) -> Block:
|
|
875
|
-
request = UpdateBlock(id=block_id,
|
|
885
|
+
request = UpdateBlock(id=block_id, template_name=name, value=text)
|
|
876
886
|
response = requests.post(f"{self.base_url}/{self.api_prefix}/blocks/{block_id}", json=request.model_dump(), headers=self.headers)
|
|
877
887
|
if response.status_code != 200:
|
|
878
888
|
raise ValueError(f"Failed to update block: {response.text}")
|
|
@@ -926,7 +936,7 @@ class RESTClient(AbstractClient):
|
|
|
926
936
|
Returns:
|
|
927
937
|
human (Human): Human block
|
|
928
938
|
"""
|
|
929
|
-
return self.create_block(label="human",
|
|
939
|
+
return self.create_block(label="human", template_name=name, text=text, template=True)
|
|
930
940
|
|
|
931
941
|
def update_human(self, human_id: str, name: Optional[str] = None, text: Optional[str] = None) -> Human:
|
|
932
942
|
"""
|
|
@@ -939,7 +949,7 @@ class RESTClient(AbstractClient):
|
|
|
939
949
|
Returns:
|
|
940
950
|
human (Human): Updated human block
|
|
941
951
|
"""
|
|
942
|
-
request = UpdateHuman(id=human_id,
|
|
952
|
+
request = UpdateHuman(id=human_id, template_name=name, value=text)
|
|
943
953
|
response = requests.post(f"{self.base_url}/{self.api_prefix}/blocks/{human_id}", json=request.model_dump(), headers=self.headers)
|
|
944
954
|
if response.status_code != 200:
|
|
945
955
|
raise ValueError(f"Failed to update human: {response.text}")
|
|
@@ -966,7 +976,7 @@ class RESTClient(AbstractClient):
|
|
|
966
976
|
Returns:
|
|
967
977
|
persona (Persona): Persona block
|
|
968
978
|
"""
|
|
969
|
-
return self.create_block(label="persona",
|
|
979
|
+
return self.create_block(label="persona", template_name=name, text=text, template=True)
|
|
970
980
|
|
|
971
981
|
def update_persona(self, persona_id: str, name: Optional[str] = None, text: Optional[str] = None) -> Persona:
|
|
972
982
|
"""
|
|
@@ -979,7 +989,7 @@ class RESTClient(AbstractClient):
|
|
|
979
989
|
Returns:
|
|
980
990
|
persona (Persona): Updated persona block
|
|
981
991
|
"""
|
|
982
|
-
request = UpdatePersona(id=persona_id,
|
|
992
|
+
request = UpdatePersona(id=persona_id, template_name=name, value=text)
|
|
983
993
|
response = requests.post(f"{self.base_url}/{self.api_prefix}/blocks/{persona_id}", json=request.model_dump(), headers=self.headers)
|
|
984
994
|
if response.status_code != 200:
|
|
985
995
|
raise ValueError(f"Failed to update persona: {response.text}")
|
|
@@ -1648,6 +1658,7 @@ class LocalClient(AbstractClient):
|
|
|
1648
1658
|
# metadata
|
|
1649
1659
|
metadata: Optional[Dict] = {"human:": DEFAULT_HUMAN, "persona": DEFAULT_PERSONA},
|
|
1650
1660
|
description: Optional[str] = None,
|
|
1661
|
+
initial_message_sequence: Optional[List[Message]] = None,
|
|
1651
1662
|
) -> AgentState:
|
|
1652
1663
|
"""Create an agent
|
|
1653
1664
|
|
|
@@ -1702,6 +1713,7 @@ class LocalClient(AbstractClient):
|
|
|
1702
1713
|
agent_type=agent_type,
|
|
1703
1714
|
llm_config=llm_config if llm_config else self._default_llm_config,
|
|
1704
1715
|
embedding_config=embedding_config if embedding_config else self._default_embedding_config,
|
|
1716
|
+
initial_message_sequence=initial_message_sequence,
|
|
1705
1717
|
),
|
|
1706
1718
|
actor=self.user,
|
|
1707
1719
|
)
|
|
@@ -2116,7 +2128,7 @@ class LocalClient(AbstractClient):
|
|
|
2116
2128
|
Returns:
|
|
2117
2129
|
human (Human): Human block
|
|
2118
2130
|
"""
|
|
2119
|
-
return self.server.create_block(CreateHuman(
|
|
2131
|
+
return self.server.create_block(CreateHuman(template_name=name, value=text, user_id=self.user_id), user_id=self.user_id)
|
|
2120
2132
|
|
|
2121
2133
|
def create_persona(self, name: str, text: str):
|
|
2122
2134
|
"""
|
|
@@ -2129,7 +2141,7 @@ class LocalClient(AbstractClient):
|
|
|
2129
2141
|
Returns:
|
|
2130
2142
|
persona (Persona): Persona block
|
|
2131
2143
|
"""
|
|
2132
|
-
return self.server.create_block(CreatePersona(
|
|
2144
|
+
return self.server.create_block(CreatePersona(template_name=name, value=text, user_id=self.user_id), user_id=self.user_id)
|
|
2133
2145
|
|
|
2134
2146
|
def list_humans(self):
|
|
2135
2147
|
"""
|
|
@@ -2635,7 +2647,7 @@ class LocalClient(AbstractClient):
|
|
|
2635
2647
|
"""
|
|
2636
2648
|
return self.server.get_blocks(label=label, template=templates_only)
|
|
2637
2649
|
|
|
2638
|
-
def create_block(self, label: str, text: str,
|
|
2650
|
+
def create_block(self, label: str, text: str, template_name: Optional[str] = None, template: bool = False) -> Block: #
|
|
2639
2651
|
"""
|
|
2640
2652
|
Create a block
|
|
2641
2653
|
|
|
@@ -2648,7 +2660,7 @@ class LocalClient(AbstractClient):
|
|
|
2648
2660
|
block (Block): Created block
|
|
2649
2661
|
"""
|
|
2650
2662
|
return self.server.create_block(
|
|
2651
|
-
CreateBlock(label=label,
|
|
2663
|
+
CreateBlock(label=label, template_name=template_name, value=text, user_id=self.user_id, template=template), user_id=self.user_id
|
|
2652
2664
|
)
|
|
2653
2665
|
|
|
2654
2666
|
def update_block(self, block_id: str, name: Optional[str] = None, text: Optional[str] = None) -> Block:
|
|
@@ -2663,7 +2675,7 @@ class LocalClient(AbstractClient):
|
|
|
2663
2675
|
Returns:
|
|
2664
2676
|
block (Block): Updated block
|
|
2665
2677
|
"""
|
|
2666
|
-
return self.server.update_block(UpdateBlock(id=block_id,
|
|
2678
|
+
return self.server.update_block(UpdateBlock(id=block_id, template_name=name, value=text))
|
|
2667
2679
|
|
|
2668
2680
|
def get_block(self, block_id: str) -> Block:
|
|
2669
2681
|
"""
|
|
@@ -139,32 +139,73 @@ def generate_schema(function, name: Optional[str] = None, description: Optional[
|
|
|
139
139
|
return schema
|
|
140
140
|
|
|
141
141
|
|
|
142
|
-
def
|
|
142
|
+
def generate_schema_from_args_schema_v1(
|
|
143
143
|
args_schema: Type[V1BaseModel], name: Optional[str] = None, description: Optional[str] = None, append_heartbeat: bool = True
|
|
144
144
|
) -> Dict[str, Any]:
|
|
145
145
|
properties = {}
|
|
146
146
|
required = []
|
|
147
147
|
for field_name, field in args_schema.__fields__.items():
|
|
148
|
-
if field.type_
|
|
148
|
+
if field.type_ == str:
|
|
149
149
|
field_type = "string"
|
|
150
|
-
elif field.type_
|
|
150
|
+
elif field.type_ == int:
|
|
151
151
|
field_type = "integer"
|
|
152
|
-
elif field.type_
|
|
152
|
+
elif field.type_ == bool:
|
|
153
153
|
field_type = "boolean"
|
|
154
154
|
else:
|
|
155
155
|
field_type = field.type_.__name__
|
|
156
|
-
|
|
156
|
+
|
|
157
|
+
properties[field_name] = {
|
|
158
|
+
"type": field_type,
|
|
159
|
+
"description": field.field_info.description,
|
|
160
|
+
}
|
|
157
161
|
if field.required:
|
|
158
162
|
required.append(field_name)
|
|
159
163
|
|
|
160
|
-
# Construct the OpenAI function call JSON object
|
|
161
164
|
function_call_json = {
|
|
162
165
|
"name": name,
|
|
163
166
|
"description": description,
|
|
164
167
|
"parameters": {"type": "object", "properties": properties, "required": required},
|
|
165
168
|
}
|
|
166
169
|
|
|
167
|
-
|
|
170
|
+
if append_heartbeat:
|
|
171
|
+
function_call_json["parameters"]["properties"]["request_heartbeat"] = {
|
|
172
|
+
"type": "boolean",
|
|
173
|
+
"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.",
|
|
174
|
+
}
|
|
175
|
+
function_call_json["parameters"]["required"].append("request_heartbeat")
|
|
176
|
+
|
|
177
|
+
return function_call_json
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def generate_schema_from_args_schema_v2(
|
|
181
|
+
args_schema: Type[BaseModel], name: Optional[str] = None, description: Optional[str] = None, append_heartbeat: bool = True
|
|
182
|
+
) -> Dict[str, Any]:
|
|
183
|
+
properties = {}
|
|
184
|
+
required = []
|
|
185
|
+
for field_name, field in args_schema.model_fields.items():
|
|
186
|
+
field_type_annotation = field.annotation
|
|
187
|
+
if field_type_annotation == str:
|
|
188
|
+
field_type = "string"
|
|
189
|
+
elif field_type_annotation == int:
|
|
190
|
+
field_type = "integer"
|
|
191
|
+
elif field_type_annotation == bool:
|
|
192
|
+
field_type = "boolean"
|
|
193
|
+
else:
|
|
194
|
+
field_type = field_type_annotation.__name__
|
|
195
|
+
|
|
196
|
+
properties[field_name] = {
|
|
197
|
+
"type": field_type,
|
|
198
|
+
"description": field.description,
|
|
199
|
+
}
|
|
200
|
+
if field.is_required():
|
|
201
|
+
required.append(field_name)
|
|
202
|
+
|
|
203
|
+
function_call_json = {
|
|
204
|
+
"name": name,
|
|
205
|
+
"description": description,
|
|
206
|
+
"parameters": {"type": "object", "properties": properties, "required": required},
|
|
207
|
+
}
|
|
208
|
+
|
|
168
209
|
if append_heartbeat:
|
|
169
210
|
function_call_json["parameters"]["properties"]["request_heartbeat"] = {
|
|
170
211
|
"type": "boolean",
|
{letta_nightly-0.5.1.dev20241103104102 → letta_nightly-0.5.1.dev20241105104128}/letta/metadata.py
RENAMED
|
@@ -348,7 +348,7 @@ class BlockModel(Base):
|
|
|
348
348
|
id = Column(String, primary_key=True, nullable=False)
|
|
349
349
|
value = Column(String, nullable=False)
|
|
350
350
|
limit = Column(BIGINT)
|
|
351
|
-
|
|
351
|
+
template_name = Column(String, nullable=True, default=None)
|
|
352
352
|
template = Column(Boolean, default=False) # True: listed as possible human/persona
|
|
353
353
|
label = Column(String, nullable=False)
|
|
354
354
|
metadata_ = Column(JSON)
|
|
@@ -357,7 +357,7 @@ class BlockModel(Base):
|
|
|
357
357
|
Index(__tablename__ + "_idx_user", user_id),
|
|
358
358
|
|
|
359
359
|
def __repr__(self) -> str:
|
|
360
|
-
return f"<Block(id='{self.id}',
|
|
360
|
+
return f"<Block(id='{self.id}', template_name='{self.template_name}', template='{self.template_name}', label='{self.label}', user_id='{self.user_id}')>"
|
|
361
361
|
|
|
362
362
|
def to_record(self) -> Block:
|
|
363
363
|
if self.label == "persona":
|
|
@@ -365,7 +365,7 @@ class BlockModel(Base):
|
|
|
365
365
|
id=self.id,
|
|
366
366
|
value=self.value,
|
|
367
367
|
limit=self.limit,
|
|
368
|
-
|
|
368
|
+
template_name=self.template_name,
|
|
369
369
|
template=self.template,
|
|
370
370
|
label=self.label,
|
|
371
371
|
metadata_=self.metadata_,
|
|
@@ -377,7 +377,7 @@ class BlockModel(Base):
|
|
|
377
377
|
id=self.id,
|
|
378
378
|
value=self.value,
|
|
379
379
|
limit=self.limit,
|
|
380
|
-
|
|
380
|
+
template_name=self.template_name,
|
|
381
381
|
template=self.template,
|
|
382
382
|
label=self.label,
|
|
383
383
|
metadata_=self.metadata_,
|
|
@@ -389,7 +389,7 @@ class BlockModel(Base):
|
|
|
389
389
|
id=self.id,
|
|
390
390
|
value=self.value,
|
|
391
391
|
limit=self.limit,
|
|
392
|
-
|
|
392
|
+
template_name=self.template_name,
|
|
393
393
|
template=self.template,
|
|
394
394
|
label=self.label,
|
|
395
395
|
metadata_=self.metadata_,
|
|
@@ -512,7 +512,7 @@ class MetadataStore:
|
|
|
512
512
|
# with a given name doesn't exist.
|
|
513
513
|
if (
|
|
514
514
|
session.query(BlockModel)
|
|
515
|
-
.filter(BlockModel.
|
|
515
|
+
.filter(BlockModel.template_name == block.template_name)
|
|
516
516
|
.filter(BlockModel.user_id == block.user_id)
|
|
517
517
|
.filter(BlockModel.template == True)
|
|
518
518
|
.filter(BlockModel.label == block.label)
|
|
@@ -520,7 +520,7 @@ class MetadataStore:
|
|
|
520
520
|
> 0
|
|
521
521
|
):
|
|
522
522
|
|
|
523
|
-
raise ValueError(f"Block with name {block.
|
|
523
|
+
raise ValueError(f"Block with name {block.template_name} already exists")
|
|
524
524
|
session.add(BlockModel(**vars(block)))
|
|
525
525
|
session.commit()
|
|
526
526
|
|
|
@@ -658,7 +658,7 @@ class MetadataStore:
|
|
|
658
658
|
user_id: Optional[str],
|
|
659
659
|
label: Optional[str] = None,
|
|
660
660
|
template: Optional[bool] = None,
|
|
661
|
-
|
|
661
|
+
template_name: Optional[str] = None,
|
|
662
662
|
id: Optional[str] = None,
|
|
663
663
|
) -> Optional[List[Block]]:
|
|
664
664
|
"""List available blocks"""
|
|
@@ -671,8 +671,8 @@ class MetadataStore:
|
|
|
671
671
|
if label:
|
|
672
672
|
query = query.filter(BlockModel.label == label)
|
|
673
673
|
|
|
674
|
-
if
|
|
675
|
-
query = query.filter(BlockModel.
|
|
674
|
+
if template_name:
|
|
675
|
+
query = query.filter(BlockModel.template_name == template_name)
|
|
676
676
|
|
|
677
677
|
if id:
|
|
678
678
|
query = query.filter(BlockModel.id == id)
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import uuid
|
|
2
1
|
from datetime import datetime
|
|
3
2
|
from enum import Enum
|
|
4
3
|
from typing import Dict, List, Optional
|
|
@@ -105,7 +104,7 @@ class AgentState(BaseAgent, validate_assignment=True):
|
|
|
105
104
|
class CreateAgent(BaseAgent):
|
|
106
105
|
# all optional as server can generate defaults
|
|
107
106
|
name: Optional[str] = Field(None, description="The name of the agent.")
|
|
108
|
-
message_ids: Optional[List[
|
|
107
|
+
message_ids: Optional[List[str]] = Field(None, description="The ids of the messages in the agent's in-context memory.")
|
|
109
108
|
memory: Optional[Memory] = Field(None, description="The in-context memory of the agent.")
|
|
110
109
|
tools: Optional[List[str]] = Field(None, description="The tools used by the agent.")
|
|
111
110
|
tool_rules: Optional[List[BaseToolRule]] = Field(None, description="The tool rules governing the agent.")
|
|
@@ -113,6 +112,11 @@ class CreateAgent(BaseAgent):
|
|
|
113
112
|
agent_type: Optional[AgentType] = Field(None, description="The type of agent.")
|
|
114
113
|
llm_config: Optional[LLMConfig] = Field(None, description="The LLM configuration used by the agent.")
|
|
115
114
|
embedding_config: Optional[EmbeddingConfig] = Field(None, description="The embedding configuration used by the agent.")
|
|
115
|
+
# Note: if this is None, then we'll populate with the standard "more human than human" initial message sequence
|
|
116
|
+
# If the client wants to make this empty, then the client can set the arg to an empty list
|
|
117
|
+
initial_message_sequence: Optional[List[Message]] = Field(
|
|
118
|
+
None, description="The initial set of messages to put in the agent's in-context memory."
|
|
119
|
+
)
|
|
116
120
|
|
|
117
121
|
@field_validator("name")
|
|
118
122
|
@classmethod
|
|
@@ -18,7 +18,7 @@ class BaseBlock(LettaBase, validate_assignment=True):
|
|
|
18
18
|
limit: int = Field(2000, description="Character limit of the block.")
|
|
19
19
|
|
|
20
20
|
# template data (optional)
|
|
21
|
-
|
|
21
|
+
template_name: Optional[str] = Field(None, description="Name of the block if it is a template.")
|
|
22
22
|
template: bool = Field(False, description="Whether the block is a template (e.g. saved human/persona options).")
|
|
23
23
|
|
|
24
24
|
# context window label
|
|
@@ -21,6 +21,8 @@ class LettaBase(BaseModel):
|
|
|
21
21
|
from_attributes=True,
|
|
22
22
|
# throw errors if attributes are given that don't belong
|
|
23
23
|
extra="forbid",
|
|
24
|
+
# handle datetime serialization consistently across all models
|
|
25
|
+
# json_encoders={datetime: lambda dt: (dt.replace(tzinfo=timezone.utc) if dt.tzinfo is None else dt).isoformat()},
|
|
24
26
|
)
|
|
25
27
|
|
|
26
28
|
# def __id_prefix__(self):
|
|
@@ -4,6 +4,7 @@ from typing import Optional
|
|
|
4
4
|
from pydantic import Field
|
|
5
5
|
|
|
6
6
|
from letta.schemas.letta_base import LettaBase
|
|
7
|
+
from letta.utils import get_utc_time
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
class OrganizationBase(LettaBase):
|
|
@@ -13,7 +14,7 @@ class OrganizationBase(LettaBase):
|
|
|
13
14
|
class Organization(OrganizationBase):
|
|
14
15
|
id: str = Field(..., description="The id of the organization.")
|
|
15
16
|
name: str = Field(..., description="The name of the organization.")
|
|
16
|
-
created_at: datetime = Field(default_factory=
|
|
17
|
+
created_at: Optional[datetime] = Field(default_factory=get_utc_time, description="The creation date of the organization.")
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
class OrganizationCreate(OrganizationBase):
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from typing import Dict, List, Optional
|
|
2
2
|
|
|
3
|
+
from composio import LogLevel
|
|
3
4
|
from pydantic import Field
|
|
4
5
|
|
|
5
6
|
from letta.functions.helpers import (
|
|
@@ -7,7 +8,10 @@ from letta.functions.helpers import (
|
|
|
7
8
|
generate_crewai_tool_wrapper,
|
|
8
9
|
generate_langchain_tool_wrapper,
|
|
9
10
|
)
|
|
10
|
-
from letta.functions.schema_generator import
|
|
11
|
+
from letta.functions.schema_generator import (
|
|
12
|
+
generate_schema_from_args_schema_v1,
|
|
13
|
+
generate_schema_from_args_schema_v2,
|
|
14
|
+
)
|
|
11
15
|
from letta.schemas.letta_base import LettaBase
|
|
12
16
|
from letta.schemas.openai.chat_completions import ToolCall
|
|
13
17
|
|
|
@@ -84,7 +88,7 @@ class ToolCreate(LettaBase):
|
|
|
84
88
|
"""
|
|
85
89
|
from composio_langchain import ComposioToolSet
|
|
86
90
|
|
|
87
|
-
composio_toolset = ComposioToolSet()
|
|
91
|
+
composio_toolset = ComposioToolSet(logging_level=LogLevel.ERROR)
|
|
88
92
|
composio_tools = composio_toolset.get_tools(actions=[action])
|
|
89
93
|
|
|
90
94
|
assert len(composio_tools) > 0, "User supplied parameters do not match any Composio tools"
|
|
@@ -96,7 +100,7 @@ class ToolCreate(LettaBase):
|
|
|
96
100
|
source_type = "python"
|
|
97
101
|
tags = ["composio"]
|
|
98
102
|
wrapper_func_name, wrapper_function_str = generate_composio_tool_wrapper(action)
|
|
99
|
-
json_schema =
|
|
103
|
+
json_schema = generate_schema_from_args_schema_v2(composio_tool.args_schema, name=wrapper_func_name, description=description)
|
|
100
104
|
|
|
101
105
|
return cls(
|
|
102
106
|
name=wrapper_func_name,
|
|
@@ -128,7 +132,7 @@ class ToolCreate(LettaBase):
|
|
|
128
132
|
tags = ["langchain"]
|
|
129
133
|
# NOTE: langchain tools may come from different packages
|
|
130
134
|
wrapper_func_name, wrapper_function_str = generate_langchain_tool_wrapper(langchain_tool, additional_imports_module_attr_map)
|
|
131
|
-
json_schema =
|
|
135
|
+
json_schema = generate_schema_from_args_schema_v1(langchain_tool.args_schema, name=wrapper_func_name, description=description)
|
|
132
136
|
|
|
133
137
|
return cls(
|
|
134
138
|
name=wrapper_func_name,
|
|
@@ -158,7 +162,7 @@ class ToolCreate(LettaBase):
|
|
|
158
162
|
source_type = "python"
|
|
159
163
|
tags = ["crew-ai"]
|
|
160
164
|
wrapper_func_name, wrapper_function_str = generate_crewai_tool_wrapper(crewai_tool, additional_imports_module_attr_map)
|
|
161
|
-
json_schema =
|
|
165
|
+
json_schema = generate_schema_from_args_schema_v1(crewai_tool.args_schema, name=wrapper_func_name, description=description)
|
|
162
166
|
|
|
163
167
|
return cls(
|
|
164
168
|
name=wrapper_func_name,
|
|
@@ -24,8 +24,8 @@ class User(UserBase):
|
|
|
24
24
|
id: str = Field(..., description="The id of the user.")
|
|
25
25
|
organization_id: Optional[str] = Field(OrganizationManager.DEFAULT_ORG_ID, description="The organization id of the user")
|
|
26
26
|
name: str = Field(..., description="The name of the user.")
|
|
27
|
-
created_at: datetime = Field(default_factory=datetime.utcnow, description="The creation date of the user.")
|
|
28
|
-
updated_at: datetime = Field(default_factory=datetime.utcnow, description="The update date of the user.")
|
|
27
|
+
created_at: Optional[datetime] = Field(default_factory=datetime.utcnow, description="The creation date of the user.")
|
|
28
|
+
updated_at: Optional[datetime] = Field(default_factory=datetime.utcnow, description="The update date of the user.")
|
|
29
29
|
is_deleted: bool = Field(False, description="Whether this user is deleted or not.")
|
|
30
30
|
|
|
31
31
|
|
|
@@ -857,7 +857,10 @@ class SyncServer(Server):
|
|
|
857
857
|
agent_state=agent_state,
|
|
858
858
|
tools=tool_objs,
|
|
859
859
|
# gpt-3.5-turbo tends to omit inner monologue, relax this requirement for now
|
|
860
|
-
first_message_verify_mono=
|
|
860
|
+
first_message_verify_mono=(
|
|
861
|
+
True if (llm_config and llm_config.model is not None and "gpt-4" in llm_config.model) else False
|
|
862
|
+
),
|
|
863
|
+
initial_message_sequence=request.initial_message_sequence,
|
|
861
864
|
)
|
|
862
865
|
elif request.agent_type == AgentType.o1_agent:
|
|
863
866
|
agent = O1Agent(
|
|
@@ -865,7 +868,9 @@ class SyncServer(Server):
|
|
|
865
868
|
agent_state=agent_state,
|
|
866
869
|
tools=tool_objs,
|
|
867
870
|
# gpt-3.5-turbo tends to omit inner monologue, relax this requirement for now
|
|
868
|
-
first_message_verify_mono=
|
|
871
|
+
first_message_verify_mono=(
|
|
872
|
+
True if (llm_config and llm_config.model is not None and "gpt-4" in llm_config.model) else False
|
|
873
|
+
),
|
|
869
874
|
)
|
|
870
875
|
# rebuilding agent memory on agent create in case shared memory blocks
|
|
871
876
|
# were specified in the new agent's memory config. we're doing this for two reasons:
|
|
@@ -1084,7 +1089,7 @@ class SyncServer(Server):
|
|
|
1084
1089
|
id: Optional[str] = None,
|
|
1085
1090
|
) -> Optional[List[Block]]:
|
|
1086
1091
|
|
|
1087
|
-
return self.ms.get_blocks(user_id=user_id, label=label, template=template,
|
|
1092
|
+
return self.ms.get_blocks(user_id=user_id, label=label, template=template, template_name=name, id=id)
|
|
1088
1093
|
|
|
1089
1094
|
def get_block(self, block_id: str):
|
|
1090
1095
|
|
|
@@ -1096,14 +1101,18 @@ class SyncServer(Server):
|
|
|
1096
1101
|
return blocks[0]
|
|
1097
1102
|
|
|
1098
1103
|
def create_block(self, request: CreateBlock, user_id: str, update: bool = False) -> Block:
|
|
1099
|
-
existing_blocks = self.ms.get_blocks(
|
|
1100
|
-
|
|
1104
|
+
existing_blocks = self.ms.get_blocks(
|
|
1105
|
+
template_name=request.template_name, user_id=user_id, template=request.template, label=request.label
|
|
1106
|
+
)
|
|
1107
|
+
|
|
1108
|
+
# for templates, update existing block template if exists
|
|
1109
|
+
if existing_blocks is not None and request.template:
|
|
1101
1110
|
existing_block = existing_blocks[0]
|
|
1102
1111
|
assert len(existing_blocks) == 1
|
|
1103
1112
|
if update:
|
|
1104
1113
|
return self.update_block(UpdateBlock(id=existing_block.id, **vars(request)))
|
|
1105
1114
|
else:
|
|
1106
|
-
raise ValueError(f"Block with name {request.
|
|
1115
|
+
raise ValueError(f"Block with name {request.template_name} already exists")
|
|
1107
1116
|
block = Block(**vars(request))
|
|
1108
1117
|
self.ms.create_block(block)
|
|
1109
1118
|
return block
|
|
@@ -1112,7 +1121,7 @@ class SyncServer(Server):
|
|
|
1112
1121
|
block = self.get_block(request.id)
|
|
1113
1122
|
block.limit = request.limit if request.limit is not None else block.limit
|
|
1114
1123
|
block.value = request.value if request.value is not None else block.value
|
|
1115
|
-
block.
|
|
1124
|
+
block.template_name = request.template_name if request.template_name is not None else block.template_name
|
|
1116
1125
|
self.ms.update_block(block=block)
|
|
1117
1126
|
return self.ms.get_block(block_id=request.id)
|
|
1118
1127
|
|
|
@@ -1773,12 +1782,12 @@ class SyncServer(Server):
|
|
|
1773
1782
|
for persona_file in list_persona_files():
|
|
1774
1783
|
text = open(persona_file, "r", encoding="utf-8").read()
|
|
1775
1784
|
name = os.path.basename(persona_file).replace(".txt", "")
|
|
1776
|
-
self.create_block(CreatePersona(user_id=user_id,
|
|
1785
|
+
self.create_block(CreatePersona(user_id=user_id, template_name=name, value=text, template=True), user_id=user_id, update=True)
|
|
1777
1786
|
|
|
1778
1787
|
for human_file in list_human_files():
|
|
1779
1788
|
text = open(human_file, "r", encoding="utf-8").read()
|
|
1780
1789
|
name = os.path.basename(human_file).replace(".txt", "")
|
|
1781
|
-
self.create_block(CreateHuman(user_id=user_id,
|
|
1790
|
+
self.create_block(CreateHuman(user_id=user_id, template_name=name, value=text, template=True), user_id=user_id, update=True)
|
|
1782
1791
|
|
|
1783
1792
|
def get_agent_message(self, agent_id: str, message_id: str) -> Optional[Message]:
|
|
1784
1793
|
"""Get a single message from the agent's memory"""
|
|
@@ -12,7 +12,7 @@ from letta.orm.tool import Tool as ToolModel
|
|
|
12
12
|
from letta.schemas.tool import Tool as PydanticTool
|
|
13
13
|
from letta.schemas.tool import ToolCreate, ToolUpdate
|
|
14
14
|
from letta.schemas.user import User as PydanticUser
|
|
15
|
-
from letta.utils import enforce_types
|
|
15
|
+
from letta.utils import enforce_types, printd
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
class ToolManager:
|
|
@@ -54,7 +54,7 @@ class ToolManager:
|
|
|
54
54
|
if update_data:
|
|
55
55
|
self.update_tool_by_id(tool.id, ToolUpdate(**update_data), actor)
|
|
56
56
|
else:
|
|
57
|
-
|
|
57
|
+
printd(
|
|
58
58
|
f"`create_or_update_tool` was called with user_id={actor.id}, organization_id={actor.organization_id}, name={tool_create.name}, but found existing tool with nothing to update."
|
|
59
59
|
)
|
|
60
60
|
except NoResultFound:
|