No description
Find a file
2026-10-04 07:52:50 +05:30
.github/workflows feat: add CI workflow, Docker deployment, and comprehensive documentation 2026-09-27 15:24:22 +05:30
src fix: preserve bold formatting in embed fields and surface descriptive errors 2026-10-04 07:52:50 +05:30
.dockerignore feat: add CI workflow, Docker deployment, and comprehensive documentation 2026-09-27 15:24:22 +05:30
.env.example feat: add CI workflow, Docker deployment, and comprehensive documentation 2026-09-27 15:24:22 +05:30
.gitignore feat: add CI workflow, Docker deployment, and comprehensive documentation 2026-09-27 15:24:22 +05:30
.gitlab-ci.yml Add LICENSE 2026-09-27 20:52:52 +05:30
Cargo.lock initial commit: OpenRouter free model radar Discord bot (WIP) 2026-09-17 07:51:54 +05:30
Cargo.toml initial commit: OpenRouter free model radar Discord bot (WIP) 2026-09-17 07:51:54 +05:30
docker-compose.yml feat: add CI workflow, Docker deployment, and comprehensive documentation 2026-09-27 15:24:22 +05:30
Dockerfile feat: add CI workflow, Docker deployment, and comprehensive documentation 2026-09-27 15:24:22 +05:30
LICENSE Add LICENSE 2026-09-27 20:52:52 +05:30
README.md docs: add live server invite and adopt minimalist style 2026-09-27 18:49:01 +05:30

Model Radar

CI License: MIT

A lightweight, crash-resilient Discord bot built in Rust with poise and serenity. Model Radar monitors OpenRouter's live model catalog for free LLMs (:free and exact $0 pricing) and dispatches real-time catalog release alerts and live auto-updating dashboards directly to Discord servers.

A live instance is running 24/7. You can see the bot in action and test commands here:
Join the Live Discord Server


Features

  • Automated OpenRouter Monitoring: Periodically polls the public OpenRouter models API (/api/v1/models) with configurable intervals.
  • Accurate Zero-Price Detection: String-based decimal parsing identifies genuine free-tier models (including scientific notation like 0e-9999) while rejecting precision artifacts, non-zero pricing, and tiered overrides.
  • Live Auto-Updating Dashboard: Running /watch posts a persistent public dashboard embed in your channel that automatically refreshes every poll interval (POLL_SECONDS), featuring new drops at the top and active stealth/experimental models directly on the first page.
  • Interactive Component Buttons: Multi-page /free-models and /status views include interactive [◀ Prev] and [Next ▶] buttons with automatic timeout disabling.
  • Model ID Autocomplete: Live slash command autocomplete for /model <id> to instantly find any model in the catalog as you type.
  • Direct OpenRouter Links: Embed titles link directly to the model's page on OpenRouter for quick browser inspection.
  • Pricing per 1M Tokens: Model inspection computes readable rates per 1 Million tokens (e.g. $0.15 / 1M tokens).
  • Flexible Subscription Filters:
    • free_only: Target free models or watch all new catalog entries.
    • search: Filter releases by model identifier or name (e.g., qwen, llama, coder).
    • min_context: Ignore models with context windows below a given token threshold (e.g. 32,768).
    • compact: Dense notification rows for high-volume channels.
  • Opt-In Role Pings: Server-level ping configuration supporting custom roles as well as @everyone.
  • Crash-Resilient State: Subscriptions and catalog states are stored atomically (.tmp write followed by atomic filesystem rename) to guarantee state integrity across crashes and container reboots.
  • Queue Bounds: Unreachable alert channels (e.g., deleted channel or revoked permissions) are capped at 50 queued events, preventing unbounded state growth.
  • Discord API Safety: Strict UTF-16 character limit enforcement and markdown character escaping prevent broken embeds or Discord 400 Bad Request rejections.
  • Dry-Run Diagnostic Mode: Test public catalog availability and parsing without needing a Discord token (--check).

Slash Commands

Command Scope Description
/free-models [search] [page] Public / Ephemeral Browse all currently available free models in OpenRouter's catalog with interactive [◀ Prev] / [Next ▶] buttons and search filter.
/status [free_only] [search] [min_context] [page] [page_size] [compact] [public] Configurable View a catalog freshness snapshot with model counts, interactive pagination, and token constraints.
/model <id> [compact] [show_pricing] [public] Configurable Inspect detailed specifications with live model ID autocomplete, cost per 1M tokens, and direct clickable links to OpenRouter.
/watch [ping_role] [free_only] [search] [min_context] [ping_enabled] [compact] [clear_role] Manage Server Posts a public live auto-updating dashboard in the channel and configures drop alerts. Supports any role or @everyone.
/unwatch Manage Server Remove the server's subscription and delete all queued pending alerts.
/stats Ephemeral View catalog freshness, last successful fetch timestamp, polling interval, and complete server subscription settings.
/testping Manage Server Dispatch a labeled test notification to verify channel permissions and role mentionability without modifying catalog state.
/about Ephemeral Display bot information, command guide, poll interval, and optional operator support link.

Getting Started

1. Create a Discord Bot Application

  1. Open the Discord Developer Portal and create a New Application.
  2. Navigate to the Bot tab:
    • Click Reset Token to generate a bot token for your DISCORD_TOKEN environment variable.
    • Note: No Privileged Gateway Intents are required (Model Radar does not require Message Content, Server Members, or Presence intents).
  3. Navigate to OAuth2 → URL Generator:
    • Scopes: Select bot and applications.commands.
    • Bot Permissions: Select View Channels, Send Messages, and Embed Links.
  4. Open the generated invite URL in your browser to invite the bot to your server.

2. Configuration & Environment Variables

Variable Required Default Description
DISCORD_TOKEN Yes — Discord Bot Token from the Developer Portal.
POLL_SECONDS No 600 Catalog polling interval in seconds (allowed: 60 to 86400).
STATE_PATH No state.json Path where subscription settings and catalog state are stored.
SUPPORT_URL No — Optional HTTPS URL (e.g. Ko-fi, GitHub Sponsors) shown in /about.
DISCORD_GUILD_ID No — Guild ID for instant slash command registration during testing (global registration takes up to an hour).

3. Deployment Options

  1. Clone the repository:

    git clone https://github.com/oiupoyt/model-radar.git
    cd model-radar
    
  2. Create .env from example:

    cp .env.example .env
    

    Edit .env and set DISCORD_TOKEN.

  3. Launch the container:

    docker compose up -d
    

    State persists in ./data.

Option B: Native Cargo Run

Prerequisites: Rust 1.85+ (Edition 2024)

# Verify catalog connection and parsing (no token required)
cargo run --locked -- --check

# Run the bot
export DISCORD_TOKEN="your_bot_token"
export POLL_SECONDS=600
cargo run --release --locked

Setting Up Alerts in Discord

  1. Pick a role for notifications (e.g. @ModelAlerts, @everyone, or any custom role).
  2. In the channel where alerts should be posted, run:
    /watch ping_role:@ModelAlerts ping_enabled:true
    
    (Or /watch ping_role:@everyone ping_enabled:true to notify everyone).
  3. Verify the setup by running:
    /testping
    
  4. Check your active server configuration at any time with /stats.

Development & Testing

# Run unit and integration tests
cargo test --locked

# Run linter
cargo clippy --all-targets -- -D warnings

# Check code formatting
cargo fmt --check

License

This project is licensed under the MIT License.