feat: Day 11 - landing page polish, SDK README, PyPI publish as vectry-agentlens

- Landing page: pip install snippet, How it Works section, dual code examples (decorator + OpenAI wrapper), Integrations section, Open Source badge
- SDK README: quickstart, OpenAI/LangChain/Custom integrations, API reference, architecture diagram
- Published vectry-agentlens v0.1.0 to PyPI (import as agentlens)
- Fixed pyproject.toml: hatchling.build backend, wheel package mapping
This commit is contained in:
Vectry
2026-02-10 01:27:00 +00:00
parent 93e69105ea
commit 0cd242447c
4 changed files with 615 additions and 71 deletions

View File

@@ -7,6 +7,14 @@ import {
GitBranch,
Cpu,
Zap,
Terminal,
Code2,
Eye,
Package,
Link2,
Bot,
Star,
Clipboard,
} from "lucide-react";
export default function HomePage() {
@@ -16,12 +24,26 @@ export default function HomePage() {
<section className="relative overflow-hidden border-b border-neutral-800/50">
<div className="absolute inset-0 bg-gradient-to-b from-emerald-500/5 via-transparent to-transparent" />
<div className="absolute inset-0 bg-[radial-gradient(ellipse_80%_50%_at_50%_-20%,rgba(16,185,129,0.1),transparent)]" />
{/* Subtle grid pattern for depth */}
<div className="absolute inset-0 bg-[linear-gradient(rgba(255,255,255,0.012)_1px,transparent_1px),linear-gradient(90deg,rgba(255,255,255,0.012)_1px,transparent_1px)] bg-[size:64px_64px]" />
<div className="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 pt-20 pb-24">
<div className="text-center">
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full border border-emerald-500/20 bg-emerald-500/5 text-emerald-400 text-sm mb-8">
<Zap className="w-4 h-4" />
<span>Agent Observability Platform</span>
{/* Top badges row */}
<div className="flex flex-wrap items-center justify-center gap-3 mb-8">
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full border border-emerald-500/20 bg-emerald-500/5 text-emerald-400 text-sm">
<Zap className="w-4 h-4" />
<span>Agent Observability Platform</span>
</div>
<a
href="https://gitea.repi.fun/repi/agentlens"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-2 px-4 py-2 rounded-full border border-neutral-700/50 bg-neutral-800/30 text-neutral-400 text-sm hover:border-neutral-600 hover:text-neutral-300 transition-all duration-200"
>
<Star className="w-3.5 h-3.5" />
<span>Open Source</span>
</a>
</div>
<h1 className="text-6xl sm:text-7xl md:text-8xl font-bold tracking-tight mb-6">
@@ -30,16 +52,31 @@ export default function HomePage() {
</span>
</h1>
<p className="text-xl sm:text-2xl text-neutral-400 max-w-3xl mx-auto mb-10 leading-relaxed">
<p className="text-xl sm:text-2xl text-neutral-400 max-w-3xl mx-auto mb-8 leading-relaxed">
See why your AI agents make the decisions they make. <br className="hidden sm:block" />
Complete observability for multi-agent systems.
</p>
{/* pip install snippet */}
<div className="flex justify-center mb-10">
<div className="inline-flex items-center gap-3 px-5 py-3 rounded-full bg-neutral-800/80 border border-neutral-700/50 backdrop-blur-sm">
<Terminal className="w-4 h-4 text-neutral-500 flex-shrink-0" />
<code className="text-sm sm:text-base font-mono text-emerald-400 tracking-wide select-all">
pip install vectry-agentlens
</code>
<div className="w-px h-5 bg-neutral-700" />
<Clipboard className="w-4 h-4 text-neutral-500 flex-shrink-0" />
</div>
</div>
<div className="flex flex-col sm:flex-row gap-4 justify-center items-center">
<button className="group px-8 py-4 bg-emerald-500 hover:bg-emerald-400 text-neutral-950 font-semibold rounded-lg transition-all duration-200 flex items-center gap-2 shadow-lg shadow-emerald-500/25 hover:shadow-emerald-500/40">
<a
href="/dashboard"
className="group px-8 py-4 bg-emerald-500 hover:bg-emerald-400 text-neutral-950 font-semibold rounded-lg transition-all duration-200 flex items-center gap-2 shadow-lg shadow-emerald-500/25 hover:shadow-emerald-500/40"
>
Get Started
<ArrowRight className="w-5 h-5 group-hover:translate-x-1 transition-transform" />
</button>
</a>
<a
href="https://gitea.repi.fun/repi/agentlens"
target="_blank"
@@ -84,7 +121,7 @@ export default function HomePage() {
</div>
<h3 className="text-xl font-semibold mb-3">Context Awareness</h3>
<p className="text-neutral-400 leading-relaxed">
Monitor context window utilization in real-time. Track what's being fed into your agents and what's being left behind.
Monitor context window utilization in real-time. Track what&apos;s being fed into your agents and what&apos;s being left behind.
</p>
</div>
@@ -102,11 +139,102 @@ export default function HomePage() {
</div>
</section>
{/* How it Works Section */}
<section className="py-24 border-b border-neutral-800/50 relative">
<div className="absolute inset-0 bg-[radial-gradient(ellipse_60%_40%_at_50%_50%,rgba(16,185,129,0.04),transparent)]" />
<div className="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-16">
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full border border-neutral-700 bg-neutral-800/30 text-neutral-400 text-sm mb-6">
<Zap className="w-4 h-4" />
<span>Quick Setup</span>
</div>
<h2 className="text-3xl sm:text-4xl font-bold mb-4">
Up and running in 3 steps
</h2>
<p className="text-lg text-neutral-400 max-w-2xl mx-auto">
Go from zero to full agent observability in under five minutes
</p>
</div>
<div className="grid md:grid-cols-3 gap-6 lg:gap-8">
{/* Step 1: Install */}
<div className="relative p-8 rounded-2xl border border-neutral-800/50 bg-neutral-900/30">
<div className="absolute -top-4 left-8">
<span className="inline-flex items-center justify-center w-8 h-8 rounded-full bg-emerald-500 text-neutral-950 text-sm font-bold shadow-lg shadow-emerald-500/25">
1
</span>
</div>
<div className="w-12 h-12 rounded-xl bg-emerald-500/10 flex items-center justify-center mb-5 mt-2">
<Package className="w-6 h-6 text-emerald-400" />
</div>
<h3 className="text-lg font-semibold mb-2">Install</h3>
<p className="text-neutral-400 text-sm mb-4">
One command to add AgentLens to your project.
</p>
<div className="px-4 py-2.5 rounded-lg bg-neutral-800/80 border border-neutral-700/50">
<code className="text-sm font-mono text-emerald-400">pip install vectry-agentlens</code>
</div>
</div>
{/* Step 2: Instrument */}
<div className="relative p-8 rounded-2xl border border-neutral-800/50 bg-neutral-900/30">
<div className="absolute -top-4 left-8">
<span className="inline-flex items-center justify-center w-8 h-8 rounded-full bg-emerald-500 text-neutral-950 text-sm font-bold shadow-lg shadow-emerald-500/25">
2
</span>
</div>
<div className="w-12 h-12 rounded-xl bg-emerald-500/10 flex items-center justify-center mb-5 mt-2">
<Code2 className="w-6 h-6 text-emerald-400" />
</div>
<h3 className="text-lg font-semibold mb-2">Instrument</h3>
<p className="text-neutral-400 text-sm mb-4">
Add the <code className="text-emerald-400/80 font-mono text-xs bg-emerald-500/5 px-1.5 py-0.5 rounded">@trace</code> decorator or use <code className="text-emerald-400/80 font-mono text-xs bg-emerald-500/5 px-1.5 py-0.5 rounded">wrap_openai()</code>.
</p>
<div className="px-4 py-2.5 rounded-lg bg-neutral-800/80 border border-neutral-700/50">
<code className="text-sm font-mono text-emerald-400">@trace</code>
<span className="text-neutral-600 text-sm font-mono"> / </span>
<code className="text-sm font-mono text-emerald-400">wrap_openai()</code>
</div>
</div>
{/* Step 3: Observe */}
<div className="relative p-8 rounded-2xl border border-neutral-800/50 bg-neutral-900/30">
<div className="absolute -top-4 left-8">
<span className="inline-flex items-center justify-center w-8 h-8 rounded-full bg-emerald-500 text-neutral-950 text-sm font-bold shadow-lg shadow-emerald-500/25">
3
</span>
</div>
<div className="w-12 h-12 rounded-xl bg-emerald-500/10 flex items-center justify-center mb-5 mt-2">
<Eye className="w-6 h-6 text-emerald-400" />
</div>
<h3 className="text-lg font-semibold mb-2">Observe</h3>
<p className="text-neutral-400 text-sm mb-4">
See every decision in the real-time dashboard.
</p>
<div className="px-4 py-2.5 rounded-lg bg-neutral-800/80 border border-neutral-700/50">
<code className="text-sm font-mono text-emerald-400">agentlens.vectry.tech</code>
</div>
</div>
</div>
{/* Connecting arrows decoration */}
<div className="hidden md:flex items-center justify-center mt-10">
<div className="flex items-center gap-2">
<div className="w-16 h-px bg-gradient-to-r from-transparent to-emerald-500/30" />
<ArrowRight className="w-4 h-4 text-emerald-500/40" />
<div className="w-16 h-px bg-emerald-500/30" />
<ArrowRight className="w-4 h-4 text-emerald-500/40" />
<div className="w-16 h-px bg-gradient-to-l from-transparent to-emerald-500/30" />
</div>
</div>
</div>
</section>
{/* Code Example Section */}
<section className="py-24 border-b border-neutral-800/50">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="grid lg:grid-cols-2 gap-12 items-center">
<div>
<div className="grid lg:grid-cols-2 gap-12 items-start">
<div className="lg:sticky lg:top-8">
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full border border-neutral-700 bg-neutral-800/30 text-neutral-400 text-sm mb-6">
<Cpu className="w-4 h-4" />
<span>Python SDK</span>
@@ -136,44 +264,210 @@ export default function HomePage() {
</ul>
</div>
{/* Code Block */}
<div className="rounded-xl overflow-hidden border border-neutral-800 bg-neutral-900/50 backdrop-blur-sm">
<div className="px-4 py-3 border-b border-neutral-800 flex items-center gap-2">
<div className="flex gap-2">
<div className="w-3 h-3 rounded-full bg-neutral-600" />
<div className="w-3 h-3 rounded-full bg-neutral-600" />
<div className="w-3 h-3 rounded-full bg-neutral-600" />
{/* Code Blocks - Two patterns stacked */}
<div className="space-y-6">
{/* Decorator Pattern */}
<div className="rounded-xl overflow-hidden border border-neutral-800 bg-neutral-900/50 backdrop-blur-sm">
<div className="px-4 py-3 border-b border-neutral-800 flex items-center justify-between">
<div className="flex items-center gap-2">
<div className="flex gap-1.5">
<div className="w-3 h-3 rounded-full bg-neutral-700" />
<div className="w-3 h-3 rounded-full bg-neutral-700" />
<div className="w-3 h-3 rounded-full bg-neutral-700" />
</div>
<span className="ml-3 text-sm text-neutral-500">decorator_pattern.py</span>
</div>
<span className="text-xs font-medium px-2.5 py-1 rounded-full bg-emerald-500/10 text-emerald-400 border border-emerald-500/20">
@trace
</span>
</div>
<span className="ml-4 text-sm text-neutral-500">example.py</span>
<pre className="p-6 overflow-x-auto text-sm leading-relaxed">
<code className="text-neutral-300">
<span className="text-purple-400">from</span>{" "}
<span className="text-neutral-300">agentlens</span>{" "}
<span className="text-purple-400">import</span>{" "}
<span className="text-emerald-300">init</span>
<span className="text-neutral-300">,</span>{" "}
<span className="text-emerald-300">trace</span>
{"\n"}
{"\n"}
<span className="text-neutral-500"># Initialize AgentLens</span>
{"\n"}
<span className="text-emerald-300">init</span>
<span className="text-neutral-300">(</span>
{"\n"}
{" "}
<span className="text-orange-300">api_key</span>
<span className="text-neutral-300">=</span>
<span className="text-emerald-300">&quot;your-api-key&quot;</span>
<span className="text-neutral-300">,</span>
{"\n"}
{" "}
<span className="text-orange-300">endpoint</span>
<span className="text-neutral-300">=</span>
<span className="text-emerald-300">&quot;https://agentlens.vectry.tech&quot;</span>
{"\n"}
<span className="text-neutral-300">)</span>
{"\n"}
{"\n"}
<span className="text-neutral-500"># Trace your agent function</span>
{"\n"}
<span className="text-purple-400">@trace</span>
<span className="text-neutral-300">(</span>
<span className="text-orange-300">name</span>
<span className="text-neutral-300">=</span>
<span className="text-emerald-300">&quot;research-agent&quot;</span>
<span className="text-neutral-300">)</span>
{"\n"}
<span className="text-purple-400">async</span>{" "}
<span className="text-purple-400">def</span>{" "}
<span className="text-emerald-300">research</span>
<span className="text-neutral-300">(</span>
<span className="text-blue-300">topic</span>
<span className="text-neutral-300">:</span>{" "}
<span className="text-blue-300">str</span>
<span className="text-neutral-300">):</span>
{"\n"}
{" "}
<span className="text-neutral-500"># Your agent logic here</span>
{"\n"}
{" "}
<span className="text-purple-400">return</span>{" "}
<span className="text-emerald-300">f&quot;Researching: {"{topic}"}&quot;</span>
</code>
</pre>
</div>
<pre className="p-6 overflow-x-auto text-sm">
<code className="text-neutral-300">
<span className="text-purple-400">from</span> <span className="text-neutral-300">agentlens</span> <span className="text-purple-400">import</span> <span className="text-emerald-300">init</span><span className="text-neutral-300">,</span> <span className="text-emerald-300">trace</span>
<br />
<br />
<span className="text-neutral-500"># Initialize AgentLens</span>
<br />
<span className="text-emerald-300">init</span><span className="text-neutral-300">(</span>
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span className="text-orange-300">api_key</span><span className="text-neutral-300">=</span><span className="text-emerald-300">"your-api-key"</span><span className="text-neutral-300">,</span>
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span className="text-orange-300">endpoint</span><span className="text-neutral-300">=</span><span className="text-emerald-300">"https://agentlens.vectry.tech"</span>
<br />
<span className="text-neutral-300">)</span>
<br />
<br />
<span className="text-neutral-500"># Trace your agent function</span>
<br />
<span className="text-purple-400">@trace</span><span className="text-neutral-300">(</span><span className="text-orange-300">name</span><span className="text-neutral-300">=</span><span className="text-emerald-300">"research-agent"</span><span className="text-neutral-300">)</span>
<br />
<span className="text-purple-400">async</span> <span className="text-purple-400">def</span> <span className="text-emerald-300">research</span><span className="text-neutral-300">(</span><span className="text-blue-300">topic</span><span className="text-neutral-300">:</span> <span className="text-blue-300">str</span><span className="text-neutral-300">):</span>
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span className="text-neutral-500"># Your agent logic here</span>
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span className="text-purple-400">return</span> <span className="text-emerald-300">f"Researching: {"{topic"}"</span>
</code>
</pre>
{/* OpenAI Wrapper Pattern */}
<div className="rounded-xl overflow-hidden border border-neutral-800 bg-neutral-900/50 backdrop-blur-sm">
<div className="px-4 py-3 border-b border-neutral-800 flex items-center justify-between">
<div className="flex items-center gap-2">
<div className="flex gap-1.5">
<div className="w-3 h-3 rounded-full bg-neutral-700" />
<div className="w-3 h-3 rounded-full bg-neutral-700" />
<div className="w-3 h-3 rounded-full bg-neutral-700" />
</div>
<span className="ml-3 text-sm text-neutral-500">openai_wrapper.py</span>
</div>
<span className="text-xs font-medium px-2.5 py-1 rounded-full bg-purple-500/10 text-purple-400 border border-purple-500/20">
wrap_openai
</span>
</div>
<pre className="p-6 overflow-x-auto text-sm leading-relaxed">
<code className="text-neutral-300">
<span className="text-purple-400">from</span>{" "}
<span className="text-neutral-300">agentlens.integrations.openai</span>{" "}
<span className="text-purple-400">import</span>{" "}
<span className="text-emerald-300">wrap_openai</span>
{"\n"}
<span className="text-purple-400">import</span>{" "}
<span className="text-neutral-300">openai</span>
{"\n"}
{"\n"}
<span className="text-neutral-500"># Wrap the OpenAI client</span>
{"\n"}
<span className="text-neutral-300">client</span>{" "}
<span className="text-neutral-300">=</span>{" "}
<span className="text-neutral-300">openai.</span>
<span className="text-emerald-300">OpenAI</span>
<span className="text-neutral-300">()</span>
{"\n"}
<span className="text-neutral-300">client</span>{" "}
<span className="text-neutral-300">=</span>{" "}
<span className="text-emerald-300">wrap_openai</span>
<span className="text-neutral-300">(client)</span>
{"\n"}
{"\n"}
<span className="text-neutral-500"># Use as normal - traces automatically</span>
{"\n"}
<span className="text-neutral-300">response</span>{" "}
<span className="text-neutral-300">=</span>{" "}
<span className="text-neutral-300">client.chat.completions.</span>
<span className="text-emerald-300">create</span>
<span className="text-neutral-300">(</span>
{"\n"}
{" "}
<span className="text-orange-300">model</span>
<span className="text-neutral-300">=</span>
<span className="text-emerald-300">&quot;gpt-4&quot;</span>
<span className="text-neutral-300">,</span>
{"\n"}
{" "}
<span className="text-orange-300">messages</span>
<span className="text-neutral-300">=</span>
<span className="text-neutral-300">[</span>
<span className="text-neutral-300">{"{"}</span>
<span className="text-emerald-300">&quot;role&quot;</span>
<span className="text-neutral-300">:</span>{" "}
<span className="text-emerald-300">&quot;user&quot;</span>
<span className="text-neutral-300">,</span>{" "}
<span className="text-emerald-300">&quot;content&quot;</span>
<span className="text-neutral-300">:</span>{" "}
<span className="text-emerald-300">&quot;Hello!&quot;</span>
<span className="text-neutral-300">{"}"}</span>
<span className="text-neutral-300">]</span>
{"\n"}
<span className="text-neutral-300">)</span>
</code>
</pre>
</div>
</div>
</div>
</div>
</section>
{/* Integrations Section */}
<section className="py-24 border-b border-neutral-800/50 relative">
<div className="absolute inset-0 bg-[radial-gradient(ellipse_50%_50%_at_50%_50%,rgba(16,185,129,0.03),transparent)]" />
<div className="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-16">
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full border border-neutral-700 bg-neutral-800/30 text-neutral-400 text-sm mb-6">
<Link2 className="w-4 h-4" />
<span>Integrations</span>
</div>
<h2 className="text-3xl sm:text-4xl font-bold mb-4">
Works with your stack
</h2>
<p className="text-lg text-neutral-400 max-w-2xl mx-auto">
First-class support for the most popular AI frameworks. Drop in and start tracing.
</p>
</div>
<div className="grid sm:grid-cols-3 gap-6 max-w-3xl mx-auto">
{/* OpenAI */}
<div className="group flex flex-col items-center p-8 rounded-2xl border border-neutral-800/50 bg-neutral-900/30 hover:border-emerald-500/20 transition-all duration-300">
<div className="w-16 h-16 rounded-2xl bg-neutral-800/80 border border-neutral-700/50 flex items-center justify-center mb-5 group-hover:border-emerald-500/30 transition-colors duration-300">
<Cpu className="w-8 h-8 text-neutral-300 group-hover:text-emerald-400 transition-colors duration-300" />
</div>
<h3 className="text-lg font-semibold mb-1">OpenAI</h3>
<p className="text-sm text-neutral-500">GPT-4, GPT-3.5, o1</p>
<span className="mt-3 text-xs font-medium px-3 py-1 rounded-full bg-emerald-500/10 text-emerald-400 border border-emerald-500/20">
wrap_openai()
</span>
</div>
{/* LangChain */}
<div className="group flex flex-col items-center p-8 rounded-2xl border border-neutral-800/50 bg-neutral-900/30 hover:border-emerald-500/20 transition-all duration-300">
<div className="w-16 h-16 rounded-2xl bg-neutral-800/80 border border-neutral-700/50 flex items-center justify-center mb-5 group-hover:border-emerald-500/30 transition-colors duration-300">
<GitBranch className="w-8 h-8 text-neutral-300 group-hover:text-emerald-400 transition-colors duration-300" />
</div>
<h3 className="text-lg font-semibold mb-1">LangChain</h3>
<p className="text-sm text-neutral-500">Chains, Agents, Tools</p>
<span className="mt-3 text-xs font-medium px-3 py-1 rounded-full bg-emerald-500/10 text-emerald-400 border border-emerald-500/20">
Auto-instrumented
</span>
</div>
{/* Custom Agents */}
<div className="group flex flex-col items-center p-8 rounded-2xl border border-neutral-800/50 bg-neutral-900/30 hover:border-emerald-500/20 transition-all duration-300">
<div className="w-16 h-16 rounded-2xl bg-neutral-800/80 border border-neutral-700/50 flex items-center justify-center mb-5 group-hover:border-emerald-500/30 transition-colors duration-300">
<Bot className="w-8 h-8 text-neutral-300 group-hover:text-emerald-400 transition-colors duration-300" />
</div>
<h3 className="text-lg font-semibold mb-1">Custom Agents</h3>
<p className="text-sm text-neutral-500">Any Python agent</p>
<span className="mt-3 text-xs font-medium px-3 py-1 rounded-full bg-emerald-500/10 text-emerald-400 border border-emerald-500/20">
@trace decorator
</span>
</div>
</div>
</div>
@@ -203,7 +497,7 @@ export default function HomePage() {
</div>
<div className="text-sm text-neutral-500">
MIT License © 2026 Vectry
MIT License &copy; 2026 Vectry
</div>
</div>
</div>