Adi12345 commited on
Commit
f98ca1d
·
verified ·
1 Parent(s): f2bf7e3

Upload app.py

Browse files
Files changed (1) hide show
  1. dvnc_ai_v2_hf/app.py +144 -37
dvnc_ai_v2_hf/app.py CHANGED
@@ -69,9 +69,13 @@ def build_metrics_md(metrics, model_used):
69
 
70
 
71
  def build_frontend_payload(data):
 
 
 
 
72
  return f"""
73
  <script>
74
- window.__DVNC_GRAPH__ = {json.dumps(data.get('graph', {}))};
75
  </script>
76
  {CONNECTOME_SNIPPET}
77
  """
@@ -153,7 +157,17 @@ html,body,.gradio-container{background:linear-gradient(180deg,#fffaf7 0%,#fff 10
153
  }
154
  .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}
155
  .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)}
156
- .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}
 
 
 
 
 
 
 
 
 
 
157
  .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}
158
  @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)}}
159
  @keyframes orbFloat{0%,100%{transform:translate(-50%,-50%) translateY(0)}50%{transform:translate(-50%,-50%) translateY(-12px)}}
@@ -181,68 +195,156 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
181
 
182
  function initDVNC(){
183
  const root = document.getElementById('dvnc-three-root');
184
- const graph = window.__DVNC_GRAPH__;
185
- if(!root || !graph || root.dataset.ready === '1') return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
  root.dataset.ready = '1';
 
187
  const scene = new THREE.Scene();
188
- const camera = new THREE.PerspectiveCamera(52, root.clientWidth / root.clientHeight, 0.1, 1000);
189
- camera.position.set(0, 0, 120);
 
190
  const renderer = new THREE.WebGLRenderer({ antialias:true, alpha:true });
191
  renderer.setSize(root.clientWidth, root.clientHeight);
192
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
193
- root.innerHTML='';
194
  root.appendChild(renderer.domElement);
195
 
196
  const controls = new OrbitControls(camera, renderer.domElement);
197
  controls.enableDamping = true;
198
- controls.autoRotate = true;
199
- controls.autoRotateSpeed = .45;
200
  controls.enablePan = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
 
202
- const ambient = new THREE.AmbientLight(0xffffff, .7); scene.add(ambient);
203
- const key = new THREE.PointLight(0xff6b35, 2.5, 260); key.position.set(30, 40, 50); scene.add(key);
204
- const fill = new THREE.PointLight(0xff8f66, 2.0, 240); fill.position.set(-40, -20, 40); scene.add(fill);
205
-
206
- const nodeMeshes = {};
207
  const active = new Set(graph.active_path || []);
208
- const palette = {core:0xff6b35, domain:0xff8f66, bridge:0xffa280, mechanism:0xffb399, outcome:0xffc2ad, candidate:0xff8f66};
209
-
210
- const nodeGeom = new THREE.SphereGeometry(1.8, 22, 22);
211
- const haloGeom = new THREE.SphereGeometry(3.4, 22, 22);
 
 
 
 
 
 
 
 
212
 
213
  for(const n of graph.nodes || []){
214
- 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 });
 
 
 
 
 
 
 
 
 
 
215
  const mesh = new THREE.Mesh(nodeGeom, mat);
216
- mesh.position.set(n.x, n.y, n.z);
217
  scene.add(mesh);
218
  nodeMeshes[n.id] = mesh;
219
- if(active.has(n.id)){
220
- const halo = new THREE.Mesh(haloGeom, new THREE.MeshBasicMaterial({ color:0xff6b35, transparent:true, opacity:.08 }));
221
- halo.position.copy(mesh.position);
222
- scene.add(halo);
223
- mesh.userData.halo = halo;
224
- }
 
 
 
 
 
 
225
  }
226
 
227
  function edgeActive(a,b){
228
  const path = graph.active_path || [];
229
  const ia = path.indexOf(a), ib = path.indexOf(b);
230
- return ia >= 0 && ib >= 0 && Math.abs(ia-ib) === 1;
231
  }
232
 
233
  for(const e of graph.edges || []){
234
  const [a,b] = e;
235
  if(!nodeMeshes[a] || !nodeMeshes[b]) continue;
 
236
  const pts = [nodeMeshes[a].position, nodeMeshes[b].position];
237
  const geo = new THREE.BufferGeometry().setFromPoints(pts);
238
- 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);
239
- line.userData.active = edgeActive(a,b);
 
 
 
 
 
 
 
 
 
 
240
  scene.add(line);
241
  }
242
 
 
 
 
 
 
 
 
243
  const stars = new THREE.Points(
244
- new THREE.BufferGeometry().setAttribute('position', new THREE.Float32BufferAttribute(Array.from({length:1200},()=> (Math.random()-.5)*220), 3)),
245
- new THREE.PointsMaterial({ color:0x8da6d8, size:.35, transparent:true, opacity:.6 })
 
 
 
 
 
 
 
 
246
  );
