@fugood/buttress-server 2.25.0-beta.21 → 2.25.0-beta.23

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.
Files changed (2) hide show
  1. package/lib/index.mjs +1 -1
  2. package/package.json +2 -2
package/lib/index.mjs CHANGED
@@ -33,7 +33,7 @@ print(path)
33
33
  === Hardware Information ===`);let t=null;if(process.platform!==`win32`)try{t=O(`uname -a`,{encoding:`utf8`}).trim()}catch{}t?console.log(`System: ${t}`):(console.log(`Hostname: ${x.hostname()}`),console.log(`OS: ${x.type()} ${x.release()}`)),console.log(`Platform: ${e.platform}`),console.log(`CPU Cores: ${x.cpus().length}`),console.log(`Total System Memory: ${(x.totalmem()/1024/1024/1024).toFixed(2)} GB`);let n=e.cpuTotalBytes>0?(e.cpuUsableBytes/e.cpuTotalBytes*100).toFixed(0):0;console.log(`Usable CPU Memory: ${(e.cpuUsableBytes/1024/1024/1024).toFixed(2)} GB (${n}% of ${(e.cpuTotalBytes/1024/1024/1024).toFixed(2)} GB)`),e.hasGpu?(console.log(`
34
34
  --- GPU Details ---`),e.devices.filter(e=>e.type===`gpu`).forEach(t=>{console.log(`GPU Backend: ${t.backend}`),console.log(`GPU Name: ${t.deviceName}`),console.log(`GPU Total Memory: ${(t.maxMemorySize/1024/1024/1024).toFixed(2)} GB`);let n=e.gpuTotalBytes>0?(e.gpuUsableBytes/e.gpuTotalBytes*100).toFixed(0):0;console.log(`GPU Usable Memory: ${(e.gpuUsableBytes/1024/1024/1024).toFixed(2)} GB (${n}% of ${(e.gpuTotalBytes/1024/1024/1024).toFixed(2)} GB)`),t.metadata&&(t.metadata.hasBFloat16&&console.log(`Supports BFloat16: Yes`),t.metadata.hasUnifiedMemory&&console.log(`Unified Memory: Yes`))})):console.log(`GPU: Not available`),console.log(`\nBackend Variant: ${e.variant}`),console.log(`Performance Score: ${e.score}`),e.fit&&(console.log(`
35
35
  --- Model Fit Analysis ---`),console.log(`Fits in GPU: ${e.fit.fitsInGpu?`Yes`:`No`}`),console.log(`Fits in CPU: ${e.fit.fitsInCpu?`Yes`:`No`}`),console.log(`Limiting Factor: ${e.fit.limiting}`))}console.log(`
