ഫ്രെയിമിന് പുറത്ത്

Framinu Purathu

Upload a photograph. It grows a personality, a grudge, and a mouth — then it argues with you out loud, in Malayalam, because you woke it up for no good reason.

a portrait gallery that finally talks back

Chapter One

The Problem (That Doesn't Exist)

Photographs have sat in galleries for decades in total silence, holding the same pose, saying nothing. Nobody has ever asked how the appam feels about being photographed instead of eaten. Nobody has checked whether the Mona Lisa is tired. Nobody has considered that your plastic chair has four legs and still cannot walk out of the frame.

Worse: nobody has ever been roasted in fluent Malayalam by their own furniture. A gap in the human experience, frankly overdue.

est. TinkerHub Useless Projects
first attempt: portrait had no opinions.
second attempt: portrait had too many opinions.
we called it balanced. 🪶
Chapter Two

The Solution (Nobody Asked For)

We gave the photograph a mouth, a grievance, and strong opinions about your photography. Hold space, talk, and it answers — in character, under twenty words, with theatrical comic timing.

<20 wordsper reply, theatrical pauses included
3×unprompted nudges before it gives up on you
₹0.30per reply, measured not guessed
Chapter Three

Ingredients for the Potion

No agent framework, no RAG, no 3D engine, no vector database. Twenty-one throwaway spike scripts and a great deal of stubbornness.

Cauldron Base

  • TypeScript 5.9 (strict), Node 22, Express 4.22
  • React 18.3 + Vite 6.4 on the front end
  • Web Audio API, AudioWorklet, hand-rolled SVG — no animation library
  • Redis for character cards and transcripts (optional, degrades gracefully)

Deliberately Left Out

  • No state manager, no UI kit
  • No RAG, no vector database, no agent framework
  • No 3D engine, no video generation
  • No lip-sync — this is audio-reactive puppetry, and proud of it
RoleServiceModel / Voice
Speech + conversationAzure AI Foundry Voice Livegpt-realtime-2.1
Malayalam synthesisSarvam AIbulbul:v3 — tarun / roopa
Image understandingAzure AI Foundrygpt-5.6-sol
Fallback synthesisAzure Speech TTSml-IN-MidhunNeural / SobhanaNeural
gpt-realtime doesn't list Malayalam. Gemini Live doesn't support it at all. Azure's two Malayalam voices can't code-mix. Sarvam could. that's the whole plot twist. 🧪
Chapter Four

The Marauder's Map

I solemnly swear the key never leaves the server.

Your mic → AudioWorklet → PCM16
↓
Node server (holds every API key)
↓
Azure Voice Live
speech-to-text + reply
Sarvam Bulbul v3
Malayalam speech out
↓
Speakers ← playback ← AnalyserNode → mouth openness
↓
Azure vision model reads the photo · Redis remembers the character
Voice Live has no token exchange, so the key can never touch the browser. found this out the hard way, before shipping — not after. 😅
Chapter Five

The Pensieve

Three memories worth extracting. The full run lives in the demo video and one minute of npm run dev.

🖼️ Memory One

The landing screen resumes a session: "നിന്റെ ചിത്രം ഓർത്തുവെച്ചു" — it remembered your picture, so you're not back at square one after a reload.

👁️ Memory Two

The character on stage, named മോനാലിസ. The eyes and mouth are SVG overlays that track your cursor and blink on their own — no video generated per reply.

🗨️ Memory Three

Mid-conversation, reconnected: it addresses you by name and carries on the exchange instead of reintroducing itself. Push-to-talk, an escape lunge, and a type-a-question fallback sit below.

Chapter Six

The Unbreakable Vow

The roasting has a boundary, and the character cannot be talked out of it.

Fair game

Talking to a photograph instead of doing something useful. Your questions. Your lighting. Your impatience.

Never a target

Body, appearance, caste, religion, region, family, gender, age, disability, money. Private individuals are never named or given an invented life story.

this rule lives inside the prompt, not the UI. easy to skip, harder to enforce — took longer than the jokes did.
Chapter Seven

Why the Real One Isn't Behind This Page

Read before assuming this is just a lazy static deploy.

  1. The model has a ceiling. Ten requests a minute, provider-side. One conversation is one session — a few visitors at once would exhaust it, and hosting only makes that ceiling reachable by strangers.
  2. There is no login. A public URL would sit an unauthenticated door in front of live API credentials. It needs a concurrency cap and per-IP limits first.
  3. Microphones need HTTPS. A plain LAN address won't grant mic access — no shortcut around real hosting or a tunnel.
  4. The key can't move to the browser. Voice Live has no short-lived-token exchange, so every credential stays on the Node server for the whole conversation. Shipping it to the client would hand a permanent secret to every visitor — which is also why this static page cannot secretly be the whole app.

So: this page explains it, the demo video shows it talking, and npm run dev has the real thing running locally in about a minute.

The House

Team CusCus

College of Engineering Chengannur

Voice, Backend & the Provider Chase
Athul Krishna
Team Lead — Node server, provider evaluation, speech synthesis, character prompts
Face, Frame & the Living Mouth
Rinto Cherian
React client, mouth editor, audio capture & playback, animation