Skip to content

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.

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.

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_agent or run_session are 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.

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.

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.

  1. Start the API and frontend.
  2. Sign in with a Firebase account accepted by the configured Firebase project.
  3. Open Providers and save a key for each text or voice provider you plan to use.
  4. Open Agent to choose independent default text and voice providers and models. Chat provider and model selectors affect only that conversation.
  5. Open Connection and save LiveKit credentials if you want voice sessions.
  6. 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.
  7. Open Contacts to add the people that incoming and outgoing calls should match.
  8. 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.
  9. 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.
  10. 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.

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.