Skip to main content

<AgentChat />

The complete chat experience out of the box:

  • message bubbles with lightweight markdown (code blocks, tables, lists, bold), a typing indicator and streaming cursor
  • a collapsible live activity feed (thinking → acting → observing → responding) attached to each assistant message
  • a welcome screen with suggested starter prompts
  • a geometry attach panel (point / polyline / polygon)
  • voice input — a mic button for dictating messages (Web Speech API)
  • per-message actions: copy, read aloud (TTS) and export as PDF
  • chat history — a slide-over of saved sessions (search, rename, delete, new chat), backed by localStorage
  • a capacity queue overlay when the server reports HTTP 503 (usage ring, retry countdown, cancel) with automatic retries
  • a stop button (cancel) while a run is in flight
  • the HitL approval modal with auto-reject countdown and optional rejection reason
  • an auth / feature-gate overlay (locked) that blocks all interaction
import { AgentChat } from "stacgis-ai-react";
import "stacgis-ai-react/dist/index.css";

export function MapAgent() {
return (
<AgentChat
apiBaseUrl="http://localhost:8000/api/v1"
title="GeoAgent"
placeholder="Ask me to geocode, route or buffer…"
onFrontendEvent={(event) => {
if (event.event_name === "zoom_to") myMap.flyTo(event.payload);
}}
/>
);
}

Props

PropTypeDefaultDescription
apiBaseUrlstringhttp://localhost:8000Agent API base URL (no trailing /agent)
titlestringAI Orchestrator ChatHeader title
placeholderstringAsk the AI agent anything…Textarea placeholder
mode"stream" | "chat""stream"SSE streaming vs blocking (set by the host app; no built-in switch)
theme"light" | "dark""dark"Colour theme (set by the host app; no built-in toggle)
approvalTimeoutMsnumber120000HitL modal auto-reject countdown (also sent to the backend as approval_timeout_s)
suggestedPromptsSuggestedPrompt[]4 geospatial defaultsStarter prompts for the welcome screen — pass [] to show only the hero (passing custom prompts is how the demo app drives the "What to try" list)
enableHistorybooleantruePersist chat sessions in localStorage and show the history panel (disable with false)
autoSpeakbooleanfalseRead the final assistant answer aloud automatically once the run completes (toggleable in the UI via the speaker button)
renderChart(spec: unknown) => React.ReactNodeCustom renderer for ```chart markdown blocks whose body is JSON — plug in your own chart library; without it the block is rendered as a JSON code block
lockedbooleanfalseLock the chat behind an auth/feature gate — an overlay is shown and every interaction is blocked until you set it to false again
lockTitlestringAI AssistantOverlay heading
lockMessagestringSign in to unlock the assistant and start chatting.Overlay body copy
lockCtaLabelstringContinueCTA button label (button rendered only when onLockedClick is set)
onLockedClick() => voidCalled when the user clicks the gate's CTA (e.g. open your sign-up)
onFrontendEvent(e: FrontendToolEvent) => voidHandle @frontend_tool UI events (see Frontend tool events)
classNamestringExtra classes on the container

SuggestedPrompt is { icon: string; text: string } — the emoji/glyph plus the prompt text sent verbatim when clicked.

Programmatic sending (ref)

AgentChat is a forwardRef component exposing an imperative AgentChatHandle:

import { useRef } from "react";
import { AgentChat, type AgentChatHandle } from "stacgis-ai-react";

const chatRef = useRef<AgentChatHandle>(null);

// e.g. the user picked a location on your map — hand it to the agent:
chatRef.current?.send(`I picked lat=${lat}, lon=${lon}. Continue with that.`);

<AgentChat ref={chatRef} apiBaseUrl="http://localhost:8000/api/v1" />;

send(text) is a no-op while a run is in flight, while the request is queued (server at capacity), or while the chat is locked. This is how the demo app wires the map location picker back into the agent.

Internal composition

AgentChat is composed of the smaller building blocks, all of which are exported if you want to build a custom layout:

ComponentPurpose
MessageBubbleA single message: markdown, attachment badges, per-message actions (copy, read aloud via onSpeak/onStopSpeaking, export as PDF — lazy-loads jspdf + html-to-image), and the attached steps feed
MarkdownRenderer (+ parseBlocks)Lightweight markdown used by bubbles: headings, bold/italic, inline code, fenced code (incl. chart blocks via renderChart), lists, tables, links, blockquotes
SuggestedPromptsWelcome screen with clickable starter prompts (title/subtitle + prompt list)
ChatHistorySlide-over session history: search, rename, delete, new chat, relative timestamps
ChatQueueOverlayServer-at-capacity overlay: usage ring (active/max slots), retry countdown, cancel
AgentActivityFeed / ActivityFeedLive ReAct step feed (thinking / acting / observing / responding)
TypingIndicator / GradientArcStreaming affordances (typing dots, avatar spinner)
ApprovalModalRendered automatically while pendingApproval is set — tool name, arguments table, auto-reject countdown, optional rejection reason

Sessions are persisted automatically when a run completes (title = first user message, truncated to 60 chars) via the useChatSessions hook.