Skip to content

Commit c47cd7b

Browse files
authored
Merge pull request #66 from ResilientApp/merge_pr
Merge team pull requests #62, #63, and #65
2 parents 54cadeb + 73eb514 commit c47cd7b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+10960
-4646
lines changed

.github/workflows/ci-quick.yml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ env:
1818
NODE_VERSION: '20.x'
1919
PYTHON_VERSION: '3.10'
2020

21+
permissions:
22+
contents: read
23+
pull-requests: write
24+
issues: write
25+
2126
jobs:
2227
# ============================================
2328
# Quick validation (lint, type check, fast tests)
@@ -106,8 +111,6 @@ jobs:
106111
"RESILIENTDB_GRAPHQL_URI=https://cloud.resilientdb.com/graphql" \
107112
"JWT_SECRET=test-secret-key-do-not-use-in-production" > .env
108113
109-
- name: Run backend unit tests only (fast)
110-
# wait for mongodb to be ready on localhost:27017
111114
- name: Wait for MongoDB
112115
run: |
113116
for i in {1..30}; do
@@ -136,12 +139,14 @@ jobs:
136139
--ci
137140
138141
- name: Build check (frontend)
142+
env:
143+
CI: false
139144
run: |
140145
cd frontend
141146
npm run build
142147
143148
- name: Comment PR with quick results
144-
if: github.event_name == 'pull_request' && always()
149+
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false && always()
145150
uses: actions/github-script@v7
146151
with:
147152
script: |

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ coverage/
3535
*.coverage
3636
backend/.coverage
3737
node_modules
38+
backend/qdrant_storage/
3839
frontend/build/
3940

4041
# Exclude all .env files

README.md

Lines changed: 118 additions & 1 deletion
Large diffs are not rendered by default.

backend/NEXT_STEPS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

backend/SETUP_VECTOR_SEARCH.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Vector Search Setup Guide
2+
3+
## Quick Start
4+
5+
### Option 1: Using Docker Compose (Recommended)
6+
7+
```bash
8+
cd backend
9+
10+
# Start Qdrant and Redis
11+
docker-compose up -d qdrant redis
12+
13+
# Verify Qdrant is running
14+
curl http://localhost:6333/healthz
15+
# Should return: {"title":"healthz","version":"1.x.x"}
16+
17+
# Install Python dependencies (if not already done)
18+
pip install -r requirements.txt
19+
20+
# Run backend
21+
python app.py
22+
23+
# Seperate terminal
24+
python worker/embedding_service.py
25+
```
26+
27+
### Option 2: Local Qdrant Installation
28+
29+
```bash
30+
# macOS with Homebrew
31+
brew install qdrant
32+
33+
# Or using Docker standalone
34+
docker run -p 6333:6333 -p 6334:6334 \
35+
-v $(pwd)/qdrant_storage:/qdrant/storage \
36+
qdrant/qdrant
37+
38+
# Install Python dependencies
39+
cd backend
40+
pip install -r requirements.txt
41+
42+
# Run backend
43+
python app.py
44+
45+
# Seperate terminal
46+
python worker/embedding_service.py
47+
```
48+
49+
---
50+
51+
## 🔧 Configuration
52+
53+
The following environment variables can be set in `config.py`:
54+
55+
```bash
56+
# Qdrant Vector Database
57+
QDRANT_HOST=localhost
58+
QDRANT_PORT=6333
59+
QDRANT_GRPC_PORT=6334
60+
QDRANT_COLLECTION_NAME=rescanvas_embeddings
61+
62+
# These are already in your config:
63+
# REDIS_HOST=localhost
64+
# REDIS_PORT=6379
65+
# MONGO_ATLAS_URI=...
66+
```

backend/app.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ def filter(self, record):
3939

4040
app = Flask(__name__)
4141

42+
# Allow large request bodies for thumbnail uploads (up to 20MB)
43+
app.config['MAX_CONTENT_LENGTH'] = 20 * 1024 * 1024
44+
4245
# Initialize rate limiting BEFORE importing routes (routes use limiter decorators)
4346
from middleware.rate_limit import init_limiter, rate_limit_error_handler
4447
limiter = init_limiter(app)
@@ -56,6 +59,9 @@ def filter(self, record):
5659
from routes.frontend import frontend_bp
5760
from routes.analytics import analytics_bp
5861
from routes.export import export_bp
62+
from routes.ai_assistant import ai_assistant_bp
63+
from routes.search_ai import search_ai_bp
64+
from routes.chatbot import chatbot_bp
5965
from services.db import redis_client
6066
from services.canvas_counter import get_canvas_draw_count
6167
from services.graphql_service import commit_transaction_via_graphql
@@ -215,6 +221,8 @@ def handle_all_exceptions(e):
215221
app.register_blueprint(submit_room_line_bp)
216222
app.register_blueprint(admin_bp)
217223
app.register_blueprint(export_bp)
224+
app.register_blueprint(ai_assistant_bp)
225+
app.register_blueprint(chatbot_bp)
218226