247
  scene.add(stars);
248
 
@@ -250,24 +352,29 @@ function initDVNC(){
250
  function animate(){
251
  requestAnimationFrame(animate);
252
  const t = clock.getElapsedTime();
253
- Object.values(nodeMeshes).forEach((m,i)=>{
254
- m.scale.setScalar(1 + Math.sin(t*1.6 + i)*0.03);
 
 
255
  if(m.userData.halo){
256
- const s = 1 + (Math.sin(t*2.2 + i)+1)*0.08;
257
- m.userData.halo.scale.setScalar(s);
258
  }
259
  });
 
 
260
  controls.update();
261
- renderer.render(scene,camera);
262
  }
263
  animate();
264
 
265
- const resize = ()=>{
266
  if(!root.clientWidth || !root.clientHeight) return;
267
  camera.aspect = root.clientWidth / root.clientHeight;
268
  camera.updateProjectionMatrix();
269
  renderer.setSize(root.clientWidth, root.clientHeight);
270
  };
 
271
  window.addEventListener('resize', resize, { passive:true });
272
  }
273
 
 
69
 
70
 
71
  def build_frontend_payload(data):
72
+ graph = data.get("graph") or {}
73
+ graph.setdefault("nodes", [])
74
+ graph.setdefault("edges", [])
75
+ graph.setdefault("active_path", [])
76
  return f"""
77
  <script>
78
+ window.__DVNC_GRAPH__ = {json.dumps(graph)};
79
  </script>
80
  {CONNECTOME_SNIPPET}
81
  """
 
157
  }
158
  .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}
159
  .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)}
160
+ .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{
161
+ height:340px;
162
+ border-radius:20px;
163
+ border:1px solid var(--line);
164
+ overflow:hidden;
165
+ background:
166
+ radial-gradient(circle at 50% 45%, rgba(255,107,53,.10), rgba(255,107,53,0) 34%),
167
+ linear-gradient(180deg,#fff8f5 0%, #fff 100%);
168
+ position:relative;
169
+ display:block;
170
+ }
171
  .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}
172
  @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)}}
173
  @keyframes orbFloat{0%,100%{transform:translate(-50%,-50%) translateY(0)}50%{transform:translate(-50%,-50%) translateY(-12px)}}
 
195
 
