babyagi3

babyagi3

babyagi3 is the third evolution of the original BabyAGI autonomous agent by Yohei Nakajima. Its philosophy is radical simplicity: everything is a message, the whole system is one loop — input → LLM → action → execute → output. Configure it once with a name and email, then control it entirely through natural language.

Under the hood babyagi3 is more sophisticated than it appears: three-layer memory (immutable event log, knowledge graph with entity/relationship extraction, and hierarchical summaries), background objective queuing, a persistent task scheduler (cron, natural language, or one-time), and dynamic tool creation where the agent writes and registers new tools mid-session that survive restarts.

Why Ravi

babyagi3 ships with multi-channel presence out of the box: email via AgentMail, SMS/iMessage via SendBlue, voice, and CLI. Every one of those channels requires an identity — an address, a number, credentials — and babyagi3 currently assembles that identity from separate accounts and API keys spread across services.

Ravi consolidates the identity layer:

  • One email address per agent — Ravi is a direct drop-in for AgentMail. The AGENTMAIL_API_KEY pattern in config.yaml maps 1:1 to a Ravi email identity: one account, fully portable, under the agent’s control.
  • One phone number per agent — The SENDBLUE_PHONE_NUMBER / OWNER_PHONE config pattern is exactly the abstraction Ravi fills. An agent-owned number the owner can text, without a separate SendBlue account.
  • Credential vault — babyagi3 stores API keys in the system keyring. Ravi secrets are a direct upgrade: cross-machine, per-identity, E2E encrypted, no keyring or OS dependencies.
  • Verification and 2FA — when babyagi3 auto-registers for services (SendBlue, Composio, AgentMail), it hits email and SMS verification walls. Ravi’s inbox and phone handle this natively without human intervention.

The result: one Ravi identity provides the agent’s complete communication presence with full provenance — no separate AgentMail account, no SendBlue account, no scattered API keys.

Setup

1. Get a Ravi identity

Sign up at ravi.app and create an identity for your babyagi3 instance. Each identity includes a provisioned email address, phone number, and encrypted secrets store.

2. Add Ravi credentials to babyagi3

In your babyagi3 config.yaml, replace the AgentMail and SendBlue entries with your Ravi credentials:

# config.yaml
agent_name: "babyagi3"

# Ravi replaces AgentMail + SendBlue
ravi_api_key: "YOUR_RAVI_API_KEY"
ravi_identity_id: "YOUR_RAVI_IDENTITY_ID"

# These map to your Ravi-provisioned address and number:
email: "youridentity@ravi.app"
phone: "+15551234567"

Store the API key in Ravi secrets rather than plaintext config:

# Store via Ravi CLI or API
ravi secrets set RAVI_API_KEY your_key_here

3. Add the Ravi channel adapter

Create listeners/ravi.py to poll Ravi for inbound messages and route them into babyagi3:

# listeners/ravi.py
import asyncio
import raviapp

async def listen(agent, config):
    client = raviapp.Client(api_key=config["ravi_api_key"])
    
    while True:
        # Poll email inbox
        threads = await client.inbox.email.list(unread=True)
        for thread in threads:
            messages = await client.inbox.email.read(thread.thread_id)
            for msg in messages:
                if not msg.is_read:
                    await agent.run_async(msg.text_content, source="email")
        
        # Poll SMS inbox
        conversations = await client.inbox.sms.list(unread=True)
        for conv in conversations:
            messages = await client.inbox.sms.read(conv.conversation_id)
            for msg in messages:
                if not msg.is_read and msg.direction == "incoming":
                    await agent.run_async(msg.body, source="sms")
        
        await asyncio.sleep(30)

Create senders/ravi.py to route outbound messages through Ravi:

# senders/ravi.py
import raviapp

class RaviSender:
    def __init__(self, config):
        self.client = raviapp.Client(api_key=config["ravi_api_key"])
    
    async def send_email(self, to, subject, body):
        await self.client.email.compose(to=to, subject=subject, body=body)
    
    async def send_sms(self, to_number, body):
        await self.client.sms.send(to_number=to_number, body=body)

4. Register the adapter in babyagi3

Add the Ravi listener and sender to babyagi3’s channel configuration:

# In your babyagi3 main.py or agent setup
from listeners.ravi import listen as ravi_listener
from senders.ravi import RaviSender

agent.register_listener("ravi", ravi_listener)
agent.register_sender("ravi", RaviSender(config))

What This Unlocks

With Ravi as babyagi3’s identity layer, the agent gains:

  • Persistent, accountable identity — the agent’s email and phone survive service changes and API key rotations
  • Native verification handling — when the agent registers for new services as part of its self-improvement loop, Ravi’s inbox and phone handle the verification steps automatically
  • Portable credentials — API keys live in Ravi secrets and travel with the identity, not with a specific machine or OS keyring
  • Multi-agent isolation — run multiple babyagi3 instances, each with its own Ravi identity, with no credential overlap

The yohei community is large and active. A babyagi3 × Ravi integration places Ravi in front of agent builders already thinking seriously about identity for personal assistants.