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
77 changes: 77 additions & 0 deletions ai-research-assistant-suite/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# πŸ§ͺ AI-Powered Research Assistant Suite

> **Multi-Disciplinary Intelligent Research Co-Pilot for SCIBASE.AI**
> **Target Algora Bounty:** Issue [#16](https://github.com/SCIBASE-AI/SCIBASE.AI/issues/16) (`$1,350.00 USD`)
> **Claimant:** `@techsp13` (`0x01E7862BEd361b72784c0819AD68548D85A9ad49`)

---

## πŸŽ₯ Demo Video & Animation

![AI Research Assistant Suite Demo](./reports/demo.gif)

*Full high-definition video artifact is available at [`reports/demo.mp4`](./reports/demo.mp4).*

---

## πŸš€ Overview

The **AI-Powered Research Assistant Suite** augments scientific workflows with automated peer review validation, reproducibility sandboxing, and corpus-level research gap discovery.

```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ AI RESEARCH ASSISTANT SUITE ARCHITECTURE β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 1. Auto Peer Review Engine β”‚ Clarity analysis, p-hacking red flags, domain rules β”‚
β”‚ 2. Reproducibility Sandbox β”‚ Output delta verification, dependency check, scoring β”‚
β”‚ 3. Research Gap Discovery β”‚ Multi-topic intersection mapping & opportunity feeds β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```

---

## 🧩 Core Modules

### 1. Auto Peer Review Reports (`peer_review_engine.py`)
- Evaluates clarity, abstract sizing, and structural completeness.
- Detects statistical red flags: claims of significance without sample size ($N$) or exact p-values.
- Verifies domain-specific checklists:
- **Molecular Biology:** Controls, accession IDs, replicate sizing.
- **Quantum Physics:** System Hamiltonian, coherence fidelity, calibration.
- **Clinical Trials:** Double-blind protocols, IRB approval, placebo controls.
- **Computer Science:** Hardware specs, baseline comparisons, random seed repeatability.

### 2. Reproducibility Checker (`reproducibility_checker.py`)
- Sandboxes execution and verifies output consistency against baseline metrics.
- Detects missing or mismatched library dependencies.
- Assigns a deterministic **Reproducibility Confidence Score** (0 - 100).

### 3. Research Gap Finder (`research_gap_finder.py`)
- Identifies under-studied intersections (e.g., `"CRISPR + Alzheimer's + single-cell RNA-seq"`).
- Analyzes publication counts, replication ratios, and unresolved questions.
- Generates personalized research opportunity feeds tailored to researcher interests and lab equipment.

---

## πŸ§ͺ Running Unit Tests

Execute the test suite with standard Python `unittest`:

```bash
python -m unittest ai-research-assistant-suite.test_assistant_suite
```

Output:
```text
Ran 8 tests in 0.003s β€” OK (100% Passing)
```

---

## 🎬 Generating Demo Video & GIF

To regenerate the demo video and animated GIF:

```bash
python ai-research-assistant-suite/render_demo_video.py
```
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
73 changes: 73 additions & 0 deletions ai-research-assistant-suite/assistant_suite.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# SPDX-License-Identifier: MIT
"""
Unified AI Research Assistant Suite Orchestrator.
Exposes peer review, reproducibility verification, and research gap discovery.
"""

from typing import Dict, Any, List, Optional
from .types import (
ScientificDomain,
PeerReviewReport,
ReproducibilityReport,
ResearchOpportunityFeed,
)
from .peer_review_engine import PeerReviewEngine
from .reproducibility_checker import ReproducibilityChecker
from .research_gap_finder import ResearchGapFinder


class AIResearchAssistantSuite:
"""Master suite providing end-to-end intelligent research co-pilot capabilities."""

def __init__(self):
self.peer_reviewer = PeerReviewEngine()
self.reproducibility_checker = ReproducibilityChecker()
self.gap_finder = ResearchGapFinder()

def run_auto_peer_review(
self,
title: str,
abstract: str,
methods: str,
results: str,
domain: ScientificDomain = ScientificDomain.GENERAL_SCIENCE,
citations: Optional[List[str]] = None,
) -> PeerReviewReport:
return self.peer_reviewer.evaluate_manuscript(
title=title,
abstract=abstract,
methods=methods,
results=results,
domain=domain,
citations=citations or [],
)

def verify_reproducibility(
self,
project_id: str,
project_name: str,
manifest_dependencies: Dict[str, str],
installed_dependencies: Dict[str, str],
files: List[str],
execution_results: Optional[List[Dict[str, Any]]] = None,
) -> ReproducibilityReport:
return self.reproducibility_checker.verify_project(
project_id=project_id,
project_name=project_name,
manifest_dependencies=manifest_dependencies,
installed_dependencies=installed_dependencies,
files=files,
execution_results=execution_results or [],
)

def discover_research_gaps(
self,
user_id: str,
user_interests: List[str],
lab_capabilities: List[str],
) -> ResearchOpportunityFeed:
return self.gap_finder.generate_user_opportunity_feed(
user_id=user_id,
user_interests=user_interests,
lab_capabilities=lab_capabilities,
)
207 changes: 207 additions & 0 deletions ai-research-assistant-suite/peer_review_engine.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
# SPDX-License-Identifier: MIT
"""
Auto Peer Review Report Generation Engine.
Performs deterministic structural and methodological manuscript evaluation.
"""

import re
import uuid
from typing import Dict, Any, List
from .types import (
ScientificDomain,
ReviewFlag,
ReviewCategory,
ReviewSeverity,
PeerReviewReport,
Recommendation,
)


class PeerReviewEngine:
"""Automated reviewer providing editorial and methodological feedback."""

def __init__(self):
self._domain_validators = {
ScientificDomain.MOLECULAR_BIOLOGY: self._validate_molecular_biology,
ScientificDomain.QUANTUM_PHYSICS: self._validate_quantum_physics,
ScientificDomain.CLINICAL_TRIALS: self._validate_clinical_trials,
ScientificDomain.COMPUTER_SCIENCE: self._validate_computer_science,
ScientificDomain.GENERAL_SCIENCE: self._validate_general_science,
}

def evaluate_manuscript(
self,
title: str,
abstract: str,
methods: str,
results: str,
domain: ScientificDomain = ScientificDomain.GENERAL_SCIENCE,
citations: List[str] = None,
) -> PeerReviewReport:
citations = citations or []
flags: List[ReviewFlag] = []
strengths: List[str] = []
weaknesses: List[str] = []

# 1. Clarity and Structure Analysis
if len(abstract.strip().split()) < 50:
flags.append(
ReviewFlag(
category=ReviewCategory.CLARITY,
severity=ReviewSeverity.MEDIUM,
message="Abstract is too brief (< 50 words) to convey complete scientific scope.",
suggestion="Expand abstract with background, methodology, quantitative findings, and conclusion.",
location="Abstract",
)
)
else:
strengths.append("Comprehensive abstract articulating research problem and summary.")

# 2. Statistical and Methodological Red Flags
full_text = f"{methods} {results}".lower()

# Check for statistical significance claims without sample size / p-values
if "significant" in full_text and not re.search(r"p\s*<\s*0\.\d+|p\s*=\s*0\.\d+", full_text):
flags.append(
ReviewFlag(
category=ReviewCategory.STATISTICAL,
severity=ReviewSeverity.HIGH,
message="Claims statistical significance without reporting exact p-values or confidence intervals.",
suggestion="Report exact p-values, degrees of freedom, and 95% confidence intervals.",
location="Results",
)
)

if "sample size" not in full_text and "n =" not in full_text and "n=" not in full_text:
flags.append(
ReviewFlag(
category=ReviewCategory.METHODOLOGY,
severity=ReviewSeverity.HIGH,
message="Sample size (N) is not explicitly defined in the methodology.",
suggestion="Explicitly state cohort/sample size (N) and statistical power calculations.",
location="Methods",
)
)
else:
strengths.append("Sample sizing and cohort parameters are clearly documented.")

# 3. Claims vs. Evidence Alignment
if "proves" in full_text or "undeniably" in full_text:
flags.append(
ReviewFlag(
category=ReviewCategory.CLAIM_EVIDENCE,
severity=ReviewSeverity.MEDIUM,
message="Overly definitive terminology ('proves', 'undeniably') found in empirical context.",
suggestion="Use rigorous hedging (e.g. 'demonstrates', 'strongly indicates', 'supports the hypothesis').",
location="Discussion/Results",
)
)

# 4. Citation and Scope Integrity
if len(citations) < 5:
flags.append(
ReviewFlag(
category=ReviewCategory.CITATION,
severity=ReviewSeverity.MEDIUM,
message=f"Sparse reference list ({len(citations)} citations). Prior art coverage may be insufficient.",
suggestion="Broaden literature review to include recent domain benchmarks and baseline studies.",
location="References",
)
)
else:
strengths.append(f"Solid literature grounding with {len(citations)} cited peer references.")

# 5. Domain-Adaptive Verification
validator = self._domain_validators.get(domain, self._validate_general_science)
domain_checks = validator(methods, results)

for check_name, passed in domain_checks.items():
if not passed:
flags.append(
ReviewFlag(
category=ReviewCategory.METHODOLOGY,
severity=ReviewSeverity.HIGH,
message=f"Domain requirement unsatisfied: {check_name.replace('_', ' ')}.",
suggestion=f"Provide documentation and verification for {check_name.replace('_', ' ')}.",
location=f"Domain Checks ({domain.value})",
)
)

# Calculate Overall Score and Recommendation
base_score = 100.0
for f in flags:
if f.severity == ReviewSeverity.CRITICAL:
base_score -= 30.0
elif f.severity == ReviewSeverity.HIGH:
base_score -= 15.0
elif f.severity == ReviewSeverity.MEDIUM:
base_score -= 8.0
else:
base_score -= 3.0

overall_score = max(0.0, min(100.0, round(base_score, 1)))

if overall_score >= 85.0:
recommendation = Recommendation.ACCEPT
elif overall_score >= 70.0:
recommendation = Recommendation.MINOR_REVISION
elif overall_score >= 50.0:
recommendation = Recommendation.MAJOR_REVISION
else:
recommendation = Recommendation.REJECT

if flags:
weaknesses.extend([f.message for f in flags[:3]])

return PeerReviewReport(
id=f"rev_{uuid.uuid4().hex[:8]}",
manuscript_title=title,
domain=domain,
overall_score=overall_score,
recommendation=recommendation,
flags=flags,
strengths=strengths,
weaknesses=weaknesses,
domain_specific_checks=domain_checks,
)

# ── Domain-Specific Rule Validators ───────────────────────────────────

def _validate_molecular_biology(self, methods: str, results: str) -> Dict[str, bool]:
text = f"{methods} {results}".lower()
return {
"negative_and_positive_controls": "control" in text or "vehicle" in text,
"accession_or_sequence_ids": bool(re.search(r"ncbi|genbank|uniprot|pdb|geo", text)),
"replicate_counts_defined": bool(re.search(r"triplicate|replicates|n\s*=\s*\d+", text)),
}

def _validate_quantum_physics(self, methods: str, results: str) -> Dict[str, bool]:
text = f"{methods} {results}".lower()
return {
"hamiltonian_or_operator_formulation": "hamiltonian" in text or "operator" in text or "state" in text,
"coherence_or_fidelity_metrics": "fidelity" in text or "coherence" in text or "t1" in text or "t2" in text,
"error_mitigation_documented": "error" in text or "noise" in text or "calibration" in text,
}

def _validate_clinical_trials(self, methods: str, results: str) -> Dict[str, bool]:
text = f"{methods} {results}".lower()
return {
"randomized_controlled_protocol": "random" in text or "rct" in text or "double-blind" in text,
"ethics_irb_approval": "irb" in text or "ethics" in text or "institutional review" in text or "consent" in text,
"placebo_or_standard_of_care": "placebo" in text or "standard of care" in text or "control group" in text,
}

def _validate_computer_science(self, methods: str, results: str) -> Dict[str, bool]:
text = f"{methods} {results}".lower()
return {
"hardware_and_runtime_specs": "gpu" in text or "cpu" in text or "ram" in text or "runtime" in text,
"baseline_comparisons": "baseline" in text or "state-of-the-art" in text or "sota" in text or "benchmark" in text,
"random_seed_reproducibility": "seed" in text or "deterministic" in text or "epochs" in text,
}

def _validate_general_science(self, methods: str, results: str) -> Dict[str, bool]:
text = f"{methods} {results}".lower()
return {
"methodology_described": len(methods.strip()) > 100,
"data_availability_statement": "data available" in text or "repository" in text or "supplementary" in text,
}
Loading