196
  function initDVNC(){
197
  const root = document.getElementById('dvnc-three-root');
198
+ if(!root || root.clientWidth === 0 || root.clientHeight === 0) return;
199
+
200
+ let graph = window.__DVNC_GRAPH__ || {};
201
+ const hasRealGraph = Array.isArray(graph.nodes) && graph.nodes.length > 0;
202
+
203
+ if(!hasRealGraph){
204
+ graph = {
205
+ nodes: [
206
+ {id:"query", group:"core", x:0, y:0, z:0},
207
+ {id:"mechanics", group:"domain", x:-26, y:16, z:-8},
208
+ {id:"conductivity", group:"bridge", x:26, y:12, z:10},
209
+ {id:"immune", group:"mechanism", x:-18, y:-18, z:14},
210
+ {id:"repair", group:"outcome", x:24, y:-16, z:-12},
211
+ {id:"candidate", group:"candidate", x:0, y:26, z:18}
212
+ ],
213
+ edges: [
214
+ ["query","mechanics"],
215
+ ["query","conductivity"],
216
+ ["query","immune"],
217
+ ["mechanics","candidate"],
218
+ ["conductivity","candidate"],
219
+ ["immune","repair"],
220
+ ["candidate","repair"]
221
+ ],
222
+ active_path: ["query","conductivity","candidate","repair"]
223
+ };
224
+ }
225
+
226
+ root.innerHTML = '';
227
  root.dataset.ready = '1';
228
+
229
  const scene = new THREE.Scene();
230
+ const camera = new THREE.PerspectiveCamera(54, root.clientWidth / root.clientHeight, 0.1, 1000);
231
+ camera.position.set(0, 0, 115);
232
+
233
  const renderer = new THREE.WebGLRenderer({ antialias:true, alpha:true });
234
  renderer.setSize(root.clientWidth, root.clientHeight);
235
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
236
+ renderer.outputColorSpace = THREE.SRGBColorSpace;
237
  root.appendChild(renderer.domElement);
238
 
239
  const controls = new OrbitControls(camera, renderer.domElement);
240
  controls.enableDamping = true;
 
 
241
  controls.enablePan = false;
242
+ controls.autoRotate = true;
243
+ controls.autoRotateSpeed = 0.55;
244
+
245
+ scene.add(new THREE.AmbientLight(0xffffff, 1.15));
246
+
247
+ const key = new THREE.PointLight(0xff6b35, 4.2, 320);
248
+ key.position.set(38, 42, 60);
249
+ scene.add(key);
250
+
251
+ const fill = new THREE.PointLight(0xffb089, 2.4, 280);
252
+ fill.position.set(-45, -18, 42);
253
+ scene.add(fill);
254
+
255
+ const rim = new THREE.PointLight(0xffffff, 1.4, 260);
256
+ rim.position.set(0, 0, 90);
257
+ scene.add(rim);
258
 
 
 
 
 
 
259
  const active = new Set(graph.active_path || []);
260
+ const nodeMeshes = {};
261
+ const palette = {
262
+ core: 0xff6b35,
263
+ domain: 0xff955f,
264
+ bridge: 0xff8a4c,
265
+ mechanism: 0xffb38f,
266
+ outcome: 0xffc7b3,
267
+ candidate: 0xff7b47
268
+ };
269
+
270
+ const nodeGeom = new THREE.SphereGeometry(3.2, 28, 28);
271
+ const haloGeom = new THREE.SphereGeometry(5.8, 28, 28);
272
 
273
  for(const n of graph.nodes || []){
274
+ const isActive = active.has(n.id);
275
+ const color = palette[n.group] || 0xd38d73;
276
+
277
+ const mat = new THREE.MeshStandardMaterial({
278
+ color,
279
+ emissive: isActive ? 0xff6b35 : color,
280
+ emissiveIntensity: isActive ? 1.9 : 0.28,
281
+ roughness: 0.22,
282
+ metalness: 0.1
283
+ });
284
+
285
  const mesh = new THREE.Mesh(nodeGeom, mat);
286
+ mesh.position.set(n.x || 0, n.y || 0, n.z || 0);
287
  scene.add(mesh);
288
  nodeMeshes[n.id] = mesh;
289
+
290
+ const halo = new THREE.Mesh(
291
+ haloGeom,
292
+ new THREE.MeshBasicMaterial({
293
+ color: isActive ? 0xff6b35 : color,
294
+ transparent: true,
295
+ opacity: isActive ? 0.14 : 0.05
296
+ })
297
+ );
298
+ halo.position.copy(mesh.position);
299
+ scene.add(halo);
300
+ mesh.userData.halo = halo;
301
  }
302
 
303
  function edgeActive(a,b){
304
  const path = graph.active_path || [];
305
  const ia = path.indexOf(a), ib = path.indexOf(b);
306
+ return ia >= 0 && ib >= 0 && Math.abs(ia - ib) === 1;
307
  }
308
 
309
  for(const e of graph.edges || []){
310
  const [a,b] = e;
311
  if(!nodeMeshes[a] || !nodeMeshes[b]) continue;
312
+
313
  const pts = [nodeMeshes[a].position, nodeMeshes[b].position];
314
  const geo = new THREE.BufferGeometry().setFromPoints(pts);
315
+ const isActive = edgeActive(a,b);
316
+
317
+ const line = new THREE.Line(
318
+ geo,
319
+ new THREE.LineBasicMaterial({
320
+ color: isActive ? 0xff6b35 : 0xd9c4bb,
321
+ transparent: true,
322
+ opacity: isActive ? 1.0 : 0.72
323
+ })
324
+ );
325
+
326
+ line.userData.active = isActive;
327
  scene.add(line);
328
  }
329
 
330
+ const starPositions = [];
331
+ for(let i = 0; i < 900; i++){
332
+ starPositions.push((Math.random() - 0.5) * 220);
333
+ starPositions.push((Math.random() - 0.5) * 220);
334
+ starPositions.push((Math.random() - 0.5) * 220);
335
+ }
336
+
337
  const stars = new THREE.Points(
338
+ new THREE.BufferGeometry().setAttribute(
339
+ 'position',
340
+ new THREE.Float32BufferAttribute(starPositions, 3)
341
+ ),
342
+ new THREE.PointsMaterial({
343
+ color: 0xf1b6a1,
344
+ size: 0.85,
345
+ transparent: true,
346
+ opacity: 0.55
347
+ })
348
  );
349
  scene.add(stars);
350
 
 
352
  function animate(){
353
  requestAnimationFrame(animate);
354
  const t = clock.getElapsedTime();
355
+
356
+ Object.values(nodeMeshes).forEach((m, i) => {
357
+ const pulse = 1 + Math.sin(t * 1.8 + i) * 0.06;
358
+ m.scale.setScalar(pulse);
359
  if(m.userData.halo){
360
+ const hs = 1 + (Math.sin(t * 2.3 + i) + 1) * 0.08;
361
+ m.userData.halo.scale.setScalar(hs);
362
  }
363
  });
364
+
365
+ stars.rotation.y += 0.0008;
366
  controls.update();
367
+ renderer.render(scene, camera);
368
  }
369
  animate();
370
 
371
+ const resize = () => {
372
  if(!root.clientWidth || !root.clientHeight) return;
373
  camera.aspect = root.clientWidth / root.clientHeight;
374
  camera.updateProjectionMatrix();
375
  renderer.setSize(root.clientWidth, root.clientHeight);
376
  };
377
+
378
  window.addEventListener('resize', resize, { passive:true });
379
  }
380