Avachat is a platform for creating AI-powered chatbot agents with custom knowledge bases. Each agent has its own personality (system prompt), knowledge documents, and can engage in real-time conversations via WebSocket using RAG (Retrieval-Augmented Generation) with hybrid search (kNN + BM25).
Built with ASP.NET Core 9, Entity Framework Core, Elasticsearch for vector/text search, and OpenAI for embeddings and chat completion. Follows Clean Architecture with separated Domain, Application, Infrastructure, and API layers.
This repository now unifies both the backend (.NET, at the repo root) and the frontend (React/Vite, under frontend/). See frontend/README.md for frontend-specific setup, scripts, and architecture. Shared feature specs for both live under specs/.
- π€ Multi-Agent Support - Create unlimited agents with custom system prompts and knowledge bases
- π RAG Pipeline - Upload
.mddocuments, auto-chunked and indexed with embeddings for retrieval - π Hybrid Search - kNN vector search + BM25 text search via Elasticsearch
- π¬ Real-Time Chat - WebSocket streaming with token-by-token response delivery
- π Auto Slug Generation - Agent slugs generated from name with accent handling and uniqueness
- π Session Management - REST endpoint to start sessions with user data collection
- π οΈ CLI Agent Loader - Console app to create/sync agents from local files
- π Chat History - Paginated sessions and messages with user context in AI prompts
- π³ Docker Ready - Development and production compose files with health checks
- ASP.NET Core 9.0 - Web API with Controllers and WebSocket middleware
- Entity Framework Core 9.x - ORM with Npgsql provider for PostgreSQL
- PostgreSQL 17 - Primary relational database
- Elasticsearch 8.17 - Vector and full-text search engine for knowledge chunks
- OpenAI API -
text-embedding-3-smallfor embeddings,gpt-4ofor chat completion
- AutoMapper 16.x - Object mapping between layers
- FluentValidation - Request validation
- MediatR - Mediator pattern
- Flurl.Http - HTTP client for Console app and integration tests
- Swashbuckle - Swagger/OpenAPI documentation
- xUnit - Test framework
- Moq - Mocking library
- FluentAssertions - Fluent assertion library
Avachat/
βββ AvaBot.API/ # REST API + WebSocket handler
β βββ Controllers/ # AgentController, ChatSessionController, KnowledgeFileController
β βββ Validators/ # FluentValidation validators
β βββ WebSocket/ # ChatWebSocketHandler
βββ AvaBot.Application/ # Business logic layer
β βββ Profiles/ # AutoMapper profiles
β βββ Services/ # AgentService, ChatService, IngestionService, SearchService
βββ AvaBot.Domain/ # Domain models and enums
β βββ Models/ # Agent, ChatSession, ChatMessage, KnowledgeFile
β βββ Enums/ # ProcessingStatus, SenderType
βββ AvaBot.DTO/ # Data Transfer Objects
βββ AvaBot.Infra/ # Infrastructure implementation
β βββ AppServices/ # ElasticsearchService, OpenAIService
β βββ Context/ # AvaBotContext (EF Core DbContext)
β βββ Repository/ # Generic repository implementations
βββ AvaBot.Infra.Interfaces/ # Generic repository and service interfaces
βββ AvaBot.Console/ # CLI for creating/syncing agents from files
βββ AvaBot.Tests/ # Unit tests (xUnit + Moq)
βββ AvaBot.Tests.API/ # Integration tests (Flurl + FluentAssertions + WebSocket)
βββ agent_input/ # Agent configuration input directory
β βββ system_prompt.md # Agent system prompt
β βββ description.md # Agent description
β βββ docs/ # Knowledge base documents (.md)
βββ bruno/ # Bruno API collection
βββ docker-compose.yml # Development environment
βββ docker-compose-prod.yml # Production environment
βββ Dockerfile # Multi-stage .NET build
βββ avabot.sql # Database schema
βββ frontend/ # React/Vite frontend (see frontend/README.md)
βββ .github/workflows/ # CI/CD pipelines
The platform follows a layered architecture where the API layer handles HTTP/WebSocket requests, delegates to Application services for business logic, which in turn use Infrastructure services for data access, search, and AI integration.
RAG Flow: User message β Generate embedding (OpenAI) β Hybrid search in Elasticsearch β Build prompt with context β Stream response from GPT-4o β Save to database.
π Source: The editable Mermaid source is available at
docs/system-design.mmd.
cp .env.example .env# Database
POSTGRES_USER=postgres
POSTGRES_PASSWORD=your_password_here
POSTGRES_DB=avabot
CONNECTION_STRING=Host=db;Database=avabot;Username=postgres;Password=your_password_here
# Elasticsearch
ELASTICSEARCH_URL=http://elasticsearch:9200
# OpenAI
OPENAI_API_KEY=your_openai_api_key_here
# App
APP_PORT=5000- Never commit the
.envfile with real credentials - Only
.env.exampleand.env.prod.exampleare version controlled - You must provide a valid OpenAI API key for the chat to work
# 1. Configure environment
cp .env.example .env
# Edit .env with your OpenAI API key
# 2. Build and start
docker compose up -d --build
# 3. Verify
docker compose ps| Service | URL |
|---|---|
| API | http://localhost:5000 |
| Swagger | http://localhost:5000/swagger |
| WebSocket Chat | ws://localhost:5000/ws/chat/{slug} |
| Elasticsearch | http://localhost:9200 |
| Kibana | http://localhost:5601 |
| PostgreSQL | localhost:5432 |
| Action | Command |
|---|---|
| Start services | docker compose up -d |
| Start with rebuild | docker compose up -d --build |
| Stop services | docker compose stop |
| View logs | docker compose logs -f api |
| Remove all | docker compose down |
| Remove with data ( |
docker compose down -v |
- .NET 9.0 SDK
- PostgreSQL 17
- Elasticsearch 8.17
- OpenAI API key
psql -U postgres -c "CREATE DATABASE avabot;"
psql -U postgres -d avabot -f avabot.sqlEdit AvaBot.API/appsettings.Development.json with your local connection strings and OpenAI key.
dotnet run --project AvaBot.APIThe API will be available at http://localhost:5030.
dotnet test AvaBot.Tests# Terminal 1: start the API
docker compose up -d
# Terminal 2: run integration tests
dotnet test AvaBot.Tests.APIAvaBot.Tests/ # 71 unit tests
βββ Application/Services/ # AgentService, ChatService, IngestionService, SearchService
βββ API/
βββ Controllers/ # AgentController, ChatSessionController, KnowledgeFileController
βββ Validators/ # AgentInsertInfoValidator
AvaBot.Tests.API/ # Integration tests (HTTP + WebSocket)
βββ Controllers/ # Agent, ChatSession, KnowledgeFile, ChatWebSocket
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/agents |
List all agents |
| GET | /api/agents/{slug} |
Get agent by slug |
| GET | /api/agents/{slug}/chat-config |
Get chat configuration |
| POST | /api/agents |
Create agent (slug auto-generated) |
| PUT | /api/agents/{id} |
Update agent |
| DELETE | /api/agents/{id} |
Delete agent |
| PATCH | /api/agents/{id}/status |
Toggle agent status |
| POST | /api/agents/{slug}/sessions |
Start chat session |
| GET | /api/agents/{agentId}/sessions |
List sessions (paginated) |
| GET | /api/sessions/{sessionId}/messages |
List messages (paginated) |
| GET | /api/agents/{agentId}/files |
List knowledge files |
| POST | /api/agents/{agentId}/files |
Upload .md file (multipart, max 10MB) |
| DELETE | /api/agents/{agentId}/files/{fileId} |
Delete knowledge file |
| POST | /api/agents/{agentId}/files/{fileId}/reprocess |
Reprocess file |
| WS | /ws/chat/{slug}?sessionId={id} |
WebSocket chat connection |
1. Connect: ws://localhost:5000/ws/chat/{slug}?sessionId={id}
2. Receive: {"type":"ready"}
3. Send: {"type":"message","content":"Hello"}
4. Receive: {"type":"chunk","content":"H"}
{"type":"chunk","content":"ello"}
{"type":"done"}
Import the collection from bruno/AvaBot API/ in Bruno for interactive API testing.
Create and sync agents from local files:
# Structure
agent_input/
βββ system_prompt.md # Agent personality (required)
βββ description.md # Agent description (optional)
βββ docs/ # Knowledge base (.md files)
βββ doc1.md
βββ doc2.md
# Run (from project root)
dotnet run --project AvaBot.Console -- "Agent Name"The CLI will:
- Create the agent if it doesn't exist, or update it if it does
- Sync all
.mdfiles fromdocs/(upload new, replace changed, remove orphans)
# 1. Configure production secrets
cp .env.prod.example .env.prod
# 2. Create external network
docker network create avabot-external
# 3. Deploy
docker compose --env-file .env.prod -f docker-compose-prod.yml up -d --buildProduction deploy via SSH is configured in .github/workflows/deploy-prod.yml (manual trigger via workflow_dispatch).
Required GitHub Secrets: PROD_SSH_HOST, PROD_SSH_USER, PROD_SSH_PASSWORD, POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB, CONNECTION_STRING, ELASTICSEARCH_URL, OPENAI_API_KEY
The database uses avabot_ prefix on all tables:
| Table | Description |
|---|---|
avabot_agents |
Agent configurations |
avabot_knowledge_files |
Uploaded knowledge documents |
avabot_chat_sessions |
Chat sessions with user data |
avabot_chat_messages |
Individual chat messages |
psql -U postgres -d avabot -f avabot.sqldocker compose exec postgres pg_dump -U postgres avabot > backup.sqldocker compose exec -T postgres psql -U postgres avabot < backup.sqlDeveloped by Rodrigo Landim
This project is licensed under the MIT License - see the LICENSE file for details.
β If you find this project useful, please consider giving it a star!
