// autopilot
Autopilot
Autopilot is kesarAI's AI-driven scanner for images, videos, and URLs. It's the probabilistic counterpart to the rule-based automod: where automod fires on exact patterns and counters you can audit line by line, Autopilot grades media with vision and language models and acts when a confidence threshold is crossed. The two systems run in parallel — automod catches the deterministic offences (slurs, link spam, mention bombs); Autopilot catches the content humans look at and react to (gore, nudity, slurs burned into a GIF template, malicious URLs).
Overview
Everything is off by default. Autopilot costs money to run — every scan calls a paid Google API — so the bot ships in a state where no scan ever happens until an administrator opens /autopilot and turns at least one toggle on. Open the panel with:
/autopilot # configure scanning, sensitivity, actionsThe command requires Discord Administrator. You can also drive every setting from the dashboard at kesarai.ch/dashboard/autopilot. Both paths write to the same store; whichever you change last wins.
What gets scanned
Autopilot inspects three sources on every non-system message:
- Attachments — files uploaded directly to Discord. MIME comes straight from Discord, so the routing (image vs animated vs video) is exact.
- Embedded media — images linked via
imgURLs in rich embeds, including webhook posts. - URLs in message content — every link in the message body gets checked against Google Web Risk if URL scanning is on.
Before any of that, a size / dimension filter drops images that aren't worth a paid scan:
- Images smaller than 5 KB(default) get skipped — that's the bytes floor where stickers, avatars, and tiny embed thumbnails live.
- Images smaller than 100 × 100 px (default) get skipped — same reason from the other direction.
Both thresholds are tunable from the dashboard's Cost guardrails subsection. The filter runs before any HTTP call, so filtered media costs nothing.
The pipeline (May 2026 cost overhaul)
The pipeline used to call Vision SafeSearch, Vision OCR, and Gemini multimodal on every image — three paid round-trips and three CDN downloads of the same JPEG. Posted the same meme twenty times in a row? You paid for it twenty times. The May 2026 redesign rebuilt this around four ideas — same detection, just stop paying for redundant work.
Single download, fanned out
When a scan starts, the image is downloaded once and the bytes are passed to every engine that needs them. Vision SafeSearch, Tesseract OCR, and Gemini multimodal all accept pre-downloaded bytes; no engine re-fetches the URL. A new vision_combined_urlpath further batches Vision's SafeSearch and OCR into a single HTTP round-trip when both run.
SHA-256 dedup cache
The bytes are hashed and looked up in a 24-hour in-memory LRU cache (10,000 entries). A hit reuses the prior verdict — zero paid API calls. The log embed surfaces this as a ⚡ cached (3h ago) diagnostic so admins can see when a repeat post got a free ride.
The cache is intentionally in-memory — restart warms back up in minutes from actual server traffic; persisting it would mean shipping 100+ MB of JSON for active servers. The cache is enabled by default; toggle it off under Cost guardrails if you specifically want every image scanned fresh.
Vision-confidently-bad shortcut
If Vision returns adult=VERY_LIKELY or violence=VERY_LIKELYon the first pass, Autopilot skips the Gemini second opinion entirely — Vision is already decisive, no need to pay twice. (Racy is excluded from this shortcut because it's over-eager and often disabled.)
Static vs animated split
GIFs and short videos used to be shoehorned through the static-image path. They're now their own pipeline: Pillow extracts frame 0 as a JPEG for Vision and Tesseract, while Gemini gets the full animated bytes so it can read motion. The log embed renders the original file inline so it actually animates rather than showing as a download link.
The cost numbers
On a representative test guild the redesign cut weekly spend from roughly $24/wk to $3–5/wk. The exact saving depends on your duplicate-rate and how much sticker / avatar traffic the size filter catches. The protection level didn't change — the same image that flagged before still flags.
Sensitivity tiers
Five categories, four levels each. Levels are off · low · medium · high, mapping to Google's likelihood ladder. A scan fires when either Vision or Gemini returns at least the configured threshold for that category (an OR-gate).
- Adult — true nudity. Vision
adult+ GeminiSEXUALLY_EXPLICIT. - Racy — suggestive imagery. Vision only (Gemini has no equivalent threshold).
- Violence — gore. Vision
violence+ GeminiDANGEROUS_CONTENT. - Hate speech — slurs in image text. Gemini
HATE_SPEECHapplied to OCR output (or read natively if you're on the new OCR default). - Harassment — personal attacks in image text. Same flow as hate speech but Gemini
HARASSMENT.
OCR pipeline (five modes)
OCR used to be a single boolean: on, paid, expensive. The new system is a ladder where each step trades cost for coverage. Fresh installs default to off; legacy guilds with ocr_enabled=true migrate to vision-ocrso behavior doesn't change behind your back.
Mode Weekly cost What it does
─────────────────────────────────────────────────────────────────────
off (default) $0 Gemini multimodal reads image text
natively as part of the safety call.
Slur-on-image still flags.
tesseract $0 Local OCR → automod word-ban match.
No Gemini safety on extracted text.
tesseract+gemini ~$1 Tesseract + Gemini Flash-Lite safety
ratings on the extracted text.
gemini-only ~$2 Force a Gemini multimodal pass even
when Vision is clean. Belt-and-braces.
vision-ocr ~$12 Legacy: Vision OCR + Gemini text-scan.
The old default. Most expensive.The OCR word-ban check toggle (independent of mode) cross-references any OCR-extracted text against your automod word-ban list. A match force-fires the configured action regardless of the sensitivity threshold — a banned word inside a screenshot still gets deleted.
Per-channel scan tiers
On top of the per-media-type master switches (Scan images / Scan videos / Scan URLs), each channel can run at one of three scan tiers:
- off— Autopilot skips this channel entirely. No download, no API call, no log entry. Useful for an intentional NSFW channel you don't want actioned, or a high-volume meme channel where false positives outweigh the catch rate.
- basic — Vision SafeSearch only, no Gemini second opinion. Cheaper, slightly higher false-positive rate on edge cases.
- full (default) — the OR-gate with Vision and Gemini both consulted. Maximum coverage; what every channel runs unless you say otherwise.
Configure overrides from either /autopilot(Discord) or the dashboard's Per-channel scan tierssubsection. Both write to the same store. Channels you don't list use full automatically.
Actions
When a category fires, Autopilot can take one or more actions, picked from the Media actions field:
- delete — remove the offending message.
- dm — DM the user a short explanation of which category fired.
Leave both off to run in log-only mode — every scan still posts to the log channel, but no message is touched and no user is DMed. Useful for a week of supervised tuning before going live.
Budgets & guardrails
Three cost guardrails sit on top of the per-scan optimisations:
- Image dedup cache — the 24-hour SHA-256 cache described above. On by default; you can switch it off under Cost guardrails if you specifically want every image scanned fresh.
- Min image size / dimensions — the 5 KB and 100 × 100 px floors. Stickers, avatars, and emoji uploads never reach a paid engine.
- Daily scan budget— default 3000 scans / 24h, rolling UTC. Once exceeded, further scans are dropped and a single warning fires per hour into the bot's log. Your wallet doesn't get a surprise bill if a raid floods a channel with attachments.
Bots and webhooks are skipped by default. Flip Moderate bots on if a bridge bot or webhook is being abused. Whitelisted roles also bypass scanning entirely; use this to exempt staff who post moderation screenshots that would otherwise trip the gore category.
The log embed
Every scan posts to the configured log channel. The embed is structured into three groups:
- Decision — verb-first title (🗑️ Deleted, 🚨 Flagged, ⚡ Reviewed (cached), ✅ Reviewed), the action taken, and which categories breached threshold.
- Evidence— a unified per-category table showing Vision's verdict, Gemini's verdict, and the overall call. If OCR ran, an excerpt of the extracted text. If the word-ban check fired, the matched phrase.
- Diagnostics— which engines actually ran (so you can see the Vision-confidently-bad shortcut take effect, or a cache hit), the cache state with age, the channel's scan tier, any skip reason (size / dimensions / tier-off), and a jump link to the original message.
Static images render inline in the embed; animated content is attached as a raw file so Discord plays it below the embed. Turn on Log all scansto see clean scans too — useful when you're initially tuning thresholds.
What's not scanned
- DMs to the bot — Autopilot only runs inside guilds.
- Bot messages— including kesarAI's own (hard-coded self-immunity so log embeds can't loop back into the scanner) and other bots, unless you flip the Moderate bots toggle.
- Members in a whitelisted role — exempt entirely; covers staff posting moderation context.
- Channels at scan tier
off— Autopilot doesn't even download the media. - Images below the size / dimension floor — stickers, avatars, tiny embed thumbnails.