Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Relay Bot — Architecture and Operations

Relay is HungryHub’s Slack AI assistant. It answers questions from team docs, ClickUp tasks, and GitHub; reviews PRs; generates release notes; and maintains per-user memory across sessions.


Architecture

Slack (Socket Mode)          GitHub Webhooks
       │                            │
       ▼                            ▼
  FastAPI / Slack Bolt          pr_webhook.py
  (main.py)                         │
       │                            │
       ▼                            ▼
  Strands Agent ──────► Amazon Bedrock (Nova Pro / Nova Lite)
       │
       ├── Knowledge Base retrieval (Bedrock KB — Aurora pgvector)
       ├── ClickUp tools (clickup_tools.py)
       ├── GitHub tools  (github_tools.py)
       └── Slack tools   (slack_tools.py)

Deployment: ECS Fargate, relay-prod cluster, relay-bot-prod service — AWS account 512438352490 (hungryhub-ai), us-east-1.

Dev environment: relay-dev cluster, relay-bot-dev service — AWS account 965444437277 (genai-sandbox), us-east-1.


Key modules

ModulePurpose
main.pySlack Bolt app, per-user agent, feedback buttons, memory management
pr_webhook.pyGitHub webhook handler — PR notifications, review assignments, CI status, nag timers
release_notes.pyAI-generated release notes from merged PRs
comment_digest.pyDigests PR review thread comments into a summary
kb_distill.pyDistils new PRs into Knowledge Base documents
kb_distill_scheduler.pySchedules KB distillation jobs
clickup_tools.pyClickUp task lookup tools for the agent
github_tools.pyGitHub PR/issue lookup tools for the agent
feedback_store.pyPersists reaction-based feedback to S3 for nightly eval
token_server.pyServes the ClickUp token submission form

Environment variables (key ones)

VariableDescription
RELAY_ENVprod or dev — gates DM-vs-channel routing for author nag messages
PR_CHANNELSlack channel ID for PR notifications (default: #github-pr-reviews)
PR_DEV_CHANNELDev-only channel for nag message visibility (unset on prod)
KNOWLEDGE_BASE_IDBedrock Knowledge Base ID
AGENTCORE_MEMORY_IDAgentCore memory resource ID (RelayBotMemory-zwhFEAFiqs)
GITHUB_APP_IDGitHub App ID for PR webhook authentication
PR_THREADS_TABLEDynamoDB table mapping PR URLs → Slack thread timestamps
PR_STATE_TABLEDynamoDB table for PR lifecycle state
RELAY_FEEDBACK_BUCKETS3 bucket for feedback records (nightly eval pipeline)

Secrets (SLACK_BOT_TOKEN, SLACK_APP_TOKEN, GITHUB_WEBHOOK_SECRET, GITHUB_APP_PRIVATE_KEY, CLICKUP_TOKEN) are stored in Secrets Manager: relay/slack-tokens-{env}.


PR notifications flow

  1. GitHub sends a webhook to Relay’s /github/webhook endpoint.
  2. pr_webhook.py verifies the HMAC signature and routes by event type.
  3. On pull_request opened: posts a summary card to PR_CHANNEL, assigns a reviewer, stores the thread TS in DynamoDB.
  4. On pull_request_review / check_suite: updates the root message with CI and review status.
  5. On merge: fires release notes draft creation.
  6. Nag messages (missing tests, missing tracking link): on prod, sent as a DM to the PR author. On dev, posted to PR_DEV_CHANNEL (or PR_CHANNEL if unset) with a “dev mode” footer.

CI/CD

  • Dev: auto-deploys on every push to main — builds image, pushes to ECR (965444437277), calls ecs update-service --force-new-deployment.
  • Prod: deploys on GitHub Release published (via release-please) or manual workflow_dispatch — builds separate image, pushes to ECR (512438352490).
  • Terraform for both environments lives in hungryhub-ai/ecs-relay/.

Common operations

Tail prod logs

aws logs tail /ecs/relay-prod --follow --profile genai-prod --region us-east-1

Force a prod redeploy (no code change)

aws ecs update-service \
  --cluster relay-prod \
  --service relay-bot-prod \
  --force-new-deployment \
  --profile genai-prod \
  --region us-east-1

Check running task environment

TASK=$(aws ecs list-tasks --cluster relay-prod --service-name relay-bot-prod \
  --query 'taskArns[0]' --output text --profile genai-prod --region us-east-1)
aws ecs describe-tasks --cluster relay-prod --tasks $TASK \
  --profile genai-prod --region us-east-1 \
  --query 'tasks[0].containers[0].environment'

Update a secret (e.g. rotate Slack token)

aws secretsmanager get-secret-value \
  --secret-id relay/slack-tokens-prod \
  --profile genai-prod --region us-east-1

# Edit locally, then:
aws secretsmanager put-secret-value \
  --secret-id relay/slack-tokens-prod \
  --secret-string '{"SLACK_BOT_TOKEN":"xoxb-...","SLACK_APP_TOKEN":"xapp-..."}' \
  --profile genai-prod --region us-east-1

# Force redeploy to pick up new secret
aws ecs update-service --cluster relay-prod --service relay-bot-prod \
  --force-new-deployment --profile genai-prod --region us-east-1

Feedback loop

Slack reactions (👍 / 👎) on Relay responses are captured by feedback_store.py and written to S3 (relay-feedback-prod-512438352490). The nightly eval pipeline (eval/nightly.py) replays these as evaluation cases against the current model.


Memory

Per-user conversation memory uses Amazon Bedrock AgentCore Memory:

  • Resource ID: RelayBotMemory-zwhFEAFiqs
  • Each user gets a named session; Relay recalls prior context across separate conversations.