4 / app_old.py
Adi12345's picture
Rename app.py to app_old.py
e664635 verified
Raw
History Blame
20.4 kB
import json
import pathlib
import gradio as gr
from dvnc_ai_v2_hf.app import demo
MODELS = ["DVNC Sovereign", "DVNC Atlas", "DVNC Curie"]
BASE_DIR = pathlib.Path(__file__).resolve().parent
#CONNECTOME_SNIPPET = (BASE_DIR / "ui" / "connectome.html").read_text(encoding="utf-8")
# replaced base connectome with enhanced connectome.
CONNECTOME_SNIPPET = (BASE_DIR / "ui" / "enhanced_connectome.html").read_text(encoding="utf-8")
def build_chat_html(query, data):
return f'''
<div class="chat-panel panel">
<div class="bubble user"><span class="role">You</span><p>{query}</p></div>
<div class="bubble ai"><span class="role">DVNC</span><p>{data.get("summary","")}</p></div>
<div class="bubble system"><span class="role">Primary Hypothesis</span><p>{data.get("primary_hypothesis","")}</p></div>
</div>
'''
def build_reasoning_html(steps):
chunks = []
for s in steps:
chunks.append(f'''
<details class="tray" {'open' if s['step']==1 else ''}>
<summary><span class="step">{s['step']}</span><div><strong>{s['agent']}</strong><small>{s['tag']}</small></div></summary>
<div class="tray-body">{s['summary']}</div>
</details>
''')
return '<div class="panel tray-panel">' + ''.join(chunks) + '</div>'
def build_cards_html(cards):
html = []
for c in cards:
html.append(f'''
<article class="candidate-card" tabindex="0">
<div class="candidate-card-inner">
<div class="candidate-face front">
<div class="top"><span class="chip">{c['agent']}</span><span class="score">{c['score']}</span></div>
<h4>{c['title']}</h4>
<p>{c['front']}</p>
<div class="meta"><span>Novelty</span><strong>{c['novelty']}</strong></div>
</div>
<div class="candidate-face back">
<div class="top"><span class="chip alt">Alt path</span><span class="score">{c['score']}</span></div>
<h4>{c['title']}</h4>
<p>{c['back']}</p>
<div class="meta"><span>Swap state</span><strong>Ready</strong></div>
</div>
</div>
</article>
''')
return '<div class="panel cards-panel"><div class="candidate-grid">' + ''.join(html) + '</div></div>'
def build_metrics_md(metrics, model_used):
lines = [f"# Discovery Output\n", f"**Claude model used:** {model_used}\n", "## Metrics"]
for k, v in metrics.items():
lines.append(f"- {k}: {v}/100")
lines.append("\n## Next action\n- Replace `core/dvnc_engine.py` with your production graph and evidence stack.")
return "\n".join(lines)
def build_frontend_payload(data):
return f"""
<script>
window.__DVNC_GRAPH__ = {json.dumps(data.get('graph', {}))};
</script>
{CONNECTOME_SNIPPET}
"""
def run(query, model_name):
data = run_discovery(query, model_name)
return (
build_chat_html(query, data),
build_frontend_payload(data),
build_reasoning_html(data.get("reasoning", [])),
build_cards_html(data.get("cards", [])),
build_metrics_md(data.get("metrics", {}), data.get("model_used", "unknown")),
)
CSS = r'''
:root{--bg:#fffaf7;--panel:#ffffff;--panel2:#fff6f1;--line:rgba(17,24,39,.08);--text:#000;--muted:#5f6675;--orange:#ff6b35;--orange-light:#ff955f;--orange-pale:#fff3ec;--teal:#b9efe8;--blue:#8fb2ff;--radius:24px;--shadow:0 16px 44px rgba(17,24,39,.06)}
html,body,.gradio-container{background:linear-gradient(180deg,#fffaf7 0%,#fff 100%)!important;color:var(--text)!important;font-family:Inter,system-ui,sans-serif}
.gradio-container{max-width:1480px!important;padding:18px!important} footer{display:none!important}
#app-shell{border:1px solid var(--line);background:rgba(255,255,255,.92);backdrop-filter:blur(14px);box-shadow:var(--shadow);border-radius:32px;overflow:hidden}
#app-shell .grid{display:grid;grid-template-columns:1.08fr .92fr;min-height:72vh}.left,.right{padding:20px}.left{border-right:1px solid var(--line);display:flex;flex-direction:column;gap:14px}.right{display:grid;grid-template-rows:auto auto auto 1fr;gap:14px}
.hero{display:flex;justify-content:space-between;align-items:center;gap:12px}
.hero-plate{padding:22px 24px 18px 24px;min-height:160px;border-bottom:1px solid var(--line);background:linear-gradient(180deg,rgba(255,255,255,.92) 0%,rgba(255,247,243,.88) 100%)}
.hero-copy{display:flex;flex-direction:column;justify-content:space-between;gap:16px;min-height:118px}
.brand{display:flex;gap:14px;align-items:center}
.logo{width:50px;height:50px;border-radius:16px;display:grid;place-items:center;border:1px solid rgba(255,107,53,.2);background:linear-gradient(135deg,var(--orange-pale),rgba(255,107,53,.08))}
.logo svg{width:26px;height:26px;color:var(--orange)}
.brand h1{margin:0;font-size:1.18rem;color:var(--text)}
.brand p{margin:4px 0 0;color:var(--muted);font-size:.9rem}
.live{display:flex;gap:10px;align-items:center;color:var(--text)}
.live i{width:10px;height:10px;border-radius:50%;background:var(--orange);display:inline-block;box-shadow:0 0 18px rgba(255,107,53,.4);animation:pulse 2s ease-in-out infinite}
.hero-orb-wrap{margin-left:auto;display:flex;align-items:center;justify-content:center;min-width:180px}
.hero-orb{position:relative;width:110px;height:110px;display:grid;place-items:center}
.hero-orb-core{width:64px;height:64px;border-radius:50%;background:radial-gradient(circle at 30% 28%,#ffd2be 0%,#ff9a6f 30%,#ff6b35 68%,#d94d1c 100%);box-shadow:0 12px 34px rgba(255,107,53,.28), inset -8px -10px 18px rgba(100,35,10,.22), inset 8px 10px 16px rgba(255,255,255,.22);animation:heroOrbFloat 5s ease-in-out infinite}
.hero-orb-ring{position:absolute;border-radius:50%;border:1px solid rgba(255,107,53,.16)}
.hero-orb-ring.ring-a{width:86px;height:86px;animation:spinSlow 10s linear infinite}
.hero-orb-ring.ring-b{width:108px;height:108px;border-color:rgba(255,107,53,.10);animation:spinReverse 14s linear infinite}
.hero-orb-glow{position:absolute;width:120px;height:120px;border-radius:50%;background:radial-gradient(circle,rgba(255,107,53,.18) 0%,rgba(255,107,53,.08) 42%,rgba(255,107,53,0) 72%)}
@keyframes heroOrbFloat{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-5px) scale(1.03)}}
@keyframes spinSlow{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}
@keyframes spinReverse{from{transform:rotate(360deg)}to{transform:rotate(0deg)}}
@keyframes pulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.6;transform:scale(.9)}}
.panel{border:1px solid var(--line);background:#ffffff;border-radius:22px;box-shadow:0 2px 12px rgba(0,0,0,.04)}
.dvnc-model-cards .gr-radio{
display:grid!important;
grid-template-columns:repeat(3,1fr);
gap:12px;
}
.dvnc-model-cards label{
display:flex!important;
flex-direction:column;
gap:4px;
padding:14px!important;
border:1px solid var(--line)!important;
border-radius:18px!important;
background:#fafbfc!important;
cursor:pointer!important;
transition:all .2s ease!important;
min-height:84px;
justify-content:center;
}
.dvnc-model-cards label:hover{
border-color:var(--orange)!important;
transform:translateY(-1px);
box-shadow:0 10px 22px rgba(255,107,53,.08);
}
.dvnc-model-cards input[type="radio"]{
margin-bottom:8px;
accent-color:var(--orange);
}
.dvnc-model-cards label:has(input[type="radio"]:checked){
border-color:var(--orange)!important;
background:var(--orange-pale)!important;
box-shadow:0 10px 24px rgba(255,107,53,.12);
}
.querybox,.querybox>div{background:#fff!important;border:1.5px solid rgba(255,107,53,.28)!important;border-radius:20px!important;box-shadow:0 6px 22px rgba(255,107,53,.08)!important}.querybox textarea{color:#000!important;background:#fff!important}.querybox:focus-within,.querybox>div:focus-within{border-color:#ff6b35!important;box-shadow:0 0 0 4px rgba(255,107,53,.10),0 8px 28px rgba(255,107,53,.10)!important}
.chat-panel{padding:14px;display:flex;flex-direction:column;gap:10px;min-height:240px;max-height:300px;overflow:auto}.bubble{max-width:86%;padding:14px 16px;border:1px solid var(--line);border-radius:20px}.bubble .role{font-size:.72rem;text-transform:uppercase;letter-spacing:.14em;color:var(--muted)}.bubble p{margin:6px 0 0;line-height:1.55;color:var(--text)}.bubble.user{margin-left:auto;background:var(--orange-pale);border-color:rgba(255,107,53,.22)}.bubble.ai{background:#fff}.bubble.system{background:var(--orange-pale);border-color:rgba(255,107,53,.22)}
.brain-shell{padding:14px}.brain-head{display:flex;justify-content:space-between;gap:16px;align-items:flex-end;margin-bottom:10px}.eyebrow{margin:0 0 4px;font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;color:var(--orange)}.brain-head h3{margin:0;font-size:1.02rem;color:var(--text)}.brain-help{color:var(--muted);font-size:.8rem}#dvnc-three-root{height:300px;border-radius:20px;border:1px solid var(--line);overflow:hidden;background:linear-gradient(180deg,#fff7f3 0%,#fff 100%);position:relative}
.working-orb{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:80px;height:80px;border-radius:50%;background:radial-gradient(circle at 30% 30%,rgba(255,143,102,.9),var(--orange));box-shadow:0 8px 32px rgba(255,107,53,.4),inset 0 -4px 12px rgba(0,0,0,.15);animation:orbPulse 2.5s ease-in-out infinite,orbFloat 4s ease-in-out infinite}
@keyframes orbPulse{0%,100%{box-shadow:0 8px 32px rgba(255,107,53,.4),inset 0 -4px 12px rgba(0,0,0,.15)}50%{box-shadow:0 12px 48px rgba(255,107,53,.7),inset 0 -4px 12px rgba(0,0,0,.2)}}
@keyframes orbFloat{0%,100%{transform:translate(-50%,-50%) translateY(0)}50%{transform:translate(-50%,-50%) translateY(-12px)}}
.tray-panel{padding:14px;display:flex;flex-direction:column;gap:10px}.tray{border:1px solid var(--line);border-radius:18px;background:#ffffff;overflow:hidden}.tray summary{list-style:none;display:grid;grid-template-columns:42px 1fr;gap:12px;align-items:center;padding:12px 14px;cursor:pointer}.tray summary::-webkit-details-marker{display:none}.tray .step{width:42px;height:42px;border-radius:14px;display:grid;place-items:center;color:#ffffff;font-weight:700;background:var(--orange);border:1px solid var(--orange-light)}.tray summary strong{display:block;color:var(--text)}.tray summary small{color:var(--muted);text-transform:uppercase;letter-spacing:.12em}.tray-body{padding:0 14px 14px 68px;color:var(--text);line-height:1.6}
.cards-panel{padding:16px}.candidate-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px}.candidate-card{perspective:1200px;min-height:250px}.candidate-card-inner{position:relative;min-height:250px;height:100%;transform-style:preserve-3d;transition:transform .8s cubic-bezier(.2,.7,.1,1)}.candidate-card:hover .candidate-card-inner,.candidate-card:focus .candidate-card-inner{transform:rotateY(180deg)}.candidate-face{position:absolute;inset:0;padding:18px;border-radius:22px;border:1px solid var(--line);backface-visibility:hidden;display:flex;flex-direction:column;gap:12px;box-shadow:0 4px 16px rgba(0,0,0,.06);background:#ffffff}.candidate-face.back{transform:rotateY(180deg);background:var(--orange-pale)}.top,.meta{display:flex;justify-content:space-between;gap:12px}.chip{font-size:.72rem;letter-spacing:.12em;text-transform:uppercase;color:var(--orange);padding:7px 10px;border-radius:999px;border:1px solid rgba(255,107,53,.2);background:var(--orange-pale)}.chip.alt{color:var(--blue);border-color:rgba(37,99,235,.2);background:rgba(37,99,235,.08)}.score{font-weight:700;color:var(--orange)}.candidate-face h4{margin:0;color:var(--text)}.candidate-face p{margin:0;color:var(--text);line-height:1.6}.meta{margin-top:auto;color:var(--muted)}
.gr-button-primary{background:linear-gradient(135deg,var(--orange),var(--orange-light))!important;color:#fff!important;border:none!important;font-weight:700!important;box-shadow:0 10px 24px rgba(255,107,53,.22)!important}.gr-button-secondary{background:#fff!important;color:#000!important;border:1px solid rgba(255,107,53,.18)!important}
@media (max-width:1180px){#app-shell .grid{grid-template-columns:1fr}.left{border-right:0;border-bottom:1px solid var(--line)}.model-strip,.candidate-grid{grid-template-columns:1fr}}
'''
HEAD = '''
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three@0.156.0/build/three.module.js",
"three/addons/": "https://unpkg.com/three@0.156.0/examples/jsm/"
}
}
</script>
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
function initDVNC(){
const root = document.getElementById('dvnc-three-root');
const graph = window.__DVNC_GRAPH__;
if(!root || !graph || root.dataset.ready === '1') return;
root.dataset.ready = '1';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(52, root.clientWidth / root.clientHeight, 0.1, 1000);
camera.position.set(0, 0, 120);
const renderer = new THREE.WebGLRenderer({ antialias:true, alpha:true });
renderer.setSize(root.clientWidth, root.clientHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
root.innerHTML='';
root.appendChild(renderer.domElement);
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.autoRotate = true;
controls.autoRotateSpeed = .45;
controls.enablePan = false;
const ambient = new THREE.AmbientLight(0xffffff, .7); scene.add(ambient);
const key = new THREE.PointLight(0xff6b35, 2.5, 260); key.position.set(30, 40, 50); scene.add(key);
const fill = new THREE.PointLight(0xff8f66, 2.0, 240); fill.position.set(-40, -20, 40); scene.add(fill);
const nodeMeshes = {};
const active = new Set(graph.active_path || []);
const palette = {core:0xff6b35, domain:0xff8f66, bridge:0xffa280, mechanism:0xffb399, outcome:0xffc2ad, candidate:0xff8f66};
const nodeGeom = new THREE.SphereGeometry(1.8, 22, 22);
const haloGeom = new THREE.SphereGeometry(3.4, 22, 22);
for(const n of graph.nodes || []){
const mat = new THREE.MeshStandardMaterial({ color: palette[n.group] || 0x9aa8c7, emissive: active.has(n.id) ? 0xff6b35 : 0x000000, emissiveIntensity: active.has(n.id) ? 1.2 : 0.15, roughness:.3, metalness:.15 });
const mesh = new THREE.Mesh(nodeGeom, mat);
mesh.position.set(n.x, n.y, n.z);
scene.add(mesh);
nodeMeshes[n.id] = mesh;
if(active.has(n.id)){
const halo = new THREE.Mesh(haloGeom, new THREE.MeshBasicMaterial({ color:0xff6b35, transparent:true, opacity:.08 }));
halo.position.copy(mesh.position);
scene.add(halo);
mesh.userData.halo = halo;
}
}
function edgeActive(a,b){
const path = graph.active_path || [];
const ia = path.indexOf(a), ib = path.indexOf(b);
return ia >= 0 && ib >= 0 && Math.abs(ia-ib) === 1;
}
for(const e of graph.edges || []){
const [a,b] = e;
if(!nodeMeshes[a] || !nodeMeshes[b]) continue;
const pts = [nodeMeshes[a].position, nodeMeshes[b].position];
const geo = new THREE.BufferGeometry().setFromPoints(pts);
const mat = new THREE.LineBasicMaterial({ color: edgeActive(a,b) ? 0xff6b35 : 0xcccccc, transparent:true, opacity: edgeActive(a,b) ? 1 : .45 }); const line = new THREE.Line(geo, mat);
line.userData.active = edgeActive(a,b);
scene.add(line);
}
const stars = new THREE.Points(
new THREE.BufferGeometry().setAttribute('position', new THREE.Float32BufferAttribute(Array.from({length:1200},()=> (Math.random()-.5)*220), 3)),
new THREE.PointsMaterial({ color:0x8da6d8, size:.35, transparent:true, opacity:.6 })
);
scene.add(stars);
const clock = new THREE.Clock();
function animate(){
requestAnimationFrame(animate);
const t = clock.getElapsedTime();
Object.values(nodeMeshes).forEach((m,i)=>{
m.scale.setScalar(1 + Math.sin(t*1.6 + i)*0.03);
if(m.userData.halo){
const s = 1 + (Math.sin(t*2.2 + i)+1)*0.08;
m.userData.halo.scale.setScalar(s);
}
});
controls.update();
renderer.render(scene,camera);
}
animate();
const resize = ()=>{
if(!root.clientWidth || !root.clientHeight) return;
camera.aspect = root.clientWidth / root.clientHeight;
camera.updateProjectionMatrix();
renderer.setSize(root.clientWidth, root.clientHeight);
};
window.addEventListener('resize', resize, { passive:true });
}
function syncModelCards(){
const root = document;
const radios = root.querySelectorAll('input[name="dvnc-model-card"]');
const gradioRadios = root.querySelectorAll('#dvnc-model-radio input[type="radio"]');
if(!radios.length || !gradioRadios.length) return;
const setActiveCard = (value) => {
root.querySelectorAll('.model-pill').forEach(card => card.classList.remove('active'));
const activeInput = root.querySelector(`input[name="dvnc-model-card"][value="${value}"]`);
if(activeInput){
activeInput.checked = true;
activeInput.closest('.model-pill')?.classList.add('active');
}
};
radios.forEach(radio => {
if(radio.dataset.bound === '1') return;
radio.dataset.bound = '1';
radio.addEventListener('change', () => {
const next = radio.value;
const target = Array.from(gradioRadios).find(r => r.value === next);
if(target){
target.click();
}
setActiveCard(next);
});
});
const checked = Array.from(gradioRadios).find(r => r.checked);
if(checked){
setActiveCard(checked.value);
}
}
new MutationObserver(()=>{initDVNC(); syncModelCards();}).observe(document.documentElement,{childList:true,subtree:true});
window.addEventListener('load', ()=>{initDVNC(); syncModelCards();});
setInterval(()=>{initDVNC(); syncModelCards();}, 1200);
</script>
'''
with gr.Blocks(css=CSS, head=HEAD, theme=gr.themes.Base(), fill_height=True) as demo:
gr.HTML('''
<div id="app-shell">
<div class="hero hero-plate">
<div class="hero-copy">
<div class="brand">
<div class="logo"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><path d="M5 17L12 4l7 13"/><path d="M8.5 12.5h7"/><circle cx="12" cy="12" r="1.8" fill="currentColor" stroke="none"/></svg></div>
<div>
<h1>DVNC.AI</h1>
<p>Connectome-native reasoning · premium scientific discovery interface</p>
</div>
</div>
<div class="live"><i></i><span>Claude-linked runtime</span></div>
</div>
<div class="hero-orb-wrap">
<div class="hero-orb">
<div class="hero-orb-core"></div>
<div class="hero-orb-ring ring-a"></div>
<div class="hero-orb-ring ring-b"></div>
<div class="hero-orb-glow"></div>
</div>
</div>
</div>
''')
model = gr.Radio(
choices=MODELS,
value="DVNC Sovereign",
label="Model family",
elem_id="dvnc-model-cards",
elem_classes=["dvnc-model-cards"]
)
query = gr.Textbox(label="Discovery query", lines=3, elem_classes=["querybox"], placeholder="Ask a scientific question, anomaly, mechanism, or hypothesis target…")
with gr.Row():
run_btn = gr.Button("Run discovery", variant="primary")
example_btn = gr.Button("Load example", variant="secondary")
chat = gr.HTML('<div class="chat-panel panel"><div class="bubble ai"><span class="role">DVNC</span><p>Enter a discovery prompt to trigger Claude-backed orchestration or demo mode if no API key is set.</p></div></div>')
gr.HTML('</section><section class="right">')
connectome = gr.HTML(CONNECTOME_SNIPPET)
trays = gr.HTML('<div class="panel tray-panel"></div>')
cards = gr.HTML('<div class="panel cards-panel"></div>')
output = gr.Markdown('# Discovery Output\n\nAwaiting query.')
gr.HTML('</section></div></div>')
example_btn.click(lambda: "How could a self-assembling conductive biomaterial improve cardiac repair by converting mechanical strain into regenerative signalling?", outputs=query)
run_btn.click(run, inputs=[query, model], outputs=[chat, connectome, trays, cards, output])
if __name__ == '__main__':
demo.launch()