DEV Community

Cover image for GigLift: Hinglish job requests in, clear briefs out (Gemma + Django)
Divyansh
Divyansh

Posted on AI-assisted

GigLift: Hinglish job requests in, clear briefs out (Gemma + Django)

Gemma 4 Challenge: Build With Gemma 4 Submission

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle

What I Built

A shop owner in India doesn't write a job posting. They send a WhatsApp message: "logo bana do dukaan ke liye, 1500 tak, Friday tak chahiye".

GigLift is a small job board for students that starts from that message. It turns it into a proper brief: what has to be delivered, which skills it needs, a budget, a deadline, and the questions the owner forgot to answer. The owner fixes whatever is wrong and publishes. Nothing is public before that. Students see gigs ranked by how well they fit their profile and send a proposal, and the owner hires one. Phone numbers show up only after a hire, and payment stays between the two people.

The ones who would pay are small business owners, for a logo, a menu card, eight reels edited or forty pages typed. Usually ₹500 to ₹3,000. The side hustle belongs to the student.

I wanted to fix the brief because a message like that leaves out half of what a freelancer needs to know. The student guesses, quotes blind, and the two of them argue about it later. A clear brief at the start costs almost nothing and heads off most of that.

GigLift itself earns nothing. Nobody has paid through it and no real client has used it yet.

Demo

Live: https://giglift-aa4q.onrender.com

It runs on Render's free tier, so the first visit after a quiet spell can take up to a minute, and the data resets whenever I redeploy. The five gigs marked "(demo)" are seeded. The footer says AI: gemma when the model answered and AI: offline when the fallback did.

Two things worth trying:

  1. Click Post a gig and paste logo bana do dukaan ke liye, 1500 tak, Friday tak chahiye. The budget and deadline in the brief should be exactly the ones you wrote.
  2. Post another with no budget, like 4 posters chahiye shaadi ke liye. The price comes back labelled as a rough guess, and the brief asks for your budget and your deadline.

Code

GigLift

Small paid jobs for students, posted in plain language. A shop owner pastes a messy WhatsApp-style request ("logo bana do, 1500 tak, Friday tak"). GigLift turns it into a clear brief. Students pitch. The client hires. No accounts, no payment fees, free to run.

Django + HTMX, one stdlib-only AI module, MIT licensed.

Live demo: https://giglift-aa4q.onrender.com (free Render tier: the first visit after idle can take up to a minute, and data resets on each redeploy. The five gigs marked "(demo)" are seeded.)

Status: working prototype, deployed. The full flow, security pass and eval below are real and reproducible. Screenshots and a first real user are next. See the roadmap.

Contents

Try

…

MIT licensed. The README has the setup steps, the eval, and a list of what's still missing.

How I Built It

It's Django with HTMX and SQLite, on Render's free plan. All the AI lives in one file, core/llm.py, standard library only, no SDK. The model is Gemma (gemma-4-26b-a4b-it), called through Google's hosted Gemini API with the same free key. If the key is missing or the call fails, rule-based fallbacks take over and the page says so.

Most of the design comes from one thing I learned early: ask a model for a price and you get a price, even when the client never gave one. So I stopped letting it decide numbers. If the client stated a budget or a deadline, a small set of rules in core/extract.py reads it straight out of the text and the model can't change it. The rules cope with English, Hinglish and Devanagari digits: 1500 tak, ₹१२००, parso, agle hafte, Friday tak. If nothing was stated, the model's number is shown as "Rough guess, not from real prices" and the client is asked. If the model writes a deliverable containing a number that isn't in the client's message, I drop that line. What's left for Gemma is the part rules can't do: understand a Hinglish request and write the deliverables and the open questions.

To check it, I wrote 30 briefs by hand (English, Hinglish, Devanagari) and built the rules on them. Then I froze extract.py, whose hash is in eval/FROZEN.txt, wrote 32 new briefs and scored them once.

Held-out, 32 briefs Old regex New rules
Stated budget read right (25) 11 22
Stated budget read wrong 14 0
Budget invented when none given (7) 7 0
Stated deadline read right (27) 8 25
Stated deadline read wrong 19 0
Deadline invented when none given (5) 5 0
Crashes 1 0

Then I ran the whole pipeline with real Gemma behind it, all 32 briefs served by the model: 22 of 25 budgets and 25 of 27 deadlines right, none wrong, none invented. That matches the rules alone, which is the point. Gemma can't change a number the client wrote.

The five misses were paanch hazar (an amount in words), 1800 mein ho jaye, due 25 Oct, and within 48 hours. A miss means the app asks the client. It never shows a wrong number.

What this doesn't show: I wrote both the rules and the test briefs, so the held-out score is optimistic. It also only measures numbers. I haven't scored Gemma's own output yet, meaning the open questions, the skills and the deliverables. That's next, along with real messages from real clients and a delivery check, where the student describes what they handed over and the model marks each deliverable done or missing.

Things that went wrong. My first offline regex crashed on "posters, 4" because it read the "rs" in "posters" as rupees. On Windows my scorer read the briefs with the wrong encoding and mangled the ₹ sign, and the budget score fell from 22 to 16 until I worked out why. Gemma's first replies didn't parse as JSON at all, so for a while every brief quietly fell back to the offline rules and I didn't notice. I rewrote the parser to take the largest valid JSON object in the reply, and the eval now prints which backend actually served the run. I also once posted a screenshot with my API key in it. I revoked it.

I spent an evening on the boring security parts too: a CSP with nonces, rate limits per session and per IP, and ownership checks on edit and hire. There are 24 Django tests, plus 7 more on the rules.

Why Does Open Innovation Matter?

I didn't run a closed model against Gemma, so I won't claim it did better. Here is what open changed for this project.

The design doesn't need a frontier model. Because code decides the numbers, the model only has to read a messy request and write a short brief, and a mid-size open model is enough for that. That makes the model replaceable. I can switch to a different one by changing GEMMA_MODEL.

The money is tight. A job is ₹600. Right now the free API key is what makes a brief cost me nothing, and open weights mean I'm not stuck if that free tier changes. I could run the same prompts on my own hardware.

Privacy matters most to me here, and it's the least finished part. These messages often have a phone number in them. Today the text goes to Google's API, so it leaves my server. With open weights, a shop's message doesn't have to end up inside a closed vendor's system. The Gemma call sits in one function, so pointing it at a model on my own machine means rewriting that function, not the prompts. I haven't built that yet.

Prize Categories

Side Hustle. Gemma is the model, so I'd also like to be considered for any Gemma-related partner category.

Top comments (0)