Skip to content
Back to work
Next.js / GenAILive · v1.0.0 · March 2026

MIA

10-persona educational AI assistant

MIA multimodal intelligent assistant interface
10
AI personas
2
Languages (ES / EN)
10
Conversations kept per agent
5
File types parsed

The problem

One generic chatbot can't serve a 9-year-old on the Peruvian primary curriculum, a student prepping for the UNI entrance exam, a small-business owner navigating SUNAT paperwork, and an engineer debugging SQL — the tone, language, and guardrails are different for each. And a frozen model can't answer 'what are the current requirements?' questions that Peruvian bureaucracy personas get asked constantly.

Architecture

01 · Personas
  • 10 agents · 4 categories
  • Per-agent system prompt
  • ES / EN per persona
02 · Input
  • Text · voice (Web Speech)
  • PDF · DOCX · XLSX · CSV
  • Server-side extraction
03 · Chat runtime
  • OpenAI streaming
  • Function calling
  • Markdown render
04 · Tools
  • Google Custom Search
  • Model decides when
05 · Persistence
  • S3 conversations
  • Last 10 per agent
  • HTML export · TTS out
MIA — persona-routed streaming chat with on-demand searchSearch is a tool call, not a habit — the model invokes it only when a question needs current information.

What it does

MIA is a bilingual educational assistant with 10 specialized personas across four categories — Education (primary school, pre-university exam prep, English certification), Business (MYPE consulting, Peruvian bureaucracy), Programming (R, Python, SQL) and General (learning companion, evidence-based parenting). Each persona carries its own system prompt and language, and conversations stream in real time with markdown rendering.

  • Agent grid landing page grouped by category
  • Last 10 conversations per agent auto-saved to S3
  • Chat export as formatted HTML; installable PWA with full dark/light OKLCH theming

Rebuilt from R Shiny

v1.0.0 is a full migration of an earlier R Shiny chatbot — the app this portfolio previously linked on shinyapps.io — onto Next.js 16 with React 19 and TypeScript: streaming-first, mobile-installable, and cheap to host on Vercel instead of a Shiny server.

Search when the model decides

The chat route exposes Google Custom Search via OpenAI function calling — the model chooses when a question needs current information (exam dates, government requirements) and when it doesn't, so most turns cost nothing extra and searches happen only on demand.

Voice and documents

  • Web Speech API voice input with Spanish/English detection matched to the persona
  • Per-message text-to-speech playback
  • File uploads with server-side extraction — PDF (pdf-parse), DOCX (mammoth), XLSX/CSV (xlsx), and images

Accounts done properly

  • Public signup disabled — only admins create accounts, bootstrapped by a CLI script
  • Role-based admin panel to add, edit and remove users
  • JWT (jose) with bcrypt and httpOnly cookies
  • All user and conversation state in S3 under a key prefix — no database

Stack

Next.js 16React 19TypeScriptOpenAI (streaming + function calling)Google Custom SearchWeb Speech APIAWS S3JWT (jose)