bow.conversations and the host embed SDK accept and return. For how to use them, see Build a chatbot app and Embed a chat assistant.
The chat components and bow.conversations run inside an artifact. The agent writes this code for you; the tables help you review it or ask for a precise change. The host embed SDK runs on your own page.
useConversation
It returns:
Components
Every component takes the hook’s object aschat (except ChatMessage and ChatResult, which take one message or result), an optional className, and an optional labels object. Style around the components, not inside them.
ChatMessages
It needs a bounded height: put it in a flex column with
min-h-0 on shrinking containers. It shows chat.error, except list errors when ChatThreads is mounted.
ChatComposer
Enter sends, Shift+Enter adds a line, and the button becomes Stop while an answer runs. When chat is unavailable, the input and button stay visible but disabled, with the reason in a note under them.
ChatThreads
It lists the viewer’s conversations with select, new, rename and archive, and a spinner on a conversation whose answer is running.
ChatSuggestions
Suggestions send on a click, never on mount. They show only while the conversation is loaded, empty and available.
ChatMessage
ChatMessages renders it: the Markdown answer with dir="auto" per block, the earlier steps collapsed, tool progress, each result as a ChatResult, and the running, stopped, failed and incomplete markers. Props as for ChatMessages, with message instead of chat.
ChatResult
It always shows the table. It draws a chart only when the result’s chart hint names real columns and fits the rows. It adds a note when rows or columns were cut.
Labels
All components accept the samelabels object. Missing keys fall back to English. Pass every key in the app’s language.
A result’s table has words of its own. Without labels they are in Hebrew when the chat labels are Hebrew. Otherwise they follow the viewer’s BOW language when it is Hebrew or Spanish, and are in English for any other language. For another language, add these keys to the same object. The same keys work as a labels prop on DataTable.
The chat keys:
{shown} and {total} are replaced with numbers.
bow.conversations
The low-level API under the components, for what they cannot do. Every call runs as the viewer, on the viewer’s own conversations with this artifact.bow.markdown(text) turns an answer’s Markdown into safe React elements, without raw HTML.
Errors are thrown with a code and a message. Send messages only on a user action.
Embed and artifact access codes are passed through as they are, for example embed.not_allowed, artifact.not_found, dashboard.not_published and access.denied.
Policy
Conversation
{ id, title, created_at, updated_at, in_progress }. in_progress is true while an answer in it is still running.
Message
Result
Results are the answer’s own query results, with your organization’s display redaction applied. Never re-read numbers from the answer text.
Stream events
send() yields these events, in order, ending with exactly one completed, or the iterator throws (UNAVAILABLE when the answer fails, INTERRUPTED when its stream breaks):
Host context in the artifact
useArtifactData().host_context holds the object the host page passed as context or with updateContext, or null. It changes while the app is open: read it during render. It is advisory and grants no access. See Use host context.
Host embed SDK
Load it from your BOW deployment, then mount:Mount options
In floating mode the panel is 600 × 720 pixels unless you set
width and height, above a 56-pixel launcher in the chosen corner. The browser window caps both: the panel is never wider than the window minus 32 pixels, or taller than the window minus 120 pixels, so on a phone it fits the screen. A browser without dvh, svh or lvh units uses the same size in vh.
If the SDK refuses a width, height, zIndex or accentColor, it logs a [bow-embed] ignoring … warning in the browser console and uses the default. SSO mode needs no identity.
Methods and properties
Events
unavailable reasons
A dead embed session is not an
unavailable reason: it ends like an expired session and arrives as authRequired with status 'failed' (sign_in_required in BOW sign-in mode). The frame notices when it next loads the artifact’s content or queries. Failed conversation calls do not tell the frame, so a chat-only app only shows embed.session_invalid in chat.error until the next renewal. In the backend-signed and identity-provider modes, that silent renewal, about five minutes before the session would have ended, asks the host for a new credential. After Sign everyone out it usually succeeds and signs the user straight back in, so the host receives authenticated, not authRequired. Renewal fails when the application is disabled, the key was rotated, or the host stops issuing credentials for the user. In SSO mode the frame asks for a new sign-in when the session would have ended.
A wrong artifact reference, an artifact that does not allow this application, a disabled application or an unlisted page origin make the browser refuse the frame, so BOW cannot report them from inside it. The SDK reports them as unavailable with reason no_response after startTimeout. A frame that answers later carries on normally.