Frontend Guide
The React/Vite console is a local test and operations UI for the Voxos API. It uses Firebase client authentication, obtains an ID token from the signed-in browser user, and sends that token to authenticated API routes.
The native Flutter app provides the signed-in chat and voice experience on iOS and Android.
The web frontend loads Firebase configuration from its selected API’s
/api/client-config response. Configure FIREBASE_WEB_APP_ID on that API.
Production images use the browser’s current origin by default; local development
can set VITE_API_BASE_URL. Server selection retains independent Firebase
sessions for different configured projects. The optional public Logo.dev key
is supplied through /runtime-config.js.
Navigation
Section titled “Navigation”The signed-in app exposes these pages:
| Page | Route | What it is for |
|---|---|---|
| Chat | /chat |
Text chats, streaming replies, per-chat provider/model overrides, tool activity, and exact ?chat=<id> links from background work. |
| Voice | /voice |
LiveKit voice sessions, room details, transcripts, and events. |
| Agent | /agent |
Default agent identity, voice defaults, and text defaults. |
| Knowledge | /knowledge |
Memories, skills, task plans, and account improvements. |
| Operations | /operations |
Active runs, schedules, agent webhook setup, run history, and live events. |
| Providers | /providers |
Central text and voice provider credentials. |
| Phone | /integrations |
Twilio and Telnyx setup, phone numbers, Telnyx readiness/repair, message/call activity, and WhatsApp linked-device setup. |
| Contacts | /contacts |
People, E.164 phone numbers, and caller-access flags. |
| Connection | /connection |
LiveKit credentials and frontend connection mode. |
| Tools | /tools |
Preferred provider routes for the default agent plus internal built-in tool grants. |
| MCP | /mcp |
Remote MCP server catalog, setup, auth, test, and grants. |
| Browser Accounts | /browser-accounts |
Built-in local or Browserless encrypted website credentials and Browser Use managed profiles, editable labels and exact website/login origins, Browser Use country, agent assignments, credential replacement, reauthentication, revoke, and delete. |
| Account | /account |
Current Firebase user, foreground location opt-in, server selection, and sign-out. |
Exact Chat links load their requested active chat directly, including chats older than the recent-chat sidebar window. A deleted or unavailable link falls back to the most recent chat with a visible explanation.
Chat labels saved, incomplete assistant responses as Partial reply. The response remains visible after refreshing or reopening the chat, while run activity shows the failure.
Signed-In UI Verification
Section titled “Signed-In UI Verification”The current page labels and workflows were verified in a local signed-in browser session on 2026-07-05. The route sweep confirmed the sidebar labels, account email display, and these route-specific sections:
- Chat: saved chats list, text provider and model overrides, one composer for messages and image requests, generated assistant images, run-aware stop control, and activity stream. Provider keys are saved on Providers.
- Voice: provider readiness, LiveKit toggle, room, participant, agent name, microphone setting, transcript panel, text panel, and event log.
- Agent: identity form; voice provider/model/pricing/voice/language/instructions; text provider/model/pricing/language/instructions plus the allowed and default subagent model controls; and an independent image-generation provider and model default. Image model details distinguish model capability from the hosted API’s generation or editing support, show current pricing guidance, and link to provider documentation. Text model choices use the same API catalog as Chat, and their detail panels list image input, tool-calling, and browser-use capabilities; choosing a default subagent model also enables it in the allowlist.
- Knowledge: memories, skills, task plans, and improvements with owner review and undo.
- Operations: active, scheduled, webhooks, history, and events tabs. Schedule creation can
select a same-agent chat or create a new task chat, and has an optional ready
stored-credential local or Browserless account selector filtered to the
selected agent’s assignments. Linked schedules and run details open their
exact chat. Webhook setup binds an agent and fixed instruction, shows a new or
rotated bearer token once with a ready-to-copy
curl, and supports enable, disable, token rotation, and deletion. A relative route is shown safely when the API has no configured public base URL. - Providers: credential cards for voice and hosted text providers, plus an OpenAI-compatible text card with a policy-allowed base URL, explicit model IDs, and optional bearer API key. Compatible OpenAI, xAI, and NVIDIA text credentials are also used for image generation; OpenAI and xAI credentials remain shared with their voice runtimes.
- Phone: Twilio credential form, Telnyx phone setup form, connected resources, and the WhatsApp linked-device panel.
- Connection: LiveKit credential form and token endpoint/sandbox/manual modes.
- Tools: action-level preferred-provider selectors plus built-in read-only and mutating internal tool grant toggles.
- MCP: catalog categories, custom server form, server list, auth/test/grant flow.
- Browser Accounts: recommended built-in local provider or optional Browserless
and Browser Use connection selection, public HTTPS and reviewed SSO origins,
Browser Use two-letter country, assignments that default off, local or
Browserless username/password submission and
replacement, Browser Use manual non-recorded sign-in, safe status metadata,
reauthentication, revoke, and delete. Connections missing
browserless_agentorrun_sessionare excluded from the selector with a direct recovery link to MCP settings, before website credentials can be submitted. - Account: signed-in Firebase email, Firebase user id, foreground location opt-in, active server, and sign-out button.
The Contacts route and its create/edit/delete states were verified from source and automated frontend tests on 2026-07-13. The signed-in browser route sweep has not yet been rerun for that page.
On 2026-08-25, the Operations webhook setup route and one-time credential panel were verified from source, a focused component test, frontend lint, and a production build. A local Firebase API sign-in check succeeded. The available browser sessions reached the sign-in gate, so the signed-in visual route sweep was not rerun for this tab.
On 2026-08-08, a signed-in local Chrome check confirmed the Browser Accounts route, its provider-neutral setup copy, and the optional Browser Account selector on Operations > Scheduled. The local account had no configured browser provider, so Browserless-specific username/password and credential-replacement states were verified through component tests rather than a real provider login.
On 2026-08-09, a signed-in local Chrome check confirmed that Chat no longer renders a per-message Browser Account selector and that Operations > Scheduled still renders its optional Browser Account binding. Focused frontend tests cover direct message sending without an approval request and the retained schedule selector.
The Telnyx readiness/activity card, full phone identifiers, explicit Repair confirmation, and recent message/call states were verified from source and focused frontend tests on 2026-07-15. Message rows now distinguish reply generation, dispatch, provider acceptance, delivery, failure, suppression, and ambiguous submission, and show the safe estimated segment count. A signed-in browser and real carrier smoke test have not yet been run for those states.
The WhatsApp panel was verified from source and focused frontend tests on 2026-07-21. It lists eligible Twilio/Telnyx numbers in full, offers Telnyx users Verify with a call, offers Verify with SMS, and keeps a direct It is already registered path. During registration it polls the no-store backend state, shows a captured numeric code and its channel, provides copy, wrong-code dismissal, and cancellation actions, and explains that the user must enter the code in WhatsApp Business. It then supports QR or pairing-code linking, hides temporary link codes while settings are read-only, regenerates expired challenges, and polls until authoritative backend validation changes the state to connected. It also surfaces reconnecting, capacity, relink, failure, and disconnect-cleanup states. A signed-in browser plus real WhatsApp Business handset link has not yet been run.
The current OpenAI, Google, and xAI model catalogs, model pricing summaries, recommended defaults, and text subagent allowlist/default controls were verified from source and focused automated tests on 2026-07-27. OpenAI text choices include the GPT-5.6 tiers, GPT-5.5, GPT-5.4 mini, and GPT-5.4 nano; GPT-5.4 mini is the primary text default. A new signed-in browser route sweep has not yet been run for these controls.
The image-generation defaults and their separate provider catalogs were verified from source and focused API and frontend tests on 2026-08-17. The catalogs contain GPT Image 2 for OpenAI, the quality and economical Grok Imagine image tiers for xAI, and FLUX.2 Klein 4B, FLUX.1 Schnell, and FLUX.1 Dev through NVIDIA NIM. The saved image provider can differ from the active text provider. Without an explicit choice, an enabled NVIDIA credential selects hosted FLUX.2 Klein 4B automatically; hosted edits route to an enabled OpenAI or xAI editor because NVIDIA’s hosted preview does not accept arbitrary private references.
The Chat Stop run control was verified from source and focused frontend
tests on 2026-07-27. It reads the server-issued run ID from the active stream,
requests durable cancellation, and aborts the stream so an in-flight provider
or every tool request in an active parallel batch is interrupted. The server
also treats a disconnected inline stream as cancellation, and the activity
model distinguishes run_cancelled from run_failed. A signed-in browser
smoke test has not yet been rerun for this control.
Dedicated subagent chats and their parent-chat delivery were verified from source and focused frontend tests on 2026-08-02. Their delegated prompts and responses are labelled Delegated task and Subagent from persisted transcript sources instead of being presented as user-authored messages. Parent chat loading includes recent child status, output, runtime events, and tool events. While a child is active, the UI polls only delegated-run summaries; it reloads the full chat once after all children finish. New child results are durable parent transcript messages with a correlation key that suppresses the legacy output projection, while tool events remain in Activity. A signed-in browser reached the local Chat shell on 2026-08-02, but the disposable account had no text-provider key, so it did not run a real delegated provider call.
The web and Flutter chat image composers were verified from source and focused
automated tests on 2026-09-19. Both clients keep text and up to four ordered
images in one draft, support repeated image selection, removal and reordering,
upload the frozen draft with bounded concurrency, and start one stream for the
complete turn. Web also accepts validated images pasted into the composer or
dropped anywhere in the chat conversation and gives a visible drop-target cue.
Its picker was confirmed in a signed-in local Chrome session. Mobile users can
take a photo, choose existing photos, or paste a copied image from the add menu;
the composer long-press menu also exposes image paste. Historical thumbnails
use authenticated byte/blob requests. Web object URLs are revoked when
replaced or unmounted; Flutter keeps a bounded thumbnail cache and opens full
images explicitly.
Both clients use the same composer and streamed message request for text,
prompt-based generation, and edits. They render a generated attachment from the
safe generate_image completion event while the assistant turn is active, then
replace it with durable chat history. Current uploaded references take
precedence; conversational follow-ups can edit the latest generated image
without a client-selected mode or a second image-specific request. Flutter
renders those assistant thumbnails and offers a full-screen Save image
action backed by iOS Photos and the Android gallery.
Real-device HEIC/photo-picker and gallery-save behavior still require device
smoke tests.
CHAT_IMAGE_INPUT_ENABLED is the shared rollout switch: when disabled, both
clients hide or reject image selection while ordinary text chat remains
available. While the rollout is enabled, the attachment action stays visible;
providers with an image route keep it enabled even when the ordinary text model
is text-only. Web names the routed multimodal model in the attachment tooltip
when image analysis uses a different model.
Foreground Location
Section titled “Foreground Location”Web and Flutter location sharing is an explicit per-device, per-account opt-in. The first enable action triggers the browser or operating-system permission prompt. Web deployment permits geolocation only for the same origin; browser geolocation still requires a secure context such as HTTPS, except for supported local development origins. The iOS app declares when-in-use access, and Android declares coarse and fine foreground access without background permission.
Both clients keep only the preference in local storage. A successful coordinate snapshot is cached in memory for at most five minutes, refreshed before a text send, and captured once at voice startup. Location errors leave chat and voice usable and are surfaced in the client without sending a coordinate. Disable the setting to clear the in-memory snapshot and stop future requests.
Place Recommendation Cards
Section titled “Place Recommendation Cards”Web and Flutter render validated Google Maps place recommendations below the assistant answer in a separate Places group. A card shows the exact returned place title and Google Maps attribution. It opens the provider URL in a new web tab on React; Flutter launches the same HTTPS URL externally so iOS or Android can route it to the installed Google Maps app. Duplicate card URLs are not repeated in the generic Sources group.
Place cards arrive only with the completed message stream. Reconciliation keeps cards attached to their exact durable assistant messages in memory across subsequent sends, but later history loads do not restore Google Maps content. Both clients reject credential-bearing URLs, non-HTTPS URLs, non-Maps Google destinations, and lookalike domains before rendering a card.
Common Flow
Section titled “Common Flow”- Start the API and frontend.
- Sign in with a Firebase account accepted by the configured Firebase project.
- Open Providers and save a key for each text or voice provider you plan to use.
- Open Agent to choose independent default text and voice providers and models. Chat provider and model selectors affect only that conversation.
- Open Connection and save LiveKit credentials if you want voice sessions.
- Open Tools, choose automatic or pinned providers for equivalent actions, and approve the internal tools the agent should be able to use. Automatic web search currently shows Exa when it is authorized and available.
- Open Contacts to add the people that incoming and outgoing calls should match.
- Open MCP or Phone to connect external tools and communication channels. For accounts without an existing Exa endpoint, MCP shows the connected keyless Exa default and lets the user disable it through the normal server controls. Platform-default metadata is descriptive; backend server state and agent grants remain the authority for tool access. For WhatsApp, select the exact connected Twilio/Telnyx number. The Phone page can securely catch its mobile-registration SMS or, for Telnyx, its verification call before continuing to the QR or pairing-code linked-device flow.
- To use Browser Accounts, select the built-in local provider and save the
website credentials. No MCP setup is required. Browserless and Browser Use
are optional hosted alternatives that must first be configured and tested
under MCP. A local or Browserless account becomes ready after Voxos encrypts
its website credentials; a Browser Use account requires manual sign-in and a
two-letter browser country that defaults to
GB. Changing that country requires manual sign-in again. Assign the account to the intended agent, then ask for the signed-in browser task directly in Chat or authenticated in-app voice. Chat no longer has a per-message Browser Account selector. In Operations, a ready assigned local or Browserless account can be attached explicitly to a schedule. - To let the agent answer requests such as “weather near me” or “restaurants near me,” open Account on web or Settings in Flutter and enable Location for your agent. The setting applies only to foreground text and in-app voice actions from that device.
Provider keys and external tokens are submitted once to the backend and stored through the encrypted user secret vault. The frontend does not receive plaintext secrets back from the API.
Browser Account setup URLs, credential replacement, and authorization responses use no-store API responses. The setup URL moves directly into a separate browser window and is not rendered or retained in React state. Account cards expose neither provider profile/session IDs nor stored website credentials; they show only whether credentials are present.
Reviewing Agent Improvements
Section titled “Reviewing Agent Improvements”Open /knowledge/improvements to inspect proposed and applied account knowledge.
The screen shows policy reasons, assessment results, proposed content,
before/after content, and cited evidence. It supports approve, reject, undo,
refresh, and loading older records. A stale review or later knowledge edit
produces a conflict message while preserving the displayed proposal. Read-only
server connections can inspect improvements and evidence; writes require an
editable connection. The automatic-learning checkbox saves the account’s standing
choice and is off until explicitly enabled.