> ## Documentation Index
> Fetch the complete documentation index at: https://docs.omnicommerce.sg/llms.txt
> Use this file to discover all available pages before exploring further.

# Embedded assistant chat

> Use OmniCommerce chat inside React applications and websites.

Publish a chat deployment for each assistant you want to expose. A deployment selects an organization agent, audience, and exact website origins. One organization can publish multiple deployments, and one website can mount several chats.

| Audience | Access | Tools |
| - | - | - |
| Public visitors | Anonymous, deployment-scoped session | Selected agent’s configured tools, skills and Deep Agent runtime |
| Organization members | OmniCommerce sign-in and current organization permissions | Selected agent’s Deep runtime and authenticated approval flow |

The selected active agent controls the tools exposed by both audiences, including configured toolkits, MCP tools, scripts, skills and subagents. Runtime settings are read from the agent configuration for each turn. Configure a dedicated agent for each public purpose and publish it explicitly. Visitors cannot override the agent, model, tool grants or organization.

Public sessions run tools with the publishing member's current organization authorization. Disabling the agent or removing that member's assistant access prevents execution. Visitors can answer matching interactive tools; organization write approvals require an authenticated member.

## Preview and publish

Open **Agents → Storefront** in your organization. Select **Create storefront chat**, choose an active agent, enter the exact websites allowed to embed it, and customize its design. Storefront manages public visitor chats and is included in **Enterprise**. This requirement applies to every public visitor installation, including React application layouts. Public sessions and subsequent requests stop if the organization loses this entitlement.

Authenticated (`org_member`) application chat is available on every plan, subject to organization membership and assistant permissions. Building and publishing applications with the OmniCommerce **Applications** feature requires Enterprise separately.

The editor has **Settings**, **Design**, and **Embed code** tabs with a persistent design preview. In **Design → Chat window**, choose a floating window or a full-height sidebar. In **Embed code → Install in**, choose a website chat bubble, inline website chat, or React application. All three installations support public visitors. Code updates immediately as you customize; publishing activates the deployment ID already shown in the draft snippet. **Live preview** opens `/sdk/chat-preview` with your deployment and layout selected. Design previews do not start AI conversations. Each chat has its own design, agent and allowed origins.

The listing supports live search, a searchable status filter, and individual or full resets. Filters stay in the URL so views can be bookmarked and shared. On mobile, use **Filters** to reveal advanced controls.

For other websites, publish using the authenticated management endpoint from an organization member session:

```ts theme={null}
const response = await fetch("/api/embed/deployments", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    organizationId: "YOUR_ORGANIZATION_ID",
    agentId: "YOUR_AGENT_ID",
    audience: "public_visitor",
    allowedOrigins: ["https://shop.example.com"],
  }),
});
if (!response.ok) throw new Error("Publication failed");
const { deploymentId } = await response.json();
```

Use exact HTTPS origins. HTTP localhost is accepted for development. A deployment ID is a public identifier; it is not an API key. Disable a deployment with `DELETE /api/embed/deployments` using `{ deploymentId, organizationId }` in the same authenticated management session. Disabling prevents new sessions and subsequent chat requests.

## React applications

Install the released SDK with its optional React integration:

```bash theme={null}
yarn add @omni-commerce/sdk@^0.8.0 react
```

The host also serves the plain JavaScript bundle at `/sdk/embed.global.js` and an installable SDK build at `/sdk/omni-commerce-sdk.tgz`.

```tsx theme={null}
"use client";

import { OmniProvider, OmniChat } from "@omni-commerce/sdk/react";

export function StoreSupport() {
  return (
    <OmniProvider deploymentId="YOUR_DEPLOYMENT_UUID">
      <OmniChat style={{ height: 600 }} />
    </OmniProvider>
  );
}
```

The components support server rendering. They mount the hosted iframe after hydration, which owns the assistant-ui runtime and styles. Your host application does not need assistant-ui or Tailwind dependencies. Set `baseUrl="http://localhost:3000"` to use a local OmniCommerce host.

Use separate providers for separate assistants:

```tsx theme={null}
<>
  <OmniProvider deploymentId="PUBLIC_SUPPORT_DEPLOYMENT_UUID">
    <OmniChat title="Store support" style={{ height: 500 }} />
  </OmniProvider>
  <OmniProvider deploymentId="MEMBER_DASHBOARD_DEPLOYMENT_UUID">
    <OmniChat title="Internal assistant" style={{ height: 500 }} />
  </OmniProvider>
</>
```

## Application context and UI actions

SDK 0.8.0 can connect the selected agent to your app's live state and local UI actions. Pass `application` with a name, description, and `getContext()` snapshot, plus optional `frontendTools`. The same options work on `OmniProvider`, `createOmniChatEmbed`, and `createOmniChatWidget`, including public deployments.

```tsx theme={null}
<OmniProvider
  deploymentId={deploymentId}
  application={{
    name: "Sales dashboard",
    description: "A dashboard with overview and activity views.",
    getContext: () => ({ activeView, filters }),
  }}
  frontendTools={{
    app_set_view: {
      description: "Change the visible dashboard view.",
      parameters: {
        type: "object",
        properties: {
          updates: {
            type: "array",
            minItems: 1,
            maxItems: 1,
            items: {
              type: "object",
              properties: {
                view: { type: "string", enum: ["overview", "activity"] },
              },
              required: ["view"],
              additionalProperties: false,
            },
          },
        },
        required: ["updates"],
        additionalProperties: false,
      },
      execute: async ({ updates }) => {
        const [{ view }] = updates as { view: "overview" | "activity" }[];
        setActiveView(view);
        return {
          success: true,
          views: [view],
          succeededCount: 1,
          failedCount: 0,
          results: [{ view, success: true }],
        };
      },
    },
  }}
>
  <OmniChat style={{ height: 600 }} />
</OmniProvider>
```

