Skip to content

Hooks

The Hooks module provides low-level React hooks that power the built-in components. Use these hooks when you need full control over the UI layout while retaining the state management, data fetching, and streaming logic.

Available Hooks

Hook Description
useAgentChat Manages chat messages, streaming, input state, and agent communication
useTraceExplorer Manages paginated trace lists with filtering and auto-refresh
useTraceDetail Fetches a single trace with its spans and config snapshot
useConversations Manages multi-turn conversation state including list, selection, and messaging

Pattern

All hooks follow a consistent pattern:

  1. Accept an options object with a backend and configuration parameters.
  2. Return a state object with data, loading indicators, errors, and action functions.
  3. Handle cleanup (abort controllers, intervals) automatically on unmount.
// General pattern
const { data, isLoading, error, ...actions } = useHookName({
  backend,
  // ... options
});

When to Use Hooks vs. Components

Use the built-in components (AgentChat, TraceExplorer, etc.) when:

  • You want a ready-to-use UI with sensible defaults
  • The built-in layout and styling meet your requirements
  • You want to minimize custom code

Use hooks when:

  • You need a custom layout that differs from the built-in components
  • You want to compose multiple data sources in a single view
  • You need to integrate agent data into an existing design system
  • You want to add custom interactions or animations

Quick Example

import {
  useAgentChat,
  createSseAgentBackend,
} from "@modernpath/agent-ui-react";

const backend = createSseAgentBackend({ baseUrl: "/api" });

function CustomChat() {
  const {
    messages,
    isLoading,
    error,
    input,
    setInput,
    send,
    reset,
    abort,
  } = useAgentChat({
    backend,
    auditingId: 1,
    agentType: "qa-chat",
    stream: true,
  });

  return (
    <div>
      <div>
        {messages.map((msg, i) => (
          <div key={i} className={`message-${msg.role}`}>
            {msg.content}
          </div>
        ))}
      </div>
      {isLoading && <div>Thinking...</div>}
      {error && <div className="error">{error.message}</div>}
      <input
        value={input}
        onChange={(e) => setInput(e.target.value)}
        onKeyDown={(e) => e.key === "Enter" && send()}
        disabled={isLoading}
      />
      <button onClick={send} disabled={isLoading}>Send</button>
      <button onClick={abort} disabled={!isLoading}>Stop</button>
      <button onClick={reset}>Clear</button>
    </div>
  );
}