Skip to content

About

Ultra-fast, zero-GC async AI agent gateway and session multiplexer for Discord in 100% Rust

Resources

Code of conduct

Contributing

Security policy

Stars

26 stars

Watchers

1 watching

Forks

 β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—   β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— 
β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—
β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘
β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘
β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•
 β•šβ•β•β•β•β•β• β•šβ•β•     β•šβ•β• β•šβ•β•β•β•β•β• 
   G  A  T  E  W  A  Y

High-performance, Zero-GC Discord Multiplexer Gateway for OMO (oh-my-openagent) in 100% Rust.

Rust Tokio Discord License Zero GC Platform


The Native Discord Bridge for OMO

OMO Gateway is a dedicated, ultra-fast Rust gateway that bridges OMO (oh-my-openagent) directly to Discord.
It multiplexes thousands of concurrent channels, threads, and DMs with sub-millisecond routing, multi-bot sharding, scale-to-zero memory reclamation, and sandboxed tool execution.


⚑ Why OMO Gateway?

OMO (oh-my-openagent) provides autonomous agent intelligence, deep planning, and subagent orchestration. However, running AI agents directly against Discord's WebSocket APIs creates operational bottlenecks:

  • Heavy Idle Memory: Running individual Discord connections per agent consumes hundreds of megabytes.
  • Concurrency & Rate Limits: Managing token streaming across many channels triggers Discord rate-limit bans without centralized debouncing.
  • Multi-Bot Management: Running multiple bot identities requires running multiple redundant runtime instances.

OMO Gateway solves this by acting as a high-throughput, pure-Rust I/O multiplexer sitting between Discord and OMO.


πŸ—οΈ Architecture

[ Discord Ingress: DMs / Server Channels / Threads / Voice ]
                             β”‚
                             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    OMO GATEWAY (Pure Rust)                  β”‚
β”‚                                                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚   Session Multiplexer   β”‚   β”‚     Delivery Ledger     β”‚  β”‚
β”‚  β”‚   (Lock-Free DashMap)   β”‚   β”‚  (SQLite WAL Idempotent)β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚               β”‚                                             β”‚
β”‚               β–Ό                                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚       Bounded Actor Worker Pool (tokio::task)         β”‚  β”‚
β”‚  β”‚     - Scale-to-Zero GC (Idle Session Eviction)        β”‚  β”‚
β”‚  β”‚     - Multi-Bot Sharding (N Bots in 1 Binary)         β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                β”‚
                                β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   OMO AGENT EXECUTION ENGINE                β”‚
β”‚                                                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  LLM Streaming & Tool-Call Loop (OpenAI/Anthropic/...)β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                               β”‚                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ Native Tools: PTY Terminal / File CRUD / MCP / Web    β”‚  β”‚
β”‚  β”‚ Dedicated Workspace Isolation (~/.omon/workspace)     β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                β”‚
                                β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    DISCORD RESPONSE EGRESS                  β”‚
β”‚  - Live-Edit Debounced Streaming (800ms sliding window)     β”‚
β”‚  - Interactive Smart Approvals ([Approve] / [Reject] UI)    β”‚
β”‚  - Songbird Real-Time Voice Audio Pipeline (Opus / PCM)     β”‚
β”‚  - Scheduled Cron Event Push Dispatch                       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

✨ Key Features

  • ⚑ Lock-Free Session Multiplexing: Routes messages across servers, threads, and DMs using composite session keys (platform, guild_id, channel_id, thread_id, user_id) with zero lock contention.
  • πŸ€– Multi-Bot Parallel Sharding: Run and control multiple Discord bot identities simultaneously from a single compiled ~20MB binary.
  • πŸ“‰ Scale-to-Zero GC: Inactive sessions automatically flush their state to SQLite and evict worker tasks, reducing idle memory footprint to near zero.
  • πŸŽ™οΈ Songbird Discord Voice: Stream bidirectional Opus/PCM audio directly in Discord voice channels.
  • ⏰ Autonomous Cron Engine: Persistent SQLite scheduler that triggers background agent prompt runs and command executions, pushing results directly to designated Discord channels.
  • πŸ› οΈ Native Tool Suite:
    • PTY Terminal: Execute commands in an isolated workspace (~/.omon/workspace).
    • File Tools: Sandboxed file read, write, and directory inspection.
    • Browser & Web: Chrome CDP control (port 9333), live web search, and text extraction.
    • Model Context Protocol (MCP): Connect to external tools via stdio and SSE.
  • πŸ›‘οΈ Smart Approval Guard: Interactively request user confirmation in Discord via button components before running dangerous shell commands.

πŸ”„ Hermes to OMO Gateway Migration Guide (for LLMs & Automations)

omon-gateway migrate performs the shipped one-click migration from Hermes Agent to OMO Gateway. Run it from the gateway directory so the imported configuration is written to that directory's .env:

# Preview the complete migration without writing files, changing the database,
# signaling processes, or invoking launchctl.
cargo run -- migrate --dry-run

# Import configuration and cron jobs, then retire the Hermes cron stores and gateway.
cargo run -- migrate

