For the complete documentation index, see llms.txt. This page is also available as Markdown.

SDK Reference

API reference for the agent client SDK (@limio/sdk/ai).

Everything exported from @limio/sdk/ai. For a walkthrough, start with Getting Started.

Available from Release 117 onwards.

useChat(options)

The conversation state machine. Bootstraps a session, lazily creates the conversation on the first send, renders optimistic messages, and rolls back on error.

const chat = useChat(options)

Options

Option
Type
Default
Description

greeting

string

server greeting

Opening assistant message, shown immediately. Falls back to the agent's server-configured greeting when omitted.

autoStart

boolean

true

Bootstrap the session on mount. Set false to defer until the surface is shown, then flip to true or call start().

onError

(error: Error) => void

none

Called when a send fails, after the pending bubble is rolled back.

Returns

Property
Type
Description

messages

ChatMessage[]

The conversation, including the greeting and any pending bubble.

session

Session | null

The current session once bootstrapped.

conversation

Conversation | null

The conversation once created, after the first send.

status

ChatStatus

"idle", "ready", "sending", or "error".

error

string | null

The last send error message, or null.

send

(text: string) => Promise<void>

Send the visitor's message. Optimistic; creates the conversation lazily.

reset

() => void

Start a fresh conversation: clears messages, re-seeds the greeting, drops the conversation, keeps the session.

start

() => Promise<void>

Bootstrap the session manually when autoStart is false. Idempotent.

ChatMessage

pending is true on the placeholder bubble shown while the agent's reply is in flight. It starts with empty content, and on a streamed reply that content fills as the text arrives while pending stays true. Render a typing indicator only while the content is empty, not for as long as the flag is set. See Streaming.

Streaming

When the agent has Stream replies enabled (see Configuring an Agent), useChat streams the reply into the pending bubble. There is nothing to turn on in your code: the hook reads the agent's setting from the session and picks the transport itself. session.streaming carries that setting if you want to read it, but the server decides per reply, so treat it as a hint rather than a guarantee.

A streamed reply arrives as a growing content on the pending message and settles into an ordinary message when it completes, holding exactly what the buffered path would have returned. Tool artifacts such as checkout links are unaffected: they arrive on the settled message either way.

Rendering a streamed reply

A pending bubble starts with empty content and fills as the reply streams, while pending stays true throughout. Test the content, not the flag: fall back to a typing indicator only while the bubble is still empty.

Keying on m.pending alone is not an error, but it hides the streamed text and delivers the reply whole at the end, which is the behaviour streaming was turned on to avoid.

useSmoothedText(text)

Models emit a reply in a handful of large chunks rather than character by character, so text rendered straight from content lands in visible jumps. useSmoothedText reveals a growing string at a steady, bounded rate, which reads as typing:

Only growth animates. A message that is already complete when it mounts renders whole, so settled history is never re-typed, and a string that changes rather than grows snaps to its new value instead of animating backwards. Under prefers-reduced-motion the type-in is off and text appears as it arrives.

The hook takes and returns a string, so a surface that wants both smoothing and markdown should smooth the text first and render the result with Markdown rather than passing blocks to MessageContent.

MessageContent

Renders a message's content blocks to React: text/markdown formatted, text/plain literal, and component blocks via the registry.

Prop
Type
Description

content

ContentBlock[]

The message content to render.

registry

MessageComponentRegistry

Optional. Renders application/vnd.limio.component+json blocks. Omit to skip them.

conversationId

string | null

Optional. Passed to the registry as render context.

markdownClassName

string

Optional. Class on each rendered markdown block, for styling the generated HTML.

textClassName

string

Optional. Class on plain-text blocks.

For full control you can import the underlying markdown renderer, Markdown, directly.

Component registry

Maps a component name to a renderer. MessageContent uses it to render component blocks; unknown names render nothing.

Member
Signature
Description

register

(name: string, render: MessageComponentRenderer) => void

Add or replace a renderer.

render

(descriptor, ctx) => ReactNode

Render a descriptor; returns null if the name is unknown.

A renderer receives the component's props and a context object:

Transport

Lower-level functions for calling the Chat API directly. useChat is built on these; reach for them only when you need to bypass the hook.

Function
Description

createSession()

Bootstrap or confirm the visitor's session. Returns the session, including the configured greeting.

createConversation()

Start a new conversation thread.

getConversation(id)

Fetch an existing conversation.

listMessages(conversationId)

The conversation's 50 most recent messages, oldest first. Not the full history of a long chat.

sendMessage(conversationId, text)

Send a message and return the agent's reply.

sendMessageStream(conversationId, text, handlers, options?)

Send a message and stream the reply. Resolves the same final Message as sendMessage.

initiateUpload(conversationId, input)

Request a presigned upload for a document.

uploadFileToS3(init, file)

Upload the file bytes to the presigned target.

contentToText(content)

Flatten a content array to a plain string. Text blocks only; component blocks are skipped.

sendMessageStream

