feat(notifications): add webhook and email notification support #118

Merged
fuzzy merged 2 commits from feature/0071-add-webhook-notification-support into main 2026-07-05 15:53:22 +00:00
Owner

What

Add webhook and email notification support for job completion events. Webhooks POST JSON payloads to a configurable URL. Email alerts send via SMTP with TLS and optional auth.

Why

Users need to be notified when jobs complete or fail, either via webhook integration or email.

Testing

  • 145 unit tests pass (11 new for notifications)
  • Pre-commit hooks pass (ruff + mypy strict)
  • Coverage: 90%

Breaking Changes

None.

Notes

Notification config in [notifications] section with webhook_url, smtp_* fields, and on_failure_only flag.

Closes #0069
Closes #0070
Closes #0071

## What Add webhook and email notification support for job completion events. Webhooks POST JSON payloads to a configurable URL. Email alerts send via SMTP with TLS and optional auth. ## Why Users need to be notified when jobs complete or fail, either via webhook integration or email. ## Testing - [x] 145 unit tests pass (11 new for notifications) - [x] Pre-commit hooks pass (ruff + mypy strict) - [x] Coverage: 90% ## Breaking Changes None. ## Notes Notification config in `[notifications]` section with `webhook_url`, `smtp_*` fields, and `on_failure_only` flag. Closes #0069 Closes #0070 Closes #0071
- Webhook POST with JSON payload on job completion
- Email alerts via SMTP (TLS, auth, configurable recipients)
- on_failure_only flag to skip success notifications
- Integrated into job lifecycle in run_job
- NotificationConfig model and config merge support
Closes #0069
Closes #0070
Closes #0071
docs: mark Phase 5 Task 2 complete
All checks were successful
CI / test (pull_request) Successful in 55s
CI / lint (pull_request) Successful in 1m24s
66a977ba5f
Webhook and email notification support done.
Closes #0071
the.auditor left a comment

Automated Review — PR #118

Result: APPROVED


The final PR on the ROADMAP. Webhook and email notification support rounds out the feature set. Clean implementation.

  • Correctness: send_webhook POSTs JSON, checks HTTP 400+. send_email supports STARTTLS + optional auth. notify() dispatches both channels independently, respects on_failure_only, and logs errors without blocking job execution. _build_payload creates structured event data.
  • Completeness: Closes #69–#71. ROADMAP fully complete. NotificationConfig dataclass added, config merging handles nested dataclass, engine wired up on MCP error / LLM error / success paths.
  • Test coverage: 11 tests covering payload building, webhook (POST, HTTP error), email (TLS+auth, no auth, connection error), and notify dispatch (skip on success, webhook sent, email on failure, webhook error logged).
  • Error handling: All notification errors caught and logged as warnings — non-blocking by design.
  • Maintainability: Clean 159-line module. send_webhook / send_email separated from dispatch logic. Engine test refactored with _mock_config() helper (nice dedup).

Suggestions (non-blocking)

  1. src/kronai/notifications.py:100-108send_email only supports STARTTLS (port 587). No implicit TLS (SMTP_SSL, port 465). Consider adding smtp_use_ssl config flag that uses smtplib.SMTP_SSL instead.

  2. src/kronai/notifications.py:69-76send_webhook has no retry logic. Unlike the LLM client (which has exponential backoff), transient webhook failures are silently logged. Consider adding retry with backoff for transient failures.

  3. src/kronai/engine.py:65 — Config is loaded inside run_job() but also in run_interval(). For an interval of N jobs, config is loaded N+1 times. Consider passing config from run_interval() to run_job() (building on the earlier refactor that moved config load earlier in this PR).

## Automated Review — PR #118 **Result: APPROVED** --- The final PR on the ROADMAP. Webhook and email notification support rounds out the feature set. Clean implementation. - **Correctness**: `send_webhook` POSTs JSON, checks HTTP 400+. `send_email` supports STARTTLS + optional auth. `notify()` dispatches both channels independently, respects `on_failure_only`, and logs errors without blocking job execution. `_build_payload` creates structured event data. - **Completeness**: Closes #69–#71. ROADMAP fully complete. `NotificationConfig` dataclass added, config merging handles nested dataclass, engine wired up on MCP error / LLM error / success paths. - **Test coverage**: 11 tests covering payload building, webhook (POST, HTTP error), email (TLS+auth, no auth, connection error), and notify dispatch (skip on success, webhook sent, email on failure, webhook error logged). - **Error handling**: All notification errors caught and logged as warnings — non-blocking by design. - **Maintainability**: Clean 159-line module. `send_webhook` / `send_email` separated from dispatch logic. Engine test refactored with `_mock_config()` helper (nice dedup). ### Suggestions (non-blocking) 1. **`src/kronai/notifications.py:100-108`** — `send_email` only supports STARTTLS (port 587). No implicit TLS (SMTP_SSL, port 465). Consider adding `smtp_use_ssl` config flag that uses `smtplib.SMTP_SSL` instead. 2. **`src/kronai/notifications.py:69-76`** — `send_webhook` has no retry logic. Unlike the LLM client (which has exponential backoff), transient webhook failures are silently logged. Consider adding retry with backoff for transient failures. 3. **`src/kronai/engine.py:65`** — Config is loaded inside `run_job()` but also in `run_interval()`. For an interval of N jobs, config is loaded N+1 times. Consider passing config from `run_interval()` to `run_job()` (building on the earlier refactor that moved config load earlier in this PR).
fuzzy merged commit 66a977ba5f into main 2026-07-05 15:53:22 +00:00
fuzzy deleted branch feature/0071-add-webhook-notification-support 2026-07-05 15:53:22 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
thwap/kronai!118
No description provided.