Skip to content

useTraceDetail

useTraceDetail fetches a single trace by ID along with its spans and optional configuration snapshot. It is used internally by TraceTimeline and is useful for building custom trace detail views.

Import

import { useTraceDetail } from "@modernpath/agent-ui-react";

Options

interface UseTraceDetailOptions {
  /** Backend instance for fetching trace data */
  backend: TraceBackend;

  /** The trace ID to fetch */
  traceId: string;
}

Return Value

interface UseTraceDetailReturn {
  /** The trace object, or null if not yet loaded */
  trace: TraceUI | null;

  /** Array of spans belonging to this trace */
  spans: SpanUI[];

  /** Configuration snapshot captured at trace time, or null */
  configSnapshot: ConfigSnapshotUI | null;

  /** Whether the fetch is in progress */
  isLoading: boolean;

  /** Error from the last failed fetch, or null */
  error: Error | null;
}

ConfigSnapshotUI Type

interface ConfigSnapshotUI {
  /** Agent configuration at trace time */
  agent?: {
    name: string;
    version: string;
    model?: string;
    temperature?: number;
  };

  /** Tool configurations */
  tools?: Array<{
    name: string;
    source: string;
  }>;

  /** Prompt template content */
  prompts?: Record<string, string>;

  /** Environment variables (sanitized) */
  environment?: Record<string, string>;
}

Behavior

Data Fetching

The hook calls backend.getTrace(traceId) when the component mounts or when traceId changes. The response includes the trace metadata, spans, and an optional config snapshot.

Loading State

isLoading is true while the fetch is in progress. trace and spans are null / empty until the data arrives.

Error Handling

If the fetch fails, error is set and trace remains null. This can happen if the trace ID is invalid or the backend is unreachable.

Cleanup

The hook cancels the in-flight request if the component unmounts or traceId changes before the fetch completes.

Usage

Basic Trace Detail

import {
  useTraceDetail,
  createHttpTraceBackend,
} from "@modernpath/agent-ui-react";

const traceBackend = createHttpTraceBackend({ baseUrl: "/api" });

function TraceDetailView({ traceId }: { traceId: string }) {
  const { trace, spans, configSnapshot, isLoading, error } =
    useTraceDetail({
      backend: traceBackend,
      traceId,
    });

  if (isLoading) return <div>Loading trace...</div>;
  if (error) return <div>Error: {error.message}</div>;
  if (!trace) return <div>Trace not found</div>;

  return (
    <div>
      <h2>Trace: {trace.traceId}</h2>
      <p>Agent: {trace.agent}</p>
      <p>Status: {trace.status}</p>
      <p>Duration: {trace.durationMs}ms</p>
      <p>Tokens: {trace.totalTokens}</p>

      <h3>Spans ({spans.length})</h3>
      <ul>
        {spans.map((span) => (
          <li key={span.spanId}>
            {span.name} ({span.kind}) - {span.status} - {span.durationMs}ms
          </li>
        ))}
      </ul>

      {configSnapshot && (
        <details>
          <summary>Configuration Snapshot</summary>
          <pre>{JSON.stringify(configSnapshot, null, 2)}</pre>
        </details>
      )}
    </div>
  );
}

With TraceTimeline Component

import {
  useTraceDetail,
  TraceTimeline,
} from "@modernpath/agent-ui-react";

function TraceTimelineView({ traceId }: { traceId: string }) {
  const { trace, spans, configSnapshot, isLoading } = useTraceDetail({
    backend: traceBackend,
    traceId,
  });

  if (isLoading || !trace) return <div>Loading...</div>;

  return (
    <TraceTimeline
      trace={trace}
      spans={spans}
      configSnapshot={configSnapshot}
      onClose={() => window.history.back()}
    />
  );
}

With React Router

import { useParams } from "react-router-dom";
import { useTraceDetail, TraceTimeline } from "@modernpath/agent-ui-react";

function TraceRoute() {
  const { traceId } = useParams<{ traceId: string }>();
  const { trace, spans, configSnapshot, isLoading, error } =
    useTraceDetail({
      backend: traceBackend,
      traceId: traceId!,
    });

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error loading trace: {error.message}</div>;
  if (!trace) return <div>Trace not found</div>;

  return (
    <TraceTimeline
      trace={trace}
      spans={spans}
      configSnapshot={configSnapshot ?? undefined}
    />
  );
}