Adds features.memfs config key that controls whether the Letta Code CLI
receives --memfs or --no-memfs when creating/resuming SDK sessions. This
enables lettabot users to opt into git-backed memory filesystem (context
repositories) for persistent local memory sync.
- Config types: memfs?: boolean on AgentConfig.features, LettaBotConfig.features, BotConfig
- Bot wiring: baseSessionOptions() and createAgent() pass memfs to SDK when defined
- Main wiring: YAML config takes precedence, LETTABOT_MEMFS env var as fallback
- Legacy fix: conversations passthrough in single-agent normalization
- Tests: 3 memfs wiring tests (true/false/undefined), 2 conversations passthrough tests
- Docs: configuration.md section with known limitations, example YAML
Fixes#335
Written by Cameron and Letta Code
"The best way to predict the future is to implement it." -- David Heinemeier Hansson
Consolidates listeningGroups and groups.requireMention into a single
groups config with explicit mode per group. Backward compatible --
legacy formats auto-normalize with deprecation warnings.
- Add shared group-mode.ts with isGroupAllowed/resolveGroupMode helpers
- Update all 5 channel adapters to use mode-based gating
- Default to mention-only for configured entries (safe), open when no config
- Listening mode now set at adapter level, bot.ts has legacy fallback
- Fix YAML large-ID parsing for groups map keys (Discord snowflakes)
- Add migration in normalizeAgents for listeningGroups + requireMention
- Add unit tests for group-mode helpers + update all gating tests
- Update docs, README, and example config
Closes#266
Written by Cameron and Letta Code
"Perfection is achieved not when there is nothing more to add, but when there is nothing left to take away." -- Antoine de Saint-Exupery
* feat: default new configs to multi-agent format
Onboarding and non-interactive config generation now emit the
agents[] array format instead of the legacy agent/channels/features
flat structure. This makes adding a second agent a simple array
append rather than a config format migration.
Existing legacy configs continue to work -- normalizeAgents()
handles both formats at runtime.
Written by Cameron and Letta Code
"The future is already here -- it's just not very evenly distributed." -- William Gibson
* test: add save/load roundtrip tests for agents[] config format
Tests the actual YAML serialization path:
- agents[] written without legacy agent/channels at top level
- roundtrip through save + load + normalizeAgents preserves all fields
- global fields (providers, transcription) stay at top level
Written by Cameron and Letta Code
"Programs must be written for people to read, and only incidentally for machines to execute." -- Abelson & Sussman
* feat: eagerly create agent during onboarding
When the user picks "Create new agent", the agent is now created
immediately (with spinner) rather than deferred to first message.
The agent ID is written directly to lettabot.yaml, making the
config file the single source of truth.
Creates the agent with system prompt, memory blocks, selected model,
display name, skills, and disables tool approvals -- same setup that
bot.ts previously did lazily on first message.
Graceful fallback: if creation fails, falls back to lazy creation.
Written by Cameron and Letta Code
"Make it work, make it right, make it fast." -- Kent Beck
Add optional displayName field to agent config. When set, outbound
agent responses are prefixed (e.g. "💜 Signo: Hello!").
Useful in multi-agent group chats where multiple bots share a channel
and users need to tell them apart.
Closes#252
Written by Cameron ◯ Letta Code
"The details are not the details. They make the design." -- Charles Eames
normalizeAgents() env var fallback (added in #224) only mapped token
and dmPolicy, missing allowedUsers for all channels. This caused
dmPolicy=allowlist to reject everyone since the allowlist was empty.
Parses *_ALLOWED_USERS env vars (comma-separated) for all five
channels, matching the existing format used by onboard.ts and the
Railway env exporter.
Written by Cameron ◯ Letta Code
"We can only see a short distance ahead, but we can see plenty there that needs to be done." -- Alan Turing
normalizeAgents() only read YAML config, breaking Railway/Docker
deploys where channels are configured via environment variables
(TELEGRAM_BOT_TOKEN, etc.). Add env var fallback in the legacy
single-agent path.
Multi-agent mode still requires YAML configuration.
Written by Cameron ◯ Letta Code
"The cheapest, fastest, and most reliable components are those that aren't there." -- Gordon Bell
* feat: add multi-agent config types, normalizeAgents, and Store v2
Foundation for multi-agent support (Phase 1a). No behavioral changes.
- Add AgentConfig interface for per-agent configuration
- Add agents[] field to LettaBotConfig for docker-compose style multi-agent configs
- Add normalizeAgents() to convert legacy single-agent config to agents[] array
- Evolve Store to v2 format with per-agent state isolation
- Auto-migrate v1 store files to v2 transparently
- 18 new tests for normalization and store migration
Part of #109
Written by Cameron ◯ Letta Code
"The only way to do great work is to love what you do." -- Steve Jobs
* fix: harden multi-agent normalization and store isolation
* style: simplify redundant WhatsApp enabled check
WhatsApp has no credential to check (uses QR pairing), so the
`enabled !== false && enabled` condition simplifies to just `enabled`.
Written by Cameron ◯ Letta Code
"Perfection is achieved not when there is nothing more to add, but when there is nothing left to take away." -- Antoine de Saint-Exupery