([]);
const spans = openTelemetrySpanAdapter.convertRawDocumentsToSpans(traceData);
return (
{/* Traces sidebar */}
{}}
onTraceSelect={setSelectedTrace}
selectedTrace={selectedTrace}
/>
{/* Tree view */}
{/* Details panel */}
{selectedSpan && }
);
}
```
## Data Integration
AgentPrism uses a normalized data format optimized for UI rendering. Transform your trace data using the provided adapters.
All adapters implement the same interface and offer some helpful methods for transforming raw data (Open Telemetry, Langfuse, and so on) and getting some info out of it.
```tsx
import {
openTelemetrySpanAdapter,
langfuseSpanAdapter,
} from "@evilmartians/agent-prism-data";
// convert whole documents to TraceSpans (normalized view)
openTelemetrySpanAdapter.convertRawDocumentsToSpans(otlpData);
// convert single span (a.k.a. record, a.k.a. Langfuse observation)
openTelemetrySpanAdapter.convertRawSpanToTraceSpan(otlpData);
// in case you want to use TreeView component
openTelemetrySpanAdapter.convertRawSpansToSpanTree(otlpData);
// get some data for a particular observation/span (e.g. when you loaded one record)
langfuseSpanAdapter.getSpanCategory(observationData);
langfuseSpanAdapter.getSpanCost(observationData);
langfuseSpanAdapter.getSpanDuration(observationData);
langfuseSpanAdapter.getSpanInputOutput(observationData);
langfuseSpanAdapter.getSpanStatus(observationData);
langfuseSpanAdapter.getSpanTokensCount(observationData);
```
### OTLP Format
For OpenTelemetry traces, use the OTLP adapter:
```tsx
import { openTelemetrySpanAdapter } from "@evilmartians/agent-prism-data";
const spans = openTelemetrySpanAdapter.convertRawDocumentsToSpans(otlpDocument);
```
### Langfuse Format
For handling Langfuse observations, use Langfuse adapter
```tsx
import { langfuseSpanAdapter } from "@evilmartians/agent-prism-data";
const spans = langfuseSpanAdapter.convertRawDocumentsToSpans(langfuseDocument);
```
### Expected Data Structure
The UI components expect this data shape:
```tsx
interface TraceViewerData {
traceRecord: TraceRecord; // Trace metadata (id, timestamp, status)
spans: TraceSpan[]; // Hierarchical span tree
badges?: BadgeProps[]; // Optional trace badges
}
```
### Supported Attributes
AgentPrism recognizes standard semantic conventions:
- **OpenTelemetry GenAI**: `gen_ai.*` (model, tokens, costs)
- **OpenInference**: `llm.*`, `retrieval.*`
- **Standard OTEL**: HTTP, database spans
- **Custom**: Add your own attributes like `gen_ai.usage.cost`
### Sample OTLP Input
```json
{
"resourceSpans": [
{
"scopeSpans": [
{
"spans": [
{
"traceId": "abc123...",
"spanId": "def456...",
"name": "openai.chat",
"attributes": [
{
"key": "gen_ai.request.model",
"value": { "stringValue": "gpt-4" }
},
{
"key": "gen_ai.usage.input_tokens",
"value": { "intValue": "150" }
}
]
}
]
}
]
}
]
}
```
## Component Architecture
```
TraceViewer (complete solution)
├── TraceList (trace selection)
├── TreeView (span hierarchy)
│ ├── SearchInput
│ ├── CollapseAndExpandControls
│ └── Individual span rows
└── DetailsView (span inspection)
```
Use `TraceViewer` for quick setup, or compose individual components for custom layouts.
## Theming
Use semantic tokens for colors. The `theme` folder in components has 2 files:
- `theme.css` - import anywhere for bundler to process. Sets CSS variables on `:root`
- `index.ts` - exports types and `agentPrismTailwindColors`. Import in tailwind config:
```jsx
import { agentPrismTailwindColors } from "./src/components/theme";
export default {
theme: {
extend: {
colors: agentPrismTailwindColors,
},
},
};
```
Customize by changing semantic token values in `theme.css`. Defaults from tailwind colors (commented), but fully customizable.
Each token has 3 values (Lightness, Chroma, Hue) in Oklch format. This enables the use of `oklch(var(--${agentPrismPrefix}-${name}) / )` in Tailwind for opacity syntax like `bg-agentprism-primary/50`.
## Contributing
We welcome contributions to AgentPrism! Please see our [Contribution Guide](CONTRIBUTING.md) for details.