* Fix CLI group settings handling
* Document group settings in config
* fix: move group settings below channel list in README, add GROUP_DEBOUNCE_SEC env var
- README: group settings section was splitting the cross-channel bullet
list; moved it after the channel table
- onboard.ts: groupDebounceSec had no env var override for non-interactive
deploys; added <CHANNEL>_GROUP_DEBOUNCE_SEC for all 5 channels
- SKILL.md: documented the new env var
Written by Cameron and Letta Code
"For every complex problem there is an answer that is clear, simple, and wrong." - H.L. Mencken
---------
Co-authored-by: Jason Carreira <jason@visotrust.com>
Co-authored-by: Cameron <cameron@pfiffer.org>
* Add lettabot-history CLI
* Document and test lettabot-history
* Validate lettabot-history limit
* fix: address review feedback on history CLI
- Extract shared loadLastTarget into cli/shared.ts (was duplicated in message.ts, react.ts, history-core.ts)
- Clamp --limit to platform maximums (Discord: 100, Slack: 1000)
- Fix Discord author formatting: use globalName/username instead of deprecated discriminator
- Add Slack fetch test
Written by Cameron ◯ Letta Code
"You miss 100% of the shots you don't take." -- Wayne Gretzky -- Michael Scott
---------
Co-authored-by: Jason Carreira <jason@visotrust.com>
Co-authored-by: Cameron <cameron@pfiffer.org>
* fix: telegram ESM compatibility and improved diagnostics
- Replace telegram-markdown-v2 with telegramify-markdown (ESM compatible)
- Add raw text fallback when Telegram formatting fails, with error notice
- Improve empty response diagnostics: log agent ID, show conversation ID
- Add reset-conversation command hint to user messages
- Add telegram-format.test.ts with 7 tests
Fixes Railway deployment ERR_REQUIRE_ESM error with remark package.
Written by Cameron and Letta Code
"The best error message is the one that never shows up." - Thomas Fuchs
* fix: add npm overrides for keyv resolution
Users were still hitting ERR_MODULE_NOT_FOUND for keyv even after
PR #154 added it as a direct dependency. This happens because npm's
hoisting doesn't always resolve peer deps of optional deps properly.
npm overrides force the package manager to use our root keyv version
for all nested references, which is the idiomatic solution for
transitive peer dependency issues.
Also adds troubleshooting entry to README.
Written by Cameron ◯ Letta Code
"The best error message is the one that never shows up."
- Thomas Fuchs
Users were confused why selfhosted mode still required an API key.
The validation check now properly skips the API key requirement when
server.mode is 'selfhosted'.
Also adds comprehensive selfhosted-setup.md guide covering:
- Letta Docker server setup
- Network configuration (Docker, remote servers)
- Troubleshooting (connection refused, stuck agent, tool approvals)
- Running as a service (systemd, launchd)
- Hardware requirements
Thanks to oculairthebear for the community guide that inspired this.
Written by Cameron and Letta Code
"I've learned that people will forget what you said, people will forget
what you did, but people will never forget how you made them feel."
- Maya Angelou
E2E testing infrastructure that tests the full message flow against a real Letta Cloud agent.
Changes:
- Add MockChannelAdapter for simulating inbound/outbound messages
- Add e2e/bot.e2e.test.ts with 4 e2e tests:
- Simple message/response
- /status command
- /help command
- Conversation context retention
- Add 'mock' to ChannelId type
- Update CI workflow with separate e2e job (uses secrets)
- Add npm run test:e2e script
E2E tests require:
- LETTA_API_KEY (already in repo secrets)
- LETTA_E2E_AGENT_ID (needs to be added)
E2E tests are skipped locally without these env vars.
Written by Cameron ◯ Letta Code
"Trust, but verify." - Ronald Reagan (on e2e testing)
Auto-detect RAILWAY_VOLUME_MOUNT_PATH and use it for all persistent data
(agent ID, cron jobs, logs). On local machines, data stays in project
directory. Template now includes volume by default.
- Add src/utils/paths.ts with getDataDir() and getWorkingDir() helpers
- Update Store, cron service, CLI tools to use data directory
- Log storage locations on startup for debugging
- Update deploy button URLs with UTM tracking
Written by Cameron ◯ Letta Code
"The best way to predict the future is to invent it." - Alan Kay
* feat: add Railway deployment support with agent auto-discovery
- Add railway.toml for build/deploy config with health checks
- Skip config file requirement when RAILWAY_ENVIRONMENT detected
- Auto-discover existing agent by name on container deploys
- Add findAgentByName() API function for agent lookup
- Add setAgentId() method to LettaBot class
- Add comprehensive Railway deployment docs
One-click deploy flow:
1. Set LETTA_API_KEY + channel tokens
2. LettaBot finds existing agent by AGENT_NAME (default: "LettaBot")
3. If not found, creates on first message
4. Subsequent deploys auto-reconnect to same agent
Written by Cameron ◯ Letta Code
"The best way to predict the future is to deploy it." - Railway, probably
* fix: specify Node 22 for Railway deployment
* fix: fail fast if LETTA_API_KEY is missing
* fix: don't await Telegram bot.start() - it never resolves
* fix: extract message from send_message tool call
* Revert "fix: extract message from send_message tool call"
This reverts commit 370306e49de3728434352d2df1b78c744e888833.
* fix: clear LETTA_AGENT_ID env var when agent doesn't exist
* docs: add Railway deploy button to README and docs
* fix: .nvmrc newline and correct MODEL default in docs
Fixes and updates:
- README.md: Remove duplicate heartbeat troubleshooting section
- docs/getting-started.md: Fix Node version (18→20), commands, repo URL
- docs/commands.md: Rewrite with accurate command list (/start, /status, /heartbeat)
- docs/README.md: New multi-channel architecture diagram
- docs/whatsapp-setup.md: Add selfChatMode safety docs, media support section
- docs/slack-setup.md: Fix broken links
New documentation:
- docs/configuration.md: Complete YAML config reference
- docs/cron-setup.md: Scheduling guide (cron jobs + heartbeats)
Written by Cameron ◯ Letta Code
"Documentation is a love letter that you write to your future self." - Damian Conway
Adds documentation to help users understand why their agent's responses
during heartbeats/cron jobs aren't being delivered to their chat channels.
- Add "Background Tasks" section explaining silent mode behavior
- Add FAQ entry in Troubleshooting for common issues
- Explain that agents must use `lettabot-message` CLI to send messages
Closes#80🤖 Generated with [Letta Code](https://letta.com)
Co-authored-by: Letta <noreply@letta.com>
* Add voice message transcription support (all channels)
Adds OpenAI Whisper transcription for voice messages across all channels:
- Telegram: ctx.message.voice
- WhatsApp: audioMessage via downloadMediaMessage
- Signal: audio attachments from local files
- Slack: audio files via url_private_download
- Discord: audio attachments
Voice messages sent to agent as "[Voice message]: <transcript>"
Configuration (config takes priority over env):
- lettabot.yaml: transcription.apiKey, transcription.model
- Env: OPENAI_API_KEY, TRANSCRIPTION_MODEL
Closes#47
Written by Cameron ◯ Letta Code
"The best interface is no interface - just talk."
* Add voice message documentation to README
- Add Voice Messages to features list
- Add configuration section for transcription
- Document supported channels
Written by Cameron ◯ Letta Code
* Notify users when voice transcription is not configured
Instead of silently ignoring voice messages, send a helpful message
linking to the documentation.
Written by Cameron ◯ Letta Code
* feat: upgrade to letta-code-sdk main + fix Signal voice transcription
- Switch from published SDK (v0.0.3) to local main branch (file:../letta-code-sdk)
- Update bot.ts for new SDK API: createSession(agentId?, options) signature
- Add conversationId tracking to store for proper conversation persistence
- Fix Signal voice transcription: read attachments from ~/.local/share/signal-cli/attachments/
- Fix Telegram markdown ESM issue: make markdownToTelegramV2 async with dynamic import
- Add transcription config to lettabot.yaml
- Add extensive debug logging for queue and session processing
Signal voice messages now properly transcribe and send to agent.
🐾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta <noreply@letta.com>
* fix: update Signal CLI message sender to use daemon JSON-RPC API
- Switch from signal-cli-rest-api to signal-cli daemon (port 8090)
- Use JSON-RPC send method instead of REST /v2/send
- Support group IDs with group: prefix
- Handle 201 responses and empty bodies correctly
🐾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta <noreply@letta.com>
* Add placeholder for untranscribed voice messages on Signal
If a voice-only message arrives and transcription fails or is disabled,
forward a placeholder so the user knows the message was received.
Written by Cameron ◯ Letta Code
---------
Co-authored-by: Letta <noreply@letta.com>
* feat: add non-interactive onboarding and SKILL.md
Add agent-friendly setup flow:
- lettabot onboard --non-interactive flag
- Reads all config from environment variables
- SKILL.md documents env-based setup for agents
- Supports all channels (Telegram, Slack, Discord, WhatsApp, Signal)
- No prompts - ideal for coding agents automating setup
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta <noreply@letta.com>
* fix: address non-interactive setup issues
- Add SLACK_APP_NAME for customizable app name (defaults to LETTA_AGENT_NAME or LettaBot)
- Clarify WhatsApp requires WHATSAPP_ENABLED and WHATSAPP_SELF_CHAT to be explicit
- Document all 5 channels supported (Telegram, Slack, Discord, WhatsApp, Signal)
- Fix WhatsApp selfChat default to be explicit false
* docs: recommend non-interactive setup as primary method
Update README per review feedback to show env-based setup first.
This is simpler for most users and ideal for automation.
* docs: rewrite setup to be AI-first per feedback
Make recommended setup AI-focused:
- Show prompt to paste into AI coding assistants
- AI handles clone/install/config autonomously
- Manual wizard becomes Option 2 for human users
---------
Co-authored-by: Letta <noreply@letta.com>
Documents how to install and enable the homeassistant skill from ClawdHub.
The skill sync workflow already supports this - just needed documentation.
🐙 Generated with [Letta Code](https://letta.com)
Co-authored-by: Letta <noreply@letta.com>