moazx commited on
Commit
0176a31
·
1 Parent(s): ef242c8

Refactor project for Lung Cancer AI Advisor: update app and API descriptions, modify .gitignore to exclude Jupyter notebooks, and remove outdated deployment documentation. Delete unused files and enhance logging for better traceability.

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitignore +2 -2
  2. 0.0.18 +0 -2
  3. DEPLOYMENT.md +0 -206
  4. DEPLOYMENT_SUMMARY.md +0 -296
  5. Medical_AI_System_Prompts.docx +0 -0
  6. QUICK_DEPLOY.md +0 -100
  7. README.md +21 -86
  8. api/__pycache__/__init__.cpython-311.pyc +0 -0
  9. api/__pycache__/__init__.cpython-313.pyc +0 -0
  10. api/__pycache__/app.cpython-311.pyc +0 -0
  11. api/__pycache__/app.cpython-313.pyc +0 -0
  12. api/__pycache__/exceptions.cpython-313.pyc +0 -0
  13. api/__pycache__/middleware.cpython-313.pyc +0 -0
  14. api/__pycache__/models.cpython-313.pyc +0 -0
  15. api/app.py +22 -6
  16. api/exceptions.py +1 -1
  17. api/middleware.py +6 -5
  18. api/models.py +1 -1
  19. api/routers/__pycache__/__init__.cpython-311.pyc +0 -0
  20. api/routers/__pycache__/__init__.cpython-313.pyc +0 -0
  21. api/routers/__pycache__/health.cpython-313.pyc +0 -0
  22. api/routers/__pycache__/medical.cpython-311.pyc +0 -0
  23. api/routers/__pycache__/medical.cpython-313.pyc +0 -0
  24. api/routers/auth.py +25 -11
  25. api/routers/health.py +39 -14
  26. api/routers/medical.py +120 -15
  27. app.py +1 -1
  28. backup/backup_20251022_110950/chunks.pkl +0 -3
  29. backup/backup_20251022_110950/vector_store/index.faiss +0 -3
  30. backup/backup_20251022_110950/vector_store/index.pkl +0 -3
  31. backup/backup_20251022_111044/chunks.pkl +0 -3
  32. backup/backup_20251022_111044/vector_store/index.faiss +0 -3
  33. backup/backup_20251022_111044/vector_store/index.pkl +0 -3
  34. core/__pycache__/__init__.cpython-311.pyc +0 -0
  35. core/__pycache__/__init__.cpython-313.pyc +0 -0
  36. core/__pycache__/agent.cpython-311.pyc +0 -0
  37. core/__pycache__/agent.cpython-313.pyc +0 -0
  38. core/__pycache__/background_init.cpython-313.pyc +0 -0
  39. core/__pycache__/config.cpython-311.pyc +0 -0
  40. core/__pycache__/config.cpython-313.pyc +0 -0
  41. core/__pycache__/data_loaders.cpython-313.pyc +0 -0
  42. core/__pycache__/github_storage.cpython-313.pyc +0 -0
  43. core/__pycache__/retrievers.cpython-313.pyc +0 -0
  44. core/__pycache__/text_processors.cpython-313.pyc +0 -0
  45. core/__pycache__/tools.cpython-313.pyc +0 -0
  46. core/__pycache__/tracing.cpython-313.pyc +0 -0
  47. core/__pycache__/utils.cpython-313.pyc +0 -0
  48. core/__pycache__/validation.cpython-313.pyc +0 -0
  49. core/agent.py +41 -23
  50. core/context_enrichment.py +8 -2
.gitignore CHANGED
@@ -207,6 +207,6 @@ marimo/_static/
207
  marimo/_lsp/
208
  __marimo__/
209
 
210
-
211
  Lung Cancer Guidelines/
212
- #frontend/frontend/
 
207
  marimo/_lsp/
208
  __marimo__/
209
 
210
+ *.ipynb
211
  Lung Cancer Guidelines/
212
+
0.0.18 DELETED
@@ -1,2 +0,0 @@
1
- Defaulting to user installation because normal site-packages is not writeable
2
- Requirement already satisfied: python-multipart in c:\users\moaze\appdata\roaming\python\python313\site-packages (0.0.9)
 
 
 
