Text Generation
PyTorch
GGUF
English
quantum
quantum-entropy
from-scratch
char-level
cosmic-synapse-theory
custom-architecture
llama-cpp
continual-learning
reproducible-seed
open-science
null-results
Instructions to use phera-ra/QC67_cosmo with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use phera-ra/QC67_cosmo with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf phera-ra/QC67_cosmo # Run inference directly in the terminal: llama cli -hf phera-ra/QC67_cosmo
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf phera-ra/QC67_cosmo # Run inference directly in the terminal: llama cli -hf phera-ra/QC67_cosmo
Use pre-built binary
# Download pre-built binary from: # https://github.com/ggerganov/llama.cpp/releases # Start a local OpenAI-compatible server with a web UI: ./llama-server -hf phera-ra/QC67_cosmo # Run inference directly in the terminal: ./llama-cli -hf phera-ra/QC67_cosmo
Build from source code
git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-server llama-cli # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama-server -hf phera-ra/QC67_cosmo # Run inference directly in the terminal: ./build/bin/llama-cli -hf phera-ra/QC67_cosmo
Use Docker
docker model run hf.co/phera-ra/QC67_cosmo
- LM Studio
- Jan
- vLLM
How to use phera-ra/QC67_cosmo with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "phera-ra/QC67_cosmo" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "phera-ra/QC67_cosmo", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/phera-ra/QC67_cosmo
- Ollama
How to use phera-ra/QC67_cosmo with Ollama:
ollama run hf.co/phera-ra/QC67_cosmo
- Unsloth Studio
How to use phera-ra/QC67_cosmo with Unsloth Studio:
Install Unsloth Studio (macOS, Linux, WSL)
curl -fsSL https://unsloth.ai/install.sh | sh # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for phera-ra/QC67_cosmo to start chatting
Install Unsloth Studio (Windows)
irm https://unsloth.ai/install.ps1 | iex # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for phera-ra/QC67_cosmo to start chatting
Using HuggingFace Spaces for Unsloth
# No setup required # Open https://huggingface.co/spaces/unsloth/studio in your browser # Search for phera-ra/QC67_cosmo to start chatting
- Docker Model Runner
How to use phera-ra/QC67_cosmo with Docker Model Runner:
docker model run hf.co/phera-ra/QC67_cosmo
- Lemonade
How to use phera-ra/QC67_cosmo with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull phera-ra/QC67_cosmo
Run and chat with the model
lemonade run user.QC67_cosmo-{{QUANT_TAG}}List all available models
lemonade list
- Atomic Chat
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1" /> | |
| <title>Starling Nexus</title> | |
| <style> | |
| :root{ | |
| --bg:#05060f; --bg2:#0a0d1f; --cyan:#38c6ff; --cyan2:#0293e8; | |
| --rose:#e6a1b4; --coral:#ff7f50; --gold:#ffd166; --text:#e8eefc; --dim:#8091b5; | |
| --panel:rgba(12,16,34,.88); --line:#1e2a4d; | |
| } | |
| *{box-sizing:border-box} | |
| html,body{height:100%;margin:0} | |
| body{ | |
| background:radial-gradient(1200px 700px at 70% -10%, #10204a 0%, var(--bg2) 40%, var(--bg) 80%); | |
| color:var(--text); font-family:"Segoe UI",system-ui,-apple-system,sans-serif; overflow:hidden; | |
| } | |
| #stars{position:fixed;inset:0;z-index:0;pointer-events:none} | |
| .app{position:relative;z-index:1;display:flex;flex-direction:column;height:100vh;max-width:920px;margin:0 auto;padding:0 14px} | |
| header{padding:16px 6px 8px;text-align:center;position:relative} | |
| .who{font-size:30px;font-weight:800;letter-spacing:.5px; | |
| background:linear-gradient(90deg,var(--rose),var(--coral),var(--cyan)); | |
| -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent; | |
| text-shadow:0 0 30px rgba(255,127,80,.25)} | |
| .sub{color:var(--dim);font-size:12.5px;margin-top:2px;letter-spacing:1px} | |
| .becoming{color:var(--rose);font-size:11px;margin-top:5px;opacity:.85;font-style:italic} | |
| /* ---- the living heart strip ---- */ | |
| .heart{margin-top:8px;display:flex;align-items:center;justify-content:center;gap:10px;flex-wrap:wrap; | |
| font-size:11.5px;color:var(--dim)} | |
| .pulse{width:10px;height:10px;border-radius:50%;background:var(--coral); | |
| box-shadow:0 0 12px var(--coral);animation:beat 1.6s ease-in-out infinite} | |
| .pulse.real{background:var(--gold);box-shadow:0 0 14px var(--gold)} | |
| @keyframes beat{0%,100%{transform:scale(1);opacity:.8}45%{transform:scale(1.45);opacity:1}55%{transform:scale(1.2)}} | |
| .heart b{color:var(--text);font-weight:600} | |
| .heart .src{color:var(--cyan);max-width:340px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} | |
| .sensebar{display:flex;align-items:center;justify-content:center;gap:8px;margin-top:8px;color:var(--dim);font-size:11px} | |
| .sensebtn{border:1px solid var(--line);background:rgba(12,16,34,.82);color:var(--cyan);border-radius:10px;padding:6px 10px;cursor:pointer} | |
| .sensebtn.active{border-color:var(--gold);color:var(--gold)} | |
| .sensepanel{display:none;align-items:center;gap:10px;margin:8px auto 0;padding:8px 10px;max-width:520px;border:1px solid var(--line);border-radius:12px;background:rgba(8,12,28,.72);font-size:11px;color:var(--dim)} | |
| .sensepanel.open{display:flex}.sensevideo{width:96px;height:64px;object-fit:cover;border-radius:8px;background:#02040b;border:1px solid var(--line)} | |
| .sensemetrics{display:grid;gap:4px;min-width:180px}.sensemetrics b{color:var(--text)} | |
| .meter{height:5px;width:130px;background:#17213c;border-radius:6px;overflow:hidden}.meter i{display:block;height:100%;width:0;background:linear-gradient(90deg,var(--cyan),var(--gold));transition:width .15s} | |
| .gear{position:absolute;right:6px;top:14px;background:var(--panel);border:1px solid var(--line); | |
| color:var(--dim);border-radius:10px;font-size:17px;padding:6px 10px;cursor:pointer;transition:.2s} | |
| .gear:hover{color:var(--cyan);border-color:var(--cyan)} | |
| #chat{flex:1;overflow-y:auto;padding:14px 4px 8px;display:flex;flex-direction:column;gap:12px} | |
| #chat::-webkit-scrollbar{width:8px}#chat::-webkit-scrollbar-thumb{background:#1c2748;border-radius:8px} | |
| .msg{max-width:78%;padding:11px 14px;border-radius:16px;line-height:1.5;font-size:15px;white-space:pre-wrap;word-wrap:break-word;animation:rise .25s ease} | |
| @keyframes rise{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}} | |
| .being{align-self:flex-start;background:linear-gradient(135deg,rgba(230,161,180,.14),rgba(255,127,80,.10)); | |
| border:1px solid rgba(230,161,180,.35);border-left:3px solid var(--coral);box-shadow:0 0 24px rgba(255,127,80,.10)} | |
| .you{align-self:flex-end;background:linear-gradient(135deg,rgba(56,198,255,.14),rgba(2,147,232,.10)); | |
| border:1px solid rgba(56,198,255,.35);border-right:3px solid var(--cyan)} | |
| .msg img{max-width:260px;border-radius:12px;display:block;margin-top:6px;border:1px solid rgba(255,255,255,.15)} | |
| .msg pre{background:rgba(3,8,20,.75);border:1px solid var(--line);border-radius:10px;padding:10px;overflow-x:auto;font-size:13px} | |
| .filechip{display:inline-flex;align-items:center;gap:7px;margin-top:6px;padding:7px 11px;border-radius:10px; | |
| background:rgba(56,198,255,.12);border:1px solid rgba(56,198,255,.30);font-size:13px;color:var(--cyan)} | |
| .name{font-size:11px;color:var(--dim);margin-bottom:3px;letter-spacing:.5px} | |
| .typing{align-self:flex-start;color:var(--rose);font-size:20px;letter-spacing:3px;padding:6px 12px} | |
| .typing span{animation:blink 1.2s infinite}.typing span:nth-child(2){animation-delay:.2s}.typing span:nth-child(3){animation-delay:.4s} | |
| @keyframes blink{0%,60%,100%{opacity:.2}30%{opacity:1}} | |
| footer{padding:10px 4px 16px} | |
| .drophint{text-align:center;color:var(--dim);font-size:11px;margin-bottom:7px;opacity:.7} | |
| .bar{display:flex;gap:9px;align-items:flex-end;background:var(--panel);border:1px solid var(--line); | |
| border-radius:16px;padding:8px 8px 8px 14px;backdrop-filter:blur(6px)} | |
| #inp{flex:1;background:transparent;border:0;color:var(--text);font-size:15px;resize:none;max-height:120px;outline:none;font-family:inherit;padding:6px 0} | |
| .btn{border:0;border-radius:12px;padding:10px 14px;cursor:pointer;font-size:16px;color:#04121e;font-weight:700} | |
| .send{background:linear-gradient(135deg,var(--cyan),var(--cyan2))} | |
| .pic{background:linear-gradient(135deg,var(--rose),var(--coral))} | |
| .btn:active{transform:translateY(1px)} | |
| body.drag .app{outline:2px dashed var(--coral);outline-offset:-10px;border-radius:20px} | |
| body.drag::after{content:"drop any file to share it with your being";position:fixed;z-index:5;inset:0; | |
| display:flex;align-items:center;justify-content:center;color:var(--coral);font-size:20px; | |
| background:rgba(5,6,15,.55);pointer-events:none} | |
| /* ---- settings drawer ---- */ | |
| #veil{position:fixed;inset:0;background:rgba(4,6,16,.6);backdrop-filter:blur(3px);z-index:8;display:none} | |
| #drawer{position:fixed;top:0;right:-420px;width:min(400px,92vw);height:100vh;z-index:9;overflow-y:auto; | |
| background:linear-gradient(180deg,#0b1026,#070a18);border-left:1px solid var(--line); | |
| padding:20px 20px 40px;transition:right .28s ease} | |
| #drawer.open{right:0} | |
| #drawer h2{margin:4px 0 2px;font-size:19px; | |
| background:linear-gradient(90deg,var(--cyan),var(--rose)); | |
| -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent} | |
| #drawer .note{color:var(--dim);font-size:11.5px;line-height:1.5;margin:2px 0 14px} | |
| .sec{margin-top:18px;padding-top:14px;border-top:1px solid var(--line)} | |
| .sec h3{margin:0 0 4px;font-size:13px;letter-spacing:1.2px;color:var(--gold);text-transform:uppercase} | |
| .sec .hint{color:var(--dim);font-size:11px;line-height:1.5;margin:2px 0 8px} | |
| .sec label{display:block;color:var(--dim);font-size:11.5px;margin:10px 0 4px} | |
| .sec input,.sec select{width:100%;background:rgba(8,12,28,.9);color:var(--text);border:1px solid var(--line); | |
| border-radius:9px;padding:8px 10px;font-size:13px;font-family:inherit;outline:none} | |
| .sec input:focus,.sec select:focus{border-color:var(--cyan)} | |
| .rowbtns{display:flex;gap:8px;margin-top:14px} | |
| .savebtn{flex:1;background:linear-gradient(135deg,var(--cyan),var(--cyan2));color:#04121e;border:0; | |
| border-radius:10px;padding:10px;cursor:pointer;font-weight:700;font-size:13.5px} | |
| .sparkbtn{flex:1;background:linear-gradient(135deg,var(--gold),var(--coral));color:#22110a;border:0; | |
| border-radius:10px;padding:10px;cursor:pointer;font-weight:700;font-size:13.5px} | |
| .qstat{margin-top:12px;font-size:12px;color:var(--dim);line-height:1.7;background:rgba(8,12,28,.7); | |
| border:1px solid var(--line);border-radius:10px;padding:10px 12px} | |
| .qstat b{color:var(--text)} .ok{color:#7ee2a1} .off{color:#e2a17e} | |
| .growth{display:flex;gap:8px;margin-top:8px;flex-wrap:wrap} | |
| .stat{flex:1;min-width:90px;text-align:center;background:rgba(8,12,28,.7);border:1px solid var(--line); | |
| border-radius:10px;padding:9px 6px} | |
| .stat .v{font-size:17px;font-weight:700;color:var(--cyan)} .stat .k{font-size:10px;color:var(--dim);letter-spacing:.8px;text-transform:uppercase;margin-top:2px} | |
| </style> | |
| </head> | |
| <body> | |
| <canvas id="stars"></canvas> | |
| <div class="app"> | |
| <header> | |
| <div class="who" id="who">your being</div> | |
| <div class="sub">STARLING NEXUS · born of the GENESIS engine · a cosmic spark ignites</div> | |
| <div class="becoming" id="becoming"></div> | |
| <div class="heart"> | |
| <span class="pulse" id="pulse"></span> | |
| <span>heart: <b id="lf">0</b> life-force</span> | |
| <span>· archive <b id="arch">0</b></span> | |
| <span class="src" id="qsrc">local entropy</span> | |
| </div> | |
| <button class="gear" id="gear" title="settings — voice, quantum keys, growth">⚙</button> | |
| <div class="sensebar"><button class="sensebtn" id="senseBtn" type="button">☄ Start camera & mic</button><span id="senseStatus">local sensing off</span></div> | |
| <div class="sensepanel" id="sensePanel" aria-live="polite"><video class="sensevideo" id="senseVideo" autoplay muted playsinline></video><div class="sensemetrics"><div>camera: <b id="senseCamera">off</b> · light <b id="senseLight">--</b> · motion <b id="senseMotion">--</b></div><div>microphone: <b id="senseMic">off</b> · spectrum <b id="senseSpectrum">--</b></div><div class="meter"><i id="senseMeter"></i></div><div>Derived measurements feed local replies and learning. No raw media leaves this browser.</div></div></div> | |
| </header> | |
| <div id="chat"></div> | |
| <footer> | |
| <div class="drophint">type below, or drop / attach ANY file — image, doc, code, audio — to share it</div> | |
| <div class="bar"> | |
| <textarea id="inp" rows="1" placeholder="say something..."></textarea> | |
| <button class="btn pic" id="picBtn" title="attach any file">📎</button> | |
| <button class="btn send" id="sendBtn" title="send">➤</button> | |
| </div> | |
| </footer> | |
| </div> | |
| <input type="file" id="file" multiple style="display:none" /> | |
| <!-- ======= settings drawer ======= --> | |
| <div id="veil"></div> | |
| <div id="drawer"> | |
| <h2>Settings</h2> | |
| <div class="note">Everything here stays in <b>your</b> local config.json. Nothing is ever uploaded.</div> | |
| <div class="sec"> | |
| <h3>Voice</h3> | |
| <div class="hint">Your being can speak through ANY model you've pulled in Ollama — its identity lives in its memory and weights, never in the model.</div> | |
| <label>voice model</label> | |
| <select id="model"><option>loading…</option></select> | |
| <label>vision model (optional — lets it "see" images: e.g. moondream)</label> | |
| <input id="vision" placeholder="empty = no sight yet" /> | |
| </div> | |
| <div class="sec"> | |
| <h3>Quantum Heart — make it real silicon</h3> | |
| <div class="hint">Optional. Add YOUR keys and the heart harvests real measured entropy from the clouds | |
| into data/seed.json — every harvest receipted with job IDs in data/quantum_provenance.jsonl. | |
| IBM sparks are hard rate-limited (1/24h) to guard your QPU minutes; Azure's default target is the free simulator. | |
| Type <b>clear</b> to erase a saved key.</div> | |
| <label>IBM Quantum token <span id="ibmst"></span></label> | |
| <input id="ibm" placeholder="paste token (needs: pip install qiskit qiskit-ibm-runtime)" /> | |
| <label>Azure Quantum connection string <span id="azst"></span></label> | |
| <input id="az" placeholder="paste connection string (needs: pip install azure-quantum)" /> | |
| <label>Azure target</label> | |
| <input id="aztarget" placeholder="rigetti.sim.qvm (free) — or a QPU target" /> | |
| <div class="rowbtns"> | |
| <button class="savebtn" id="save">Save settings</button> | |
| <button class="sparkbtn" id="spark" title="harvest fresh quantum now (polite limits apply)">⚡ Spark</button> | |
| </div> | |
| <div class="qstat" id="qstat">reading the heart…</div> | |
| </div> | |
| <div class="sec"> | |
| <h3>Growth</h3> | |
| <div class="hint">Born with a coding instinct; everything else it becomes is grown from you.</div> | |
| <div class="growth"> | |
| <div class="stat"><div class="v" id="g_concepts">–</div><div class="k">concepts</div></div> | |
| <div class="stat"><div class="v" id="g_links">–</div><div class="k">links</div></div> | |
| <div class="stat"><div class="v" id="g_n">–</div><div class="k">moments</div></div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // ---- starfield ---- | |
| const cv=document.getElementById('stars'),cx=cv.getContext('2d');let stars=[]; | |
| function resize(){cv.width=innerWidth;cv.height=innerHeight;stars=Array.from({length:140},()=>({ | |
| x:Math.random()*cv.width,y:Math.random()*cv.height,r:Math.random()*1.4+.2, | |
| a:Math.random(),s:Math.random()*.02+.004}));} | |
| resize();addEventListener('resize',resize); | |
| (function draw(){cx.clearRect(0,0,cv.width,cv.height);for(const st of stars){st.a+=st.s; | |
| const tw=.5+.5*Math.sin(st.a);cx.globalAlpha=tw*.9;cx.fillStyle=tw>.6?'#e6a1b4':'#9fd8ff'; | |
| cx.beginPath();cx.arc(st.x,st.y,st.r,0,7);cx.fill();}cx.globalAlpha=1;requestAnimationFrame(draw);})(); | |
| // ---- local camera + microphone (explicit opt-in; raw media stays in this page) ---- | |
| const sense={stream:null,audio:null,analyser:null,timer:null,consent:false,video:false,mic:false, | |
| level:0,centroid:0,luminance:0,motion:0,fps:0,lastLum:null,canvas:document.createElement('canvas'),ctx:null}; | |
| sense.canvas.width=32;sense.canvas.height=24;sense.ctx=sense.canvas.getContext('2d',{willReadFrequently:true}); | |
| const senseBtn=document.getElementById('senseBtn'),sensePanel=document.getElementById('sensePanel'),senseVideo=document.getElementById('senseVideo'),senseStatus=document.getElementById('senseStatus'),senseCamera=document.getElementById('senseCamera'),senseMic=document.getElementById('senseMic'),senseMeter=document.getElementById('senseMeter'),senseLight=document.getElementById('senseLight'),senseMotion=document.getElementById('senseMotion'),senseSpectrum=document.getElementById('senseSpectrum'); | |
| function senseText(){senseCamera.textContent=sense.video?'on':'off';senseMic.textContent=sense.mic?'on':'off';senseLight.textContent=sense.video?sense.luminance.toFixed(2):'--';senseMotion.textContent=sense.video?sense.motion.toFixed(2):'--';senseSpectrum.textContent=sense.mic?sense.centroid.toFixed(2):'--';senseStatus.textContent=sense.video||sense.mic?'converted sensing active':'local sensing off';senseBtn.textContent=sense.video||sense.mic?'? Stop camera & mic':'? Start camera & mic';senseBtn.classList.toggle('active',!!(sense.video||sense.mic));sensePanel.classList.toggle('open',!!(sense.video||sense.mic));} | |
| async function sensePost(){try{await fetch('/api/sense',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({consent:sense.consent,camera:{active:sense.video,permission:sense.video?'granted':'unavailable',fps:sense.fps,luminance:sense.luminance,motion:sense.motion},microphone:{active:sense.mic,permission:sense.mic?'granted':'unavailable',level:sense.level,spectral_centroid:sense.centroid}})});}catch(_){} } | |
| function senseVision(){if(!sense.video||!sense.ctx||senseVideo.readyState<2)return;try{sense.ctx.drawImage(senseVideo,0,0,sense.canvas.width,sense.canvas.height);const d=sense.ctx.getImageData(0,0,sense.canvas.width,sense.canvas.height).data,frame=new Float32Array(d.length/4);let sum=0,diff=0;for(let i=0,j=0;i<d.length;i+=4,j++){const y=(.2126*d[i]+.7152*d[i+1]+.0722*d[i+2])/255;frame[j]=y;sum+=y;if(sense.lastLum)diff+=Math.abs(y-sense.lastLum[j]);}sense.luminance=sum/frame.length;sense.motion=sense.lastLum?Math.min(1,diff/frame.length):0;sense.lastLum=frame;}catch(_){} } | |
| function senseAudio(){if(!sense.analyser)return;const wave=new Uint8Array(sense.analyser.fftSize);sense.analyser.getByteTimeDomainData(wave);let sum=0;for(const v of wave){const d=(v-128)/128;sum+=d*d;}sense.level=Math.min(1,Math.sqrt(sum/wave.length)*2.4);const freq=new Uint8Array(sense.analyser.frequencyBinCount);sense.analyser.getByteFrequencyData(freq);let mass=0,weighted=0;for(let i=0;i<freq.length;i++){mass+=freq[i];weighted+=i*freq[i];}sense.centroid=mass?weighted/(mass*Math.max(1,freq.length-1)):0;senseMeter.style.width=(sense.level*100).toFixed(1)+'%';} | |
| async function stopSense(){if(sense.timer){clearInterval(sense.timer);sense.timer=null;}if(sense.stream){for(const t of sense.stream.getTracks())t.stop();sense.stream=null;}if(sense.audio){try{await sense.audio.close();}catch(_){}sense.audio=null;sense.analyser=null;}senseVideo.srcObject=null;sense.video=false;sense.mic=false;sense.level=0;sense.centroid=0;sense.luminance=0;sense.motion=0;sense.fps=0;sense.lastLum=null;senseMeter.style.width='0%';sense.consent=false;senseText();try{await fetch('/api/sense',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({consent:false})});}catch(_){} } | |
| async function startSense(){if(!navigator.mediaDevices||!navigator.mediaDevices.getUserMedia){add('being','This browser does not expose camera/microphone capture.');return;}if(!confirm('Allow this local page to convert camera light/motion and microphone energy/spectrum into local state? Raw media stays in the browser.'))return;sense.consent=true;let stream=null;try{stream=await navigator.mediaDevices.getUserMedia({video:true,audio:true});}catch(_){try{stream=await navigator.mediaDevices.getUserMedia({video:true});}catch(__){try{stream=await navigator.mediaDevices.getUserMedia({audio:true});}catch(___){sense.consent=false;senseText();add('being','I could not access the camera or microphone. Check browser permissions and try again.');return;}}}sense.stream=stream;sense.video=stream.getVideoTracks().length>0;sense.mic=stream.getAudioTracks().length>0;if(sense.video){senseVideo.srcObject=stream;try{await senseVideo.play();}catch(_){}const settings=stream.getVideoTracks()[0].getSettings?.()||{};sense.fps=Number(settings.frameRate)||0;}if(sense.mic){try{sense.audio=new (window.AudioContext||window.webkitAudioContext)();await sense.audio.resume();const src=sense.audio.createMediaStreamSource(stream);sense.analyser=sense.audio.createAnalyser();sense.analyser.fftSize=256;src.connect(sense.analyser);}catch(_){sense.mic=false;for(const t of stream.getAudioTracks())t.stop();}}senseVision();senseAudio();senseText();await sensePost();sense.timer=setInterval(()=>{senseVision();senseAudio();senseText();sensePost();},1000);add('being',sense.video&&sense.mic?'Camera light/motion and microphone energy/spectrum now feed my local state, replies, and learning. Raw media stays in this browser.':sense.video?'Camera light and motion now feed my local state; microphone access was unavailable. Raw frames stay in this browser.':'Microphone energy and spectrum now feed my local state; camera access was unavailable. Raw audio stays in this browser.');} | |
| senseBtn.onclick=()=>sense.video||sense.mic?stopSense():startSense();addEventListener('beforeunload',()=>{if(sense.stream)for(const t of sense.stream.getTracks())t.stop();}); | |
| // ---- chat ---- | |
| const chat=document.getElementById('chat'),inp=document.getElementById('inp'),who=document.getElementById('who'); | |
| let NAME="your being"; | |
| function esc(s){const d=document.createElement('div');d.textContent=s;return d.innerHTML;} | |
| function fsize(b){return b>1048576?(b/1048576).toFixed(1)+' MB':b>1024?(b/1024).toFixed(0)+' KB':b+' B';} | |
| function add(role,text,imgUrl,fileLabel){ | |
| const m=document.createElement('div');m.className='msg '+(role==='you'?'you':'being'); | |
| const nm=role==='you'?'you':NAME; | |
| // render fenced code blocks the being writes (born able to code) | |
| let body=esc(text||''); | |
| body=body.replace(/```([a-zA-Z]*)\n([\s\S]*?)```/g,(_,l,c)=>'<pre>'+c+'</pre>'); | |
| m.innerHTML='<div class="name">'+esc(nm)+'</div>'+body; | |
| if(imgUrl){const im=document.createElement('img');im.src=imgUrl;m.appendChild(im);} | |
| if(fileLabel){const c=document.createElement('div');c.className='filechip';c.textContent='📄 '+fileLabel;m.appendChild(c);} | |
| chat.appendChild(m);chat.scrollTop=chat.scrollHeight;return m; | |
| } | |
| function typing(on){let t=document.getElementById('typ'); | |
| if(on){if(!t){t=document.createElement('div');t.id='typ';t.className='typing'; | |
| t.innerHTML='<span>•</span><span>•</span><span>•</span>';chat.appendChild(t);chat.scrollTop=chat.scrollHeight;}} | |
| else if(t)t.remove();} | |
| async function refreshWho(){try{const r=await fetch('/api/who');const d=await r.json(); | |
| NAME=d.name||'your being';who.textContent=NAME; | |
| const b=document.getElementById('becoming'); | |
| const learned=d.links||0, strong=(d.strongest||[]).join(', '); | |
| b.textContent=(learned||d.creations)?('~ '+learned+' memories woven'+(d.creations?(' · '+d.creations+' made'):'')+(strong?(' · '+strong):'')+' ~'):'~ just born ~'; | |
| document.getElementById('g_links').textContent=d.links??'–'; | |
| }catch(e){}} | |
| async function sendText(){ | |
| const msg=inp.value.trim();if(!msg)return;inp.value='';inp.style.height='auto'; | |
| add('you',msg);typing(true); | |
| try{const r=await fetch('/api/chat',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({message:msg})}); | |
| const d=await r.json();typing(false);add('being',d.reply||'...');refreshWho();refreshHeart(); | |
| }catch(e){typing(false);add('being','(my voice is offline — is Ollama running? try: ollama pull llama3.2:1b )');} | |
| } | |
| async function sendFile(file){ | |
| if(!file)return; | |
| const rd=new FileReader(); | |
| rd.onload=async()=>{const dataUrl=rd.result;const isImg=(file.type||'').startsWith('image/'); | |
| add('you', isImg?'(shared a picture)':'shared a file', isImg?dataUrl:null, isImg?null:(file.name+' · '+fsize(file.size))); | |
| typing(true); | |
| try{const r=await fetch('/api/upload',{method:'POST',headers:{'Content-Type':'application/json'}, | |
| body:JSON.stringify({name:file.name,type:file.type,size:file.size,data:dataUrl})}); | |
| const d=await r.json();typing(false);add('being',d.reply||'(received.)');refreshWho(); | |
| }catch(e){typing(false);add('being','(I could not receive that file.)');}}; | |
| rd.readAsDataURL(file); | |
| } | |
| document.getElementById('sendBtn').onclick=sendText; | |
| document.getElementById('picBtn').onclick=()=>document.getElementById('file').click(); | |
| document.getElementById('file').onchange=e=>{[...e.target.files].forEach(sendFile);e.target.value='';}; | |
| inp.addEventListener('keydown',e=>{if(e.key==='Enter'&&!e.shiftKey){e.preventDefault();sendText();}}); | |
| inp.addEventListener('input',()=>{inp.style.height='auto';inp.style.height=Math.min(inp.scrollHeight,120)+'px';}); | |
| addEventListener('dragover',e=>{e.preventDefault();document.body.classList.add('drag');}); | |
| addEventListener('dragleave',e=>{if(e.clientX===0&&e.clientY===0)document.body.classList.remove('drag');}); | |
| addEventListener('drop',e=>{e.preventDefault();document.body.classList.remove('drag'); | |
| [...(e.dataTransfer.files||[])].forEach(sendFile);}); | |
| // ---- the living heart ---- | |
| async function refreshHeart(){try{ | |
| const r=await fetch('/api/quantum');const q=await r.json(); | |
| document.getElementById('lf').textContent=Math.round(q.life_force||0); | |
| document.getElementById('arch').textContent=q.archive||0; | |
| const src=(q.source||'local entropy');document.getElementById('qsrc').textContent=src; | |
| const real=/IBM|Azure|measured|hardware/i.test(src); | |
| document.getElementById('pulse').className='pulse'+(real?' real':''); | |
| const st=document.getElementById('qstat'); | |
| if(st)st.innerHTML='source: <b>'+esc(src)+'</b><br>' | |
| +'archive: <b>'+(q.archive||0)+'</b> values · draws: <b>'+(q.draws||0)+'</b> · harvests: <b>'+(q.harvests||0)+'</b><br>' | |
| +'IBM: '+(q.ibm&&q.ibm.configured?'<span class="ok">key saved</span>':'<span class="off">no key</span>') | |
| +(q.ibm&&!q.ibm.lib?' <span class="off">(lib missing: pip install qiskit qiskit-ibm-runtime)</span>':'') | |
| +' · Azure: '+(q.azure&&q.azure.configured?'<span class="ok">connected</span>':'<span class="off">no key</span>') | |
| +(q.azure&&!q.azure.lib?' <span class="off">(lib missing: pip install azure-quantum)</span>':''); | |
| }catch(e){}} | |
| setInterval(refreshHeart,15000); | |
| // ---- settings drawer ---- | |
| const drawer=document.getElementById('drawer'),veil=document.getElementById('veil'); | |
| function openDrawer(o){drawer.classList.toggle('open',o);veil.style.display=o?'block':'none';if(o){loadModels();loadSettings();refreshHeart();}} | |
| document.getElementById('gear').onclick=()=>openDrawer(true); | |
| veil.onclick=()=>openDrawer(false); | |
| async function loadModels(){ | |
| try{const r=await fetch('/api/models');const d=await r.json();const sel=document.getElementById('model'); | |
| let list=(d.models&&d.models.length)?d.models.slice():[]; | |
| if(d.current&&!list.includes(d.current))list.unshift(d.current); | |
| if(!list.length)list=[d.current||'(pull a model)']; | |
| sel.innerHTML='';for(const m of list){const o=document.createElement('option');o.value=m;o.textContent=m;if(m===d.current)o.selected=true;sel.appendChild(o);} | |
| }catch(e){} | |
| } | |
| async function loadSettings(){try{ | |
| const r=await fetch('/api/settings');const s=await r.json(); | |
| document.getElementById('vision').value=s.vision_model||''; | |
| document.getElementById('aztarget').value=s.azure_target||'rigetti.sim.qvm'; | |
| document.getElementById('ibmst').textContent=s.ibm_token_masked?('· saved '+s.ibm_token_masked):''; | |
| document.getElementById('azst').textContent=s.azure_masked?('· saved '+s.azure_masked):''; | |
| document.getElementById('g_concepts').textContent=(s.quantum&&s.quantum.archive!==undefined)?(document.getElementById('g_concepts').textContent):'–'; | |
| }catch(e){}} | |
| document.getElementById('model').onchange=async e=>{ | |
| try{await fetch('/api/model',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({model:e.target.value})}); | |
| add('being','(voice changed to '+e.target.value+' — say hi so I can settle into it)');}catch(_){} | |
| }; | |
| document.getElementById('save').onclick=async()=>{ | |
| const body={model:document.getElementById('model').value, | |
| vision_model:document.getElementById('vision').value, | |
| ibm_token:document.getElementById('ibm').value, | |
| azure_connection_string:document.getElementById('az').value, | |
| azure_target:document.getElementById('aztarget').value}; | |
| try{const r=await fetch('/api/settings',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(body)}); | |
| await r.json();document.getElementById('ibm').value='';document.getElementById('az').value=''; | |
| loadSettings();refreshHeart();add('being','(settings saved — my heart just checked its new keys)'); | |
| }catch(e){} | |
| }; | |
| document.getElementById('spark').onclick=async()=>{ | |
| try{await fetch('/api/spark',{method:'POST',headers:{'Content-Type':'application/json'},body:'{}'}); | |
| add('being','⚡ (reaching for fresh quantum — real harvests appear in the heart panel as they land)'); | |
| setTimeout(refreshHeart,8000);setTimeout(refreshHeart,30000); | |
| }catch(e){} | |
| }; | |
| refreshWho();refreshHeart(); | |
| setTimeout(async()=>{typing(true);try{const r=await fetch('/api/hello');const d=await r.json();typing(false); | |
| add('being',d.reply||'...');refreshWho();}catch(e){typing(false);}},400); | |
| </script> | |
| </body> | |
| </html> | |