Skip to content
All work
LLM ApplicationLive · 2026

EchoPersona

A voice-driven assistant for queries and task management, with configurable prompt and voice behaviour, persisted conversation history and usage analytics.

  • React
  • TypeScript
  • Supabase
  • Web Speech API
  • Zod

Overview

A browser-based assistant driven by speech as well as text. Recognition and synthesis are isolated behind dedicated hooks, conversation history is persisted per authenticated user, and an admin surface exposes prompt, model, voice and general settings as configuration rather than as constants buried in the code.

Problem

A text-only assistant is the wrong interface when someone's hands or eyes are occupied, and a voice interface built directly against the browser speech APIs leaks their statefulness through the whole application.

Assistant behaviour also needs to change without a deployment. If the system prompt and voice settings are constants in source, every adjustment becomes an engineering task.

Business context

Assistant behaviour is tuned continuously after launch, mostly by people who are not going to open a pull request. Treating the prompt as configuration is what makes that iteration possible.

Conversation history serves two purposes: continuity for the user, and a record that makes it possible to see what people actually ask rather than what was assumed.

Solution

Speech recognition and speech synthesis are each confined to their own hook, with shared types and utilities beside them, so the rest of the application consumes a stable interface instead of the browser's event-driven API surface.

A single assistant context owns conversation state, which keeps chat views presentational and prevents the session from being reconstructed in several places.

Authentication and persistence run on Supabase: accounts, verification and per-user history without operating a separate backend for what is a well-solved problem.

Prompt, API, voice and general settings live in an admin surface, and analytics views surface query volume and the most frequent queries.

Architecture

  1. Input

    Speech recognition

    Web Speech API hook

    Text input

    Chat composer

  2. Session

    Assistant context

    Conversation state

    History context

    Persisted transcripts

  3. Configuration

    Prompt settings

    Behaviour without redeploy

    Voice settings

    Synthesis parameters

    API settings

    Provider configuration

  4. Platform

    Supabase auth

    Accounts and verification

    Supabase data

    History per user

  5. Output

    Speech synthesis

    Spoken response

    Analytics

    Volume and top queries

Browser speech APIs isolated behind hooks, session state owned by one context, identity and history delegated to a managed platform.

Implementation

Recognition and synthesis are separated because they fail independently: a browser may support one and not the other, and permission handling applies only to input. Combining them would force the application to reason about both at once.

Forms are validated with Zod schemas through React Hook Form, so settings that reach the assistant are shape-checked before they are stored.

Server state is handled by React Query rather than by hand-rolled effects, which removes an entire category of stale-data and race bugs from the history and analytics views.

The component layer is built on Radix primitives, so keyboard interaction and focus management in dialogs, menus and popovers come from accessible primitives rather than from bespoke implementations.

Engineering challenges

  • Browser speech APIs are stateful and inconsistent

    Recognition sessions start, end and error asynchronously, and support varies by browser. Confining that behind hooks keeps the inconsistency in one place instead of spreading it through every component that speaks or listens.

  • Behaviour that must change without a deploy

    Prompts are tuned far more often than code ships. Storing them as configuration turns a release into a settings change.

  • Conversation state in several views at once

    Chat, history and analytics all read the same session. A single owning context prevents three subtly different copies of the truth.

Key decisions

A managed platform for auth and persistence
Accounts, verification and per-user storage are solved problems. Building them again would add operational load without adding anything a user notices.
Prompt as configuration, not as code
It moves iteration out of the deployment pipeline and to the people actually tuning the assistant.
Accessible primitives for the interface
Keyboard and focus behaviour is easy to get wrong by hand and expensive to retrofit.

Results

No production metrics are published for this project yet. I would rather show nothing here than a number I cannot stand behind — the architecture and the decisions above are the part worth reviewing.

Technology

Application

  • React
  • Vite
  • TypeScript
  • React Router

Voice

  • Web Speech API
  • Speech recognition
  • Speech synthesis

Platform

  • Supabase auth
  • Supabase persistence

State & contracts

  • React Query
  • React Hook Form
  • Zod

Interface

  • shadcn/ui
  • Radix UI
  • Tailwind CSS
  • Recharts

Contact

Have an AI product or workflow worth building?

Send me the problem — not the spec. If it’s a fit I’ll tell you how I’d approach it; if it isn’t, I’ll say so.

Faisalabad, Pakistan · PKT (UTC+5) · Working remotely