letta-nightly 0.6.0.dev20241204232133__tar.gz → 0.6.0.dev20241205104308__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.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/PKG-INFO +1 -1
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/client/client.py +10 -6
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/metadata.py +2 -65
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/orm/__init__.py +1 -0
- letta_nightly-0.6.0.dev20241205104308/letta/orm/job.py +29 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/orm/sqlalchemy_base.py +29 -10
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/orm/user.py +3 -3
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/job.py +9 -9
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/routers/v1/jobs.py +18 -10
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/routers/v1/sources.py +7 -5
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/server.py +8 -44
- letta_nightly-0.6.0.dev20241205104308/letta/services/job_manager.py +85 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/services/tool_execution_sandbox.py +29 -5
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/utils.py +19 -3
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/pyproject.toml +1 -1
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/LICENSE +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/README.md +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/__init__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/__main__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/agent.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/agent_store/chroma.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/agent_store/db.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/agent_store/lancedb.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/agent_store/milvus.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/agent_store/qdrant.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/agent_store/storage.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/benchmark/benchmark.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/benchmark/constants.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/cli/cli.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/cli/cli_config.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/cli/cli_load.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/client/__init__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/client/streaming.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/client/utils.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/config.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/constants.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/credentials.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/data_sources/connectors.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/data_sources/connectors_helper.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/embeddings.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/errors.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/functions/__init__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/functions/function_sets/base.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/functions/function_sets/extras.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/functions/functions.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/functions/helpers.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/functions/schema_generator.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/helpers/__init__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/helpers/tool_rule_solver.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/humans/__init__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/humans/examples/basic.txt +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/humans/examples/cs_phd.txt +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/interface.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/llm_api/__init__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/llm_api/anthropic.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/llm_api/azure_openai.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/llm_api/azure_openai_constants.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/llm_api/cohere.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/llm_api/google_ai.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/llm_api/helpers.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/llm_api/llm_api_tools.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/llm_api/mistral.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/llm_api/openai.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/README.md +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/__init__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/chat_completion_proxy.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/constants.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/function_parser.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/grammars/__init__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/grammars/gbnf_grammar_generator.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/grammars/json.gbnf +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/grammars/json_func_calls_with_inner_thoughts.gbnf +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/json_parser.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/koboldcpp/api.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/koboldcpp/settings.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/llamacpp/api.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/llamacpp/settings.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/llm_chat_completion_wrappers/__init__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/llm_chat_completion_wrappers/airoboros.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/llm_chat_completion_wrappers/chatml.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/llm_chat_completion_wrappers/configurable_wrapper.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/llm_chat_completion_wrappers/dolphin.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/llm_chat_completion_wrappers/llama3.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/llm_chat_completion_wrappers/simple_summary_wrapper.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/llm_chat_completion_wrappers/wrapper_base.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/llm_chat_completion_wrappers/zephyr.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/lmstudio/api.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/lmstudio/settings.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/ollama/api.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/ollama/settings.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/settings/__init__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/settings/deterministic_mirostat.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/settings/settings.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/settings/simple.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/utils.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/vllm/api.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/webui/api.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/webui/legacy_api.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/webui/legacy_settings.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/local_llm/webui/settings.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/log.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/main.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/memory.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/o1_agent.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/openai_backcompat/__init__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/openai_backcompat/openai_object.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/orm/__all__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/orm/agents_tags.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/orm/base.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/orm/block.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/orm/blocks_agents.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/orm/enums.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/orm/errors.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/orm/file.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/orm/mixins.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/orm/organization.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/orm/sandbox_config.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/orm/source.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/orm/tool.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/persistence_manager.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/personas/__init__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/personas/examples/anna_pa.txt +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/personas/examples/google_search_persona.txt +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/personas/examples/memgpt_doc.txt +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/personas/examples/memgpt_starter.txt +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/personas/examples/o1_persona.txt +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/personas/examples/sam.txt +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/personas/examples/sam_pov.txt +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/personas/examples/sam_simple_pov_gpt35.txt +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/personas/examples/sqldb/test.db +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/prompts/__init__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/prompts/gpt_summarize.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/prompts/gpt_system.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/prompts/system/memgpt_base.txt +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/prompts/system/memgpt_chat.txt +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/prompts/system/memgpt_chat_compressed.txt +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/prompts/system/memgpt_chat_fstring.txt +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/prompts/system/memgpt_doc.txt +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/prompts/system/memgpt_gpt35_extralong.txt +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/prompts/system/memgpt_intuitive_knowledge.txt +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/prompts/system/memgpt_modified_chat.txt +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/prompts/system/memgpt_modified_o1.txt +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/providers.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/pytest.ini +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/agent.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/agents_tags.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/api_key.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/block.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/blocks_agents.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/embedding_config.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/enums.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/file.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/health.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/letta_base.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/letta_message.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/letta_request.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/letta_response.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/llm_config.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/memory.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/message.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/openai/chat_completion_request.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/openai/chat_completion_response.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/openai/chat_completions.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/openai/embedding_response.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/openai/openai.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/organization.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/passage.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/sandbox_config.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/source.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/tool.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/tool_rule.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/usage.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/user.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/__init__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/constants.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/generate_openapi_schema.sh +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/__init__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/app.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/auth/__init__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/auth/index.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/auth_token.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/interface.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/routers/__init__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/routers/openai/__init__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/routers/openai/assistants/__init__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/routers/openai/assistants/assistants.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/routers/openai/assistants/schemas.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/routers/openai/assistants/threads.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/routers/openai/chat_completions/__init__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/routers/openai/chat_completions/chat_completions.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/routers/v1/__init__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/routers/v1/agents.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/routers/v1/blocks.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/routers/v1/health.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/routers/v1/llms.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/routers/v1/organizations.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/routers/v1/sandbox_configs.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/routers/v1/tools.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/routers/v1/users.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/static_files.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/rest_api/utils.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/startup.sh +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/static_files/assets/index-3ab03d5b.css +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/static_files/assets/index-9fa459a2.js +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/static_files/favicon.ico +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/static_files/index.html +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/static_files/memgpt_logo_transparent.png +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/utils.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/ws_api/__init__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/ws_api/example_client.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/ws_api/interface.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/ws_api/protocol.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/server/ws_api/server.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/services/__init__.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/services/agents_tags_manager.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/services/block_manager.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/services/blocks_agents_manager.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/services/organization_manager.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/services/per_agent_lock_manager.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/services/sandbox_config_manager.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/services/source_manager.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/services/tool_manager.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/services/tool_sandbox_env/.gitkeep +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/services/user_manager.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/settings.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/streaming_interface.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/streaming_utils.py +0 -0
- {letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/system.py +0 -0
|
@@ -2859,8 +2859,12 @@ class LocalClient(AbstractClient):
|
|
|
2859
2859
|
Returns:
|
|
2860
2860
|
job (Job): Data loading job including job status and metadata
|
|
2861
2861
|
"""
|
|
2862
|
-
|
|
2863
|
-
|
|
2862
|
+
job = Job(
|
|
2863
|
+
user_id=self.user_id,
|
|
2864
|
+
status=JobStatus.created,
|
|
2865
|
+
metadata_={"type": "embedding", "filename": filename, "source_id": source_id},
|
|
2866
|
+
)
|
|
2867
|
+
job = self.server.job_manager.create_job(pydantic_job=job, actor=self.user)
|
|
2864
2868
|
|
|
2865
2869
|
# TODO: implement blocking vs. non-blocking
|
|
2866
2870
|
self.server.load_file_to_source(source_id=source_id, file_path=filename, job_id=job.id)
|
|
@@ -2870,16 +2874,16 @@ class LocalClient(AbstractClient):
|
|
|
2870
2874
|
self.server.source_manager.delete_file(file_id, actor=self.user)
|
|
2871
2875
|
|
|
2872
2876
|
def get_job(self, job_id: str):
|
|
2873
|
-
return self.server.
|
|
2877
|
+
return self.server.job_manager.get_job_by_id(job_id=job_id, actor=self.user)
|
|
2874
2878
|
|
|
2875
2879
|
def delete_job(self, job_id: str):
|
|
2876
|
-
return self.server.delete_job(job_id)
|
|
2880
|
+
return self.server.job_manager.delete_job(job_id=job_id, actor=self.user)
|
|
2877
2881
|
|
|
2878
2882
|
def list_jobs(self):
|
|
2879
|
-
return self.server.list_jobs(
|
|
2883
|
+
return self.server.job_manager.list_jobs(actor=self.user)
|
|
2880
2884
|
|
|
2881
2885
|
def list_active_jobs(self):
|
|
2882
|
-
return self.server.
|
|
2886
|
+
return self.server.job_manager.list_jobs(actor=self.user, statuses=[JobStatus.created, JobStatus.running])
|
|
2883
2887
|
|
|
2884
2888
|
def create_source(self, name: str, embedding_config: Optional[EmbeddingConfig] = None) -> Source:
|
|
2885
2889
|
"""
|
{letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/metadata.py
RENAMED
|
@@ -12,15 +12,14 @@ from letta.orm.base import Base
|
|
|
12
12
|
from letta.schemas.agent import PersistedAgentState
|
|
13
13
|
from letta.schemas.api_key import APIKey
|
|
14
14
|
from letta.schemas.embedding_config import EmbeddingConfig
|
|
15
|
-
from letta.schemas.enums import
|
|
16
|
-
from letta.schemas.job import Job
|
|
15
|
+
from letta.schemas.enums import ToolRuleType
|
|
17
16
|
from letta.schemas.llm_config import LLMConfig
|
|
18
17
|
from letta.schemas.openai.chat_completions import ToolCall, ToolCallFunction
|
|
19
18
|
from letta.schemas.tool_rule import ChildToolRule, InitToolRule, TerminalToolRule
|
|
20
19
|
from letta.schemas.user import User
|
|
21
20
|
from letta.services.per_agent_lock_manager import PerAgentLockManager
|
|
22
21
|
from letta.settings import settings
|
|
23
|
-
from letta.utils import enforce_types,
|
|
22
|
+
from letta.utils import enforce_types, printd
|
|
24
23
|
|
|
25
24
|
|
|
26
25
|
class LLMConfigColumn(TypeDecorator):
|
|
@@ -258,31 +257,6 @@ class AgentSourceMappingModel(Base):
|
|
|
258
257
|
return f"<AgentSourceMapping(user_id='{self.user_id}', agent_id='{self.agent_id}', source_id='{self.source_id}')>"
|
|
259
258
|
|
|
260
259
|
|
|
261
|
-
class JobModel(Base):
|
|
262
|
-
__tablename__ = "jobs"
|
|
263
|
-
__table_args__ = {"extend_existing": True}
|
|
264
|
-
|
|
265
|
-
id = Column(String, primary_key=True)
|
|
266
|
-
user_id = Column(String)
|
|
267
|
-
status = Column(String, default=JobStatus.pending)
|
|
268
|
-
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
|
269
|
-
completed_at = Column(DateTime(timezone=True), onupdate=func.now())
|
|
270
|
-
metadata_ = Column(JSON)
|
|
271
|
-
|
|
272
|
-
def __repr__(self) -> str:
|
|
273
|
-
return f"<Job(id='{self.id}', status='{self.status}')>"
|
|
274
|
-
|
|
275
|
-
def to_record(self):
|
|
276
|
-
return Job(
|
|
277
|
-
id=self.id,
|
|
278
|
-
user_id=self.user_id,
|
|
279
|
-
status=self.status,
|
|
280
|
-
created_at=self.created_at,
|
|
281
|
-
completed_at=self.completed_at,
|
|
282
|
-
metadata_=self.metadata_,
|
|
283
|
-
)
|
|
284
|
-
|
|
285
|
-
|
|
286
260
|
class MetadataStore:
|
|
287
261
|
uri: Optional[str] = None
|
|
288
262
|
|
|
@@ -455,40 +429,3 @@ class MetadataStore:
|
|
|
455
429
|
AgentSourceMappingModel.agent_id == agent_id, AgentSourceMappingModel.source_id == source_id
|
|
456
430
|
).delete()
|
|
457
431
|
session.commit()
|
|
458
|
-
|
|
459
|
-
@enforce_types
|
|
460
|
-
def create_job(self, job: Job):
|
|
461
|
-
with self.session_maker() as session:
|
|
462
|
-
session.add(JobModel(**vars(job)))
|
|
463
|
-
session.commit()
|
|
464
|
-
|
|
465
|
-
def delete_job(self, job_id: str):
|
|
466
|
-
with self.session_maker() as session:
|
|
467
|
-
session.query(JobModel).filter(JobModel.id == job_id).delete()
|
|
468
|
-
session.commit()
|
|
469
|
-
|
|
470
|
-
def get_job(self, job_id: str) -> Optional[Job]:
|
|
471
|
-
with self.session_maker() as session:
|
|
472
|
-
results = session.query(JobModel).filter(JobModel.id == job_id).all()
|
|
473
|
-
if len(results) == 0:
|
|
474
|
-
return None
|
|
475
|
-
assert len(results) == 1, f"Expected 1 result, got {len(results)}"
|
|
476
|
-
return results[0].to_record()
|
|
477
|
-
|
|
478
|
-
def list_jobs(self, user_id: str) -> List[Job]:
|
|
479
|
-
with self.session_maker() as session:
|
|
480
|
-
results = session.query(JobModel).filter(JobModel.user_id == user_id).all()
|
|
481
|
-
return [r.to_record() for r in results]
|
|
482
|
-
|
|
483
|
-
def update_job(self, job: Job) -> Job:
|
|
484
|
-
with self.session_maker() as session:
|
|
485
|
-
session.query(JobModel).filter(JobModel.id == job.id).update(vars(job))
|
|
486
|
-
session.commit()
|
|
487
|
-
return Job
|
|
488
|
-
|
|
489
|
-
def update_job_status(self, job_id: str, status: JobStatus):
|
|
490
|
-
with self.session_maker() as session:
|
|
491
|
-
session.query(JobModel).filter(JobModel.id == job_id).update({"status": status})
|
|
492
|
-
if status == JobStatus.COMPLETED:
|
|
493
|
-
session.query(JobModel).filter(JobModel.id == job_id).update({"completed_at": get_utc_time()})
|
|
494
|
-
session.commit()
|
|
@@ -2,6 +2,7 @@ from letta.orm.base import Base
|
|
|
2
2
|
from letta.orm.block import Block
|
|
3
3
|
from letta.orm.blocks_agents import BlocksAgents
|
|
4
4
|
from letta.orm.file import FileMetadata
|
|
5
|
+
from letta.orm.job import Job
|
|
5
6
|
from letta.orm.organization import Organization
|
|
6
7
|
from letta.orm.sandbox_config import SandboxConfig, SandboxEnvironmentVariable
|
|
7
8
|
from letta.orm.source import Source
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from typing import TYPE_CHECKING, Optional
|
|
3
|
+
|
|
4
|
+
from sqlalchemy import JSON, String
|
|
5
|
+
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
6
|
+
|
|
7
|
+
from letta.orm.mixins import UserMixin
|
|
8
|
+
from letta.orm.sqlalchemy_base import SqlalchemyBase
|
|
9
|
+
from letta.schemas.enums import JobStatus
|
|
10
|
+
from letta.schemas.job import Job as PydanticJob
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from letta.orm.user import User
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Job(SqlalchemyBase, UserMixin):
|
|
17
|
+
"""Jobs run in the background and are owned by a user.
|
|
18
|
+
Typical jobs involve loading and processing sources etc.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
__tablename__ = "jobs"
|
|
22
|
+
__pydantic_model__ = PydanticJob
|
|
23
|
+
|
|
24
|
+
status: Mapped[JobStatus] = mapped_column(String, default=JobStatus.created, doc="The current status of the job.")
|
|
25
|
+
completed_at: Mapped[Optional[datetime]] = mapped_column(nullable=True, doc="The unix timestamp of when the job was completed.")
|
|
26
|
+
metadata_: Mapped[Optional[dict]] = mapped_column(JSON, default=lambda: {}, doc="The metadata of the job.")
|
|
27
|
+
|
|
28
|
+
# relationships
|
|
29
|
+
user: Mapped["User"] = relationship("User", back_populates="jobs")
|
|
@@ -31,24 +31,43 @@ class SqlalchemyBase(CommonSqlalchemyMetaMixins, Base):
|
|
|
31
31
|
def list(
|
|
32
32
|
cls, *, db_session: "Session", cursor: Optional[str] = None, limit: Optional[int] = 50, **kwargs
|
|
33
33
|
) -> List[Type["SqlalchemyBase"]]:
|
|
34
|
-
"""
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
"""
|
|
35
|
+
List records with optional cursor (for pagination), limit, and automatic filtering.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
db_session: The database session to use.
|
|
39
|
+
cursor: Optional ID to start pagination from.
|
|
40
|
+
limit: Maximum number of records to return.
|
|
41
|
+
**kwargs: Filters passed as equality conditions or iterable for IN filtering.
|
|
39
42
|
|
|
40
|
-
|
|
43
|
+
Returns:
|
|
44
|
+
A list of model instances matching the filters.
|
|
45
|
+
"""
|
|
46
|
+
logger.debug(f"Listing {cls.__name__} with filters {kwargs}")
|
|
47
|
+
with db_session as session:
|
|
48
|
+
# Start with a base query
|
|
49
|
+
query = select(cls)
|
|
50
|
+
|
|
51
|
+
# Apply filtering logic
|
|
52
|
+
for key, value in kwargs.items():
|
|
53
|
+
column = getattr(cls, key)
|
|
54
|
+
if isinstance(value, (list, tuple, set)): # Check for iterables
|
|
55
|
+
query = query.where(column.in_(value))
|
|
56
|
+
else: # Single value for equality filtering
|
|
57
|
+
query = query.where(column == value)
|
|
58
|
+
|
|
59
|
+
# Apply cursor for pagination
|
|
41
60
|
if cursor:
|
|
42
61
|
query = query.where(cls.id > cursor)
|
|
43
62
|
|
|
44
|
-
# Add a limit to the query if provided
|
|
45
|
-
query = query.order_by(cls.id).limit(limit)
|
|
46
|
-
|
|
47
63
|
# Handle soft deletes if the class has the 'is_deleted' attribute
|
|
48
64
|
if hasattr(cls, "is_deleted"):
|
|
49
65
|
query = query.where(cls.is_deleted == False)
|
|
50
66
|
|
|
51
|
-
#
|
|
67
|
+
# Add ordering and limit
|
|
68
|
+
query = query.order_by(cls.id).limit(limit)
|
|
69
|
+
|
|
70
|
+
# Execute the query and return results as model instances
|
|
52
71
|
return list(session.execute(query).scalars())
|
|
53
72
|
|
|
54
73
|
@classmethod
|
{letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/orm/user.py
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import TYPE_CHECKING
|
|
1
|
+
from typing import TYPE_CHECKING, List
|
|
2
2
|
|
|
3
3
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
4
4
|
|
|
@@ -7,7 +7,7 @@ from letta.orm.sqlalchemy_base import SqlalchemyBase
|
|
|
7
7
|
from letta.schemas.user import User as PydanticUser
|
|
8
8
|
|
|
9
9
|
if TYPE_CHECKING:
|
|
10
|
-
from letta.orm
|
|
10
|
+
from letta.orm import Job, Organization
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class User(SqlalchemyBase, OrganizationMixin):
|
|
@@ -20,10 +20,10 @@ class User(SqlalchemyBase, OrganizationMixin):
|
|
|
20
20
|
|
|
21
21
|
# relationships
|
|
22
22
|
organization: Mapped["Organization"] = relationship("Organization", back_populates="users")
|
|
23
|
+
jobs: Mapped[List["Job"]] = relationship("Job", back_populates="user", doc="the jobs associated with this user.")
|
|
23
24
|
|
|
24
25
|
# TODO: Add this back later potentially
|
|
25
26
|
# agents: Mapped[List["Agent"]] = relationship(
|
|
26
27
|
# "Agent", secondary="users_agents", back_populates="users", doc="the agents associated with this user."
|
|
27
28
|
# )
|
|
28
29
|
# tokens: Mapped[List["Token"]] = relationship("Token", back_populates="user", doc="the tokens associated with this user.")
|
|
29
|
-
# jobs: Mapped[List["Job"]] = relationship("Job", back_populates="user", doc="the jobs associated with this user.")
|
{letta_nightly-0.6.0.dev20241204232133 → letta_nightly-0.6.0.dev20241205104308}/letta/schemas/job.py
RENAMED
|
@@ -4,12 +4,13 @@ from typing import Optional
|
|
|
4
4
|
from pydantic import Field
|
|
5
5
|
|
|
6
6
|
from letta.schemas.enums import JobStatus
|
|
7
|
-
from letta.schemas.letta_base import
|
|
8
|
-
from letta.utils import get_utc_time
|
|
7
|
+
from letta.schemas.letta_base import OrmMetadataBase
|
|
9
8
|
|
|
10
9
|
|
|
11
|
-
class JobBase(
|
|
10
|
+
class JobBase(OrmMetadataBase):
|
|
12
11
|
__id_prefix__ = "job"
|
|
12
|
+
status: JobStatus = Field(default=JobStatus.created, description="The status of the job.")
|
|
13
|
+
completed_at: Optional[datetime] = Field(None, description="The unix timestamp of when the job was completed.")
|
|
13
14
|
metadata_: Optional[dict] = Field(None, description="The metadata of the job.")
|
|
14
15
|
|
|
15
16
|
|
|
@@ -27,12 +28,11 @@ class Job(JobBase):
|
|
|
27
28
|
"""
|
|
28
29
|
|
|
29
30
|
id: str = JobBase.generate_id_field()
|
|
30
|
-
|
|
31
|
-
created_at: datetime = Field(default_factory=get_utc_time, description="The unix timestamp of when the job was created.")
|
|
32
|
-
completed_at: Optional[datetime] = Field(None, description="The unix timestamp of when the job was completed.")
|
|
33
|
-
user_id: str = Field(..., description="The unique identifier of the user associated with the job.")
|
|
31
|
+
user_id: Optional[str] = Field(None, description="The unique identifier of the user associated with the job.")
|
|
34
32
|
|
|
35
33
|
|
|
36
34
|
class JobUpdate(JobBase):
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
status: Optional[JobStatus] = Field(None, description="The status of the job.")
|
|
36
|
+
|
|
37
|
+
class Config:
|
|
38
|
+
extra = "ignore" # Ignores extra fields
|
|
@@ -2,6 +2,8 @@ from typing import List, Optional
|
|
|
2
2
|
|
|
3
3
|
from fastapi import APIRouter, Depends, Header, HTTPException, Query
|
|
4
4
|
|
|
5
|
+
from letta.orm.errors import NoResultFound
|
|
6
|
+
from letta.schemas.enums import JobStatus
|
|
5
7
|
from letta.schemas.job import Job
|
|
6
8
|
from letta.server.rest_api.utils import get_letta_server
|
|
7
9
|
from letta.server.server import SyncServer
|
|
@@ -21,12 +23,11 @@ def list_jobs(
|
|
|
21
23
|
actor = server.get_user_or_default(user_id=user_id)
|
|
22
24
|
|
|
23
25
|
# TODO: add filtering by status
|
|
24
|
-
jobs = server.list_jobs(
|
|
26
|
+
jobs = server.job_manager.list_jobs(actor=actor)
|
|
25
27
|
|
|
26
|
-
# TODO: eventually use ORM
|
|
27
|
-
# results = session.query(JobModel).filter(JobModel.user_id == user_id, JobModel.metadata_["source_id"].astext == sourced_id).all()
|
|
28
28
|
if source_id:
|
|
29
29
|
# can't be in the ORM since we have source_id stored in the metadata_
|
|
30
|
+
# TODO: Probably change this
|
|
30
31
|
jobs = [job for job in jobs if job.metadata_.get("source_id") == source_id]
|
|
31
32
|
return jobs
|
|
32
33
|
|
|
@@ -41,32 +42,39 @@ def list_active_jobs(
|
|
|
41
42
|
"""
|
|
42
43
|
actor = server.get_user_or_default(user_id=user_id)
|
|
43
44
|
|
|
44
|
-
return server.
|
|
45
|
+
return server.job_manager.list_jobs(actor=actor, statuses=[JobStatus.created, JobStatus.running])
|
|
45
46
|
|
|
46
47
|
|
|
47
48
|
@router.get("/{job_id}", response_model=Job, operation_id="get_job")
|
|
48
49
|
def get_job(
|
|
49
50
|
job_id: str,
|
|
51
|
+
user_id: Optional[str] = Header(None, alias="user_id"),
|
|
50
52
|
server: "SyncServer" = Depends(get_letta_server),
|
|
51
53
|
):
|
|
52
54
|
"""
|
|
53
55
|
Get the status of a job.
|
|
54
56
|
"""
|
|
57
|
+
actor = server.get_user_or_default(user_id=user_id)
|
|
55
58
|
|
|
56
|
-
|
|
59
|
+
try:
|
|
60
|
+
return server.job_manager.get_job_by_id(job_id=job_id, actor=actor)
|
|
61
|
+
except NoResultFound:
|
|
62
|
+
raise HTTPException(status_code=404, detail="Job not found")
|
|
57
63
|
|
|
58
64
|
|
|
59
65
|
@router.delete("/{job_id}", response_model=Job, operation_id="delete_job")
|
|
60
66
|
def delete_job(
|
|
61
67
|
job_id: str,
|
|
68
|
+
user_id: Optional[str] = Header(None, alias="user_id"),
|
|
62
69
|
server: "SyncServer" = Depends(get_letta_server),
|
|
63
70
|
):
|
|
64
71
|
"""
|
|
65
72
|
Delete a job by its job_id.
|
|
66
73
|
"""
|
|
67
|
-
|
|
68
|
-
if not job:
|
|
69
|
-
raise HTTPException(status_code=404, detail="Job not found")
|
|
74
|
+
actor = server.get_user_or_default(user_id=user_id)
|
|
70
75
|
|
|
71
|
-
|
|
72
|
-
|
|
76
|
+
try:
|
|
77
|
+
job = server.job_manager.delete_job_by_id(job_id=job_id, actor=actor)
|
|
78
|
+
return job
|
|
79
|
+
except NoResultFound:
|
|
80
|
+
raise HTTPException(status_code=404, detail="Job not found")
|
|
@@ -16,6 +16,7 @@ from letta.schemas.file import FileMetadata
|
|
|
16
16
|
from letta.schemas.job import Job
|
|
17
17
|
from letta.schemas.passage import Passage
|
|
18
18
|
from letta.schemas.source import Source, SourceCreate, SourceUpdate
|
|
19
|
+
from letta.schemas.user import User
|
|
19
20
|
from letta.server.rest_api.utils import get_letta_server
|
|
20
21
|
from letta.server.server import SyncServer
|
|
21
22
|
from letta.utils import sanitize_filename
|
|
@@ -175,13 +176,14 @@ def upload_file_to_source(
|
|
|
175
176
|
completed_at=None,
|
|
176
177
|
)
|
|
177
178
|
job_id = job.id
|
|
178
|
-
server.
|
|
179
|
+
server.job_manager.create_job(job, actor=actor)
|
|
179
180
|
|
|
180
181
|
# create background task
|
|
181
|
-
background_tasks.add_task(load_file_to_source_async, server, source_id=source.id, file=file, job_id=job.id, bytes=bytes)
|
|
182
|
+
background_tasks.add_task(load_file_to_source_async, server, source_id=source.id, file=file, job_id=job.id, bytes=bytes, actor=actor)
|
|
182
183
|
|
|
183
184
|
# return job information
|
|
184
|
-
job
|
|
185
|
+
# Is this necessary? Can we just return the job from create_job?
|
|
186
|
+
job = server.job_manager.get_job_by_id(job_id=job_id, actor=actor)
|
|
185
187
|
assert job is not None, "Job not found"
|
|
186
188
|
return job
|
|
187
189
|
|
|
@@ -234,7 +236,7 @@ def delete_file_from_source(
|
|
|
234
236
|
raise HTTPException(status_code=404, detail=f"File with id={file_id} not found.")
|
|
235
237
|
|
|
236
238
|
|
|
237
|
-
def load_file_to_source_async(server: SyncServer, source_id: str, job_id: str, file: UploadFile, bytes: bytes):
|
|
239
|
+
def load_file_to_source_async(server: SyncServer, source_id: str, job_id: str, file: UploadFile, bytes: bytes, actor: User):
|
|
238
240
|
# Create a temporary directory (deleted after the context manager exits)
|
|
239
241
|
with tempfile.TemporaryDirectory() as tmpdirname:
|
|
240
242
|
# Sanitize the filename
|
|
@@ -246,4 +248,4 @@ def load_file_to_source_async(server: SyncServer, source_id: str, job_id: str, f
|
|
|
246
248
|
buffer.write(bytes)
|
|
247
249
|
|
|
248
250
|
# Pass the file to load_file_to_source
|
|
249
|
-
server.load_file_to_source(source_id, file_path, job_id)
|
|
251
|
+
server.load_file_to_source(source_id, file_path, job_id, actor)
|
|
@@ -6,7 +6,7 @@ import warnings
|
|
|
6
6
|
from abc import abstractmethod
|
|
7
7
|
from asyncio import Lock
|
|
8
8
|
from datetime import datetime
|
|
9
|
-
from typing import Callable,
|
|
9
|
+
from typing import Callable, List, Optional, Tuple, Union
|
|
10
10
|
|
|
11
11
|
from composio.client import Composio
|
|
12
12
|
from composio.client.collections import ActionModel, AppModel
|
|
@@ -56,7 +56,7 @@ from letta.schemas.embedding_config import EmbeddingConfig
|
|
|
56
56
|
|
|
57
57
|
# openai schemas
|
|
58
58
|
from letta.schemas.enums import JobStatus
|
|
59
|
-
from letta.schemas.job import Job
|
|
59
|
+
from letta.schemas.job import Job, JobUpdate
|
|
60
60
|
from letta.schemas.letta_message import FunctionReturn, LettaMessage
|
|
61
61
|
from letta.schemas.llm_config import LLMConfig
|
|
62
62
|
from letta.schemas.memory import (
|
|
@@ -75,6 +75,7 @@ from letta.schemas.user import User
|
|
|
75
75
|
from letta.services.agents_tags_manager import AgentsTagsManager
|
|
76
76
|
from letta.services.block_manager import BlockManager
|
|
77
77
|
from letta.services.blocks_agents_manager import BlocksAgentsManager
|
|
78
|
+
from letta.services.job_manager import JobManager
|
|
78
79
|
from letta.services.organization_manager import OrganizationManager
|
|
79
80
|
from letta.services.per_agent_lock_manager import PerAgentLockManager
|
|
80
81
|
from letta.services.sandbox_config_manager import SandboxConfigManager
|
|
@@ -256,6 +257,7 @@ class SyncServer(Server):
|
|
|
256
257
|
self.agents_tags_manager = AgentsTagsManager()
|
|
257
258
|
self.sandbox_config_manager = SandboxConfigManager(tool_settings)
|
|
258
259
|
self.blocks_agents_manager = BlocksAgentsManager()
|
|
260
|
+
self.job_manager = JobManager()
|
|
259
261
|
|
|
260
262
|
# Managers that interface with parallelism
|
|
261
263
|
self.per_agent_lock_manager = PerAgentLockManager()
|
|
@@ -1469,39 +1471,12 @@ class SyncServer(Server):
|
|
|
1469
1471
|
|
|
1470
1472
|
# TODO: delete data from agent passage stores (?)
|
|
1471
1473
|
|
|
1472
|
-
def
|
|
1473
|
-
"""Create a new job"""
|
|
1474
|
-
job = Job(
|
|
1475
|
-
user_id=user_id,
|
|
1476
|
-
status=JobStatus.created,
|
|
1477
|
-
metadata_=metadata,
|
|
1478
|
-
)
|
|
1479
|
-
self.ms.create_job(job)
|
|
1480
|
-
return job
|
|
1481
|
-
|
|
1482
|
-
def delete_job(self, job_id: str):
|
|
1483
|
-
"""Delete a job"""
|
|
1484
|
-
self.ms.delete_job(job_id)
|
|
1485
|
-
|
|
1486
|
-
def get_job(self, job_id: str) -> Job:
|
|
1487
|
-
"""Get a job"""
|
|
1488
|
-
return self.ms.get_job(job_id)
|
|
1489
|
-
|
|
1490
|
-
def list_jobs(self, user_id: str) -> List[Job]:
|
|
1491
|
-
"""List all jobs for a user"""
|
|
1492
|
-
return self.ms.list_jobs(user_id=user_id)
|
|
1493
|
-
|
|
1494
|
-
def list_active_jobs(self, user_id: str) -> List[Job]:
|
|
1495
|
-
"""List all active jobs for a user"""
|
|
1496
|
-
jobs = self.ms.list_jobs(user_id=user_id)
|
|
1497
|
-
return [job for job in jobs if job.status in [JobStatus.created, JobStatus.running]]
|
|
1498
|
-
|
|
1499
|
-
def load_file_to_source(self, source_id: str, file_path: str, job_id: str) -> Job:
|
|
1474
|
+
def load_file_to_source(self, source_id: str, file_path: str, job_id: str, actor: User) -> Job:
|
|
1500
1475
|
|
|
1501
1476
|
# update job
|
|
1502
|
-
job = self.
|
|
1477
|
+
job = self.job_manager.get_job_by_id(job_id, actor=actor)
|
|
1503
1478
|
job.status = JobStatus.running
|
|
1504
|
-
self.
|
|
1479
|
+
self.job_manager.update_job_by_id(job_id=job_id, job_update=JobUpdate(**job.model_dump()), actor=actor)
|
|
1505
1480
|
|
|
1506
1481
|
# try:
|
|
1507
1482
|
from letta.data_sources.connectors import DirectoryConnector
|
|
@@ -1509,23 +1484,12 @@ class SyncServer(Server):
|
|
|
1509
1484
|
source = self.source_manager.get_source_by_id(source_id=source_id)
|
|
1510
1485
|
connector = DirectoryConnector(input_files=[file_path])
|
|
1511
1486
|
num_passages, num_documents = self.load_data(user_id=source.created_by_id, source_name=source.name, connector=connector)
|
|
1512
|
-
# except Exception as e:
|
|
1513
|
-
# # job failed with error
|
|
1514
|
-
# error = str(e)
|
|
1515
|
-
# print(error)
|
|
1516
|
-
# job.status = JobStatus.failed
|
|
1517
|
-
# job.metadata_["error"] = error
|
|
1518
|
-
# self.ms.update_job(job)
|
|
1519
|
-
# # TODO: delete any associated passages/files?
|
|
1520
|
-
|
|
1521
|
-
# # return failed job
|
|
1522
|
-
# return job
|
|
1523
1487
|
|
|
1524
1488
|
# update job status
|
|
1525
1489
|
job.status = JobStatus.completed
|
|
1526
1490
|
job.metadata_["num_passages"] = num_passages
|
|
1527
1491
|
job.metadata_["num_documents"] = num_documents
|
|
1528
|
-
self.
|
|
1492
|
+
self.job_manager.update_job_by_id(job_id=job_id, job_update=JobUpdate(**job.model_dump()), actor=actor)
|
|
1529
1493
|
|
|
1530
1494
|
return job
|
|
1531
1495
|
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
from typing import List, Optional
|
|
2
|
+
|
|
3
|
+
from letta.orm.job import Job as JobModel
|
|
4
|
+
from letta.schemas.enums import JobStatus
|
|
5
|
+
from letta.schemas.job import Job as PydanticJob
|
|
6
|
+
from letta.schemas.job import JobUpdate
|
|
7
|
+
from letta.schemas.user import User as PydanticUser
|
|
8
|
+
from letta.utils import enforce_types, get_utc_time
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class JobManager:
|
|
12
|
+
"""Manager class to handle business logic related to Jobs."""
|
|
13
|
+
|
|
14
|
+
def __init__(self):
|
|
15
|
+
# Fetching the db_context similarly as in OrganizationManager
|
|
16
|
+
from letta.server.server import db_context
|
|
17
|
+
|
|
18
|
+
self.session_maker = db_context
|
|
19
|
+
|
|
20
|
+
@enforce_types
|
|
21
|
+
def create_job(self, pydantic_job: PydanticJob, actor: PydanticUser) -> PydanticJob:
|
|
22
|
+
"""Create a new job based on the JobCreate schema."""
|
|
23
|
+
with self.session_maker() as session:
|
|
24
|
+
# Associate the job with the user
|
|
25
|
+
pydantic_job.user_id = actor.id
|
|
26
|
+
job_data = pydantic_job.model_dump()
|
|
27
|
+
job = JobModel(**job_data)
|
|
28
|
+
job.create(session, actor=actor) # Save job in the database
|
|
29
|
+
return job.to_pydantic()
|
|
30
|
+
|
|
31
|
+
@enforce_types
|
|
32
|
+
def update_job_by_id(self, job_id: str, job_update: JobUpdate, actor: PydanticUser) -> PydanticJob:
|
|
33
|
+
"""Update a job by its ID with the given JobUpdate object."""
|
|
34
|
+
with self.session_maker() as session:
|
|
35
|
+
# Fetch the job by ID
|
|
36
|
+
job = JobModel.read(db_session=session, identifier=job_id) # TODO: Add this later , actor=actor)
|
|
37
|
+
|
|
38
|
+
# Update job attributes with only the fields that were explicitly set
|
|
39
|
+
update_data = job_update.model_dump(exclude_unset=True, exclude_none=True)
|
|
40
|
+
|
|
41
|
+
# Automatically update the completion timestamp if status is set to 'completed'
|
|
42
|
+
if update_data.get("status") == JobStatus.completed and not job.completed_at:
|
|
43
|
+
job.completed_at = get_utc_time()
|
|
44
|
+
|
|
45
|
+
for key, value in update_data.items():
|
|
46
|
+
setattr(job, key, value)
|
|
47
|
+
|
|
48
|
+
# Save the updated job to the database
|
|
49
|
+
return job.update(db_session=session) # TODO: Add this later , actor=actor)
|
|
50
|
+
|
|
51
|
+
@enforce_types
|
|
52
|
+
def get_job_by_id(self, job_id: str, actor: PydanticUser) -> PydanticJob:
|
|
53
|
+
"""Fetch a job by its ID."""
|
|
54
|
+
with self.session_maker() as session:
|
|
55
|
+
# Retrieve job by ID using the Job model's read method
|
|
56
|
+
job = JobModel.read(db_session=session, identifier=job_id) # TODO: Add this later , actor=actor)
|
|
57
|
+
return job.to_pydantic()
|
|
58
|
+
|
|
59
|
+
@enforce_types
|
|
60
|
+
def list_jobs(
|
|
61
|
+
self, actor: PydanticUser, cursor: Optional[str] = None, limit: Optional[int] = 50, statuses: Optional[List[JobStatus]] = None
|
|
62
|
+
) -> List[PydanticJob]:
|
|
63
|
+
"""List all jobs with optional pagination and status filter."""
|
|
64
|
+
with self.session_maker() as session:
|
|
65
|
+
filter_kwargs = {"user_id": actor.id}
|
|
66
|
+
|
|
67
|
+
# Add status filter if provided
|
|
68
|
+
if statuses:
|
|
69
|
+
filter_kwargs["status"] = statuses
|
|
70
|
+
|
|
71
|
+
jobs = JobModel.list(
|
|
72
|
+
db_session=session,
|
|
73
|
+
cursor=cursor,
|
|
74
|
+
limit=limit,
|
|
75
|
+
**filter_kwargs,
|
|
76
|
+
)
|
|
77
|
+
return [job.to_pydantic() for job in jobs]
|
|
78
|
+
|
|
79
|
+
@enforce_types
|
|
80
|
+
def delete_job_by_id(self, job_id: str, actor: PydanticUser) -> PydanticJob:
|
|
81
|
+
"""Delete a job by its ID."""
|
|
82
|
+
with self.session_maker() as session:
|
|
83
|
+
job = JobModel.read(db_session=session, identifier=job_id) # TODO: Add this later , actor=actor)
|
|
84
|
+
job.hard_delete(db_session=session) # TODO: Add this later , actor=actor)
|
|
85
|
+
return job.to_pydantic()
|
|
@@ -172,9 +172,31 @@ class ToolExecutionSandbox:
|
|
|
172
172
|
capture_output=True,
|
|
173
173
|
text=True,
|
|
174
174
|
)
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
175
|
+
|
|
176
|
+
# Handle error with optimistic error parsing from the string
|
|
177
|
+
# This is very brittle, so we fall back to a RuntimeError if parsing fails
|
|
178
|
+
if result.returncode != 0:
|
|
179
|
+
# Log the error
|
|
180
|
+
logger.error(f"Sandbox execution error:\n{result.stderr}")
|
|
181
|
+
|
|
182
|
+
# Parse and raise the actual error from stderr
|
|
183
|
+
tb_lines = result.stderr.strip().splitlines()
|
|
184
|
+
exception_line = tb_lines[-1] # The last line contains the exception
|
|
185
|
+
|
|
186
|
+
try:
|
|
187
|
+
# Split exception type and message
|
|
188
|
+
exception_type, exception_message = exception_line.split(": ", 1)
|
|
189
|
+
exception_type = exception_type.strip()
|
|
190
|
+
exception_message = exception_message.strip()
|
|
191
|
+
|
|
192
|
+
# Dynamically raise the exception
|
|
193
|
+
exception_class = eval(exception_type) # Look up the exception type
|
|
194
|
+
|
|
195
|
+
except Exception:
|
|
196
|
+
# Fallback to RuntimeError if parsing fails
|
|
197
|
+
raise RuntimeError(result.stderr)
|
|
198
|
+
|
|
199
|
+
raise exception_class(exception_message)
|
|
178
200
|
|
|
179
201
|
func_result, stdout = self.parse_out_function_results_markers(result.stdout)
|
|
180
202
|
func_return, agent_state = self.parse_best_effort(func_result)
|
|
@@ -184,9 +206,11 @@ class ToolExecutionSandbox:
|
|
|
184
206
|
except subprocess.TimeoutExpired:
|
|
185
207
|
raise TimeoutError(f"Executing tool {self.tool_name} has timed out.")
|
|
186
208
|
except subprocess.CalledProcessError as e:
|
|
187
|
-
|
|
209
|
+
logger.error(f"Executing tool {self.tool_name} has process error: {e}")
|
|
210
|
+
raise e
|
|
188
211
|
except Exception as e:
|
|
189
|
-
|
|
212
|
+
logger.error(f"Executing tool {self.tool_name} has an unexpected error: {e}")
|
|
213
|
+
raise e
|
|
190
214
|
|
|
191
215
|
def run_local_dir_sandbox_runpy(
|
|
192
216
|
self, sbx_config: SandboxConfig, env_vars: Dict[str, str], temp_file_path: str, old_stdout: TextIO
|