DEPLOYMENT.md DELETED
@@ -1,206 +0,0 @@
1
- # Hugging Face Deployment Guide
2
-
3
- ## Overview
4
- This guide explains how to deploy the Lung Cancer Clinical Decision Support System to Hugging Face Spaces.
5
-
6
- ## Prerequisites
7
- - Hugging Face account
8
- - Git installed locally
9
- - OpenAI API key (for the agent)
10
- - GitHub Personal Access Token (for side effects storage)
11
-
12
- ## Deployment Steps
13
-
14
- ### 1. Create a New Hugging Face Space
15
-
16
- 1. Go to [Hugging Face Spaces](https://huggingface.co/spaces)
17
- 2. Click "Create new Space"
18
- 3. Configure:
19
- - **Space name**: `moazx-api` (or your preferred name)
20
- - **License**: Choose appropriate license
21
- - **SDK**: Docker
22
- - **Hardware**: CPU Basic (or upgrade as needed)
23
-
24
- ### 2. Configure Environment Variables
25
-
26
- In your Hugging Face Space settings, add these secrets:
27
-
28
- ```bash
29
- OPENAI_API_KEY=your_openai_api_key_here
30
- GITHUB_TOKEN=your_github_token_here
31
- GITHUB_REPO=your_username/your_repo_name
32
- GITHUB_BRANCH=main
33
- PORT=7860
34
- ```
35
-
36
- ### 3. Deploy the Application
37
-
38
- #### Option A: Direct Push to Hugging Face
39
-
40
- ```bash
41
- # Clone your Hugging Face Space repository
42
- git clone https://huggingface.co/spaces/YOUR_USERNAME/moazx-api
43
- cd moazx-api
44
-
45
- # Copy all backend files
46
- cp -r /path/to/backend/* .
47
-
48
- # Add and commit
49
- git add .
50
- git commit -m "Initial deployment"
51
- git push
52
- ```
53
-
54
- #### Option B: Using Hugging Face CLI
55
-
56
- ```bash
57
- # Install Hugging Face CLI
58
- pip install huggingface_hub
59
-
60
- # Login
61
- huggingface-cli login
62
-
63
- # Push to Space
64
- huggingface-cli upload YOUR_USERNAME/moazx-api . --repo-type=space
65
- ```
66
-
67
- ### 4. Verify Deployment
68
-
69
- 1. Wait for the Space to build (check the logs)
70
- 2. Once running, test the API:
71
- - Visit: `https://YOUR_USERNAME-moazx-api.hf.space`
72
- - Check health: `https://YOUR_USERNAME-moazx-api.hf.space/health`
73
- - View docs: `https://YOUR_USERNAME-moazx-api.hf.space/docs`
74
-
75
- ### 5. Deploy Frontend
76
-
77
- The frontend is configured to use the API at `https://moazx-api.hf.space`.
78
-
79
- #### Option A: Serve from the same Space
80
- The frontend files are already in the `/frontend` directory and will be served automatically.
81
-
82
- #### Option B: Deploy to separate hosting
83
- Deploy the frontend folder to:
84
- - Netlify
85
- - Vercel
86
- - GitHub Pages
87
- - Any static hosting service
88
-
89
- ## API Endpoints
90
-
91
- Once deployed, your API will be available at:
92
-
93
- ```
94
- Base URL: https://moazx-api.hf.space
95
-
96
- Endpoints:
97
- - GET / - API information
98
- - GET /health - Health check
99
- - GET /health/initialization - Initialization status
100
- - POST /auth/login - User login
101
- - POST /auth/logout - User logout
102
- - GET /auth/status - Authentication status
103
- - GET /ask - Ask a question (non-streaming)
104
- - GET /ask/stream - Ask a question (streaming)
105
- - GET /export/{format} - Export conversation
106
- ```
107
-
108
- ## Frontend Configuration
109
-
110
- The frontend is already configured to use the Hugging Face API:
111
-
112
- ```javascript
113
- // In frontend/script.js
114
- this.apiBase = 'https://moazx-api.hf.space';
115
- ```
116
-
117
- ## Authentication
118
-
119
- The system uses session-based authentication:
120
-
121
- 1. Default credentials (change in production):
122
- - Username: `admin`
123
- - Password: `admin123`
124
-
125
- 2. To change credentials, update `api/routers/auth.py`
126
-
127
- ## Monitoring
128
-
129
- Monitor your deployment:
130
-
131
- 1. **Hugging Face Space Logs**: Check the logs tab in your Space
132
- 2. **API Health**: Monitor `/health` endpoint
133
- 3. **Initialization Status**: Check `/health/initialization`
134
-
135
- ## Troubleshooting
136
-
137
- ### Issue: Space fails to build
138
- - Check Dockerfile syntax
139
- - Verify all dependencies in requirements.txt
140
- - Check Space logs for specific errors
141
-
142
- ### Issue: API returns 500 errors
143
- - Verify environment variables are set correctly
144
- - Check that OPENAI_API_KEY is valid
145
- - Review application logs
146
-
147
- ### Issue: CORS errors in frontend
148
- - Verify CORS middleware configuration in `api/middleware.py`
149
- - Ensure frontend URL is in allowed origins
150
-
151
- ### Issue: Slow initialization
152
- - The system loads models in the background
153
- - Check `/health/initialization` for status
154
- - Consider upgrading to better hardware tier
155
-
156
- ## Performance Optimization
157
-
158
- ### For Better Performance:
159
- 1. Upgrade to GPU hardware tier (for faster embeddings)
160
- 2. Use persistent storage for cached data
161
- 3. Enable CDN for frontend assets
162
-
163
- ### Memory Management:
164
- - Current setup uses CPU-optimized models
165
- - Faiss-cpu for vector search
166
- - Sentence-transformers for embeddings
167
-
168
- ## Security Considerations
169
-
170
- 1. **Change default credentials** in production
171
- 2. **Rotate API keys** regularly
172
- 3. **Enable rate limiting** (already configured)
173
- 4. **Use HTTPS** (automatic on Hugging Face)
174
- 5. **Review CORS settings** for production
175
-
176
- ## Updating the Deployment
177
-
178
- To update your deployment:
179
-
180
- ```bash
181
- # Make changes locally
182
- git add .
183
- git commit -m "Update description"
184
- git push
185
-
186
- # Hugging Face will automatically rebuild
187
- ```
188
-
189
- ## Cost Considerations
190
-
191
- - **Free tier**: CPU Basic (limited resources)
192
- - **Paid tiers**: Better performance and reliability
193
- - **API costs**: OpenAI API usage (pay per token)
194
-
195
- ## Support
196
-
197
- For issues:
198
- 1. Check Hugging Face Space logs
199
- 2. Review application logs at `/logs/app.log`
200
- 3. Test endpoints using `/docs` (Swagger UI)
201
-
202
- ## Additional Resources
203
-
204
- - [Hugging Face Spaces Documentation](https://huggingface.co/docs/hub/spaces)
205
- - [FastAPI Documentation](https://fastapi.tiangolo.com/)
206
- - [Docker Documentation](https://docs.docker.com/)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
DEPLOYMENT_SUMMARY.md DELETED
@@ -1,296 +0,0 @@
1
- # Deployment Summary - Hugging Face Integration
2
-
3
- ## Changes Made for Hugging Face Deployment
4
-
5
- ### 1. Frontend Configuration (`frontend/script.js`)
6
- **Changed:**
7
- - Updated API base URL from `http://127.0.0.1:8000` to `https://moazx-api.hf.space`
8
-
9
- **Impact:**
10
- - Frontend now connects to the deployed Hugging Face Space API
11
- - Works seamlessly with the production backend
12
-
13
- ### 2. Backend Configuration (`app.py`)
14
- **Changed:**
15
- - Updated host from `127.0.0.1` to `0.0.0.0` (bind to all interfaces)
16
- - Updated port to use environment variable `PORT` (default: 7860)
17
- - Disabled reload for production
18
- - Configured for single worker deployment
19
-
20
- **Impact:**
21
- - Backend now accepts connections from external sources
22
- - Compatible with Hugging Face Spaces port configuration
23
- - Optimized for production deployment
24
-
25
- ### 3. CORS Middleware (`api/middleware.py`)
26
- **Already Configured:**
27
- - CORS middleware already includes `https://moazx-api.hf.space`
28
- - Supports multiple origins for development and production
29
- - Allows credentials for authentication
30
-
31
- **No changes needed** - already production-ready!
32
-
33
- ### 4. Docker Configuration (`Dockerfile`)
34
- **Already Configured:**
35
- - Multi-stage build for optimized image size
36
- - Exposes port 7860 (Hugging Face standard)
37
- - Runs as non-root user for security
38
- - Uses Python 3.11-slim for minimal footprint
39
-
40
- **No changes needed** - already production-ready!
41
-
42
- ### 5. Environment Variables (`.env.example`)
43
- **Updated:**
44
- - Added comprehensive documentation for all environment variables
45
- - Included GitHub storage configuration
46
- - Added server configuration (PORT, HOST)
47
- - Added CORS configuration
48
- - Documented authentication credentials
49
-
50
- **Action Required:**
51
- - Copy `.env.example` to `.env` and fill in your actual values
52
- - Set these as secrets in Hugging Face Space settings
53
-
54
- ### 6. Documentation
55
- **Created/Updated:**
56
- - `DEPLOYMENT.md` - Comprehensive deployment guide
57
- - `README.md` - Updated with full feature list and usage instructions
58
- - `.env.example` - Complete environment variable documentation
59
-
60
- ## Deployment Checklist
61
-
62
- ### ✅ Code Changes Complete
63
- - [x] Frontend API endpoint updated
64
- - [x] Backend configured for production
65
- - [x] CORS properly configured
66
- - [x] Docker configuration verified
67
- - [x] Environment variables documented
68
-
69
- ### 📋 Next Steps for Deployment
70
-
71
- 1. **Prepare Hugging Face Space**
72
- ```bash
73
- # Create a new Space on Hugging Face
74
- # Name: moazx-api
75
- # SDK: Docker
76
- # Hardware: CPU Basic (or better)
77
- ```
78
-
79
- 2. **Set Environment Variables in Hugging Face**
80
- Go to Space Settings → Variables and Secrets:
81
- ```
82
- OPENAI_API_KEY=your_actual_key
83
- GITHUB_TOKEN=your_github_token
84
- GITHUB_REPO=username/repo
85
- GITHUB_BRANCH=main
86
- PORT=7860
87
- ```
88
-
89
- 3. **Deploy Code to Hugging Face**
90
- ```bash
91
- # Clone your HF Space
92
- git clone https://huggingface.co/spaces/YOUR_USERNAME/moazx-api
93
- cd moazx-api
94
-
95
- # Copy all backend files
96
- cp -r /path/to/backend/* .
97
-
98
- # Commit and push
99
- git add .
100
- git commit -m "Initial deployment"
101
- git push
102
- ```
103
-
104
- 4. **Verify Deployment**
105
- - Wait for build to complete (check logs)
106
- - Test health endpoint: `https://moazx-api.hf.space/health`
107
- - Test API docs: `https://moazx-api.hf.space/docs`
108
- - Test frontend by opening `frontend/index.html`
109
-
110
- 5. **Test Functionality**
111
- - Login with credentials (admin/admin123)
112
- - Ask a test question
113
- - Verify citations are working
114
- - Test export functionality
115
- - Check streaming responses
116
-
117
- ## File Structure for Deployment
118
-
119
- ```
120
- backend/
121
- ├── api/
122
- │ ├── __init__.py
123
- │ ├── app.py # Main FastAPI application
124
- │ ├── middleware.py # CORS, auth, rate limiting
125
- │ ├── exceptions.py
126
- │ ├── models.py
127
- │ └── routers/
128
- │ ├── medical.py # Medical query endpoints
129
- │ ├── health.py # Health check endpoints
130
- │ ├── export.py # Export endpoints
131
- │ └── auth.py # Authentication endpoints
132
- ├── core/
133
- │ ├── agent.py # LangChain agent configuration ⭐
134
- │ ├── tools.py # Agent tools
135
- │ ├── retrievers.py # Hybrid search
136
- │ ├── context_enrichment.py # Context page enrichment
137
- │ ├── vector_store.py # FAISS vector store
138
- │ └── ...
139
- ├── frontend/
140
- │ ├── index.html # Main UI
141
- │ ├── script.js # Frontend logic ⭐ (updated)
142
- │ ├── styles.css # Styling
143
- │ └── login.html # Login page
144
- ├── data/
145
- │ ├── chunks.pkl # Preprocessed document chunks
146
- │ └── medical_terms_cache.json
147
- ├── Dockerfile # Docker configuration
148
- ├── requirements.txt # Python dependencies
149
- ├── app.py # Entry point ⭐ (updated)
150
- ├── README.md # Documentation ⭐ (updated)
151
- ├── DEPLOYMENT.md # Deployment guide ⭐ (new)
152
- ├── .env.example # Environment variables ⭐ (updated)
153
- └── .gitignore
154
-
155
- ⭐ = Files modified/created for deployment
156
- ```
157
-
158
- ## Configuration Summary
159
-
160
- ### API Endpoint
161
- - **Production**: `https://moazx-api.hf.space`
162
- - **Local Dev**: `http://localhost:7860`
163
-
164
- ### Authentication
165
- - **Default Username**: `admin`
166
- - **Default Password**: `admin123`
167
- - **⚠️ Change in production!**
168
-
169
- ### Required Environment Variables
170
- ```bash
171
- OPENAI_API_KEY=required
172
- GITHUB_TOKEN=optional (for side effects)
173
- GITHUB_REPO=optional
174
- PORT=7860
175
- ```
176
-
177
- ### Optional Environment Variables
178
- ```bash
179
- LANGSMITH_API_KEY=optional (for tracing)
180
- ALLOWED_ORIGINS=optional (auto-configured)
181
- AUTH_USERNAME=optional (defaults to admin)
182
- AUTH_PASSWORD=optional (defaults to admin123)
183
- ```
184
-
185
- ## Testing the Deployment
186
-
187
- ### 1. Health Check
188
- ```bash
189
- curl https://moazx-api.hf.space/health
190
- ```
191
-
192
- Expected response:
193
- ```json
194
- {
195
- "status": "healthy",
196
- "timestamp": "2025-01-22T...",
197
- "version": "1.0.0"
198
- }
199
- ```
200
-
201
- ### 2. API Documentation
202
- Visit: `https://moazx-api.hf.space/docs`
203
-
204
- ### 3. Test Query (with authentication)
205
- ```bash
206
- # Login first
207
- curl -X POST https://moazx-api.hf.space/auth/login \
208
- -H "Content-Type: application/json" \
209
- -d '{"username":"admin","password":"admin123"}' \
210
- -c cookies.txt
211
-
212
- # Ask a question
213
- curl -X GET "https://moazx-api.hf.space/ask?query=What%20is%20EGFR%20mutation&session_id=test123" \
214
- -b cookies.txt
215
- ```
216
-
217
- ## Troubleshooting
218
-
219
- ### Issue: Build fails on Hugging Face
220
- - Check Dockerfile syntax
221
- - Verify requirements.txt has all dependencies
222
- - Check Space logs for specific errors
223
-
224
- ### Issue: API returns 500 errors
225
- - Verify OPENAI_API_KEY is set correctly
226
- - Check application logs in Space
227
- - Verify data files (chunks.pkl) are present
228
-
229
- ### Issue: Frontend can't connect
230
- - Verify CORS settings in middleware.py
231
- - Check that frontend is using correct API URL
232
- - Test API endpoint directly first
233
-
234
- ### Issue: Authentication fails
235
- - Verify credentials in auth.py
236
- - Check cookie settings
237
- - Ensure HTTPS is being used
238
-
239
- ## Performance Considerations
240
-
241
- ### Current Setup
242
- - **CPU-optimized**: Uses faiss-cpu and CPU-only PyTorch
243
- - **Memory**: ~2-4GB RAM usage
244
- - **Startup time**: 30-60 seconds (background initialization)
245
-
246
- ### Optimization Options
247
- 1. **Upgrade to GPU tier** - Faster embeddings and inference
248
- 2. **Enable caching** - Cache frequently accessed documents
249
- 3. **Optimize chunk size** - Reduce memory footprint
250
- 4. **Use persistent storage** - Store vector index on disk
251
-
252
- ## Security Checklist
253
-
254
- - [x] HTTPS enabled (automatic on Hugging Face)
255
- - [x] Session-based authentication implemented
256
- - [x] Rate limiting configured (100 req/min)
257
- - [x] CORS properly configured
258
- - [x] Input validation in place
259
- - [ ] Change default credentials (TODO in production)
260
- - [ ] Rotate API keys regularly (TODO)
261
- - [ ] Enable monitoring/logging (TODO)
262
-
263
- ## Monitoring
264
-
265
- ### Key Metrics to Monitor
266
- 1. **API Response Time**: Check X-Process-Time header
267
- 2. **Error Rate**: Monitor 500 errors in logs
268
- 3. **Initialization Status**: `/health/initialization` endpoint
269
- 4. **OpenAI API Usage**: Monitor token consumption
270
-
271
- ### Logs Location
272
- - Hugging Face Space logs tab
273
- - Application logs: `/logs/app.log`
274
-
275
- ## Next Steps After Deployment
276
-
277
- 1. **Test thoroughly** with real clinical questions
278
- 2. **Monitor performance** and optimize as needed
279
- 3. **Update documentation** with actual deployment URL
280
- 4. **Set up monitoring** and alerts
281
- 5. **Plan for scaling** if usage increases
282
- 6. **Regular updates** to medical guidelines
283
- 7. **Security audit** and credential rotation
284
-
285
- ## Support Resources
286
-
287
- - **Deployment Guide**: See `DEPLOYMENT.md`
288
- - **API Documentation**: Visit `/docs` on deployed Space
289
- - **Hugging Face Docs**: https://huggingface.co/docs/hub/spaces
290
- - **FastAPI Docs**: https://fastapi.tiangolo.com/
291
-
292
- ---
293
-
294
- **Deployment Status**: ✅ Ready for Deployment
295
-
296
- All code changes are complete. Follow the deployment checklist to deploy to Hugging Face Spaces.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Medical_AI_System_Prompts.docx ADDED
Binary file (44.4 kB). View file
 
QUICK_DEPLOY.md DELETED
@@ -1,100 +0,0 @@
1
- # Quick Deployment Guide - Hugging Face
2
-
3
- ## 🚀 Deploy in 5 Steps
4
-
5
- ### Step 1: Create Hugging Face Space
6
- 1. Go to https://huggingface.co/spaces
7
- 2. Click "Create new Space"
8
- 3. Settings:
9
- - Name: `moazx-api`
10
- - SDK: **Docker**
11
- - Hardware: CPU Basic (minimum)
12
-
13
- ### Step 2: Set Environment Variables
14
- In Space Settings → Secrets, add:
15
- ```
16
- OPENAI_API_KEY=sk-...your-key...
17
- GITHUB_TOKEN=ghp_...your-token...
18
- GITHUB_REPO=username/repo-name
19
- GITHUB_BRANCH=main
20
- PORT=7860
21
- ```
22
-
23
- ### Step 3: Push Code
24
- ```bash
25
- # Clone your Space
26
- git clone https://huggingface.co/spaces/YOUR_USERNAME/moazx-api
27
- cd moazx-api
28
-
29
- # Copy all files from backend folder
30
- cp -r /path/to/backend/* .
31
-
32
- # Commit and push
33
- git add .
34
- git commit -m "Deploy Lung Cancer Clinical Decision Support System"
35
- git push
36
- ```
37
-
38
- ### Step 4: Wait for Build
39
- - Watch the build logs in your Space
40
- - Wait for "Running" status (30-60 seconds)
41
-
42
- ### Step 5: Test
43
- ```bash
44
- # Test health endpoint
45
- curl https://YOUR_USERNAME-moazx-api.hf.space/health
46
-
47
- # Visit API docs
48
- open https://YOUR_USERNAME-moazx-api.hf.space/docs
49
- ```
50
-
51
- ## ✅ Verification Checklist
52
-
53
- - [ ] Space is running (green status)
54
- - [ ] `/health` returns `{"status": "healthy"}`
55
- - [ ] `/docs` shows API documentation
56
- - [ ] Can login with admin/admin123
57
- - [ ] Can ask a test question
58
- - [ ] Streaming responses work
59
- - [ ] Citations appear in answers
60
-
61
- ## 🔧 Quick Fixes
62
-
63
- ### Build Failed?
64
- - Check Dockerfile syntax
65
- - Verify all files are committed
66
- - Check Space logs for errors
67
-
68
- ### API Not Responding?
69
- - Verify OPENAI_API_KEY is set
70
- - Check Space logs
71
- - Restart the Space
72
-
73
- ### Frontend Can't Connect?
74
- - Update `frontend/script.js` with your Space URL:
75
- ```javascript
76
- this.apiBase = 'https://YOUR_USERNAME-moazx-api.hf.space';
77
- ```
78
-
79
- ## 📱 Access Your Deployment
80
-
81
- - **API**: `https://YOUR_USERNAME-moazx-api.hf.space`
82
- - **Docs**: `https://YOUR_USERNAME-moazx-api.hf.space/docs`
83
- - **Health**: `https://YOUR_USERNAME-moazx-api.hf.space/health`
84
-
85
- ## 🔐 Default Credentials
86
-
87
- - Username: `admin`
88
- - Password: `admin123`
89
-
90
- **⚠️ Change these in production!**
91
-
92
- ## 📚 Full Documentation
93
-
94
- - Detailed guide: `DEPLOYMENT.md`
95
- - Complete summary: `DEPLOYMENT_SUMMARY.md`
96
- - README: `README.md`
97
-
98
- ---
99
-
100
- **Need Help?** Check the full deployment guide in `DEPLOYMENT.md`
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
README.md CHANGED
@@ -33,22 +33,16 @@ A specialized AI-powered clinical decision support system for thoracic oncologis
33
  ## 🚀 Deployment
34
 
35
  ### Live API
36
- The API is deployed at: **https://moazx-api.hf.space**
37
 
38
  ### Quick Start
39
 
40
  1. **Access the API**:
41
- - API Docs: https://moazx-api.hf.space/docs
42
- - Health Check: https://moazx-api.hf.space/health
43
 
44
- 2. **Use the Frontend**:
45
- - Open `frontend/index.html` in a browser
46
- - Login with credentials (default: admin/admin123)
47
- - Start asking clinical questions
48
 
49
- ### Deploy Your Own Instance
50
 
51
- See [DEPLOYMENT.md](DEPLOYMENT.md) for detailed deployment instructions.
52
 
53
  ## 📚 API Endpoints
54
 
@@ -61,10 +55,22 @@ See [DEPLOYMENT.md](DEPLOYMENT.md) for detailed deployment instructions.
61
  - `POST /auth/login` - User login
62
  - `POST /auth/logout` - User logout
63
  - `GET /auth/status` - Check authentication status
64
-
65
  ### Medical Queries
66
- - `GET /ask?query={question}&session_id={id}` - Ask a question (non-streaming)
67
- - `GET /ask/stream?query={question}&session_id={id}` - Ask a question (streaming)
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
  ### Export
70
  - `GET /export/{format}?session_id={id}` - Export conversation (format: pdf, docx, txt)
@@ -116,46 +122,6 @@ See `.env.example` for all configuration options:
116
  - `PORT`: Server port (default: 7860)
117
  - `ALLOWED_ORIGINS`: CORS allowed origins
118
 
119
- ### Authentication
120
-
121
- Default credentials (change in production):
122
- - Username: `admin`
123
- - Password: `admin123`
124
-
125
- Update in `api/routers/auth.py` or via environment variables.
126
-
127
- ## 📖 Usage Examples
128
-
129
- ### Using the API
130
-
131
- ```python
132
- import requests
133
-
134
- # Login
135
- response = requests.post(
136
- "https://moazx-api.hf.space/auth/login",
137
- json={"username": "admin", "password": "admin123"}
138
- )
139
- cookies = response.cookies
140
-
141
- # Ask a question
142
- response = requests.get(
143
- "https://moazx-api.hf.space/ask",
144
- params={
145
- "query": "What is the first-line treatment for EGFR-mutated NSCLC?",
146
- "session_id": "my-session-123"
147
- },
148
- cookies=cookies
149
- )
150
- print(response.json()["response"])
151
- ```
152
-
153
- ### Using the Frontend
154
-
155
- 1. Open `frontend/index.html`
156
- 2. Login with credentials
157
- 3. Type your clinical question
158
- 4. Receive evidence-based answers with citations
159
 
160
  ## 🏗️ Architecture
161
 
@@ -178,10 +144,11 @@ print(response.json()["response"])
178
  ## 📊 Response Format
179
 
180
  The agent provides:
181
- - **Concise, targeted answers** for busy clinicians
182
  - **Inline citations** after each statement
183
  - **Comprehensive reference list** at the end
184
- - **Structured formatting** for easy scanning
 
185
 
186
  Example:
187
  ```
@@ -194,35 +161,3 @@ Example:
194
  **References:**
195
  (Source: NCCN.pdf, Pages: 45, 46, Provider: NCCN, Location: NSCLC Treatment Algorithm)
196
  ```
197
-
198
- ## 🔒 Security
199
-
200
- - Session-based authentication
201
- - Rate limiting (100 requests/minute)
202
- - CORS protection
203
- - Input validation
204
- - Secure cookie handling
205
-
206
- ## 📝 License
207
-
208
- [Add your license here]
209
-
210
- ## 🤝 Contributing
211
-
212
- Contributions are welcome! Please read the contributing guidelines first.
213
-
214
- ## 📧 Support
215
-
216
- For issues or questions:
217
- - Check the [DEPLOYMENT.md](DEPLOYMENT.md) guide
218
- - Review API docs at `/docs`
219
- - Open an issue on GitHub
220
-
221
- ## 🙏 Acknowledgments
222
-
223
- Built with:
224
- - FastAPI
225
- - LangChain
226
- - OpenAI
227
- - FAISS
228
- - Sentence Transformers
 
33
  ## 🚀 Deployment
34
 
35
  ### Live API
36
+ The API is deployed at: **https://moazx-lung-cancer-ai-advisor.hf.space**
37
 
38
  ### Quick Start
39
 
40
  1. **Access the API**:
41
+ - API Docs: https://moazx-lung-cancer-ai-advisor.hf.space/docs
42
+ - Health Check: https://moazx-lung-cancer-ai-advisor.hf.space/health
43
 
 
 
 
 
44
 
 
45
 
 
46
 
47
  ## 📚 API Endpoints
48
 
 
55
  - `POST /auth/login` - User login
56
  - `POST /auth/logout` - User logout
57
  - `GET /auth/status` - Check authentication status
58
+ up
59
  ### Medical Queries
60
+ - `POST /ask` - Ask a question (complete response)
61
+ ```json
62
+ {
63
+ "query": "What are the early symptoms of lung cancer?",
64
+ "session_id": "user_123_session_1699612345"
65
+ }
66
+ ```
67
+ - `POST /ask/stream` - Ask a question (streaming response)
68
+ ```json
69
+ {
70
+ "query": "What are the treatment options?",
71
+ "session_id": "user_123_session_1699612345"
72
+ }
73
+ ```
74
 
75
  ### Export
76
  - `GET /export/{format}?session_id={id}` - Export conversation (format: pdf, docx, txt)
 
122
  - `PORT`: Server port (default: 7860)
123
  - `ALLOWED_ORIGINS`: CORS allowed origins
124
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
 
126
  ## 🏗️ Architecture
127
 
 
144
  ## 📊 Response Format
145
 
146
  The agent provides:
147
+ - **Concise, evidence-based answers** for busy clinicians
148
  - **Inline citations** after each statement
149
  - **Comprehensive reference list** at the end
150
+ - **Structured markdown formatting** for easy scanning
151
+ - **Real-time streaming** for immediate feedback
152
 
153
  Example:
154
  ```
 
161
  **References:**
162
  (Source: NCCN.pdf, Pages: 45, 46, Provider: NCCN, Location: NSCLC Treatment Algorithm)
163
  ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
api/__pycache__/__init__.cpython-311.pyc CHANGED
Binary files a/api/__pycache__/__init__.cpython-311.pyc and b/api/__pycache__/__init__.cpython-311.pyc differ
 
api/__pycache__/__init__.cpython-313.pyc CHANGED
Binary files a/api/__pycache__/__init__.cpython-313.pyc and b/api/__pycache__/__init__.cpython-313.pyc differ
 
api/__pycache__/app.cpython-311.pyc CHANGED
Binary files a/api/__pycache__/app.cpython-311.pyc and b/api/__pycache__/app.cpython-311.pyc differ
 
api/__pycache__/app.cpython-313.pyc CHANGED
Binary files a/api/__pycache__/app.cpython-313.pyc and b/api/__pycache__/app.cpython-313.pyc differ
 
api/__pycache__/exceptions.cpython-313.pyc CHANGED
Binary files a/api/__pycache__/exceptions.cpython-313.pyc and b/api/__pycache__/exceptions.cpython-313.pyc differ
 
api/__pycache__/middleware.cpython-313.pyc CHANGED
Binary files a/api/__pycache__/middleware.cpython-313.pyc and b/api/__pycache__/middleware.cpython-313.pyc differ
 
api/__pycache__/models.cpython-313.pyc CHANGED
Binary files a/api/__pycache__/models.cpython-313.pyc and b/api/__pycache__/models.cpython-313.pyc differ
 
api/app.py CHANGED
@@ -31,7 +31,7 @@ logger = logging.getLogger(__name__)
31
  async def lifespan(app: FastAPI):
32
  """Application lifespan management with background initialization"""
33
  # Startup
34
- logger.info("Starting Medical RAG AI Advisor API...")
35
 
36
  # Start background initialization of heavy components
37
  try:
@@ -46,13 +46,29 @@ async def lifespan(app: FastAPI):
46
  yield
47
 
48
  # Shutdown
49
- logger.info("Shutting down Medical RAG AI Advisor API...")
50
 
51
 
52
  # Create FastAPI application
53
  app = FastAPI(
54
- title="Medical RAG AI Advisor API",
55
- description="Professional API for medical information retrieval and advisory services",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  version="1.0.0",
57
  docs_url="/docs",
58
  redoc_url="/redoc",
@@ -83,9 +99,9 @@ app.include_router(export.router)
83
  async def root():
84
  """Root endpoint with API information"""
85
  return {
86
- "name": "Medical RAG AI Advisor API",
87
  "version": "1.0.0",
88
- "description": "Professional API for medical information retrieval and advisory services",
89
  "docs": "/docs",
90
  "health": "/health",
91
  "endpoints": {
 
31
  async def lifespan(app: FastAPI):
32
  """Application lifespan management with background initialization"""
33
  # Startup
34
+ logger.info("Starting Lung Cancer AI Advisor API...")
35
 
36
  # Start background initialization of heavy components
37
  try:
 
46
  yield
47
 
48
  # Shutdown
49
+ logger.info("Shutting down Lung Cancer AI Advisor API...")
50
 
51
 
52
  # Create FastAPI application
53
  app = FastAPI(
54
+ title="Lung Cancer AI Advisor API",
55
+ description="""AI-Powered Lung Cancer Information & Support API
56
+
57
+ This API provides intelligent responses to lung cancer-related queries using advanced AI and medical knowledge retrieval.
58
+
59
+ **Key Features:**
60
+ - Intelligent Query Processing: AI agent automatically selects appropriate tools and data sources
61
+ - Session Management: Maintains conversation context across multiple queries
62
+ - Streaming Support: Real-time response streaming for better UX
63
+ - Medical Knowledge Base: Access to comprehensive lung cancer information
64
+
65
+ **Main Endpoints:**
66
+ - POST /ask - Get complete AI response for a query
67
+ - POST /ask/stream - Stream AI response in real-time (recommended for better UX)
68
+ - GET /health - Check API health and initialization status
69
+ - POST /export/{format} - Export conversation history
70
+
71
+ """,
72
  version="1.0.0",
73
  docs_url="/docs",
74
  redoc_url="/redoc",
 
99
  async def root():
100
  """Root endpoint with API information"""
101
  return {
102
+ "name": "Lung Cancer AI Advisor API",
103
  "version": "1.0.0",
104
+ "description": "AI-powered advisor for lung cancer information and support",
105
  "docs": "/docs",
106
  "health": "/health",
107
  "endpoints": {
api/exceptions.py CHANGED
@@ -1,5 +1,5 @@
1
  """
2
- Exception handlers for Medical RAG AI Advisor API
3
  """
4
  import logging
5
  from datetime import datetime
 
1
  """
2
+ Exception handlers for Lung Cancer AI Advisor API
3
  """
4
  import logging
5
  from datetime import datetime
api/middleware.py CHANGED
@@ -1,5 +1,5 @@
1
  """
2
- Middleware for Medical RAG AI Advisor API
3
  """
4
  import time
5
  import logging
@@ -147,7 +147,8 @@ def get_cors_middleware_config():
147
  # Default to allowing Hugging Face Space and localhost
148
  # Include null for file:// protocol and common local development origins
149
  allowed_origins = [
150
- "https://moazx-api.hf.space",
 
151
  "http://localhost:8000",
152
  "http://127.0.0.1:8000",
153
  "http://localhost:5500", # Live Server default port
@@ -160,7 +161,7 @@ def get_cors_middleware_config():
160
  return {
161
  "allow_origins": allowed_origins,
162
  "allow_credentials": True,
163
- "allow_methods": ["*"],
164
- "allow_headers": ["*"],
165
- "expose_headers": ["*"],
166
  }
 
1
  """
2
+ Middleware for Lung Cancer AI Advisor API
3
  """
4
  import time
5
  import logging
 
147
  # Default to allowing Hugging Face Space and localhost
148
  # Include null for file:// protocol and common local development origins
149
  allowed_origins = [
150
+ "http://127.0.0.1:7860",
151
+ "https://huggingface.co",
152
  "http://localhost:8000",
153
  "http://127.0.0.1:8000",
154
  "http://localhost:5500", # Live Server default port
 
161
  return {
162
  "allow_origins": allowed_origins,
163
  "allow_credentials": True,
164
+ "allow_methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
165
+ "allow_headers": ["Content-Type", "Authorization", "Accept", "Origin", "X-Requested-With", "Cookie"],
166
+ "expose_headers": ["Set-Cookie"],
167
  }
api/models.py CHANGED
@@ -1,5 +1,5 @@
1
  """
2
- API Models and Schemas for Medical RAG AI Advisor
3
  """
4
  from pydantic import BaseModel, Field
5
  from typing import Optional, List, Dict, Any
 
1
  """
2
+ API Models and Schemas for Lung Cancer AI Advisor
3
  """
4
  from pydantic import BaseModel, Field
5
  from typing import Optional, List, Dict, Any
api/routers/__pycache__/__init__.cpython-311.pyc CHANGED
Binary files a/api/routers/__pycache__/__init__.cpython-311.pyc and b/api/routers/__pycache__/__init__.cpython-311.pyc differ
 
api/routers/__pycache__/__init__.cpython-313.pyc CHANGED
Binary files a/api/routers/__pycache__/__init__.cpython-313.pyc and b/api/routers/__pycache__/__init__.cpython-313.pyc differ
 
api/routers/__pycache__/health.cpython-313.pyc CHANGED
Binary files a/api/routers/__pycache__/health.cpython-313.pyc and b/api/routers/__pycache__/health.cpython-313.pyc differ
 
api/routers/__pycache__/medical.cpython-311.pyc CHANGED
Binary files a/api/routers/__pycache__/medical.cpython-311.pyc and b/api/routers/__pycache__/medical.cpython-311.pyc differ
 
api/routers/__pycache__/medical.cpython-313.pyc CHANGED
Binary files a/api/routers/__pycache__/medical.cpython-313.pyc and b/api/routers/__pycache__/medical.cpython-313.pyc differ
 
api/routers/auth.py CHANGED
@@ -100,6 +100,9 @@ async def login(
100
  """
101
  Login endpoint - validates credentials and creates session
102
  """
 
 
 
103
  # Verify credentials
104
  if not verify_credentials(username, password):
105
  logger.warning(f"Failed login attempt for username: {username}")
@@ -107,18 +110,22 @@ async def login(
107
 
108
  # Create session
109
  token = create_session(username)
 
110
 
111
  # Set secure cookie
112
- # In development (HTTP), use lax samesite and secure=False
113
- # In production (HTTPS), use none samesite and secure=True
114
- is_production = os.getenv("ENVIRONMENT", "development") == "production"
 
 
 
 
 
 
 
 
115
 
116
- origin = request.headers.get("origin")
117
- parsed_origin = urlparse(origin) if origin else None
118
- is_cross_site = bool(parsed_origin and parsed_origin.hostname and parsed_origin.hostname != request.url.hostname)
119
- is_https = request.url.scheme == "https"
120
- samesite = "none" if (is_https and (is_production or is_cross_site)) else "lax"
121
- secure = True if samesite == "none" else is_production
122
 
123
  response.set_cookie(
124
  key="session_token",
@@ -126,7 +133,8 @@ async def login(
126
  httponly=True,
127
  max_age=SESSION_MAX_AGE,
128
  samesite=samesite,
129
- secure=secure
 
130
  )
131
 
132
  logger.info(f"Successful login for user: {username}")
@@ -175,12 +183,18 @@ async def verify(session_token: Optional[str] = Cookie(None)):
175
 
176
 
177
  @router.get("/status")
178
- async def status(session_token: Optional[str] = Cookie(None)):
179
  """
180
  Check authentication status without raising exception
181
  """
 
182
  session_data = verify_session(session_token)
183
 
 
 
 
 
 
184
  return {
185
  "authenticated": session_data is not None,
186
  "username": session_data.get("username") if session_data else None
 
100
  """
101
  Login endpoint - validates credentials and creates session
102
  """
103
+ # Log login attempt
104
+ logger.info(f"Login attempt for username: {username}, Origin: {request.headers.get('origin')}")
105
+
106
  # Verify credentials
107
  if not verify_credentials(username, password):
108
  logger.warning(f"Failed login attempt for username: {username}")
 
110
 
111
  # Create session
112
  token = create_session(username)
113
+ logger.info(f"Session created for user: {username}")
114
 
115
  # Set secure cookie
116
+ # Detect if we're running on HTTPS (Hugging Face Spaces use HTTPS)
117
+ is_https = request.url.scheme == "https" or request.headers.get("x-forwarded-proto") == "https"
118
+
119
+ # For HTTPS (production/HF Spaces), use SameSite=None with Secure=True for cross-origin
120
+ # For HTTP (local dev), use SameSite=Lax with Secure=False
121
+ if is_https:
122
+ samesite = "none"
123
+ secure = True
124
+ else:
125
+ samesite = "lax"
126
+ secure = False
127
 
128
+ logger.info(f"Setting cookie with samesite={samesite}, secure={secure}, is_https={is_https}")
 
 
 
 
 
129
 
130
  response.set_cookie(
131
  key="session_token",
 
133
  httponly=True,
134
  max_age=SESSION_MAX_AGE,
135
  samesite=samesite,
136
+ secure=secure,
137
+ path="/"
138
  )
139
 
140
  logger.info(f"Successful login for user: {username}")
 
183
 
184
 
185
  @router.get("/status")
186
+ async def status(request: Request, session_token: Optional[str] = Cookie(None)):
187
  """
188
  Check authentication status without raising exception
189
  """
190
+ logger.info(f"Status check - Cookie present: {session_token is not None}, Origin: {request.headers.get('origin')}")
191
  session_data = verify_session(session_token)
192
 
193
+ if session_data:
194
+ logger.info(f"Status check - Authenticated as: {session_data.get('username')}")
195
+ else:
196
+ logger.info("Status check - Not authenticated")
197
+
198
  return {
199
  "authenticated": session_data is not None,
200
  "username": session_data.get("username") if session_data else None
api/routers/health.py CHANGED
@@ -3,11 +3,6 @@ Health Check and System Status Router
3
  """
4
  from datetime import datetime
5
  from fastapi import APIRouter
6
- import sys
7
- import os
8
-
9
- # Add src to path for imports
10
- sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
11
 
12
  from api.models import HealthStatus, InitializationStatus
13
 
@@ -23,28 +18,58 @@ async def health_check():
23
 
24
  # Check agent availability
25
  try:
26
- from agent import safe_run_agent
27
  components["agent"] = "healthy"
28
  except Exception:
29
  components["agent"] = "unhealthy"
30
 
31
  # Check vector store
32
  try:
33
- from vector_store import VectorStore
34
- components["vector_store"] = "healthy"
35
- except Exception:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  components["vector_store"] = "unhealthy"
37
 
38
  # Check data loaders
39
  try:
40
- from data_loaders import load_pdf_documents
41
  components["data_loaders"] = "healthy"
42
  except Exception:
43
  components["data_loaders"] = "unhealthy"
44
 
45
  # Check tools
46
  try:
47
- from tools import medical_guidelines_knowledge_tool
48
  components["tools"] = "healthy"
49
  except Exception:
50
  components["tools"] = "unhealthy"
@@ -52,7 +77,7 @@ async def health_check():
52
  # Check initialization status
53
  initialization_status = None
54
  try:
55
- from background_init import (
56
  is_initialization_complete,
57
  get_initialization_status,
58
  is_initialization_successful,
@@ -130,8 +155,8 @@ async def get_version():
130
  """
131
  return {
132
  "version": "1.0.0",
133
- "name": "Medical RAG AI Advisor API",
134
- "description": "Professional API for medical information retrieval and advisory services",
135
  "build_date": "2024-01-01"
136
  }
137
 
 
3
  """
4
  from datetime import datetime
5
  from fastapi import APIRouter
 
 
 
 
 
6
 
7
  from api.models import HealthStatus, InitializationStatus
8
 
 
18
 
19
  # Check agent availability
20
  try:
21
+ from core.agent import safe_run_agent
22
  components["agent"] = "healthy"
23
  except Exception:
24
  components["agent"] = "unhealthy"
25
 
26
  # Check vector store
27
  try:
28
+ from core.vector_store import get_vector_store, load_vector_store
29
+ from core.background_init import is_initialization_complete
30
+
31
+ # If initialization is complete, check the vector store directly
32
+ if is_initialization_complete():
33
+ vector_store = get_vector_store()
34
+ if vector_store is not None:
35
+ components["vector_store"] = "healthy"
36
+ else:
37
+ # If vector store is None, try to load it
38
+ try:
39
+ loaded_store = load_vector_store()
40
+ if loaded_store is not None:
41
+ components["vector_store"] = "healthy"
42
+ else:
43
+ components["vector_store"] = "unhealthy"
44
+ except Exception as e:
45
+ logger.error(f"Failed to load vector store: {e}")
46
+ components["vector_store"] = "unhealthy"
47
+ else:
48
+ # If initialization is not complete, the vector store might not be ready yet
49
+ # but we'll check if it exists and can be loaded
50
+ try:
51
+ loaded_store = load_vector_store()
52
+ if loaded_store is not None:
53
+ components["vector_store"] = "healthy"
54
+ else:
55
+ components["vector_store"] = "initializing"
56
+ except Exception as e:
57
+ logger.warning(f"Vector store not ready yet: {e}")
58
+ components["vector_store"] = "initializing"
59
+ except Exception as e:
60
+ logger.error(f"Error checking vector store health: {e}")
61
  components["vector_store"] = "unhealthy"
62
 
63
  # Check data loaders
64
  try:
65
+ from core.data_loaders import load_pdf_documents
66
  components["data_loaders"] = "healthy"
67
  except Exception:
68
  components["data_loaders"] = "unhealthy"
69
 
70
  # Check tools
71
  try:
72
+ from core.tools import medical_guidelines_knowledge_tool
73
  components["tools"] = "healthy"
74
  except Exception:
75
  components["tools"] = "unhealthy"
 
77
  # Check initialization status
78
  initialization_status = None
79
  try:
80
+ from core.background_init import (
81
  is_initialization_complete,
82
  get_initialization_status,
83
  is_initialization_successful,
 
155
  """
156
  return {
157
  "version": "1.0.0",
158
+ "name": "Lung Cancer AI Advisor API",
159
+ "description": "AI-powered advisor for lung cancer information and support",
160
  "build_date": "2024-01-01"
161
  }
162
 
api/routers/medical.py CHANGED
@@ -1,9 +1,11 @@
1
  """
2
- Medical Query Router for RAG AI Advisor
3
  """
4
  import asyncio
 
5
  from fastapi import APIRouter, HTTPException
6
  from fastapi.responses import StreamingResponse
 
7
  import sys
8
  import os
9
 
@@ -15,18 +17,78 @@ from core.agent import safe_run_agent, safe_run_agent_streaming
15
  router = APIRouter(tags=["medical"])
16
 
17
 
18
- @router.get("/ask")
19
- async def ask(query: str, session_id: str = "default"):
20
  """
21
- Process a medical query - agent decides which tools to use
22
 
23
- Args:
24
- query: The medical question or query
25
- session_id: Optional session identifier for conversation continuity (default: "default")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  try:
28
- response = await safe_run_agent(user_input=query, session_id=session_id)
29
- return {"response": response, "session_id": session_id}
30
 
31
  except Exception as e:
32
  raise HTTPException(
@@ -34,20 +96,60 @@ async def ask(query: str, session_id: str = "default"):
34
  detail=f"Error processing medical query: {str(e)}"
35
  )
36
 
 
 
 
37
 
38
- @router.get("/ask/stream")
39
- async def ask_stream(query: str, session_id: str = "default"):
 
 
 
 
 
40
  """
41
- Process a medical query with streaming response - agent decides which tools to use
 
 
 
 
 
 
 
 
 
 
 
 
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  Args:
44
- query: The medical question or query
45
- session_id: Optional session identifier for conversation continuity (default: "default")
 
 
 
 
 
46
  """
47
  async def event_stream():
48
  try:
49
  chunk_buffer = ""
50
- async for chunk in safe_run_agent_streaming(user_input=query, session_id=session_id):
51
  chunk_buffer += chunk
52
 
53
  # Send chunks in reasonable sizes for smoother streaming
@@ -64,3 +166,6 @@ async def ask_stream(query: str, session_id: str = "default"):
64
  yield f"Error: {str(e)}"
65
 
66
  return StreamingResponse(event_stream(), media_type="text/markdown")
 
 
 
 
1
  """
2
+ Medical Query Router for Lung Cancer AI Advisor
3
  """
4
  import asyncio
5
+ import inspect
6
  from fastapi import APIRouter, HTTPException
7
  from fastapi.responses import StreamingResponse
8
+ from pydantic import BaseModel, Field
9
  import sys
10
  import os
11
 
 
17
  router = APIRouter(tags=["medical"])
18
 
19
 
20
+ class QueryRequest(BaseModel):
 
21
  """
22
+ Request model for medical queries
23
 
24
+ Example:
25
+ {
26
+ "query": "What are the early symptoms of lung cancer?",
27
+ "session_id": "user_123_session_456"
28
+ }
29
+ """
30
+ query: str = Field(
31
+ ...,
32
+ description="The medical question or query about lung cancer",
33
+ example="Give me the options for first line treatment for NSCLC?"
34
+ )
35
+ session_id: str = Field(
36
+ ...,
37
+ description="Unique session identifier for conversation continuity. Use the same `session_id` to maintain context across multiple queries. Format: `user_{user_id}_session_{timestamp}`",
38
+ example="user_123_session_1699612345"
39
+ )
40
+
41
+
42
+ @router.post(
43
+ "/ask",
44
+ summary="Ask a lung cancer question",
45
+ )
46
+ async def ask(request: QueryRequest):
47
  """
48
+ Process a lung cancer-related medical query and return a complete response.
49
+
50
+ The AI agent intelligently selects appropriate tools and data sources to provide
51
+ accurate, evidence-based information about lung cancer.
52
+
53
+ Request Body:
54
+ - `query` (required): Your medical question about lung cancer
55
+ - `session_id` (required): Unique identifier to maintain conversation context
56
+
57
+ Response:
58
+ - `response`: Complete AI-generated answer in markdown format
59
+ - `session_id`: Echo of the session identifier used
60
+
61
+ Example Request:
62
+ {
63
+ "query": "What are the early symptoms of lung cancer?",
64
+ "session_id": "user_123_session_1699612345"
65
+ }
66
+
67
+ Example Response:
68
+ {
69
+ "response": "Early symptoms of lung cancer may include...\n\n**Common Early Signs:**\n- Persistent cough...",
70
+ "session_id": "user_123_session_1699612345"
71
+ }
72
+
73
+ Frontend Integration Tips:
74
+ - Use the same `session_id` for follow-up questions to maintain context
75
+ - Display response in markdown renderer for better formatting
76
+ - Show loading state while waiting for response
77
+ - Handle 500 errors gracefully with user-friendly messages
78
+
79
+ Args:
80
+ request: QueryRequest containing query and session_id
81
+
82
+ Returns:
83
+ Dictionary with response text and session_id
84
+
85
+ Raises:
86
+ HTTPException: 500 if query processing fails
87
+ """
88
+
89
  try:
90
+ response = await safe_run_agent(user_input=request.query, session_id=request.session_id)
91
+ return {"response": response, "session_id": request.session_id}
92
 
93
  except Exception as e:
94
  raise HTTPException(
 
96
  detail=f"Error processing medical query: {str(e)}"
97
  )
98
 
99
+ # Dedent the docstring so OpenAPI/Redoc renderers don't treat the
100
+ # indented lines as a markdown code block (leading 4-space indentation).
101
+ ask.__doc__ = inspect.cleandoc(ask.__doc__ or "")
102
 
103
+
104
+ @router.post(
105
+ "/ask/stream",
106
+ summary="Ask a lung cancer question with streaming response",
107
+
108
+ )
109
+ async def ask_stream(request: QueryRequest):
110
  """
111
+ Process a lung cancer-related medical query with real-time streaming response.
112
+
113
+ Recommended for frontend use - Provides better user experience by streaming
114
+ the response as it's generated, similar to ChatGPT.
115
+
116
+ Request Body:
117
+ - `query` (required): Your medical question about lung cancer
118
+ - `session_id` (required): Unique identifier to maintain conversation context
119
+
120
+ Response:
121
+ - Streaming text/markdown content
122
+ - Response is sent in chunks as it's generated
123
+ - Connection stays open until response is complete
124
 
125
+
126
+ Example Request:
127
+ {
128
+ "query": "Explain the difference between small cell and non-small cell lung cancer",
129
+ "session_id": "user_123_session_1699612345"
130
+ }
131
+
132
+ Frontend Integration Tips:
133
+ - Use the same `session_id` for follow-up questions to maintain context
134
+ - Display response in markdown renderer for better formatting
135
+ - Show loading state while waiting for response
136
+ - Render markdown progressively as chunks arrive
137
+ - Show typing indicator while streaming
138
+ - Handle 500 errors gracefully with user-friendly messages
139
+
140
  Args:
141
+ request: QueryRequest containing query and session_id
142
+
143
+ Returns:
144
+ StreamingResponse with text/markdown content
145
+
146
+ Raises:
147
+ HTTPException: 500 if query processing fails
148
  """
149
  async def event_stream():
150
  try:
151
  chunk_buffer = ""
152
+ async for chunk in safe_run_agent_streaming(user_input=request.query, session_id=request.session_id):
153
  chunk_buffer += chunk
154
 
155
  # Send chunks in reasonable sizes for smoother streaming
 
166
  yield f"Error: {str(e)}"
167
 
168
  return StreamingResponse(event_stream(), media_type="text/markdown")
169
+
170
+ # Dedent streaming endpoint docstring for proper Markdown rendering in docs
171
+ ask_stream.__doc__ = inspect.cleandoc(ask_stream.__doc__ or "")
app.py CHANGED
@@ -1,5 +1,5 @@
1
  """
2
- Startup script for Medical RAG AI Advisor API
3
  """
4
  import sys
5
  import os
 
1
  """
2
+ Startup script for Lung Cancer AI Advisor API
3
  """
4
  import sys
5
  import os
backup/backup_20251022_110950/chunks.pkl DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:b038845d797cac35024d39df8c7a861d741a1f7c2edc1a54286e17de1806b38e
3
- size 3878660
 
 
 
 
backup/backup_20251022_110950/vector_store/index.faiss DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:824156db2ada7613098cc7c9a8c27d66b33553885146fb6f66ab450ddc5d95cb
3
- size 8248365
 
 
 
 
backup/backup_20251022_110950/vector_store/index.pkl DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:2655709226a3c13f4dae2efc131aaee81f68ac696a9b9a7aa8daeabc026d40d4
3
- size 4020637
 
 
 
 
backup/backup_20251022_111044/chunks.pkl DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:b038845d797cac35024d39df8c7a861d741a1f7c2edc1a54286e17de1806b38e
3
- size 3878660
 
 
 
 
backup/backup_20251022_111044/vector_store/index.faiss DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:824156db2ada7613098cc7c9a8c27d66b33553885146fb6f66ab450ddc5d95cb
3
- size 8248365
 
 
 
 
backup/backup_20251022_111044/vector_store/index.pkl DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:2655709226a3c13f4dae2efc131aaee81f68ac696a9b9a7aa8daeabc026d40d4
3
- size 4020637
 
 
 
 
core/__pycache__/__init__.cpython-311.pyc CHANGED
Binary files a/core/__pycache__/__init__.cpython-311.pyc and b/core/__pycache__/__init__.cpython-311.pyc differ
 
core/__pycache__/__init__.cpython-313.pyc CHANGED
Binary files a/core/__pycache__/__init__.cpython-313.pyc and b/core/__pycache__/__init__.cpython-313.pyc differ
 
core/__pycache__/agent.cpython-311.pyc CHANGED
Binary files a/core/__pycache__/agent.cpython-311.pyc and b/core/__pycache__/agent.cpython-311.pyc differ
 
core/__pycache__/agent.cpython-313.pyc CHANGED
Binary files a/core/__pycache__/agent.cpython-313.pyc and b/core/__pycache__/agent.cpython-313.pyc differ
 
core/__pycache__/background_init.cpython-313.pyc CHANGED
Binary files a/core/__pycache__/background_init.cpython-313.pyc and b/core/__pycache__/background_init.cpython-313.pyc differ
 
core/__pycache__/config.cpython-311.pyc CHANGED
Binary files a/core/__pycache__/config.cpython-311.pyc and b/core/__pycache__/config.cpython-311.pyc differ
 
core/__pycache__/config.cpython-313.pyc CHANGED
Binary files a/core/__pycache__/config.cpython-313.pyc and b/core/__pycache__/config.cpython-313.pyc differ
 
core/__pycache__/data_loaders.cpython-313.pyc CHANGED
Binary files a/core/__pycache__/data_loaders.cpython-313.pyc and b/core/__pycache__/data_loaders.cpython-313.pyc differ
 
core/__pycache__/github_storage.cpython-313.pyc CHANGED
Binary files a/core/__pycache__/github_storage.cpython-313.pyc and b/core/__pycache__/github_storage.cpython-313.pyc differ
 
core/__pycache__/retrievers.cpython-313.pyc CHANGED
Binary files a/core/__pycache__/retrievers.cpython-313.pyc and b/core/__pycache__/retrievers.cpython-313.pyc differ
 
core/__pycache__/text_processors.cpython-313.pyc CHANGED
Binary files a/core/__pycache__/text_processors.cpython-313.pyc and b/core/__pycache__/text_processors.cpython-313.pyc differ
 
core/__pycache__/tools.cpython-313.pyc CHANGED
Binary files a/core/__pycache__/tools.cpython-313.pyc and b/core/__pycache__/tools.cpython-313.pyc differ
 
core/__pycache__/tracing.cpython-313.pyc CHANGED
Binary files a/core/__pycache__/tracing.cpython-313.pyc and b/core/__pycache__/tracing.cpython-313.pyc differ
 
core/__pycache__/utils.cpython-313.pyc CHANGED
Binary files a/core/__pycache__/utils.cpython-313.pyc and b/core/__pycache__/utils.cpython-313.pyc differ
 
core/__pycache__/validation.cpython-313.pyc CHANGED
Binary files a/core/__pycache__/validation.cpython-313.pyc and b/core/__pycache__/validation.cpython-313.pyc differ
 
core/agent.py CHANGED
@@ -4,6 +4,7 @@ from typing import Any, AsyncGenerator
4
  import asyncio
5
  import requests
6
  import os
 
7
  from langchain.agents import create_openai_tools_agent, AgentExecutor
8
  from langchain.memory import ConversationBufferWindowMemory
9
  from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
@@ -101,22 +102,30 @@ Your primary purpose is to provide evidence-based clinical guidance on lung canc
101
 
102
  **AUDIENCE**: Your responses are for thoracic oncologists, pulmonologists, and medical experts managing lung cancer. Use appropriate medical terminology, clinical precision, and expert-level detail specific to lung cancer management.
103
 
104
- **RESPONSE STYLE - CRITICAL: CONCISE, PRECISE, DOCTOR-SPECIFIC ANSWERS**:
105
  - **IMMEDIATE DIRECT ANSWERS**: Start immediately with the answer - NO introductory phrases like "I will retrieve...", "Let me search...", "Please hold on...", or status updates
106
  - **NO PREAMBLES**: Never announce what you're about to do - just do it and present the results directly
107
  - **ZERO PROCEDURAL STATEMENTS**: Do NOT write "I will retrieve", "I will search", "I will gather", "Please wait", "Hold on", or any similar phrases - START DIRECTLY WITH THE CLINICAL ANSWER
108
  - **FIRST WORD RULE**: Your response must begin with the actual answer content (e.g., a heading, clinical information, or direct statement) - never with a procedural announcement
109
- - **CONCISE & TARGETED**: Provide focused, actionable answers directly addressing the clinical question
110
- - **PRECISION OVER VOLUME**: Include only the most clinically relevant information - avoid unnecessary elaboration
 
 
 
 
 
 
 
 
111
  - **CLINICAL EFFICIENCY**: Respect physicians' time by delivering key information first, then supporting details
112
- - **STRUCTURED BREVITY**: Use clear hierarchical formatting (headers, bullet points) to enable rapid information scanning
113
- - **ESSENTIAL DETAILS ONLY**: Include specific clinical parameters, dosing, biomarkers, and monitoring when directly relevant to the query
114
  - **PRIORITIZED INFORMATION**: Lead with the most critical clinical decision points, contraindications, and evidence-based recommendations
115
  - **LUNG CANCER FOCUS**: Prioritize lung cancer-specific information including histology, molecular markers, staging, and treatment selection
116
- - Use precise medical terminology without oversimplification
117
- - Reference specific guideline sources (tables, figures, algorithms) with concise citations
118
- - Highlight critical nuances, contraindications, and special populations only when clinically significant
119
- - When multiple approaches exist, prioritize by evidence level and clinical context
120
  - **CONTEXT AWARENESS**: Use context pages to ensure accuracy, but synthesize information concisely
121
  - **DIRECT ANSWERS**: Answer the specific question asked without providing tangential information
122
 
@@ -129,6 +138,13 @@ Your primary purpose is to provide evidence-based clinical guidance on lung canc
129
  - Even for basic lung cancer concepts (e.g., "what is EGFR mutation", "ALK rearrangement", "PD-L1 expression"), you MUST retrieve information from the guidelines first
130
  - Only after retrieving guideline information should you formulate your answer based on what was retrieved
131
 
 
 
 
 
 
 
 
132
  **TOOL USAGE REQUIREMENTS:**
133
  1. **MEDICAL QUESTIONS** (definitions, treatments, guidelines, etc.):
134
  - MANDATORY: Use "medical_guidelines_knowledge_tool" FIRST
@@ -250,16 +266,19 @@ class SessionMemoryManager:
250
 
251
  def __init__(self):
252
  self._sessions = {}
253
- self._default_window_size = 10
254
 
255
  def get_memory(self, session_id: str = "default") -> ConversationBufferWindowMemory:
256
  """Get or create memory for a specific session."""
257
  if session_id not in self._sessions:
258
- self._sessions[session_id] = ConversationBufferWindowMemory(
259
- memory_key="chat_history",
260
- return_messages=True,
261
- max_window_size=self._default_window_size
262
- )
 
 
 
263
  return self._sessions[session_id]
264
 
265
  def clear_session(self, session_id: str) -> bool:
@@ -359,7 +378,7 @@ def _perform_automatic_validation(user_input: str, response: str) -> None:
359
  """
360
  try:
361
  # Import here to avoid circular imports
362
- from .tools import _last_question, _last_documents, _last_user_question
363
 
364
  # Check if we have the necessary context for validation
365
  if not _last_question or not _last_documents:
@@ -414,10 +433,6 @@ async def run_agent_streaming(user_input: str, session_id: str = "default", max_
414
  yield "Sorry, I didn't receive any questions. Please enter your question or request."
415
  return
416
 
417
- # Store the original user question for validation
418
- from .tools import store_user_question
419
- store_user_question(user_input.strip())
420
-
421
  retry_count = 0
422
  last_error = None
423
  current_run_id = None
@@ -545,13 +560,16 @@ async def run_agent_streaming(user_input: str, session_id: str = "default", max_
545
  yield "Sorry, the system is currently busy. Please try again in a little while."
546
  return
547
 
548
- except APIError as e:
549
  retry_count += 1
550
  last_error = e
551
- logger.error(f"OpenAI API error: {str(e)}")
 
552
 
553
  if retry_count <= max_retries:
554
- await asyncio.sleep(2)
 
 
555
  continue
556
  else:
557
  yield "Sorry, there was an error connecting to the service. Please try again later."
 
4
  import asyncio
5
  import requests
6
  import os
7
+ import httpx
8
  from langchain.agents import create_openai_tools_agent, AgentExecutor
9
  from langchain.memory import ConversationBufferWindowMemory
10
  from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
 
102
 
103
  **AUDIENCE**: Your responses are for thoracic oncologists, pulmonologists, and medical experts managing lung cancer. Use appropriate medical terminology, clinical precision, and expert-level detail specific to lung cancer management.
104
 
105
+ **RESPONSE STYLE - CRITICAL: CONCISE, ACCURATE, MEDIUM-LENGTH ANSWERS FOR MEDICAL EXPERTS**:
106
  - **IMMEDIATE DIRECT ANSWERS**: Start immediately with the answer - NO introductory phrases like "I will retrieve...", "Let me search...", "Please hold on...", or status updates
107
  - **NO PREAMBLES**: Never announce what you're about to do - just do it and present the results directly
108
  - **ZERO PROCEDURAL STATEMENTS**: Do NOT write "I will retrieve", "I will search", "I will gather", "Please wait", "Hold on", or any similar phrases - START DIRECTLY WITH THE CLINICAL ANSWER
109
  - **FIRST WORD RULE**: Your response must begin with the actual answer content (e.g., a heading, clinical information, or direct statement) - never with a procedural announcement
110
+
111
+ **RESPONSE LENGTH - MEDIUM AND BALANCED**:
112
+ - **NOT TOO LONG**: Avoid excessive detail, lengthy explanations, or exhaustive lists that overwhelm busy clinicians
113
+ - **NOT TOO SHORT**: Provide sufficient clinical context, key recommendations, and essential details for informed decision-making
114
+ - **MEDIUM LENGTH TARGET**: Aim for 200-400 words for standard queries; 400-600 words for complex multi-part questions
115
+ - **QUALITY OVER QUANTITY**: Every sentence must add clinical value - eliminate redundancy and filler content
116
+ - **CONCISE & COMPLETE**: Cover all essential aspects of the query without unnecessary elaboration
117
+
118
+ **EXPERT-TAILORED CONTENT**:
119
+ - **PRECISION & ACCURACY**: Provide exact, evidence-based information from guidelines - no speculation or general knowledge
120
  - **CLINICAL EFFICIENCY**: Respect physicians' time by delivering key information first, then supporting details
121
+ - **STRUCTURED CLARITY**: Use clear hierarchical formatting (headers, bullet points) to enable rapid information scanning
122
+ - **ESSENTIAL DETAILS**: Include specific clinical parameters, dosing, biomarkers, and monitoring when directly relevant to the query
123
  - **PRIORITIZED INFORMATION**: Lead with the most critical clinical decision points, contraindications, and evidence-based recommendations
124
  - **LUNG CANCER FOCUS**: Prioritize lung cancer-specific information including histology, molecular markers, staging, and treatment selection
125
+ - **MEDICAL TERMINOLOGY**: Use precise medical terminology appropriate for thoracic oncologists and pulmonologists
126
+ - **CONCISE CITATIONS**: Reference specific guideline sources (tables, figures, algorithms) with brief inline citations
127
+ - **CLINICALLY SIGNIFICANT NUANCES**: Highlight critical nuances, contraindications, and special populations only when clinically significant
128
+ - **EVIDENCE-BASED PRIORITIZATION**: When multiple approaches exist, prioritize by evidence level and clinical context
129
  - **CONTEXT AWARENESS**: Use context pages to ensure accuracy, but synthesize information concisely
130
  - **DIRECT ANSWERS**: Answer the specific question asked without providing tangential information
131
 
 
138
  - Even for basic lung cancer concepts (e.g., "what is EGFR mutation", "ALK rearrangement", "PD-L1 expression"), you MUST retrieve information from the guidelines first
139
  - Only after retrieving guideline information should you formulate your answer based on what was retrieved
140
 
141
+ **STRICT QUERY ADHERENCE - ALL PROVIDERS REQUIREMENT:**
142
+ - When the user explicitly requests information from "all guidelines", "all providers", "according to all guidelines", or similar phrasing, you MUST retrieve and present information from ALL available guideline providers (NCCN, ASCO, ESMO, NICE, Manus)
143
+ - Do NOT selectively omit providers - if the user asks for "all", you must query each provider separately and include ALL results
144
+ - Call the medical_guidelines_knowledge_tool multiple times (once per provider) when "all providers" is requested
145
+ - Present a comprehensive answer that includes recommendations from every available provider
146
+ - If a specific provider has no information on the topic, explicitly state that in your response
147
+
148
  **TOOL USAGE REQUIREMENTS:**
149
  1. **MEDICAL QUESTIONS** (definitions, treatments, guidelines, etc.):
150
  - MANDATORY: Use "medical_guidelines_knowledge_tool" FIRST
 
266
 
267
  def __init__(self):
268
  self._sessions = {}
269
+ self._default_window_size = 20 # Increased from 10 to maintain better context
270
 
271
  def get_memory(self, session_id: str = "default") -> ConversationBufferWindowMemory:
272
  """Get or create memory for a specific session."""
273
  if session_id not in self._sessions:
274
+ import warnings
275
+ with warnings.catch_warnings():
276
+ warnings.filterwarnings("ignore", category=DeprecationWarning)
277
+ self._sessions[session_id] = ConversationBufferWindowMemory(
278
+ memory_key="chat_history",
279
+ return_messages=True,
280
+ max_window_size=self._default_window_size
281
+ )
282
  return self._sessions[session_id]
283
 
284
  def clear_session(self, session_id: str) -> bool:
 
378
  """
379
  try:
380
  # Import here to avoid circular imports
381
+ from .tools import _last_question, _last_documents
382
 
383
  # Check if we have the necessary context for validation
384
  if not _last_question or not _last_documents:
 
433
  yield "Sorry, I didn't receive any questions. Please enter your question or request."
434
  return
435
 
 
 
 
 
436
  retry_count = 0
437
  last_error = None
438
  current_run_id = None
 
560
  yield "Sorry, the system is currently busy. Please try again in a little while."
561
  return
562
 
563
+ except (APIError, httpx.RemoteProtocolError, httpx.ReadError, httpx.ConnectError) as e:
564
  retry_count += 1
565
  last_error = e
566
+ error_type = type(e).__name__
567
+ logger.error(f"OpenAI API/Connection error ({error_type}): {str(e)}")
568
 
569
  if retry_count <= max_retries:
570
+ wait_time = min(2 ** retry_count, 10) # Exponential backoff, max 10 seconds
571
+ logger.info(f"Retrying after {wait_time} seconds... (Attempt {retry_count}/{max_retries})")
572
+ await asyncio.sleep(wait_time)
573
  continue
574
  else:
575
  yield "Sorry, there was an error connecting to the service. Please try again later."
core/context_enrichment.py CHANGED
@@ -25,6 +25,7 @@ class ContextEnricher:
25
  """
26
  self._document_cache: Dict[str, List[Document]] = {}
27
  self._cache_size = cache_size
 
28
 
29
  def enrich_documents(
30
  self,
@@ -187,8 +188,13 @@ class ContextEnricher:
187
  try:
188
  from . import utils
189
 
190
- # Load all chunks
191
- all_chunks = utils.load_chunks()
 
 
 
 
 
192
  if not all_chunks:
193
  logger.debug(f"No chunks available for enrichment")
194
  return None
 
25
  """
26
  self._document_cache: Dict[str, List[Document]] = {}
27
  self._cache_size = cache_size
28
+ self._all_chunks_cache: Optional[List[Document]] = None # Cache all chunks to avoid reloading
29
 
30
  def enrich_documents(
31
  self,
 
188
  try:
189
  from . import utils
190
 
191
+ # Load all chunks (use cached version to avoid redundant loading)
192
+ if self._all_chunks_cache is None:
193
+ self._all_chunks_cache = utils.load_chunks()
194
+ if self._all_chunks_cache:
195
+ logger.debug(f"Loaded {len(self._all_chunks_cache)} chunks into enricher cache")
196
+
197
+ all_chunks = self._all_chunks_cache
198
  if not all_chunks:
199
  logger.debug(f"No chunks available for enrichment")
200
  return None