Algolia-Central

Knowledge/AgentStudio/08-frontend-integration.md

08 — Frontend Integration

How Agent Studio agents reach the user. Three integration paths exist; production agents use them in different combinations.

Three integration paths

Path What it is When to use
HTTP API direct POST to /agent-studio/1/agents/{agentId}/completions with custom transport Custom UIs, non-React apps, full control over UX
Native widgets <Chat>, <FilterSuggestions> from react-instantsearch or instantsearch.js Standard chat or filter-suggestion UIs, fastest path to production
AI SDK UI useChat hook from @ai-sdk/react (which <Chat> is built on) Custom React components with managed message state and streaming

Path 1: HTTP API direct

Lowest level. Full control. What we use today.

const response = await fetch(
  `https://${appId}.algolia.net/agent-studio/1/agents/${agentId}/completions?compatibilityMode=ai-sdk-4&stream=true`,
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-Algolia-Application-Id": appId,
      "X-Algolia-API-Key": apiKey,
      "X-Algolia-Secure-User-Token": jwt  // optional
    },
    body: JSON.stringify({
      id: "alg_cnv_abc123",
      messages: [{ id: "alg_msg_1", role: "user", content: query }]
    })
  }
);
// Process SSE stream

SSE event types (compatibilityMode=ai-sdk-4): - Text deltas - Tool call requests (9: prefix in v4 stream) - Tool result sends back (client → server) - Reasoning chunks (if sendReasoning: true) - e: and d: finish reasons (tool-approval-required, stop, etc.)

Compatibility mode ai-sdk-5 uses data: prefix and named event types (data-tool-approval, finish-step, finish). We currently use v4. v5 maps better to AI SDK React patterns.

Path 2: Native widgets

<Chat> widget (react-instantsearch)

Per 04-frontend-widgets.md §1.

import { liteClient as algoliasearch } from 'algoliasearch/lite';
import { InstantSearch, Chat } from 'react-instantsearch';

const searchClient = algoliasearch(APP_ID, API_KEY);

<InstantSearch indexName="instant_search" searchClient={searchClient}>
  <Chat agentId="..." />
</InstantSearch>

Required (one of): agentId OR transport (custom HTTP config).

Key optional props: - feedback (boolean) — thumbs up/down on assistant messages (only with agentId) - tools (Record<string, Tool>) — client-side tool definitions: jsx tools={{ suggest_searches: { onToolCall: async ({ input, addToolResult, indexUiState, setIndexUiState }) => { // Execute the tool's intent await addToolResult({ output: { success: true, ... } }); }, layoutComponent: ({ message }) => ( // Render the tool call/result as a UI component <SearchSuggestionsCard suggestions={message.input.suggestions} /> ) } }} - getSearchPageURL: (uiState) => string — for "View all" navigation - layoutComponentChatInlineLayout or ChatOverlayLayout - classNames — CSS class overrides - translations — UI text dictionary - itemComponent, assistantMessageLeadingComponent, userMessageLeadingComponent, promptFooterComponent, etc. — slot overrides

Notable: Works with Vercel AI SDK 5 transport. NO UMD/CDN — ES modules only.

<FilterSuggestions> widget

For agents created with the "Filter suggestions" template. Renders AI-suggested facet filters.

<FilterSuggestions
  agentId="..."
  attributes={['brand', 'category']}  // restrict to specific facets
  maxSuggestions={3}                   // default 3, max 5
  debounceMs={300}                     // delay before fetching
  hitsToSample={5}                     // # search results sent as context
/>

Frontend renders clickable suggestion chips. Each click applies the filter to the active InstantSearch state.

Vanilla JS variants

instantsearch.js/es/widgets exports chat() and filterSuggestions():

import { chat, filterSuggestions } from 'instantsearch.js/es/widgets';

instantsearch.addWidgets([
  chat({ container: '#chat', agentId: '...' }),
  filterSuggestions({ container: '#filters', agentId: '...', attributes: ['brand'] })
]);

Same prop surface as React, slight syntax difference. NO UMD/CDN — ES modules only. Requires instantsearch.js 4.46.0+.

Path 3: AI SDK UI

For custom React UIs without the full <Chat> shell.

import { useChat } from '@ai-sdk/react';

const { messages, input, handleInputChange, handleSubmit, isLoading } = useChat({
  api: `https://${appId}.algolia.net/agent-studio/1/agents/${agentId}/completions?compatibilityMode=ai-sdk-5&stream=true`,
  headers: {
    'X-Algolia-Application-Id': appId,
    'X-Algolia-API-Key': apiKey
  }
});

<Chat> is built on top of useChat (per 04-frontend-widgets.md). Use useChat directly when you want managed message state + streaming but custom layout.

Tool integration: the round-trip

Critical pattern (per 02-tools.md §3.2 and 04-frontend-widgets.md §1):

  1. Agent decides to call client_side tool X with arguments { ... }
  2. Streaming response includes a tool-call request event
  3. <Chat> (or your useChat handler) invokes the tool's onToolCall({ input, addToolResult, ... })
  4. Your code: - Performs the action (mutate UI state, call backend, fetch user data, etc.) - Calls await addToolResult({ output: <result> })
  5. The result is sent back to the agent, which uses it to continue its response
  6. Optionally, your tool's layoutComponent({ message }) renders the call+result as a UI element in the chat

The <Chat> widget handles the round-trip wiring automatically. With raw useChat, you wire onToolCall yourself.

Component slots and customization

<Chat> exposes many slots for customization:

Slot Purpose
itemComponent Custom search result item renderer (when search tool returns hits)
headerCloseIconComponent, headerMaximizeIconComponent, etc. Header icon customization
messagesErrorComponent Error state for messages
messagesLoaderComponent Loader animation
assistantMessageLeadingComponent / Trailing / Footer Avatar / metadata / disclaimer slots
userMessageLeadingComponent / Trailing / Footer User-side equivalents
promptHeaderComponent / promptFooterComponent Above/below the input
toggleButtonIconComponent For overlay layout, the toggle icon
suggestionsComponent Custom suggestions renderer (when suggestions.enabled: true)

Per-tool customization via tools[toolName].layoutComponent (and tools[toolName].onToolCall).

CSS classes

Standard .ais-Chat class hierarchy. Override via classNames prop. Major sub-elements:

Area Classes
Root root, container
Header root, clear, close, maximize, title, titleIcon
Messages root, content, scroll
Message root, container, leading, content, actions
Prompt root, textarea, submit, body, footer
Toggle toggleButton

Translations / i18n

Customizable text across header, messages, message, prompt sections via the translations prop. See 04-frontend-widgets.md §1 "Translation Keys" for the full key list.

Vercel AI SDK 5 compatibility

The widget transport must be Vercel AI SDK 5 compatible. The compatibilityMode=ai-sdk-4 query parameter exists for older clients; ai-sdk-5 is the current default. Migration from v4 to v5 is mainly stream event format — text deltas and tool calls keep similar semantics.

For RC3 Phoenix: standardize on ai-sdk-5 for new code; migrate v4 code over time.

Beta status caveats

All four widgets (Chat React, Chat JS, FilterSuggestions React, FilterSuggestions JS) are BETA. Breaking changes possible in minor versions. Pin versions in package.json and read changelogs before upgrading.

What this section does NOT cover