36
- === Full Capabilities JSON ===`),console.log(JSON.stringify(u,null,2)),process.exit(0)}catch(e){console.error(`Failed to get capabilities:`,e.message),process.exit(1)}}var qr=e({finalizeGenerator:()=>Zr,generatorRegistry:()=>Z,getCapabilities:()=>J,getModelIdentifier:()=>ti,ggmlLlm:()=>Qr,ggmlStt:()=>ei,globalDownloadManager:()=>Jr,mlxLlm:()=>$r,showModelsTable:()=>Ur,showSttModelsTable:()=>Gr,startGenerator:()=>Xr,startModelDownload:()=>ri,status:()=>ni,testGgmlLlmCapabilities:()=>Wr,testGgmlSttCapabilities:()=>Kr});const Z=new Map,Jr={downloads:new Map,getDownload(e){return this.downloads.get(e)||null},setDownload(e,t){this.downloads.set(e,t)},deleteDownload(e){this.downloads.delete(e)},isDownloading(e){return this.downloads.has(e)},getActiveDownloads(){return Array.from(this.downloads.entries()).map(([e,t])=>({localPath:e,promise:t}))}},Yr=e=>{let t=Z.get(e);if(!t)throw Error(`Unknown generator id "${e}"`);return t},Q=(e,t)=>{let n=Yr(e);if(n.type!==t)throw Error(`Generator "${e}" does not support ${t} backend`);return n.instance};async function Xr(e,t){let n={"ggml-llm":{create:pn,getId:mn},"ggml-stt":{create:tr,getId:nr},"mlx-llm":{create:Lr,getId:Rr}}[e];if(!n)throw Error(`Unsupported backend type: ${e}`);let r=n.getId(t);if(!r)throw Error(`Buttress generator config missing repo identifier`);let i=`${e}:${r}`,a=Z.get(i);if(a)return a.refCount+=1,a.instance.resetFinalized?.(),{id:a.id,info:a.instance.info};let o=await n.create(i,t,{globalDownloadManager:Jr}),s={id:i,type:o.type,instance:o,refCount:1};return Z.set(i,s),{id:i,info:o.info}}async function Zr(e){let t=Z.get(e);return t?(--t.refCount,t.refCount<=0&&(await t.instance.finalize(),(t.instance.hasPendingReleases?.()??!1)||Z.delete(e)),!0):!1}const Qr={async initContext(e,t){return Q(e,`ggml-llm`).initContext(t)},async completion(e,t){return Q(e,`ggml-llm`).completion(t)},async tokenize(e,t){return Q(e,`ggml-llm`).tokenize(t)},async detokenize(e,t){return Q(e,`ggml-llm`).detokenize(t)},async applyChatTemplate(e,t){return Q(e,`ggml-llm`).applyChatTemplate(t)},async releaseContext(e,t){let n=Z.get(e);if(!n)return{released:!0,alreadyReleased:!0};if(n.type!==`ggml-llm`)throw Error(`Generator "${e}" does not support ggml-llm backend`);return n.instance.releaseContext(t)}},$r={async initContext(e,t){return Q(e,`mlx-llm`).initContext(t)},async completion(e,t){return Q(e,`mlx-llm`).completion(t)},async tokenize(e,t){return Q(e,`mlx-llm`).tokenize(t)},async detokenize(e,t){return Q(e,`mlx-llm`).detokenize(t)},async applyChatTemplate(e,t){return Q(e,`mlx-llm`).applyChatTemplate(t)},async releaseContext(e,t){let n=Z.get(e);if(!n)return{released:!0,alreadyReleased:!0};if(n.type!==`mlx-llm`)throw Error(`Generator "${e}" does not support mlx-llm backend`);return n.instance.releaseContext(t)}},ei={async initContext(e,t){return Q(e,`ggml-stt`).initContext(t)},async transcribe(e,t){return Q(e,`ggml-stt`).transcribe(t)},async transcribeData(e,t){return Q(e,`ggml-stt`).transcribeData(t)},async releaseContext(e,t){let n=Z.get(e);if(!n)return{released:!0,alreadyReleased:!0};if(n.type!==`ggml-stt`)throw Error(`Generator "${e}" does not support ggml-stt backend`);return n.instance.releaseContext(t)}};function ti(e,t){return e===`ggml-llm`?mn(t):e===`ggml-stt`?nr(t):e===`mlx-llm`?Rr(t):null}const ni={getFullStatus:()=>it(Z),getGgmlLlmStatus:()=>tt(Z),getGgmlSttStatus:()=>nt(Z),getMlxLlmStatus:()=>rt(Z),subscribeToStatus:$e,subscribeToStatusWithId:et,llmStatusTracker:H,sttStatusTracker:U,statusEmitter:V};async function ri(e,t,n={}){let r={"ggml-llm":hn,"ggml-stt":rr,"mlx-llm":Br}[e];return r?r(t,Jr,n):{started:!1,localPath:null,repoId:null,error:`Unknown backend type: ${e}`}}let ii=null;const ai={name:`@fugood/buttress-server`,version:`0.0.0`},oi=()=>{if(ii)return ii;try{let e=te(new URL(`../package.json`,import.meta.url)),t=JSON.parse(k.readFileSync(e,`utf8`));ii={name:t.name||ai.name,version:t.version||ai.version,description:t.description}}catch{ii=ai}return ii},si=!(`Bun`in globalThis),ci=e=>new n({adapter:si?t():void 0,...e}),li=a.Object({id:a.String(),name:a.String(),version:a.String(),generators:a.Array(a.Object({type:a.String(),score:a.Optional(a.Number()),hasGpu:a.Optional(a.Boolean()),usableBytes:a.Optional(a.Number())})),authentication:a.Object({required:a.Boolean(),type:a.String(),kid:a.Optional(a.String()),bound:a.Optional(a.Boolean())}),workspace:a.Optional(a.Object({id:a.String(),name:a.Optional(a.String())}))}),ui=({store:{serverInfo:e}})=>({id:e.id,name:e.name,version:e.version,generators:e.generators,authentication:e.authentication,workspace:e.workspace});var di=e=>{let t=ci(),n=e.autodiscover?.http?.path??`/buttress/info`;return t.get(n,ui,{response:li}),t};let fi=null;const pi=async e=>{if(fi&&fi.kid===e.kid)return fi.key;let t=await N(e.issuerPublicKey,`EdDSA`);return fi={kid:e.kid,key:t},t},mi=/^Bearer\s+(.+)$/i,hi=(e,t)=>{if(e){let t=e.authorization||e.Authorization;if(t){let e=t.match(mi);return e?e[1].trim():t.trim()}}if(t){let e=t.access_token??t.token;if(typeof e==`string`&&e)return e}return null},gi=async(e,t)=>{if(!e||!t)return null;try{let{payload:n}=await P(e,await pi(t),{algorithms:[`EdDSA`]}),r=n;return r.k!==`ba`||r.w_id!==t.id||r.st!==`ws`&&r.st!==`dev`||!r.sid||!r.exp?null:{workspaceId:r.w_id,subjectType:r.st,subjectId:r.sid,jti:r.jti,exp:r.exp}}catch{return null}},_i=async({headers:e,query:t,set:n,store:r})=>{let i=r.workspaceState?.workspace;if(i&&!await gi(hi(e,t),i))return n.status=401,n.headers&&(n.headers[`WWW-Authenticate`]=`Bearer`),{error:{code:`UNAUTHORIZED`,message:`Invalid or missing workspace access token`}}},vi=e=>{if(!e)return null;let t=e[`x-buttress-sess-id`]??e[`X-BUTTRESS-SESS-ID`];return t?t.trim():null},yi=async({headers:e,query:t,set:n,store:r})=>{let i=r.sessions,a=vi(e);if(!a||!i)return n.status=401,{error:{code:`SESSION_REQUIRED`,message:`Missing buttress session id`}};let o=i.get(a);if(!o)return n.status=401,{error:{code:`SESSION_INVALID`,message:`Unknown or expired buttress session`}};let s=r.workspaceState?.workspace;if(s&&o.identity){let r=await gi(hi(e,t),s);if(!r||r.subjectId!==o.identity.subjectId||r.subjectType!==o.identity.subjectType)return n.status=403,{error:{code:`SESSION_FORBIDDEN`,message:`Token identity mismatch for this session`}}}},bi=(e,t)=>{let n=e.sessions,r=vi(t);if(!r||!n)return null;let i=n.get(r);return i?{sessionId:r,session:i}:null},xi=(e,t,n)=>{let r=l.join(e,t),i=l.join(r,n),a=l.relative(r,i);return{sessionDir:r,filePath:i,safe:a!==``&&!a.startsWith(`..`)&&!l.isAbsolute(a)}},Si=typeof process<`u`&&process.versions!=null&&process.versions.node!=null;var Ci=ci().onBeforeHandle(_i).onBeforeHandle(yi).post(`/buttress/upload`,async({body:{file:e},headers:t,store:n})=>{let r=bi(n,t);if(!r)return{ok:!1,error:`Session guard mis-wired`};let{sessionId:i}=r,{config:a}=n,o=`${Date.now()}-${e.name.replace(/[^\dA-Za-z]/g,`_`)}`,{sessionDir:s,filePath:c,safe:l}=xi(a.server.temp_file_dir,i,o);if(!l)return{ok:!1,error:`Invalid file path`};try{return await p(s,{recursive:!0}),Si?await b(c,await e.stream()):await b(c,await e.arrayBuffer()),{ok:!0,filename:o}}catch(e){return{ok:!1,error:String(e)}}},{body:a.Object({file:a.File()}),response:a.Object({ok:a.Boolean(),filename:a.Optional(a.String()),error:a.Optional(a.String())})}).get(`/buttress/download/:filename`,async({params:{filename:e},headers:t,store:n,status:i})=>{let a=bi(n,t);if(!a)return i(500),`Session guard mis-wired`;let{sessionId:o}=a,{config:s}=n,{filePath:c,safe:l}=xi(s.server.temp_file_dir,o,e);return l?r(c):(i(400),`Invalid file path`)},{params:a.Object({filename:a.String()})});const wi=l.dirname(te(import.meta.url)),Ti=async()=>{let e=[l.join(wi,`..`,`public`,`status.html`),l.join(wi,`..`,`..`,`public`,`status.html`)];return(await Promise.all(e.map(e=>f.access(e).then(()=>e,()=>null)))).find(e=>e!==null)??null},Ei=e=>{let{status:t}=e;return t?.getFullStatus?t.getFullStatus():{timestamp:new Date().toISOString(),ggmlLlm:{generators:[],history:{}},ggmlStt:{generators:[],history:{}}}},Di=async()=>{let e=await Ti();if(!e)return console.error(`[Status] Failed to find status.html in candidate paths`),new Response(`Status page not found`,{status:404,headers:{"Content-Type":`text/plain`}});try{let t=await f.readFile(e,`utf-8`);return new Response(t,{headers:{"Content-Type":`text/html; charset=utf-8`}})}catch(e){return console.error(`[Status] Failed to serve status page:`,e),new Response(`Status page not found`,{status:404,headers:{"Content-Type":`text/plain`}})}};var Oi=ci().get(`/status`,Di).get(`/status/`,Di).get(`/buttress/status`,({store:{backend:e}})=>Ei(e));const ki=[`ggml-llm`,`mlx-llm`],Ai=new Map;function ji(e,t){return t===`mlx-llm`?e.mlxLlm:e.ggmlLlm}async function Mi(e,t,n,r=`[LLM]`){let i=(t.generators||[]).filter(e=>ki.includes(e.type));if(i.length===0)throw Error(`No LLM generator configured. Add a [[generators]] with type = "ggml-llm" or "mlx-llm" to your config.`);let a=i[0],o=n||a.model?.repo_id;if(n){let e=i.find(e=>e.model?.repo_id===n);e&&(a=e)}else o=a.model?.repo_id;let s=a.type||`ggml-llm`,c=o,l=Ai.get(c);if(l?.initialized)return l;let{generators:u,server:d,...f}=t.global||{},p={...f,...a,model:{...a.model,repo_id:o}};console.log(`${r} Creating ${s} generator for ${c}`);let{id:m}=await e.startGenerator(s,p),h={id:m,type:s,config:p,repoId:o,initialized:!1};return Ai.set(c,h),await ji(e,s).initContext(m,{}),h.initialized=!0,console.log(`${r} Generator ready: ${c}`),h}function Ni(e){let t=e.timings||{},n=t.prompt_n??t.promptN??0,r=t.cache_n??t.cacheN??0,i=t.predicted_n??t.predictedN??0;return{promptTokens:n||e.prompt_tokens||e.promptTokens||0,cachedTokens:r,completionTokens:i||e.tokens_evaluated||e.tokensEvaluated||e.tokens_predicted||e.tokensPredicted||0}}function Pi(e){let{promptTokens:t,cachedTokens:n,completionTokens:r}=Ni(e),i=t+n;return{prompt_tokens:i,completion_tokens:r,total_tokens:i+r}}const Fi=()=>`chatcmpl-${Date.now()}-${Math.random().toString(36).slice(2,9)}`;async function Ii(e,t,n,r){let i=e.getReader(),a=``,o=null,s=null,c=`stop`,l={prompt_tokens:0,completion_tokens:0,total_tokens:0};try{let e=!1;for(;!e;){let n=await i.read();if({done:e}=n,e)break;let{event:r,data:u}=n.value;if(r===`token`)u.content!=null&&(a=u.content),u.reasoning_content!=null&&(o=u.reasoning_content);else if(r===`result`)u.content==null?u.text&&(a=u.text):a=u.content,u.reasoning_content!=null&&(o=u.reasoning_content),u.tool_calls?.length>0?(s=u.tool_calls.map((e,n)=>({id:e.id||`call_${t}_${n}`,type:`function`,function:{name:e.function?.name||``,arguments:e.function?.arguments||``}})),c=`tool_calls`):c=u.interrupted?`length`:`stop`,l=Pi(u);else if(r===`error`)throw Error(u.message)}}finally{i.cancel().catch(()=>{})}let u={role:`assistant`,content:a||null};return o&&(u.reasoning_content=o),s&&(u.tool_calls=s),{id:t,object:`chat.completion`,created:n,model:r,choices:[{index:0,message:u,finish_reason:c}],usage:l}}function Li({global:e}){let t=ci({prefix:`/oai-compat`});return t.use(ie({origin:e?.openai_compat?.cors_allowed_origins??!1,methods:[`GET`,`POST`,`OPTIONS`],allowedHeaders:[`Content-Type`,`Authorization`],maxAge:86400,preflight:!0})),t.onBeforeHandle(_i),t.get(`/v1/models`,({store:e})=>{let{config:t}=e,n=(t.generators||[]).filter(e=>ki.includes(e.type)).map(e=>({id:e.model?.repo_id||e.type,object:`model`,created:Math.floor(Date.now()/1e3),owned_by:`local`}));return n.length===0&&n.push({id:`ggml-llm`,object:`model`,created:Math.floor(Date.now()/1e3),owned_by:`local`}),{object:`list`,data:n}}),t.post(`/v1/chat/completions`,async function*({body:e,set:t,store:n}){let{config:r,backend:a}=n,{messages:o=[],stream:s=!1,model:c,tools:l,temperature:u,stop:d,top_p:f,max_tokens:p,presence_penalty:m,frequency_penalty:h,tool_choice:g,stream_options:_,enable_thinking:v}=e;if(!o||o.length===0)return t.status=400,{error:{message:`messages is required and must not be empty`,type:`invalid_request_error`}};try{let e=await Mi(a,r,c,`[OpenAI]`),t=Fi(),n=Math.floor(Date.now()/1e3),y=e.repoId||`ggml-llm`,b={reasoning_format:`auto`,messages:o,jinja:!0,add_generation_prompt:!0};u!=null&&(b.temperature=u),f!=null&&(b.top_p=f),p!=null&&(b.n_predict=p),d!=null&&(b.stop=Array.isArray(d)?d:[d]),m!=null&&(b.presence_penalty=m),h!=null&&(b.frequency_penalty=h),l!=null&&(b.tools=l),g!=null&&(b.tool_choice=g),b.enable_thinking=v??!1;let x=await ji(a,e.type).completion(e.id,{options:b});if(!s)return await Ii(x,t,n,y);let S=_?.include_usage===!0,C=x.getReader(),w=``,T=``,E=new Map,D=new Map;try{let e=!1;for(;!e;){let r=await C.read();if({done:e}=r,e)break;let{event:a,data:o}=r.value;if(a===`token`){let e={};if(o.content!=null){let t=o.content;t.length>w.length&&(e.content=t.slice(w.length),w=t)}if(o.reasoning_content!=null){let t=o.reasoning_content;t.length>T.length&&(e.reasoning_content=t.slice(T.length),T=t)}if(o.tool_calls?.length>0){let n=[];o.tool_calls.forEach((e,r)=>{let i={index:r};D.has(r)||(D.set(r,e.id||`call_${t}_${r}`),i.id=D.get(r),i.type=`function`);let a=e.function?.arguments||``,o=E.get(r)||``,s={};!E.has(r)&&e.function?.name&&(s.name=e.function.name),a.length>o.length&&(s.arguments=a.slice(o.length),E.set(r,a)),Object.keys(s).length>0?(i.function=s,n.push(i)):i.id&&(i.function={name:e.function?.name||``,arguments:``},n.push(i))}),n.length>0&&(e.tool_calls=n)}Object.keys(e).length>0&&(yield i({data:JSON.stringify({id:t,object:`chat.completion.chunk`,created:n,model:y,choices:[{index:0,delta:e,finish_reason:null}]})}))}else if(a===`result`){let e=`stop`;o.tool_calls?.length>0||D.size>0?e=`tool_calls`:o.interrupted&&(e=`length`);let r={id:t,object:`chat.completion.chunk`,created:n,model:y,choices:[{index:0,delta:{},finish_reason:e}]};S&&(r.usage=Pi(o)),yield i({data:JSON.stringify(r)})}else a===`error`&&(yield i({data:JSON.stringify({error:{message:o.message,type:`server_error`}})}))}yield i({data:`[DONE]`})}finally{C.cancel().catch(()=>{})}}catch(e){return console.error(`[OpenAI] Chat completion error:`,e),t.status=500,{error:{message:e.message||`Internal server error`,type:`server_error`}}}},{body:a.Object({model:a.Optional(a.String()),messages:a.Array(a.Any()),stream:a.Optional(a.Boolean()),temperature:a.Optional(a.Number()),top_p:a.Optional(a.Number()),max_tokens:a.Optional(a.Number()),stop:a.Optional(a.Union([a.String(),a.Array(a.String())])),presence_penalty:a.Optional(a.Number()),frequency_penalty:a.Optional(a.Number()),tools:a.Optional(a.Array(a.Any())),tool_choice:a.Optional(a.Any()),stream_options:a.Optional(a.Object({include_usage:a.Optional(a.Boolean())})),enable_thinking:a.Optional(a.Boolean())})}),t}const Ri=()=>`msg_${Date.now()}${Math.random().toString(36).slice(2,11)}`;function zi(e){let t={},n=[];if(e.system!=null){let t=``;if(typeof e.system==`string`)t=e.system;else if(Array.isArray(e.system))for(let n of e.system)n?.type===`text`&&typeof n.text==`string`&&(t+=n.text);t&&n.push({role:`system`,content:t})}if(!Array.isArray(e.messages))throw Error(`'messages' is required and must be an array`);for(let t of e.messages){let e=t?.role||`user`;if(t?.content==null){if(e===`assistant`)continue;n.push(t);continue}if(typeof t.content==`string`){n.push({role:e,content:t.content});continue}if(!Array.isArray(t.content)){n.push(t);continue}let r=[],i=[],a=[],o=``,s=!1;for(let e of t.content){let t=e?.type||``;if(t===`text`)i.push({type:`text`,text:e.text||``});else if(t===`thinking`)o+=e.thinking||``;else if(t===`image`){let t=e.source||{};if(t.type===`base64`){let e=t.media_type||`image/jpeg`,n=t.data||``;i.push({type:`image_url`,image_url:{url:`data:${e};base64,${n}`}})}else t.type===`url`&&i.push({type:`image_url`,image_url:{url:t.url||``}})}else if(t===`tool_use`)r.push({id:e.id||``,type:`function`,function:{name:e.name||``,arguments:JSON.stringify(e.input??{})}}),s=!0;else if(t===`tool_result`){let t=e.tool_use_id||``,n=``,r=e.content;if(typeof r==`string`)n=r;else if(Array.isArray(r))for(let e of r)e?.type===`text`&&(n+=e.text||``);a.push({role:`tool`,tool_call_id:t,content:n})}}if(i.length>0||s||o){let t={role:e};i.length>0?t.content=i:(s||o)&&(t.content=``),r.length>0&&(t.tool_calls=r),o&&(t.reasoning_content=o),n.push(t)}for(let e of a)n.push(e)}if(t.messages=n,Array.isArray(e.tools)&&(t.tools=e.tools.map(e=>({type:`function`,function:{name:e.name||``,description:e.description||``,parameters:e.input_schema||{}}}))),e.tool_choice&&typeof e.tool_choice==`object`){let n=e.tool_choice.type;n===`auto`?t.tool_choice=`auto`:n===`any`||n===`tool`?t.tool_choice=`required`:n===`none`&&(t.tool_choice=`none`)}else Array.isArray(t.tools)&&t.tools.length>0&&(t.tool_choice=`auto`);e.stop_sequences!=null&&(t.stop=Array.isArray(e.stop_sequences)?e.stop_sequences:[e.stop_sequences]),t.max_tokens=e.max_tokens??4096;for(let n of[`temperature`,`top_p`,`top_k`,`stream`])e[n]!=null&&(t[n]=e[n]);return e.thinking&&typeof e.thinking==`object`&&e.thinking.type===`enabled`&&(t.enable_thinking=!0,e.thinking.budget_tokens!=null&&(t.thinking_budget_tokens=e.thinking.budget_tokens)),t}function Bi(e,t){return t?`tool_use`:e.stopping_word||e.stoppingWord?`stop_sequence`:e.interrupted||e.truncated?`max_tokens`:`end_turn`}function Vi(e){let{promptTokens:t,cachedTokens:n,completionTokens:r}=Ni(e);return{cache_read_input_tokens:n,input_tokens:t,output_tokens:r}}async function Hi(e,t,n){let r=e.getReader(),i=``,a=``,o=[],s={cache_read_input_tokens:0,input_tokens:0,output_tokens:0},c=`end_turn`,l=null;try{let e=!1;for(;!e;){let t=await r.read();if({done:e}=t,e)break;let{event:n,data:u}=t.value;if(n===`token`)u.content!=null&&(i=u.content),u.reasoning_content!=null&&(a=u.reasoning_content);else if(n===`result`)u.content==null?u.text&&u.reasoning_content==null&&(i=u.text):i=u.content,u.reasoning_content!=null&&(a=u.reasoning_content),Array.isArray(u.tool_calls)&&(o=u.tool_calls),s=Vi(u),l=u.stopping_word||u.stoppingWord||null,c=Bi(u,o.length>0);else if(n===`error`)throw Error(u.message||`completion error`)}}finally{r.cancel().catch(()=>{})}let u=[];a&&u.push({type:`thinking`,thinking:a,signature:``}),i&&u.push({type:`text`,text:i});for(let e of o){let t={};try{t=JSON.parse(e.function?.arguments||`{}`)}catch{t={}}u.push({type:`tool_use`,id:e.id||`toolu_${Math.random().toString(36).slice(2,11)}`,name:e.function?.name||``,input:t})}return{id:t,type:`message`,role:`assistant`,content:u,model:n,stop_reason:c,stop_sequence:l,usage:s}}function Ui({global:e}){let t=ci({prefix:`/anthropic-messages`});return t.use(ie({origin:e?.anthropic_messages?.cors_allowed_origins??!1,methods:[`GET`,`POST`,`OPTIONS`],allowedHeaders:[`Content-Type`,`Authorization`,`x-api-key`,`anthropic-version`],maxAge:86400,preflight:!0})),t.onBeforeHandle(_i),t.post(`/v1/messages`,async function*({body:e,set:t,store:n}){let{config:r,backend:a}=n,o=e;try{if(!Array.isArray(o.messages)||o.messages.length===0)return t.status=400,{type:`error`,error:{type:`invalid_request_error`,message:`messages is required and must not be empty`}};let e=zi(o),n=await Mi(a,r,o.model,`[Anthropic]`),s=Ri(),c=n.repoId||`ggml-llm`,l={reasoning_format:`auto`,messages:e.messages,jinja:!0,add_generation_prompt:!0};e.temperature!=null&&(l.temperature=e.temperature),e.top_p!=null&&(l.top_p=e.top_p),e.top_k!=null&&(l.top_k=e.top_k),e.max_tokens!=null&&(l.n_predict=e.max_tokens),e.stop!=null&&(l.stop=e.stop),e.tools!=null&&(l.tools=e.tools),e.tool_choice!=null&&(l.tool_choice=e.tool_choice),l.enable_thinking=e.enable_thinking??!1,e.thinking_budget_tokens!=null&&(l.thinking_budget_tokens=e.thinking_budget_tokens);let u=await ji(a,n.type).completion(n.id,{options:l});if(!o.stream)return await Hi(u,s,c);let d=u.getReader(),f=``,p=``,m=new Map,h=new Map,g=new Map,_=new Set,v=!1,y=!1,b=0,x=0,S={cache_read_input_tokens:0,input_tokens:0,output_tokens:0},C=`end_turn`,w=null,T=!1,E=e=>(v?1:0)+(y?1:0)+e;try{let e=!1;for(;!e;){let t=await d.read();if({done:e}=t,e)break;let{event:n,data:r}=t.value;if(n===`token`){if(!T){let e=Vi(r);yield i({event:`message_start`,data:JSON.stringify({type:`message_start`,message:{id:s,type:`message`,role:`assistant`,content:[],model:c,stop_reason:null,stop_sequence:null,usage:e}})}),T=!0}if(r.reasoning_content!=null){let e=r.reasoning_content;e.length>p.length&&(v||(yield i({event:`content_block_start`,data:JSON.stringify({type:`content_block_start`,index:0,content_block:{type:`thinking`,thinking:``}})}),v=!0,b=1),yield i({event:`content_block_delta`,data:JSON.stringify({type:`content_block_delta`,index:0,delta:{type:`thinking_delta`,thinking:e.slice(p.length)}})}),p=e)}if(r.content!=null){let e=r.content;e.length>f.length&&(y||=(yield i({event:`content_block_start`,data:JSON.stringify({type:`content_block_start`,index:b,content_block:{type:`text`,text:``}})}),!0),yield i({event:`content_block_delta`,data:JSON.stringify({type:`content_block_delta`,index:b,delta:{type:`text_delta`,text:e.slice(f.length)}})}),f=e)}if(Array.isArray(r.tool_calls)&&r.tool_calls.length>0){for(let e=0;e<r.tool_calls.length;e+=1){let t=r.tool_calls[e],n=E(e),a=t?.function?.arguments||``,o=m.get(e)||``;if(!_.has(e)){let r=t?.id||`toolu_${s}_${e}`,a=t?.function?.name||g.get(e)||``;h.set(e,r),g.set(e,a),_.add(e),yield i({event:`content_block_start`,data:JSON.stringify({type:`content_block_start`,index:n,content_block:{type:`tool_use`,id:r,name:a,input:{}}})})}a.length>o.length&&(yield i({event:`content_block_delta`,data:JSON.stringify({type:`content_block_delta`,index:n,delta:{type:`input_json_delta`,partial_json:a.slice(o.length)}})}),m.set(e,a))}x=r.tool_calls.length}}else if(n===`result`){if(!T){let e=Vi(r);yield i({event:`message_start`,data:JSON.stringify({type:`message_start`,message:{id:s,type:`message`,role:`assistant`,content:[],model:c,stop_reason:null,stop_sequence:null,usage:e}})}),T=!0}Array.isArray(r.tool_calls)&&(x=Math.max(x,r.tool_calls.length)),S=Vi(r),w=r.stopping_word||r.stoppingWord||null,C=Bi(r,_.size>0)}else if(n===`error`){yield i({event:`error`,data:JSON.stringify({type:`error`,error:{type:`api_error`,message:r.message||`completion error`}})});return}}v&&(yield i({event:`content_block_delta`,data:JSON.stringify({type:`content_block_delta`,index:0,delta:{type:`signature_delta`,signature:``}})}),yield i({event:`content_block_stop`,data:JSON.stringify({type:`content_block_stop`,index:0})})),y&&(yield i({event:`content_block_stop`,data:JSON.stringify({type:`content_block_stop`,index:b})}));for(let e of[..._].sort((e,t)=>e-t))yield i({event:`content_block_stop`,data:JSON.stringify({type:`content_block_stop`,index:E(e)})});yield i({event:`message_delta`,data:JSON.stringify({type:`message_delta`,delta:{stop_reason:C,stop_sequence:w},usage:{output_tokens:S.output_tokens}})}),yield i({event:`message_stop`,data:JSON.stringify({type:`message_stop`})})}finally{d.cancel().catch(()=>{})}}catch(e){return console.error(`[Anthropic] Messages error:`,e),t.status=500,{type:`error`,error:{type:`api_error`,message:e?.message||`Internal server error`}}}},{body:a.Object({model:a.Optional(a.String()),messages:a.Array(a.Any()),system:a.Optional(a.Any()),max_tokens:a.Optional(a.Number()),stream:a.Optional(a.Boolean()),temperature:a.Optional(a.Number()),top_p:a.Optional(a.Number()),top_k:a.Optional(a.Number()),stop_sequences:a.Optional(a.Union([a.String(),a.Array(a.String())])),tools:a.Optional(a.Array(a.Any())),tool_choice:a.Optional(a.Any()),thinking:a.Optional(a.Any()),metadata:a.Optional(a.Any())})}),t.post(`/v1/messages/count_tokens`,async({body:e,set:t,store:n})=>{let{config:r,backend:i}=n,a=e;try{let e=zi(a),t=await Mi(i,r,a.model,`[Anthropic]`),n=ji(i,t.type),o={messages:e.messages,add_generation_prompt:!0,jinja:!0};e.tools!=null&&(o.tools=e.tools);let s=await n.applyChatTemplate(t.id,o),c=typeof s==`string`?s:s?.prompt||``,l=await n.tokenize(t.id,{text:c,add_special:!0,parse_special:!0});return{input_tokens:(Array.isArray(l)?l:l?.tokens||[]).length}}catch(e){return console.error(`[Anthropic] count_tokens error:`,e),t.status=500,{type:`error`,error:{type:`api_error`,message:e?.message||`Internal server error`}}}},{body:a.Object({model:a.Optional(a.String()),messages:a.Array(a.Any()),system:a.Optional(a.Any()),tools:a.Optional(a.Array(a.Any())),tool_choice:a.Optional(a.Any())})}),t.get(`/v1/models`,({store:e})=>{let{config:t}=e,n=(t.generators||[]).filter(e=>ki.includes(e.type)).map(e=>{let t=e.model?.repo_id||e.type;return{id:t,type:`model`,display_name:t,created_at:new Date().toISOString()}});return n.length===0&&n.push({id:`ggml-llm`,type:`model`,display_name:`ggml-llm`,created_at:new Date().toISOString()}),{data:n,has_more:!1,first_id:n[0]?.id,last_id:n.at(-1)?.id}}),t}const Wi=(e={},t={})=>{let n=Array.isArray(e)?[...e]:{...e};return Object.entries(t||{}).forEach(([e,t])=>{t&&typeof t==`object`&&!Array.isArray(t)?n[e]=Wi(n[e]||{},t):n[e]=t}),n},Gi=e=>e&&typeof e==`object`?structuredClone(e):null,Ki=(e,t)=>Wi(Gi(e)||{},Gi(t)||{}),qi=(e,t)=>Wi(structuredClone(e.global),t||{}),Ji=(e,t,n,r)=>{if(e.generators.length>0){let i=e.generators.filter(e=>e?.type===n);if(i.length>0&&r){let a=i.find(e=>t.getModelIdentifier(n,e)===r);if(a)return qi(e,a)}}return Object.keys(e.global).length>0?qi(e,{}):null},Yi={udp:{port:8089,announcements:{enabled:!0,interval:5e3},requests:{enabled:!0,responseDelay:100}},http:{enabled:!0,path:`/buttress/info`,cors:!0}},Xi=e=>e?e===!0?{...Yi}:Wi(Yi,e):null,Zi=(e,t)=>{if(!e.generators||e.generators.length===0)return t.map(e=>({type:e}));let n=new Set;return e.generators.forEach(e=>{e.type&&n.add(e.type)}),n.size===0?t.map(e=>({type:e})):Array.from(n).map(e=>({type:e}))},Qi=(e,t,n)=>e===void 0?n:typeof e==`number`?e:t(e)??n,$i=6e4,ea=1024*1024*50,ta=e=>{let t=F.machineIdSync(),n=Wi({server:{id:`buttress-${t}`,name:`Buttress Server (${t.slice(-8)})`,port:2080,temp_file_dir:l.join(x.tmpdir(),`.buttress`),session_timeout:$i,max_body_size:ea},autodiscover:!1},Gi(e)||{}),r=Array.isArray(n.generators)?n.generators:[],{server:i,generators:a,autodiscover:o,...s}=n;return{autodiscover:Xi(o),server:{id:i.id,name:i.name,port:i.port,log_level:i.log_level,temp_file_dir:i.temp_file_dir,max_body_size:Qi(i.max_body_size,E.parse,ea),session_timeout:Qi(i.session_timeout,I,$i)},global:s,generators:r}},na={getCapabilities:M.tuple([M.object({type:M.string().optional().default(`ggml-llm`),config:M.any().optional(),currentClientCapabilities:M.any().optional(),options:M.any().optional()}).nullable().optional()]),startGenerator:M.tuple([M.string(),M.any().optional()]),finalizeGenerator:M.tuple([M.string()])};var ra={async getCapabilities({backend:e,config:t},n=null){console.log(`[Server] Get Capabilities:`,n);let{type:r=`ggml-llm`,config:i,currentClientCapabilities:a=null,options:o={}}=n||{type:`ggml-llm`},s=Gi(i),c=Ki(Ji(t,e,r,e.getModelIdentifier(r,s)),i);if(Object.keys(c).length===0)throw Error(`Buttress server missing generator configuration`);return c.backend=c.backend||{},c.backend.type||(c.backend.type=r),e.getCapabilities(r,a,{...o,config:c})},async startGenerator({backend:e,config:t,session:n},r,i){console.log(`[Server] Start Generator:`,r,i);let a=Gi(i),o=Ki(Ji(t,e,r,e.getModelIdentifier(r,a)),i);if(Object.keys(o).length===0)throw Error(`Buttress server missing generator configuration`);o.backend=o.backend||{},o.backend.type||(o.backend.type=r);let s=await e.startGenerator(r,o);return n.generators.add(s.id),s},async finalizeGenerator({backend:e,session:t},n){return console.log(`[Server] Finalize Generator:`,n),t.generators.delete(n),e.finalizeGenerator(n)}};const ia={initContext:M.tuple([M.string(),M.any().optional()]),completion:M.tuple([M.string(),M.any().optional()]),tokenize:M.tuple([M.string(),M.any()]),detokenize:M.tuple([M.string(),M.any()]),applyChatTemplate:M.tuple([M.string(),M.any()]),releaseContext:M.tuple([M.string()])};function aa(e){return function({backend:t,session:n},r,i){return new d({async start(a){try{let o=await e(t).initContext(r,{...i,onProgress:e=>{a.enqueue({event:`progress`,data:{progress:e}})}});n.initializedContexts.add(r),await new Promise(e=>setTimeout(e,1e3));let{download:s,...c}=o||{};a.enqueue({event:`result`,data:{result:c}}),a.close()}catch(e){a.error(e)}}})}}function oa(e,t){return async function({backend:n,session:r},i,a){return console.log(`[Server] ${t}:`,{id:i,force:a}),r.initializedContexts.has(i)?(r.initializedContexts.delete(i),e(n).releaseContext(i,{force:a})):(console.log(`[Server] ${t} skipped - not initialized by this session:`,{id:i}),{released:!1,skipped:!0})}}function sa(e,t){return{initContext:aa(e),completion({backend:n},r,i){return console.log(`[Server] ${t}Completion:`,{id:r,property:i}),e(n).completion(r,i)},async tokenize({backend:n},r,i){return console.log(`[Server] ${t}Tokenize:`,{id:r,property:i}),e(n).tokenize(r,i)},async detokenize({backend:n},r,i){return console.log(`[Server] ${t}Detokenize:`,{id:r,property:i}),e(n).detokenize(r,i)},async applyChatTemplate({backend:n},r,i){return console.log(`[Server] ${t}Apply Chat Template:`,{id:r,property:i}),e(n).applyChatTemplate(r,i)},releaseContext:oa(e,`${t}Release Context`)}}var ca=sa(e=>e.ggmlLlm,``);const la={initContext:M.tuple([M.string(),M.any().optional()]),transcribe:M.tuple([M.string(),M.string(),M.any().optional()]),transcribeData:M.tuple([M.string(),M.union([M.instanceof(Buffer),M.instanceof(Uint8Array)]),M.any().optional()]),releaseContext:M.tuple([M.string()])},ua=e=>e.ggmlStt,da={common:ra,ggmlLlm:ca,ggmlStt:{initContext:aa(ua),async transcribe({backend:e,config:{server:t},peerId:n},r,i,a){console.log(`[Server] Transcribe:`,{id:r,audioPath:i,options:a});let{filePath:o,safe:s}=xi(t.temp_file_dir,n,i);if(!s)throw Error(`Invalid audioPath`);return e.ggmlStt.transcribe(r,{audioPath:o,options:a})},async transcribeData({backend:e},t,n,r){return console.log(`[Server] Transcribe Data:`,{id:t,audioDataLength:n?.length||0,options:r}),e.ggmlStt.transcribeData(t,{audioData:n,options:r})},releaseContext:oa(ua,`Release STT Context`)},mlxLlm:sa(e=>e.mlxLlm,`MLX `)},fa={common:na,ggmlLlm:ia,ggmlStt:la,mlxLlm:ia};var pa=da;const ma=e=>{try{return JSON.parse(e,(e,t)=>{if(!t)return t;if(t?.type===`Buffer`&&t?.data)return L.from(t.data,`base64`);if(t?.type===`Uint8Array`&&t?.data){let e=L.from(t.data,`base64`);return e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)}return t?.type===`Error`&&t?.name&&t?.message?Error(t.name,t.message):t})}catch{return e}},ha=e=>{try{return JSON.stringify(e,(e,t)=>t instanceof Error?{type:`Error`,name:t.name,message:t.message}:t instanceof L?{type:`Buffer`,data:t.toString(`base64`)}:t instanceof Uint8Array?{type:`Uint8Array`,data:L.from(t).toString(`base64`)}:t)}catch{return e}},ga={score:0,hasGpu:!1,usableBytes:0},_a=e=>e?{score:Number(e.score)||0,hasGpu:!!e.hasGpu,usableBytes:Number(e.gpuUsableBytes||e.cpuUsableBytes||0)}:ga,va=async e=>{let t=[];for(let n of e){let e=ga;try{e=_a((await J(n.type,null,{}))?.buttress?.selected)}catch(e){console.warn(`[Caps] Failed to detect capabilities for "${n.type}":`,e instanceof Error?e.message:e)}t.push({...n,...e})}return t},ya=()=>{let e=x.networkInterfaces();return Object.values(e).flat().find(e=>e?.family===`IPv4`&&!e?.internal)?.address||null},ba=e=>{let t=e.split(`.`).map(Number);return t.length!==4||t.some(e=>Number.isNaN(e))?0:(t[0]<<24|t[1]<<16|t[2]<<8|t[3])>>>0},xa=e=>[e>>>24&255,e>>>16&255,e>>>8&255,e&255].join(`.`),Sa=()=>{let e=[],t=new Set;for(let n of Object.values(x.networkInterfaces()))for(let r of n??[]){if(r.family!==`IPv4`||r.internal||!r.address||!r.netmask)continue;let n=ba(r.address),i=ba(r.netmask);if(!n||!i||i===4294967295)continue;let a=xa((n&i|~i>>>0)>>>0);if(a===r.address)continue;let o=`${r.address}->${a}`;t.has(o)||(t.add(o),e.push({address:r.address,broadcast:a}))}return e},Ca=e=>{if(!e)return!1;let t=e;return t.code===`ENOTSUP`||/Failed to bind socket/i.test(t.message??``)};var wa=class e{name=`udp`;receiver=null;senders=[];announcementTimer=null;config;getServerInfo;port;signer;constructor(e,t,n){this.config=e,this.getServerInfo=t,this.port=e.port??8089,this.signer=n}async start(){this.receiver=await this.bindReceiver(!0).catch(e=>{if(!Ca(e))throw e;return console.warn(`[Autodiscover UDP] SO_REUSEPORT not supported by this runtime; falling back to REUSEADDR only (multiple buttress instances on one host will not coexist on the discovery port).`),this.bindReceiver(!1)}),this.receiver.on(`message`,(e,t)=>{this.handleMessage(e,t)}),this.receiver.on(`error`,e=>{console.error(`[Autodiscover UDP] Receiver error:`,e.message)}),this.receiver.setBroadcast(!0),this.senders=await this.createSenders();let e=this.senders.map(e=>`${e.address}->${e.broadcast}`).join(`, `)||`<none>`;if(console.log(`[Autodiscover UDP] Listening on port ${this.port}; announce interfaces: ${e}`),this.config.announcements.enabled){let e=this.config.announcements.interval??5e3;this.announcementTimer=setInterval(()=>{this.sendAnnouncement()},e),this.sendAnnouncement()}}async stop(){this.announcementTimer&&=(clearInterval(this.announcementTimer),null),await Promise.all(this.senders.map(({socket:e})=>new Promise(t=>{e.close(()=>t())}))),this.senders=[],this.receiver&&=(await new Promise(e=>{this.receiver.close(()=>e())}),null)}async bindReceiver(e){let t=R.createSocket(e?{type:`udp4`,reuseAddr:!0,reusePort:!0}:{type:`udp4`,reuseAddr:!0});return new Promise((e,n)=>{let r=e=>{t.close(),n(e)};t.once(`error`,r),t.bind(this.port,()=>{t.off(`error`,r),e(t)})})}async createSenders(){let e=Sa();return(await Promise.all(e.map(async e=>{try{let t=R.createSocket({type:`udp4`});return await new Promise((n,r)=>{let i=e=>{t.close(),r(e)};t.once(`error`,i),t.bind({port:0,address:e.address},()=>{t.off(`error`,i),t.setBroadcast(!0),n()})}),t.on(`error`,t=>{console.error(`[Autodiscover UDP] Sender ${e.address} error:`,t.message)}),{...e,socket:t}}catch(t){return console.warn(`[Autodiscover UDP] Failed to bind sender on ${e.address}:`,t.message),null}}))).filter(e=>e!==null)}handleMessage(e,t){try{let n=JSON.parse(e.toString());if(n.t===`QUERY`&&this.config.requests.enabled){let e=n.d,r=this.config.requests.responseDelay??0,i=r>0?Math.random()*r:0;setTimeout(()=>{this.sendResponse(e.id,t)},i)}}catch{}}static canonicalBytes(e,t,n){return Buffer.from(JSON.stringify({t:e,d:t,ts:n}),`utf8`)}signEnvelope(t,n){if(!this.signer)return null;let r=Math.floor(Date.now()/1e3),i=o.sign(null,e.canonicalBytes(t,n,r),this.signer.privateKey).toString(`base64`);return{t,v:`2.0`,d:n,ts:r,kid:this.signer.kid,sig:i}}sendAnnouncement(){if(this.senders.length===0)return;let e=this.getServerInfo(),t=this.signEnvelope(`ANNOUNCE`,{info:e});if(!t){console.warn("[Autodiscover UDP] no per-server keypair; skipping announcement. Run `bricks buttress bind` to register a key.");return}let n=Buffer.from(JSON.stringify(t));for(let{broadcast:e,socket:t,address:r}of this.senders)t.send(n,0,n.length,this.port,e,t=>{t&&console.error(`[Autodiscover UDP] Announcement ${r}->${e} error:`,t.message)})}sendResponse(e,t){if(!this.receiver)return;let n=this.getServerInfo(),r=this.signEnvelope(`RESPONSE`,{request_id:e,info:n});if(!r)return;let i=Buffer.from(JSON.stringify(r));this.receiver.send(i,0,i.length,t.port,t.address,e=>{e&&console.error(`[Autodiscover UDP] Response error:`,e.message)})}},Ta=class{transports=[];started=!1;constructor(e,t,n){this.config=e,this.getServerInfo=t,this.signer=n,(e.udp?.announcements?.enabled||e.udp?.requests?.enabled)&&this.transports.push(new wa(e.udp,t,n))}async start(){this.started||=((await Promise.allSettled(this.transports.map(e=>e.start()))).forEach((e,t)=>{e.status===`rejected`&&console.error(`[Autodiscover] Failed to start ${this.transports[t].name}:`,e.reason)}),!0)}async stop(){this.started&&=(await Promise.allSettled(this.transports.map(e=>e.stop())),!1)}};const Ea=()=>process.env.BRICKS_BUTTRESS_STATE_DIR||l.join(x.homedir(),`.bricks-cli`,`buttress`),Da=()=>l.join(Ea(),`state.json`),Oa=e=>{if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.id==`string`&&typeof t.serverId==`string`&&typeof t.issuerPublicKey==`string`&&typeof t.kid==`string`},ka=e=>{if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.publicKeySpki==`string`&&typeof t.privateKeyPkcs8==`string`&&typeof t.kid==`string`},Aa=()=>{let e=Da();try{let t=k.readFileSync(e,`utf8`),n=JSON.parse(t);return{workspace:Oa(n?.workspace)?n.workspace:null,serverKeyPair:ka(n?.serverKeyPair)?n.serverKeyPair:null}}catch(e){return e.code!==`ENOENT`&&console.warn(`[Buttress] Failed to read workspace state:`,e.message),{workspace:null,serverKeyPair:null}}},$=oi(),ja=e=>{if(!e)return{repoId:null,filename:null};let[t,n]=e.split(`:`);return{repoId:t,filename:n||null}};async function Ma({modelIds:e=[],defaultConfig:t=null}={}){let n=[];console.log(`${$.name} v${$.version}`),console.log(`Generating model capabilities comparison...
36
+ === Full Capabilities JSON ===`),console.log(JSON.stringify(u,null,2)),process.exit(0)}catch(e){console.error(`Failed to get capabilities:`,e.message),process.exit(1)}}var qr=e({finalizeGenerator:()=>Zr,generatorRegistry:()=>Z,getCapabilities:()=>J,getModelIdentifier:()=>ti,ggmlLlm:()=>Qr,ggmlStt:()=>ei,globalDownloadManager:()=>Jr,mlxLlm:()=>$r,showModelsTable:()=>Ur,showSttModelsTable:()=>Gr,startGenerator:()=>Xr,startModelDownload:()=>ri,status:()=>ni,testGgmlLlmCapabilities:()=>Wr,testGgmlSttCapabilities:()=>Kr});const Z=new Map,Jr={downloads:new Map,getDownload(e){return this.downloads.get(e)||null},setDownload(e,t){this.downloads.set(e,t)},deleteDownload(e){this.downloads.delete(e)},isDownloading(e){return this.downloads.has(e)},getActiveDownloads(){return Array.from(this.downloads.entries()).map(([e,t])=>({localPath:e,promise:t}))}},Yr=e=>{let t=Z.get(e);if(!t)throw Error(`Unknown generator id "${e}"`);return t},Q=(e,t)=>{let n=Yr(e);if(n.type!==t)throw Error(`Generator "${e}" does not support ${t} backend`);return n.instance};async function Xr(e,t){let n={"ggml-llm":{create:pn,getId:mn},"ggml-stt":{create:tr,getId:nr},"mlx-llm":{create:Lr,getId:Rr}}[e];if(!n)throw Error(`Unsupported backend type: ${e}`);let r=n.getId(t);if(!r)throw Error(`Buttress generator config missing repo identifier`);let i=`${e}:${r}`,a=Z.get(i);if(a)return a.refCount+=1,a.instance.resetFinalized?.(),{id:a.id,info:a.instance.info};let o=await n.create(i,t,{globalDownloadManager:Jr}),s={id:i,type:o.type,instance:o,refCount:1};return Z.set(i,s),{id:i,info:o.info}}async function Zr(e){let t=Z.get(e);return t?(--t.refCount,t.refCount<=0&&(await t.instance.finalize(),(t.instance.hasPendingReleases?.()??!1)||Z.delete(e)),!0):!1}const Qr={async initContext(e,t){return Q(e,`ggml-llm`).initContext(t)},async completion(e,t){return Q(e,`ggml-llm`).completion(t)},async tokenize(e,t){return Q(e,`ggml-llm`).tokenize(t)},async detokenize(e,t){return Q(e,`ggml-llm`).detokenize(t)},async applyChatTemplate(e,t){return Q(e,`ggml-llm`).applyChatTemplate(t)},async releaseContext(e,t){let n=Z.get(e);if(!n)return{released:!0,alreadyReleased:!0};if(n.type!==`ggml-llm`)throw Error(`Generator "${e}" does not support ggml-llm backend`);return n.instance.releaseContext(t)}},$r={async initContext(e,t){return Q(e,`mlx-llm`).initContext(t)},async completion(e,t){return Q(e,`mlx-llm`).completion(t)},async tokenize(e,t){return Q(e,`mlx-llm`).tokenize(t)},async detokenize(e,t){return Q(e,`mlx-llm`).detokenize(t)},async applyChatTemplate(e,t){return Q(e,`mlx-llm`).applyChatTemplate(t)},async releaseContext(e,t){let n=Z.get(e);if(!n)return{released:!0,alreadyReleased:!0};if(n.type!==`mlx-llm`)throw Error(`Generator "${e}" does not support mlx-llm backend`);return n.instance.releaseContext(t)}},ei={async initContext(e,t){return Q(e,`ggml-stt`).initContext(t)},async transcribe(e,t){return Q(e,`ggml-stt`).transcribe(t)},async transcribeData(e,t){return Q(e,`ggml-stt`).transcribeData(t)},async releaseContext(e,t){let n=Z.get(e);if(!n)return{released:!0,alreadyReleased:!0};if(n.type!==`ggml-stt`)throw Error(`Generator "${e}" does not support ggml-stt backend`);return n.instance.releaseContext(t)}};function ti(e,t){return e===`ggml-llm`?mn(t):e===`ggml-stt`?nr(t):e===`mlx-llm`?Rr(t):null}const ni={getFullStatus:()=>it(Z),getGgmlLlmStatus:()=>tt(Z),getGgmlSttStatus:()=>nt(Z),getMlxLlmStatus:()=>rt(Z),subscribeToStatus:$e,subscribeToStatusWithId:et,llmStatusTracker:H,sttStatusTracker:U,statusEmitter:V};async function ri(e,t,n={}){let r={"ggml-llm":hn,"ggml-stt":rr,"mlx-llm":Br}[e];return r?r(t,Jr,n):{started:!1,localPath:null,repoId:null,error:`Unknown backend type: ${e}`}}let ii=null;const ai={name:`@fugood/buttress-server`,version:`0.0.0`},oi=()=>{if(ii)return ii;try{let e=te(new URL(`../package.json`,import.meta.url)),t=JSON.parse(k.readFileSync(e,`utf8`));ii={name:t.name||ai.name,version:t.version||ai.version,description:t.description}}catch{ii=ai}return ii},si=!(`Bun`in globalThis),ci=e=>new n({adapter:si?t():void 0,...e}),li=a.Object({id:a.String(),name:a.String(),version:a.String(),generators:a.Array(a.Object({type:a.String(),score:a.Optional(a.Number()),hasGpu:a.Optional(a.Boolean()),usableBytes:a.Optional(a.Number())})),authentication:a.Object({required:a.Boolean(),type:a.String(),kid:a.Optional(a.String()),bound:a.Optional(a.Boolean())}),workspace:a.Optional(a.Object({id:a.String(),name:a.Optional(a.String())}))}),ui=({store:{serverInfo:e}})=>({id:e.id,name:e.name,version:e.version,generators:e.generators,authentication:e.authentication,workspace:e.workspace});var di=e=>{let t=ci(),n=e.autodiscover?.http?.path??`/buttress/info`;return t.get(n,ui,{response:li}),t};let fi=null;const pi=async e=>{if(fi&&fi.kid===e.kid)return fi.key;let t=await N(e.issuerPublicKey,`EdDSA`);return fi={kid:e.kid,key:t},t},mi=/^Bearer\s+(.+)$/i,hi=(e,t)=>{if(e){let t=e.authorization||e.Authorization;if(t){let e=t.match(mi);return e?e[1].trim():t.trim()}}if(t){let e=t.access_token??t.token;if(typeof e==`string`&&e)return e}return null},gi=async(e,t)=>{if(!e||!t)return null;try{let{payload:n}=await P(e,await pi(t),{algorithms:[`EdDSA`]}),r=n;return r.k!==`ba`||r.w_id!==t.id||r.st!==`ws`&&r.st!==`dev`||!r.sid||!r.exp?null:{workspaceId:r.w_id,subjectType:r.st,subjectId:r.sid,jti:r.jti,exp:r.exp}}catch{return null}},_i=async({headers:e,query:t,set:n,store:r})=>{let i=r.workspaceState?.workspace;if(i&&!await gi(hi(e,t),i))return n.status=401,n.headers&&(n.headers[`WWW-Authenticate`]=`Bearer`),{error:{code:`UNAUTHORIZED`,message:`Invalid or missing workspace access token`}}},vi=e=>{if(!e)return null;let t=e[`x-buttress-sess-id`]??e[`X-BUTTRESS-SESS-ID`];return t?t.trim():null},yi=async({headers:e,query:t,set:n,store:r})=>{let i=r.sessions,a=vi(e);if(!a||!i)return n.status=401,{error:{code:`SESSION_REQUIRED`,message:`Missing buttress session id`}};let o=i.get(a);if(!o)return n.status=401,{error:{code:`SESSION_INVALID`,message:`Unknown or expired buttress session`}};let s=r.workspaceState?.workspace;if(s&&o.identity){let r=await gi(hi(e,t),s);if(!r||r.subjectId!==o.identity.subjectId||r.subjectType!==o.identity.subjectType)return n.status=403,{error:{code:`SESSION_FORBIDDEN`,message:`Token identity mismatch for this session`}}}},bi=(e,t)=>{let n=e.sessions,r=vi(t);if(!r||!n)return null;let i=n.get(r);return i?{sessionId:r,session:i}:null},xi=(e,t,n)=>{let r=l.join(e,t),i=l.join(r,n),a=l.relative(r,i);return{sessionDir:r,filePath:i,safe:a!==``&&!a.startsWith(`..`)&&!l.isAbsolute(a)}},Si=typeof process<`u`&&process.versions!=null&&process.versions.node!=null;var Ci=ci().onBeforeHandle(_i).onBeforeHandle(yi).post(`/buttress/upload`,async({body:{file:e},headers:t,store:n})=>{let r=bi(n,t);if(!r)return{ok:!1,error:`Session guard mis-wired`};let{sessionId:i}=r,{config:a}=n,o=`${Date.now()}-${e.name.replace(/[^\dA-Za-z]/g,`_`)}`,{sessionDir:s,filePath:c,safe:l}=xi(a.server.temp_file_dir,i,o);if(!l)return{ok:!1,error:`Invalid file path`};try{return await p(s,{recursive:!0}),Si?await b(c,await e.stream()):await b(c,await e.arrayBuffer()),{ok:!0,filename:o}}catch(e){return{ok:!1,error:String(e)}}},{body:a.Object({file:a.File()}),response:a.Object({ok:a.Boolean(),filename:a.Optional(a.String()),error:a.Optional(a.String())})}).get(`/buttress/download/:filename`,async({params:{filename:e},headers:t,store:n,status:i})=>{let a=bi(n,t);if(!a)return i(500),`Session guard mis-wired`;let{sessionId:o}=a,{config:s}=n,{filePath:c,safe:l}=xi(s.server.temp_file_dir,o,e);return l?r(c):(i(400),`Invalid file path`)},{params:a.Object({filename:a.String()})});const wi=l.dirname(te(import.meta.url)),Ti=async()=>{let e=[l.join(wi,`..`,`public`,`status.html`),l.join(wi,`..`,`..`,`public`,`status.html`)];return(await Promise.all(e.map(e=>f.access(e).then(()=>e,()=>null)))).find(e=>e!==null)??null},Ei=e=>{let{status:t}=e;return t?.getFullStatus?t.getFullStatus():{timestamp:new Date().toISOString(),ggmlLlm:{generators:[],history:{}},ggmlStt:{generators:[],history:{}}}},Di=async()=>{let e=await Ti();if(!e)return console.error(`[Status] Failed to find status.html in candidate paths`),new Response(`Status page not found`,{status:404,headers:{"Content-Type":`text/plain`}});try{let t=await f.readFile(e,`utf-8`);return new Response(t,{headers:{"Content-Type":`text/html; charset=utf-8`}})}catch(e){return console.error(`[Status] Failed to serve status page:`,e),new Response(`Status page not found`,{status:404,headers:{"Content-Type":`text/plain`}})}};var Oi=ci().get(`/status`,Di).get(`/status/`,Di).get(`/buttress/status`,({store:{backend:e}})=>Ei(e));const ki=[`ggml-llm`,`mlx-llm`],Ai=new Map;function ji(e,t){return t===`mlx-llm`?e.mlxLlm:e.ggmlLlm}async function Mi(e,t,n,r=`[LLM]`){let i=(t.generators||[]).filter(e=>ki.includes(e.type));if(i.length===0)throw Error(`No LLM generator configured. Add a [[generators]] with type = "ggml-llm" or "mlx-llm" to your config.`);let a=i[0],o=n||a.model?.repo_id;if(n){let e=i.find(e=>e.model?.repo_id===n);e&&(a=e)}else o=a.model?.repo_id;let s=a.type||`ggml-llm`,c=o,l=Ai.get(c);if(l?.initialized)return l;let{generators:u,server:d,...f}=t.global||{},p={...f,...a,model:{...a.model,repo_id:o}};console.log(`${r} Creating ${s} generator for ${c}`);let{id:m}=await e.startGenerator(s,p),h={id:m,type:s,config:p,repoId:o,initialized:!1};return Ai.set(c,h),await ji(e,s).initContext(m,{}),h.initialized=!0,console.log(`${r} Generator ready: ${c}`),h}function Ni(e){let t=e.timings||{},n=t.prompt_n??t.promptN??0,r=t.cache_n??t.cacheN??0,i=t.predicted_n??t.predictedN??0;return{promptTokens:n||e.prompt_tokens||e.promptTokens||0,cachedTokens:r,completionTokens:i||e.tokens_evaluated||e.tokensEvaluated||e.tokens_predicted||e.tokensPredicted||0}}function Pi(e){let{promptTokens:t,cachedTokens:n,completionTokens:r}=Ni(e),i=t+n;return{prompt_tokens:i,completion_tokens:r,total_tokens:i+r}}const Fi=()=>`chatcmpl-${Date.now()}-${Math.random().toString(36).slice(2,9)}`;async function Ii(e,t,n,r){let i=e.getReader(),a=``,o=null,s=null,c=`stop`,l={prompt_tokens:0,completion_tokens:0,total_tokens:0};try{let e=!1;for(;!e;){let n=await i.read();if({done:e}=n,e)break;let{event:r,data:u}=n.value;if(r===`token`)u.content!=null&&(a=u.content),u.reasoning_content!=null&&(o=u.reasoning_content);else if(r===`result`)u.content==null?u.text&&(a=u.text):a=u.content,u.reasoning_content!=null&&(o=u.reasoning_content),u.tool_calls?.length>0?(s=u.tool_calls.map((e,n)=>({id:e.id||`call_${t}_${n}`,type:`function`,function:{name:e.function?.name||``,arguments:e.function?.arguments||``}})),c=`tool_calls`):c=u.interrupted?`length`:`stop`,l=Pi(u);else if(r===`error`)throw Error(u.message)}}finally{i.cancel().catch(()=>{})}let u={role:`assistant`,content:a||null};return o&&(u.reasoning_content=o),s&&(u.tool_calls=s),{id:t,object:`chat.completion`,created:n,model:r,choices:[{index:0,message:u,finish_reason:c}],usage:l}}function Li({global:e}){let t=ci({prefix:`/oai-compat`});return t.use(ie({origin:e?.openai_compat?.cors_allowed_origins??!1,methods:[`GET`,`POST`,`OPTIONS`],allowedHeaders:[`Content-Type`,`Authorization`],maxAge:86400,preflight:!0})),t.onBeforeHandle(_i),t.get(`/v1/models`,({store:e})=>{let{config:t}=e,n=(t.generators||[]).filter(e=>ki.includes(e.type)).map(e=>({id:e.model?.repo_id||e.type,object:`model`,created:Math.floor(Date.now()/1e3),owned_by:`local`}));return n.length===0&&n.push({id:`ggml-llm`,object:`model`,created:Math.floor(Date.now()/1e3),owned_by:`local`}),{object:`list`,data:n}}),t.post(`/v1/chat/completions`,async function*({body:e,set:t,store:n}){let{config:r,backend:a}=n,{messages:o=[],stream:s=!1,model:c,tools:l,temperature:u,stop:d,top_p:f,max_tokens:p,presence_penalty:m,frequency_penalty:h,tool_choice:g,stream_options:_,enable_thinking:v}=e;if(!o||o.length===0)return t.status=400,{error:{message:`messages is required and must not be empty`,type:`invalid_request_error`}};try{let e=await Mi(a,r,c,`[OpenAI]`),t=Fi(),n=Math.floor(Date.now()/1e3),y=e.repoId||`ggml-llm`,b={reasoning_format:`auto`,messages:o,jinja:!0,add_generation_prompt:!0};u!=null&&(b.temperature=u),f!=null&&(b.top_p=f),p!=null&&(b.n_predict=p),d!=null&&(b.stop=Array.isArray(d)?d:[d]),m!=null&&(b.presence_penalty=m),h!=null&&(b.frequency_penalty=h),l!=null&&(b.tools=l),g!=null&&(b.tool_choice=g),b.enable_thinking=v??!1;let x=await ji(a,e.type).completion(e.id,{options:b});if(!s)return await Ii(x,t,n,y);let S=_?.include_usage===!0,C=x.getReader(),w=``,T=``,E=new Map,D=new Map;try{let e=!1;for(;!e;){let r=await C.read();if({done:e}=r,e)break;let{event:a,data:o}=r.value;if(a===`token`){let e={};if(o.content!=null){let t=o.content;t.length>w.length&&(e.content=t.slice(w.length),w=t)}if(o.reasoning_content!=null){let t=o.reasoning_content;t.length>T.length&&(e.reasoning_content=t.slice(T.length),T=t)}if(o.tool_calls?.length>0){let n=[];o.tool_calls.forEach((e,r)=>{let i={index:r};D.has(r)||(D.set(r,e.id||`call_${t}_${r}`),i.id=D.get(r),i.type=`function`);let a=e.function?.arguments||``,o=E.get(r)||``,s={};!E.has(r)&&e.function?.name&&(s.name=e.function.name),a.length>o.length&&(s.arguments=a.slice(o.length),E.set(r,a)),Object.keys(s).length>0?(i.function=s,n.push(i)):i.id&&(i.function={name:e.function?.name||``,arguments:``},n.push(i))}),n.length>0&&(e.tool_calls=n)}Object.keys(e).length>0&&(yield i({data:JSON.stringify({id:t,object:`chat.completion.chunk`,created:n,model:y,choices:[{index:0,delta:e,finish_reason:null}]})}))}else if(a===`result`){let e=`stop`;o.tool_calls?.length>0||D.size>0?e=`tool_calls`:o.interrupted&&(e=`length`);let r={id:t,object:`chat.completion.chunk`,created:n,model:y,choices:[{index:0,delta:{},finish_reason:e}]};S&&(r.usage=Pi(o)),yield i({data:JSON.stringify(r)})}else a===`error`&&(yield i({data:JSON.stringify({error:{message:o.message,type:`server_error`}})}))}yield i({data:`[DONE]`})}finally{C.cancel().catch(()=>{})}}catch(e){return console.error(`[OpenAI] Chat completion error:`,e),t.status=500,{error:{message:e.message||`Internal server error`,type:`server_error`}}}},{body:a.Object({model:a.Optional(a.String()),messages:a.Array(a.Any()),stream:a.Optional(a.Boolean()),temperature:a.Optional(a.Number()),top_p:a.Optional(a.Number()),max_tokens:a.Optional(a.Number()),stop:a.Optional(a.Union([a.String(),a.Array(a.String())])),presence_penalty:a.Optional(a.Number()),frequency_penalty:a.Optional(a.Number()),tools:a.Optional(a.Array(a.Any())),tool_choice:a.Optional(a.Any()),stream_options:a.Optional(a.Object({include_usage:a.Optional(a.Boolean())})),enable_thinking:a.Optional(a.Boolean())})}),t}const Ri=()=>`msg_${Date.now()}${Math.random().toString(36).slice(2,11)}`;function zi(e){let t={},n=[];if(e.system!=null){let t=``;if(typeof e.system==`string`)t=e.system;else if(Array.isArray(e.system))for(let n of e.system)n?.type===`text`&&typeof n.text==`string`&&(t+=n.text);t&&n.push({role:`system`,content:t})}if(!Array.isArray(e.messages))throw Error(`'messages' is required and must be an array`);for(let t of e.messages){let e=t?.role||`user`;if(t?.content==null){if(e===`assistant`)continue;n.push(t);continue}if(typeof t.content==`string`){n.push({role:e,content:t.content});continue}if(!Array.isArray(t.content)){n.push(t);continue}let r=[],i=[],a=[],o=``,s=!1;for(let e of t.content){let t=e?.type||``;if(t===`text`)i.push({type:`text`,text:e.text||``});else if(t===`thinking`)o+=e.thinking||``;else if(t===`image`){let t=e.source||{};if(t.type===`base64`){let e=t.media_type||`image/jpeg`,n=t.data||``;i.push({type:`image_url`,image_url:{url:`data:${e};base64,${n}`}})}else t.type===`url`&&i.push({type:`image_url`,image_url:{url:t.url||``}})}else if(t===`tool_use`)r.push({id:e.id||``,type:`function`,function:{name:e.name||``,arguments:JSON.stringify(e.input??{})}}),s=!0;else if(t===`tool_result`){let t=e.tool_use_id||``,n=``,r=e.content;if(typeof r==`string`)n=r;else if(Array.isArray(r))for(let e of r)e?.type===`text`&&(n+=e.text||``);a.push({role:`tool`,tool_call_id:t,content:n})}}if(i.length>0||s||o){let t={role:e};i.length>0?t.content=i:(s||o)&&(t.content=``),r.length>0&&(t.tool_calls=r),o&&(t.reasoning_content=o),n.push(t)}for(let e of a)n.push(e)}if(t.messages=n,Array.isArray(e.tools)&&(t.tools=e.tools.map(e=>({type:`function`,function:{name:e.name||``,description:e.description||``,parameters:e.input_schema||{}}}))),e.tool_choice&&typeof e.tool_choice==`object`){let n=e.tool_choice.type;n===`auto`?t.tool_choice=`auto`:n===`any`||n===`tool`?t.tool_choice=`required`:n===`none`&&(t.tool_choice=`none`)}else Array.isArray(t.tools)&&t.tools.length>0&&(t.tool_choice=`auto`);e.stop_sequences!=null&&(t.stop=Array.isArray(e.stop_sequences)?e.stop_sequences:[e.stop_sequences]),t.max_tokens=e.max_tokens??4096;for(let n of[`temperature`,`top_p`,`top_k`,`stream`])e[n]!=null&&(t[n]=e[n]);return e.thinking&&typeof e.thinking==`object`&&e.thinking.type===`enabled`&&(t.enable_thinking=!0,e.thinking.budget_tokens!=null&&(t.thinking_budget_tokens=e.thinking.budget_tokens)),t}function Bi(e,t){return t?`tool_use`:e.stopping_word||e.stoppingWord?`stop_sequence`:e.interrupted||e.truncated?`max_tokens`:`end_turn`}function Vi(e){let{promptTokens:t,cachedTokens:n,completionTokens:r}=Ni(e);return{cache_read_input_tokens:n,input_tokens:t,output_tokens:r}}async function Hi(e,t,n){let r=e.getReader(),i=``,a=``,o=[],s={cache_read_input_tokens:0,input_tokens:0,output_tokens:0},c=`end_turn`,l=null;try{let e=!1;for(;!e;){let t=await r.read();if({done:e}=t,e)break;let{event:n,data:u}=t.value;if(n===`token`)u.content!=null&&(i=u.content),u.reasoning_content!=null&&(a=u.reasoning_content);else if(n===`result`)u.content==null?u.text&&u.reasoning_content==null&&(i=u.text):i=u.content,u.reasoning_content!=null&&(a=u.reasoning_content),Array.isArray(u.tool_calls)&&(o=u.tool_calls),s=Vi(u),l=u.stopping_word||u.stoppingWord||null,c=Bi(u,o.length>0);else if(n===`error`)throw Error(u.message||`completion error`)}}finally{r.cancel().catch(()=>{})}let u=[];a&&u.push({type:`thinking`,thinking:a,signature:``}),i&&u.push({type:`text`,text:i});for(let e of o){let t={};try{t=JSON.parse(e.function?.arguments||`{}`)}catch{t={}}u.push({type:`tool_use`,id:e.id||`toolu_${Math.random().toString(36).slice(2,11)}`,name:e.function?.name||``,input:t})}return{id:t,type:`message`,role:`assistant`,content:u,model:n,stop_reason:c,stop_sequence:l,usage:s}}function Ui({global:e}){let t=ci({prefix:`/anthropic-messages`});return t.use(ie({origin:e?.anthropic_messages?.cors_allowed_origins??!1,methods:[`GET`,`POST`,`OPTIONS`],allowedHeaders:[`Content-Type`,`Authorization`,`x-api-key`,`anthropic-version`],maxAge:86400,preflight:!0})),t.onBeforeHandle(_i),t.post(`/v1/messages`,async function*({body:e,set:t,store:n}){let{config:r,backend:a}=n,o=e;try{if(!Array.isArray(o.messages)||o.messages.length===0)return t.status=400,{type:`error`,error:{type:`invalid_request_error`,message:`messages is required and must not be empty`}};let e=zi(o),n=await Mi(a,r,o.model,`[Anthropic]`),s=Ri(),c=n.repoId||`ggml-llm`,l={reasoning_format:`auto`,messages:e.messages,jinja:!0,add_generation_prompt:!0};e.temperature!=null&&(l.temperature=e.temperature),e.top_p!=null&&(l.top_p=e.top_p),e.top_k!=null&&(l.top_k=e.top_k),e.max_tokens!=null&&(l.n_predict=e.max_tokens),e.stop!=null&&(l.stop=e.stop),e.tools!=null&&(l.tools=e.tools),e.tool_choice!=null&&(l.tool_choice=e.tool_choice),l.enable_thinking=e.enable_thinking??!1,e.thinking_budget_tokens!=null&&(l.thinking_budget_tokens=e.thinking_budget_tokens);let u=await ji(a,n.type).completion(n.id,{options:l});if(!o.stream)return await Hi(u,s,c);let d=u.getReader(),f=``,p=``,m=new Map,h=new Map,g=new Map,_=new Set,v=!1,y=!1,b=0,x=0,S={cache_read_input_tokens:0,input_tokens:0,output_tokens:0},C=`end_turn`,w=null,T=!1,E=e=>(v?1:0)+(y?1:0)+e;try{let e=!1;for(;!e;){let t=await d.read();if({done:e}=t,e)break;let{event:n,data:r}=t.value;if(n===`token`){if(!T){let e=Vi(r);yield i({event:`message_start`,data:JSON.stringify({type:`message_start`,message:{id:s,type:`message`,role:`assistant`,content:[],model:c,stop_reason:null,stop_sequence:null,usage:e}})}),T=!0}if(r.reasoning_content!=null){let e=r.reasoning_content;e.length>p.length&&(v||(yield i({event:`content_block_start`,data:JSON.stringify({type:`content_block_start`,index:0,content_block:{type:`thinking`,thinking:``}})}),v=!0,b=1),yield i({event:`content_block_delta`,data:JSON.stringify({type:`content_block_delta`,index:0,delta:{type:`thinking_delta`,thinking:e.slice(p.length)}})}),p=e)}if(r.content!=null){let e=r.content;e.length>f.length&&(y||=(yield i({event:`content_block_start`,data:JSON.stringify({type:`content_block_start`,index:b,content_block:{type:`text`,text:``}})}),!0),yield i({event:`content_block_delta`,data:JSON.stringify({type:`content_block_delta`,index:b,delta:{type:`text_delta`,text:e.slice(f.length)}})}),f=e)}if(Array.isArray(r.tool_calls)&&r.tool_calls.length>0){for(let e=0;e<r.tool_calls.length;e+=1){let t=r.tool_calls[e],n=E(e),a=t?.function?.arguments||``,o=m.get(e)||``;if(!_.has(e)){let r=t?.id||`toolu_${s}_${e}`,a=t?.function?.name||g.get(e)||``;h.set(e,r),g.set(e,a),_.add(e),yield i({event:`content_block_start`,data:JSON.stringify({type:`content_block_start`,index:n,content_block:{type:`tool_use`,id:r,name:a,input:{}}})})}a.length>o.length&&(yield i({event:`content_block_delta`,data:JSON.stringify({type:`content_block_delta`,index:n,delta:{type:`input_json_delta`,partial_json:a.slice(o.length)}})}),m.set(e,a))}x=r.tool_calls.length}}else if(n===`result`){if(!T){let e=Vi(r);yield i({event:`message_start`,data:JSON.stringify({type:`message_start`,message:{id:s,type:`message`,role:`assistant`,content:[],model:c,stop_reason:null,stop_sequence:null,usage:e}})}),T=!0}Array.isArray(r.tool_calls)&&(x=Math.max(x,r.tool_calls.length)),S=Vi(r),w=r.stopping_word||r.stoppingWord||null,C=Bi(r,_.size>0)}else if(n===`error`){yield i({event:`error`,data:JSON.stringify({type:`error`,error:{type:`api_error`,message:r.message||`completion error`}})});return}}v&&(yield i({event:`content_block_delta`,data:JSON.stringify({type:`content_block_delta`,index:0,delta:{type:`signature_delta`,signature:``}})}),yield i({event:`content_block_stop`,data:JSON.stringify({type:`content_block_stop`,index:0})})),y&&(yield i({event:`content_block_stop`,data:JSON.stringify({type:`content_block_stop`,index:b})}));for(let e of[..._].sort((e,t)=>e-t))yield i({event:`content_block_stop`,data:JSON.stringify({type:`content_block_stop`,index:E(e)})});yield i({event:`message_delta`,data:JSON.stringify({type:`message_delta`,delta:{stop_reason:C,stop_sequence:w},usage:{output_tokens:S.output_tokens}})}),yield i({event:`message_stop`,data:JSON.stringify({type:`message_stop`})})}finally{d.cancel().catch(()=>{})}}catch(e){return console.error(`[Anthropic] Messages error:`,e),t.status=500,{type:`error`,error:{type:`api_error`,message:e?.message||`Internal server error`}}}},{body:a.Object({model:a.Optional(a.String()),messages:a.Array(a.Any()),system:a.Optional(a.Any()),max_tokens:a.Optional(a.Number()),stream:a.Optional(a.Boolean()),temperature:a.Optional(a.Number()),top_p:a.Optional(a.Number()),top_k:a.Optional(a.Number()),stop_sequences:a.Optional(a.Union([a.String(),a.Array(a.String())])),tools:a.Optional(a.Array(a.Any())),tool_choice:a.Optional(a.Any()),thinking:a.Optional(a.Any()),metadata:a.Optional(a.Any())})}),t.post(`/v1/messages/count_tokens`,async({body:e,set:t,store:n})=>{let{config:r,backend:i}=n,a=e;try{let e=zi(a),t=await Mi(i,r,a.model,`[Anthropic]`),n=ji(i,t.type),o={messages:e.messages,add_generation_prompt:!0,jinja:!0};e.tools!=null&&(o.tools=e.tools);let s=await n.applyChatTemplate(t.id,o),c=typeof s==`string`?s:s?.prompt||``,l=await n.tokenize(t.id,{text:c,add_special:!0,parse_special:!0});return{input_tokens:(Array.isArray(l)?l:l?.tokens||[]).length}}catch(e){return console.error(`[Anthropic] count_tokens error:`,e),t.status=500,{type:`error`,error:{type:`api_error`,message:e?.message||`Internal server error`}}}},{body:a.Object({model:a.Optional(a.String()),messages:a.Array(a.Any()),system:a.Optional(a.Any()),tools:a.Optional(a.Array(a.Any())),tool_choice:a.Optional(a.Any())})}),t.get(`/v1/models`,({store:e})=>{let{config:t}=e,n=(t.generators||[]).filter(e=>ki.includes(e.type)).map(e=>{let t=e.model?.repo_id||e.type;return{id:t,type:`model`,display_name:t,created_at:new Date().toISOString()}});return n.length===0&&n.push({id:`ggml-llm`,type:`model`,display_name:`ggml-llm`,created_at:new Date().toISOString()}),{data:n,has_more:!1,first_id:n[0]?.id,last_id:n.at(-1)?.id}}),t}const Wi=(e={},t={})=>{let n=Array.isArray(e)?[...e]:{...e};return Object.entries(t||{}).forEach(([e,t])=>{t&&typeof t==`object`&&!Array.isArray(t)?n[e]=Wi(n[e]||{},t):n[e]=t}),n},Gi=e=>e&&typeof e==`object`?structuredClone(e):null,Ki=(e,t)=>Wi(Gi(e)||{},Gi(t)||{}),qi=(e,t)=>Wi(structuredClone(e.global),t||{}),Ji=(e,t,n,r)=>{if(e.generators.length>0){let i=e.generators.filter(e=>e?.type===n);if(i.length>0&&r){let a=i.find(e=>t.getModelIdentifier(n,e)===r);if(a)return qi(e,a)}}return Object.keys(e.global).length>0?qi(e,{}):null},Yi={udp:{port:8089,announcements:{enabled:!0,interval:5e3},requests:{enabled:!0,responseDelay:100}},http:{enabled:!0,path:`/buttress/info`,cors:!0}},Xi=e=>e?e===!0?{...Yi}:Wi(Yi,e):null,Zi=(e,t)=>{if(!e.generators||e.generators.length===0)return t.map(e=>({type:e}));let n=new Set;return e.generators.forEach(e=>{e.type&&n.add(e.type)}),n.size===0?t.map(e=>({type:e})):Array.from(n).map(e=>({type:e}))},Qi=(e,t,n)=>e===void 0?n:typeof e==`number`?e:t(e)??n,$i=6e4,ea=1024*1024*50,ta=e=>{let t=F.machineIdSync(),n=Wi({server:{id:`buttress-${t}`,name:`Buttress Server (${t.slice(-8)})`,port:2080,temp_file_dir:l.join(x.tmpdir(),`.buttress`),session_timeout:$i,max_body_size:ea},autodiscover:!1},Gi(e)||{}),r=Array.isArray(n.generators)?n.generators:[],{server:i,generators:a,autodiscover:o,...s}=n;return{autodiscover:Xi(o),server:{id:i.id,name:i.name,port:i.port,log_level:i.log_level,temp_file_dir:i.temp_file_dir,max_body_size:Qi(i.max_body_size,E.parse,ea),session_timeout:Qi(i.session_timeout,I,$i)},global:s,generators:r}},na={getCapabilities:M.tuple([M.object({type:M.string().optional().default(`ggml-llm`),config:M.any().optional(),currentClientCapabilities:M.any().optional(),options:M.any().optional()}).nullable().optional()]),startGenerator:M.tuple([M.string(),M.any().optional()]),finalizeGenerator:M.tuple([M.string()])};var ra={async getCapabilities({backend:e,config:t},n=null){console.log(`[Server] Get Capabilities:`,n);let{type:r=`ggml-llm`,config:i,currentClientCapabilities:a=null,options:o={}}=n||{type:`ggml-llm`},s=Gi(i),c=Ki(Ji(t,e,r,e.getModelIdentifier(r,s)),i);if(Object.keys(c).length===0)throw Error(`Buttress server missing generator configuration`);return c.backend=c.backend||{},c.backend.type||(c.backend.type=r),e.getCapabilities(r,a,{...o,config:c})},async startGenerator({backend:e,config:t,session:n},r,i){console.log(`[Server] Start Generator:`,r,i);let a=Gi(i),o=Ki(Ji(t,e,r,e.getModelIdentifier(r,a)),i);if(Object.keys(o).length===0)throw Error(`Buttress server missing generator configuration`);o.backend=o.backend||{},o.backend.type||(o.backend.type=r);let s=await e.startGenerator(r,o);return n.generators.add(s.id),s},async finalizeGenerator({backend:e,session:t},n){return console.log(`[Server] Finalize Generator:`,n),t.generators.delete(n),e.finalizeGenerator(n)}};const ia={initContext:M.tuple([M.string(),M.any().optional()]),completion:M.tuple([M.string(),M.any().optional()]),tokenize:M.tuple([M.string(),M.any()]),detokenize:M.tuple([M.string(),M.any()]),applyChatTemplate:M.tuple([M.string(),M.any()]),releaseContext:M.tuple([M.string()])};function aa(e){return function({backend:t,session:n},r,i){return new d({async start(a){try{let o=await e(t).initContext(r,{...i,onProgress:e=>{a.enqueue({event:`progress`,data:{progress:e}})}});n.initializedContexts.add(r),await new Promise(e=>setTimeout(e,1e3));let{download:s,...c}=o||{};a.enqueue({event:`result`,data:{result:c}}),a.close()}catch(e){a.error(e)}}})}}function oa(e,t){return async function({backend:n,session:r},i,a){return console.log(`[Server] ${t}:`,{id:i,force:a}),r.initializedContexts.has(i)?(r.initializedContexts.delete(i),e(n).releaseContext(i,{force:a})):(console.log(`[Server] ${t} skipped - not initialized by this session:`,{id:i}),{released:!1,skipped:!0})}}function sa(e,t){return{initContext:aa(e),completion({backend:n},r,i){return console.log(`[Server] ${t}Completion:`,{id:r,property:i}),e(n).completion(r,i)},async tokenize({backend:n},r,i){return console.log(`[Server] ${t}Tokenize:`,{id:r,property:i}),e(n).tokenize(r,i)},async detokenize({backend:n},r,i){return console.log(`[Server] ${t}Detokenize:`,{id:r,property:i}),e(n).detokenize(r,i)},async applyChatTemplate({backend:n},r,i){return console.log(`[Server] ${t}Apply Chat Template:`,{id:r,property:i}),e(n).applyChatTemplate(r,i)},releaseContext:oa(e,`${t}Release Context`)}}var ca=sa(e=>e.ggmlLlm,``);const la={initContext:M.tuple([M.string(),M.any().optional()]),transcribe:M.tuple([M.string(),M.string(),M.any().optional()]),transcribeData:M.tuple([M.string(),M.union([M.instanceof(Buffer),M.instanceof(Uint8Array)]),M.any().optional()]),releaseContext:M.tuple([M.string()])},ua=e=>e.ggmlStt,da={common:ra,ggmlLlm:ca,ggmlStt:{initContext:aa(ua),async transcribe({backend:e,config:{server:t},peerId:n},r,i,a){console.log(`[Server] Transcribe:`,{id:r,audioPath:i,options:a});let{filePath:o,safe:s}=xi(t.temp_file_dir,n,i);if(!s)throw Error(`Invalid audioPath`);return e.ggmlStt.transcribe(r,{audioPath:o,options:a})},async transcribeData({backend:e},t,n,r){return console.log(`[Server] Transcribe Data:`,{id:t,audioDataLength:n?.length||0,options:r}),e.ggmlStt.transcribeData(t,{audioData:n,options:r})},releaseContext:oa(ua,`Release STT Context`)},mlxLlm:sa(e=>e.mlxLlm,`MLX `)},fa={common:na,ggmlLlm:ia,ggmlStt:la,mlxLlm:ia};var pa=da;const ma=e=>{try{return JSON.parse(e,(e,t)=>t&&(t?.type===`Buffer`&&t?.data||t?.type===`Uint8Array`&&t?.data?L.from(t.data,`base64`):t?.type===`Error`&&t?.name&&t?.message?Error(t.name,t.message):t))}catch{return e}},ha=e=>{try{return JSON.stringify(e,(e,t)=>t instanceof Error?{type:`Error`,name:t.name,message:t.message}:t instanceof L?{type:`Buffer`,data:t.toString(`base64`)}:t instanceof Uint8Array?{type:`Uint8Array`,data:L.from(t).toString(`base64`)}:t)}catch{return e}},ga={score:0,hasGpu:!1,usableBytes:0},_a=e=>e?{score:Number(e.score)||0,hasGpu:!!e.hasGpu,usableBytes:Number(e.gpuUsableBytes||e.cpuUsableBytes||0)}:ga,va=async e=>{let t=[];for(let n of e){let e=ga;try{e=_a((await J(n.type,null,{}))?.buttress?.selected)}catch(e){console.warn(`[Caps] Failed to detect capabilities for "${n.type}":`,e instanceof Error?e.message:e)}t.push({...n,...e})}return t},ya=()=>{let e=x.networkInterfaces();return Object.values(e).flat().find(e=>e?.family===`IPv4`&&!e?.internal)?.address||null},ba=e=>{let t=e.split(`.`).map(Number);return t.length!==4||t.some(e=>Number.isNaN(e))?0:(t[0]<<24|t[1]<<16|t[2]<<8|t[3])>>>0},xa=e=>[e>>>24&255,e>>>16&255,e>>>8&255,e&255].join(`.`),Sa=()=>{let e=[],t=new Set;for(let n of Object.values(x.networkInterfaces()))for(let r of n??[]){if(r.family!==`IPv4`||r.internal||!r.address||!r.netmask)continue;let n=ba(r.address),i=ba(r.netmask);if(!n||!i||i===4294967295)continue;let a=xa((n&i|~i>>>0)>>>0);if(a===r.address)continue;let o=`${r.address}->${a}`;t.has(o)||(t.add(o),e.push({address:r.address,broadcast:a}))}return e},Ca=e=>{if(!e)return!1;let t=e;return t.code===`ENOTSUP`||/Failed to bind socket/i.test(t.message??``)};var wa=class e{name=`udp`;receiver=null;senders=[];announcementTimer=null;config;getServerInfo;port;signer;constructor(e,t,n){this.config=e,this.getServerInfo=t,this.port=e.port??8089,this.signer=n}async start(){this.receiver=await this.bindReceiver(!0).catch(e=>{if(!Ca(e))throw e;return console.warn(`[Autodiscover UDP] SO_REUSEPORT not supported by this runtime; falling back to REUSEADDR only (multiple buttress instances on one host will not coexist on the discovery port).`),this.bindReceiver(!1)}),this.receiver.on(`message`,(e,t)=>{this.handleMessage(e,t)}),this.receiver.on(`error`,e=>{console.error(`[Autodiscover UDP] Receiver error:`,e.message)}),this.receiver.setBroadcast(!0),this.senders=await this.createSenders();let e=this.senders.map(e=>`${e.address}->${e.broadcast}`).join(`, `)||`<none>`;if(console.log(`[Autodiscover UDP] Listening on port ${this.port}; announce interfaces: ${e}`),this.config.announcements.enabled){let e=this.config.announcements.interval??5e3;this.announcementTimer=setInterval(()=>{this.sendAnnouncement()},e),this.sendAnnouncement()}}async stop(){this.announcementTimer&&=(clearInterval(this.announcementTimer),null),await Promise.all(this.senders.map(({socket:e})=>new Promise(t=>{e.close(()=>t())}))),this.senders=[],this.receiver&&=(await new Promise(e=>{this.receiver.close(()=>e())}),null)}async bindReceiver(e){let t=R.createSocket(e?{type:`udp4`,reuseAddr:!0,reusePort:!0}:{type:`udp4`,reuseAddr:!0});return new Promise((e,n)=>{let r=e=>{t.close(),n(e)};t.once(`error`,r),t.bind(this.port,()=>{t.off(`error`,r),e(t)})})}async createSenders(){let e=Sa();return(await Promise.all(e.map(async e=>{try{let t=R.createSocket({type:`udp4`});return await new Promise((n,r)=>{let i=e=>{t.close(),r(e)};t.once(`error`,i),t.bind({port:0,address:e.address},()=>{t.off(`error`,i),t.setBroadcast(!0),n()})}),t.on(`error`,t=>{console.error(`[Autodiscover UDP] Sender ${e.address} error:`,t.message)}),{...e,socket:t}}catch(t){return console.warn(`[Autodiscover UDP] Failed to bind sender on ${e.address}:`,t.message),null}}))).filter(e=>e!==null)}handleMessage(e,t){try{let n=JSON.parse(e.toString());if(n.t===`QUERY`&&this.config.requests.enabled){let e=n.d,r=this.config.requests.responseDelay??0,i=r>0?Math.random()*r:0;setTimeout(()=>{this.sendResponse(e.id,t)},i)}}catch{}}static canonicalBytes(e,t,n){return Buffer.from(JSON.stringify({t:e,d:t,ts:n}),`utf8`)}signEnvelope(t,n){if(!this.signer)return null;let r=Math.floor(Date.now()/1e3),i=o.sign(null,e.canonicalBytes(t,n,r),this.signer.privateKey).toString(`base64`);return{t,v:`2.0`,d:n,ts:r,kid:this.signer.kid,sig:i}}sendAnnouncement(){if(this.senders.length===0)return;let e=this.getServerInfo(),t=this.signEnvelope(`ANNOUNCE`,{info:e});if(!t){console.warn("[Autodiscover UDP] no per-server keypair; skipping announcement. Run `bricks buttress bind` to register a key.");return}let n=Buffer.from(JSON.stringify(t));for(let{broadcast:e,socket:t,address:r}of this.senders)t.send(n,0,n.length,this.port,e,t=>{t&&console.error(`[Autodiscover UDP] Announcement ${r}->${e} error:`,t.message)})}sendResponse(e,t){if(!this.receiver)return;let n=this.getServerInfo(),r=this.signEnvelope(`RESPONSE`,{request_id:e,info:n});if(!r)return;let i=Buffer.from(JSON.stringify(r));this.receiver.send(i,0,i.length,t.port,t.address,e=>{e&&console.error(`[Autodiscover UDP] Response error:`,e.message)})}},Ta=class{transports=[];started=!1;constructor(e,t,n){this.config=e,this.getServerInfo=t,this.signer=n,(e.udp?.announcements?.enabled||e.udp?.requests?.enabled)&&this.transports.push(new wa(e.udp,t,n))}async start(){this.started||=((await Promise.allSettled(this.transports.map(e=>e.start()))).forEach((e,t)=>{e.status===`rejected`&&console.error(`[Autodiscover] Failed to start ${this.transports[t].name}:`,e.reason)}),!0)}async stop(){this.started&&=(await Promise.allSettled(this.transports.map(e=>e.stop())),!1)}};const Ea=()=>process.env.BRICKS_BUTTRESS_STATE_DIR||l.join(x.homedir(),`.bricks-cli`,`buttress`),Da=()=>l.join(Ea(),`state.json`),Oa=e=>{if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.id==`string`&&typeof t.serverId==`string`&&typeof t.issuerPublicKey==`string`&&typeof t.kid==`string`},ka=e=>{if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.publicKeySpki==`string`&&typeof t.privateKeyPkcs8==`string`&&typeof t.kid==`string`},Aa=()=>{let e=Da();try{let t=k.readFileSync(e,`utf8`),n=JSON.parse(t);return{workspace:Oa(n?.workspace)?n.workspace:null,serverKeyPair:ka(n?.serverKeyPair)?n.serverKeyPair:null}}catch(e){return e.code!==`ENOENT`&&console.warn(`[Buttress] Failed to read workspace state:`,e.message),{workspace:null,serverKeyPair:null}}},$=oi(),ja=e=>{if(!e)return{repoId:null,filename:null};let[t,n]=e.split(`:`);return{repoId:t,filename:n||null}};async function Ma({modelIds:e=[],defaultConfig:t=null}={}){let n=[];console.log(`${$.name} v${$.version}`),console.log(`Generating model capabilities comparison...
37
37
  `),n.push(`${$.name} v${$.version}`),n.push(`## Model Capabilities Comparison
