feat: connect generated letta api key with modal function wrapper (#6329)

base

Co-authored-by: Letta Bot <noreply@letta.com>
This commit is contained in:
jnjpng
2025-11-21 15:26:03 -08:00
committed by Caren Thomas
parent 4420d711d8
commit 442b916fa9
3 changed files with 12 additions and 9 deletions

View File

@@ -84,7 +84,9 @@ class SandboxToolExecutor(ToolExecutor):
organization_id=actor.organization_id,
)
# TODO: pass through letta api key
tool_execution_result = await sandbox.run(agent_state=agent_state_copy, additional_env_vars=sandbox_env_vars)
tool_execution_result = await sandbox.run(
agent_id=agent_state.id, agent_state=agent_state_copy, additional_env_vars=sandbox_env_vars
)
except Exception as e:
# Modal execution failed, log and fall back to E2B/LOCAL
logger.warning(f"Modal execution failed for tool {tool.name}: {e}. Falling back to {tool_settings.sandbox_type.value}")

View File

@@ -61,7 +61,7 @@ def modal_tool_wrapper(tool: PydanticTool, actor: PydanticUser, sandbox_env_vars
packages = [str(req) for req in tool.pip_requirements] if tool.pip_requirements else []
for package in MODAL_SAFE_IMPORT_MODULES:
packages.append(package)
packages.append("letta_client")
packages.append("letta_client>=1.1.1")
packages.append("letta") # Base letta without extras
packages.append("asyncpg>=0.30.0") # Fixes asyncpg import error
packages.append("psycopg2-binary>=2.9.10") # PostgreSQL adapter (pre-compiled, no build required)
@@ -116,22 +116,23 @@ def modal_tool_wrapper(tool: PydanticTool, actor: PydanticUser, sandbox_env_vars
print("Passing agent_state as dict to tool", file=sys.stderr)
reconstructed_agent_state = agent_state
# Set environment variables
if env_vars:
for key, value in env_vars.items():
os.environ[key] = str(value)
# TODO: directly instantiate the letta client once we upgrade to 1.0.0+ in core
# Initialize the Letta client
if letta_api_key:
letta_client = Letta(token=letta_api_key, base_url=os.environ.get("LETTA_API_URL", "https://api.letta.com"))
else:
letta_client = None
# if letta_api_key:
# letta_client = Letta(token=letta_api_key, base_url=os.environ.get("LETTA_API_URL", "https://api.letta.com"))
# else:
# letta_client = None
tool_namespace = {
"__builtins__": __builtins__, # Include built-in functions
"_letta_client": letta_client, # Make letta_client available
# "_letta_client": letta_client, # Make letta_client available
"os": os, # Include os module for env vars access
"agent_id": agent_id,
"_LETTA_API_KEY": letta_api_key,
# Add any other modules/variables the tool might need
}

View File

@@ -103,7 +103,7 @@ class AsyncToolSandboxModal(AsyncToolSandboxBase):
if additional_env_vars is None:
letta_api_key = None
else:
letta_api_key = additional_env_vars.get("LETTA_API_KEY", None)
letta_api_key = additional_env_vars.get("LETTA_SECRET_API_KEY", None)
# Construct dynamic env vars
# Priority order (later overrides earlier):