@dvai-bridge/core 4.0.1 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -16,7 +16,7 @@
16
16
  `))}catch{s.enqueue(n.encode(`data: ${p}
17
17
 
18
18
  `))}}}}finally{s.close()}}})}async function N(t,e){if(!e.backend)return Response.json({error:"AI engine not initialized"},{status:503});let r=t.prompt,n=Array.isArray(r)?r.join(`
19
- `):r??"",i={...t,messages:[{role:"user",content:n}]};delete i.prompt;try{if(i.stream){let o=e.backend.createStreamingResponse(i),a=re(o,t.model||e.modelId);return new Response(a,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}let s=await e.backend.chatCompletion(i);return Response.json(te(s))}catch(s){return Response.json({error:s.message},{status:500})}}var Ae=u(()=>{"use strict"});function ne(t){let e="";for(let n of t)e+=String.fromCharCode(n);return(typeof btoa<"u"?btoa(e):Buffer.from(e,"binary").toString("base64")).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}var fr,ct=u(()=>{"use strict";fr=require("@noble/curves/ed25519")});function R(){let t=typeof globalThis.crypto<"u"?globalThis.crypto:void 0;if(!t||typeof t.getRandomValues!="function")throw new Error("[DVAI/pairing] no secure random source");let e=new Uint8Array(32);return t.getRandomValues(e),ne(e)}function ie(){let t=typeof globalThis.crypto<"u"?globalThis.crypto:void 0;if(!t||typeof t.getRandomValues!="function")throw new Error("[DVAI/pairing] no secure random source");let e=new Uint8Array(16);return t.getRandomValues(e),ne(e)}async function U(t,e){let r=globalThis.crypto;if(!r?.subtle)throw new Error("[DVAI/pairing] WebCrypto subtle not available");let n=gr(t),i=await r.subtle.importKey("raw",n,{name:"HMAC",hash:"SHA-256"},!1,["sign"]),s=await r.subtle.sign("HMAC",i,new TextEncoder().encode(e));return ne(new Uint8Array(s))}async function se(t,e,r){let n=await U(t,e);return yr(n,r)}function yr(t,e){if(t.length!==e.length)return!1;let r=0;for(let n=0;n<t.length;n++)r|=t.charCodeAt(n)^e.charCodeAt(n);return r===0}function gr(t){let e=t.replace(/-/g,"+").replace(/_/g,"/"),r=e+"=".repeat((4-e.length%4)%4),n=typeof atob<"u"?atob(r):Buffer.from(r,"base64").toString("binary"),i=new Uint8Array(n.length);for(let s=0;s<n.length;s++)i[s]=n.charCodeAt(s);return i}async function oe(t,e,r,n){let i=n?await vr(n):"0000000000000000000000000000000000000000000000000000000000000000";return`${t}
19
+ `):r??"",i={...t,messages:[{role:"user",content:n}]};delete i.prompt;try{if(i.stream){let o=e.backend.createStreamingResponse(i),a=re(o,t.model||e.modelId);return new Response(a,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}let s=await e.backend.chatCompletion(i);return Response.json(te(s))}catch(s){return Response.json({error:s.message},{status:500})}}var Ae=u(()=>{"use strict"});function ne(t){let e="";for(let n of t)e+=String.fromCharCode(n);return(typeof btoa<"u"?btoa(e):Buffer.from(e,"binary").toString("base64")).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}var fr,ct=u(()=>{"use strict";fr=require("@noble/curves/ed25519.js")});function R(){let t=typeof globalThis.crypto<"u"?globalThis.crypto:void 0;if(!t||typeof t.getRandomValues!="function")throw new Error("[DVAI/pairing] no secure random source");let e=new Uint8Array(32);return t.getRandomValues(e),ne(e)}function ie(){let t=typeof globalThis.crypto<"u"?globalThis.crypto:void 0;if(!t||typeof t.getRandomValues!="function")throw new Error("[DVAI/pairing] no secure random source");let e=new Uint8Array(16);return t.getRandomValues(e),ne(e)}async function U(t,e){let r=globalThis.crypto;if(!r?.subtle)throw new Error("[DVAI/pairing] WebCrypto subtle not available");let n=gr(t),i=await r.subtle.importKey("raw",n,{name:"HMAC",hash:"SHA-256"},!1,["sign"]),s=await r.subtle.sign("HMAC",i,new TextEncoder().encode(e));return ne(new Uint8Array(s))}async function se(t,e,r){let n=await U(t,e);return yr(n,r)}function yr(t,e){if(t.length!==e.length)return!1;let r=0;for(let n=0;n<t.length;n++)r|=t.charCodeAt(n)^e.charCodeAt(n);return r===0}function gr(t){let e=t.replace(/-/g,"+").replace(/_/g,"/"),r=e+"=".repeat((4-e.length%4)%4),n=typeof atob<"u"?atob(r):Buffer.from(r,"base64").toString("binary"),i=new Uint8Array(n.length);for(let s=0;s<n.length;s++)i[s]=n.charCodeAt(s);return i}async function oe(t,e,r,n){let i=n?await vr(n):"0000000000000000000000000000000000000000000000000000000000000000";return`${t}
20
20
  ${e.toUpperCase()}
