diff --git a/letta/server/server.py b/letta/server/server.py index e532d467..ee0fb45c 100644 --- a/letta/server/server.py +++ b/letta/server/server.py @@ -83,6 +83,7 @@ from letta.server.rest_api.utils import sse_async_generator from letta.services.agent_manager import AgentManager from letta.services.block_manager import BlockManager from letta.services.group_manager import GroupManager +from letta.services.helpers.tool_execution_helper import prepare_local_sandbox from letta.services.identity_manager import IdentityManager from letta.services.job_manager import JobManager from letta.services.llm_batch_manager import LLMBatchManager @@ -259,6 +260,13 @@ class SyncServer(Server): ) logger.info(f"Successfully created default local sandbox config:\n{sandbox_config.get_local_config().model_dump()}") + if use_venv and tool_settings.tool_exec_autoreload_venv: + prepare_local_sandbox( + sandbox_config.get_local_config(), + env=os.environ.copy(), + force_recreate=True, + ) + # collect providers (always has Letta as a default) self._enabled_providers: List[Provider] = [LettaProvider()] if model_settings.openai_api_key: diff --git a/letta/services/helpers/tool_execution_helper.py b/letta/services/helpers/tool_execution_helper.py index ac86f480..043594cc 100644 --- a/letta/services/helpers/tool_execution_helper.py +++ b/letta/services/helpers/tool_execution_helper.py @@ -171,3 +171,30 @@ def add_imports_and_pydantic_schemas_for_args(args_json_schema: dict) -> str: ) result = parser.parse() return result + + +def prepare_local_sandbox( + local_cfg: LocalSandboxConfig, + env: Dict[str, str], + force_recreate: bool = False, +) -> None: + """ + Ensure the sandbox virtual-env is freshly created and that + requirements are installed. Uses your existing helpers. + """ + sandbox_dir = os.path.expanduser(local_cfg.sandbox_dir) + venv_path = os.path.join(sandbox_dir, local_cfg.venv_name) + + create_venv_for_local_sandbox( + sandbox_dir_path=sandbox_dir, + venv_path=venv_path, + env=env, + force_recreate=force_recreate, + ) + + install_pip_requirements_for_sandbox( + local_cfg, + upgrade=True, + user_install_if_no_venv=False, + env=env, + ) diff --git a/letta/settings.py b/letta/settings.py index 59a4cd7c..7adea271 100644 --- a/letta/settings.py +++ b/letta/settings.py @@ -19,6 +19,7 @@ class ToolSettings(BaseSettings): tool_exec_dir: Optional[str] = None tool_sandbox_timeout: float = 180 tool_exec_venv_name: Optional[str] = None + tool_exec_autoreload_venv: bool = True # MCP settings mcp_connect_to_server_timeout: float = 30.0