Taylor commited on
Commit
354d478
·
1 Parent(s): 4ee26f9

feat: edge mesh gateway client

Browse files

Routes through the Aether mesh: Local WASM > CF Workers > Cloud Run.
Shows live mesh status (which layer is responding).
Every HF Space visitor smoketests the inference mesh.
No downloads, instant start, streaming SSE output.

Replaces client-side 385MB model download with edge gateway call.

Files changed (2) hide show
  1. aether-engine.js +0 -50
  2. index.html +189 -21
aether-engine.js DELETED
@@ -1,50 +0,0 @@
1
- const WASM_B64="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";
2
- // Decode base64 WASM
3
- function b64(s){const b=atob(s);const u=new Uint8Array(b.length);for(let i=0;i<b.length;i++)u[i]=b.charCodeAt(i);return u;}
4
- // Config
5
- const C={hiddenDim:960,numLayers:32,numHeads:15,numKvHeads:5,headDim:64,intermediateSize:2560,vocabSize:49152,ropeTheta:100000,rmsNormEps:1e-5,eosToken:2};
6
- const kvDim=C.numKvHeads*C.headDim,gqaRatio=C.numHeads/C.numKvHeads;
7
- let simd=null,model=null;
8
- const $=id=>document.getElementById(id);
9
- function status(m,c){$('st').textContent=m;$('st').className='st '+c;}
10
- function prog(p){$('pg').style.width=p+'%';}
11
-
12
- // WASM SIMD loader
13
- async function loadSIMD(){try{const w=b64(WASM_B64);const{instance}=await WebAssembly.instantiate(w,{env:{expf:Math.exp,tanhf:Math.tanh,powf:Math.pow}});const e=instance.exports;e.resetHeap(65536);const m=e.memory;const hf=()=>new Float32Array(m.buffer);const cp=(p,f)=>hf().set(f,p>>2);const rd=(p,n)=>hf().slice(p>>2,(p>>2)+n);const wr=fn=>(...a)=>{const s=e.getHeapPtr();try{return fn(s,...a)}finally{e.resetHeap(s)}};return{matVec:wr((s,mt,vc,r,c)=>{if(mt.byteLength>1e8)return mvJS(mt,vc,r,c);const mp=e.allocate(mt.byteLength),vp=e.allocate(vc.byteLength),rp=e.allocate(r*4);cp(mp,mt);cp(vp,vc);e.matVecSimdBatch4(mp,vp,rp,r,c);return rd(rp,r)}),rmsNorm:wr((s,x,w,eps)=>{const xp=e.allocate(x.byteLength),wp=e.allocate(w.byteLength),rp=e.allocate(x.byteLength);cp(xp,x);cp(wp,w);e.rmsNormSimd(xp,wp,rp,x.length,eps);return rd(rp,x.length)}),softmax:wr((s,x)=>{const xp=e.allocate(x.byteLength),rp=e.allocate(x.byteLength);cp(xp,x);e.softmaxSimd(xp,rp,x.length);return rd(rp,x.length)}),fusedSiluMul:wr((s,g,u)=>{const gp=e.allocate(g.byteLength),up=e.allocate(u.byteLength),rp=e.allocate(g.byteLength);cp(gp,g);cp(up,u);e.fusedSiluMul(gp,up,rp,g.length);return rd(rp,g.length)}),add:wr((s,a,b)=>{const ap=e.allocate(a.byteLength),bp=e.allocate(b.byteLength),rp=e.allocate(a.byteLength);cp(ap,a);cp(bp,b);e.addSimd(ap,bp,rp,a.length);return rd(rp,a.length)})}}catch(e){return null}}
14
-
15
- // JS fallbacks
16
- function mvJS(m,v,r,c){const o=new Float32Array(r);for(let i=0;i<r;i++){let s=0;const off=i*c;for(let j=0;j<c;j++)s+=m[off+j]*v[j];o[i]=s}return o}
17
- function rnJS(x,w,e){let s=0;for(let i=0;i<x.length;i++)s+=x[i]*x[i];s=1/Math.sqrt(s/x.length+e);const o=new Float32Array(x.length);for(let i=0;i<x.length;i++)o[i]=x[i]*s*w[i];return o}
18
- function smJS(x){let m=-Infinity;for(let i=0;i<x.length;i++)if(x[i]>m)m=x[i];const o=new Float32Array(x.length);let s=0;for(let i=0;i<x.length;i++){o[i]=Math.exp(x[i]-m);s+=o[i]}for(let i=0;i<x.length;i++)o[i]/=s;return o}
19
- function fsmJS(g,u){const o=new Float32Array(g.length);for(let i=0;i<g.length;i++){const v=g[i];o[i]=(v/(1+Math.exp(-v)))*u[i]}return o}
20
- function addJS(a,b){const o=new Float32Array(a.length);for(let i=0;i<a.length;i++)o[i]=a[i]+b[i];return o}
21
- const op=()=>({matVec:simd?.matVec||mvJS,rmsNorm:simd?.rmsNorm||rnJS,softmax:simd?.softmax||smJS,fusedSiluMul:simd?.fusedSiluMul||fsmJS,add:simd?.add||addJS});
22
-
23
- // Q8_0 dequant
24
- function fp16(lo,hi){const h=lo|(hi<<8),s=(h>>15)&1,e=(h>>10)&0x1f,f=h&0x3ff;if(e===0)return f===0?0:(s?-1:1)*(f/1024)*Math.pow(2,-14);if(e===31)return 0;return(s?-1:1)*Math.pow(2,e-15)*(1+f/1024)}
25
- function dqQ8(d,n){const o=new Float32Array(n);for(let b=0;b<Math.ceil(n/32);b++){const off=b*34,sc=fp16(d[off],d[off+1]);for(let i=0;i<Math.min(32,n-b*32);i++){const v=d[off+2+i];o[b*32+i]=(v>127?v-256:v)*sc}}return o}
26
- function dq(d,n,t){if(t===0)return new Float32Array(d.buffer,d.byteOffset,n);if(t===8)return dqQ8(d,n);return dqQ8(d,n)}
27
-
28
- // GGUF parser
29
- const BSZ={2:32,3:32,6:32,7:32,8:32,9:32,10:256,11:256,12:256,13:256,14:256,15:256};
30
- const BBY={2:18,3:20,6:22,7:24,8:34,9:36,10:84,11:110,12:144,13:176,14:210,15:292};
31
- const TSZ={0:4,1:2,16:1,17:2,18:4,19:8,20:8};
32
- function csz(d,t){let n=1n;for(const x of d)n*=x;const b=BSZ[t];if(b&&BBY[t])return Math.ceil(Number(n)/b)*BBY[t];return Math.ceil(Number(n)*(TSZ[t]??4))}
33
- function skipV(v,o,t){switch(t){case 0:case 1:case 7:return o+1;case 2:case 3:return o+2;case 4:case 5:case 6:return o+4;case 10:case 11:case 12:return o+8;case 8:return o+8+Number(v.getBigUint64(o,true));case 9:{const at=v.getUint32(o,true),al=Number(v.getBigUint64(o+4,true));let c=o+12;for(let i=0;i<al;i++)c=skipV(v,c,at);return c}default:throw new Error('bad type '+t)}}
34
- function parseGGUF(buf){const v=new DataView(buf);let o=0;if(v.getUint32(o,true)!==0x46554747)throw new Error('Not GGUF');o+=4;o+=4;const tc=Number(v.getBigUint64(o,true));o+=8;const kc=Number(v.getBigUint64(o,true));o+=8;for(let i=0;i<kc;i++){const kl=Number(v.getBigUint64(o,true));o+=8+kl;const vt=v.getUint32(o,true);o+=4;o=skipV(v,o,vt)}const ts=[];for(let i=0;i<tc;i++){const nl=Number(v.getBigUint64(o,true));o+=8;let nm='';for(let j=0;j<nl;j++)nm+=String.fromCharCode(v.getUint8(o+j));o+=nl;const nd=v.getUint32(o,true);o+=4;const dims=[];for(let d=0;d<nd;d++){dims.push(v.getBigUint64(o,true));o+=8}const tp=v.getUint32(o,true);o+=4;const of2=v.getBigUint64(o,true);o+=8;ts.push({name:nm,dims,type:tp,offset:of2,size:csz(dims,tp),numElements:Number(dims.reduce((a,b)=>a*b,1n))})}return{tensors:ts,dataOffset:Math.ceil(o/32)*32}}
35
-
36
- // Tokenizer
37
- class Tok{constructor(j){const m=j.model||{};this.vocab=m.vocab||{};this.rev={};for(const[t,id]of Object.entries(this.vocab))this.rev[id]=t;this.mr={};for(const[i,mg]of(m.merges||[]).entries())this.mr[mg]=i;this.added={};if(j.added_tokens)for(const t of j.added_tokens)this.added[t.content]=t.id}encode(text){const sp=/<\|[^|]+\|>/g;const parts=[];let last=0,m;while((m=sp.exec(text))!==null){if(m.index>last)parts.push({t:text.slice(last,m.index),s:false});parts.push({t:m[0],s:true});last=m.index+m[0].length}if(last<text.length)parts.push({t:text.slice(last),s:false});const tokens=[];for(const p of parts){if(p.s){const id=this.added[p.t]??this.vocab[p.t];if(id!==undefined)tokens.push(id);continue}const words=p.t.match(/\S+|\s+/g)||[];for(const w of words){let syms=[];for(const ch of w){if(this.vocab[ch]!==undefined)syms.push(ch);else{const enc=new TextEncoder().encode(ch);for(const b of enc)syms.push(`<0x${b.toString(16).toUpperCase().padStart(2,'0')}>`)}}while(syms.length>1){let best=Infinity,bi=-1;for(let i=0;i<syms.length-1;i++){const r=this.mr[`${syms[i]} ${syms[i+1]}`];if(r!==undefined&&r<best){best=r;bi=i}}if(bi===-1)break;syms.splice(bi,2,syms[bi]+syms[bi+1])}for(const s of syms){const id=this.vocab[s]??this.added[s];if(id!==undefined)tokens.push(id)}}}return tokens}decode(tokens){const p=[];for(const t of tokens){const s=this.rev[t];if(s&&s.startsWith('<0x')&&s.endsWith('>'))p.push(String.fromCharCode(parseInt(s.slice(3,-1),16)));else if(s&&!s.startsWith('<|'))p.push(s)}return p.join('').replace(/Ġ/g,' ').replace(/Ċ/g,'\n')}}
38
-
39
- // RoPE (LLaMA adjacent)
40
- function rope(x,hd,pos,theta){for(let i=0;i<hd;i+=2){const fr=1/Math.pow(theta,(2*(i/2))/hd);const an=pos*fr;const co=Math.cos(an),si=Math.sin(an);const x0=x[i],x1=x[i+1];x[i]=x0*co-x1*si;x[i+1]=x0*si+x1*co}}
41
-
42
- // Load model
43
- async function loadModel(){status('Loading WASM SIMD...','ld');simd=await loadSIMD();status('Downloading model (385MB)...','ld');const r=await fetch('https://huggingface.co/bartowski/SmolLM2-360M-Instruct-GGUF/resolve/main/SmolLM2-360M-Instruct-Q8_0.gguf');const total=parseInt(r.headers.get('content-length')||'0');const rd2=r.body.getReader();const chunks=[];let loaded=0;while(true){const{done,value}=await rd2.read();if(done)break;chunks.push(value);loaded+=value.length;if(total){const p=Math.round(loaded/total*100);prog(p);status(`Downloading... ${(loaded/1e6).toFixed(0)}/${(total/1e6).toFixed(0)}MB (${p}%)`,'ld')}}const buf=new Uint8Array(loaded);let off=0;for(const c of chunks){buf.set(c,off);off+=c.length}status('Downloading tokenizer...','ld');const tr=await fetch('https://huggingface.co/HuggingFaceTB/SmolLM2-360M-Instruct/resolve/main/tokenizer.json');const tj=await tr.json();const tok=new Tok(tj);status('Parsing GGUF...','ld');const parsed=parseGGUF(buf.buffer);const byName={};for(const t of parsed.tensors)byName[t.name]=t;function get(nm){const t=byName[nm];if(!t)return null;const raw=new Uint8Array(buf.buffer,parsed.dataOffset+Number(t.offset),t.size);return dq(raw,t.numElements,t.type)}status('Dequantizing layers...','ld');const emb=get('token_embd.weight');const layers=[];for(let i=0;i<C.numLayers;i++){prog(Math.round(i/C.numLayers*100));status(`Dequantizing ${i+1}/${C.numLayers}...`,'ld');layers.push({an:get(`blk.${i}.attn_norm.weight`),fn:get(`blk.${i}.ffn_norm.weight`),qw:get(`blk.${i}.attn_q.weight`),kw:get(`blk.${i}.attn_k.weight`),vw:get(`blk.${i}.attn_v.weight`),ow:get(`blk.${i}.attn_output.weight`),gw:get(`blk.${i}.ffn_gate.weight`),uw:get(`blk.${i}.ffn_up.weight`),dw:get(`blk.${i}.ffn_down.weight`)});await new Promise(r=>setTimeout(r,0))}const on=get('output_norm.weight');let ow=get('output.weight');if(!ow)ow=emb;model={emb,layers,on,ow,tok};status(`Ready! SIMD: ${simd?'YES':'NO'} | Your browser is the inference engine`,'ok');prog(100);$('gn').disabled=false}
44
-
45
- // Generate
46
- async function generate(){if(!model)return;const prompt=$('pr').value.trim();if(!prompt)return;$('gn').disabled=true;$('ou').textContent='';$('ou').style.color='#e4e4e7';$('ss').textContent='';const o=op();const cp=`<|im_start|>user\n${prompt}<|im_end|>\n<|im_start|>assistant\n`;const inToks=model.tok.encode(cp);const all=[...inToks];const kvc=Array.from({length:C.numLayers},()=>({k:[],v:[]}));const times=[];const t0=performance.now();for(let step=0;step<inToks.length+200-1;step++){const ts=performance.now();const pos=step,tid=all[step];let x=model.emb.slice(tid*C.hiddenDim,(tid+1)*C.hiddenDim);for(let l=0;l<C.numLayers;l++){const ly=model.layers[l];const n=o.rmsNorm(x,ly.an,C.rmsNormEps);const q=o.matVec(ly.qw,n,C.hiddenDim,C.hiddenDim);const k=o.matVec(ly.kw,n,kvDim,C.hiddenDim);const v=o.matVec(ly.vw,n,kvDim,C.hiddenDim);for(let h=0;h<C.numHeads;h++)rope(q.subarray(h*C.headDim,(h+1)*C.headDim),C.headDim,pos,C.ropeTheta);for(let h=0;h<C.numKvHeads;h++)rope(k.subarray(h*C.headDim,(h+1)*C.headDim),C.headDim,pos,C.ropeTheta);kvc[l].k.push(new Float32Array(k));kvc[l].v.push(new Float32Array(v));const sl=kvc[l].k.length;const ao=new Float32Array(C.hiddenDim);for(let h=0;h<C.numHeads;h++){const kh=Math.floor(h/gqaRatio);const qh=q.subarray(h*C.headDim,(h+1)*C.headDim);const sc=new Float32Array(sl);for(let s=0;s<sl;s++){const kH=kvc[l].k[s].subarray(kh*C.headDim,(kh+1)*C.headDim);let d=0;for(let i=0;i<C.headDim;i++)d+=qh[i]*kH[i];sc[s]=d/Math.sqrt(C.headDim)}const w=smJS(sc);for(let s=0;s<sl;s++){const vH=kvc[l].v[s].subarray(kh*C.headDim,(kh+1)*C.headDim);const wt=w[s];for(let i=0;i<C.headDim;i++)ao[h*C.headDim+i]+=wt*vH[i]}}const pr=o.matVec(ly.ow,ao,C.hiddenDim,C.hiddenDim);const pa=o.add(x,pr);const fi=o.rmsNorm(pa,ly.fn,C.rmsNormEps);const g=o.matVec(ly.gw,fi,C.intermediateSize,C.hiddenDim);const u=o.matVec(ly.uw,fi,C.intermediateSize,C.hiddenDim);const ac=o.fusedSiluMul(g,u);const dn=o.matVec(ly.dw,ac,C.hiddenDim,C.intermediateSize);x=o.add(pa,dn)}if(step>=inToks.length-1){const fn=o.rmsNorm(x,model.on,C.rmsNormEps);const lg=o.matVec(model.ow,fn,C.vocabSize,C.hiddenDim);for(let i=0;i<lg.length;i++)lg[i]/=0.7;const pb=o.softmax(lg);const ix=Array.from(pb).map((p,i)=>({p,i})).sort((a,b)=>b.p-a.p);let cum=0,ch=ix[0].i;const r=Math.random();for(const{p,i}of ix){cum+=p;if(r<cum){ch=i;break}if(cum>.9)break}times.push(performance.now()-ts);if(ch===C.eosToken)break;all.push(ch);const gt=all.slice(inToks.length);$('ou').textContent=model.tok.decode(gt);const avg=times.reduce((a,b)=>a+b,0)/times.length;$('ss').textContent=`${gt.length} tokens | ${((performance.now()-t0)/1000).toFixed(1)}s | ${avg.toFixed(0)}ms/tok | SIMD: ${simd?'YES':'NO'}`;await new Promise(r=>setTimeout(r,0))}}$('gn').disabled=false}
47
-
48
- $('gn').addEventListener('click',generate);
49
- $('pr').addEventListener('keydown',e=>{if(e.key==='Enter'&&!e.shiftKey){e.preventDefault();generate()}});
50
- loadModel().catch(e=>status('Error: '+e.message,'error'));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
index.html CHANGED
@@ -1,37 +1,205 @@
1
  <!DOCTYPE html>
