Skip to content

bot: read-only Telegram / Lark training-ops bot on the dashboard API - #339

Merged
michaellchung merged 1 commit into
mainfrom
pr/ops-bot
Nov 11, 2026
Merged

michaellchung merged 1 commit into
mainfrom
pr/ops-bot

Conversation

@michaellchung

Copy link
Copy Markdown
Contributor

Depends on #337 (stacked on pr/dashboard-sft: the bot reads the sft section of /api/view).

Summary

python -m yeto.bot: a read-only Telegram / Lark (Feishu) training-ops bot. It polls the dashboard's /api/view over HTTP, answers chat commands and pushes tiered alerts; it never connects to nodes or training processes.

Changes

  • Channels behind one interface: Telegram Bot API (long polling), the Lark self-built app bot (tenant token cached and refreshed, interactive cards, chart images, commands and card actions over the lark-oapi long connection when installed) and the Lark group webhook (signed, send-only). Each channel is enabled when its configuration is complete; configuration is environment variables only.
  • Alerts: P0 (stale island, loss NaN/Inf, HBM at the limit, syncer outer step not advancing, OOM / checkpoint-failure / disk hooks; re-notified until acked), P1 (loss spike, grad_norm, missed rounds, HBM / host / syncer memory, rejected or timed-out pushes, eval regression; 1 h cooldown), P2 (checkpoints, new eval point, joins, finished islands). Transitions only, one merged card per poll; held-back alerts are delivered when a mute / quiet hours / cooldown ends if still active.
  • Commands: /status /island /eval /merge /res /ckpt /alerts /ack /details /mute /unmute /help /start; progress card every 2 h and a daily digest (matplotlib charts when installed, text sparklines otherwise).
  • Access control: only the registered report chat may command or press buttons; users are authorized by numeric id (Telegram from.id, Lark open_id), never by display name; registering the chat and anything that changes alerting (/ack, /mute, /unmute, decision presses) require a configured allowlist. Decision cards only record the pressed option in an append-only audit log and execute nothing.
  • YETO_BOT_DRY_RUN=1 prints request bodies instead of calling out; bot and webhook tokens are redacted there and in HTTP errors.

Testing

  • pytest tests/test_bot_app.py tests/test_bot_channels.py tests/test_bot_monitor.py tests/test_dashboard_sft.py: 99 passed, 2 skipped (lark_oapi, matplotlib not installed). Channels are tested against fake HTTP; nothing calls Telegram or Lark.
  • scripts/precommit_check.py: clean (severity names P0/P1/P2 give tag warnings only).

Run locally on macOS arm64, Python 3.11 with the CI install (torch==2.8.0 CPU, -r pyproject.toml --extra test), PYTHONPATH=. python -m pytest ... --timeout=600. Optional stacks that are not installed (Miles, harbor, lark-oapi, matplotlib) skip as on CI.

Notes

  • TELEGRAM_ALLOWED_USERS takes numeric user ids; a non-numeric entry fails at startup rather than silently locking everyone out.
  • View rows are read by the column names the dashboard sends (cols / merge_cols).
  • The P0/P1/P2 severity names trigger the pre-commit tag warning (warning only).

🤖 Generated with Claude Code

@michaellchung
michaellchung deleted the branch pr/dashboard-sft November 9, 2026 05:15
@michaellchung michaellchung reopened this Nov 9, 2026
python -m yeto.bot polls the dashboard's /api/view over HTTP (never ssh,
never the training processes), answers chat commands and pushes tiered
alerts. Configuration is environment variables only.

- Channels behind one interface (send / poll_commands / answer):
  Telegram Bot API with getUpdates long polling, the Lark self-built app
  bot (tenant_access_token cached and refreshed before expiry, im/v1
  messages as interactive cards, im/v1/images for charts, commands and
  card.action.trigger over the lark-oapi long connection when installed)
  and the Lark group webhook (signed, send-only). Each channel is enabled
  when its configuration is complete; Markdown/card sends fall back to
  plain text; long messages are truncated.
- Alerts: P0 (red, mentions the owners, re-notified every 30 min until acked: stale
  island, loss NaN/Inf, HBM peak at the refs limit, syncer outer step not
  advancing past median round + 2 x grace, OOM / checkpoint-failure / disk
  hooks), P1 (orange, 1 h cooldown per subject: loss > mean + 3 sd,
  grad_norm, missed rounds, HBM warn, host memory, syncer RSS, rejected /
  timed-out pushes, eval worse than the previous point) and P2 (grey:
  checkpoints, new eval point, joins, finished islands). Transitions only,
  one merged card per poll with Ack / Details / Open dashboard buttons;
  /ack, /mute, /unmute and quiet hours (P0 only).
- Progress card every 2 h and a daily digest with loss / eval charts
  (matplotlib when installed, text sparklines otherwise).
- Commands: /status /island /eval /merge /res /ckpt /alerts /ack /details
  /mute /unmute /help /start; only the registered report chat may command
  or press buttons. Users are authorized by numeric id (Telegram from.id,
  Lark open_id), never by display name. Registering the report chat with
  /start, and anything that changes alerting (/ack, /mute, /unmute,
  decision presses), needs a configured allowlist; read-only commands do
  not. Commands given through the local --command CLI are trusted.
- Decision-request cards record the pressed option in an append-only JSONL
  audit log and execute nothing. Text that is not a command goes to an
  optional natural-language handler with read-only tools.
- Alerts held back by mute, quiet hours or a cooldown are delivered when
  the hold ends if their condition is still active.
- View rows are read by the column names the dashboard sends; eval
  references are every vs_<name> comparison; the HBM warning line derives
  from the HBM limit.
- YETO_BOT_DRY_RUN=1 prints every request body instead of calling out;
  bot and webhook tokens are redacted from it and from HTTP errors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@michaellchung
michaellchung changed the base branch from pr/dashboard-sft to main November 11, 2026 00:54
@michaellchung
michaellchung merged commit be38ff4 into main Nov 11, 2026
2 checks passed
@michaellchung
michaellchung deleted the pr/ops-bot branch November 11, 2026 00:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant