Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,483 changes: 1,483 additions & 0 deletions AGENTSKILL.MS

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
of this license document, but changing it is not allowed.

Preamble

Expand Down
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,21 @@ cd AGENTS.md
./scripts/start.sh
```

---
### ☁️ Vercel Deployment

This repository includes a Vercel serverless entrypoint and routing config, so the FastAPI dashboard is served at `/` instead of returning `404: NOT_FOUND`.

```bash
# From the project root
vercel
```

Vercel uses:
- `vercel.json` to route every request to the Python serverless function.
- `api/index.py` as the FastAPI entrypoint.
- `requirements.txt` to install runtime dependencies.

---

## 🔌 API Examples
Expand Down
14 changes: 14 additions & 0 deletions api/index.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""Vercel serverless entrypoint for the FastAPI application."""

from __future__ import annotations

import sys
from importlib import import_module
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
APP_DIR = ROOT / "app"
if str(APP_DIR) not in sys.path:
sys.path.insert(0, str(APP_DIR))

app = import_module("universal_compiler_agent.server").app
1 change: 1 addition & 0 deletions app/universal_compiler_agent/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@
planButton.addEventListener('click', () => submit('/plan', planButton));
compileButton.addEventListener('click', () => submit('/compile', compileButton));
</script>
<script defer src="https://cdn.vercel-insights.com/v1/script.js"></script>
</body>
</html>
"""
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ dev = [
"pytest>=8.0,<9.0",
"ruff>=0.6,<1.0",
"httpx>=0.28,<1.0",
"httpx2>=0.28,<1.0",
"codespell[toml]>=2.3,<3.0"
]

Expand Down
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fastapi>=0.115,<1.0
uvicorn[standard]>=0.30,<1.0
pydantic>=2.8,<3.0
25 changes: 25 additions & 0 deletions tests/test_vercel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import importlib.util
import json
from pathlib import Path

from fastapi.testclient import TestClient


def test_vercel_routes_all_paths_to_fastapi_entrypoint() -> None:
config = json.loads(Path("vercel.json").read_text(encoding="utf-8"))

assert config["builds"] == [{"src": "api/index.py", "use": "@vercel/python"}]
assert config["routes"] == [{"src": "/(.*)", "dest": "api/index.py"}]


def test_vercel_entrypoint_exposes_fastapi_app() -> None:
spec = importlib.util.spec_from_file_location("vercel_entrypoint", "api/index.py")
assert spec is not None
assert spec.loader is not None
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)

response = TestClient(module.app).get("/")

assert response.status_code == 200
assert "Universal Project Compiler Agent" in response.text
14 changes: 14 additions & 0 deletions vercel.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"builds": [
{
"src": "api/index.py",
"use": "@vercel/python"
}
],
"routes": [
{
"src": "/(.*)",
"dest": "api/index.py"
}
]
}
Loading