A fullstack template for building AI-powered applications with CopilotKit and Agno.
- Multi-provider AI: OpenAI, Anthropic, Google Gemini, Mistral, Ollama, LM Studio
- Multi-Conversations: Multiple chat conversations per user with auto-generated titles
- Session Memory: Conversation history persisted in PostgreSQL
- Multi-KB RAG: Multiple knowledge bases with group-based access control
- Personal Knowledge Bases: Private KB for each user with configurable limits
- Web Search: Real-time information via DuckDuckGo integration
- Smart PDF Processing: Column-aware extraction for multi-column documents
- Large File Support: Automatic chunking for documents up to 200MB
- File Upload: Support for PDF, Word, Markdown, Text, and 20+ code file formats
- Batch Operations: Delete multiple documents or conversations at once
- Group-based Access Control: Keycloak groups with READ/WRITE permissions per KB
- Admin Dashboard: User & group management, KB permissions, system health
- Modern UI: shadcn/ui components with dark/light theme support
- Authentication: Keycloak + NextAuth.js with secure OAuth2/OIDC
- AG-UI Protocol: Real-time streaming communication between frontend and backend
- Source Citations: AI responses cite document sources from knowledge base
- Multi-cloud Deployment: Infrastructure as Code for AWS and Azure (OpenTofu)
| Layer | Technology |
|---|---|
| Frontend | Next.js 15, React 19, TypeScript, CopilotKit, shadcn/ui |
| Backend | Python 3.11, Agno, FastAPI |
| Protocol | AG-UI (Agent-User Interaction) |
| Auth | Keycloak + NextAuth.js |
| Database | PostgreSQL 16 + PgVector |
| Infrastructure | Docker, OpenTofu |
- Node.js 18+ (recommended: 20+)
- pnpm 9+ (install with
npm install -g pnpm) - Docker and Docker Compose
- Git
- Ollama for local LLM inference (https://ollama.ai)
git clone [email protected]:fulltechfactory/agentic-fullstack-template.git keystone
cd keystone# For cloud provider (OpenAI recommended for RAG embeddings)
make setup-dev AI_PROVIDER=openai AI_API_KEY=sk-your-key
# Or with Ollama (RAG requires OpenAI for embeddings)
make setup-dev AI_PROVIDER=ollama AI_URL=http://host.docker.internal:11434make dev-upThis starts:
- PostgreSQL + PgVector on
localhost:5432 - Keycloak on
http://localhost:8080 - Backend API on
http://localhost:8000
Wait ~1 minute for Keycloak to initialize.
make frontendOpen http://localhost:3000 and sign in with adminuser / adminuser.
Keystone supports production deployment on multiple cloud providers using OpenTofu (Infrastructure as Code).
| Provider | Infrastructure Type | Status | Documentation |
|---|---|---|---|
| AWS | VM + Attached Storage | ✅ Ready | RUNBOOK_AWS.md |
| Azure | VM + Attached Storage | ✅ Ready | RUNBOOK_AZURE.md |
| GCP | VM + Attached Storage | 🚧 Planned | - |
| Scaleway | VM + Attached Storage | 🚧 Planned | - |
# Configure production environment
make setup-deploy
# Initialize OpenTofu
make infra-init
# Preview infrastructure
make infra-plan
# Deploy
make infra-applySingle VM deployment with all services (PostgreSQL, Keycloak, Backend, Frontend) running on one instance with an attached persistent disk.
Best suited for:
- Small to medium deployments (< 100 concurrent users)
- Development/staging environments
- Cost-conscious production (~$30-35/month)
┌─────────────────────────────────────────┐
│ Cloud VM │
│ ┌─────────────────────────────────┐ │
│ │ Docker │ │
│ │ PostgreSQL │ Keycloak │ Backend │ │
│ └─────────────────────────────────┘ │
│ ┌─────────────────────────────────┐ │
│ │ Caddy (SSL) │ Frontend │ │
│ └─────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────┐ │
│ │ Persistent Disk (20GB) │ │
│ │ /data/postgres │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────┘
After installation, follow these steps to set up your organization:
Log in with adminuser / adminuser to access the admin panel.
Navigate to Users & Groups and create a new group (e.g., "RH"). A Knowledge Base is automatically created for each group.
Create users and assign them to appropriate groups.
In KB Management, grant WRITE permission to users who need to manage documents.
Users with WRITE permission can upload files via the Knowledge Base page using drag & drop.
All group members can query the knowledge base through the chat interface.
| Role | Description |
|---|---|
ADMIN |
Manage users, groups, KBs and permissions (no access to KB content) |
USER |
Access to chat and knowledge bases based on group membership |
| User | Password | Role | Description |
|---|---|---|---|
adminuser |
adminuser |
ADMIN | Default administrator |
| Permission | Description |
|---|---|
| READ (implicit) | All group members can query the KB via chat |
| WRITE (explicit) | User can add/modify/delete documents in the KB |
| READ cross-group | User can read a KB they're not a member of |
Key principle: ADMIN role manages access but cannot read document content.
| Category | Extensions |
|---|---|
| Documents | .pdf, .docx |
| Text | .txt, .md |
| Code | .py, .js, .ts, .tsx, .jsx, .c, .cpp, .h, .rs, .go, .java, .html, .css, .json, .yaml, .sql, .sh, and more |
- Drag & drop upload interface
- Automatic text extraction from PDF and Word documents
- Column-aware PDF extraction for multi-column layouts
- Automatic chunking for large documents
- Language detection for code files
- Maximum file size: 200MB
- Metadata preservation (filename, type, language)
- Batch deletion of documents
The application supports multiple knowledge bases: group KBs linked to Keycloak groups, and personal KBs for individual users.
Group Knowledge Bases:
- ADMIN creates a group → Knowledge Base is auto-created
- Group members automatically have READ access to their KB
- ADMIN grants WRITE permission to specific users
- Users with WRITE can upload documents (text or files)
Personal Knowledge Bases:
- Auto-created when user first accesses the Knowledge Base page
- Only the owner can access their personal KB
- Configurable limits (default: 10 documents, 50MB total)
- Marked with "Personal" badge in the UI
Chat Integration:
- Chat searches all accessible KBs (group + personal) and cites sources in responses
For Users (Knowledge Base page):
- View all accessible KBs with READ/WRITE badges
- Personal KB shown with purple "Personal" badge
- Upload files via drag & drop (with WRITE permission)
- Add text documents manually
- Delete documents individually or in batch (with WRITE permission)
For Admins (KB Management page):
- View all group KBs with document counts
- Manage permissions (grant/revoke WRITE, add cross-group READ)
- Cannot access document content
- Personal KBs are not visible to admins
- Create and delete users
- Create and delete groups (auto-creates/deletes associated KB)
- Assign users to groups
- Toggle group membership
- View all knowledge bases with document counts
- Grant WRITE permission to users
- Grant cross-group READ access
- Remove permissions
- System health monitoring
- Database connection status
- AI provider configuration
- Session statistics
Users can have multiple separate chat conversations, each with its own history.
- Conversation List: Sidebar displays recent conversations (10 most recent)
- Auto-generated Titles: Conversation title is automatically generated from the first message using AI
- Full Management: Create, rename, and delete conversations
- Batch Deletion: Delete multiple conversations at once via the management page (
/conversations) - Persistent History: Each conversation maintains its own chat history across sessions
- History Display: Previous messages are loaded and displayed when switching conversations
- User creates a new conversation (or one is auto-created)
- Each conversation has a unique ID used as the CopilotKit
threadId - First message triggers AI-powered title generation
- Conversations are sorted by last activity (most recent first)
- Switching conversations loads the appropriate chat history
The agent remembers conversation history across page refreshes and server restarts.
- User authenticates via Keycloak → receives a unique
user_id - Each conversation has a unique
conversation_idused asthreadId - Backend (Agno) stores conversation history in PostgreSQL (
agent_sessionstable) - On each request, Agno loads the session history from the database
The agent searches accessible knowledge bases to answer questions with relevant context.
- Users upload documents via the Knowledge Base UI (group KBs require WRITE permission)
- Content is extracted with smart processing:
- PDFs: Column-aware extraction for multi-column documents (PyMuPDF + pdfplumber fallback)
- Large files: Automatic chunking for documents up to 200MB
- Text is chunked and embedded using OpenAI
text-embedding-3-small - Embeddings are stored in PostgreSQL with PgVector
- On each query, relevant documents are retrieved from all accessible KBs (group + personal)
- The agent uses this context and cites the source documents in responses
| Type | Access | Description |
|---|---|---|
| Group KB | Group members | Shared KB for each Keycloak group |
| Personal KB | Owner only | Private KB for individual users |
RAG requires OpenAI API key for embeddings (even when using other providers for chat).
The agent can search the web for real-time information using DuckDuckGo.
- Automatically triggered when knowledge base doesn't have relevant information
- Useful for current events, recent updates, and general knowledge
- No API key required (uses DuckDuckGo's free search)
The application supports light, dark, and system themes. Toggle via the sun/moon icon in the sidebar footer.
- Collapsible sidebar with icon-only mode
- Role-based navigation items
- User profile with sign-out option
| Table | Purpose |
|---|---|
app.conversations |
User conversations metadata (title, timestamps) |
app.agent_sessions |
Session data and conversation runs (Agno) |
app.knowledge_bases |
KB metadata (name, slug, group, owner) |
app.knowledge_embeddings |
RAG document embeddings (PgVector) |
app.knowledge_base_permissions |
WRITE and cross-group READ permissions |
| User | Password | Purpose |
|---|---|---|
| postgres | postgres | Superuser (never used in app) |
| migration | migration | Schema migrations (DDL) |
| appuser | appuser | Application runtime |
| keycloak | keycloak | Keycloak database access |
| Command | Description |
|---|---|
make setup-dev |
Configure local development environment |
make setup-staging |
Configure staging environment (cloud) |
make setup-deploy |
Configure production environment (cloud) |
make test-setup |
Run automated tests for setup commands |
| Command | Description |
|---|---|
make dev-up |
Start backend services (PostgreSQL, Keycloak, Backend) |
make dev-down |
Stop all services |
make dev-logs |
Show container logs |
make dev-ps |
Show container status |
make dev-clean |
Remove all data and volumes |
make db-migrate |
Run database migrations |
| Command | Description |
|---|---|
make frontend |
Start frontend development server |
make frontend-install |
Install frontend dependencies |
make frontend-env |
Generate frontend/.env.local |
| Command | Description |
|---|---|
make infra-init |
Initialize OpenTofu |
make infra-plan |
Preview infrastructure changes |
make infra-apply |
Deploy infrastructure |
make infra-destroy |
Destroy infrastructure |
make infra-output |
Show infrastructure outputs |
| Provider | Type | Configuration |
|---|---|---|
| OpenAI | Cloud | AI_PROVIDER=openai AI_API_KEY=sk-... |
| Anthropic | Cloud | AI_PROVIDER=anthropic AI_API_KEY=sk-ant-... |
| Google Gemini | Cloud | AI_PROVIDER=gemini AI_API_KEY=... |
| Mistral | Cloud | AI_PROVIDER=mistral AI_API_KEY=... |
| Ollama | Local | AI_PROVIDER=ollama AI_URL=http://host.docker.internal:11434 |
| LM Studio | Local | AI_PROVIDER=lmstudio AI_URL=http://host.docker.internal:1234 |
Access Keycloak admin at http://localhost:8080 with:
- Username:
admin - Password:
admin
To rename the project for your own use (after forking):
./scripts/rename-project.sh "My Project Name"This updates all references (containers, database, Keycloak realm, UI).
- Multi-provider AI support
- Authentication (Keycloak + NextAuth.js)
- Session Memory (PostgreSQL)
- RAG (Retrieval-Augmented Generation with PgVector)
- Multi-KB with group-based access control
- File upload (PDF, Word, Markdown, Code files)
- Modern UI with shadcn/ui
- Dark/Light theme support
- Admin dashboard (stats, health monitoring)
- Admin user & group management
- KB Management (permissions, WRITE/READ control)
- Source citations in chat responses
- Infrastructure as Code - AWS (OpenTofu)
- Infrastructure as Code - Azure (OpenTofu)
- Web search (DuckDuckGo integration)
- Large file support (chunking up to 200MB)
- Smart PDF extraction (column-aware for multi-column docs)
- Personal Knowledge Bases (private per-user KBs)
- Batch document deletion
- Multi-conversations (multiple chats per user)
- Auto-generated conversation titles (AI-powered)
- Conversation history display (load previous messages)
- KB selector in chat (filter by specific KB)
- User Memory (persistent user preferences)
- Infrastructure as Code - GCP (OpenTofu)
- Infrastructure as Code - Scaleway (OpenTofu)
- Test suite (frontend, backend, infrastructure)
Clear your browser cookies for localhost:3000 and try again.
Wait ~1 minute after make dev-up for Keycloak to fully initialize.
make dev-down
docker system prune -f
make dev-updocker logs keystone-postgres
docker logs keystone-keycloak
docker logs keystone-backend
docker logs keystone-keycloak-setupmake dev-clean
make dev-upMIT