`getContext()` runs before each turn, so React state and filters stay current without recreating the chat. Share only selected data; never return credentials, entire application stores, or base64 images. Context is limited to 32 KiB of JSON and the complete configuration to 64 KiB.

Frontend tools must use unique `app_` names, JSON object schemas, and bounded array arguments for actions that can target several controls or entities. Up to 24 tools are supported. Native LangGraph interrupts park these calls while the SDK runs your `execute()` function locally. The host result returns as the tool result, including failures. Keep results under 12,000 bytes, return concrete evidence, and make mutations idempotent; `execute()` receives `toolCallId` and an `abortSignal` that cancels when the embed is destroyed. Repeated delivery of the same parked call is deduplicated during that embed's lifetime.

Local UI tools do not add server permissions or override existing tools. The deployment's agent continues to control its server tools, scripts, MCP servers, skills, and subagents. The SDK validates frame source, exact origin, deployment, and request IDs before calling a host handler. Functions remain in your application and are never sent to the model. Custom React tool renderers are not exposed through the hosted iframe.

Try `/sdk/chat-preview?deploymentId=YOUR_DEPLOYMENT_ID&view=application` to see the agent change the preview's Activity view and search control.

## JavaScript websites

```js theme={null}
import { createOmniChatEmbed } from "@omni-commerce/sdk/embed";

const chat = createOmniChatEmbed(document.getElementById("support-chat"), {
  deploymentId: "YOUR_DEPLOYMENT_UUID",
  onError: (error) => console.error(error.message),
});

// When removing the host view:
chat.destroy();
```

Give the container an explicit height. For a website launcher, use `createOmniChatWidget(document.body, options)` instead. It accepts `presentation` (`floating` by default or `sidebar`), `launcherLabel`, `position` (`left` or `right`), `launcherBackground`, `launcherForeground`, `panelBackground`, and `panelForeground`, and returns `open()`, `close()`, and `destroy()`. SDK 0.8.1 loads the saved launcher label, layout, position and colors from your deployment ID before showing the bubble. The generated Storefront snippet contains only `deploymentId` and `baseUrl`, so saved design and agent changes apply on the next website load without editing the snippet or redeploying your website. Explicit styling options remain available for hosts that intentionally want overrides; omit them to inherit future saved changes. Replace older snippets that contain styling options once with the new deployment-only snippet. The returned `ready` promise resolves when the saved appearance is mounted and rejects on a loading error; `onError` also receives that error.

```js theme={null}
import { createOmniChatWidget } from "@omni-commerce/sdk/embed";

const chat = createOmniChatWidget(document.body, {
  deploymentId: "YOUR_DEPLOYMENT_UUID",
  presentation: "sidebar",
  position: "right",
});
```

The sidebar fills the viewport height, uses the selected left or right edge, and fills the width on smaller screens. The launcher hides while it is open. Inline and React application chat stay inside their host container and use its size instead of the launcher layout.

The responsive widget isolates its launcher and panel in Shadow DOM, while the hosted iframe owns chat styles. Shopify theme button and font rules cannot restyle the chat. Opening or reopening focuses the composer. Closing retains the conversation; Escape and the icon close control return focus to the launcher.

The hosted UI shows a compact thinking status before the first token. Tool work and reasoning share one collapsed activity disclosure per turn; the final answer appears outside it. Text streams with assistant-ui’s native smoothing and no separate typing row. Copy actions appear as a small corner overlay on hover or keyboard focus, with no placeholder row or added spacing. A checkmark confirms copying without a toast. The website panel is taller and adapts to the available viewport.

Type **@** in the composer to select a reference. Public storefronts offer public catalog products and the selected agent’s tools, toolkits, and available skills. Authenticated applications also offer organization references permitted by the member’s access. Mentioning a tool does not grant additional tools to the agent. The chat also supports nested Deep Agent messages, Markdown tables and code, media and source links, scrolling to the latest message, and stopping a reply. Visitor file uploads and the demo’s host-side custom tool-renderer/composer hooks are not exposed by this iframe SDK.

The script integration generated in Storefront loads `/sdk/embed.global.js` from your OmniCommerce host. The same bundle is available in the SDK package for hosting on your own asset server. Each mount owns its own iframe and session.

## Sessions and permissions

Public sessions are minted automatically. Member deployments offer an OmniCommerce sign-in popup when a session is unavailable, including browsers that block third-party cookies. Membership and assistant permissions are checked on each member request. An optional `getSession` callback can supply a scoped session `{ token, threadId, expiresIn }` that your integration has obtained through the supported member flow.

Tokens stay in memory, renew before expiration, and never appear in iframe URLs or browser storage. A page reload starts a new session unless your integration supplies a valid existing session. The host and iframe exchange messages only after checking the source window, exact origin, and deployment ID. Allow the OmniCommerce host in your website’s `frame-src` and `connect-src` Content Security Policy.

For script snippets, also allow that host in `script-src` and apply your website’s nonce or hash to the initialization script when required by its policy.

AI usage is billed to the deployment’s organization for both audiences.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.