VibecoderMcSwaggins commited on
Commit
0efdc2f
·
1 Parent(s): f1e4e5b

feat(examples): add Phase 6-8 demos for full stack demonstration

Browse files

- Add embeddings_demo: semantic search & deduplication (no API keys)
- Add hypothesis_demo: mechanistic reasoning (requires LLM)
- Add full_stack_demo: complete pipeline with mock and real modes
- Update examples README with comprehensive documentation

Examples demonstrate:
- Text embedding with sentence-transformers
- ChromaDB vector storage and similarity search
- Semantic deduplication by meaning
- Drug -> Target -> Pathway -> Effect hypothesis generation
- Structured scientific report generation

examples/README.md CHANGED
@@ -1,28 +1,181 @@
1
- # Examples
2
 
3
- Demo scripts for DeepCritical functionality.
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
  ## 1. Search Demo (Phase 2)
6
 
7
- Demonstrates parallel search across PubMed and Web. **No API keys required.**
8
 
9
  ```bash
10
  uv run python examples/search_demo/run_search.py "metformin cancer"
11
  ```
12
 
 
 
 
 
 
 
 
 
13
  ## 2. Agent Demo (Phase 4)
14
 
15
- Demonstrates the full search-judge-synthesize loop.
16
 
17
- **Option A: Mock Mode (No Keys)**
18
- Test the logic/mechanics without an LLM.
19
  ```bash
20
  uv run python examples/orchestrator_demo/run_agent.py "metformin cancer" --mock
21
  ```
22
 
23
- **Option B: Real Mode (Requires Keys)**
24
- Uses the real LLM Judge to evaluate evidence.
25
- Requires `OPENAI_API_KEY` or `ANTHROPIC_API_KEY` in `.env`.
26
  ```bash
27
  uv run python examples/orchestrator_demo/run_agent.py "metformin cancer"
28
- ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # DeepCritical Examples
2
 
3
+ Demo scripts demonstrating each phase of the drug repurposing research agent.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ # Run without API keys (mock modes available)
9
+ uv run python examples/embeddings_demo/run_embeddings.py
10
+ uv run python examples/full_stack_demo/run_full.py --mock
11
+
12
+ # Run with API keys (set OPENAI_API_KEY or ANTHROPIC_API_KEY)
13
+ uv run python examples/full_stack_demo/run_full.py "metformin cancer"
14
+ ```
15
+
16
+ ---
17
 
18
  ## 1. Search Demo (Phase 2)
19
 
20
+ Demonstrates parallel search across PubMed and Web sources. **No API keys required.**
21
 
22
  ```bash
23
  uv run python examples/search_demo/run_search.py "metformin cancer"
24
  ```
25
 
26
+ **What it shows:**
27
+ - PubMed E-utilities search
28
+ - DuckDuckGo web search
29
+ - Scatter-gather orchestration
30
+ - Evidence model with citations
31
+
32
+ ---
33
+
34
  ## 2. Agent Demo (Phase 4)
35
 
36
+ Demonstrates the search-judge-synthesize loop.
37
 
38
+ **Mock Mode (No API Keys):**
 
39
  ```bash
40
  uv run python examples/orchestrator_demo/run_agent.py "metformin cancer" --mock
41
  ```
42
 
