Skip to content
View yabhinav1's full-sized avatar

Block or report yabhinav1

Block user

Prevent this user from interacting with your repositories and sending you notifications. Learn more about blocking users.

You must be logged in to block users.

Content in all repositories owned by your account will be closed.
Maximum 250 characters. Please don’t include any personal information such as legal names or email addresses. Markdown is supported. This note will only be visible to you.
Report abuse

Contact GitHub support about this user’s behavior. Learn more about reporting abuse.

Report abuse
yabhinav1/README.md

Abhinav

Full-stack developer in Delhi. First-year CSE at JIMS Greater Noida (GGSIPU). Self-taught. Everything below runs in production, and I'm the one who keeps it running, which is where most of what I know came from. The one team build is marked.

Portfolio · Email · Open to internships and freelance work

Now: building out DailyOS, keeping Annie's shards healthy, and looking for a first internship.

Annie Discord bot that replaces six single-purpose bots. 417 commands, sharded, with a Next.js dashboard. annie.monster
DailyOS Personal productivity OS. Eleven modules over one Prisma schema. live · source
The Silent Co-Driver Scores driver stress from F1 team radio. 3rd place, AI Race Month. source · slides

Annie · annie.monster

Annie's dashboard

Closed source. An all-in-one Discord bot that replaces the six single-purpose bots most servers end up running — economy, moderation, music, games, social, community tools.

417 commands (313 prefix + 104 slash) across 23 categories · 29 event listeners · ~125k lines · sharded through discord.js ShardingManager · anti-nuke and automod · a simulated coin market with generated charts.

The dashboard is a separate Next.js app — ~41k lines, 128 API routes — with Discord OAuth2, per-guild config panels so nobody has to memorise command syntax, premium checkout with IPN callbacks, a public status page with incident history, and rendered ticket transcripts.

The bug I'm most proud of fixing

Shards leaked memory on a 2-core container: RSS climbed steadily while the JS heap stayed flat. It wasn't JavaScript.

glibc's mmap threshold is dynamic — it ratchets upward every time a large buffer is freed. So after the first few canvas/sharp image buffers came and went, subsequent large allocations started coming from the arena heap (sbrk) instead of mmap, and arena memory is never returned to the OS.

Pinning MALLOC_MMAP_THRESHOLD_ to a fixed 128KB disables the ratchet — every large allocation uses mmap, which is returned on free. MALLOC_ARENA_MAX=2 stops the container (which reports 16 cores but is limited to 2) from opening ~128 malloc arenas that fragment and never hand memory back.

Both have to be set in code before manager.spawn(), not in .env — glibc and libuv read them at process start, before dotenv ever runs.

DailyOS notes canvas

A personal productivity OS — notes with folders, tasks, projects, calendar, habits, goals, analytics, study mode, focus timer, doodle canvas, and a developer mode. Eleven modules over 34 Prisma models in one schema, so a task can come from a note and a habit can roll into a goal without an integration in between.

Notes carry three editing modes on one record: rich text, a sketch pad, and a freeform canvas you double-click to drop text onto. File bytes live in MongoDB GridFS rather than Postgres, so a large PDF isn't sitting in a row that gets read on every page load.

Next.js 16, Prisma, Neon, Auth.js v5. Vercel behind Cloudflare.

The bug I'm most proud of fixing

Uploading a profile picture signed you out, and everything afterwards crawled. The two symptoms looked unrelated and had one cause.

An uploaded avatar was stored as a data URL — up to two megabytes — and handed to updateSession, which put it on the session token. That token is serialised into a cookie, and a cookie holds about four kilobytes. Auth.js does not fail on that; it splits the token across numbered chunks — authjs.session-token.0, .1, .2 — so every subsequent request carried megabytes of cookie. That was the slowness.

The sign-out was the proxy: it looked for the session cookie by exact name, so the moment the token was chunked there was no cookie by that name, and a signed-in user looked signed out.

Matching the chunk prefix fixes the symptom. The actual fix was keeping the bytes out of the token at all — the jwt callback reads the avatar from the database and puts a URL on the token, and the image is served from a route. No future caller can reintroduce it by passing an image either.

The Silent Co-Driver · source · slides

3rd place, AI Race Month · GrandPrix — two-person team, built in a day.

Driver stress score plotted against lap times

A pit wall watches tyre temps, fuel and sector deltas. Nobody has time to process the one channel that carries fatigue first: the driver's own voice. This reads Formula 1 team radio, scores how stressed the driver sounds 0-100, and lines that score up against his real lap times.

Three Hugging Face models chained — faster-whisper large-v3 for transcription with per-word timestamps, HuBERT for emotion from the sound, DistilRoBERTa for emotion from the words — blended 65/35 in favour of tone, because a driver saying "I'm fine" through gritted teeth is not fine. Vocal energy separates the two ways of not being okay: stress is loud, fatigue is flat. Thresholds are the 90th percentile measured across 63 real clips, not numbers that felt right.

278 laps · 72 radio calls · 4 drivers, one Grand Prix. Radio from a Hugging Face dataset, lap times from the F1 timing feed via fastf1, joined only on a timestamp. FastAPI backend, no framework on the frontend, and every model runs locally so it works with the wifi off.

The bug I'm most proud of fixing

The transcripts looked fine. But on one clip the loudest part of the waveform had no words against it.

Whisper was silently dropping whichever speaker talked first. On real team radio the driver asks and the engineer answers — so we were keeping the engineer's calm reply and throwing away the driver's question. On a project that exists to read the driver's voice, every score was measuring the wrong person, and nothing errored.

vad_filter=True fixed it: voice-activity detection segments the audio before transcription instead of letting the decoder decide what counts as speech. The trade-off is that VAD trims some word starts, so a few transcripts came back slightly worse — a garbled phrase is a much smaller failure than a missing speaker, so we kept it and filtered the garbled ones out of the demo.

The join has a similar story. Lap boundaries were first derived by assuming the race started at 17:10:00 UTC. Lights-out was 17:13:00, so all 34 radio calls sat two to three laps early — and the chart still looked entirely plausible. Only loading the session telemetry and using the real LapStartDate fixed it.

Portfolio · yabhinav.dpdns.org · source

Server-rendered Node with a /admin panel, SQLite via Node's built-in node:sqlite, no build step, two runtime dependencies.


Stack

Frontend Next.js · React · TypeScript · Tailwind · Framer Motion · HTML/CSS · Chart.js
Backend Node · Express · Python · FastAPI · MongoDB · SQLite · Turso · discord.js · Hugging Face
Infra AWS · Oracle Cloud · Vultr · Vercel · Fly.io · Cloudflare · Docker · Linux VPS · DNS · OAuth2 · sharding

A snake eating my GitHub contribution graph

Open to internships and freelance work — yabhinav0011@gmail.com

Pinned Loading

  1. silent-co-driver silent-co-driver Public

    Scores F1 driver stress from team radio with Whisper, HuBERT and DistilRoBERTa. 3rd place, AI Race Month.

    HTML 3

  2. dailyos dailyos Public

    Personal productivity OS: notes, tasks, habits, goals and more over one Prisma schema. Next.js 16.

    TypeScript 2

  3. portfolio portfolio Public

    Server-rendered Node portfolio with an admin panel, node:sqlite, no build step.

    JavaScript 1