Scheduling
Scheduling is a technique for triggering Letta agents at regular intervals. Many real-world applications require proactive behavior, such as checking emails every few hours or scraping news sites. Scheduling can support autonomous agents with the capability to manage ongoing processes.
Common Use Cases
Section titled “Common Use Cases”When building autonomous agents with Letta, you often need to trigger them at regular intervals for tasks like:
- System Monitoring: Health checks that adapt based on historical patterns
- Data Processing: Intelligent ETL processes that handle edge cases contextually
- Memory Maintenance: Agents that optimize their own knowledge base over time
- Proactive Notifications: Context-aware alerts that consider user preferences and timing
- Continuous Learning: Agents that regularly ingest new information and update their understanding
This guide covers simple approaches to implement scheduled agent interactions.
Option 1: Simple Loop
Section titled “Option 1: Simple Loop”The most straightforward approach for development and testing:
import { LettaClient } from "@letta-ai/letta-client";
const client = new LettaClient({ token: process.env.LETTA_API_KEY });const agentId = "your_agent_id";
while (true) { const response = await client.agents.messages.create(agentId, { messages: [ { role: "user", content: `Scheduled check at ${new Date()}`, }, ], }); console.log(`[${new Date()}] Agent responded`); await new Promise((resolve) => setTimeout(resolve, 300000)); // 5 minutes}import timeimport osfrom letta_client import Lettafrom datetime import datetime
client = Letta(token=os.getenv("LETTA_API_KEY"))agent_id = "your_agent_id"
while True: response = client.agents.messages.create( agent_id=agent_id, messages=[{ "role": "user", "content": f"Scheduled check at {datetime.now()}" }] ) print(f"[{datetime.now()}] Agent responded") time.sleep(300) # 5 minutesPros: Simple, easy to debug Cons: Blocks terminal, stops if process dies
Option 2: System Cron Jobs
Section titled “Option 2: System Cron Jobs”For production deployments, use cron for reliability:
#!/usr/bin/env nodeimport { LettaClient } from "@letta-ai/letta-client";
async function sendMessage() { try { const client = new LettaClient({ token: process.env.LETTA_API_KEY }); const response = await client.agents.messages.create("your_agent_id", { messages: [ { role: "user", content: "Scheduled maintenance check", }, ], }); console.log(`[${new Date()}] Success`); } catch (error) { console.error(`[${new Date()}] Error:`, error); }}
sendMessage();#!/usr/bin/env python3from letta_client import Lettafrom datetime import datetime
try: import os client = Letta(token=os.getenv("LETTA_API_KEY")) response = client.agents.messages.create( agent_id="your_agent_id", messages=[{ "role": "user", "content": "Scheduled maintenance check" }] ) print(f"[{datetime.now()}] Success")except Exception as e: print(f"[{datetime.now()}] Error: {e}")Add to crontab with crontab -e:
*/5 * * * * /usr/bin/python3 /path/to/send_message.py >> /var/log/letta_cron.log 2>&1# or for Node.js:*/5 * * * * /usr/bin/node /path/to/send_message.js >> /var/log/letta_cron.log 2>&1Pros: System-managed, survives reboots Cons: Requires cron access
Best Practices
Section titled “Best Practices”- Error Handling: Always wrap API calls in try-catch blocks
- Logging: Log both successes and failures for debugging
- Environment Variables: Store credentials securely
- Rate Limiting: Respect API limits and add backoff for failures
Example: Memory Maintenance Bot
Section titled “Example: Memory Maintenance Bot”Complete example that performs periodic memory cleanup:
#!/usr/bin/env nodeimport { LettaClient } from "@letta-ai/letta-client";
async function runMaintenance() { try { const client = new LettaClient({ token: process.env.LETTA_API_KEY }); const agentId = "your_agent_id";
const response = await client.agents.messages.create(agentId, { messages: [ { role: "user", content: "Please review your memory blocks for outdated information and clean up as needed.", }, ], });
// Print any assistant messages for (const message of response.messages) { if (message.messageType === "assistant_message") { console.log(`Agent response: ${message.content?.substring(0, 100)}...`); } } } catch (error) { console.error("Maintenance failed:", error); }}
// Run if called directlyif (import.meta.url === `file://${process.argv[1]}`) { runMaintenance();}#!/usr/bin/env python3import loggingfrom datetime import datetimefrom letta_client import Letta
logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
def run_maintenance(): try: import os client = Letta(token=os.getenv("LETTA_API_KEY")) agent_id = "your_agent_id"
response = client.agents.messages.create( agent_id=agent_id, messages=[{ "role": "user", "content": "Please review your memory blocks for outdated information and clean up as needed." }] )
# Print any assistant messages for message in response.messages: if message.message_type == "assistant_message": logging.info(f"Agent response: {message.content[:100]}...")
except Exception as e: logging.error(f"Maintenance failed: {e}")
if __name__ == "__main__": run_maintenance()Choose the scheduling method that best fits your deployment environment. For production systems, cron offers the best reliability, while simple loops are perfect for development and testing.