219227
# Register versioned API v1 blueprints for external applications
220228
from api_v1.auth import auth_v1_bp
@@ -232,6 +240,7 @@ def handle_all_exceptions(e):
232240
app.register_blueprint(users_v1_bp)
233241
app.register_blueprint(stamps_bp, url_prefix='/api')
234242
app.register_blueprint(templates_v1_bp)
243+
app.register_blueprint(search_ai_bp)
235244

236245
# Frontend serving must be last to avoid route conflicts
237246
app.register_blueprint(frontend_bp)

backend/config.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@
4646
REDIS_HOST = os.getenv("REDIS_HOST", "localhost")
4747
REDIS_PORT = int(os.getenv("REDIS_PORT", "6379"))
4848

49+
# Qdrant Vector Database Configuration
50+
QDRANT_HOST = os.getenv("QDRANT_HOST", "localhost")
51+
QDRANT_PORT = int(os.getenv("QDRANT_PORT", "6333"))
52+
QDRANT_COLLECTION_NAME = os.getenv("QDRANT_COLLECTION_NAME", "rescanvas_embeddings")
53+
EMBEDDING_DIMENSION = 512 # OpenCLIP ViT-B-32 output dimension
54+
QDRANT_GRPC_PORT = int(os.getenv("QDRANT_GRPC_PORT", "6334"))
55+
4956
# Rate Limiting Configuration
5057
RATE_LIMIT_STORAGE_URI = f"redis://{REDIS_HOST}:{REDIS_PORT}"
5158
RATE_LIMIT_ENABLED = os.getenv("RATE_LIMIT_ENABLED", "True") == "True"

backend/docker-compose.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,25 @@ services:
1818
networks:
1919
- rescanvas-network
2020

21+
qdrant:
22+
image: qdrant/qdrant:latest
23+
container_name: rescanvas-qdrant
24+
ports:
25+
- "6333:6333" # HTTP API
26+
- "6334:6334" # gRPC API
27+
volumes:
28+
- qdrant_data:/qdrant/storage
29+
environment:
30+
- QDRANT__SERVICE__GRPC_PORT=6334
31+
restart: unless-stopped
32+
healthcheck:
33+
test: ["CMD", "curl", "-f", "http://localhost:6333/healthz"]
34+
interval: 10s
35+
timeout: 5s
36+
retries: 5
37+
networks:
38+
- rescanvas-network
39+
2140
backend:
2241
build:
2342
context: .
@@ -34,6 +53,9 @@ services:
3453
- RATE_LIMIT_STORAGE_URI=redis://redis:6379
3554
- REDIS_HOST=redis
3655
- REDIS_PORT=6379
56+
- QDRANT_HOST=qdrant
57+
- QDRANT_PORT=6333
58+
- QDRANT_GRPC_PORT=6334
3759
- JWT_SECRET=${JWT_SECRET:-dev-insecure-change-me}
3860
- OPENAI_API_KEY=${OPENAI_API_KEY}
3961
- ANALYTICS_ENABLED=${ANALYTICS_ENABLED:-True}
@@ -46,6 +68,8 @@ services:
4668
depends_on:
4769
redis:
4870
condition: service_healthy
71+
qdrant:
72+
condition: service_healthy
4973
restart: unless-stopped
5074
healthcheck:
5175
test: ["CMD", "curl", "-f", "http://localhost:10010/api/analytics/health"]
@@ -59,6 +83,8 @@ services:
5983
volumes:
6084
redis_data:
6185
driver: local
86+
qdrant_data:
87+
driver: local
6288

6389
networks:
6490
rescanvas-network:

backend/requirements.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@ python-engineio==4.12.3
5151
python-socketio==5.14.1
5252
redis==6.2.0
5353
requests==2.32.4
54-
resilient-python-cache==0.1.1
54+
# resilient-python-cache==0.1.1
5555
rich==13.9.4
56+
openai>=1.0.0
5657
simple-websocket==1.1.0
5758
simplejson==3.19.3
5859
six==1.17.0
@@ -64,3 +65,9 @@ websockets==10.4
6465
Werkzeug==3.1.3
6566
wrapt==2.0.0
6667
wsproto==1.2.0
68+
# AI/ML dependencies for semantic search
69+
torch>=2.0.0
70+
open_clip_torch>=2.20.0
71+
pillow>=10.0.0
72+
qdrant-client>=1.7.0
73+
numpy>=1.24.0

0 commit comments

Comments
 (0)