Skip to content

Commit 2f9c7a2

Browse files
committed
docs: cron integration with --deliver flag
- CLI.md: add --deliver to run flags table + examples - CONFIG.md: add Telegram config section with default_chat_id - TELEGRAM.md: add Cron Integration section (prerequisites, setup, debugging, config reference)
1 parent 76f4478 commit 2f9c7a2

3 files changed

Lines changed: 150 additions & 1 deletion

File tree

docs/CLI.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
| `--max-iter <n>` | int | `90` | Max think→act cycles |
3838
| `--thinking <level>` | string | profile default | Reasoning depth: `enabled`/`disabled`/`low`/`medium`/`high` |
3939
| `--sandbox` | bool | false | Execute shell commands inside Docker container |
40+
| `--deliver` | bool | false | Deliver the agent's final response to the configured Telegram `default_chat_id`. Requires `telegram.bot_token` + `telegram.default_chat_id` in config. Use with cron for scheduled agent tasks. |
4041
| `--interaction-mode <mode>` | string | `engaging` | Tool-call rendering: `engaging` (emoji narration) or `verbose` (raw tool output) |
4142
| `--no-color` | bool | false | Disable colored terminal output |
4243
| `--prompt-caching` | bool | false | Enable Anthropic/OpenAI/DeepSeek prompt caching markers |
@@ -324,7 +325,14 @@ odek run "Set up CI with GitHub Actions"
324325
# File attachments
325326
odek run --ctx go.mod "check go version"
326327
odek run -c main.go,util.go "refactor both files"
327-
odek run "@schema.sql design a migration plan"
328+
odek run "&#64;schema.sql design a migration plan"
329+
330+
# Cron integration: deliver agent result to Telegram
331+
odek run --deliver "Daily weather forecast for Berlin"
332+
odek run --deliver "Check the CI pipeline status"
333+
334+
# Systemd cron example (crontab -e):
335+
# */5 * * * * /usr/local/bin/odek run "Say hello" --deliver >> /tmp/odek-cron.log 2>&1
328336
```
329337

330338
## Config priority

docs/CONFIG.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,56 @@ and are available in `odek run`, `odek repl`, `odek continue`, and `odek serve`.
272272

273273
See [docs/MCP.md](docs/MCP.md#odek-as-mcp-client) for detailed instructions.
274274

275+
## Telegram
276+
277+
The `telegram` section configures the Telegram bot integration and the `--deliver` flag.
278+
279+
```json
280+
{
281+
"telegram": {
282+
"bot_token": "8610437446:AAElHFJ...",
283+
"allowed_users": [8592463065],
284+
"allowed_chats": [],
285+
"poll_interval": 1,
286+
"poll_timeout": 30,
287+
"max_msg_length": 4096,
288+
"session_ttl_hours": 24,
289+
"log_level": "info",
290+
"log_file": "",
291+
"default_chat_id": 8592463065
292+
}
293+
}
294+
```
295+
296+
| Field | Env var | Default | Description |
297+
|-------|---------|---------|-------------|
298+
| `bot_token` | `ODEK_TELEGRAM_BOT_TOKEN` | — (required) | Telegram bot API token from @BotFather |
299+
| `allowed_users` || all | Restrict bot to specific user IDs |
300+
| `allowed_chats` || all | Restrict bot to specific chat IDs |
301+
| `poll_interval` || 1 | Seconds between poll cycles |
302+
| `poll_timeout` || 30 | Long-poll timeout (1-60 seconds) |
303+
| `max_msg_length` || 4096 | Max characters per message |
304+
| `session_ttl_hours` || 24 | Hours before inactive session expires |
305+
| `log_level` || info | Log level: debug, info, warn, error |
306+
| `log_file` || stderr | Log file path (empty = stderr) |
307+
| `default_chat_id` || 0 | **Required for `--deliver`** — numeric chat ID where `odek run --deliver` sends results. Get this from your bot's update or use a tool like `@userinfobot`. |
308+
309+
### --deliver flag
310+
311+
The `--deliver` flag on `odek run` sends the agent's final response to the configured
312+
`default_chat_id` as a plain text message. This enables **cron-based scheduled agent
313+
workflows** — no daemon needed.
314+
315+
```bash
316+
# Run an agent task and deliver the result to Telegram
317+
odek run --deliver "Check the CI pipeline status"
318+
319+
# Works with task text first too
320+
odek run "Daily summary" --deliver
321+
```
322+
323+
See [docs/TELEGRAM.md](docs/TELEGRAM.md#cron-integration) for full cron setup instructions.
324+
275325
## odek init
276326

277327
Create a config file template:

docs/TELEGRAM.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,97 @@ This avoids binary overwrite races, stale HTTP/2 connections, and session contex
378378

379379
A fire-and-forget goroutine sends `sendChatAction("typing")` every 4 seconds while the agent runs. Each API call is dispatched in its own goroutine so a slow or hanging HTTP call cannot block the ticker and permanently stop the indicator.
380380

381+
## Cron Integration
382+
383+
odek can run fully offline agent tasks and deliver the result to Telegram, enabling system cron-based scheduled agent workflows — no daemon or scheduler required.
384+
385+
### How it works
386+
387+
```
388+
cron daemon ──[every N minutes]──► odek run "<task>" --deliver
389+
390+
┌──────┴──────┐
391+
│ agent loop │
392+
│ (no daemon) │
393+
└──────┬──────┘
394+
│ result text
395+
396+
Telegram API
397+
398+
┌──────┴──────┐
399+
│ your chat │
400+
└─────────────┘
401+
```
402+
403+
Each cron tick spawns an independent `odek run` process. The agent executes the task, produces a result, and exits. The `--deliver` flag sends the result to your configured Telegram chat as a plain text message. No persistent bot process, no long-polling — just a single agent run per tick.
404+
405+
### Prerequisites
406+
407+
1. **Telegram bot token** and **default chat ID** must be configured in `~/.odek/config.json`:
408+
409+
```json
410+
{
411+
"telegram": {
412+
"bot_token": "8610437446:AAElHFJ...",
413+
"default_chat_id": 8592463065
414+
}
415+
}
416+
```
417+
418+
2. **Verify delivery works** before setting up cron:
419+
420+
```bash
421+
odek run "Say hello" --deliver
422+
```
423+
424+
If no message arrives, check:
425+
- The bot token is valid (`curl https://api.telegram.org/bot<TOKEN>/getMe`)
426+
- The `default_chat_id` is correct (the numeric chat ID, not the username)
427+
- The binary is at a stable path (system cron uses a minimal PATH, so use the full path)
428+
429+
### Setting up a cron job
430+
431+
```bash
432+
# Edit your crontab
433+
crontab -e
434+
435+
# Add a job — runs every 5 minutes
436+
*/5 * * * * /usr/local/bin/odek run "Say hello briefly" --deliver >> /tmp/odek-cron.log 2>&1
437+
```
438+
439+
**Important:**
440+
- Use the **full absolute path** to the `odek` binary — cron runs with a minimal `PATH`
441+
- Always redirect stderr to a log file (`2>&1`) for debugging
442+
- Place `--deliver` **before** the task text, or anywhere after it (both work)
443+
- The agent runs in **single-shot mode** by default — no session persistence, no learning loop
444+
- Each cron tick is a fully independent agent invocation with no memory of previous runs
445+
446+
### Debugging
447+
448+
If messages don't arrive:
449+
450+
```bash
451+
# 1. Verify the binary works standalone
452+
/usr/local/bin/odek run "test" --deliver
453+
454+
# 2. Check cron's stderr log
455+
cat /tmp/odek-cron.log
456+
457+
# 3. Confirm Telegram API is reachable from cron's environment
458+
# Add to crontab to test:
459+
# * * * * * curl -s "https://api.telegram.org/bot<TOKEN>/getMe" >> /tmp/telegram-test.log 2>&1
460+
461+
# 4. Check that the config file is readable by cron's user
462+
ls -la ~/.odek/config.json
463+
```
464+
465+
### Config reference
466+
467+
| Config field | Env var | Description |
468+
|---|---|---|
469+
| `telegram.bot_token` | `ODEK_TELEGRAM_BOT_TOKEN` | Telegram bot API token (required) |
470+
| `telegram.default_chat_id` || Numeric chat ID to deliver results to (required) |
471+
381472
## Testing
382473

383474
The Telegram package has **473 tests** with **87.1% coverage**. Tests use:

0 commit comments

Comments
 (0)