@fugood/buttress-server 2.26.0-beta.13 → 2.26.0-beta.14
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/README.md +19 -3
- package/config/sample.toml +6 -0
- package/lib/index.mjs +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -216,6 +216,8 @@ Most ggml-llm `[generators.model]` keys can also live in `[runtime]` as defaults
|
|
|
216
216
|
| `no_extra_bufts` | boolean | Disable extra compute buffer types |
|
|
217
217
|
| `cpu_mask`, `cpu_strict` | string / boolean | CPU affinity (advanced) |
|
|
218
218
|
| `devices` | string[] | Restrict to specific GGML devices |
|
|
219
|
+
| `split_mode` | `"none"` / `"layer"` / `"row"` / `"tensor"` | ggml-llm GPU splitting: single GPU, layers + KV (default), weight rows, or weights + KV (experimental tensor parallelism) |
|
|
220
|
+
| `tensor_split` | number[]\|string | ggml-llm per-GPU proportions, e.g. `[3, 1]` or `"3,1"`; unset uses the native automatic split |
|
|
219
221
|
| Speculative keys | various | `speculative`, `spec_type`, `spec_draft_n_max/n_min/p_min/p_split`, plus draft-model GPU/cache settings |
|
|
220
222
|
|
|
221
223
|
### `[autodiscover]`
|
|
@@ -277,6 +279,10 @@ Additional keys honored by **ggml-llm**, **ggml-stt** and **ggml-tts** (mlx-llm
|
|
|
277
279
|
|
|
278
280
|
Loads a GGUF LLM. Runtime keys above can be overridden per-generator under `[generators.model]`; `[generators.backend]` only controls backend selection and resource planning.
|
|
279
281
|
|
|
282
|
+
GPU splitting (`split_mode`, `tensor_split`) is currently configurable only in Buttress.
|
|
283
|
+
TODO: Expose these options in the LLM (GGML) generator. The experimental `tensor` mode
|
|
284
|
+
requires a compatible GPU backend and model architecture.
|
|
285
|
+
|
|
280
286
|
**`[generators.backend]`**
|
|
281
287
|
|
|
282
288
|
| Key | Type | Default | Notes |
|
|
@@ -292,6 +298,7 @@ Loads a GGUF LLM. Runtime keys above can be overridden per-generator under `[gen
|
|
|
292
298
|
| ----------------------------------------------------------------------------- | ---------------- | -------------------------------------------------------------------- |
|
|
293
299
|
| `n_ctx` | number | Context window. Auto-capped at the model's training context. |
|
|
294
300
|
| `n_gpu_layers` | number\|`"auto"` | Layers offloaded to GPU (default `"auto"`) |
|
|
301
|
+
| `split_mode`, `tensor_split` | string / number[]\|string | Per-model overrides for the GPU split defaults in `[runtime]` |
|
|
295
302
|
| `n_batch` | number | Prompt batch size (default `512`) |
|
|
296
303
|
| `embedding` | boolean | Enable llama.cpp embedding mode for a dedicated embedding model (default `false`) |
|
|
297
304
|
| `pooling_type` | string | Optional embedding pooling override such as `mean` |
|
|
@@ -364,12 +371,21 @@ spec_draft_cache_type_v = "f16"
|
|
|
364
371
|
|
|
365
372
|
Loads a Whisper GGML model for speech-to-text.
|
|
366
373
|
|
|
374
|
+
With `@fugood/whisper.node` 1.2.0-rc.0, `snapdragon` enables experimental
|
|
375
|
+
Whisper Hexagon NPU acceleration on Linux arm64 with a working Qualcomm
|
|
376
|
+
HTP/FastRPC runtime. This variant does not include OpenCL. Install it with
|
|
377
|
+
`--ggml-variant=snapdragon` (the default CPU package remains available for fallback).
|
|
378
|
+
The platform package includes the HTP libraries; the loader defaults
|
|
379
|
+
`ADSP_LIBRARY_PATH` to that package directory and `GGML_HEXAGON_NDEV` to `16`,
|
|
380
|
+
without overriding explicit environment values. Hexagon always enables flash
|
|
381
|
+
attention, even when `use_flash_attn` is off.
|
|
382
|
+
|
|
367
383
|
**`[generators.backend]`**
|
|
368
384
|
|
|
369
385
|
| Key | Type | Default | Notes |
|
|
370
386
|
| --------------------- | -------- | ----------------------------- | ---------------------------------- |
|
|
371
|
-
| `variant` | string | auto | `cuda` / `vulkan` / `default`
|
|
372
|
-
| `variant_preference` | string[] | `["cuda","vulkan","default"]` | Probe order
|
|
387
|
+
| `variant` | string | auto | `cuda` / `vulkan` / `snapdragon` / `default` |
|
|
388
|
+
| `variant_preference` | string[] | `["cuda","vulkan","snapdragon","default"]` | Probe order |
|
|
373
389
|
| `gpu_memory_fraction` | number | `0.85` | |
|
|
374
390
|
| `cpu_memory_fraction` | number | `0.5` | |
|
|
375
391
|
|
|
@@ -394,7 +410,7 @@ Loads a Whisper GGML model for speech-to-text.
|
|
|
394
410
|
[[generators]]
|
|
395
411
|
type = "ggml-stt"
|
|
396
412
|
[generators.backend]
|
|
397
|
-
variant_preference = ["cuda", "vulkan", "default"]
|
|
413
|
+
variant_preference = ["cuda", "vulkan", "snapdragon", "default"]
|
|
398
414
|
[generators.model]
|
|
399
415
|
repo_id = "BricksDisplay/whisper-ggml"
|
|
400
416
|
filename = "ggml-large-v3-turbo-q8_0.bin"
|
package/config/sample.toml
CHANGED
|
@@ -78,6 +78,12 @@ cache_type_k = "q8_0"
|
|
|
78
78
|
cache_type_v = "q8_0"
|
|
79
79
|
n_threads = 6
|
|
80
80
|
|
|
81
|
+
# Optional ggml-llm multi-GPU defaults (also supported under [generators.model]).
|
|
82
|
+
# split_mode = "layer" # none / layer (default) / row / tensor (experimental)
|
|
83
|
+
# tensor_split = [3, 1] # per-GPU proportions; also accepts "3,1"
|
|
84
|
+
# Tensor mode requires a compatible GPU backend and model architecture.
|
|
85
|
+
# TODO: Expose these Buttress-only options in the LLM (GGML) generator.
|
|
86
|
+
|
|
81
87
|
# Delay before releasing context when refCount reaches 0 (default: 10000ms)
|
|
82
88
|
# Set to 0 for immediate release
|
|
83
89
|
context_release_delay_ms = 30000
|
package/lib/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{n as e,t}from"./rolldown-runtime-dTnj95Mm.mjs";import{a as n,i as r,n as i,o as a,r as o,s,t as c}from"./config-DbRjQnNp.mjs";import{builtinModules as l,createRequire as u}from"node:module";import{node as d}from"@elysiajs/node";import{Elysia as f,file as p,sse as m,t as h}from"elysia";import*as g from"node:stream/web";import{ReadableStream as _}from"node:stream/web";import v,{lstat as y,mkdir as b,open as x,readFile as S,readdir as C,realpath as w,rename as T,rm as E,stat as D,unlink as O,writeFile as k}from"node:fs/promises";import ee,{createHash as A,randomBytes as te,randomUUID as j,timingSafeEqual as ne}from"node:crypto";import M from"node:path";import N from"node:os";import{gguf as re}from"@huggingface/gguf";import{getBackendDevicesInfo as P,isLibVariantAvailable as ie,loadModel as ae}from"@fugood/llama.node";import oe from"bytes";import{EventEmitter as se}from"node:events";import ce,{constants as le,createWriteStream as ue}from"node:fs";import{initParakeet as de,initWhisper as fe}from"@fugood/whisper.node";import{fileURLToPath as pe,pathToFileURL as me}from"node:url";import{execFile as he,execSync as ge,spawn as _e,spawnSync as ve}from"node:child_process";import ye from"fs";import be from"path";import xe from"url";import*as Se from"onnxruntime-node";import{listSupportedBackends as Ce}from"onnxruntime-node";import{Tensor as we}from"onnxruntime-common";import{Readable as Te}from"stream";import{pipeline as Ee}from"stream/promises";import De from"sharp";import{Buffer as Oe}from"buffer";import{ZodError as ke,z as F}from"zod";import{importSPKI as Ae,jwtVerify as je}from"jose";import Me from"ms";import Ne from"node:vm";import{moduleRunnerTransformSync as Pe,transformSync as Fe}from"oxc-transform";import Ie from"lodash";import eee from"moment";import*as tee from"mathjs";import nee from"voca";import ree from"chroma-js";import iee from"json5";import aee from"qs";import{nanoid as oee}from"nanoid";import see from"md5";import{Server as cee}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as lee,ListToolsRequestSchema as uee}from"@modelcontextprotocol/sdk/types.js";import{Readable as Le}from"node:stream";import{pipeline as Re}from"node:stream/promises";import{Buffer as ze}from"node:buffer";import Be from"node:dgram";import{Agent as dee,BACKGROUND_CONTEXT as Ve,FileError as fee,JsonlSessionRepo as pee,err as He,ok as Ue}from"@earendil-works/pi-agent-core";import{createProvider as mee}from"@earendil-works/pi-ai";import{builtinModels as hee}from"@earendil-works/pi-ai/providers/all";import{stream as gee,streamSimple as _ee}from"@earendil-works/pi-ai/api/openai-completions";import We from"@iarna/toml";import vee from"node:readline/promises";const Ge=1024**3,Ke=(e,t,n)=>Math.min(Math.max(e,t),n),qe=e=>e?40:0,Je=(e=0)=>{if(!e)return 0;let t=12*Ge;return Ke(e/t*20,0,20)},Ye=(e=0)=>{if(!e)return 0;let t=32*Ge;return Ke(e/t*10,0,10)},Xe=e=>e?10:0,Ze=(e=`default`,t=null)=>{let n=String(e).toLowerCase();return n?n.includes(`cuda`)?20:n.includes(`vulkan`)?10:n.includes(`default`)?t===`darwin`||t===`ios`?15:5:0:0},Qe=({platform:e,variant:t,hasGpu:n,gpuUsableBytes:r=0,cpuUsableBytes:i=0,ok:a=!0}={})=>{if(!a)return 0;let o=qe(n)+Ze(t,e)+Je(r),s=Ye(i),c=Xe(a);return Math.min(100,Math.round(o+s+c))},$e=e=>e?typeof e.score==`number`&&Number.isFinite(e.score)?Number(e.score):Qe(e):0,et=(...e)=>e.some(e=>e?.fitsInGpu||e?.fitsInCpu),tt=({clientScore:e,buttressScore:t,threshold:n=1.1,clientFitsInMemory:r=!1,buttressFitsInMemory:i=!1})=>r&&!i?{recommendation:`local`,reason:`client-fits-in-memory`}:i&&!r?{recommendation:`buttress`,reason:`buttress-fits-in-memory`}:e>t*n?{recommendation:`local`,reason:`client-better`}:t>e*n?{recommendation:`buttress`,reason:`buttress-better`}:{recommendation:`either`,reason:`comparable-scores`},nt=({platform:e,variant:t,hasGpu:n,gpuUsableBytes:r=0,cpuUsableBytes:i=0,ok:a=!0}={})=>({gpuPresence:qe(n),variant:Ze(t,e),gpuMemory:Je(r),cpuMemory:Ye(i),availability:Xe(a)}),yee=.85,bee=.5,rt=e=>!e&&e!==0?[]:Array.isArray(e)?e.filter(e=>e!=null):[e],it=({device:e,modelBytes:t=0,extraBytes:n=0}={})=>{let r=e?Math.max(0,Number(t)||0)+Math.max(0,Number(n)||0):t+n;if(!e)return{totalRequiredBytes:r,fitsInGpu:!1,fitsInCpu:!1,limiting:`unknown-device`};let i=e.hasGpu&&r>0&&r<=e.gpuUsableBytes,a=r>0&&r<=e.cpuUsableBytes,o=`ok`;return!i&&e.hasGpu&&(o=`gpu-memory`),a||(o=i?`cpu-memory`:`insufficient-memory`),{totalRequiredBytes:r,fitsInGpu:i,fitsInCpu:a,limiting:o}},xee=[`cuda`,`vulkan`,`snapdragon`,`default`],See=e=>e&&String(e).trim().toLowerCase()||null,Cee=({variant:e,preferVariants:t=[],variantPreference:n=[],defaultVariants:r=xee}={})=>{let i=[];e&&i.push(e),i.push(...rt(t)),i.push(...rt(n)),i.push(...r);let a=new Set;for(let e of i){let t=See(e);t&&a.add(t)}return Array.from(a)},wee=(e={})=>{let t=String(e.type||e.deviceType||e.kind||``).toLowerCase();return!!(t.includes(`gpu`)||t.includes(`cuda`)||t.includes(`metal`)||t.includes(`vulkan`)||t.includes(`snapdragon`))},Tee=e=>Array.isArray(e)?e.map(e=>({...e})):[],Eee=(e,t)=>e===`snapdragon`?t.filter(e=>e.deviceName!==`GPUOpenCL`):t,Dee=({platform:e,totalMemoryInBytes:t,variant:n,devices:r,gpuMemoryFraction:i,cpuMemoryFraction:a,ok:o,error:s})=>{let c=Tee(Eee(n,r)),l=c.some(wee),u=c.filter(e=>wee(e)&&Number.isFinite(Number(e.maxMemorySize))).reduce((e,t)=>e+t.maxMemorySize,0),d=t,f=l?Math.floor(u*i):0,p=d?Math.floor(d*a):0,m={platform:e,variant:n,hasGpu:l,gpuUsableBytes:f,cpuUsableBytes:p,ok:o};return{platform:e,ok:o,variant:n,hasGpu:l,devices:c,gpuTotalBytes:u,gpuUsableBytes:f,cpuTotalBytes:d,cpuUsableBytes:p,score:Qe(m),breakdown:o?nt(m):null,error:s,timestamp:new Date().toISOString()}},Oee=({device:e,modelBytes:t=0,kvCacheBytes:n=0}={})=>it({device:e,modelBytes:t,extraBytes:n}),kee=async({platform:e,variant:t=null,preferVariants:n=[],variantPreference:r=[],gpuMemoryFraction:i=yee,cpuMemoryFraction:a=bee,includeBreakdown:o=!1,totalMemoryInBytes:s,modelBytes:c=null,kvCacheBytes:l=null,limitedKvCacheBytes:u=null,dependencies:d={},defaultVariants:f=xee}={})=>{let{getBackendDevicesInfo:p,isLibVariantAvailable:m}=d;if(typeof p!=`function`||typeof m!=`function`)throw TypeError(`GGML capability detection requires getBackendDevicesInfo and isLibVariantAvailable functions`);let h=Cee({variant:t,preferVariants:n,variantPreference:r,defaultVariants:f}),g=[];for(let t of h)try{if(!await m(t))throw Error(`Variant ${t} not available on this platform`);let n=await p(t);g.push(Dee({platform:e,totalMemoryInBytes:s,variant:t,devices:n,gpuMemoryFraction:i,cpuMemoryFraction:a,ok:!0}))}catch(n){let r=n instanceof Error?n.message:String(n);g.push(Dee({platform:e,totalMemoryInBytes:s,variant:t,devices:[],gpuMemoryFraction:i,cpuMemoryFraction:a,ok:!1,error:r}))}let _=g.filter(e=>e.ok)[0]||null,v={ok:!!_,selected:_?{..._,breakdown:o?_.breakdown:void 0}:null,attempts:g};if(!o&&v.selected&&delete v.selected.breakdown,!v||!c&&!l)return v;let y=e=>{if(!e)return e;let t=Oee({device:e,modelBytes:c||0,kvCacheBytes:l||0}),n=null;return u!=null&&u!==l&&(n=Oee({device:e,modelBytes:c||0,kvCacheBytes:u})),{...e,fit:t,...n&&{limitedFit:n}}};return v.selected=y(v.selected),v.attempts=Array.isArray(v.attempts)?v.attempts.map(y):v.attempts,v},Aee=`ggml-llm`,jee=async({platform:e,variant:t,preferVariants:n,variantPreference:r=[],gpuMemoryFraction:i,cpuMemoryFraction:a,includeBreakdown:o,totalMemoryInBytes:s,modelBytes:c,processingBytes:l=null,kvCacheBytes:u=null,dependencies:d}={},f)=>kee({platform:e,variant:t,preferVariants:n,variantPreference:r&&r.length>0?r:f,gpuMemoryFraction:i,cpuMemoryFraction:a,includeBreakdown:o,totalMemoryInBytes:s,modelBytes:c,kvCacheBytes:l??u,dependencies:d,defaultVariants:f}),Mee=[`cuda`,`vulkan`,`default`],Nee=async(e={})=>jee(e,Mee),Pee=[`cuda`,`vulkan`,`default`],Fee=async(e={})=>jee(e,Pee),at=async({platform:e,arch:t=null,unifiedMemoryFraction:n=.85,includeBreakdown:r=!1,totalMemoryInBytes:i,modelBytes:a=null,kvCacheBytes:o=null,limitedKvCacheBytes:s=null}={})=>{let c=[];e!==`darwin`&&c.push(`MLX requires macOS`),t&&t!==`arm64`&&c.push(`MLX requires Apple Silicon (arm64)`);let l=c.length===0,u=l?Math.floor(i*n):0,d={platform:e,variant:`mlx`,hasGpu:l,gpuUsableBytes:u,cpuUsableBytes:u,ok:l},f=Qe(d),p=l?nt(d):null,m={platform:e,ok:l,variant:`mlx`,hasGpu:l,unifiedMemory:!0,devices:l?[{type:`metal`,deviceName:`Apple Silicon (Unified Memory)`,maxMemorySize:i}]:[],gpuTotalBytes:l?i:0,gpuUsableBytes:u,cpuTotalBytes:i,cpuUsableBytes:u,score:f,breakdown:r?p:void 0,error:l?void 0:c.join(`; `),timestamp:new Date().toISOString()};r||delete m.breakdown;let h={ok:l,selected:l?m:null,attempts:[m],errors:l?[]:c};if(!a&&!o)return h;let g=e=>{if(!e)return e;let t=it({device:e,modelBytes:a||0,extraBytes:o||0}),n=null;return s!=null&&s!==o&&(n=it({device:e,modelBytes:a||0,extraBytes:s})),{...e,fit:t,...n&&{limitedFit:n}}};return h.selected=g(h.selected),h.attempts=h.attempts.map(g),h},Iee=[`cuda`,`coreml`,`qnn`,`dml`,`webgpu`,`cpu`],ot={cuda:100,coreml:90,qnn:80,dml:80,webgpu:70,cpu:10},st=e=>e&&String(e).trim().toLowerCase()||null,Lee=({provider:e,preferProviders:t=[],providerPreference:n=[]}={})=>{let r=[];e&&r.push(e),r.push(...rt(t)),r.push(...rt(n)),r.push(...Iee);let i=r.map(st).filter(Boolean);return Array.from(new Set(i))},Ree=new Set([`cuda`,`coreml`,`dml`,`webgpu`]),zee=(e=``)=>Ree.has(String(e).toLowerCase()),Bee=e=>Array.isArray(e)?e.map(e=>typeof e==`string`?{name:e,available:!0}:{name:e.name,available:!0}):[],ct=({platform:e,totalMemoryInBytes:t,provider:n,available:r,gpuMemoryFraction:i,cpuMemoryFraction:a,ok:o,error:s})=>{let c=zee(n),l=0;c&&r&&(n===`cuda`?l=8*1024*1024*1024:n===`coreml`?l=Math.floor(t*.5):n===`dml`&&(l=6*1024*1024*1024));let u=t,d=c?Math.floor(l*i):0,f=u?Math.floor(u*a):0,p={platform:e,variant:n,hasGpu:c,gpuUsableBytes:d,cpuUsableBytes:f,ok:o},m=Qe(p),h=o?nt(p):null;return{platform:e,ok:o,provider:n,hasGpu:c,available:r,gpuTotalBytes:l,gpuUsableBytes:d,cpuTotalBytes:u,cpuUsableBytes:f,score:m,breakdown:h,error:s,timestamp:new Date().toISOString()}},Vee=({device:e,modelBytes:t=0,workingMemory:n=0}={})=>it({device:e,modelBytes:t,extraBytes:n}),lt=async({platform:e,provider:t=null,preferProviders:n=[],providerPreference:r=[],gpuMemoryFraction:i=yee,cpuMemoryFraction:a=bee,includeBreakdown:o=!1,totalMemoryInBytes:s,modelBytes:c=null,workingMemory:l=null,dependencies:u={}}={})=>{let{listSupportedBackends:d}=u;if(typeof d!=`function`)throw TypeError(`ONNX capability detection requires listSupportedBackends function`);let f=Lee({provider:t,preferProviders:n,providerPreference:r}),p=[],m=[];try{let e=await d();m=Bee(e)}catch{m=f.map(e=>({name:e,available:!1}))}let h=new Set(m.filter(e=>e.available).map(e=>e.name.toLowerCase()));for(let t of f){if(!h.has(t)){p.push(ct({platform:e,totalMemoryInBytes:s,provider:t,available:!1,gpuMemoryFraction:i,cpuMemoryFraction:a,ok:!1,error:`Provider ${t} not available on this platform`}));continue}p.push(ct({platform:e,totalMemoryInBytes:s,provider:t,available:!0,gpuMemoryFraction:i,cpuMemoryFraction:a,ok:!0}))}let g=p.filter(e=>e.ok),_=(t?g.find(e=>e.provider===st(t)):null)||g.find(e=>e.hasGpu)||g.sort((e,t)=>{let n=ot[e.provider]||0;return(ot[t.provider]||0)-n})[0]||null,v=[],y=[t,...n].filter(Boolean).map(st);for(let e of y)e&&!h.has(e)&&v.push(`Requested provider "${e}" is not available (installed: ${[...h].join(`, `)||`none`})`);let b={ok:!!_,selected:_?{..._,breakdown:o?_.breakdown:void 0}:null,attempts:p,warnings:v};if(!o&&b.selected&&delete b.selected.breakdown,!b||!c&&!l)return b;let x=e=>{if(!e)return e;let t=Vee({device:e,modelBytes:c||0,workingMemory:l||0});return{...e,fit:t}};return b.selected=x(b.selected),b.attempts=Array.isArray(b.attempts)?b.attempts.map(x):b.attempts,b},ut=`onnx-stt`,dt=`onnx-tts`,Hee=new Map([[Aee,kee],[`ggml-stt`,Nee],[`ggml-tts`,Fee],[`mlx-llm`,at],[ut,lt],[dt,lt]]),ft=async({platform:e,totalMemoryInBytes:t,backend:n=Aee,dependencies:r,...i}={})=>{let a=Hee.get(n);if(!a)throw Error(`No capability detector registered for backend "${n}"`);return await a({...i,dependencies:r,totalMemoryInBytes:t,platform:e})},pt={f16:2,f32:4,q8_0:1,q6_k:.75,q5_k:.625,q5_k_m:.625,q5_k_s:.625,q5_1:.625,q5_0:.625,q4_k:.5,q4_k_m:.5,q4_k_s:.5,q4_1:.5,q4_0:.5,iq4_nl:.5},mt=e=>{let t=e?String(e).toLowerCase():`f16`;return pt[t]||pt.f16},Uee=(e,t,n,r,i,a={},{totalLayers:o=null,swaLayers:s=0,swaContext:c=null,swaContextMultiplier:l=1,swaAdditionalTokens:u=0,swaFull:d=!1}={})=>{if(!e||!t||!n||!r||!i)return 0;let f=Number(o!=null&&o!==void 0?o:e),p=Math.max(0,Math.floor(f));if(!p)return 0;let m=mt(a.k),h=mt(a.v),g=Number(n)*(Number(r)*m+Number(i)*h);if(!g)return 0;let _=Math.max(0,Number(t)||0),v=Math.min(p,Math.max(0,Math.floor(Number(s)||0))),y=Math.max(0,p-v),b=c!=null&&Number.isFinite(Number(c))?Math.max(0,Number(c)):_,x=Math.max(1,Number(l)||1),S=Math.max(0,Number(u)||0),C=b*x+S,w=d?_:Math.min(_,C),T=y*_+v*Math.max(0,Math.floor(w));return Math.round(g*T)},Wee=({modelBytes:e=0,audioLengthSeconds:t=30,sampleRate:n=16e3,bytesPerSample:r=4}={})=>{let i=Math.max(0,Number(e)||0),a=Math.max(0,Math.floor(Math.max(0,t)*n*r)),o=1024*1024,s=1024*o,c;c=i<200*o?120*o:i<500*o?140*o:i<2*s?150*o:160*o;let l;l=i<200*o?70*o:i<500*o?135*o:220*o;let u;u=i<100*o?20*o:i<200*o?30*o:i<500*o?85*o:i<2*s?215*o:360*o;let d=c+l+u;return{modelBytes:i,audioBufferBytes:a,processingBufferBytes:d,totalBytes:i+d+a}},Gee=({modelBytes:e=0,audioLengthSeconds:t=30,sampleRate:n=16e3,bytesPerSample:r=4}={})=>{let i=Math.max(0,Number(e)||0),a=Math.max(0,Math.floor(Math.max(0,t)*n*r)),o=640*1048576;return{modelBytes:i,audioBufferBytes:a,processingBufferBytes:o,totalBytes:i+o+a}},ht=({modelBytes:e=0,vocoderBytes:t=0,contextSize:n=8192,vocoderBatchSize:r=4096}={})=>{let i=Math.max(0,Number(e)||0),a=Math.max(0,Number(t)||0),o=Math.max(0,Number(n)||0),s=Math.max(0,Number(r)||0),c=o*98304,l=s*24576,u=Math.max(100663296,c+l);return{modelBytes:i+a,backboneBytes:i,vocoderBytes:a,kvCacheBytes:c,codecBufferBytes:l,processingBufferBytes:u,totalBytes:i+a+u}},gt=e=>e?String(e).trim().toLowerCase():null,Kee=(e={},t=null)=>{if(!e)return null;let n=gt(t),r=n?`${n}.attention.sliding_window`:null,i=(r&&e[r]!=null?e[r]:null)??e[`llama.attention.sliding_window`];if(i==null)return null;let a=Number(i);return Number.isFinite(a)?a:null},qee=(e=0,t=0,n=!1)=>{let r=Math.max(0,Math.floor(Number(e)||0)),i=Math.max(0,Math.floor(Number(t)||0));if(!r||i===1)return 0;if(i<=0)return r;let a=Math.max(0,i-1),o=Math.floor(r/i),s=r%i,c=n?Math.max(0,s-1):Math.min(s,a);return o*a+c},_t=({arch:e,nLayer:t=0})=>({arch:gt(e),enabled:!1,window:null,pattern:null,denseFirst:!1,type:null,kvLayers:Math.max(0,Math.floor(Number(t)||0)),swaLayers:0}),Jee=new Map([[`llama4`,({nSwa:e})=>e===0?{enabled:!1}:{enabled:!0,window:e&&e>0?e:8192,pattern:4,type:`chunked`}],[`afmoe`,({nSwa:e})=>!e||e<=0?{enabled:!1}:{enabled:!0,window:e,pattern:4,type:`standard`}],[`phi3`,()=>({enabled:!1})],[`gemma2`,({nSwa:e})=>{let t=e&&e>0?e:4096;return t?{enabled:!0,window:t,pattern:2,type:`standard`}:{enabled:!1}}],[`gemma3`,({nSwa:e})=>!e||e<=0?{enabled:!1}:{enabled:!0,window:e,pattern:6,type:`standard`}],[`gemma3n`,({nLayer:e,nSwa:t})=>!t||t<=0?{enabled:!1}:{enabled:!0,window:t,pattern:5,type:`standard`,kvLayers:Math.min(20,e)}],[`gemma-embedding`,({nSwa:e})=>!e||e<=0?{enabled:!1}:{enabled:!0,window:e,pattern:6,type:`symmetric`}],[`cohere2`,({nSwa:e})=>!e||e<=0?{enabled:!1}:{enabled:!0,window:e,pattern:4,type:`standard`}],[`olmo2`,({nSwa:e})=>!e||e<=0?{enabled:!1}:{enabled:!0,window:e,pattern:4,type:`standard`}],[`exaone4`,({nLayer:e,nSwa:t})=>{let n=e>=64,r=null;return t&&t>0?r=t:n&&(r=4096),r?{enabled:!0,window:r,pattern:4,type:`standard`}:{enabled:!1}}],[`gpt-oss`,({nSwa:e})=>!e||e<=0?{enabled:!1}:{enabled:!0,window:e,pattern:2,type:`standard`}],[`gemma4`,({nLayer:e,nSwa:t,metadata:n})=>{if(!t||t<=0)return{enabled:!1};let r=Number(n?.[`gemma4.attention.shared_kv_layers`])||0,i=Math.max(0,e-r),a=n?.[`gemma4.attention.sliding_window_pattern`];return Array.isArray(a)?{enabled:!0,window:t,type:`standard`,swaLayers:a.slice(0,i).filter(e=>Number(e)>0).length,kvLayers:i}:{enabled:!0,window:t,pattern:6,type:`standard`,kvLayers:i}}],[`smallthinker`,({nSwa:e})=>!e||e<=0?{enabled:!1}:{enabled:!0,window:4096,pattern:4,denseFirst:!0,type:`standard`}]]),vt=({arch:e,metadata:t={},nLayer:n=0}={})=>{let r=gt(e||t[`general.architecture`]),i=Math.max(0,Math.floor(Number(n)||0)),a=Kee(t,r),o=r?Jee.get(r):null;if(!o)return _t({arch:r,nLayer:n});let s=o({nLayer:i,nSwa:a,metadata:t});if(!s||!s.enabled||!s.window||s.window<=0)return _t({arch:r,nLayer:n});let c=Math.max(0,Math.floor(Number(s.pattern)||0)),l=s.kvLayers!=null&&Number.isFinite(Number(s.kvLayers))?Number(s.kvLayers):i,u=Math.max(0,Math.floor(l)),d=s.swaLayers!=null&&Number.isFinite(Number(s.swaLayers))?Math.max(0,Math.floor(Number(s.swaLayers))):qee(u,c,!!s.denseFirst);return{arch:r,enabled:d>0,window:s.window,pattern:c,denseFirst:!!s.denseFirst,type:s.type||`standard`,kvLayers:u,swaLayers:d}},Yee=new Set([`mamba`,`mamba2`,`rwkv6`,`rwkv6qwen2`,`rwkv7`,`arwkv7`]),Xee=new Set([`jamba`,`falcon-h1`,`plamo2`,`granitehybrid`,`lfm2`,`lfm2moe`,`nemotron_h`,`nemotron_h_moe`,`qwen3next`]),yt=e=>e?String(e).trim().toLowerCase():null,Zee=e=>{let t=yt(e);return t?Yee.has(t):!1},Qee=e=>{let t=yt(e);return t?Xee.has(t):!1},bt=e=>Zee(e)?`recurrent`:Qee(e)?`hybrid`:`transformer`,xt=(e={})=>{let t=e[`general.architecture`],n=(t,n=null)=>{let r=e[t],i=Number(r);return Number.isFinite(i)?i:n},r=(t,n=null)=>{let r=e[t];if(Array.isArray(r))return r;let i=Number(r);return Number.isFinite(i)?i:n},i=t?n(`${t}.context_length`,n(`llama.context_length`)):null,a=t?n(`${t}.block_count`,n(`llama.block_count`)):null,o=t?n(`${t}.embedding_length`,n(`llama.embedding_length`)):null,s=t?n(`${t}.attention.head_count`,n(`llama.attention.head_count`)):null,c=t?r(`${t}.attention.head_count_kv`,r(`llama.attention.head_count_kv`,s)):null,l=null,u=null;if(Array.isArray(c)){let e=c.filter(e=>Number(e)>0);e.length>0?(l=Math.max(...e.map(Number)),u=e.length):(l=0,u=0)}else l=c;let d=t?n(`${t}.attention.key_length`,n(`llama.attention.key_length`)):null,f=t?n(`${t}.attention.value_length`,n(`llama.attention.value_length`)):null,p=e[`general.quantization_version`]||null,m=e[`general.file_type`]||null,h=t?n(`${t}.ssm.conv_kernel`):null,g=t?n(`${t}.ssm.state_size`):null,_=t?n(`${t}.ssm.inner_size`):null,v=t?n(`${t}.ssm.group_count`):null,y=t?n(`${t}.ssm.time_step_rank`):null,b=t?n(`${t}.rwkv.head_size`):null,x=t?n(`${t}.rwkv.token_shift_count`,2):null,S=t?n(`${t}.attention.shared_kv_layers`,0):0,C=u!=null&&a!=null?a-u:null;return{arch:t,nCtxTrain:i,nLayer:a,nEmbd:o,nHead:s,nHeadKv:l,nEmbdHeadK:d,nEmbdHeadV:f,quantVersion:p,fileType:m,attentionLayerCount:u,recurrentLayerCount:C,ssmDConv:h,ssmDState:g,ssmDInner:_,ssmNGroup:v,ssmDtRank:y,rwkvHeadSize:b,rwkvTokenShiftCount:x,sharedKvLayers:S}},St=({layerCount:e,headKvCount:t,embdHeadKCount:n,embdHeadVCount:r,cacheTypes:i,swaConfig:a,kvUnified:o=!1,nParallel:s=1,swaFull:c=!1,arch:l=null,attentionLayerCount:u=null})=>{let d=bt(l);if(d===`recurrent`)return()=>0;let f=d===`hybrid`&&u!=null?Math.max(0,Math.floor(Number(u)||0)):e,p=a?.window&&o?Math.max(1,Number(s)||1):1,m=o?1:Math.max(1,Number(s)||1);return e=>Uee(f,e,t,n,r,i,{totalLayers:f,swaLayers:a?.swaLayers||0,swaContext:a?.window,swaFull:c,swaContextMultiplier:p})*m},Ct=({nLayer:e,nEmbd:t,recurrentLayerCount:n=null,nSeqMax:r=1,ssmDConv:i=null,ssmDState:a=null,ssmDInner:o=null,ssmNGroup:s=null,ssmDtRank:c=null,rwkvHeadSize:l=null,rwkvTokenShiftCount:u=2,arch:d=null})=>{if(bt(d)===`transformer`)return 0;let f=n==null?Math.max(0,Math.floor(Number(e)||0)):Math.max(0,Math.floor(Number(n)||0));if(f===0)return 0;let p=Math.max(1,Math.floor(Number(r)||1)),m=0,h=0;if(l!=null&&l>0&&t!=null&&t>0)m=Math.max(1,Number(u)||2)*t,h=t*l;else if(a!=null&&o!=null){let e=Math.max(0,Number(i)||0),t=Math.max(0,Number(a)||0),n=Math.max(0,Number(o)||0),r=Math.max(1,Number(s)||1);Math.max(0,Number(c)||0)>0?(m=e>0?(e-1)*2*r*t:0,h=Math.floor(t*n/2)):(m=e>0?(e-1)*(n+2*r*t):0,h=t*n)}else return 0;let g=(m+h)*p*f*4;return Math.max(0,g)},wt=({maxCtx:e,availableMemory:t,modelBytes:n,kvBytesForCtx:r})=>{let i=Math.max(1,Math.floor(Number(e)||0));if(!r||t<=n)return i;let a=1,o=i,s=i;for(;a<=o;){let e=Math.floor((a+o)/2);n+r(e)<=t?(s=e,a=e+1):o=e-1}return s},$ee={fp32:``,fp16:`_fp16`,int8:`_int8`,uint8:`_uint8`,q8:`_quantized`,q4:`_q4`,q4f16:`_q4f16`,bnb4:`_bnb4`},Tt={cuda:2,coreml:1.5,dml:1.8,webgpu:2,qnn:1.5,cpu:1.3},ete={whisper:[`encoder_model`,`decoder_model_merged`],speech_to_text:[`encoder_model`,`decoder_model_merged`],speecht5:[`encoder_model`,`decoder_model_merged`],vits:[`model`],style_text_to_speech_2:[`model`],bert_vits2:[`model`],chatterbox:[`embed_tokens`,`language_model`,`speech_encoder`,`conditional_decoder`],llama:[`model`],gpt2:[`model`],qwen2:[`model`],phi:[`model`],mistral:[`model`],gemma:[`model`]},tte=[`model`],nte=(e,t,n)=>{if(typeof t==`object`&&t){let n=t[e];if(typeof n==`string`&&n!==`auto`)return n}else if(typeof t==`string`&&t!==`auto`)return t;let r=n?.dtype;if(typeof r==`object`&&r){let t=r[e];if(typeof t==`string`&&t!==`auto`)return t}else if(typeof r==`string`&&r!==`auto`)return r;return`fp32`},rte=e=>ete[e]||tte,Et=({siblings:e,modelType:t,dtype:n,tjConfig:r,subfolder:i=`onnx`})=>{let a=rte(t),o=[],s=[],c=0,l=new Map(e.map(e=>[e.rfilename,e]));for(let e of a){let t=nte(e,n,r),a=`${i}/${e}${$ee[t]??``}.onnx`,u=`${a}_data`,d=l.get(a),f=l.get(u);if(!d){o.push(`File not found: ${e} (dtype=${t})`),s.push({name:e,dtype:t,bytes:0});continue}let p=(d.size||0)+(f?.size||0);s.push({name:e,dtype:t,bytes:p,onnxPath:a,dataPath:f?u:null}),c+=p}return{totalBytes:c,files:s,warnings:o}},Dt=(e,t=`cpu`)=>{let n=Tt[t]||Tt.cpu;return Math.ceil(e*n)},Ot=new se;Ot.setMaxListeners(100);const kt=()=>{let e=[];return Object.defineProperties(e,{start:{value:0,writable:!0},count:{value:0,writable:!0}}),e},At=(e,t,n)=>{if(n<=0)return;let r={...t,timestamp:t.timestamp||new Date().toISOString()};if(e.count<n){e.push(r),e.count+=1;return}e[e.start]=r,e.start=(e.start+1)%n},jt=e=>{let t=[];for(let n=0;n<e.count;n+=1){let r=(e.start+e.count-1-n)%e.length;t.push(e[r])}return t},Mt=e=>{e.length=0,e.start=0,e.count=0};var Nt=class{constructor(e=9999){this.maxEntries=e,this.modelLoads=kt(),this.completions=kt(),this.transcriptions=kt()}addModelLoad(e){At(this.modelLoads,e,this.maxEntries),Ot.emit(`status:modelLoad`,e),Ot.emit(`status:change`,{type:`modelLoad`,entry:e})}addCompletion(e){At(this.completions,e,this.maxEntries),Ot.emit(`status:completion`,e),Ot.emit(`status:change`,{type:`completion`,entry:e})}addTranscription(e){At(this.transcriptions,e,this.maxEntries),Ot.emit(`status:transcription`,e),Ot.emit(`status:change`,{type:`transcription`,entry:e})}getModelLoadHistory(){return jt(this.modelLoads)}getCompletionHistory(){return jt(this.completions)}getTranscriptionHistory(){return jt(this.transcriptions)}clear(){Mt(this.modelLoads),Mt(this.completions),Mt(this.transcriptions)}};const Pt=new Nt,Ft=new Nt,It=new Nt,Lt=new Nt,Rt=new Nt;let zt=0;function Bt(e){let t=t=>e(t);return Ot.on(`status:change`,t),()=>Ot.off(`status:change`,t)}function ite(e){return zt+=1,{subscriberId:zt,unsubscribe:Bt(e)}}function Vt(e){let t=[];return{generators:Array.from(e.entries()).filter(([,e])=>e.type===`ggml-llm`).map(([e,n])=>{let{instance:r}=n,i=[];return r.contexts&&(i=Array.from(r.contexts.entries()).map(([n,r])=>{let i={key:n,refCount:r.refCount,hasModel:!!r.context};if(r.context){let a=r.context.parallel.getStatus();i.parallelStatus=a,t.push({generatorId:e,contextKey:n,...a})}return i})),{id:e,type:n.type,refCount:n.refCount,repoId:r.info?.model?.repoId||null,quantization:r.info?.model?.quantization||null,variant:r.info?.runtime?.variant||null,nCtx:r.info?.runtime?.n_ctx||null,nParallel:r.info?.runtime?.n_parallel||null,contexts:i}}),parallelStatuses:t,history:{modelLoads:Pt.getModelLoadHistory().filter(e=>e.variant!==`mlx`),completions:Pt.getCompletionHistory().filter(e=>e.variant!==`mlx`)}}}function Ht(e){return{generators:Array.from(e.entries()).filter(([,e])=>e.type===`ggml-stt`).map(([e,t])=>{let{instance:n}=t,r=n.getStatus?.()||{},i=r.queueStatus||{processing:!1,queuedCount:0};return{id:e,type:t.type,refCount:t.refCount,repoId:n.info?.model?.repoId||null,quantization:n.info?.model?.quantization||null,modelType:n.info?.model?.modelType||null,variant:n.info?.runtime?.variant||null,hasContext:r.hasContext||!1,contextRefCount:r.contextRefCount||0,queueStatus:i}}),history:{modelLoads:Ft.getModelLoadHistory(),transcriptions:Ft.getTranscriptionHistory()}}}function Ut(e){return{generators:Array.from(e.entries()).filter(([,e])=>e.type===`mlx-llm`).map(([e,t])=>{let{instance:n}=t,r=n.getStatus?.()||{};return{id:e,type:t.type,refCount:t.refCount,repoId:r.repoId||n.info?.model?.repoId||null,variant:r.variant||`mlx`,contexts:r.contexts||[]}}),history:{modelLoads:Pt.getModelLoadHistory().filter(e=>e.variant===`mlx`),completions:Pt.getCompletionHistory().filter(e=>e.variant===`mlx`)}}}function ate(e){return{generators:Array.from(e.entries()).filter(([,e])=>e.type===`onnx-stt`).map(([e,t])=>{let{instance:n}=t;return{id:e,type:t.type,refCount:t.refCount,repoId:n.info?.model?.repoId||null,dtype:n.info?.model?.dtype||null,provider:n.info?.runtime?.provider||null,device:n.info?.runtime?.device||null,modelBytes:n.info?.model?.modelBytes||0,pipelines:n.getStatus?.()?.pipelineCount??0}}),history:{modelLoads:Lt.getModelLoadHistory(),transcriptions:Lt.getTranscriptionHistory()}}}function Wt(e){return{generators:Array.from(e.entries()).filter(([,e])=>e.type===`ggml-tts`).map(([e,t])=>{let{instance:n}=t;return{id:e,type:t.type,refCount:t.refCount,repoId:n.info?.model?.repoId||null,quantization:n.info?.model?.quantization||null,vocoderRepoId:n.info?.model?.vocoderRepoId||null,family:n.getStatus?.()?.family||null,variant:n.info?.runtime?.variant||null,useGpu:n.info?.runtime?.use_gpu||!1,modelBytes:n.info?.resources?.modelBytes||0,hasContext:n.getStatus?.()?.hasContext??!1}}),history:{modelLoads:It.getModelLoadHistory(),syntheses:It.getTranscriptionHistory()}}}function ote(e){return{generators:Array.from(e.entries()).filter(([,e])=>e.type===`onnx-tts`).map(([e,t])=>{let{instance:n}=t;return{id:e,type:t.type,refCount:t.refCount,repoId:n.info?.model?.repoId||null,dtype:n.info?.model?.dtype||null,provider:n.info?.runtime?.provider||null,device:n.info?.runtime?.device||null,modelBytes:n.info?.model?.modelBytes||0,vocoderRepoId:n.info?.model?.vocoderRepoId||null,pipelines:n.getStatus?.()?.pipelineCount??0}}),history:{modelLoads:Rt.getModelLoadHistory(),syntheses:Rt.getTranscriptionHistory()}}}function ste(e){return{timestamp:new Date().toISOString(),ggmlLlm:Vt(e),ggmlStt:Ht(e),mlxLlm:Ut(e),onnxStt:ate(e),onnxTts:ote(e),ggmlTts:Wt(e)}}const Gt=e=>new Date(e.lastAccessedAt).getTime();async function Kt({entries:e,totalSize:t,maxEntries:n,maxSizeBytes:r,removeEntry:i,getEntrySize:a=e=>e.fileSize||0}){let o=Object.values(e||{}),s=o.length,c=t||0;if(s<=n&&c<=r)return{evictedEntries:[],totalSize:c};o.sort((e,t)=>Gt(e)-Gt(t));let l=[];for(let t of o){if(s<=n&&c<=r)break;await i(t),c-=a(t),--s,delete e[t.id],l.push(t)}return{evictedEntries:l,totalSize:Math.max(0,c)}}const qt=(e={},t={})=>(Object.entries(t||{}).forEach(([t,n])=>{n&&typeof n==`object`&&!Array.isArray(n)?((!e[t]||typeof e[t]!=`object`)&&(e[t]={}),qt(e[t],n)):e[t]=n}),e),Jt=e=>e==null?void 0:Math.min(1,Math.max(0,Number(e))),Yt=(e,t=[])=>!e&&e!==0?[...t]:Array.isArray(e)?e.filter(e=>e!=null):[e],Xt=(e,t)=>{let n=t?t instanceof Set?t:new Set(t):null;return Array.from(new Set(Yt(e).flatMap(e=>{let t=e?String(e).toLowerCase():null;return t&&(!n||n.has(t))?[t]:[]})))},Zt=e=>{let t=new Set(e);return{normalizeVariants:e=>Xt(e,t),sanitizeVariant:e=>{if(!e)return null;let n=String(e).toLowerCase();return t.has(n)?n:null}}},cte=globalThis.WritableStream||g.WritableStream,Qt=async e=>{await b(e,{recursive:!0})},$t=e=>e===`..`||e.startsWith(`..${M.sep}`)||M.isAbsolute(e),lte=(e,t)=>{if(typeof e!=`string`||e.length===0)throw Error(`Invalid model cache path: ${t} must be a non-empty relative path`);let n=e.replaceAll(`\\`,`/`);if(M.posix.isAbsolute(n)||M.win32.parse(e).root)throw Error(`Invalid model cache path: ${t} must be relative`);let r=n.split(`/`);if(r.some(e=>!e||e===`.`||e===`..`))throw Error(`Invalid model cache path: ${t} must not contain empty, "." or ".." segments`);return r},en=(e,t,n)=>{let r=M.resolve(e),i=t.flatMap(([e,t])=>lte(e,`${n} ${t}`)),a=M.resolve(r,...i),o=M.relative(r,a);if(!o||$t(o))throw Error(`Invalid model cache path: ${n} escapes the configured cache root`);return a},tn=(e,t,n)=>en(e,[[t.repoId,`repository`],[t.revision,`revision`],[t.filename,`filename`]],n),ute=async e=>{let t;try{t=await y(e)}catch(n){if(n?.code!==`ENOENT`)throw n;try{await b(e)}catch(e){if(e?.code!==`EEXIST`)throw e}t=await y(e)}if(t.isSymbolicLink()||!t.isDirectory())throw Error(`Unsafe download destination: cache path contains a non-directory or symlink`)},nn=async(e,t)=>{let n=M.resolve(t),r=M.resolve(e),i=M.relative(n,r);if(!i||$t(i))throw Error(`Unsafe download destination: path escapes the allowed root`);await Qt(n);let a=await w(n),o=i.split(M.sep),s=a;for(let e of o.slice(0,-1))s=M.join(s,e),await ute(s);let c=M.join(a,...o);try{if((await y(c)).isSymbolicLink())throw Error(`Unsafe download destination: target is a symlink`)}catch(e){if(e?.code!==`ENOENT`)throw e}return r},rn=async(e,t)=>{try{let n=await D(e);return!t||n.size===t}catch{return!1}},an=async(e,t={})=>{if(typeof fetch!=`function`)throw Error(`Global fetch is not available in this runtime`);let n=await fetch(e,t);if(!n.ok){let t=await n.text().catch(()=>``);throw Error(`Failed to fetch ${e}: ${n.status} ${n.statusText} ${t}`.trim())}return n.json()},on=async(e,t={})=>{if(typeof fetch!=`function`)throw Error(`Global fetch is not available in this runtime`);let n=await fetch(e,{...t,method:`HEAD`});if(!n.ok)throw Error(`Failed to fetch headers for ${e}: ${n.status} ${n.statusText}`);return n},sn=async(e,t)=>{t&&await t.close().catch(()=>{}),await O(e).catch(()=>{})},cn=async(e,t,n,r,i,{allowedRoot:a}={})=>{if(typeof fetch!=`function`)throw Error(`Global fetch is not available in this runtime`);let o=a?await nn(n,a):n;a||await Qt(M.dirname(o));let s=await fetch(e,{headers:t});if(!s.ok||!s.body)throw Error(`Failed to download ${e}: ${s.status} ${s.statusText}`);let c=await x(o,a?le.O_WRONLY|le.O_CREAT|le.O_TRUNC|(le.O_NOFOLLOW||0):`w`),l=Number(s.headers.get(`content-length`))||r||0,u=0,d=.05;try{await s.body.pipeTo(new cte({async write(e){if(await c.write(e),u+=e.byteLength,typeof i==`function`&&l>0){let e=Math.min(1,u/l);for(;e>=d;)i(d),d+=.05}},async close(){await c.close(),typeof i==`function`&&i(1)},async abort(e){throw await sn(o,c),e}}))}catch(e){throw await sn(o,c),e}if(r){let e=await D(o);if(e.size!==r)throw await sn(o),Error(`Downloaded file size mismatch, expected ${r} got ${e.size}`)}},dte=(e,t,n)=>{let r=A(`sha256`).update(n).digest(`hex`);return M.join(e,`.metadata-cache`,t,`${r}.json`)},ln=({defaultBaseDir:e,replacer:t,reviver:n,onRead:r,onWrite:i,onWriteError:a}={})=>({read:async(t,i,a=e)=>{try{let e=dte(a,i,t),o=await S(e,`utf-8`);return r?.({cacheType:i,filePath:e}),JSON.parse(o,n)}catch{return null}},write:async(n,r,o,s=e)=>{try{let e=dte(s,r,n);await b(M.dirname(e),{recursive:!0}),await k(e,JSON.stringify(o,t),`utf-8`),i?.({cacheType:r,filePath:e})}catch(e){a?.({cacheType:r,error:e})}}}),un=e=>{let t=!0;return{enqueue:n=>{t&&e.enqueue(n)},close:()=>{t&&(t=!1,e.close())},error:n=>{t&&(t=!1,e.error(n))},markClosed:()=>{t=!1}}},fte=globalThis.ReadableStream||g.ReadableStream,pte=(e,t)=>Object.prototype.hasOwnProperty.call(e||{},t),mte=`https://huggingface.co`,hte=`https://huggingface.co/api`,dn=M.join(N.homedir(),`.buttress`,`models`),fn=[`cuda`,`vulkan`,`snapdragon`,`default`],gte=[`mxfp4`,`q8_0`,`q6_k`,`q6`,`q5_k_m`,`q5_k_s`,`q5_k`,`q5_1`,`q5_0`,`q4_k_m`,`q4_k_s`,`q4_k`,`q4_1`,`q4_0`,`q3`,`q2`],pn=.5,mn=[`speculative`,`spec_type`,`spec_draft_n_max`,`spec_draft_n_min`,`spec_draft_p_min`,`spec_draft_p_split`],_te=[...mn,`spec_draft_n_gpu_layers`,`spec_draft_cache_type_k`,`spec_draft_cache_type_v`],vte=[`model_draft`,`draft_model`,`spec_draft_n_gpu_layers`,`spec_draft_cache_type_k`,`spec_draft_cache_type_v`],yte=(e,t)=>{if(!(t==null||t===``)){if(e===`spec_draft_n_max`||e===`spec_draft_n_min`){let e=Number(t);return Number.isFinite(e)?Math.max(0,Math.floor(e)):void 0}if(e===`spec_draft_p_min`||e===`spec_draft_p_split`){let e=Number(t);return Number.isFinite(e)?Math.max(0,e):void 0}if(e===`spec_draft_n_gpu_layers`){let e=Number(t);return Number.isFinite(e)?Math.floor(e):void 0}return t}},bte=e=>{let t={};for(let n of _te){let r=yte(n,e.model[n]??e.runtime[n]);r!==void 0&&(t[n]=r)}return t},xte=(e={})=>{let t={};for(let n of mn){let r=yte(n,e[n]);r!==void 0&&(t[n]=r)}return t},Ste=(e={},t={})=>{let n={...e||{}};for(let e of vte)delete n[e];let r=xte(t);return!Object.keys(r).length||mn.some(e=>pte(n,e))?n:{...r,...n}},hn={backend:{type:`ggml-llm`,variant:null,variant_preference:fn,gpu_memory_fraction:.85,cpu_memory_fraction:pn},model:{repo_id:null,revision:`main`,filename:null,url:null,quantization:null,preferred_quantizations:[],n_ctx:null,n_gpu_layers:`auto`,allow_local_file:!1,local_path:null,api_base:hte,base_url:mte,enable_mtmd:!1,mmproj_filename:null,mmproj_url:null,mmproj_local_path:null,mmproj_use_gpu:null,mmproj_image_min_tokens:-1,mmproj_image_max_tokens:-1,model_draft:null,embedding:!1,pooling_type:null,vocab_only:!1,speculative:null,spec_type:null,spec_draft_n_max:null,spec_draft_n_min:null,spec_draft_p_min:null,spec_draft_p_split:null,spec_draft_n_gpu_layers:null,spec_draft_cache_type_k:null,spec_draft_cache_type_v:null},runtime:{cache_dir:dn,prefer_variants:[],huggingface_token:process.env.HUGGINGFACE_TOKEN||null,http_headers:{},session_cache:{enabled:!0,max_size_bytes:10*1024*1024*1024,max_entries:1e3},context_release_delay_ms:1e4}},{normalizeVariants:gn,sanitizeVariant:Cte}=Zt(fn),_n=(e={})=>{let t=structuredClone(hn);if(qt(t,e),t.backend.variant=Cte(t.backend.variant),t.backend.variant_preference=gn(t.backend.variant_preference),t.backend.variant_preference.length===0&&(t.backend.variant_preference=[...fn]),t.runtime.prefer_variants=gn(t.runtime.prefer_variants),t.model.preferred_quantizations=Xt(t.model.preferred_quantizations||t.model.quantizations),t.model.quantization){let e=String(t.model.quantization).toLowerCase();t.model.preferred_quantizations.includes(e)||t.model.preferred_quantizations.unshift(e)}t.model.n_parallel=t.model.n_parallel?Math.max(1,Number(t.model.n_parallel)):void 0,t.model.n_batch=Math.max(1,Number(t.model.n_batch)||512),t.model.base_url=t.model.base_url||mte,t.model.api_base=t.model.api_base||hte,t.model.enable_mtmd=!!t.model.enable_mtmd;let n=e=>{if(e==null)return-1;let t=Number(e);return Number.isFinite(t)?Math.floor(t):-1};t.model.mmproj_image_min_tokens=n(t.model.mmproj_image_min_tokens),t.model.mmproj_image_max_tokens=n(t.model.mmproj_image_max_tokens),t.runtime.cache_dir=t.runtime.cache_dir?M.resolve(t.runtime.cache_dir):dn,t.runtime.session_cache={...hn.runtime.session_cache,...t.runtime.session_cache||{}};let r=Number(t.runtime.context_release_delay_ms);return t.runtime.context_release_delay_ms=Number.isFinite(r)?Math.max(0,r):hn.runtime.context_release_delay_ms,t},wte=e=>{let t=e.toLowerCase();return gte.find(e=>t.includes(e))||null},Tte=e=>{let t=[];return e.backend.variant&&t.push(e.backend.variant),e.runtime.prefer_variants.length>0&&t.push(...e.runtime.prefer_variants),t.push(...e.backend.variant_preference),t.push(`default`),gn(t)},{read:vn,write:yn}=ln({defaultBaseDir:dn,replacer:(e,t)=>typeof t==`bigint`?`__bigint__${t.toString()}`:t,reviver:(e,t)=>typeof t==`string`&&t.startsWith(`__bigint__`)?BigInt(t.slice(10)):t,onRead:({cacheType:e,filePath:t})=>console.log(`[Cache] Hit ${e} cache:`,M.basename(t)),onWrite:({cacheType:e,filePath:t})=>console.log(`[Cache] Wrote ${e} cache:`,M.basename(t)),onWriteError:({cacheType:e,error:t})=>console.warn(`[Cache] Failed to write ${e} cache:`,t.message)}),bn=(e=dn)=>M.join(e,`.session-state-cache`),Ete=(e=dn)=>M.join(bn(e),`cache-map.json`),xn=(e=dn)=>M.join(bn(e),`temp`),Dte=(e=dn)=>M.join(bn(e),`states`),Ote=()=>({version:1,entries:{},totalSize:0}),kte=async(e=dn)=>{try{let t=await S(Ete(e),`utf-8`),n=JSON.parse(t);return!n.entries||typeof n.entries!=`object`?Ote():n}catch{return Ote()}},Ate=new Map,jte=e=>{let t=Ate.get(e);return t||(t=kte(e),Ate.set(e,t)),t},Mte=async(e,t=dn)=>{let n=Ete(t),r=`${n}.tmp.${Date.now()}`;try{await Qt(M.dirname(n)),await k(r,JSON.stringify(e,null,2),`utf-8`),await T(r,n)}catch(e){throw await O(r).catch(()=>{}),e}},Nte=(e,t)=>{let n=JSON.stringify({text:e,model:t.modelPath,variant:t.variant,n_gpu_layers:t.n_gpu_layers,n_ctx:t.n_ctx,cacheTypeK:t.cacheTypeK,cacheTypeV:t.cacheTypeV,kvUnified:t.kvUnified,swaFull:t.swaFull,flashAttnType:t.flashAttnType});return A(`sha256`).update(n).digest(`hex`).slice(0,24)},Pte=(e,t=dn)=>M.join(Dte(t),`${e}.bin`),Fte=(e=dn)=>{let t=`${Date.now()}-${Math.random().toString(36).slice(2,10)}`;return M.join(xn(e),`${t}.bin`)},Sn=e=>(e.stateFileSize||0)+(e.promptStateSize||0),Cn=e=>`${e}.meta`,wn=async(...e)=>{let t=e.filter(Boolean).flatMap(e=>[e,Cn(e)]);await Promise.all(t.map(e=>O(e).catch(()=>{})))},Ite=async(e,t)=>{await T(e,t),await T(Cn(e),Cn(t)).catch(()=>O(Cn(t)).catch(()=>{}))},Tn=e=>wn(e.stateFilePath,e.promptStatePath),En=(e,t)=>e.modelPath===t.modelPath&&e.variant===t.variant&&e.n_gpu_layers===t.n_gpu_layers&&e.n_ctx>=t.n_ctx&&e.cacheTypeK===t.cacheTypeK&&e.cacheTypeV===t.cacheTypeV&&e.kvUnified===t.kvUnified&&e.swaFull===t.swaFull&&e.flashAttnType===t.flashAttnType&&!!e.isRecurrent==!!t.isRecurrent&&!!e.isHybrid==!!t.isHybrid,Lte=(e,t)=>{let n=Math.min(e.length,t.length),r=0;for(;r<n&&e[r]===t[r];)r+=1;return r},Rte=(e,t,n,r=!1)=>{let i=Object.values(n.entries);console.log(`[SessionCache] Finding match for promptText (${e.length} chars), exactMatch=${r}`),console.log(`[SessionCache] Checking ${i.length} cache entries`);let a=i.filter(e=>En(e.metadata,t));if(r){let t=a.find(t=>t.fullText===e);return t?(console.log(`[SessionCache] Exact match found: ${t.id} (${t.fullText.length} chars)`),{entry:t,prefixLength:t.fullText.length,exactMatch:!0}):null}let o=a.reduce((t,n)=>{let r=Lte(e,n.fullText);return r>t.prefixLen||r===t.prefixLen&&n.fullText.length>(t.entry?.fullText?.length||0)?{entry:n,prefixLen:r}:t},{entry:null,prefixLen:0});return o.entry?(console.log(`[SessionCache] Prefix match found: ${o.entry.id} (${o.prefixLen}/${o.entry.fullText.length} chars)`),{entry:o.entry,prefixLength:o.prefixLen}):(console.log(`[SessionCache] No match found`),null)},zte=async(e,t,n)=>{let{evictedEntries:r,totalSize:i}=await Kt({entries:e.entries,totalSize:e.totalSize,maxEntries:n,maxSizeBytes:t,getEntrySize:Sn,removeEntry:async e=>{await Tn(e),console.log(`[SessionCache] Evicted entry: ${e.id}`)}});return e.totalSize=i,r.map(e=>e.id)},Bte=async(e,t,n,r)=>{let i=[];for(let[a,o]of Object.entries(e.entries))a!==n&&En(o.metadata,r)&&t.startsWith(o.fullText)&&o.fullText.length<t.length&&i.push(o);return await Promise.all(i.map(async t=>{await Tn(t),e.totalSize-=Sn(t),delete e.entries[t.id],console.log(`[SessionCache] Evicted superseded prefix entry: ${t.id} (${t.promptText.length} prompt chars)`)})),i.map(e=>e.id)},Vte=async(e=dn)=>{let t=xn(e);try{let e=await C(t),n=Date.now();await Promise.all(e.map(async e=>{let r=M.join(t,e),i=await D(r).catch(()=>null);i&&n-i.mtimeMs>36e5&&(await O(r).catch(()=>{}),console.log(`[SessionCache] Cleaned up temp file: ${e}`))}))}catch{}},Dn=async e=>{try{return await D(e),!0}catch{return!1}},Hte=(e,t)=>e==null?t:typeof e==`number`?e:typeof e==`string`?oe.parse(e)??t:t;var Ute=class e{constructor(e,t){this.config=e,this.plan=t,this.baseDir=e.runtime.cache_dir,this.enabled=e.runtime.session_cache?.enabled!==!1,this.maxSizeBytes=Hte(e.runtime.session_cache?.max_size_bytes,10*1024*1024*1024),this.maxEntries=e.runtime.session_cache?.max_entries||1e3,this.metadata={variant:t.info?.runtime?.variant||null,n_gpu_layers:t.info?.runtime?.n_gpu_layers||0,n_ctx:t.info?.runtime?.n_ctx||0,modelPath:t.localPath,cacheTypeK:t.info?.runtime?.cache_type_k||`f16`,cacheTypeV:t.info?.runtime?.cache_type_v||`f16`,kvUnified:t.info?.runtime?.kv_unified??null,swaFull:t.info?.runtime?.swa_full??null,flashAttnType:t.info?.runtime?.flash_attn_type||`off`,isRecurrent:!1,isHybrid:!1},this.cacheMap=null,this.initialized=!1}updateModelInfo(e){e&&(this.metadata.isRecurrent=!!e.is_recurrent,this.metadata.isHybrid=!!e.is_hybrid,(this.metadata.isRecurrent||this.metadata.isHybrid)&&console.log(`[SessionCache] Model architecture: recurrent=${this.metadata.isRecurrent}, hybrid=${this.metadata.isHybrid}`))}requiresExactMatch(){return this.metadata.isRecurrent||this.metadata.isHybrid}async persistCacheMap(){try{await Mte(this.cacheMap,this.baseDir)}catch(e){console.warn(`[SessionCache] Failed to persist cache map: ${e?.message||e}`)}}static checkTokenPrefixMatch(e,t){if(e.length>t.length)return!1;for(let n=0;n<e.length;n+=1)if(e[n]!==t[n])return!1;return!0}static async tokenizeToArray(e,t){let n=await e.tokenize(t);return Array.from(n?.tokens||[])}async findFormattedMatchForRecurrent(t,n,r){let i=await e.tokenizeToArray(r,n),a=t.map(async t=>{try{let n=await e.tokenizeToArray(r,t.fullText);if(e.checkTokenPrefixMatch(n,i))return{entry:t,usePromptState:!1,tokenCount:n.length};if(t.promptStatePath&&t.promptText){let n=await e.tokenizeToArray(r,t.promptText);if(e.checkTokenPrefixMatch(n,i))return{entry:t,usePromptState:!0,tokenCount:n.length}}return null}catch(e){return console.warn(`[SessionCache] Failed to check entry ${t.id}: ${e.message}`),null}}),o=(await Promise.all(a)).find(e=>e!==null);if(!o)return console.log(`[SessionCache] No token prefix match found for recurrent/hybrid model`),null;let{entry:s,usePromptState:c,tokenCount:l}=o;console.log(`[SessionCache] Token prefix match: ${s.id} (${l} tokens, usePromptState=${c})`);let u=c?s.promptStatePath:s.stateFilePath;return await Dn(u)?(s.lastAccessedAt=new Date().toISOString(),await this.persistCacheMap(),{entry:s,usePromptState:c}):(await this.removeStaleEntry(s),null)}async initialize(){if(!(!this.enabled||this.initialized))try{await Qt(bn(this.baseDir)),await Qt(xn(this.baseDir)),await Qt(Dte(this.baseDir)),this.cacheMap=await jte(this.baseDir),this.initialized=!0,console.log(`[SessionCache] Initialized with ${Object.keys(this.cacheMap.entries).length} entries`)}catch(e){console.warn(`[SessionCache] Failed to initialize: ${e.message}`),this.enabled=!1}}async removeStaleEntry(e){console.log(`[SessionCache] Removing stale entry: ${e.id}`),await Tn(e),delete this.cacheMap.entries[e.id],this.cacheMap.totalSize-=Sn(e),await this.persistCacheMap()}async findMatchingEntry(e,t=null){if(!this.enabled||!this.cacheMap)return null;let n=this.requiresExactMatch();if(n&&t){let n=Object.values(this.cacheMap.entries).filter(e=>En(e.metadata,this.metadata)&&e.fullText);return this.findFormattedMatchForRecurrent(n,e,t)}let r=Rte(e,this.metadata,this.cacheMap,n);if(!r)return null;let{entry:i}=r;return await Dn(i.stateFilePath)?(i.lastAccessedAt=new Date().toISOString(),await this.persistCacheMap(),{entry:i,usePromptState:!1}):(await this.removeStaleEntry(i),null)}async prepareCompletionOptions(e,t,n=null){let r={options:e,cacheEntry:null,promptPrefix:null};if(!this.enabled)return r;let i=await this.findMatchingEntry(t,n);if(!i)return r;let{entry:a,usePromptState:o}=i,s=o?a.promptStatePath:a.stateFilePath,c=o?a.promptText:a.fullText;return console.log(`[SessionCache] Found matching entry: ${a.id} (${c.length} chars, usePromptState=${o})`),{options:{...e,load_state_path:s},cacheEntry:a,promptPrefix:c}}async saveCompletionState(e,t,n,r=0,i=null){if(!this.enabled)return null;let a=e+t,o=Nte(a,this.metadata),s=()=>wn(n,i);if(this.cacheMap.entries[o]){console.log(`[SessionCache] Entry already exists for prompt: ${o}, updating position`);let e=this.cacheMap.entries[o];return e.lastAccessedAt=new Date().toISOString(),delete this.cacheMap.entries[o],this.cacheMap.entries[o]=e,await this.persistCacheMap(),s(),e}let c=Pte(o,this.baseDir),l=i?Pte(`${o}-prompt`,this.baseDir):null;try{await Qt(M.dirname(c)),await Ite(n,c);let s=await D(c),u=0;if(i&&l)try{await Ite(i,l),u=(await D(l)).size,console.log(`[SessionCache] Saved prompt state: ${l}`)}catch(e){console.warn(`[SessionCache] Failed to save prompt state: ${e.message}`)}let d={id:o,promptText:e,completionText:t,fullText:a,promptTokenCount:r,stateFilePath:c,stateFileSize:s.size,promptStatePath:l||null,promptStateSize:u,metadata:{...this.metadata},createdAt:new Date().toISOString(),lastAccessedAt:new Date().toISOString()};return this.cacheMap.entries[o]=d,this.cacheMap.totalSize+=s.size+u,this.requiresExactMatch()||await Bte(this.cacheMap,e,o,this.metadata),await zte(this.cacheMap,this.maxSizeBytes,this.maxEntries),await Mte(this.cacheMap,this.baseDir),console.log(`[SessionCache] Saved entry: ${o} (${s.size} bytes, ${a.length} chars)`),d}catch(e){return console.warn(`[SessionCache] Failed to save state: ${e.message}`),s(),null}}async generateTempStatePath(){return await Qt(xn(this.baseDir)),Fte(this.baseDir)}async cleanup(){await Vte(this.baseDir)}};const On=async(e,t,n=dn)=>{let r=JSON.stringify({url:e,headers:t}),i=await vn(r,`range-metadata`,n);if(i)return i;let a=!/^https?:/i.test(e),{metadata:o}=await re(e,{fetch,additionalFetchHeaders:t,allowLocalFile:a});return await yn(r,`range-metadata`,o,n),o},kn=(e,t)=>t.localPath?t.localPath:e.model.local_path?M.resolve(e.model.local_path):tn(e.runtime.cache_dir,t,`model`),Wte=e=>{let t=e.model.model_draft??e.model.draft_model??e.runtime.model_draft??e.runtime.draft_model;if(!t)return null;if(typeof t!=`string`&&(typeof t!=`object`||Array.isArray(t)))throw Error("`model.model_draft` must be a URL/path string or model config object");let n;n=typeof t==`string`?/^https?:\/\//i.test(t)?{url:t}:{local_path:t}:{...t};let r=n.repo_id||n.repository||n.model||n.url||n.local_path;if(!r)throw Error("`model.model_draft` requires `repo_id`, `url`, or `local_path`");let i=`model-draft/${A(`sha256`).update(String(r)).digest(`hex`).slice(0,16)}`,a={revision:e.model.revision||`main`,preferred_quantizations:[],allow_local_file:e.model.allow_local_file,api_base:e.model.api_base,base_url:e.model.base_url,...n,repo_id:n.repo_id||n.repository||n.model||i};if(a.preferred_quantizations=Array.from(new Set(Yt(a.preferred_quantizations||a.quantizations).map(e=>e?String(e).toLowerCase():null).filter(Boolean))),a.quantization){let e=String(a.quantization).toLowerCase();a.quantization=e,a.preferred_quantizations.includes(e)||a.preferred_quantizations.unshift(e)}return a.url&&!a.filename&&(a.filename=a.url.split(`/`).pop()?.split(`?`)[0]),{...e,model:a}},An=async e=>{let t=Wte(e);if(!t)return{draftConfig:null,draftArtifact:null};if(t.model.local_path){if(!t.model.allow_local_file)throw Error("`model.model_draft.local_path` requires `model.allow_local_file = true`");let e=M.resolve(String(t.model.local_path).replace(/^file:\/\//i,``)),n=await D(e).catch(()=>null);if(!n?.isFile())throw Error(`Draft model file not found: ${e}`);return{draftConfig:t,draftArtifact:{repoId:t.model.repo_id,revision:t.model.revision,filename:M.basename(e),url:e,size:n.size,headers:{},localPath:e}}}return{draftConfig:t,draftArtifact:await jn(t)}},jn=async e=>{let t=e.model.repo_id||e.model.repository||e.model.model;if(!t)throw Error("`model.repo_id` is required in Buttress backend config");let n=e.model.revision||`main`,r=e.runtime.cache_dir,i=JSON.stringify({repoId:t,revision:n,filename:e.model.filename,url:e.model.url,quantization:e.model.quantization,preferred_quantizations:e.model.preferred_quantizations}),a=await vn(i,`artifact-info`,r);if(a)return a;let o={...e.runtime.http_headers||{}};if(e.runtime.huggingface_token&&(o.Authorization=`Bearer ${e.runtime.huggingface_token}`),e.model.url){let a=await on(e.model.url,{headers:o}),s=Number(a.headers.get(`content-length`))||null,c={repoId:t,revision:n,filename:e.model.filename||e.model.url.split(`/`).pop(),url:e.model.url,size:s,headers:o};return await yn(i,`artifact-info`,c,r),c}let{filename:s}=e.model,c=e.model.quantization&&String(e.model.quantization).toLowerCase(),l=await an(`${e.model.api_base}/models/${t}?revision=${n}&blobs=true`,{headers:o}),u=l?.siblings||l?.files||[],d=[];for(let e of u){let t=e.rfilename||e.path||e.filename;typeof t==`string`&&t.endsWith(`.gguf`)&&d.push(t)}if(d.length===0)throw Error(`No GGUF artifacts found in repo ${t}`);let f=e.model.preferred_quantizations.length>0?e.model.preferred_quantizations:gte,p=d.map(e=>e.toLowerCase()),m=()=>{for(let e of f){let t=p.findIndex(t=>t.includes(e));if(t!==-1)return{filename:d[t],quantization:e}}return null};if(s)c||=wte(s);else{let{filename:e,quantization:t}=m()||{filename:d[0],quantization:null};s=e,c=t||wte(s)}let h=`${e.model.base_url.replace(/\/+$/,``)}/${t}/resolve/${n}/${s}`,g=/-(\d{5})-of-(\d{5})\.gguf$/,_=s.match(g),v=null;if(_){let[,,r]=_,i=await an(`${e.model.api_base}/models/${t}?revision=${n}&blobs=true`,{headers:o}),a=i?.siblings||i?.files||[],c=Number(r);v=0;for(let e=1;e<=c;e+=1){let t=String(e).padStart(5,`0`),n=s.replace(g,`-${t}-of-${r}.gguf`),i=a.find(e=>(e.rfilename||e.path||e.filename)===n),o=Number(i?.size);Number.isFinite(o)&&o>0&&(v+=o)}}else{let e=await on(h,{headers:o});v=Number(e.headers.get(`content-length`))||null}let y={repoId:t,revision:n,filename:s,url:h,size:v,quantization:c,headers:o,isSplit:!!_,splitCount:_?Number(_[2]):0};return await yn(i,`artifact-info`,y,r),y},Gte=/^mmproj-.*\.gguf$/i,Mn=async(e,t)=>{if(!e.model.enable_mtmd)return null;let n=e.runtime.cache_dir,r={...e.runtime.http_headers||{}};e.runtime.huggingface_token&&(r.Authorization=`Bearer ${e.runtime.huggingface_token}`);let i=t?.repoId||e.model.repo_id,a=t?.revision||e.model.revision||`main`,o=JSON.stringify({kind:`mmproj`,repoId:i,revision:a,mmproj_filename:e.model.mmproj_filename,mmproj_url:e.model.mmproj_url,mmproj_local_path:e.model.mmproj_local_path}),s=await vn(o,`artifact-info`,n);if(s)return s;if(e.model.mmproj_url){let t=await on(e.model.mmproj_url,{headers:r}),s=Number(t.headers.get(`content-length`))||null,c={repoId:i,revision:a,filename:e.model.mmproj_filename||e.model.mmproj_url.split(`/`).pop(),url:e.model.mmproj_url,size:s,headers:r};return await yn(o,`artifact-info`,c,n),c}if(e.model.mmproj_local_path){if(!e.model.allow_local_file)throw Error("`model.mmproj_local_path` requires `model.allow_local_file = true`");let t={repoId:i,revision:a,filename:M.basename(e.model.mmproj_local_path),url:null,size:null,headers:r,localPath:M.resolve(e.model.mmproj_local_path)};return await yn(o,`artifact-info`,t,n),t}if(!i)throw Error("Cannot derive mmproj artifact without `model.repo_id`");let c=await an(`${e.model.api_base}/models/${i}?revision=${a}&blobs=true`,{headers:r}),l=c?.siblings||c?.files||[],u=l.map(e=>e.rfilename||e.path||e.filename).filter(e=>typeof e==`string`),d=e.model.mmproj_filename;if(d){if(!u.includes(d))throw Error(`mmproj file "${d}" not found in repo ${i}`)}else{let e=u.filter(e=>Gte.test(e));if(e.length===0)return console.warn(`[buttress] enable_mtmd set but no mmproj file found in ${i}; skipping multimodal load`),null;let n=t?.quantization&&String(t.quantization).toLowerCase();d=n&&e.find(e=>e.toLowerCase().includes(n))||e[0]}let f=`${e.model.base_url.replace(/\/+$/,``)}/${i}/resolve/${a}/${d}`,p=l.find(e=>(e.rfilename||e.path||e.filename)===d),m=Number(p?.size);if(!Number.isFinite(m)||m<=0){let e=await on(f,{headers:r});m=Number(e.headers.get(`content-length`))||null}let h={repoId:i,revision:a,filename:d,url:f,size:m,headers:r};return await yn(o,`artifact-info`,h,n),h},Nn=(e,t)=>t?.localPath?t.localPath:t?tn(e.runtime.cache_dir,t,`mmproj`):null,Pn=async(e,{modelBytes:t=null,kvCacheBytes:n=null}={})=>{let r=Tte(e),[i,...a]=r,o=Jt(e.backend?.gpu_memory_fraction)??(hn.backend.gpu_memory_fraction||1),s=Jt(e.backend?.cpu_memory_fraction)??pn,c=await ft({platform:process.platform,totalMemoryInBytes:N.totalmem(),backend:`ggml-llm`,variant:i||null,preferVariants:a,gpuMemoryFraction:o,cpuMemoryFraction:s,dependencies:{getBackendDevicesInfo:P,isLibVariantAvailable:ie},modelBytes:t,kvCacheBytes:n}),l=e=>({...e,devices:Array.isArray(e.devices)?e.devices:[],ok:e.ok,hasGpu:!!e.hasGpu,totalMemory:e.gpuTotalBytes||e.totalMemory||0,error:e.ok?null:Error(e.error||`Variant ${e.variant} not available on this platform`)});if(!c.ok||!c.selected){let e=(c.attempts||[]).map(e=>`${e.variant}: ${e.error||`unknown error`}`).join(`; `);throw Error(`Unable to initialize any backend variant (${r.join(`, `)}). Errors: ${e}`)}let u=(c.attempts||[]).map(l);return{selected:l(c.selected),attempts:u}},Kte=async e=>{let t=await jn(e),{draftConfig:n,draftArtifact:r}=await An(e),i=await Mn(e,t),a=await On(t.url,t.headers,e.runtime.cache_dir),{arch:o,nCtxTrain:s,nLayer:c,nEmbd:l,nHead:u,nHeadKv:d,nEmbdHeadK:f,nEmbdHeadV:p,quantVersion:m,fileType:h,attentionLayerCount:g,recurrentLayerCount:_,ssmDConv:v,ssmDState:y,ssmDInner:b,ssmNGroup:x,ssmDtRank:S,rwkvHeadSize:C,rwkvTokenShiftCount:w}=xt(a),T=Number.isFinite(Number(c))?Number(c):0,E=Number.isFinite(Number(l))?Number(l):0,D=Number.isFinite(Number(u))?Number(u):0,O=Number.isFinite(Number(d))?Number(d):D,k=D>0&&E>0?E/D:128,ee=f!=null&&Number.isFinite(Number(f))?Number(f):k,A=p!=null&&Number.isFinite(Number(p))?Number(p):k,te=vt({arch:o,metadata:a,nLayer:T}),j=te&&Number.isFinite(Number(te.kvLayers))?Number(te.kvLayers):T,ne=Math.max(0,Math.floor(Number(j)||0)),M={use_mmap:e.model.use_mmap??e.runtime.use_mmap,use_mlock:e.model.use_mlock??e.runtime.use_mlock,no_extra_bufts:e.model.no_extra_bufts??e.runtime.no_extra_bufts,n_threads:e.model.n_threads??e.runtime.n_threads,n_ctx:e.model.n_ctx??e.runtime.n_ctx,n_batch:e.model.n_batch??e.runtime.n_batch,n_ubatch:e.model.n_ubatch??e.runtime.n_ubatch,n_cpu_moe:e.model.n_cpu_moe??e.runtime.n_cpu_moe,n_parallel:(e.model.n_parallel??e.runtime.n_parallel)||4,cpu_mask:e.model.cpu_mask??e.runtime.cpu_mask,cpu_strict:e.model.cpu_strict??e.runtime.cpu_strict,devices:e.model.devices??e.runtime.devices,n_gpu_layers:e.model.n_gpu_layers??e.runtime.n_gpu_layers,flash_attn_type:e.model.flash_attn_type??e.runtime.flash_attn_type,cache_type_k:e.model.cache_type_k??e.runtime.cache_type_k,cache_type_v:e.model.cache_type_v??e.runtime.cache_type_v,kv_unified:e.model.kv_unified??e.runtime.kv_unified,swa_full:e.model.swa_full??e.runtime.swa_full,ctx_shift:e.model.ctx_shift??e.runtime.ctx_shift,state_cache_budget_mb:e.model.state_cache_budget_mb??e.runtime.state_cache_budget_mb,state_cache_max_checkpoints:e.model.state_cache_max_checkpoints??e.runtime.state_cache_max_checkpoints,...bte(e)},re=M.n_ctx?Number(M.n_ctx):null,P=re||s||4096,ie=[],ae=[],oe=!0;if(re&&s&&re>s){oe=!1;let e=`Requested context length (${re}) exceeds model training context (${s})`;ie.push(e),ae.push(e),P=s}re&&!s&&ie.push(`Model metadata missing training context length, using requested value`);let se={k:M.cache_type_k,v:M.cache_type_v},ce=t.size>0?t.size:0,le=r?.size>0?r.size:0,ue=ce+le,de=St({layerCount:ne,headKvCount:O,embdHeadKCount:ee,embdHeadVCount:A,cacheTypes:se,swaConfig:te,kvUnified:M.kv_unified,nParallel:M.n_parallel,swaFull:M.swa_full,arch:o,attentionLayerCount:g}),fe=Ct({nLayer:T,nEmbd:E,recurrentLayerCount:_,nSeqMax:M.n_parallel||4,ssmDConv:v,ssmDState:y,ssmDInner:b,ssmNGroup:x,ssmDtRank:S,rwkvHeadSize:C,rwkvTokenShiftCount:w,arch:o}),pe=de(P),me=await Pn(e,{modelBytes:ue,kvCacheBytes:pe+fe}),he=me.selected.totalMemory||0,ge=he*(e.backend.gpu_memory_fraction||1),_e=Jt(e.backend.cpu_memory_fraction)??pn,ve=Math.max(0,N.totalmem()*_e),ye=me.selected.hasGpu?ge:ve,be=wt({maxCtx:P,availableMemory:ye,modelBytes:ue,kvBytesForCtx:de});if(!re&&be){let e=Math.max(32,s?Math.min(be,s):be);e<P&&ie.push(`Context length capped to ${e} by memory limits`),P=e}P>be&&(P=be);let xe=Math.floor(be);console.log(`[buttress] Memory-limited context length: ${xe}`);let Se=de(P),Ce=ue+Se+fe,we=T?ce/(T+1):ce,Te=0;me.selected.hasGpu&&we>0&&(Te=Math.min(T+1,Math.max(0,Math.floor(ge/we)))),console.log(`[buttress] Auto GPU layer capacity (${me.selected.variant}): ${Te}/${T+1}`);let Ee;Ee=M.n_gpu_layers===`auto`||M.n_gpu_layers==null?Te:Math.max(0,Math.min(Number(M.n_gpu_layers)||0,T+1));let De=(()=>{let e=M.flash_attn_type&&String(M.flash_attn_type).toLowerCase();return e===`on`||e===`off`?e:me.selected.hasGpu?`auto`:`off`})(),Oe=e.runtime.cache_dir,ke=kn(e,t),F=await rn(ke,t.size),Ae=r?kn(n,r):null,je=Ae?await rn(Ae,r.size):!1,Me=r?{repoId:r.repoId,revision:r.revision,filename:r.filename,quantization:r.quantization,url:r.url,sizeBytes:r.size,download:{cacheDir:n.runtime.cache_dir,localPath:Ae,exists:je}}:null,Ne=Nn(e,i),Pe=Ne?await rn(Ne,i?.size):!1,Fe=i?{enabled:!0,initialized:!1,filename:i.filename,url:i.url,sizeBytes:i.size,localPath:Ne,exists:Pe,useGpu:e.model.mmproj_use_gpu,imageMinTokens:e.model.mmproj_image_min_tokens,imageMaxTokens:e.model.mmproj_image_max_tokens}:{enabled:!1,requested:!!e.model.enable_mtmd};return{config:e,info:{ok:oe,backend:`ggml-llm`,warnings:ie,errors:ae,model:{repoId:t.repoId,revision:t.revision,filename:t.filename,quantization:t.quantization,url:t.url,sizeBytes:t.size,metadata:{architecture:o,n_ctx_train:s,n_layer:T,n_embd:E,quantization_version:m,file_type:h,kv_layer_count:ne,swa:te?.enabled?{window:te.window,pattern:te.pattern,dense_first:te.denseFirst,type:te.type,layers:te.swaLayers}:null}},draftModel:Me,runtime:{...M,variant:me.selected.variant,n_ctx:P,requested_ctx:re,n_gpu_layers:Ee,auto_gpu_layers:Te,flash_attn_type:De,cache_type_k:se.k,cache_type_v:se.v,estimated_max_n_ctx:xe},resources:{modelBytes:ue,targetModelBytes:ce,draftModelBytes:le,kvCacheBytes:Se,recurrentMemoryBytes:fe,totalEstimatedBytes:Ce,gpuCapacityBytes:he,gpuUsableBytes:ge,cpuUsableBytes:ve,fit:me.selected.fit},devices:{selected:me.selected,attempts:me.attempts},download:{cacheDir:Oe,localPath:ke,exists:F},multimodal:Fe,timestamp:new Date().toISOString()},artifact:t,mmprojArtifact:i,mmprojLocalPath:Ne,mmprojLocalExists:Pe,metadata:{arch:o,nCtxTrain:s,nLayer:T,nEmbd:E},devices:me,cacheTypes:se,localPath:ke,localExists:F,draftPlan:r?{config:n,artifact:r,localPath:Ae,localExists:je,info:{download:Me.download}}:null}},qte=(e,t)=>{let n=typeof t==`string`?t:t?.prompt;if(!n)return e;let{messages:r,tools:i,tool_choice:a,parallel_tool_calls:o,chat_template:s,chatTemplate:c,jinja:l,add_generation_prompt:u,chat_template_kwargs:d,force_pure_content:f,now:p,...m}=e,h={...m,prompt:n};return typeof t!=`object`||t.type!==`jinja`?h:(typeof t.chat_format==`number`&&(h.chat_format=t.chat_format),t.grammar&&(h.grammar=t.grammar),typeof t.grammar_lazy==`boolean`&&(h.grammar_lazy=t.grammar_lazy),t.grammar_triggers?.length&&(h.grammar_triggers=t.grammar_triggers),t.preserved_tokens?.length&&(h.preserved_tokens=t.preserved_tokens),t.additional_stops?.length&&(h.stop=[...m.stop||[],...t.additional_stops]),t.media_paths?.length&&(h.media_paths=t.media_paths),typeof t.generation_prompt==`string`&&(h.generation_prompt=t.generation_prompt),typeof t.thinking_forced_open==`boolean`&&(h.thinking_forced_open=t.thinking_forced_open),typeof t.thinking_start_tag==`string`&&(h.thinking_start_tag=t.thinking_start_tag),typeof t.thinking_end_tag==`string`&&(h.thinking_end_tag=t.thinking_end_tag),t.chat_parser&&(h.chat_parser=t.chat_parser),h)},Jte=(e,t,n=null,r=null)=>{let i,a,o=Date.now(),s=0;return new fte({async start(c){a=un(c);try{let c=await e.parallel.completion(t,(e,t)=>{t&&(t.token&&(s+=1),a.enqueue({event:`token`,data:{requestId:e,...t}}))}),{requestId:l}=c;i=c.stop;let u=await c.promise;console.log(`[Completion] Result:`,u),a.enqueue({event:`result`,data:{requestId:l,...u}}),a.close();let d=Date.now()-o,f=u.timings||{};Pt.addCompletion({id:`completion-${l}`,generatorId:n,requestId:l,repoId:r?.repoId||null,quantization:r?.quantization||null,variant:r?.variant||null,cacheTokens:f.cache_n??0,promptTokens:f.prompt_n??0,tokensGenerated:f.predicted_n??s,tokensPerSecond:f.predicted_per_second??0,promptPerSecond:f.prompt_per_second??0,durationMs:d,success:!0,interrupted:u.interrupted||!1,contextFull:u.context_full||u.contextFull||!1})}catch(e){a.enqueue({event:`error`,data:{message:e?.message||String(e)}}),a.error(e),Pt.addCompletion({id:`completion-${Date.now()}`,generatorId:n,repoId:r?.repoId||null,quantization:r?.quantization||null,variant:r?.variant||null,durationMs:Date.now()-o,tokensGenerated:s,success:!1,error:e?.message||String(e)})}},cancel(){a?.markClosed(),i&&i()}})},Yte=(e,t,n,r,i,a,o=null,s=null,c=null)=>{let l,u,d=``,f=!1,p=Date.now(),m=0,h=()=>wn(i,c);return new fte({async start(g){u=un(g);try{let g=await e.parallel.completion(t,(e,t)=>{t&&(t.token&&(d+=t.token,m+=1),u.enqueue({event:`token`,data:{requestId:e,...t}}))}),{requestId:_}=g;l=g.stop;let v=await g.promise;v.text?d=v.text:v.content&&(d=v.content),f=!v.interrupted&&!v.context_full,console.log(`[Completion] Result:`,v),u.enqueue({event:`result`,data:{requestId:_,...v}}),u.close();let y=Date.now()-p,b=v.timings||{};Pt.addCompletion({id:`completion-${_}`,generatorId:o,requestId:_,repoId:s?.repoId||null,quantization:s?.quantization||null,variant:s?.variant||null,cacheTokens:b.cache_n??0,promptTokens:b.prompt_n??a??0,tokensGenerated:b.predicted_n??m,tokensPerSecond:b.predicted_per_second??0,promptPerSecond:b.prompt_per_second??0,durationMs:y,success:!0,interrupted:v.interrupted||!1,contextFull:v.context_full||v.contextFull||!1,usedCache:!!t.load_state_path}),f&&n.enabled&&d?n.saveCompletionState(r,d,i,a,c).catch(e=>{console.warn(`[SessionCache] Save failed:`,e.message)}):h()}catch(e){u.enqueue({event:`error`,data:{message:e?.message||String(e)}}),u.error(e),Pt.addCompletion({id:`completion-${Date.now()}`,generatorId:o,repoId:s?.repoId||null,quantization:s?.quantization||null,variant:s?.variant||null,durationMs:Date.now()-p,tokensGenerated:m,success:!1,error:e?.message||String(e)}),h()}},cancel(){u?.markClosed(),l&&l(),h()}})},Fn=e=>{let t={model:e.plan.localPath,modelDraft:e.plan.draftPlan?.localPath||null,runtime:e.plan.info.runtime};return A(`sha256`).update(JSON.stringify(t)).digest(`hex`).slice(0,24)},In=async(e,t,n,r)=>{let i=(e,t,n)=>{e>=0&&Number.isFinite(e)&&typeof r==`function`&&r((t+e)/n)};if(t.isSplit&&t.splitCount>0){let r=/-(\d{5})-of-(\d{5})\.gguf$/,a=M.dirname(n),o=t.splitCount,s=0;for(let n=1;n<=o;n+=1){let c=String(n).padStart(5,`0`),l=t.filename.replace(r,`-${c}-of-${String(o).padStart(5,`0`)}.gguf`),u=`${e.model.base_url.replace(/\/+$/,``)}/${t.repoId}/resolve/${t.revision}/${l}`,d=M.join(a,M.basename(l));await rn(d)||await cn(u,t.headers,d,null,e=>{i(e,s,o)},{allowedRoot:e.runtime.cache_dir}),s+=1}return}await cn(t.url,t.headers,n,t.size,e=>{i(e,0,1)},{allowedRoot:e.runtime.cache_dir})},Ln=async(e,t,n,r=null)=>{let{config:i,localPath:a,artifact:o}=e;if(i.model.local_path&&!i.model.allow_local_file)throw Error("Local model path provided but `model.allow_local_file` is not enabled");if(!i.model.local_path&&!o.localPath&&await nn(a,i.runtime.cache_dir),e.localExists&&!t.has(a))return e.info.download.exists=!0,typeof n==`function`&&n(.5),a;let s=a;if(r){let t=r.getDownload(s);if(t){console.log(`[ensureModelFile] Waiting for global download: ${o.repoId}`);try{if(await t,await rn(a,o.size))return e.localExists=!0,e.info.download.exists=!0,typeof n==`function`&&n(.5),a}catch(e){console.warn(`[ensureModelFile] Global download failed, will retry: ${e.message}`)}}}t.has(s)||t.set(s,(async()=>{let t=o.isSplit&&o.splitCount>0;t||console.log(`Downloading model: 0%`),await In(i,o,a,e=>{let r=Math.round(e*100);console.log(`Downloading model${t?` splits`:``}: ${Math.min(100,r)}%`),typeof n==`function`&&n(e*.5)}),e.localExists=!0,e.info.download.exists=!0})());try{await t.get(s)}finally{t.delete(s)}return a},Xte=async(e,t,n,r=null)=>{let{mmprojArtifact:i,mmprojLocalPath:a}=e;if(!i||!a)return null;if(i.localPath){if(!await rn(a))throw Error(`mmproj local file not found: ${a}`);return e.mmprojLocalExists=!0,e.info.multimodal.exists=!0,typeof n==`function`&&n(1),a}if(await nn(a,e.config.runtime.cache_dir),e.mmprojLocalExists&&!t.has(a))return e.info.multimodal.exists=!0,typeof n==`function`&&n(1),a;let o=a;if(r){let t=r.getDownload(o);if(t)try{if(await t,await rn(a,i.size))return e.mmprojLocalExists=!0,e.info.multimodal.exists=!0,typeof n==`function`&&n(1),a}catch(e){console.warn(`[ensureMmprojFile] Global download failed, will retry: ${e.message}`)}}t.has(o)||t.set(o,(async()=>{console.log(`Downloading mmproj: 0%`),await cn(i.url,i.headers,a,i.size,e=>{if(e>=0&&Number.isFinite(e)){let t=Math.round(e*100);console.log(`Downloading mmproj: ${Math.min(100,t)}%`),typeof n==`function`&&n(e)}},{allowedRoot:e.config.runtime.cache_dir}),e.mmprojLocalExists=!0,e.info.multimodal.exists=!0})());try{await t.get(o)}finally{t.delete(o)}return a},Zte=async(e,t)=>{let n=Fn(e),r=e.contexts.get(n);if(r&&!r.released)return r.releaseTimer&&(clearTimeout(r.releaseTimer),r.releaseTimer=null,console.log(`[Context] Cancelled pending release for context "${n}"`)),r.releaseRequested=!1,r.refCount+=1,console.log(`[Context] Reusing existing context "${n}", refCount=${r.refCount}`),typeof t==`function`&&t(0),r.context||await r.ready,typeof t==`function`&&t(1),r;console.log(r?`[Context] Record exists but released=${r.released}, creating new context`:`[Context] No existing record for "${n}", creating new context`),r={key:n,refCount:1,ready:null,released:!1},e.contexts.set(n,r),r.ready=(async()=>{let i=Date.now(),a=e.plan.draftPlan&&typeof t==`function`?e=>t(e*.7):t,o=await Ln(e.plan,e.downloads,a,e.globalDownloadManager),s=e.plan.draftPlan?await Ln(e.plan.draftPlan,e.downloads,typeof t==`function`?e=>t(.35+e*.3):null,e.globalDownloadManager):null;typeof t==`function`&&t(.5);let c=!!e.config.model.embedding,l=!!e.config.model.vocab_only,u={model:o,n_threads:e.plan.info.runtime.n_threads,use_mmap:e.plan.info.runtime.use_mmap,use_mlock:e.plan.info.runtime.use_mlock,no_extra_bufts:e.plan.info.runtime.no_extra_bufts,cpu_mask:e.plan.info.runtime.cpu_mask,cpu_strict:e.plan.info.runtime.cpu_strict,devices:e.plan.info.runtime.devices,n_ctx:e.plan.info.runtime.n_ctx,n_gpu_layers:e.plan.info.runtime.n_gpu_layers,n_parallel:c?1:e.plan.info.runtime.n_parallel,n_batch:e.plan.info.runtime.n_batch,n_ubatch:e.plan.info.runtime.n_ubatch,n_cpu_moe:e.plan.info.runtime.n_cpu_moe,flash_attn_type:e.plan.info.runtime.flash_attn_type,ctx_shift:e.plan.info.runtime.ctx_shift,kv_unified:e.plan.info.runtime.kv_unified,swa_full:e.plan.info.runtime.swa_full,state_cache_budget_mb:e.plan.info.runtime.state_cache_budget_mb,state_cache_max_checkpoints:e.plan.info.runtime.state_cache_max_checkpoints,lib_variant:e.plan.info.runtime.variant,embedding:c};e.config.model.pooling_type&&(u.pooling_type=e.config.model.pooling_type),l&&(u.vocab_only=!0,u.n_gpu_layers=0,u.n_parallel=1),s&&(u.model_draft=s);for(let t of _te){let n=e.plan.info.runtime[t];n!=null&&(u[t]=n)}e.plan.info.runtime.flash_attn_type!==`off`&&(u.cache_type_k=e.plan.info.runtime.cache_type_k,u.cache_type_v=e.plan.info.runtime.cache_type_v),console.log(`[Context] Load Options:`,u);let d;try{if(d=await ae(u,e=>{typeof t==`function`&&(t(.5+e*.25),e%5==0&&console.log(`[Context] Load Model Progress:`,e))}),!c&&!l&&e.plan.info.runtime.n_parallel&&!await d.parallel.enable({n_parallel:e.plan.info.runtime.n_parallel,n_batch:e.plan.info.runtime.n_batch}))throw Error(`Failed to enable parallel decoding mode for context`);if(e.plan.mmprojArtifact){let t=await Xte(e.plan,e.downloads,null,e.globalDownloadManager);if(t){let n=e.config.model.mmproj_use_gpu,r={path:t,use_gpu:n==null?(e.plan.info.runtime.n_gpu_layers||0)>0:!!n,image_min_tokens:e.config.model.mmproj_image_min_tokens,image_max_tokens:e.config.model.mmproj_image_max_tokens};console.log(`[Context] initMultimodal:`,r),await d.initMultimodal(r)?e.plan.info.multimodal.initialized=!0:console.warn(`[Context] initMultimodal returned false; multimodal disabled`)}}if(r.released){try{d.parallel?.disable?.()}catch{}throw Error(`Context "${n}" was released before the model finished loading`)}return typeof t==`function`&&t(1),r.context=d,r.modelInfo=d.getModelInfo(),Pt.addModelLoad({id:`${e.id}-${n}`,generatorId:e.id,contextKey:n,repoId:e.plan.info.model?.repoId||null,quantization:e.plan.info.model?.quantization||null,variant:e.plan.info.runtime?.variant||null,nCtx:e.plan.info.runtime?.n_ctx||null,nGpuLayers:e.plan.info.runtime?.n_gpu_layers||null,durationMs:Date.now()-i,success:!0}),r}catch(t){if(Pt.addModelLoad({id:`${e.id}-${n}`,generatorId:e.id,contextKey:n,repoId:e.plan.info.model?.repoId||null,quantization:e.plan.info.model?.quantization||null,variant:e.plan.info.runtime?.variant||null,durationMs:Date.now()-i,success:!1,error:t?.message||String(t)}),d)try{d.release()}catch{}throw t}})();try{return await r.ready,r}catch(t){throw e.contexts.get(n)===r&&e.contexts.delete(n),t}},Rn=async(e,t,n=!1)=>{if(t.released||!n&&t.refCount>0)return!1;t.released=!0,e.contexts.delete(t.key);try{t.context?.parallel?.disable?.()}catch{}return await t.context?.release?.(),!0},Qte=async(e,t,n=!1)=>{if(t.releaseRequested=!0,t.releaseTimer&&=(clearTimeout(t.releaseTimer),null),n)t.refCount=0;else if(t.refCount=Math.max(0,t.refCount-1),t.refCount>0)return t.releaseRequested=!1,!1;let r=e.config.runtime.context_release_delay_ms;if(typeof r!=`number`||!Number.isFinite(r))return Rn(e,t);let i=Math.max(0,Math.floor(r));return n||i<=0?Rn(e,t):(console.log(`[Context] Scheduling release in ${i}ms for context "${t.key}"`),t.releaseTimer=setTimeout(async()=>{if(t.releaseTimer=null,t.refCount>0){console.log(`[Context] Release cancelled, refCount=${t.refCount} for context "${t.key}"`),t.releaseRequested=!1;return}console.log(`[Context] Releasing context "${t.key}" after ${i}ms delay`),await Rn(e,t)},i),!0)};async function $te(e,t,n={}){let{globalDownloadManager:r=null}=n,i=_n(t),a=await Kte(i),o=new Ute(i,a);await o.initialize();let s={id:e,type:`ggml-llm`,config:i,plan:a,info:a.info,contexts:new Map,downloads:new Map,globalDownloadManager:r,sessionCache:o,finalized:!1};return{id:e,type:`ggml-llm`,info:a.info,contexts:s.contexts,initContext:async(e={})=>{let{onProgress:t}=e,n=await Zte(s,t);return s.sessionCache.updateModelInfo(n.modelInfo),{modelInfo:n.modelInfo?{...n.modelInfo}:null,runtime:{...s.plan.info.runtime},download:{...s.plan.info.download},multimodal:s.plan.info.multimodal?{...s.plan.info.multimodal}:null}},completion:async(e={})=>{let{options:t={},useCache:n=!0}=e,r=Ste(t,s.plan.info.runtime),i=Fn(s),a=s.contexts.get(i);if(!a)throw Error(`Context "${i}" not initialized`);await a.ready;let o=r.prompt||``,c=null,l=null,u=r;if(!o&&r.messages){({messages:c}=r),l={chatTemplate:r.chat_template||r.chatTemplate,jinja:r.jinja??!0,tools:r.tools,parallel_tool_calls:r.parallel_tool_calls,tool_choice:r.tool_choice,reasoning_format:r.reasoning_format,enable_thinking:r.enable_thinking,add_generation_prompt:r.add_generation_prompt,now:r.now,chat_template_kwargs:r.chat_template_kwargs,force_pure_content:r.force_pure_content};let e=await a.context.getFormattedChat(c,l.chatTemplate,l);o=e?.prompt||e||``,u=qte(r,e)}if(n&&s.sessionCache.enabled&&o){let{options:e}=await s.sessionCache.prepareCompletionOptions(u,o,a.context),t=await s.sessionCache.generateTempStatePath(),n=(await a.context.tokenize(o))?.tokens?.length||0,r={...e,save_state_path:t},i=s.sessionCache.requiresExactMatch(),c=!!r.load_state_path,l=null;i&&!c&&(l=await s.sessionCache.generateTempStatePath(),r.save_prompt_state_path=l);let d={repoId:s.plan.info.model?.repoId||null,quantization:s.plan.info.model?.quantization||null,variant:s.plan.info.runtime?.variant||null};return Yte(a.context,r,s.sessionCache,o,t,n,s.id,d,l)}let d={repoId:s.plan.info.model?.repoId||null,quantization:s.plan.info.model?.quantization||null,variant:s.plan.info.runtime?.variant||null};return Jte(a.context,u,s.id,d)},tokenize:async(e={})=>{let{text:t=``,params:n={}}=e,r=Fn(s),i=s.contexts.get(r);if(!i)throw Error(`Context "${r}" not initialized`);await i.ready;let a=await i.context.tokenize(t,n);if(!a)return{tokens:[]};let o=Array.from(a.tokens??[],Number);return{...a,tokens:o}},detokenize:async(e={})=>{let{tokens:t=[]}=e,n=Fn(s),r=s.contexts.get(n);if(!r)throw Error(`Context "${n}" not initialized`);await r.ready;let i=t.map(e=>Number(e));return r.context.detokenize(i)},embedding:async(e={})=>{let{text:t=``,params:n={}}=e;if(s.config.model.vocab_only)throw Error(`Embedding is not available on a vocab-only context`);if(!s.config.model.embedding)throw Error("Embedding requires a context loaded with `model.embedding` enabled");let r=Fn(s),i=s.contexts.get(r);if(!i)throw Error(`Context "${r}" not initialized`);await i.ready;let a=await i.context.embedding(t,n);return a?{...a,embedding:Array.from(a.embedding??[],Number)}:{embedding:[]}},applyChatTemplate:async(e={})=>{let{messages:t=[],template:n,params:r}=e,i=Fn(s),a=s.contexts.get(i);if(!a)throw Error(`Context "${i}" not initialized`);return await a.ready,await a.context.getFormattedChat(t,n,r)},releaseContext:async()=>{if(s.finalized)return!1;let e=Fn(s),t=s.contexts.get(e);return t?Qte(s,t,!1):!1},finalize:async()=>{if(s.finalized)return;s.finalized=!0;let e=Array.from(s.contexts.values()),t=e.map(e=>e.released||e.releaseRequested||e.releaseTimer||(e.refCount=Math.max(0,e.refCount-1),e.refCount>0)?Promise.resolve(!1):Rn(s,e));await Promise.allSettled(t),(e.length===0||e.every(e=>e.released))&&await s.sessionCache.cleanup()},getStatus:()=>{let e=[],t=Array.from(s.contexts.entries()).map(([t,n])=>{let r={key:t,refCount:n.refCount,hasModel:!!n.context};if(n.context){let i=n.context.parallel.getStatus();r.parallelStatus=i,e.push({contextKey:t,...i})}return r});return{id:s.id,type:s.type,repoId:s.plan.info.model?.repoId||null,quantization:s.plan.info.model?.quantization||null,variant:s.plan.info.runtime?.variant||null,nCtx:s.plan.info.runtime?.n_ctx||null,nParallel:s.plan.info.runtime?.n_parallel||null,contexts:t,parallelStatuses:e}},subscribeParallelStatus:e=>{let t=Array.from(s.contexts.entries()).filter(([,e])=>e.context).map(([t,n])=>n.context.parallel.subscribeToStatus(n=>{e({contextKey:t,...n})}));return{remove:()=>{t.forEach(e=>{e?.remove&&e.remove()})}}},hasPendingReleases:()=>Array.from(s.contexts.values()).some(e=>!e.released&&(e.releaseRequested||e.releaseTimer||e.refCount>0)),resetFinalized:()=>{s.finalized=!1}}}const zn=e=>{let t=_n(e);return t.model.repo_id||t.model.repository||t.model.model||null},ene=e=>{let t=_n(e);return t.model.vocab_only?`vocab`:t.model.embedding?`embedding`:null};async function tne(e,t,n={}){let{onProgress:r,onComplete:i,onError:a}=n;try{let n=_n(e),o=await jn(n),s=kn(n,o);!n.model.local_path&&!o.localPath&&await nn(s,n.runtime.cache_dir);let{repoId:c}=o,{draftConfig:l,draftArtifact:u}=await An(n),d=u?kn(l,u):null,f=await Mn(n,o).catch(e=>(console.warn(`[Download] Failed to derive mmproj artifact: ${e.message}`),null)),p=Nn(n,f),m=async()=>{if(!f||!p||f.localPath)return;if(await nn(p,n.runtime.cache_dir),await rn(p,f.size)){console.log(`[Download] mmproj already exists: ${p}`);return}let e=t.getDownload(p);if(e){await e;return}let r=(async()=>{try{await cn(f.url,f.headers,p,f.size,e=>{e>=0&&Number.isFinite(e)&&console.log(`[Download] mmproj ${c}: ${Math.round(e*100)}%`)},{allowedRoot:n.runtime.cache_dir})}finally{t.deleteDownload(p)}})();t.setDownload(p,r),await r},h=async()=>{if(!l||!u||!d||u.localPath)return;if(await rn(d,u.size)){console.log(`[Download] Draft model already exists: ${d}`);return}let e=t.getDownload(d);if(e){await e;return}let n=Ln({config:l,artifact:u,localPath:d,localExists:!1,info:{download:{localPath:d,exists:!1}}},new Map,null).finally(()=>{t.deleteDownload(d)});t.setDownload(d,n),await n};if(await rn(s,o.size))return console.log(`[Download] Model already exists: ${c} at ${s}`),await h(),await m().catch(e=>{console.error(`[Download] mmproj download failed: ${e.message}`),typeof a==`function`&&a(e)}),typeof i==`function`&&i({localPath:s,repoId:c,alreadyExists:!0}),{started:!1,localPath:s,repoId:c,alreadyExists:!0};let g=t.getDownload(s);if(g)return console.log(`[Download] Already downloading: ${c}`),g.then(()=>{typeof i==`function`&&i({localPath:s,repoId:c,joinedExisting:!0})}).catch(e=>{typeof a==`function`&&a(e)}),{started:!1,localPath:s,repoId:c,alreadyDownloading:!0};console.log(`[Download] Starting download: ${c}`);let _=(async()=>{try{await In(n,o,s,e=>{console.log(`[Download] ${c}: ${Math.round(e*100)}%`),typeof r==`function`&&r(e)}),await h(),await m(),console.log(`[Download] Completed: ${c}`),typeof i==`function`&&i({localPath:s,repoId:c})}catch(e){throw console.error(`[Download] Failed: ${c}`,e.message),typeof a==`function`&&a(e),e}finally{t.deleteDownload(s)}})();return t.setDownload(s,_),{started:!0,localPath:s,repoId:c}}catch(e){return console.error(`[Download] Failed to start download:`,e.message),typeof a==`function`&&a(e),{started:!1,localPath:null,repoId:null,error:e.message}}}async function nne(e){let t=_n(e),n=await jn(t),{draftArtifact:r}=await An(t),i=await On(n.url,n.headers,t.runtime.cache_dir),{arch:a,nCtxTrain:o,nLayer:s,nEmbd:c,nHead:l,nHeadKv:u,nEmbdHeadK:d,nEmbdHeadV:f,quantVersion:p,fileType:m,attentionLayerCount:h,recurrentLayerCount:g,ssmDConv:_,ssmDState:v,ssmDInner:y,ssmNGroup:b,ssmDtRank:x,rwkvHeadSize:S,rwkvTokenShiftCount:C}=xt(i),w=Number.isFinite(Number(s))?Number(s):0,T=Number.isFinite(Number(c))?Number(c):0,E=Number.isFinite(Number(l))?Number(l):0,D=Number.isFinite(Number(u))?Number(u):E,O=E>0&&T>0?T/E:128,k=d!=null&&Number.isFinite(Number(d))?Number(d):O,ee=f!=null&&Number.isFinite(Number(f))?Number(f):O,A=vt({arch:a,metadata:i,nLayer:w}),te=A&&Number.isFinite(Number(A.kvLayers))?Number(A.kvLayers):w,j=Math.max(0,Math.floor(Number(te)||0)),ne=(t.model.n_ctx?Number(t.model.n_ctx):null)||o||4096,M={k:t.model.cache_type_k,v:t.model.cache_type_v},re=n.size>0?n.size:0,P=r?.size>0?r.size:0,ie=re+P,ae=t.model.n_parallel||4,oe=St({layerCount:j,headKvCount:D,embdHeadKCount:k,embdHeadVCount:ee,cacheTypes:M,swaConfig:A,kvUnified:t.model.kv_unified,nParallel:ae,swaFull:t.model.swa_full,arch:a,attentionLayerCount:h}),se=Ct({nLayer:w,nEmbd:T,recurrentLayerCount:g,nSeqMax:ae,ssmDConv:_,ssmDState:v,ssmDInner:y,ssmNGroup:b,ssmDtRank:x,rwkvHeadSize:S,rwkvTokenShiftCount:C,arch:a}),ce=Jt(t.backend?.gpu_memory_fraction)??(hn.backend.gpu_memory_fraction||1),le=Jt(t.backend?.cpu_memory_fraction)??pn,ue=oe(ne),de=await Pn(t,{modelBytes:ie,kvCacheBytes:ue}),fe=(de.selected.totalMemory||0)*ce,pe=Math.max(0,N.totalmem()*le),me=wt({maxCtx:ne,availableMemory:de.selected.hasGpu?fe:pe,modelBytes:ie,kvBytesForCtx:oe}),he=oe(ne),ge=oe(me);return{kvInfo:{nCtxTrain:o,nLayer:w,nEmbd:T,nHeadKv:D,nEmbdHeadK:k,nEmbdHeadV:ee,nHeadCount:E,nHeadKvCount:D,kvLayerCount:j,swa:A?.enabled?{window:A.window,pattern:A.pattern,denseFirst:A.denseFirst,type:A.type,layers:A.swaLayers}:null},modelBytes:ie,targetModelBytes:re,draftModelBytes:P,kvCacheBytes:he,limitedKvCacheBytes:ge,memoryLimitedCtx:me,recurrentMemoryBytes:se,quantization:{name:n.quantization||null,fileType:m,version:p}}}async function rne(e=null,t={}){let{threshold:n=1.1,includeBreakdown:r=!1,config:i,...a}=t,o=null,s=null,c=null,l=null,u=null,d=null,f=null,p=null,m=null;if(i)try{let{modelBytes:e,targetModelBytes:t,draftModelBytes:n,kvCacheBytes:r,limitedKvCacheBytes:a,memoryLimitedCtx:h,recurrentMemoryBytes:g,kvInfo:_,quantization:v}=await nne(i);o=e,s=t,c=n,l=r,u=a,d=h,f=g,p=_,m=v}catch{}let h=Jt(i?.backend?.gpu_memory_fraction),g=Jt(i?.backend?.cpu_memory_fraction),_=await ft({...a,platform:process.platform,totalMemoryInBytes:N.totalmem(),backend:`ggml-llm`,includeBreakdown:r,gpuMemoryFraction:h,cpuMemoryFraction:g,dependencies:{getBackendDevicesInfo:P,isLibVariantAvailable:ie},modelBytes:o,kvCacheBytes:l,limitedKvCacheBytes:u}),v=_.selected,y=$e(v);v.modelBytes=o||null,v.targetModelBytes=s||null,v.draftModelBytes=c||null,v.kvCacheBytes=l||null,v.memoryLimitedCtx=d||null,v.limitedKvCacheBytes=u||null,v.recurrentMemoryBytes=f||null,v.kvInfo=p||null,v.quantization=m||null;let b=null,x=null;if(e){let t=$e(e);x={...e,score:t};let r=`buttress`,i=`buttress-higher-score`;if(!_.ok)r=`local`,i=`buttress-unavailable`;else if(!t&&t!==0)r=`buttress`,i=`missing-client-score`;else{let e=x.fit,a=x.limitedFit,o=v?.fit,s=v?.limitedFit;({recommendation:r,reason:i}=tt({clientScore:t,buttressScore:y,threshold:n,clientFitsInMemory:et(e,a),buttressFitsInMemory:et(o,s)}))}b={buttressScore:y,clientScore:t,threshold:n,recommendation:r,reason:i}}!_.ok&&!b&&(b={buttressScore:y,clientScore:e?.score??null,threshold:n,recommendation:`local`,reason:`buttress-unavailable`});let S=null;return i&&(S={repoId:i.model?.repo_id||null,quantization:i.model?.quantization||null,nCtx:i.model?.n_ctx||null,cacheKType:i.model?.cache_type_k||`f16`,cacheVType:i.model?.cache_type_v||`f16`}),{type:`ggml-llm`,timestamp:new Date().toISOString(),buttress:_,client:x,comparison:b,modelConfig:S}}const ine=e=>{if(!e)return null;if(e instanceof ArrayBuffer)return e;if(ArrayBuffer.isView(e))return e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength);if(typeof e==`string`){let t=e.startsWith(`data:`)?e.split(`,`)[1]||``:e,n=Buffer.from(t,`base64`);return n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength)}throw Error(`Unsupported audioData format, expected base64 string or ArrayBuffer`)};var Bn=class{constructor(){this.queue=[],this.queueHead=0,this.processing=!1,this.currentTaskId=null}async enqueue(e,t=null){return new Promise((n,r)=>{this.queue.push({task:e,resolve:n,reject:r,taskId:t}),this.processNext()})}async processNext(){if(this.processing||this.queueHead>=this.queue.length)return;this.processing=!0;let e=this.queue[this.queueHead];this.queue[this.queueHead]=null,this.queueHead+=1,this.compactQueueIfNeeded();let{task:t,resolve:n,reject:r,taskId:i}=e;this.currentTaskId=i;try{n(await t())}catch(e){r(e)}finally{this.processing=!1,this.currentTaskId=null,this.processNext()}}compactQueueIfNeeded(){if(this.queueHead===this.queue.length){this.queue=[],this.queueHead=0;return}this.queueHead>64&&this.queueHead*2>=this.queue.length&&(this.queue=this.queue.slice(this.queueHead),this.queueHead=0)}getStatus(){return{processing:this.processing,queuedCount:this.queue.length-this.queueHead,currentTaskId:this.currentTaskId}}};const Vn=`https://huggingface.co`,Hn=`https://huggingface.co/api`,Un=M.join(N.homedir(),`.buttress`,`models`),Wn=[`cuda`,`vulkan`,`default`],Gn=[`q8_0`,`q5_1`,`q5_0`,`q4_k`,`q4_1`,`q4_0`],Kn=`fp16`,qn=.5,ane=[`whisper`,`parakeet`],one=[`parakeet-tdt-0.6b-v3`,`parakeet`,`large-v3-turbo`,`distil-large-v3`,`large-v3`,`large-v2`,`large-v1`,`large`,`distil-medium`,`medium.en`,`medium`,`small.en-tdrz`,`distil-small.en`,`small.en`,`small`,`base.en`,`base`,`tiny.en`,`tiny`],Jn=e=>{if(!e)return null;let t=e.toLowerCase();return one.find(e=>t.includes(e))||null},Yn={backend:{type:`ggml-stt`,variant:null,variant_preference:Wn,gpu_memory_fraction:.85,cpu_memory_fraction:qn},model:{repo_id:`BricksDisplay/whisper-ggml`,revision:`main`,filename:null,url:null,quantization:null,preferred_quantizations:[`q8_0`,Kn,`q5_1`],allow_local_file:!1,local_path:null,api_base:Hn,base_url:Vn,use_gpu:!0,use_flash_attn:`auto`},runtime:{cache_dir:Un,prefer_variants:[],huggingface_token:process.env.HUGGINGFACE_TOKEN||null,http_headers:{},max_threads:null,context_release_delay_ms:1e4}},{normalizeVariants:Xn,sanitizeVariant:sne}=Zt(Wn),cne=e=>{let t=e.model.engine&&String(e.model.engine).toLowerCase();return t?t===`parakeet`?`parakeet`:`whisper`:`${e.model.repo_id||``} ${e.model.filename||``} ${e.model.url||``}`.toLowerCase().includes(`parakeet`)?`parakeet`:`whisper`},Zn=(e={})=>{let t=structuredClone(Yn);if(qt(t,e),t.model.engine=cne(t),t.model.engine===`parakeet`&&t.model.repo_id===Yn.model.repo_id&&!t.model.url&&(t.model.repo_id=`ggml-org/parakeet-GGUF`),t.backend.variant=sne(t.backend.variant),t.backend.variant_preference=Xn(t.backend.variant_preference||Wn),t.backend.variant_preference.length===0&&(t.backend.variant_preference=[...Wn]),t.runtime.prefer_variants=Xn(t.runtime.prefer_variants),t.model.preferred_quantizations=Xt(t.model.preferred_quantizations||t.model.quantizations),t.model.quantization){let e=String(t.model.quantization).toLowerCase();t.model.preferred_quantizations.includes(e)||t.model.preferred_quantizations.unshift(e)}t.model.base_url=t.model.base_url||Vn,t.model.api_base=t.model.api_base||Hn,t.runtime.cache_dir=t.runtime.cache_dir?M.resolve(t.runtime.cache_dir):Un;let n=Number(t.runtime.context_release_delay_ms);return t.runtime.context_release_delay_ms=Number.isFinite(n)?Math.max(0,n):Yn.runtime.context_release_delay_ms,t},Qn=e=>{let t=e.toLowerCase();return Gn.find(e=>t.includes(e))||null},lne=e=>{let t=[];return e.backend.variant&&t.push(e.backend.variant),e.runtime.prefer_variants.length>0&&t.push(...e.runtime.prefer_variants),t.push(...e.backend.variant_preference),t.push(`default`),Xn(t)},$n=ln({defaultBaseDir:Un}),er=(e,t)=>e.model.local_path?M.resolve(e.model.local_path):tn(e.runtime.cache_dir,t,`model`),tr=async e=>{let t=e.model.repo_id||e.model.repository||e.model.model;if(!t)throw Error("`model.repo_id` is required in Buttress backend config");let n=e.model.revision||`main`,r=e.runtime.cache_dir,i=JSON.stringify({repoId:t,revision:n,filename:e.model.filename,url:e.model.url,quantization:e.model.quantization,preferred_quantizations:e.model.preferred_quantizations}),a=await $n.read(i,`artifact-info`,r);if(a)return a;let o={...e.runtime.http_headers||{}};if(e.runtime.huggingface_token&&(o.Authorization=`Bearer ${e.runtime.huggingface_token}`),e.model.url){let a=await on(e.model.url,{headers:o}),s=Number(a.headers.get(`content-length`))||null,c=e.model.filename||e.model.url.split(`/`).pop(),l={repoId:t,revision:n,filename:c,url:e.model.url,size:s,quantization:Qn(c||``),headers:o};return await $n.write(i,`artifact-info`,l,r),l}let{filename:s}=e.model,c=e.model.quantization&&String(e.model.quantization).toLowerCase(),l=await an(`${e.model.api_base}/models/${t}?revision=${n}&blobs=true`,{headers:o}),u=(l?.siblings||l?.files||[]).map(e=>e.rfilename||e.path||e.filename).filter(e=>typeof e==`string`&&e.endsWith(`.bin`));if(u.length===0)throw Error(`No model artifacts found in repo ${t}`);let d=e.model.preferred_quantizations.length>0?e.model.preferred_quantizations:Gn,f=()=>{for(let e of d)if(e===Kn){let e=u.find(e=>{let t=e.toLowerCase();return!Gn.some(e=>t.includes(e))});if(e)return{filename:e,quantization:null}}else{let t=u.find(t=>t.toLowerCase().includes(e));if(t)return{filename:t,quantization:e}}return null};if(s)c||=Qn(s);else{let{filename:e,quantization:t}=f()||{filename:u[0],quantization:null};s=e,c=t||Qn(s)}let p=`${e.model.base_url.replace(/\/+$/,``)}/${t}/resolve/${n}/${s}`,m=await on(p,{headers:o}),h=Number(m.headers.get(`content-length`))||null,g={repoId:t,revision:n,filename:s,url:p,size:h,quantization:c,headers:o,isSplit:!1,splitCount:0};return await $n.write(i,`artifact-info`,g,r),g},une=async(e,{modelBytes:t=null,processingBytes:n=null}={})=>{let r=lne(e),[i,...a]=r,o=Jt(e.backend?.gpu_memory_fraction)??(Yn.backend.gpu_memory_fraction||1),s=Jt(e.backend?.cpu_memory_fraction)??qn,c=await ft({platform:process.platform,totalMemoryInBytes:N.totalmem(),backend:`ggml-stt`,variant:i||null,preferVariants:a,variantPreference:e.backend.variant_preference,gpuMemoryFraction:o,cpuMemoryFraction:s,dependencies:{getBackendDevicesInfo:P,isLibVariantAvailable:ie},modelBytes:t,kvCacheBytes:n}),l=e=>({...e,devices:Array.isArray(e.devices)?e.devices:[],ok:e.ok,hasGpu:!!e.hasGpu,totalMemory:e.gpuTotalBytes||e.totalMemory||0,error:e.ok?null:Error(e.error||`Variant ${e.variant} not available on this platform`)});if(!c.ok||!c.selected){let e=(c.attempts||[]).map(e=>`${e.variant}: ${e.error||`unknown error`}`).join(`; `);throw Error(`Unable to initialize any backend variant (${r.join(`, `)}). Errors: ${e}`)}let u=(c.attempts||[]).map(l);return{selected:l(c.selected),attempts:u}},nr=(e,t)=>e===`parakeet`?Gee(t):Wee(t),dne=async e=>{let{engine:t}=e.model,n=await tr(e),r=nr(t,{modelBytes:n.size>0?n.size:0}),i=await une(e,{modelBytes:r.modelBytes,processingBytes:r.processingBufferBytes}),a=i.selected.hasGpu&&(i.selected.fit?.fitsInGpu===void 0||i.selected.fit.fitsInGpu);e.model.use_gpu===!1&&(a=!1);let o=e.model.use_flash_attn&&String(e.model.use_flash_attn).toLowerCase(),s;s=t===`parakeet`?!1:o===`on`||o===`true`?!0:o===`off`||o===`false`?!1:a;let c=e.runtime.cache_dir,l=er(e,n),u=await rn(l,n.size);return{config:e,info:{ok:!0,backend:`ggml-stt`,engine:t,model:{repoId:n.repoId,revision:n.revision,filename:n.filename,quantization:n.quantization,modelType:Jn(n.filename),engine:t,url:n.url,sizeBytes:n.size},runtime:{variant:i.selected.variant,use_gpu:a,use_flash_attn:s,max_threads:e.runtime.max_threads?Number(e.runtime.max_threads):null},resources:{...r,gpuCapacityBytes:i.selected.gpuTotalBytes,gpuUsableBytes:i.selected.gpuUsableBytes,cpuUsableBytes:i.selected.cpuUsableBytes,fit:i.selected.fit},devices:{selected:i.selected,attempts:i.attempts},download:{cacheDir:c,localPath:l,exists:u},timestamp:new Date().toISOString()},artifact:n,memory:r,devices:i,localPath:l,localExists:u}},fne=async(e,t,n,r=null)=>{let{localPath:i,artifact:a,config:o}=e;if(o.model.local_path||await nn(i,o.runtime.cache_dir),e.localExists)return typeof n==`function`&&n(1),i;if(r){let t=r.getDownload(i);if(t){console.log(`[ensureModelFile] Waiting for global STT download: ${a.repoId}`);try{if(await t,await rn(i,a.size))return e.localExists=!0,e.info.download.exists=!0,typeof n==`function`&&n(1),i}catch(e){console.warn(`[ensureModelFile] Global STT download failed, will retry: ${e.message}`)}}}let s=t.get(i);if(s)return await s,typeof n==`function`&&n(1),i;let c=(async()=>{if(o.model.allow_local_file){if(!await rn(i,a.size))throw Error(`Local model file not found: ${i}`);return i}return await cn(a.url,a.headers,i,a.size,n,{allowedRoot:o.runtime.cache_dir}),i})();t.set(i,c);try{return await c,i}finally{t.delete(i)}},pne=async(e,t)=>{if(e.contextRecord&&!e.contextRecord.released)return e.contextRecord.releaseTimer&&(clearTimeout(e.contextRecord.releaseTimer),e.contextRecord.releaseTimer=null,console.log(`[Context] Cancelled pending STT release`)),e.contextRecord.releaseRequested=!1,e.contextRecord.refCount+=1,console.log(`[Context] Reusing existing STT context, refCount=${e.contextRecord.refCount}`),typeof t==`function`&&t(0),e.contextRecord.context||await e.contextRecord.ready,typeof t==`function`&&t(1),e.contextRecord;e.contextRecord?console.log(`[Context] STT record exists but released=${e.contextRecord.released}, creating new context`):console.log(`[Context] No existing STT record, creating new context`);let n={refCount:1,ready:null,released:!1};e.contextRecord=n,n.ready=(async()=>{let r=Date.now();try{typeof t==`function`&&t(0);let i=await fne(e.plan,e.downloads,t,e.globalDownloadManager);typeof t==`function`&&t(.5);let a=e.plan.info.engine===`parakeet`?await de({filePath:i,useGpu:!!e.plan.info.runtime.use_gpu},e.plan.info.runtime.variant):await fe({filePath:i,useFlashAttn:!!e.plan.info.runtime.use_flash_attn,useGpu:!!e.plan.info.runtime.use_gpu,nThreads:e.plan.info.runtime.max_threads},e.plan.info.runtime.variant);typeof t==`function`&&t(1),n.context=a;try{n.modelInfo=a.getModelInfo()}catch{n.modelInfo=null}return Ft.addModelLoad({id:e.id,generatorId:e.id,repoId:e.plan.info.model?.repoId||null,quantization:e.plan.info.model?.quantization||null,modelType:e.plan.info.model?.modelType||null,variant:e.plan.info.runtime?.variant||null,useGpu:e.plan.info.runtime?.use_gpu||!1,durationMs:Date.now()-r,success:!0}),n}catch(t){throw Ft.addModelLoad({id:e.id,generatorId:e.id,repoId:e.plan.info.model?.repoId||null,quantization:e.plan.info.model?.quantization||null,modelType:e.plan.info.model?.modelType||null,variant:e.plan.info.runtime?.variant||null,durationMs:Date.now()-r,success:!1,error:t?.message||String(t)}),t}})();try{return await n.ready,typeof t==`function`&&t(1),n}catch(t){throw e.contextRecord=null,t}},rr=async(e,t,n=!1)=>t.released||!n&&t.refCount>0?!1:(t.released=!0,e.contextRecord=null,await t.context?.release?.(),!0),mne=async(e,t,n=!1)=>{if(t.releaseRequested=!0,t.releaseTimer&&=(clearTimeout(t.releaseTimer),null),n)t.refCount=0;else if(t.refCount=Math.max(0,t.refCount-1),t.refCount>0)return t.releaseRequested=!1,!1;let r=e.config.runtime.context_release_delay_ms;if(typeof r!=`number`||!Number.isFinite(r))return rr(e,t);let i=Math.max(0,Math.floor(r));return n||i<=0?rr(e,t):(console.log(`[Context] Scheduling STT release in ${i}ms`),t.releaseTimer=setTimeout(async()=>{if(t.releaseTimer=null,t.refCount>0){console.log(`[Context] STT release cancelled, refCount=${t.refCount}`),t.releaseRequested=!1;return}console.log(`[Context] Releasing STT context after ${i}ms delay`),await rr(e,t)},i),!0)};async function hne(e,t,n={}){let{globalDownloadManager:r=null}=n,i=Zn(t),a=await dne(i),o={id:e,type:`ggml-stt`,config:i,plan:a,info:a.info,contextRecord:null,downloads:new Map,globalDownloadManager:r,queue:new Bn,finalized:!1},s=async()=>{if(o.finalized)return;o.finalized=!0;let e=o.contextRecord;e&&(e.released||e.releaseRequested||e.releaseTimer||(e.refCount=Math.max(0,e.refCount-1),!(e.refCount>0)&&await rr(o,e)))},c=async(e={})=>{let{onProgress:t}=e;try{let e=await pne(o,t);return{modelInfo:e.modelInfo&&typeof e.modelInfo==`object`?{...e.modelInfo}:null,runtime:{...o.plan.info.runtime},download:{...o.plan.info.download}}}catch(e){throw console.error(`[Context] Error initializing context:`,e),e}},l=async()=>{if(o.finalized)return!1;let e=o.contextRecord;return e?mne(o,e):!1},u=async(e={})=>{let{audioPath:t,audioData:n,options:r={}}=e,i=o.contextRecord;if(!i)throw Error(`Context not initialized`);let a={...r};o.plan.info.engine===`parakeet`&&(a={...r.maxThreads!=null&&{maxThreads:r.maxThreads},...r.audioCtx!=null&&{audioCtx:r.audioCtx}}),o.plan.info.runtime.max_threads&&a.maxThreads==null&&(a.maxThreads=o.plan.info.runtime.max_threads);let s=`transcription-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,c=Date.now();return o.queue.enqueue(async()=>{await i.ready;try{let e;if(n){let t=ine(n),{promise:r}=i.context.transcribeData(t,a);e=await r}else{if(!t)throw Error(`audioPath or audioData is required for transcription`);let n=M.resolve(t),{promise:r}=i.context.transcribe(n,a);e=await r}return Ft.addTranscription({id:s,generatorId:o.id,repoId:o.plan.info.model?.repoId||null,quantization:o.plan.info.model?.quantization||null,modelType:o.plan.info.model?.modelType||null,variant:o.plan.info.runtime?.variant||null,durationMs:Date.now()-c,segmentCount:e?.segments?.length||0,textLength:e?.text?.length||0,success:!0}),e}catch(e){throw Ft.addTranscription({id:s,generatorId:o.id,repoId:o.plan.info.model?.repoId||null,quantization:o.plan.info.model?.quantization||null,modelType:o.plan.info.model?.modelType||null,variant:o.plan.info.runtime?.variant||null,durationMs:Date.now()-c,success:!1,error:e?.message||String(e)}),e}},s)};return{id:e,type:`ggml-stt`,info:a.info,queue:o.queue,initContext:c,transcribe:async(e={})=>u(e),transcribeData:async(e={})=>u(e),releaseContext:l,finalize:s,getStatus:()=>({id:o.id,type:o.type,engine:o.plan.info.engine,repoId:o.plan.info.model?.repoId||null,quantization:o.plan.info.model?.quantization||null,modelType:o.plan.info.model?.modelType||null,variant:o.plan.info.runtime?.variant||null,hasContext:!!o.contextRecord?.context,contextRefCount:o.contextRecord?.refCount||0,queueStatus:o.queue.getStatus()}),hasPendingReleases:()=>{let e=o.contextRecord;return e?!e.released&&(e.releaseRequested||e.releaseTimer||e.refCount>0):!1},resetFinalized:()=>{o.finalized=!1}}}const ir=e=>{let t=Zn(e),n=t.model.repo_id||t.model.repository||t.model.model||null;if(!n)return null;let r=Jn(t.model.filename);return r?`${n}:${r}`:n};async function gne(e,t,n={}){let{onProgress:r,onComplete:i,onError:a}=n;try{let n=Zn(e),o=await tr(n),s=er(n,o),{repoId:c}=o;if(n.model.local_path||await nn(s,n.runtime.cache_dir),await rn(s,o.size))return console.log(`[Download] STT model already exists: ${c} at ${s}`),typeof i==`function`&&i({localPath:s,repoId:c,alreadyExists:!0}),{started:!1,localPath:s,repoId:c,alreadyExists:!0};let l=t.getDownload(s);if(l)return console.log(`[Download] Already downloading STT model: ${c}`),l.then(()=>{typeof i==`function`&&i({localPath:s,repoId:c,joinedExisting:!0})}).catch(e=>{typeof a==`function`&&a(e)}),{started:!1,localPath:s,repoId:c,alreadyDownloading:!0};console.log(`[Download] Starting STT model download: ${c}`);let u=(async()=>{try{await cn(o.url,o.headers,s,o.size,e=>{e>=0&&Number.isFinite(e)&&(console.log(`[Download] ${c}: ${Math.round(e*100)}%`),typeof r==`function`&&r(e))},{allowedRoot:n.runtime.cache_dir}),console.log(`[Download] Completed STT model: ${c}`),typeof i==`function`&&i({localPath:s,repoId:c})}catch(e){throw console.error(`[Download] Failed STT model: ${c}`,e.message),typeof a==`function`&&a(e),e}finally{t.deleteDownload(s)}})();return t.setDownload(s,u),{started:!0,localPath:s,repoId:c}}catch(e){return console.error(`[Download] Failed to start STT download:`,e.message),typeof a==`function`&&a(e),{started:!1,localPath:null,repoId:null,error:e.message}}}async function _ne(e=null,t={}){let{threshold:n=1.1,includeBreakdown:r=!1,config:i,...a}=t,o=null,s=null,c=null,l=null;if(i){let e=Zn(i);l=e.model.engine;try{let t=await tr(e);o=t.size??null,{processingBufferBytes:s}=nr(l,{modelBytes:o}),c=t.quantization||null}catch{}}let u=Jt(i?.backend?.gpu_memory_fraction),d=Jt(i?.backend?.cpu_memory_fraction),f=await ft({...a,platform:process.platform,totalMemoryInBytes:N.totalmem(),backend:`ggml-stt`,includeBreakdown:r,gpuMemoryFraction:u,cpuMemoryFraction:d,dependencies:{getBackendDevicesInfo:P,isLibVariantAvailable:ie},modelBytes:o,kvCacheBytes:s}),p=f.selected,m=$e(p);p&&(p.modelBytes=o||null,p.processingBytes=s||null,p.quantization=c||null);let h=null,g=null;if(e){let t=$e(e);g={...e,score:t};let r=`buttress`,i=`buttress-higher-score`;if(!f.ok)r=`local`,i=`buttress-unavailable`;else if(!t&&t!==0)r=`buttress`,i=`missing-client-score`;else{let a=e.fit&&p?.fit;({recommendation:r,reason:i}=tt({clientScore:t,buttressScore:m,threshold:n,clientFitsInMemory:a?et(e.fit):!1,buttressFitsInMemory:a?et(p.fit):!1}))}h={buttressScore:m,clientScore:t,threshold:n,recommendation:r,reason:i}}!f.ok&&!h&&(h={buttressScore:m,clientScore:e?.score??null,threshold:n,recommendation:`local`,reason:`buttress-unavailable`});let _=null;return i&&(_={repoId:i.model?.repo_id||null,quantization:i.model?.quantization||null,filename:i.model?.filename||null,engine:l}),{type:`ggml-stt`,engines:[...ane],timestamp:new Date().toISOString(),buttress:f,client:g,comparison:h,modelConfig:_}}const ar=e=>M.join(e,`.tts-cache`),or=e=>M.join(ar(e),`audio`),sr=e=>M.join(ar(e),`cache-map.json`),cr=(e,t,n)=>{let r=JSON.stringify({text:e,model:t,options:n});return A(`sha256`).update(r).digest(`hex`).slice(0,24)};var lr=class{constructor(e){this.baseDir=e.runtime.cache_dir,this.enabled=e.runtime.output_cache?.enabled!==!1,this.maxSizeBytes=e.runtime.output_cache?.max_size_bytes??2147483648,this.maxEntries=e.runtime.output_cache?.max_entries??5e3,this.cacheMap=null}async load(){if(this.enabled)try{let e=await S(sr(this.baseDir),`utf-8`);this.cacheMap=JSON.parse(e),this.cacheMap?.entries||(this.cacheMap={entries:{},totalSize:0})}catch{this.cacheMap={entries:{},totalSize:0}}}async save(){if(!this.cacheMap)return;let e=sr(this.baseDir);await b(M.dirname(e),{recursive:!0}),await k(e,JSON.stringify(this.cacheMap,null,2),`utf-8`)}async lookup(e,t,n){if(!this.enabled||!this.cacheMap)return null;let r=cr(e,t,n),i=this.cacheMap.entries[r];if(!i)return null;try{await D(i.filePath)}catch{return delete this.cacheMap.entries[r],this.cacheMap.totalSize-=i.fileSize||0,await this.save(),null}return i.lastAccessedAt=new Date().toISOString(),await this.save(),i}async store(e,t,n,r,i,a){if(!this.enabled||!this.cacheMap)return null;let o=cr(e,t,n),s=or(this.baseDir);await b(s,{recursive:!0});let c=M.join(s,`${o}.wav`),l=Buffer.from(r);await k(c,l);let u=l.length,d=this.cacheMap.entries[o];return d&&(this.cacheMap.totalSize-=d.fileSize||0),this.cacheMap.entries[o]={id:o,filePath:c,fileSize:u,samplingRate:i,channels:a,text:e.slice(0,200),createdAt:new Date().toISOString(),lastAccessedAt:new Date().toISOString()},this.cacheMap.totalSize+=u,await this.evict(),await this.save(),this.cacheMap.entries[o]}async evict(){if(!this.cacheMap)return;let{totalSize:e}=await Kt({entries:this.cacheMap.entries,totalSize:this.cacheMap.totalSize,maxEntries:this.maxEntries,maxSizeBytes:this.maxSizeBytes,removeEntry:e=>O(e.filePath).catch(()=>{})});this.cacheMap.totalSize=e}};const ur=async({cache:e,cacheDir:t,text:n,modelInfo:r,options:i,wavBuffer:a,samplingRate:o,channels:s=1})=>{let c=await e.store(n,r,i,a,o,s);if(c)return{cachedId:c.id,cachedFile:c.filePath,sampling_rate:o,channels:s};let l=cr(n,r,i),u=or(t);await b(u,{recursive:!0});let d=M.join(u,`tmp-${l}.wav`);return await k(d,Buffer.from(a)),{cachedId:l,cachedFile:d,sampling_rate:o,channels:s}},vne=(e,t,n)=>{let r=Buffer.alloc(44),i=16*e*t>>3,a=16*t>>3;return r.write(`RIFF`,0),r.writeUInt32LE(n+44-8,4),r.write(`WAVE`,8),r.write(`fmt `,12),r.writeUInt32LE(16,16),r.writeUInt16LE(1,20),r.writeUInt16LE(t,22),r.writeUInt32LE(e,24),r.writeUInt32LE(i,28),r.writeUInt16LE(a,32),r.writeUInt16LE(16,34),r.write(`data`,36),r.writeUInt32LE(n,40),r},yne=(e,t,n=1)=>{let r=Buffer.allocUnsafe(e.length*2);for(let t=0;t<e.length;t+=1){let n=Math.max(-1,Math.min(1,e[t]));r.writeInt16LE(Math.round(n*32767),t*2)}return Buffer.concat([vne(t,n,r.length),r])},dr=`https://huggingface.co`,fr=`https://huggingface.co/api`,pr=M.join(N.homedir(),`.buttress`,`models`),mr=[`cuda`,`vulkan`,`default`],hr=[`q8_0`,`q6_k`,`q5_k_m`,`q5_1`,`q4_k_m`,`q4_0`],gr=`fp16`,_r=.5,vr=[`outetts`,`soprano`,`neutts`,`csm`,`qwen3_tts`,`moss_tts`,`moss_ttsd`,`chatterbox`,`bluemagpie`],yr=24e3,br={backend:{type:`ggml-tts`,variant:null,variant_preference:mr,gpu_memory_fraction:.85,cpu_memory_fraction:_r},model:{repo_id:null,revision:`main`,filename:null,url:null,quantization:null,preferred_quantizations:[`q4_k_m`,`q8_0`,gr],vocoder_repo_id:null,vocoder_revision:null,vocoder_filename:null,vocoder_url:null,vocoder_quantization:null,allow_local_file:!1,local_path:null,vocoder_local_path:null,api_base:fr,base_url:dr,use_gpu:!0,n_gpu_layers:99,sample_rate:yr},runtime:{cache_dir:pr,prefer_variants:[],huggingface_token:process.env.HUGGINGFACE_TOKEN||null,http_headers:{},n_ctx:8192,n_batch:8192,n_ubatch:512,max_threads:null,vocoder_batch_size:4096,use_mlock:!1,use_mmap:!0,flash_attn_type:`off`,context_release_delay_ms:1e4,output_cache:{enabled:!0,max_size_bytes:2*1024*1024*1024,max_entries:5e3}}},{normalizeVariants:xr,sanitizeVariant:bne}=Zt(mr),Sr=(e={})=>{let t=structuredClone(br);if(qt(t,e),t.backend.variant=bne(t.backend.variant),t.backend.variant_preference=xr(t.backend.variant_preference||mr),t.backend.variant_preference.length===0&&(t.backend.variant_preference=[...mr]),t.runtime.prefer_variants=xr(t.runtime.prefer_variants),t.model.preferred_quantizations=Xt(t.model.preferred_quantizations||t.model.quantizations),t.model.quantization){let e=String(t.model.quantization).toLowerCase();t.model.preferred_quantizations.includes(e)||t.model.preferred_quantizations.unshift(e)}t.model.base_url=t.model.base_url||dr,t.model.api_base=t.model.api_base||fr,t.model.vocoder_revision=t.model.vocoder_revision||t.model.revision,t.model.sample_rate=Number(t.model.sample_rate)||yr,t.runtime.cache_dir=t.runtime.cache_dir?M.resolve(t.runtime.cache_dir):pr;let n=Number(t.runtime.context_release_delay_ms);return t.runtime.context_release_delay_ms=Number.isFinite(n)?Math.max(0,n):br.runtime.context_release_delay_ms,t},Cr=e=>{let t=(e||``).toLowerCase();return hr.find(e=>t.includes(e))||null},xne=e=>e.toLowerCase().replace(/\.gguf$/,``).replace(/[-_.](q\d[a-z0-9_]*|f16|fp16|f32|bf16|mxfp4)$/,``),Sne=e=>{let t=[];return e.backend.variant&&t.push(e.backend.variant),t.push(...e.runtime.prefer_variants),t.push(...e.backend.variant_preference),t.push(`default`),xr(t)},wr=ln({defaultBaseDir:pr}),Tr=async(e,t=`model`)=>{let n=t===`vocoder`,r=n&&e.model.vocoder_repo_id||e.model.repo_id;if(!r)throw Error(n?"`model.vocoder_repo_id` (or `model.repo_id`) is required in Buttress GGML-TTS backend config":"`model.repo_id` is required in Buttress GGML-TTS backend config");let i=(n?e.model.vocoder_revision:e.model.revision)||`main`,a=n?e.model.vocoder_url:e.model.url,o=n?e.model.vocoder_filename:e.model.filename,s=n?e.model.vocoder_quantization:e.model.quantization,c=e.runtime.cache_dir,l=JSON.stringify({role:t,repoId:r,revision:i,filename:o,url:a,quantization:s,preferred_quantizations:e.model.preferred_quantizations}),u=await wr.read(l,`artifact-info`,c);if(u)return u;let d={...e.runtime.http_headers||{}};if(e.runtime.huggingface_token&&(d.Authorization=`Bearer ${e.runtime.huggingface_token}`),a){let e=await on(a,{headers:d}),n=o||a.split(`/`).pop(),u={role:t,repoId:r,revision:i,filename:n,url:a,size:Number(e.headers.get(`content-length`))||null,quantization:s||Cr(n),headers:d};return await wr.write(l,`artifact-info`,u,c),u}let f=o,p=s&&String(s).toLowerCase();if(f)p||=Cr(f);else{let t=await an(`${e.model.api_base}/models/${r}?revision=${i}&blobs=true`,{headers:d}),a=(t?.siblings||t?.files||[]).map(e=>e.rfilename||e.path||e.filename).filter(e=>typeof e==`string`&&e.endsWith(`.gguf`));if(a.length===0)throw Error(`No GGUF artifacts found in repo ${r}`);let o=e=>/codec|vocoder|wavtokenizer|dac|mimi/i.test(e),s=a.filter(e=>o(e)===n),c=s.length>0?s:a;if(n){let e=new Set(c.map(xne));if(e.size>1)throw Error(`Repo ${r} contains multiple codecs (${Array.from(e).sort().join(`, `)}). Set \`model.vocoder_filename\` to the one matching your TTS backbone.`)}let l=e.model.preferred_quantizations.length>0?e.model.preferred_quantizations:hr,u=null;for(let e of l)if(e===gr){let e=c.find(e=>!hr.some(t=>e.toLowerCase().includes(t)));if(e){u={filename:e,quantization:null};break}}else{let t=c.find(t=>t.toLowerCase().includes(e));if(t){u={filename:t,quantization:e};break}}u||={filename:c[0],quantization:null},f=u.filename,p=u.quantization||Cr(f)}let m=`${e.model.base_url.replace(/\/+$/,``)}/${r}/resolve/${i}/${f}`,h=await on(m,{headers:d}),g={role:t,repoId:r,revision:i,filename:f,url:m,size:Number(h.headers.get(`content-length`))||null,quantization:p,headers:d};return await wr.write(l,`artifact-info`,g,c),g},Er=(e,t)=>{let n=t.role===`vocoder`?e.model.vocoder_local_path:e.model.local_path;return n?M.resolve(n):tn(e.runtime.cache_dir,t,`model`)},Cne=async(e,{modelBytes:t=null,processingBytes:n=null}={})=>{let r=Sne(e),[i,...a]=r,o=Jt(e.backend?.gpu_memory_fraction)??br.backend.gpu_memory_fraction,s=Jt(e.backend?.cpu_memory_fraction)??_r,c=await ft({platform:process.platform,totalMemoryInBytes:N.totalmem(),backend:`ggml-tts`,variant:i||null,preferVariants:a,variantPreference:e.backend.variant_preference,gpuMemoryFraction:o,cpuMemoryFraction:s,dependencies:{getBackendDevicesInfo:P,isLibVariantAvailable:ie},modelBytes:t,processingBytes:n});if(!c.ok||!c.selected){let e=(c.attempts||[]).map(e=>`${e.variant}: ${e.error||`unknown error`}`).join(`; `);throw Error(`Unable to initialize any backend variant (${r.join(`, `)}). Errors: ${e}`)}return{selected:c.selected,attempts:c.attempts||[]}},wne=async e=>{let t=await Tr(e,`model`),n=await Tr(e,`vocoder`),r=ht({modelBytes:t.size||0,vocoderBytes:n.size||0,contextSize:e.runtime.n_ctx,vocoderBatchSize:e.runtime.vocoder_batch_size}),i=await Cne(e,{modelBytes:r.modelBytes,processingBytes:r.processingBufferBytes}),a=i.selected.hasGpu&&(i.selected.fit?.fitsInGpu===void 0||i.selected.fit.fitsInGpu);e.model.use_gpu===!1&&(a=!1);let o=Er(e,t),s=Er(e,n);return{config:e,info:{ok:!0,backend:`ggml-tts`,families:[...vr],model:{repoId:t.repoId,revision:t.revision,filename:t.filename,quantization:t.quantization,url:t.url,sizeBytes:t.size,vocoderRepoId:n.repoId,vocoderFilename:n.filename,vocoderSizeBytes:n.size,sampleRate:e.model.sample_rate},runtime:{variant:i.selected.variant,use_gpu:a,n_gpu_layers:a?e.model.n_gpu_layers:0,n_ctx:e.runtime.n_ctx,n_batch:e.runtime.n_batch,n_ubatch:e.runtime.n_ubatch,vocoder_batch_size:e.runtime.vocoder_batch_size,max_threads:e.runtime.max_threads?Number(e.runtime.max_threads):null,use_mlock:!!e.runtime.use_mlock,use_mmap:e.runtime.use_mmap!==!1,flash_attn_type:e.runtime.flash_attn_type},resources:{...r,gpuCapacityBytes:i.selected.gpuTotalBytes,gpuUsableBytes:i.selected.gpuUsableBytes,cpuUsableBytes:i.selected.cpuUsableBytes,fit:i.selected.fit},devices:i,download:{cacheDir:e.runtime.cache_dir,localPath:o,vocoderLocalPath:s,exists:await rn(o,t.size),vocoderExists:await rn(s,n.size)},timestamp:new Date().toISOString()},artifact:t,vocoderArtifact:n,memory:r,devices:i,localPath:o,vocoderLocalPath:s}},Dr=async({config:e,artifact:t,localPath:n,downloads:r,onProgress:i,globalDownloadManager:a})=>{if((t.role===`vocoder`?e.model.vocoder_local_path:e.model.local_path)||await nn(n,e.runtime.cache_dir),await rn(n,t.size))return i?.(1),n;let o=a?.getDownload(n);if(o)try{if(await o,await rn(n,t.size))return i?.(1),n}catch(e){console.warn(`[ensureArtifactFile] Global TTS download failed, will retry: ${e.message}`)}let s=r.get(n);if(s)return await s,i?.(1),n;let c=(async()=>{if(e.model.allow_local_file){if(!await rn(n,t.size))throw Error(`Local model file not found: ${n}`);return n}return await cn(t.url,t.headers,n,t.size,i,{allowedRoot:e.runtime.cache_dir}),n})();r.set(n,c);try{return await c}finally{r.delete(n)}},Tne=(e,t,n)=>{let{audio_tokens:r,embeddings:i,embedding_dim:a}=t;if(n===`continuous_embd`||i?.length&&a){if(!i?.length)throw Error(`No audio embeddings generated`);return e.decodeAudioEmbeddings(i,a)}if(!r?.length)throw Error(`No audio tokens generated`);return e.decodeAudioTokens(r)},Ene=async(e,t)=>{if(e.contextRecord&&!e.contextRecord.released)return e.contextRecord.releaseTimer&&(clearTimeout(e.contextRecord.releaseTimer),e.contextRecord.releaseTimer=null),e.contextRecord.releaseRequested=!1,e.contextRecord.refCount+=1,t?.(0),e.contextRecord.context||await e.contextRecord.ready,t?.(1),e.contextRecord;let n={refCount:1,ready:null,released:!1};e.contextRecord=n,n.ready=(async()=>{let r=Date.now(),{info:i}=e.plan;try{t?.(0);let a=await Dr({config:e.config,artifact:e.plan.artifact,localPath:e.plan.localPath,downloads:e.downloads,onProgress:e=>t?.(e*.3),globalDownloadManager:e.globalDownloadManager}),o=await Dr({config:e.config,artifact:e.plan.vocoderArtifact,localPath:e.plan.vocoderLocalPath,downloads:e.downloads,onProgress:e=>t?.(.3+e*.2),globalDownloadManager:e.globalDownloadManager}),s=await ae({model:a,n_ctx:i.runtime.n_ctx,n_batch:i.runtime.n_batch,n_ubatch:i.runtime.n_ubatch,n_threads:i.runtime.max_threads??void 0,n_gpu_layers:i.runtime.n_gpu_layers,use_mlock:i.runtime.use_mlock,use_mmap:i.runtime.use_mmap,flash_attn_type:i.runtime.flash_attn_type,lib_variant:i.runtime.variant},e=>t?.(.5+e/100*.4));try{await s.initVocoder({path:o,n_batch:i.runtime.vocoder_batch_size})}catch(e){throw await s.release?.().catch(()=>{}),e}return t?.(1),n.context=s,n.capabilities=s.getTTSCapabilities(),n.sampleRate=Number(s.getAudioSampleRate())||i.model.sampleRate,n.modelInfo={repoId:i.model.repoId,filename:i.model.filename,quantization:i.model.quantization,vocoderRepoId:i.model.vocoderRepoId,vocoderFilename:i.model.vocoderFilename,sampleRate:n.sampleRate,family:n.capabilities?.family||null,promptKind:n.capabilities?.promptKind||null,requiresPhonemes:!!n.capabilities?.requiresPhonemes},It.addModelLoad({id:e.id,generatorId:e.id,repoId:i.model.repoId,quantization:i.model.quantization,vocoderRepoId:i.model.vocoderRepoId,family:n.modelInfo.family,variant:i.runtime.variant,useGpu:i.runtime.use_gpu,durationMs:Date.now()-r,success:!0}),n}catch(t){throw It.addModelLoad({id:e.id,generatorId:e.id,repoId:i.model?.repoId||null,quantization:i.model?.quantization||null,variant:i.runtime?.variant||null,durationMs:Date.now()-r,success:!1,error:t?.message||String(t)}),t}})();try{return await n.ready,t?.(1),n}catch(t){throw e.contextRecord=null,t}},Or=async(e,t,n=!1)=>{if(t.released||!n&&t.refCount>0)return!1;t.released=!0,e.contextRecord=null;try{await t.context?.releaseVocoder?.()}catch{}return await t.context?.release?.(),!0},Dne=async(e,t,n=!1)=>{if(t.releaseRequested=!0,t.releaseTimer&&=(clearTimeout(t.releaseTimer),null),n)t.refCount=0;else if(t.refCount=Math.max(0,t.refCount-1),t.refCount>0)return t.releaseRequested=!1,!1;let r=e.config.runtime.context_release_delay_ms;if(typeof r!=`number`||!Number.isFinite(r))return Or(e,t);let i=Math.max(0,Math.floor(r));return n||i<=0?Or(e,t):(t.releaseTimer=setTimeout(async()=>{if(t.releaseTimer=null,t.refCount>0){t.releaseRequested=!1;return}await Or(e,t)},i),!0)};async function One(e,t,n={}){let{globalDownloadManager:r=null}=n,i=Sr(t),a=await wne(i),o=new lr(i);await o.load();let s={id:e,type:`ggml-tts`,config:i,plan:a,info:a.info,contextRecord:null,downloads:new Map,globalDownloadManager:r,queue:new Bn,outputCache:o,finalized:!1};return{id:e,type:`ggml-tts`,info:a.info,queue:s.queue,initContext:async(e={})=>{let{onProgress:t}=e,n=await Ene(s,t);return{modelInfo:n.modelInfo?{...n.modelInfo}:null,runtime:{...s.plan.info.runtime},download:{...s.plan.info.download}}},synthesize:async(e={})=>{let{text:t,options:n={}}=e;if(!t)throw Error(`Text input is required for speech synthesis`);let{info:r}=s.plan,i={repoId:r.model.repoId,filename:r.model.filename,quantization:r.model.quantization,vocoderFilename:r.model.vocoderFilename,variant:r.runtime.variant},a=await s.outputCache.lookup(t,i,n);if(a)return It.addTranscription({id:s.id,repoId:i.repoId,variant:i.variant,textLength:t.length,durationMs:0,cached:!0,success:!0}),{cachedId:a.id,cachedFile:a.filePath,sampling_rate:a.samplingRate,channels:a.channels};let o=s.contextRecord;if(!o)throw Error(`Context not initialized`);let c=Date.now();return s.queue.enqueue(async()=>{await o.ready;let{context:e}=o,{speaker:a=null,temperature:l=.1,repeatPenalty:u=1.1,topK:d=40,topP:f=.9,minP:p=.05,nPredict:m=-1,seed:h}=n;try{e.clearCache?.(!1);let{prompt:g,grammar:_,embedding:v,flow:y}=await e.getFormattedAudioCompletion({prompt:t,...a?{speaker:a}:{}}),b=await e.completion({prompt:g,grammar:_,embedding:v,temperature:l,repeat_penalty:u,top_k:d,top_p:f,min_p:p,n_predict:m,...h!=null&&{seed:h}}),x=await Tne(e,b,y),S=x instanceof Float32Array?x:Float32Array.from(x),C=o.sampleRate||r.model.sampleRate;return It.addTranscription({id:s.id,repoId:i.repoId,variant:i.variant,family:o.modelInfo?.family||null,textLength:t.length,audioLength:S.length,samplingRate:C,durationMs:Date.now()-c,cached:!1,success:!0}),ur({cache:s.outputCache,cacheDir:s.config.runtime.cache_dir,text:t,modelInfo:i,options:n,wavBuffer:yne(S,C,1),samplingRate:C,channels:1})}catch(e){throw It.addTranscription({id:s.id,repoId:i.repoId,variant:i.variant,textLength:t.length,durationMs:Date.now()-c,cached:!1,success:!1,error:e?.message||String(e)}),e}},`synthesis-${Date.now()}-${Math.random().toString(36).slice(2,8)}`)},releaseContext:async()=>{if(s.finalized)return!1;let e=s.contextRecord;return e?Dne(s,e):!1},finalize:async()=>{if(s.finalized)return;s.finalized=!0;let e=s.contextRecord;!e||e.released||e.releaseRequested||e.releaseTimer||(e.refCount=Math.max(0,e.refCount-1),!(e.refCount>0)&&await Or(s,e))},getStatus:()=>({id:s.id,type:s.type,repoId:s.plan.info.model?.repoId||null,quantization:s.plan.info.model?.quantization||null,vocoderRepoId:s.plan.info.model?.vocoderRepoId||null,family:s.contextRecord?.modelInfo?.family||null,variant:s.plan.info.runtime?.variant||null,hasContext:!!s.contextRecord?.context,contextRefCount:s.contextRecord?.refCount||0,queueStatus:s.queue.getStatus()}),hasPendingReleases:()=>{let e=s.contextRecord;return e?!e.released&&(e.releaseRequested||e.releaseTimer||e.refCount>0):!1},resetFinalized:()=>{s.finalized=!1}}}const kr=e=>{let t=Sr(e),n=t.model.repo_id;if(!n)return null;let r=[n,t.model.revision||`main`];return r.push(t.model.vocoder_repo_id||n),t.model.vocoder_filename&&r.push(t.model.vocoder_filename),r.join(`:`)};async function kne(e,t,n={}){let{onProgress:r,onComplete:i,onError:a}=n;try{let n=Sr(e),o=[await Tr(n,`model`),await Tr(n,`vocoder`)],{repoId:s}=o[0],c=[];for(let e of o){let i=Er(n,e);if(!n.model.local_path&&!n.model.vocoder_local_path&&await nn(i,n.runtime.cache_dir),await rn(i,e.size)||t.getDownload(i))continue;let o=(async()=>{try{await cn(e.url,e.headers,i,e.size,e=>{e>=0&&Number.isFinite(e)&&r?.(e)},{allowedRoot:n.runtime.cache_dir})}catch(t){throw console.error(`[Download] Failed TTS ${e.role}: ${s}`,t.message),a?.(t),t}finally{t.deleteDownload(i)}})();t.setDownload(i,o),c.push({localPath:i,promise:o})}let l=Er(n,o[0]);return c.length===0?(i?.({localPath:l,repoId:s,alreadyExists:!0}),{started:!1,localPath:l,repoId:s,alreadyExists:!0}):(Promise.all(c.map(e=>e.promise)).then(()=>i?.({localPath:l,repoId:s})).catch(()=>{}),{started:!0,localPath:l,repoId:s})}catch(e){return console.error(`[Download] Failed to start TTS download:`,e.message),a?.(e),{started:!1,localPath:null,repoId:null,error:e.message}}}async function Ane(e=null,t={}){let{threshold:n=1.1,includeBreakdown:r=!1,config:i,...a}=t,o=null,s=null,c=null;if(i){let e=Sr(i);try{let t=await Tr(e,`model`),n=await Tr(e,`vocoder`),r=ht({modelBytes:t.size||0,vocoderBytes:n.size||0,contextSize:e.runtime.n_ctx,vocoderBatchSize:e.runtime.vocoder_batch_size});o=r.modelBytes,s=r.processingBufferBytes,c=t.quantization||null}catch{}}let l=Jt(i?.backend?.gpu_memory_fraction),u=Jt(i?.backend?.cpu_memory_fraction),d=await ft({...a,platform:process.platform,totalMemoryInBytes:N.totalmem(),backend:`ggml-tts`,includeBreakdown:r,gpuMemoryFraction:l,cpuMemoryFraction:u,dependencies:{getBackendDevicesInfo:P,isLibVariantAvailable:ie},modelBytes:o,processingBytes:s}),f=d.selected,p=$e(f);f&&(f.modelBytes=o||null,f.processingBytes=s||null,f.quantization=c||null);let m=null,h=null;if(e){let t=$e(e);h={...e,score:t};let r=`buttress`,i=`buttress-higher-score`;if(!d.ok)r=`local`,i=`buttress-unavailable`;else{let a=e.fit&&f?.fit;({recommendation:r,reason:i}=tt({clientScore:t,buttressScore:p,threshold:n,clientFitsInMemory:a?et(e.fit):!1,buttressFitsInMemory:a?et(f.fit):!1}))}m={buttressScore:p,clientScore:t,threshold:n,recommendation:r,reason:i}}return!d.ok&&!m&&(m={buttressScore:p,clientScore:e?.score??null,threshold:n,recommendation:`local`,reason:`buttress-unavailable`}),{type:`ggml-tts`,families:[...vr],timestamp:new Date().toISOString(),buttress:d,client:h,comparison:m,modelConfig:i?{repoId:i.model?.repo_id||null,filename:i.model?.filename||null,quantization:i.model?.quantization||null,vocoderRepoId:i.model?.vocoder_repo_id||null}:null}}const Ar=`<tool_call>`,jr=`</tool_call>`;function Mr(e,t){let n=e,r=``,i=[];for(;;){let e=n.indexOf(Ar);if(e===-1)break;r+=n.slice(0,e);let a=n.slice(e+11),o=a.indexOf(jr);if(o===-1)return{content:r.trimEnd(),toolCalls:i};let s=a.slice(0,o).trim();try{let e=JSON.parse(s);e&&typeof e.name==`string`?i.push({id:`mlx_call_${t}_${i.length}`,type:`function`,function:{name:e.name,arguments:JSON.stringify(e.arguments??{})}}):r+=Ar+a.slice(0,o)+jr}catch{r+=Ar+a.slice(0,o)+jr}n=a.slice(o+12)}r+=n;let a=r.length;for(let e=1;e<11&&e<=r.length;e++)if(Ar.startsWith(r.slice(-e))){a=r.length-e;break}return{content:r.slice(0,a).trimEnd(),toolCalls:i}}const{ReadableStream:Nr}=typeof globalThis<`u`&&globalThis.ReadableStream&&globalThis.WritableStream?{ReadableStream:globalThis.ReadableStream,WritableStream:globalThis.WritableStream}:g,jne=pe(import.meta.url),Mne=M.dirname(jne),Nne=(()=>{let e=[process.env.BUTTRESS_MLX_BRIDGE_PATH,M.join(Mne,`mlx-bridge.py`),M.join(M.dirname(process.execPath),`mlx-bridge.py`)].filter(Boolean);return e.find(e=>ce.existsSync(e))||e[0]})(),Pr=`mlx-vlm==0.4.0`,Fr=`mlx-lm==0.31.1`,Ir=M.join(N.homedir(),`.buttress`,`models`),Pne={backend:{type:`mlx-llm`},model:{repo_id:null,revision:`main`,adapter_path:null,tokenizer_config:null,model_config:null,vlm:`auto`},runtime:{cache_dir:Ir,huggingface_token:process.env.HUGGINGFACE_TOKEN||null,mlx_env_dir:null,mlx_lm_package:Fr,mlx_vlm_package:Pr,context_release_delay_ms:1e4,session_cache:{enabled:!0,max_size_bytes:5*1024*1024*1024,max_entries:100}}},Fne=(e,t)=>e==null?t:typeof e==`number`?e:typeof e==`string`?oe.parse(e)??t:t,Lr=(e={})=>{let t=structuredClone(Pne);return qt(t,e),t},Rr=async(e,t={})=>{let n=await fetch(e,t);if(!n.ok)throw Error(`HTTP ${n.status}: ${e}`);return n.json()},zr=ln();async function Ine(e,{revision:t=`main`,cacheDir:n,token:r}={}){let i=JSON.stringify({repoId:e,revision:t,type:`mlx-model-metadata`});if(n){let e=await zr.read(i,`mlx-model-metadata`,n);if(e)return e}let a={};r&&(a.Authorization=`Bearer ${r}`);let o=(await Rr(`https://huggingface.co/api/models/${e}?revision=${t}&blobs=true`,{headers:a}))?.siblings||[],s=0;for(let e of o){let t=e.rfilename||e.path||e.filename||``;/\.(safetensors|npz)$/.test(t)&&(s+=Number(e.size)||0)}let c=null;try{c=await Rr(`https://huggingface.co/${e}/raw/${t}/config.json`,{headers:a})}catch{}let l=c?.text_config||c||{},u=c||{},d=u.model_type||u.architectures?.[0]||null,f=l.hidden_size||l.dim||0,p=l.num_hidden_layers||l.n_layers||0,m=l.num_attention_heads||l.n_heads||0,h=l.num_key_value_heads??m,g=l.vocab_size||0,_=l.max_position_embeddings||0,v=l.intermediate_size||0,y=l.head_dim||l.v_head_dim||(m>0&&f>0&&Number.isInteger(f/m)?f/m:0),b=l.kv_lora_rank||0,x=l.qk_rope_head_dim||0,S=b>0,C=u.quantization||u.quantization_config||null,w=C?.bits||null,T=C?.group_size||null,E=l.dtype||u.torch_dtype||(w?`${w}bit`:null),D={repoId:e,revision:t,modelBytes:s,arch:d,hiddenSize:f,numLayers:p,numHeads:m,numKvHeads:h,headDim:y,vocabSize:g,maxCtx:_,intermediateSize:v,quantBits:w,quantGroupSize:T,dtype:E,isMLA:S,kvLoraRank:b,qkRopeHeadDim:x,fileCount:o.length,config:c};return n&&await zr.write(i,`mlx-model-metadata`,D,n),D}function Br({numLayers:e,numKvHeads:t,headDim:n,contextLength:r,isMLA:i,kvLoraRank:a,qkRopeHeadDim:o}){return!e||!r?0:i&&a>0?e*(a+(o||0))*r*2:!t||!n?0:e*t*n*r*2*2}const Vr=async e=>{try{return await D(e),!0}catch{return!1}},Hr=(e,t,n={})=>new Promise((r,i)=>{he(e,t,{timeout:n.timeout||3e5,...n},(t,n,a)=>{if(t){let n=a?.toString().trim()||t.message;i(Error(`${e} failed: ${n}`))}else r({stdout:n?.toString()||``,stderr:a?.toString()||``})})}),Ur=new Map;async function Wr({envDir:e,mlxLmPackage:t,mlxVlmPackage:n,onProgress:r}){let i=M.resolve(e),a=Ur.get(i);if(a){let e=await a;return r?.(1),e}let o=Lne({envDir:i,mlxLmPackage:t,mlxVlmPackage:n,onProgress:r});Ur.set(i,o);try{return await o}finally{Ur.delete(i)}}const Gr=[3,10];async function Lne({envDir:e,mlxLmPackage:t,mlxVlmPackage:n,onProgress:r}){let i=M.join(e,`bin`,`python3`),a=M.join(e,`bin`,`pip`);if(await Vr(i))try{return await Hr(i,[`-c`,`import mlx_vlm; import torch`],{timeout:1e4}),r?.(1),i}catch{}if(!await Vr(i)){r?.(.1);try{let{stdout:e}=await Hr(`python3`,[`-c`,`import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")`],{timeout:5e3}),[t,n]=e.trim().split(`.`).map(Number);(t<Gr[0]||t===Gr[0]&&n<Gr[1])&&console.warn(`[mlx-llm] WARNING: System Python is ${t}.${n}, but mlx-vlm requires >= ${Gr.join(`.`)}. You may get an older mlx-vlm version with reduced functionality. Consider installing Python >= 3.10 (e.g. via Homebrew).`)}catch{}console.log(`[mlx-llm] Creating venv at ${e}`),await b(e,{recursive:!0}),await Hr(`python3`,[`-m`,`venv`,e],{timeout:6e4}),r?.(.3)}console.log(`[mlx-llm] Installing ${n}`),r?.(.4);let o=[`install`,t,n,`torch`,`torchvision`],s={...process.env};return await Hr(a,o,{timeout:6e5,env:s}),r?.(.9),await Hr(i,[`-c`,`import mlx_vlm; import torch; print(mlx_vlm.__version__)`],{timeout:15e3}),r?.(1),console.log(`[mlx-llm] mlx-vlm installed successfully`),i}var Rne=class{constructor(){this.process=null,this.pendingRequests=new Map,this.requestCounter=0,this.readyPromise=null,this.buffer=``}spawn(e){return this.process=_e(e,[Nne],{stdio:[`pipe`,`pipe`,`pipe`],env:{...process.env,PYTHONUNBUFFERED:`1`}}),this.process.stderr.on(`data`,e=>{let t=e.toString().trim();t&&console.log(t)}),this.process.on(`exit`,e=>{console.log(`[mlx-llm] Bridge process exited with code ${e}`);for(let[t,n]of this.pendingRequests)n.reject(Error(`Bridge process exited (code ${e})`)),this.pendingRequests.delete(t);this.process=null}),this.process.stdout.on(`data`,e=>{this.buffer+=e.toString();let t=this.buffer.split(`
|
|
2
|
+
import{n as e,t}from"./rolldown-runtime-dTnj95Mm.mjs";import{a as n,i as r,n as i,o as a,r as o,s,t as c}from"./config-DbRjQnNp.mjs";import{builtinModules as l,createRequire as u}from"node:module";import{node as d}from"@elysiajs/node";import{Elysia as f,file as p,sse as m,t as h}from"elysia";import*as g from"node:stream/web";import{ReadableStream as _}from"node:stream/web";import v,{lstat as y,mkdir as b,open as x,readFile as S,readdir as C,realpath as w,rename as T,rm as E,stat as D,unlink as O,writeFile as k}from"node:fs/promises";import ee,{createHash as A,randomBytes as te,randomUUID as j,timingSafeEqual as ne}from"node:crypto";import M from"node:path";import N from"node:os";import{gguf as re}from"@huggingface/gguf";import{getBackendDevicesInfo as P,isLibVariantAvailable as ie,loadModel as ae}from"@fugood/llama.node";import oe from"bytes";import{EventEmitter as se}from"node:events";import ce,{constants as le,createWriteStream as ue}from"node:fs";import{initParakeet as de,initWhisper as fe}from"@fugood/whisper.node";import{fileURLToPath as pe,pathToFileURL as me}from"node:url";import{execFile as he,execSync as ge,spawn as _e,spawnSync as ve}from"node:child_process";import ye from"fs";import be from"path";import xe from"url";import*as Se from"onnxruntime-node";import{listSupportedBackends as Ce}from"onnxruntime-node";import{Tensor as we}from"onnxruntime-common";import{Readable as Te}from"stream";import{pipeline as Ee}from"stream/promises";import De from"sharp";import{Buffer as Oe}from"buffer";import{ZodError as ke,z as F}from"zod";import{importSPKI as Ae,jwtVerify as je}from"jose";import Me from"ms";import Ne from"node:vm";import{moduleRunnerTransformSync as Pe,transformSync as Fe}from"oxc-transform";import Ie from"lodash";import eee from"moment";import*as tee from"mathjs";import nee from"voca";import ree from"chroma-js";import iee from"json5";import aee from"qs";import{nanoid as oee}from"nanoid";import see from"md5";import{Server as cee}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as lee,ListToolsRequestSchema as uee}from"@modelcontextprotocol/sdk/types.js";import{Readable as Le}from"node:stream";import{pipeline as Re}from"node:stream/promises";import{Buffer as ze}from"node:buffer";import Be from"node:dgram";import{Agent as dee,BACKGROUND_CONTEXT as Ve,FileError as fee,JsonlSessionRepo as pee,err as He,ok as Ue}from"@earendil-works/pi-agent-core";import{createProvider as mee}from"@earendil-works/pi-ai";import{builtinModels as hee}from"@earendil-works/pi-ai/providers/all";import{stream as gee,streamSimple as _ee}from"@earendil-works/pi-ai/api/openai-completions";import We from"@iarna/toml";import vee from"node:readline/promises";const Ge=1024**3,Ke=(e,t,n)=>Math.min(Math.max(e,t),n),qe=e=>e?40:0,Je=(e=0)=>{if(!e)return 0;let t=12*Ge;return Ke(e/t*20,0,20)},Ye=(e=0)=>{if(!e)return 0;let t=32*Ge;return Ke(e/t*10,0,10)},Xe=e=>e?10:0,Ze=(e=`default`,t=null)=>{let n=String(e).toLowerCase();return n?n.includes(`cuda`)?20:n.includes(`vulkan`)?10:n.includes(`default`)?t===`darwin`||t===`ios`?15:5:0:0},Qe=({platform:e,variant:t,hasGpu:n,gpuUsableBytes:r=0,cpuUsableBytes:i=0,ok:a=!0}={})=>{if(!a)return 0;let o=qe(n)+Ze(t,e)+Je(r),s=Ye(i),c=Xe(a);return Math.min(100,Math.round(o+s+c))},$e=e=>e?typeof e.score==`number`&&Number.isFinite(e.score)?Number(e.score):Qe(e):0,et=(...e)=>e.some(e=>e?.fitsInGpu||e?.fitsInCpu),tt=({clientScore:e,buttressScore:t,threshold:n=1.1,clientFitsInMemory:r=!1,buttressFitsInMemory:i=!1})=>r&&!i?{recommendation:`local`,reason:`client-fits-in-memory`}:i&&!r?{recommendation:`buttress`,reason:`buttress-fits-in-memory`}:e>t*n?{recommendation:`local`,reason:`client-better`}:t>e*n?{recommendation:`buttress`,reason:`buttress-better`}:{recommendation:`either`,reason:`comparable-scores`},nt=({platform:e,variant:t,hasGpu:n,gpuUsableBytes:r=0,cpuUsableBytes:i=0,ok:a=!0}={})=>({gpuPresence:qe(n),variant:Ze(t,e),gpuMemory:Je(r),cpuMemory:Ye(i),availability:Xe(a)}),yee=.85,bee=.5,rt=e=>!e&&e!==0?[]:Array.isArray(e)?e.filter(e=>e!=null):[e],it=({device:e,modelBytes:t=0,extraBytes:n=0}={})=>{let r=e?Math.max(0,Number(t)||0)+Math.max(0,Number(n)||0):t+n;if(!e)return{totalRequiredBytes:r,fitsInGpu:!1,fitsInCpu:!1,limiting:`unknown-device`};let i=e.hasGpu&&r>0&&r<=e.gpuUsableBytes,a=r>0&&r<=e.cpuUsableBytes,o=`ok`;return!i&&e.hasGpu&&(o=`gpu-memory`),a||(o=i?`cpu-memory`:`insufficient-memory`),{totalRequiredBytes:r,fitsInGpu:i,fitsInCpu:a,limiting:o}},xee=[`cuda`,`vulkan`,`snapdragon`,`default`],See=e=>e&&String(e).trim().toLowerCase()||null,Cee=({variant:e,preferVariants:t=[],variantPreference:n=[],defaultVariants:r=xee}={})=>{let i=[];e&&i.push(e),i.push(...rt(t)),i.push(...rt(n)),i.push(...r);let a=new Set;for(let e of i){let t=See(e);t&&a.add(t)}return Array.from(a)},wee=(e={})=>{let t=String(e.type||e.deviceType||e.kind||``).toLowerCase();return!!(t===`accel`||t.includes(`gpu`)||t.includes(`cuda`)||t.includes(`metal`)||t.includes(`vulkan`)||t.includes(`snapdragon`))},Tee=e=>Array.isArray(e)?e.map(e=>({...e})):[],Eee=(e,t)=>e===`snapdragon`?t.filter(e=>e.deviceName!==`GPUOpenCL`):t,Dee=({platform:e,totalMemoryInBytes:t,variant:n,devices:r,gpuMemoryFraction:i,cpuMemoryFraction:a,ok:o,error:s})=>{let c=Tee(Eee(n,r)),l=c.some(wee),u=c.filter(e=>wee(e)&&Number.isFinite(Number(e.maxMemorySize))).reduce((e,t)=>e+t.maxMemorySize,0),d=t,f=l?Math.floor(u*i):0,p=d?Math.floor(d*a):0,m={platform:e,variant:n,hasGpu:l,gpuUsableBytes:f,cpuUsableBytes:p,ok:o};return{platform:e,ok:o,variant:n,hasGpu:l,devices:c,gpuTotalBytes:u,gpuUsableBytes:f,cpuTotalBytes:d,cpuUsableBytes:p,score:Qe(m),breakdown:o?nt(m):null,error:s,timestamp:new Date().toISOString()}},Oee=({device:e,modelBytes:t=0,kvCacheBytes:n=0}={})=>it({device:e,modelBytes:t,extraBytes:n}),kee=async({platform:e,variant:t=null,preferVariants:n=[],variantPreference:r=[],gpuMemoryFraction:i=yee,cpuMemoryFraction:a=bee,includeBreakdown:o=!1,totalMemoryInBytes:s,modelBytes:c=null,kvCacheBytes:l=null,limitedKvCacheBytes:u=null,dependencies:d={},defaultVariants:f=xee}={})=>{let{getBackendDevicesInfo:p,isLibVariantAvailable:m}=d;if(typeof p!=`function`||typeof m!=`function`)throw TypeError(`GGML capability detection requires getBackendDevicesInfo and isLibVariantAvailable functions`);let h=Cee({variant:t,preferVariants:n,variantPreference:r,defaultVariants:f}),g=[];for(let t of h)try{if(!await m(t))throw Error(`Variant ${t} not available on this platform`);let n=await p(t);g.push(Dee({platform:e,totalMemoryInBytes:s,variant:t,devices:n,gpuMemoryFraction:i,cpuMemoryFraction:a,ok:!0}))}catch(n){let r=n instanceof Error?n.message:String(n);g.push(Dee({platform:e,totalMemoryInBytes:s,variant:t,devices:[],gpuMemoryFraction:i,cpuMemoryFraction:a,ok:!1,error:r}))}let _=g.filter(e=>e.ok)[0]||null,v={ok:!!_,selected:_?{..._,breakdown:o?_.breakdown:void 0}:null,attempts:g};if(!o&&v.selected&&delete v.selected.breakdown,!v||!c&&!l)return v;let y=e=>{if(!e)return e;let t=Oee({device:e,modelBytes:c||0,kvCacheBytes:l||0}),n=null;return u!=null&&u!==l&&(n=Oee({device:e,modelBytes:c||0,kvCacheBytes:u})),{...e,fit:t,...n&&{limitedFit:n}}};return v.selected=y(v.selected),v.attempts=Array.isArray(v.attempts)?v.attempts.map(y):v.attempts,v},Aee=`ggml-llm`,jee=async({platform:e,variant:t,preferVariants:n,variantPreference:r=[],gpuMemoryFraction:i,cpuMemoryFraction:a,includeBreakdown:o,totalMemoryInBytes:s,modelBytes:c,processingBytes:l=null,kvCacheBytes:u=null,dependencies:d}={},f)=>kee({platform:e,variant:t,preferVariants:n,variantPreference:r&&r.length>0?r:f,gpuMemoryFraction:i,cpuMemoryFraction:a,includeBreakdown:o,totalMemoryInBytes:s,modelBytes:c,kvCacheBytes:l??u,dependencies:d,defaultVariants:f}),Mee=[`cuda`,`vulkan`,`snapdragon`,`default`],Nee=async(e={})=>jee(e,Mee),Pee=[`cuda`,`vulkan`,`default`],Fee=async(e={})=>jee(e,Pee),at=async({platform:e,arch:t=null,unifiedMemoryFraction:n=.85,includeBreakdown:r=!1,totalMemoryInBytes:i,modelBytes:a=null,kvCacheBytes:o=null,limitedKvCacheBytes:s=null}={})=>{let c=[];e!==`darwin`&&c.push(`MLX requires macOS`),t&&t!==`arm64`&&c.push(`MLX requires Apple Silicon (arm64)`);let l=c.length===0,u=l?Math.floor(i*n):0,d={platform:e,variant:`mlx`,hasGpu:l,gpuUsableBytes:u,cpuUsableBytes:u,ok:l},f=Qe(d),p=l?nt(d):null,m={platform:e,ok:l,variant:`mlx`,hasGpu:l,unifiedMemory:!0,devices:l?[{type:`metal`,deviceName:`Apple Silicon (Unified Memory)`,maxMemorySize:i}]:[],gpuTotalBytes:l?i:0,gpuUsableBytes:u,cpuTotalBytes:i,cpuUsableBytes:u,score:f,breakdown:r?p:void 0,error:l?void 0:c.join(`; `),timestamp:new Date().toISOString()};r||delete m.breakdown;let h={ok:l,selected:l?m:null,attempts:[m],errors:l?[]:c};if(!a&&!o)return h;let g=e=>{if(!e)return e;let t=it({device:e,modelBytes:a||0,extraBytes:o||0}),n=null;return s!=null&&s!==o&&(n=it({device:e,modelBytes:a||0,extraBytes:s})),{...e,fit:t,...n&&{limitedFit:n}}};return h.selected=g(h.selected),h.attempts=h.attempts.map(g),h},Iee=[`cuda`,`coreml`,`qnn`,`dml`,`webgpu`,`cpu`],ot={cuda:100,coreml:90,qnn:80,dml:80,webgpu:70,cpu:10},st=e=>e&&String(e).trim().toLowerCase()||null,Lee=({provider:e,preferProviders:t=[],providerPreference:n=[]}={})=>{let r=[];e&&r.push(e),r.push(...rt(t)),r.push(...rt(n)),r.push(...Iee);let i=r.map(st).filter(Boolean);return Array.from(new Set(i))},Ree=new Set([`cuda`,`coreml`,`dml`,`webgpu`]),zee=(e=``)=>Ree.has(String(e).toLowerCase()),Bee=e=>Array.isArray(e)?e.map(e=>typeof e==`string`?{name:e,available:!0}:{name:e.name,available:!0}):[],ct=({platform:e,totalMemoryInBytes:t,provider:n,available:r,gpuMemoryFraction:i,cpuMemoryFraction:a,ok:o,error:s})=>{let c=zee(n),l=0;c&&r&&(n===`cuda`?l=8*1024*1024*1024:n===`coreml`?l=Math.floor(t*.5):n===`dml`&&(l=6*1024*1024*1024));let u=t,d=c?Math.floor(l*i):0,f=u?Math.floor(u*a):0,p={platform:e,variant:n,hasGpu:c,gpuUsableBytes:d,cpuUsableBytes:f,ok:o},m=Qe(p),h=o?nt(p):null;return{platform:e,ok:o,provider:n,hasGpu:c,available:r,gpuTotalBytes:l,gpuUsableBytes:d,cpuTotalBytes:u,cpuUsableBytes:f,score:m,breakdown:h,error:s,timestamp:new Date().toISOString()}},Vee=({device:e,modelBytes:t=0,workingMemory:n=0}={})=>it({device:e,modelBytes:t,extraBytes:n}),lt=async({platform:e,provider:t=null,preferProviders:n=[],providerPreference:r=[],gpuMemoryFraction:i=yee,cpuMemoryFraction:a=bee,includeBreakdown:o=!1,totalMemoryInBytes:s,modelBytes:c=null,workingMemory:l=null,dependencies:u={}}={})=>{let{listSupportedBackends:d}=u;if(typeof d!=`function`)throw TypeError(`ONNX capability detection requires listSupportedBackends function`);let f=Lee({provider:t,preferProviders:n,providerPreference:r}),p=[],m=[];try{let e=await d();m=Bee(e)}catch{m=f.map(e=>({name:e,available:!1}))}let h=new Set(m.filter(e=>e.available).map(e=>e.name.toLowerCase()));for(let t of f){if(!h.has(t)){p.push(ct({platform:e,totalMemoryInBytes:s,provider:t,available:!1,gpuMemoryFraction:i,cpuMemoryFraction:a,ok:!1,error:`Provider ${t} not available on this platform`}));continue}p.push(ct({platform:e,totalMemoryInBytes:s,provider:t,available:!0,gpuMemoryFraction:i,cpuMemoryFraction:a,ok:!0}))}let g=p.filter(e=>e.ok),_=(t?g.find(e=>e.provider===st(t)):null)||g.find(e=>e.hasGpu)||g.sort((e,t)=>{let n=ot[e.provider]||0;return(ot[t.provider]||0)-n})[0]||null,v=[],y=[t,...n].filter(Boolean).map(st);for(let e of y)e&&!h.has(e)&&v.push(`Requested provider "${e}" is not available (installed: ${[...h].join(`, `)||`none`})`);let b={ok:!!_,selected:_?{..._,breakdown:o?_.breakdown:void 0}:null,attempts:p,warnings:v};if(!o&&b.selected&&delete b.selected.breakdown,!b||!c&&!l)return b;let x=e=>{if(!e)return e;let t=Vee({device:e,modelBytes:c||0,workingMemory:l||0});return{...e,fit:t}};return b.selected=x(b.selected),b.attempts=Array.isArray(b.attempts)?b.attempts.map(x):b.attempts,b},ut=`onnx-stt`,dt=`onnx-tts`,Hee=new Map([[Aee,kee],[`ggml-stt`,Nee],[`ggml-tts`,Fee],[`mlx-llm`,at],[ut,lt],[dt,lt]]),ft=async({platform:e,totalMemoryInBytes:t,backend:n=Aee,dependencies:r,...i}={})=>{let a=Hee.get(n);if(!a)throw Error(`No capability detector registered for backend "${n}"`);return await a({...i,dependencies:r,totalMemoryInBytes:t,platform:e})},pt={f16:2,f32:4,q8_0:1,q6_k:.75,q5_k:.625,q5_k_m:.625,q5_k_s:.625,q5_1:.625,q5_0:.625,q4_k:.5,q4_k_m:.5,q4_k_s:.5,q4_1:.5,q4_0:.5,iq4_nl:.5},mt=e=>{let t=e?String(e).toLowerCase():`f16`;return pt[t]||pt.f16},Uee=(e,t,n,r,i,a={},{totalLayers:o=null,swaLayers:s=0,swaContext:c=null,swaContextMultiplier:l=1,swaAdditionalTokens:u=0,swaFull:d=!1}={})=>{if(!e||!t||!n||!r||!i)return 0;let f=Number(o!=null&&o!==void 0?o:e),p=Math.max(0,Math.floor(f));if(!p)return 0;let m=mt(a.k),h=mt(a.v),g=Number(n)*(Number(r)*m+Number(i)*h);if(!g)return 0;let _=Math.max(0,Number(t)||0),v=Math.min(p,Math.max(0,Math.floor(Number(s)||0))),y=Math.max(0,p-v),b=c!=null&&Number.isFinite(Number(c))?Math.max(0,Number(c)):_,x=Math.max(1,Number(l)||1),S=Math.max(0,Number(u)||0),C=b*x+S,w=d?_:Math.min(_,C),T=y*_+v*Math.max(0,Math.floor(w));return Math.round(g*T)},Wee=({modelBytes:e=0,audioLengthSeconds:t=30,sampleRate:n=16e3,bytesPerSample:r=4}={})=>{let i=Math.max(0,Number(e)||0),a=Math.max(0,Math.floor(Math.max(0,t)*n*r)),o=1024*1024,s=1024*o,c;c=i<200*o?120*o:i<500*o?140*o:i<2*s?150*o:160*o;let l;l=i<200*o?70*o:i<500*o?135*o:220*o;let u;u=i<100*o?20*o:i<200*o?30*o:i<500*o?85*o:i<2*s?215*o:360*o;let d=c+l+u;return{modelBytes:i,audioBufferBytes:a,processingBufferBytes:d,totalBytes:i+d+a}},Gee=({modelBytes:e=0,audioLengthSeconds:t=30,sampleRate:n=16e3,bytesPerSample:r=4}={})=>{let i=Math.max(0,Number(e)||0),a=Math.max(0,Math.floor(Math.max(0,t)*n*r)),o=640*1048576;return{modelBytes:i,audioBufferBytes:a,processingBufferBytes:o,totalBytes:i+o+a}},ht=({modelBytes:e=0,vocoderBytes:t=0,contextSize:n=8192,vocoderBatchSize:r=4096}={})=>{let i=Math.max(0,Number(e)||0),a=Math.max(0,Number(t)||0),o=Math.max(0,Number(n)||0),s=Math.max(0,Number(r)||0),c=o*98304,l=s*24576,u=Math.max(100663296,c+l);return{modelBytes:i+a,backboneBytes:i,vocoderBytes:a,kvCacheBytes:c,codecBufferBytes:l,processingBufferBytes:u,totalBytes:i+a+u}},gt=e=>e?String(e).trim().toLowerCase():null,Kee=(e={},t=null)=>{if(!e)return null;let n=gt(t),r=n?`${n}.attention.sliding_window`:null,i=(r&&e[r]!=null?e[r]:null)??e[`llama.attention.sliding_window`];if(i==null)return null;let a=Number(i);return Number.isFinite(a)?a:null},qee=(e=0,t=0,n=!1)=>{let r=Math.max(0,Math.floor(Number(e)||0)),i=Math.max(0,Math.floor(Number(t)||0));if(!r||i===1)return 0;if(i<=0)return r;let a=Math.max(0,i-1),o=Math.floor(r/i),s=r%i,c=n?Math.max(0,s-1):Math.min(s,a);return o*a+c},_t=({arch:e,nLayer:t=0})=>({arch:gt(e),enabled:!1,window:null,pattern:null,denseFirst:!1,type:null,kvLayers:Math.max(0,Math.floor(Number(t)||0)),swaLayers:0}),Jee=new Map([[`llama4`,({nSwa:e})=>e===0?{enabled:!1}:{enabled:!0,window:e&&e>0?e:8192,pattern:4,type:`chunked`}],[`afmoe`,({nSwa:e})=>!e||e<=0?{enabled:!1}:{enabled:!0,window:e,pattern:4,type:`standard`}],[`phi3`,()=>({enabled:!1})],[`gemma2`,({nSwa:e})=>{let t=e&&e>0?e:4096;return t?{enabled:!0,window:t,pattern:2,type:`standard`}:{enabled:!1}}],[`gemma3`,({nSwa:e})=>!e||e<=0?{enabled:!1}:{enabled:!0,window:e,pattern:6,type:`standard`}],[`gemma3n`,({nLayer:e,nSwa:t})=>!t||t<=0?{enabled:!1}:{enabled:!0,window:t,pattern:5,type:`standard`,kvLayers:Math.min(20,e)}],[`gemma-embedding`,({nSwa:e})=>!e||e<=0?{enabled:!1}:{enabled:!0,window:e,pattern:6,type:`symmetric`}],[`cohere2`,({nSwa:e})=>!e||e<=0?{enabled:!1}:{enabled:!0,window:e,pattern:4,type:`standard`}],[`olmo2`,({nSwa:e})=>!e||e<=0?{enabled:!1}:{enabled:!0,window:e,pattern:4,type:`standard`}],[`exaone4`,({nLayer:e,nSwa:t})=>{let n=e>=64,r=null;return t&&t>0?r=t:n&&(r=4096),r?{enabled:!0,window:r,pattern:4,type:`standard`}:{enabled:!1}}],[`gpt-oss`,({nSwa:e})=>!e||e<=0?{enabled:!1}:{enabled:!0,window:e,pattern:2,type:`standard`}],[`gemma4`,({nLayer:e,nSwa:t,metadata:n})=>{if(!t||t<=0)return{enabled:!1};let r=Number(n?.[`gemma4.attention.shared_kv_layers`])||0,i=Math.max(0,e-r),a=n?.[`gemma4.attention.sliding_window_pattern`];return Array.isArray(a)?{enabled:!0,window:t,type:`standard`,swaLayers:a.slice(0,i).filter(e=>Number(e)>0).length,kvLayers:i}:{enabled:!0,window:t,pattern:6,type:`standard`,kvLayers:i}}],[`smallthinker`,({nSwa:e})=>!e||e<=0?{enabled:!1}:{enabled:!0,window:4096,pattern:4,denseFirst:!0,type:`standard`}]]),vt=({arch:e,metadata:t={},nLayer:n=0}={})=>{let r=gt(e||t[`general.architecture`]),i=Math.max(0,Math.floor(Number(n)||0)),a=Kee(t,r),o=r?Jee.get(r):null;if(!o)return _t({arch:r,nLayer:n});let s=o({nLayer:i,nSwa:a,metadata:t});if(!s||!s.enabled||!s.window||s.window<=0)return _t({arch:r,nLayer:n});let c=Math.max(0,Math.floor(Number(s.pattern)||0)),l=s.kvLayers!=null&&Number.isFinite(Number(s.kvLayers))?Number(s.kvLayers):i,u=Math.max(0,Math.floor(l)),d=s.swaLayers!=null&&Number.isFinite(Number(s.swaLayers))?Math.max(0,Math.floor(Number(s.swaLayers))):qee(u,c,!!s.denseFirst);return{arch:r,enabled:d>0,window:s.window,pattern:c,denseFirst:!!s.denseFirst,type:s.type||`standard`,kvLayers:u,swaLayers:d}},Yee=new Set([`mamba`,`mamba2`,`rwkv6`,`rwkv6qwen2`,`rwkv7`,`arwkv7`]),Xee=new Set([`jamba`,`falcon-h1`,`plamo2`,`granitehybrid`,`lfm2`,`lfm2moe`,`nemotron_h`,`nemotron_h_moe`,`qwen3next`]),yt=e=>e?String(e).trim().toLowerCase():null,Zee=e=>{let t=yt(e);return t?Yee.has(t):!1},Qee=e=>{let t=yt(e);return t?Xee.has(t):!1},bt=e=>Zee(e)?`recurrent`:Qee(e)?`hybrid`:`transformer`,xt=(e={})=>{let t=e[`general.architecture`],n=(t,n=null)=>{let r=e[t],i=Number(r);return Number.isFinite(i)?i:n},r=(t,n=null)=>{let r=e[t];if(Array.isArray(r))return r;let i=Number(r);return Number.isFinite(i)?i:n},i=t?n(`${t}.context_length`,n(`llama.context_length`)):null,a=t?n(`${t}.block_count`,n(`llama.block_count`)):null,o=t?n(`${t}.embedding_length`,n(`llama.embedding_length`)):null,s=t?n(`${t}.attention.head_count`,n(`llama.attention.head_count`)):null,c=t?r(`${t}.attention.head_count_kv`,r(`llama.attention.head_count_kv`,s)):null,l=null,u=null;if(Array.isArray(c)){let e=c.filter(e=>Number(e)>0);e.length>0?(l=Math.max(...e.map(Number)),u=e.length):(l=0,u=0)}else l=c;let d=t?n(`${t}.attention.key_length`,n(`llama.attention.key_length`)):null,f=t?n(`${t}.attention.value_length`,n(`llama.attention.value_length`)):null,p=e[`general.quantization_version`]||null,m=e[`general.file_type`]||null,h=t?n(`${t}.ssm.conv_kernel`):null,g=t?n(`${t}.ssm.state_size`):null,_=t?n(`${t}.ssm.inner_size`):null,v=t?n(`${t}.ssm.group_count`):null,y=t?n(`${t}.ssm.time_step_rank`):null,b=t?n(`${t}.rwkv.head_size`):null,x=t?n(`${t}.rwkv.token_shift_count`,2):null,S=t?n(`${t}.attention.shared_kv_layers`,0):0,C=u!=null&&a!=null?a-u:null;return{arch:t,nCtxTrain:i,nLayer:a,nEmbd:o,nHead:s,nHeadKv:l,nEmbdHeadK:d,nEmbdHeadV:f,quantVersion:p,fileType:m,attentionLayerCount:u,recurrentLayerCount:C,ssmDConv:h,ssmDState:g,ssmDInner:_,ssmNGroup:v,ssmDtRank:y,rwkvHeadSize:b,rwkvTokenShiftCount:x,sharedKvLayers:S}},St=({layerCount:e,headKvCount:t,embdHeadKCount:n,embdHeadVCount:r,cacheTypes:i,swaConfig:a,kvUnified:o=!1,nParallel:s=1,swaFull:c=!1,arch:l=null,attentionLayerCount:u=null})=>{let d=bt(l);if(d===`recurrent`)return()=>0;let f=d===`hybrid`&&u!=null?Math.max(0,Math.floor(Number(u)||0)):e,p=a?.window&&o?Math.max(1,Number(s)||1):1,m=o?1:Math.max(1,Number(s)||1);return e=>Uee(f,e,t,n,r,i,{totalLayers:f,swaLayers:a?.swaLayers||0,swaContext:a?.window,swaFull:c,swaContextMultiplier:p})*m},Ct=({nLayer:e,nEmbd:t,recurrentLayerCount:n=null,nSeqMax:r=1,ssmDConv:i=null,ssmDState:a=null,ssmDInner:o=null,ssmNGroup:s=null,ssmDtRank:c=null,rwkvHeadSize:l=null,rwkvTokenShiftCount:u=2,arch:d=null})=>{if(bt(d)===`transformer`)return 0;let f=n==null?Math.max(0,Math.floor(Number(e)||0)):Math.max(0,Math.floor(Number(n)||0));if(f===0)return 0;let p=Math.max(1,Math.floor(Number(r)||1)),m=0,h=0;if(l!=null&&l>0&&t!=null&&t>0)m=Math.max(1,Number(u)||2)*t,h=t*l;else if(a!=null&&o!=null){let e=Math.max(0,Number(i)||0),t=Math.max(0,Number(a)||0),n=Math.max(0,Number(o)||0),r=Math.max(1,Number(s)||1);Math.max(0,Number(c)||0)>0?(m=e>0?(e-1)*2*r*t:0,h=Math.floor(t*n/2)):(m=e>0?(e-1)*(n+2*r*t):0,h=t*n)}else return 0;let g=(m+h)*p*f*4;return Math.max(0,g)},wt=({maxCtx:e,availableMemory:t,modelBytes:n,kvBytesForCtx:r})=>{let i=Math.max(1,Math.floor(Number(e)||0));if(!r||t<=n)return i;let a=1,o=i,s=i;for(;a<=o;){let e=Math.floor((a+o)/2);n+r(e)<=t?(s=e,a=e+1):o=e-1}return s},$ee={fp32:``,fp16:`_fp16`,int8:`_int8`,uint8:`_uint8`,q8:`_quantized`,q4:`_q4`,q4f16:`_q4f16`,bnb4:`_bnb4`},Tt={cuda:2,coreml:1.5,dml:1.8,webgpu:2,qnn:1.5,cpu:1.3},ete={whisper:[`encoder_model`,`decoder_model_merged`],speech_to_text:[`encoder_model`,`decoder_model_merged`],speecht5:[`encoder_model`,`decoder_model_merged`],vits:[`model`],style_text_to_speech_2:[`model`],bert_vits2:[`model`],chatterbox:[`embed_tokens`,`language_model`,`speech_encoder`,`conditional_decoder`],llama:[`model`],gpt2:[`model`],qwen2:[`model`],phi:[`model`],mistral:[`model`],gemma:[`model`]},tte=[`model`],nte=(e,t,n)=>{if(typeof t==`object`&&t){let n=t[e];if(typeof n==`string`&&n!==`auto`)return n}else if(typeof t==`string`&&t!==`auto`)return t;let r=n?.dtype;if(typeof r==`object`&&r){let t=r[e];if(typeof t==`string`&&t!==`auto`)return t}else if(typeof r==`string`&&r!==`auto`)return r;return`fp32`},rte=e=>ete[e]||tte,Et=({siblings:e,modelType:t,dtype:n,tjConfig:r,subfolder:i=`onnx`})=>{let a=rte(t),o=[],s=[],c=0,l=new Map(e.map(e=>[e.rfilename,e]));for(let e of a){let t=nte(e,n,r),a=`${i}/${e}${$ee[t]??``}.onnx`,u=`${a}_data`,d=l.get(a),f=l.get(u);if(!d){o.push(`File not found: ${e} (dtype=${t})`),s.push({name:e,dtype:t,bytes:0});continue}let p=(d.size||0)+(f?.size||0);s.push({name:e,dtype:t,bytes:p,onnxPath:a,dataPath:f?u:null}),c+=p}return{totalBytes:c,files:s,warnings:o}},Dt=(e,t=`cpu`)=>{let n=Tt[t]||Tt.cpu;return Math.ceil(e*n)},Ot=new se;Ot.setMaxListeners(100);const kt=()=>{let e=[];return Object.defineProperties(e,{start:{value:0,writable:!0},count:{value:0,writable:!0}}),e},At=(e,t,n)=>{if(n<=0)return;let r={...t,timestamp:t.timestamp||new Date().toISOString()};if(e.count<n){e.push(r),e.count+=1;return}e[e.start]=r,e.start=(e.start+1)%n},jt=e=>{let t=[];for(let n=0;n<e.count;n+=1){let r=(e.start+e.count-1-n)%e.length;t.push(e[r])}return t},Mt=e=>{e.length=0,e.start=0,e.count=0};var Nt=class{constructor(e=9999){this.maxEntries=e,this.modelLoads=kt(),this.completions=kt(),this.transcriptions=kt()}addModelLoad(e){At(this.modelLoads,e,this.maxEntries),Ot.emit(`status:modelLoad`,e),Ot.emit(`status:change`,{type:`modelLoad`,entry:e})}addCompletion(e){At(this.completions,e,this.maxEntries),Ot.emit(`status:completion`,e),Ot.emit(`status:change`,{type:`completion`,entry:e})}addTranscription(e){At(this.transcriptions,e,this.maxEntries),Ot.emit(`status:transcription`,e),Ot.emit(`status:change`,{type:`transcription`,entry:e})}getModelLoadHistory(){return jt(this.modelLoads)}getCompletionHistory(){return jt(this.completions)}getTranscriptionHistory(){return jt(this.transcriptions)}clear(){Mt(this.modelLoads),Mt(this.completions),Mt(this.transcriptions)}};const Pt=new Nt,Ft=new Nt,It=new Nt,Lt=new Nt,Rt=new Nt;let zt=0;function Bt(e){let t=t=>e(t);return Ot.on(`status:change`,t),()=>Ot.off(`status:change`,t)}function ite(e){return zt+=1,{subscriberId:zt,unsubscribe:Bt(e)}}function Vt(e){let t=[];return{generators:Array.from(e.entries()).filter(([,e])=>e.type===`ggml-llm`).map(([e,n])=>{let{instance:r}=n,i=[];return r.contexts&&(i=Array.from(r.contexts.entries()).map(([n,r])=>{let i={key:n,refCount:r.refCount,hasModel:!!r.context};if(r.context){let a=r.context.parallel.getStatus();i.parallelStatus=a,t.push({generatorId:e,contextKey:n,...a})}return i})),{id:e,type:n.type,refCount:n.refCount,repoId:r.info?.model?.repoId||null,quantization:r.info?.model?.quantization||null,variant:r.info?.runtime?.variant||null,nCtx:r.info?.runtime?.n_ctx||null,nParallel:r.info?.runtime?.n_parallel||null,contexts:i}}),parallelStatuses:t,history:{modelLoads:Pt.getModelLoadHistory().filter(e=>e.variant!==`mlx`),completions:Pt.getCompletionHistory().filter(e=>e.variant!==`mlx`)}}}function Ht(e){return{generators:Array.from(e.entries()).filter(([,e])=>e.type===`ggml-stt`).map(([e,t])=>{let{instance:n}=t,r=n.getStatus?.()||{},i=r.queueStatus||{processing:!1,queuedCount:0};return{id:e,type:t.type,refCount:t.refCount,repoId:n.info?.model?.repoId||null,quantization:n.info?.model?.quantization||null,modelType:n.info?.model?.modelType||null,variant:n.info?.runtime?.variant||null,hasContext:r.hasContext||!1,contextRefCount:r.contextRefCount||0,queueStatus:i}}),history:{modelLoads:Ft.getModelLoadHistory(),transcriptions:Ft.getTranscriptionHistory()}}}function Ut(e){return{generators:Array.from(e.entries()).filter(([,e])=>e.type===`mlx-llm`).map(([e,t])=>{let{instance:n}=t,r=n.getStatus?.()||{};return{id:e,type:t.type,refCount:t.refCount,repoId:r.repoId||n.info?.model?.repoId||null,variant:r.variant||`mlx`,contexts:r.contexts||[]}}),history:{modelLoads:Pt.getModelLoadHistory().filter(e=>e.variant===`mlx`),completions:Pt.getCompletionHistory().filter(e=>e.variant===`mlx`)}}}function ate(e){return{generators:Array.from(e.entries()).filter(([,e])=>e.type===`onnx-stt`).map(([e,t])=>{let{instance:n}=t;return{id:e,type:t.type,refCount:t.refCount,repoId:n.info?.model?.repoId||null,dtype:n.info?.model?.dtype||null,provider:n.info?.runtime?.provider||null,device:n.info?.runtime?.device||null,modelBytes:n.info?.model?.modelBytes||0,pipelines:n.getStatus?.()?.pipelineCount??0}}),history:{modelLoads:Lt.getModelLoadHistory(),transcriptions:Lt.getTranscriptionHistory()}}}function Wt(e){return{generators:Array.from(e.entries()).filter(([,e])=>e.type===`ggml-tts`).map(([e,t])=>{let{instance:n}=t;return{id:e,type:t.type,refCount:t.refCount,repoId:n.info?.model?.repoId||null,quantization:n.info?.model?.quantization||null,vocoderRepoId:n.info?.model?.vocoderRepoId||null,family:n.getStatus?.()?.family||null,variant:n.info?.runtime?.variant||null,useGpu:n.info?.runtime?.use_gpu||!1,modelBytes:n.info?.resources?.modelBytes||0,hasContext:n.getStatus?.()?.hasContext??!1}}),history:{modelLoads:It.getModelLoadHistory(),syntheses:It.getTranscriptionHistory()}}}function ote(e){return{generators:Array.from(e.entries()).filter(([,e])=>e.type===`onnx-tts`).map(([e,t])=>{let{instance:n}=t;return{id:e,type:t.type,refCount:t.refCount,repoId:n.info?.model?.repoId||null,dtype:n.info?.model?.dtype||null,provider:n.info?.runtime?.provider||null,device:n.info?.runtime?.device||null,modelBytes:n.info?.model?.modelBytes||0,vocoderRepoId:n.info?.model?.vocoderRepoId||null,pipelines:n.getStatus?.()?.pipelineCount??0}}),history:{modelLoads:Rt.getModelLoadHistory(),syntheses:Rt.getTranscriptionHistory()}}}function ste(e){return{timestamp:new Date().toISOString(),ggmlLlm:Vt(e),ggmlStt:Ht(e),mlxLlm:Ut(e),onnxStt:ate(e),onnxTts:ote(e),ggmlTts:Wt(e)}}const Gt=e=>new Date(e.lastAccessedAt).getTime();async function Kt({entries:e,totalSize:t,maxEntries:n,maxSizeBytes:r,removeEntry:i,getEntrySize:a=e=>e.fileSize||0}){let o=Object.values(e||{}),s=o.length,c=t||0;if(s<=n&&c<=r)return{evictedEntries:[],totalSize:c};o.sort((e,t)=>Gt(e)-Gt(t));let l=[];for(let t of o){if(s<=n&&c<=r)break;await i(t),c-=a(t),--s,delete e[t.id],l.push(t)}return{evictedEntries:l,totalSize:Math.max(0,c)}}const qt=(e={},t={})=>(Object.entries(t||{}).forEach(([t,n])=>{n&&typeof n==`object`&&!Array.isArray(n)?((!e[t]||typeof e[t]!=`object`)&&(e[t]={}),qt(e[t],n)):e[t]=n}),e),Jt=e=>e==null?void 0:Math.min(1,Math.max(0,Number(e))),Yt=(e,t=[])=>!e&&e!==0?[...t]:Array.isArray(e)?e.filter(e=>e!=null):[e],Xt=(e,t)=>{let n=t?t instanceof Set?t:new Set(t):null;return Array.from(new Set(Yt(e).flatMap(e=>{let t=e?String(e).toLowerCase():null;return t&&(!n||n.has(t))?[t]:[]})))},Zt=e=>{let t=new Set(e);return{normalizeVariants:e=>Xt(e,t),sanitizeVariant:e=>{if(!e)return null;let n=String(e).toLowerCase();return t.has(n)?n:null}}},cte=globalThis.WritableStream||g.WritableStream,Qt=async e=>{await b(e,{recursive:!0})},$t=e=>e===`..`||e.startsWith(`..${M.sep}`)||M.isAbsolute(e),lte=(e,t)=>{if(typeof e!=`string`||e.length===0)throw Error(`Invalid model cache path: ${t} must be a non-empty relative path`);let n=e.replaceAll(`\\`,`/`);if(M.posix.isAbsolute(n)||M.win32.parse(e).root)throw Error(`Invalid model cache path: ${t} must be relative`);let r=n.split(`/`);if(r.some(e=>!e||e===`.`||e===`..`))throw Error(`Invalid model cache path: ${t} must not contain empty, "." or ".." segments`);return r},en=(e,t,n)=>{let r=M.resolve(e),i=t.flatMap(([e,t])=>lte(e,`${n} ${t}`)),a=M.resolve(r,...i),o=M.relative(r,a);if(!o||$t(o))throw Error(`Invalid model cache path: ${n} escapes the configured cache root`);return a},tn=(e,t,n)=>en(e,[[t.repoId,`repository`],[t.revision,`revision`],[t.filename,`filename`]],n),ute=async e=>{let t;try{t=await y(e)}catch(n){if(n?.code!==`ENOENT`)throw n;try{await b(e)}catch(e){if(e?.code!==`EEXIST`)throw e}t=await y(e)}if(t.isSymbolicLink()||!t.isDirectory())throw Error(`Unsafe download destination: cache path contains a non-directory or symlink`)},nn=async(e,t)=>{let n=M.resolve(t),r=M.resolve(e),i=M.relative(n,r);if(!i||$t(i))throw Error(`Unsafe download destination: path escapes the allowed root`);await Qt(n);let a=await w(n),o=i.split(M.sep),s=a;for(let e of o.slice(0,-1))s=M.join(s,e),await ute(s);let c=M.join(a,...o);try{if((await y(c)).isSymbolicLink())throw Error(`Unsafe download destination: target is a symlink`)}catch(e){if(e?.code!==`ENOENT`)throw e}return r},rn=async(e,t)=>{try{let n=await D(e);return!t||n.size===t}catch{return!1}},an=async(e,t={})=>{if(typeof fetch!=`function`)throw Error(`Global fetch is not available in this runtime`);let n=await fetch(e,t);if(!n.ok){let t=await n.text().catch(()=>``);throw Error(`Failed to fetch ${e}: ${n.status} ${n.statusText} ${t}`.trim())}return n.json()},on=async(e,t={})=>{if(typeof fetch!=`function`)throw Error(`Global fetch is not available in this runtime`);let n=await fetch(e,{...t,method:`HEAD`});if(!n.ok)throw Error(`Failed to fetch headers for ${e}: ${n.status} ${n.statusText}`);return n},sn=async(e,t)=>{t&&await t.close().catch(()=>{}),await O(e).catch(()=>{})},cn=async(e,t,n,r,i,{allowedRoot:a}={})=>{if(typeof fetch!=`function`)throw Error(`Global fetch is not available in this runtime`);let o=a?await nn(n,a):n;a||await Qt(M.dirname(o));let s=await fetch(e,{headers:t});if(!s.ok||!s.body)throw Error(`Failed to download ${e}: ${s.status} ${s.statusText}`);let c=await x(o,a?le.O_WRONLY|le.O_CREAT|le.O_TRUNC|(le.O_NOFOLLOW||0):`w`),l=Number(s.headers.get(`content-length`))||r||0,u=0,d=.05;try{await s.body.pipeTo(new cte({async write(e){if(await c.write(e),u+=e.byteLength,typeof i==`function`&&l>0){let e=Math.min(1,u/l);for(;e>=d;)i(d),d+=.05}},async close(){await c.close(),typeof i==`function`&&i(1)},async abort(e){throw await sn(o,c),e}}))}catch(e){throw await sn(o,c),e}if(r){let e=await D(o);if(e.size!==r)throw await sn(o),Error(`Downloaded file size mismatch, expected ${r} got ${e.size}`)}},dte=(e,t,n)=>{let r=A(`sha256`).update(n).digest(`hex`);return M.join(e,`.metadata-cache`,t,`${r}.json`)},ln=({defaultBaseDir:e,replacer:t,reviver:n,onRead:r,onWrite:i,onWriteError:a}={})=>({read:async(t,i,a=e)=>{try{let e=dte(a,i,t),o=await S(e,`utf-8`);return r?.({cacheType:i,filePath:e}),JSON.parse(o,n)}catch{return null}},write:async(n,r,o,s=e)=>{try{let e=dte(s,r,n);await b(M.dirname(e),{recursive:!0}),await k(e,JSON.stringify(o,t),`utf-8`),i?.({cacheType:r,filePath:e})}catch(e){a?.({cacheType:r,error:e})}}}),un=e=>{let t=!0;return{enqueue:n=>{t&&e.enqueue(n)},close:()=>{t&&(t=!1,e.close())},error:n=>{t&&(t=!1,e.error(n))},markClosed:()=>{t=!1}}},fte=globalThis.ReadableStream||g.ReadableStream,pte=(e,t)=>Object.prototype.hasOwnProperty.call(e||{},t),mte=`https://huggingface.co`,hte=`https://huggingface.co/api`,dn=M.join(N.homedir(),`.buttress`,`models`),fn=[`cuda`,`vulkan`,`snapdragon`,`default`],gte=[`mxfp4`,`q8_0`,`q6_k`,`q6`,`q5_k_m`,`q5_k_s`,`q5_k`,`q5_1`,`q5_0`,`q4_k_m`,`q4_k_s`,`q4_k`,`q4_1`,`q4_0`,`q3`,`q2`],pn=.5,mn=[`speculative`,`spec_type`,`spec_draft_n_max`,`spec_draft_n_min`,`spec_draft_p_min`,`spec_draft_p_split`],_te=[...mn,`spec_draft_n_gpu_layers`,`spec_draft_cache_type_k`,`spec_draft_cache_type_v`],vte=[`model_draft`,`draft_model`,`spec_draft_n_gpu_layers`,`spec_draft_cache_type_k`,`spec_draft_cache_type_v`],yte=(e,t)=>{if(!(t==null||t===``)){if(e===`spec_draft_n_max`||e===`spec_draft_n_min`){let e=Number(t);return Number.isFinite(e)?Math.max(0,Math.floor(e)):void 0}if(e===`spec_draft_p_min`||e===`spec_draft_p_split`){let e=Number(t);return Number.isFinite(e)?Math.max(0,e):void 0}if(e===`spec_draft_n_gpu_layers`){let e=Number(t);return Number.isFinite(e)?Math.floor(e):void 0}return t}},bte=e=>{let t={};for(let n of _te){let r=yte(n,e.model[n]??e.runtime[n]);r!==void 0&&(t[n]=r)}return t},xte=(e={})=>{let t={};for(let n of mn){let r=yte(n,e[n]);r!==void 0&&(t[n]=r)}return t},Ste=(e={},t={})=>{let n={...e||{}};for(let e of vte)delete n[e];let r=xte(t);return!Object.keys(r).length||mn.some(e=>pte(n,e))?n:{...r,...n}},hn={backend:{type:`ggml-llm`,variant:null,variant_preference:fn,gpu_memory_fraction:.85,cpu_memory_fraction:pn},model:{repo_id:null,revision:`main`,filename:null,url:null,quantization:null,preferred_quantizations:[],n_ctx:null,n_gpu_layers:`auto`,allow_local_file:!1,local_path:null,api_base:hte,base_url:mte,enable_mtmd:!1,mmproj_filename:null,mmproj_url:null,mmproj_local_path:null,mmproj_use_gpu:null,mmproj_image_min_tokens:-1,mmproj_image_max_tokens:-1,model_draft:null,embedding:!1,pooling_type:null,vocab_only:!1,speculative:null,spec_type:null,spec_draft_n_max:null,spec_draft_n_min:null,spec_draft_p_min:null,spec_draft_p_split:null,spec_draft_n_gpu_layers:null,spec_draft_cache_type_k:null,spec_draft_cache_type_v:null},runtime:{cache_dir:dn,prefer_variants:[],huggingface_token:process.env.HUGGINGFACE_TOKEN||null,http_headers:{},session_cache:{enabled:!0,max_size_bytes:10*1024*1024*1024,max_entries:1e3},context_release_delay_ms:1e4}},{normalizeVariants:gn,sanitizeVariant:Cte}=Zt(fn),_n=(e={})=>{let t=structuredClone(hn);if(qt(t,e),t.backend.variant=Cte(t.backend.variant),t.backend.variant_preference=gn(t.backend.variant_preference),t.backend.variant_preference.length===0&&(t.backend.variant_preference=[...fn]),t.runtime.prefer_variants=gn(t.runtime.prefer_variants),t.model.preferred_quantizations=Xt(t.model.preferred_quantizations||t.model.quantizations),t.model.quantization){let e=String(t.model.quantization).toLowerCase();t.model.preferred_quantizations.includes(e)||t.model.preferred_quantizations.unshift(e)}t.model.n_parallel=t.model.n_parallel?Math.max(1,Number(t.model.n_parallel)):void 0,t.model.n_batch=Math.max(1,Number(t.model.n_batch)||512),t.model.base_url=t.model.base_url||mte,t.model.api_base=t.model.api_base||hte,t.model.enable_mtmd=!!t.model.enable_mtmd;let n=e=>{if(e==null)return-1;let t=Number(e);return Number.isFinite(t)?Math.floor(t):-1};t.model.mmproj_image_min_tokens=n(t.model.mmproj_image_min_tokens),t.model.mmproj_image_max_tokens=n(t.model.mmproj_image_max_tokens),t.runtime.cache_dir=t.runtime.cache_dir?M.resolve(t.runtime.cache_dir):dn,t.runtime.session_cache={...hn.runtime.session_cache,...t.runtime.session_cache||{}};let r=Number(t.runtime.context_release_delay_ms);return t.runtime.context_release_delay_ms=Number.isFinite(r)?Math.max(0,r):hn.runtime.context_release_delay_ms,t},wte=e=>{let t=e.toLowerCase();return gte.find(e=>t.includes(e))||null},Tte=e=>{let t=[];return e.backend.variant&&t.push(e.backend.variant),e.runtime.prefer_variants.length>0&&t.push(...e.runtime.prefer_variants),t.push(...e.backend.variant_preference),t.push(`default`),gn(t)},{read:vn,write:yn}=ln({defaultBaseDir:dn,replacer:(e,t)=>typeof t==`bigint`?`__bigint__${t.toString()}`:t,reviver:(e,t)=>typeof t==`string`&&t.startsWith(`__bigint__`)?BigInt(t.slice(10)):t,onRead:({cacheType:e,filePath:t})=>console.log(`[Cache] Hit ${e} cache:`,M.basename(t)),onWrite:({cacheType:e,filePath:t})=>console.log(`[Cache] Wrote ${e} cache:`,M.basename(t)),onWriteError:({cacheType:e,error:t})=>console.warn(`[Cache] Failed to write ${e} cache:`,t.message)}),bn=(e=dn)=>M.join(e,`.session-state-cache`),Ete=(e=dn)=>M.join(bn(e),`cache-map.json`),xn=(e=dn)=>M.join(bn(e),`temp`),Dte=(e=dn)=>M.join(bn(e),`states`),Ote=()=>({version:1,entries:{},totalSize:0}),kte=async(e=dn)=>{try{let t=await S(Ete(e),`utf-8`),n=JSON.parse(t);return!n.entries||typeof n.entries!=`object`?Ote():n}catch{return Ote()}},Ate=new Map,jte=e=>{let t=Ate.get(e);return t||(t=kte(e),Ate.set(e,t)),t},Mte=async(e,t=dn)=>{let n=Ete(t),r=`${n}.tmp.${Date.now()}`;try{await Qt(M.dirname(n)),await k(r,JSON.stringify(e,null,2),`utf-8`),await T(r,n)}catch(e){throw await O(r).catch(()=>{}),e}},Nte=(e,t)=>{let n=JSON.stringify({text:e,model:t.modelPath,variant:t.variant,n_gpu_layers:t.n_gpu_layers,n_ctx:t.n_ctx,cacheTypeK:t.cacheTypeK,cacheTypeV:t.cacheTypeV,kvUnified:t.kvUnified,swaFull:t.swaFull,flashAttnType:t.flashAttnType});return A(`sha256`).update(n).digest(`hex`).slice(0,24)},Pte=(e,t=dn)=>M.join(Dte(t),`${e}.bin`),Fte=(e=dn)=>{let t=`${Date.now()}-${Math.random().toString(36).slice(2,10)}`;return M.join(xn(e),`${t}.bin`)},Sn=e=>(e.stateFileSize||0)+(e.promptStateSize||0),Cn=e=>`${e}.meta`,wn=async(...e)=>{let t=e.filter(Boolean).flatMap(e=>[e,Cn(e)]);await Promise.all(t.map(e=>O(e).catch(()=>{})))},Ite=async(e,t)=>{await T(e,t),await T(Cn(e),Cn(t)).catch(()=>O(Cn(t)).catch(()=>{}))},Tn=e=>wn(e.stateFilePath,e.promptStatePath),En=(e,t)=>e.modelPath===t.modelPath&&e.variant===t.variant&&e.n_gpu_layers===t.n_gpu_layers&&e.n_ctx>=t.n_ctx&&e.cacheTypeK===t.cacheTypeK&&e.cacheTypeV===t.cacheTypeV&&e.kvUnified===t.kvUnified&&e.swaFull===t.swaFull&&e.flashAttnType===t.flashAttnType&&!!e.isRecurrent==!!t.isRecurrent&&!!e.isHybrid==!!t.isHybrid,Lte=(e,t)=>{let n=Math.min(e.length,t.length),r=0;for(;r<n&&e[r]===t[r];)r+=1;return r},Rte=(e,t,n,r=!1)=>{let i=Object.values(n.entries);console.log(`[SessionCache] Finding match for promptText (${e.length} chars), exactMatch=${r}`),console.log(`[SessionCache] Checking ${i.length} cache entries`);let a=i.filter(e=>En(e.metadata,t));if(r){let t=a.find(t=>t.fullText===e);return t?(console.log(`[SessionCache] Exact match found: ${t.id} (${t.fullText.length} chars)`),{entry:t,prefixLength:t.fullText.length,exactMatch:!0}):null}let o=a.reduce((t,n)=>{let r=Lte(e,n.fullText);return r>t.prefixLen||r===t.prefixLen&&n.fullText.length>(t.entry?.fullText?.length||0)?{entry:n,prefixLen:r}:t},{entry:null,prefixLen:0});return o.entry?(console.log(`[SessionCache] Prefix match found: ${o.entry.id} (${o.prefixLen}/${o.entry.fullText.length} chars)`),{entry:o.entry,prefixLength:o.prefixLen}):(console.log(`[SessionCache] No match found`),null)},zte=async(e,t,n)=>{let{evictedEntries:r,totalSize:i}=await Kt({entries:e.entries,totalSize:e.totalSize,maxEntries:n,maxSizeBytes:t,getEntrySize:Sn,removeEntry:async e=>{await Tn(e),console.log(`[SessionCache] Evicted entry: ${e.id}`)}});return e.totalSize=i,r.map(e=>e.id)},Bte=async(e,t,n,r)=>{let i=[];for(let[a,o]of Object.entries(e.entries))a!==n&&En(o.metadata,r)&&t.startsWith(o.fullText)&&o.fullText.length<t.length&&i.push(o);return await Promise.all(i.map(async t=>{await Tn(t),e.totalSize-=Sn(t),delete e.entries[t.id],console.log(`[SessionCache] Evicted superseded prefix entry: ${t.id} (${t.promptText.length} prompt chars)`)})),i.map(e=>e.id)},Vte=async(e=dn)=>{let t=xn(e);try{let e=await C(t),n=Date.now();await Promise.all(e.map(async e=>{let r=M.join(t,e),i=await D(r).catch(()=>null);i&&n-i.mtimeMs>36e5&&(await O(r).catch(()=>{}),console.log(`[SessionCache] Cleaned up temp file: ${e}`))}))}catch{}},Dn=async e=>{try{return await D(e),!0}catch{return!1}},Hte=(e,t)=>e==null?t:typeof e==`number`?e:typeof e==`string`?oe.parse(e)??t:t;var Ute=class e{constructor(e,t){this.config=e,this.plan=t,this.baseDir=e.runtime.cache_dir,this.enabled=e.runtime.session_cache?.enabled!==!1,this.maxSizeBytes=Hte(e.runtime.session_cache?.max_size_bytes,10*1024*1024*1024),this.maxEntries=e.runtime.session_cache?.max_entries||1e3,this.metadata={variant:t.info?.runtime?.variant||null,n_gpu_layers:t.info?.runtime?.n_gpu_layers||0,n_ctx:t.info?.runtime?.n_ctx||0,modelPath:t.localPath,cacheTypeK:t.info?.runtime?.cache_type_k||`f16`,cacheTypeV:t.info?.runtime?.cache_type_v||`f16`,kvUnified:t.info?.runtime?.kv_unified??null,swaFull:t.info?.runtime?.swa_full??null,flashAttnType:t.info?.runtime?.flash_attn_type||`off`,isRecurrent:!1,isHybrid:!1},this.cacheMap=null,this.initialized=!1}updateModelInfo(e){e&&(this.metadata.isRecurrent=!!e.is_recurrent,this.metadata.isHybrid=!!e.is_hybrid,(this.metadata.isRecurrent||this.metadata.isHybrid)&&console.log(`[SessionCache] Model architecture: recurrent=${this.metadata.isRecurrent}, hybrid=${this.metadata.isHybrid}`))}requiresExactMatch(){return this.metadata.isRecurrent||this.metadata.isHybrid}async persistCacheMap(){try{await Mte(this.cacheMap,this.baseDir)}catch(e){console.warn(`[SessionCache] Failed to persist cache map: ${e?.message||e}`)}}static checkTokenPrefixMatch(e,t){if(e.length>t.length)return!1;for(let n=0;n<e.length;n+=1)if(e[n]!==t[n])return!1;return!0}static async tokenizeToArray(e,t){let n=await e.tokenize(t);return Array.from(n?.tokens||[])}async findFormattedMatchForRecurrent(t,n,r){let i=await e.tokenizeToArray(r,n),a=t.map(async t=>{try{let n=await e.tokenizeToArray(r,t.fullText);if(e.checkTokenPrefixMatch(n,i))return{entry:t,usePromptState:!1,tokenCount:n.length};if(t.promptStatePath&&t.promptText){let n=await e.tokenizeToArray(r,t.promptText);if(e.checkTokenPrefixMatch(n,i))return{entry:t,usePromptState:!0,tokenCount:n.length}}return null}catch(e){return console.warn(`[SessionCache] Failed to check entry ${t.id}: ${e.message}`),null}}),o=(await Promise.all(a)).find(e=>e!==null);if(!o)return console.log(`[SessionCache] No token prefix match found for recurrent/hybrid model`),null;let{entry:s,usePromptState:c,tokenCount:l}=o;console.log(`[SessionCache] Token prefix match: ${s.id} (${l} tokens, usePromptState=${c})`);let u=c?s.promptStatePath:s.stateFilePath;return await Dn(u)?(s.lastAccessedAt=new Date().toISOString(),await this.persistCacheMap(),{entry:s,usePromptState:c}):(await this.removeStaleEntry(s),null)}async initialize(){if(!(!this.enabled||this.initialized))try{await Qt(bn(this.baseDir)),await Qt(xn(this.baseDir)),await Qt(Dte(this.baseDir)),this.cacheMap=await jte(this.baseDir),this.initialized=!0,console.log(`[SessionCache] Initialized with ${Object.keys(this.cacheMap.entries).length} entries`)}catch(e){console.warn(`[SessionCache] Failed to initialize: ${e.message}`),this.enabled=!1}}async removeStaleEntry(e){console.log(`[SessionCache] Removing stale entry: ${e.id}`),await Tn(e),delete this.cacheMap.entries[e.id],this.cacheMap.totalSize-=Sn(e),await this.persistCacheMap()}async findMatchingEntry(e,t=null){if(!this.enabled||!this.cacheMap)return null;let n=this.requiresExactMatch();if(n&&t){let n=Object.values(this.cacheMap.entries).filter(e=>En(e.metadata,this.metadata)&&e.fullText);return this.findFormattedMatchForRecurrent(n,e,t)}let r=Rte(e,this.metadata,this.cacheMap,n);if(!r)return null;let{entry:i}=r;return await Dn(i.stateFilePath)?(i.lastAccessedAt=new Date().toISOString(),await this.persistCacheMap(),{entry:i,usePromptState:!1}):(await this.removeStaleEntry(i),null)}async prepareCompletionOptions(e,t,n=null){let r={options:e,cacheEntry:null,promptPrefix:null};if(!this.enabled)return r;let i=await this.findMatchingEntry(t,n);if(!i)return r;let{entry:a,usePromptState:o}=i,s=o?a.promptStatePath:a.stateFilePath,c=o?a.promptText:a.fullText;return console.log(`[SessionCache] Found matching entry: ${a.id} (${c.length} chars, usePromptState=${o})`),{options:{...e,load_state_path:s},cacheEntry:a,promptPrefix:c}}async saveCompletionState(e,t,n,r=0,i=null){if(!this.enabled)return null;let a=e+t,o=Nte(a,this.metadata),s=()=>wn(n,i);if(this.cacheMap.entries[o]){console.log(`[SessionCache] Entry already exists for prompt: ${o}, updating position`);let e=this.cacheMap.entries[o];return e.lastAccessedAt=new Date().toISOString(),delete this.cacheMap.entries[o],this.cacheMap.entries[o]=e,await this.persistCacheMap(),s(),e}let c=Pte(o,this.baseDir),l=i?Pte(`${o}-prompt`,this.baseDir):null;try{await Qt(M.dirname(c)),await Ite(n,c);let s=await D(c),u=0;if(i&&l)try{await Ite(i,l),u=(await D(l)).size,console.log(`[SessionCache] Saved prompt state: ${l}`)}catch(e){console.warn(`[SessionCache] Failed to save prompt state: ${e.message}`)}let d={id:o,promptText:e,completionText:t,fullText:a,promptTokenCount:r,stateFilePath:c,stateFileSize:s.size,promptStatePath:l||null,promptStateSize:u,metadata:{...this.metadata},createdAt:new Date().toISOString(),lastAccessedAt:new Date().toISOString()};return this.cacheMap.entries[o]=d,this.cacheMap.totalSize+=s.size+u,this.requiresExactMatch()||await Bte(this.cacheMap,e,o,this.metadata),await zte(this.cacheMap,this.maxSizeBytes,this.maxEntries),await Mte(this.cacheMap,this.baseDir),console.log(`[SessionCache] Saved entry: ${o} (${s.size} bytes, ${a.length} chars)`),d}catch(e){return console.warn(`[SessionCache] Failed to save state: ${e.message}`),s(),null}}async generateTempStatePath(){return await Qt(xn(this.baseDir)),Fte(this.baseDir)}async cleanup(){await Vte(this.baseDir)}};const On=async(e,t,n=dn)=>{let r=JSON.stringify({url:e,headers:t}),i=await vn(r,`range-metadata`,n);if(i)return i;let a=!/^https?:/i.test(e),{metadata:o}=await re(e,{fetch,additionalFetchHeaders:t,allowLocalFile:a});return await yn(r,`range-metadata`,o,n),o},kn=(e,t)=>t.localPath?t.localPath:e.model.local_path?M.resolve(e.model.local_path):tn(e.runtime.cache_dir,t,`model`),Wte=e=>{let t=e.model.model_draft??e.model.draft_model??e.runtime.model_draft??e.runtime.draft_model;if(!t)return null;if(typeof t!=`string`&&(typeof t!=`object`||Array.isArray(t)))throw Error("`model.model_draft` must be a URL/path string or model config object");let n;n=typeof t==`string`?/^https?:\/\//i.test(t)?{url:t}:{local_path:t}:{...t};let r=n.repo_id||n.repository||n.model||n.url||n.local_path;if(!r)throw Error("`model.model_draft` requires `repo_id`, `url`, or `local_path`");let i=`model-draft/${A(`sha256`).update(String(r)).digest(`hex`).slice(0,16)}`,a={revision:e.model.revision||`main`,preferred_quantizations:[],allow_local_file:e.model.allow_local_file,api_base:e.model.api_base,base_url:e.model.base_url,...n,repo_id:n.repo_id||n.repository||n.model||i};if(a.preferred_quantizations=Array.from(new Set(Yt(a.preferred_quantizations||a.quantizations).map(e=>e?String(e).toLowerCase():null).filter(Boolean))),a.quantization){let e=String(a.quantization).toLowerCase();a.quantization=e,a.preferred_quantizations.includes(e)||a.preferred_quantizations.unshift(e)}return a.url&&!a.filename&&(a.filename=a.url.split(`/`).pop()?.split(`?`)[0]),{...e,model:a}},An=async e=>{let t=Wte(e);if(!t)return{draftConfig:null,draftArtifact:null};if(t.model.local_path){if(!t.model.allow_local_file)throw Error("`model.model_draft.local_path` requires `model.allow_local_file = true`");let e=M.resolve(String(t.model.local_path).replace(/^file:\/\//i,``)),n=await D(e).catch(()=>null);if(!n?.isFile())throw Error(`Draft model file not found: ${e}`);return{draftConfig:t,draftArtifact:{repoId:t.model.repo_id,revision:t.model.revision,filename:M.basename(e),url:e,size:n.size,headers:{},localPath:e}}}return{draftConfig:t,draftArtifact:await jn(t)}},jn=async e=>{let t=e.model.repo_id||e.model.repository||e.model.model;if(!t)throw Error("`model.repo_id` is required in Buttress backend config");let n=e.model.revision||`main`,r=e.runtime.cache_dir,i=JSON.stringify({repoId:t,revision:n,filename:e.model.filename,url:e.model.url,quantization:e.model.quantization,preferred_quantizations:e.model.preferred_quantizations}),a=await vn(i,`artifact-info`,r);if(a)return a;let o={...e.runtime.http_headers||{}};if(e.runtime.huggingface_token&&(o.Authorization=`Bearer ${e.runtime.huggingface_token}`),e.model.url){let a=await on(e.model.url,{headers:o}),s=Number(a.headers.get(`content-length`))||null,c={repoId:t,revision:n,filename:e.model.filename||e.model.url.split(`/`).pop(),url:e.model.url,size:s,headers:o};return await yn(i,`artifact-info`,c,r),c}let{filename:s}=e.model,c=e.model.quantization&&String(e.model.quantization).toLowerCase(),l=await an(`${e.model.api_base}/models/${t}?revision=${n}&blobs=true`,{headers:o}),u=l?.siblings||l?.files||[],d=[];for(let e of u){let t=e.rfilename||e.path||e.filename;typeof t==`string`&&t.endsWith(`.gguf`)&&d.push(t)}if(d.length===0)throw Error(`No GGUF artifacts found in repo ${t}`);let f=e.model.preferred_quantizations.length>0?e.model.preferred_quantizations:gte,p=d.map(e=>e.toLowerCase()),m=()=>{for(let e of f){let t=p.findIndex(t=>t.includes(e));if(t!==-1)return{filename:d[t],quantization:e}}return null};if(s)c||=wte(s);else{let{filename:e,quantization:t}=m()||{filename:d[0],quantization:null};s=e,c=t||wte(s)}let h=`${e.model.base_url.replace(/\/+$/,``)}/${t}/resolve/${n}/${s}`,g=/-(\d{5})-of-(\d{5})\.gguf$/,_=s.match(g),v=null;if(_){let[,,r]=_,i=await an(`${e.model.api_base}/models/${t}?revision=${n}&blobs=true`,{headers:o}),a=i?.siblings||i?.files||[],c=Number(r);v=0;for(let e=1;e<=c;e+=1){let t=String(e).padStart(5,`0`),n=s.replace(g,`-${t}-of-${r}.gguf`),i=a.find(e=>(e.rfilename||e.path||e.filename)===n),o=Number(i?.size);Number.isFinite(o)&&o>0&&(v+=o)}}else{let e=await on(h,{headers:o});v=Number(e.headers.get(`content-length`))||null}let y={repoId:t,revision:n,filename:s,url:h,size:v,quantization:c,headers:o,isSplit:!!_,splitCount:_?Number(_[2]):0};return await yn(i,`artifact-info`,y,r),y},Gte=/^mmproj-.*\.gguf$/i,Mn=async(e,t)=>{if(!e.model.enable_mtmd)return null;let n=e.runtime.cache_dir,r={...e.runtime.http_headers||{}};e.runtime.huggingface_token&&(r.Authorization=`Bearer ${e.runtime.huggingface_token}`);let i=t?.repoId||e.model.repo_id,a=t?.revision||e.model.revision||`main`,o=JSON.stringify({kind:`mmproj`,repoId:i,revision:a,mmproj_filename:e.model.mmproj_filename,mmproj_url:e.model.mmproj_url,mmproj_local_path:e.model.mmproj_local_path}),s=await vn(o,`artifact-info`,n);if(s)return s;if(e.model.mmproj_url){let t=await on(e.model.mmproj_url,{headers:r}),s=Number(t.headers.get(`content-length`))||null,c={repoId:i,revision:a,filename:e.model.mmproj_filename||e.model.mmproj_url.split(`/`).pop(),url:e.model.mmproj_url,size:s,headers:r};return await yn(o,`artifact-info`,c,n),c}if(e.model.mmproj_local_path){if(!e.model.allow_local_file)throw Error("`model.mmproj_local_path` requires `model.allow_local_file = true`");let t={repoId:i,revision:a,filename:M.basename(e.model.mmproj_local_path),url:null,size:null,headers:r,localPath:M.resolve(e.model.mmproj_local_path)};return await yn(o,`artifact-info`,t,n),t}if(!i)throw Error("Cannot derive mmproj artifact without `model.repo_id`");let c=await an(`${e.model.api_base}/models/${i}?revision=${a}&blobs=true`,{headers:r}),l=c?.siblings||c?.files||[],u=l.map(e=>e.rfilename||e.path||e.filename).filter(e=>typeof e==`string`),d=e.model.mmproj_filename;if(d){if(!u.includes(d))throw Error(`mmproj file "${d}" not found in repo ${i}`)}else{let e=u.filter(e=>Gte.test(e));if(e.length===0)return console.warn(`[buttress] enable_mtmd set but no mmproj file found in ${i}; skipping multimodal load`),null;let n=t?.quantization&&String(t.quantization).toLowerCase();d=n&&e.find(e=>e.toLowerCase().includes(n))||e[0]}let f=`${e.model.base_url.replace(/\/+$/,``)}/${i}/resolve/${a}/${d}`,p=l.find(e=>(e.rfilename||e.path||e.filename)===d),m=Number(p?.size);if(!Number.isFinite(m)||m<=0){let e=await on(f,{headers:r});m=Number(e.headers.get(`content-length`))||null}let h={repoId:i,revision:a,filename:d,url:f,size:m,headers:r};return await yn(o,`artifact-info`,h,n),h},Nn=(e,t)=>t?.localPath?t.localPath:t?tn(e.runtime.cache_dir,t,`mmproj`):null,Pn=async(e,{modelBytes:t=null,kvCacheBytes:n=null}={})=>{let r=Tte(e),[i,...a]=r,o=Jt(e.backend?.gpu_memory_fraction)??(hn.backend.gpu_memory_fraction||1),s=Jt(e.backend?.cpu_memory_fraction)??pn,c=await ft({platform:process.platform,totalMemoryInBytes:N.totalmem(),backend:`ggml-llm`,variant:i||null,preferVariants:a,gpuMemoryFraction:o,cpuMemoryFraction:s,dependencies:{getBackendDevicesInfo:P,isLibVariantAvailable:ie},modelBytes:t,kvCacheBytes:n}),l=e=>({...e,devices:Array.isArray(e.devices)?e.devices:[],ok:e.ok,hasGpu:!!e.hasGpu,totalMemory:e.gpuTotalBytes||e.totalMemory||0,error:e.ok?null:Error(e.error||`Variant ${e.variant} not available on this platform`)});if(!c.ok||!c.selected){let e=(c.attempts||[]).map(e=>`${e.variant}: ${e.error||`unknown error`}`).join(`; `);throw Error(`Unable to initialize any backend variant (${r.join(`, `)}). Errors: ${e}`)}let u=(c.attempts||[]).map(l);return{selected:l(c.selected),attempts:u}},Kte=async e=>{let t=await jn(e),{draftConfig:n,draftArtifact:r}=await An(e),i=await Mn(e,t),a=await On(t.url,t.headers,e.runtime.cache_dir),{arch:o,nCtxTrain:s,nLayer:c,nEmbd:l,nHead:u,nHeadKv:d,nEmbdHeadK:f,nEmbdHeadV:p,quantVersion:m,fileType:h,attentionLayerCount:g,recurrentLayerCount:_,ssmDConv:v,ssmDState:y,ssmDInner:b,ssmNGroup:x,ssmDtRank:S,rwkvHeadSize:C,rwkvTokenShiftCount:w}=xt(a),T=Number.isFinite(Number(c))?Number(c):0,E=Number.isFinite(Number(l))?Number(l):0,D=Number.isFinite(Number(u))?Number(u):0,O=Number.isFinite(Number(d))?Number(d):D,k=D>0&&E>0?E/D:128,ee=f!=null&&Number.isFinite(Number(f))?Number(f):k,A=p!=null&&Number.isFinite(Number(p))?Number(p):k,te=vt({arch:o,metadata:a,nLayer:T}),j=te&&Number.isFinite(Number(te.kvLayers))?Number(te.kvLayers):T,ne=Math.max(0,Math.floor(Number(j)||0)),M={use_mmap:e.model.use_mmap??e.runtime.use_mmap,use_mlock:e.model.use_mlock??e.runtime.use_mlock,no_extra_bufts:e.model.no_extra_bufts??e.runtime.no_extra_bufts,n_threads:e.model.n_threads??e.runtime.n_threads,n_ctx:e.model.n_ctx??e.runtime.n_ctx,n_batch:e.model.n_batch??e.runtime.n_batch,n_ubatch:e.model.n_ubatch??e.runtime.n_ubatch,n_cpu_moe:e.model.n_cpu_moe??e.runtime.n_cpu_moe,n_parallel:(e.model.n_parallel??e.runtime.n_parallel)||4,cpu_mask:e.model.cpu_mask??e.runtime.cpu_mask,cpu_strict:e.model.cpu_strict??e.runtime.cpu_strict,devices:e.model.devices??e.runtime.devices,split_mode:e.model.split_mode??e.runtime.split_mode,tensor_split:e.model.tensor_split??e.runtime.tensor_split,n_gpu_layers:e.model.n_gpu_layers??e.runtime.n_gpu_layers,flash_attn_type:e.model.flash_attn_type??e.runtime.flash_attn_type,cache_type_k:e.model.cache_type_k??e.runtime.cache_type_k,cache_type_v:e.model.cache_type_v??e.runtime.cache_type_v,kv_unified:e.model.kv_unified??e.runtime.kv_unified,swa_full:e.model.swa_full??e.runtime.swa_full,ctx_shift:e.model.ctx_shift??e.runtime.ctx_shift,state_cache_budget_mb:e.model.state_cache_budget_mb??e.runtime.state_cache_budget_mb,state_cache_max_checkpoints:e.model.state_cache_max_checkpoints??e.runtime.state_cache_max_checkpoints,...bte(e)},re=M.n_ctx?Number(M.n_ctx):null,P=re||s||4096,ie=[],ae=[],oe=!0;if(re&&s&&re>s){oe=!1;let e=`Requested context length (${re}) exceeds model training context (${s})`;ie.push(e),ae.push(e),P=s}re&&!s&&ie.push(`Model metadata missing training context length, using requested value`);let se={k:M.cache_type_k,v:M.cache_type_v},ce=t.size>0?t.size:0,le=r?.size>0?r.size:0,ue=ce+le,de=St({layerCount:ne,headKvCount:O,embdHeadKCount:ee,embdHeadVCount:A,cacheTypes:se,swaConfig:te,kvUnified:M.kv_unified,nParallel:M.n_parallel,swaFull:M.swa_full,arch:o,attentionLayerCount:g}),fe=Ct({nLayer:T,nEmbd:E,recurrentLayerCount:_,nSeqMax:M.n_parallel||4,ssmDConv:v,ssmDState:y,ssmDInner:b,ssmNGroup:x,ssmDtRank:S,rwkvHeadSize:C,rwkvTokenShiftCount:w,arch:o}),pe=de(P),me=await Pn(e,{modelBytes:ue,kvCacheBytes:pe+fe}),he=me.selected.totalMemory||0,ge=he*(e.backend.gpu_memory_fraction||1),_e=Jt(e.backend.cpu_memory_fraction)??pn,ve=Math.max(0,N.totalmem()*_e),ye=me.selected.hasGpu?ge:ve,be=wt({maxCtx:P,availableMemory:ye,modelBytes:ue,kvBytesForCtx:de});if(!re&&be){let e=Math.max(32,s?Math.min(be,s):be);e<P&&ie.push(`Context length capped to ${e} by memory limits`),P=e}P>be&&(P=be);let xe=Math.floor(be);console.log(`[buttress] Memory-limited context length: ${xe}`);let Se=de(P),Ce=ue+Se+fe,we=T?ce/(T+1):ce,Te=0;me.selected.hasGpu&&we>0&&(Te=Math.min(T+1,Math.max(0,Math.floor(ge/we)))),console.log(`[buttress] Auto GPU layer capacity (${me.selected.variant}): ${Te}/${T+1}`);let Ee;Ee=M.n_gpu_layers===`auto`||M.n_gpu_layers==null?Te:Math.max(0,Math.min(Number(M.n_gpu_layers)||0,T+1));let De=(()=>{let e=M.flash_attn_type&&String(M.flash_attn_type).toLowerCase();return e===`on`||e===`off`?e:me.selected.hasGpu?`auto`:`off`})(),Oe=e.runtime.cache_dir,ke=kn(e,t),F=await rn(ke,t.size),Ae=r?kn(n,r):null,je=Ae?await rn(Ae,r.size):!1,Me=r?{repoId:r.repoId,revision:r.revision,filename:r.filename,quantization:r.quantization,url:r.url,sizeBytes:r.size,download:{cacheDir:n.runtime.cache_dir,localPath:Ae,exists:je}}:null,Ne=Nn(e,i),Pe=Ne?await rn(Ne,i?.size):!1,Fe=i?{enabled:!0,initialized:!1,filename:i.filename,url:i.url,sizeBytes:i.size,localPath:Ne,exists:Pe,useGpu:e.model.mmproj_use_gpu,imageMinTokens:e.model.mmproj_image_min_tokens,imageMaxTokens:e.model.mmproj_image_max_tokens}:{enabled:!1,requested:!!e.model.enable_mtmd};return{config:e,info:{ok:oe,backend:`ggml-llm`,warnings:ie,errors:ae,model:{repoId:t.repoId,revision:t.revision,filename:t.filename,quantization:t.quantization,url:t.url,sizeBytes:t.size,metadata:{architecture:o,n_ctx_train:s,n_layer:T,n_embd:E,quantization_version:m,file_type:h,kv_layer_count:ne,swa:te?.enabled?{window:te.window,pattern:te.pattern,dense_first:te.denseFirst,type:te.type,layers:te.swaLayers}:null}},draftModel:Me,runtime:{...M,variant:me.selected.variant,n_ctx:P,requested_ctx:re,n_gpu_layers:Ee,auto_gpu_layers:Te,flash_attn_type:De,cache_type_k:se.k,cache_type_v:se.v,estimated_max_n_ctx:xe},resources:{modelBytes:ue,targetModelBytes:ce,draftModelBytes:le,kvCacheBytes:Se,recurrentMemoryBytes:fe,totalEstimatedBytes:Ce,gpuCapacityBytes:he,gpuUsableBytes:ge,cpuUsableBytes:ve,fit:me.selected.fit},devices:{selected:me.selected,attempts:me.attempts},download:{cacheDir:Oe,localPath:ke,exists:F},multimodal:Fe,timestamp:new Date().toISOString()},artifact:t,mmprojArtifact:i,mmprojLocalPath:Ne,mmprojLocalExists:Pe,metadata:{arch:o,nCtxTrain:s,nLayer:T,nEmbd:E},devices:me,cacheTypes:se,localPath:ke,localExists:F,draftPlan:r?{config:n,artifact:r,localPath:Ae,localExists:je,info:{download:Me.download}}:null}},qte=(e,t)=>{let n=typeof t==`string`?t:t?.prompt;if(!n)return e;let{messages:r,tools:i,tool_choice:a,parallel_tool_calls:o,chat_template:s,chatTemplate:c,jinja:l,add_generation_prompt:u,chat_template_kwargs:d,force_pure_content:f,now:p,...m}=e,h={...m,prompt:n};return typeof t!=`object`||t.type!==`jinja`?h:(typeof t.chat_format==`number`&&(h.chat_format=t.chat_format),t.grammar&&(h.grammar=t.grammar),typeof t.grammar_lazy==`boolean`&&(h.grammar_lazy=t.grammar_lazy),t.grammar_triggers?.length&&(h.grammar_triggers=t.grammar_triggers),t.preserved_tokens?.length&&(h.preserved_tokens=t.preserved_tokens),t.additional_stops?.length&&(h.stop=[...m.stop||[],...t.additional_stops]),t.media_paths?.length&&(h.media_paths=t.media_paths),typeof t.generation_prompt==`string`&&(h.generation_prompt=t.generation_prompt),typeof t.thinking_forced_open==`boolean`&&(h.thinking_forced_open=t.thinking_forced_open),typeof t.thinking_start_tag==`string`&&(h.thinking_start_tag=t.thinking_start_tag),typeof t.thinking_end_tag==`string`&&(h.thinking_end_tag=t.thinking_end_tag),t.chat_parser&&(h.chat_parser=t.chat_parser),h)},Jte=(e,t,n=null,r=null)=>{let i,a,o=Date.now(),s=0;return new fte({async start(c){a=un(c);try{let c=await e.parallel.completion(t,(e,t)=>{t&&(t.token&&(s+=1),a.enqueue({event:`token`,data:{requestId:e,...t}}))}),{requestId:l}=c;i=c.stop;let u=await c.promise;console.log(`[Completion] Result:`,u),a.enqueue({event:`result`,data:{requestId:l,...u}}),a.close();let d=Date.now()-o,f=u.timings||{};Pt.addCompletion({id:`completion-${l}`,generatorId:n,requestId:l,repoId:r?.repoId||null,quantization:r?.quantization||null,variant:r?.variant||null,cacheTokens:f.cache_n??0,promptTokens:f.prompt_n??0,tokensGenerated:f.predicted_n??s,tokensPerSecond:f.predicted_per_second??0,promptPerSecond:f.prompt_per_second??0,durationMs:d,success:!0,interrupted:u.interrupted||!1,contextFull:u.context_full||u.contextFull||!1})}catch(e){a.enqueue({event:`error`,data:{message:e?.message||String(e)}}),a.error(e),Pt.addCompletion({id:`completion-${Date.now()}`,generatorId:n,repoId:r?.repoId||null,quantization:r?.quantization||null,variant:r?.variant||null,durationMs:Date.now()-o,tokensGenerated:s,success:!1,error:e?.message||String(e)})}},cancel(){a?.markClosed(),i&&i()}})},Yte=(e,t,n,r,i,a,o=null,s=null,c=null)=>{let l,u,d=``,f=!1,p=Date.now(),m=0,h=()=>wn(i,c);return new fte({async start(g){u=un(g);try{let g=await e.parallel.completion(t,(e,t)=>{t&&(t.token&&(d+=t.token,m+=1),u.enqueue({event:`token`,data:{requestId:e,...t}}))}),{requestId:_}=g;l=g.stop;let v=await g.promise;v.text?d=v.text:v.content&&(d=v.content),f=!v.interrupted&&!v.context_full,console.log(`[Completion] Result:`,v),u.enqueue({event:`result`,data:{requestId:_,...v}}),u.close();let y=Date.now()-p,b=v.timings||{};Pt.addCompletion({id:`completion-${_}`,generatorId:o,requestId:_,repoId:s?.repoId||null,quantization:s?.quantization||null,variant:s?.variant||null,cacheTokens:b.cache_n??0,promptTokens:b.prompt_n??a??0,tokensGenerated:b.predicted_n??m,tokensPerSecond:b.predicted_per_second??0,promptPerSecond:b.prompt_per_second??0,durationMs:y,success:!0,interrupted:v.interrupted||!1,contextFull:v.context_full||v.contextFull||!1,usedCache:!!t.load_state_path}),f&&n.enabled&&d?n.saveCompletionState(r,d,i,a,c).catch(e=>{console.warn(`[SessionCache] Save failed:`,e.message)}):h()}catch(e){u.enqueue({event:`error`,data:{message:e?.message||String(e)}}),u.error(e),Pt.addCompletion({id:`completion-${Date.now()}`,generatorId:o,repoId:s?.repoId||null,quantization:s?.quantization||null,variant:s?.variant||null,durationMs:Date.now()-p,tokensGenerated:m,success:!1,error:e?.message||String(e)}),h()}},cancel(){u?.markClosed(),l&&l(),h()}})},Fn=e=>{let t={model:e.plan.localPath,modelDraft:e.plan.draftPlan?.localPath||null,runtime:e.plan.info.runtime};return A(`sha256`).update(JSON.stringify(t)).digest(`hex`).slice(0,24)},In=async(e,t,n,r)=>{let i=(e,t,n)=>{e>=0&&Number.isFinite(e)&&typeof r==`function`&&r((t+e)/n)};if(t.isSplit&&t.splitCount>0){let r=/-(\d{5})-of-(\d{5})\.gguf$/,a=M.dirname(n),o=t.splitCount,s=0;for(let n=1;n<=o;n+=1){let c=String(n).padStart(5,`0`),l=t.filename.replace(r,`-${c}-of-${String(o).padStart(5,`0`)}.gguf`),u=`${e.model.base_url.replace(/\/+$/,``)}/${t.repoId}/resolve/${t.revision}/${l}`,d=M.join(a,M.basename(l));await rn(d)||await cn(u,t.headers,d,null,e=>{i(e,s,o)},{allowedRoot:e.runtime.cache_dir}),s+=1}return}await cn(t.url,t.headers,n,t.size,e=>{i(e,0,1)},{allowedRoot:e.runtime.cache_dir})},Ln=async(e,t,n,r=null)=>{let{config:i,localPath:a,artifact:o}=e;if(i.model.local_path&&!i.model.allow_local_file)throw Error("Local model path provided but `model.allow_local_file` is not enabled");if(!i.model.local_path&&!o.localPath&&await nn(a,i.runtime.cache_dir),e.localExists&&!t.has(a))return e.info.download.exists=!0,typeof n==`function`&&n(.5),a;let s=a;if(r){let t=r.getDownload(s);if(t){console.log(`[ensureModelFile] Waiting for global download: ${o.repoId}`);try{if(await t,await rn(a,o.size))return e.localExists=!0,e.info.download.exists=!0,typeof n==`function`&&n(.5),a}catch(e){console.warn(`[ensureModelFile] Global download failed, will retry: ${e.message}`)}}}t.has(s)||t.set(s,(async()=>{let t=o.isSplit&&o.splitCount>0;t||console.log(`Downloading model: 0%`),await In(i,o,a,e=>{let r=Math.round(e*100);console.log(`Downloading model${t?` splits`:``}: ${Math.min(100,r)}%`),typeof n==`function`&&n(e*.5)}),e.localExists=!0,e.info.download.exists=!0})());try{await t.get(s)}finally{t.delete(s)}return a},Xte=async(e,t,n,r=null)=>{let{mmprojArtifact:i,mmprojLocalPath:a}=e;if(!i||!a)return null;if(i.localPath){if(!await rn(a))throw Error(`mmproj local file not found: ${a}`);return e.mmprojLocalExists=!0,e.info.multimodal.exists=!0,typeof n==`function`&&n(1),a}if(await nn(a,e.config.runtime.cache_dir),e.mmprojLocalExists&&!t.has(a))return e.info.multimodal.exists=!0,typeof n==`function`&&n(1),a;let o=a;if(r){let t=r.getDownload(o);if(t)try{if(await t,await rn(a,i.size))return e.mmprojLocalExists=!0,e.info.multimodal.exists=!0,typeof n==`function`&&n(1),a}catch(e){console.warn(`[ensureMmprojFile] Global download failed, will retry: ${e.message}`)}}t.has(o)||t.set(o,(async()=>{console.log(`Downloading mmproj: 0%`),await cn(i.url,i.headers,a,i.size,e=>{if(e>=0&&Number.isFinite(e)){let t=Math.round(e*100);console.log(`Downloading mmproj: ${Math.min(100,t)}%`),typeof n==`function`&&n(e)}},{allowedRoot:e.config.runtime.cache_dir}),e.mmprojLocalExists=!0,e.info.multimodal.exists=!0})());try{await t.get(o)}finally{t.delete(o)}return a},Zte=async(e,t)=>{let n=Fn(e),r=e.contexts.get(n);if(r&&!r.released)return r.releaseTimer&&(clearTimeout(r.releaseTimer),r.releaseTimer=null,console.log(`[Context] Cancelled pending release for context "${n}"`)),r.releaseRequested=!1,r.refCount+=1,console.log(`[Context] Reusing existing context "${n}", refCount=${r.refCount}`),typeof t==`function`&&t(0),r.context||await r.ready,typeof t==`function`&&t(1),r;console.log(r?`[Context] Record exists but released=${r.released}, creating new context`:`[Context] No existing record for "${n}", creating new context`),r={key:n,refCount:1,ready:null,released:!1},e.contexts.set(n,r),r.ready=(async()=>{let i=Date.now(),a=e.plan.draftPlan&&typeof t==`function`?e=>t(e*.7):t,o=await Ln(e.plan,e.downloads,a,e.globalDownloadManager),s=e.plan.draftPlan?await Ln(e.plan.draftPlan,e.downloads,typeof t==`function`?e=>t(.35+e*.3):null,e.globalDownloadManager):null;typeof t==`function`&&t(.5);let c=!!e.config.model.embedding,l=!!e.config.model.vocab_only,u={model:o,n_threads:e.plan.info.runtime.n_threads,use_mmap:e.plan.info.runtime.use_mmap,use_mlock:e.plan.info.runtime.use_mlock,no_extra_bufts:e.plan.info.runtime.no_extra_bufts,cpu_mask:e.plan.info.runtime.cpu_mask,cpu_strict:e.plan.info.runtime.cpu_strict,devices:e.plan.info.runtime.devices,split_mode:e.plan.info.runtime.split_mode,tensor_split:e.plan.info.runtime.tensor_split,n_ctx:e.plan.info.runtime.n_ctx,n_gpu_layers:e.plan.info.runtime.n_gpu_layers,n_parallel:c?1:e.plan.info.runtime.n_parallel,n_batch:e.plan.info.runtime.n_batch,n_ubatch:e.plan.info.runtime.n_ubatch,n_cpu_moe:e.plan.info.runtime.n_cpu_moe,flash_attn_type:e.plan.info.runtime.flash_attn_type,ctx_shift:e.plan.info.runtime.ctx_shift,kv_unified:e.plan.info.runtime.kv_unified,swa_full:e.plan.info.runtime.swa_full,state_cache_budget_mb:e.plan.info.runtime.state_cache_budget_mb,state_cache_max_checkpoints:e.plan.info.runtime.state_cache_max_checkpoints,lib_variant:e.plan.info.runtime.variant,embedding:c};e.config.model.pooling_type&&(u.pooling_type=e.config.model.pooling_type),l&&(u.vocab_only=!0,u.n_gpu_layers=0,u.n_parallel=1),s&&(u.model_draft=s);for(let t of _te){let n=e.plan.info.runtime[t];n!=null&&(u[t]=n)}e.plan.info.runtime.flash_attn_type!==`off`&&(u.cache_type_k=e.plan.info.runtime.cache_type_k,u.cache_type_v=e.plan.info.runtime.cache_type_v),console.log(`[Context] Load Options:`,u);let d;try{if(d=await ae(u,e=>{typeof t==`function`&&(t(.5+e*.25),e%5==0&&console.log(`[Context] Load Model Progress:`,e))}),!c&&!l&&e.plan.info.runtime.n_parallel&&!await d.parallel.enable({n_parallel:e.plan.info.runtime.n_parallel,n_batch:e.plan.info.runtime.n_batch}))throw Error(`Failed to enable parallel decoding mode for context`);if(e.plan.mmprojArtifact){let t=await Xte(e.plan,e.downloads,null,e.globalDownloadManager);if(t){let n=e.config.model.mmproj_use_gpu,r={path:t,use_gpu:n==null?(e.plan.info.runtime.n_gpu_layers||0)>0:!!n,image_min_tokens:e.config.model.mmproj_image_min_tokens,image_max_tokens:e.config.model.mmproj_image_max_tokens};console.log(`[Context] initMultimodal:`,r),await d.initMultimodal(r)?e.plan.info.multimodal.initialized=!0:console.warn(`[Context] initMultimodal returned false; multimodal disabled`)}}if(r.released){try{d.parallel?.disable?.()}catch{}throw Error(`Context "${n}" was released before the model finished loading`)}return typeof t==`function`&&t(1),r.context=d,r.modelInfo=d.getModelInfo(),Pt.addModelLoad({id:`${e.id}-${n}`,generatorId:e.id,contextKey:n,repoId:e.plan.info.model?.repoId||null,quantization:e.plan.info.model?.quantization||null,variant:e.plan.info.runtime?.variant||null,nCtx:e.plan.info.runtime?.n_ctx||null,nGpuLayers:e.plan.info.runtime?.n_gpu_layers||null,durationMs:Date.now()-i,success:!0}),r}catch(t){if(Pt.addModelLoad({id:`${e.id}-${n}`,generatorId:e.id,contextKey:n,repoId:e.plan.info.model?.repoId||null,quantization:e.plan.info.model?.quantization||null,variant:e.plan.info.runtime?.variant||null,durationMs:Date.now()-i,success:!1,error:t?.message||String(t)}),d)try{d.release()}catch{}throw t}})();try{return await r.ready,r}catch(t){throw e.contexts.get(n)===r&&e.contexts.delete(n),t}},Rn=async(e,t,n=!1)=>{if(t.released||!n&&t.refCount>0)return!1;t.released=!0,e.contexts.delete(t.key);try{t.context?.parallel?.disable?.()}catch{}return await t.context?.release?.(),!0},Qte=async(e,t,n=!1)=>{if(t.releaseRequested=!0,t.releaseTimer&&=(clearTimeout(t.releaseTimer),null),n)t.refCount=0;else if(t.refCount=Math.max(0,t.refCount-1),t.refCount>0)return t.releaseRequested=!1,!1;let r=e.config.runtime.context_release_delay_ms;if(typeof r!=`number`||!Number.isFinite(r))return Rn(e,t);let i=Math.max(0,Math.floor(r));return n||i<=0?Rn(e,t):(console.log(`[Context] Scheduling release in ${i}ms for context "${t.key}"`),t.releaseTimer=setTimeout(async()=>{if(t.releaseTimer=null,t.refCount>0){console.log(`[Context] Release cancelled, refCount=${t.refCount} for context "${t.key}"`),t.releaseRequested=!1;return}console.log(`[Context] Releasing context "${t.key}" after ${i}ms delay`),await Rn(e,t)},i),!0)};async function $te(e,t,n={}){let{globalDownloadManager:r=null}=n,i=_n(t),a=await Kte(i),o=new Ute(i,a);await o.initialize();let s={id:e,type:`ggml-llm`,config:i,plan:a,info:a.info,contexts:new Map,downloads:new Map,globalDownloadManager:r,sessionCache:o,finalized:!1};return{id:e,type:`ggml-llm`,info:a.info,contexts:s.contexts,initContext:async(e={})=>{let{onProgress:t}=e,n=await Zte(s,t);return s.sessionCache.updateModelInfo(n.modelInfo),{modelInfo:n.modelInfo?{...n.modelInfo}:null,runtime:{...s.plan.info.runtime},download:{...s.plan.info.download},multimodal:s.plan.info.multimodal?{...s.plan.info.multimodal}:null}},completion:async(e={})=>{let{options:t={},useCache:n=!0}=e,r=Ste(t,s.plan.info.runtime),i=Fn(s),a=s.contexts.get(i);if(!a)throw Error(`Context "${i}" not initialized`);await a.ready;let o=r.prompt||``,c=null,l=null,u=r;if(!o&&r.messages){({messages:c}=r),l={chatTemplate:r.chat_template||r.chatTemplate,jinja:r.jinja??!0,tools:r.tools,parallel_tool_calls:r.parallel_tool_calls,tool_choice:r.tool_choice,reasoning_format:r.reasoning_format,enable_thinking:r.enable_thinking,add_generation_prompt:r.add_generation_prompt,now:r.now,chat_template_kwargs:r.chat_template_kwargs,force_pure_content:r.force_pure_content};let e=await a.context.getFormattedChat(c,l.chatTemplate,l);o=e?.prompt||e||``,u=qte(r,e)}if(n&&s.sessionCache.enabled&&o){let{options:e}=await s.sessionCache.prepareCompletionOptions(u,o,a.context),t=await s.sessionCache.generateTempStatePath(),n=(await a.context.tokenize(o))?.tokens?.length||0,r={...e,save_state_path:t},i=s.sessionCache.requiresExactMatch(),c=!!r.load_state_path,l=null;i&&!c&&(l=await s.sessionCache.generateTempStatePath(),r.save_prompt_state_path=l);let d={repoId:s.plan.info.model?.repoId||null,quantization:s.plan.info.model?.quantization||null,variant:s.plan.info.runtime?.variant||null};return Yte(a.context,r,s.sessionCache,o,t,n,s.id,d,l)}let d={repoId:s.plan.info.model?.repoId||null,quantization:s.plan.info.model?.quantization||null,variant:s.plan.info.runtime?.variant||null};return Jte(a.context,u,s.id,d)},tokenize:async(e={})=>{let{text:t=``,params:n={}}=e,r=Fn(s),i=s.contexts.get(r);if(!i)throw Error(`Context "${r}" not initialized`);await i.ready;let a=await i.context.tokenize(t,n);if(!a)return{tokens:[]};let o=Array.from(a.tokens??[],Number);return{...a,tokens:o}},detokenize:async(e={})=>{let{tokens:t=[]}=e,n=Fn(s),r=s.contexts.get(n);if(!r)throw Error(`Context "${n}" not initialized`);await r.ready;let i=t.map(e=>Number(e));return r.context.detokenize(i)},embedding:async(e={})=>{let{text:t=``,params:n={}}=e;if(s.config.model.vocab_only)throw Error(`Embedding is not available on a vocab-only context`);if(!s.config.model.embedding)throw Error("Embedding requires a context loaded with `model.embedding` enabled");let r=Fn(s),i=s.contexts.get(r);if(!i)throw Error(`Context "${r}" not initialized`);await i.ready;let a=await i.context.embedding(t,n);return a?{...a,embedding:Array.from(a.embedding??[],Number)}:{embedding:[]}},applyChatTemplate:async(e={})=>{let{messages:t=[],template:n,params:r}=e,i=Fn(s),a=s.contexts.get(i);if(!a)throw Error(`Context "${i}" not initialized`);return await a.ready,await a.context.getFormattedChat(t,n,r)},releaseContext:async()=>{if(s.finalized)return!1;let e=Fn(s),t=s.contexts.get(e);return t?Qte(s,t,!1):!1},finalize:async()=>{if(s.finalized)return;s.finalized=!0;let e=Array.from(s.contexts.values()),t=e.map(e=>e.released||e.releaseRequested||e.releaseTimer||(e.refCount=Math.max(0,e.refCount-1),e.refCount>0)?Promise.resolve(!1):Rn(s,e));await Promise.allSettled(t),(e.length===0||e.every(e=>e.released))&&await s.sessionCache.cleanup()},getStatus:()=>{let e=[],t=Array.from(s.contexts.entries()).map(([t,n])=>{let r={key:t,refCount:n.refCount,hasModel:!!n.context};if(n.context){let i=n.context.parallel.getStatus();r.parallelStatus=i,e.push({contextKey:t,...i})}return r});return{id:s.id,type:s.type,repoId:s.plan.info.model?.repoId||null,quantization:s.plan.info.model?.quantization||null,variant:s.plan.info.runtime?.variant||null,nCtx:s.plan.info.runtime?.n_ctx||null,nParallel:s.plan.info.runtime?.n_parallel||null,contexts:t,parallelStatuses:e}},subscribeParallelStatus:e=>{let t=Array.from(s.contexts.entries()).filter(([,e])=>e.context).map(([t,n])=>n.context.parallel.subscribeToStatus(n=>{e({contextKey:t,...n})}));return{remove:()=>{t.forEach(e=>{e?.remove&&e.remove()})}}},hasPendingReleases:()=>Array.from(s.contexts.values()).some(e=>!e.released&&(e.releaseRequested||e.releaseTimer||e.refCount>0)),resetFinalized:()=>{s.finalized=!1}}}const zn=e=>{let t=_n(e);return t.model.repo_id||t.model.repository||t.model.model||null},ene=e=>{let t=_n(e);return t.model.vocab_only?`vocab`:t.model.embedding?`embedding`:null};async function tne(e,t,n={}){let{onProgress:r,onComplete:i,onError:a}=n;try{let n=_n(e),o=await jn(n),s=kn(n,o);!n.model.local_path&&!o.localPath&&await nn(s,n.runtime.cache_dir);let{repoId:c}=o,{draftConfig:l,draftArtifact:u}=await An(n),d=u?kn(l,u):null,f=await Mn(n,o).catch(e=>(console.warn(`[Download] Failed to derive mmproj artifact: ${e.message}`),null)),p=Nn(n,f),m=async()=>{if(!f||!p||f.localPath)return;if(await nn(p,n.runtime.cache_dir),await rn(p,f.size)){console.log(`[Download] mmproj already exists: ${p}`);return}let e=t.getDownload(p);if(e){await e;return}let r=(async()=>{try{await cn(f.url,f.headers,p,f.size,e=>{e>=0&&Number.isFinite(e)&&console.log(`[Download] mmproj ${c}: ${Math.round(e*100)}%`)},{allowedRoot:n.runtime.cache_dir})}finally{t.deleteDownload(p)}})();t.setDownload(p,r),await r},h=async()=>{if(!l||!u||!d||u.localPath)return;if(await rn(d,u.size)){console.log(`[Download] Draft model already exists: ${d}`);return}let e=t.getDownload(d);if(e){await e;return}let n=Ln({config:l,artifact:u,localPath:d,localExists:!1,info:{download:{localPath:d,exists:!1}}},new Map,null).finally(()=>{t.deleteDownload(d)});t.setDownload(d,n),await n};if(await rn(s,o.size))return console.log(`[Download] Model already exists: ${c} at ${s}`),await h(),await m().catch(e=>{console.error(`[Download] mmproj download failed: ${e.message}`),typeof a==`function`&&a(e)}),typeof i==`function`&&i({localPath:s,repoId:c,alreadyExists:!0}),{started:!1,localPath:s,repoId:c,alreadyExists:!0};let g=t.getDownload(s);if(g)return console.log(`[Download] Already downloading: ${c}`),g.then(()=>{typeof i==`function`&&i({localPath:s,repoId:c,joinedExisting:!0})}).catch(e=>{typeof a==`function`&&a(e)}),{started:!1,localPath:s,repoId:c,alreadyDownloading:!0};console.log(`[Download] Starting download: ${c}`);let _=(async()=>{try{await In(n,o,s,e=>{console.log(`[Download] ${c}: ${Math.round(e*100)}%`),typeof r==`function`&&r(e)}),await h(),await m(),console.log(`[Download] Completed: ${c}`),typeof i==`function`&&i({localPath:s,repoId:c})}catch(e){throw console.error(`[Download] Failed: ${c}`,e.message),typeof a==`function`&&a(e),e}finally{t.deleteDownload(s)}})();return t.setDownload(s,_),{started:!0,localPath:s,repoId:c}}catch(e){return console.error(`[Download] Failed to start download:`,e.message),typeof a==`function`&&a(e),{started:!1,localPath:null,repoId:null,error:e.message}}}async function nne(e){let t=_n(e),n=await jn(t),{draftArtifact:r}=await An(t),i=await On(n.url,n.headers,t.runtime.cache_dir),{arch:a,nCtxTrain:o,nLayer:s,nEmbd:c,nHead:l,nHeadKv:u,nEmbdHeadK:d,nEmbdHeadV:f,quantVersion:p,fileType:m,attentionLayerCount:h,recurrentLayerCount:g,ssmDConv:_,ssmDState:v,ssmDInner:y,ssmNGroup:b,ssmDtRank:x,rwkvHeadSize:S,rwkvTokenShiftCount:C}=xt(i),w=Number.isFinite(Number(s))?Number(s):0,T=Number.isFinite(Number(c))?Number(c):0,E=Number.isFinite(Number(l))?Number(l):0,D=Number.isFinite(Number(u))?Number(u):E,O=E>0&&T>0?T/E:128,k=d!=null&&Number.isFinite(Number(d))?Number(d):O,ee=f!=null&&Number.isFinite(Number(f))?Number(f):O,A=vt({arch:a,metadata:i,nLayer:w}),te=A&&Number.isFinite(Number(A.kvLayers))?Number(A.kvLayers):w,j=Math.max(0,Math.floor(Number(te)||0)),ne=(t.model.n_ctx?Number(t.model.n_ctx):null)||o||4096,M={k:t.model.cache_type_k,v:t.model.cache_type_v},re=n.size>0?n.size:0,P=r?.size>0?r.size:0,ie=re+P,ae=t.model.n_parallel||4,oe=St({layerCount:j,headKvCount:D,embdHeadKCount:k,embdHeadVCount:ee,cacheTypes:M,swaConfig:A,kvUnified:t.model.kv_unified,nParallel:ae,swaFull:t.model.swa_full,arch:a,attentionLayerCount:h}),se=Ct({nLayer:w,nEmbd:T,recurrentLayerCount:g,nSeqMax:ae,ssmDConv:_,ssmDState:v,ssmDInner:y,ssmNGroup:b,ssmDtRank:x,rwkvHeadSize:S,rwkvTokenShiftCount:C,arch:a}),ce=Jt(t.backend?.gpu_memory_fraction)??(hn.backend.gpu_memory_fraction||1),le=Jt(t.backend?.cpu_memory_fraction)??pn,ue=oe(ne),de=await Pn(t,{modelBytes:ie,kvCacheBytes:ue}),fe=(de.selected.totalMemory||0)*ce,pe=Math.max(0,N.totalmem()*le),me=wt({maxCtx:ne,availableMemory:de.selected.hasGpu?fe:pe,modelBytes:ie,kvBytesForCtx:oe}),he=oe(ne),ge=oe(me);return{kvInfo:{nCtxTrain:o,nLayer:w,nEmbd:T,nHeadKv:D,nEmbdHeadK:k,nEmbdHeadV:ee,nHeadCount:E,nHeadKvCount:D,kvLayerCount:j,swa:A?.enabled?{window:A.window,pattern:A.pattern,denseFirst:A.denseFirst,type:A.type,layers:A.swaLayers}:null},modelBytes:ie,targetModelBytes:re,draftModelBytes:P,kvCacheBytes:he,limitedKvCacheBytes:ge,memoryLimitedCtx:me,recurrentMemoryBytes:se,quantization:{name:n.quantization||null,fileType:m,version:p}}}async function rne(e=null,t={}){let{threshold:n=1.1,includeBreakdown:r=!1,config:i,...a}=t,o=null,s=null,c=null,l=null,u=null,d=null,f=null,p=null,m=null;if(i)try{let{modelBytes:e,targetModelBytes:t,draftModelBytes:n,kvCacheBytes:r,limitedKvCacheBytes:a,memoryLimitedCtx:h,recurrentMemoryBytes:g,kvInfo:_,quantization:v}=await nne(i);o=e,s=t,c=n,l=r,u=a,d=h,f=g,p=_,m=v}catch{}let h=Jt(i?.backend?.gpu_memory_fraction),g=Jt(i?.backend?.cpu_memory_fraction),_=await ft({...a,platform:process.platform,totalMemoryInBytes:N.totalmem(),backend:`ggml-llm`,includeBreakdown:r,gpuMemoryFraction:h,cpuMemoryFraction:g,dependencies:{getBackendDevicesInfo:P,isLibVariantAvailable:ie},modelBytes:o,kvCacheBytes:l,limitedKvCacheBytes:u}),v=_.selected,y=$e(v);v.modelBytes=o||null,v.targetModelBytes=s||null,v.draftModelBytes=c||null,v.kvCacheBytes=l||null,v.memoryLimitedCtx=d||null,v.limitedKvCacheBytes=u||null,v.recurrentMemoryBytes=f||null,v.kvInfo=p||null,v.quantization=m||null;let b=null,x=null;if(e){let t=$e(e);x={...e,score:t};let r=`buttress`,i=`buttress-higher-score`;if(!_.ok)r=`local`,i=`buttress-unavailable`;else if(!t&&t!==0)r=`buttress`,i=`missing-client-score`;else{let e=x.fit,a=x.limitedFit,o=v?.fit,s=v?.limitedFit;({recommendation:r,reason:i}=tt({clientScore:t,buttressScore:y,threshold:n,clientFitsInMemory:et(e,a),buttressFitsInMemory:et(o,s)}))}b={buttressScore:y,clientScore:t,threshold:n,recommendation:r,reason:i}}!_.ok&&!b&&(b={buttressScore:y,clientScore:e?.score??null,threshold:n,recommendation:`local`,reason:`buttress-unavailable`});let S=null;return i&&(S={repoId:i.model?.repo_id||null,quantization:i.model?.quantization||null,nCtx:i.model?.n_ctx||null,cacheKType:i.model?.cache_type_k||`f16`,cacheVType:i.model?.cache_type_v||`f16`}),{type:`ggml-llm`,timestamp:new Date().toISOString(),buttress:_,client:x,comparison:b,modelConfig:S}}const ine=e=>{if(!e)return null;if(e instanceof ArrayBuffer)return e;if(ArrayBuffer.isView(e))return e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength);if(typeof e==`string`){let t=e.startsWith(`data:`)?e.split(`,`)[1]||``:e,n=Buffer.from(t,`base64`);return n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength)}throw Error(`Unsupported audioData format, expected base64 string or ArrayBuffer`)};var Bn=class{constructor(){this.queue=[],this.queueHead=0,this.processing=!1,this.currentTaskId=null}async enqueue(e,t=null){return new Promise((n,r)=>{this.queue.push({task:e,resolve:n,reject:r,taskId:t}),this.processNext()})}async processNext(){if(this.processing||this.queueHead>=this.queue.length)return;this.processing=!0;let e=this.queue[this.queueHead];this.queue[this.queueHead]=null,this.queueHead+=1,this.compactQueueIfNeeded();let{task:t,resolve:n,reject:r,taskId:i}=e;this.currentTaskId=i;try{n(await t())}catch(e){r(e)}finally{this.processing=!1,this.currentTaskId=null,this.processNext()}}compactQueueIfNeeded(){if(this.queueHead===this.queue.length){this.queue=[],this.queueHead=0;return}this.queueHead>64&&this.queueHead*2>=this.queue.length&&(this.queue=this.queue.slice(this.queueHead),this.queueHead=0)}getStatus(){return{processing:this.processing,queuedCount:this.queue.length-this.queueHead,currentTaskId:this.currentTaskId}}};const Vn=`https://huggingface.co`,Hn=`https://huggingface.co/api`,Un=M.join(N.homedir(),`.buttress`,`models`),Wn=[`cuda`,`vulkan`,`snapdragon`,`default`],Gn=[`q8_0`,`q5_1`,`q5_0`,`q4_k`,`q4_1`,`q4_0`],Kn=`fp16`,qn=.5,ane=[`whisper`,`parakeet`],one=[`parakeet-tdt-0.6b-v3`,`parakeet`,`large-v3-turbo`,`distil-large-v3`,`large-v3`,`large-v2`,`large-v1`,`large`,`distil-medium`,`medium.en`,`medium`,`small.en-tdrz`,`distil-small.en`,`small.en`,`small`,`base.en`,`base`,`tiny.en`,`tiny`],Jn=e=>{if(!e)return null;let t=e.toLowerCase();return one.find(e=>t.includes(e))||null},Yn={backend:{type:`ggml-stt`,variant:null,variant_preference:Wn,gpu_memory_fraction:.85,cpu_memory_fraction:qn},model:{repo_id:`BricksDisplay/whisper-ggml`,revision:`main`,filename:null,url:null,quantization:null,preferred_quantizations:[`q8_0`,Kn,`q5_1`],allow_local_file:!1,local_path:null,api_base:Hn,base_url:Vn,use_gpu:!0,use_flash_attn:`auto`},runtime:{cache_dir:Un,prefer_variants:[],huggingface_token:process.env.HUGGINGFACE_TOKEN||null,http_headers:{},max_threads:null,context_release_delay_ms:1e4}},{normalizeVariants:Xn,sanitizeVariant:sne}=Zt(Wn),cne=e=>{let t=e.model.engine&&String(e.model.engine).toLowerCase();return t?t===`parakeet`?`parakeet`:`whisper`:`${e.model.repo_id||``} ${e.model.filename||``} ${e.model.url||``}`.toLowerCase().includes(`parakeet`)?`parakeet`:`whisper`},Zn=(e={})=>{let t=structuredClone(Yn);if(qt(t,e),t.model.engine=cne(t),t.model.engine===`parakeet`&&t.model.repo_id===Yn.model.repo_id&&!t.model.url&&(t.model.repo_id=`ggml-org/parakeet-GGUF`),t.backend.variant=sne(t.backend.variant),t.backend.variant_preference=Xn(t.backend.variant_preference||Wn),t.backend.variant_preference.length===0&&(t.backend.variant_preference=[...Wn]),t.runtime.prefer_variants=Xn(t.runtime.prefer_variants),t.model.preferred_quantizations=Xt(t.model.preferred_quantizations||t.model.quantizations),t.model.quantization){let e=String(t.model.quantization).toLowerCase();t.model.preferred_quantizations.includes(e)||t.model.preferred_quantizations.unshift(e)}t.model.base_url=t.model.base_url||Vn,t.model.api_base=t.model.api_base||Hn,t.runtime.cache_dir=t.runtime.cache_dir?M.resolve(t.runtime.cache_dir):Un;let n=Number(t.runtime.context_release_delay_ms);return t.runtime.context_release_delay_ms=Number.isFinite(n)?Math.max(0,n):Yn.runtime.context_release_delay_ms,t},Qn=e=>{let t=e.toLowerCase();return Gn.find(e=>t.includes(e))||null},lne=e=>{let t=[];return e.backend.variant&&t.push(e.backend.variant),e.runtime.prefer_variants.length>0&&t.push(...e.runtime.prefer_variants),t.push(...e.backend.variant_preference),t.push(`default`),Xn(t)},$n=ln({defaultBaseDir:Un}),er=(e,t)=>e.model.local_path?M.resolve(e.model.local_path):tn(e.runtime.cache_dir,t,`model`),tr=async e=>{let t=e.model.repo_id||e.model.repository||e.model.model;if(!t)throw Error("`model.repo_id` is required in Buttress backend config");let n=e.model.revision||`main`,r=e.runtime.cache_dir,i=JSON.stringify({repoId:t,revision:n,filename:e.model.filename,url:e.model.url,quantization:e.model.quantization,preferred_quantizations:e.model.preferred_quantizations}),a=await $n.read(i,`artifact-info`,r);if(a)return a;let o={...e.runtime.http_headers||{}};if(e.runtime.huggingface_token&&(o.Authorization=`Bearer ${e.runtime.huggingface_token}`),e.model.url){let a=await on(e.model.url,{headers:o}),s=Number(a.headers.get(`content-length`))||null,c=e.model.filename||e.model.url.split(`/`).pop(),l={repoId:t,revision:n,filename:c,url:e.model.url,size:s,quantization:Qn(c||``),headers:o};return await $n.write(i,`artifact-info`,l,r),l}let{filename:s}=e.model,c=e.model.quantization&&String(e.model.quantization).toLowerCase(),l=await an(`${e.model.api_base}/models/${t}?revision=${n}&blobs=true`,{headers:o}),u=(l?.siblings||l?.files||[]).map(e=>e.rfilename||e.path||e.filename).filter(e=>typeof e==`string`&&e.endsWith(`.bin`));if(u.length===0)throw Error(`No model artifacts found in repo ${t}`);let d=e.model.preferred_quantizations.length>0?e.model.preferred_quantizations:Gn,f=()=>{for(let e of d)if(e===Kn){let e=u.find(e=>{let t=e.toLowerCase();return!Gn.some(e=>t.includes(e))});if(e)return{filename:e,quantization:null}}else{let t=u.find(t=>t.toLowerCase().includes(e));if(t)return{filename:t,quantization:e}}return null};if(s)c||=Qn(s);else{let{filename:e,quantization:t}=f()||{filename:u[0],quantization:null};s=e,c=t||Qn(s)}let p=`${e.model.base_url.replace(/\/+$/,``)}/${t}/resolve/${n}/${s}`,m=await on(p,{headers:o}),h=Number(m.headers.get(`content-length`))||null,g={repoId:t,revision:n,filename:s,url:p,size:h,quantization:c,headers:o,isSplit:!1,splitCount:0};return await $n.write(i,`artifact-info`,g,r),g},une=async(e,{modelBytes:t=null,processingBytes:n=null}={})=>{let r=lne(e),[i,...a]=r,o=Jt(e.backend?.gpu_memory_fraction)??(Yn.backend.gpu_memory_fraction||1),s=Jt(e.backend?.cpu_memory_fraction)??qn,c=await ft({platform:process.platform,totalMemoryInBytes:N.totalmem(),backend:`ggml-stt`,variant:i||null,preferVariants:a,variantPreference:e.backend.variant_preference,gpuMemoryFraction:o,cpuMemoryFraction:s,dependencies:{getBackendDevicesInfo:P,isLibVariantAvailable:ie},modelBytes:t,kvCacheBytes:n}),l=e=>({...e,devices:Array.isArray(e.devices)?e.devices:[],ok:e.ok,hasGpu:!!e.hasGpu,totalMemory:e.gpuTotalBytes||e.totalMemory||0,error:e.ok?null:Error(e.error||`Variant ${e.variant} not available on this platform`)});if(!c.ok||!c.selected){let e=(c.attempts||[]).map(e=>`${e.variant}: ${e.error||`unknown error`}`).join(`; `);throw Error(`Unable to initialize any backend variant (${r.join(`, `)}). Errors: ${e}`)}let u=(c.attempts||[]).map(l);return{selected:l(c.selected),attempts:u}},nr=(e,t)=>e===`parakeet`?Gee(t):Wee(t),dne=async e=>{let{engine:t}=e.model,n=await tr(e),r=nr(t,{modelBytes:n.size>0?n.size:0}),i=await une(e,{modelBytes:r.modelBytes,processingBytes:r.processingBufferBytes}),a=i.selected.hasGpu&&(i.selected.fit?.fitsInGpu===void 0||i.selected.fit.fitsInGpu);e.model.use_gpu===!1&&(a=!1);let o=e.model.use_flash_attn&&String(e.model.use_flash_attn).toLowerCase(),s;s=t===`parakeet`?!1:o===`on`||o===`true`?!0:o===`off`||o===`false`?!1:a;let c=e.runtime.cache_dir,l=er(e,n),u=await rn(l,n.size);return{config:e,info:{ok:!0,backend:`ggml-stt`,engine:t,model:{repoId:n.repoId,revision:n.revision,filename:n.filename,quantization:n.quantization,modelType:Jn(n.filename),engine:t,url:n.url,sizeBytes:n.size},runtime:{variant:i.selected.variant,use_gpu:a,use_flash_attn:s,max_threads:e.runtime.max_threads?Number(e.runtime.max_threads):null},resources:{...r,gpuCapacityBytes:i.selected.gpuTotalBytes,gpuUsableBytes:i.selected.gpuUsableBytes,cpuUsableBytes:i.selected.cpuUsableBytes,fit:i.selected.fit},devices:{selected:i.selected,attempts:i.attempts},download:{cacheDir:c,localPath:l,exists:u},timestamp:new Date().toISOString()},artifact:n,memory:r,devices:i,localPath:l,localExists:u}},fne=async(e,t,n,r=null)=>{let{localPath:i,artifact:a,config:o}=e;if(o.model.local_path||await nn(i,o.runtime.cache_dir),e.localExists)return typeof n==`function`&&n(1),i;if(r){let t=r.getDownload(i);if(t){console.log(`[ensureModelFile] Waiting for global STT download: ${a.repoId}`);try{if(await t,await rn(i,a.size))return e.localExists=!0,e.info.download.exists=!0,typeof n==`function`&&n(1),i}catch(e){console.warn(`[ensureModelFile] Global STT download failed, will retry: ${e.message}`)}}}let s=t.get(i);if(s)return await s,typeof n==`function`&&n(1),i;let c=(async()=>{if(o.model.allow_local_file){if(!await rn(i,a.size))throw Error(`Local model file not found: ${i}`);return i}return await cn(a.url,a.headers,i,a.size,n,{allowedRoot:o.runtime.cache_dir}),i})();t.set(i,c);try{return await c,i}finally{t.delete(i)}},pne=async(e,t)=>{if(e.contextRecord&&!e.contextRecord.released)return e.contextRecord.releaseTimer&&(clearTimeout(e.contextRecord.releaseTimer),e.contextRecord.releaseTimer=null,console.log(`[Context] Cancelled pending STT release`)),e.contextRecord.releaseRequested=!1,e.contextRecord.refCount+=1,console.log(`[Context] Reusing existing STT context, refCount=${e.contextRecord.refCount}`),typeof t==`function`&&t(0),e.contextRecord.context||await e.contextRecord.ready,typeof t==`function`&&t(1),e.contextRecord;e.contextRecord?console.log(`[Context] STT record exists but released=${e.contextRecord.released}, creating new context`):console.log(`[Context] No existing STT record, creating new context`);let n={refCount:1,ready:null,released:!1};e.contextRecord=n,n.ready=(async()=>{let r=Date.now();try{typeof t==`function`&&t(0);let i=await fne(e.plan,e.downloads,t,e.globalDownloadManager);typeof t==`function`&&t(.5);let a=e.plan.info.engine===`parakeet`?await de({filePath:i,useGpu:!!e.plan.info.runtime.use_gpu},e.plan.info.runtime.variant):await fe({filePath:i,useFlashAttn:!!e.plan.info.runtime.use_flash_attn,useGpu:!!e.plan.info.runtime.use_gpu,nThreads:e.plan.info.runtime.max_threads},e.plan.info.runtime.variant);typeof t==`function`&&t(1),n.context=a;try{n.modelInfo=a.getModelInfo()}catch{n.modelInfo=null}return Ft.addModelLoad({id:e.id,generatorId:e.id,repoId:e.plan.info.model?.repoId||null,quantization:e.plan.info.model?.quantization||null,modelType:e.plan.info.model?.modelType||null,variant:e.plan.info.runtime?.variant||null,useGpu:e.plan.info.runtime?.use_gpu||!1,durationMs:Date.now()-r,success:!0}),n}catch(t){throw Ft.addModelLoad({id:e.id,generatorId:e.id,repoId:e.plan.info.model?.repoId||null,quantization:e.plan.info.model?.quantization||null,modelType:e.plan.info.model?.modelType||null,variant:e.plan.info.runtime?.variant||null,durationMs:Date.now()-r,success:!1,error:t?.message||String(t)}),t}})();try{return await n.ready,typeof t==`function`&&t(1),n}catch(t){throw e.contextRecord=null,t}},rr=async(e,t,n=!1)=>t.released||!n&&t.refCount>0?!1:(t.released=!0,e.contextRecord=null,await t.context?.release?.(),!0),mne=async(e,t,n=!1)=>{if(t.releaseRequested=!0,t.releaseTimer&&=(clearTimeout(t.releaseTimer),null),n)t.refCount=0;else if(t.refCount=Math.max(0,t.refCount-1),t.refCount>0)return t.releaseRequested=!1,!1;let r=e.config.runtime.context_release_delay_ms;if(typeof r!=`number`||!Number.isFinite(r))return rr(e,t);let i=Math.max(0,Math.floor(r));return n||i<=0?rr(e,t):(console.log(`[Context] Scheduling STT release in ${i}ms`),t.releaseTimer=setTimeout(async()=>{if(t.releaseTimer=null,t.refCount>0){console.log(`[Context] STT release cancelled, refCount=${t.refCount}`),t.releaseRequested=!1;return}console.log(`[Context] Releasing STT context after ${i}ms delay`),await rr(e,t)},i),!0)};async function hne(e,t,n={}){let{globalDownloadManager:r=null}=n,i=Zn(t),a=await dne(i),o={id:e,type:`ggml-stt`,config:i,plan:a,info:a.info,contextRecord:null,downloads:new Map,globalDownloadManager:r,queue:new Bn,finalized:!1},s=async()=>{if(o.finalized)return;o.finalized=!0;let e=o.contextRecord;e&&(e.released||e.releaseRequested||e.releaseTimer||(e.refCount=Math.max(0,e.refCount-1),!(e.refCount>0)&&await rr(o,e)))},c=async(e={})=>{let{onProgress:t}=e;try{let e=await pne(o,t);return{modelInfo:e.modelInfo&&typeof e.modelInfo==`object`?{...e.modelInfo}:null,runtime:{...o.plan.info.runtime},download:{...o.plan.info.download}}}catch(e){throw console.error(`[Context] Error initializing context:`,e),e}},l=async()=>{if(o.finalized)return!1;let e=o.contextRecord;return e?mne(o,e):!1},u=async(e={})=>{let{audioPath:t,audioData:n,options:r={}}=e,i=o.contextRecord;if(!i)throw Error(`Context not initialized`);let a={...r};o.plan.info.engine===`parakeet`&&(a={...r.maxThreads!=null&&{maxThreads:r.maxThreads},...r.audioCtx!=null&&{audioCtx:r.audioCtx}}),o.plan.info.runtime.max_threads&&a.maxThreads==null&&(a.maxThreads=o.plan.info.runtime.max_threads);let s=`transcription-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,c=Date.now();return o.queue.enqueue(async()=>{await i.ready;try{let e;if(n){let t=ine(n),{promise:r}=i.context.transcribeData(t,a);e=await r}else{if(!t)throw Error(`audioPath or audioData is required for transcription`);let n=M.resolve(t),{promise:r}=i.context.transcribe(n,a);e=await r}return Ft.addTranscription({id:s,generatorId:o.id,repoId:o.plan.info.model?.repoId||null,quantization:o.plan.info.model?.quantization||null,modelType:o.plan.info.model?.modelType||null,variant:o.plan.info.runtime?.variant||null,durationMs:Date.now()-c,segmentCount:e?.segments?.length||0,textLength:e?.text?.length||0,success:!0}),e}catch(e){throw Ft.addTranscription({id:s,generatorId:o.id,repoId:o.plan.info.model?.repoId||null,quantization:o.plan.info.model?.quantization||null,modelType:o.plan.info.model?.modelType||null,variant:o.plan.info.runtime?.variant||null,durationMs:Date.now()-c,success:!1,error:e?.message||String(e)}),e}},s)};return{id:e,type:`ggml-stt`,info:a.info,queue:o.queue,initContext:c,transcribe:async(e={})=>u(e),transcribeData:async(e={})=>u(e),releaseContext:l,finalize:s,getStatus:()=>({id:o.id,type:o.type,engine:o.plan.info.engine,repoId:o.plan.info.model?.repoId||null,quantization:o.plan.info.model?.quantization||null,modelType:o.plan.info.model?.modelType||null,variant:o.plan.info.runtime?.variant||null,hasContext:!!o.contextRecord?.context,contextRefCount:o.contextRecord?.refCount||0,queueStatus:o.queue.getStatus()}),hasPendingReleases:()=>{let e=o.contextRecord;return e?!e.released&&(e.releaseRequested||e.releaseTimer||e.refCount>0):!1},resetFinalized:()=>{o.finalized=!1}}}const ir=e=>{let t=Zn(e),n=t.model.repo_id||t.model.repository||t.model.model||null;if(!n)return null;let r=Jn(t.model.filename);return r?`${n}:${r}`:n};async function gne(e,t,n={}){let{onProgress:r,onComplete:i,onError:a}=n;try{let n=Zn(e),o=await tr(n),s=er(n,o),{repoId:c}=o;if(n.model.local_path||await nn(s,n.runtime.cache_dir),await rn(s,o.size))return console.log(`[Download] STT model already exists: ${c} at ${s}`),typeof i==`function`&&i({localPath:s,repoId:c,alreadyExists:!0}),{started:!1,localPath:s,repoId:c,alreadyExists:!0};let l=t.getDownload(s);if(l)return console.log(`[Download] Already downloading STT model: ${c}`),l.then(()=>{typeof i==`function`&&i({localPath:s,repoId:c,joinedExisting:!0})}).catch(e=>{typeof a==`function`&&a(e)}),{started:!1,localPath:s,repoId:c,alreadyDownloading:!0};console.log(`[Download] Starting STT model download: ${c}`);let u=(async()=>{try{await cn(o.url,o.headers,s,o.size,e=>{e>=0&&Number.isFinite(e)&&(console.log(`[Download] ${c}: ${Math.round(e*100)}%`),typeof r==`function`&&r(e))},{allowedRoot:n.runtime.cache_dir}),console.log(`[Download] Completed STT model: ${c}`),typeof i==`function`&&i({localPath:s,repoId:c})}catch(e){throw console.error(`[Download] Failed STT model: ${c}`,e.message),typeof a==`function`&&a(e),e}finally{t.deleteDownload(s)}})();return t.setDownload(s,u),{started:!0,localPath:s,repoId:c}}catch(e){return console.error(`[Download] Failed to start STT download:`,e.message),typeof a==`function`&&a(e),{started:!1,localPath:null,repoId:null,error:e.message}}}async function _ne(e=null,t={}){let{threshold:n=1.1,includeBreakdown:r=!1,config:i,...a}=t,o=null,s=null,c=null,l=null;if(i){let e=Zn(i);l=e.model.engine;try{let t=await tr(e);o=t.size??null,{processingBufferBytes:s}=nr(l,{modelBytes:o}),c=t.quantization||null}catch{}}let u=Jt(i?.backend?.gpu_memory_fraction),d=Jt(i?.backend?.cpu_memory_fraction),f=await ft({...a,platform:process.platform,totalMemoryInBytes:N.totalmem(),backend:`ggml-stt`,includeBreakdown:r,gpuMemoryFraction:u,cpuMemoryFraction:d,dependencies:{getBackendDevicesInfo:P,isLibVariantAvailable:ie},modelBytes:o,kvCacheBytes:s}),p=f.selected,m=$e(p);p&&(p.modelBytes=o||null,p.processingBytes=s||null,p.quantization=c||null);let h=null,g=null;if(e){let t=$e(e);g={...e,score:t};let r=`buttress`,i=`buttress-higher-score`;if(!f.ok)r=`local`,i=`buttress-unavailable`;else if(!t&&t!==0)r=`buttress`,i=`missing-client-score`;else{let a=e.fit&&p?.fit;({recommendation:r,reason:i}=tt({clientScore:t,buttressScore:m,threshold:n,clientFitsInMemory:a?et(e.fit):!1,buttressFitsInMemory:a?et(p.fit):!1}))}h={buttressScore:m,clientScore:t,threshold:n,recommendation:r,reason:i}}!f.ok&&!h&&(h={buttressScore:m,clientScore:e?.score??null,threshold:n,recommendation:`local`,reason:`buttress-unavailable`});let _=null;return i&&(_={repoId:i.model?.repo_id||null,quantization:i.model?.quantization||null,filename:i.model?.filename||null,engine:l}),{type:`ggml-stt`,engines:[...ane],timestamp:new Date().toISOString(),buttress:f,client:g,comparison:h,modelConfig:_}}const ar=e=>M.join(e,`.tts-cache`),or=e=>M.join(ar(e),`audio`),sr=e=>M.join(ar(e),`cache-map.json`),cr=(e,t,n)=>{let r=JSON.stringify({text:e,model:t,options:n});return A(`sha256`).update(r).digest(`hex`).slice(0,24)};var lr=class{constructor(e){this.baseDir=e.runtime.cache_dir,this.enabled=e.runtime.output_cache?.enabled!==!1,this.maxSizeBytes=e.runtime.output_cache?.max_size_bytes??2147483648,this.maxEntries=e.runtime.output_cache?.max_entries??5e3,this.cacheMap=null}async load(){if(this.enabled)try{let e=await S(sr(this.baseDir),`utf-8`);this.cacheMap=JSON.parse(e),this.cacheMap?.entries||(this.cacheMap={entries:{},totalSize:0})}catch{this.cacheMap={entries:{},totalSize:0}}}async save(){if(!this.cacheMap)return;let e=sr(this.baseDir);await b(M.dirname(e),{recursive:!0}),await k(e,JSON.stringify(this.cacheMap,null,2),`utf-8`)}async lookup(e,t,n){if(!this.enabled||!this.cacheMap)return null;let r=cr(e,t,n),i=this.cacheMap.entries[r];if(!i)return null;try{await D(i.filePath)}catch{return delete this.cacheMap.entries[r],this.cacheMap.totalSize-=i.fileSize||0,await this.save(),null}return i.lastAccessedAt=new Date().toISOString(),await this.save(),i}async store(e,t,n,r,i,a){if(!this.enabled||!this.cacheMap)return null;let o=cr(e,t,n),s=or(this.baseDir);await b(s,{recursive:!0});let c=M.join(s,`${o}.wav`),l=Buffer.from(r);await k(c,l);let u=l.length,d=this.cacheMap.entries[o];return d&&(this.cacheMap.totalSize-=d.fileSize||0),this.cacheMap.entries[o]={id:o,filePath:c,fileSize:u,samplingRate:i,channels:a,text:e.slice(0,200),createdAt:new Date().toISOString(),lastAccessedAt:new Date().toISOString()},this.cacheMap.totalSize+=u,await this.evict(),await this.save(),this.cacheMap.entries[o]}async evict(){if(!this.cacheMap)return;let{totalSize:e}=await Kt({entries:this.cacheMap.entries,totalSize:this.cacheMap.totalSize,maxEntries:this.maxEntries,maxSizeBytes:this.maxSizeBytes,removeEntry:e=>O(e.filePath).catch(()=>{})});this.cacheMap.totalSize=e}};const ur=async({cache:e,cacheDir:t,text:n,modelInfo:r,options:i,wavBuffer:a,samplingRate:o,channels:s=1})=>{let c=await e.store(n,r,i,a,o,s);if(c)return{cachedId:c.id,cachedFile:c.filePath,sampling_rate:o,channels:s};let l=cr(n,r,i),u=or(t);await b(u,{recursive:!0});let d=M.join(u,`tmp-${l}.wav`);return await k(d,Buffer.from(a)),{cachedId:l,cachedFile:d,sampling_rate:o,channels:s}},vne=(e,t,n)=>{let r=Buffer.alloc(44),i=16*e*t>>3,a=16*t>>3;return r.write(`RIFF`,0),r.writeUInt32LE(n+44-8,4),r.write(`WAVE`,8),r.write(`fmt `,12),r.writeUInt32LE(16,16),r.writeUInt16LE(1,20),r.writeUInt16LE(t,22),r.writeUInt32LE(e,24),r.writeUInt32LE(i,28),r.writeUInt16LE(a,32),r.writeUInt16LE(16,34),r.write(`data`,36),r.writeUInt32LE(n,40),r},yne=(e,t,n=1)=>{let r=Buffer.allocUnsafe(e.length*2);for(let t=0;t<e.length;t+=1){let n=Math.max(-1,Math.min(1,e[t]));r.writeInt16LE(Math.round(n*32767),t*2)}return Buffer.concat([vne(t,n,r.length),r])},dr=`https://huggingface.co`,fr=`https://huggingface.co/api`,pr=M.join(N.homedir(),`.buttress`,`models`),mr=[`cuda`,`vulkan`,`default`],hr=[`q8_0`,`q6_k`,`q5_k_m`,`q5_1`,`q4_k_m`,`q4_0`],gr=`fp16`,_r=.5,vr=[`outetts`,`soprano`,`neutts`,`csm`,`qwen3_tts`,`moss_tts`,`moss_ttsd`,`chatterbox`,`bluemagpie`],yr=24e3,br={backend:{type:`ggml-tts`,variant:null,variant_preference:mr,gpu_memory_fraction:.85,cpu_memory_fraction:_r},model:{repo_id:null,revision:`main`,filename:null,url:null,quantization:null,preferred_quantizations:[`q4_k_m`,`q8_0`,gr],vocoder_repo_id:null,vocoder_revision:null,vocoder_filename:null,vocoder_url:null,vocoder_quantization:null,allow_local_file:!1,local_path:null,vocoder_local_path:null,api_base:fr,base_url:dr,use_gpu:!0,n_gpu_layers:99,sample_rate:yr},runtime:{cache_dir:pr,prefer_variants:[],huggingface_token:process.env.HUGGINGFACE_TOKEN||null,http_headers:{},n_ctx:8192,n_batch:8192,n_ubatch:512,max_threads:null,vocoder_batch_size:4096,use_mlock:!1,use_mmap:!0,flash_attn_type:`off`,context_release_delay_ms:1e4,output_cache:{enabled:!0,max_size_bytes:2*1024*1024*1024,max_entries:5e3}}},{normalizeVariants:xr,sanitizeVariant:bne}=Zt(mr),Sr=(e={})=>{let t=structuredClone(br);if(qt(t,e),t.backend.variant=bne(t.backend.variant),t.backend.variant_preference=xr(t.backend.variant_preference||mr),t.backend.variant_preference.length===0&&(t.backend.variant_preference=[...mr]),t.runtime.prefer_variants=xr(t.runtime.prefer_variants),t.model.preferred_quantizations=Xt(t.model.preferred_quantizations||t.model.quantizations),t.model.quantization){let e=String(t.model.quantization).toLowerCase();t.model.preferred_quantizations.includes(e)||t.model.preferred_quantizations.unshift(e)}t.model.base_url=t.model.base_url||dr,t.model.api_base=t.model.api_base||fr,t.model.vocoder_revision=t.model.vocoder_revision||t.model.revision,t.model.sample_rate=Number(t.model.sample_rate)||yr,t.runtime.cache_dir=t.runtime.cache_dir?M.resolve(t.runtime.cache_dir):pr;let n=Number(t.runtime.context_release_delay_ms);return t.runtime.context_release_delay_ms=Number.isFinite(n)?Math.max(0,n):br.runtime.context_release_delay_ms,t},Cr=e=>{let t=(e||``).toLowerCase();return hr.find(e=>t.includes(e))||null},xne=e=>e.toLowerCase().replace(/\.gguf$/,``).replace(/[-_.](q\d[a-z0-9_]*|f16|fp16|f32|bf16|mxfp4)$/,``),Sne=e=>{let t=[];return e.backend.variant&&t.push(e.backend.variant),t.push(...e.runtime.prefer_variants),t.push(...e.backend.variant_preference),t.push(`default`),xr(t)},wr=ln({defaultBaseDir:pr}),Tr=async(e,t=`model`)=>{let n=t===`vocoder`,r=n&&e.model.vocoder_repo_id||e.model.repo_id;if(!r)throw Error(n?"`model.vocoder_repo_id` (or `model.repo_id`) is required in Buttress GGML-TTS backend config":"`model.repo_id` is required in Buttress GGML-TTS backend config");let i=(n?e.model.vocoder_revision:e.model.revision)||`main`,a=n?e.model.vocoder_url:e.model.url,o=n?e.model.vocoder_filename:e.model.filename,s=n?e.model.vocoder_quantization:e.model.quantization,c=e.runtime.cache_dir,l=JSON.stringify({role:t,repoId:r,revision:i,filename:o,url:a,quantization:s,preferred_quantizations:e.model.preferred_quantizations}),u=await wr.read(l,`artifact-info`,c);if(u)return u;let d={...e.runtime.http_headers||{}};if(e.runtime.huggingface_token&&(d.Authorization=`Bearer ${e.runtime.huggingface_token}`),a){let e=await on(a,{headers:d}),n=o||a.split(`/`).pop(),u={role:t,repoId:r,revision:i,filename:n,url:a,size:Number(e.headers.get(`content-length`))||null,quantization:s||Cr(n),headers:d};return await wr.write(l,`artifact-info`,u,c),u}let f=o,p=s&&String(s).toLowerCase();if(f)p||=Cr(f);else{let t=await an(`${e.model.api_base}/models/${r}?revision=${i}&blobs=true`,{headers:d}),a=(t?.siblings||t?.files||[]).map(e=>e.rfilename||e.path||e.filename).filter(e=>typeof e==`string`&&e.endsWith(`.gguf`));if(a.length===0)throw Error(`No GGUF artifacts found in repo ${r}`);let o=e=>/codec|vocoder|wavtokenizer|dac|mimi/i.test(e),s=a.filter(e=>o(e)===n),c=s.length>0?s:a;if(n){let e=new Set(c.map(xne));if(e.size>1)throw Error(`Repo ${r} contains multiple codecs (${Array.from(e).sort().join(`, `)}). Set \`model.vocoder_filename\` to the one matching your TTS backbone.`)}let l=e.model.preferred_quantizations.length>0?e.model.preferred_quantizations:hr,u=null;for(let e of l)if(e===gr){let e=c.find(e=>!hr.some(t=>e.toLowerCase().includes(t)));if(e){u={filename:e,quantization:null};break}}else{let t=c.find(t=>t.toLowerCase().includes(e));if(t){u={filename:t,quantization:e};break}}u||={filename:c[0],quantization:null},f=u.filename,p=u.quantization||Cr(f)}let m=`${e.model.base_url.replace(/\/+$/,``)}/${r}/resolve/${i}/${f}`,h=await on(m,{headers:d}),g={role:t,repoId:r,revision:i,filename:f,url:m,size:Number(h.headers.get(`content-length`))||null,quantization:p,headers:d};return await wr.write(l,`artifact-info`,g,c),g},Er=(e,t)=>{let n=t.role===`vocoder`?e.model.vocoder_local_path:e.model.local_path;return n?M.resolve(n):tn(e.runtime.cache_dir,t,`model`)},Cne=async(e,{modelBytes:t=null,processingBytes:n=null}={})=>{let r=Sne(e),[i,...a]=r,o=Jt(e.backend?.gpu_memory_fraction)??br.backend.gpu_memory_fraction,s=Jt(e.backend?.cpu_memory_fraction)??_r,c=await ft({platform:process.platform,totalMemoryInBytes:N.totalmem(),backend:`ggml-tts`,variant:i||null,preferVariants:a,variantPreference:e.backend.variant_preference,gpuMemoryFraction:o,cpuMemoryFraction:s,dependencies:{getBackendDevicesInfo:P,isLibVariantAvailable:ie},modelBytes:t,processingBytes:n});if(!c.ok||!c.selected){let e=(c.attempts||[]).map(e=>`${e.variant}: ${e.error||`unknown error`}`).join(`; `);throw Error(`Unable to initialize any backend variant (${r.join(`, `)}). Errors: ${e}`)}return{selected:c.selected,attempts:c.attempts||[]}},wne=async e=>{let t=await Tr(e,`model`),n=await Tr(e,`vocoder`),r=ht({modelBytes:t.size||0,vocoderBytes:n.size||0,contextSize:e.runtime.n_ctx,vocoderBatchSize:e.runtime.vocoder_batch_size}),i=await Cne(e,{modelBytes:r.modelBytes,processingBytes:r.processingBufferBytes}),a=i.selected.hasGpu&&(i.selected.fit?.fitsInGpu===void 0||i.selected.fit.fitsInGpu);e.model.use_gpu===!1&&(a=!1);let o=Er(e,t),s=Er(e,n);return{config:e,info:{ok:!0,backend:`ggml-tts`,families:[...vr],model:{repoId:t.repoId,revision:t.revision,filename:t.filename,quantization:t.quantization,url:t.url,sizeBytes:t.size,vocoderRepoId:n.repoId,vocoderFilename:n.filename,vocoderSizeBytes:n.size,sampleRate:e.model.sample_rate},runtime:{variant:i.selected.variant,use_gpu:a,n_gpu_layers:a?e.model.n_gpu_layers:0,n_ctx:e.runtime.n_ctx,n_batch:e.runtime.n_batch,n_ubatch:e.runtime.n_ubatch,vocoder_batch_size:e.runtime.vocoder_batch_size,max_threads:e.runtime.max_threads?Number(e.runtime.max_threads):null,use_mlock:!!e.runtime.use_mlock,use_mmap:e.runtime.use_mmap!==!1,flash_attn_type:e.runtime.flash_attn_type},resources:{...r,gpuCapacityBytes:i.selected.gpuTotalBytes,gpuUsableBytes:i.selected.gpuUsableBytes,cpuUsableBytes:i.selected.cpuUsableBytes,fit:i.selected.fit},devices:i,download:{cacheDir:e.runtime.cache_dir,localPath:o,vocoderLocalPath:s,exists:await rn(o,t.size),vocoderExists:await rn(s,n.size)},timestamp:new Date().toISOString()},artifact:t,vocoderArtifact:n,memory:r,devices:i,localPath:o,vocoderLocalPath:s}},Dr=async({config:e,artifact:t,localPath:n,downloads:r,onProgress:i,globalDownloadManager:a})=>{if((t.role===`vocoder`?e.model.vocoder_local_path:e.model.local_path)||await nn(n,e.runtime.cache_dir),await rn(n,t.size))return i?.(1),n;let o=a?.getDownload(n);if(o)try{if(await o,await rn(n,t.size))return i?.(1),n}catch(e){console.warn(`[ensureArtifactFile] Global TTS download failed, will retry: ${e.message}`)}let s=r.get(n);if(s)return await s,i?.(1),n;let c=(async()=>{if(e.model.allow_local_file){if(!await rn(n,t.size))throw Error(`Local model file not found: ${n}`);return n}return await cn(t.url,t.headers,n,t.size,i,{allowedRoot:e.runtime.cache_dir}),n})();r.set(n,c);try{return await c}finally{r.delete(n)}},Tne=(e,t,n)=>{let{audio_tokens:r,embeddings:i,embedding_dim:a}=t;if(n===`continuous_embd`||i?.length&&a){if(!i?.length)throw Error(`No audio embeddings generated`);return e.decodeAudioEmbeddings(i,a)}if(!r?.length)throw Error(`No audio tokens generated`);return e.decodeAudioTokens(r)},Ene=async(e,t)=>{if(e.contextRecord&&!e.contextRecord.released)return e.contextRecord.releaseTimer&&(clearTimeout(e.contextRecord.releaseTimer),e.contextRecord.releaseTimer=null),e.contextRecord.releaseRequested=!1,e.contextRecord.refCount+=1,t?.(0),e.contextRecord.context||await e.contextRecord.ready,t?.(1),e.contextRecord;let n={refCount:1,ready:null,released:!1};e.contextRecord=n,n.ready=(async()=>{let r=Date.now(),{info:i}=e.plan;try{t?.(0);let a=await Dr({config:e.config,artifact:e.plan.artifact,localPath:e.plan.localPath,downloads:e.downloads,onProgress:e=>t?.(e*.3),globalDownloadManager:e.globalDownloadManager}),o=await Dr({config:e.config,artifact:e.plan.vocoderArtifact,localPath:e.plan.vocoderLocalPath,downloads:e.downloads,onProgress:e=>t?.(.3+e*.2),globalDownloadManager:e.globalDownloadManager}),s=await ae({model:a,n_ctx:i.runtime.n_ctx,n_batch:i.runtime.n_batch,n_ubatch:i.runtime.n_ubatch,n_threads:i.runtime.max_threads??void 0,n_gpu_layers:i.runtime.n_gpu_layers,use_mlock:i.runtime.use_mlock,use_mmap:i.runtime.use_mmap,flash_attn_type:i.runtime.flash_attn_type,lib_variant:i.runtime.variant},e=>t?.(.5+e/100*.4));try{await s.initVocoder({path:o,n_batch:i.runtime.vocoder_batch_size})}catch(e){throw await s.release?.().catch(()=>{}),e}return t?.(1),n.context=s,n.capabilities=s.getTTSCapabilities(),n.sampleRate=Number(s.getAudioSampleRate())||i.model.sampleRate,n.modelInfo={repoId:i.model.repoId,filename:i.model.filename,quantization:i.model.quantization,vocoderRepoId:i.model.vocoderRepoId,vocoderFilename:i.model.vocoderFilename,sampleRate:n.sampleRate,family:n.capabilities?.family||null,promptKind:n.capabilities?.promptKind||null,requiresPhonemes:!!n.capabilities?.requiresPhonemes},It.addModelLoad({id:e.id,generatorId:e.id,repoId:i.model.repoId,quantization:i.model.quantization,vocoderRepoId:i.model.vocoderRepoId,family:n.modelInfo.family,variant:i.runtime.variant,useGpu:i.runtime.use_gpu,durationMs:Date.now()-r,success:!0}),n}catch(t){throw It.addModelLoad({id:e.id,generatorId:e.id,repoId:i.model?.repoId||null,quantization:i.model?.quantization||null,variant:i.runtime?.variant||null,durationMs:Date.now()-r,success:!1,error:t?.message||String(t)}),t}})();try{return await n.ready,t?.(1),n}catch(t){throw e.contextRecord=null,t}},Or=async(e,t,n=!1)=>{if(t.released||!n&&t.refCount>0)return!1;t.released=!0,e.contextRecord=null;try{await t.context?.releaseVocoder?.()}catch{}return await t.context?.release?.(),!0},Dne=async(e,t,n=!1)=>{if(t.releaseRequested=!0,t.releaseTimer&&=(clearTimeout(t.releaseTimer),null),n)t.refCount=0;else if(t.refCount=Math.max(0,t.refCount-1),t.refCount>0)return t.releaseRequested=!1,!1;let r=e.config.runtime.context_release_delay_ms;if(typeof r!=`number`||!Number.isFinite(r))return Or(e,t);let i=Math.max(0,Math.floor(r));return n||i<=0?Or(e,t):(t.releaseTimer=setTimeout(async()=>{if(t.releaseTimer=null,t.refCount>0){t.releaseRequested=!1;return}await Or(e,t)},i),!0)};async function One(e,t,n={}){let{globalDownloadManager:r=null}=n,i=Sr(t),a=await wne(i),o=new lr(i);await o.load();let s={id:e,type:`ggml-tts`,config:i,plan:a,info:a.info,contextRecord:null,downloads:new Map,globalDownloadManager:r,queue:new Bn,outputCache:o,finalized:!1};return{id:e,type:`ggml-tts`,info:a.info,queue:s.queue,initContext:async(e={})=>{let{onProgress:t}=e,n=await Ene(s,t);return{modelInfo:n.modelInfo?{...n.modelInfo}:null,runtime:{...s.plan.info.runtime},download:{...s.plan.info.download}}},synthesize:async(e={})=>{let{text:t,options:n={}}=e;if(!t)throw Error(`Text input is required for speech synthesis`);let{info:r}=s.plan,i={repoId:r.model.repoId,filename:r.model.filename,quantization:r.model.quantization,vocoderFilename:r.model.vocoderFilename,variant:r.runtime.variant},a=await s.outputCache.lookup(t,i,n);if(a)return It.addTranscription({id:s.id,repoId:i.repoId,variant:i.variant,textLength:t.length,durationMs:0,cached:!0,success:!0}),{cachedId:a.id,cachedFile:a.filePath,sampling_rate:a.samplingRate,channels:a.channels};let o=s.contextRecord;if(!o)throw Error(`Context not initialized`);let c=Date.now();return s.queue.enqueue(async()=>{await o.ready;let{context:e}=o,{speaker:a=null,temperature:l=.1,repeatPenalty:u=1.1,topK:d=40,topP:f=.9,minP:p=.05,nPredict:m=-1,seed:h}=n;try{e.clearCache?.(!1);let{prompt:g,grammar:_,embedding:v,flow:y}=await e.getFormattedAudioCompletion({prompt:t,...a?{speaker:a}:{}}),b=await e.completion({prompt:g,grammar:_,embedding:v,temperature:l,repeat_penalty:u,top_k:d,top_p:f,min_p:p,n_predict:m,...h!=null&&{seed:h}}),x=await Tne(e,b,y),S=x instanceof Float32Array?x:Float32Array.from(x),C=o.sampleRate||r.model.sampleRate;return It.addTranscription({id:s.id,repoId:i.repoId,variant:i.variant,family:o.modelInfo?.family||null,textLength:t.length,audioLength:S.length,samplingRate:C,durationMs:Date.now()-c,cached:!1,success:!0}),ur({cache:s.outputCache,cacheDir:s.config.runtime.cache_dir,text:t,modelInfo:i,options:n,wavBuffer:yne(S,C,1),samplingRate:C,channels:1})}catch(e){throw It.addTranscription({id:s.id,repoId:i.repoId,variant:i.variant,textLength:t.length,durationMs:Date.now()-c,cached:!1,success:!1,error:e?.message||String(e)}),e}},`synthesis-${Date.now()}-${Math.random().toString(36).slice(2,8)}`)},releaseContext:async()=>{if(s.finalized)return!1;let e=s.contextRecord;return e?Dne(s,e):!1},finalize:async()=>{if(s.finalized)return;s.finalized=!0;let e=s.contextRecord;!e||e.released||e.releaseRequested||e.releaseTimer||(e.refCount=Math.max(0,e.refCount-1),!(e.refCount>0)&&await Or(s,e))},getStatus:()=>({id:s.id,type:s.type,repoId:s.plan.info.model?.repoId||null,quantization:s.plan.info.model?.quantization||null,vocoderRepoId:s.plan.info.model?.vocoderRepoId||null,family:s.contextRecord?.modelInfo?.family||null,variant:s.plan.info.runtime?.variant||null,hasContext:!!s.contextRecord?.context,contextRefCount:s.contextRecord?.refCount||0,queueStatus:s.queue.getStatus()}),hasPendingReleases:()=>{let e=s.contextRecord;return e?!e.released&&(e.releaseRequested||e.releaseTimer||e.refCount>0):!1},resetFinalized:()=>{s.finalized=!1}}}const kr=e=>{let t=Sr(e),n=t.model.repo_id;if(!n)return null;let r=[n,t.model.revision||`main`];return r.push(t.model.vocoder_repo_id||n),t.model.vocoder_filename&&r.push(t.model.vocoder_filename),r.join(`:`)};async function kne(e,t,n={}){let{onProgress:r,onComplete:i,onError:a}=n;try{let n=Sr(e),o=[await Tr(n,`model`),await Tr(n,`vocoder`)],{repoId:s}=o[0],c=[];for(let e of o){let i=Er(n,e);if(!n.model.local_path&&!n.model.vocoder_local_path&&await nn(i,n.runtime.cache_dir),await rn(i,e.size)||t.getDownload(i))continue;let o=(async()=>{try{await cn(e.url,e.headers,i,e.size,e=>{e>=0&&Number.isFinite(e)&&r?.(e)},{allowedRoot:n.runtime.cache_dir})}catch(t){throw console.error(`[Download] Failed TTS ${e.role}: ${s}`,t.message),a?.(t),t}finally{t.deleteDownload(i)}})();t.setDownload(i,o),c.push({localPath:i,promise:o})}let l=Er(n,o[0]);return c.length===0?(i?.({localPath:l,repoId:s,alreadyExists:!0}),{started:!1,localPath:l,repoId:s,alreadyExists:!0}):(Promise.all(c.map(e=>e.promise)).then(()=>i?.({localPath:l,repoId:s})).catch(()=>{}),{started:!0,localPath:l,repoId:s})}catch(e){return console.error(`[Download] Failed to start TTS download:`,e.message),a?.(e),{started:!1,localPath:null,repoId:null,error:e.message}}}async function Ane(e=null,t={}){let{threshold:n=1.1,includeBreakdown:r=!1,config:i,...a}=t,o=null,s=null,c=null;if(i){let e=Sr(i);try{let t=await Tr(e,`model`),n=await Tr(e,`vocoder`),r=ht({modelBytes:t.size||0,vocoderBytes:n.size||0,contextSize:e.runtime.n_ctx,vocoderBatchSize:e.runtime.vocoder_batch_size});o=r.modelBytes,s=r.processingBufferBytes,c=t.quantization||null}catch{}}let l=Jt(i?.backend?.gpu_memory_fraction),u=Jt(i?.backend?.cpu_memory_fraction),d=await ft({...a,platform:process.platform,totalMemoryInBytes:N.totalmem(),backend:`ggml-tts`,includeBreakdown:r,gpuMemoryFraction:l,cpuMemoryFraction:u,dependencies:{getBackendDevicesInfo:P,isLibVariantAvailable:ie},modelBytes:o,processingBytes:s}),f=d.selected,p=$e(f);f&&(f.modelBytes=o||null,f.processingBytes=s||null,f.quantization=c||null);let m=null,h=null;if(e){let t=$e(e);h={...e,score:t};let r=`buttress`,i=`buttress-higher-score`;if(!d.ok)r=`local`,i=`buttress-unavailable`;else{let a=e.fit&&f?.fit;({recommendation:r,reason:i}=tt({clientScore:t,buttressScore:p,threshold:n,clientFitsInMemory:a?et(e.fit):!1,buttressFitsInMemory:a?et(f.fit):!1}))}m={buttressScore:p,clientScore:t,threshold:n,recommendation:r,reason:i}}return!d.ok&&!m&&(m={buttressScore:p,clientScore:e?.score??null,threshold:n,recommendation:`local`,reason:`buttress-unavailable`}),{type:`ggml-tts`,families:[...vr],timestamp:new Date().toISOString(),buttress:d,client:h,comparison:m,modelConfig:i?{repoId:i.model?.repo_id||null,filename:i.model?.filename||null,quantization:i.model?.quantization||null,vocoderRepoId:i.model?.vocoder_repo_id||null}:null}}const Ar=`<tool_call>`,jr=`</tool_call>`;function Mr(e,t){let n=e,r=``,i=[];for(;;){let e=n.indexOf(Ar);if(e===-1)break;r+=n.slice(0,e);let a=n.slice(e+11),o=a.indexOf(jr);if(o===-1)return{content:r.trimEnd(),toolCalls:i};let s=a.slice(0,o).trim();try{let e=JSON.parse(s);e&&typeof e.name==`string`?i.push({id:`mlx_call_${t}_${i.length}`,type:`function`,function:{name:e.name,arguments:JSON.stringify(e.arguments??{})}}):r+=Ar+a.slice(0,o)+jr}catch{r+=Ar+a.slice(0,o)+jr}n=a.slice(o+12)}r+=n;let a=r.length;for(let e=1;e<11&&e<=r.length;e++)if(Ar.startsWith(r.slice(-e))){a=r.length-e;break}return{content:r.slice(0,a).trimEnd(),toolCalls:i}}const{ReadableStream:Nr}=typeof globalThis<`u`&&globalThis.ReadableStream&&globalThis.WritableStream?{ReadableStream:globalThis.ReadableStream,WritableStream:globalThis.WritableStream}:g,jne=pe(import.meta.url),Mne=M.dirname(jne),Nne=(()=>{let e=[process.env.BUTTRESS_MLX_BRIDGE_PATH,M.join(Mne,`mlx-bridge.py`),M.join(M.dirname(process.execPath),`mlx-bridge.py`)].filter(Boolean);return e.find(e=>ce.existsSync(e))||e[0]})(),Pr=`mlx-vlm==0.4.0`,Fr=`mlx-lm==0.31.1`,Ir=M.join(N.homedir(),`.buttress`,`models`),Pne={backend:{type:`mlx-llm`},model:{repo_id:null,revision:`main`,adapter_path:null,tokenizer_config:null,model_config:null,vlm:`auto`},runtime:{cache_dir:Ir,huggingface_token:process.env.HUGGINGFACE_TOKEN||null,mlx_env_dir:null,mlx_lm_package:Fr,mlx_vlm_package:Pr,context_release_delay_ms:1e4,session_cache:{enabled:!0,max_size_bytes:5*1024*1024*1024,max_entries:100}}},Fne=(e,t)=>e==null?t:typeof e==`number`?e:typeof e==`string`?oe.parse(e)??t:t,Lr=(e={})=>{let t=structuredClone(Pne);return qt(t,e),t},Rr=async(e,t={})=>{let n=await fetch(e,t);if(!n.ok)throw Error(`HTTP ${n.status}: ${e}`);return n.json()},zr=ln();async function Ine(e,{revision:t=`main`,cacheDir:n,token:r}={}){let i=JSON.stringify({repoId:e,revision:t,type:`mlx-model-metadata`});if(n){let e=await zr.read(i,`mlx-model-metadata`,n);if(e)return e}let a={};r&&(a.Authorization=`Bearer ${r}`);let o=(await Rr(`https://huggingface.co/api/models/${e}?revision=${t}&blobs=true`,{headers:a}))?.siblings||[],s=0;for(let e of o){let t=e.rfilename||e.path||e.filename||``;/\.(safetensors|npz)$/.test(t)&&(s+=Number(e.size)||0)}let c=null;try{c=await Rr(`https://huggingface.co/${e}/raw/${t}/config.json`,{headers:a})}catch{}let l=c?.text_config||c||{},u=c||{},d=u.model_type||u.architectures?.[0]||null,f=l.hidden_size||l.dim||0,p=l.num_hidden_layers||l.n_layers||0,m=l.num_attention_heads||l.n_heads||0,h=l.num_key_value_heads??m,g=l.vocab_size||0,_=l.max_position_embeddings||0,v=l.intermediate_size||0,y=l.head_dim||l.v_head_dim||(m>0&&f>0&&Number.isInteger(f/m)?f/m:0),b=l.kv_lora_rank||0,x=l.qk_rope_head_dim||0,S=b>0,C=u.quantization||u.quantization_config||null,w=C?.bits||null,T=C?.group_size||null,E=l.dtype||u.torch_dtype||(w?`${w}bit`:null),D={repoId:e,revision:t,modelBytes:s,arch:d,hiddenSize:f,numLayers:p,numHeads:m,numKvHeads:h,headDim:y,vocabSize:g,maxCtx:_,intermediateSize:v,quantBits:w,quantGroupSize:T,dtype:E,isMLA:S,kvLoraRank:b,qkRopeHeadDim:x,fileCount:o.length,config:c};return n&&await zr.write(i,`mlx-model-metadata`,D,n),D}function Br({numLayers:e,numKvHeads:t,headDim:n,contextLength:r,isMLA:i,kvLoraRank:a,qkRopeHeadDim:o}){return!e||!r?0:i&&a>0?e*(a+(o||0))*r*2:!t||!n?0:e*t*n*r*2*2}const Vr=async e=>{try{return await D(e),!0}catch{return!1}},Hr=(e,t,n={})=>new Promise((r,i)=>{he(e,t,{timeout:n.timeout||3e5,...n},(t,n,a)=>{if(t){let n=a?.toString().trim()||t.message;i(Error(`${e} failed: ${n}`))}else r({stdout:n?.toString()||``,stderr:a?.toString()||``})})}),Ur=new Map;async function Wr({envDir:e,mlxLmPackage:t,mlxVlmPackage:n,onProgress:r}){let i=M.resolve(e),a=Ur.get(i);if(a){let e=await a;return r?.(1),e}let o=Lne({envDir:i,mlxLmPackage:t,mlxVlmPackage:n,onProgress:r});Ur.set(i,o);try{return await o}finally{Ur.delete(i)}}const Gr=[3,10];async function Lne({envDir:e,mlxLmPackage:t,mlxVlmPackage:n,onProgress:r}){let i=M.join(e,`bin`,`python3`),a=M.join(e,`bin`,`pip`);if(await Vr(i))try{return await Hr(i,[`-c`,`import mlx_vlm; import torch`],{timeout:1e4}),r?.(1),i}catch{}if(!await Vr(i)){r?.(.1);try{let{stdout:e}=await Hr(`python3`,[`-c`,`import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")`],{timeout:5e3}),[t,n]=e.trim().split(`.`).map(Number);(t<Gr[0]||t===Gr[0]&&n<Gr[1])&&console.warn(`[mlx-llm] WARNING: System Python is ${t}.${n}, but mlx-vlm requires >= ${Gr.join(`.`)}. You may get an older mlx-vlm version with reduced functionality. Consider installing Python >= 3.10 (e.g. via Homebrew).`)}catch{}console.log(`[mlx-llm] Creating venv at ${e}`),await b(e,{recursive:!0}),await Hr(`python3`,[`-m`,`venv`,e],{timeout:6e4}),r?.(.3)}console.log(`[mlx-llm] Installing ${n}`),r?.(.4);let o=[`install`,t,n,`torch`,`torchvision`],s={...process.env};return await Hr(a,o,{timeout:6e5,env:s}),r?.(.9),await Hr(i,[`-c`,`import mlx_vlm; import torch; print(mlx_vlm.__version__)`],{timeout:15e3}),r?.(1),console.log(`[mlx-llm] mlx-vlm installed successfully`),i}var Rne=class{constructor(){this.process=null,this.pendingRequests=new Map,this.requestCounter=0,this.readyPromise=null,this.buffer=``}spawn(e){return this.process=_e(e,[Nne],{stdio:[`pipe`,`pipe`,`pipe`],env:{...process.env,PYTHONUNBUFFERED:`1`}}),this.process.stderr.on(`data`,e=>{let t=e.toString().trim();t&&console.log(t)}),this.process.on(`exit`,e=>{console.log(`[mlx-llm] Bridge process exited with code ${e}`);for(let[t,n]of this.pendingRequests)n.reject(Error(`Bridge process exited (code ${e})`)),this.pendingRequests.delete(t);this.process=null}),this.process.stdout.on(`data`,e=>{this.buffer+=e.toString();let t=this.buffer.split(`
|
|
3
3
|
`);this.buffer=t.pop();for(let e of t)if(e.trim())try{this.handleMessage(JSON.parse(e))}catch(t){console.error(`[mlx-llm] Failed to parse bridge message:`,e,t)}}),this.readyPromise=new Promise((e,t)=>{this.pendingRequests.set(`__init__`,{resolve:()=>e(),reject:t}),setTimeout(()=>t(Error(`Bridge startup timeout`)),3e4)}),this.readyPromise}handleMessage(e){let t=this.pendingRequests.get(e.id);t&&(e.error?(t.reject(Error(e.error.message)),this.pendingRequests.delete(e.id)):e.event?e.event===`result`?(t.resolve(e.data),this.pendingRequests.delete(e.id)):t.onEvent?.(e.event,e.data):e.result!==void 0&&(t.resolve(e.result),this.pendingRequests.delete(e.id)))}async call(e,t={}){if(!this.process)throw Error(`Bridge not running`);let n=String(++this.requestCounter);return new Promise((r,i)=>{this.pendingRequests.set(n,{resolve:r,reject:i}),this.write({id:n,method:e,params:t})})}stream(e,t,n){if(!this.process)throw Error(`Bridge not running`);let r=String(++this.requestCounter);return{id:r,promise:new Promise((i,a)=>{this.pendingRequests.set(r,{resolve:i,reject:a,onEvent:n}),this.write({id:r,method:e,params:t})})}}cancel(e){this.process&&this.write({id:`cancel-${e}`,method:`cancel`,params:{request_id:e}})}write(e){this.process?.stdin?.write(JSON.stringify(e)+`
|
|
4
4
|
`)}kill(){this.process&&=(this.process.kill(),null),this.pendingRequests.clear()}get alive(){return this.process!=null&&!this.process.killed}};function Kr(){let e=[];return process.platform!==`darwin`&&e.push(`MLX requires macOS (Apple Silicon)`),N.arch()!==`arm64`&&e.push(`MLX requires Apple Silicon (arm64)`),e}function zne(e){let t=Kr();return{config:e,info:{ok:t.length===0,backend:`mlx-llm`,warnings:[],errors:[...t],model:{repoId:e.model.repo_id,revision:e.model.revision},runtime:{variant:`mlx`},resources:{},devices:{selected:{variant:`mlx`,hasGpu:!0}},download:{cacheDir:e.runtime.cache_dir,localPath:null,exists:!1},timestamp:new Date().toISOString()}}}const qr=e=>Array.isArray(e)?e.map(e=>{if(!e)return e;if(e.content==null)return{...e,content:``};if(!Array.isArray(e.content))return e;let t=e.content.filter(e=>e?.type===`text`&&typeof e.text==`string`).map(e=>e.text).join(``);return{...e,content:t}}):e,Bne=e=>{if(!e)return[];let t=[];for(let n of e)if(Array.isArray(n.content))for(let e of n.content)e.type===`image_url`&&e.image_url?.url&&t.push(e.image_url.url);return t},Jr=`</think>`;function Yr(e,t){if(!t)return{reasoningContent:``,content:e};let n=e.indexOf(Jr);if(n!==-1)return{reasoningContent:e.slice(0,n).replace(/^\n+/,``),content:e.slice(n+8).replace(/^\n+/,``)};let r=e.length;for(let t=1;t<=8&&t<=e.length;t++)if(Jr.startsWith(e.slice(-t))){r=e.length-t;break}return{reasoningContent:e.slice(0,r).replace(/^\n+/,``),content:``}}function Vne(e,t,n,r,{enableThinking:i=!1,parseToolCalls:a=!1}={}){let o=null,s,c=Date.now(),l=0,u=``;return new Nr({start(d){s=un(d);let{id:f,promise:p}=e.stream(`generate`,t,(e,t)=>{if(e===`token`){l+=1,u+=t.token||``;let e=Yr(u,i),n=a?Mr(e.content,f):{content:e.content,toolCalls:[]};s.enqueue({event:`token`,data:{requestId:f,token:t.token,token_id:t.token_id,text:u,content:n.content,reasoning_content:e.reasoningContent}})}});o=f,p.then(e=>{let t={prompt_n:e.prompt_tokens??0,prompt_per_second:e.prompt_tps??0,predicted_n:e.generation_tokens??l,predicted_per_second:e.generation_tps??0},o=Yr(u,i),d=a?Mr(o.content,f):{content:o.content,toolCalls:[]};s.enqueue({event:`result`,data:{requestId:f,text:u,content:d.content,...d.toolCalls.length>0?{tool_calls:d.toolCalls}:{},reasoning_content:o.reasoningContent,timings:t,prompt_tokens:t.prompt_n,tokens_predicted:t.predicted_n,interrupted:e.interrupted||!1,peak_memory:e.peak_memory}}),s.close(),Pt.addCompletion({id:`completion-${f}`,generatorId:n,requestId:f,repoId:r?.repoId||null,quantization:r?.quantization||null,variant:`mlx`,promptTokens:t.prompt_n,tokensGenerated:t.predicted_n,tokensPerSecond:t.predicted_per_second,promptPerSecond:t.prompt_per_second,durationMs:Date.now()-c,success:!0,interrupted:e.interrupted||!1})}).catch(e=>{s.enqueue({event:`error`,data:{message:e?.message||String(e)}}),s.error(e),Pt.addCompletion({id:`completion-${Date.now()}`,generatorId:n,repoId:r?.repoId||null,variant:`mlx`,durationMs:Date.now()-c,tokensGenerated:l,success:!1,error:e?.message||String(e)})})},cancel(){s?.markClosed(),o&&e.cancel(o)}})}async function Hne(e,t,n={}){let r=Lr(t),i=zne(r);i.info.ok||console.error(`[mlx-llm] Platform check failed:`,i.info.errors);let a={id:e,type:`mlx-llm`,config:r,plan:i,info:i.info,contexts:new Map,bridge:null,queue:new Bn,finalized:!1},o=`mlx:${r.model.repo_id}`,s=e=>{e.releaseTimer&&(clearTimeout(e.releaseTimer),e.releaseTimer=null,e.releaseRequested=!1,e.resolveRelease(!1),e.resolveRelease=null,e.releasePromise=null)},c=async(e={})=>{let{onProgress:t}=e,n=a.contexts.get(o);if(n&&!n.released)return n.refCount+=1,s(n),await n.ready,{modelInfo:n.modelInfo,runtime:{...a.info.runtime},download:{...a.info.download}};let i={key:o,refCount:1,ready:null,released:!1,releaseRequested:!1,releaseTimer:null,releasePromise:null,resolveRelease:null,modelInfo:null};a.contexts.set(o,i);let c=Date.now();i.ready=(async()=>{let e=r.runtime.cache_dir||Ir,n=await Wr({envDir:r.runtime.mlx_env_dir||M.join(e,`mlx-env`),mlxLmPackage:r.runtime.mlx_lm_package||Fr,mlxVlmPackage:r.runtime.mlx_vlm_package||Pr,onProgress:t?e=>t(e*.3):void 0});(!a.bridge||!a.bridge.alive)&&(a.bridge=new Rne,await a.bridge.spawn(n)),t?.(.4);let o={model:r.model.repo_id};r.model.revision&&(o.revision=r.model.revision),r.model.adapter_path&&(o.adapter_path=r.model.adapter_path),r.model.vlm!=null&&(o.vlm=r.model.vlm),r.model.tokenizer_config&&(o.tokenizer_config=r.model.tokenizer_config),r.model.model_config&&(o.model_config=r.model.model_config),r.runtime.huggingface_token&&(process.env.HF_TOKEN=r.runtime.huggingface_token),await a.bridge.call(`load`,o),t?.(.9);let s=await a.bridge.call(`get_info`);i.modelInfo={model:s.model,peak_memory:s.peak_memory,active_memory:s.active_memory};let l=r.runtime.session_cache;l?.enabled!==!1&&await a.bridge.call(`configure_cache`,{enabled:!0,cache_dir:M.join(e,`mlx-session-cache`),max_entries:l?.max_entries||100,max_size_bytes:Fne(l?.max_size_bytes,5*1024*1024*1024)}),a.info.download.exists=!0,t?.(1),Pt.addModelLoad({id:`load-${Date.now()}`,generatorId:a.id,repoId:r.model.repo_id,variant:`mlx`,durationMs:Date.now()-c,success:!0})})();try{await i.ready}catch(e){throw i.released=!0,a.contexts.get(o)===i&&a.contexts.delete(o),Pt.addModelLoad({id:`load-${Date.now()}`,generatorId:a.id,repoId:r.model.repo_id,variant:`mlx`,durationMs:Date.now()-c,success:!1,error:e?.message||String(e)}),e}return{modelInfo:i.modelInfo,runtime:{...a.info.runtime},download:{...a.info.download}}},l=async e=>{if(e.released)return!1;e.released=!0;try{a.bridge?.alive&&await a.bridge.call(`release`)}catch(e){console.error(`[mlx-llm] Error releasing context:`,e.message)}return a.contexts.get(e.key)===e&&a.contexts.delete(e.key),!0};return{id:e,type:`mlx-llm`,info:i.info,contexts:a.contexts,queue:a.queue,initContext:c,completion:async(e={})=>{let{options:t={}}=e,n=a.contexts.get(o);if(!n)throw Error(`Context "${o}" not initialized`);await n.ready;let r=Bne(t.messages),i=t.prompt||``;if(!i&&t.messages){let e={messages:qr(t.messages),add_generation_prompt:t.add_generation_prompt??!0,tools:t.tools,...t.chat_template_kwargs};t.enable_thinking!=null&&(e.enable_thinking=t.enable_thinking),i=(await a.bridge.call(`apply_chat_template`,e)).text}let s={prompt:i,max_tokens:t.n_predict??t.max_tokens??256};r.length>0&&(s.image=r),t.temperature!=null&&(s.temperature=t.temperature),t.top_p!=null&&(s.top_p=t.top_p),t.top_k!=null&&(s.top_k=t.top_k),t.min_p!=null&&(s.min_p=t.min_p),t.seed!=null&&(s.seed=t.seed),t.repetition_penalty!=null&&(s.repetition_penalty=t.repetition_penalty),t.stop&&(s.stop=t.stop);let c={repoId:a.info.model?.repoId||null},l=`completion-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;return new Nr({start(e){a.queue.enqueue(async()=>{let n=Vne(a.bridge,s,a.id,c,{enableThinking:!!t.enable_thinking,parseToolCalls:Array.isArray(t.tools)&&t.tools.length>0}).getReader();try{for(;;){let{value:t,done:r}=await n.read();if(r)break;e.enqueue(t)}e.close()}catch(t){throw e.error(t),t}},l).catch(t=>{try{e.error(t)}catch{}})},cancel(){a.bridge?.alive}})},tokenize:async(e={})=>{let{text:t=``}=e,n=a.contexts.get(o);if(!n)throw Error(`Context "${o}" not initialized`);return await n.ready,a.bridge.call(`tokenize`,{text:t})},detokenize:async(e={})=>{let{tokens:t=[]}=e,n=a.contexts.get(o);if(!n)throw Error(`Context "${o}" not initialized`);return await n.ready,(await a.bridge.call(`detokenize`,{tokens:t})).text},applyChatTemplate:async(e={})=>{let{messages:t=[],params:n={}}=e,r=a.contexts.get(o);if(!r)throw Error(`Context "${o}" not initialized`);await r.ready;let i={messages:qr(t),add_generation_prompt:n.add_generation_prompt??!0,tools:n.tools,...n.chat_template_kwargs};return(await a.bridge.call(`apply_chat_template`,i)).text},releaseContext:async()=>{if(a.finalized)return!1;let e=a.contexts.get(o);if(!e||(e.releaseRequested=!0,e.refCount=Math.max(0,e.refCount-1),e.refCount>0))return!1;if(e.releasePromise)return e.releasePromise;let t=r.runtime.context_release_delay_ms??1e4;return t>0?(e.releasePromise=new Promise((n,r)=>{e.resolveRelease=n,e.releaseTimer=setTimeout(async()=>{e.releaseTimer=null;try{n(e.refCount<=0&&!e.released&&await l(e))}catch(e){r(e)}finally{e.resolveRelease=null,e.releasePromise=null}},t)}),e.releasePromise):l(e)},finalize:async()=>{if(a.finalized)return;a.finalized=!0;let e=Array.from(a.contexts.values());for(let t of e)s(t),t.released||(t.refCount=0,await l(t));a.bridge?.kill(),a.bridge=null},getStatus:()=>({id:a.id,type:a.type,repoId:a.info.model?.repoId||null,variant:`mlx`,contexts:Array.from(a.contexts.entries()).map(([e,t])=>({key:e,refCount:t.refCount,hasModel:!t.released})),queueStatus:a.queue.getStatus()}),hasPendingReleases:()=>Array.from(a.contexts.values()).some(e=>!e.released&&(e.releaseRequested||e.releaseTimer||e.refCount>0)),resetFinalized:()=>{a.finalized=!1}}}const Xr=e=>Lr(e).model.repo_id||null;async function Une(e=null,t={}){let{includeBreakdown:n=!1,config:r}=t,i=Kr(),a=i.length===0,o=!1,s=!1;if(a){try{await Hr(`python3`,[`--version`],{timeout:5e3}),o=!0}catch{}if(o)try{await Hr(`python3`,[`-c`,`import mlx`],{timeout:1e4}),s=!0}catch{}}let c=await at({platform:process.platform,arch:N.arch(),totalMemoryInBytes:N.totalmem(),includeBreakdown:n}),l=null,u=null,d=null,f=null,p=null,m=null,h=null;if(r){let e=Lr(r),t=e.model.repo_id;if(t)try{l=await Ine(t,{revision:e.model.revision,cacheDir:e.runtime.cache_dir||Ir,token:e.runtime.huggingface_token}),u=l.modelBytes||0,f=l.maxCtx||4096;let n={numLayers:l.numLayers,numKvHeads:l.numKvHeads,headDim:l.headDim,isMLA:l.isMLA,kvLoraRank:l.kvLoraRank,qkRopeHeadDim:l.qkRopeHeadDim};d=Br({...n,contextLength:f});let r=c.ok?c.selected.gpuUsableBytes:0;if(r>0&&u>0&&l.numLayers){let e=r-u;if(e>0){let t;t=l.isMLA&&l.kvLoraRank>0?l.numLayers*(l.kvLoraRank+(l.qkRopeHeadDim||0))*2:l.numKvHeads&&l.headDim?l.numLayers*l.numKvHeads*l.headDim*2*2:0,t>0&&(m=Math.floor(e/t),m=Math.min(m,f))}else m=0;m!=null&&m<f&&(p=Br({...n,contextLength:m}))}h={repoId:t,revision:e.model.revision,nCtx:f,architecture:l.arch,quantBits:l.quantBits,quantGroupSize:l.quantGroupSize}}catch{}}let g=c.ok?{...c.selected,modelBytes:u,kvCacheBytes:d,memoryLimitedCtx:m,limitedKvCacheBytes:p,kvInfo:l?{nCtxTrain:l.maxCtx||null,nLayer:l.numLayers,nEmbd:l.hiddenSize,nHeadKv:l.numKvHeads,headDim:l.headDim}:null,quantization:l?{bits:l.quantBits,groupSize:l.quantGroupSize,dtype:l.dtype}:null}:null;if(c.ok&&u!=null&&u>0){let e=u+(d||0),t=c.selected.gpuUsableBytes,n=e<=t;if(g.fit={totalRequiredBytes:e,fitsInGpu:n,fitsInCpu:e<=t,limiting:n?`none`:`insufficient-memory`},p!=null&&p!==d){let e=u+p;g.limitedFit={totalRequiredBytes:e,fitsInGpu:e<=t,fitsInCpu:e<=t,limiting:e<=t?`none`:`insufficient-memory`}}}return{type:`mlx-llm`,available:a,platform:{ok:a,os:process.platform,arch:N.arch(),errors:i},python:{available:o},mlx:{systemAvailable:s,venvSupported:o},buttress:c.ok?{ok:c.ok,selected:g,attempts:c.attempts}:{ok:!1,selected:null,attempts:c.attempts||[],errors:c.errors},modelConfig:h,timestamp:new Date().toISOString()}}async function Wne(e,t,n={}){let{onProgress:r,onComplete:i,onError:a}=n,o=Lr(e),s=o.model.repo_id;if(!s)return{started:!1,localPath:null,repoId:null,error:`Missing repo_id`};let c=Kr();if(c.length>0)return{started:!1,localPath:null,repoId:s,error:c.join(`; `)};let l=`mlx:${s}`;if(t?.isDownloading(l))return{started:!1,localPath:null,repoId:s,alreadyDownloading:!0};let u=(async()=>{try{let e=o.runtime.cache_dir||Ir,t=await Wr({envDir:o.runtime.mlx_env_dir||M.join(e,`mlx-env`),mlxLmPackage:o.runtime.mlx_lm_package||Fr,mlxVlmPackage:o.runtime.mlx_vlm_package||Pr,onProgress:r?e=>r(e*.3):void 0});r?.(.3);let n=o.model.revision||`main`,a=`
|
|
5
5
|
from huggingface_hub import snapshot_download
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fugood/buttress-server",
|
|
3
|
-
"version": "2.26.0-beta.
|
|
3
|
+
"version": "2.26.0-beta.14",
|
|
4
4
|
"main": "lib/index.mjs",
|
|
5
5
|
"types": "lib/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"@earendil-works/pi-tui": "^0.85.0",
|
|
43
43
|
"@elysiajs/cors": "^1.1.1",
|
|
44
44
|
"@elysiajs/node": "^1.4.2",
|
|
45
|
-
"@fugood/llama.node": "^1.8.0-rc.
|
|
46
|
-
"@fugood/whisper.node": "^1.
|
|
45
|
+
"@fugood/llama.node": "^1.8.0-rc.6",
|
|
46
|
+
"@fugood/whisper.node": "^1.2.0-rc.0",
|
|
47
47
|
"@huggingface/gguf": "^0.3.2",
|
|
48
48
|
"@iarna/toml": "^3.0.0",
|
|
49
49
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
@@ -69,10 +69,10 @@
|
|
|
69
69
|
"zod": "^3.25.76"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
|
-
"@fugood/bricks-cli": "^2.26.0-beta.
|
|
72
|
+
"@fugood/bricks-cli": "^2.26.0-beta.14",
|
|
73
73
|
"@fugood/bricks-devtools-core": "^2.26.0-beta.11",
|
|
74
74
|
"tsdown": "^0.22.4",
|
|
75
75
|
"typescript": "^7.0.2"
|
|
76
76
|
},
|
|
77
|
-
"gitHead": "
|
|
77
|
+
"gitHead": "76d3875738e297dff0689a65b80b3498eaa8f389"
|
|
78
78
|
}
|