Kelas AI

September 2026 to present · Contract engineer, one of two · Voice tutor and onboarding

A wooden school slate with a chalk website sketch and Spark, Kelas AI's golden star guide

Kelas Sekejap is a Malaysian learning site for English, money and careers. Kelas AI is its app for people who have never built an app or website. A learner describes an idea in chat, and an AI builder turns it into a website. I worked on it under contract as one of two engineers, starting with the first commit in September.

Generating a website is the easy part now. The hard part is the learner looking at a screen full of buttons with no idea which one to press. Most of my work went into Spark, the tutor. Spark talks with the learner by voice or text, reads what is on the screen, points at the right control and draws on the page while it explains.

A tutor that can see the page

The first version I built was a chat that shaped an idea into a brief the learner could copy. Live voice came a few days later. The browser asks our server for a short-lived, single-use Gemini Live token, so the real API key never leaves the server, and then streams 16 kHz microphone audio straight to Gemini. Learners can cut Spark off mid-sentence. Calls end after nine minutes and offer to reconnect.

Spark never sees a screenshot. When it needs to act, it reads a summary of the page instead: the visible controls with their positions and shapes, the question on screen, the build step, and any errors. It can only point at controls that are on the screen right now. If a control has gone, the tool call fails and Spark has to say so instead of pointing at nothing.

How Spark sees and acts

Learner
VoiceMicrophone audio as 16 kHz PCM
ActionsClicks, messages, builds and previews
Browser
Screen summaryControls, bounds and shapes. No screenshots
Activity policyMerging, cooldowns and a rate cap
Models
Gemini LiveVoice, with a single-use token
Text SupportTyped replies with the same tools
On screen
Drawing layerOutlines, arrows, labels and spotlights
UI actionsPoint, fill a field, send, copy
Voice and typed Support share one set of tools, and the browser checks every call against what is on the screen.

Drawing on the screen

Pointing was not enough for someone who has never heard the word 'composer'. I built a drawing layer the tutor controls. It can draw outlines that match a button's real corner radius, circles, arrows, underlines, labels, and spotlights that dim the rest of the page. A drawing can attach to an element and follow it as the page scrolls. The page stays clickable underneath, and Escape clears everything.

Spark also reacts to what the learner does. Picking a starter, sending a message, pressing Build or opening the preview each gets a reply in about half a second. A small policy stops it from talking too much. It merges events that land within 0.4 seconds, gives each kind of event a cooldown, and allows six reactions a minute. In a voice call, an urgent reaction can interrupt Spark's own sentence but never the learner's.

The Kelas AI chat screen with the message box outlined by the tutor's drawing layer and voice call controls open above it
An earlier build, with the robot guide that came before Spark. During a voice call the tutor has outlined the message box. Clear at the top removes its drawings.
what the learner says or doeswhat Spark does
"What's happening?"
Explains the current stepFrom the stage, layout, question on screen and build step
"Where is my website?"
Answers from the screen summaryBuild state, preview and version
"What does it do?"
Explains and outlines the controlThe outline matches the control's shape
Presses Build
Comments right awayAbout half a second, within the rate cap
Spark answers about the screen in front of the learner.
A drawing tool callupdateOverlay
// Spark outlines Build, then labels it
updateOverlay({
  mode: "replace",
  objects: [
    { id: "build", type: "outline", targetId: "build-website-button" },
    { id: "tip", type: "label", targetId: "build-website-button",
      text: "Press this when your idea is ready", placement: "above" },
  ],
});

npm run dev:all

Voice and typed Support send the same tool calls, and the browser rejects a target that is not on screen. Locally, npm run dev:all starts the app, database, builder worker and previews.

From first visit to first website

In October I rebuilt the first few minutes. On a new learner's first visit, Spark fills the screen to say hello, flies to its corner and offers to talk, type or be skipped. After sign-up it asks four questions and fills each answer into the form itself. Then it opens Lesson 1 and walks the learner through what the site is for, who it is for and how it should look. Spark pastes the finished prompt into the main box and leaves Enter to the learner, so the first website is one they started.

I also set up the Turborepo monorepo and the one-command local stack, streamed chat replies, showed the builder agent's steps live, and added image and document attachments, image generation in chat, an Astro landing page, and the Settings and Lessons pages. My teammate built most of the hosted builder, the browser sandbox and preview hosting.

The Kelas AI sign-in page with Spark, a small golden star, pointing at Create an account
Spark on the sign-in page, pointing new learners at Create an account.

From hello to a first website

01Meet Spark

A full-screen hello, then talk, type or skip.

02Four questions

Spark asks, then fills each answer into the form.

03Lesson 1

What the site is for, who it serves and how it looks.

04Press Enter

Spark pastes the prompt. The learner sends it.

05Watch the build

The builder agent's steps appear as they happen.

06Spark reacts

It comments on the build and the preview.

Spark fills in forms, but the learner sends the prompt that starts the build.