diff --git a/README.md b/README.md new file mode 100644 index 0000000..cf0b11a --- /dev/null +++ b/README.md @@ -0,0 +1,78 @@ +# SearchlyAI + +SearchlyAI is a powerful Retrieve-Augmented Generation (RAG) search engine that allows users to ingest documents (PDF, TXT) and web pages, and then query them using natural language. It leverages Google's Gemini for embeddings and answer generation, and FAISS for efficient vector similarity search. + +## 🚀 Features + +- **Multi-Source Ingestion**: Support for PDF documents, text files, and web pages. +- **Semantic Search**: Uses vector embeddings to understand the *meaning* behind your query, not just keyword matching. +- **RAG Architecture**: Retrieves relevant context and generates natural language answers using LLMs. +- **Session Management**: Keeps data isolated per session. +- **Efficient Vector Storage**: Uses FAISS for lighting-fast similarity search. + +## 🛠️ Tech Stack + +### Backend +- **Framework**: FastAPI +- **LLM & Embeddings**: Google Gemini (via LangChain/GenerativeAI) +- **Vector Store**: FAISS +- **Validation**: Pydantic + +### Frontend +- **Framework**: React (Vite) +- **Language**: TypeScript +- **Styling**: (Pending - to be built) + +## 📂 Project Structure + +``` +SearchlyAI/ +├── backend/ # FastAPI Backend +│ ├── app/ # Application logic +│ └── data/ # Local vector store data +├── frontend/ # React Frontend (Vite) +├── docker-compose.yml # Docker orchestration +└── README.md # This file +``` + +## 🏎️ Getting Started + +### Prerequisites +- Docker & Docker Compose +- Node.js (for local frontend dev) +- Python 3.10+ (for local backend dev) +- Google Gemini API Key + +### Running with Docker + +1. Set up your environment variables: + ```bash + cp backend/.env.example backend/.env + # Edit backend/.env and add your GEMINI_API_KEY + ``` + +2. Run the stack: + ```bash + docker-compose up --build + ``` + +### Local Development + +**Backend:** +```bash +cd backend +python -m venv venv +source venv/bin/activate # or venv\Scripts\activate on Windows +pip install -r requirements.txt +uvicorn main:app --reload +``` + +**Frontend:** +```bash +cd frontend +npm install +npm run dev +``` + +## 📄 License +MIT diff --git a/backend/README.md b/backend/README.md index 5a6b5a8..5f57eb7 100644 --- a/backend/README.md +++ b/backend/README.md @@ -1,6 +1,6 @@ -# RAG Search Engine Backend +# SearchlyAI Backend -This is the backend for a RAG (Retrieval-Augmented Generation) Search Engine built with FastAPI. +This is the backend API for SearchlyAI, built with FastAPI. ## Structure - `app/api`: API route definitions @@ -8,7 +8,6 @@ This is the backend for a RAG (Retrieval-Augmented Generation) Search Engine bui - `app/services`: Business logic (ingestion, chunking, embeddings, etc.) - `app/schemas`: Pydantic models - `app/utils`: Helper functions -- `app/llm`: LLM abstractions (OpenAI, Gemini) ## Setup @@ -24,7 +23,7 @@ This is the backend for a RAG (Retrieval-Augmented Generation) Search Engine bui ``` 3. Configure environment variables: - Copy `.env.example` to `.env` and fill in your API keys. + Copy `.env.example` to `.env` and fill in your API keys (Gemini API Key is required). 4. Run the server: ```bash diff --git a/backend/app/core/config.py b/backend/app/core/config.py index 8ab1ece..981298f 100644 --- a/backend/app/core/config.py +++ b/backend/app/core/config.py @@ -4,7 +4,7 @@ class Settings(BaseSettings): # App - APP_NAME: str = "SemanticSearch AI" + APP_NAME: str = "SearchlyAI" ENV: str = "development" # Gemini diff --git a/backend/main.py b/backend/main.py index 864ee78..648e206 100644 --- a/backend/main.py +++ b/backend/main.py @@ -11,7 +11,7 @@ setup_logging() app = FastAPI( - title="SemanticSearch AI", + title="SearchlyAI", description="AI-powered semantic search engine using RAG", version="1.0.0" ) diff --git a/frontend/.gitignore b/frontend/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/frontend/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/frontend/README.md b/frontend/README.md new file mode 100644 index 0000000..d2e7761 --- /dev/null +++ b/frontend/README.md @@ -0,0 +1,73 @@ +# React + TypeScript + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## React Compiler + +The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation). + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: + +```js +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + // Other configs... + + // Remove tseslint.configs.recommended and replace with this + tseslint.configs.recommendedTypeChecked, + // Alternatively, use this for stricter rules + tseslint.configs.strictTypeChecked, + // Optionally, add this for stylistic rules + tseslint.configs.stylisticTypeChecked, + + // Other configs... + ], + languageOptions: { + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + // other options... + }, + }, +]) +``` + +You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules: + +```js +// eslint.config.js +import reactX from 'eslint-plugin-react-x' +import reactDom from 'eslint-plugin-react-dom' + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + // Other configs... + // Enable lint rules for React + reactX.configs['recommended-typescript'], + // Enable lint rules for React DOM + reactDom.configs.recommended, + ], + languageOptions: { + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + // other options... + }, + }, +]) +``` diff --git a/frontend/eslint.config.js b/frontend/eslint.config.js new file mode 100644 index 0000000..5e6b472 --- /dev/null +++ b/frontend/eslint.config.js @@ -0,0 +1,23 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' +import { defineConfig, globalIgnores } from 'eslint/config' + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + js.configs.recommended, + tseslint.configs.recommended, + reactHooks.configs.flat.recommended, + reactRefresh.configs.vite, + ], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + }, +]) diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 0000000..072a57e --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,13 @@ + + +
+ + + +
+ Edit src/App.tsx and save to test HMR
+
+ Click on the Vite and React logos to learn more +
+ > + ) +} + +export default App diff --git a/frontend/src/assets/react.svg b/frontend/src/assets/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/frontend/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/index.css b/frontend/src/index.css new file mode 100644 index 0000000..08a3ac9 --- /dev/null +++ b/frontend/src/index.css @@ -0,0 +1,68 @@ +:root { + font-family: system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx new file mode 100644 index 0000000..bef5202 --- /dev/null +++ b/frontend/src/main.tsx @@ -0,0 +1,10 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import './index.css' +import App from './App.tsx' + +createRoot(document.getElementById('root')!).render( +