feat: initial monorepo scaffold - Next.js 15 + Prisma + Python SDK stubs
- Turborepo monorepo with apps/web and packages/database, sdk-python - Next.js 15 app with professional landing page (dark theme, emerald accent) - Prisma schema: Trace, DecisionPoint, Span, Event models with full indexing - Docker Compose: web (port 4200), postgres:16, redis:7, migrate service - Python SDK package stubs: init, trace decorator, log_decision, integrations - Multi-stage Dockerfile for standalone Next.js production build
This commit is contained in:
6
apps/web/next-env.d.ts
vendored
Normal file
6
apps/web/next-env.d.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
/// <reference path="./.next/types/routes.d.ts" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|
||||
7
apps/web/next.config.mjs
Normal file
7
apps/web/next.config.mjs
Normal file
@@ -0,0 +1,7 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const config = {
|
||||
transpilePackages: ["@agentlens/database"],
|
||||
output: "standalone",
|
||||
};
|
||||
|
||||
export default config;
|
||||
30
apps/web/package.json
Normal file
30
apps/web/package.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "@agentlens/web",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "next lint",
|
||||
"db:generate": "prisma generate --schema=../../packages/database/prisma/schema.prisma",
|
||||
"db:push": "prisma db push --schema=../../packages/database/prisma/schema.prisma",
|
||||
"db:migrate": "prisma migrate deploy --schema=../../packages/database/prisma/schema.prisma"
|
||||
},
|
||||
"dependencies": {
|
||||
"@agentlens/database": "*",
|
||||
"next": "^15.1.0",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"lucide-react": "^0.469.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4.0.0",
|
||||
"@types/node": "^22.0.0",
|
||||
"@types/react": "^19.0.0",
|
||||
"@types/react-dom": "^19.0.0",
|
||||
"postcss": "^8.5.0",
|
||||
"tailwindcss": "^4.0.0",
|
||||
"typescript": "^5.7"
|
||||
}
|
||||
}
|
||||
6
apps/web/postcss.config.mjs
Normal file
6
apps/web/postcss.config.mjs
Normal file
@@ -0,0 +1,6 @@
|
||||
const config = {
|
||||
plugins: {
|
||||
"@tailwindcss/postcss": {},
|
||||
},
|
||||
};
|
||||
export default config;
|
||||
0
apps/web/public/.gitkeep
Normal file
0
apps/web/public/.gitkeep
Normal file
1
apps/web/src/app/globals.css
Normal file
1
apps/web/src/app/globals.css
Normal file
@@ -0,0 +1 @@
|
||||
@import "tailwindcss";
|
||||
24
apps/web/src/app/layout.tsx
Normal file
24
apps/web/src/app/layout.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import { Inter } from "next/font/google";
|
||||
import type { Metadata } from "next";
|
||||
import "./globals.css";
|
||||
|
||||
const inter = Inter({ subsets: ["latin"] });
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "AgentLens",
|
||||
description: "Agent observability that traces decisions, not just API calls",
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
return (
|
||||
<html lang="en" className="dark">
|
||||
<body className={`${inter.className} bg-neutral-950 text-neutral-100 antialiased`}>
|
||||
{children}
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
213
apps/web/src/app/page.tsx
Normal file
213
apps/web/src/app/page.tsx
Normal file
@@ -0,0 +1,213 @@
|
||||
import {
|
||||
Activity,
|
||||
Brain,
|
||||
DollarSign,
|
||||
ArrowRight,
|
||||
CheckCircle2,
|
||||
GitBranch,
|
||||
Cpu,
|
||||
Zap,
|
||||
} from "lucide-react";
|
||||
|
||||
export default function HomePage() {
|
||||
return (
|
||||
<div className="min-h-screen bg-neutral-950">
|
||||
{/* Hero Section */}
|
||||
<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)]" />
|
||||
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<h1 className="text-6xl sm:text-7xl md:text-8xl font-bold tracking-tight mb-6">
|
||||
<span className="bg-gradient-to-br from-emerald-400 via-emerald-300 to-emerald-500 bg-clip-text text-transparent">
|
||||
AgentLens
|
||||
</span>
|
||||
</h1>
|
||||
|
||||
<p className="text-xl sm:text-2xl text-neutral-400 max-w-3xl mx-auto mb-10 leading-relaxed">
|
||||
See why your AI agents make the decisions they make. <br className="hidden sm:block" />
|
||||
Complete observability for multi-agent systems.
|
||||
</p>
|
||||
|
||||
<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">
|
||||
Get Started
|
||||
<ArrowRight className="w-5 h-5 group-hover:translate-x-1 transition-transform" />
|
||||
</button>
|
||||
<a
|
||||
href="https://gitea.repi.fun/repi/agentlens"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="px-8 py-4 border border-neutral-700 hover:border-neutral-600 text-neutral-300 font-medium rounded-lg transition-all duration-200"
|
||||
>
|
||||
View Source
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Features 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="text-center mb-16">
|
||||
<h2 className="text-3xl sm:text-4xl font-bold mb-4">
|
||||
Everything you need to understand your agents
|
||||
</h2>
|
||||
<p className="text-lg text-neutral-400 max-w-2xl mx-auto">
|
||||
From decision trees to cost intelligence, get complete visibility into how your AI systems operate
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid md:grid-cols-3 gap-8">
|
||||
{/* Feature 1: Decision Trees */}
|
||||
<div className="group p-8 rounded-2xl border border-neutral-800/50 bg-gradient-to-b from-neutral-900/50 to-transparent hover:border-emerald-500/30 transition-all duration-300">
|
||||
<div className="w-14 h-14 rounded-xl bg-emerald-500/10 flex items-center justify-center mb-6 group-hover:scale-110 transition-transform duration-300">
|
||||
<GitBranch className="w-7 h-7 text-emerald-400" />
|
||||
</div>
|
||||
<h3 className="text-xl font-semibold mb-3">Decision Trees</h3>
|
||||
<p className="text-neutral-400 leading-relaxed">
|
||||
Visualize the complete reasoning behind every agent choice. See the branching logic, alternatives considered, and the path chosen.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Feature 2: Context Awareness */}
|
||||
<div className="group p-8 rounded-2xl border border-neutral-800/50 bg-gradient-to-b from-neutral-900/50 to-transparent hover:border-emerald-500/30 transition-all duration-300">
|
||||
<div className="w-14 h-14 rounded-xl bg-emerald-500/10 flex items-center justify-center mb-6 group-hover:scale-110 transition-transform duration-300">
|
||||
<Brain className="w-7 h-7 text-emerald-400" />
|
||||
</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.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Feature 3: Cost Intelligence */}
|
||||
<div className="group p-8 rounded-2xl border border-neutral-800/50 bg-gradient-to-b from-neutral-900/50 to-transparent hover:border-emerald-500/30 transition-all duration-300">
|
||||
<div className="w-14 h-14 rounded-xl bg-emerald-500/10 flex items-center justify-center mb-6 group-hover:scale-110 transition-transform duration-300">
|
||||
<DollarSign className="w-7 h-7 text-emerald-400" />
|
||||
</div>
|
||||
<h3 className="text-xl font-semibold mb-3">Cost Intelligence</h3>
|
||||
<p className="text-neutral-400 leading-relaxed">
|
||||
Track spending per decision, per agent, per trace. Get granular insights into where every dollar goes in your AI operations.
|
||||
</p>
|
||||
</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="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>
|
||||
</div>
|
||||
|
||||
<h2 className="text-3xl sm:text-4xl font-bold mb-4">
|
||||
Instrument your agents in minutes
|
||||
</h2>
|
||||
<p className="text-lg text-neutral-400 mb-8 leading-relaxed">
|
||||
Our Python SDK integrates seamlessly with LangChain, OpenAI, and custom agents. Add observability without changing your architecture.
|
||||
</p>
|
||||
|
||||
<ul className="space-y-4">
|
||||
{[
|
||||
"Drop-in decorators for automatic tracing",
|
||||
"No code changes required for LangChain",
|
||||
"Async-first design with minimal overhead",
|
||||
"Type-safe with full IDE support",
|
||||
].map((feature, i) => (
|
||||
<li key={i} className="flex items-start gap-3">
|
||||
<div className="w-6 h-6 rounded-full bg-emerald-500/20 flex items-center justify-center flex-shrink-0 mt-0.5">
|
||||
<CheckCircle2 className="w-4 h-4 text-emerald-400" />
|
||||
</div>
|
||||
<span className="text-neutral-300">{feature}</span>
|
||||
</li>
|
||||
))}
|
||||
</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" />
|
||||
</div>
|
||||
<span className="ml-4 text-sm text-neutral-500">example.py</span>
|
||||
</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 />
|
||||
<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 />
|
||||
<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 />
|
||||
<span className="text-neutral-500"># Your agent logic here</span>
|
||||
<br />
|
||||
<span className="text-purple-400">return</span> <span className="text-emerald-300">f"Researching: {"{topic"}"</span>
|
||||
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Footer */}
|
||||
<footer className="py-12 border-t border-neutral-800/50">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex flex-col md:flex-row justify-between items-center gap-6">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-8 h-8 rounded bg-gradient-to-br from-emerald-400 to-emerald-600 flex items-center justify-center">
|
||||
<Activity className="w-5 h-5 text-white" />
|
||||
</div>
|
||||
<span className="font-semibold text-lg">AgentLens</span>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-8 text-sm text-neutral-400">
|
||||
<a href="https://vectry.tech" target="_blank" rel="noopener noreferrer" className="hover:text-emerald-400 transition-colors">
|
||||
Built by Vectry
|
||||
</a>
|
||||
<a href="https://gitea.repi.fun/repi/agentlens" target="_blank" rel="noopener noreferrer" className="hover:text-emerald-400 transition-colors">
|
||||
Source Code
|
||||
</a>
|
||||
<a href="https://agentlens.vectry.tech/docs" target="_blank" rel="noopener noreferrer" className="hover:text-emerald-400 transition-colors">
|
||||
Documentation
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="text-sm text-neutral-500">
|
||||
MIT License © 2026 Vectry
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
23
apps/web/tsconfig.json
Normal file
23
apps/web/tsconfig.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"plugins": [{ "name": "next" }],
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
Reference in New Issue
Block a user