DEV Community

Pavankumar Prajapati
Pavankumar Prajapati

Posted on

DM Polisher — Open-weight AI cold-DM writer for a friend

This is a submission for the Hacktoberfest Weekend Challenge: Build for a Friend

What I Built
DM Polisher — a cold-outreach message polisher built for a friend who kept sending the same templated internship DMs to every company: "I hope this email finds you well… I'm passionate about technology… Would you like to connect?" Zero responses.

DM Polisher turns their saved skills + a target company into a crisp, three-sentence message — hook, proof of work, ask — with no AI clichés. LinkedIn DMs come out short and DM-tight; cold emails get a greeting and a sign-off. The friend saves their profile once; every draft after that reuses it.

Demo
Live: https://dm-polisher.onrender.com/
Video: [VIDEO LINK]

Code
https://github.com/PavanCoderr/dm-polisher

How I Built It

Open-source AI core: meta-llama/llama-3.1-8b-instruct (open-weight Llama 3.1 8B) served through Backboard. Each student maps to one Backboard assistant: its instructions hold the three-sentence writing contract, its memories hold the student's skills, and generation runs with memory: "Readonly" so the model recalls — never rewrites — their context.

Frontend: React 19, Vite 7, Tailwind v4, shadcn/ui, React Router 7
Backend & auth: Convex (queries, mutations, a "use node" action), Convex Auth with guest sign-in

Hosting: Render static site via render.yaml; the generated Convex client is committed to git because npx convex codegen needs a login token CI doesn't have

Resilience: if Backboard is unreachable, a deterministic offline writer in src/convex/mockWriter.ts produces the same structure and the UI flags the draft as degraded — the demo can never dead-end.

Why Does Open Innovation Matter?
Costs nothing to run. The model is open-weight, routed via Backboard — no per-request SaaS bill — and the offline writer is free.

The model is swappable. Two env vars (BACKBORD_LLM_PROVIDER, BACKBORD_MODEL_NAME) re-point the same contract at any open-weight model; prompt, memory, and metrics stay untouched.

Behavior is editable. The writing contract is one editable string in src/lib/backboard.ts, pushed into the assistant's instructions. Closed tooling hides that; open makes it yours.

Memory is inspectable. Skills live as readable memories on the student's assistant, and the data stays in the student's own Convex deployment.

Concrete proof it mattered: v1 called a closed gpt-4o-mini endpoint through an unprovisioned platform key and threw on the first generation. Moving the same contract onto an open-weight model through Backboard fixed the demo and let me see exactly what the model receives.

Prize Categories
Best Use of Render — the app is hosted on Render as a static site (blueprint in render.yaml, zero-state restartable)

Best Use of Backboard — Backboard is the AI brain: assistant per student, skills-as-memories, open-weight model routing, memory: "Readonly" generation

Best Use of ElevenLabs — the demo video is narrated with ElevenLabs voice cloning + Studio

Best Use of GitHub Copilot — GitHub Actions CI (npm run typecheck + build on every push), with Copilot CLI used to review and refine the pipeline

Top comments (0)