AgentPrism Documentation

repository·main·Indexed 18 days ago

https://github.com/evilmartians/agent-prism

An open-source React library for visualizing AI agent traces. It transforms JSON trace data from OpenTelemetry (OTLP) and Langfuse into interactive, hierarchical diagrams to debug agent workflows, LLM calls, and tool executions. The library includes a TraceViewer component, data transformation adapters (@evilmartians/agent-prism-data), and TypeScript definitions (@evilmartians/agent-prism-types) for managing spans, metadata, and metrics.

Tokens
19.8K
Snippets
56
Records
84
Agent score
60%

What's inside AgentPrism

  1. Quick Start with TraceViewer

    main

    The TraceViewer component is the fastest way to implement a complete trace visualization interface. It includes a Trace List, a hierarchical Tree View with search, and a Details Panel for inspecting span attributes.

    To use it, pass an array of data objects containing a traceRecord (metadata) and spans (the normalized span tree). Use the openTelemetrySpanAdapter to convert raw OTLP data into the required span format.

    import { TraceViewer } from "./components/agent-prism/TraceViewer";
    import { openTelemetrySpanAdapter } from "@evilmartians/agent-prism-data";
    
    function App() {
      return (
        <TraceViewer
          data={[
            {
              traceRecord: yourTraceRecord,
              spans: 
                openTelemetrySpanAdapter.convertRawDocumentsToSpans(yourTraceData),
            },
          ]}
        />
      );
    }
  2. Run the AgentPrism SaaS development server

    main

    To start the development environment for the AgentPrism SaaS application, run the development command using your preferred package manager. Once started, the application will be available at http://localhost:3000.

    npm run dev
    # or
    yarn dev
    # or
    pnpm dev
    # or
    bun dev
  3. Install AgentPrism

    main

    AgentPrism requires React 19+, Tailwind CSS 3, and TypeScript. Installation involves three steps: copying the UI components, installing the data/types packages, and installing the required UI dependencies.

    1. Copy UI components Use degit to copy the component source directly into your project structure:

    npx degit evilmartians/agent-prism/packages/ui/src/components src/components/agent-prism

    2. Install data and types packages

    npm install @evilmartians/agent-prism-data @evilmartians/agent-prism-types

    3. Install UI dependencies

    npm install @radix-ui/react-collapsible @radix-ui/react-tabs classnames lucide-react react-json-pretty react-resizable-panels
    npx degit evilmartians/agent-prism/packages/ui/src/components src/components/agent-prism
    npm install @evilmartians/agent-prism-data @evilmartians/agent-prism-types
    npm install @radix-ui/react-collapsible @radix-ui/react-tabs classnames lucide-react react-json-pretty react-resizable-panels
  4. Configure AgentPrism theming with Tailwind CSS

    main

    AgentPrism uses semantic tokens for colors based on the OKLCH color space. To use these colors in your Tailwind configuration, you must import agentPrismTailwindColors from the theme module.

    1. Import the theme types in your tailwind.config.js.
    2. Extend the theme by adding agentPrismTailwindColors to the colors object.
    3. Customize colors by modifying the theme.css file in your components folder. This file sets CSS variables on :root.

    Because tokens use OKLCH, you can use Tailwind's opacity syntax (e.g., bg-agentprism-primary/50).

    import { agentPrismTailwindColors } from "./src/components/theme";
    
    export default {
      theme: {
        extend: {
          colors: agentPrismTailwindColors,
        },
      },
    };
  5. Langfuse data structure for AgentPrism

    main

    When integrating Langfuse data with AgentPrism, the top-level data object must follow the LangfuseDocument shape. A LangfuseDocument consists of a single LangfuseTrace and an array of its associated LangfuseObservation objects.

    LangfuseDocument

    {
      trace: LangfuseTrace;
      observations: LangfuseObservation[];
    }
    export type LangfuseDocument = {
      trace: LangfuseTrace;
      observations: LangfuseObservation[];
    };
  6. Import types and constants from @evilmartians/agent-prism-types

    main

    You can import both TypeScript types for UI-ready spans and raw data structures, as well as semantic convention constants for OpenInference and OpenTelemetry mappings.

    Use import type for type-only imports to ensure they are stripped during compilation.

    // Import types
    import type {
      TraceSpan,
      TraceSpanAttribute,
      TraceSpanCategory,
      OpenTelemetrySpan,
      OpenTelemetryDocument,
    } from "@evilmartians/agent-prism-types";
    
    // Import constants for OpenInference semantic conventions
    import {
      OPENINFERENCE_ATTRIBUTES,
      OPENINFERENCE_MAPPINGS,
      OPENTELEMETRY_GENAI_MAPPINGS,
    } from "@evilmartians/agent-prism-types";
  7. Build custom layouts with individual components

    main

    If you need more control than TraceViewer provides, you can compose the UI using individual components. The core components are:

    • TraceList: For selecting traces from a list.
    • TreeView: For visualizing the hierarchical span tree (supports search, expand/collapse, and custom span card options).
    • DetailsView: For inspecting the attributes of a selected span.

    Example of a manual layout using a grid:

    import { useState } from "react";
    import type { TraceRecord, TraceSpan } from "@evilmartians/agent-prism-types";
    import { openTelemetrySpanAdapter } from "@evilmartians/agent-prism-data";
    
    import { TraceList } from "./components/agent-prism/TraceList/TraceList";
    import { TreeView } from "./components/agent-prism/TreeView";
    import { DetailsView } from "./components/agent-prism/DetailsView/DetailsView";
    
    // ... (mock data setup) ...
    
    export function App() {
      const [selectedTrace, setSelectedTrace] = useState<TraceRecord | undefined>(undefined);
      const [selectedSpan, setSelectedSpan] = useState<TraceSpan | undefined>(undefined);
      const [expandedSpansIds, setExpandedSpansIds] = useState<string[]>([]);
    
      const spans = openTelemetrySpanAdapter.convertRawDocumentsToSpans(traceData);
    
      return (
        <div className="grid grid-cols-3 gap-4">
          <TraceList
            traces={traces}
            expanded={true}
            onExpandStateChange={() => {}}
            onTraceSelect={setSelectedTrace}
            selectedTrace={selectedTrace}
          />
    
          <TreeView
            spans={spans}
            onSpanSelect={setSelectedSpan}
            selectedSpan={selectedSpan}
            expandedSpansIds={expandedSpansIds}
            onExpandSpansIdsChange={setExpandedSpansIds}
            spanCardViewOptions={{
              expandButton: "inside",
            }}
          />
    
          {selectedSpan && <DetailsView data={selectedSpan} />}
        </div>
      );
    }
  8. Extract metadata and metrics from OpenTelemetry spans

    main

    The openTelemetrySpanAdapter provides several utility methods to extract specific information from an individual span, such as cost, duration, tokens, and status. This is useful for populating UI components or performing analytics on traces.

    import { openTelemetrySpanAdapter } from "@evilmartians/agent-prism-data";
    
    // Extract information from spans
    const category = openTelemetrySpanAdapter.getSpanCategory(otlpSpan);
    const cost = openTelemetrySpanAdapter.getSpanCost(otlpSpan);
    const duration = openTelemetrySpanAdapter.getSpanDuration(otlpSpan);
    const inputOutput = openTelemetrySpanAdapter.getSpanInputOutput(otlpSpan);
    const status = openTelemetrySpanAdapter.getSpanStatus(otlpSpan);
    const tokens = openTelemetrySpanAdapter.getSpanTokensCount(otlpSpan);