Architecture
PromptBus is designed as a transparent local proxy with a modular architecture. This page describes the key modules and how they interact.
System Diagram
┌─────────────────────────────────────────────────────┐ │ PromptBus │ │ ┌──────────┐ ┌───────────┐ ┌──────────────────┐ │ │ │ Proxy │──│Classifier │──│ Rules Engine │ │ │ │ Server │ │(heuristic)│ │ (config-driven) │ │ │ └────┬─────┘ └───────────┘ └────────┬─────────┘ │ │ │ │ │ │ ┌────▼─────────────────────────────────▼──────────┐ │ │ │ Logger (SQLite) │ │ │ └──────────────────────────────────────────────────┘ │ │ │ │ ┌──────────────────────────────────────────────────┐ │ │ │ Dashboard Server (Express + HTML/CSS/JS SPA) │ │ │ └──────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────┘
Modules
1. Core Proxy
The proxy server (src/core/proxy/) listens on 127.0.0.1:4701 and:
- Forwards all requests to
api.anthropic.com - Parses request bodies (Messages API JSON)
- Injects the classifier + rules engine to rewrite fields
- Streams responses without buffering (uses
.pipe()) - Forwards upstream errors faithfully (no generic 500s)
- Logs only a fingerprint (last 4 chars) of auth headers
2. Classifier
The classifier (src/core/classifier/) uses pure keyword-matching heuristics:
- No LLM call on the hot path — zero extra latency
- Analyzes the last user message
- Produces a
TaskProfilewith type, signals, and confidence - Handles edge cases: empty body, non-JSON, null body
3. Rules Engine
The rules engine (src/core/rules_engine/):
- Loads
config/rules.yamlwith caching - Supports hot reload via
invalidateCache() - Applies
TaskProfileagainst rules to produceRoutingDecision - Respects
never_downgradeoverrides
4. Logger
The logger (src/core/logger/) uses SQLite via better-sqlite3:
- Database at
~/.local/share/promptbus/promptbus.db - Stores requests, pricing data, and system info
- WAL mode for concurrent access
- Auto-prunes logs older than
log_retention_days - Self-healing on corrupt database
5. Dashboard
The dashboard (src/dashboard/) is an Express server:
- Serves a single-page application on
127.0.0.1:4702 - REST API for logs, rules, and status
- Frontend is vanilla HTML/CSS/JS (no framework)
- Auto-polls every 8 seconds for live updates
- Responsive design with dark theme
Data Flow
Request Flow
1. Claude Code sends request to PromptBus (port 4701)
2. Proxy server parses the request body
3. Classifier analyzes the last user message
4. Classifier returns TaskProfile { type, signals, confidence }
5. Rules Engine matches TaskProfile against config rules
6. Rules Engine returns RoutingDecision { model, effort, downgraded }
7. Proxy rewrites model/effort fields
8. Proxy forwards request to api.anthropic.com
9. Response is streamed back to Claude Code
10. Logger records the decision to SQLite
11. Dashboard displays live data from SQLiteSafety Guarantees
- Crash safety: If classifier or rules engine throws, request passes through unmodified
- Confidence floor: Below-threshold requests never downgrade (default 0.6)
- Unknown types: Default to
never_downgrade - No data exfiltration: Only auth fingerprints (last 4 chars) are logged
- DB self-healing: Corrupt SQLite database is automatically recreated