Add agentic platform: event bus, webhook API, scheduler, notifications#21
Add agentic platform: event bus, webhook API, scheduler, notifications#21RichardAtCT merged 3 commits intomainfrom
Conversation
Transform the bot from a reactive chat relay into a proactive agentic
platform. New components run alongside the existing Telegram handler
path, controlled by feature flags (disabled by default).
New modules:
- src/events/ - Async event bus with typed events (UserMessage, Webhook,
Scheduled, AgentResponse), handlers that bridge events to Claude, and
security middleware wrapping existing validators
- src/api/ - FastAPI webhook server (POST /webhooks/{provider}) with
GitHub HMAC-SHA256 signature verification and generic Bearer auth
- src/scheduler/ - APScheduler-based cron scheduler that publishes
ScheduledEvents, with SQLite persistence for job definitions
- src/notifications/ - Delivery service subscribing to AgentResponseEvent,
sends via Telegram with per-chat rate limiting and message splitting
Changes to existing files:
- settings.py: enable_api_server, api_server_port, enable_scheduler,
github_webhook_secret, webhook_api_secret, notification_chat_ids
- features.py: api_server_enabled, scheduler_enabled properties
- database.py: Migration 3 adds scheduled_jobs + webhook_events tables,
enables WAL mode for concurrent writes
- main.py: Wires event bus, notification service, API server, and
scheduler as concurrent tasks with ordered shutdown
- bot/core.py: Make initialize() idempotent for pre-init access to
Telegram Bot instance
- pyproject.toml: Add fastapi, uvicorn, apscheduler dependencies
Tests: 40 new tests (240 total), all passing
|
PR Review Summary
What looks good
Issues / questions
Suggested tests (if needed)
Verdict
|
1. Generic webhooks now require WEBHOOK_API_SECRET (fail-closed). Without
a configured secret, the endpoint returns 500 instead of accepting
unauthenticated requests.
2. Webhook deduplication via delivery_id: before publishing to the bus,
check webhook_events table for existing delivery_id and short-circuit
with {"status": "duplicate"} if already seen. Records events for audit.
3. After asyncio.wait(FIRST_COMPLETED), inspect completed tasks for
exceptions and log them with task name and error type before proceeding
to shutdown.
|
PR Review Summary
What looks good
Issues / questions
Suggested tests (if needed)
Verdict
|
Replace the SELECT-then-INSERT dedup flow with a single atomic INSERT OR IGNORE followed by SELECT changes(). The insert only succeeds when delivery_id is new (UNIQUE constraint), so concurrent identical deliveries cannot both pass the gate. Only publish to the event bus when the insert actually wrote a row.
|
PR Review Summary
What looks good
Issues / questions
Suggested tests (if needed)
Verdict
|
Summary
src/events/) — Async event bus with typed events (UserMessage,Webhook,Scheduled,AgentResponse), anAgentHandlerthat bridges events toClaudeIntegration.run_command(), and security middleware wrapping existing validatorssrc/api/) — FastAPI server (POST /webhooks/{provider}) with GitHub HMAC-SHA256 signature verification and generic Bearer token authsrc/scheduler/) — APScheduler-based cron system with SQLite persistence for job definitions, publishesScheduledEvents to the bussrc/notifications/) — Subscribes toAgentResponseEvent, delivers to Telegram with per-chat rate limiting (1 msg/sec) and automatic message splittingenable_api_server,enable_scheduler), DB migration 3 (scheduled_jobs + webhook_events tables, WAL mode), concurrent task orchestration inmain.pywith ordered shutdownAll new features are disabled by default via feature flags. The existing Telegram handler path is untouched — the event bus runs alongside it. No custom plugin system; leverages Claude Code's native Skills + MCP servers for integrations.
Test plan
poetry run pytest)black+isort+flake8clean on all new/modified filesmypyclean on all new modulescurl -X POST localhost:8080/webhooks/testwithENABLE_API_SERVER=true🤖 Generated with Claude Code