Understanding the Architecture
Explore ThePopeBot's event-driven architecture, learn how the Event Handler and Agent Engine work together, and trace the full lifecycle of a request.
Event Handler + Agent Engine Explained
ThePopeBot is built on two core pillars that work together to process every incoming request:
The Event Handler
The Event Handler is the entry point for all interactions. It receives raw events from various channels (web UI, Telegram, webhooks, cron jobs) and normalizes them into a unified event format.
[Telegram Message] βββ
[Web UI Input] βββ€βββΆ Event Handler βββΆ Normalized Event
[Webhook Payload] βββ€
[Cron Trigger] βββ
The Event Handler is responsible for:
- Authentication: Verifying the source of incoming events
- Normalization: Converting channel-specific formats into a standard event object
- Routing: Directing events to the appropriate agent or pipeline
- Rate limiting: Protecting the system from abuse
The Agent Engine
The Agent Engine is the brain of the system. It receives normalized events and orchestrates the full reasoning and execution cycle:
- Context Assembly β Gathers relevant history, tools, and system prompts
- Planning β Determines what steps are needed to fulfill the request
- Execution β Runs each step, calling tools and LLM APIs as needed
- Observation β Evaluates results and decides whether to continue or respond
- Response β Sends the final output back through the Event Handler
File Structure Walkthrough
Understanding the project layout helps you navigate and extend the codebase:
thepopebot/
βββ src/
β βββ agents/ # Agent definitions and configurations
β β βββ default.ts # The default general-purpose agent
β β βββ reviewer.ts # Code review specialist agent
β βββ engine/ # Core agent engine
β β βββ planner.ts # Task planning logic
β β βββ executor.ts # Step execution and tool calling
β β βββ context.ts # Context assembly and management
β βββ events/ # Event handler and channel adapters
β β βββ handler.ts # Main event handler
β β βββ telegram.ts # Telegram adapter
β β βββ webhook.ts # Webhook adapter
β βββ tools/ # Tool definitions for agents
β β βββ filesystem.ts
β β βββ git.ts
β β βββ search.ts
β βββ config/ # Configuration files
β βββ agents.yaml # Agent registry
β βββ tools.yaml # Tool registry
βββ docker-compose.yml
βββ .env.example
βββ package.json
Request Lifecycle
Let us trace a message from the moment it arrives until the response is sent back. Consider a user sending βReview the latest PRβ through Telegram:
Step 1: Event Ingestion
The Telegram adapter receives the message and creates a normalized event:
const event: AgentEvent = {
source: 'telegram',
userId: 'user-12345',
message: 'Review the latest PR',
timestamp: Date.now(),
metadata: { chatId: 67890 }
};
Step 2: Routing
The Event Handler inspects the event and routes it to the appropriate agent. Based on the message content mentioning βPRβ, it routes to the reviewer agent.
Step 3: Context Assembly
The engine gathers:
- The agentβs system prompt
- Recent conversation history
- Available tools (git, filesystem, GitHub API)
- Any relevant project context
Step 4: Planning and Execution
The agent engine calls the LLM with the assembled context. The LLM produces a plan:
- Fetch the latest PR using the GitHub tool
- Read the changed files
- Analyze the diff for issues
- Generate a review summary
Each step is executed sequentially, with the results fed back to the LLM for the next step.
Step 5: Response Delivery
The final review summary is sent back through the Event Handler, which formats it for the Telegram channel and delivers it to the user.
Key Configuration Files
agents.yaml
This file defines which agents are available and their properties:
agents:
default:
name: "General Assistant"
model: "gpt-4"
temperature: 0.7
tools:
- filesystem
- search
reviewer:
name: "Code Reviewer"
model: "gpt-4"
temperature: 0.3
tools:
- git
- filesystem
systemPrompt: "./prompts/reviewer.md"
tools.yaml
This file registers available tools and their configurations:
tools:
filesystem:
description: "Read and write files"
permissions:
- read
- write
git:
description: "Git operations"
permissions:
- read
- diff
How Messages Flow Through the System
Here is the complete flow visualized:
User Input
β
βΌ
Channel Adapter (Telegram / Web / Webhook / Cron)
β
βΌ
Event Handler βββΆ Authentication βββΆ Normalization βββΆ Routing
β
βΌ
Agent Engine
βββ Context Assembly
βββ LLM Planning
βββ Tool Execution (loop)
βββ Response Generation
β
βΌ
Event Handler βββΆ Channel Formatting βββΆ Delivery
β
βΌ
User Response
Each layer is designed to be independent and replaceable. You can swap out the Telegram adapter for a Slack adapter without touching the Agent Engine. You can change the LLM provider without modifying the Event Handler. This separation of concerns is what makes ThePopeBot extensible and maintainable.