Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Chat

There is one chat component. ChatWidget is the full-control component: streaming text, tool-call cards, confirmations, ask-user cards, session history, theming, and an imperative handle. AmodalChat (in the package root) is a preset of the same component: ChatWidget with position="inline" and serverUrl defaulted from the nearest AmodalProvider. Pick the entry point, not a different widget.

ChatWidget is exported from both the package root and the @amodalai/react/widget subpath; the subpath exists so a chat-only embed doesn't import the whole SDK, and it also ships the widget's building blocks for composing a custom chat surface (see Building blocks).

Installation

npm install @amodalai/react

Quick start

Inside an AmodalProvider, the preset is enough:

import { AmodalChat } from "@amodalai/react";
import "@amodalai/react/style.css";
 
<AmodalChat user={{ id: userId }} />;

For any other position, or outside a provider, use ChatWidget directly:

import { ChatWidget } from "@amodalai/react/widget";
import "@amodalai/react/widget/style.css";
 
<ChatWidget
  serverUrl="https://your-agent.example.com"
  user={{ id: userId }}
  position="floating"
  historyEnabled
/>;

Props

AmodalChat accepts every ChatWidget prop except position (pinned to inline); its serverUrl is optional and defaults to the provider's runtimeUrl.

Connection and identity

PropDefaultMeaning
serverUrlrequiredBase URL of the agent's runtime server.
userrequired{ id: string }; attributed to the session.
getTokennoneReturns a bearer token for authenticated requests (sync or async).
scopeIdnoneMulti-tenant isolation: scopes sessions, memory, and stores per value.
scopeContextnoneKey-value pairs injected into connection API calls via contextInjection.

Behavior

PropDefaultMeaning
positionfloatingSee Positions.
defaultOpenfalseStart open (togglable positions only).
historyEnabledfalseSession history drawer.
showHeader / showInput / showFeedbacktrue / true / falseHeader bar; input bar; thumbs up/down on assistant messages.
sessionTypenoneWhich curated surface (skills, tools, knowledge) loads into the session.
deployIdactive deployPin a specific deployment.
initialMessagenoneAuto-sent once on mount.
resumeSessionIdnoneLoad an existing session as read-only history; takes precedence over initialMessage.

Callbacks

PropMeaning
onToolCall(call)A tool call completed; receives the full ToolCallInfo.
onKBProposal(proposal)The agent proposed a knowledge-base update.
onEvent(event)Every widget event (agent-driven and interaction).
onSessionCreated(sessionId)First stream init returned a session id.
onStreamEnd()The SSE stream ended.
onStateChange({ sessionId, messages })Session state changed (for external persistence).

Extension points

PropMeaning
themeSee Theming.
widgetsWidgetRegistry of custom renderers for rich inline widgets.
inlineBlockRenderersRenderers for block types the widget doesn't render natively; native types (text, ask_choice, proposal) cannot be overridden.
streamFnCustom transport ((text, signal, images?) => AsyncIterable<SSEEvent>); replaces the built-in chat API call for non-standard endpoints.
entityExtractorsReplaces the default entity extractor for entity events.

Imperative handle

The ref exposes ChatWidgetHandle:

const chat = useRef<ChatWidgetHandle>(null);
chat.current?.sendMessage("Summarize today's alerts"); // as if the user typed it
chat.current?.getSessionId();

Positions

PositionBehavior
inlineRenders in-place within your layout
floatingFloating button that expands into a chat panel
rightFixed panel on the right side
bottomFixed panel at the bottom

Theming

The theme prop covers the common cases:

<ChatWidget
  serverUrl={serverUrl}
  user={{ id: userId }}
  theme={{
    mode: "auto", // 'light' | 'dark' | 'auto' (follows prefers-color-scheme)
    primaryColor: "#6e56cf",
    borderRadius: "12px",
    headerText: "Ask the agent",
    placeholder: "Type a message…",
    verboseTools: true, // full tool-call params, results, timing
  }}
/>

Other ChatTheme fields: backgroundColor, fontFamily, fontSize, userBubbleColor, agentBubbleColor, toolCallColor, emptyStateText.

For anything the prop doesn't cover, override the CSS custom properties (no Tailwind dependency):

.pcw-widget {
  --pcw-primary: #6e56cf;
  --pcw-bg: #ffffff;
  --pcw-text: #1a1a1a;
  --pcw-border: #e5e5e5;
  --pcw-radius: 12px;
}

SSE events

The widget handles these event types from the runtime:

EventDescription
text_deltaStreaming text output
tool_call_startTool execution beginning
tool_call_resultTool execution complete
skill_activatedSkill activation
widgetWidget rendered inline
confirmation_requiredWrite operation needs approval
doneResponse complete

Building blocks

For a custom chat surface, the /widget subpath exports the pieces ChatWidget is made of:

  • Components: MessageList, InputBar, SessionHistory, StreamingIndicator, ToolCallCard, AskUserCard, KBProposalCard, SkillPill, TagEditor, FormattedText, and WidgetRenderer (with its WidgetRegistry type).
  • Hooks: useChat (the widget's chat state machine), useWidgetEvents, useSessionHistory.
  • Chat API: listSessions, getSessionHistory, createSession.
  • Theme utilities: defaultTheme, applyTheme, mergeTheme.

The provider-based hooks and headless clients live in the package root; see @amodalai/react.