letta-nightly 0.5.4.dev20241125104219__tar.gz → 0.5.4.dev20241127104220__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.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/PKG-INFO +1 -1
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/agent.py +6 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/cli/cli_config.py +1 -1
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/client/client.py +72 -47
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/errors.py +12 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/functions/functions.py +4 -6
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/functions/schema_generator.py +6 -5
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/metadata.py +6 -1
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/orm/block.py +2 -1
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/orm/blocks_agents.py +4 -1
- letta_nightly-0.5.4.dev20241127104220/letta/orm/errors.py +14 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/orm/sqlalchemy_base.py +59 -7
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/block.py +1 -1
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/tool.py +25 -1
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/routers/v1/agents.py +15 -13
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/routers/v1/tools.py +48 -7
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/server.py +10 -2
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/services/block_manager.py +17 -1
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/services/blocks_agents_manager.py +8 -1
- letta_nightly-0.5.4.dev20241127104220/letta/services/per_agent_lock_manager.py +18 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/services/tool_manager.py +5 -12
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/pyproject.toml +1 -1
- letta_nightly-0.5.4.dev20241125104219/letta/orm/errors.py +0 -6
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/LICENSE +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/README.md +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/__init__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/__main__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/agent_store/chroma.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/agent_store/db.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/agent_store/lancedb.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/agent_store/milvus.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/agent_store/qdrant.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/agent_store/storage.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/benchmark/benchmark.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/benchmark/constants.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/cli/cli.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/cli/cli_load.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/client/__init__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/client/streaming.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/client/utils.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/config.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/constants.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/credentials.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/data_sources/connectors.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/data_sources/connectors_helper.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/embeddings.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/functions/__init__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/functions/function_sets/base.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/functions/function_sets/extras.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/functions/helpers.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/helpers/__init__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/helpers/tool_rule_solver.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/humans/__init__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/humans/examples/basic.txt +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/humans/examples/cs_phd.txt +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/interface.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/llm_api/__init__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/llm_api/anthropic.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/llm_api/azure_openai.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/llm_api/azure_openai_constants.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/llm_api/cohere.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/llm_api/google_ai.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/llm_api/helpers.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/llm_api/llm_api_tools.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/llm_api/mistral.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/llm_api/openai.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/README.md +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/__init__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/chat_completion_proxy.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/constants.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/function_parser.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/grammars/__init__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/grammars/gbnf_grammar_generator.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/grammars/json.gbnf +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/grammars/json_func_calls_with_inner_thoughts.gbnf +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/json_parser.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/koboldcpp/api.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/koboldcpp/settings.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/llamacpp/api.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/llamacpp/settings.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/llm_chat_completion_wrappers/__init__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/llm_chat_completion_wrappers/airoboros.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/llm_chat_completion_wrappers/chatml.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/llm_chat_completion_wrappers/configurable_wrapper.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/llm_chat_completion_wrappers/dolphin.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/llm_chat_completion_wrappers/llama3.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/llm_chat_completion_wrappers/simple_summary_wrapper.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/llm_chat_completion_wrappers/wrapper_base.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/llm_chat_completion_wrappers/zephyr.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/lmstudio/api.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/lmstudio/settings.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/ollama/api.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/ollama/settings.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/settings/__init__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/settings/deterministic_mirostat.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/settings/settings.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/settings/simple.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/utils.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/vllm/api.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/webui/api.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/webui/legacy_api.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/webui/legacy_settings.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/local_llm/webui/settings.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/log.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/main.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/memory.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/o1_agent.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/openai_backcompat/__init__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/openai_backcompat/openai_object.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/orm/__all__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/orm/__init__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/orm/agents_tags.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/orm/base.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/orm/enums.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/orm/file.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/orm/mixins.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/orm/organization.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/orm/sandbox_config.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/orm/source.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/orm/tool.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/orm/user.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/persistence_manager.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/personas/__init__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/personas/examples/anna_pa.txt +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/personas/examples/google_search_persona.txt +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/personas/examples/memgpt_doc.txt +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/personas/examples/memgpt_starter.txt +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/personas/examples/o1_persona.txt +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/personas/examples/sam.txt +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/personas/examples/sam_pov.txt +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/personas/examples/sam_simple_pov_gpt35.txt +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/personas/examples/sqldb/test.db +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/prompts/__init__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/prompts/gpt_summarize.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/prompts/gpt_system.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/prompts/system/memgpt_base.txt +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/prompts/system/memgpt_chat.txt +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/prompts/system/memgpt_chat_compressed.txt +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/prompts/system/memgpt_chat_fstring.txt +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/prompts/system/memgpt_doc.txt +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/prompts/system/memgpt_gpt35_extralong.txt +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/prompts/system/memgpt_intuitive_knowledge.txt +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/prompts/system/memgpt_modified_chat.txt +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/prompts/system/memgpt_modified_o1.txt +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/providers.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/pytest.ini +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/agent.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/agents_tags.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/api_key.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/blocks_agents.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/embedding_config.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/enums.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/file.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/health.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/job.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/letta_base.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/letta_message.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/letta_request.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/letta_response.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/llm_config.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/memory.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/message.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/openai/chat_completion_request.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/openai/chat_completion_response.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/openai/chat_completions.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/openai/embedding_response.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/openai/openai.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/organization.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/passage.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/sandbox_config.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/source.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/tool_rule.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/usage.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/schemas/user.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/__init__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/constants.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/generate_openapi_schema.sh +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/__init__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/app.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/auth/__init__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/auth/index.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/auth_token.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/interface.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/routers/__init__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/routers/openai/__init__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/routers/openai/assistants/__init__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/routers/openai/assistants/assistants.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/routers/openai/assistants/schemas.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/routers/openai/assistants/threads.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/routers/openai/chat_completions/__init__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/routers/openai/chat_completions/chat_completions.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/routers/v1/__init__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/routers/v1/blocks.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/routers/v1/health.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/routers/v1/jobs.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/routers/v1/llms.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/routers/v1/organizations.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/routers/v1/sandbox_configs.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/routers/v1/sources.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/routers/v1/users.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/static_files.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/rest_api/utils.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/startup.sh +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/static_files/assets/index-3ab03d5b.css +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/static_files/assets/index-9fa459a2.js +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/static_files/favicon.ico +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/static_files/index.html +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/static_files/memgpt_logo_transparent.png +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/utils.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/ws_api/__init__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/ws_api/example_client.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/ws_api/interface.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/ws_api/protocol.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/server/ws_api/server.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/services/__init__.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/services/agents_tags_manager.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/services/organization_manager.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/services/sandbox_config_manager.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/services/source_manager.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/services/tool_execution_sandbox.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/services/tool_sandbox_env/.gitkeep +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/services/user_manager.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/settings.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/streaming_interface.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/streaming_utils.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/system.py +0 -0
- {letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/utils.py +0 -0
{letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/agent.py
RENAMED
|
@@ -1325,6 +1325,12 @@ class Agent(BaseAgent):
|
|
|
1325
1325
|
|
|
1326
1326
|
def update_state(self) -> AgentState:
|
|
1327
1327
|
message_ids = [msg.id for msg in self._messages]
|
|
1328
|
+
|
|
1329
|
+
# Assert that these are all strings
|
|
1330
|
+
if any(not isinstance(m_id, str) for m_id in message_ids):
|
|
1331
|
+
warnings.warn(f"Non-string message IDs found in agent state: {message_ids}")
|
|
1332
|
+
message_ids = [m_id for m_id in message_ids if isinstance(m_id, str)]
|
|
1333
|
+
|
|
1328
1334
|
assert isinstance(self.memory, Memory), f"Memory is not a Memory object: {type(self.memory)}"
|
|
1329
1335
|
|
|
1330
1336
|
# override any fields that may have been updated
|
|
@@ -136,7 +136,7 @@ def add_tool(
|
|
|
136
136
|
func = eval(func_def.name)
|
|
137
137
|
|
|
138
138
|
# 4. Add or update the tool
|
|
139
|
-
tool = client.
|
|
139
|
+
tool = client.create_or_update_tool(func=func, name=name, tags=tags, update=update)
|
|
140
140
|
print(f"Tool {tool.name} added successfully")
|
|
141
141
|
|
|
142
142
|
|
|
@@ -211,6 +211,14 @@ class AbstractClient(object):
|
|
|
211
211
|
) -> Tool:
|
|
212
212
|
raise NotImplementedError
|
|
213
213
|
|
|
214
|
+
def create_or_update_tool(
|
|
215
|
+
self,
|
|
216
|
+
func,
|
|
217
|
+
name: Optional[str] = None,
|
|
218
|
+
tags: Optional[List[str]] = None,
|
|
219
|
+
) -> Tool:
|
|
220
|
+
raise NotImplementedError
|
|
221
|
+
|
|
214
222
|
def update_tool(
|
|
215
223
|
self,
|
|
216
224
|
id: str,
|
|
@@ -532,7 +540,7 @@ class RESTClient(AbstractClient):
|
|
|
532
540
|
# add memory tools
|
|
533
541
|
memory_functions = get_memory_functions(memory)
|
|
534
542
|
for func_name, func in memory_functions.items():
|
|
535
|
-
tool = self.
|
|
543
|
+
tool = self.create_or_update_tool(func, name=func_name, tags=["memory", "letta-base"])
|
|
536
544
|
tool_names.append(tool.name)
|
|
537
545
|
|
|
538
546
|
# check if default configs are provided
|
|
@@ -1440,18 +1448,39 @@ class RESTClient(AbstractClient):
|
|
|
1440
1448
|
Returns:
|
|
1441
1449
|
tool (Tool): The created tool.
|
|
1442
1450
|
"""
|
|
1451
|
+
source_code = parse_source_code(func)
|
|
1452
|
+
source_type = "python"
|
|
1443
1453
|
|
|
1444
|
-
#
|
|
1445
|
-
|
|
1454
|
+
# call server function
|
|
1455
|
+
request = ToolCreate(source_type=source_type, source_code=source_code, name=name, tags=tags)
|
|
1456
|
+
response = requests.post(f"{self.base_url}/{self.api_prefix}/tools", json=request.model_dump(), headers=self.headers)
|
|
1457
|
+
if response.status_code != 200:
|
|
1458
|
+
raise ValueError(f"Failed to create tool: {response.text}")
|
|
1459
|
+
return Tool(**response.json())
|
|
1446
1460
|
|
|
1447
|
-
|
|
1448
|
-
|
|
1461
|
+
def create_or_update_tool(
|
|
1462
|
+
self,
|
|
1463
|
+
func: Callable,
|
|
1464
|
+
name: Optional[str] = None,
|
|
1465
|
+
tags: Optional[List[str]] = None,
|
|
1466
|
+
) -> Tool:
|
|
1467
|
+
"""
|
|
1468
|
+
Creates or updates a tool. This stores the source code of function on the server, so that the server can execute the function and generate an OpenAI JSON schemas for it when using with an agent.
|
|
1469
|
+
|
|
1470
|
+
Args:
|
|
1471
|
+
func (callable): The function to create a tool for.
|
|
1472
|
+
name: (str): Name of the tool (must be unique per-user.)
|
|
1473
|
+
tags (Optional[List[str]], optional): Tags for the tool. Defaults to None.
|
|
1474
|
+
|
|
1475
|
+
Returns:
|
|
1476
|
+
tool (Tool): The created tool.
|
|
1477
|
+
"""
|
|
1449
1478
|
source_code = parse_source_code(func)
|
|
1450
1479
|
source_type = "python"
|
|
1451
1480
|
|
|
1452
1481
|
# call server function
|
|
1453
1482
|
request = ToolCreate(source_type=source_type, source_code=source_code, name=name, tags=tags)
|
|
1454
|
-
response = requests.
|
|
1483
|
+
response = requests.put(f"{self.base_url}/{self.api_prefix}/tools", json=request.model_dump(), headers=self.headers)
|
|
1455
1484
|
if response.status_code != 200:
|
|
1456
1485
|
raise ValueError(f"Failed to create tool: {response.text}")
|
|
1457
1486
|
return Tool(**response.json())
|
|
@@ -1489,45 +1518,6 @@ class RESTClient(AbstractClient):
|
|
|
1489
1518
|
raise ValueError(f"Failed to update tool: {response.text}")
|
|
1490
1519
|
return Tool(**response.json())
|
|
1491
1520
|
|
|
1492
|
-
# def create_tool(
|
|
1493
|
-
# self,
|
|
1494
|
-
# func,
|
|
1495
|
-
# name: Optional[str] = None,
|
|
1496
|
-
# update: Optional[bool] = True, # TODO: actually use this
|
|
1497
|
-
# tags: Optional[List[str]] = None,
|
|
1498
|
-
# ):
|
|
1499
|
-
# """Create a tool
|
|
1500
|
-
|
|
1501
|
-
# Args:
|
|
1502
|
-
# func (callable): The function to create a tool for.
|
|
1503
|
-
# tags (Optional[List[str]], optional): Tags for the tool. Defaults to None.
|
|
1504
|
-
# update (bool, optional): Update the tool if it already exists. Defaults to True.
|
|
1505
|
-
|
|
1506
|
-
# Returns:
|
|
1507
|
-
# Tool object
|
|
1508
|
-
# """
|
|
1509
|
-
|
|
1510
|
-
# # TODO: check if tool already exists
|
|
1511
|
-
# # TODO: how to load modules?
|
|
1512
|
-
# # parse source code/schema
|
|
1513
|
-
# source_code = parse_source_code(func)
|
|
1514
|
-
# json_schema = generate_schema(func, name)
|
|
1515
|
-
# source_type = "python"
|
|
1516
|
-
# json_schema["name"]
|
|
1517
|
-
|
|
1518
|
-
# # create data
|
|
1519
|
-
# data = {"source_code": source_code, "source_type": source_type, "tags": tags, "json_schema": json_schema, "update": update}
|
|
1520
|
-
# try:
|
|
1521
|
-
# CreateToolRequest(**data) # validate data
|
|
1522
|
-
# except Exception as e:
|
|
1523
|
-
# raise ValueError(f"Failed to create tool: {e}, invalid input {data}")
|
|
1524
|
-
|
|
1525
|
-
# # make REST request
|
|
1526
|
-
# response = requests.post(f"{self.base_url}/{self.api_prefix}/tools", json=data, headers=self.headers)
|
|
1527
|
-
# if response.status_code != 200:
|
|
1528
|
-
# raise ValueError(f"Failed to create tool: {response.text}")
|
|
1529
|
-
# return ToolModel(**response.json())
|
|
1530
|
-
|
|
1531
1521
|
def list_tools(self, cursor: Optional[str] = None, limit: Optional[int] = 50) -> List[Tool]:
|
|
1532
1522
|
"""
|
|
1533
1523
|
List available tools for the user.
|
|
@@ -1977,7 +1967,7 @@ class LocalClient(AbstractClient):
|
|
|
1977
1967
|
# add memory tools
|
|
1978
1968
|
memory_functions = get_memory_functions(memory)
|
|
1979
1969
|
for func_name, func in memory_functions.items():
|
|
1980
|
-
tool = self.
|
|
1970
|
+
tool = self.create_or_update_tool(func, name=func_name, tags=["memory", "letta-base"])
|
|
1981
1971
|
tool_names.append(tool.name)
|
|
1982
1972
|
|
|
1983
1973
|
self.interface.clear()
|
|
@@ -2573,7 +2563,6 @@ class LocalClient(AbstractClient):
|
|
|
2573
2563
|
tool_create = ToolCreate.from_composio(action=action)
|
|
2574
2564
|
return self.server.tool_manager.create_or_update_tool(pydantic_tool=Tool(**tool_create.model_dump()), actor=self.user)
|
|
2575
2565
|
|
|
2576
|
-
# TODO: Use the above function `add_tool` here as there is duplicate logic
|
|
2577
2566
|
def create_tool(
|
|
2578
2567
|
self,
|
|
2579
2568
|
func,
|
|
@@ -2601,6 +2590,42 @@ class LocalClient(AbstractClient):
|
|
|
2601
2590
|
if not tags:
|
|
2602
2591
|
tags = []
|
|
2603
2592
|
|
|
2593
|
+
# call server function
|
|
2594
|
+
return self.server.tool_manager.create_tool(
|
|
2595
|
+
Tool(
|
|
2596
|
+
source_type=source_type,
|
|
2597
|
+
source_code=source_code,
|
|
2598
|
+
name=name,
|
|
2599
|
+
tags=tags,
|
|
2600
|
+
description=description,
|
|
2601
|
+
),
|
|
2602
|
+
actor=self.user,
|
|
2603
|
+
)
|
|
2604
|
+
|
|
2605
|
+
def create_or_update_tool(
|
|
2606
|
+
self,
|
|
2607
|
+
func,
|
|
2608
|
+
name: Optional[str] = None,
|
|
2609
|
+
tags: Optional[List[str]] = None,
|
|
2610
|
+
description: Optional[str] = None,
|
|
2611
|
+
) -> Tool:
|
|
2612
|
+
"""
|
|
2613
|
+
Creates or updates a tool. This stores the source code of function on the server, so that the server can execute the function and generate an OpenAI JSON schemas for it when using with an agent.
|
|
2614
|
+
|
|
2615
|
+
Args:
|
|
2616
|
+
func (callable): The function to create a tool for.
|
|
2617
|
+
name: (str): Name of the tool (must be unique per-user.)
|
|
2618
|
+
tags (Optional[List[str]], optional): Tags for the tool. Defaults to None.
|
|
2619
|
+
description (str, optional): The description.
|
|
2620
|
+
|
|
2621
|
+
Returns:
|
|
2622
|
+
tool (Tool): The created tool.
|
|
2623
|
+
"""
|
|
2624
|
+
source_code = parse_source_code(func)
|
|
2625
|
+
source_type = "python"
|
|
2626
|
+
if not tags:
|
|
2627
|
+
tags = []
|
|
2628
|
+
|
|
2604
2629
|
# call server function
|
|
2605
2630
|
return self.server.tool_manager.create_or_update_tool(
|
|
2606
2631
|
Tool(
|
{letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/errors.py
RENAMED
|
@@ -10,6 +10,18 @@ class LettaError(Exception):
|
|
|
10
10
|
"""Base class for all Letta related errors."""
|
|
11
11
|
|
|
12
12
|
|
|
13
|
+
class LettaToolCreateError(LettaError):
|
|
14
|
+
"""Error raised when a tool cannot be created."""
|
|
15
|
+
|
|
16
|
+
default_error_message = "Error creating tool."
|
|
17
|
+
|
|
18
|
+
def __init__(self, message=None):
|
|
19
|
+
if message is None:
|
|
20
|
+
message = self.default_error_message
|
|
21
|
+
self.message = message
|
|
22
|
+
super().__init__(self.message)
|
|
23
|
+
|
|
24
|
+
|
|
13
25
|
class LLMError(LettaError):
|
|
14
26
|
pass
|
|
15
27
|
|
|
@@ -3,9 +3,10 @@ import inspect
|
|
|
3
3
|
import os
|
|
4
4
|
from textwrap import dedent # remove indentation
|
|
5
5
|
from types import ModuleType
|
|
6
|
-
from typing import
|
|
6
|
+
from typing import Dict, List, Optional
|
|
7
7
|
|
|
8
8
|
from letta.constants import CLI_WARNING_PREFIX
|
|
9
|
+
from letta.errors import LettaToolCreateError
|
|
9
10
|
from letta.functions.schema_generator import generate_schema
|
|
10
11
|
|
|
11
12
|
|
|
@@ -13,10 +14,7 @@ def derive_openai_json_schema(source_code: str, name: Optional[str] = None) -> d
|
|
|
13
14
|
# auto-generate openai schema
|
|
14
15
|
try:
|
|
15
16
|
# Define a custom environment with necessary imports
|
|
16
|
-
env = {
|
|
17
|
-
"Optional": Optional, # Add any other required imports here
|
|
18
|
-
"List": List
|
|
19
|
-
}
|
|
17
|
+
env = {"Optional": Optional, "List": List, "Dict": Dict} # Add any other required imports here
|
|
20
18
|
|
|
21
19
|
env.update(globals())
|
|
22
20
|
exec(source_code, env)
|
|
@@ -29,7 +27,7 @@ def derive_openai_json_schema(source_code: str, name: Optional[str] = None) -> d
|
|
|
29
27
|
json_schema = generate_schema(func, name=name)
|
|
30
28
|
return json_schema
|
|
31
29
|
except Exception as e:
|
|
32
|
-
raise
|
|
30
|
+
raise LettaToolCreateError(f"Failed to derive JSON schema from source code: {e}")
|
|
33
31
|
|
|
34
32
|
|
|
35
33
|
def parse_source_code(func) -> str:
|
|
@@ -131,11 +131,12 @@ def generate_schema(function, name: Optional[str] = None, description: Optional[
|
|
|
131
131
|
else:
|
|
132
132
|
# Add parameter details to the schema
|
|
133
133
|
param_doc = next((d for d in docstring.params if d.arg_name == param.name), None)
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
134
|
+
if param_doc:
|
|
135
|
+
schema["parameters"]["properties"][param.name] = {
|
|
136
|
+
# "type": "string" if param.annotation == str else str(param.annotation),
|
|
137
|
+
"type": type_to_json_schema_type(param.annotation) if param.annotation != inspect.Parameter.empty else "string",
|
|
138
|
+
"description": param_doc.description,
|
|
139
|
+
}
|
|
139
140
|
if param.default == inspect.Parameter.empty:
|
|
140
141
|
schema["parameters"]["required"].append(param.name)
|
|
141
142
|
|
{letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/metadata.py
RENAMED
|
@@ -25,6 +25,7 @@ from letta.schemas.tool_rule import (
|
|
|
25
25
|
ToolRule,
|
|
26
26
|
)
|
|
27
27
|
from letta.schemas.user import User
|
|
28
|
+
from letta.services.per_agent_lock_manager import PerAgentLockManager
|
|
28
29
|
from letta.settings import settings
|
|
29
30
|
from letta.utils import enforce_types, get_utc_time, printd
|
|
30
31
|
|
|
@@ -383,7 +384,11 @@ class MetadataStore:
|
|
|
383
384
|
session.commit()
|
|
384
385
|
|
|
385
386
|
@enforce_types
|
|
386
|
-
def delete_agent(self, agent_id: str):
|
|
387
|
+
def delete_agent(self, agent_id: str, per_agent_lock_manager: PerAgentLockManager):
|
|
388
|
+
# TODO: Remove this once Agent is on the ORM
|
|
389
|
+
# TODO: To prevent unbounded growth
|
|
390
|
+
per_agent_lock_manager.clear_lock(agent_id)
|
|
391
|
+
|
|
387
392
|
with self.session_maker() as session:
|
|
388
393
|
|
|
389
394
|
# delete agents
|
{letta_nightly-0.5.4.dev20241125104219 → letta_nightly-0.5.4.dev20241127104220}/letta/orm/block.py
RENAMED
|
@@ -10,7 +10,7 @@ from letta.schemas.block import Block as PydanticBlock
|
|
|
10
10
|
from letta.schemas.block import Human, Persona
|
|
11
11
|
|
|
12
12
|
if TYPE_CHECKING:
|
|
13
|
-
from letta.orm
|
|
13
|
+
from letta.orm import BlocksAgents, Organization
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class Block(OrganizationMixin, SqlalchemyBase):
|
|
@@ -35,6 +35,7 @@ class Block(OrganizationMixin, SqlalchemyBase):
|
|
|
35
35
|
|
|
36
36
|
# relationships
|
|
37
37
|
organization: Mapped[Optional["Organization"]] = relationship("Organization")
|
|
38
|
+
blocks_agents: Mapped[list["BlocksAgents"]] = relationship("BlocksAgents", back_populates="block", cascade="all, delete")
|
|
38
39
|
|
|
39
40
|
def to_pydantic(self) -> Type:
|
|
40
41
|
match self.label:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from sqlalchemy import ForeignKey, ForeignKeyConstraint, String, UniqueConstraint
|
|
2
|
-
from sqlalchemy.orm import Mapped, mapped_column
|
|
2
|
+
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
3
3
|
|
|
4
4
|
from letta.orm.sqlalchemy_base import SqlalchemyBase
|
|
5
5
|
from letta.schemas.blocks_agents import BlocksAgents as PydanticBlocksAgents
|
|
@@ -27,3 +27,6 @@ class BlocksAgents(SqlalchemyBase):
|
|
|
27
27
|
agent_id: Mapped[str] = mapped_column(String, ForeignKey("agents.id"), primary_key=True)
|
|
28
28
|
block_id: Mapped[str] = mapped_column(String, primary_key=True)
|
|
29
29
|
block_label: Mapped[str] = mapped_column(String, primary_key=True)
|
|
30
|
+
|
|
31
|
+
# relationships
|
|
32
|
+
block: Mapped["Block"] = relationship("Block", back_populates="blocks_agents")
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
class NoResultFound(Exception):
|
|
2
|
+
"""A record or records cannot be found given the provided search params"""
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class MalformedIdError(Exception):
|
|
6
|
+
"""An id not in the right format, most likely violating uuid4 format."""
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class UniqueConstraintViolationError(ValueError):
|
|
10
|
+
"""Custom exception for unique constraint violations."""
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ForeignKeyConstraintViolationError(ValueError):
|
|
14
|
+
"""Custom exception for foreign key constraint violations."""
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
from typing import TYPE_CHECKING, List, Literal, Optional, Type
|
|
2
2
|
|
|
3
3
|
from sqlalchemy import String, select
|
|
4
|
+
from sqlalchemy.exc import DBAPIError
|
|
4
5
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
5
6
|
|
|
6
7
|
from letta.log import get_logger
|
|
7
8
|
from letta.orm.base import Base, CommonSqlalchemyMetaMixins
|
|
8
|
-
from letta.orm.errors import
|
|
9
|
+
from letta.orm.errors import (
|
|
10
|
+
ForeignKeyConstraintViolationError,
|
|
11
|
+
NoResultFound,
|
|
12
|
+
UniqueConstraintViolationError,
|
|
13
|
+
)
|
|
9
14
|
|
|
10
15
|
if TYPE_CHECKING:
|
|
11
16
|
from pydantic import BaseModel
|
|
@@ -102,12 +107,14 @@ class SqlalchemyBase(CommonSqlalchemyMetaMixins, Base):
|
|
|
102
107
|
|
|
103
108
|
if actor:
|
|
104
109
|
self._set_created_and_updated_by_fields(actor.id)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
110
|
+
try:
|
|
111
|
+
with db_session as session:
|
|
112
|
+
session.add(self)
|
|
113
|
+
session.commit()
|
|
114
|
+
session.refresh(self)
|
|
115
|
+
return self
|
|
116
|
+
except DBAPIError as e:
|
|
117
|
+
self._handle_dbapi_error(e)
|
|
111
118
|
|
|
112
119
|
def delete(self, db_session: "Session", actor: Optional["User"] = None) -> Type["SqlalchemyBase"]:
|
|
113
120
|
logger.debug(f"Soft deleting {self.__class__.__name__} with ID: {self.id} with actor={actor}")
|
|
@@ -168,6 +175,51 @@ class SqlalchemyBase(CommonSqlalchemyMetaMixins, Base):
|
|
|
168
175
|
raise ValueError(f"object {actor} has no organization accessor")
|
|
169
176
|
return query.where(cls.organization_id == org_id, cls.is_deleted == False)
|
|
170
177
|
|
|
178
|
+
@classmethod
|
|
179
|
+
def _handle_dbapi_error(cls, e: DBAPIError):
|
|
180
|
+
"""Handle database errors and raise appropriate custom exceptions."""
|
|
181
|
+
orig = e.orig # Extract the original error from the DBAPIError
|
|
182
|
+
error_code = None
|
|
183
|
+
error_message = str(orig) if orig else str(e)
|
|
184
|
+
logger.info(f"Handling DBAPIError: {error_message}")
|
|
185
|
+
|
|
186
|
+
# Handle SQLite-specific errors
|
|
187
|
+
if "UNIQUE constraint failed" in error_message:
|
|
188
|
+
raise UniqueConstraintViolationError(
|
|
189
|
+
f"A unique constraint was violated for {cls.__name__}. Check your input for duplicates: {e}"
|
|
190
|
+
) from e
|
|
191
|
+
|
|
192
|
+
if "FOREIGN KEY constraint failed" in error_message:
|
|
193
|
+
raise ForeignKeyConstraintViolationError(
|
|
194
|
+
f"A foreign key constraint was violated for {cls.__name__}. Check your input for missing or invalid references: {e}"
|
|
195
|
+
) from e
|
|
196
|
+
|
|
197
|
+
# For psycopg2
|
|
198
|
+
if hasattr(orig, "pgcode"):
|
|
199
|
+
error_code = orig.pgcode
|
|
200
|
+
# For pg8000
|
|
201
|
+
elif hasattr(orig, "args") and len(orig.args) > 0:
|
|
202
|
+
# The first argument contains the error details as a dictionary
|
|
203
|
+
err_dict = orig.args[0]
|
|
204
|
+
if isinstance(err_dict, dict):
|
|
205
|
+
error_code = err_dict.get("C") # 'C' is the error code field
|
|
206
|
+
logger.info(f"Extracted error_code: {error_code}")
|
|
207
|
+
|
|
208
|
+
# Handle unique constraint violations
|
|
209
|
+
if error_code == "23505":
|
|
210
|
+
raise UniqueConstraintViolationError(
|
|
211
|
+
f"A unique constraint was violated for {cls.__name__}. Check your input for duplicates: {e}"
|
|
212
|
+
) from e
|
|
213
|
+
|
|
214
|
+
# Handle foreign key violations
|
|
215
|
+
if error_code == "23503":
|
|
216
|
+
raise ForeignKeyConstraintViolationError(
|
|
217
|
+
f"A foreign key constraint was violated for {cls.__name__}. Check your input for missing or invalid references: {e}"
|
|
218
|
+
) from e
|
|
219
|
+
|
|
220
|
+
# Re-raise for other unhandled DBAPI errors
|
|
221
|
+
raise
|
|
222
|
+
|
|
171
223
|
@property
|
|
172
224
|
def __pydantic_model__(self) -> Type["BaseModel"]:
|
|
173
225
|
raise NotImplementedError("Sqlalchemy models must declare a __pydantic_model__ property to be convertable.")
|
|
@@ -30,7 +30,7 @@ class BaseBlock(LettaBase, validate_assignment=True):
|
|
|
30
30
|
|
|
31
31
|
@model_validator(mode="after")
|
|
32
32
|
def verify_char_limit(self) -> Self:
|
|
33
|
-
if len(self.value) > self.limit:
|
|
33
|
+
if self.value and len(self.value) > self.limit:
|
|
34
34
|
error_msg = f"Edit failed: Exceeds {self.limit} character limit (requested {len(self.value)}) - {str(self)}."
|
|
35
35
|
raise ValueError(error_msg)
|
|
36
36
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from typing import Dict, List, Optional
|
|
2
2
|
|
|
3
|
-
from pydantic import Field
|
|
3
|
+
from pydantic import Field, model_validator
|
|
4
4
|
|
|
5
|
+
from letta.functions.functions import derive_openai_json_schema
|
|
5
6
|
from letta.functions.helpers import (
|
|
6
7
|
generate_composio_tool_wrapper,
|
|
7
8
|
generate_langchain_tool_wrapper,
|
|
@@ -44,6 +45,29 @@ class Tool(BaseTool):
|
|
|
44
45
|
created_by_id: Optional[str] = Field(None, description="The id of the user that made this Tool.")
|
|
45
46
|
last_updated_by_id: Optional[str] = Field(None, description="The id of the user that made this Tool.")
|
|
46
47
|
|
|
48
|
+
@model_validator(mode="after")
|
|
49
|
+
def populate_missing_fields(self):
|
|
50
|
+
"""
|
|
51
|
+
Populate missing fields: name, description, and json_schema.
|
|
52
|
+
"""
|
|
53
|
+
# Derive JSON schema if not provided
|
|
54
|
+
if not self.json_schema:
|
|
55
|
+
self.json_schema = derive_openai_json_schema(source_code=self.source_code)
|
|
56
|
+
|
|
57
|
+
# Derive name from the JSON schema if not provided
|
|
58
|
+
if not self.name:
|
|
59
|
+
# TODO: This in theory could error, but name should always be on json_schema
|
|
60
|
+
# TODO: Make JSON schema a typed pydantic object
|
|
61
|
+
self.name = self.json_schema.get("name")
|
|
62
|
+
|
|
63
|
+
# Derive description from the JSON schema if not provided
|
|
64
|
+
if not self.description:
|
|
65
|
+
# TODO: This in theory could error, but description should always be on json_schema
|
|
66
|
+
# TODO: Make JSON schema a typed pydantic object
|
|
67
|
+
self.description = self.json_schema.get("description")
|
|
68
|
+
|
|
69
|
+
return self
|
|
70
|
+
|
|
47
71
|
def to_dict(self):
|
|
48
72
|
"""
|
|
49
73
|
Convert tool into OpenAI representation.
|
|
@@ -475,19 +475,21 @@ async def send_message(
|
|
|
475
475
|
"""
|
|
476
476
|
actor = server.get_user_or_default(user_id=user_id)
|
|
477
477
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
478
|
+
agent_lock = server.per_agent_lock_manager.get_lock(agent_id)
|
|
479
|
+
async with agent_lock:
|
|
480
|
+
result = await send_message_to_agent(
|
|
481
|
+
server=server,
|
|
482
|
+
agent_id=agent_id,
|
|
483
|
+
user_id=actor.id,
|
|
484
|
+
messages=request.messages,
|
|
485
|
+
stream_steps=request.stream_steps,
|
|
486
|
+
stream_tokens=request.stream_tokens,
|
|
487
|
+
return_message_object=request.return_message_object,
|
|
488
|
+
# Support for AssistantMessage
|
|
489
|
+
use_assistant_message=request.use_assistant_message,
|
|
490
|
+
assistant_message_function_name=request.assistant_message_function_name,
|
|
491
|
+
assistant_message_function_kwarg=request.assistant_message_function_kwarg,
|
|
492
|
+
)
|
|
491
493
|
return result
|
|
492
494
|
|
|
493
495
|
|
|
@@ -2,6 +2,8 @@ from typing import List, Optional
|
|
|
2
2
|
|
|
3
3
|
from fastapi import APIRouter, Body, Depends, Header, HTTPException
|
|
4
4
|
|
|
5
|
+
from letta.errors import LettaToolCreateError
|
|
6
|
+
from letta.orm.errors import UniqueConstraintViolationError
|
|
5
7
|
from letta.schemas.tool import Tool, ToolCreate, ToolUpdate
|
|
6
8
|
from letta.server.rest_api.utils import get_letta_server
|
|
7
9
|
from letta.server.server import SyncServer
|
|
@@ -13,12 +15,13 @@ router = APIRouter(prefix="/tools", tags=["tools"])
|
|
|
13
15
|
def delete_tool(
|
|
14
16
|
tool_id: str,
|
|
15
17
|
server: SyncServer = Depends(get_letta_server),
|
|
18
|
+
user_id: Optional[str] = Header(None, alias="user_id"), # Extract user_id from header, default to None if not present
|
|
16
19
|
):
|
|
17
20
|
"""
|
|
18
21
|
Delete a tool by name
|
|
19
22
|
"""
|
|
20
|
-
|
|
21
|
-
server.tool_manager.
|
|
23
|
+
actor = server.get_user_or_default(user_id=user_id)
|
|
24
|
+
server.tool_manager.delete_tool_by_id(tool_id=tool_id, actor=actor)
|
|
22
25
|
|
|
23
26
|
|
|
24
27
|
@router.get("/{tool_id}", response_model=Tool, operation_id="get_tool")
|
|
@@ -83,12 +86,50 @@ def create_tool(
|
|
|
83
86
|
"""
|
|
84
87
|
Create a new tool
|
|
85
88
|
"""
|
|
86
|
-
|
|
87
|
-
|
|
89
|
+
try:
|
|
90
|
+
actor = server.get_user_or_default(user_id=user_id)
|
|
91
|
+
tool = Tool(**request.model_dump())
|
|
92
|
+
return server.tool_manager.create_tool(pydantic_tool=tool, actor=actor)
|
|
93
|
+
except UniqueConstraintViolationError as e:
|
|
94
|
+
# Log or print the full exception here for debugging
|
|
95
|
+
print(f"Error occurred: {e}")
|
|
96
|
+
clean_error_message = f"Tool with name {request.name} already exists."
|
|
97
|
+
raise HTTPException(status_code=409, detail=clean_error_message)
|
|
98
|
+
except LettaToolCreateError as e:
|
|
99
|
+
# HTTP 400 == Bad Request
|
|
100
|
+
print(f"Error occurred during tool creation: {e}")
|
|
101
|
+
# print the full stack trace
|
|
102
|
+
import traceback
|
|
103
|
+
|
|
104
|
+
print(traceback.format_exc())
|
|
105
|
+
raise HTTPException(status_code=400, detail=str(e))
|
|
106
|
+
except Exception as e:
|
|
107
|
+
# Catch other unexpected errors and raise an internal server error
|
|
108
|
+
print(f"Unexpected error occurred: {e}")
|
|
109
|
+
raise HTTPException(status_code=500, detail=f"An unexpected error occurred: {str(e)}")
|
|
110
|
+
|
|
88
111
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
112
|
+
@router.put("/", response_model=Tool, operation_id="upsert_tool")
|
|
113
|
+
def upsert_tool(
|
|
114
|
+
request: ToolCreate = Body(...),
|
|
115
|
+
server: SyncServer = Depends(get_letta_server),
|
|
116
|
+
user_id: Optional[str] = Header(None, alias="user_id"),
|
|
117
|
+
):
|
|
118
|
+
"""
|
|
119
|
+
Create or update a tool
|
|
120
|
+
"""
|
|
121
|
+
try:
|
|
122
|
+
actor = server.get_user_or_default(user_id=user_id)
|
|
123
|
+
tool = server.tool_manager.create_or_update_tool(pydantic_tool=Tool(**request.model_dump()), actor=actor)
|
|
124
|
+
return tool
|
|
125
|
+
except UniqueConstraintViolationError as e:
|
|
126
|
+
# Log the error and raise a conflict exception
|
|
127
|
+
print(f"Unique constraint violation occurred: {e}")
|
|
128
|
+
raise HTTPException(status_code=409, detail=str(e))
|
|
129
|
+
except Exception as e:
|
|
130
|
+
# Catch other unexpected errors and raise an internal server error
|
|
131
|
+
print(f"Unexpected error occurred: {e}")
|
|
132
|
+
raise HTTPException(status_code=500, detail=f"An unexpected error occurred: {str(e)}")
|
|
92
133
|
|
|
93
134
|
|
|
94
135
|
@router.patch("/{tool_id}", response_model=Tool, operation_id="update_tool")
|
|
@@ -3,6 +3,7 @@ import os
|
|
|
3
3
|
import traceback
|
|
4
4
|
import warnings
|
|
5
5
|
from abc import abstractmethod
|
|
6
|
+
from asyncio import Lock
|
|
6
7
|
from datetime import datetime
|
|
7
8
|
from typing import Callable, Dict, List, Optional, Tuple, Union
|
|
8
9
|
|
|
@@ -79,6 +80,7 @@ from letta.services.agents_tags_manager import AgentsTagsManager
|
|
|
79
80
|
from letta.services.block_manager import BlockManager
|
|
80
81
|
from letta.services.blocks_agents_manager import BlocksAgentsManager
|
|
81
82
|
from letta.services.organization_manager import OrganizationManager
|
|
83
|
+
from letta.services.per_agent_lock_manager import PerAgentLockManager
|
|
82
84
|
from letta.services.sandbox_config_manager import SandboxConfigManager
|
|
83
85
|
from letta.services.source_manager import SourceManager
|
|
84
86
|
from letta.services.tool_manager import ToolManager
|
|
@@ -231,6 +233,9 @@ class SyncServer(Server):
|
|
|
231
233
|
|
|
232
234
|
self.credentials = LettaCredentials.load()
|
|
233
235
|
|
|
236
|
+
# Locks
|
|
237
|
+
self.send_message_lock = Lock()
|
|
238
|
+
|
|
234
239
|
# Initialize the metadata store
|
|
235
240
|
config = LettaConfig.load()
|
|
236
241
|
if settings.letta_pg_uri_no_default:
|
|
@@ -252,6 +257,9 @@ class SyncServer(Server):
|
|
|
252
257
|
self.blocks_agents_manager = BlocksAgentsManager()
|
|
253
258
|
self.sandbox_config_manager = SandboxConfigManager(tool_settings)
|
|
254
259
|
|
|
260
|
+
# Managers that interface with parallelism
|
|
261
|
+
self.per_agent_lock_manager = PerAgentLockManager()
|
|
262
|
+
|
|
255
263
|
# Make default user and org
|
|
256
264
|
if init_with_default_org_and_user:
|
|
257
265
|
self.default_org = self.organization_manager.create_default_organization()
|
|
@@ -925,7 +933,7 @@ class SyncServer(Server):
|
|
|
925
933
|
logger.exception(e)
|
|
926
934
|
try:
|
|
927
935
|
if agent:
|
|
928
|
-
self.ms.delete_agent(agent_id=agent.agent_state.id)
|
|
936
|
+
self.ms.delete_agent(agent_id=agent.agent_state.id, per_agent_lock_manager=self.per_agent_lock_manager)
|
|
929
937
|
except Exception as delete_e:
|
|
930
938
|
logger.exception(f"Failed to delete_agent:\n{delete_e}")
|
|
931
939
|
raise e
|
|
@@ -1522,7 +1530,7 @@ class SyncServer(Server):
|
|
|
1522
1530
|
|
|
1523
1531
|
# Next, attempt to delete it from the actual database
|
|
1524
1532
|
try:
|
|
1525
|
-
self.ms.delete_agent(agent_id=agent_id)
|
|
1533
|
+
self.ms.delete_agent(agent_id=agent_id, per_agent_lock_manager=self.per_agent_lock_manager)
|
|
1526
1534
|
except Exception as e:
|
|
1527
1535
|
logger.exception(f"Failed to delete agent {agent_id} via ID with:\n{str(e)}")
|
|
1528
1536
|
raise ValueError(f"Failed to delete agent {agent_id} in database")
|