@fugood/buttress-server 2.26.0-beta.28 → 2.26.0-beta.29

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 CHANGED
@@ -91,7 +91,7 @@ When you save a new `[server] port` or `id` while the server runs, the window ke
91
91
 
92
92
  `--tab chat|status|settings` opens the window on that tab instead of the one detection picks.
93
93
 
94
- **Platform support.** The window uses gpuix (a React renderer for GPUI) and runs under Bun on `darwin-arm64`, `linux-x64` and `win32-x64`, the platforms with gpuix prebuilt modules. Under Node.js or on another platform the command stops with a message; open `http://<host>:<port>/status` in a browser instead. The standalone binary includes the window (its installer adds gpuix's native module to the sidecar on those platforms); the npm package does not include `@fugood/buttress-ui`, and the command says so. Light or dark follows the macOS appearance; other platforms use light.
94
+ **Platform support.** The window uses gpuix (a React renderer for GPUI) and runs under Bun on `darwin-arm64`, `linux-x64`, `win32-x64` and `win32-arm64`, the platforms with gpuix prebuilt modules. Under Node.js or on another platform the command stops with a message; open `http://<host>:<port>/status` in a browser instead. The standalone binary includes the window (its installer adds gpuix's native module to the sidecar on those platforms); the npm package does not include `@fugood/buttress-ui`, and the command says so. Light or dark follows the macOS appearance; other platforms use light.
95
95
 
96
96
  ### Chat tab
97
97
 
@@ -89,7 +89,7 @@ type CallToolResult<TStructured = { [key: string]: unknown }> = {
89
89
 
90
90
  `)),o.join(`
91
91
 
92
- `)}const E=new Map;function te(e){let r=e??t(import.meta.url).resolve(`quickjs-wasi/quickjs.wasm`),i=E.get(r);if(!i){let{WebAssembly:e}=globalThis;i=n(r).then(t=>e.compile(t)).catch(e=>{throw E.delete(r),e}),E.set(r,i)}return i}const ne=/^[A-Za-z_$][A-Za-z0-9_$]*$/,D=new Set([`tools`,`ALL_TOOLS`,`console`,`text`,`image`,`exit`,`globalThis`,`store`,`load`]);function O(e){return e instanceof Error?e.message:String(e)}function k(e){let t=Object.create(null);for(let[n,r]of Object.entries(e??{})){let e=JSON.stringify(r);e!==void 0&&(t[n]=e)}return t}var A=class extends Error{};function j(e,t){try{return JSON.parse(e)}catch{throw new A(`${t} is not valid JSON`)}}function M(e){let t=j(e,`store writes`);if(!Array.isArray(t))throw new A(`store writes are not an array`);let n={set:Object.create(null),delete:[]};for(let e of t){if(!Array.isArray(e)||typeof e[0]!=`string`||(e.length===2?typeof e[1]!=`string`:e.length!==1))throw new A(`store writes contain a malformed entry`);let[t,r]=e;r===void 0?n.delete.push(t):n.set[t]=j(r,`store value for ${JSON.stringify(t)}`)}return n}function re(e){let t=j(e,`script error`);if(typeof t!=`object`||!t)throw new A(`script error is not an object`);let{name:n,message:r,stack:i}=t;if(typeof r!=`string`||n!==void 0&&typeof n!=`string`||i!==void 0&&typeof i!=`string`)throw new A(`script error is malformed`);return{kind:`script`,name:n,message:r,stack:i}}function ie(){return new URL(import.meta.url.endsWith(`.ts`)?`./worker.ts`:`./worker.js`,import.meta.url)}var ae=class{promise;resolveResult;worker;interrupt=new SharedArrayBuffer(4);tools;globals;signal;timer;output=[];calls=[];pending=new Map;finished=!1;constructor(e){this.promise=new Promise(e=>{this.resolveResult=e}),this.tools=e.tools,this.globals=e.globals,this.signal=e.signal,Number.isFinite(e.timeoutMs)&&(this.timer=setTimeout(()=>{this.finish({kind:`timeout`,message:`Execution timed out after ${e.timeoutMs} ms`})},e.timeoutMs)),e.signal&&(e.signal.aborted?this.onAbort():e.signal.addEventListener(`abort`,this.onAbort,{once:!0})),e.wasm.then(t=>this.start(e,t),e=>{this.finish({kind:`sandbox`,message:`Failed to load QuickJS: ${O(e)}`})})}abort(e){return this.finish({kind:`aborted`,message:e}),this.promise}start(e,t){if(this.finished)return;let n={code:e.code,tools:[...e.tools.values()].map(e=>({name:e.name,jsName:a(e.name),description:e.description??``})),globals:[...e.globals.values()].map(e=>({name:e.name,spread:e.spread===!0})),wasm:t,memoryLimitBytes:e.memoryLimitBytes,store:e.store,interrupt:this.interrupt},r;try{r=new i(e.workerUrl,{workerData:n})}catch(e){this.finish({kind:`sandbox`,message:`Failed to start worker: ${O(e)}`});return}this.worker=r,r.on(`message`,e=>{try{this.handleMessage(e)}catch(e){this.finish({kind:`sandbox`,message:e instanceof A?`Sandbox bridge broken: ${e.message}. The script may have modified built-ins such as a prototype's toJSON.`:`Sandbox host failed: ${O(e)}`})}}),r.on(`error`,e=>{this.finish({kind:`sandbox`,name:e instanceof Error?e.name:void 0,message:O(e)})}),r.on(`exit`,e=>{this.finish({kind:`sandbox`,message:`Worker exited with code ${e} before the script settled`})})}onAbort=()=>{let e=this.signal?.reason;this.finish({kind:`aborted`,message:e instanceof Error?e.message:`Execution aborted`})};post(e){this.worker?.postMessage(e)}handleMessage(t){if(!this.finished){if(!e(t))throw new A(`unknown message from the worker`);switch(t.type){case`output`:this.output.push(t.item);break;case`call`:if(this.pending.has(t.id))throw new A(`duplicate call id ${t.id}`);this.handleCall(t);break;case`done`:this.handleDone(t);break;case`crash`:this.finish({kind:`sandbox`,message:t.message});break}}}handleDone(e){if(!e.ok){this.finish(re(e.error));return}let t=e.value===void 0?void 0:j(e.value,`return value`);this.finish(void 0,t,M(e.writes))}async handleCall(e){let{id:t,name:n}=e,r=e.target===`tool`,i=r?{name:n,status:`cancelled`,durationMs:0}:void 0;i&&this.calls.push(i);let a={record:i,startedAt:performance.now(),controller:new AbortController};this.pending.set(t,a);let o,s;try{let i=(r?this.tools:this.globals).get(n);if(!i)throw Error(`Unknown ${r?`tool`:`global`} "${n}"`);let c=e.args===void 0?void 0:JSON.parse(e.args),l=await i.execute(c,{signal:a.controller.signal});s={type:`result`,id:t,ok:!0,payload:l===void 0?void 0:JSON.stringify(l)},o=`ok`}catch(e){s={type:`result`,id:t,ok:!1,payload:O(e)},o=`error`}this.pending.delete(t)&&(i&&(i.status=o,i.durationMs=performance.now()-a.startedAt),this.post(s))}finish(e,t,n){if(this.finished)return;this.finished=!0,clearTimeout(this.timer),this.signal?.removeEventListener(`abort`,this.onAbort);let r=performance.now();for(let e of this.pending.values())e.record&&(e.record.durationMs=r-e.startedAt),e.controller.abort();this.pending.clear();let i=e?{ok:!1,error:e,output:this.output,calls:this.calls}:{ok:!0,value:t,output:this.output,calls:this.calls,storeWrites:n??{set:{},delete:[]}};if(!this.worker){this.resolveResult(i);return}Atomics.store(new Int32Array(this.interrupt),0,1),this.worker.terminate().catch(()=>void 0).then(()=>this.resolveResult(i))}},oe=class{toolsByName=new Map;globalsByName=new Map;timeoutMs;memoryLimitBytes;wasm;workerUrl;running=new Set;closed=!1;constructor(e={}){this.timeoutMs=e.timeoutMs??3e5,this.memoryLimitBytes=e.memoryLimitBytes,this.wasm=e.wasm,this.workerUrl=e.workerUrl??ie();for(let t of e.tools??[])this.registerTool(t);let t=new Set;for(let n of e.globals??[]){let e=n.name.split(`.`);if(e.length>2||!e.every(e=>ne.test(e))||D.has(e[0]))throw Error(`Invalid global name "${n.name}"`);if(this.globalsByName.has(n.name))throw Error(`Global "${n.name}" is already registered`);e.length===2&&t.add(e[0]),this.globalsByName.set(n.name,n)}for(let e of t)if(this.globalsByName.has(e))throw Error(`Global "${e}" conflicts with the namespace "${e}"`)}registerTool(e){if(this.toolsByName.has(e.name))throw Error(`Tool "${e.name}" is already registered`);this.toolsByName.set(e.name,e)}unregisterTool(e){return this.toolsByName.delete(e)}get tools(){return[...this.toolsByName.values()]}get globals(){return[...this.globalsByName.values()]}execute(e,t={}){if(this.closed)return Promise.reject(Error(`Sandbox is closed`));let n=new ae({code:e,tools:new Map(this.toolsByName),globals:this.globalsByName,timeoutMs:t.timeoutMs??this.timeoutMs,signal:t.signal,memoryLimitBytes:this.memoryLimitBytes,store:k(t.store),wasm:this.wasm===void 0?te():Promise.resolve(this.wasm),workerUrl:this.workerUrl});return this.running.add(n),n.promise.finally(()=>this.running.delete(n))}async close(){this.closed=!0,await Promise.all([...this.running].map(e=>e.abort(`Sandbox closed`)))}};const se=[`max_output_tokens`,`timeout_ms`],N="`max_output_tokens` and `timeout_ms`",ce=2147483647;String.raw`
92
+ `)}const E=new Map;function te(e){let r=e??t(import.meta.url).resolve(`quickjs-wasi/quickjs.wasm`),i=E.get(r);if(!i){let{WebAssembly:e}=globalThis;i=n(r).then(t=>e.compile(t)).catch(e=>{throw E.delete(r),e}),E.set(r,i)}return i}const D=/^[A-Za-z_$][A-Za-z0-9_$]*$/,ne=new Set([`tools`,`ALL_TOOLS`,`console`,`text`,`image`,`exit`,`globalThis`,`store`,`load`]);function O(e){return e instanceof Error?e.message:String(e)}function k(e){let t=Object.create(null);for(let[n,r]of Object.entries(e??{})){let e=JSON.stringify(r);e!==void 0&&(t[n]=e)}return t}var A=class extends Error{};function j(e,t){try{return JSON.parse(e)}catch{throw new A(`${t} is not valid JSON`)}}function re(e){let t=j(e,`store writes`);if(!Array.isArray(t))throw new A(`store writes are not an array`);let n={set:Object.create(null),delete:[]};for(let e of t){if(!Array.isArray(e)||typeof e[0]!=`string`||(e.length===2?typeof e[1]!=`string`:e.length!==1))throw new A(`store writes contain a malformed entry`);let[t,r]=e;r===void 0?n.delete.push(t):n.set[t]=j(r,`store value for ${JSON.stringify(t)}`)}return n}function M(e){let t=j(e,`script error`);if(typeof t!=`object`||!t)throw new A(`script error is not an object`);let{name:n,message:r,stack:i}=t;if(typeof r!=`string`||n!==void 0&&typeof n!=`string`||i!==void 0&&typeof i!=`string`)throw new A(`script error is malformed`);return{kind:`script`,name:n,message:r,stack:i}}function ie(){return new URL(import.meta.url.endsWith(`.ts`)?`./worker.ts`:`./worker.js`,import.meta.url)}var ae=class{promise;resolveResult;worker;interrupt=new SharedArrayBuffer(4);tools;globals;signal;timer;output=[];calls=[];pending=new Map;finished=!1;constructor(e){this.promise=new Promise(e=>{this.resolveResult=e}),this.tools=e.tools,this.globals=e.globals,this.signal=e.signal,Number.isFinite(e.timeoutMs)&&(this.timer=setTimeout(()=>{this.finish({kind:`timeout`,message:`Execution timed out after ${e.timeoutMs} ms`})},e.timeoutMs)),e.signal&&(e.signal.aborted?this.onAbort():e.signal.addEventListener(`abort`,this.onAbort,{once:!0})),e.wasm.then(t=>this.start(e,t),e=>{this.finish({kind:`sandbox`,message:`Failed to load QuickJS: ${O(e)}`})})}abort(e){return this.finish({kind:`aborted`,message:e}),this.promise}start(e,t){if(this.finished)return;let n={code:e.code,tools:[...e.tools.values()].map(e=>({name:e.name,jsName:a(e.name),description:e.description??``})),globals:[...e.globals.values()].map(e=>({name:e.name,spread:e.spread===!0})),wasm:t,memoryLimitBytes:e.memoryLimitBytes,store:e.store,interrupt:this.interrupt},r;try{r=new i(e.workerUrl,{workerData:n})}catch(e){this.finish({kind:`sandbox`,message:`Failed to start worker: ${O(e)}`});return}this.worker=r,r.on(`message`,e=>{try{this.handleMessage(e)}catch(e){this.finish({kind:`sandbox`,message:e instanceof A?`Sandbox bridge broken: ${e.message}. The script may have modified built-ins such as a prototype's toJSON.`:`Sandbox host failed: ${O(e)}`})}}),r.on(`error`,e=>{this.finish({kind:`sandbox`,name:e instanceof Error?e.name:void 0,message:O(e)})}),r.on(`exit`,e=>{this.finish({kind:`sandbox`,message:`Worker exited with code ${e} before the script settled`})})}onAbort=()=>{let e=this.signal?.reason;this.finish({kind:`aborted`,message:e instanceof Error?e.message:`Execution aborted`})};post(e){this.worker?.postMessage(e)}handleMessage(t){if(!this.finished){if(!e(t))throw new A(`unknown message from the worker`);switch(t.type){case`output`:this.output.push(t.item);break;case`call`:if(this.pending.has(t.id))throw new A(`duplicate call id ${t.id}`);this.handleCall(t);break;case`done`:this.handleDone(t);break;case`crash`:this.finish({kind:`sandbox`,message:t.message});break}}}handleDone(e){if(!e.ok){this.finish(M(e.error));return}let t=e.value===void 0?void 0:j(e.value,`return value`);this.finish(void 0,t,re(e.writes))}async handleCall(e){let{id:t,name:n}=e,r=e.target===`tool`,i=r?{name:n,status:`cancelled`,durationMs:0}:void 0;i&&this.calls.push(i);let a={record:i,startedAt:performance.now(),controller:new AbortController};this.pending.set(t,a);let o,s;try{let i=(r?this.tools:this.globals).get(n);if(!i)throw Error(`Unknown ${r?`tool`:`global`} "${n}"`);let c=e.args===void 0?void 0:JSON.parse(e.args),l=await i.execute(c,{signal:a.controller.signal});s={type:`result`,id:t,ok:!0,payload:l===void 0?void 0:JSON.stringify(l)},o=`ok`}catch(e){s={type:`result`,id:t,ok:!1,payload:O(e)},o=`error`}this.pending.delete(t)&&(i&&(i.status=o,i.durationMs=performance.now()-a.startedAt),this.post(s))}finish(e,t,n){if(this.finished)return;this.finished=!0,clearTimeout(this.timer),this.signal?.removeEventListener(`abort`,this.onAbort);let r=performance.now();for(let e of this.pending.values())e.record&&(e.record.durationMs=r-e.startedAt),e.controller.abort();this.pending.clear();let i=e?{ok:!1,error:e,output:this.output,calls:this.calls}:{ok:!0,value:t,output:this.output,calls:this.calls,storeWrites:n??{set:{},delete:[]}};if(!this.worker){this.resolveResult(i);return}Atomics.store(new Int32Array(this.interrupt),0,1),this.worker.terminate().catch(()=>void 0).then(()=>this.resolveResult(i))}},oe=class{toolsByName=new Map;globalsByName=new Map;timeoutMs;memoryLimitBytes;wasm;workerUrl;running=new Set;closed=!1;constructor(e={}){this.timeoutMs=e.timeoutMs??3e5,this.memoryLimitBytes=e.memoryLimitBytes,this.wasm=e.wasm,this.workerUrl=e.workerUrl??ie();for(let t of e.tools??[])this.registerTool(t);let t=new Set;for(let n of e.globals??[]){let e=n.name.split(`.`);if(e.length>2||!e.every(e=>D.test(e))||ne.has(e[0]))throw Error(`Invalid global name "${n.name}"`);if(this.globalsByName.has(n.name))throw Error(`Global "${n.name}" is already registered`);e.length===2&&t.add(e[0]),this.globalsByName.set(n.name,n)}for(let e of t)if(this.globalsByName.has(e))throw Error(`Global "${e}" conflicts with the namespace "${e}"`)}registerTool(e){if(this.toolsByName.has(e.name))throw Error(`Tool "${e.name}" is already registered`);this.toolsByName.set(e.name,e)}unregisterTool(e){return this.toolsByName.delete(e)}get tools(){return[...this.toolsByName.values()]}get globals(){return[...this.globalsByName.values()]}execute(e,t={}){if(this.closed)return Promise.reject(Error(`Sandbox is closed`));let n=new ae({code:e,tools:new Map(this.toolsByName),globals:this.globalsByName,timeoutMs:t.timeoutMs??this.timeoutMs,signal:t.signal,memoryLimitBytes:this.memoryLimitBytes,store:k(t.store),wasm:this.wasm===void 0?te():Promise.resolve(this.wasm),workerUrl:this.workerUrl});return this.running.add(n),n.promise.finally(()=>this.running.delete(n))}async close(){this.closed=!0,await Promise.all([...this.running].map(e=>e.abort(`Sandbox closed`)))}};const se=[`max_output_tokens`,`timeout_ms`],N="`max_output_tokens` and `timeout_ms`",ce=2147483647;String.raw`
93
93
  start: options_source | plain_source
94
94
  options_source: OPTIONS_LINE NEWLINE SOURCE
95
95
  plain_source: SOURCE
@@ -102,7 +102,7 @@ SOURCE: /[\s\S]+/
102
102
  `),Ne=e=>typeof e==`string`?e:JSON.stringify(e)??String(e);function Pe(e,t){if(!e)return structuredClone(t);for(let n of[`input`,`output`,`cacheRead`,`cacheWrite`,`totalTokens`])e[n]=(e[n]??0)+(t[n]??0);if(t.cost){e.cost??={};for(let[n,r]of Object.entries(t.cost))e.cost[n]=(e.cost[n]??0)+(r??0)}return e}function Fe(e){return e.length===0?`No tool calls were made.`:`Tool calls made before the failure (they are not undone): ${e.map(e=>`${e.name} (${e.status})`).join(`, `)}`}function Ie(e,t){return`${e.kind===`script`?e.stack??`${e.name??`Error`}: ${e.message}`:e.kind===`timeout`?`Script timed out: ${e.message}`:e.kind===`aborted`?`Script aborted: ${e.message}`:`Script sandbox failed: ${e.message}`}\n\n${Fe(t)}`}function Le(e,t){let n=Math.floor(t/2),r=t-n,i=e.length-n-r;return`${e.slice(0,n)}…${Math.ceil(i/4)} tokens truncated…${r>0?e.slice(-r):``}`}function Re(e,t){let n=Array.from({length:e.length}),r=e.map((e,t)=>({length:e,index:t})).sort((e,t)=>e.length-t.length),i=t;return r.forEach(({length:e,index:t},a)=>{n[t]=Math.min(e,Math.floor(i/(r.length-a))),i-=n[t]}),n}async function ze(e,t,n){let r=e.filter(e=>e.type===`text`).map(e=>e.text),i=r.join(`
103
103
  `),a=t*4;if(r.length===0||i.length<=a)return{items:e};let o=Re(r.map(e=>e.length),a),s=r.every((e,t)=>e.length<=o[t]||o[t]>=400)?r.map((e,t)=>e.length>o[t]?Le(e,o[t]):e).join(`
104
104
  `):Le(i,a),c=`Warning: truncated output (original token count: ${Math.ceil(i.length/4)})\nTotal output lines: ${i.split(`
105
- `).length}\n\n${s}`,l;if(n)try{l=await n(i),l&&(c+=`\n\n[Full output: ${l} (read with offset/limit)]`)}catch(e){c+=`\n\n[Could not save the full output: ${e?.message||e}]`}return{items:[{type:`text`,text:c},...e.filter(e=>e.type===`image`)],...l?{fullOutputPath:l}:{}}}function Be(e,t){let{result:n}=t;if(e.outputSchema&&n.structuredContent!==void 0)return n.structuredContent;let r=Me(n);if(t.isError)throw Error(r||`Tool "${e.name}" failed`);return r}function Ve(e,t){let n=a(e),r=a(t),i=e=>e.includes(`__`)?e.slice(e.lastIndexOf(`__`)+2):void 0;return e===t||n===r||i(e)===t||i(n)===r}function He(e,t,n){let r=he(e,{getNamespace:n}),i=e=>({name:a(e.name),description:t.get(e.name)??``}),o=t=>e.map(n).find(e=>e&&Ve(e.name,t));return[{name:`searchTools`,spread:!0,execute:([e,t])=>{if(typeof e!=`string`)throw Error(`searchTools() expects a query string`);let n=t?.limit??8;if(typeof n!=`number`||!Number.isInteger(n)||n<=0)throw Error(`searchTools() limit must be a positive integer`);let a=t?.namespace;if(a!=null&&typeof a!=`string`)throw Error(`searchTools() namespace must be a string`);let s=a?o(a):void 0;return a&&!s?[]:_e(r,e,n,{namespace:s?.name,maxLimit:Math.max(n,8)}).map(i)}},{name:`describeTool`,spread:!0,execute:([n])=>{if(typeof n!=`string`)throw Error(`describeTool() expects a tool name`);let r=e.find(e=>e.name===n||a(e.name)===n);return r?t.get(r.name):void 0}},{name:`describeNamespace`,spread:!0,execute:([t])=>{if(typeof t!=`string`)throw Error(`describeNamespace() expects a namespace name`);let r=o(t);if(r)return{name:r.name,...r.description?{description:r.description}:{},...r.instructions?{instructions:r.instructions}:{},tools:e.filter(e=>n(e)?.name===r.name).map(e=>a(e.name))}}}]}async function Ue({toolCallId:e,code:t,signal:n,onUpdate:r,tools:i,executeTool:a,store:o={},models:s,getNamespace:l=()=>void 0,sandbox:u={},spillOutput:d}){let f=performance.now(),p;try{p=de(t)}catch(e){if(!(e instanceof P))throw e;return{content:[{type:`text`,text:`Script failed\nScript error:\n${e.message}`}],details:{calls:[]},isError:!0}}let{code:m,options:h}=p,g=[],_=0,v,y=0,b=()=>g.slice(-200).map(e=>({...e})),x=()=>r?.({content:[],details:{calls:b()}}),S=e=>(g.push(e),e),C=new Map(i.map(e=>[e.name,c(ee(e))])),w=i.map(t=>({name:t.name,description:C.get(t.name),execute:async(n={},{signal:r})=>{let i=S({id:`${e}/${++_}`,name:t.name,args:je(n),status:`running`});x();let o=performance.now(),s=await a(t,n,{id:i.id,parentToolCallId:e,signal:r});return i.durationMs=performance.now()-o,s.isError?(i.status=r.aborted?`cancelled`:`error`,i.error=Ae(Me(s.result)||`Tool "${t.name}" failed`,500)):i.status=`ok`,x(),Be(t,s)}})),T=Math.min(h.timeoutMs??u.defaultTimeoutMs??1/0,u.maxTimeoutMs??1/0),E=new oe({tools:w,globals:[...He(i,C,l),...s?Ee(s,{toolCallId:e,track:S,publish:x,addUsage:e=>{v=Pe(v,e)},addGeneratedImages:e=>{y+=e}}):[]],timeoutMs:T,memoryLimitBytes:u.memoryLimitBytes??268435456,...u.wasmPath?{wasm:te(u.wasmPath)}:{},...u.workerUrl?{workerUrl:u.workerUrl}:{}}),ne=u.limit??(e=>e()),D;try{D=await ne(()=>E.execute(m,{signal:n,store:o}))}finally{await E.close()}for(let e of g)e.status===`running`&&(e.status=`cancelled`);let O=D.output.map(e=>e.type===`text`?{type:`text`,text:e.text}:e);D.ok?D.value!==void 0&&O.push({type:`text`,text:Ne(D.value)}):O.push({type:`text`,text:`Script error:\n${Ie(D.error,g)}`}),y>0&&!O.some(e=>e.type===`image`)&&O.push({type:`text`,text:`Note: models.generateImages() returned ${y} image${y===1?``:`s`} that the script did not show. Show each image block of result.output with image(block).`});let k=await ze(O,h.maxOutputTokens??1e4,d),A=((performance.now()-f)/1e3).toFixed(1),j=`${D.ok?`Script completed`:`Script failed`}\nWall time ${A} seconds\nOutput:\n`,M=D.ok?D.storeWrites:null,re=M&&(Object.keys(M.set).length>0||M.delete.length>0);return{content:[{type:`text`,text:j},...k.items],details:{calls:b(),...g.length>200?{omittedCalls:g.length-200}:{},...re?{storeWrites:M}:{},...k.fullOutputPath?{fullOutputPath:k.fullOutputPath}:{}},...v?{usage:v}:{},...D.ok?{}:{isError:!0}}}const H=`codemode`,U=`codemodeStore`,W=e=>typeof e==`object`&&!!e&&!Array.isArray(e);function We(e,t){if(!(!W(t)||!W(t.set)||!Array.isArray(t.delete))){for(let n of t.delete)delete e[n];Object.assign(e,t.set)}}function Ge(e){let t=Object.create(null);for(let n of Array.isArray(e)?e:[]){if(W(n?.codemodeStore)){for(let e of Object.keys(t))delete t[e];Object.assign(t,n[U])}n?.role===`toolResult`&&n.toolName===`codemode`&&We(t,n.details?.storeWrites)}return t}function Ke(e,t){let n=Ge(t);Object.keys(n).length>0&&(e[U]=n)}var qe=class extends Error{constructor(e,t){super(e),this.name=`ParseError`,this.type=t.type,this.field=t.field,this.value=t.value,this.line=t.line}};function G(e){}function Je(e){if(typeof e==`function`)throw TypeError("`callbacks` must be an object, got a function instead. Did you mean `{onEvent: fn}`?");let{onEvent:t=G,onError:n=G,onRetry:r=G,onComment:i}=e,a=``,o=!0,s,c=``,l=``;function u(e){let t=o?e.replace(/^\xEF\xBB\xBF/,``):e,[n,r]=Ye(`${a}${t}`);for(let e of n)d(e);a=r,o=!1}function d(e){if(e===``){p();return}if(e.startsWith(`:`)){i&&i(e.slice(e.startsWith(`: `)?2:1));return}let t=e.indexOf(`:`);if(t!==-1){let n=e.slice(0,t),r=e[t+1]===` `?2:1;f(n,e.slice(t+r),e);return}f(e,``,e)}function f(e,t,i){switch(e){case`event`:l=t;break;case`data`:c=`${c}${t}
105
+ `).length}\n\n${s}`,l;if(n)try{l=await n(i),l&&(c+=`\n\n[Full output: ${l} (read with offset/limit)]`)}catch(e){c+=`\n\n[Could not save the full output: ${e?.message||e}]`}return{items:[{type:`text`,text:c},...e.filter(e=>e.type===`image`)],...l?{fullOutputPath:l}:{}}}function Be(e,t){let{result:n}=t;if(e.outputSchema&&n.structuredContent!==void 0)return n.structuredContent;let r=Me(n);if(t.isError)throw Error(r||`Tool "${e.name}" failed`);return r}function Ve(e,t){let n=a(e),r=a(t),i=e=>e.includes(`__`)?e.slice(e.lastIndexOf(`__`)+2):void 0;return e===t||n===r||i(e)===t||i(n)===r}function He(e,t,n){let r=he(e,{getNamespace:n}),i=e=>({name:a(e.name),description:t.get(e.name)??``}),o=t=>e.map(n).find(e=>e&&Ve(e.name,t));return[{name:`searchTools`,spread:!0,execute:([e,t])=>{if(typeof e!=`string`)throw Error(`searchTools() expects a query string`);let n=t?.limit??8;if(typeof n!=`number`||!Number.isInteger(n)||n<=0)throw Error(`searchTools() limit must be a positive integer`);let a=t?.namespace;if(a!=null&&typeof a!=`string`)throw Error(`searchTools() namespace must be a string`);let s=a?o(a):void 0;return a&&!s?[]:_e(r,e,n,{namespace:s?.name,maxLimit:Math.max(n,8)}).map(i)}},{name:`describeTool`,spread:!0,execute:([n])=>{if(typeof n!=`string`)throw Error(`describeTool() expects a tool name`);let r=e.find(e=>e.name===n||a(e.name)===n);return r?t.get(r.name):void 0}},{name:`describeNamespace`,spread:!0,execute:([t])=>{if(typeof t!=`string`)throw Error(`describeNamespace() expects a namespace name`);let r=o(t);if(r)return{name:r.name,...r.description?{description:r.description}:{},...r.instructions?{instructions:r.instructions}:{},tools:e.filter(e=>n(e)?.name===r.name).map(e=>a(e.name))}}}]}async function Ue({toolCallId:e,code:t,signal:n,onUpdate:r,tools:i,executeTool:a,store:o={},models:s,getNamespace:l=()=>void 0,sandbox:u={},spillOutput:d}){let f=performance.now(),p;try{p=de(t)}catch(e){if(!(e instanceof P))throw e;return{content:[{type:`text`,text:`Script failed\nScript error:\n${e.message}`}],details:{calls:[]},isError:!0}}let{code:m,options:h}=p,g=[],_=[],v=0,y,b=0,x=()=>g.slice(-200).map(e=>({...e})),S=()=>r?.({content:[],details:{calls:x()}}),C=e=>(g.push(e),e),w=new Map(i.map(e=>[e.name,c(ee(e))])),T=i.map(t=>({name:t.name,description:w.get(t.name),execute:async(n={},{signal:r})=>{let i=C({id:`${e}/${++v}`,name:t.name,args:je(n),status:`running`});S();let o=performance.now(),s=await a(t,n,{id:i.id,parentToolCallId:e,signal:r});if(i.durationMs=performance.now()-o,s.isError)i.status=r.aborted?`cancelled`:`error`,i.error=Ae(Me(s.result)||`Tool "${t.name}" failed`,500);else{i.status=`ok`;let e=s.result?.details?.sources;t.name===`web_search`&&Array.isArray(e)&&_.push(...e)}return S(),Be(t,s)}})),E=Math.min(h.timeoutMs??u.defaultTimeoutMs??1/0,u.maxTimeoutMs??1/0),D=new oe({tools:T,globals:[...He(i,w,l),...s?Ee(s,{toolCallId:e,track:C,publish:S,addUsage:e=>{y=Pe(y,e)},addGeneratedImages:e=>{b+=e}}):[]],timeoutMs:E,memoryLimitBytes:u.memoryLimitBytes??268435456,...u.wasmPath?{wasm:te(u.wasmPath)}:{},...u.workerUrl?{workerUrl:u.workerUrl}:{}}),ne=u.limit??(e=>e()),O;try{O=await ne(()=>D.execute(m,{signal:n,store:o}))}finally{await D.close()}for(let e of g)e.status===`running`&&(e.status=`cancelled`);let k=O.output.map(e=>e.type===`text`?{type:`text`,text:e.text}:e);O.ok?O.value!==void 0&&k.push({type:`text`,text:Ne(O.value)}):k.push({type:`text`,text:`Script error:\n${Ie(O.error,g)}`}),b>0&&!k.some(e=>e.type===`image`)&&k.push({type:`text`,text:`Note: models.generateImages() returned ${b} image${b===1?``:`s`} that the script did not show. Show each image block of result.output with image(block).`});let A=await ze(k,h.maxOutputTokens??1e4,d),j=((performance.now()-f)/1e3).toFixed(1),re=`${O.ok?`Script completed`:`Script failed`}\nWall time ${j} seconds\nOutput:\n`,M=O.ok?O.storeWrites:null,ie=M&&(Object.keys(M.set).length>0||M.delete.length>0);return{content:[{type:`text`,text:re},...A.items],details:{calls:x(),...g.length>200?{omittedCalls:g.length-200}:{},..._.length>0?{sources:_}:{},...ie?{storeWrites:M}:{},...A.fullOutputPath?{fullOutputPath:A.fullOutputPath}:{}},...y?{usage:y}:{},...O.ok?{}:{isError:!0}}}const H=`codemode`,U=`codemodeStore`,W=e=>typeof e==`object`&&!!e&&!Array.isArray(e);function We(e,t){if(!(!W(t)||!W(t.set)||!Array.isArray(t.delete))){for(let n of t.delete)delete e[n];Object.assign(e,t.set)}}function Ge(e){let t=Object.create(null);for(let n of Array.isArray(e)?e:[]){if(W(n?.codemodeStore)){for(let e of Object.keys(t))delete t[e];Object.assign(t,n[U])}n?.role===`toolResult`&&n.toolName===`codemode`&&We(t,n.details?.storeWrites)}return t}function Ke(e,t){let n=Ge(t);Object.keys(n).length>0&&(e[U]=n)}var qe=class extends Error{constructor(e,t){super(e),this.name=`ParseError`,this.type=t.type,this.field=t.field,this.value=t.value,this.line=t.line}};function G(e){}function Je(e){if(typeof e==`function`)throw TypeError("`callbacks` must be an object, got a function instead. Did you mean `{onEvent: fn}`?");let{onEvent:t=G,onError:n=G,onRetry:r=G,onComment:i}=e,a=``,o=!0,s,c=``,l=``;function u(e){let t=o?e.replace(/^\xEF\xBB\xBF/,``):e,[n,r]=Ye(`${a}${t}`);for(let e of n)d(e);a=r,o=!1}function d(e){if(e===``){p();return}if(e.startsWith(`:`)){i&&i(e.slice(e.startsWith(`: `)?2:1));return}let t=e.indexOf(`:`);if(t!==-1){let n=e.slice(0,t),r=e[t+1]===` `?2:1;f(n,e.slice(t+r),e);return}f(e,``,e)}function f(e,t,i){switch(e){case`event`:l=t;break;case`data`:c=`${c}${t}
106
106
  `;break;case`id`:s=t.includes(`\0`)?void 0:t;break;case`retry`:/^\d+$/.test(t)?r(parseInt(t,10)):n(new qe(`Invalid \`retry\` value: "${t}"`,{type:`invalid-retry`,value:t,line:i}));break;default:n(new qe(`Unknown field "${e.length>20?`${e.slice(0,20)}\u2026`:e}"`,{type:`unknown-field`,field:e,value:t,line:i}));break}}function p(){c.length>0&&t({id:s,event:l||void 0,data:c.endsWith(`
107
107
  `)?c.slice(0,-1):c}),s=void 0,c=``,l=``}function m(e={}){a&&e.consume&&d(a),o=!0,s=void 0,c=``,l=``,a=``}return{feed:u,reset:m}}function Ye(e){let t=[],n=``,r=0;for(;r<e.length;){let i=e.indexOf(`\r`,r),a=e.indexOf(`
108
108
  `,r),o=-1;if(i!==-1&&a!==-1?o=Math.min(i,a):i===-1?a!==-1&&(o=a):o=i===e.length-1?-1:i,o===-1){n=e.slice(r);break}else{let n=e.slice(r,o);t.push(n),r=o+1,e[r-1]===`\r`&&e[r]===`
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import{a as e,i as t,n,o as r,r as i}from"./net-BvSOGnw5.mjs";import{a,c as o,n as s}from"./config-DiYweJ2m.mjs";import{n as c,r as l}from"./client-qqI-HCOj.mjs";import u from"node:fs/promises";import d from"node:path";import f from"node:fs";import{execFile as p,spawn as m}from"node:child_process";import h from"node-machine-id";import g from"@iarna/toml";import{promisify as _}from"node:util";const v=_(p),y=e=>e?.code===`ENOENT`,b=async e=>{try{return await u.stat(e)}catch(e){if(y(e))return null;throw e}},x=e=>{if(!e)return{};try{let{env:t}=g.parse(e);return t&&typeof t==`object`&&!Array.isArray(t)?t:{}}catch{return{}}},S=e=>(process.platform===`win32`?/^[\w@%+=:,./\\-]+$/:/^[\w@%+=:,./-]+$/).test(e)?e:process.platform===`win32`?`"${e}"`:`'${e.replaceAll(`'`,`'\\''`)}'`,C=e=>process.platform===`darwin`?[`open`,e]:process.platform===`win32`?[`rundll32`,`url.dll,FileProtocolHandler`,e]:[`xdg-open`,e],w=()=>{if(process.platform===`darwin`)return[{argv:[`pbcopy`]}];if(process.platform===`win32`)return[{argv:[`clip`],encode:e=>Buffer.from(`\ufeff${e}`,`utf16le`)}];let e={argv:[`wl-copy`]},t={argv:[`xclip`,`-selection`,`clipboard`]};return process.env.WAYLAND_DISPLAY?[e,t]:[t,e]},T=(e,t)=>new Promise((n,r)=>{let i=m(e,t,{detached:!0,stdio:`ignore`});i.once(`error`,r),i.once(`spawn`,()=>{i.unref(),n()})}),E=(e,t,n)=>new Promise((r,i)=>{let a=m(e,t,{stdio:[`pipe`,`ignore`,`ignore`]});a.once(`error`,i),a.stdin.once(`error`,i),a.once(`exit`,t=>{t===0?r():i(Error(`${e} exited with code ${t}`))}),a.stdin.end(n)}),D=n=>{let o=new Set,p=()=>{for(let e of[...o])e()};return{configPath:n,serverVersion:e().version,machineId:h.machineIdSync(),async readConfigText(){try{return await u.readFile(n,`utf8`)}catch(e){if(y(e))return null;throw e}},async writeConfigText(e,{backup:t}){let r=await u.realpath(n).catch(()=>n),i=await b(r);await u.mkdir(d.dirname(r),{recursive:!0}),p();let a=d.join(d.dirname(r),`.${d.basename(r)}.${process.pid}-${Date.now()}.tmp`);try{await u.writeFile(a,e,{encoding:`utf8`,flag:`wx`,...i?{mode:i.mode&511}:{}}),i&&await u.chmod(a,i.mode&4095);let o=null;return t&&i&&(o=`${n}.bak`,await u.copyFile(r,o)),await u.rename(a,r),{backupPath:o}}catch(e){throw await u.rm(a,{force:!0}),e}},async statConfig(){let e=await b(n);return e?{mtimeMs:e.mtimeMs}:null},watchConfig(e){let t=d.basename(n),r=null,i=null,a=!1,s=()=>{if(o.delete(s),!a)try{i=f.watch(d.dirname(n),(n,i)=>{i&&i!==t||(r&&clearTimeout(r),r=setTimeout(()=>{r=null,e()},100))}),i.on(`error`,e=>{console.warn(`[ui] Stopped watching ${n}: ${e.message}`),i?.close()})}catch(e){y(e)?o.add(s):console.warn(`[ui] Cannot watch ${n}: ${e.message}`)}};return s(),()=>{a=!0,o.delete(s),r&&clearTimeout(r),i?.close()}},async probeCaps(e){return(await t(e.map(e=>({type:e})))).map(({type:e,score:t,hasGpu:n,usableBytes:r})=>({type:e,score:t??0,hasGpu:n??!1,usableBytes:r??0}))},async getBackendDefaults(e){return r(e)},resolveHfToken(e){let t={...x(e.raw.env),...process.env};return[e.runtime.huggingface_token,t.HUGGINGFACE_TOKEN,t.HF_TOKEN].find(e=>typeof e==`string`&&e.trim()!==``)?.trim()??null},async hostInfo(){return i()},async preferredAppearance(){if(process.platform!==`darwin`)return`light`;try{let{stdout:e}=await v(`defaults`,[`read`,`-g`,`AppleInterfaceStyle`]);return e.trim()===`Dark`?`dark`:`light`}catch{return`light`}},async openExternal(e){let{protocol:t}=new URL(e);if(t!==`http:`&&t!==`https:`)throw Error(`Only http(s) links can be opened: ${e}`);let[n,...r]=C(e);await T(n,r)},async copyToClipboard(e){let t=null;for(let{argv:n,encode:r}of w()){let[i,...a]=n;try{await E(i,a,r?r(e):e);return}catch(e){t=e}}throw t},startCommand:()=>`bricks-buttress --config ${S(n)}`,agentConnection(e){if(!f.existsSync(n))return null;let t;try{t=c(n)}catch{return null}let{config:r,agentsConfig:i}=t;return i?{baseUrl:`http://127.0.0.1:${e?.port??(r.server.port||2080)}`,token:l(i.runtimeTokenFile)}:null},agentsConfigError(e){let t=e;if(t===void 0)try{t=f.readFileSync(n,`utf8`)}catch{return{agents:0,error:null}}let r;try{r=g.parse(t)}catch(e){return{agents:0,error:`invalid TOML: ${O(e)}`}}let i=Array.isArray(r.agents)?r.agents.length:0;if(i===0)return{agents:0,error:null};try{return s(a(r),{configDir:d.dirname(n)}),{agents:i,error:null}}catch(e){return{agents:i,error:O(e)}}}}},O=e=>e instanceof Error?e.message:String(e),k=()=>import(`@fugood/buttress-ui`),A=[`darwin-arm64`,`linux-x64`,`win32-x64`],j=[`chat`,`status`,`settings`],M=e=>j.includes(e),N=e=>{let t=[],n;for(let r=0;r<e.length;r+=1){let i=e[r];if(i===`-h`||i===`--help`)return{kind:`help`};if(i===`-c`||i===`--config`){let n=e[r+1];if(n===void 0)return{kind:`error`,message:`${i} needs a config file path`};t.push(n),r+=1}else if(i===`--tab`){let t=e[r+1];if(t===void 0||!M(t)){let e=t===void 0?``:` (got "${t}")`;return{kind:`error`,message:`--tab needs one of ${j.join(`, `)}${e}`}}n=t,r+=1}else if(i.startsWith(`-`))return{kind:`error`,message:`Unknown option: ${i}`};else t.push(i)}return t.length===0?{kind:`error`,message:`bricks-buttress ui needs a config file path`}:t.length>1?{kind:`error`,message:`Give one config file path (got ${t.join(`, `)})`}:t[0].includes(`
3
- `)?{kind:`error`,message:`bricks-buttress ui edits a config file; inline TOML is not supported`}:{kind:`run`,configPath:d.resolve(t[0]),initialTab:n}},P=()=>({isBun:`Bun`in globalThis,platform:process.platform,arch:process.arch}),F=(e,t)=>e.isBun?A.includes(`${e.platform}-${e.arch}`)?null:`bricks-buttress ui runs on darwin-arm64, linux-x64 and win32-x64; on this machine open ${t()} in a browser instead`:`bricks-buttress ui needs Bun; run it with bun or the standalone bricks-buttress binary`,I=e=>{try{let t=g.parse(f.readFileSync(e,`utf8`)).server?.port;return Number.isInteger(t)&&t>0?t:o}catch{return o}},L=e=>`http://${n()??`localhost`}:${I(e)}/status`,R=e=>e instanceof Error?e.message:String(e),z=e=>{let{code:t,specifier:n}=e??{};return t===`ERR_MODULE_NOT_FOUND`&&n===`@fugood/buttress-ui`},B=e=>process.env.BUTTRESS_SERVER_DISTRIBUTION===`1`&&R(e).includes(`@gpuix/native-`),V=async e=>{try{let{launchButtressUi:e}=await k();return e}catch(t){z(t)?console.error(`This bricks-buttress install does not include the settings window (the npm package leaves it out); use the standalone bricks-buttress binary or a source checkout, or open ${L(e)} in a browser instead`):B(t)?console.error(`The window's native module (gpuix) is missing next to bricks-buttress; run \`bricks-buttress update\` to reinstall it, or open ${L(e)} in a browser instead (${R(t)})`):console.error(`bricks-buttress ui failed to load the window: ${R(t)}`),process.exit(1)}},H=async e=>{let t=N(e);t.kind===`help`&&(console.log(`
2
+ import{a as e,i as t,n,o as r,r as i}from"./net-YKjcwlKu.mjs";import{a,c as o,n as s}from"./config-DiYweJ2m.mjs";import{n as c,r as l}from"./client-qqI-HCOj.mjs";import u from"node:fs/promises";import d from"node:path";import f from"node:fs";import{execFile as p,spawn as m}from"node:child_process";import h from"node-machine-id";import g from"@iarna/toml";import{promisify as _}from"node:util";const v=_(p),y=e=>e?.code===`ENOENT`,b=async e=>{try{return await u.stat(e)}catch(e){if(y(e))return null;throw e}},x=e=>{if(!e)return{};try{let{env:t}=g.parse(e);return t&&typeof t==`object`&&!Array.isArray(t)?t:{}}catch{return{}}},S=e=>(process.platform===`win32`?/^[\w@%+=:,./\\-]+$/:/^[\w@%+=:,./-]+$/).test(e)?e:process.platform===`win32`?`"${e}"`:`'${e.replaceAll(`'`,`'\\''`)}'`,C=e=>process.platform===`darwin`?[`open`,e]:process.platform===`win32`?[`rundll32`,`url.dll,FileProtocolHandler`,e]:[`xdg-open`,e],w=()=>{if(process.platform===`darwin`)return[{argv:[`pbcopy`]}];if(process.platform===`win32`)return[{argv:[`clip`],encode:e=>Buffer.from(`\ufeff${e}`,`utf16le`)}];let e={argv:[`wl-copy`]},t={argv:[`xclip`,`-selection`,`clipboard`]};return process.env.WAYLAND_DISPLAY?[e,t]:[t,e]},T=(e,t)=>new Promise((n,r)=>{let i=m(e,t,{detached:!0,stdio:`ignore`});i.once(`error`,r),i.once(`spawn`,()=>{i.unref(),n()})}),E=(e,t,n)=>new Promise((r,i)=>{let a=m(e,t,{stdio:[`pipe`,`ignore`,`ignore`]});a.once(`error`,i),a.stdin.once(`error`,i),a.once(`exit`,t=>{t===0?r():i(Error(`${e} exited with code ${t}`))}),a.stdin.end(n)}),D=n=>{let o=new Set,p=()=>{for(let e of[...o])e()};return{configPath:n,serverVersion:e().version,machineId:h.machineIdSync(),async readConfigText(){try{return await u.readFile(n,`utf8`)}catch(e){if(y(e))return null;throw e}},async writeConfigText(e,{backup:t}){let r=await u.realpath(n).catch(()=>n),i=await b(r);await u.mkdir(d.dirname(r),{recursive:!0}),p();let a=d.join(d.dirname(r),`.${d.basename(r)}.${process.pid}-${Date.now()}.tmp`);try{await u.writeFile(a,e,{encoding:`utf8`,flag:`wx`,...i?{mode:i.mode&511}:{}}),i&&await u.chmod(a,i.mode&4095);let o=null;return t&&i&&(o=`${n}.bak`,await u.copyFile(r,o)),await u.rename(a,r),{backupPath:o}}catch(e){throw await u.rm(a,{force:!0}),e}},async statConfig(){let e=await b(n);return e?{mtimeMs:e.mtimeMs}:null},watchConfig(e){let t=d.basename(n),r=null,i=null,a=!1,s=()=>{if(o.delete(s),!a)try{i=f.watch(d.dirname(n),(n,i)=>{i&&i!==t||(r&&clearTimeout(r),r=setTimeout(()=>{r=null,e()},100))}),i.on(`error`,e=>{console.warn(`[ui] Stopped watching ${n}: ${e.message}`),i?.close()})}catch(e){y(e)?o.add(s):console.warn(`[ui] Cannot watch ${n}: ${e.message}`)}};return s(),()=>{a=!0,o.delete(s),r&&clearTimeout(r),i?.close()}},async probeCaps(e){return(await t(e.map(e=>({type:e})))).map(({type:e,score:t,hasGpu:n,usableBytes:r})=>({type:e,score:t??0,hasGpu:n??!1,usableBytes:r??0}))},async getBackendDefaults(e){return r(e)},resolveHfToken(e){let t={...x(e.raw.env),...process.env};return[e.runtime.huggingface_token,t.HUGGINGFACE_TOKEN,t.HF_TOKEN].find(e=>typeof e==`string`&&e.trim()!==``)?.trim()??null},async hostInfo(){return i()},async preferredAppearance(){if(process.platform!==`darwin`)return`light`;try{let{stdout:e}=await v(`defaults`,[`read`,`-g`,`AppleInterfaceStyle`]);return e.trim()===`Dark`?`dark`:`light`}catch{return`light`}},async openExternal(e){let{protocol:t}=new URL(e);if(t!==`http:`&&t!==`https:`)throw Error(`Only http(s) links can be opened: ${e}`);let[n,...r]=C(e);await T(n,r)},async copyToClipboard(e){let t=null;for(let{argv:n,encode:r}of w()){let[i,...a]=n;try{await E(i,a,r?r(e):e);return}catch(e){t=e}}throw t},startCommand:()=>`bricks-buttress --config ${S(n)}`,agentConnection(e){if(!f.existsSync(n))return null;let t;try{t=c(n)}catch{return null}let{config:r,agentsConfig:i}=t;return i?{baseUrl:`http://127.0.0.1:${e?.port??(r.server.port||2080)}`,token:l(i.runtimeTokenFile)}:null},agentsConfigError(e){let t=e;if(t===void 0)try{t=f.readFileSync(n,`utf8`)}catch{return{agents:0,error:null}}let r;try{r=g.parse(t)}catch(e){return{agents:0,error:`invalid TOML: ${O(e)}`}}let i=Array.isArray(r.agents)?r.agents.length:0;if(i===0)return{agents:0,error:null};try{return s(a(r),{configDir:d.dirname(n)}),{agents:i,error:null}}catch(e){return{agents:i,error:O(e)}}}}},O=e=>e instanceof Error?e.message:String(e),k=()=>import(`@fugood/buttress-ui`),A=[`darwin-arm64`,`linux-x64`,`win32-x64`,`win32-arm64`],j=[`chat`,`status`,`settings`],M=e=>j.includes(e),N=e=>{let t=[],n;for(let r=0;r<e.length;r+=1){let i=e[r];if(i===`-h`||i===`--help`)return{kind:`help`};if(i===`-c`||i===`--config`){let n=e[r+1];if(n===void 0)return{kind:`error`,message:`${i} needs a config file path`};t.push(n),r+=1}else if(i===`--tab`){let t=e[r+1];if(t===void 0||!M(t)){let e=t===void 0?``:` (got "${t}")`;return{kind:`error`,message:`--tab needs one of ${j.join(`, `)}${e}`}}n=t,r+=1}else if(i.startsWith(`-`))return{kind:`error`,message:`Unknown option: ${i}`};else t.push(i)}return t.length===0?{kind:`error`,message:`bricks-buttress ui needs a config file path`}:t.length>1?{kind:`error`,message:`Give one config file path (got ${t.join(`, `)})`}:t[0].includes(`
3
+ `)?{kind:`error`,message:`bricks-buttress ui edits a config file; inline TOML is not supported`}:{kind:`run`,configPath:d.resolve(t[0]),initialTab:n}},P=()=>({isBun:`Bun`in globalThis,platform:process.platform,arch:process.arch}),F=(e,t)=>e.isBun?A.includes(`${e.platform}-${e.arch}`)?null:`bricks-buttress ui runs on darwin-arm64, linux-x64, win32-x64 and win32-arm64; on this machine open ${t()} in a browser instead`:`bricks-buttress ui needs Bun; run it with bun or the standalone bricks-buttress binary`,I=e=>{try{let t=g.parse(f.readFileSync(e,`utf8`)).server?.port;return Number.isInteger(t)&&t>0?t:o}catch{return o}},L=e=>`http://${n()??`localhost`}:${I(e)}/status`,R=e=>e instanceof Error?e.message:String(e),z=e=>{let{code:t,specifier:n}=e??{};return t===`ERR_MODULE_NOT_FOUND`&&n===`@fugood/buttress-ui`},B=e=>process.env.BUTTRESS_SERVER_DISTRIBUTION===`1`&&R(e).includes(`@gpuix/native-`),V=async e=>{try{let{launchButtressUi:e}=await k();return e}catch(t){z(t)?console.error(`This bricks-buttress install does not include the settings window (the npm package leaves it out); use the standalone bricks-buttress binary or a source checkout, or open ${L(e)} in a browser instead`):B(t)?console.error(`The window's native module (gpuix) is missing next to bricks-buttress; run \`bricks-buttress update\` to reinstall it, or open ${L(e)} in a browser instead (${R(t)})`):console.error(`bricks-buttress ui failed to load the window: ${R(t)}`),process.exit(1)}},H=async e=>{let t=N(e);t.kind===`help`&&(console.log(`
4
4
  Usage:
5
5
  bricks-buttress ui [-c|--config] <config.toml> [--tab <chat|status|settings>]
6
6
 
@@ -23,8 +23,8 @@ server that runs it and to chat with its agents.
23
23
  The window opens on Chat when the server runs and has agents, on Status
24
24
  when it runs without agents, and on Settings otherwise; --tab overrides it.
25
25
 
26
- Runs under Bun on darwin-arm64, linux-x64 and win32-x64. On other machines,
27
- open http://<host>:<port>/status in a browser.
26
+ Runs under Bun on darwin-arm64, linux-x64, win32-x64 and win32-arm64. On
27
+ other machines, open http://<host>:<port>/status in a browser.
28
28
 
29
29
  Options:
30
30
  -c, --config <path> Config file to edit (a positional path works too)
package/lib/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{a as e,c as t,d as n,i as r,l as i,n as a,o,r as s,s as c,t as l,u}from"./net-BvSOGnw5.mjs";import{a as d,c as f,d as p,f as m,i as h,l as g,n as _,o as v,p as y,r as b,s as x,t as S,u as C}from"./config-DiYweJ2m.mjs";import{builtinModules as ee,createRequire as w}from"node:module";import{node as T}from"@elysiajs/node";import{Elysia as te,file as ne,sse as E,t as D}from"elysia";import{ReadableStream as re}from"node:stream/web";import O,{mkdir as ie,rm as k,unlink as A,writeFile as ae}from"node:fs/promises";import oe,{randomBytes as se,randomUUID as j,timingSafeEqual as ce}from"node:crypto";import M from"node:path";import N from"node:os";import le from"bytes";import P,{createWriteStream as ue}from"node:fs";import{fileURLToPath as de,pathToFileURL as fe}from"node:url";import{execSync as pe,spawn as me,spawnSync as he}from"node:child_process";import{ZodError as ge,z as F}from"zod";import{importSPKI as _e,jwtVerify as ve}from"jose";import ye from"ms";import be from"node:vm";import{moduleRunnerTransformSync as xe,transformSync as Se}from"oxc-transform";import Ce from"lodash";import we from"moment";import*as Te from"mathjs";import Ee from"voca";import De from"chroma-js";import Oe from"json5";import ke from"qs";import{nanoid as Ae}from"nanoid";import je from"md5";import{Server as Me}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as Ne,ListToolsRequestSchema as Pe}from"@modelcontextprotocol/sdk/types.js";import{Readable as Fe}from"node:stream";import{pipeline as Ie}from"node:stream/promises";import Le from"@iarna/toml";import{Buffer as Re}from"node:buffer";import ze from"node:dgram";import{Agent as Be}from"@earendil-works/pi-agent-core";import{createProvider as Ve,uuidv7 as He}from"@earendil-works/pi-ai";import{builtinModels as Ue}from"@earendil-works/pi-ai/providers/all";import{stream as We,streamSimple as Ge}from"@earendil-works/pi-ai/api/openai-completions";import Ke from"node:readline/promises";const qe=!(`Bun`in globalThis),I=e=>new te({adapter:qe?T():void 0,...e}),Je=(e,t,n)=>Buffer.from(JSON.stringify({t:e,d:t,ts:n}),`utf8`),Ye=(e,t,n)=>{if(!e)return null;let r=Math.floor(Date.now()/1e3),i=oe.sign(null,Je(t,n,r),e.privateKey).toString(`base64`);return{t,v:`2.0`,d:n,ts:r,kid:e.kid,sig:i}},Xe=e=>{let{workspace:t,serverKeyPair:n}=e;return!t||!n?null:{kid:n.kid,privateKey:oe.createPrivateKey({key:Buffer.from(n.privateKeyPkcs8,`base64`),format:`der`,type:`pkcs8`})}},Ze=D.Object({id:D.String(),name:D.String(),version:D.String(),address:D.String(),addresses:D.Array(D.String()),port:D.Number(),url:D.String(),generators:D.Array(D.Object({type:D.String(),score:D.Optional(D.Number()),hasGpu:D.Optional(D.Boolean()),usableBytes:D.Optional(D.Number())})),authentication:D.Object({required:D.Boolean(),type:D.String(),kid:D.Optional(D.String()),bound:D.Optional(D.Boolean())}),workspace:D.Optional(D.Object({id:D.String(),name:D.Optional(D.String())})),functions:D.Optional(D.Object({enabled:D.Boolean(),count:D.Number()})),envelope:D.Optional(D.Any())}),Qe=e=>[...new Set([e.address,...e.addresses||[]].filter(e=>typeof e==`string`&&e.length>0))],$e=e=>({id:e.id,name:e.name,version:e.version,address:e.address,addresses:Qe(e),port:e.port,url:e.url,generators:e.generators,authentication:e.authentication,workspace:e.workspace,functions:e.functions});var et=(e,t=null)=>{let n=I(),r=e.autodiscover?.http?.path??`/buttress/info`;return n.get(r,({store:{serverInfo:e}})=>{let n=$e(e),r=Ye(t,`ANNOUNCE`,{info:n});return r?{...n,envelope:r}:n},{response:Ze}),n};const tt=e=>`Bun`in globalThis?globalThis.Bun.file(e):ne(e);let nt=null;const rt=async e=>{if(nt&&nt.kid===e.kid)return nt.key;let t=await _e(e.issuerPublicKey,`EdDSA`);return nt={kid:e.kid,key:t},t},it=/^Bearer\s+(.+)$/i,at=(e,t)=>{if(e){let t=e.authorization||e.Authorization;if(t){let e=t.match(it);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},ot=async(e,t)=>{if(!e||!t)return null;try{let{payload:n}=await ve(e,await rt(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}},st=(async({headers:e,query:t,set:n,store:r})=>{let i=r.workspaceState?.workspace;if(!i)return;let a=at(e,t);if(!r.agentsService?.verifyInternalToken?.(a)&&!await ot(a,i))return n.status=401,n.headers&&(n.headers[`WWW-Authenticate`]=`Bearer`),{error:{code:`UNAUTHORIZED`,message:`Invalid or missing workspace access token`}}}),ct=e=>{if(!e)return null;let t=e[`x-buttress-sess-id`]??e[`X-BUTTRESS-SESS-ID`];return t?t.trim():null},lt=(async({headers:e,query:t,set:n,store:r})=>{let i=r.sessions,a=ct(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 ot(at(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`}}}}),ut=(e,t)=>{let n=e.sessions,r=ct(t);if(!r||!n)return null;let i=n.get(r);return i?{sessionId:r,session:i}:null},dt=typeof process<`u`&&process.versions!=null&&process.versions.node!=null;var ft=I().onBeforeHandle(st).onBeforeHandle(lt).post(`/buttress/upload`,async({body:{file:e},headers:t,store:n})=>{let r=ut(n,t);if(!r)return{ok:!1,error:`Session guard mis-wired`};let{session:i}=r;try{let t=dt?e.stream():await e.arrayBuffer();return{ok:!0,filename:await i.fileManager.storeUpload(e.name,t)}}catch(e){return{ok:!1,error:String(e)}}},{body:D.Object({file:D.File()}),response:D.Object({ok:D.Boolean(),filename:D.Optional(D.String()),error:D.Optional(D.String())})}).get(`/buttress/download/:filename`,async({params:{filename:e},headers:t,store:n,set:r})=>{let i=ut(n,t);if(!i)return r.status=500,`Session guard mis-wired`;let{session:a}=i,o=a.fileManager.resolve(e);return o?tt(o):(r.status=404,`File not found`)},{params:D.Object({filename:D.String()})});const pt=(()=>{let e=new Set,t=[],n=(n,r)=>{if(!e.delete(n)||!r)return;let i=Date.now();t.unshift({type:n.type,repoId:n.repoId,filename:n.filename,totalBytes:null,durationMs:i-n.startedAt,finishedAt:new Date(i).toISOString(),...r}),t.length=Math.min(t.length,20)};return{begin(t){let r={type:t.type,repoId:t.repoId,filename:t.filename??null,startedAt:Date.now(),progress:null};return e.add(r),{progress(t){e.has(r)&&Number.isFinite(t)&&(r.progress=Math.round(Math.min(1,Math.max(0,t))*1e3)/1e3)},setRepoId(e){r.repoId=e},complete:()=>n(r,{success:!0}),fail:e=>n(r,{success:!1,error:e instanceof Error?e.message:String(e)}),discard:()=>n(r,null)}},snapshot(){return{active:[...e].map(e=>({type:e.type,repoId:e.repoId,filename:e.filename,receivedBytes:0,totalBytes:null,bytesPerSecond:null,startedAt:new Date(e.startedAt).toISOString(),progress:e.progress})),recent:[...t]}}}})(),mt=(e,t=200)=>e.length>t?`${e.slice(0,t)}…`:e,L=((e=50)=>{let t={calls:{total:0,failed:0},uploads:{total:0,failed:0,bytes:0},downloads:{total:0,missed:0,bytes:0},auth:{total:0,denied:0},daemons:{invocations:0,failed:0}},n={calls:[],uploads:[],downloads:[],auth:[],daemons:[]},r=null,i=(t,n)=>{t.unshift(n),t.length>e&&(t.length=e)};return{recordCall(e){t.calls.total+=1,e.success||(t.calls.failed+=1),i(n.calls,{...e,error:e.error&&mt(e.error),timestamp:new Date().toISOString()})},recordUpload(e){t.uploads.total+=1,e.success?t.uploads.bytes+=e.size:t.uploads.failed+=1,i(n.uploads,{...e,error:e.error&&mt(e.error),timestamp:new Date().toISOString()})},recordDownload(e){t.downloads.total+=1,e.success?t.downloads.bytes+=e.size??0:t.downloads.missed+=1,i(n.downloads,{...e,path:mt(e.path),timestamp:new Date().toISOString()})},recordDaemonActivity(e){t.daemons.invocations+=1,e.success||(t.daemons.failed+=1),i(n.daemons,{...e,error:e.error&&mt(e.error),timestamp:new Date().toISOString()})},setDaemonsProvider(e){r=e},recordAuth(e){t.auth.total+=1,e.outcome!==`allowed`&&(t.auth.denied+=1),i(n.auth,{...e,path:mt(e.path),timestamp:new Date().toISOString()})},snapshot(){let e=[];try{e=r?.()??[]}catch{}return{counters:{calls:{...t.calls},uploads:{...t.uploads},downloads:{...t.downloads},auth:{...t.auth},daemons:{...t.daemons}},daemons:e,history:{calls:[...n.calls],uploads:[...n.uploads],downloads:[...n.downloads],auth:[...n.auth],daemons:[...n.daemons]}}}}})(),ht=M.dirname(de(import.meta.url)),gt=()=>{try{let e=w(import.meta.url).resolve(`@fugood/buttress-ui/package.json`);return M.join(M.dirname(e),`lib`,`status.html`)}catch{return null}},_t=async()=>{let e=gt(),t=[...e?[e]:[],M.join(ht,`..`,`public`,`status.html`),M.join(ht,`..`,`..`,`public`,`status.html`),M.join(M.dirname(process.execPath),`public`,`status.html`)];return(await Promise.all(t.map(e=>O.access(e).then(()=>e,()=>null)))).find(e=>e!==null)??null},vt=e=>{let{status:t}=e;return t?.getFullStatus?t.getFullStatus():{timestamp:new Date().toISOString(),ggmlLlm:{generators:[],history:{}},ggmlStt:{generators:[],history:{}},onnxStt:{generators:[],history:{}},onnxTts:{generators:[],history:{}},ggmlTts:{generators:[],history:{}},ggmlDecision:{generators:[],history:{}}}},yt=async()=>{let e=await _t();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 O.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`}})}},bt=e=>e?.functions?{enabled:!0,count:e.functions.count,daemonCount:e.functions.daemons??0,...L.snapshot()}:{enabled:!1},xt=(e,t)=>{if(!e)return null;let{udp:n,http:r}=e,i=!!(n?.announcements?.enabled||n?.requests?.enabled);return{udpPort:i?n.port??null:null,udpAnnouncing:i&&!!(t.workspace&&t.serverKeyPair),httpPath:r?.enabled?r.path??`/buttress/info`:null}},St=({config:e,endpoints:t,functionsService:n,agentsService:r,workspaceState:i})=>{let a=r?.list()??[];return{openaiCompat:t.openaiCompat,anthropicMessages:t.anthropicMessages,typesafeCompat:t.typesafeCompat,autodiscover:xt(e.autodiscover,i),functions:{enabled:n!==null,count:n?.stats.count??0,daemons:n?.stats.daemons??0,hotReload:n?.config.hotReload??!1},agents:r?{enabled:!0,count:a.length,names:a}:null}},Ct=e=>typeof e==`string`&&e.trim()!==``?e:null,wt=e=>e.map(({type:e,model:t})=>({type:e,repoId:Ct(t?.repo_id)??Ct(t?.repository),quantization:Ct(t?.quantization)})),Tt=e=>{let{serverInfo:t,startedAt:n,sessions:r,config:i,host:a}=e;return{id:t.id,name:t.name,version:t.version,port:t.port,startedAt:new Date(n).toISOString(),uptimeMs:Date.now()-n,sessions:{open:r.size},generatorTypes:[...new Set(i.generators.map(e=>e.type))],generators:wt(i.generators),features:St(e),host:a,caps:t.generators.map(({type:e,score:t,hasGpu:n,usableBytes:r})=>({type:e,score:t??0,hasGpu:n??!1,usableBytes:r??0}))}};var Et=I().get(`/status`,yt).get(`/status/`,yt).get(`/buttress/status`,({store:e})=>({...vt(e.backend),functions:bt(e.serverInfo),server:Tt(e),downloads:pt.snapshot()}));const Dt=[`repo_id`,`revision`,`filename`,`quantization`,`url`,`local_path`],Ot=[`mmproj_repo_id`,`mmproj_revision`,`mmproj_filename`,`mmproj_url`,`mmproj_local_path`],kt=(e,t)=>{let n=e?.[t];return n==null||n===``?t===`revision`?`main`:null:n},At=(e,t,n)=>n.every(n=>kt(e,n)===kt(t,n)),jt=(e,t)=>e?.rank_pooling?`rank pooling needs an embedding context`:t?.embedding||t?.vocab_only?`the LLM is embedding or vocab-only`:Ot.some(t=>kt(e,t)!=null)&&!At(e,t,Ot)?`the projectors differ`:null,Mt=(e,t)=>{if(t?.backend?.share_llm_context!==!0)return null;let n=t.model,r=(e?.generators||[]).find(e=>e?.type===`ggml-llm`&&At(e.model,n,Dt));return r?jt(n,r.model)?null:r:null},Nt=(e,t)=>(e?.generators||[]).find(e=>e?.type===`ggml-decision`&&e.backend?.share_llm_context===!0&&At(e.model,t,Dt))?Mt(e,{backend:{share_llm_context:!0},model:t}):null,Pt=e=>{let t=e?.generators||[],n=[];for(let r of t.filter(e=>e?.type===`ggml-decision`)){let i=r.model?.repo_id,a=t.find(e=>e?.type===`ggml-llm`&&At(e.model,r.model,Dt));if(!a)continue;if(r.backend?.share_llm_context!==!0){n.push(`${i}: decisions load their own context (set [generators.backend] share_llm_context = true to share the ggml-llm one)`);continue}let o=jt(r.model,a.model);if(o){n.push(`${i}: decisions load their own context (${o})`);continue}n.push(`${i}: decisions share the ggml-llm context`);let s={...e.global?.runtime,...a.runtime,...a.model},c=Number(s.n_parallel)||4,l=Math.floor((Number(s.n_ctx)||0)/c),u=Number(r.runtime?.n_ctx??r.model?.n_ctx)||0;s.kv_unified!==!0&&l>0&&u>l&&n.push(` warning: a decision gets ${l} tokens per slot (n_ctx / n_parallel), less than its n_ctx ${u}; raise the LLM n_ctx or set kv_unified = true`)}return n},Ft=[`ggml-llm`,`mlx-llm`],It=m({family:`LLM`,types:Ft}),Lt={jinja:!0,add_generation_prompt:!0,reasoning_format:`auto`,enable_thinking:!1};function Rt(e,t){return t===`mlx-llm`?e.mlxLlm:e.ggmlLlm}const zt=y({max:4,resolve:It,prepare:async(e,t)=>{await Rt(e,t.type).initContext(t.id,{})}});async function Bt(e,t,n=`[LLM]`){return zt.release(e,t,n)}async function Vt(e,t,n,r=`[LLM]`){return zt.getOrCreate(e,t,n,r)}function Ht(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 Ut(e){return!!(e.stopped_limit||e.stopped_limited||e.context_full)}function Wt(e){let{promptTokens:t,cachedTokens:n,completionTokens:r}=Ht(e),i=t+n;return{prompt_tokens:i,completion_tokens:r,total_tokens:i+r}}const Gt=e=>e?.type===`ggml-decision`,Kt=e=>{let t=new Set,n=new Set;for(let r of(e.generators||[]).filter(Gt)){let e=p(r);t.has(e)&&n.add(e),t.add(e)}return[...n]},qt=(e,t)=>t===`ggml-llm`?e.ggmlLlm:e.ggmlDecision,Jt=m({family:`decision`,types:[`ggml-decision`]}),Yt=y({max:2,resolve:(e,t)=>{let n=Jt(e,t),r=Mt(e,n.mergedConfig);return r?It(e,p(r)):n},prepare:async(e,t)=>{await qt(e,t.type).initContext(t.id,{})},dispose:async(e,t)=>{t.type===`ggml-llm`&&await e.ggmlLlm.releaseContext(t.id,{})}});async function Xt(e,t,{model:n,...r},i=`[Decision]`){let a=await Yt.getOrCreate(e,t,n,i);try{return await qt(e,a.type).decide(a.id,{request:r})}finally{await Yt.release(e,a,i)}}const Zt=[`wav`,`mp3`];var R=class extends Error{param;constructor(e,t){super(t),this.param=e}};const Qt=e=>typeof e==`object`&&!!e&&!Array.isArray(e),$t=e=>typeof e==`string`&&e.trim()!==``,en=e=>/^(0|[1-9]\d{0,9})$/.test(e),tn=(e,t)=>$t(t)?`${e}: ${t}`:e,nn=(e,t)=>e>0&&t>0?`The attached media.`:t>0?t>1?`The attached audio clips.`:`The attached audio clip.`:e>1?`The attached images.`:`The attached image.`,rn=e=>{if(typeof e==`string`){if(e.trim()===``)throw new R(`input`,"`input` must not be empty");return{state:e}}if(!Array.isArray(e)||e.length===0)throw new R(`input`,"`input` must be a string or a non-empty message array");let t=[],n=[],r=0;if(e.forEach((e,i)=>{let a=`input[${i}]`;if(!Qt(e)||e.role!==`user`)throw new R(`${a}.role`,"Only `user` messages are supported");if(e.type!=null&&e.type!==`message`)throw new R(`${a}.type`,"Message `type` must be `message`");let{content:o}=e;if(typeof o==`string`){t.push(o);return}if(!Array.isArray(o))throw new R(`${a}.content`,"`content` must be a string or an array of parts");o.forEach((e,i)=>{let o=`${a}.content[${i}]`;if(e?.type===`input_text`&&typeof e.text==`string`)t.push(e.text);else if(e?.type===`input_image`){if(typeof e.image_url!=`string`||!e.image_url.startsWith(`data:`))throw new R(`${o}.image_url`,`Images must be inline base64 data URLs`);n.push(e.image_url)}else if(e?.type===`input_audio`){let{data:t,format:i}=e.input_audio||{};if(!$t(t)||t.startsWith(`data:`))throw new R(`${o}.input_audio.data`,"Audio must be inline base64 `data`");if(!Zt.includes(i))throw new R(`${o}.input_audio.format`,`Audio \`format\` must be one of ${Zt.join(`, `)}`);n.push(`data:audio/${i};base64,${t}`),r+=1}else throw new R(`${o}.type`,"Content parts must be `input_text`, `input_image` or `input_audio`")})}),n.length>128)throw new R(`input`,`At most 128 images and audio clips are allowed`);let i=t.filter(e=>e.trim()!==``).join(`
2
+ import{a as e,c as t,d as n,i as r,l as i,n as a,o,r as s,s as c,t as l,u}from"./net-YKjcwlKu.mjs";import{a as d,c as f,d as p,f as m,i as h,l as g,n as _,o as v,p as y,r as b,s as x,t as S,u as C}from"./config-DiYweJ2m.mjs";import{builtinModules as ee,createRequire as w}from"node:module";import{node as T}from"@elysiajs/node";import{Elysia as te,file as ne,sse as E,t as D}from"elysia";import{ReadableStream as re}from"node:stream/web";import O,{mkdir as ie,rm as k,unlink as A,writeFile as ae}from"node:fs/promises";import oe,{randomBytes as se,randomUUID as j,timingSafeEqual as ce}from"node:crypto";import M from"node:path";import N from"node:os";import le from"bytes";import P,{createWriteStream as ue}from"node:fs";import{fileURLToPath as de,pathToFileURL as fe}from"node:url";import{execSync as pe,spawn as me,spawnSync as he}from"node:child_process";import{ZodError as ge,z as F}from"zod";import{importSPKI as _e,jwtVerify as ve}from"jose";import ye from"ms";import be from"node:vm";import{moduleRunnerTransformSync as xe,transformSync as Se}from"oxc-transform";import Ce from"lodash";import we from"moment";import*as Te from"mathjs";import Ee from"voca";import De from"chroma-js";import Oe from"json5";import ke from"qs";import{nanoid as Ae}from"nanoid";import je from"md5";import{Server as Me}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as Ne,ListToolsRequestSchema as Pe}from"@modelcontextprotocol/sdk/types.js";import{Readable as Fe}from"node:stream";import{pipeline as Ie}from"node:stream/promises";import Le from"@iarna/toml";import{Buffer as Re}from"node:buffer";import ze from"node:dgram";import{Agent as Be}from"@earendil-works/pi-agent-core";import{createProvider as Ve,uuidv7 as He}from"@earendil-works/pi-ai";import{builtinModels as Ue}from"@earendil-works/pi-ai/providers/all";import{stream as We,streamSimple as Ge}from"@earendil-works/pi-ai/api/openai-completions";import Ke from"node:readline/promises";const qe=!(`Bun`in globalThis),I=e=>new te({adapter:qe?T():void 0,...e}),Je=(e,t,n)=>Buffer.from(JSON.stringify({t:e,d:t,ts:n}),`utf8`),Ye=(e,t,n)=>{if(!e)return null;let r=Math.floor(Date.now()/1e3),i=oe.sign(null,Je(t,n,r),e.privateKey).toString(`base64`);return{t,v:`2.0`,d:n,ts:r,kid:e.kid,sig:i}},Xe=e=>{let{workspace:t,serverKeyPair:n}=e;return!t||!n?null:{kid:n.kid,privateKey:oe.createPrivateKey({key:Buffer.from(n.privateKeyPkcs8,`base64`),format:`der`,type:`pkcs8`})}},Ze=D.Object({id:D.String(),name:D.String(),version:D.String(),address:D.String(),addresses:D.Array(D.String()),port:D.Number(),url:D.String(),generators:D.Array(D.Object({type:D.String(),score:D.Optional(D.Number()),hasGpu:D.Optional(D.Boolean()),usableBytes:D.Optional(D.Number())})),authentication:D.Object({required:D.Boolean(),type:D.String(),kid:D.Optional(D.String()),bound:D.Optional(D.Boolean())}),workspace:D.Optional(D.Object({id:D.String(),name:D.Optional(D.String())})),functions:D.Optional(D.Object({enabled:D.Boolean(),count:D.Number()})),envelope:D.Optional(D.Any())}),Qe=e=>[...new Set([e.address,...e.addresses||[]].filter(e=>typeof e==`string`&&e.length>0))],$e=e=>({id:e.id,name:e.name,version:e.version,address:e.address,addresses:Qe(e),port:e.port,url:e.url,generators:e.generators,authentication:e.authentication,workspace:e.workspace,functions:e.functions});var et=(e,t=null)=>{let n=I(),r=e.autodiscover?.http?.path??`/buttress/info`;return n.get(r,({store:{serverInfo:e}})=>{let n=$e(e),r=Ye(t,`ANNOUNCE`,{info:n});return r?{...n,envelope:r}:n},{response:Ze}),n};const tt=e=>`Bun`in globalThis?globalThis.Bun.file(e):ne(e);let nt=null;const rt=async e=>{if(nt&&nt.kid===e.kid)return nt.key;let t=await _e(e.issuerPublicKey,`EdDSA`);return nt={kid:e.kid,key:t},t},it=/^Bearer\s+(.+)$/i,at=(e,t)=>{if(e){let t=e.authorization||e.Authorization;if(t){let e=t.match(it);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},ot=async(e,t)=>{if(!e||!t)return null;try{let{payload:n}=await ve(e,await rt(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}},st=(async({headers:e,query:t,set:n,store:r})=>{let i=r.workspaceState?.workspace;if(!i)return;let a=at(e,t);if(!r.agentsService?.verifyInternalToken?.(a)&&!await ot(a,i))return n.status=401,n.headers&&(n.headers[`WWW-Authenticate`]=`Bearer`),{error:{code:`UNAUTHORIZED`,message:`Invalid or missing workspace access token`}}}),ct=e=>{if(!e)return null;let t=e[`x-buttress-sess-id`]??e[`X-BUTTRESS-SESS-ID`];return t?t.trim():null},lt=(async({headers:e,query:t,set:n,store:r})=>{let i=r.sessions,a=ct(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 ot(at(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`}}}}),ut=(e,t)=>{let n=e.sessions,r=ct(t);if(!r||!n)return null;let i=n.get(r);return i?{sessionId:r,session:i}:null},dt=typeof process<`u`&&process.versions!=null&&process.versions.node!=null;var ft=I().onBeforeHandle(st).onBeforeHandle(lt).post(`/buttress/upload`,async({body:{file:e},headers:t,store:n})=>{let r=ut(n,t);if(!r)return{ok:!1,error:`Session guard mis-wired`};let{session:i}=r;try{let t=dt?e.stream():await e.arrayBuffer();return{ok:!0,filename:await i.fileManager.storeUpload(e.name,t)}}catch(e){return{ok:!1,error:String(e)}}},{body:D.Object({file:D.File()}),response:D.Object({ok:D.Boolean(),filename:D.Optional(D.String()),error:D.Optional(D.String())})}).get(`/buttress/download/:filename`,async({params:{filename:e},headers:t,store:n,set:r})=>{let i=ut(n,t);if(!i)return r.status=500,`Session guard mis-wired`;let{session:a}=i,o=a.fileManager.resolve(e);return o?tt(o):(r.status=404,`File not found`)},{params:D.Object({filename:D.String()})});const pt=(()=>{let e=new Set,t=[],n=(n,r)=>{if(!e.delete(n)||!r)return;let i=Date.now();t.unshift({type:n.type,repoId:n.repoId,filename:n.filename,totalBytes:null,durationMs:i-n.startedAt,finishedAt:new Date(i).toISOString(),...r}),t.length=Math.min(t.length,20)};return{begin(t){let r={type:t.type,repoId:t.repoId,filename:t.filename??null,startedAt:Date.now(),progress:null};return e.add(r),{progress(t){e.has(r)&&Number.isFinite(t)&&(r.progress=Math.round(Math.min(1,Math.max(0,t))*1e3)/1e3)},setRepoId(e){r.repoId=e},complete:()=>n(r,{success:!0}),fail:e=>n(r,{success:!1,error:e instanceof Error?e.message:String(e)}),discard:()=>n(r,null)}},snapshot(){return{active:[...e].map(e=>({type:e.type,repoId:e.repoId,filename:e.filename,receivedBytes:0,totalBytes:null,bytesPerSecond:null,startedAt:new Date(e.startedAt).toISOString(),progress:e.progress})),recent:[...t]}}}})(),mt=(e,t=200)=>e.length>t?`${e.slice(0,t)}…`:e,L=((e=50)=>{let t={calls:{total:0,failed:0},uploads:{total:0,failed:0,bytes:0},downloads:{total:0,missed:0,bytes:0},auth:{total:0,denied:0},daemons:{invocations:0,failed:0}},n={calls:[],uploads:[],downloads:[],auth:[],daemons:[]},r=null,i=(t,n)=>{t.unshift(n),t.length>e&&(t.length=e)};return{recordCall(e){t.calls.total+=1,e.success||(t.calls.failed+=1),i(n.calls,{...e,error:e.error&&mt(e.error),timestamp:new Date().toISOString()})},recordUpload(e){t.uploads.total+=1,e.success?t.uploads.bytes+=e.size:t.uploads.failed+=1,i(n.uploads,{...e,error:e.error&&mt(e.error),timestamp:new Date().toISOString()})},recordDownload(e){t.downloads.total+=1,e.success?t.downloads.bytes+=e.size??0:t.downloads.missed+=1,i(n.downloads,{...e,path:mt(e.path),timestamp:new Date().toISOString()})},recordDaemonActivity(e){t.daemons.invocations+=1,e.success||(t.daemons.failed+=1),i(n.daemons,{...e,error:e.error&&mt(e.error),timestamp:new Date().toISOString()})},setDaemonsProvider(e){r=e},recordAuth(e){t.auth.total+=1,e.outcome!==`allowed`&&(t.auth.denied+=1),i(n.auth,{...e,path:mt(e.path),timestamp:new Date().toISOString()})},snapshot(){let e=[];try{e=r?.()??[]}catch{}return{counters:{calls:{...t.calls},uploads:{...t.uploads},downloads:{...t.downloads},auth:{...t.auth},daemons:{...t.daemons}},daemons:e,history:{calls:[...n.calls],uploads:[...n.uploads],downloads:[...n.downloads],auth:[...n.auth],daemons:[...n.daemons]}}}}})(),ht=M.dirname(de(import.meta.url)),gt=()=>{try{let e=w(import.meta.url).resolve(`@fugood/buttress-ui/package.json`);return M.join(M.dirname(e),`lib`,`status.html`)}catch{return null}},_t=async()=>{let e=gt(),t=[...e?[e]:[],M.join(ht,`..`,`public`,`status.html`),M.join(ht,`..`,`..`,`public`,`status.html`),M.join(M.dirname(process.execPath),`public`,`status.html`)];return(await Promise.all(t.map(e=>O.access(e).then(()=>e,()=>null)))).find(e=>e!==null)??null},vt=e=>{let{status:t}=e;return t?.getFullStatus?t.getFullStatus():{timestamp:new Date().toISOString(),ggmlLlm:{generators:[],history:{}},ggmlStt:{generators:[],history:{}},onnxStt:{generators:[],history:{}},onnxTts:{generators:[],history:{}},ggmlTts:{generators:[],history:{}},ggmlDecision:{generators:[],history:{}}}},yt=async()=>{let e=await _t();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 O.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`}})}},bt=e=>e?.functions?{enabled:!0,count:e.functions.count,daemonCount:e.functions.daemons??0,...L.snapshot()}:{enabled:!1},xt=(e,t)=>{if(!e)return null;let{udp:n,http:r}=e,i=!!(n?.announcements?.enabled||n?.requests?.enabled);return{udpPort:i?n.port??null:null,udpAnnouncing:i&&!!(t.workspace&&t.serverKeyPair),httpPath:r?.enabled?r.path??`/buttress/info`:null}},St=({config:e,endpoints:t,functionsService:n,agentsService:r,workspaceState:i})=>{let a=r?.list()??[];return{openaiCompat:t.openaiCompat,anthropicMessages:t.anthropicMessages,typesafeCompat:t.typesafeCompat,autodiscover:xt(e.autodiscover,i),functions:{enabled:n!==null,count:n?.stats.count??0,daemons:n?.stats.daemons??0,hotReload:n?.config.hotReload??!1},agents:r?{enabled:!0,count:a.length,names:a}:null}},Ct=e=>typeof e==`string`&&e.trim()!==``?e:null,wt=e=>e.map(({type:e,model:t})=>({type:e,repoId:Ct(t?.repo_id)??Ct(t?.repository),quantization:Ct(t?.quantization)})),Tt=e=>{let{serverInfo:t,startedAt:n,sessions:r,config:i,host:a}=e;return{id:t.id,name:t.name,version:t.version,port:t.port,startedAt:new Date(n).toISOString(),uptimeMs:Date.now()-n,sessions:{open:r.size},generatorTypes:[...new Set(i.generators.map(e=>e.type))],generators:wt(i.generators),features:St(e),host:a,caps:t.generators.map(({type:e,score:t,hasGpu:n,usableBytes:r})=>({type:e,score:t??0,hasGpu:n??!1,usableBytes:r??0}))}};var Et=I().get(`/status`,yt).get(`/status/`,yt).get(`/buttress/status`,({store:e})=>({...vt(e.backend),functions:bt(e.serverInfo),server:Tt(e),downloads:pt.snapshot()}));const Dt=[`repo_id`,`revision`,`filename`,`quantization`,`url`,`local_path`],Ot=[`mmproj_repo_id`,`mmproj_revision`,`mmproj_filename`,`mmproj_url`,`mmproj_local_path`],kt=(e,t)=>{let n=e?.[t];return n==null||n===``?t===`revision`?`main`:null:n},At=(e,t,n)=>n.every(n=>kt(e,n)===kt(t,n)),jt=(e,t)=>e?.rank_pooling?`rank pooling needs an embedding context`:t?.embedding||t?.vocab_only?`the LLM is embedding or vocab-only`:Ot.some(t=>kt(e,t)!=null)&&!At(e,t,Ot)?`the projectors differ`:null,Mt=(e,t)=>{if(t?.backend?.share_llm_context!==!0)return null;let n=t.model,r=(e?.generators||[]).find(e=>e?.type===`ggml-llm`&&At(e.model,n,Dt));return r?jt(n,r.model)?null:r:null},Nt=(e,t)=>(e?.generators||[]).find(e=>e?.type===`ggml-decision`&&e.backend?.share_llm_context===!0&&At(e.model,t,Dt))?Mt(e,{backend:{share_llm_context:!0},model:t}):null,Pt=e=>{let t=e?.generators||[],n=[];for(let r of t.filter(e=>e?.type===`ggml-decision`)){let i=r.model?.repo_id,a=t.find(e=>e?.type===`ggml-llm`&&At(e.model,r.model,Dt));if(!a)continue;if(r.backend?.share_llm_context!==!0){n.push(`${i}: decisions load their own context (set [generators.backend] share_llm_context = true to share the ggml-llm one)`);continue}let o=jt(r.model,a.model);if(o){n.push(`${i}: decisions load their own context (${o})`);continue}n.push(`${i}: decisions share the ggml-llm context`);let s={...e.global?.runtime,...a.runtime,...a.model},c=Number(s.n_parallel)||4,l=Math.floor((Number(s.n_ctx)||0)/c),u=Number(r.runtime?.n_ctx??r.model?.n_ctx)||0;s.kv_unified!==!0&&l>0&&u>l&&n.push(` warning: a decision gets ${l} tokens per slot (n_ctx / n_parallel), less than its n_ctx ${u}; raise the LLM n_ctx or set kv_unified = true`)}return n},Ft=[`ggml-llm`,`mlx-llm`],It=m({family:`LLM`,types:Ft}),Lt={jinja:!0,add_generation_prompt:!0,reasoning_format:`auto`,enable_thinking:!1};function Rt(e,t){return t===`mlx-llm`?e.mlxLlm:e.ggmlLlm}const zt=y({max:4,resolve:It,prepare:async(e,t)=>{await Rt(e,t.type).initContext(t.id,{})}});async function Bt(e,t,n=`[LLM]`){return zt.release(e,t,n)}async function Vt(e,t,n,r=`[LLM]`){return zt.getOrCreate(e,t,n,r)}function Ht(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 Ut(e){return!!(e.stopped_limit||e.stopped_limited||e.context_full)}function Wt(e){let{promptTokens:t,cachedTokens:n,completionTokens:r}=Ht(e),i=t+n;return{prompt_tokens:i,completion_tokens:r,total_tokens:i+r}}const Gt=e=>e?.type===`ggml-decision`,Kt=e=>{let t=new Set,n=new Set;for(let r of(e.generators||[]).filter(Gt)){let e=p(r);t.has(e)&&n.add(e),t.add(e)}return[...n]},qt=(e,t)=>t===`ggml-llm`?e.ggmlLlm:e.ggmlDecision,Jt=m({family:`decision`,types:[`ggml-decision`]}),Yt=y({max:2,resolve:(e,t)=>{let n=Jt(e,t),r=Mt(e,n.mergedConfig);return r?It(e,p(r)):n},prepare:async(e,t)=>{await qt(e,t.type).initContext(t.id,{})},dispose:async(e,t)=>{t.type===`ggml-llm`&&await e.ggmlLlm.releaseContext(t.id,{})}});async function Xt(e,t,{model:n,...r},i=`[Decision]`){let a=await Yt.getOrCreate(e,t,n,i);try{return await qt(e,a.type).decide(a.id,{request:r})}finally{await Yt.release(e,a,i)}}const Zt=[`wav`,`mp3`];var R=class extends Error{param;constructor(e,t){super(t),this.param=e}};const Qt=e=>typeof e==`object`&&!!e&&!Array.isArray(e),$t=e=>typeof e==`string`&&e.trim()!==``,en=e=>/^(0|[1-9]\d{0,9})$/.test(e),tn=(e,t)=>$t(t)?`${e}: ${t}`:e,nn=(e,t)=>e>0&&t>0?`The attached media.`:t>0?t>1?`The attached audio clips.`:`The attached audio clip.`:e>1?`The attached images.`:`The attached image.`,rn=e=>{if(typeof e==`string`){if(e.trim()===``)throw new R(`input`,"`input` must not be empty");return{state:e}}if(!Array.isArray(e)||e.length===0)throw new R(`input`,"`input` must be a string or a non-empty message array");let t=[],n=[],r=0;if(e.forEach((e,i)=>{let a=`input[${i}]`;if(!Qt(e)||e.role!==`user`)throw new R(`${a}.role`,"Only `user` messages are supported");if(e.type!=null&&e.type!==`message`)throw new R(`${a}.type`,"Message `type` must be `message`");let{content:o}=e;if(typeof o==`string`){t.push(o);return}if(!Array.isArray(o))throw new R(`${a}.content`,"`content` must be a string or an array of parts");o.forEach((e,i)=>{let o=`${a}.content[${i}]`;if(e?.type===`input_text`&&typeof e.text==`string`)t.push(e.text);else if(e?.type===`input_image`){if(typeof e.image_url!=`string`||!e.image_url.startsWith(`data:`))throw new R(`${o}.image_url`,`Images must be inline base64 data URLs`);n.push(e.image_url)}else if(e?.type===`input_audio`){let{data:t,format:i}=e.input_audio||{};if(!$t(t)||t.startsWith(`data:`))throw new R(`${o}.input_audio.data`,"Audio must be inline base64 `data`");if(!Zt.includes(i))throw new R(`${o}.input_audio.format`,`Audio \`format\` must be one of ${Zt.join(`, `)}`);n.push(`data:audio/${i};base64,${t}`),r+=1}else throw new R(`${o}.type`,"Content parts must be `input_text`, `input_image` or `input_audio`")})}),n.length>128)throw new R(`input`,`At most 128 images and audio clips are allowed`);let i=t.filter(e=>e.trim()!==``).join(`
3
3
 
4
4
  `);if(i===``&&n.length===0)throw new R(`input`,"`input` has no text, images or audio");return{state:i||nn(n.length-r,r),...n.length>0?{images:n}:{}}},an=(e,t)=>{let n=new Set;e.forEach((e,r)=>{let{value:i}=e||{};if(typeof i!=`string`&&typeof i!=`boolean`)throw new R(`${t}[${r}].value`,"A choice `value` must be a string or a boolean");let a=`${typeof i}:${i}`;if(n.has(a))throw new R(`${t}[${r}].value`,`Choice values must be unique`);n.add(a)});let r=e.map(({value:e})=>String(e)),i=new Set(r).size===r.length&&!r.some(e=>en(e)),a=e.map(({value:e},t)=>({key:i?r[t]:`option_${t+1}`,value:e}));return{options:a,criteria:Object.fromEntries(e.map(({description:e},t)=>[a[t].key,i?$t(e)?e:null:tn(r[t],e)]))}},on=e=>{if(!Qt(e))throw new R(null,`Request body must be an object`);let{model:t,input:n,questions:r}=e;if(!$t(t))throw new R(`model`,"`model` is required");let{state:i,images:a}=rn(n);if(!Array.isArray(r)||r.length===0)throw new R(`questions`,"`questions` must be a non-empty array");let o=new Set,s=[],c={};return r.forEach((e,t)=>{let n=`questions[${t}]`;if(!Qt(e))throw new R(n,`A question must be an object`);let{type:r,instructions:i}=e;if(!$t(i))throw new R(`${n}.instructions`,"`instructions` is required");let a=null;if(e.name!=null){if(typeof e.name!=`string`)throw new R(`${n}.name`,"`name` must be a string");if(o.has(e.name))throw new R(`${n}.name`,`Duplicate question name "${e.name}"`);o.add(e.name),{name:a}=e}let l=`q${t}`;if(r===`predicate`)s.push({id:l,name:a,type:r}),c[l]={type:`noul`,instructions:i};else if(r===`choice`){let{choices:t}=e;if(!Array.isArray(t)||t.length<2||t.length>255)throw new R(`${n}.choices`,`Provide between 2 and 255 choices`);let{options:o,criteria:u}=an(t,`${n}.choices`);s.push({id:l,name:a,type:r,options:o}),c[l]={type:`choice`,instructions:i,criteria:u}}else if(r===`score`){let{levels:t}=e;if(!Array.isArray(t)||t.length<2||t.length>10)throw new R(`${n}.levels`,`Provide between 2 and 10 levels`);t.forEach((e,t)=>{if(!$t(e?.label))throw new R(`${n}.levels[${t}].label`,"A level needs a `label`")}),s.push({id:l,name:a,type:r,labels:t.map(e=>e.label)}),c[l]={type:`score`,instructions:i,criteria:t.map(e=>tn(e.label,e.description))}}else throw new R(`${n}.type`,"Question `type` must be `predicate`, `choice` or `score`")}),{model:t,request:{state:i,questions:c,...a?{images:a}:{}},plan:{questions:s}}},z=e=>Number.isFinite(e)?e:0,sn=(e,t,n)=>{let r=t.questions.map(t=>{let n=e.answers?.[t.id]||{},{name:r}=t;if(t.type===`predicate`)return{type:`predicate`,name:r,probability:z(n.noul)};let i=n.probabilities||{};if(t.type===`choice`){let e=t.options.find(e=>e.key===n.choice);return{type:`choice`,name:r,choice:e?e.value:n.choice,probabilities:t.options.map(({key:e,value:t})=>({value:t,probability:z(i[e])})),confidence:z(n.confidence)}}return{type:`score`,name:r,score:z(n.score),probabilities:t.labels.map((e,t)=>({value:t,label:e,probability:z(i[String(t)])})),confidence:z(n.confidence)}}),i=z(e.usage?.input_tokens),a=z(e.usage?.output_tokens);return{model:n,answers:r,usage:{input_tokens:i,input_tokens_details:{cached_tokens:0,cache_write_tokens:0},output_tokens:a,output_tokens_details:{reasoning_tokens:0},total_tokens:i+a}}},cn=()=>`chatcmpl-${Date.now()}-${Math.random().toString(36).slice(2,9)}`;async function ln(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 r=n.value;if(!r)break;let{event:u,data:d}=r;if(u===`token`)d.content!=null&&(a=d.content),d.reasoning_content!=null&&(o=d.reasoning_content);else if(u===`result`)d.content==null?d.text&&(a=d.text):a=d.content,d.reasoning_content!=null&&(o=d.reasoning_content),d.tool_calls?.length>0?(s=d.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=d.interrupted||Ut(d)?`length`:`stop`,l=Wt(d);else if(u===`error`)throw Error(d.message)}}finally{C(i)}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 un(e,t,n,r){let i=[];return e.forEach((e,a)=>{let o={index:a};n.has(a)||(n.set(a,e.id||`call_${t}_${a}`),o.id=n.get(a),o.type=`function`);let s=e.function?.arguments||``,c=r.get(a)||``,l={};!r.has(a)&&e.function?.name&&(l.name=e.function.name),s.length>c.length&&(l.arguments=s.slice(c.length),r.set(a,s)),Object.keys(l).length>0?(o.function=l,i.push(o)):o.id&&(o.function={name:e.function?.name||``,arguments:``},i.push(o))}),i}async function*dn(e,t,n,r,i){let a=e.getReader(),o=``,s=``,c=new Map,l=new Map;try{let e=!1;for(;!e;){let u=await a.read();if({done:e}=u,e)break;let d=u.value;if(!d)break;let{event:f,data:p}=d;if(f===`token`){let e={};if(p.content!=null){let t=p.content;t.length>o.length&&(e.content=t.slice(o.length),o=t)}if(p.reasoning_content!=null){let t=p.reasoning_content;t.length>s.length&&(e.reasoning_content=t.slice(s.length),s=t)}if(p.tool_calls?.length>0){let n=un(p.tool_calls,t,l,c);n.length>0&&(e.tool_calls=n)}Object.keys(e).length>0&&(yield E({data:JSON.stringify({id:t,object:`chat.completion.chunk`,created:n,model:r,choices:[{index:0,delta:e,finish_reason:null}]})}))}else if(f===`result`){if(p.tool_calls?.length>0){let e=un(p.tool_calls,t,l,c);e.length>0&&(yield E({data:JSON.stringify({id:t,object:`chat.completion.chunk`,created:n,model:r,choices:[{index:0,delta:{tool_calls:e},finish_reason:null}]})}))}let e=`stop`;p.tool_calls?.length>0||l.size>0?e=`tool_calls`:(p.interrupted||Ut(p))&&(e=`length`);let a={id:t,object:`chat.completion.chunk`,created:n,model:r,choices:[{index:0,delta:{},finish_reason:e}]};i&&(a.usage=Wt(p)),yield E({data:JSON.stringify(a)})}else f===`error`&&(yield E({data:JSON.stringify({error:{message:p.message,type:`server_error`}})}))}yield E({data:`[DONE]`})}finally{C(a)}}const fn=e=>{let t=e?.model||{};return e.type===`ggml-llm`?!!t.enable_mtmd:Gt(e)?!!(t.mmproj_repo_id||t.mmproj_filename||t.mmproj_url||t.mmproj_local_path):!1},pn=(e,t)=>{if(fn(t))return!0;let n=Mt(e,t);return n!=null&&fn(n)},mn=e=>{let t=new Map;for(let n of e){let e=Ft.includes(n?.type);if(!e&&!Gt(n))continue;let r=p(n),i=t.get(r)||{image:!1,text:!1,decisions:!1};i.image||=fn(n),e?i.text=!0:i.decisions=!0,t.set(r,i)}let n=Array.from(t).sort(([,e],[,t])=>Number(t.text)-Number(e.text));return new Map(n.map(([e,{image:t,text:n,decisions:r}])=>[e,{input_modalities:t?[`text`,`image`]:[`text`],output_modalities:[...n?[`text`]:[],...r?[`decisions`]:[]]}]))};function hn(){let e=I({prefix:`/oai-compat`});return e.onBeforeHandle(st),e.get(`/v1/models`,({store:e})=>{let{config:t}=e,n=Array.from(mn(t.generators||[]),([e,t])=>({id:e,object:`model`,created:Math.floor(Date.now()/1e3),owned_by:`local`,architecture:t}));return n.length===0&&n.push({id:`ggml-llm`,object:`model`,created:Math.floor(Date.now()/1e3),owned_by:`local`,architecture:{input_modalities:[`text`],output_modalities:[`text`]}}),{object:`list`,data:n}}),e.post(`/v1/chat/completions`,async function*({body:e,set:t,store:n}){let{config:r,backend:i}=n,{messages:a=[],stream:o=!1,model:s,tools:c,temperature:l,stop:u,top_p:d,max_tokens:f,presence_penalty:p,frequency_penalty:m,tool_choice:h,stream_options:g,enable_thinking:_}=e;if(!a||a.length===0)return t.status=400,{error:{message:`messages is required and must not be empty`,type:`invalid_request_error`}};let v=null;try{v=await Vt(i,r,s,`[OpenAI]`);let e=cn(),t=Math.floor(Date.now()/1e3),n=v.repoId||`ggml-llm`,y={...Lt,messages:a};l!=null&&(y.temperature=l),d!=null&&(y.top_p=d),f!=null&&(y.n_predict=f),u!=null&&(y.stop=Array.isArray(u)?u:[u]),p!=null&&(y.presence_penalty=p),m!=null&&(y.frequency_penalty=m),c!=null&&(y.tools=c),h!=null&&(y.tool_choice=h),y.enable_thinking=_??!1;let b=await Rt(i,v.type).completion(v.id,{options:y});if(!o)return await ln(b,e,t,n);yield*dn(b,e,t,n,g?.include_usage===!0)}catch(e){return console.error(`[OpenAI] Chat completion error:`,e),t.status=500,{error:{message:e.message||`Internal server error`,type:`server_error`}}}finally{await Bt(i,v,`[OpenAI]`)}},{body:D.Object({model:D.Optional(D.String()),messages:D.Array(D.Any()),stream:D.Optional(D.Boolean()),temperature:D.Optional(D.Number()),top_p:D.Optional(D.Number()),max_tokens:D.Optional(D.Number()),stop:D.Optional(D.Union([D.String(),D.Array(D.String())])),presence_penalty:D.Optional(D.Number()),frequency_penalty:D.Optional(D.Number()),tools:D.Optional(D.Array(D.Any())),tool_choice:D.Optional(D.Any()),stream_options:D.Optional(D.Object({include_usage:D.Optional(D.Boolean())})),enable_thinking:D.Optional(D.Boolean())})}),e.post(`/v1/decisions`,async({body:e,set:t,store:n})=>{let{config:r,backend:i}=n,a=(e,n,r,i=null)=>(t.status=e,{error:{message:r,type:`invalid_request_error`,param:n,code:i}}),o;try{o=on(e)}catch(e){if(e instanceof R)return a(400,e.param,e.message);throw e}let s=(r.generators||[]).filter(Gt),c=s.map(p),{model:l}=o;if(!c.includes(l))return a(404,`model`,`The decision model "${l}" does not exist. Available: ${c.join(`, `)||`(none)`}`,`model_not_found`);let u=s[c.indexOf(l)];if(o.request.images&&!pn(r,u))return a(400,`input`,`The decision model "${l}" takes no images or audio: it has no projector (mmproj) configured`);try{return sn(await Xt(i,r,{model:l,...o.request},`[OpenAI]`),o.plan,l)}catch(e){return console.error(`[OpenAI] Decision failed:`,e?.message||e),t.status=500,{error:{message:e?.message||`Decision failed`,type:`server_error`}}}}),e}const gn=()=>`msg_${Date.now()}${Math.random().toString(36).slice(2,11)}`;function _n(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 vn(e,t){return t?`tool_use`:e.stopping_word||e.stoppingWord?`stop_sequence`:e.interrupted||e.truncated||Ut(e)?`max_tokens`:`end_turn`}function yn(e){let{promptTokens:t,cachedTokens:n,completionTokens:r}=Ht(e);return{cache_read_input_tokens:n,input_tokens:t,output_tokens:r}}async function bn(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 n=t.value;if(!n)break;let{event:u,data:d}=n;if(u===`token`)d.content!=null&&(i=d.content),d.reasoning_content!=null&&(a=d.reasoning_content);else if(u===`result`)d.content==null?d.text&&d.reasoning_content==null&&(i=d.text):i=d.content,d.reasoning_content!=null&&(a=d.reasoning_content),Array.isArray(d.tool_calls)&&(o=d.tool_calls),s=yn(d),l=d.stopping_word||d.stoppingWord||null,c=vn(d,o.length>0);else if(u===`error`)throw Error(d.message||`completion error`)}}finally{C(r)}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}}async function*xn(e,t,n){let r=e.getReader(),i=``,a=``,o=new Map,s=new Map,c=new Map,l=new Set,u=!1,d=!1,f=0,p=-1,m=-1,h=new Map,g={cache_read_input_tokens:0,input_tokens:0,output_tokens:0},_=`end_turn`,v=null,y=!1;function*b(e){for(let n=0;n<e.length;n+=1){let r=e[n],i=r?.function?.arguments||``,a=o.get(n)||``;if(!l.has(n)){let e=r?.id||`toolu_${t}_${n}`,i=r?.function?.name||c.get(n)||``;s.set(n,e),c.set(n,i),h.set(n,f),l.add(n),yield E({event:`content_block_start`,data:JSON.stringify({type:`content_block_start`,index:f,content_block:{type:`tool_use`,id:e,name:i,input:{}}})}),f+=1}let u=h.get(n);i.length>a.length&&(yield E({event:`content_block_delta`,data:JSON.stringify({type:`content_block_delta`,index:u,delta:{type:`input_json_delta`,partial_json:i.slice(a.length)}})}),o.set(n,i))}}try{let e=!1;for(;!e;){let o=await r.read();if({done:e}=o,e)break;let s=o.value;if(!s)break;let{event:c,data:h}=s;if(c===`token`){if(!y){let e=yn(h);yield E({event:`message_start`,data:JSON.stringify({type:`message_start`,message:{id:t,type:`message`,role:`assistant`,content:[],model:n,stop_reason:null,stop_sequence:null,usage:e}})}),y=!0}if(h.reasoning_content!=null){let e=h.reasoning_content;e.length>a.length&&(u||(p=f,f+=1,u=!0,yield E({event:`content_block_start`,data:JSON.stringify({type:`content_block_start`,index:p,content_block:{type:`thinking`,thinking:``}})})),yield E({event:`content_block_delta`,data:JSON.stringify({type:`content_block_delta`,index:p,delta:{type:`thinking_delta`,thinking:e.slice(a.length)}})}),a=e)}if(h.content!=null){let e=h.content;e.length>i.length&&(d||(m=f,f+=1,d=!0,yield E({event:`content_block_start`,data:JSON.stringify({type:`content_block_start`,index:m,content_block:{type:`text`,text:``}})})),yield E({event:`content_block_delta`,data:JSON.stringify({type:`content_block_delta`,index:m,delta:{type:`text_delta`,text:e.slice(i.length)}})}),i=e)}Array.isArray(h.tool_calls)&&h.tool_calls.length>0&&(yield*b(h.tool_calls))}else if(c===`result`){if(!y){let e=yn(h);yield E({event:`message_start`,data:JSON.stringify({type:`message_start`,message:{id:t,type:`message`,role:`assistant`,content:[],model:n,stop_reason:null,stop_sequence:null,usage:e}})}),y=!0}Array.isArray(h.tool_calls)&&h.tool_calls.length>0&&(yield*b(h.tool_calls)),g=yn(h),v=h.stopping_word||h.stoppingWord||null,_=vn(h,l.size>0)}else if(c===`error`){yield E({event:`error`,data:JSON.stringify({type:`error`,error:{type:`api_error`,message:h.message||`completion error`}})});return}}u&&(yield E({event:`content_block_delta`,data:JSON.stringify({type:`content_block_delta`,index:p,delta:{type:`signature_delta`,signature:``}})}),yield E({event:`content_block_stop`,data:JSON.stringify({type:`content_block_stop`,index:p})})),d&&(yield E({event:`content_block_stop`,data:JSON.stringify({type:`content_block_stop`,index:m})}));for(let e of[...l].sort((e,t)=>e-t))yield E({event:`content_block_stop`,data:JSON.stringify({type:`content_block_stop`,index:h.get(e)})});yield E({event:`message_delta`,data:JSON.stringify({type:`message_delta`,delta:{stop_reason:_,stop_sequence:v},usage:{input_tokens:g.input_tokens,cache_read_input_tokens:g.cache_read_input_tokens,output_tokens:g.output_tokens}})}),yield E({event:`message_stop`,data:JSON.stringify({type:`message_stop`})})}finally{C(r)}}function Sn(){let e=I({prefix:`/anthropic-messages`});return e.onBeforeHandle(st),e.post(`/v1/messages`,async function*({body:e,set:t,store:n}){let{config:r,backend:i}=n,a=e,o=null;try{if(!Array.isArray(a.messages)||a.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=_n(a);o=await Vt(i,r,a.model,`[Anthropic]`);let n=gn(),s=o.repoId||`ggml-llm`,c={...Lt,messages:e.messages};e.temperature!=null&&(c.temperature=e.temperature),e.top_p!=null&&(c.top_p=e.top_p),e.top_k!=null&&(c.top_k=e.top_k),e.max_tokens!=null&&(c.n_predict=e.max_tokens),e.stop!=null&&(c.stop=e.stop),e.tools!=null&&(c.tools=e.tools),e.tool_choice!=null&&(c.tool_choice=e.tool_choice),c.enable_thinking=e.enable_thinking??!1,e.thinking_budget_tokens!=null&&(c.thinking_budget_tokens=e.thinking_budget_tokens);let l=await Rt(i,o.type).completion(o.id,{options:c});if(!a.stream)return await bn(l,n,s);yield*xn(l,n,s)}catch(e){return console.error(`[Anthropic] Messages error:`,e),t.status=500,{type:`error`,error:{type:`api_error`,message:e?.message||`Internal server error`}}}finally{await Bt(i,o,`[Anthropic]`)}},{body:D.Object({model:D.Optional(D.String()),messages:D.Array(D.Any()),system:D.Optional(D.Any()),max_tokens:D.Optional(D.Number()),stream:D.Optional(D.Boolean()),temperature:D.Optional(D.Number()),top_p:D.Optional(D.Number()),top_k:D.Optional(D.Number()),stop_sequences:D.Optional(D.Union([D.String(),D.Array(D.String())])),tools:D.Optional(D.Array(D.Any())),tool_choice:D.Optional(D.Any()),thinking:D.Optional(D.Any()),metadata:D.Optional(D.Any())})}),e.post(`/v1/messages/count_tokens`,async({body:e,set:t,store:n})=>{let{config:r,backend:i}=n,a=e,o=null;try{let e=_n(a);o=await Vt(i,r,a.model,`[Anthropic]`);let t=Rt(i,o.type),n={messages:e.messages,add_generation_prompt:!0,jinja:!0};e.tools!=null&&(n.tools=e.tools);let s=await t.applyChatTemplate(o.id,n),c=typeof s==`string`?s:s?.prompt||``,l=await t.tokenize(o.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`}}}finally{await Bt(i,o,`[Anthropic]`)}},{body:D.Object({model:D.Optional(D.String()),messages:D.Array(D.Any()),system:D.Optional(D.Any()),tools:D.Optional(D.Array(D.Any())),tool_choice:D.Optional(D.Any())})}),e.get(`/v1/models`,({store:e})=>{let{config:t}=e,n=(t.generators||[]).filter(e=>Ft.includes(e.type)).map(e=>{let t=p(e);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}}),e}const Cn=[`choice`,`score`,`noul`],B=(e,t)=>({loc:[`body`,...e],msg:t,type:`value_error`}),wn=e=>typeof e==`object`&&!!e&&!Array.isArray(e),Tn=e=>{if(!wn(e))return[B([],`Request body must be a JSON object`)];let t=[],{state:n,questions:r}=e,i=[],a=0;for(let t of[`images`,`files`]){let n=e[t];n!==void 0&&(!Array.isArray(n)||n.some(e=>typeof e!=`string`||!e.startsWith(`data:`))?i.push(B([t],`\`${t}\` must be an array of data URLs`)):a+=n.length)}if((n==null||n===``?a===0:![`string`,`object`].includes(typeof n))&&t.push(B([`state`],"`state` must be a non-empty string, object or array, or null with media")),!wn(r)||Object.keys(r).length===0)t.push(B([`questions`],"`questions` must be a non-empty object"));else for(let[e,n]of Object.entries(r)){let r=[`questions`,e];if(!wn(n)||!Cn.includes(n.type)){t.push(B([...r,`type`],`Question type must be one of ${Cn}`));continue}let{type:i,criteria:a}=n;if(i===`choice`){let e=wn(a)?Object.keys(a).length:0;(e===0||e>255)&&t.push(B([...r,`criteria`],`A choice needs 1 to 255 options in an object`))}else i===`score`?(!Array.isArray(a)||a.length<2||a.length>10)&&t.push(B([...r,`criteria`],`A score needs an ordered array of 2 to 10 levels`)):a!=null&&!wn(a)&&t.push(B([...r,`criteria`],`Noul criteria must be { true?, false?, yes?, no? }`))}return[...t,...i]},En=e=>[...new Set((e.generators||[]).filter(Gt).map(p))];function Dn(){let e=I({prefix:`/typesafe-compat`});return e.onBeforeHandle(({set:e})=>{e.headers[`x-typesafe-request-id`]=j()}),e.onBeforeHandle(st),e.get(`/v1/models`,({store:e})=>({models:En(e.config).map(e=>({name:e,description:`Buttress decision generator`,release_date:``}))})),e.post(`/v1/systemone`,async({body:e,set:t,store:n})=>{let{config:r,backend:i}=n,a=Tn(e),o=En(r),s=e,c=s?.model,l=o.includes(c)?c:void 0;if(a.length===0&&!l){let e=o.join(`, `)||`(none)`;a.push(B([`model`],typeof c==`string`?`Unknown decision model "${c}". Available: ${e}`:`\`model\` is required. Available: ${e}`))}if(a.length>0)return t.status=422,{detail:a};let{state:u,questions:d,images:f,files:p}=s;try{return{...await Xt(i,r,{model:l,state:u??null,questions:d,...f?.length?{images:f}:{},...p?.length?{files:p}:{}},`[TypeSafe]`),model:l}}catch(e){return console.error(`[TypeSafe] Decision failed:`,e?.message||e),t.status=500,{error:{message:e?.message||`Decision failed`}}}}),e}const On=[`.ts`,`.mts`,`.js`,`.mjs`],kn=/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/,An=new Set([`mcp`,`files`,`upload`]),jn=new Set([`cross-site`,`same-site`]),Mn=e=>jn.has(String(e[`sec-fetch-site`]||``).toLowerCase()),Nn=(e,t)=>t?t===`*`?!0:e?(Array.isArray(t)?t:[t]).includes(e):!1:!1,Pn=e=>{let t=/^\/functions\/([^/]+)\/?$/.exec(e);if(!t)return;let n;try{n=decodeURIComponent(t[1])}catch{return}return An.has(n)?void 0:n},Fn=(e,t)=>({error:{code:e,message:t}}),In=({allowUnauthenticated:e,allowedOrigins:t,getCustomAuth:n})=>(async({headers:r,query:i,set:a,store:o,request:s,path:c})=>{let l=(c||(s?new URL(s.url).pathname:``)).split(`?`)[0],u=s?.method||`GET`,d=(e,t,n)=>{L.recordAuth({method:u,path:l,outcome:e,mode:t,subject:n})},f=r.origin||r.Origin;if((f||Mn(r))&&!Nn(f,t))return d(`FUNCTIONS_ORIGIN_BLOCKED`),a.status=403,Fn(`FUNCTIONS_ORIGIN_BLOCKED`,`Cross-site browser requests${f?` from origin "${f}"`:``} are not allowed. Add the origin to [functions] cors_allowed_origins to permit browser access.`);let p=null;if(n)try{p=await n()}catch{return d(`FUNCTIONS_AUTH_UNAVAILABLE`),a.status=500,Fn(`FUNCTIONS_AUTH_UNAVAILABLE`,`The custom auth function (_auth) failed to load; calls are rejected until it is fixed.`)}let m=o.workspaceState?.workspace??null,h=at(r,i),g=null;if(!p||p.mode===`both`){let t=p?`both`:`workspace`;if(!m){if(!e)return d(`FUNCTIONS_UNAUTHENTICATED_DISABLED`,t),a.status=403,Fn(`FUNCTIONS_UNAUTHENTICATED_DISABLED`,"Local functions require a workspace binding. Run `bricks buttress bind`, or set [functions] allow_unauthenticated = true to run them unauthenticated.")}else if(g=await ot(h,m),!g)return d(`UNAUTHORIZED`,t),a.status=401,a.headers&&(a.headers[`WWW-Authenticate`]=`Bearer`),Fn(`UNAUTHORIZED`,`Invalid or missing workspace access token`);if(!p){d(`allowed`,`workspace`,g?.subjectId);return}}else g=m?await ot(h,m):null;let _={method:u,path:l,name:Pn(l),headers:r,query:i,token:h,workspaceAuth:{bound:!!m,authenticated:!!g,identity:g}},v;try{v=await p.run(_)}catch(e){return console.warn(`[Functions] custom auth function threw:`,e?.message||e),d(`FUNCTIONS_AUTH_ERROR`,p.mode,g?.subjectId),a.status=500,Fn(`FUNCTIONS_AUTH_ERROR`,`The custom auth function failed`)}let y=typeof v==`object`&&v?v:null;if(v===!0||y?.ok===!0){d(`allowed`,p.mode,g?.subjectId);return}d(`FUNCTIONS_AUTH_REJECTED`,p.mode,g?.subjectId);let b=typeof y?.status==`number`&&y.status>=400&&y.status<=499?y.status:403;return a.status=b,b===401&&a.headers&&(a.headers[`WWW-Authenticate`]=`Bearer`),Fn(`FUNCTIONS_AUTH_REJECTED`,typeof y?.error==`string`&&y.error||`Rejected by the custom auth function`)}),Ln=new Set([`.ts`,`.mts`,`.cts`]),Rn=(e,t)=>{let n=t.map(e=>e.codeframe||e.message||String(e)).join(`
5
5
  `);return`Failed to parse ${M.basename(e)}:\n${n}`},zn=(e,t)=>{let n=t;if(Ln.has(M.extname(e))){let r=Se(e,t,{sourceType:`module`});if(r.errors?.length)throw SyntaxError(Rn(e,r.errors));n=r.code}let r=xe(e,n);if(r.errors?.length)throw SyntaxError(Rn(e,r.errors));return{code:r.code,deps:r.deps||[],dynamicDeps:r.dynamicDeps||[]}},Bn=Function(`specifier`,`return import(specifier)`),Vn=new Set(ee),Hn={sqlite3:()=>import(`sqlite3`),"sqlite-vec":()=>import(`sqlite-vec`)};var Un=class extends Error{constructor(e){super(e),this.name=`FunctionImportError`}};const Wn=(e={})=>({console,setTimeout,clearTimeout,setInterval,clearInterval,setImmediate,clearImmediate,queueMicrotask,URL,URLSearchParams,TextEncoder,TextDecoder,AbortController,AbortSignal,Buffer,structuredClone,performance,crypto:globalThis.crypto,fetch:globalThis.fetch,atob:globalThis.atob,btoa:globalThis.btoa,Event:globalThis.Event,EventTarget:globalThis.EventTarget,...e}),Gn=async e=>{try{return(await O.stat(e)).isFile()}catch{return!1}},Kn=e=>{let t=M.extname(e);if(!t)return[...On.map(t=>`${e}${t}`),...On.map(t=>M.join(e,`index${t}`))];let n=[e];return t===`.js`&&n.push(`${e.slice(0,-3)}.ts`),t===`.mjs`&&n.push(`${e.slice(0,-4)}.mts`),n},qn=async(e,t,n)=>{if(e.startsWith(`node:`)){let n=e.slice(5);if(!Vn.has(n))throw new Un(`Cannot import "${e}" from ${M.basename(t)}: unknown Node builtin.`);return{kind:`builtin`,id:e}}if(Vn.has(e))return{kind:`builtin`,id:`node:${e}`};if(Object.prototype.hasOwnProperty.call(Hn,e))return{kind:`package`,id:e};if(!(e.startsWith(`./`)||e.startsWith(`../`))&&!M.isAbsolute(e))throw new Un(`Cannot import "${e}" from ${M.basename(t)}: local functions may only import Node builtins (e.g. "node:fs/promises"), "sqlite3", "sqlite-vec", and sibling files in the functions directory. Other package imports are not supported.`);let r=M.resolve(M.dirname(t),e),i=M.relative(n,r);if(i.startsWith(`..`)||M.isAbsolute(i))throw new Un(`Cannot import "${e}" from ${M.basename(t)}: path escapes the functions directory.`);for(let e of Kn(r))if(await Gn(e))return{kind:`file`,path:e};throw new Un(`Cannot import "${e}" from ${M.basename(t)}: file not found.`)},Jn=async(e,{rootDir:t,globals:n={}})=>{let r=be.createContext(Wn(n)),i=new Map,a=new Map,o=new Map,s=e=>{let t=i.get(e);if(t)return Promise.resolve(t);let n=a.get(e);if(n)return n;let r=c(e).finally(()=>{a.delete(e)});return a.set(e,r),r},c=async e=>{let[n,a]=await Promise.all([O.readFile(e,`utf8`),O.stat(e)]);o.set(e,a.mtimeMs);let{code:c}=zn(e,n),l={};i.set(e,l);let u=be.runInContext(`(async function (__vite_ssr_exports__, __vite_ssr_import__, __vite_ssr_dynamic_import__, __vite_ssr_exportAll__, __vite_ssr_import_meta__) {
@@ -627,7 +627,7 @@ export default async function (context: ButtressDaemonContext) {
627
627
  `).slice(1)){if(!e.trim())continue;let t;try{t=JSON.parse(e)}catch{continue}n.push(...Array.isArray(t)?t:[t])}return n},Ro=e=>{let t=new Map,n=null;for(let r of e)r?.kind===`entry`&&typeof r.id==`string`?t.set(r.id,r):r?.kind===`value`&&r.namespace===`pi.branch.tip`&&r.key===`main`&&(!n||r.seq>n.seq)&&(n={seq:r.seq,id:r.value??null});let r=[],i=new Set;for(let e=n?.id??null;e!=null&&!i.has(e);){i.add(e);let n=t.get(e);if(!n)break;n.type===`message`&&r.push(n.message),e=n.parentId}return r.reverse()},zo=async e=>{let t=await Lo(e.path);return e.legacy?Ro(t):t.filter(e=>e?.kind===`message`).map(e=>e.message)},Bo=e=>`${JSON.stringify({kind:`message`,message:e})}\n`,Vo=async(e,t)=>{let n={kind:`header`,format:No,v:1,id:e.id,createdAt:e.createdAt,...e.parentSessionId?{parentSessionId:e.parentSessionId}:{}},r=`${e.path}.${He()}.tmp`;try{await O.writeFile(r,JSON.stringify(n)+`
628
628
  `+t.map(Bo).join(``)),await O.rename(r,e.path)}catch(e){throw await O.rm(r,{force:!0}),e}},Ho=e=>({sessionId:e.id,createdAt:new Date(e.createdAt).toISOString(),updatedAt:new Date(e.modifiedAt).toISOString(),parentSession:e.parentSessionId??null,preview:Fo(e.path)}),Uo=e=>{P.mkdirSync(e.sessionsDir,{recursive:!0});let t=t=>{let n=M.resolve(e.sessionsDir,`/agents/${t}`);return M.join(e.sessionsDir,`--${n.replace(/^[/\\]/,``).replace(/[/\\:]/g,`-`)}--`)},n=async e=>{let n=t(e);try{return(await O.readdir(n)).filter(e=>e.endsWith(`.jsonl`)).map(e=>M.join(n,e))}catch(e){if(e?.code===`ENOENT`)return[];throw e}},r=async e=>(await n(e)).map(Io).filter(e=>e!==null),i=async(e,t)=>{let r=`_${encodeURIComponent(t)}.jsonl`,i=(await n(e)).find(e=>e.endsWith(r)),a=i?Io(i):null;if(!a||a.id!==t)throw Error(`[Agents] unknown session "${t}" for agent "${e}"`);return a},a=async(e,n,r)=>{let i=He(),a=Date.now(),o=t(e);await O.mkdir(o,{recursive:!0});let s=new Date(a).toISOString().replace(/[:.]/g,`-`),c={id:i,createdAt:a,...r?{parentSessionId:r}:{},path:M.join(o,`${s}_${encodeURIComponent(i)}.jsonl`)};return await Vo(c,n),{metadata:{...c,modifiedAt:a,legacy:!1},appendable:!0}},o=async e=>{if(e.appendable)return;let{metadata:t}=e;if(t.legacy)await Vo(t,await zo(t)),t.legacy=!1;else{let e=await O.readFile(t.path,`utf8`);e.endsWith(`
629
629
  `)||await O.truncate(t.path,Buffer.byteLength(e.slice(0,e.lastIndexOf(`
630
- `)+1)))}e.appendable=!0};return{create:e=>a(e,[]),open:async(e,t)=>({metadata:await i(e,t),appendable:!1}),fork:async(e,t)=>{let n=await i(e,t);return a(e,await zo(n),n.id)},append:async(e,t)=>{await o(e),await O.appendFile(e.metadata.path,Bo(t))},list:async(e,t=50)=>(await r(e)).sort((e,t)=>t.modifiedAt-e.modifiedAt).slice(0,t).map(Ho),messages:async e=>(await zo(e.metadata)).filter(e=>!(e.role===`assistant`&&[`error`,`aborted`,`deferred`].includes(e.stopReason))),sweep:async t=>{let n=0,i=Date.now();for(let a of t){let t;try{t=await r(a)}catch{continue}t.sort((e,t)=>t.modifiedAt-e.modifiedAt);for(let[r,a]of t.entries()){let t=e.sessionMaxCount!=null&&r>=e.sessionMaxCount,o=e.sessionMaxAgeMs!=null&&i-a.modifiedAt>e.sessionMaxAgeMs;if(!(!t&&!o))try{await O.rm(a.path),n+=1}catch(e){console.warn(`[Agents] retention: failed to delete session ${a.id}:`,e?.message||e)}}}return n}}},Wo=256*1024,Go=e=>e.length<=Wo?e:`${e.slice(0,Wo)}\n… [truncated ${e.length-Wo} characters]`,Ko=()=>import(`./mcp-DzknURyz.mjs`),qo=e=>({...e.url?{url:e.url,headers:e.headers}:{},...e.command?{command:e.command,args:e.args,env:e.env}:{},...e.timeout==null?{}:{timeout:e.timeout},...e.exposure?{exposure:e.exposure}:{},...e.toolExposure?{toolExposure:e.toolExposure}:{}}),Jo=({configDir:e})=>{let t=new Map,n=async(t,n)=>{let r=await Ko(),i=r.validateMcpServerConfig(t,qo(n));if(typeof i==`string`)throw Error(i);return r.connectMcpServer({name:t,config:i,cwd:e,clientName:`buttress-agent`})};return{toolsFor:async(e,r)=>{let i=[];for(let[a,o]of Object.entries(r)){let r=`${e} ${a}`,s=t.get(r);s||(s=n(a,o),t.set(r,s),s.catch(()=>t.delete(r)));try{i.push(await s)}catch(t){let n=`MCP server "${a}" failed to connect: ${t?.message||t}`;if(o.optional){console.warn(`[Agents] ${e}: ${n} (optional — continuing without it)`);continue}throw Error(`[Agents] ${e}: ${n}`)}}let{createMcpAgentTools:a}=await Ko();return a(i,{defaultExposure:`direct`,limitText:Go})},dispose:async()=>{let e=[...t.values()];t.clear(),await Promise.all(e.map(async e=>{try{await(await e).close()}catch{}}))}}},Yo=()=>import(`./codemode-CRowB9aL.mjs`);function Xo(){let e=process.env.BUTTRESS_CODEMODE_WORKER;if(e)return{workerUrl:e,wasmPath:process.env.BUTTRESS_CODEMODE_WASM};let t=new URL(`./codemode-worker.mjs`,import.meta.url),n=new URL(`./quickjs.wasm`,import.meta.url);return t.protocol!==`file:`||!P.existsSync(de(t))?{}:{workerUrl:t,wasmPath:de(n)}}async function Zo({tools:e,declaredNames:t,getState:n,models:r}){let i=await Yo();return i.createCodemodeTool({getTools:()=>e,declaredNames:t,executeTool:(e,t,r)=>i.runNestedToolCall(e,t,{...r,state:n()}),getStore:()=>i.collectCodemodeStore(n()?.messages),models:i.createCodemodeModels({classifiers:async()=>r}),sandbox:{...Xo(),defaultTimeoutMs:i.DEFAULT_CODEMODE_TIMEOUT_MS,maxTimeoutMs:i.MAX_CODEMODE_TIMEOUT_MS}})}const Qo=async(e,{functions:t,runtime:n,depth:r,onToolEmit:i})=>{if(e.tools.length===0)return[];if(!t)throw Error(`[Agents] ${e.name}: tools are configured but local functions are disabled (set [functions] enabled = true)`);let a=await t.list(),o=new Map(a.map(e=>[e.name,e])),s=e.tools.filter(e=>!o.has(e));if(s.length>0)throw Error(`[Agents] ${e.name}: configured tool${s.length===1?``:`s`} not found in the functions directory: ${s.join(`, `)}`);return e.tools.map(e=>{let a=o.get(e);return{name:e,label:e,description:a.description||`Local function: ${e}`,parameters:a.parameters||{type:`object`,properties:{}},execute:async(a,o,s)=>{try{return{content:[{type:`text`,text:ii(await t.call(e,o??{},{runtime:n,signal:s,surface:`agent`,agentDepth:r,emit:(t,n)=>i?.(e,t,n,a)}))}],details:{}}}catch(e){return{content:[{type:`text`,text:`Tool error: ${e?.message||String(e)}`}],details:{}}}}}})};let $o=w(import.meta.url);var es,q,ts,ns,rs,is,as,os={84361(e){e.exports=import(`./wrapper-3PX6qE3t.mjs`).then(function(e){return e})},41314(e){e.exports=$o(`node:dgram`)},51455(e){e.exports=$o(`node:fs/promises`)},48161(e){e.exports=$o(`node:os`)},76760(e){e.exports=$o(`node:path`)},66442(e){e.exports=function(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r},e.exports.__esModule=!0,e.exports.default=e.exports},3634(e){e.exports=function(e){if(Array.isArray(e))return e},e.exports.__esModule=!0,e.exports.default=e.exports},99436(e){function t(e,t,n,r,i,a,o){try{var s=e[a](o),c=s.value}catch(e){n(e);return}s.done?t(c):Promise.resolve(c).then(r,i)}e.exports=function(e){return function(){var n=this,r=arguments;return new Promise(function(i,a){var o=e.apply(n,r);function s(e){t(o,i,a,s,c,`next`,e)}function c(e){t(o,i,a,s,c,`throw`,e)}s(void 0)})}},e.exports.__esModule=!0,e.exports.default=e.exports},96525(e){e.exports=function(e,t){var n=e==null?null:`u`>typeof Symbol&&e[Symbol.iterator]||e[`@@iterator`];if(n!=null){var r,i,a,o,s=[],c=!0,l=!1;try{if(a=(n=n.call(e)).next,t===0){if(Object(n)!==n)return;c=!1}else for(;!(c=(r=a.call(n)).done)&&(s.push(r.value),s.length!==t);c=!0);}catch(e){l=!0,i=e}finally{try{if(!c&&n.return!=null&&(o=n.return(),Object(o)!==o))return}finally{if(l)throw i}}return s}},e.exports.__esModule=!0,e.exports.default=e.exports},5523(e){e.exports=function(){throw TypeError(`Invalid attempt to destructure non-iterable instance.
630
+ `)+1)))}e.appendable=!0};return{create:e=>a(e,[]),open:async(e,t)=>({metadata:await i(e,t),appendable:!1}),fork:async(e,t)=>{let n=await i(e,t);return a(e,await zo(n),n.id)},append:async(e,t)=>{await o(e),await O.appendFile(e.metadata.path,Bo(t))},list:async(e,t=50)=>(await r(e)).sort((e,t)=>t.modifiedAt-e.modifiedAt).slice(0,t).map(Ho),messages:async e=>(await zo(e.metadata)).filter(e=>!(e.role===`assistant`&&[`error`,`aborted`,`deferred`].includes(e.stopReason))),sweep:async t=>{let n=0,i=Date.now();for(let a of t){let t;try{t=await r(a)}catch{continue}t.sort((e,t)=>t.modifiedAt-e.modifiedAt);for(let[r,a]of t.entries()){let t=e.sessionMaxCount!=null&&r>=e.sessionMaxCount,o=e.sessionMaxAgeMs!=null&&i-a.modifiedAt>e.sessionMaxAgeMs;if(!(!t&&!o))try{await O.rm(a.path),n+=1}catch(e){console.warn(`[Agents] retention: failed to delete session ${a.id}:`,e?.message||e)}}}return n}}},Wo=256*1024,Go=e=>e.length<=Wo?e:`${e.slice(0,Wo)}\n… [truncated ${e.length-Wo} characters]`,Ko=()=>import(`./mcp-DzknURyz.mjs`),qo=e=>({...e.url?{url:e.url,headers:e.headers}:{},...e.command?{command:e.command,args:e.args,env:e.env}:{},...e.timeout==null?{}:{timeout:e.timeout},...e.exposure?{exposure:e.exposure}:{},...e.toolExposure?{toolExposure:e.toolExposure}:{}}),Jo=({configDir:e})=>{let t=new Map,n=async(t,n)=>{let r=await Ko(),i=r.validateMcpServerConfig(t,qo(n));if(typeof i==`string`)throw Error(i);return r.connectMcpServer({name:t,config:i,cwd:e,clientName:`buttress-agent`})};return{toolsFor:async(e,r)=>{let i=[];for(let[a,o]of Object.entries(r)){let r=`${e} ${a}`,s=t.get(r);s||(s=n(a,o),t.set(r,s),s.catch(()=>t.delete(r)));try{i.push(await s)}catch(t){let n=`MCP server "${a}" failed to connect: ${t?.message||t}`;if(o.optional){console.warn(`[Agents] ${e}: ${n} (optional — continuing without it)`);continue}throw Error(`[Agents] ${e}: ${n}`)}}let{createMcpAgentTools:a}=await Ko();return a(i,{defaultExposure:`direct`,limitText:Go})},dispose:async()=>{let e=[...t.values()];t.clear(),await Promise.all(e.map(async e=>{try{await(await e).close()}catch{}}))}}},Yo=()=>import(`./codemode-C7j8OJ4D.mjs`);function Xo(){let e=process.env.BUTTRESS_CODEMODE_WORKER;if(e)return{workerUrl:e,wasmPath:process.env.BUTTRESS_CODEMODE_WASM};let t=new URL(`./codemode-worker.mjs`,import.meta.url),n=new URL(`./quickjs.wasm`,import.meta.url);return t.protocol!==`file:`||!P.existsSync(de(t))?{}:{workerUrl:t,wasmPath:de(n)}}async function Zo({tools:e,declaredNames:t,getState:n,models:r}){let i=await Yo();return i.createCodemodeTool({getTools:()=>e,declaredNames:t,executeTool:(e,t,r)=>i.runNestedToolCall(e,t,{...r,state:n()}),getStore:()=>i.collectCodemodeStore(n()?.messages),models:i.createCodemodeModels({classifiers:async()=>r}),sandbox:{...Xo(),defaultTimeoutMs:i.DEFAULT_CODEMODE_TIMEOUT_MS,maxTimeoutMs:i.MAX_CODEMODE_TIMEOUT_MS}})}const Qo=async(e,{functions:t,runtime:n,depth:r,onToolEmit:i})=>{if(e.tools.length===0)return[];if(!t)throw Error(`[Agents] ${e.name}: tools are configured but local functions are disabled (set [functions] enabled = true)`);let a=await t.list(),o=new Map(a.map(e=>[e.name,e])),s=e.tools.filter(e=>!o.has(e));if(s.length>0)throw Error(`[Agents] ${e.name}: configured tool${s.length===1?``:`s`} not found in the functions directory: ${s.join(`, `)}`);return e.tools.map(e=>{let a=o.get(e);return{name:e,label:e,description:a.description||`Local function: ${e}`,parameters:a.parameters||{type:`object`,properties:{}},execute:async(a,o,s)=>{try{return{content:[{type:`text`,text:ii(await t.call(e,o??{},{runtime:n,signal:s,surface:`agent`,agentDepth:r,emit:(t,n)=>i?.(e,t,n,a)}))}],details:{}}}catch(e){return{content:[{type:`text`,text:`Tool error: ${e?.message||String(e)}`}],details:{}}}}}})};let $o=w(import.meta.url);var es,q,ts,ns,rs,is,as,os={84361(e){e.exports=import(`./wrapper-3PX6qE3t.mjs`).then(function(e){return e})},41314(e){e.exports=$o(`node:dgram`)},51455(e){e.exports=$o(`node:fs/promises`)},48161(e){e.exports=$o(`node:os`)},76760(e){e.exports=$o(`node:path`)},66442(e){e.exports=function(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r},e.exports.__esModule=!0,e.exports.default=e.exports},3634(e){e.exports=function(e){if(Array.isArray(e))return e},e.exports.__esModule=!0,e.exports.default=e.exports},99436(e){function t(e,t,n,r,i,a,o){try{var s=e[a](o),c=s.value}catch(e){n(e);return}s.done?t(c):Promise.resolve(c).then(r,i)}e.exports=function(e){return function(){var n=this,r=arguments;return new Promise(function(i,a){var o=e.apply(n,r);function s(e){t(o,i,a,s,c,`next`,e)}function c(e){t(o,i,a,s,c,`throw`,e)}s(void 0)})}},e.exports.__esModule=!0,e.exports.default=e.exports},96525(e){e.exports=function(e,t){var n=e==null?null:`u`>typeof Symbol&&e[Symbol.iterator]||e[`@@iterator`];if(n!=null){var r,i,a,o,s=[],c=!0,l=!1;try{if(a=(n=n.call(e)).next,t===0){if(Object(n)!==n)return;c=!1}else for(;!(c=(r=a.call(n)).done)&&(s.push(r.value),s.length!==t);c=!0);}catch(e){l=!0,i=e}finally{try{if(!c&&n.return!=null&&(o=n.return(),Object(o)!==o))return}finally{if(l)throw i}}return s}},e.exports.__esModule=!0,e.exports.default=e.exports},5523(e){e.exports=function(){throw TypeError(`Invalid attempt to destructure non-iterable instance.
631
631
  In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)},e.exports.__esModule=!0,e.exports.default=e.exports},68832(e,t,n){var r=n(3634),i=n(96525),a=n(78243),o=n(5523);e.exports=function(e,t){return r(e)||i(e,t)||a(e,t)||o()},e.exports.__esModule=!0,e.exports.default=e.exports},78243(e,t,n){var r=n(66442);e.exports=function(e,t){if(e){if(typeof e==`string`)return r(e,t);var n={}.toString.call(e).slice(8,-1);return n===`Object`&&e.constructor&&(n=e.constructor.name),n===`Map`||n===`Set`?Array.from(e):n===`Arguments`||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?r(e,t):void 0}},e.exports.__esModule=!0,e.exports.default=e.exports},13346(e,t,n){n.a(e,async function(e,r){try{n.d(t,{TB:()=>o.verifyDevToolsServer,fl:()=>a.createCdpClient,le:()=>i.le});var i=n(38372),a=n(28193),o=n(75646),s=e([a]);a=(s.then?(await s)():s)[0],r()}catch(e){r(e)}})},28193(e,t,n){n.a(e,async function(e,r){try{n.d(t,{createCdpClient:()=>h});var i,a=n(99436),o=n(73610),s=n(72197),c=n(84361),l=n(19557),u=e([c]);c=(u.then?(await u)():u)[0];var d=15e3,f={[o.AB.takenOver]:`Another DevTools client took this device.`,[o.AB.targetGone]:`The device stopped its DevTools server (the app restarted or went to the background). Retry the command.`},p=({address:e,port:t,method:n,phase:r=`request`,closeCode:i,closeReason:a,local:o=!1})=>{var s=a?Buffer.isBuffer(a)?a.toString(`utf8`):String(a):``,c=r===`connect`?`before the CDP session opened`:n?`while waiting for ${n}`:`during the CDP session`,l=`${e}:${t}`,u=[];i!=null&&u.push(`code ${i}`),s&&u.push(`reason: ${s}`);var d=[o?`CDP client closed the connection to ${l} ${c}.`:`CDP connection to ${l} closed ${c}.`,u.length>0?`WebSocket close ${u.join(`, `)}.`:null,o?null:f[i]??`The DevTools server currently accepts one CDP client at a time. Another DevTools window or CLI command may have replaced this session. Retry the command, close the other inspector, or avoid running DevTools commands in parallel.`].filter(Boolean).join(`
632
632
  `),p=Error(d);return p.code=`CDP_CONNECTION_CLOSED`,p.method=n,p.phase=r,p.closeCode=i,p.closeReason=s,p},m=(i=a(function*(e,t,n){var r=n?typeof n==`string`?{passcode:n}:n:{},i=r.passcode,a=r.accessToken;if(a)return`ws://${e}:${t}/ws?access_token=${encodeURIComponent(a)}`;if(!i)try{var o=(yield(0,l.uE)(`http://${e}:${t}/json/list`))?.[0]?.webSocketDebuggerUrl;if(o){var s=o.match(/\/ws(?:\/.*)?$/);if(s)return`ws://${e}:${t}${s[0]}`}}catch{}return i?`ws://${e}:${t}/ws/${encodeURIComponent(i)}`:`ws://${e}:${t}/ws`}),function(e,t,n){return i.apply(this,arguments)}),h=(e,t,n)=>{var r,i,o=0,l=new Map,u=new Map,f=null,h=0,g=e=>{for(var t of l.values()){var n=t.reject,r=t.timer,i=t.method;clearTimeout(r),n(e(i))}l.clear()};return{connect:(r=a(function*(){var r=++h,a=yield m(e,t,n);if(r!==h)throw p({address:e,port:t,phase:`connect`,local:!0});return new Promise((n,r)=>{i=new c.WebSocket(a,{handshakeTimeout:d});var o=!1;i.once(`open`,()=>{o=!0,f=null,n()}),i.once(`error`,n=>{o||r(Error(n.message||`Cannot connect to ${e}:${t}`))}),i.on(`message`,e=>{try{var t=JSON.parse(e.toString());if(t.id!=null&&l.has(t.id)){var n=l.get(t.id),r=n.resolve,i=n.reject,a=n.timer,o=n.method;clearTimeout(a),l.delete(t.id),t.error?i((0,s.e)(t.error,o)):r(t.result);return}if(t.method){var c=u.get(t.method);if(c)for(var d of c)d(t.params)}}catch{}}),i.on(`close`,(n,i)=>{f={closeCode:n,closeReason:i},o||r(p({address:e,port:t,phase:`connect`,closeCode:n,closeReason:i})),g(r=>p({address:e,port:t,method:r,closeCode:n,closeReason:i}))})})}),function(){return r.apply(this,arguments)}),send:(n,r={},a=d)=>new Promise((s,c)=>{if(!i||i.readyState!==i.OPEN)return f?void c(p({address:e,port:t,method:n,closeCode:f.closeCode,closeReason:f.closeReason})):void c(Error(`Not connected to CDP at ${e}:${t} while sending ${n}`));var u=++o,d=setTimeout(()=>{l.delete(u),c(Error(`Timeout: ${n}`))},a);l.set(u,{resolve:s,reject:c,timer:d,method:n}),i.send(JSON.stringify({id:u,method:n,params:r}))}),on:(e,t)=>{u.has(e)||u.set(e,[]),u.get(e).push(t)},off:(e,t)=>{var n=u.get(e);if(n){var r=n.indexOf(t);r>=0&&n.splice(r,1)}},close:()=>{h++,g(n=>p({address:e,port:t,method:n,local:!0})),i&&=(i.terminate(),null)}}};r()}catch(e){r(e)}})},38372(e,t,n){n.d(t,{le:()=>m});var r,i,a,o=n(68832),s=n(99436),c=n(51455),l=n(76760),u=n(75646),d=n(19557),f=(r=s(function*(e,t,n=3e3){return(0,d.uE)(`http://${e}:${t}/json/list`,n)}),function(e,t){return r.apply(this,arguments)}),p=(i=s(function*(e,t=1e3){for(var n=[],r=e,i=0;i<10;i++){var a=l.join(r,`.bricks`,`devtools.json`);try{var o=yield c.readFile(a,`utf8`),s=JSON.parse(o),d=yield(0,u.verifyDevToolsServer)(s.address||`localhost`,s.port,t);d&&n.push({name:s.name||`BRICKS Simulator`,address:s.address||`localhost`,port:s.port,protocols:[`cdp`],hasPasscode:!1,source:`project`,projectPath:r,...d})}catch{}var f=l.dirname(r);if(f===r)break;r=f}return n}),function(e){return i.apply(this,arguments)}),m=(a=s(function*({timeout:e=3e3,verify:t=!1,udpOnly:n=!1,project:r=!0,port:i=19851,cwd:a=process.cwd(),onStatus:c}={}){var l,d=(0,u.discoverDevToolsServers)({timeout:e,idleTimeout:800}),m=n?Promise.resolve([]):(c?.(`Scanning via UDP + HTTP probe...`),(0,u.httpProbeSubnet)({port:i,timeout:e})),h=r?p(a,1e3):Promise.resolve([]),g=o(yield Promise.all([d,m,h]),3),_=(e=>{var t=new Map;for(var n of e){var r=n.deviceId||`${n.address}:${n.port}`,i=t.get(r);if(!i){t.set(r,{...n,addresses:[n.address],protocols:[...n.protocols||[]]});continue}for(var a of(i.addresses.includes(n.address)||i.addresses.push(n.address),i.address===`127.0.0.1`&&n.address!==`127.0.0.1`&&(i.address=n.address),n.protocols||[]))i.protocols.includes(a)||i.protocols.push(a);for(var s of Object.entries(n)){var c=o(s,2),l=c[0],u=c[1];u!=null&&l!==`address`&&l!==`addresses`&&l!==`protocols`&&(i[l]===void 0||i[l]===null)&&(i[l]=u)}}return[...t.values()]})([...g[0],...g[1],...g[2]]);if(_.length===0)return[];if(t){c?.(`Verifying ${_.length} server(s)...`);var v,y=yield Promise.all(_.map((v=s(function*(e){var t=yield(0,u.verifyDevToolsServer)(e.address,e.port);return{...e,...t||{},address:e.address,port:e.port,verified:!!t,version:t?.version||e.version}}),function(e){return v.apply(this,arguments)})));_.splice(0,_.length,...y)}return c?.(`Checking chrome://inspect support...`),yield Promise.all(_.map((l=s(function*(e){var t=yield f(e.address,e.port);if(t){e.chromeInspect=!0;var n=(e=>{if(!e)return null;var t=e.match(/\/ws\/(.+)$/);return t?decodeURIComponent(t[1]):null})(t[0]?.webSocketDebuggerUrl);n&&(e.passcode=n)}}),function(e){return l.apply(this,arguments)}))),_}),function(){return a.apply(this,arguments)})},75646(e,t,n){n.d(t,{discoverDevToolsServers:()=>c,httpProbeSubnet:()=>l,verifyDevToolsServer:()=>u});var r,i,a=n(99436),o=n(19557),s=`bricks-devtools`,c=({timeout:e=3e3,idleTimeout:t=0}={})=>(0,o.YH)({port:19900,timeout:e,idleTimeout:t,buildQuery:()=>Buffer.from(JSON.stringify({t:`QUERY`,v:`1.0`,s,d:{id:`cli-${(0,o.BW)()}`}})),parseMessage:(e,t)=>{var n=(0,o.nl)(e,e=>e?.s===s);if(!n)return null;var r=t.address;return{key:`${r}:${n.port}`,value:{...n,address:r}}}}),l=(r=a(function*({port:e=19851,connectTimeout:t=500,concurrency:n=50,timeout:r=0}={}){var i=(0,o.r9)();if(i.length===0)return[];var s=[],c=r>0?Date.now()+r:0,l=[],d=new Set;for(var f of i){var p=f.address.split(`.`).slice(0,3).join(`.`);if(!d.has(p)){d.add(p);for(var m=1;m<255;m++)l.push(`${p}.${m}`)}}for(var h=0;h<l.length&&!(c&&Date.now()>=c);h+=n){var g=l.slice(h,h+n);yield Promise.allSettled(g.map(function(){var n=a(function*(n){var r=yield u(n,e,t);r&&s.push({...r,address:n,port:e})});return function(e){return n.apply(this,arguments)}}()))}return s}),function(){return r.apply(this,arguments)}),u=(i=a(function*(e,t,n=3e3){return(0,o.uE)(`http://${e}:${t}/devtools/info`,n)}),function(e,t){return i.apply(this,arguments)})},19557(e,t,n){n.d(t,{BW:()=>s,YH:()=>d,nl:()=>l,r9:()=>u,uE:()=>f});var r,i=n(99436),a=n(41314),o=n(48161),s=()=>Math.random().toString(36).slice(2,9),c=new Set([`ANNOUNCE`,`RESPONSE`]),l=(e,t)=>{var n=JSON.parse(e.toString());return t(n)&&c.has(n.t)&&n.d?.info||null},u=()=>{var e=[];for(var t of Object.values(o.networkInterfaces()))for(var n of t)if(function(){if(n.family!==`IPv4`||n.internal)return 1;var t=n.address.split(`.`).map(Number),r=n.netmask.split(`.`).map(Number),i=t.map((e,t)=>(e|255&~r[t]).toString()).join(`.`);e.push({address:n.address,broadcast:i})}())continue;return e},d=({port:e,timeout:t=3e3,idleTimeout:n=0,buildQuery:r,parseMessage:i})=>new Promise((o,s)=>{var c=new Map,l=a.createSocket(`udp4`),d=null,f=null,p=!1,m=e=>{if(!p){p=!0,clearTimeout(d),clearTimeout(f);try{l.close()}catch{}e?s(e):o([...c.values()])}};l.on(`error`,m),l.on(`message`,(e,t)=>{if(!p)try{var r=i(e,t);if(!r||c.has(r.key))return;c.set(r.key,r.value),n&&!p&&(clearTimeout(f),f=setTimeout(m,n))}catch{}});try{l.bind(()=>{if(!p)try{l.setBroadcast(!0);var n=r();for(var i of(()=>{var e=new Set([`255.255.255.255`,`127.0.0.1`]);for(var t of u())e.add(t.broadcast);return[...e]})())l.send(n,0,n.length,e,i);d=setTimeout(m,t)}catch(e){m(e)}})}catch(e){m(e)}}),f=(r=i(function*(e,t=3e3){var n,r=new AbortController;try{n=setTimeout(()=>r.abort(),t);var i=yield fetch(e,{signal:r.signal});return i.ok?yield i.json():null}catch{return null}finally{n!==void 0&&clearTimeout(n),r.abort()}}),function(e){return r.apply(this,arguments)})},72197(e,t,n){n.d(t,{e:()=>r});let r=(e,t)=>{let n=Error(typeof e==`string`?e:e?.message||`CDP request failed${t?`: ${t}`:``}`);return e&&typeof e==`object`&&(e.code!==void 0&&(n.code=e.code),e.data!==void 0&&(n.data=e.data)),t&&(n.method=t),n}},73610(e,t,n){n.d(t,{AB:()=>r}),Object.freeze({ready:`bricks-devtools:ready`,init:`bricks-devtools:init`,hello:`bricks-devtools:hello`,connect:`bricks-devtools:connect`,disconnect:`bricks-devtools:disconnect`,close:`bricks-devtools:close`,openUrl:`bricks-devtools:open-url`,save:`bricks-devtools:save`,copy:`bricks-devtools:copy`,shortcut:`bricks-devtools:shortcut`,open:`bricks-devtools:open`,closed:`bricks-devtools:closed`,config:`bricks-devtools:config`,target:`bricks-devtools:target`});let r=Object.freeze({takenOver:4e3,targetGone:4001,signedOut:4003,noTarget:1006})}},ss={};function J(e){var t=ss[e];if(t!==void 0)return t.exports;var n=ss[e]={exports:{}};return os[e](n,n.exports,J),n.exports}q=(es=typeof Symbol==`function`)?Symbol(`rspack queues`):`__rspack_queues`,ts=J.aE=es?Symbol(`rspack exports`):`__webpack_exports__`,ns=es?Symbol(`rspack error`):`__rspack_error`,rs=es?Symbol(`rspack done`):`__rspack_done`,is=J.zS=es?Symbol(`rspack defer`):`__rspack_defer`,J.zT=e=>{if(e.some(e=>{var t=ss[e];return!t||!1===t[rs]}))return{then:(t,n)=>Promise.all(e.map(J)).then(t,n)}},as=e=>{e&&e.d<1&&(e.d=1,e.forEach(e=>e.r--),e.forEach(e=>e.r--?e.r++:e()))},J.a=(e,t,n)=>{n&&((r=[]).d=-1);var r,i,a,o,s=new Set,c=e.exports,l=new Promise((e,t)=>{o=t,a=e});l[ts]=c,l[q]=e=>{r&&e(r),s.forEach(e),l.catch(()=>{})},e.exports=l,t(e=>{i=e.map(e=>{if(typeof e==`object`&&e){if(!e[q]&&e[is]){var t=J.zT(e[is]);if(!t)return e;var n=e;e={then(e,r){t.then(()=>e(n),r)}}}if(e[q])return e;if(e.then){var r=[];r.d=0,e.then(e=>{i[ts]=e,as(r)},e=>{i[ns]=e,as(r)});var i={};return i[is]=!1,i[q]=e=>e(r),i}}var a={};return a[q]=()=>{},a[ts]=e,a});var t,n=()=>i.map(e=>{if(e[is])return e;if(e[ns])throw e[ns];return e[ts]}),a=new Promise(e=>{(t=()=>e(n)).r=0;var a=e=>e!==r&&!s.has(e)&&(s.add(e),e&&!e.d&&(t.r++,e.push(t)));i.map(e=>e[is]||e[q](a))});return t.r?a:n()},e=>(e?o(l[ns]=e):a(c),as(r),l[rs]=!0)),r&&r.d<0&&(r.d=0)},J.d=(e,t)=>{for(var n in t)J.o(t,n)&&!J.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},J.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);var cs=J(13346),ls=(cs=await cs).fl,us=cs.le,ds=cs.TB;const fs=e=>{if(!e)return{};let t={};for(let n=0;n<e.length;n+=2)t[e[n]]=e[n+1];return t},ps=e=>{if(typeof e!=`object`||!e)return{value:e};if(`value`in e)return{value:e.value};if(`unserializableValue`in e)return{value:e.unserializableValue};if(e.objectId){let t=e.preview?.properties;return Array.isArray(t)&&t.length>0?{value:t.reduce((e,t)=>(e[t.name]=t.value,e),{}),byRef:!0}:{value:e.description||`[${e.type}]`,byRef:!0}}return{value:e.type===`undefined`?void 0:e.description}},ms=e=>{if(e)return`value`in e?e.value:e.unserializableValue||e.description},hs=({text:e,exception:t}={})=>(e&&!/^Uncaught\b/.test(e)?e:t?.description||t?.value||e)||`Runtime evaluation failed`,gs=e=>{if(e.exceptionDetails)throw Error(hs(e.exceptionDetails))},_s=async(e,t,{awaitPromise:n=!1}={})=>e.send(`Runtime.evaluate`,{expression:t,objectGroup:`console`,returnByValue:!0,awaitPromise:!!n,generatePreview:!0}),vs=new WeakMap,ys=async(e,t)=>(await e.send(`Runtime.callFunctionOn`,{functionDeclaration:`function () { return typeof usage }`,objectGroup:`console`,returnByValue:!0},t))?.result?.value===`function`?`Runtime.callFunctionOn`:`Runtime.evaluate`,bs=async(e,t,{timeout:n,awaitPromise:r=!0}={})=>{if(!vs.has(e)){let t=ys(e,n);vs.set(e,t),t.catch(()=>vs.delete(e))}let i={objectGroup:`console`,returnByValue:!0,awaitPromise:!!r};return await vs.get(e)===`Runtime.evaluate`?e.send(`Runtime.evaluate`,{expression:t,...i},n):e.send(`Runtime.callFunctionOn`,{functionDeclaration:`function () { return (\n${t}\n) }`,...i},n)},xs=/^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*$/,Ss=e=>{if(!xs.test(e))throw Error(`Not a dotted path of identifiers: ${e}`);let t=e.split(`.`).map((e,t,n)=>n.slice(0,t+1).join(`.`)),n=t.pop();return`!!(${[...t.length?[`typeof ${t[0]}!='undefined'`,...t]:[],`typeof ${n}=='function'`].join(`&&`)})`},Cs=({subspaceId:e,handler:t,action:n,parameters:r,property:i,waitAsync:a,sync:o})=>{let s={handler:t,action:n};return r!==void 0&&(s.parameters=r),i!==void 0&&(s.property=i),a!==void 0&&(s.waitAsync=a),o!==void 0&&(s.sync=o),`(() => {
633
633
  const systemRef = globalThis.system
@@ -689,7 +689,7 @@ Options:
689
689
  Up to date.`),process.exit(0)),console.log(`\nUpdate available: ${c} -> ${f}. Run 'bricks-buttress update' to install.`),process.exit(1)),m&&(console.log(`
690
690
  Already running the latest version.`),await ll({message:`Reinstall anyway?`,defaultValue:!1,autoYes:n})||(console.log(`Skipped.`),process.exit(0)));let h=[`npm`,`bun`,`binary`].includes(l.method);h||console.log(`Cannot auto-detect installer (method: ${l.method}); falling back to binary install.`);let g=h?l.method:`binary`;await ll({message:`Update using "${g}" method?`,defaultValue:!0,autoYes:n})||(console.log(`Cancelled.`),process.exit(0));let _=async e=>{console.log(`\n-> Running ${e} update...`);try{return await so(e,u,l,{ggmlVariant:s}),!0}catch(t){return console.error(`\n${e} update failed: ${t.message}`),!1}},v=await _(g),y=g;!v&&g!==`binary`&&await ll({message:`Try the binary installer as a fallback?`,defaultValue:!0,autoYes:n})&&(y=`binary`,v=await _(`binary`)),v||(console.error(`
691
691
  Update failed. See messages above.`),y===`binary`&&console.error(`The previously installed version is still in place.`),process.exit(1)),console.log(`
692
- Update complete.`),process.exit(0)},dl=e();var fl=async()=>{if(process.argv[2]===`update`){await ul(process.argv.slice(3));return}if(process.argv[2]===`agent`){let{runAgentCommand:e}=await import(`./cli-KbjOekMI.mjs`);await e(process.argv.slice(3)),process.exit(0)}if(process.argv[2]===`ui`){let{runUiCommand:e}=await import(`./command-DcJp0Euy.mjs`);await e(process.argv.slice(3));return}(process.argv.includes(`--version`)||process.argv.includes(`-v`))&&(console.log(dl.version),process.exit(0)),(process.argv.includes(`--help`)||process.argv.includes(`-h`))&&(console.log(`
692
+ Update complete.`),process.exit(0)},dl=e();var fl=async()=>{if(process.argv[2]===`update`){await ul(process.argv.slice(3));return}if(process.argv[2]===`agent`){let{runAgentCommand:e}=await import(`./cli-KbjOekMI.mjs`);await e(process.argv.slice(3)),process.exit(0)}if(process.argv[2]===`ui`){let{runUiCommand:e}=await import(`./command-CkGRa0_N.mjs`);await e(process.argv.slice(3));return}(process.argv.includes(`--version`)||process.argv.includes(`-v`))&&(console.log(dl.version),process.exit(0)),(process.argv.includes(`--help`)||process.argv.includes(`-h`))&&(console.log(`
693
693
  bricks-buttress v${dl.version}
694
694
 
695
695
  Buttress server for remote inference with GGML backends.