The compiled binary accepts the same subcommand (omo-gateway migrate). The default flow runs in this order:

  1. Import Hermes configuration from $HERMES_HOME (default: ~/.hermes), including the root .env, config.yaml, and profile .env files.
  2. Authoritatively rewrite the gateway .env. If .env already exists, its complete previous contents are first copied to .env.bak-<timestamp>.
  3. Synchronize Hermes cron jobs into the gateway SQLite cron_jobs table.
  4. Verify each Hermes job exists in the gateway database, back up each non-empty jobs.json as jobs.json.bak-omon-migration-<timestamp>, and atomically replace its job list with an empty list.
  5. Stop live Hermes gateway processes recorded by the root and profile gateway.lock files. On macOS, matching ~/Library/LaunchAgents/ai.hermes.gateway*.plist services are booted out with launchctl and the plist files are renamed to .plist.disabled so launchd cannot restart them.

The backups and .disabled LaunchAgent files make the file cutover reversible; the original files are retained rather than deleted.

Migration modes

Command Behavior
omo-gateway migrate Full import and cutover. Writes the authoritative .env, imports cron jobs, empties backed-up Hermes cron stores after verification, and stops/disables the Hermes gateway.
omo-gateway migrate --dry-run Read-only projection of configuration, cron, process, and LaunchAgent changes. It performs zero writes and does not run cron synchronization or destructive side effects.
omo-gateway migrate --no-cutover Import only. Writes the gateway .env and synchronizes cron jobs, but does not empty Hermes cron stores or stop/disable Hermes services.

Use --no-cutover when Hermes must remain available during a staged migration. Do not run both gateways against the same bot tokens and cron schedules after the final cutover.

What the importer maps

The command performs these mappings automatically; this table is a reference, not a manual copy-and-paste procedure.

Hermes Location Hermes Key OMO Gateway .env Key Mapping behavior
$HERMES_HOME/.env DISCORD_BOT_TOKEN DISCORD_BOT_TOKEN Preserves the primary token.
$HERMES_HOME/profiles/*/.env DISCORD_BOT_TOKEN DISCORD_BOT_TOKENS Collects non-empty profile tokens in stable order and removes duplicates, including the primary token.
$HERMES_HOME/.env or profile .env DISCORD_ALLOWED_USERS DISCORD_ALLOWED_USERS The root value wins; otherwise the first profile value is used.
$HERMES_HOME/.env or profile .env DISCORD_FREE_RESPONSE_CHANNELS DISCORD_FREE_RESPONSE_CHANNELS The root value wins; otherwise the first profile value is used.
$HERMES_HOME/.env or profile .env DISCORD_HOME_CHANNEL DISCORD_HOME_CHANNEL Preserved; the gateway also treats these as free-response channels at runtime.
$HERMES_HOME/.env or config.yaml DISCORD_ALLOWED_CHANNELS or discord.allowed_channels DISCORD_ALLOWED_CHANNELS Preserves allowed channel filters.
$HERMES_HOME/.env or config.yaml DISCORD_IGNORED_CHANNELS or discord.ignored_channels DISCORD_IGNORED_CHANNELS Preserves ignored channel filters.
$HERMES_HOME/.env or config.yaml DISCORD_ALLOWED_ROLES or discord.allowed_roles DISCORD_ALLOWED_ROLES Preserves authorized Discord role IDs.
$HERMES_HOME/config.yaml model.default / model.name / model.model DEFAULT_MODEL Preserves the configured model identifier.
$HERMES_HOME/config.yaml model.base_url, model.api_key ANTHROPIC_BASE_URL, ANTHROPIC_API_KEY Used when the default model name starts with claude.
$HERMES_HOME/config.yaml model.base_url, model.api_key OPENAI_API_BASE, OPENAI_API_KEY Used for other model names.
$HERMES_HOME/.env or config.yaml APPROVAL_MODE or approvals.mode APPROVAL_MODE The root .env value wins; otherwise the YAML approval mode is used.

Unmapped target keys from an existing gateway .env are preserved during merge; backups are recorded before any modifications.

Cron stores, workspace, and skills

  • Cron stores: Hermes jobs are read from $HERMES_HOME/cron/jobs.json and $HERMES_HOME/profiles/*/cron/jobs.json. OMON_HERMES_PROFILES can restrict the profiles synchronized by the runtime; when unset, the default store and profile directories are discovered automatically. Cron pre-run scripts default to an 1800s (30-minute) timeout, configurable globally via OMON_CRON_SCRIPT_TIMEOUT_SECS or per job via timeout_seconds/timeout.
  • Workspace & Authorized Roots: When OMON_WORKSPACE_ROOT is unset, OMO Gateway isolates terminal and file tools under $HOME/.omon/workspace. Additional authorized directory paths can be configured via OMON_TOOL_ROOTS (colon-separated absolute paths; defaults to $HOME when unset; workspace is always allowed; approval policies and hardline command guards still apply).
  • Skills: OMO Gateway scans $HERMES_HOME/skills (default: ~/.hermes/skills) and ~/.omon/skills for SKILL.md bundles.

