diff --git a/README.md b/README.md index a5f714b..d4d5dba 100644 --- a/README.md +++ b/README.md @@ -326,6 +326,8 @@ Check the [ADE](https://app.letta.com) to see if your agent is attempting to use ## Documentation - [Getting Started](docs/getting-started.md) +- [Self-Hosted Setup](docs/selfhosted-setup.md) - Run with your own Letta server +- [Configuration Reference](docs/configuration.md) - [Slack Setup](docs/slack-setup.md) - [Discord Setup](docs/discord-setup.md) - [WhatsApp Setup](docs/whatsapp-setup.md) diff --git a/docs/README.md b/docs/README.md index 7471a74..8a9b1cb 100644 --- a/docs/README.md +++ b/docs/README.md @@ -5,10 +5,12 @@ LettaBot is a multi-channel AI assistant powered by [Letta](https://letta.com) t ## Guides - [Getting Started](./getting-started.md) - Installation and basic setup +- [Self-Hosted Setup](./selfhosted-setup.md) - Run with your own Letta server - [Configuration Reference](./configuration.md) - All config options - [Commands Reference](./commands.md) - Bot commands reference - [Scheduling Tasks](./cron-setup.md) - Cron jobs and heartbeats - [Gmail Pub/Sub](./gmail-pubsub.md) - Email notifications integration +- [Railway Deployment](./railway-deploy.md) - Deploy to Railway ### Channel Setup - [Telegram Setup](./telegram-setup.md) - BotFather token setup diff --git a/docs/selfhosted-setup.md b/docs/selfhosted-setup.md new file mode 100644 index 0000000..79febdd --- /dev/null +++ b/docs/selfhosted-setup.md @@ -0,0 +1,309 @@ +# Self-Hosted Letta Server Setup + +Run LettaBot with your own Letta server instead of Letta Cloud. + +## Prerequisites + +1. **Docker** installed and running +2. **Node.js 20+** for LettaBot +3. **API keys** for your LLM provider (OpenAI, Anthropic, etc.) + +## Step 1: Start Letta Server + +```bash +docker run -d \ + --name letta-server \ + -v ~/.letta/.persist/pgdata:/var/lib/postgresql/data \ + -p 8283:8283 \ + -e OPENAI_API_KEY="sk-..." \ + letta/letta:latest +``` + +For Anthropic models: +```bash +docker run -d \ + --name letta-server \ + -v ~/.letta/.persist/pgdata:/var/lib/postgresql/data \ + -p 8283:8283 \ + -e ANTHROPIC_API_KEY="sk-ant-..." \ + letta/letta:latest +``` + +Verify it's running: +```bash +curl http://localhost:8283/v1/health +``` + +## Step 2: Configure LettaBot + +### Option A: Interactive Setup (Recommended) + +```bash +lettabot onboard +``` + +Select "Enter self-hosted URL" and enter `http://localhost:8283`. + +### Option B: Manual Configuration + +Create `lettabot.yaml`: + +```yaml +server: + mode: selfhosted + baseUrl: http://localhost:8283 + # apiKey: optional-if-server-requires-auth + +agent: + name: LettaBot + model: gpt-4o # Or claude-sonnet-4, etc. + +channels: + telegram: + enabled: true + token: YOUR_TELEGRAM_BOT_TOKEN # From @BotFather + dmPolicy: pairing # pairing | allowlist | open + +features: + cron: false + heartbeat: + enabled: false +``` + +## Step 3: Start LettaBot + +```bash +lettabot server +``` + +You should see: +``` +[Config] Loaded from /path/to/lettabot.yaml +[Config] Mode: selfhosted, Agent: LettaBot, Model: gpt-4o +Starting LettaBot... +LettaBot initialized. Agent ID: (new) +[Telegram] Bot started as @YourBotName +``` + +## Network Configuration + +### Remote Server + +If your Letta server is on a different machine: + +```yaml +server: + baseUrl: http://192.168.1.100:8283 +``` + +### Docker to Docker + +If LettaBot runs in Docker and needs to reach Letta server on the host: + +```yaml +server: + baseUrl: http://host.docker.internal:8283 +``` + +### Docker Compose + +```yaml +services: + letta: + image: letta/letta:latest + ports: + - "8283:8283" + volumes: + - letta-data:/var/lib/postgresql/data + environment: + - OPENAI_API_KEY=${OPENAI_API_KEY} + + lettabot: + build: . + depends_on: + - letta + environment: + - LETTA_BASE_URL=http://letta:8283 + volumes: + - ./lettabot.yaml:/app/lettabot.yaml + - ./lettabot-agent.json:/app/lettabot-agent.json + +volumes: + letta-data: +``` + +## Troubleshooting + +### Connection Refused + +``` +Error: connect ECONNREFUSED 127.0.0.1:8283 +``` + +**Fix:** Ensure Letta server is running: +```bash +docker ps | grep letta +curl http://localhost:8283/v1/health +``` + +### Agent Stuck / Not Responding + +If the bot hangs after sending a message: + +**1. Check for pending tool approvals** + +Some tools may have `requires_approval: true` set. LettaBot disables these on startup, but check: + +```bash +# List tools and their approval status +curl http://localhost:8283/v1/agents/YOUR_AGENT_ID/tools | jq '.[].requires_approval' + +# Disable approval for a specific tool +curl -X PATCH http://localhost:8283/v1/tools/TOOL_ID \ + -H "Content-Type: application/json" \ + -d '{"requires_approval": null}' +``` + +**2. Invalid conversation ID** + +If the conversation was deleted but LettaBot still references it: + +```bash +# Clear the stored conversation (keeps agent) +cat lettabot-agent.json | jq 'del(.conversationId)' > tmp.json && mv tmp.json lettabot-agent.json + +# Restart +lettabot server +``` + +**3. Check server logs** + +```bash +docker logs letta-server --tail 100 +``` + +### Model Not Available + +``` +Error: Model 'claude-sonnet-4' not found +``` + +Ensure you set the correct API key when starting Letta server: +- OpenAI models: `-e OPENAI_API_KEY="sk-..."` +- Anthropic models: `-e ANTHROPIC_API_KEY="sk-ant-..."` + +### Reset Everything + +```bash +# Remove LettaBot state +rm lettabot-agent.json + +# Remove Letta server data (WARNING: deletes all agents) +docker stop letta-server +docker rm letta-server +rm -rf ~/.letta/.persist/pgdata + +# Restart fresh +docker run ... (same command as before) +lettabot server +``` + +## Running as a Service + +### systemd (Linux) + +Create `/etc/systemd/system/lettabot.service`: + +```ini +[Unit] +Description=LettaBot - Multi-channel AI Assistant +After=network.target docker.service +Wants=docker.service + +[Service] +Type=simple +User=your-user +WorkingDirectory=/path/to/lettabot +ExecStart=/usr/bin/npx lettabot server +Restart=on-failure +RestartSec=10 +Environment=NODE_ENV=production + +[Install] +WantedBy=multi-user.target +``` + +```bash +sudo systemctl daemon-reload +sudo systemctl enable lettabot +sudo systemctl start lettabot + +# View logs +journalctl -u lettabot -f +``` + +### launchd (macOS) + +Create `~/Library/LaunchAgents/com.lettabot.plist`: + +```xml + + + + + Label + com.lettabot + ProgramArguments + + /usr/local/bin/npx + lettabot + server + + WorkingDirectory + /path/to/lettabot + RunAtLoad + + KeepAlive + + StandardOutPath + /tmp/lettabot.log + StandardErrorPath + /tmp/lettabot.err + + +``` + +```bash +launchctl load ~/Library/LaunchAgents/com.lettabot.plist + +# View logs +tail -f /tmp/lettabot.log +``` + +## Hardware Requirements + +**Minimum for LettaBot itself:** +- 512MB RAM, 1 CPU core +- LettaBot is lightweight - the heavy lifting is done by Letta server + +**For Letta server with cloud LLMs (OpenAI/Anthropic):** +- 2GB RAM, 2 CPU cores +- No GPU required (LLM runs in the cloud) + +**For local LLM inference (e.g., Ollama):** +- 16GB+ system RAM for 7B models +- 48GB+ for 70B models +- GPU recommended: 8GB+ VRAM for 7B, 48GB+ for larger + +## Security Considerations + +1. **Network exposure**: Don't expose port 8283 to the internet without authentication +2. **API keys**: Keep your `.env` and `lettabot.yaml` out of version control +3. **Tool permissions**: Review which tools your agent has access to (Bash can execute arbitrary commands) +4. **DM policy**: Use `pairing` (default) to require approval for new users + +## Getting Help + +- [GitHub Issues](https://github.com/letta-ai/lettabot/issues) +- [Letta Documentation](https://docs.letta.com) +- [Letta Discord](https://discord.gg/letta) diff --git a/src/main.ts b/src/main.ts index a4382b6..6697259 100644 --- a/src/main.ts +++ b/src/main.ts @@ -304,10 +304,11 @@ if (!config.telegram.enabled && !config.slack.enabled && !config.whatsapp.enable process.exit(1); } -// Validate LETTA_API_KEY is set for cloud mode -if (!process.env.LETTA_API_KEY) { - console.error('\n Error: LETTA_API_KEY is required.'); - console.error(' Get your API key from https://app.letta.com and set it as an environment variable.\n'); +// Validate LETTA_API_KEY is set for cloud mode (selfhosted mode doesn't require it) +if (yamlConfig.server.mode !== 'selfhosted' && !process.env.LETTA_API_KEY) { + console.error('\n Error: LETTA_API_KEY is required for Letta Cloud.'); + console.error(' Get your API key from https://app.letta.com and set it as an environment variable.'); + console.error(' Or use selfhosted mode: run "lettabot onboard" and select "Enter self-hosted URL".\n'); process.exit(1); }