A superset of sendMessage: await it the same way and you get the same final Message, but the text also reaches handlers as it arrives. Calling it for an agent that has streaming switched off is safe and returns the reply in one piece, firing no deltas, so a surface can always use it.

Handler
When it fires

onDelta

Each chunk of reply text. Append it to what you have already shown.

onReset

A step called tools, so the text since the last reset was preamble rather than the answer. Discard it. Agents are told not to narrate before a tool call, so this rarely fires; it is the safety net for a model that narrates regardless.

onDelta is required; onReset is optional. options.signal takes an AbortSignal to cancel the request and stop reading mid-reply, which is worth wiring to unmount.

If the connection drops after some text has rendered, the reply is unaffected: the turn finishes and is saved server-side regardless of whether anyone is listening. Recover it with listMessages, which is what useChat does before it reports an error.

Configuring the transport

By default the transport calls the Chat API same-origin, authenticated by the visitor's Limio session cookie. A component running on your shop needs no configuration. For a cross-origin embed, configureChatTransport switches to bearer-token auth:

Function
Description

configureChatTransport(overrides)

Set the API base URL and a bearer-token source.

resetChatTransport()

Restore the default same-origin cookie mode.

Presentation

Everything the admin configured for the agent arrives on the session as session.presentation (type ChatPresentation). Every field is optional: absent means your surface applies its own default, so read each one with a fallback.

Field
Type
What it is

greeting

string

Opening assistant message. useChat seeds it for you; you only need this field to render it yourself.

title

string

Chat header title.

placeholder

string

Composer placeholder.

pointers

string[]

Starter questions to offer before the visitor's first message. The displayed text is the text to send.

footer

string

Markdown shown beneath the composer. Links allowed.

launcherIcon

string

The agent's logo, for a launcher or a header avatar. A site-relative /public/... asset path: resolve it with resolveAssetUrl.

launcherLabel

string

Short call-to-action for a launcher, such as "Ask Limio".

greetingPopup

boolean

Whether the greeting should show as a popup bubble from a closed launcher.

greetingPopupDelay

number

Seconds to wait before showing that popup.

greetingPopupMessage

string

Dedicated text for the popup bubble. Prefer it over greeting when set; the opened chat still greets with greeting.

theme

ChatTheme

Brand colours and bubble style. See Theming below.

The launcher fields describe a floating launcher, which the built-in widget renders. A custom surface is free to ignore them or to use them for its own entry point.

Theming

Apply the agent's admin-configured theme (see Theming an Agent) to a custom surface. The theme arrives on the session as session.presentation.theme.

Function
Description

themeRootProps(theme)

The props a surface spreads onto its root element: token overrides as style, plus a data-bubble-style attribute. A no-op when the theme is absent or empty.

themeTokens(theme)

The framework-neutral half: the CSS custom-property overrides as a plain object, for non-React callers to apply with el.style.setProperty.

The overrides are Limio design-token variables, so they restyle elements whose styles consume those tokens. A surface with its own palette should read the hex fields off the theme directly instead.

ChatTheme

Every field is optional; absent means the design-system default. Colours are 6-digit #hex.

Field
Colours

accentColor

The brand colour: visitor bubbles, the launcher and buttons, unless a finer field below overrides it.

userBubbleColor

The visitor's bubbles only.

agentBubbleColor

The agent's bubbles.

headerColor

The header bar. Its text colour is derived for you, so it stays legible.

launcherColor

The launcher only.

backgroundColor

The panel surface.

textColor

Body text.

borderColor

Panel and composer borders.

bubbleStyle

A bubble decoration preset, not a colour. See below.

bubbleStyle is a BubbleStyle: "rounded" (the default), "tailed", "flat", "outlined", "shadowed", "bordered", "minimal" or "gradient". themeRootProps applies it as a data-bubble-style attribute on your root element.

The colours reach your surface as CSS variables, so they land whatever stylesheet you ship. The bubble shapes do not: the presets live in the widget's own stylesheet, keyed off that attribute. A surface with its own bubble CSS should read bubbleStyle and style its bubbles itself; a surface that wants the stock shapes should import the widget's stylesheet (@limio/chat/dist/chat.css), which is scoped to the chat root and will not touch the rest of your page.

Bubble text colour is not a field: it is derived from the bubble colour behind it, so text on a themed bubble stays readable whatever the admin picks.

Brand assets

Function
Description

resolveAssetUrl(value)

Resolve a site-relative /public/... asset path (such as presentation.launcherIcon) against the origin the transport talks to, so it also loads in a cross-origin embed. Absolute URLs pass through untouched.

useBrandIcon(iconPath)

React hook wrapping the above for an <img>: returns { src, onError }. src is the resolved URL, or undefined when the icon is unset or failed to load, so you can fall back to your own default rather than render a broken image.

Types

The wire types come from Limio's shared agent protocol and are re-exported for convenience: ContentBlock, Message, ToolArtifact, and Usage, plus the transport types Session, Conversation, CreateConversationResponse, ChatTransport, StreamHandlers, and ApiError.

A ContentBlock is a typed piece of message content:

Last updated

Was this helpful?