43
+ **Real Mode (Requires API Keys):**
 
 
44
  ```bash
45
  uv run python examples/orchestrator_demo/run_agent.py "metformin cancer"
46
+ ```
47
+
48
+ **What it shows:**
49
+ - Iterative search refinement
50
+ - LLM-based evidence assessment
51
+ - Synthesis generation
52
+ - Event streaming for UI updates
53
+
54
+ ---
55
+
56
+ ## 3. Magentic Demo (Phase 5)
57
+
58
+ Demonstrates multi-agent coordination using Microsoft Agent Framework.
59
+
60
+ ```bash
61
+ # Requires OPENAI_API_KEY (Magentic uses OpenAI)
62
+ uv run python examples/orchestrator_demo/run_magentic.py "metformin cancer"
63
+ ```
64
+
65
+ **What it shows:**
66
+ - MagenticBuilder workflow
67
+ - SearchAgent, JudgeAgent, HypothesisAgent, ReportAgent coordination
68
+ - Manager-based orchestration
69
+
70
+ ---
71
+
72
+ ## 4. Embeddings Demo (Phase 6)
73
+
74
+ Demonstrates semantic search and deduplication. **No API keys required.**
75
+
76
+ ```bash
77
+ uv run python examples/embeddings_demo/run_embeddings.py
78
+ ```
79
+
80
+ **What it shows:**
81
+ - Text embedding with sentence-transformers
82
+ - ChromaDB vector storage
83
+ - Semantic similarity search
84
+ - Duplicate detection by meaning (not just URL)
85
+ - Cosine similarity calculations
86
+
87
+ ---
88
+
89
+ ## 5. Hypothesis Demo (Phase 7)
90
+
91
+ Demonstrates mechanistic hypothesis generation.
92
+
93
+ ```bash
94
+ # Requires OPENAI_API_KEY or ANTHROPIC_API_KEY
95
+ uv run python examples/hypothesis_demo/run_hypothesis.py "metformin Alzheimer's"
96
+ uv run python examples/hypothesis_demo/run_hypothesis.py "sildenafil heart failure"
97
+ ```
98
+
99
+ **What it shows:**
100
+ - Drug -> Target -> Pathway -> Effect reasoning
101
+ - Knowledge gap identification
102
+ - Search query suggestions for targeted research
103
+ - Confidence scoring
104
+
105
+ ---
106
+
107
+ ## 6. Full Stack Demo (Phases 1-8)
108
+
109
+ **The complete pipeline** - demonstrates all phases working together.
110
+
111
+ **Mock Mode (No API Keys):**
112
+ ```bash
113
+ uv run python examples/full_stack_demo/run_full.py --mock
114
+ ```
115
+
116
+ **Real Mode:**
117
+ ```bash
118
+ uv run python examples/full_stack_demo/run_full.py "metformin Alzheimer's"
119
+ uv run python examples/full_stack_demo/run_full.py "sildenafil heart failure" -i 3
120
+ ```
121
+
122
+ **What it shows:**
123
+ 1. **Search** - PubMed + Web evidence collection
124
+ 2. **Embeddings** - Semantic deduplication
125
+ 3. **Hypothesis** - Mechanistic reasoning
126
+ 4. **Judge** - Evidence quality assessment
127
+ 5. **Report** - Structured scientific report generation
128
+
129
+ Output includes a publication-quality research report with:
130
+ - Executive summary
131
+ - Methodology
132
+ - Hypotheses tested (with support/contradict counts)
133
+ - Mechanistic and clinical findings
134
+ - Drug candidates
135
+ - Limitations
136
+ - Formatted references
137
+
138
+ ---
139
+
140
+ ## API Keys
141
+
142
+ | Example | Required Keys |
143
+ |---------|--------------|
144
+ | search_demo | None (optional NCBI_API_KEY for higher rate limits) |
145
+ | orchestrator_demo --mock | None |
146
+ | orchestrator_demo | OPENAI_API_KEY or ANTHROPIC_API_KEY |
147
+ | run_magentic | OPENAI_API_KEY |
148
+ | embeddings_demo | None |
149
+ | hypothesis_demo | OPENAI_API_KEY or ANTHROPIC_API_KEY |
150
+ | full_stack_demo --mock | None |
151
+ | full_stack_demo | OPENAI_API_KEY or ANTHROPIC_API_KEY |
152
+
153
+ ---
154
+
155
+ ## Architecture Overview
156
+
157
+ ```
158
+ User Query
159
+ |
160
+ v
161
+ [Phase 2: Search] --> PubMed + Web
162
+ |
163
+ v
164
+ [Phase 6: Embeddings] --> Semantic Deduplication
165
+ |
166
+ v
167
+ [Phase 7: Hypothesis] --> Drug -> Target -> Pathway -> Effect
168
+ |
169
+ v
170
+ [Phase 3: Judge] --> "Is evidence sufficient?"
171
+ |
172
+ +---> NO --> Refine queries, loop back to Search
173
+ |
174
+ +---> YES --> Continue to Report
175
+ |
176
+ v
177
+ [Phase 8: Report] --> Structured Scientific Report
178
+ |
179
+ v
180
+ Final Output with Citations
181
+ ```
examples/embeddings_demo/run_embeddings.py ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Demo: Semantic Search & Deduplication (Phase 6).
4
+
5
+ This script demonstrates embedding-based capabilities:
6
+ - Text embedding with sentence-transformers
7
+ - Semantic similarity search via ChromaDB
8
+ - Duplicate detection by meaning (not just URL)
9
+
10
+ Usage:
11
+ uv run python examples/embeddings_demo/run_embeddings.py
12
+
13
+ No API keys required - uses local sentence-transformers model.
14
+ """
15
+
16
+ import asyncio
17
+
18
+ from src.services.embeddings import EmbeddingService
19
+ from src.utils.models import Citation, Evidence
20
+
21
+
22
+ def create_sample_evidence() -> list[Evidence]:
23
+ """Create sample evidence with some semantic duplicates."""
24
+ return [
25
+ Evidence(
26
+ content="Metformin activates AMPK which inhibits mTOR signaling pathway.",
27
+ citation=Citation(
28
+ source="pubmed",
29
+ title="Metformin and AMPK activation",
30
+ url="https://pubmed.ncbi.nlm.nih.gov/11111/",
31
+ date="2023",
32
+ authors=["Smith J"],
33
+ ),
34
+ ),
35
+ Evidence(
36
+ content="The drug metformin works by turning on AMPK, blocking the mTOR pathway.",
37
+ citation=Citation(
38
+ source="pubmed",
39
+ title="AMPK-mTOR axis in diabetes treatment",
40
+ url="https://pubmed.ncbi.nlm.nih.gov/22222/",
41
+ date="2022",
42
+ authors=["Jones A"],
43
+ ),
44
+ ),
45
+ Evidence(
46
+ content="Sildenafil increases nitric oxide signaling for vasodilation.",
47
+ citation=Citation(
48
+ source="web",
49
+ title="How Viagra Works",
50
+ url="https://example.com/viagra-mechanism",
51
+ date="2023",
52
+ authors=["WebMD"],
53
+ ),
54
+ ),
55
+ Evidence(
56
+ content="Clinical trials show metformin reduces cancer incidence in diabetic patients.",
57
+ citation=Citation(
58
+ source="pubmed",
59
+ title="Metformin and cancer prevention",
60
+ url="https://pubmed.ncbi.nlm.nih.gov/33333/",
61
+ date="2024",
62
+ authors=["Lee K", "Park S"],
63
+ ),
64
+ ),
65
+ Evidence(
66
+ content="Metformin inhibits mTOR through AMPK activation mechanism.",
67
+ citation=Citation(
68
+ source="pubmed",
69
+ title="mTOR inhibition by Metformin",
70
+ url="https://pubmed.ncbi.nlm.nih.gov/44444/",
71
+ date="2023",
72
+ authors=["Brown M"],
73
+ ),
74
+ ),
75
+ ]
76
+
77
+
78
+ def create_fresh_service(name_suffix: str = "") -> EmbeddingService:
79
+ """Create a fresh embedding service with unique collection name."""
80
+ import uuid
81
+
82
+ # Create service with unique collection by modifying the internal collection
83
+ service = EmbeddingService.__new__(EmbeddingService)
84
+ service._model = __import__("sentence_transformers").SentenceTransformer("all-MiniLM-L6-v2")
85
+ service._client = __import__("chromadb").Client()
86
+ collection_name = f"demo_{name_suffix}_{uuid.uuid4().hex[:8]}"
87
+ service._collection = service._client.create_collection(
88
+ name=collection_name, metadata={"hnsw:space": "cosine"}
89
+ )
90
+ return service
91
+
92
+
93
+ async def demo_embedding() -> None:
94
+ """Demo single text embedding."""
95
+ print("\n" + "=" * 60)
96
+ print("1. TEXT EMBEDDING DEMO")
97
+ print("=" * 60)
98
+
99
+ service = create_fresh_service("embed")
100
+
101
+ texts = [
102
+ "Metformin activates AMPK",
103
+ "Aspirin reduces inflammation",
104
+ "Metformin turns on the AMPK enzyme",
105
+ ]
106
+
107
+ print("\nEmbedding sample texts...")
108
+ embeddings = await service.embed_batch(texts)
109
+
110
+ for text, emb in zip(texts, embeddings, strict=False):
111
+ print(f" '{text[:40]}...' -> [{emb[0]:.4f}, {emb[1]:.4f}, ... ] (dim={len(emb)})")
112
+
113
+ # Calculate similarity between text 0 and text 2 (semantically similar)
114
+ import numpy as np
115
+
116
+ sim_0_2 = np.dot(embeddings[0], embeddings[2]) / (
117
+ np.linalg.norm(embeddings[0]) * np.linalg.norm(embeddings[2])
118
+ )
119
+ sim_0_1 = np.dot(embeddings[0], embeddings[1]) / (
120
+ np.linalg.norm(embeddings[0]) * np.linalg.norm(embeddings[1])
121
+ )
122
+
123
+ print(f"\nSimilarity (Metformin AMPK) vs (Metformin turns on AMPK): {sim_0_2:.3f}")
124
+ print(f"Similarity (Metformin AMPK) vs (Aspirin inflammation): {sim_0_1:.3f}")
125
+ print(" -> Semantically similar texts have higher cosine similarity!")
126
+
127
+
128
+ async def demo_semantic_search() -> None:
129
+ """Demo semantic similarity search."""
130
+ print("\n" + "=" * 60)
131
+ print("2. SEMANTIC SEARCH DEMO")
132
+ print("=" * 60)
133
+
134
+ service = create_fresh_service("search")
135
+
136
+ # Add some documents to the vector store
137
+ docs = [
138
+ ("doc1", "Metformin activates AMPK enzyme in liver cells", {"source": "pubmed"}),
139
+ ("doc2", "Aspirin inhibits COX-2 to reduce inflammation", {"source": "pubmed"}),
140
+ ("doc3", "Statins lower cholesterol by inhibiting HMG-CoA reductase", {"source": "web"}),
141
+ ("doc4", "AMPK activation leads to improved glucose metabolism", {"source": "pubmed"}),
142
+ ("doc5", "Sildenafil works via nitric oxide pathway", {"source": "web"}),
143
+ ]
144
+
145
+ print("\nIndexing documents...")
146
+ for doc_id, content, meta in docs:
147
+ await service.add_evidence(doc_id, content, meta)
148
+ print(f" Added: {doc_id}")
149
+
150
+ # Search for semantically related content
151
+ query = "drugs that activate AMPK"
152
+ print(f"\nSearching for: '{query}'")
153
+
154
+ results = await service.search_similar(query, n_results=3)
155
+
156
+ print("\nTop 3 results:")
157
+ for i, r in enumerate(results, 1):
158
+ # Lower distance = more similar (cosine distance: 0=identical, 2=opposite)
159
+ similarity = 1 - r["distance"]
160
+ print(f" {i}. [{similarity:.2%} similar] {r['content'][:60]}...")
161
+
162
+
163
+ async def demo_deduplication() -> None:
164
+ """Demo semantic deduplication."""
165
+ print("\n" + "=" * 60)
166
+ print("3. SEMANTIC DEDUPLICATION DEMO")
167
+ print("=" * 60)
168
+
169
+ # Create fresh service for clean demo
170
+ service = create_fresh_service("dedup")
171
+
172
+ evidence = create_sample_evidence()
173
+ print(f"\nOriginal evidence count: {len(evidence)}")
174
+ for i, e in enumerate(evidence, 1):
175
+ print(f" {i}. {e.citation.title}")
176
+
177
+ print("\nRunning semantic deduplication (threshold=0.85)...")
178
+ unique = await service.deduplicate(evidence, threshold=0.85)
179
+
180
+ print(f"\nUnique evidence count: {len(unique)}")
181
+ print(f"Removed {len(evidence) - len(unique)} semantic duplicates\n")
182
+
183
+ for i, e in enumerate(unique, 1):
184
+ print(f" {i}. {e.citation.title}")
185
+
186
+ print("\n -> Notice: Papers about 'Metformin AMPK mTOR' were deduplicated!")
187
+ print(" Different titles, same semantic meaning = duplicate removed.")
188
+
189
+
190
+ async def main() -> None:
191
+ """Run all embedding demos."""
192
+ print("\n" + "=" * 60)
193
+ print("DeepCritical Embeddings Demo (Phase 6)")
194
+ print("Using: sentence-transformers + ChromaDB")
195
+ print("=" * 60)
196
+
197
+ await demo_embedding()
198
+ await demo_semantic_search()
199
+ await demo_deduplication()
200
+
201
+ print("\n" + "=" * 60)
202
+ print("Demo complete! Embeddings enable:")
203
+ print(" - Finding papers by MEANING, not just keywords")
204
+ print(" - Removing duplicate findings automatically")
205
+ print(" - Building diverse evidence sets for research")
206
+ print("=" * 60 + "\n")
207
+
208
+
209
+ if __name__ == "__main__":
210
+ asyncio.run(main())
examples/full_stack_demo/run_full.py ADDED
@@ -0,0 +1,456 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Demo: Full Stack DeepCritical Agent (Phases 1-8).
4
+
5
+ This script demonstrates the COMPLETE drug repurposing research pipeline:
6
+ - Phase 2: Search (PubMed + Web)
7
+ - Phase 6: Embeddings (Semantic deduplication)
8
+ - Phase 7: Hypothesis (Mechanistic reasoning)
9
+ - Phase 3: Judge (Evidence assessment)
10
+ - Phase 8: Report (Structured scientific report)
11
+
12
+ Usage:
13
+ # Full demo with real searches and LLM (requires API keys)
14
+ uv run python examples/full_stack_demo/run_full.py "metformin Alzheimer's"
15
+
16
+ # Mock mode - demonstrates pipeline without API calls
17
+ uv run python examples/full_stack_demo/run_full.py --mock
18
+
19
+ # With specific iterations
20
+ uv run python examples/full_stack_demo/run_full.py "sildenafil heart failure" --iterations 2
21
+ """
22
+
23
+ import argparse
24
+ import asyncio
25
+ import os
26
+ import sys
27
+ from typing import Any
28
+
29
+ from src.utils.models import Citation, Evidence, MechanismHypothesis
30
+
31
+
32
+ def print_header(title: str) -> None:
33
+ """Print a formatted section header."""
34
+ print(f"\n{'='*70}")
35
+ print(f" {title}")
36
+ print(f"{'='*70}\n")
37
+
38
+
39
+ def print_step(step: int, name: str) -> None:
40
+ """Print a step indicator."""
41
+ print(f"\n[Step {step}] {name}")
42
+ print("-" * 50)
43
+
44
+
45
+ def create_mock_evidence() -> list[Evidence]:
46
+ """Create comprehensive mock evidence for demo without API calls."""
47
+ return [
48
+ Evidence(
49
+ content=(
50
+ "Metformin, a first-line treatment for type 2 diabetes, activates "
51
+ "AMP-activated protein kinase (AMPK). AMPK is a master metabolic "
52
+ "regulator that inhibits mTOR signaling, reducing protein synthesis "
53
+ "and cell proliferation. This mechanism has implications beyond "
54
+ "glucose control."
55
+ ),
56
+ citation=Citation(
57
+ source="pubmed",
58
+ title="Metformin activates AMPK through LKB1-dependent mechanisms",
59
+ url="https://pubmed.ncbi.nlm.nih.gov/19001324/",
60
+ date="2023-06",
61
+ authors=["Zhang L", "Wang H", "Chen Y"],
62
+ ),
63
+ ),
64
+ Evidence(
65
+ content=(
66
+ "In transgenic mouse models of Alzheimer's disease, metformin treatment "
67
+ "reduced tau phosphorylation by 45% and decreased amyloid-beta plaque "
68
+ "formation. Treated mice showed improved performance on Morris water "
69
+ "maze tests, suggesting preserved spatial memory."
70
+ ),
71
+ citation=Citation(
72
+ source="pubmed",
73
+ title="Metformin ameliorates tau pathology in AD mouse models",
74
+ url="https://pubmed.ncbi.nlm.nih.gov/31256789/",
75
+ date="2024-01",
76
+ authors=["Kim J", "Lee S", "Park M", "Tanaka K"],
77
+ ),
78
+ ),
79
+ Evidence(
80
+ content=(
81
+ "A population-based cohort study of 100,000 diabetic patients found "
82
+ "that metformin users had 35% lower risk of developing Alzheimer's "
83
+ "disease compared to sulfonylurea users (HR=0.65, 95% CI: 0.58-0.73). "
84
+ "The protective effect increased with duration of use."
85
+ ),
86
+ citation=Citation(
87
+ source="pubmed",
88
+ title="Metformin and dementia risk: UK Biobank analysis",
89
+ url="https://pubmed.ncbi.nlm.nih.gov/34567890/",
90
+ date="2023-09",
91
+ authors=["Smith A", "Johnson B", "Williams C"],
92
+ ),
93
+ ),
94
+ Evidence(
95
+ content=(
96
+ "mTOR hyperactivation is observed in Alzheimer's disease brain tissue. "
97
+ "mTOR inhibition by rapamycin or metformin promotes autophagy, which "
98
+ "clears misfolded proteins including tau and amyloid-beta aggregates. "
99
+ "This suggests a common therapeutic pathway."
100
+ ),
101
+ citation=Citation(
102
+ source="pubmed",
103
+ title="mTOR-autophagy axis in neurodegeneration",
104
+ url="https://pubmed.ncbi.nlm.nih.gov/32109876/",
105
+ date="2023-03",
106
+ authors=["Brown C", "Davis D", "Miller E"],
107
+ ),
108
+ ),
109
+ Evidence(
110
+ content=(
111
+ "Metformin crosses the blood-brain barrier via organic cation "
112
+ "transporters (OCT1, OCT2). CSF concentrations reach approximately "
113
+ "1-2% of plasma levels, sufficient for AMPK activation in neurons. "
114
+ "Brain accumulation is observed in hippocampus and prefrontal cortex."
115
+ ),
116
+ citation=Citation(
117
+ source="pubmed",
118
+ title="Brain pharmacokinetics of metformin in humans",
119
+ url="https://pubmed.ncbi.nlm.nih.gov/35678901/",
120
+ date="2024-02",
121
+ authors=["Wilson E", "Garcia F"],
122
+ ),
123
+ ),
124
+ Evidence(
125
+ content=(
126
+ "Phase 2 clinical trial (NCT04098666) showed metformin 2000mg/day "
127
+ "for 12 months slowed cognitive decline by 18% compared to placebo "
128
+ "in patients with mild cognitive impairment. Biomarker analysis "
129
+ "showed reduced CSF tau levels in the treatment group."
130
+ ),
131
+ citation=Citation(
132
+ source="web",
133
+ title="Metformin for Alzheimer's prevention trial results",
134
+ url="https://clinicaltrials.gov/ct2/show/NCT04098666",
135
+ date="2024-03",
136
+ authors=["NIH Clinical Center"],
137
+ ),
138
+ ),
139
+ ]
140
+
141
+
142
+ def create_mock_hypotheses() -> list[MechanismHypothesis]:
143
+ """Create mock hypotheses for demonstration."""
144
+ return [
145
+ MechanismHypothesis(
146
+ drug="Metformin",
147
+ target="AMPK",
148
+ pathway="mTOR inhibition -> Autophagy activation",
149
+ effect="Clearance of tau and amyloid-beta aggregates",
150
+ confidence=0.85,
151
+ supporting_evidence=[
152
+ "https://pubmed.ncbi.nlm.nih.gov/19001324/",
153
+ "https://pubmed.ncbi.nlm.nih.gov/32109876/",
154
+ ],
155
+ contradicting_evidence=[],
156
+ search_suggestions=[
157
+ "AMPK autophagy neurodegeneration",
158
+ "metformin tau clearance",
159
+ ],
160
+ ),
161
+ MechanismHypothesis(
162
+ drug="Metformin",
163
+ target="Glucose metabolism",
164
+ pathway="Improved neuronal energy homeostasis",
165
+ effect="Reduced oxidative stress and neuroinflammation",
166
+ confidence=0.70,
167
+ supporting_evidence=["https://pubmed.ncbi.nlm.nih.gov/31256789/"],
168
+ contradicting_evidence=[],
169
+ search_suggestions=[
170
+ "metformin brain glucose metabolism",
171
+ "neuronal insulin resistance alzheimer",
172
+ ],
173
+ ),
174
+ ]
175
+
176
+
177
+ async def run_mock_demo() -> None:
178
+ """Run full pipeline with mock data (no API keys needed)."""
179
+ print_header("DeepCritical Full Stack Demo (MOCK MODE)")
180
+ print("Running with synthetic data - no API keys required.\n")
181
+
182
+ evidence = create_mock_evidence()
183
+ hypotheses = create_mock_hypotheses()
184
+
185
+ # Step 1: Show evidence
186
+ print_step(1, "SEARCH (Phase 2) - Evidence Collection")
187
+ print(f"Collected {len(evidence)} pieces of evidence:\n")
188
+ for i, e in enumerate(evidence, 1):
189
+ print(f" [{i}] {e.citation.source.upper()}: {e.citation.title[:50]}...")
190
+ print(f" {e.content[:80]}...")
191
+ print()
192
+
193
+ # Step 2: Embedding deduplication
194
+ print_step(2, "EMBEDDINGS (Phase 6) - Semantic Deduplication")
195
+ try:
196
+ from src.services.embeddings import EmbeddingService
197
+
198
+ service = EmbeddingService()
199
+ unique = await service.deduplicate(evidence, threshold=0.85)
200
+ print(f"Original: {len(evidence)} papers")
201
+ print(f"After deduplication: {len(unique)} unique papers")
202
+ print("(Semantic duplicates removed by meaning, not just URL)")
203
+ except ImportError:
204
+ print("Embedding dependencies not installed - skipping deduplication")
205
+ unique = evidence
206
+
207
+ # Step 3: Hypothesis generation
208
+ print_step(3, "HYPOTHESIS (Phase 7) - Mechanistic Reasoning")
209
+ print(f"Generated {len(hypotheses)} hypotheses:\n")
210
+ for i, h in enumerate(hypotheses, 1):
211
+ print(f" Hypothesis {i} (Confidence: {h.confidence:.0%})")
212
+ print(f" {h.drug} -> {h.target} -> {h.pathway} -> {h.effect}")
213
+ print(f" Suggested searches: {', '.join(h.search_suggestions)}")
214
+ print()
215
+
216
+ # Step 4: Judge assessment
217
+ print_step(4, "JUDGE (Phase 3) - Evidence Assessment")
218
+ print("Assessment Results:")
219
+ print(" Mechanism Score: 8/10 (Strong mechanistic evidence)")
220
+ print(" Clinical Score: 7/10 (Phase 2 trial + observational data)")
221
+ print(" Confidence: 75%")
222
+ print(" Recommendation: SYNTHESIZE (Evidence sufficient)")
223
+ print()
224
+
225
+ # Step 5: Report generation
226
+ print_step(5, "REPORT (Phase 8) - Structured Scientific Report")
227
+
228
+ report = f"""
229
+ # Drug Repurposing Analysis: Metformin for Alzheimer's Disease
230
+
231
+ ## Executive Summary
232
+ This analysis evaluated metformin as a potential therapeutic for Alzheimer's
233
+ disease. Evidence from {len(unique)} sources supports a plausible mechanism
234
+ through AMPK activation and mTOR inhibition, leading to enhanced autophagy
235
+ and clearance of pathological protein aggregates. Clinical data shows
236
+ promising risk reduction in observational studies and early trial results.
237
+
238
+ ## Research Question
239
+ Can metformin, a type 2 diabetes medication, be repurposed for the prevention
240
+ or treatment of Alzheimer's disease?
241
+
242
+ ## Methodology
243
+ - Searched PubMed and web sources for "metformin Alzheimer's disease"
244
+ - Applied semantic deduplication to remove redundant findings
245
+ - Generated mechanistic hypotheses using LLM reasoning
246
+ - Evaluated evidence quality with structured assessment
247
+
248
+ ## Hypotheses Tested
249
+ - **Metformin -> AMPK -> mTOR inhibition -> Neuroprotection** (SUPPORTED)
250
+ - 4 supporting papers, 0 contradicting
251
+ - **Metformin -> Glucose metabolism -> Reduced oxidative stress** (PARTIAL)
252
+ - 2 supporting papers, requires more investigation
253
+
254
+ ## Mechanistic Findings
255
+ Strong evidence supports AMPK activation as the primary mechanism. Metformin
256
+ crosses the blood-brain barrier and achieves therapeutic concentrations in
257
+ hippocampus and cortex. Downstream effects include:
258
+ - mTOR inhibition
259
+ - Autophagy activation
260
+ - Tau dephosphorylation
261
+ - Amyloid-beta clearance
262
+
263
+ ## Clinical Findings
264
+ - Observational: 35% risk reduction (HR=0.65, n=100,000)
265
+ - Preclinical: 45% reduction in tau phosphorylation in AD mice
266
+ - Phase 2 trial: 18% slower cognitive decline vs placebo
267
+
268
+ ## Drug Candidates
269
+ - **Metformin** - Primary candidate with established safety profile
270
+
271
+ ## Limitations
272
+ - Abstract-level analysis only
273
+ - Observational data subject to confounding
274
+ - Limited RCT data available
275
+ - Optimal dosing for neuroprotection unclear
276
+
277
+ ## Conclusion
278
+ Metformin shows strong potential for Alzheimer's disease prevention/treatment.
279
+ The AMPK-mTOR-autophagy mechanism is well-supported. Recommend Phase 3 trials
280
+ with cognitive endpoints.
281
+
282
+ ## References
283
+ """
284
+ max_authors_display = 2
285
+ for i, e in enumerate(unique[:6], 1):
286
+ authors = ", ".join(e.citation.authors[:max_authors_display])
287
+ if len(e.citation.authors) > max_authors_display:
288
+ authors += " et al."
289
+ ref_line = (
290
+ f"{i}. {authors}. *{e.citation.title}*. "
291
+ f"{e.citation.source.upper()} ({e.citation.date}). "
292
+ f"[Link]({e.citation.url})"
293
+ )
294
+ report += ref_line + "\n"
295
+
296
+ report += f"""
297
+ ---
298
+ *Report generated from {len(unique)} papers across 3 search iterations.
299
+ Confidence: 75%*
300
+ """
301
+
302
+ print(report)
303
+
304
+
305
+ async def _run_search_iteration(
306
+ query: str,
307
+ iteration: int,
308
+ evidence_store: dict[str, Any],
309
+ all_evidence: list[Evidence],
310
+ search_handler: Any,
311
+ embedding_service: Any,
312
+ ) -> list[Evidence]:
313
+ """Run a single search iteration with deduplication."""
314
+ search_queries = [query]
315
+ if evidence_store.get("hypotheses"):
316
+ for h in evidence_store["hypotheses"][-2:]:
317
+ search_queries.extend(h.search_suggestions[:1])
318
+
319
+ for q in search_queries[:2]:
320
+ result = await search_handler.execute(q, max_results_per_tool=5)
321
+ print(f" '{q}' -> {result.total_found} results")
322
+ new_unique = await embedding_service.deduplicate(result.evidence)
323
+ print(f" After dedup: {len(new_unique)} unique")
324
+ all_evidence.extend(new_unique)
325
+
326
+ evidence_store["current"] = all_evidence
327
+ evidence_store["iteration_count"] = iteration
328
+ return all_evidence
329
+
330
+
331
+ async def run_real_demo(query: str, max_iterations: int) -> None:
332
+ """Run full pipeline with real API calls."""
333
+ print_header("DeepCritical Full Stack Demo")
334
+ print(f"Query: {query}")
335
+ print(f"Max iterations: {max_iterations}")
336
+ print("Mode: REAL (Live API calls)\n")
337
+
338
+ # Import real components
339
+ from src.agent_factory.judges import JudgeHandler
340
+ from src.agents.hypothesis_agent import HypothesisAgent
341
+ from src.agents.report_agent import ReportAgent
342
+ from src.services.embeddings import EmbeddingService
343
+ from src.tools.pubmed import PubMedTool
344
+ from src.tools.search_handler import SearchHandler
345
+ from src.tools.websearch import WebTool
346
+
347
+ # Initialize services
348
+ embedding_service = EmbeddingService()
349
+ search_handler = SearchHandler(tools=[PubMedTool(), WebTool()], timeout=30.0)
350
+ judge_handler = JudgeHandler()
351
+
352
+ # Shared evidence store
353
+ evidence_store: dict[str, Any] = {"current": [], "hypotheses": [], "iteration_count": 0}
354
+ all_evidence: list[Evidence] = []
355
+
356
+ for iteration in range(1, max_iterations + 1):
357
+ print_step(iteration, f"ITERATION {iteration}/{max_iterations}")
358
+
359
+ # Step 1: Search
360
+ print("\n[Search] Querying PubMed and Web...")
361
+ all_evidence = await _run_search_iteration(
362
+ query, iteration, evidence_store, all_evidence, search_handler, embedding_service
363
+ )
364
+
365
+ # Step 2: Generate hypotheses (first iteration only)
366
+ if iteration == 1:
367
+ print("\n[Hypothesis] Generating mechanistic hypotheses...")
368
+ hypothesis_agent = HypothesisAgent(evidence_store, embedding_service)
369
+ hyp_response = await hypothesis_agent.run(query)
370
+ print(hyp_response.messages[0].text[:500] + "...")
371
+
372
+ # Step 3: Judge
373
+ print("\n[Judge] Assessing evidence quality...")
374
+ assessment = await judge_handler.assess(query, all_evidence)
375
+ print(f" Mechanism: {assessment.details.mechanism_score}/10")
376
+ print(f" Clinical: {assessment.details.clinical_evidence_score}/10")
377
+ print(f" Recommendation: {assessment.recommendation}")
378
+
379
+ if assessment.recommendation == "synthesize":
380
+ print("\n[Judge says] Evidence sufficient! Generating report...")
381
+ evidence_store["last_assessment"] = assessment.details.model_dump()
382
+ break
383
+
384
+ next_queries = assessment.next_search_queries[:2]
385
+ print(f"\n[Judge says] Need more evidence. Next queries: {next_queries}")
386
+ query = assessment.next_search_queries[0] if assessment.next_search_queries else query
387
+
388
+ # Step 4: Generate report
389
+ print_step(iteration + 1, "REPORT GENERATION")
390
+ report_agent = ReportAgent(evidence_store, embedding_service)
391
+ report_response = await report_agent.run(query)
392
+
393
+ print("\n" + "=" * 70)
394
+ print("FINAL RESEARCH REPORT")
395
+ print("=" * 70)
396
+ print(report_response.messages[0].text)
397
+
398
+
399
+ async def main() -> None:
400
+ """Entry point."""
401
+ parser = argparse.ArgumentParser(
402
+ description="DeepCritical Full Stack Demo (Phases 1-8)",
403
+ formatter_class=argparse.RawDescriptionHelpFormatter,
404
+ epilog="""
405
+ Examples:
406
+ # Mock mode (no API keys)
407
+ uv run python examples/full_stack_demo/run_full.py --mock
408
+
409
+ # Real mode with metformin query
410
+ uv run python examples/full_stack_demo/run_full.py "metformin alzheimer"
411
+
412
+ # Sildenafil for heart failure
413
+ uv run python examples/full_stack_demo/run_full.py "sildenafil heart failure" -i 3
414
+ """,
415
+ )
416
+ parser.add_argument(
417
+ "query",
418
+ nargs="?",
419
+ default="metformin Alzheimer's disease",
420
+ help="Research query",
421
+ )
422
+ parser.add_argument(
423
+ "--mock",
424
+ action="store_true",
425
+ help="Run with mock data (no API keys needed)",
426
+ )
427
+ parser.add_argument(
428
+ "-i",
429
+ "--iterations",
430
+ type=int,
431
+ default=2,
432
+ help="Max search iterations (default: 2)",
433
+ )
434
+
435
+ args = parser.parse_args()
436
+
437
+ if args.mock:
438
+ await run_mock_demo()
439
+ else:
440
+ # Check for API keys
441
+ if not (os.getenv("OPENAI_API_KEY") or os.getenv("ANTHROPIC_API_KEY")):
442
+ print("Error: Real mode requires OPENAI_API_KEY or ANTHROPIC_API_KEY")
443
+ print("Use --mock for demo without API keys.")
444
+ sys.exit(1)
445
+
446
+ await run_real_demo(args.query, args.iterations)
447
+
448
+ print("\n" + "=" * 70)
449
+ print(" DeepCritical Full Stack Demo Complete!")
450
+ print(" Phases demonstrated: Foundation -> Search -> Judge -> UI ->")
451
+ print(" Magentic -> Embeddings -> Hypothesis -> Report")
452
+ print("=" * 70 + "\n")
453
+
454
+
455
+ if __name__ == "__main__":
456
+ asyncio.run(main())
examples/hypothesis_demo/run_hypothesis.py ADDED
@@ -0,0 +1,223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Demo: Hypothesis Generation (Phase 7).
4
+
5
+ This script demonstrates mechanistic hypothesis generation:
6
+ - Drug -> Target -> Pathway -> Effect reasoning
7
+ - Knowledge gap identification
8
+ - Search query suggestions for targeted research
9
+
10
+ Usage:
11
+ # Requires OPENAI_API_KEY or ANTHROPIC_API_KEY
12
+ uv run python examples/hypothesis_demo/run_hypothesis.py
13
+
14
+ # With custom drug query
15
+ uv run python examples/hypothesis_demo/run_hypothesis.py "aspirin heart disease"
16
+ """
17
+
18
+ import argparse
19
+ import asyncio
20
+ import os
21
+ import sys
22
+ from typing import Any
23
+
24
+ from src.agents.hypothesis_agent import HypothesisAgent
25
+ from src.utils.models import Citation, Evidence
26
+
27
+
28
+ def create_metformin_evidence() -> list[Evidence]:
29
+ """Create sample evidence about metformin for hypothesis generation."""
30
+ return [
31
+ Evidence(
32
+ content=(
33
+ "Metformin activates AMP-activated protein kinase (AMPK), a master regulator "
34
+ "of cellular energy homeostasis. AMPK activation leads to inhibition of mTOR "
35
+ "signaling, reducing protein synthesis and cell proliferation."
36
+ ),
37
+ citation=Citation(
38
+ source="pubmed",
39
+ title="Metformin and AMPK: mechanisms of action",
40
+ url="https://pubmed.ncbi.nlm.nih.gov/12345/",
41
+ date="2023",
42
+ authors=["Zhang L", "Wang H"],
43
+ ),
44
+ ),
45
+ Evidence(
46
+ content=(
47
+ "In Alzheimer's disease models, AMPK activation by metformin reduced tau "
48
+ "phosphorylation and amyloid-beta accumulation. These effects correlated "
49
+ "with improved cognitive function in transgenic mice."
50
+ ),
51
+ citation=Citation(
52
+ source="pubmed",
53
+ title="Metformin neuroprotective effects in AD models",
54
+ url="https://pubmed.ncbi.nlm.nih.gov/23456/",
55
+ date="2024",
56
+ authors=["Kim J", "Lee S", "Park M"],
57
+ ),
58
+ ),
59
+ Evidence(
60
+ content=(
61
+ "Clinical observational studies show diabetic patients on metformin have "
62
+ "30-40% reduced incidence of Alzheimer's disease compared to those on "
63
+ "other diabetes medications."
64
+ ),
65
+ citation=Citation(
66
+ source="pubmed",
67
+ title="Metformin use and dementia risk: population study",
68
+ url="https://pubmed.ncbi.nlm.nih.gov/34567/",
69
+ date="2023",
70
+ authors=["Smith A", "Johnson B"],
71
+ ),
72
+ ),
73
+ Evidence(
74
+ content=(
75
+ "mTOR inhibition has emerged as a key therapeutic target in neurodegenerative "
76
+ "diseases. Rapamycin and metformin both reduce mTOR activity, though through "
77
+ "different upstream mechanisms."
78
+ ),
79
+ citation=Citation(
80
+ source="pubmed",
81
+ title="mTOR pathway in neurodegeneration",
82
+ url="https://pubmed.ncbi.nlm.nih.gov/45678/",
83
+ date="2022",
84
+ authors=["Brown C", "Davis D"],
85
+ ),
86
+ ),
87
+ Evidence(
88
+ content=(
89
+ "Metformin crosses the blood-brain barrier and accumulates in the hippocampus "
90
+ "and cortex. Brain concentrations sufficient for AMPK activation are achieved "
91
+ "at standard diabetic doses."
92
+ ),
93
+ citation=Citation(
94
+ source="pubmed",
95
+ title="Pharmacokinetics of metformin in brain tissue",
96
+ url="https://pubmed.ncbi.nlm.nih.gov/56789/",
97
+ date="2023",
98
+ authors=["Wilson E"],
99
+ ),
100
+ ),
101
+ ]
102
+
103
+
104
+ def create_sildenafil_evidence() -> list[Evidence]:
105
+ """Create sample evidence about sildenafil (Viagra) for hypothesis generation."""
106
+ return [
107
+ Evidence(
108
+ content=(
109
+ "Sildenafil inhibits phosphodiesterase type 5 (PDE5), preventing breakdown "
110
+ "of cGMP. Elevated cGMP causes smooth muscle relaxation and vasodilation "
111
+ "in pulmonary vasculature."
112
+ ),
113
+ citation=Citation(
114
+ source="pubmed",
115
+ title="PDE5 inhibition mechanism of sildenafil",
116
+ url="https://pubmed.ncbi.nlm.nih.gov/67890/",
117
+ date="2022",
118
+ authors=["Miller F"],
119
+ ),
120
+ ),
121
+ Evidence(
122
+ content=(
123
+ "In pulmonary arterial hypertension (PAH), sildenafil reduces pulmonary "
124
+ "vascular resistance and improves exercise capacity. FDA approved for PAH "
125
+ "under brand name Revatio."
126
+ ),
127
+ citation=Citation(
128
+ source="pubmed",
129
+ title="Sildenafil in pulmonary hypertension treatment",
130
+ url="https://pubmed.ncbi.nlm.nih.gov/78901/",
131
+ date="2023",
132
+ authors=["Garcia R", "Martinez L"],
133
+ ),
134
+ ),
135
+ Evidence(
136
+ content=(
137
+ "PDE5 is expressed in cardiac myocytes. Sildenafil has shown cardioprotective "
138
+ "effects in animal models of heart failure by enhancing nitric oxide-cGMP "
139
+ "signaling in the myocardium."
140
+ ),
141
+ citation=Citation(
142
+ source="pubmed",
143
+ title="Cardiac effects of PDE5 inhibition",
144
+ url="https://pubmed.ncbi.nlm.nih.gov/89012/",
145
+ date="2024",
146
+ authors=["Thompson K"],
147
+ ),
148
+ ),
149
+ ]
150
+
151
+
152
+ async def run_hypothesis_demo(query: str) -> None:
153
+ """Run the hypothesis generation demo."""
154
+ print(f"\n{'='*60}")
155
+ print("DeepCritical Hypothesis Agent Demo (Phase 7)")
156
+ print(f"Query: {query}")
157
+ print(f"{'='*60}\n")
158
+
159
+ # Select appropriate evidence based on query
160
+ if "sildenafil" in query.lower() or "viagra" in query.lower():
161
+ evidence = create_sildenafil_evidence()
162
+ print("Using: Sildenafil evidence set (3 papers)")
163
+ else:
164
+ evidence = create_metformin_evidence()
165
+ print("Using: Metformin evidence set (5 papers)")
166
+
167
+ # Create evidence store (shared context between agents)
168
+ evidence_store: dict[str, Any] = {"current": evidence, "hypotheses": []}
169
+
170
+ # Create hypothesis agent
171
+ agent = HypothesisAgent(evidence_store)
172
+
173
+ print("\nGenerating mechanistic hypotheses...\n")
174
+ print("-" * 60)
175
+
176
+ # Run hypothesis generation
177
+ response = await agent.run(query)
178
+
179
+ # Print the formatted response
180
+ print(response.messages[0].text)
181
+
182
+ print("-" * 60)
183
+
184
+ # Show stored hypotheses
185
+ hypotheses = evidence_store.get("hypotheses", [])
186
+ print(f"\n{len(hypotheses)} hypotheses stored in evidence_store")
187
+
188
+ if hypotheses:
189
+ print("\nHypothesis search queries generated:")
190
+ for h in hypotheses:
191
+ queries = h.to_search_queries()
192
+ print(f" - {h.drug} -> {h.target}: {queries[:2]}")
193
+
194
+
195
+ async def main() -> None:
196
+ """Run the demo."""
197
+ parser = argparse.ArgumentParser(description="Hypothesis Generation Demo")
198
+ parser.add_argument(
199
+ "query",
200
+ nargs="?",
201
+ default="metformin Alzheimer's disease",
202
+ help="Research query (default: 'metformin Alzheimer\\'s disease')",
203
+ )
204
+ args = parser.parse_args()
205
+
206
+ # Check for API key
207
+ if not (os.getenv("OPENAI_API_KEY") or os.getenv("ANTHROPIC_API_KEY")):
208
+ print("Error: Hypothesis generation requires an LLM.")
209
+ print("Set OPENAI_API_KEY or ANTHROPIC_API_KEY in your environment.")
210
+ sys.exit(1)
211
+
212
+ await run_hypothesis_demo(args.query)
213
+
214
+ print("\n" + "=" * 60)
215
+ print("Demo complete! The Hypothesis Agent:")
216
+ print(" - Analyzes evidence to find Drug -> Target -> Pathway -> Effect chains")
217
+ print(" - Identifies knowledge gaps in current evidence")
218
+ print(" - Suggests targeted search queries to test hypotheses")
219
+ print("=" * 60 + "\n")
220
+
221
+
222
+ if __name__ == "__main__":
223
+ asyncio.run(main())