38
38
  `),(!e||e.length===0)&&(console.error(`Error: No model IDs provided`),process.exit(1));try{let r=(e={},t={})=>{let n=Array.isArray(e)?[...e]:{...e};return Object.entries(t||{}).forEach(([e,t])=>{t&&typeof t==`object`&&!Array.isArray(t)?n[e]=r(n[e]||{},t):n[e]=t}),n},{server:i,generators:a=[],...o}=t||{},s=e=>r(structuredClone(o),e||{}),c=e=>{if(Array.isArray(a)&&a.length>0){let t=a.filter(e=>e?.type===`ggml-llm`);if(t.length>0&&e){let n=t.find(t=>t.model?.repo_id===e);if(n)return s(n)}}return Object.keys(o).length>0?s({}):null},u=[];for(let t=0;t<e.length;t+=1){let n=e[t];console.log(`[${t+1}/${e.length}] Analyzing ${n}...`);let r=c(n);r={...r||{},model:{...o.runtime,...r?.model||{},repo_id:n}};let i=await J(`ggml-llm`,null,{config:r,includeBreakdown:!0});u.push({modelId:n,capabilities:i,modelInfo:i.buttress?.selected||null,modelConfig:i.modelConfig||null})}let d=e=>e?(e/1024/1024/1024).toFixed(2):`N/A`,f=e=>e?`✅`:`🚫`;n.push(`| Model ID | Size (GB) | Context Size | KV Cache Size (GB) | Recurrent Mem (GB) | Total Required Memory (GB) | Fits GPU (Full) | Fits CPU (Full) |`),n.push(`|----------|-----------|--------------|--------------------|--------------------|----------------------------|-----------------|-----------------|`),u.forEach(({modelId:e,modelInfo:t,modelConfig:r})=>{let i=d(t?.modelBytes),a=r?.nCtx||t?.kvInfo?.nCtxTrain||`N/A`,o=qe(t),s=Number(a),c=t?.kvCacheBytes||(o&&Number.isFinite(s)&&s>0?o(s):o&&o(t?.kvInfo?.nCtxTrain||0))||null,l=d(c),u=t?.recurrentMemoryBytes||0,p=u>0?d(u):`-`,m=d(t?.modelBytes&&(c!=null||u>0)?t.modelBytes+(c||0)+u:t?.fit?.totalRequiredBytes),h=f(t?.fit?.fitsInGpu),g=f(t?.fit?.fitsInCpu);n.push(`| ${e} | ${i} | ${a} | ${l} | ${p} | ${m} | ${h} | ${g} |`);let _=t?.memoryLimitedCtx!=null||t?.limitedFit!=null,v=!t?.fit?.fitsInGpu||!t?.fit?.fitsInCpu;if(_&&v){let e=t?.memoryLimitedCtx||a,r=Number(e),s=t?.limitedKvCacheBytes||o&&Number.isFinite(r)&&r>0&&o(r)||null,c=d(s),h=d(t?.modelBytes&&(s!=null||u>0)?t.modelBytes+(s||0)+u:t?.limitedFit?.totalRequiredBytes),g=f(t?.limitedFit?.fitsInGpu),_=f(t?.limitedFit?.fitsInCpu);(e!==a||c!==l||h!==m)&&n.push(`| ↳ Limited | ${i} | ${e} | ${c} | ${p} | ${h} | ${g} | ${_} |`)}}),n.push(`
39
39
  ---`),n.push(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fugood/buttress-server",
3
- "version": "2.25.0-beta.21",
3
+ "version": "2.25.0-beta.23",
4
4
  "main": "lib/index.mjs",
5
5
  "types": "lib/index.d.mts",
6
6
  "type": "module",
@@ -45,5 +45,5 @@
45
45
  "tsdown": "^0.20.1",
46
46
  "typescript": "^5.9.3"
47
47
  },
48
- "gitHead": "67820284dd8b6d9084a6731c8be0d6c9f0fc3a86"
48
+ "gitHead": "8b167250b57c5e9973e60de8266b880d15adcce6"
49
49
  }