SIDE PROJECT · CURRENT
LetMeCheckThatBot
A group-chat agent that reads the thread, its media, and its links, then answers in context when called.
It has run in my own friend group since 2022. GroupChatRobot is the same engine, open to any group.
Read, transcribed, and searchable by meaning since 2022.
A hard cap on the model key. It has never been hit.
Messages and their meanings sit in one SQLite file on my own hardware.
44 real job tasks, scored blind against a standard setup and human professionals.
THE REASONING
The bot runs live on Telegram at @LetMeCheckThatBot →



Flashback triggers for low-activity channels
Proactive messages are strictly constrained to prevent unwanted bot noise in active discussions.
- Trigger: a room under twenty messages in seven days. Scheduled broadcasts without activity thresholds create chat fatigue.
- Payload: a past conversation day selected by semantic clustering and scored for engagement.
- Form: contextual recap in verbatim participant quotes.
- Rate: at most once per week per channel.
- Delivery: notification suppressed, surfacing on the next manual channel open without pushing mobile alerts.
GDPval benchmark evaluation across 44 professional tasks 76 model · 70 this harness · 84 human
Benchmark results indicate strong performance on structured professional tasks using lower-cost model configurations.
- The tasks came from GDPval, OpenAI’s set of actual job tasks across 44 occupations.
- Each task ships a human professional’s own finished work and an expert grading checklist.
- Claude Sonnet 4.6, a model from a different company, scored the machine’s work and the human’s the same way.
- One task from each of the 44 jobs.
- Standard setup 76. This bot’s own harness 70. Human experts 84.
Every task, output, and score is published, so you can judge it yourself in the benchmark explorer.
Chat archive privacy and data isolation
This page is an architecture record, not a public data set. Screenshots depict synthetic test messages and isolated personal testing chats. The database, user memory vectors, and raw chat logs are isolated in host volume mounts.
Message IDs from desktop Telegram exports are client-specific in basic groups, so archive-only rows cannot serve as native reply targets.
In benchmark runs, mathematical and tabular outputs are cross-verified against deterministic validators to prevent unnoticed arithmetic hallucinations.
Agent loop architecture, tool inventory, and model tiers
The core execution pattern runs an augmented language model sequentially in a bounded tool loop:
- Read recent context, determine next action, invoke a tool, parse tool output, and evaluate stopping conditions.
- A maximum limit of six tool iterations bounds latency and prevents recursive searching.
- Remaining iteration counts are passed into each prompt to encourage timely synthesis.
THE 25 TOOLS
- Web search, article scraping, screenshot capture, and forum retrieval.
- Video downloading and timestamped segment clipping via yt-dlp.
- Multimodal OCR and image inspection.
- Sandboxed Python execution for charts and tabular analysis.
- Local Whisper speech-to-text and Kokoro text-to-speech audio synthesis.
- Semantic vector search over conversation history and group polling.
THE MODELS UNDERNEATH
Model calls route through OpenRouter.
- Primary: MiMo v2.5. High-context tool-calling runner capped at $5 monthly usage.
- Hosted fallback: Gemini 2.5 Flash Lite. High-availability failover on primary outage.
- Local fallback: Functionary. Small local model providing bounded core tools offline.
- Vision: GLM-4.6V. Purpose-trained for document and UI analysis.
Malformed function calls are parsed with regex fallbacks and normalized before execution, preventing avoidable loop exits.
Local semantic memory using SQLite vector embeddings
WRITING IT DOWN
- Once the translators return text, the row goes to a single background worker.
- The worker calls Qwen3-Embedding-0.6B quantized to Q8, shrunk so it runs on modest hardware for a sliver of precision, on Ollama, which runs models locally, same ThinkPad, and gets back 1,024 numbers: the message’s coordinates in meaning-space.
- That vector, a list of numbers capturing the message’s meaning so similar ideas land near each other, is written into the message’s own row in SQLite, a database that lives in a single file with no server to run, next to the text. No separate vector database, no embedding API.
- One call at a time, so it never crowds the GPU Penny is also using.
WHY LOCAL
- Every message that lands has to be embedded, so the embedding model is a runtime dependency. A model on my own shelf cannot deprecate its weights, rate-limit me, or go down at the wrong moment.
- Cost is the smaller half, and it is real: more than 100,000 messages through a hosted API would have been a recurring bill.
GETTING IT BACK
- Recall blends keyword and meaning.
- Embed the question once, then a binary-quantized sqlite-vec index, a vector-search extension inside that same SQLite file, retrieves candidates from that room.
- Re-score those against the full 1,024-dimension vectors, then merge the strongest hits with exact keyword matches.
- So “that thai place” finds the right night whether you remember the words or only the feeling.
- The index lives in the same file and is replaceable. The full vectors are the durable asset.
- It also sketches each regular from their own messages, so it knows who is in the room before it speaks.
The result is multimodal retrieval-augmented generation over the group chat, meaning it fetches the few relevant memories first and answers from them rather than guessing, for images and audio as well as text: the room’s whole history, in every modality, instead of the last fifty lines.
Supported document, media, and link parsing
Goes in → becomes text
- text
- read in place
- voice note
- Whisper, to a transcript
- photo, screenshot
- vision, read word for word
- pasted link
- headless browser, full page
- video link
- yt-dlp, title and transcript
- video, GIF
- sampled into frames
- any file
- contents pulled in
Comes back → in any format
- an answer
- in the thread, with a source
- a native reply
- quoting the exact old message
- a video or clip
- found and posted as the file
- a meme
- built and dropped in
- a voice memo
- spoken aloud, on the laptop
- a built file
- spreadsheet, doc, chart, pdf
- a quick poll
- an either-or, to the room
- Pasted link: opened in headless Chromium, a full browser running invisibly with no window, scrolled the whole way to wake the lazy-loaded parts, captured top to bottom.
- Video link: yt-dlp, an open command-line tool for video metadata, pulls title, channel, description, and transcript.
- Screenshot or image: a vision model, an AI model that reads what is in an image, transcribes the words inside it verbatim.
- Video or silent GIF: sampled into unique frames and read across them.
- Voice note nobody played: a local Whisper container, running an open speech-to-text model, returns a transcript.
A search snippet is a lead, not evidence, so a pasted link gets opened. These four are live full-page grabs through the bot’s own browser, including this page.