🗣️ AIVoice — an assistive conversation voice

A web app that lets a nonverbal person take part in a conversation by choosing from response options the AI generates, rather than speaking.

The verbal partner says something → an "AI ear" listens → it offers the person several ways to reply (agree, stay neutral, gently push back, ask a question, keep it light, or share an opinion) → the person (or a trusted person) taps the option that fits. That chosen reply is their voice.

Why it works

Human talk is largely predictable moves — agreeing, staying neutral, disagreeing, showing interest, keeping it light, steering. AIVoice turns each of those moves into a selectable option, so a person who can't speak is expressing the same conversational intent, just by choosing.

Feature rundown

  • Chat interface — verbal partner's words on the right, the person's chosen replies on the left (tagged with the direction they chose).
  • Response options — 4-6 different conversational directions to pick from on every exchange.
  • Typed replies — a trusted person can type a custom reply on their behalf.
  • Speech-to-text 🎤 — the verbal partner can speak instead of typing (browser Web Speech API, no key).
  • Text-to-speech 🔊 — every message can be read aloud, each option can be heard before choosing, and the chosen reply is spoken automatically — the person's voice.
  • Profile — name, age, closeness, personality traits, likes, a long free-form "about this person" field (more detail = better responses), and which directions to offer.
  • Age-appropriateness is enforced — it's written into the system prompt as a hard rule. A 20-year-old profile gets 20-year-old language; a 6-year-old profile never gets adult language, no matter what the conversation partner says.
  • Multiple LLM providers — OpenAI, DeepSeek, OpenRouter, Ollama (local), Anthropic, and Gemini, plus a built-in no-key demo provider so you can try it instantly.

Try it

Live at https://aivoice.val.run — open the Profile & Setup tab first to describe the person (especially age), then use the Conversation tab.

Architecture

Rendering mermaid diagram...

Setup (environment variables)

The demo provider works with no configuration. To use a real LLM provider, add the matching key in the val's environment settings — the provider then produces responses tailored to the person's profile:

ProviderEnv vars
OpenAIOPENAI_API_KEY · OPENAI_MODEL (opt)
DeepSeekDEEPSEEK_API_KEY · DEEPSEEK_MODEL (opt)
OpenRouterOPENROUTER_API_KEY · OPENROUTER_MODEL (opt)
OllamaOLLAMA_BASE_URL (point at a reachable/tunneled endpoint; http://localhost:11434/v1 is the default) · OLLAMA_MODEL (opt)
AnthropicANTHROPIC_API_KEY · ANTHROPIC_MODEL (opt)
GeminiGEMINI_API_KEY · GEMINI_MODEL (opt)

Pick the provider inside the Profile & Setup tab. If the chosen provider is unreachable or lacks a key, the app falls back to the demo provider so a conversation never hard-stops.

Files

index.ts                  Hono server (frontend + JSON API)
store.ts                  Types + SQLite (profile, conversation, pending options)
llm.ts                    Multi-provider LLM abstraction + demo provider
prompts.ts                Direction taxonomy + age-appropriate prompt building
frontend/
  root.tsx                HTML shell
  index.tsx               React entrypoint
  components/App.tsx      Chat + profile UI

Privacy & tuning

Conversations and the profile are stored in the val's own project-scoped SQLite database, isolated to this val. To keep the VULNERABLE edge cases clear: a caregiver writing a child's profile should keep the age field accurate, since it is the strongest guard rail for language level.