Skip to main content
Every answer a wondeya page gives is produced by the same pipeline. A visitor’s question goes in; a small set of typed, validated components comes out and streams onto the page. The model chooses what to show and which material to use; it never writes the page itself.

The steps

1

Understand

The agent reads the question together with the conversation so far, detects the language the visitor is writing in, and rewrites the question into two focused search queries: one for knowledge, one for images. The answer will come back in the visitor’s language. A question that is off topic for the business skips retrieval entirely; the agent steers back politely instead of answering it.
2

Select topics and images, at the same time

Two fast model calls run in parallel. One picks which of the agent’s knowledge topics the question touches, choosing from each topic’s description of what it covers. The other picks candidate images from the agent’s registry, from a shortlist of id, kind, orientation and what each image shows. Never a URL. Images already shown in the conversation are excluded in code, not just in the prompt.
3

Synthesize each topic

Each selected topic gets its own synthesis, all in parallel, and each one runs its own retrieval.Retrieval is hybrid. A deterministic topic map and a vector search over the agent’s indexed passages run side by side and their rankings are fused, returning the eight best passages for that topic. The two halves fail differently on purpose: the topic map needs no model, no index and no network, so a page keeps answering when the vector half is unavailable or still warming up.The synthesis distills those passages into a short grounded summary of what the knowledge says about the question. One failed topic never sinks the turn; the builder works with the summaries that made it.
4

Build the answer

A single call composes the whole answer from the grounded summaries and the image shortlist: one to three components from the closed catalog, in order, plus the one-line spoken reply. Building writes copy; it does not go looking for new facts. A build that produces no valid component gets exactly one repair attempt before the turn errors.
5

Validate, sanitize, resolve

Every built component goes through the same pipeline, in that exact order, server-side:
  1. Validate the component’s props against its schema. Unknown fields are a rejection, not a silently dropped key.
  2. Sanitize every text field, leaving reference ids untouched.
  3. Resolve ids into real data: an image id becomes a signed URL from wondeya’s own storage, a link id becomes the URL you registered.
The guardrails fail closed, per component: a duplicate slot is dropped (the first one wins), and so is a component with invalid props, one referencing an action or link id that does not exist, or an image component that resolved no approved image. The rest of the answer still arrives; a whole turn is never lost because one section was malformed.
6

Stream

The page receives events over Server-Sent Events as they happen: the conversation id first, then a coarse status and a progress line while the turn is worked out, the written reply, each section exactly once with validated props ready to render, and finally the authoritative list of the sections that made it. There are no loading placeholders: a section appears when it is ready.

What the stream contains

The transport is an AI SDK UI message stream over SSE. Six kinds of events travel on it:

Why it is shaped this way

The model selects; the server resolves. A component type comes from a fixed catalog. An image comes from your registry, by id. A link comes from the list you approved, by id. The schemas make a URL structurally impossible to express in the model’s output, so a prompt injection hidden inside an uploaded PDF cannot put an arbitrary link or a script in front of a visitor: there is no field for it to travel in. Everything is grounded. Figures, prices and promises are taken from retrieved passages. When the knowledge does not support an answer, the agent says so and offers a next step instead of inventing one. The server owns the conversation. The first event of every turn hands the page a conversation id; the page echoes it on the next question and the server replays the history, the visitor’s turns and the components already shown, from its own stored transcript. A client cannot forge the history, and knowing what was shown is what lets a follow-up refine the page instead of restarting it. Transcripts belong to the anonymous tab session, expire on a sliding 24-hour clock, and never store the visitor’s IP. The public endpoint is defended. The endpoint that serves visitors is anonymous by nature, so it is layered: an origin allowlist, per-IP rate limits, an invisible bot check, a per-session cooldown, a cache for identical opening questions and a global daily fuse. Security and privacy explains the whole stack.