β οΈ Heads up before you run anything. This is an educational project. It demonstrates GitHub GraphQL automation, multi-model LLM orchestration, and how production-grade HTTP clients handle failure. Running it blind against real repos without reading the output could get your GitHub account flagged. Read GitHub's Acceptable Use Policy first. This isn't to cover bases β it's because the bot is powerful enough to do real damage if you're careless with it.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β π§ GALAXY BRAIN BOT β
β High-Level Overview β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
You run the bot
β
βΌ
βββββββββββββββ GraphQL v4 ββββββββββββββββββββββββ
β Discovery β βββββββββββββββββββΆ β GitHub Discussions β
β Engine β βββββββββββββββββββ β (open threads) β
βββββββββββββββ paginated results ββββββββββββββββββββββββ
β
βΌ
βββββββββββββββ already answered? ββββββββββββββββββββ
β Filter β ββββββββββββββββββββββββΆβ Stats JSON β
β + Dedup β βββββββββββββββββββββββββ (skip if found) β
βββββββββββββββ ββββββββββββββββββββ
β
βΌ
βββββββββββββββ prompt + context ββββββββββββββββββββ
β LLM Layer β βββββββββββββββββββββββΆβ OpenRouter API β
β (18 models)β ββββββββββββββββββββββββ free tier β
βββββββββββββββ generated answer ββββββββββββββββββββ
β
βΌ
βββββββββββββββ you confirm (y/n)
β Post / β βββββββββββββββββββββββΆ GitHub Discussion reply
β Skip β
βββββββββββββββ
β
βΌ
βββββββββββββββ
β Track it β βββΆ galaxy_brain_stats.json
β + notify β βββΆ Discord / Slack webhook
βββββββββββββββ
Galaxy Brain Bot finds open GitHub Discussion threads, generates answers using free LLMs through OpenRouter, and optionally posts them under your account. It then watches for accepted answers so you can track your Galaxy Brain badge progress.
The interesting part isn't the badge farming. It's the infrastructure underneath: circuit breakers, adaptive rate limiting, key rotation, TTL caching, graceful shutdown. These are the patterns any production bot needs, and they're all here in readable Python.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β SYSTEM ARCHITECTURE β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββββββββββ β
β β Shutdown β β InMemory β β CircuitBreaker β β
β β Handler β β Cache β β (per endpoint) β β
β β β β β β β β
β β SIGINT/TERM β β TTL: 300s β β threshold β open β β
β β sets flag β β dict+stamps β β timeout β half-open β β
β ββββββββ¬ββββββββ ββββββββ¬ββββββββ ββββββββββββ¬ββββββββββββ β
β β β β β
β ββββββββββββββββββββΌβββββββββββββββββββββββββ β
β βΌ β
β ββββββββββββββββββ β
β β GitHub β β
β β GraphQL v4 β β
β β Client β β
β βββββββββ¬βββββββββ β
β β β
β βββββββββββββββββββΌβββββββββββββββββββ β
β βΌ βΌ βΌ β
β βββββββββββββββ βββββββββββββββ ββββββββββββββββ β
β β Discovery β β Comment β β Badge β β
β β (topics, β β Reader β β Progress β β
β β stars, β β (avoids β β Tracker β β
β β recency) β β duplicates)β β β β
β βββββββββββββββ βββββββββββββββ ββββββββββββββββ β
β β β
β βΌ β
β ββββββββββββββββββ β
β β KeyManager β β
β β + ModelTrackerβ β
β β β β
β β round-robin β β
β β keys/models β β
β βββββββββ¬βββββββββ β
β β β
β βΌ β
β ββββββββββββββββββ β
β β OpenRouter β β
β β 18+ free LLMs β β
β ββββββββββββββββββ β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
This is the most underrated piece in the codebase. Without it, when an endpoint goes down, the bot hammers it until the session ends.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CIRCUIT BREAKER STATE MACHINE β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β requests N consecutive β
β succeed failures β
β ββββββββββββββββ ββββββββββββββββ β
β β β βββββββΆ β β β
β β CLOSED β β OPEN β β
β β (normal ops) β βββββββ β (blocked) β β
β β β probe β β β
β ββββββββββββββββ success ββββββββ¬ββββββββ β
β β timeout β
β βΌ expires β
β ββββββββββββββββ β
β β HALF-OPEN β β
β β (let 1 probe β β
β β through) β β
β ββββββββββββββββ β
β β
β Configurable: threshold=5 failures β
β timeout=120 seconds β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Three states. Closed means everything's fine β requests go through. Open means something broke β requests are blocked without hitting the endpoint. Half-open means the timeout expired and one probe gets through. If it succeeds, back to closed. If it fails, back to open.
You can tune CIRCUIT_BREAKER_THRESHOLD and CIRCUIT_BREAKER_TIMEOUT in .env.
Not all rate limiting is equal. Respecting the headers the server sends back is smarter than just sleeping for a fixed amount.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ADAPTIVE BACKOFF DECISION TREE β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β API responds with 429 or 403 β
β β β
β βΌ β
β βββββββββββββββββββββββ β
β β Retry-After β β
β β header present? β β
β ββββββββββββ¬βββββββββββ β
β yes β no β
β βββββββββββ΄βββββββββββ β
β βΌ βΌ β
β sleep(Retry-After) X-RateLimit-Reset β
β β header present? β
β β β β
β β yes β no β
β β βββββββββββββ΄βββββββββ β
β β βΌ βΌ β
β β sleep until exponential β
β β reset time backoff β
β β (2^n seconds) β
β ββββββββββββββββββββββββββ β
β β β
β βΌ β
β retry request β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββοΏ½οΏ½
The bot doesn't just call one model and give up if it's slow. It cycles through 18+ free models on OpenRouter, skipping any that return empty responses, 429s, or 404s.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MODEL ROTATION FLOW β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Model list (18+ free-tier models) β
β [qwen3.6-plus, llama-3.3-70b, gemma-3-27b, ...] β
β β β
β βΌ β
β ββββββββββββββββ β
β β Try model 1 β β
β ββββββββ¬ββββββββ β
β good β bad (empty / 429 / 404) β
β β β β
β βΌ βΌ β
β use answer log failure β
β β β β
β β βΌ β
β β try model 2 β model 3 β ... β
β β β
β βΌ β
β ModelTracker records: β
β - success count β
β - failure count β
β - average latency (ms) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
At the end of a session, --models shows you a table of which models worked, how often, and how fast.
- Auto-discovery β finds repos using topic tags, star counts, and activity recency. No hardcoded lists needed.
- Smart deduplication β saves answered discussion IDs to
galaxy_brain_stats.jsonso the bot never double-posts across sessions. - CoC-aware filtering β skips repos with codes of conduct that restrict automated participation (not perfect, but it tries).
- Comment-aware β reads existing replies before generating an answer so it doesn't pile on something already covered.
- Circuit breakers β per endpoint, configurable threshold and timeout (see diagram above).
- Adaptive backoff β reads
Retry-After,X-RateLimit-Reset, and falls back to exponential delays when neither header is present. - Key rotation β cycles multiple OpenRouter API keys when one hits a rate limit.
- Model rotation β tries 18+ free models in order and skips broken ones automatically.
- 18+ free models via OpenRouter β Qwen, Llama, Gemma, Nemotron, and more.
- Vision support β detects if a model handles images and includes them from the discussion when relevant.
- Link fetching β pulls external URLs from discussion bodies for richer context before generating an answer.
- Configurable answer length β min/max character limits stop one-liner garbage from getting posted.
- Badge progress β shows accepted answer count and current tier toward the Galaxy Brain badge.
- Stats by org β breaks down your answers by repository owner.
- Session model performance β tracks which AI models succeed vs. fail and their latency.
- Webhook notifications β Discord and Slack alerts on new acceptances and session summaries.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π₯ BRONZE 8 accepted answers
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π₯ SILVER 16 accepted answers
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π₯ GOLD 32 accepted answers
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
The bot shows your current tier and how many accepted answers you need for the next one. Run --stats to check anytime.
Requirements: Python 3.8+, a GitHub account, a free OpenRouter account.
# Clone the repo
git clone https://github.com/itxashancode/Galaxy-Brain-Automation.git
cd Galaxy-Brain-Automation
# Install dependencies
pip install -r requirements.txt
# Copy and fill in your credentials
cp .env.template .env
nano .envrequirements.txt:
requests>=2.31.0
rich>=13.7.0
python-dotenv>=1.0.0
Create a .env file in the project root. Every option has a comment explaining what it does.
# ββ GitHub βββββββββββββββββββββββββββββββββββββββββββββββββββββ
# needs read:discussion and write:discussion scopes
GITHUB_TOKEN=ghp_your_token_here
GITHUB_USERNAME=your_github_username
# ββ OpenRouter βββββββββββββββββββββββββββββββββββββββββββββββββ
# comma-separated if you have multiple keys
OPENROUTER_KEYS=sk-or-v1-your_key_here
# optional: override the model list (defaults to 18-model rotation)
# OPENROUTER_MODELS=qwen/qwen3.6-plus:free,meta-llama/llama-3.3-70b-instruct:free
# ββ Webhooks (optional) ββββββββββββββββββββββββββββββββββββββββ
DISCORD_WEBHOOK_URL=
SLACK_WEBHOOK_URL=
# ββ Bot behavior βββββββββββββββββββββββββββββββββββββββββββββββ
MIN_REPO_STARS=10
MAX_ANSWERS_PER_SESSION=5
DELAY_BETWEEN_ANSWERS=5
AUTO_APPROVE_ANSWERS=false # keep this false until you trust the output
# ββ Discovery ββββββββββββββββββββββββββββββββββββββββββββββββββ
DISCOVERY_TOPICS=python,javascript,open-source,programming
DISCOVERY_MIN_STARS=5
DISCOVERY_MAX_REPOS=50
# ββ Answer quality βββββββββββββββββββββββββββββββββββββββββββββ
ANSWER_MIN_CHARS=120 # prevents one-liner garbage
ANSWER_MAX_CHARS=900
# ββ Performance ββββββββββββββββββββββββββββββββββββββββββββββββ
CACHE_TTL_SECONDS=300
CIRCUIT_BREAKER_THRESHOLD=5
CIRCUIT_BREAKER_TIMEOUT=120
RECENT_HOURS=24Getting a GitHub token: Settings β Developer settings β Personal access tokens β Tokens (classic). Enable repo and write:discussion.
Getting an OpenRouter key: Sign up at openrouter.ai, go to Keys, create a free key. The bot only uses :free tier models by default β it won't cost you anything.
# Full session: finds discussions, generates answers, asks before posting
python galaxy_brain_bot.py
# Run tests first to verify your setup
python test_bot.py
# Test mode: generate answers without posting anything
python galaxy_brain_bot.py --test
# Check if any previously posted answers were accepted
python galaxy_brain_bot.py --check
# Show your accumulated stats
python galaxy_brain_bot.py --stats
# Show model performance from this session
python galaxy_brain_bot.py --models
# Override topics and star threshold for this session only
python galaxy_brain_bot.py --topics rust,go,cli --min-stars 50
# Clear in-memory cache at startup
python galaxy_brain_bot.py --cache-clearββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β FULL SESSION FLOWCHART β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
python galaxy_brain_bot.py
β
βΌ
ββββββββββββββββββββββββ
β Load .env config β
β Init all components β
β (cache, breakers, β
β key/model managers)β
ββββββββββββ¬ββββββββββββ
β
βΌ
ββββββββββββββββββββββββ
β Discovery phase ββββ DISCOVERY_TOPICS, MIN_STARS, RECENT_HOURS
β GraphQL β find reposβ
β with open Discussionsβ
ββββββββββββ¬ββββββββββββ
β
βΌ
ββββββββββββββββββββββββ
β Filter repos ββββ CoC check, star threshold, dedup
β Skip already-done β
β Skip CoC-restricted β
ββββββββββββ¬ββββββββββββ
β
βΌ
ββββββββββββββββββββββββ
β For each discussion β
β that passes filters:β
ββββββββββββ¬ββββββββββββ
β
βββββββ΄βββββββ
βΌ βΌ
fetch body fetch existing
+ images comments
+ linked URLs
β β
βββββββ¬βββββββ
β
βΌ
ββββββββββββββββββββββββ
β Build prompt β
β (body + context β
β + existing replies)β
ββββββββββββ¬ββοΏ½οΏ½βββββββββ
β
βΌ
ββββββββββββββββββββββββ
β Send to OpenRouter ββββ tries model 1 β 2 β 3 ... (rotation)
β Get answer back β
ββββββββββββ¬ββββββββββββ
β
βΌ
ββββββββββββββββββββββββ
β Length check β
β (MIN_CHARS/MAX_CHARS)β
ββββββββββββ¬ββββββββββββ
β
βΌ
ββββββββββββββββββββββββ
β Show answer to you β
β β confirm (y/n)? ββββ AUTO_APPROVE_ANSWERS=false
ββββββββββββ¬ββββββββββββ
β
yes β no
ββββββββββ΄βββββββββ
βΌ βΌ
Post to Skip it,
GitHub log it
β
βΌ
Save to
stats.json
β
βΌ
Fire webhooks
(Discord/Slack)
β
βΌ
ββββββββββββββββββββββββ
β Session summary β
β (model performance, β
β badge progress, β
β answers posted) β
ββββββββββββββββββββββββ
All of these are :free tier β no billing required.
βββββββββββββββββββββββββββββββββββββββββββββββ¬βββββββββββββββ¬βββββββββ
β Model β Vision β Size β
βββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββΌβββββββββ€
β qwen/qwen3.6-plus:free β β β Large β
β stepfun/step-3.5-flash:free β β β Large β
β nvidia/nemotron-3-super-120b-a12b:free β β 120B β
β arcee-ai/trinity-large-preview:free β β Large β
β z-ai/glm-4.5-air:free β β Medium β
β nvidia/nemotron-3-nano-30b-a3b:free β β 30B β
β minimax/minimax-m2.5:free β β β Large β
β openai/gpt-oss-120b:free β β 120B β
β meta-llama/llama-3.3-70b-instruct:free β β 70B β
β google/gemma-3-27b-it:free β β β 27B β
β + 8 more in rotation β β β
βββββββββββββββββββββββββββββββββββββββββββββββ΄βββββββββββββββ΄βββββββββ
Override with OPENROUTER_MODELS=model1,model2 in your .env if you want to pin specific ones.
Galaxy-Brain-Automation/
βββ galaxy_brain_bot.py # Main bot β all logic lives here
βββ galaxy_brain_stats.json # Persisted answer history (auto-created)
βββ galaxy_brain.log # Session logs
βββ test_bot.py # Full test suite β run this first
βββ test_connection.py # Quick credential check
βββ requirements.txt
βββ .env # Your credentials (never commit this)
βββ .env.template # Example config
Each component is isolated enough that you can pull it into other projects.
| Component | What it does |
|---|---|
ShutdownHandler |
Catches SIGINT/SIGTERM, sets a flag. All loops check shutdown.requested before each iteration β Ctrl+C finishes cleanly instead of corrupting the stats file. |
InMemoryCache |
Simple dict with timestamps. TTL defaults to 300 seconds. Prevents re-fetching the same GraphQL queries within a session. |
CircuitBreaker |
Opens after N consecutive failures, blocks requests for a timeout, then half-opens to let one probe through. Resets on success. |
KeyManager |
Holds multiple OpenRouter keys, rotates to the next when one hits rate limits, tracks per-key failure counts. |
ModelTracker |
Records successes, failures, and latency per model. Generates the session summary table. |
# Full test suite (run this before anything else)
python test_bot.py
# Quick credential check only
python test_connection.py
# Quick end-to-end (finds repos, generates answers, doesn't post)
python test_bot.py --quickThe test suite checks: imports, .env config, GitHub API auth, OpenRouter API auth (tries each key against multiple models), GraphQL access, and stats file I/O. If it passes clean, the bot is ready to run.
A few things worth saying plainly, not as legal cover but because they matter:
- Don't spam.
MAX_ANSWERS_PER_SESSIONexists for a reason. Fifty low-quality posts in an hour will get your account flagged, and it makes the Discussion threads worse for everyone. - Read the answers before posting.
AUTO_APPROVE_ANSWERS=falseis the default. Keep it that way until you've seen enough output to trust the model on that type of question. - Check the repo's code of conduct. Some repos explicitly prohibit automated responses. The bot tries to detect this, but it's not foolproof.
- Don't post where you'd be unwanted. The goal is to help people who are stuck, not to farm acceptances.
The bot was built to understand how automated discussion participation works. If you use it to post garbage at scale, that's on you.
Most bot tutorials show you how to hit an API and print the response. This one actually handles failure.
The circuit breaker is a real circuit breaker, not a try/except with a sleep. The rate limiting reads actual server headers instead of guessing. The key rotation is stateful and tracks per-key health. The shutdown handler means Ctrl+C doesn't leave a corrupted JSON file.
These aren't exotic patterns. They're the basics every production bot needs, and they're all in one readable file.
Open an issue or PR. The most useful contributions right now are better prompt templates, more model configs, or a smarter discussion-quality filter that skips questions the bot is unlikely to answer well. PRs that just add more badges to this README will be closed immediately.
MIT. Do what you want with the code. If it breaks something, that's between you and your GitHub account.