21
21
  ${r}
22
22
  ${i}`}async function vr(t){let e=globalThis.crypto;if(!e?.subtle)throw new Error("[DVAI/pairing] WebCrypto subtle not available");let r=await e.subtle.digest("SHA-256",new TextEncoder().encode(t));return Array.from(new Uint8Array(r)).map(n=>n.toString(16).padStart(2,"0")).join("")}var ae=u(()=>{"use strict";ct()});function j(t){let e={none:3,integrated:8,discrete:35,"apple-silicon":40},r={low:.6,mid:1,high:1.3},n;t.ramGb<4?n=.3:t.ramGb<8?n=.7:n=1;let i=t.hasNpu?1.4:1,s=e[t.gpuClass]*r[t.cpuClass]*n*i;return Math.round(s*10)/10}function Se(){if(typeof navigator<"u"){let t=navigator,e=t.deviceMemory??4,r=t.hardwareConcurrency??4,n=typeof t.gpu<"u";return{hasNpu:!1,ramGb:e,gpuClass:n?"discrete":"none",cpuClass:r>=8?"high":r>=4?"mid":"low"}}return typeof globalThis.process<"u"&&globalThis.process.versions?.node,{hasNpu:!1,ramGb:4,gpuClass:"integrated",cpuClass:"mid"}}async function H(){if(typeof globalThis.process<"u"&&globalThis.process.versions?.node)try{let t=await import("os"),e=t.totalmem(),r=Math.round(e/1024**3),n=t.cpus().length;return{hasNpu:!1,ramGb:r,gpuClass:"integrated",cpuClass:n>=12?"high":n>=6?"mid":"low"}}catch{}return Se()}var Ee=u(()=>{"use strict"});var Re={};b(Re,{HardwareTooWeakError:()=>B,assessCapability:()=>Me});async function Me(t={}){let e=t.hardwareMinimum??br,r=t.minLocalCapability??wr;e>r;let n=t.hints??await H(),i=j(n);return i<e?{mode:"too-weak",tokPerSec:i,hints:n,reason:`estimated ${i} tok/s, below the ${e} tok/s hardware floor \u2014 local inference would be unusable, no peer to offload to either (a peer-only mode still requires the host to bring up discovery + pairing).`}:i<r?{mode:"offload-only",tokPerSec:i,hints:n,reason:`estimated ${i} tok/s, below the ${r} tok/s comfort threshold \u2014 model will not be loaded locally; every request will be forwarded to a paired peer.`}:{mode:"ok",tokPerSec:i,hints:n,reason:`estimated ${i} tok/s, above the ${r} tok/s local-capability threshold \u2014 running normally.`}}var br,wr,B,ce=u(()=>{"use strict";Ee();br=3,wr=10;B=class extends Error{tokPerSec;hardwareMinimum;hints;constructor(e){super(`DVAI: ${e.reason}`),this.name="HardwareTooWeakError",this.tokPerSec=e.tokPerSec,this.hardwareMinimum=e.hardwareMinimum,this.hints=e.hints}}});async function $(t,e,r){if(e.chatCompletionInterceptor)try{let i=await e.chatCompletionInterceptor(t,e,r);if(i!==null)return i}catch(i){return Response.json({error:i?.message??"interceptor failed"},{status:500})}if(!e.backend)return Response.json({error:"AI engine not initialized"},{status:503});let n=async()=>{let i=e.backend;if(!i)return Response.json({error:"AI engine not initialized"},{status:503});if(t.stream){let o=i.createStreamingResponse(t);return new Response(o,{headers:kr})}let s=await i.chatCompletion(t);return Response.json(s)};try{return e.backend.lastFatalError&&e.onRecovery&&await e.onRecovery(),await n()}catch(i){if(e.backend?.lastFatalError&&e.onRecovery)try{return await e.onRecovery(),await n()}catch{}return Response.json({error:i.message},{status:500})}}var kr,dt=u(()=>{"use strict";kr={"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}});async function W(t,e){if(!e.backend)return Response.json({error:"AI engine not initialized"},{status:503});if(e.resolvedBackend==="webllm")return Response.json({error:"Embeddings are not supported on the WebLLM backend. Use backend: 'transformers' with pipelineTask: 'feature-extraction'."},{status:400});if(typeof e.backend.embedding!="function")return Response.json({error:"The current backend does not support embeddings. For transformers: use pipelineTask: 'feature-extraction'."},{status:400});let r=t?.input;if(r==null)return Response.json({error:"Missing 'input' field."},{status:400});try{let n=await e.backend.embedding(r);return Response.json({object:"list",data:n.map((i,s)=>({object:"embedding",embedding:i,index:s})),model:t.model||e.modelId,usage:{prompt_tokens:0,total_tokens:0}})}catch(n){return Response.json({error:n.message},{status:500})}}var lt=u(()=>{"use strict"});async function z(t){return Response.json({object:"list",data:[{id:t.modelId,object:"model",created:Math.floor(Date.now()/1e3),owned_by:"dvai-bridge"}]})}var pt=u(()=>{"use strict"});var _e=u(()=>{"use strict";dt();Ae();lt();pt()});function Pr(t){let e=t,r=e,n="/chat/completions";if(e.endsWith(n))r=e.slice(0,-n.length);else try{let i=new URL(e),s=i.pathname.split("/").filter(Boolean);s.pop(),i.pathname="/"+s.join("/"),r=i.toString().replace(/\/$/,"")}catch{}return{chat:e,completions:`${r}/completions`,embeddings:`${r}/embeddings`,models:`${r}/models`,base:r}}var ut,F,de,mt=u(()=>{"use strict";ut=require("msw/browser"),F=require("msw");_e();de=class{constructor(e){this.opts=e}opts;kind="msw";worker=null;async start(e){let r=Pr(this.opts.mockUrl);if(this.opts.serviceWorkerUrl){let n=[F.http.post(r.chat,async({request:i})=>$(await i.json(),e)),F.http.post(r.completions,async({request:i})=>N(await i.json(),e)),F.http.post(r.embeddings,async({request:i})=>W(await i.json(),e)),F.http.get(r.models,async()=>z(e))];this.worker=(0,ut.setupWorker)(...n),await this.worker.start({onUnhandledRequest:"bypass",serviceWorker:{url:this.opts.serviceWorkerUrl}})}return{baseUrl:r.base}}async stop(){this.worker&&(this.worker.stop(),this.worker=null)}}});async function le(t,e=38883,r=16,n="127.0.0.1"){for(let i=0;i<r;i++){let s=e+i;try{return await new Promise((o,a)=>{let c=d=>{t.off("error",c),a(d)};t.once("error",c),t.listen(s,n,()=>{t.off("error",c),o()})}),s}catch(o){if(o.code!=="EADDRINUSE")throw o}}throw new Error(`[DVAI] Could not bind HTTP transport to any port in range ${e}..${e+r-1} (all in use). Another local AI server may already be running.`)}var ht,ft,Oe=u(()=>{"use strict";ht=38883,ft=16});function Cr(t,e){return e==="*"?"*":typeof e=="string"?e:t&&e.includes(t)?t:null}function Ir(t,e){let r=Cr(t,e),n={"Access-Control-Allow-Methods":"POST, GET, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","Access-Control-Allow-Private-Network":"true"};return r&&(n["Access-Control-Allow-Origin"]=r),n}async function pe(t){let e=[];for await(let n of t)e.push(n);let r=Buffer.concat(e).toString("utf8");if(!r)return{};try{return JSON.parse(r)}catch{throw new Error("Invalid JSON body")}}async function ue(t,e,r){let n={...r};if(e.headers.forEach((s,o)=>{n[o]=s}),e.body){t.writeHead(e.status,n);let s=e.body.getReader();try{for(;;){let{done:o,value:a}=await s.read();if(o)break;t.write(Buffer.from(a))}}finally{t.end()}return}let i=await e.text();t.writeHead(e.status,n),t.end(i)}async function Dr(t,e,r,n){let i=t.headers.origin,s=Ir(i,n.corsOrigin);if(t.method==="OPTIONS"){e.writeHead(204,s),e.end();return}let a=new URL(t.url||"/","http://127.0.0.1").pathname;try{if(t.method==="POST"&&a==="/v1/chat/completions"){let d=await pe(t),l={};for(let[p,h]of Object.entries(t.headers))typeof h=="string"?l[p.toLowerCase()]=h:Array.isArray(h)&&h.length>0&&(l[p.toLowerCase()]=h.join(", "));let m=await $(d,r,l);return ue(e,m,s)}if(t.method==="POST"&&a==="/v1/completions"){let d=await pe(t),l=await N(d,r);return ue(e,l,s)}if(t.method==="POST"&&a==="/v1/embeddings"){let d=await pe(t),l=await W(d,r);return ue(e,l,s)}if(t.method==="GET"&&a==="/v1/models"){let d=await z(r);return ue(e,d,s)}let c=r.dvaiRoutes;if(c){let d=`${t.method??"GET"} ${a}`,l=c[d];if(l){let m;(t.method==="POST"||t.method==="PUT"||t.method==="PATCH")&&(m=await pe(t));let p=await l({body:m}),h={...s,"Content-Type":"application/json"};e.writeHead(p.status,h),e.end(JSON.stringify(p.body));return}}e.writeHead(404,{...s,"Content-Type":"application/json"}),e.end(JSON.stringify({error:"not found"}))}catch(c){e.writeHead(500,{...s,"Content-Type":"application/json"}),e.end(JSON.stringify({error:c?.message??"unknown error"}))}}var me,yt=u(()=>{"use strict";_e();Oe();me=class{constructor(e){this.opts=e}opts;kind="http";server=null;boundPort;async start(e){let{createServer:r}=await import("http"),n=r((o,a)=>{Dr(o,a,e,this.opts).catch(c=>{try{a.writeHead(500,{"Content-Type":"application/json"}),a.end(JSON.stringify({error:c.message}))}catch{}})}),i=this.opts.bindHost??"127.0.0.1",s=await le(n,this.opts.httpBasePort,this.opts.httpMaxPortAttempts,i);return this.server=n,this.boundPort=s,{baseUrl:`http://${i}:${s}/v1`,port:s}}async stop(){this.server&&(await new Promise(e=>this.server.close(()=>e())),this.server=null,this.boundPort=void 0)}}});var he,gt=u(()=>{"use strict";he=class{constructor(e){this.opts=e}opts;kind="capacitor";async start(e){let{DVAIBridge:r}=await import("@dvai-bridge/capacitor"),n=await r.start({backend:this.opts.capacitorBackend,modelPath:this.opts.nativeModelPath,mmprojPath:this.opts.nativeMmprojPath,gpuLayers:this.opts.nativeGpuLayers,contextSize:this.opts.nativeContextSize,threads:this.opts.nativeThreads,embeddingMode:this.opts.nativeEmbeddingMode,httpBasePort:this.opts.httpBasePort,httpMaxPortAttempts:this.opts.httpMaxPortAttempts,corsOrigin:this.opts.corsOrigin,autoUnloadOnLowMemory:this.opts.autoUnloadOnLowMemory,logLevel:this.opts.logLevel});return{baseUrl:n.baseUrl,port:n.port}}async stop(){let{DVAIBridge:e}=await import("@dvai-bridge/capacitor");await e.stop()}}});var vt={};b(vt,{BASE_PORT:()=>ht,CapacitorTransport:()=>he,HttpTransport:()=>me,MAX_PORT_ATTEMPTS:()=>ft,MswTransport:()=>de,selectTransport:()=>Tr,tryBind:()=>le});function Tr(t){if(t.serviceWorkerUrl===""&&t.transport==null)return"none";let e=t.transport??"auto";return e!=="auto"?e:xr()?"capacitor":Ar()?"msw":Sr()?"http":"none"}function xr(){return typeof window<"u"&&!!window.Capacitor?.isNativePlatform?.()}function Ar(){return typeof window<"u"&&typeof document<"u"&&typeof navigator<"u"&&typeof navigator.serviceWorker<"u"}function Sr(){return typeof process<"u"&&process.versions!=null&&process.versions.node!=null}var bt=u(()=>{"use strict";mt();yt();gt();Oe()});function fe(t){if(!t.config.enabled)return{kind:"local"};if(t.header==="never")return{kind:"local"};let e=t.peers.map(s=>({peer:s,score:s.capability[t.modelId]??0,hasModel:s.loadedModels.includes(t.modelId)})).filter(s=>s.score>0).sort((s,o)=>{if(s.hasModel!==o.hasModel)return s.hasModel?-1:1;if(s.score!==o.score)return o.score-s.score;let a={mdns:0,static:1,custom:2,rendezvous:3};return a[s.peer.via]-a[o.peer.via]}),r=e[0]?.peer,n=e[0]?.score??0,i=t.config.minLocalCapability;return t.header==="require"?r&&n>=i?{kind:"offload",peer:r}:{kind:"no_capable_device",checked:wt(t),localCapability:t.localCapability,required:i}:t.localCapability>=i?{kind:"local"}:r&&n>t.localCapability?{kind:"offload",peer:r}:t.localCapability>0?{kind:"local"}:{kind:"no_capable_device",checked:wt(t),localCapability:t.localCapability,required:i}}function wt(t){let e=[{deviceId:"self",capabilityScore:t.localCapability,reason:t.localCapability<t.config.minLocalCapability?"below threshold":"no eligible peer found"}];for(let r of t.peers){let n=r.capability[t.modelId]??0;e.push({deviceId:r.deviceId,deviceName:r.deviceName,capabilityScore:n,reason:n===0?"model not advertised":n<t.config.minLocalCapability?"below threshold":"checked"})}return e}var Le=u(()=>{"use strict"});function ye(t,e){let r=`No device with capability \u2265 ${t.required} tok/s for model ${e.modelId} was reachable. Local: ${t.localCapability} tok/s; ${t.checked.length-1} peer(s) checked.`;return{status:503,headers:{"Content-Type":"application/json","Retry-After":"30"},body:{error:{type:"no_capable_device",code:503,message:r,checked:t.checked,localCapability:t.localCapability,requiredAtLeast:t.required,rendezvousConfigured:e.rendezvousConfigured,pairedRemotePeers:e.pairedRemotePeers,requestId:e.requestId}}}}var Ve=u(()=>{"use strict"});function ge(t){let e;if(t instanceof Headers)e=t.get("x-dvai-offload");else for(let[n,i]of Object.entries(t))if(n.toLowerCase()==="x-dvai-offload"){e=i;break}if(!e)return"prefer";let r=e.toLowerCase().trim();return Er.has(r)?r:"prefer"}var Er,Ne=u(()=>{"use strict";Er=new Set(["never","prefer","require"])});async function ve(t,e){if(t.via==="rendezvous"&&(!t.baseUrl||!t.baseUrl.startsWith("http")))throw new Error("[DVAI/offload] rendezvous-paired peers require WebSocket relay (not yet implemented in v3.0.0-rc1; expected in v3.0.0 final).");let r=`${t.baseUrl.replace(/\/$/,"")}${e.path}`,n={"Content-Type":"application/json","X-DVAI-Forwarded":"1",...e.headers??{}},i=await fetch(r,{method:e.method,headers:n,body:e.body!==void 0?JSON.stringify(e.body):void 0,signal:e.signal}),s={};return i.headers.forEach((o,a)=>{s[a]=o}),e.stream&&i.body?{status:i.status,headers:s,stream:i.body}:{status:i.status,headers:s,body:await i.json().catch(()=>{})}}var Ue=u(()=>{"use strict"});function Pt(t){return async function(r,n,i){if(!t.config.enabled)return null;let s=Mr(i),o=t.getPeers(),a=n.modelId,c=t.getLocalCapability(a),d=fe({config:t.config,modelId:a,localCapability:c,peers:o,header:s});if(d.kind==="local")return t.offloadOnlyMode?kt(503,{error:{type:"no_local_backend",code:503,message:"DVAI is running in offload-only mode (device below minLocalCapability) and the request requested local execution (X-DVAI-Offload: never). Either drop the header or route to a peer."}}):null;if(d.kind==="offload"){let m=r&&typeof r=="object"&&r.stream===!0;try{let p=await ve(d.peer,{method:"POST",path:"/chat/completions",body:r,stream:m,headers:Rr(i)});try{t.config.onOffload?.(d.peer)}catch{}return p.stream?new Response(p.stream,{status:p.status,headers:p.headers}):new Response(JSON.stringify(p.body),{status:p.status,headers:p.headers})}catch(p){return kt(502,{error:{type:"peer_unreachable",code:502,message:`Offload to peer ${d.peer.deviceId} failed: ${p instanceof Error?p.message:String(p)}`,peerId:d.peer.deviceId}})}}let l=ye(d,{rendezvousConfigured:!!t.config.rendezvousUrl,pairedRemotePeers:o.filter(m=>m.via==="rendezvous").length,modelId:a});return new Response(JSON.stringify(l.body),{status:l.status,headers:l.headers})}}function Mr(t){return t?ge(t):"prefer"}function Rr(t){if(!t)return{};let e={},r=new Set(["host","content-length","connection","keep-alive","transfer-encoding"]);for(let[n,i]of Object.entries(t))r.has(n.toLowerCase())||(e[n]=i);return e}function kt(t,e){return new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":"application/json"}})}var Ct=u(()=>{"use strict";Le();Ve();Ue();Ne()});var It={};b(It,{buildNoCapableDeviceResponse:()=>ye,buildOffloadInterceptor:()=>Pt,decide:()=>fe,parseOffloadHeader:()=>ge,proxyToPeer:()=>ve});var Dt=u(()=>{"use strict";Le();Ve();Ne();Ue();Ct()});function Or(){if(typeof globalThis.process<"u"){let t=globalThis.process.env,e=t.HOME??t.USERPROFILE??".";return t.LOCALAPPDATA?`${t.LOCALAPPDATA}/dvai-bridge/capability.json`:t.XDG_CACHE_HOME?`${t.XDG_CACHE_HOME}/dvai-bridge/capability.json`:`${e}/.cache/dvai-bridge/capability.json`}return"./.dvai-bridge-capability.json"}function Tt(){return typeof indexedDB<"u"?new O:typeof globalThis.process<"u"&&globalThis.process.versions?.node?new L:new q}var q,_r,P,_,O,L,xt=u(()=>{"use strict";q=class{map=new Map;async get(e){return this.map.get(this.keyOf(e))}async set(e){this.map.set(this.keyOf({modelId:e.modelId,libraryVersion:e.libraryVersion}),e)}async list(){return Array.from(this.map.values())}async clear(){this.map.clear()}keyOf(e){return`${e.libraryVersion}::${e.modelId}`}},_r="dvai-bridge",P="capability-v1",_="meta-v1",O=class{dbPromise;openDb(){return this.dbPromise||(this.dbPromise=new Promise((e,r)=>{let n=indexedDB.open(_r,1);n.onupgradeneeded=()=>{let i=n.result;i.objectStoreNames.contains(P)||i.createObjectStore(P),i.objectStoreNames.contains(_)||i.createObjectStore(_)},n.onsuccess=()=>e(n.result),n.onerror=()=>r(n.error)})),this.dbPromise}async get(e){let r=await this.openDb();return await new Promise((n,i)=>{let o=r.transaction(P,"readonly").objectStore(P).get(this.keyOf(e));o.onsuccess=()=>n(o.result),o.onerror=()=>i(o.error)})}async set(e){let r=await this.openDb();await new Promise((n,i)=>{let s=r.transaction(P,"readwrite");s.objectStore(P).put(e,this.keyOf({modelId:e.modelId,libraryVersion:e.libraryVersion})),s.oncomplete=()=>n(),s.onerror=()=>i(s.error)})}async list(){let e=await this.openDb();return await new Promise((r,n)=>{let s=e.transaction(P,"readonly").objectStore(P).getAll();s.onsuccess=()=>r(s.result),s.onerror=()=>n(s.error)})}async clear(){let e=await this.openDb();await new Promise((r,n)=>{let i=e.transaction(P,"readwrite");i.objectStore(P).clear(),i.oncomplete=()=>r(),i.onerror=()=>n(i.error)})}async getMeta(e){let r=await this.openDb();return await new Promise((n,i)=>{let o=r.transaction(_,"readonly").objectStore(_).get(e);o.onsuccess=()=>n(o.result),o.onerror=()=>i(o.error)})}async setMeta(e,r){let n=await this.openDb();await new Promise((i,s)=>{let o=n.transaction(_,"readwrite");o.objectStore(_).put(r,e),o.oncomplete=()=>i(),o.onerror=()=>s(o.error)})}keyOf(e){return`${e.libraryVersion}::${e.modelId}`}},L=class{cachePath;cache;constructor(e){this.cachePath=e??Or()}async load(){if(this.cache)return this.cache;let e=await import("fs/promises"),r=await import("path");try{let n=await e.readFile(this.cachePath,"utf8");this.cache=JSON.parse(n)}catch{this.cache={deviceId:"",scores:{}}}return await e.mkdir(r.dirname(this.cachePath),{recursive:!0}),this.cache}async save(){if(!this.cache)return;await(await import("fs/promises")).writeFile(this.cachePath,JSON.stringify(this.cache,null,2),"utf8")}async get(e){return(await this.load()).scores[this.keyOf(e)]}async set(e){let r=await this.load();r.scores[this.keyOf({modelId:e.modelId,libraryVersion:e.libraryVersion})]=e,await this.save()}async list(){let e=await this.load();return Object.values(e.scores)}async clear(){let e=await this.load();e.scores={},await this.save()}async getDeviceId(){return(await this.load()).deviceId}async setDeviceId(e){let r=await this.load();r.deviceId=e,await this.save()}keyOf(e){return`${e.libraryVersion}::${e.modelId}`}}});function K(){let t=typeof globalThis.crypto<"u"?globalThis.crypto:void 0;if(!t||typeof t.getRandomValues!="function")throw new Error("[DVAI/capability] No secure random source available. globalThis.crypto.getRandomValues required (Node \u226519, modern browsers, Bun, Deno).");let e=new Uint8Array(16);return t.getRandomValues(e),Lr(e)}function Lr(t){let e="";for(let n of t)e+=String.fromCharCode(n);return(typeof btoa<"u"?btoa(e):Buffer.from(e,"binary").toString("base64")).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}var At=u(()=>{"use strict"});async function je(t){let e=performance.now(),r=await t.backend.chatCompletion({messages:[{role:"user",content:Vr}],max_tokens:50,stream:!1}),n=(performance.now()-e)/1e3,i=r.usage?.completion_tokens,s=r.choices[0]?.message?.content??r.choices[0]?.text??"",o=i??Nr(s),a=o>0&&n>0?Math.round(o/n*10)/10:0;return{modelId:t.modelId,deviceId:t.deviceId,libraryVersion:t.libraryVersion,tokPerSec:a,source:"probe",measuredAt:Date.now()}}function Nr(t){return Math.max(1,Math.round(t.length/4))}var Vr,St=u(()=>{"use strict";Vr="Generate a single short sentence about clouds."});var be={};b(be,{HardwareTooWeakError:()=>B,InMemoryCapabilityCache:()=>q,IndexedDBCapabilityCache:()=>O,NodeFsCapabilityCache:()=>L,assessCapability:()=>Me,clearCapabilityCache:()=>jr,createCapabilityCache:()=>Tt,detectDeviceHints:()=>Se,detectDeviceHintsAsync:()=>H,ensureDeviceId:()=>He,generateDeviceId:()=>K,getCapability:()=>Ur,heuristicTokPerSec:()=>j,probeAndCache:()=>Be,probeCapability:()=>je});async function He(t){if(t instanceof O){let r=await t.getMeta(Et);if(r)return r;let n=K();return await t.setMeta(Et,n),n}if(t instanceof L){let r=await t.getDeviceId();if(r)return r;let n=K();return await t.setDeviceId(n),n}return K()}async function Ur(t){let e=await t.cache.get({modelId:t.modelId,libraryVersion:t.libraryVersion});if(e)return e;let r=t.hints??await H(),n=await He(t.cache);return{modelId:t.modelId,deviceId:n,libraryVersion:t.libraryVersion,tokPerSec:j(r),source:"heuristic",measuredAt:Date.now()}}async function Be(t){let e=await He(t.cache),r=await je({backend:t.backend,modelId:t.modelId,libraryVersion:t.libraryVersion,deviceId:e});return await t.cache.set(r),r}async function jr(t){await t.clear()}var Et,J=u(()=>{"use strict";xt();Ee();At();St();ce();Et="dvai.deviceId"});var x,$e=u(()=>{"use strict";x="_dvai-bridge._tcp.local"});var we,Mt=u(()=>{"use strict";we=class{listeners=new Set;peerList;started=!1;constructor(e){let r=Date.now();this.peerList=e.map(n=>({...n,lastSeenAt:n.lastSeenAt&&n.lastSeenAt>0?n.lastSeenAt:r,via:"static"}))}async start(){if(!this.started){this.started=!0;for(let e of this.peerList)this.emit({type:"peer-up",peer:e})}}async stop(){this.started=!1;for(let e of this.peerList)this.emit({type:"peer-down",deviceId:e.deviceId})}peers(){return this.started?[...this.peerList]:[]}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}emit(e){for(let r of this.listeners)try{r(e)}catch(n){console.error("[DVAI/discovery] listener threw:",n)}}}});var Rt={};b(Rt,{NodeMdnsDiscovery:()=>We});var We,_t=u(()=>{"use strict";$e();We=class{constructor(e){this.opts=e}opts;mdns;peerMap=new Map;listeners=new Set;queryTimer;gcTimer;started=!1;async start(){if(this.started)return;let e;try{e=await import("multicast-dns")}catch{this.emit({type:"error",message:"[DVAI/discovery] `multicast-dns` not installed; LAN discovery disabled. Install with `npm i multicast-dns` (optional dep) to enable peer discovery."});return}let r=typeof e=="function"?e:e.default;this.mdns=r(),this.started=!0,this.mdns.on("response",s=>this.onResponse(s)),this.broadcastQuery();let n=this.opts.queryIntervalMs??3e4;this.queryTimer=setInterval(()=>this.broadcastQuery(),n);let i=this.opts.gcIntervalMs??6e4;this.gcTimer=setInterval(()=>this.gc(),i)}async stop(){if(this.started){this.started=!1,this.queryTimer&&clearInterval(this.queryTimer),this.gcTimer&&clearInterval(this.gcTimer),this.mdns?.destroy(),this.mdns=void 0;for(let e of this.peerMap.values())this.emit({type:"peer-down",deviceId:e.deviceId});this.peerMap.clear()}}peers(){return Array.from(this.peerMap.values())}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}broadcastQuery(){if(this.mdns){try{this.mdns.query({questions:[{name:x,type:"PTR"}]})}catch(e){this.emit({type:"error",message:`mDNS query failed: ${String(e)}`})}if(this.opts.advertise)try{this.mdns.respond({answers:this.buildAdvertisementAnswers(this.opts.advertise)})}catch(e){this.emit({type:"error",message:`mDNS respond failed: ${String(e)}`})}}}buildAdvertisementAnswers(e){let r=`${e.deviceId}.${x}`;return[{name:x,type:"PTR",data:r,ttl:120},{name:r,type:"SRV",data:{port:e.port,target:`${e.deviceId}.local`},ttl:120},{name:r,type:"TXT",data:this.encodeTxt(e),ttl:120}]}encodeTxt(e){return[`dvaiVersion=${e.dvaiVersion}`,`deviceId=${e.deviceId}`,`deviceName=${e.deviceName}`,`models=${e.models.join(",")}`,`capability=${JSON.stringify(e.capability)}`,`port=${e.port}`,`secure=${e.secure?"1":"0"}`]}onResponse(e){let r=[...e.answers,...e.additionals??[]],n,i;for(let l of r)l.type==="SRV"&&String(l.name).endsWith(x)&&(n=l),l.type==="TXT"&&String(l.name).endsWith(x)&&(i=l);if(!n||!i)return;let s=this.decodeTxt(i.data);if(!s||s.deviceId===this.opts.selfDeviceId)return;let o=n.data,a=`${s.secure?"https":"http"}://${o.target}:${o.port}/v1`,c={deviceId:s.deviceId,deviceName:s.deviceName,dvaiVersion:s.dvaiVersion,baseUrl:a,loadedModels:s.models,capability:s.capability,via:"mdns",secure:s.secure,lastSeenAt:Date.now()},d=this.peerMap.get(c.deviceId);this.peerMap.set(c.deviceId,c),d||this.emit({type:"peer-up",peer:c})}decodeTxt(e){let r;if(Array.isArray(e))r=e.map(s=>Buffer.isBuffer(s)?s.toString("utf8"):String(s));else if(Buffer.isBuffer(e))r=e.toString("utf8").split(`