- NextAuth v5 credentials auth with registration/login pages - API key CRUD (create, list, revoke) with secure hashing - Stripe checkout, webhooks, and customer portal integration - Rate limiting per subscription tier - All dashboard API endpoints scoped to authenticated user - Prisma schema: User, Account, Session, ApiKey, plus Stripe fields - Auth middleware protecting dashboard and API routes Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-Claude) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
314 lines
14 KiB
TypeScript
314 lines
14 KiB
TypeScript
import type { Metadata } from "next";
|
|
import { CodeBlock } from "@/components/code-block";
|
|
|
|
export const metadata: Metadata = {
|
|
title: "Python SDK",
|
|
description:
|
|
"Full reference for the AgentLens Python SDK: init(), @trace decorator, log_decision(), TraceContext, and configuration.",
|
|
};
|
|
|
|
function ApiSection({
|
|
name,
|
|
signature,
|
|
description,
|
|
children,
|
|
}: {
|
|
name: string;
|
|
signature: string;
|
|
description: string;
|
|
children?: React.ReactNode;
|
|
}) {
|
|
return (
|
|
<div className="mb-10 pb-10 border-b border-neutral-800/50 last:border-0">
|
|
<h3 className="text-xl font-semibold mb-1">{name}</h3>
|
|
<div className="px-3 py-1.5 rounded-lg bg-neutral-900/50 border border-neutral-800/50 inline-block mb-3">
|
|
<code className="text-sm font-mono text-emerald-400">{signature}</code>
|
|
</div>
|
|
<p className="text-neutral-400 leading-relaxed mb-4">{description}</p>
|
|
{children}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default function PythonSdkPage() {
|
|
return (
|
|
<div>
|
|
<h1 className="text-4xl font-bold tracking-tight mb-4">Python SDK</h1>
|
|
<p className="text-lg text-neutral-400 mb-4 leading-relaxed">
|
|
The AgentLens Python SDK provides decorators, context managers, and
|
|
helper functions to instrument your AI agents.
|
|
</p>
|
|
|
|
<div className="px-4 py-3 rounded-lg bg-neutral-900/50 border border-neutral-800/50 mb-10">
|
|
<code className="text-sm font-mono text-emerald-400">
|
|
pip install vectry-agentlens
|
|
</code>
|
|
</div>
|
|
|
|
<h2 className="text-2xl font-semibold mb-6">API Reference</h2>
|
|
|
|
<ApiSection
|
|
name="init()"
|
|
signature="agentlens.init(api_key, endpoint, *, flush_interval=5.0, max_batch_size=100, enabled=True)"
|
|
description="Initialize the AgentLens SDK. Must be called before any tracing functions. Typically called once at application startup. Your API key can be created after registering at agentlens.vectry.tech — go to Dashboard > API Keys to generate one."
|
|
>
|
|
<h4 className="text-sm font-medium text-neutral-300 mb-2">
|
|
Parameters
|
|
</h4>
|
|
<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">Parameter</th>
|
|
<th className="text-left py-2 pr-4 text-neutral-400 font-medium">Type</th>
|
|
<th className="text-left py-2 pr-4 text-neutral-400 font-medium">Default</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">api_key</td>
|
|
<td className="py-2 pr-4 text-neutral-500">str</td>
|
|
<td className="py-2 pr-4 text-neutral-500">required</td>
|
|
<td className="py-2">Your AgentLens API key (from <a href="/dashboard/keys" className="text-emerald-400 hover:underline">Dashboard → API Keys</a>)</td>
|
|
</tr>
|
|
<tr className="border-b border-neutral-800/50">
|
|
<td className="py-2 pr-4 font-mono text-emerald-400 text-xs">endpoint</td>
|
|
<td className="py-2 pr-4 text-neutral-500">str</td>
|
|
<td className="py-2 pr-4 text-neutral-500">required</td>
|
|
<td className="py-2">AgentLens server URL</td>
|
|
</tr>
|
|
<tr className="border-b border-neutral-800/50">
|
|
<td className="py-2 pr-4 font-mono text-emerald-400 text-xs">flush_interval</td>
|
|
<td className="py-2 pr-4 text-neutral-500">float</td>
|
|
<td className="py-2 pr-4 text-neutral-500">5.0</td>
|
|
<td className="py-2">Seconds between automatic flushes</td>
|
|
</tr>
|
|
<tr className="border-b border-neutral-800/50">
|
|
<td className="py-2 pr-4 font-mono text-emerald-400 text-xs">max_batch_size</td>
|
|
<td className="py-2 pr-4 text-neutral-500">int</td>
|
|
<td className="py-2 pr-4 text-neutral-500">100</td>
|
|
<td className="py-2">Max traces per batch request</td>
|
|
</tr>
|
|
<tr>
|
|
<td className="py-2 pr-4 font-mono text-emerald-400 text-xs">enabled</td>
|
|
<td className="py-2 pr-4 text-neutral-500">bool</td>
|
|
<td className="py-2 pr-4 text-neutral-500">True</td>
|
|
<td className="py-2">Set to False to disable tracing globally</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<CodeBlock title="example.py" language="python">{`import agentlens
|
|
|
|
agentlens.init(
|
|
api_key="al_key_abc123",
|
|
endpoint="https://agentlens.vectry.tech",
|
|
flush_interval=10.0,
|
|
max_batch_size=50,
|
|
)`}</CodeBlock>
|
|
</ApiSection>
|
|
|
|
<ApiSection
|
|
name="@trace"
|
|
signature='@agentlens.trace(name=None, tags=None, metadata=None)'
|
|
description="Decorator that wraps a function in a trace. The trace starts when the function is called and ends when it returns or raises. Works with both sync and async functions."
|
|
>
|
|
<h4 className="text-sm font-medium text-neutral-300 mb-2">
|
|
Parameters
|
|
</h4>
|
|
<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">Parameter</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">name</td>
|
|
<td className="py-2 pr-4 text-neutral-500">str | None</td>
|
|
<td className="py-2">Trace name. Defaults to the function name.</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">list[str] | None</td>
|
|
<td className="py-2">Tags to attach to the trace</td>
|
|
</tr>
|
|
<tr>
|
|
<td className="py-2 pr-4 font-mono text-emerald-400 text-xs">metadata</td>
|
|
<td className="py-2 pr-4 text-neutral-500">dict | None</td>
|
|
<td className="py-2">Arbitrary metadata dict</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<CodeBlock title="decorator.py" language="python">{`from agentlens import trace
|
|
|
|
@trace(name="research-agent", tags=["research", "v2"])
|
|
async def research(topic: str) -> str:
|
|
result = await search(topic)
|
|
summary = await summarize(result)
|
|
return summary
|
|
|
|
# Can also be used without arguments
|
|
@trace
|
|
def simple_agent(prompt: str) -> str:
|
|
return call_llm(prompt)`}</CodeBlock>
|
|
</ApiSection>
|
|
|
|
<ApiSection
|
|
name="log_decision()"
|
|
signature="agentlens.log_decision(type, chosen, alternatives, *, reasoning=None, context_snapshot=None)"
|
|
description="Log a decision point within the current trace context. Must be called from within a @trace-decorated function."
|
|
>
|
|
<h4 className="text-sm font-medium text-neutral-300 mb-2">
|
|
Parameters
|
|
</h4>
|
|
<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">Parameter</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">type</td>
|
|
<td className="py-2 pr-4 text-neutral-500">str</td>
|
|
<td className="py-2">One of: TOOL_SELECTION, ROUTING, RETRY, ESCALATION, MEMORY_RETRIEVAL, PLANNING, CUSTOM</td>
|
|
</tr>
|
|
<tr className="border-b border-neutral-800/50">
|
|
<td className="py-2 pr-4 font-mono text-emerald-400 text-xs">chosen</td>
|
|
<td className="py-2 pr-4 text-neutral-500">dict</td>
|
|
<td className="py-2">What was chosen</td>
|
|
</tr>
|
|
<tr className="border-b border-neutral-800/50">
|
|
<td className="py-2 pr-4 font-mono text-emerald-400 text-xs">alternatives</td>
|
|
<td className="py-2 pr-4 text-neutral-500">list[dict]</td>
|
|
<td className="py-2">What else was considered</td>
|
|
</tr>
|
|
<tr className="border-b border-neutral-800/50">
|
|
<td className="py-2 pr-4 font-mono text-emerald-400 text-xs">reasoning</td>
|
|
<td className="py-2 pr-4 text-neutral-500">str | None</td>
|
|
<td className="py-2">Why this choice was made</td>
|
|
</tr>
|
|
<tr>
|
|
<td className="py-2 pr-4 font-mono text-emerald-400 text-xs">context_snapshot</td>
|
|
<td className="py-2 pr-4 text-neutral-500">dict | None</td>
|
|
<td className="py-2">Snapshot of context at decision time</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<CodeBlock title="decisions.py" language="python">{`import agentlens
|
|
from agentlens import trace
|
|
|
|
@trace(name="routing-agent")
|
|
async def route_request(user_input: str):
|
|
intent = classify_intent(user_input)
|
|
|
|
agentlens.log_decision(
|
|
type="ROUTING",
|
|
chosen={"handler": "refund", "confidence": 0.92},
|
|
alternatives=[
|
|
{"handler": "faq", "confidence": 0.65},
|
|
{"handler": "escalate", "confidence": 0.23},
|
|
],
|
|
reasoning="High confidence refund intent detected",
|
|
context_snapshot={"intent": intent, "input_length": len(user_input)},
|
|
)
|
|
|
|
return await handle_refund(user_input)`}</CodeBlock>
|
|
</ApiSection>
|
|
|
|
<ApiSection
|
|
name="TraceContext"
|
|
signature="agentlens.TraceContext"
|
|
description="Context manager for manual trace lifecycle control. Use this when the @trace decorator does not fit your workflow."
|
|
>
|
|
<CodeBlock title="context.py" language="python">{`import agentlens
|
|
|
|
async def process_batch(items: list[str]):
|
|
for item in items:
|
|
ctx = agentlens.TraceContext(
|
|
name=f"process-{item}",
|
|
tags=["batch"],
|
|
)
|
|
ctx.start()
|
|
|
|
try:
|
|
result = await process(item)
|
|
ctx.add_span(
|
|
name="process",
|
|
type="CUSTOM",
|
|
input={"item": item},
|
|
output={"result": result},
|
|
status="COMPLETED",
|
|
)
|
|
ctx.end(status="COMPLETED")
|
|
except Exception as e:
|
|
ctx.add_event(type="ERROR", name=str(e))
|
|
ctx.end(status="ERROR")`}</CodeBlock>
|
|
</ApiSection>
|
|
|
|
<ApiSection
|
|
name="shutdown()"
|
|
signature="agentlens.shutdown(timeout=10.0)"
|
|
description="Flush all pending traces and shut down the background sender. Call this before your application exits to avoid losing data."
|
|
>
|
|
<CodeBlock title="shutdown.py" language="python">{`import agentlens
|
|
import atexit
|
|
|
|
agentlens.init(api_key="...", endpoint="...")
|
|
|
|
# Register shutdown hook
|
|
atexit.register(agentlens.shutdown)
|
|
|
|
# Or call manually
|
|
agentlens.shutdown(timeout=30.0)`}</CodeBlock>
|
|
</ApiSection>
|
|
|
|
<section className="mt-12">
|
|
<h2 className="text-2xl font-semibold mb-4">Configuration</h2>
|
|
<p className="text-neutral-400 leading-relaxed mb-4">
|
|
The SDK can also be configured via environment variables. These take
|
|
precedence over values passed to <code className="text-emerald-400 font-mono text-xs bg-emerald-500/5 px-1.5 py-0.5 rounded">init()</code>.
|
|
</p>
|
|
<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">Variable</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">AGENTLENS_API_KEY</td>
|
|
<td className="py-2">API key for authentication</td>
|
|
</tr>
|
|
<tr className="border-b border-neutral-800/50">
|
|
<td className="py-2 pr-4 font-mono text-emerald-400 text-xs">AGENTLENS_ENDPOINT</td>
|
|
<td className="py-2">Server URL</td>
|
|
</tr>
|
|
<tr className="border-b border-neutral-800/50">
|
|
<td className="py-2 pr-4 font-mono text-emerald-400 text-xs">AGENTLENS_ENABLED</td>
|
|
<td className="py-2">Set to "false" to disable tracing</td>
|
|
</tr>
|
|
<tr>
|
|
<td className="py-2 pr-4 font-mono text-emerald-400 text-xs">AGENTLENS_FLUSH_INTERVAL</td>
|
|
<td className="py-2">Flush interval in seconds</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
);
|
|
}
|