Spaces:
Sleeping
Sleeping
File size: 19,478 Bytes
9b96c37 1361cf1 9b96c37 1361cf1 9b96c37 ff07764 9b96c37 1361cf1 ff07764 1361cf1 9b96c37 1361cf1 9b96c37 1361cf1 9b96c37 1361cf1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 | """
DVNC.AI β root app.py
Fixed: all internal module imports now use correct underscore names
matching the actual function/constant names in dvnc_ai_v2_hf/.
"""
# ββ Standard library ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
import html
import random
import re
import sys
from pathlib import Path
from typing import Dict, List, Optional
# Ensure the repository root is on sys.path so the package is importable
ROOT = Path(__file__).resolve().parent
if str(ROOT) not in sys.path:
sys.path.insert(0, str(ROOT))
# ββ Third-party βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
import gradio as gr
# ββ Internal modules ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
from dvnc_ai_v2_hf.agent_route_cards import build_agent_route_cards_html
from dvnc_ai_v2_hf.discovery_app_bridge import (
get_default_route_state,
get_discovery_css,
get_initial_discovery_timeline_html,
)
from dvnc_ai_v2_hf.dvnc_ui_layout import get_dvnc_layout_css
from dvnc_ai_v2_hf.graph_canvas_patch import render_graph_canvas_html
from dvnc_ai_v2_hf.self_learning_graph import (
DEFAULT_SOURCES,
SEARCH_MODES,
SOURCE_OPTIONS,
build_journal_html,
ingest_selected_papers,
parse_uploaded_pdf,
render_parse_result,
run_paper_discovery,
safe_text,
)
# ββ Constants βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
MODELS = [
{
"name": "DVNC Sovereign",
"tag": "flagship",
"desc": "Maximum depth orchestration for frontier discovery",
},
{
"name": "DVNC Atlas",
"tag": "research",
"desc": "Balanced reasoning, graph traversal, and synthesis",
},
{
"name": "DVNC Curie",
"tag": "lab",
"desc": "Experimental hypothesis generation for anomalous signals",
},
]
AGENTS = [
"Query Interpreter",
"Graph Divergence Mapper",
"Evidence Harvester",
"Analogy Engine",
"Hypothesis Composer",
"Adversarial Critic",
"Experimental Program Designer",
]
NODES = [
{"id": "seed", "label": "Seed Query", "group": "core", "x": 10, "y": 0, "z": 0},
{"id": "bio", "label": "Biomaterials", "group": "domain", "x": 24, "y": 12, "z": -8},
{"id": "card", "label": "Cardiac Repair", "group": "domain", "x": 38, "y": 3, "z": 14},
{"id": "nano", "label": "Nanostructure", "group": "bridge", "x": 24, "y": -18, "z": 16},
{"id": "selfasm", "label": "Self-Assembly", "group": "bridge", "x": 40, "y": -16, "z": -16},
{"id": "electro", "label": "Electro-signalling", "group": "mechanism", "x": 58, "y": 10, "z": -10},
{"id": "immune", "label": "Immune Modulation", "group": "mechanism", "x": 64, "y": -8, "z": 10},
{"id": "trial", "label": "Validation Path", "group": "outcome", "x": 80, "y": 0, "z": 0},
{"id": "alt1", "label": "Piezoelectric Scaffold", "group": "candidate", "x": 56, "y": 26, "z": 14},
{"id": "alt2", "label": "Peptide Mesh", "group": "candidate", "x": 54, "y": -27, "z": -14},
]
EDGES = [
("seed", "bio"), ("seed", "nano"), ("bio", "card"), ("nano", "selfasm"),
("selfasm", "electro"), ("card", "immune"), ("electro", "trial"),
("immune", "trial"), ("card", "alt1"), ("selfasm", "alt2"),
("alt1", "trial"), ("alt2", "trial"),
]
DEFAULT_PATH = ["seed", "nano", "selfasm", "electro", "trial"]
CANDIDATES = [
{
"title": "Piezoelectric Scaffold Cascade",
"front": "Use mechano-electric scaffolds to convert cardiac strain into micro-current signalling.",
"back": "Discovery path: anomalous healing signal -> piezoelectric analog -> ion-channel entrainment -> tissue regeneration. Risk: power density and fibrosis coupling.",
"score": 92,
"novelty": "High",
"agent": "Hypothesis Composer",
},
{
"title": "Peptide Self-Assembly Mesh",
"front": "Deploy dynamic peptide meshes that self-assemble around damaged myocardium and guide repair.",
"back": "Discovery path: self-assembly -> local immune choreography -> regenerative substrate formation. Risk: degradation timing and targeting specificity.",
"score": 88,
"novelty": "High",
"agent": "Analogy Engine",
},
{
"title": "Immune-Tuned Conductive Hydrogel",
"front": "Blend conductivity with macrophage-state modulation to reduce scarring and restore conduction.",
"back": "Discovery path: inflammation mismatch -> conductive medium -> macrophage polarization -> synchronized healing. Risk: persistence and biocompatibility.",
"score": 85,
"novelty": "Medium-High",
"agent": "Adversarial Critic",
},
]
ACADEMIC_INSIGHTS = [
{
"hypothesis": "Implementation of mechano-electric scaffolds to transduce cardiac strain into localized micro-current signalling for myocardial regeneration.",
"metrics": {
"Novelty": 92,
"Mechanistic clarity": 85,
"Experimental tractability": 78,
"Cross-domain distance": 94,
},
"outline": (
"1. Synthesize candidate piezoelectric biomaterial scaffolds with tunable strain-electric coupling.\n"
"2. Evaluate in vitro electromechanical transduction and subsequent ion-channel entrainment.\n"
"3. Conduct in vivo comparative models to assess regenerative efficacy against gold-standard substrates.\n"
"4. Rigorously validate to exclude pathological fibrosis and power-density toxicity."
),
"path": ["seed", "bio", "card", "alt1", "trial"],
},
{
"hypothesis": "Deployment of dynamic peptide networks that self-assemble post-infarction to orchestrate local immunological responses and guide substrate regeneration.",
"metrics": {
"Novelty": 88,
"Mechanistic clarity": 82,
"Experimental tractability": 86,
"Cross-domain distance": 85,
},
"outline": (
"1. Formulate peptide sequences programmed for triggered in situ self-assembly within the myocardial infarct zone.\n"
"2. Quantify macrophage polarization and local immune choreography post-deployment.\n"
"3. Map the temporospatial degradation profile against de novo tissue formation.\n"
"4. Falsify against off-target aggregation and delayed clearance risks."
),
"path": ["seed", "nano", "selfasm", "alt2", "trial"],
},
{
"hypothesis": "Integration of conductive hydrogels with immunomodulatory properties to simultaneously bridge electrical uncoupling and mitigate adverse fibrotic scarring.",
"metrics": {
"Novelty": 85,
"Mechanistic clarity": 90,
"Experimental tractability": 88,
"Cross-domain distance": 79,
},
"outline": (
"1. Fabricate biocompatible hydrogels featuring precisely tuned electrical conductivity and immunomodulatory motifs.\n"
"2. Monitor electrophysiological synchronization across the scaffold-tissue interface.\n"
"3. Assess macrophage state transitions and suppression of adverse fibrotic remodelling.\n"
"4. Validate long-term persistence, hemocompatibility, and mechanical integration."
),
"path": ["seed", "bio", "card", "immune", "trial"],
},
]
# ββ Utility helpers βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def norm_text(x: Optional[str]) -> str:
return re.sub(r"\s+", " ", (x or "")).strip()
def build_learning_graph_html(nodes, edges, title="Self-Learning Knowledge Graph"):
return render_graph_canvas_html(
{
"status": "ok" if (nodes or edges) else "empty",
"nodes": nodes or [],
"edges": edges or [],
},
title=title,
height=780,
)
# ββ HTML builders βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def build_connectome_html(path_ids: List[str]) -> str:
active = set(path_ids)
node_map = {n["id"]: n for n in NODES}
path_pairs = {
pair
for i in range(len(path_ids) - 1)
for pair in [(path_ids[i], path_ids[i + 1]), (path_ids[i + 1], path_ids[i])]
}
baselines, activelines, circles, labels = [], [], [], []
for a, b in EDGES:
na, nb = node_map[a], node_map[b]
x1, y1 = na["x"] * 8 + 80, na["y"] * 6 + 280
x2, y2 = nb["x"] * 8 + 80, nb["y"] * 6 + 280
baselines.append(f'e class="edge" x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}"/>')
if (a, b) in path_pairs:
activelines.append(f'e class="edge active" x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}"/>')
for n in NODES:
cx, cy = n["x"] * 8 + 80, n["y"] * 6 + 280
is_active = n["id"] in active
state = "chosen" if is_active else "idle"
halo_cls = "halo active" if is_active else "halo"
lbl_cls = "label active" if is_active else "label"
radius = 18 if is_active else 13
halo_r = 30 if is_active else 0
circles.append(
f'ircle class="{halo_cls}" cx="{cx}" cy="{cy}" r="{halo_r}"/>'
f'ircle class="node {state}" cx="{cx}" cy="{cy}" r="{radius}"/>'
f'<title>{safe_text(n["label"])}</title>'
f'<text class="{lbl_cls}" x="{cx}" y="{cy + radius + 14}" text-anchor="middle">{safe_text(n["label"][:18])}</text>'
)
return f"""<div class="brain-shell panel">
<div class="brain-header">
<div><p class="eyebrow">Connectome</p><h3>3D Connectome</h3></div>
<div class="brain-legend">
<span><span class="dot dot-live"></span>lit path</span>
<span><span class="dot dot-chosen"></span>chosen node</span>
<span><span class="dot dot-idle"></span>available node</span>
</div></div>
<div class="brain-stage">
<svg class="brain-svg" viewBox="0 0 880 560">
{''.join(baselines)} {''.join(activelines)} {''.join(circles)}
</svg></div></div>"""
def build_cards_html(cards: List[Dict]) -> str:
items = []
for i, c in enumerate(cards):
items.append(
f"""<div class="candidate-card" tabindex="0">
<div class="candidate-card-inner">
<div class="candidate-face">
<div class="candidate-top"><span class="chip">{safe_text(c["agent"])}</span><span class="score">{safe_text(c["score"])}</span></div>
<h4>{safe_text(c["title"])}</h4>
<p>{safe_text(c["front"])}</p>
<div class="meta-row"><span>Novelty <strong>{safe_text(c["novelty"])}</strong></span></div>
<button class="mini" onclick="triggerRouteSwap({i})">Use as main insight</button>
</div>
<div class="candidate-face candidate-back">
<div class="candidate-top"><span class="chip alt">Alternative path</span><span class="score">{safe_text(c["score"])}</span></div>
<h4>{safe_text(c["title"])}</h4>
<p>{safe_text(c["back"])}</p>
<div class="meta-row"><span>Swap into route <strong>Enabled</strong></span></div>
<button class="mini" onclick="triggerRouteSwap({i})">Use as main insight</button>
</div>
</div></div>"""
)
return '<div class="candidate-grid">' + "".join(items) + "</div>"
def build_chat_html(query: str, result: Dict) -> str:
return f"""<div class="chat-panel panel"><div class="chat-thread">
<div class="bubble bubble-user"><span class="role">You</span><p>{safe_text(query)}</p></div>
<div class="bubble bubble-ai"><span class="role">DVNC Sovereign</span><p>{safe_text(result["summary"])}</p></div>
<div class="bubble bubble-system"><span class="role">Discovery Signal</span>
<p><strong>Primary hypothesis:</strong> {safe_text(result["primary_hypothesis"])}</p>
</div></div></div>"""
def build_models_html(selected: str) -> str:
items = []
for m in MODELS:
active = "active" if m["name"] == selected else ""
items.append(
f'<div class="model-pill {active}"><span class="model-name">{safe_text(m["name"])}</span>'
f'<span class="model-tag">{safe_text(m["tag"])}</span>'
f'<small>{safe_text(m["desc"])}</small></div>'
)
return '<div class="model-switcher">' + "".join(items) + "</div>"
# ββ Discovery logic βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def run_discovery(query: str, model_name: str):
random.seed(len(query or "") + len(model_name or ""))
if "curie" in (query or "").lower() or "einstein" in (query or "").lower():
primary = "Map the anomaly first, then force a distant analogy before composing the experimental programme."
path = ["seed", "bio", "card", "immune", "trial"]
else:
primary = (
"Utilization of a self-assembling conductive scaffold to transduce mechanical "
"strain into localized regenerative signalling pathways."
)
path = DEFAULT_PATH
summaries = [
"Normalises the user prompt into a graph-searchable seed and isolates the tension inside the question.",
"Finds remote conceptual bridges instead of staying near the starting domain cluster.",
"Pulls evidence packets and conflict signals required for grounded hypothesis formation.",
"Generates cross-domain analogies with a bias toward mechanism transfer rather than keyword similarity.",
"Composes the lead hypothesis and two structurally different variants.",
"Attacks weak assumptions, hidden confounders, and feasibility gaps.",
"Produces a staged validation plan with measurable falsification criteria.",
]
tags = ["input", "graph", "evidence", "analogy", "compose", "critique", "experiment"]
reasoning = [
{"step": i + 1, "agent": AGENTS[i], "tag": tags[i], "summary": summaries[i]}
for i in range(7)
]
result = {
"summary": (
"A deeper route was chosen through the connectome, with live alternatives preserved "
"as swappable cards so the reasoning path can be inspected rather than hidden."
),
"primary_hypothesis": primary,
"reasoning": reasoning,
"cards": CANDIDATES,
"path": path,
"metrics": {
"Novelty": 93,
"Mechanistic clarity": 89,
"Experimental tractability": 82,
"Cross-domain distance": 91,
},
}
chat_html = build_chat_html(query, result)
connectome_html = build_connectome_html(path)
timeline_html = build_agent_route_cards_html(reasoning)
metrics_md = "\n".join(f"- {k}: {v}/100" for k, v in result["metrics"].items())
hypothesis_md = (
"# Discovery Output\n\n"
f"**Model:** {model_name}\n\n"
f"**Primary hypothesis:** {result['primary_hypothesis']}\n\n"
"## Scoring\n"
f"{metrics_md}\n\n"
"## Experimental outline\n"
"1. Construct the candidate material or protocol.\n"
"2. Test mechanistic signal expression under controlled conditions.\n"
"3. Compare against baseline and nearest-neighbour alternatives.\n"
"4. Falsify using the adversarial risk criteria surfaced in the reasoning path.\n"
)
cards_html = build_cards_html(CANDIDATES)
route_state = get_default_route_state()
return (
chat_html,
connectome_html,
timeline_html,
cards_html,
hypothesis_md,
build_models_html(model_name),
route_state,
)
def apply_route_swap(query: str, model_name: str, route_swap_payload: str, route_state):
try:
idx = int(route_swap_payload)
except Exception:
idx = 0
if not (0 <= idx < len(ACADEMIC_INSIGHTS)):
idx = 0
academic = ACADEMIC_INSIGHTS[idx]
connectome_html = build_connectome_html(academic["path"])
result = {
"summary": (
"Main insight formally adopted. The connectome pathway and validation protocol "
"have been realigned to the selected candidate methodology."
),
"primary_hypothesis": academic["hypothesis"],
}
chat_html = build_chat_html(query, result)
metrics_md = "\n".join(f"- {k}: {v}/100" for k, v in academic["metrics"].items())
hypothesis_md = (
"# Discovery Output\n\n"
f"**Model:** {model_name}\n\n"
f"**Primary hypothesis:** {academic['hypothesis']}\n\n"
"## Scoring\n"
f"{metrics_md}\n\n"
"## Experimental outline\n"
f"{academic['outline']}\n"
)
return chat_html, connectome_html, gr.update(), hypothesis_md, route_state
# ββ Example loaders ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def load_example() -> str:
return "How could a self-assembling conductive biomaterial improve cardiac tissue regeneration by converting mechanical strain into repair signalling?"
def load_paper_topic() -> str:
return "self-assembling conductive biomaterials for cardiac repair"
# ββ CSS / HEAD ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
BASE_CSS = r"""
:root {
--bg:#ffffff; --panel:#ffffff; --line:rgba(0,0,0,.12); --text:#111111;
--muted:#5b5b5b; --soft:rgba(0,0,0,.62); --gold:#ff6600; --teal:#17b8a6;
--blue:#628dff; --chosen:#ff7a1a; --idle:#b8d8ff; --idle-stroke:#5e8fe6;
--query-node:#ffd8b3; --paper-node:#d7f6f2; --upload-node:#e7defe;
--shadow:0 16px 40px rgba(0,0,0,.12);
}
html,body,.gradio-container{background:#ffffff !important;font-family:Inter,ui-sans-serif,system-ui,sans-serif;}
.gradio-container{max-width:1640px !important;padding:20px !important;}
#dvnc-shell{border:1px solid var(--line);border-radius:28px;overflow:hidden;background:#ffffff;box-shadow:var(--shadow);padding:20px 22px 22px;}
.hero-bar{display:flex;justify-content:space-between;align-items:center;gap:16px;padding-bottom:12px;border-bottom:1px solid rgba(0,0,0,.06);margin-bottom:16px;}
.brand{display:flex;align-items:center;gap:14px;}
.logo{width:42px;height:42px;border-radius:14px;display:grid;place-items:center;color:var(--gold);background:linear-gradient(135deg,rgba(255,122,26,.12),rgba(23,184,166,.10));border:1px solid rgba(0,0,0,.08);}
.brand h1{font-size:1.05rem;margin:0;font-weight:700;letter-spacing:.12em;text-transform:uppercase;}
.brand p{margin:3px 0 0;color:var(--muted);font-size:.84rem;}
.status{display:flex;gap:10px;align-items:center;color:var(--soft);font-size:.85rem;}
.status-dot{width:10px;height:10px;border-radius:50%;background:var(--teal);box-shadow:0 0 0 6px rgba(23,184,166,.10),0 0 14px rgba(23,184,166,.25);}
.panel{background:#ffffff;border:1px solid var(--line);border-radius:22px;box-shadow:inset 0 1px 0 rgba(255,255,255,. |