πŸš€ Quickstart

1. Build and Run from Source

# Clone the repository
git clone https://github.com/Indosaram/omon-gateway.git
cd omon-gateway

# Configure environment
cp .env.example .env
# Edit .env with your Discord bot tokens and LLM endpoint

# Build and run optimized release binary
cargo run --release

2. Run with Docker Compose

docker compose up -d

3. Run as macOS Background Service (LaunchAgent)

# Build release binary
cargo build --release --bin omon-gateway

# Install LaunchAgent
cp ai.omon.gateway.plist ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/ai.omon.gateway.plist

βš™οΈ Configuration Reference

Environment Variable Default Description
DISCORD_BOT_TOKEN Required Primary Discord Bot Token
DISCORD_BOT_TOKENS Optional Comma-separated tokens for Multi-Bot sharding
DISCORD_ALLOWED_USERS Optional Allowed Discord user IDs (empty allows all)
DISCORD_ALLOWED_ROLES Optional Comma-separated Discord role IDs allowed to interact with the bot
DISCORD_ALLOW_ALL_USERS false When true, bypasses user/role allowlists and grants access to all users
DISCORD_ALLOWED_CHANNELS Optional Comma-separated channel IDs allowed to process messages (DMs exempt)
DISCORD_IGNORED_CHANNELS Optional Comma-separated channel IDs ignored completely
DISCORD_FREE_RESPONSE_CHANNELS Optional Channels where the bot responds without @mention
DISCORD_AUTO_THREAD false When true, @mentions in guild text channels auto-create a public thread and route responses there
DISCORD_THREAD_SESSIONS_PER_USER true When false, all users in a thread share the same conversation session
DISCORD_THREAD_REQUIRE_MENTION false When true, requires an @-mention to respond even in active bot threads
DISCORD_ALLOW_BOTS none Bot handling policy: none (default), mentions (respond only when @-mentioned), all
DISCORD_CHANNEL_CONTEXT false When true, @mentions in guild channels backfill recent channel history as conversation context
DISCORD_CHANNEL_CONTEXT_LIMIT 10 Maximum preceding messages to backfill when channel context is enabled (clamped to <= 25)
DISCORD_CHANNEL_TOPIC_CONTEXT false When true, fetches channel topic and forum parent description as prompt context
DISCORD_CHANNEL_PROMPTS Optional JSON object mapping channel IDs to custom system_prompt and skills
DISCORD_PROCESSING_REACTIONS true When true, adds πŸ‘€ reaction when processing starts, swapping to βœ… on success or ❌ on failure
DISCORD_CHUNK_PAGINATION true When true, adds (i/N) pagination indicator headers to messages split across multiple chunks
DISCORD_RUNTIME_FOOTER false When true, appends a compact runtime metadata footer (model Β· context% Β· cwd) to the final assistant message
DISCORD_PROFILE_ROUTES Optional JSON array of hierarchical profile routing rules mapping (guild, channel, thread) to custom models, prompts, and toolsets
DEFAULT_MODEL gpt-4o Default LLM model identifier
OPENAI_API_BASE https://api.openai.com/v1 OpenAI-compatible endpoint URL
OPENAI_API_KEY Optional OpenAI API key
ANTHROPIC_BASE_URL Optional Anthropic Messages endpoint URL
ANTHROPIC_API_KEY Optional Anthropic API key
DATABASE_URL sqlite://omon_gateway.db SQLite database path (WAL mode)
OMON_WORKSPACE_ROOT $HOME/.omon/workspace Dedicated sandboxed working directory used by terminal and file tools
OMON_TOOL_ROOTS $HOME Optional colon-separated absolute paths authorized for tool access (defaults to HOME; workspace always allowed; approval and hardline guards apply)
HERMES_HOME $HOME/.hermes Hermes root used by migration, cron synchronization, and Hermes skill discovery
OMON_HERMES_PROFILES Auto-discover Optional comma-separated Hermes cron profiles; when unset, synchronizes default plus discovered profile directories
OMON_CRON_SCRIPT_TIMEOUT_SECS 1800 Timeout in seconds for cron pre-run / script executions (default 1800 / 30m; overridable per job via timeout_seconds or timeout)
APPROVAL_MODE smart Enforced terminal approval policy: smart gates dangerous commands, always gates every command, and never/yolo bypass approval
APPROVAL_TIMEOUT_SECS 900 Seconds to wait for a Discord command approval before the request expires (default 900)
APPROVALS_DENY Optional Comma-separated wildcard globs (npm publish *,kubectl delete *) unconditionally blocked before policy, YOLO, or allowlists
DISCORD_APPROVAL_MENTIONS false When true, @-mentions allowed users (<@uid>) on approval prompts for push notifications

πŸ“œ License

Licensed under the Apache License 2.0.

About

Ultra-fast, zero-GC async AI agent gateway and session multiplexer for Discord in 100% Rust

Resources

Code of conduct

Contributing

Security policy

Stars

26 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages