Sandbox Execution
Understand how custom tools execute in sandboxed Python environments with full API access via client injection.
Custom tools execute in sandboxed Python environments to provide security and isolation while maintaining full access to the Letta API.
Execution Environment
Section titled “Execution Environment”When a custom tool is called, it runs in an isolated Python environment with:
- Python 3.x runtime - Standard Python interpreter
- Package dependencies - Configurable Python packages
- Environment variables - Custom configuration and secrets
- Isolated filesystem - Sandboxed file access
- Client injection - Automatic Letta API access
Client Injection
Section titled “Client Injection”Custom tools automatically receive environment variables and a pre-initialized Letta client, making it easy to interact with the Letta API from within your tools.
Auto-Injected Environment Variables
Section titled “Auto-Injected Environment Variables”Three environment variables are automatically available in your tool scope:
LETTA_API_KEY- API key for authenticationLETTA_AGENT_ID- Current agent’s IDLETTA_PROJECT_ID- Current project ID
def get_agent_info() -> str: """ Get information about the current agent.
Returns: str: Agent ID and project ID """ import os
agent_id = os.environ.get('LETTA_AGENT_ID') project_id = os.environ.get('LETTA_PROJECT_ID')
return f"Agent ID: {agent_id}, Project: {project_id}"Pre-Initialized Client Object
Section titled “Pre-Initialized Client Object”A client object is automatically available in your tool scope - no import or initialization needed:
def list_project_agents() -> str: """ List all agents in the current project.
Returns: str: Number of agents found """ # 'client' is already initialized - no import needed agents = client.agents.list()
agent_count = len(list(agents.items)) return f"Found {agent_count} agents in project"The client is a fully initialized Letta client instance with access to all API endpoints.
API Operations
Section titled “API Operations”Tools can perform any Letta API operation using the injected client:
Read Operations
Section titled “Read Operations”client.agents.list()- List agents in your projectclient.agents.retrieve(agent_id=...)- Get agent informationclient.tools.list()- List available toolsclient.agents.messages.list()- Read message history- Multi-agent queries - Retrieve information from other agents
Write Operations
Section titled “Write Operations”client.blocks.update(block_id=..., value=...)- Update memory blocksclient.agents.create(...)- Create new agentsclient.agents.update(agent_id=..., ...)- Modify agent configurationclient.tools.upsert_from_function(...)- Create or update tools- Any other API operations
Use Cases
Section titled “Use Cases”Dynamic Memory Management
Section titled “Dynamic Memory Management”Update your agent’s memory blocks dynamically:
def memory_clear(label: str) -> str: """ Clear the value of a memory block.
Args: label: The label of the memory block to clear (e.g., "notes", "human")
Returns: str: Confirmation message """ import os
# Get current agent ID from environment agent_id = os.environ.get('LETTA_AGENT_ID')
# Retrieve agent to get block IDs agent = client.agents.retrieve(agent_id=agent_id)
# Find the block by label target_block = None for block in agent.memory.blocks: if block.label == label: target_block = block break
if not target_block: return f"Memory block '{label}' not found"
# Update the block value client.blocks.update( block_id=target_block.id, value="" )
return f"Cleared memory block '{label}'"Multi-Agent Coordination
Section titled “Multi-Agent Coordination”Query other agents in your project to enable collaboration:
def find_specialist_agent(topic: str) -> str: """ Find a specialist agent based on topic expertise.
Args: topic: The topic to find an expert for (e.g., "math", "code", "writing")
Returns: str: Information about the specialist agent found """ # List all agents in the project agents = client.agents.list()
# Search for an agent with matching expertise for agent in agents.items: if topic.lower() in agent.name.lower(): return f"Found specialist: {agent.name} (ID: {agent.id})"
return f"No specialist found for {topic}"Agent Introspection
Section titled “Agent Introspection”Read your own agent’s memory and configuration:
def analyze_my_memory() -> dict: """ Analyze the current agent's memory blocks.
Returns: dict: Memory analysis with block information """ import os
# Get current agent ID from environment agent_id = os.environ.get('LETTA_AGENT_ID')
# Retrieve agent information agent = client.agents.retrieve(agent_id=agent_id)
# Analyze memory blocks memory_info = {} for block in agent.memory.blocks: memory_info[block.label] = { "value": block.value, "limit": block.limit, "usage": len(block.value), "usage_percentage": (len(block.value) / block.limit * 100) if block.limit else 0 }
return memory_infoSubagent Creation
Section titled “Subagent Creation”Create specialized agents dynamically:
def create_specialist_agent(specialty: str, task: str) -> str: """ Create a specialist agent for a specific task.
Args: specialty: The agent's area of expertise (e.g., "math", "research") task: The initial task for the agent
Returns: str: New agent ID and status """ # Create a specialized agent new_agent = client.agents.create( name=f"{specialty}-specialist", memory_blocks=[ {"label": "human", "value": f"Task: {task}"}, {"label": "persona", "value": f"You are a {specialty} specialist"} ], model="openai/gpt-4o-mini", embedding="openai/text-embedding-3-small" )
return f"Created {specialty} agent (ID: {new_agent.id}) for task: {task}"Cross-Agent Information Retrieval
Section titled “Cross-Agent Information Retrieval”Access data from multiple agents:
def gather_team_status() -> str: """ Gather status information from all agents in the team.
Returns: str: Summary of team agent statuses """ # List all agents agents = client.agents.list()
team_summary = [] for agent in agents.items: # Get detailed agent info agent_detail = client.agents.retrieve(agent_id=agent.id)
# Summarize agent state team_summary.append(f"- {agent.name}: {len(agent_detail.memory.blocks)} memory blocks")
return "Team Status:\n" + "\n".join(team_summary)Installing Dependencies
Section titled “Installing Dependencies”Specify Python packages your custom tools need to use. See Tool Variables for complete details on configuring dependencies.
// Create a tool with custom dependenciesconst tool = await client.tools.upsert({ name: "analyze_sentiment", defaultRequiresApproval: false, jsonSchema: { type: "function", function: { name: "analyze_sentiment", description: "Analyze sentiment of text", parameters: { type: "object", properties: { text: { type: "string", description: "Text to analyze", }, }, required: ["text"], }, }, }, sourceCode: `def analyze_sentiment(text: str) -> str: """Analyze sentiment of text using TextBlob.""" from textblob import TextBlob blob = TextBlob(text) return f"Sentiment: {blob.sentiment.polarity}"`, packages: ["textblob"],});from letta_client import Lettaimport os
client = Letta(api_key=os.environ["LETTA_API_KEY"])
def analyze_sentiment(text: str) -> str: """ Analyze sentiment of text using TextBlob.
Args: text: The text to analyze
Returns: str: Sentiment analysis result """ from textblob import TextBlob blob = TextBlob(text) return f"Sentiment: {blob.sentiment.polarity}"
tool = client.tools.upsert_from_function( func=analyze_sentiment, packages=["textblob"])Environment Variables
Section titled “Environment Variables”Configure custom environment variables for API keys and configuration. See Tool Variables for details.
// Create agent with custom tool environment variablesconst agent = await client.agents.create({ memory_blocks: [ { label: "human", value: "Name: Alice" }, { label: "persona", value: "You are a helpful assistant" }, ], tools: ["my_api_tool"], toolExecEnvironmentVariables: { EXTERNAL_API_KEY: "your-api-key-here", API_ENDPOINT: "https://api.example.com", },});# Create agent with custom tool environment variablesagent = client.agents.create( memory_blocks=[ {"label": "human", "value": "Name: Alice"}, {"label": "persona", "value": "You are a helpful assistant"} ], tools=["my_api_tool"], tool_exec_environment_variables={ "EXTERNAL_API_KEY": "your-api-key-here", "API_ENDPOINT": "https://api.example.com" })Related
Section titled “Related”- Custom Tools - How to create custom tools
- Client-Side Tools - For write operations and full permissions
- Tool Variables - Configure dependencies and environment
- Tool Execution Modes - Compare all execution modes