feat: expose polling configuration in lettabot.yaml (#202)

Add a top-level `polling` section to lettabot.yaml for configuring
background polling (Gmail, etc.) instead of relying solely on env vars.

- Add `PollingYamlConfig` type with `enabled`, `intervalMs`, and `gmail` subsection
- Update `configToEnv()` to map new polling config to env vars
- Update `main.ts` to read from YAML config with env var fallback
- Maintain backward compat with `integrations.google` legacy path
- Document polling config in docs/configuration.md

Fixes #201

Co-authored-by: letta-code <248085862+letta-code@users.noreply.github.com>
Co-authored-by: Cameron <cpfiffer@users.noreply.github.com>
This commit is contained in:
github-actions[bot]
2026-02-07 13:09:05 -08:00
committed by GitHub
parent 9a1fd68b7e
commit 2fe5ebe06d
4 changed files with 93 additions and 11 deletions

View File

@@ -66,6 +66,14 @@ features:
enabled: true
intervalMin: 60
# Polling (background checks for Gmail, etc.)
polling:
enabled: true
intervalMs: 60000 # Check every 60 seconds
gmail:
enabled: true
account: user@example.com
# Voice transcription
transcription:
provider: openai
@@ -181,6 +189,47 @@ features:
Enable scheduled tasks. See [Cron Setup](./cron-setup.md).
## Polling Configuration
Background polling for integrations like Gmail. Runs independently of agent cron jobs.
```yaml
polling:
enabled: true # Master switch (default: auto-detected from sub-configs)
intervalMs: 60000 # Check every 60 seconds (default: 60000)
gmail:
enabled: true
account: user@example.com # Gmail account to poll
```
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `polling.enabled` | boolean | auto | Master switch. Defaults to `true` if any sub-config is enabled |
| `polling.intervalMs` | number | `60000` | Polling interval in milliseconds |
| `polling.gmail.enabled` | boolean | auto | Enable Gmail polling. Auto-detected from `account` |
| `polling.gmail.account` | string | - | Gmail account to poll for unread messages |
### Legacy config path
For backward compatibility, Gmail polling can also be configured under `integrations.google`:
```yaml
integrations:
google:
enabled: true
account: user@example.com
pollIntervalSec: 60
```
The top-level `polling` section takes priority if both are present.
### Environment variable fallback
| Env Variable | Polling Config Equivalent |
|--------------|--------------------------|
| `GMAIL_ACCOUNT` | `polling.gmail.account` |
| `POLLING_INTERVAL_MS` | `polling.intervalMs` |
## Transcription Configuration
Voice message transcription via OpenAI Whisper:
@@ -223,5 +272,7 @@ Environment variables override config file values:
| `WHATSAPP_SELF_CHAT_MODE` | `channels.whatsapp.selfChat` |
| `SIGNAL_PHONE_NUMBER` | `channels.signal.phone` |
| `OPENAI_API_KEY` | `transcription.apiKey` |
| `GMAIL_ACCOUNT` | `polling.gmail.account` |
| `POLLING_INTERVAL_MS` | `polling.intervalMs` |
See [SKILL.md](../SKILL.md) for complete environment variable reference.

View File

@@ -169,11 +169,19 @@ export function configToEnv(config: LettaBotConfig): Record<string, string> {
env.MAX_TOOL_CALLS = String(config.features.maxToolCalls);
}
// Integrations - Google (Gmail polling)
if (config.integrations?.google?.enabled && config.integrations.google.account) {
// Polling - top-level polling config (preferred)
if (config.polling?.gmail?.enabled && config.polling.gmail.account) {
env.GMAIL_ACCOUNT = config.polling.gmail.account;
}
if (config.polling?.intervalMs) {
env.POLLING_INTERVAL_MS = String(config.polling.intervalMs);
}
// Integrations - Google (legacy path for Gmail polling, lower priority)
if (!env.GMAIL_ACCOUNT && config.integrations?.google?.enabled && config.integrations.google.account) {
env.GMAIL_ACCOUNT = config.integrations.google.account;
}
if (config.integrations?.google?.pollIntervalSec) {
if (!env.POLLING_INTERVAL_MS && config.integrations?.google?.pollIntervalSec) {
env.POLLING_INTERVAL_MS = String(config.integrations.google.pollIntervalSec * 1000);
}

View File

@@ -46,7 +46,12 @@ export interface LettaBotConfig {
maxToolCalls?: number; // Abort if agent calls this many tools in one turn (default: 100)
};
// Polling - system-level background checks (Gmail, etc.)
polling?: PollingYamlConfig;
// Integrations (Google Workspace, etc.)
// NOTE: integrations.google is a legacy path for polling config.
// Prefer the top-level `polling` section instead.
integrations?: {
google?: GoogleConfig;
};
@@ -74,6 +79,15 @@ export interface TranscriptionConfig {
model?: string; // Defaults to 'whisper-1'
}
export interface PollingYamlConfig {
enabled?: boolean; // Master switch (default: auto-detected from sub-configs)
intervalMs?: number; // Polling interval in milliseconds (default: 60000)
gmail?: {
enabled?: boolean; // Enable Gmail polling
account?: string; // Gmail account to poll (e.g., user@example.com)
};
}
export interface ProviderConfig {
id: string; // e.g., 'anthropic', 'openai'
name: string; // e.g., 'lc-anthropic'

View File

@@ -287,15 +287,24 @@ const config = {
},
// Polling - system-level background checks
polling: {
enabled: !!process.env.GMAIL_ACCOUNT, // Enable if any poller is configured
intervalMs: parseInt(process.env.POLLING_INTERVAL_MS || '60000', 10), // Default 1 minute
// Priority: YAML polling section > YAML integrations.google (legacy) > env vars
polling: (() => {
const gmailAccount = yamlConfig.polling?.gmail?.account
|| process.env.GMAIL_ACCOUNT || '';
const gmailEnabled = yamlConfig.polling?.gmail?.enabled ?? !!gmailAccount;
const intervalMs = yamlConfig.polling?.intervalMs
?? parseInt(process.env.POLLING_INTERVAL_MS || '60000', 10);
const enabled = yamlConfig.polling?.enabled ?? gmailEnabled;
return {
enabled,
intervalMs,
gmail: {
enabled: !!process.env.GMAIL_ACCOUNT,
account: process.env.GMAIL_ACCOUNT || '',
},
enabled: gmailEnabled,
account: gmailAccount,
},
};
})(),
};
// Validate at least one channel is configured
if (!config.telegram.enabled && !config.slack.enabled && !config.whatsapp.enabled && !config.signal.enabled && !config.discord.enabled) {