Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions VECTRA/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
PINECONE_API_KEY=pcsk_57FuYE_GKRroZMBbMYXg7XPuBY9edzbojk4pYWr6tEnfYDhdipupy9wzzw1eQ45bktMYoS
PINECONE_ENV=gcp-starter
OPENAI_API_KEY=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
PINECONE_INDEX_NAME=vectra-health
4 changes: 4 additions & 0 deletions VECTRA/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
PINECONE_API_KEY=pcsk_57FuYE_GKRroZMBbMYXg7XPuBY9edzbojk4pYWr6tEnfYDhdipupy9wzzw1eQ45bktMYoS
PINECONE_ENV=gcp-starter
OPENAI_API_KEY=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
PINECONE_INDEX_NAME=vectra-health
50 changes: 50 additions & 0 deletions VECTRA/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# VECTRA: Agentic Healthcare AI

VECTRA is an advanced multi-agent disease prediction system that combines robust Machine Learning with Semantic Search and Large Language Models (RAG).

## Features
- **Hybrid Reasoning**: Uses Random Forest for high-confidence predictions and LLM+RAG for complex cases.
- **Multi-Agent Architecture**: Specialized agents for Perception, Reasoning, Decision, Retrieval, and Safety.
- **Explainable AI**: Provides clear explanations for every diagnosis.
- **Safety First**: Integrated medical disclaimers and guardrails.

## Setup

1. **Install Dependencies**
```bash
pip install -r requirements.txt
```

2. **Configuration**
Copy `.env.example` to `.env` and fill in your API keys:
```bash
cp .env.example .env
```

3. **Data & Training**
Build the knowledge base and train the model:
```bash
python knowledge_base/build_kb.py
python vector_store/indexer.py # Requires valid Pinecone Key
python models/train.py
```

4. **Run Server**
```bash
uvicorn api.vectra_api:app --reload
```

5. **Run Frontend**
(Requires React setup - instructions generic)
The `ui/frontend` folder contains the source components.

## API Usage
POST `/predict`
```json
{
"symptoms": ["fever", "cough", "fatigue"]
}
```

## Disclaimer
This system is for educational purposes only. Please consult a licensed medical professional.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
9 changes: 9 additions & 0 deletions VECTRA/agents/decision_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class DecisionAgent:
def decide_route(self, confidence, threshold=0.6):
"""
Decides whether to route to ML Direct or RAG fallback.
"""
if confidence >= threshold:
return "ML_DIRECT"
else:
return "RAG_FALLBACK"
9 changes: 9 additions & 0 deletions VECTRA/agents/explanation_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class ExplanationAgent:
def format_explanation(self, disease, confidence, symptoms):
return (
f"Based on the symptoms provided ({', '.join(symptoms)}), "
f"there is a {confidence*100:.1f}% probability of {disease}."
)

def format_rag_explanation(self, llm_response):
return llm_response
16 changes: 16 additions & 0 deletions VECTRA/agents/perception_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class PerceptionAgent:
def process_input(self, raw_symptoms):
"""
Parses and cleans input symptoms.
Args:
raw_symptoms (list or str): User input.
Returns:
list: Cleaned list of symptoms.
"""
if isinstance(raw_symptoms, str):
symptoms = raw_symptoms.split(",")
else:
symptoms = raw_symptoms

cleaned = [s.strip() for s in symptoms if s.strip()]
return cleaned
8 changes: 8 additions & 0 deletions VECTRA/agents/reasoning_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class ReasoningAgent:
def analyze(self, symptoms):
"""
Enhances user symptoms if needed, checks for contradictions.
For V1, primarily passes symptoms through.
"""
# Future: Ontology mapping or symptom expansion
return symptoms
21 changes: 21 additions & 0 deletions VECTRA/agents/retrieval_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import sys
import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from vector_store.retriever import Retriever

class RetrievalAgent:
def __init__(self):
self.retriever = Retriever()

def fetch_context(self, symptoms):
query = ", ".join(symptoms)
# Setup for RAG: retrieve documents related to the symptoms
results = self.retriever.retrieve(query, top_k=3)

docs = []
for match in results:
if 'metadata' in match:
docs.append(match['metadata'].get('text', ''))

