Skip to content

Commit 52be3b9

Browse files
vishalshenoytkucar
authored and
tkucar
committed
AI impact dashboard (#808)
1 parent 4df2e83 commit 52be3b9

38 files changed

+7070
-0
lines changed
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# AI Impact Analysis
2+
3+
This script analyzes a codebase to measure and report the impact of AI-generated code contributions. It provides detailed insights about AI vs human contributions, helping teams understand the role of AI in their development process.
4+
5+
## Features
6+
7+
- **Repository Analysis**: Automatically detects and analyzes git repositories:
8+
9+
- Uses current directory if it's a git repo
10+
11+
- Searches parent directories for a git repo
12+
13+
- Falls back to cloning a specified repository if needed
14+
15+
```python
16+
# Basic repository setup
17+
repo_path = os.getcwd()
18+
repo_config = RepoConfig.from_repo_path(repo_path)
19+
repo_operator = RepoOperator(repo_config=repo_config)
20+
project = ProjectConfig.from_repo_operator(repo_operator=repo_operator, programming_language=ProgrammingLanguage.PYTHON)
21+
codebase = Codebase(projects=[project])
22+
```
23+
24+
- **Comprehensive Statistics**:
25+
26+
- Total number of commits and AI vs human contribution percentages
27+
- Files with significant AI contribution (>50%)
28+
- AI-touched symbols and their impact
29+
- Detailed contributor breakdown (human and AI contributors)
30+
31+
```python
32+
# Run the analysis
33+
ai_authors = ["github-actions[bot]", "dependabot[bot]"]
34+
results = analyze_ai_impact(codebase, ai_authors)
35+
36+
# Access statistics
37+
stats = results["stats"]
38+
print(f"Total commits: {stats['total_commits']}")
39+
print(f"AI commits: {stats['ai_commits']} ({stats['ai_percentage']:.1f}%)")
40+
print(f"Files with >50% AI: {stats['ai_file_count']} of {stats['total_file_count']}")
41+
42+
# View contributors
43+
for author, count in results["contributors"]:
44+
is_ai = any(ai_name in author for ai_name in ai_authors)
45+
print(f"{'🤖' if is_ai else '👤'} {author}: {count} commits")
46+
```
47+
48+
- **High-Impact Code Detection**:
49+
50+
- Identifies AI-written code that is heavily used by other parts of the codebase
51+
- Shows dependency relationships for AI-contributed code
52+
53+
```python
54+
# Access high-impact AI symbols
55+
for symbol in results["high_impact_symbols"]:
56+
print(f"Symbol: {symbol['name']} ({symbol['filepath']})")
57+
print(f"Used by {symbol['usage_count']} other symbols")
58+
print(f"Last edited by: {symbol['last_editor']}")
59+
60+
# View top AI-contributed files
61+
for file_path, percentage in stats["top_ai_files"]:
62+
print(f"{file_path}: {percentage:.1f}% AI contribution")
63+
```
64+
65+
- **Detailed Attribution**:
66+
67+
- Maps symbols to git history
68+
- Tracks last editor and complete editor history for each symbol
69+
- Flags AI-authored symbols
70+
71+
```python
72+
# Get attribution information for a specific symbol
73+
symbol = codebase.get_symbol("path/to/file.py:MyClass.my_method")
74+
75+
# Access attribution data
76+
print(f"Last editor: {symbol.last_editor}")
77+
print(f"Editor history: {symbol.editor_history}")
78+
print(f"AI authored: {symbol.is_ai_authored}")
79+
80+
# Find all AI-authored symbols
81+
ai_symbols = [s for s in codebase.get_symbols() if s.is_ai_authored]
82+
for symbol in ai_symbols:
83+
print(f"AI symbol: {symbol.name}")
84+
```
85+
86+
## Output
87+
88+
The script generates:
89+
90+
1. Console output with summary statistics
91+
1. Detailed analysis in `ai_impact_analysis.json`
92+
1. Attribution information added to codebase symbols
93+
94+
## Usage
95+
96+
```bash
97+
python run.py
98+
```
99+
100+
The script will automatically:
101+
102+
1. Initialize and analyze the codebase
103+
1. Process git history
104+
1. Generate attribution information
105+
1. Output detailed statistics
106+
107+
You can also visualize the AI impact analysis results using a dashboard. For setup and usage instructions, please see the documentation in the `/dashboard` subdirectory.
108+
109+
## Symbol Attribution
110+
111+
After running the analysis, symbols in the codebase will have the following attribution information:
112+
113+
- `symbol.last_editor`: The last person who edited the symbol
114+
- `symbol.editor_history`: List of all editors who have touched the symbol
115+
- `symbol.is_ai_authored`: Boolean indicating if the symbol was authored by AI
116+
117+
## Learn More
118+
119+
- [Attributions](https://docs.codegen.com/tutorials/attributions)
120+
- [Codegen Documentation](https://docs.codegen.com)
121+
122+
## Contributing
123+
124+
Feel free to submit issues and enhancement requests!
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# AI Impact Analysis Dashboard
2+
3+
A web dashboard for visualizing AI-generated code contributions in your codebase. This dashboard provides detailed insights about AI vs human contributions, helping understand the role of AI in a codebase development process.
4+
5+
## Setup
6+
7+
### Backend
8+
9+
1. Install dependencies:
10+
11+
```bash
12+
uv venv
13+
source .venv/bin/activate
14+
uv pip install modal codegen fastapi
15+
```
16+
17+
2. Deploy or serve the Modal endpoint:
18+
19+
```bash
20+
modal serve backend/api.py
21+
```
22+
23+
```bash
24+
modal deploy backend/api.py
25+
```
26+
27+
### Frontend
28+
29+
1. Install dependencies:
30+
31+
```bash
32+
cd frontend
33+
npm install
34+
```
35+
36+
2. Update the API endpoint:
37+
Edit the fetch URL on line 29 in `components/repo-analysis-dashboard.tsx` to point to your Modal endpoint:
38+
39+
```bash
40+
fetch(`[your-modal-deployment-url]/analyze?repo_full_name=${repoFullName}`, {
41+
method: 'POST',
42+
})
43+
```
44+
45+
3. Start the development server:
46+
47+
```bash
48+
npm run dev
49+
```
50+
51+
## Usage
52+
53+
1. Visit the dashboard in your browser (default: http://localhost:3000)
54+
1. Enter a GitHub repository name (format: username/repo)
55+
1. Click "Analyze Repo" to generate insights
56+
57+
The dashboard will display:
58+
59+
- Summary statistics of AI contributions
60+
- Monthly contribution timeline
61+
- Top files with AI contributions
62+
- High-impact AI-authored symbols
63+
- Contributor breakdown visualization
64+
65+
## Architecture
66+
67+
- **Backend**: Modal-deployed FastAPI service that:
68+
69+
- Clones and analyzes repositories
70+
- Processes git history
71+
- Calculates AI impact metrics
72+
- Returns structured analysis data
73+
74+
- **Frontend**: Next.js application with:
75+
76+
- Interactive charts
77+
- Visualized AI impact metrics
78+
79+
## Learn More
80+
81+
- [AI Impact Analysis Documentation](https://docs.codegen.com/tutorials/attributions)
82+
- [Codegen Documentation](https://docs.codegen.com)
83+
84+
## Contributing
85+
86+
Feel free to submit issues and enhancement requests!
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
from codegen import Codebase
2+
from codegen.extensions.attribution.main import (
3+
add_attribution_to_symbols,
4+
analyze_ai_impact,
5+
)
6+
from fastapi import FastAPI
7+
from fastapi.middleware.cors import CORSMiddleware
8+
import modal
9+
10+
image = modal.Image.debian_slim().apt_install("git").pip_install("codegen", "fastapi", "intervaltree", "pygit2", "requests")
11+
12+
app = modal.App(name="ai-impact-analysis", image=image)
13+
14+
fastapi_app = FastAPI()
15+
16+
fastapi_app.add_middleware(
17+
CORSMiddleware,
18+
allow_origins=["*"],
19+
allow_credentials=True,
20+
allow_methods=["*"],
21+
allow_headers=["*"],
22+
)
23+
24+
25+
@fastapi_app.post("/analyze")
26+
async def analyze(repo_full_name: str):
27+
codebase = Codebase.from_repo(repo_full_name=repo_full_name, language="python", full_history=True)
28+
29+
print("🤖 Analyzing AI impact on codebase...")
30+
31+
ai_authors = [
32+
"renovate[bot]",
33+
"dependabot[bot]",
34+
"github-actions[bot]",
35+
"devin-ai-integration[bot]",
36+
]
37+
38+
results = analyze_ai_impact(codebase, ai_authors)
39+
40+
print("\n🏷️ Adding attribution information to symbols...")
41+
add_attribution_to_symbols(codebase, ai_authors)
42+
print("✅ Attribution information added to symbols")
43+
44+
return results
45+
46+
47+
@app.function(image=image)
48+
@modal.asgi_app()
49+
def fastapi_modal_app():
50+
return fastapi_app
51+
52+
53+
if __name__ == "__main__":
54+
app.deploy("ai-impact-analysis")
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
@tailwind base;
2+
@tailwind components;
3+
@tailwind utilities;
4+
5+
@layer base {
6+
:root {
7+
--background: 0 0% 100%;
8+
--foreground: 222.2 84% 4.9%;
9+
10+
--card: 0 0% 100%;
11+
--card-foreground: 222.2 84% 4.9%;
12+
13+
--popover: 0 0% 100%;
14+
--popover-foreground: 222.2 84% 4.9%;
15+
16+
--primary: 221.2 83.2% 53.3%;
17+
--primary-foreground: 210 40% 98%;
18+
19+
--secondary: 210 40% 96.1%;
20+
--secondary-foreground: 222.2 47.4% 11.2%;
21+
22+
--muted: 210 40% 96.1%;
23+
--muted-foreground: 215.4 16.3% 46.9%;
24+
25+
--accent: 210 40% 96.1%;
26+
--accent-foreground: 222.2 47.4% 11.2%;
27+
28+
--destructive: 0 84.2% 60.2%;
29+
--destructive-foreground: 210 40% 98%;
30+
31+
--border: 214.3 31.8% 91.4%;
32+
--input: 214.3 31.8% 91.4%;
33+
--ring: 221.2 83.2% 53.3%;
34+
35+
--radius: 0.5rem;
36+
}
37+
38+
.dark {
39+
--background: 222.2 84% 4.9%;
40+
--foreground: 210 40% 98%;
41+
42+
--card: 222.2 84% 4.9%;
43+
--card-foreground: 210 40% 98%;
44+
45+
--popover: 222.2 84% 4.9%;
46+
--popover-foreground: 210 40% 98%;
47+
48+
--primary: 217.2 91.2% 59.8%;
49+
--primary-foreground: 222.2 47.4% 11.2%;
50+
51+
--secondary: 217.2 32.6% 17.5%;
52+
--secondary-foreground: 210 40% 98%;
53+
54+
--muted: 217.2 32.6% 17.5%;
55+
--muted-foreground: 215 20.2% 65.1%;
56+
57+
--accent: 217.2 32.6% 17.5%;
58+
--accent-foreground: 210 40% 98%;
59+
60+
--destructive: 0 62.8% 30.6%;
61+
--destructive-foreground: 210 40% 98%;
62+
63+
--border: 217.2 32.6% 17.5%;
64+
--input: 217.2 32.6% 17.5%;
65+
--ring: 224.3 76.3% 48%;
66+
}
67+
}
68+
69+
@layer base {
70+
* {
71+
@apply border-border;
72+
}
73+
body {
74+
@apply bg-background text-foreground;
75+
}
76+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import type { Metadata } from "next";
2+
import { Inter } from "next/font/google";
3+
import type React from "react";
4+
import "./globals.css";
5+
import { ThemeProvider } from "@/components/theme-provider";
6+
7+
const inter = Inter({ subsets: ["latin"] });
8+
9+
export const metadata: Metadata = {
10+
title: "AI Code Impact Analysis",
11+
};
12+
13+
export default function RootLayout({
14+
children,
15+
}: {
16+
children: React.ReactNode;
17+
}) {
18+
return (
19+
<html lang="en" suppressHydrationWarning>
20+
<body className={inter.className}>
21+
<ThemeProvider
22+
attribute="class"
23+
defaultTheme="light"
24+
enableSystem
25+
disableTransitionOnChange
26+
>
27+
{children}
28+
</ThemeProvider>
29+
</body>
30+
</html>
31+
);
32+
}
33+
34+
import "./globals.css";
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { RepoAnalysisDashboard } from "@/components/repo-analysis-dashboard";
2+
3+
export default function Home() {
4+
return (
5+
<main className="min-h-screen bg-background">
6+
<RepoAnalysisDashboard />
7+
</main>
8+
);
9+
}

0 commit comments

Comments
 (0)