2
  <html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
3
- <title>Aether Browser -- Client-Side LLM Inference</title>
4
- <style>*{margin:0;padding:0;box-sizing:border-box}body{background:#09090b;color:#fafafa;font-family:system-ui,sans-serif}
5
- .c{max-width:900px;margin:0 auto;padding:2rem 1rem}h1{font-size:2.2rem;font-weight:300;text-align:center;margin-bottom:.5rem}
6
- .a{color:#06b6d4}.sub{color:#71717a;text-align:center;font-size:.9rem;margin-bottom:2rem;line-height:1.6}
7
- #st{text-align:center;margin:1rem 0;font-size:.85rem;color:#52525b;font-family:monospace}
8
- .ok{color:#22c55e !important}.ld{color:#f59e0b !important}.error{color:#ef4444 !important}
9
- .pb{width:100%;height:4px;background:#1f1f23;border-radius:2px;margin:.5rem 0;overflow:hidden}
10
- .pb .f{height:100%;background:#06b6d4;border-radius:2px;transition:width .3s}
11
  .ir{display:flex;gap:1rem;margin-bottom:1rem}
12
- textarea{flex:1;background:#111114;border:1px solid #1f1f23;border-radius:8px;color:#fafafa;font-size:1rem;padding:1rem;resize:none;font-family:inherit;outline:none}
13
  textarea:focus{border-color:#06b6d4}
14
  button{background:#06b6d4;border:none;border-radius:8px;color:#09090b;font-weight:600;font-size:.9rem;padding:.75rem 2rem;cursor:pointer}
15
  button:disabled{opacity:.5;cursor:not-allowed}
16
  .out{background:#0c0c0f;border:1px solid #1f1f23;border-radius:8px;padding:1.5rem;min-height:200px;margin:1rem 0;font-size:.95rem;line-height:1.6;white-space:pre-wrap}
17
  .stats{font-family:monospace;font-size:.8rem;color:#52525b;margin-top:.5rem}
 
 
 
 
18
  .ch{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:1rem}
19
  .ch span{background:#111114;border:1px solid #1f1f23;border-radius:6px;color:#a1a1aa;font-size:.85rem;padding:.4rem .8rem;cursor:pointer}
20
  .ch span:hover{border-color:#06b6d4;color:#fafafa}
 
21
  .ft{text-align:center;padding:2rem 0;border-top:1px solid #1f1f23;margin-top:2rem;font-size:.8rem;color:#52525b}
22
- .ft a{color:#06b6d4;text-decoration:none}</style></head><body>
 
23
  <div class="c">
24
- <h1><span class="a">Aether</span> Browser</h1>
25
- <p class="sub">SmolLM2-360M running entirely in your browser.<br>14KB WASM SIMD binary. Zero server. Zero dependencies. Your CPU, your speed.<br>Model downloads once (385MB Q8_0 GGUF), then cached.</p>
26
- <div id="st" class="ld">Initializing...</div>
27
- <div class="pb"><div id="pg" class="f" style="width:0%"></div></div>
28
- <div class="ir"><textarea id="pr" rows="2" placeholder="What is the shape of failure?"></textarea><button id="gn" disabled>Generate</button></div>
29
- <div class="ch"><span onclick="document.getElementById('pr').value='hello'">hello</span><span onclick="document.getElementById('pr').value='What is the shape of failure?'">shape of failure</span><span onclick="document.getElementById('pr').value='Write a haiku about entropy.'">haiku</span><span onclick="document.getElementById('pr').value='Explain consciousness.'">consciousness</span></div>
30
- <div id="ou" class="out" style="color:#52525b">Output will appear here after model loads...</div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  <div id="ss" class="stats"></div>
32
- <div class="ft"><p>SmolLM2-360M-Instruct &middot; Q8_0 GGUF &middot; Aether WASM-SIMD &middot; 100% client-side</p>
33
- <p style="margin-top:.5rem"><a href="https://forkracefold.com/">Whitepaper</a> &middot; <a href="https://huggingface.co/spaces/forkjoin-ai/aether">Server comparison</a> &middot; <a href="https://huggingface.co/spaces/forkjoin-ai/glossolalia">Glossolalia</a> &middot; <a href="https://huggingface.co/spaces/forkjoin-ai/five-bules">Five Bules</a></p>
34
- <p style="margin-top:.5rem">&phi;&sup2; = &phi; + 1</p></div>
 
 
 
 
 
 
 
 
 
35
  </div>
36
- <script src="aether-engine.js"></script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  </body></html>
 
1
  <!DOCTYPE html>
2
  <html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
3
+ <title>Aether -- Edge Mesh Inference</title>
4
+ <style>
5
+ *{margin:0;padding:0;box-sizing:border-box}
6
+ body{background:#09090b;color:#fafafa;font-family:system-ui,sans-serif}
7
+ .c{max-width:900px;margin:0 auto;padding:2rem 1rem}
8
+ h1{font-size:2.2rem;font-weight:300;text-align:center;margin-bottom:.5rem}
9
+ .a{color:#06b6d4}
10
+ .sub{color:#71717a;text-align:center;font-size:.9rem;margin-bottom:2rem;line-height:1.6}
11
  .ir{display:flex;gap:1rem;margin-bottom:1rem}
12
+ textarea{flex:1;background:#111114;border:1px solid #1f1f23;border-radius:8px;color:#fafafa;font-size:1rem;padding:1rem;resize:none;font-family:inherit;outline:none;min-height:80px}
13
  textarea:focus{border-color:#06b6d4}
14
  button{background:#06b6d4;border:none;border-radius:8px;color:#09090b;font-weight:600;font-size:.9rem;padding:.75rem 2rem;cursor:pointer}
15
  button:disabled{opacity:.5;cursor:not-allowed}
16
  .out{background:#0c0c0f;border:1px solid #1f1f23;border-radius:8px;padding:1.5rem;min-height:200px;margin:1rem 0;font-size:.95rem;line-height:1.6;white-space:pre-wrap}
17
  .stats{font-family:monospace;font-size:.8rem;color:#52525b;margin-top:.5rem}
18
+ .mesh{text-align:center;margin:1rem 0;font-family:monospace;font-size:.8rem;color:#52525b;background:#0c0c0f;border:1px solid #1f1f23;border-radius:8px;padding:1rem}
19
+ .mesh .active{color:#22c55e}
20
+ .mesh .waiting{color:#f59e0b}
21
+ .mesh .label{color:#71717a}
22
  .ch{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:1rem}
23
  .ch span{background:#111114;border:1px solid #1f1f23;border-radius:6px;color:#a1a1aa;font-size:.85rem;padding:.4rem .8rem;cursor:pointer}
24
  .ch span:hover{border-color:#06b6d4;color:#fafafa}
25
+ select{background:#111114;border:1px solid #1f1f23;border-radius:6px;color:#fafafa;padding:.5rem;font-size:.85rem;outline:none}
26
  .ft{text-align:center;padding:2rem 0;border-top:1px solid #1f1f23;margin-top:2rem;font-size:.8rem;color:#52525b}
27
+ .ft a{color:#06b6d4;text-decoration:none}
28
+ </style></head><body>
29
  <div class="c">
30
+ <h1><span class="a">Aether</span></h1>
31
+ <p class="sub">
32
+ Edge mesh inference. Local WASM &rarr; Cloudflare Workers &rarr; Cloud Run.<br>
33
+ Your request routes through the fastest available path.<br>
34
+ Every query smoketests the mesh. Zero downloads. Instant start.
35
+ </p>
36
+
37
+ <div class="mesh" id="mesh">
38
+ <span class="label">MESH:</span>
39
+ <span id="m-local" class="waiting">Local WASM</span> &rarr;
40
+ <span id="m-edge" class="waiting">CF Workers</span> &rarr;
41
+ <span id="m-cloud" class="waiting">Cloud Run</span>
42
+ <br><span id="m-status" style="color:#52525b">idle</span>
43
+ </div>
44
+
45
+ <div class="ir">
46
+ <textarea id="pr" placeholder="What is the shape of failure?"></textarea>
47
+ <div style="display:flex;flex-direction:column;gap:.5rem">
48
+ <select id="model">
49
+ <option value="cyrano-360m">SmolLM2-360M</option>
50
+ </select>
51
+ <button id="gn">Generate</button>
52
+ </div>
53
+ </div>
54
+
55
+ <div class="ch">
56
+ <span onclick="document.getElementById('pr').value='hello'">hello</span>
57
+ <span onclick="document.getElementById('pr').value='What is the shape of failure?'">shape of failure</span>
58
+ <span onclick="document.getElementById('pr').value='Write a haiku about entropy.'">haiku</span>
59
+ <span onclick="document.getElementById('pr').value='How do you handle rejection?'">rejection</span>
60
+ <span onclick="document.getElementById('pr').value='Tell me about yourself.'">about you</span>
61
+ </div>
62
+
63
+ <div id="ou" class="out" style="color:#52525b">Response will stream here...</div>
64
  <div id="ss" class="stats"></div>
65
+
66
+ <div class="ft">
67
+ <p>Aether inference mesh &middot; WASM SIMD at edge &middot; Glossolalia decoder &middot; D1 persistence</p>
68
+ <p style="margin-top:.5rem">
69
+ <a href="https://forkracefold.com/">Whitepaper</a> &middot;
70
+ <a href="https://huggingface.co/spaces/forkjoin-ai/the-void">The Void</a> &middot;
71
+ <a href="https://huggingface.co/spaces/forkjoin-ai/glossolalia">Glossolalia</a> &middot;
72
+ <a href="https://huggingface.co/spaces/forkjoin-ai/metacog">Metacog</a> &middot;
73
+ <a href="https://huggingface.co/spaces/forkjoin-ai/five-bules">Five Bules</a>
74
+ </p>
75
+ <p style="margin-top:.5rem">&phi;&sup2; = &phi; + 1</p>
76
+ </div>
77
  </div>
78
+
79
+ <script>
80
+ const API = 'https://api.edgework.ai';
81
+ const $=id=>document.getElementById(id);
82
+
83
+ function meshState(layer, state) {
84
+ const el = $('m-' + layer);
85
+ if (el) el.className = state;
86
+ }
87
+
88
+ async function generate() {
89
+ const prompt = $('pr').value.trim();
90
+ if (!prompt) return;
91
+ $('gn').disabled = true;
92
+ $('ou').textContent = '';
93
+ $('ou').style.color = '#e4e4e7';
94
+ $('ss').textContent = '';
95
+ $('m-status').textContent = 'connecting...';
96
+ meshState('edge', 'active');
97
+ meshState('local', 'waiting');
98
+ meshState('cloud', 'waiting');
99
+
100
+ const model = $('model').value;
101
+ const t0 = performance.now();
102
+
103
+ try {
104
+ const resp = await fetch(`${API}/v1/chat/completions`, {
105
+ method: 'POST',
106
+ headers: { 'Content-Type': 'application/json' },
107
+ body: JSON.stringify({
108
+ model,
109
+ messages: [{ role: 'user', content: prompt }],
110
+ max_tokens: 256,
111
+ temperature: 0.7,
112
+ stream: true,
113
+ }),
114
+ });
115
+
116
+ if (!resp.ok) {
117
+ const err = await resp.text();
118
+ $('ou').textContent = `[Edge error ${resp.status}: ${err.slice(0, 300)}]`;
119
+ $('m-status').textContent = `error ${resp.status}`;
120
+ meshState('edge', 'waiting');
121
+ $('gn').disabled = false;
122
+ return;
123
+ }
124
+
125
+ $('m-status').textContent = 'streaming...';
126
+
127
+ // Check which backend responded via headers
128
+ const backend = resp.headers.get('x-inference-backend') || resp.headers.get('x-served-by') || 'edge';
129
+ if (backend.includes('cloud') || backend.includes('gcp')) {
130
+ meshState('cloud', 'active');
131
+ $('m-status').textContent = 'Cloud Run responding';
132
+ } else if (backend.includes('wasm') || backend.includes('local')) {
133
+ meshState('local', 'active');
134
+ $('m-status').textContent = 'WASM inference (edge)';
135
+ } else {
136
+ $('m-status').textContent = 'Edge responding';
137
+ }
138
+
139
+ // Try streaming
140
+ const contentType = resp.headers.get('content-type') || '';
141
+ let tokens = 0;
142
+ let fullText = '';
143
+
144
+ if (contentType.includes('text/event-stream') || contentType.includes('application/json')) {
145
+ const reader = resp.body.getReader();
146
+ const decoder = new TextDecoder();
147
+ let buffer = '';
148
+
149
+ while (true) {
150
+ const { done, value } = await reader.read();
151
+ if (done) break;
152
+ buffer += decoder.decode(value, { stream: true });
153
+ const lines = buffer.split('\n');
154
+ buffer = lines.pop() || '';
155
+
156
+ for (const line of lines) {
157
+ if (!line.startsWith('data: ')) continue;
158
+ const data = line.slice(6).trim();
159
+ if (data === '[DONE]') continue;
160
+ try {
161
+ const parsed = JSON.parse(data);
162
+ const delta = parsed.choices?.[0]?.delta?.content || parsed.choices?.[0]?.text || '';
163
+ if (delta) {
164
+ fullText += delta;
165
+ tokens++;
166
+ $('ou').textContent = fullText;
167
+ const elapsed = (performance.now() - t0) / 1000;
168
+ $('ss').textContent = `${tokens} tokens | ${elapsed.toFixed(1)}s | ${(elapsed*1000/tokens).toFixed(0)}ms/tok | via ${API}`;
169
+ }
170
+ } catch {}
171
+ }
172
+ }
173
+ }
174
+
175
+ // Non-streaming fallback
176
+ if (!fullText) {
177
+ const body = await resp.text();
178
+ try {
179
+ const j = JSON.parse(body);
180
+ fullText = j.choices?.[0]?.message?.content || j.choices?.[0]?.text || body;
181
+ } catch {
182
+ fullText = body;
183
+ }
184
+ $('ou').textContent = fullText;
185
+ const elapsed = (performance.now() - t0) / 1000;
186
+ $('ss').textContent = `${elapsed.toFixed(1)}s | via ${API}`;
187
+ }
188
+
189
+ $('m-status').textContent = `done (${((performance.now()-t0)/1000).toFixed(1)}s)`;
190
+
191
+ } catch (e) {
192
+ $('ou').textContent = `[Connection error: ${e.message}]`;
193
+ $('m-status').textContent = 'connection failed';
194
+ meshState('edge', 'waiting');
195
+ }
196
+
197
+ $('gn').disabled = false;
198
+ }
199
+
200
+ $('gn').addEventListener('click', generate);
201
+ $('pr').addEventListener('keydown', e => {
202
+ if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); generate(); }
203
+ });
204
+ </script>
205
  </body></html>