return docs
10 changes: 10 additions & 0 deletions VECTRA/agents/safety_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class SafetyAgent:
DISCLAIMER = "This system is for educational purposes only. Please consult a licensed medical professional."

def check_safety(self, text):
# Placeholder for PII or harmful content check
return True

def attach_disclaimer(self, response_dict):
response_dict["disclaimer"] = self.DISCLAIMER
return response_dict
Binary file added VECTRA/api/__pycache__/vectra_api.cpython-314.pyc
Binary file not shown.
91 changes: 91 additions & 0 deletions VECTRA/api/vectra_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Optional
import sys
import os

# Add project root to path
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from models.inference import InferenceEngine
from agents.perception_agent import PerceptionAgent
from agents.reasoning_agent import ReasoningAgent
from agents.decision_agent import DecisionAgent
from agents.retrieval_agent import RetrievalAgent
from agents.explanation_agent import ExplanationAgent
from agents.safety_agent import SafetyAgent
from rag.rag_pipeline import RAGPipeline

app = FastAPI(title="VECTRA API")

# Initialize Agents
perception = PerceptionAgent()
reasoning = ReasoningAgent()
decision = DecisionAgent()
retrieval = RetrievalAgent()
explanation = ExplanationAgent()
safety = SafetyAgent()
rag = RAGPipeline()
inference = InferenceEngine()

class SymptomRequest(BaseModel):
symptoms: List[str]

class PredictionResponse(BaseModel):
top_5_predictions: List[tuple]
confidence: float
used_llm: bool
explanation: str
sources: List[str]
disclaimer: str

@app.post("/predict", response_model=PredictionResponse)
def predict(request: SymptomRequest):
# 1. Perception
clean_symptoms = perception.process_input(request.symptoms)

# 2. Reasoning
analyzed_symptoms = reasoning.analyze(clean_symptoms)

# 3. Model Inference (Always run to get confidence)
ml_result = inference.predict(analyzed_symptoms)
confidence = ml_result["confidence"]
top_5 = ml_result["top_5"]

# 4. Decision
route = decision.decide_route(confidence)

used_llm = False
final_explanation = ""
sources = []

if route == "ML_DIRECT":
top_disease = top_5[0][0]
final_explanation = explanation.format_explanation(top_disease, confidence, analyzed_symptoms)
used_llm = False
else:
# Fallback to RAG
docs = retrieval.fetch_context(analyzed_symptoms)
sources = docs # For display purposes

# Generator
llm_response = rag.generate_diagnosis(analyzed_symptoms, docs)
final_explanation = explanation.format_rag_explanation(llm_response)
used_llm = True

# 5. Safety
response_data = {
"top_5_predictions": top_5,
"confidence": confidence,
"used_llm": used_llm,
"explanation": final_explanation,
"sources": sources
}

safe_response = safety.attach_disclaimer(response_data)

return safe_response

@app.get("/")
def health_check():
return {"status": "VECTRA System Ready"}
Binary file not shown.
24 changes: 24 additions & 0 deletions VECTRA/config/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import os
from dotenv import load_dotenv

# 🔑 Explicitly point to .env in project root
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
ENV_PATH = os.path.join(BASE_DIR, ".env")

load_dotenv(dotenv_path=ENV_PATH)

class Settings:
PINECONE_API_KEY = os.getenv("PINECONE_API_KEY")
PINECONE_INDEX_NAME = os.getenv("PINECONE_INDEX_NAME", "vectra-health")
PINECONE_HOST = os.getenv("PINECONE_HOST")
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")

# Paths
BASE_DIR = BASE_DIR
DATA_DIR = os.path.join(BASE_DIR, "data")
MODEL_PATH = os.path.join(BASE_DIR, "models", "symptom_model.pkl")

# 🔍 TEMP DEBUG
print("DEBUG | PINECONE_API_KEY:", PINECONE_API_KEY)

settings = Settings()
5 changes: 5 additions & 0 deletions VECTRA/custom_test_pinecone.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
try:
from pinecone import Pinecone
print("SUCCESS: Pinecone imported successfully.")
except Exception as e:
print(f"FAILURE: {e}")
Loading