feat: documentation pages and updated model pricing
- Add 13 documentation pages under /docs (getting-started, concepts, SDK refs, integrations, API reference, self-hosting, OpenCode plugin) - Shared docs layout with collapsible sidebar navigation - Update model pricing across all SDKs: add GPT-5.x, GPT-4.1, o3/o4-mini, Claude 4.5 series, claude-opus-4-6 - Update trace-analytics context window lookup with current models
This commit is contained in:
279
apps/web/src/app/docs/concepts/page.tsx
Normal file
279
apps/web/src/app/docs/concepts/page.tsx
Normal file
@@ -0,0 +1,279 @@
|
||||
import type { Metadata } from "next";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Core Concepts",
|
||||
description:
|
||||
"Understand the four core data types in AgentLens: Traces, Spans, Decision Points, and Events.",
|
||||
};
|
||||
|
||||
function CodeBlock({ children, title }: { children: string; title?: string }) {
|
||||
return (
|
||||
<div className="rounded-xl overflow-hidden border border-neutral-800 bg-neutral-900/50 my-4">
|
||||
{title && (
|
||||
<div className="px-4 py-2.5 border-b border-neutral-800 text-xs text-neutral-500 font-mono">
|
||||
{title}
|
||||
</div>
|
||||
)}
|
||||
<pre className="p-4 overflow-x-auto text-sm leading-relaxed">
|
||||
<code className="text-neutral-300">{children}</code>
|
||||
</pre>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ConceptCard({
|
||||
title,
|
||||
description,
|
||||
children,
|
||||
}: {
|
||||
title: string;
|
||||
description: string;
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<div className="mb-12 pb-12 border-b border-neutral-800/50 last:border-0">
|
||||
<h2 className="text-2xl font-semibold mb-3">{title}</h2>
|
||||
<p className="text-neutral-400 leading-relaxed mb-6">{description}</p>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function ConceptsPage() {
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold tracking-tight mb-4">
|
||||
Core Concepts
|
||||
</h1>
|
||||
<p className="text-lg text-neutral-400 mb-10 leading-relaxed">
|
||||
AgentLens organizes observability data into four core types. Together
|
||||
they give you a complete picture of what your agents do and why.
|
||||
</p>
|
||||
|
||||
<ConceptCard
|
||||
title="Trace"
|
||||
description="A Trace is the top-level container for a single agent execution. It groups all the work that happens from the moment your agent starts until it finishes. Every span, decision point, and event belongs to exactly one trace."
|
||||
>
|
||||
<h3 className="text-base font-medium text-neutral-200 mb-3">
|
||||
Properties
|
||||
</h3>
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full text-sm">
|
||||
<thead>
|
||||
<tr className="border-b border-neutral-800">
|
||||
<th className="text-left py-2 pr-4 text-neutral-400 font-medium">
|
||||
Field
|
||||
</th>
|
||||
<th className="text-left py-2 pr-4 text-neutral-400 font-medium">
|
||||
Type
|
||||
</th>
|
||||
<th className="text-left py-2 text-neutral-400 font-medium">
|
||||
Description
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="text-neutral-300">
|
||||
<tr className="border-b border-neutral-800/50">
|
||||
<td className="py-2 pr-4 font-mono text-emerald-400 text-xs">id</td>
|
||||
<td className="py-2 pr-4 text-neutral-500">string</td>
|
||||
<td className="py-2">Unique identifier (UUID v4)</td>
|
||||
</tr>
|
||||
<tr className="border-b border-neutral-800/50">
|
||||
<td className="py-2 pr-4 font-mono text-emerald-400 text-xs">name</td>
|
||||
<td className="py-2 pr-4 text-neutral-500">string</td>
|
||||
<td className="py-2">Human-readable label for the trace</td>
|
||||
</tr>
|
||||
<tr className="border-b border-neutral-800/50">
|
||||
<td className="py-2 pr-4 font-mono text-emerald-400 text-xs">status</td>
|
||||
<td className="py-2 pr-4 text-neutral-500">enum</td>
|
||||
<td className="py-2">RUNNING, COMPLETED, or ERROR</td>
|
||||
</tr>
|
||||
<tr className="border-b border-neutral-800/50">
|
||||
<td className="py-2 pr-4 font-mono text-emerald-400 text-xs">tags</td>
|
||||
<td className="py-2 pr-4 text-neutral-500">string[]</td>
|
||||
<td className="py-2">Freeform labels for filtering</td>
|
||||
</tr>
|
||||
<tr className="border-b border-neutral-800/50">
|
||||
<td className="py-2 pr-4 font-mono text-emerald-400 text-xs">sessionId</td>
|
||||
<td className="py-2 pr-4 text-neutral-500">string?</td>
|
||||
<td className="py-2">Groups traces from the same session</td>
|
||||
</tr>
|
||||
<tr className="border-b border-neutral-800/50">
|
||||
<td className="py-2 pr-4 font-mono text-emerald-400 text-xs">startedAt</td>
|
||||
<td className="py-2 pr-4 text-neutral-500">ISO datetime</td>
|
||||
<td className="py-2">When the trace began</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="py-2 pr-4 font-mono text-emerald-400 text-xs">endedAt</td>
|
||||
<td className="py-2 pr-4 text-neutral-500">ISO datetime?</td>
|
||||
<td className="py-2">When the trace finished (null if still running)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</ConceptCard>
|
||||
|
||||
<ConceptCard
|
||||
title="Span"
|
||||
description="A Span represents a unit of work within a trace. Spans form a tree: each span can have a parent, creating a hierarchy that shows how work is nested. For example, an AGENT span may contain several LLM_CALL and TOOL_CALL child spans."
|
||||
>
|
||||
<h3 className="text-base font-medium text-neutral-200 mb-3">
|
||||
Span Types
|
||||
</h3>
|
||||
<div className="grid sm:grid-cols-2 gap-3 mb-6">
|
||||
{[
|
||||
{ type: "LLM_CALL", desc: "A call to a language model (OpenAI, Anthropic, etc.)" },
|
||||
{ type: "TOOL_CALL", desc: "An invocation of an external tool or function" },
|
||||
{ type: "MEMORY_OP", desc: "A read or write to a vector store or memory system" },
|
||||
{ type: "CHAIN", desc: "A sequential pipeline of operations" },
|
||||
{ type: "AGENT", desc: "A top-level agent or sub-agent execution" },
|
||||
{ type: "CUSTOM", desc: "Any user-defined operation type" },
|
||||
].map((item) => (
|
||||
<div
|
||||
key={item.type}
|
||||
className="p-3 rounded-lg border border-neutral-800/50 bg-neutral-900/30"
|
||||
>
|
||||
<span className="font-mono text-xs text-emerald-400">
|
||||
{item.type}
|
||||
</span>
|
||||
<p className="text-xs text-neutral-500 mt-1">{item.desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<h3 className="text-base font-medium text-neutral-200 mb-3">
|
||||
Nesting example
|
||||
</h3>
|
||||
<CodeBlock>{`Trace: "research-agent"
|
||||
Span: "agent" (AGENT)
|
||||
Span: "plan" (LLM_CALL)
|
||||
Span: "web-search" (TOOL_CALL)
|
||||
Span: "summarize" (LLM_CALL)`}</CodeBlock>
|
||||
|
||||
<h3 className="text-base font-medium text-neutral-200 mb-3 mt-6">
|
||||
Key properties
|
||||
</h3>
|
||||
<ul className="text-sm text-neutral-400 space-y-2 ml-1">
|
||||
<li>
|
||||
<span className="font-mono text-emerald-400 text-xs">input</span> / <span className="font-mono text-emerald-400 text-xs">output</span> — JSON payloads capturing what went in and came out
|
||||
</li>
|
||||
<li>
|
||||
<span className="font-mono text-emerald-400 text-xs">tokenCount</span> — Total tokens consumed (for LLM_CALL spans)
|
||||
</li>
|
||||
<li>
|
||||
<span className="font-mono text-emerald-400 text-xs">costUsd</span> — Dollar cost of this span
|
||||
</li>
|
||||
<li>
|
||||
<span className="font-mono text-emerald-400 text-xs">durationMs</span> — Wall-clock time in milliseconds
|
||||
</li>
|
||||
<li>
|
||||
<span className="font-mono text-emerald-400 text-xs">parentSpanId</span> — Reference to the parent span (null for root spans)
|
||||
</li>
|
||||
</ul>
|
||||
</ConceptCard>
|
||||
|
||||
<ConceptCard
|
||||
title="Decision Point"
|
||||
description="A Decision Point records where your agent chose between alternatives. This is what separates AgentLens from generic tracing tools: you see the reasoning, what was chosen, and what was considered but rejected."
|
||||
>
|
||||
<h3 className="text-base font-medium text-neutral-200 mb-3">
|
||||
Decision Point Types
|
||||
</h3>
|
||||
<div className="grid sm:grid-cols-2 gap-3 mb-6">
|
||||
{[
|
||||
{ type: "TOOL_SELECTION", desc: "Agent chose which tool to call" },
|
||||
{ type: "ROUTING", desc: "Agent routed to a specific sub-agent or branch" },
|
||||
{ type: "RETRY", desc: "Agent decided to retry a failed operation" },
|
||||
{ type: "ESCALATION", desc: "Agent escalated to a human or higher-level agent" },
|
||||
{ type: "MEMORY_RETRIEVAL", desc: "Agent chose what context to retrieve" },
|
||||
{ type: "PLANNING", desc: "Agent formulated a multi-step plan" },
|
||||
].map((item) => (
|
||||
<div
|
||||
key={item.type}
|
||||
className="p-3 rounded-lg border border-neutral-800/50 bg-neutral-900/30"
|
||||
>
|
||||
<span className="font-mono text-xs text-emerald-400">
|
||||
{item.type}
|
||||
</span>
|
||||
<p className="text-xs text-neutral-500 mt-1">{item.desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<h3 className="text-base font-medium text-neutral-200 mb-3">
|
||||
Structure
|
||||
</h3>
|
||||
<CodeBlock title="decision_point.json">{`{
|
||||
"type": "TOOL_SELECTION",
|
||||
"reasoning": "User asked about weather, need real-time data",
|
||||
"chosen": { "tool": "weather_api", "confidence": 0.95 },
|
||||
"alternatives": [
|
||||
{ "tool": "web_search", "confidence": 0.72 },
|
||||
{ "tool": "knowledge_base", "confidence": 0.31 }
|
||||
],
|
||||
"contextSnapshot": { "user_intent": "weather_query" }
|
||||
}`}</CodeBlock>
|
||||
</ConceptCard>
|
||||
|
||||
<ConceptCard
|
||||
title="Event"
|
||||
description="An Event is a discrete occurrence during a trace that does not represent a unit of work but is worth recording. Events capture errors, retries, fallbacks, and other notable moments."
|
||||
>
|
||||
<h3 className="text-base font-medium text-neutral-200 mb-3">
|
||||
Event Types
|
||||
</h3>
|
||||
<div className="grid sm:grid-cols-2 gap-3 mb-6">
|
||||
{[
|
||||
{ type: "ERROR", desc: "An exception or failure occurred" },
|
||||
{ type: "RETRY", desc: "An operation was retried" },
|
||||
{ type: "FALLBACK", desc: "A fallback path was triggered" },
|
||||
{ type: "CONTEXT_OVERFLOW", desc: "Context window limit was exceeded" },
|
||||
{ type: "USER_FEEDBACK", desc: "User provided feedback on an output" },
|
||||
{ type: "CUSTOM", desc: "Any user-defined event type" },
|
||||
].map((item) => (
|
||||
<div
|
||||
key={item.type}
|
||||
className="p-3 rounded-lg border border-neutral-800/50 bg-neutral-900/30"
|
||||
>
|
||||
<span className="font-mono text-xs text-emerald-400">
|
||||
{item.type}
|
||||
</span>
|
||||
<p className="text-xs text-neutral-500 mt-1">{item.desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<h3 className="text-base font-medium text-neutral-200 mb-3">
|
||||
Example
|
||||
</h3>
|
||||
<CodeBlock title="event.json">{`{
|
||||
"type": "CONTEXT_OVERFLOW",
|
||||
"name": "token-limit-exceeded",
|
||||
"metadata": {
|
||||
"limit": 128000,
|
||||
"actual": 131072,
|
||||
"truncated_chars": 4200
|
||||
},
|
||||
"timestamp": "2026-01-15T10:30:00.000Z"
|
||||
}`}</CodeBlock>
|
||||
</ConceptCard>
|
||||
|
||||
<section>
|
||||
<h2 className="text-2xl font-semibold mb-4">How they fit together</h2>
|
||||
<CodeBlock>{`Trace: "customer-support-agent"
|
||||
|
|
||||
+-- Span: "classify-intent" (LLM_CALL)
|
||||
| Decision: ROUTING -> chose "refund-flow" over "faq-flow"
|
||||
|
|
||||
+-- Span: "refund-flow" (AGENT)
|
||||
| +-- Span: "lookup-order" (TOOL_CALL)
|
||||
| +-- Span: "process-refund" (TOOL_CALL)
|
||||
| Event: ERROR -> "payment-gateway-timeout"
|
||||
| Event: RETRY -> "retrying with backup gateway"
|
||||
| +-- Span: "process-refund-retry" (TOOL_CALL)
|
||||
|
|
||||
+-- Span: "compose-response" (LLM_CALL)`}</CodeBlock>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user