webdaemon 34.1.0 → 35.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,40 +1,40 @@
1
- async function Ut(n,t=0){let e=new TextEncoder().encode(n);if(!crypto.subtle)throw"Requires secure origin (localhost or https:)";let o=await crypto.subtle.digest("SHA-1",e),r=new Uint8Array(o),s=String.fromCodePoint(...r),a=btoa(s).replaceAll("+","-").replaceAll("/","_").replaceAll("=","");return t?a.substring(0,t):a}async function je(n,t=0){let e=new TextEncoder().encode(n);if(!crypto.subtle)throw"Requires secure origin (localhost or https:)";let o=await crypto.subtle.digest("SHA-1",e),s=Array.from(new Uint8Array(o)).map(i=>i.toString(16).padStart(2,"0")).join("");return t?s.substring(0,t):s}async function E(n){return typeof n=="string"&&(n=new URL(n)),await Ut(String(n),8)}var N={name:"RSASSA-PKCS1-v1_5",hash:"SHA-256"},tt=/https?:\/\/[^\/]+$/,Lt=/^\/issuer\/[a-f0-9]{32}$/,Dt=1e3*30,d=class n{static Source={PARTY_CONTROL:"party:control"};static Counterparty={PUBLIC:"public"};static Capability={OPEN:"open",CLOSE:"close",GRANT:"grant",REVOKE:"revoke",OFFER:"offer",RETRACT:"retract",DELETE:"delete",CATALOG:"catalog",ALIAS:"alias",UNALIAS:"unalias",GET_ITEM:"getitem",SET_ITEM:"setitem",PUSH:"push",LOG:"log",WEBLOG:"weblog",CHAT:"chat",READ_MEMORY:"read_memory",WRITE_MEMORY:"write_memory",READ:"read",WRITE:"write"};static DEFAULT_EXPIRY_MILLIS=1e3*60*60*24;static TOKEN_HEADER="x-tabserver-token";static SCOPE_SEPARATOR=/[\s,;\|]+/;static#t=1e3*60;static#e=2048;static#n=new Map;static#s=new Map;#o=null;#r=null;#l;#p;#h;#a;constructor(t){let e=null;if(typeof t=="object")e=t;else if(typeof t=="string")try{e=JSON.parse(atob(t))}catch{throw"Invalid token format"}else throw`Cannot construct token from ${typeof t}`;this.#r=e.sig,delete e.sig,this.#o=e;let{iss:o,aud:r,sub:s,src:i,scope:a,iat:l,exp:c,pre:u}=e;if(!o||!r||!s||!i||!a||!l||!c)throw"Token must include iss, aud, sub, src, scope, iat and exp";if(u!==void 0){if(!Array.isArray(u))throw"The pre attribute must be an array of principals";for(let h of u)if(!h||typeof h.sub!="string"||typeof h.src!="string")throw"Each pre principal must have a sub and src"}if(!r.match(tt)||!s.match(tt))throw"The aud and sub attributes must be origins";if(this.#l=new URL(r),this.#p=new URL(s),this.#h=new URL(i),this.#h.hash)throw"The src attribute must have no fragment component.";this.#o=e}async signWith(t){if(this.#o==null)throw"No payload to sign";let e=await t,o=await crypto.subtle.importKey("jwk",e,N,!0,["sign"]),r=JSON.stringify(this.#o),s=new TextEncoder().encode(r).buffer,i=new Uint8Array(s),a=await crypto.subtle.sign(N,o,i),l=n.bytesToBase64(new Uint8Array(a));return this.#r=l,l}async verifySignatory(){let t=String(this.getIssuer()),{signatory:e,publicKey:o}=await n.#i(t);this.#a=e,this.#f(),await this.#u(o)}async fetchSignatory(){let t=String(this.getIssuer());this.#a=await n.#m(t),this.#f()}async checkSignature(t){if(!this.#o||!this.#r)throw"checkSignature: no payload or signatureBase64";let e=await t,o=await n.#C(e,String(this.getIssuer()));await this.#u(o)}async#u(t){if(!this.#o||!this.#r)throw"checkSignature: no payload or signatureBase64";let e=JSON.stringify(this.#o),o=new TextEncoder().encode(e),r=n.base64ToBytes(this.#r);if(!await crypto.subtle.verify(N,t,r,o))throw`Signature rejected by issuer ${this.getIssuer()}`}#f(){if(!this.#a)throw"validateSignatory: no signatory";let t=this.#a.src,e=this.getSrc(),o=this.getIssuer();if(o.origin!==this.getSub())throw`Token issuer origin '${o.origin}' should be token sub '${this.getSub()}'`;if(e===n.Source.PARTY_CONTROL){if(t!==n.Source.PARTY_CONTROL)throw`Token src '${e}' cannot be signed by signatory src '${t}'`}else if(this.#h.protocol==="http:"||this.#h.protocol==="https:"){if(t!==e&&t!==n.Source.PARTY_CONTROL)throw`Token src '${e}' cannot be signed by signatory src '${t}'`}else throw`Unsupported token src '${e}'`;if(t===n.Source.PARTY_CONTROL){if(!o.pathname.startsWith("/device/"))throw`Party control signatory issuer path '${o.pathname}' must start with /device/`;return}let r=new URL(t);if(r.protocol!=="http:"&&r.protocol!=="https:")throw`Invalid signatory src '${t}'`;if(!Lt.test(o.pathname))throw`App signatory issuer path '${o.pathname}' must match /issuer/<appId>`}static async#i(t){let e=n.#y(t);if(e)return e;let o=n.#s.get(t);if(o)return await o;let r=(async()=>{let s=await n.#m(t),i=await n.#C(s.jwk,t),a={signatory:s,publicKey:i,expiresAt:Date.now()+n.#t};return n.#w(t,a),a})();n.#s.set(t,r);try{return await r}finally{n.#s.delete(t)}}static#y(t){let e=n.#n.get(t);return e?e.expiresAt<=Date.now()?(n.#n.delete(t),null):(n.#n.delete(t),n.#n.set(t,e),e):null}static#w(t,e){for(n.#n.has(t)&&n.#n.delete(t),n.#n.set(t,e);n.#n.size>n.#e;){let o=n.#n.keys().next().value;if(!o)break;console.log("Evicting token signatory cache entry due max size",{issuer:t,entryExpiresAt:e.expiresAt,cacheMaxEntries:n.#e}),n.#n.delete(o)}}static async#m(t){try{let o=await(await fetch(t,{headers:{"content-type":"application/json"}})).json();if("error"in o)throw o.error;let r=o.ok;if(!r||typeof r!="object"||!r.jwk||typeof r.jwk!="object")throw"Invalid signatory response";if(typeof r.src!="string")throw"Invalid signatory src";return r}catch(e){throw`Failed to read signatory at ${t}: ${e}`}}static async#C(t,e){if(!t||typeof t!="object"||"error"in t)throw`Missing or invalid public JWK at issuer ${e}`;try{return await crypto.subtle.importKey("jwk",t,N,!0,["verify"])}catch{throw`Missing or invalid public JWK at issuer ${e}`}}getSignedPayload(){if(!this.#r||!this.#o)throw"getSignedPayload: no signatureBase64 or payload";return{...this.#o,sig:this.#r}}getPayload(){if(!this.#o)throw"getPayload: no payload";return this.#o}getAud(){return this.#l.origin}getParty(){return this.#l.host}getSub(){return this.#p.origin}getSrc(){return String(this.#h)}getCounterparty(){return this.#p.host}getPre(){return this.#o?.pre??[]}getSignatorySrc(){if(!this.#a)throw"getSignatorySrc: no signatory";return this.#a.src}getSourceUrl(){return this.#h}getIssuer(){return new URL(this.getPayload().iss)}getSources(){if(!this.#o)throw"getSources: no payload";let t=[];for(let e in this.#o.scope)t.push(e);return t}getCapabilities(t){if(!this.#o)throw"getCapabilities: no payload";let e=this.#o.scope;if(!(t in e))throw`Source '${t}' not in scope`;return e[t].split(n.SCOPE_SEPARATOR)}hasCapability(t,e){return this.getCapabilities(t).includes(e)}checkPeriod(){if(!this.#o)throw"checkPeriod: no payload";let{iat:t,exp:e}=this.#o,o=Date.now();if(o<t-Dt)throw"Token is not yet valid";if(o>e)throw"Token has expired"}asSignedBase64(){return btoa(JSON.stringify(this.getSignedPayload()))}static bytesToBase64(t){let e=Array.from(t,o=>String.fromCodePoint(o)).join("");return btoa(e)}static base64ToBytes(t){let e=atob(t);return Uint8Array.from(e,o=>o.codePointAt(0)??0)}static from(t){let e=t.headers.get(n.TOKEN_HEADER);return e?new n(e):null}static toSearchString(t){let e=new URLSearchParams;for(let o in t){let s=t[o].asSignedBase64();e.append(o,s)}return e.toString()}};var Gt=/^[\w\-.:]+(?:\/[\w\-.:]+)*$/,jt=/^[\w\-.:%_]+(?:\/[\w\-.:%_]+)*$/,R=class{#t;constructor(t){this.#t=t}getItem(t){return Bt(this.#t,t)}getItemsLike(t){return Vt(this.#t,t)}setItem(t,e){return _t(this.#t,t,e)}removeItem(t){return Ht(this.#t,t)}};function V(n){if(n.match(Gt)==null)throw`DaemonStorage: Invalid key: '${n}`}function Ft(n){if(n.match(jt)==null)throw`DaemonStorage: Invalid like key: ${n}`}function Kt(n){try{return JSON.stringify(n)}catch{throw"DaemonStorage: Invalid value"}}async function _t(n,t,e){V(t);let o=Kt(e),r=`${n.getAud()}/storage/${t}`;return(await fetch(r,{method:"PUT",headers:{"X-Tabserver-Token":n.asSignedBase64(),"Content-Type":"application/json"},body:o})).json()}async function Bt(n,t){V(t);let e=`${n.getAud()}/storage/${t}`;return(await fetch(e,{method:"GET",headers:{"X-Tabserver-Token":n.asSignedBase64()}})).json()}async function Vt(n,t){Ft(t);let e=new URL(`${n.getAud()}/storage`);return e.searchParams.append("like",t),await(await fetch(e,{method:"GET",headers:{"X-Tabserver-Token":n.asSignedBase64()}})).json()}async function Ht(n,t){V(t);let e=`${n.getAud()}/storage/${t}`;return(await fetch(e,{method:"DELETE",headers:{"X-Tabserver-Token":n.asSignedBase64()}})).json()}var et={Ash:"\xE6",Hash:"#"},Yt={Ash:encodeURIComponent("\xE6")},I=class{params=new URLSearchParams;extractHash(t){t=t.startsWith(et.Hash)?t.substring(1):t;let e=t.indexOf(Yt.Ash);if(e===-1)return t;let o=new URLSearchParams(t.slice(e));return this.extract(o),t.slice(0,e)}extractQuery(t){let e=new URLSearchParams(t);return this.extract(e),e.toString()}extract(t){let e=Array.from(t.keys());for(let o of e)o.startsWith(et.Ash)&&(this.params.set(o.substring(1),t.get(o)??""),t.delete(o))}getParams(){return this.params}};var $="party",nt="prefix",Wt="lastKnownDaemon",x=class n{static#t;#e;#n;#s;#o;static async getInstance(t=void 0){if(!t&&!n.#t)throw"Must provide app name";if(t&&n.#t&&t!==n.#t.#e)throw`Cannot change app name from ${n.#t.#e} to ${t}`;if(t&&!n.#t&&(n.#t=new n(t),await n.#t.init()),!n.#t)throw"No instance of BrowserApp";return n.#t}constructor(t){this.#e=t,this.#n=`${t}Party`,this.#s=`${t}Tokens`,this.#o=`${t}AppUrl`}async init(){let t=new URL(globalThis.location.href),e=new I,o=e.extractHash(t.hash),r=e.extractQuery(t.search),s=e.getParams();if(s.has($)){sessionStorage[this.#s]=s.toString();let i=this.getToken();await i.verifySignatory(),sessionStorage[this.#n]=i.getParty(),localStorage.setItem(Wt,i.getParty());let a=i.getSourceUrl();if(a.origin!==t.origin||a.pathname!==t.pathname||a.search!==t.search)throw`Party token is for different app: ${a}`}return t.hash=o,t.search=r,(s.has($)||sessionStorage[this.#o]===void 0)&&(sessionStorage[this.#o]=t.toString()),globalThis.history.replaceState(null,"",t.toString()),this}isOrphan(){return sessionStorage[this.#n]===void 0||sessionStorage[this.#s]===void 0}getAppName(){return this.#e}getAppUrl(){return sessionStorage[this.#o]}getParty(){return sessionStorage[this.#n]}getPartyOrigin(){return`${globalThis.location.protocol}//${this.getParty()}`}getDefaultPrefix(t=null){t||(t=this.getAppUrl());let e=new URL(t);return e.hash="",E(e)}getPrefix(){return this.hasParam(nt)?Promise.resolve(this.getParam(nt)??""):this.getDefaultPrefix()}async getAgentUrl(t){let e=this.getPartyOrigin(),o=await this.getPrefix(),r=`${e}/tab/${o}`;return t?`${r}/${t}`:r}async getAgentEndpoint(t){let{party:e=this.getParty(),appUrl:o=this.getAppUrl(),prefix:r=await this.getDefaultPrefix(o),tab:s}=t,a=`${new URL(o).protocol}//${e}/tab/${r}`;return s?`${a}/${s}`:a}getTokenBase64(t=$){let e=sessionStorage[this.#s],r=new URLSearchParams(e).get(t);if(!r)throw`No token for ${t}, check 'audience' in YML`;return r}getToken(t=$){let e=this.getTokenBase64(t);return new d(e)}getParam(t){let e=new URL(globalThis.location.href).searchParams;for(let[r,s]of e)if(t.toLowerCase()==r.toLowerCase())return s;return document.querySelector("link[rel=webdaemon]")?.getAttribute(t)??null}hasParam(t){return new URL(globalThis.location.href).searchParams.has(t)?!0:document.querySelector("link[rel=webdaemon]")?.hasAttribute(t)??!1}getStorage(){return new R(this.getToken())}};var qt="agent",M=class{#t=new Map;register(t,e,o){return this.#t.set(t,{descriptor:e,execute:o}),this}descriptors(){return[...this.#t.values()].map(t=>t.descriptor)}async executeToolCalls(t,e={}){let o=[];for(let r of t){let s=this.#t.get(r.name);if(!s){o.push({toolCallId:r.id,name:r.name,content:`No client tool named ${r.name}`,isError:!0});continue}try{let i=await s.execute(r.input||{},e);o.push({toolCallId:r.id,name:r.name,content:JSON.stringify(i)})}catch(i){o.push({toolCallId:r.id,name:r.name,content:String(i),isError:!0})}}return o}},ot=class{#t;#e;#n;#s=null;#o;constructor(t={}){this.#t=t.app,this.#e=t.appName,this.#n=t.agentTab??qt,this.#o=t.clientTools??new M}get app(){return this.#t??null}get agentUrl(){return this.#s}get clientTools(){return this.#o}async init(){return this.#t??=await x.getInstance(this.#e),this.#t.isOrphan()||(this.#s=await this.#t.getAgentUrl(this.#n)),this}isOrphan(){return!!this.#t?.isOrphan()}getParty(){return this.#r().getParty()}listChats({targetParty:t}){return this.postAgent("/chats",{targetParty:t})}listModels({targetParty:t}){return this.postAgent("/models",{targetParty:t})}createSession(t){return this.postAgent("/session",{targetParty:t.targetParty,...t.chatId?{chatId:t.chatId}:{},systemPrompt:t.systemPrompt,temperature:t.temperature,...t.model?{model:t.model}:{},clientTools:this.#o.descriptors()})}async sendMessage(t){let e=t.onEvent,o=e?await this.postAgentStream("/send",{targetParty:t.targetParty,chatId:t.chatId,message:t.message,temperature:t.temperature,toolsEnabled:t.toolsEnabled,toolDetails:t.toolDetails},e):await this.postAgent("/send",{targetParty:t.targetParty,chatId:t.chatId,message:t.message,temperature:t.temperature,toolsEnabled:t.toolsEnabled,toolDetails:t.toolDetails});for(await t.onConversationResult?.(o);o.clientToolCalls?.length;){await t.onClientToolCalls?.(o.clientToolCalls);let r=await this.#o.executeToolCalls(o.clientToolCalls,{targetParty:t.targetParty});o=await this.sendClientToolResults({targetParty:t.targetParty,chatId:t.chatId,toolResults:r,temperature:t.temperature,toolsEnabled:t.toolsEnabled,toolDetails:t.toolDetails,onEvent:e}),await t.onConversationResult?.(o)}return o}sendClientToolResults(t){let e={targetParty:t.targetParty,chatId:t.chatId,toolResults:t.toolResults,temperature:t.temperature,toolsEnabled:t.toolsEnabled,toolDetails:t.toolDetails};return t.onEvent?this.postAgentStream("/client-tool-results",e,t.onEvent):this.postAgent("/client-tool-results",e)}closeChat({targetParty:t,chatId:e}){return this.postAgent("/close",{targetParty:t,chatId:e})}deleteChat({targetParty:t,chatId:e}){return this.postAgent("/delete",{targetParty:t,chatId:e})}async postAgent(t,e){if(!this.#s)throw"Agent URL is not available";let r=await(await fetch(`${this.#s}${t}`,{method:"POST",headers:{"Content-Type":"application/json","X-Tabserver-Token":this.#r().getTokenBase64()},body:JSON.stringify(e)})).json();if("error"in r)throw r.error;return r.ok}async postAgentStream(t,e,o){if(!this.#s)throw"Agent URL is not available";let r=await fetch(`${this.#s}${t}`,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/x-ndjson","X-Tabserver-Token":this.#r().getTokenBase64()},body:JSON.stringify(e)});if(!r.body)throw"Streaming response has no body";let s={events:[]},i=async u=>{let h=u.trim();if(!h)return;let p=JSON.parse(h);if(p.type==="event")s.events?.push(p.event),await o?.(p.event);else if(p.type==="done")p.clientToolCalls?.length&&(s.clientToolCalls=p.clientToolCalls);else if(p.type==="error")throw p.message},a=r.body.getReader(),l=new TextDecoder,c="";for(;;){let{value:u,done:h}=await a.read();if(h)break;c+=l.decode(u,{stream:!0});let p;for(;(p=c.indexOf(`
2
- `))>=0;){let y=c.slice(0,p);c=c.slice(p+1),await i(y)}}return c+=l.decode(),await i(c),s}normalizeTargetParty(t){let e=String(t??"").trim();if(!e)throw"Daemon host is required";try{let o=e.includes("://")?new URL(e):new URL(`${globalThis.location.protocol}//${e}`);if(!o.host)throw"missing host";return o.host}catch{throw`Invalid daemon host: ${t}`}}#r(){if(!this.#t)throw"Browser app is not initialised";return this.#t}};function ze(n=void 0){let t=new M;return t.register("browser_daemon_identity",{type:"function",name:"browser_daemon_identity",execution:"client",description:"Get the active chat daemon and the counterparty it is talking to, derived from the browser launch token and active chat target.",parameters:{type:"object",properties:{},additionalProperties:!1}},async(e,o={})=>{let s=(n??await x.getInstance()).getToken(),i=o.targetParty||s.getParty();return{aud:o.targetAud||`${globalThis.location.protocol}//${i}`,sub:s.getSub(),party:i,counterparty:s.getCounterparty(),src:s.getSrc()}}),t.register("browser_language",{type:"function",name:"browser_language",execution:"client",description:"Get the browser language preferences for this page.",parameters:{type:"object",properties:{},additionalProperties:!1}},()=>({language:navigator.language,languages:Array.from(navigator.languages??[])})),t.register("browser_time",{type:"function",name:"browser_time",execution:"client",description:"Get the current timezone and local time from the browser.",parameters:{type:"object",properties:{},additionalProperties:!1}},()=>{let e=new Date,o=Intl.DateTimeFormat().resolvedOptions().timeZone;return{timeZone:o,isoTime:e.toISOString(),localTime:e.toLocaleString(void 0,{timeZone:o}),offsetMinutes:-e.getTimezoneOffset()}}),t}var Xt={name:"RSASSA-PKCS1-v1_5",modulusLength:2048,publicExponent:new Uint8Array([1,0,1]),hash:"SHA-256"},rt=class{#t;#e;constructor(t=Xt){if(this.#t=t,!crypto.subtle)throw"Crypto.subtle requires secure environment"}async generate(){this.#e=await crypto.subtle.generateKey(this.#t,!0,["sign","verify"])}async publicJwk(){if(!this.#e)throw"Must generate keypair";let t=this.#e.publicKey;return await crypto.subtle.exportKey("jwk",t)}async privateJwk(){if(!this.#e)throw"Must generate keypair";let t=this.#e.privateKey;return await crypto.subtle.exportKey("jwk",t)}async publicPem(){if(!this.#e)throw"Must generate keypair";let t=this.#e.publicKey,e=await crypto.subtle.exportKey("spki",t);return`-----BEGIN PUBLIC KEY-----
1
+ async function Ut(o,t=0){let e=new TextEncoder().encode(o);if(!crypto.subtle)throw"Requires secure origin (localhost or https:)";let n=await crypto.subtle.digest("SHA-1",e),r=new Uint8Array(n),s=String.fromCodePoint(...r),a=btoa(s).replaceAll("+","-").replaceAll("/","_").replaceAll("=","");return t?a.substring(0,t):a}async function je(o,t=0){let e=new TextEncoder().encode(o);if(!crypto.subtle)throw"Requires secure origin (localhost or https:)";let n=await crypto.subtle.digest("SHA-1",e),s=Array.from(new Uint8Array(n)).map(i=>i.toString(16).padStart(2,"0")).join("");return t?s.substring(0,t):s}async function E(o){return typeof o=="string"&&(o=new URL(o)),await Ut(String(o),8)}var N={name:"RSASSA-PKCS1-v1_5",hash:"SHA-256"},tt=/https?:\/\/[^\/]+$/,Lt=/^\/issuer\/[a-f0-9]{32}$/,Dt=1e3*30,d=class o{static Source={PARTY_CONTROL:"party:control"};static Counterparty={PUBLIC:"public"};static Capability={OPEN:"open",CLOSE:"close",GRANT:"grant",REVOKE:"revoke",OFFER:"offer",RETRACT:"retract",DELETE:"delete",CATALOG:"catalog",ALIAS:"alias",UNALIAS:"unalias",GET_ITEM:"getitem",SET_ITEM:"setitem",PUSH:"push",LOG:"log",WEBLOG:"weblog",CHAT:"chat",READ_MEMORY:"read_memory",WRITE_MEMORY:"write_memory",READ:"read",WRITE:"write"};static DEFAULT_EXPIRY_MILLIS=1e3*60*60*24;static TOKEN_HEADER="x-tabserver-token";static SCOPE_SEPARATOR=/[\s,;\|]+/;static#t=1e3*60;static#e=2048;static#o=new Map;static#s=new Map;#n=null;#r=null;#l;#p;#h;#a;constructor(t){let e=null;if(typeof t=="object")e=t;else if(typeof t=="string")try{e=JSON.parse(atob(t))}catch{throw"Invalid token format"}else throw`Cannot construct token from ${typeof t}`;this.#r=e.sig,delete e.sig,this.#n=e;let{iss:n,aud:r,sub:s,src:i,scope:a,iat:l,exp:c,pre:u}=e;if(!n||!r||!s||!i||!a||!l||!c)throw"Token must include iss, aud, sub, src, scope, iat and exp";if(u!==void 0){if(!Array.isArray(u))throw"The pre attribute must be an array of principals";for(let h of u)if(!h||typeof h.sub!="string"||typeof h.src!="string")throw"Each pre principal must have a sub and src"}if(!r.match(tt)||!s.match(tt))throw"The aud and sub attributes must be origins";if(this.#l=new URL(r),this.#p=new URL(s),this.#h=new URL(i),this.#h.hash)throw"The src attribute must have no fragment component.";this.#n=e}async signWith(t){if(this.#n==null)throw"No payload to sign";let e=await t,n=await crypto.subtle.importKey("jwk",e,N,!0,["sign"]),r=JSON.stringify(this.#n),s=new TextEncoder().encode(r).buffer,i=new Uint8Array(s),a=await crypto.subtle.sign(N,n,i),l=o.bytesToBase64(new Uint8Array(a));return this.#r=l,l}async verifySignatory(){let t=String(this.getIssuer()),{signatory:e,publicKey:n}=await o.#i(t);this.#a=e,this.#f(),await this.#u(n)}async fetchSignatory(){let t=String(this.getIssuer());this.#a=await o.#m(t),this.#f()}async checkSignature(t){if(!this.#n||!this.#r)throw"checkSignature: no payload or signatureBase64";let e=await t,n=await o.#C(e,String(this.getIssuer()));await this.#u(n)}async#u(t){if(!this.#n||!this.#r)throw"checkSignature: no payload or signatureBase64";let e=JSON.stringify(this.#n),n=new TextEncoder().encode(e),r=o.base64ToBytes(this.#r);if(!await crypto.subtle.verify(N,t,r,n))throw`Signature rejected by issuer ${this.getIssuer()}`}#f(){if(!this.#a)throw"validateSignatory: no signatory";let t=this.#a.src,e=this.getSrc(),n=this.getIssuer();if(n.origin!==this.getSub())throw`Token issuer origin '${n.origin}' should be token sub '${this.getSub()}'`;if(e===o.Source.PARTY_CONTROL){if(t!==o.Source.PARTY_CONTROL)throw`Token src '${e}' cannot be signed by signatory src '${t}'`}else if(this.#h.protocol==="http:"||this.#h.protocol==="https:"){if(t!==e&&t!==o.Source.PARTY_CONTROL)throw`Token src '${e}' cannot be signed by signatory src '${t}'`}else throw`Unsupported token src '${e}'`;if(t===o.Source.PARTY_CONTROL){if(!n.pathname.startsWith("/device/"))throw`Party control signatory issuer path '${n.pathname}' must start with /device/`;return}let r=new URL(t);if(r.protocol!=="http:"&&r.protocol!=="https:")throw`Invalid signatory src '${t}'`;if(!Lt.test(n.pathname))throw`App signatory issuer path '${n.pathname}' must match /issuer/<appId>`}static async#i(t){let e=o.#y(t);if(e)return e;let n=o.#s.get(t);if(n)return await n;let r=(async()=>{let s=await o.#m(t),i=await o.#C(s.jwk,t),a={signatory:s,publicKey:i,expiresAt:Date.now()+o.#t};return o.#w(t,a),a})();o.#s.set(t,r);try{return await r}finally{o.#s.delete(t)}}static#y(t){let e=o.#o.get(t);return e?e.expiresAt<=Date.now()?(o.#o.delete(t),null):(o.#o.delete(t),o.#o.set(t,e),e):null}static#w(t,e){for(o.#o.has(t)&&o.#o.delete(t),o.#o.set(t,e);o.#o.size>o.#e;){let n=o.#o.keys().next().value;if(!n)break;console.log("Evicting token signatory cache entry due max size",{issuer:t,entryExpiresAt:e.expiresAt,cacheMaxEntries:o.#e}),o.#o.delete(n)}}static async#m(t){try{let n=await(await fetch(t,{headers:{"content-type":"application/json"}})).json();if("error"in n)throw n.error;let r=n.ok;if(!r||typeof r!="object"||!r.jwk||typeof r.jwk!="object")throw"Invalid signatory response";if(typeof r.src!="string")throw"Invalid signatory src";return r}catch(e){throw`Failed to read signatory at ${t}: ${e}`}}static async#C(t,e){if(!t||typeof t!="object"||"error"in t)throw`Missing or invalid public JWK at issuer ${e}`;try{return await crypto.subtle.importKey("jwk",t,N,!0,["verify"])}catch{throw`Missing or invalid public JWK at issuer ${e}`}}getSignedPayload(){if(!this.#r||!this.#n)throw"getSignedPayload: no signatureBase64 or payload";return{...this.#n,sig:this.#r}}getPayload(){if(!this.#n)throw"getPayload: no payload";return this.#n}getAud(){return this.#l.origin}getParty(){return this.#l.host}getSub(){return this.#p.origin}getSrc(){return String(this.#h)}getCounterparty(){return this.#p.host}getPre(){return this.#n?.pre??[]}getSignatorySrc(){if(!this.#a)throw"getSignatorySrc: no signatory";return this.#a.src}getSourceUrl(){return this.#h}getIssuer(){return new URL(this.getPayload().iss)}getSources(){if(!this.#n)throw"getSources: no payload";let t=[];for(let e in this.#n.scope)t.push(e);return t}getCapabilities(t){if(!this.#n)throw"getCapabilities: no payload";let e=this.#n.scope;if(!(t in e))throw`Source '${t}' not in scope`;return e[t].split(o.SCOPE_SEPARATOR)}hasCapability(t,e){return this.getCapabilities(t).includes(e)}checkPeriod(){if(!this.#n)throw"checkPeriod: no payload";let{iat:t,exp:e}=this.#n,n=Date.now();if(n<t-Dt)throw"Token is not yet valid";if(n>e)throw"Token has expired"}asSignedBase64(){return btoa(JSON.stringify(this.getSignedPayload()))}static bytesToBase64(t){let e=Array.from(t,n=>String.fromCodePoint(n)).join("");return btoa(e)}static base64ToBytes(t){let e=atob(t);return Uint8Array.from(e,n=>n.codePointAt(0)??0)}static from(t){let e=t.headers.get(o.TOKEN_HEADER);return e?new o(e):null}static toSearchString(t){let e=new URLSearchParams;for(let n in t){let s=t[n].asSignedBase64();e.append(n,s)}return e.toString()}};var Gt=/^[\w\-.:]+(?:\/[\w\-.:]+)*$/,jt=/^[\w\-.:%_]+(?:\/[\w\-.:%_]+)*$/,R=class{#t;constructor(t){this.#t=t}getItem(t){return Bt(this.#t,t)}getItemsLike(t){return Vt(this.#t,t)}setItem(t,e){return _t(this.#t,t,e)}removeItem(t){return Ht(this.#t,t)}};function V(o){if(o.match(Gt)==null)throw`DaemonStorage: Invalid key: '${o}`}function Ft(o){if(o.match(jt)==null)throw`DaemonStorage: Invalid like key: ${o}`}function Kt(o){try{return JSON.stringify(o)}catch{throw"DaemonStorage: Invalid value"}}async function _t(o,t,e){V(t);let n=Kt(e),r=`${o.getAud()}/storage/${t}`;return(await fetch(r,{method:"PUT",headers:{"X-Tabserver-Token":o.asSignedBase64(),"Content-Type":"application/json"},body:n})).json()}async function Bt(o,t){V(t);let e=`${o.getAud()}/storage/${t}`;return(await fetch(e,{method:"GET",headers:{"X-Tabserver-Token":o.asSignedBase64()}})).json()}async function Vt(o,t){Ft(t);let e=new URL(`${o.getAud()}/storage`);return e.searchParams.append("like",t),await(await fetch(e,{method:"GET",headers:{"X-Tabserver-Token":o.asSignedBase64()}})).json()}async function Ht(o,t){V(t);let e=`${o.getAud()}/storage/${t}`;return(await fetch(e,{method:"DELETE",headers:{"X-Tabserver-Token":o.asSignedBase64()}})).json()}var et={Ash:"\xE6",Hash:"#"},Yt={Ash:encodeURIComponent("\xE6")},I=class{params=new URLSearchParams;extractHash(t){t=t.startsWith(et.Hash)?t.substring(1):t;let e=t.indexOf(Yt.Ash);if(e===-1)return t;let n=new URLSearchParams(t.slice(e));return this.extract(n),t.slice(0,e)}extractQuery(t){let e=new URLSearchParams(t);return this.extract(e),e.toString()}extract(t){let e=Array.from(t.keys());for(let n of e)n.startsWith(et.Ash)&&(this.params.set(n.substring(1),t.get(n)??""),t.delete(n))}getParams(){return this.params}};var $="party",ot="prefix",Wt="lastKnownDaemon",x=class o{static#t;#e;#o;#s;#n;static async getInstance(t=void 0){if(!t&&!o.#t)throw"Must provide app name";if(t&&o.#t&&t!==o.#t.#e)throw`Cannot change app name from ${o.#t.#e} to ${t}`;if(t&&!o.#t&&(o.#t=new o(t),await o.#t.init()),!o.#t)throw"No instance of BrowserApp";return o.#t}constructor(t){this.#e=t,this.#o=`${t}Party`,this.#s=`${t}Tokens`,this.#n=`${t}AppUrl`}async init(){let t=new URL(globalThis.location.href),e=new I,n=e.extractHash(t.hash),r=e.extractQuery(t.search),s=e.getParams();if(s.has($)){sessionStorage[this.#s]=s.toString();let i=this.getToken();await i.verifySignatory(),sessionStorage[this.#o]=i.getParty(),localStorage.setItem(Wt,i.getParty());let a=i.getSourceUrl();if(a.origin!==t.origin||a.pathname!==t.pathname||a.search!==t.search)throw`Party token is for different app: ${a}`}return t.hash=n,t.search=r,(s.has($)||sessionStorage[this.#n]===void 0)&&(sessionStorage[this.#n]=t.toString()),globalThis.history.replaceState(null,"",t.toString()),this}isOrphan(){return sessionStorage[this.#o]===void 0||sessionStorage[this.#s]===void 0}getAppName(){return this.#e}getAppUrl(){return sessionStorage[this.#n]}getParty(){return sessionStorage[this.#o]}getPartyOrigin(){return`${globalThis.location.protocol}//${this.getParty()}`}getDefaultPrefix(t=null){t||(t=this.getAppUrl());let e=new URL(t);return e.hash="",E(e)}getPrefix(){return this.hasParam(ot)?Promise.resolve(this.getParam(ot)??""):this.getDefaultPrefix()}async getAgentUrl(t){let e=this.getPartyOrigin(),n=await this.getPrefix(),r=`${e}/tab/${n}`;return t?`${r}/${t}`:r}async getAgentEndpoint(t){let{party:e=this.getParty(),appUrl:n=this.getAppUrl(),prefix:r=await this.getDefaultPrefix(n),tab:s}=t,a=`${new URL(n).protocol}//${e}/tab/${r}`;return s?`${a}/${s}`:a}getTokenBase64(t=$){let e=sessionStorage[this.#s],r=new URLSearchParams(e).get(t);if(!r)throw`No token for ${t}, check 'audience' in YML`;return r}getToken(t=$){let e=this.getTokenBase64(t);return new d(e)}getParam(t){let e=new URL(globalThis.location.href).searchParams;for(let[r,s]of e)if(t.toLowerCase()==r.toLowerCase())return s;return document.querySelector("link[rel=webdaemon]")?.getAttribute(t)??null}hasParam(t){return new URL(globalThis.location.href).searchParams.has(t)?!0:document.querySelector("link[rel=webdaemon]")?.hasAttribute(t)??!1}getStorage(){return new R(this.getToken())}};var qt="agent",M=class{#t=new Map;register(t,e,n){return this.#t.set(t,{descriptor:e,execute:n}),this}descriptors(){return[...this.#t.values()].map(t=>t.descriptor)}async executeToolCalls(t,e={}){let n=[];for(let r of t){let s=this.#t.get(r.name);if(!s){n.push({toolCallId:r.id,name:r.name,content:`No client tool named ${r.name}`,isError:!0});continue}try{let i=await s.execute(r.input||{},e);n.push({toolCallId:r.id,name:r.name,content:JSON.stringify(i)})}catch(i){n.push({toolCallId:r.id,name:r.name,content:String(i),isError:!0})}}return n}},nt=class{#t;#e;#o;#s=null;#n;constructor(t={}){this.#t=t.app,this.#e=t.appName,this.#o=t.agentTab??qt,this.#n=t.clientTools??new M}get app(){return this.#t??null}get agentUrl(){return this.#s}get clientTools(){return this.#n}async init(){return this.#t??=await x.getInstance(this.#e),this.#t.isOrphan()||(this.#s=await this.#t.getAgentUrl(this.#o)),this}isOrphan(){return!!this.#t?.isOrphan()}getParty(){return this.#r().getParty()}listChats({targetParty:t}){return this.postAgent("/chats",{targetParty:t})}listModels({targetParty:t}){return this.postAgent("/models",{targetParty:t})}createSession(t){return this.postAgent("/session",{targetParty:t.targetParty,...t.chatId?{chatId:t.chatId}:{},systemPrompt:t.systemPrompt,temperature:t.temperature,...t.model?{model:t.model}:{},clientTools:this.#n.descriptors()})}async sendMessage(t){let e=t.onEvent,n=e?await this.postAgentStream("/send",{targetParty:t.targetParty,chatId:t.chatId,message:t.message,temperature:t.temperature,toolsEnabled:t.toolsEnabled,toolDetails:t.toolDetails},e):await this.postAgent("/send",{targetParty:t.targetParty,chatId:t.chatId,message:t.message,temperature:t.temperature,toolsEnabled:t.toolsEnabled,toolDetails:t.toolDetails});for(await t.onConversationResult?.(n);n.clientToolCalls?.length;){await t.onClientToolCalls?.(n.clientToolCalls);let r=await this.#n.executeToolCalls(n.clientToolCalls,{targetParty:t.targetParty});n=await this.sendClientToolResults({targetParty:t.targetParty,chatId:t.chatId,toolResults:r,temperature:t.temperature,toolsEnabled:t.toolsEnabled,toolDetails:t.toolDetails,onEvent:e}),await t.onConversationResult?.(n)}return n}sendClientToolResults(t){let e={targetParty:t.targetParty,chatId:t.chatId,toolResults:t.toolResults,temperature:t.temperature,toolsEnabled:t.toolsEnabled,toolDetails:t.toolDetails};return t.onEvent?this.postAgentStream("/client-tool-results",e,t.onEvent):this.postAgent("/client-tool-results",e)}closeChat({targetParty:t,chatId:e}){return this.postAgent("/close",{targetParty:t,chatId:e})}deleteChat({targetParty:t,chatId:e}){return this.postAgent("/delete",{targetParty:t,chatId:e})}async postAgent(t,e){if(!this.#s)throw"Agent URL is not available";let r=await(await fetch(`${this.#s}${t}`,{method:"POST",headers:{"Content-Type":"application/json","X-Tabserver-Token":this.#r().getTokenBase64()},body:JSON.stringify(e)})).json();if("error"in r)throw r.error;return r.ok}async postAgentStream(t,e,n){if(!this.#s)throw"Agent URL is not available";let r=await fetch(`${this.#s}${t}`,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/x-ndjson","X-Tabserver-Token":this.#r().getTokenBase64()},body:JSON.stringify(e)});if(!r.body)throw"Streaming response has no body";let s={events:[]},i=async u=>{let h=u.trim();if(!h)return;let p=JSON.parse(h);if(p.type==="event")s.events?.push(p.event),await n?.(p.event);else if(p.type==="done")p.clientToolCalls?.length&&(s.clientToolCalls=p.clientToolCalls);else if(p.type==="error")throw p.message},a=r.body.getReader(),l=new TextDecoder,c="";for(;;){let{value:u,done:h}=await a.read();if(h)break;c+=l.decode(u,{stream:!0});let p;for(;(p=c.indexOf(`
2
+ `))>=0;){let y=c.slice(0,p);c=c.slice(p+1),await i(y)}}return c+=l.decode(),await i(c),s}normalizeTargetParty(t){let e=String(t??"").trim();if(!e)throw"Daemon host is required";try{let n=e.includes("://")?new URL(e):new URL(`${globalThis.location.protocol}//${e}`);if(!n.host)throw"missing host";return n.host}catch{throw`Invalid daemon host: ${t}`}}#r(){if(!this.#t)throw"Browser app is not initialised";return this.#t}};function ze(o=void 0){let t=new M;return t.register("browser_daemon_identity",{type:"function",name:"browser_daemon_identity",execution:"client",description:"Get the active chat daemon and the counterparty it is talking to, derived from the browser launch token and active chat target.",parameters:{type:"object",properties:{},additionalProperties:!1}},async(e,n={})=>{let s=(o??await x.getInstance()).getToken(),i=n.targetParty||s.getParty();return{aud:n.targetAud||`${globalThis.location.protocol}//${i}`,sub:s.getSub(),party:i,counterparty:s.getCounterparty(),src:s.getSrc()}}),t.register("browser_language",{type:"function",name:"browser_language",execution:"client",description:"Get the browser language preferences for this page.",parameters:{type:"object",properties:{},additionalProperties:!1}},()=>({language:navigator.language,languages:Array.from(navigator.languages??[])})),t.register("browser_time",{type:"function",name:"browser_time",execution:"client",description:"Get the current timezone and local time from the browser.",parameters:{type:"object",properties:{},additionalProperties:!1}},()=>{let e=new Date,n=Intl.DateTimeFormat().resolvedOptions().timeZone;return{timeZone:n,isoTime:e.toISOString(),localTime:e.toLocaleString(void 0,{timeZone:n}),offsetMinutes:-e.getTimezoneOffset()}}),t}var Xt={name:"RSASSA-PKCS1-v1_5",modulusLength:2048,publicExponent:new Uint8Array([1,0,1]),hash:"SHA-256"},rt=class{#t;#e;constructor(t=Xt){if(this.#t=t,!crypto.subtle)throw"Crypto.subtle requires secure environment"}async generate(){this.#e=await crypto.subtle.generateKey(this.#t,!0,["sign","verify"])}async publicJwk(){if(!this.#e)throw"Must generate keypair";let t=this.#e.publicKey;return await crypto.subtle.exportKey("jwk",t)}async privateJwk(){if(!this.#e)throw"Must generate keypair";let t=this.#e.privateKey;return await crypto.subtle.exportKey("jwk",t)}async publicPem(){if(!this.#e)throw"Must generate keypair";let t=this.#e.publicKey,e=await crypto.subtle.exportKey("spki",t);return`-----BEGIN PUBLIC KEY-----
3
3
  ${btoa(String.fromCharCode(...new Uint8Array(e))).match(/.{1,64}/g)?.join(`
4
4
  `)??""}
5
5
  -----END PUBLIC KEY-----`}async privatePem(){if(!this.#e)throw"Must generate keypair";let t=this.#e.privateKey,e=await crypto.subtle.exportKey("pkcs8",t);return`-----BEGIN PRIVATE KEY-----
6
6
  ${btoa(String.fromCharCode(...new Uint8Array(e))).match(/.{1,64}/g)?.join(`
7
7
  `)??""}
8
- -----END PRIVATE KEY-----`}};var st=class{#t;#e;#n;#s;#o;#r;#l;async initWithKey(t,e,o,r){this.#e=e.startsWith("https:")?"https:":"http:",this.#n=t,this.#o=e,this.#t=o,this.#s=r,await this.#p()}async checkActivate(){if(!this.#r)throw"checkActivate: No token";let t=new URL(`${this.#r.getAud()}/activate`),e=this.#r.asSignedBase64(),o={},r;try{r=await fetch(t,{method:"POST",headers:{"x-tabserver-token":e,"content-type":"application/json"},body:JSON.stringify(o)});let{ok:s,error:i}=await r.json();if(i)throw i;return!!s.isNew}catch(s){throw console.error(s),`Cannot activate ${this.#r.getParty()}`}}async makeOffer(t,e=null){let{type:o="TRANSIENT",ttl:r=300,expiry:s=30,payload:i}=e??{};if(!this.#r)throw"makeOffer: No token";let a=new URL(`${this.#r.getAud()}/offer`),l=this.#r.asSignedBase64(),c={role:"party",type:o,ttl:r,description:`Offered by ${this.#r.getCounterparty()}`,payload:i,expiry:new Date(Date.now()+1e3*s),flow:t},h=await(await fetch(a,{method:"POST",headers:{"x-tabserver-token":l,"content-type":"application/json"},body:JSON.stringify(c)})).json();if("error"in h)throw h.error;let{claimCode:p,_checkState:y}=h.ok;return this.#l=p,h.ok}async checkState(){if(!this.#r||!this.#l)throw"checkState: No token or claimCode";let t=new URL(`${this.#r.getAud()}/offer/check`);t.searchParams.append("claimCode",this.#l);let e=this.#r.asSignedBase64(),r=await(await fetch(t,{headers:{"x-tabserver-token":e}})).json();if("error"in r)throw r.error;return r.ok.checkState}async confirmClaim(t){if(!this.#r||!this.#l)throw"confirmClaim: No token or claimCode";let e=new URL(`${this.#r.getAud()}/offer/confirm`),o=await this.#r.asSignedBase64(),r={claimCode:this.#l,checkCode:t},i=await(await fetch(e,{method:"POST",headers:{"x-tabserver-token":o,"content-type":"application/json"},body:JSON.stringify(r)})).json();if("error"in i)throw i.error;return i.ok}getChild(){if(!this.#n)throw"getChild: no child";return this.#n}getChildOrigin(){if(!this.#s||!this.#n)throw"getDaemonUrl: no issUrl or daemon";return`${this.#e}//${this.#n}`}async#p(){if(!this.#s||!this.#n||!this.#t)throw"buildToken: missing iss, child or privateJwk";let t=this.#s,e=this.getChildOrigin(),o=new URL(this.#s).origin,r;if(this.#o){let a=new URL(this.#o);r=`${a.origin}${a.pathname}${a.search}`}else r="party:control";let s={iss:t,aud:e,sub:o,src:r,scope:{"party:control":"offer"},iat:Date.now(),exp:Date.now()+1e3*60*3},i=new d(s);await i.signWith(Promise.resolve(this.#t)),this.#r=i}};var zt="qrcode",it=class{#t;#e;constructor(t,e){this.#t=t,this.#e=e}generate(){let t=qrcode(0,"L");t.addData(this.#e),t.make();let e=t.createDataURL();return this.#t.classList.add(zt),this.#t.src=e,new Promise((o,r)=>{this.#t.onload=o,this.#t.onerror=r})}};function g(n,t){if("ok"in n){let i=JSON.stringify(n);return new Response(i,{status:200,headers:{...t,"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}let e=n.error,[,o,r]=e.match(/^(\d{3})\s(.+)/)??[null,"200",e],s=JSON.stringify({error:r});return new Response(s,{status:Number(o),headers:{...t,"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}function on(n={error:"404 Not Found"}){let t=JSON.stringify(n);return new Response(t,{status:404,headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}function rn(n,t=[]){return new Response(null,{status:302,headers:{Location:n.toString(),"Access-Control-Allow-Origin":"*",...t}})}function sn(n){let{name:t,value:e,domain:o,sameSite:r,path:s="/",expires:i,secure:a=!0,httpOnly:l=!0}=n,c=[];return c.push(`${encodeURIComponent(t)}=${encodeURIComponent(e)}`),o&&c.push(`Domain=${o}`),r&&c.push(`SameSite=${r}`),c.push(`Path=${s}`),i&&c.push(`Expires=${i.toUTCString()}`),a&&c.push("Secure"),l&&c.push("HttpOnly"),c.join("; ")}var at="x-forwarded-host",ct="x-forwarded-proto",lt="x-forwarded-pathname",J="x-tabserver-continuation";function H(n){return n.headers.has(ct)?n.headers.get(ct)+":":new URL(n.url).protocol}function Y(n){return n.headers.has(at)?n.headers.get(at)||"":new URL(n.url).host}function Qt(n){return n.headers.has(lt)?n.headers.get(lt)||"":new URL(n.url).pathname}function Zt(n){let t=H(n),e=Y(n),o=Qt(n);return new URL(`${t}//${e}${o}`)}function cn(n){let t=new URL(n.url),e=Zt(n);return e.search=t.search,e.hash=t.hash,e}function ln(n){return new URL(n.url).pathname}function un(n,t){let e=te(n);return t in e?e[t]:null}function te(n){let t={},e=n.headers.get("Cookie");if(e)for(let o of e.split("; ")){let[r,s]=o.split("=");t[r]=s}return t}var ut="daemon",ee="config",ne="event",ht={Config:"config"},pt="config",oe=1e3*60*60,m=class n extends EventTarget{static#t=new n;static Ev=ht;static getInstance(){return this.#t}static shouldHandle(t){return n.isConfig(t)||n.isEvent(t)}static isConfig(t){let e=new URL(t.url);return t.method=="POST"&&e.pathname==`/${ut}/${ee}`&&t.headers.get("Content-Type")=="application/json"}static isEvent(t){let e=new URL(t.url);return t.method=="POST"&&e.pathname==`/${ut}/${ne}`&&t.headers.get("Content-Type")=="application/json"}async handler(t){return n.isConfig(t)?await this.handleConfig(t):n.isEvent(t)?await this.handleEvent(t):g({error:"Invalid daemon request"})}async handleConfig(t){let e=await t.json();return sessionStorage.setItem(pt,JSON.stringify(e)),this.dispatchEvent(new CustomEvent(ht.Config,{detail:e})),g({ok:!0})}async handleEvent(t){let{type:e,payload:o}=await t.json();return this.dispatchEvent(new CustomEvent(e,{detail:o})),g({ok:!0})}static getConfig(){let t=sessionStorage.getItem(pt);if(!t)throw"DaemonConfig not ready";return JSON.parse(t)}static getPrivateKey(){let{system:{privateJwk:t}}=n.getConfig();return Promise.resolve(t)}static async getTokenFor(t,e=null,o=null,r=oe,s=[]){let i=n.getConfig();if(!i)throw"Lifecycle configuration not yet available";let{system:{protocol:a,party:l,issuer:c,source:u}}=i,h=new URL(u),p=e?`${a}//${e}`:`${a}//${l}`,y=`${a}//${l}`,S=Date.now(),f={iss:c,aud:p,sub:y,src:o??`${h.origin}${h.pathname}${h.search}`,scope:t,iat:S,exp:S+r,...s.length?{pre:s.map(({sub:Mt,src:Jt})=>({sub:Mt,src:Jt}))}:{}},B=new d(f);return await B.signWith(n.getPrivateKey()),B}static async getStorage(){let t=await n.getStorageToken();return new R(t)}static getStorageToken(){let{system:{party:t}}=n.getConfig(),e={[d.Source.PARTY_CONTROL]:`${d.Capability.GET_ITEM} ${d.Capability.SET_ITEM}`};return n.getTokenFor(e,t)}};var dt=class{token;request;url;protocol;host;constructor(t){this.request=t,this.url=new URL(t.url),this.protocol=H(t),this.host=Y(t),this.token=d.from(t)}async validate(t=!0){if(this.token){await this.token.verifySignatory();let e=this.token.getParty();if(e!==this.host)throw`Token party '${e}' should be '${this.host}'`}if(t&&!this.token)throw"Must provide x-tabserver-token"}assertCapability(t){let{system:{source:e}}=m.getConfig();if(!this.token?.hasCapability(e,t))throw`Token must request capability '${t}' on ${e}`}async handler(){try{return await this.validate(),await this.handle()}catch(t){return console.error(t),g({error:t?t.toString():"Error logged on console"})}}};function gt(n){if(n===null)return n;if(Array.isArray(n))return n.map(gt);if(typeof n=="object"){let t={};for(let[e,o]of Object.entries(n))t[e]=gt(o);return t}return n}function Rn(n){return n!==null}function Pn(n){return n!==void 0}var v=class{#t;#e=1;constructor(t){if(t.post){this.#t=t.post;return}if(!t.url)throw new Error("JsonRpcMcpClient requires post or url");let e=t.fetch??fetch;this.#t=async o=>{let r=typeof t.headers=="function"?await t.headers():t.headers??{};return await(await e(t.url,{method:"POST",headers:se(r),body:JSON.stringify(o)})).json()}}async listTools(){let e=(await this.#n("tools/list",{}))?.tools;return Array.isArray(e)?e:[]}async callTool(t,e={}){let o=await this.#n("tools/call",{name:t,arguments:e});if(o?.isError)throw re(o);return o?.structuredContent??null}async#n(t,e){let o=await this.#t({jsonrpc:"2.0",id:this.#e++,method:t,params:e});if(o.error)throw o.error.message??JSON.stringify(o.error);return o.result}};function re(n){let t=n?.content;if(Array.isArray(t)){let e=t[0];if(typeof e?.text=="string")return e.text}return"MCP tool failed"}function se(n){let t=new Headers(n);return t.set("Content-Type","application/json"),t}var U=class{#t;#e;#n=[];#s=new Map;#o=new Map;constructor(t){this.#t=t.postParty,this.#e=t.postPartyRaw}get toolCatalog(){return this.#n}async refreshCatalog(){let t=await this.#t("/ai/tools/catalog",{});this.setCatalog(t.tools)}setCatalog(t){let e=Array.isArray(t)?t:[];this.#n=e,this.#s=new Map(this.#n.filter(o=>o.tool?.name&&o.route).map(o=>[o.tool.name,o.route])),this.#o.clear()}chatTools(t={}){return[...this.#n.map(ae).filter(mt),...t.clientTools??[]]}async executeToolCalls(t){let e=[];for(let o of t)try{e.push({toolCallId:o.id,name:o.name,content:await this.executeToolCall(o)})}catch(r){e.push({toolCallId:o.id,name:o.name,content:String(r),isError:!0})}return e}async executeToolCall(t){let e=this.#s.get(t.name);if(!e)throw new Error(`No discovered tool named ${t.name}`);if(e.method!=="POST"||!e.path)throw new Error(`Unsupported route for tool ${t.name}`);if(e.kind==="platform"){let o=await this.#t(e.path,t.input);return JSON.stringify(o)}if(e.kind==="mcp")return await this.#r(e,t);throw new Error(`Unsupported route kind for tool ${t.name}`)}async#r(t,e){let o=this.#o.get(t.path);o||(o=new v({post:s=>this.#e(t.path,s)}),this.#o.set(t.path,o));let r=await o.callTool(t.mcpToolName||e.name,{...e.input});return JSON.stringify(r)}},L=class{#t;#e=new Map;constructor(t){this.#t=t}async refreshCatalog(){await Promise.all(this.#t.map(t=>t.runtime.refreshCatalog()))}chatTools(t={}){this.#e.clear();let e=this.#t.map(s=>s.runtime.chatTools().filter(i=>i.execution==="server"&&this.#n(s,i.name))),o=new Map;for(let s of e)for(let i of s)o.set(i.name,(o.get(i.name)??0)+1);let r=[];return this.#t.forEach((s,i)=>{for(let a of e[i]){let c=(o.get(a.name)??0)>1?`${i}__${a.name}`:a.name;this.#e.set(c,{provider:s,realName:a.name}),r.push({...a,name:c})}}),[...r,...t.clientTools??[]]}async executeToolCall(t){let e=this.#e.get(t.name);if(!e)throw new Error(`No discovered tool named ${t.name}`);return await e.provider.runtime.executeToolCall({...t,name:e.realName})}#n(t,e){return!t.allowedTools||t.allowedTools.has(e)}},D=class{#t;#e=[];constructor(t){this.#t=new v({post:t.postRpc})}async refreshCatalog(){let t=await this.#t.listTools();this.#e=t.map(ie).filter(mt)}chatTools(t={}){return[...this.#e,...t.clientTools??[]]}async executeToolCall(t){let e=await this.#t.callTool(t.name,{...t.input});return JSON.stringify(e)}};function ie(n){let t=n;return t?.name?{type:"function",name:t.name,execution:"server",description:t.description,parameters:t.inputSchema}:null}function ae(n){return n?.tool?.name?{type:"function",name:n.tool.name,execution:"server",description:n.tool.description,parameters:n.tool.inputSchema}:null}function kn(n,t){return!t||t===n?n:n?`${t}
8
+ -----END PRIVATE KEY-----`}};var st=class{#t;#e;#o;#s;#n;#r;#l;async initWithKey(t,e,n,r){let s=e===d.Source.PARTY_CONTROL?r:e;this.#e=s.startsWith("https:")?"https:":"http:",this.#o=t,this.#n=e,this.#t=n,this.#s=r,await this.#p()}async checkActivate(){if(!this.#r)throw"checkActivate: No token";let t=new URL(`${this.#r.getAud()}/activate`),e=this.#r.asSignedBase64(),n=this.#r.getParty(),r={},s;try{s=await fetch(t,{method:"POST",headers:{"x-tabserver-token":e,"content-type":"application/json"},body:JSON.stringify(r)})}catch(a){throw console.error(a),`Cannot reach ${n} \u2014 does a daemon provider serve that name?`}let i;try{i=await s.json()}catch(a){throw console.error(a),`Cannot activate ${n}: ${s.status} from ${t.host}`}if(i.error)throw`Cannot activate ${n}: ${i.error}`;return i.ok.isNew===!0}async makeOffer(t,e=null){let{type:n="TRANSIENT",ttl:r=300,expiry:s=30,payload:i}=e??{};if(!this.#r)throw"makeOffer: No token";let a=new URL(`${this.#r.getAud()}/offer`),l=this.#r.asSignedBase64(),c={role:"party",type:n,ttl:r,description:`Offered by ${this.#r.getCounterparty()}`,payload:i,expiry:new Date(Date.now()+1e3*s),flow:t},h=await(await fetch(a,{method:"POST",headers:{"x-tabserver-token":l,"content-type":"application/json"},body:JSON.stringify(c)})).json();if("error"in h)throw h.error;let{claimCode:p,_checkState:y}=h.ok;return this.#l=p,h.ok}async checkState(){if(!this.#r||!this.#l)throw"checkState: No token or claimCode";let t=new URL(`${this.#r.getAud()}/offer/check`);t.searchParams.append("claimCode",this.#l);let e=this.#r.asSignedBase64(),r=await(await fetch(t,{headers:{"x-tabserver-token":e}})).json();if("error"in r)throw r.error;return r.ok.checkState}async confirmClaim(t){if(!this.#r||!this.#l)throw"confirmClaim: No token or claimCode";let e=new URL(`${this.#r.getAud()}/offer/confirm`),n=await this.#r.asSignedBase64(),r={claimCode:this.#l,checkCode:t},i=await(await fetch(e,{method:"POST",headers:{"x-tabserver-token":n,"content-type":"application/json"},body:JSON.stringify(r)})).json();if("error"in i)throw i.error;return i.ok}getChild(){if(!this.#o)throw"getChild: no child";return this.#o}getChildOrigin(){if(!this.#s||!this.#o)throw"getDaemonUrl: no issUrl or daemon";return`${this.#e}//${this.#o}`}async#p(){if(!this.#s||!this.#o||!this.#t)throw"buildToken: missing iss, child or privateJwk";let t=this.#s,e=this.getChildOrigin(),n=new URL(this.#s).origin,r;if(this.#n&&this.#n!==d.Source.PARTY_CONTROL){let a=new URL(this.#n);r=`${a.origin}${a.pathname}${a.search}`}else r=d.Source.PARTY_CONTROL;let s={iss:t,aud:e,sub:n,src:r,scope:{"party:control":"offer"},iat:Date.now(),exp:Date.now()+1e3*60*3},i=new d(s);await i.signWith(Promise.resolve(this.#t)),this.#r=i}};var zt="qrcode",it=class{#t;#e;constructor(t,e){this.#t=t,this.#e=e}generate(){let t=qrcode(0,"L");t.addData(this.#e),t.make();let e=t.createDataURL();return this.#t.classList.add(zt),this.#t.src=e,new Promise((n,r)=>{this.#t.onload=n,this.#t.onerror=r})}};function g(o,t){if("ok"in o){let i=JSON.stringify(o);return new Response(i,{status:200,headers:{...t,"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}let e=o.error,[,n,r]=e.match(/^(\d{3})\s(.+)/)??[null,"200",e],s=JSON.stringify({error:r});return new Response(s,{status:Number(n),headers:{...t,"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}function no(o={error:"404 Not Found"}){let t=JSON.stringify(o);return new Response(t,{status:404,headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}function ro(o,t=[]){return new Response(null,{status:302,headers:{Location:o.toString(),"Access-Control-Allow-Origin":"*",...t}})}function so(o){let{name:t,value:e,domain:n,sameSite:r,path:s="/",expires:i,secure:a=!0,httpOnly:l=!0}=o,c=[];return c.push(`${encodeURIComponent(t)}=${encodeURIComponent(e)}`),n&&c.push(`Domain=${n}`),r&&c.push(`SameSite=${r}`),c.push(`Path=${s}`),i&&c.push(`Expires=${i.toUTCString()}`),a&&c.push("Secure"),l&&c.push("HttpOnly"),c.join("; ")}var at="x-forwarded-host",ct="x-forwarded-proto",lt="x-forwarded-pathname",J="x-tabserver-continuation";function H(o){return o.headers.has(ct)?o.headers.get(ct)+":":new URL(o.url).protocol}function Y(o){return o.headers.has(at)?o.headers.get(at)||"":new URL(o.url).host}function Qt(o){return o.headers.has(lt)?o.headers.get(lt)||"":new URL(o.url).pathname}function Zt(o){let t=H(o),e=Y(o),n=Qt(o);return new URL(`${t}//${e}${n}`)}function ao(o){let t=new URL(o.url),e=Zt(o);return e.search=t.search,e.hash=t.hash,e}function co(o){return new URL(o.url).pathname}function lo(o,t){let e=te(o);return t in e?e[t]:null}function te(o){let t={},e=o.headers.get("Cookie");if(e)for(let n of e.split("; ")){let[r,s]=n.split("=");t[r]=s}return t}var ut="daemon",ee="config",oe="event",ht={Config:"config"},pt="config",ne=1e3*60*60,m=class o extends EventTarget{static#t=new o;static Ev=ht;static getInstance(){return this.#t}static shouldHandle(t){return o.isConfig(t)||o.isEvent(t)}static isConfig(t){let e=new URL(t.url);return t.method=="POST"&&e.pathname==`/${ut}/${ee}`&&t.headers.get("Content-Type")=="application/json"}static isEvent(t){let e=new URL(t.url);return t.method=="POST"&&e.pathname==`/${ut}/${oe}`&&t.headers.get("Content-Type")=="application/json"}async handler(t){return o.isConfig(t)?await this.handleConfig(t):o.isEvent(t)?await this.handleEvent(t):g({error:"Invalid daemon request"})}async handleConfig(t){let e=await t.json();return sessionStorage.setItem(pt,JSON.stringify(e)),this.dispatchEvent(new CustomEvent(ht.Config,{detail:e})),g({ok:!0})}async handleEvent(t){let{type:e,payload:n}=await t.json();return this.dispatchEvent(new CustomEvent(e,{detail:n})),g({ok:!0})}static getConfig(){let t=sessionStorage.getItem(pt);if(!t)throw"DaemonConfig not ready";return JSON.parse(t)}static getPrivateKey(){let{system:{privateJwk:t}}=o.getConfig();return Promise.resolve(t)}static async getTokenFor(t,e=null,n=null,r=ne,s=[]){let i=o.getConfig();if(!i)throw"Lifecycle configuration not yet available";let{system:{protocol:a,party:l,issuer:c,source:u}}=i,h=new URL(u),p=e?`${a}//${e}`:`${a}//${l}`,y=`${a}//${l}`,S=Date.now(),f={iss:c,aud:p,sub:y,src:n??`${h.origin}${h.pathname}${h.search}`,scope:t,iat:S,exp:S+r,...s.length?{pre:s.map(({sub:Mt,src:Jt})=>({sub:Mt,src:Jt}))}:{}},B=new d(f);return await B.signWith(o.getPrivateKey()),B}static async getStorage(){let t=await o.getStorageToken();return new R(t)}static getStorageToken(){let{system:{party:t}}=o.getConfig(),e={[d.Source.PARTY_CONTROL]:`${d.Capability.GET_ITEM} ${d.Capability.SET_ITEM}`};return o.getTokenFor(e,t)}};var dt=class{token;request;url;protocol;host;constructor(t){this.request=t,this.url=new URL(t.url),this.protocol=H(t),this.host=Y(t),this.token=d.from(t)}async validate(t=!0){if(this.token){await this.token.verifySignatory();let e=this.token.getParty();if(e!==this.host)throw`Token party '${e}' should be '${this.host}'`}if(t&&!this.token)throw"Must provide x-tabserver-token"}assertCapability(t){let{system:{source:e}}=m.getConfig();if(!this.token?.hasCapability(e,t))throw`Token must request capability '${t}' on ${e}`}async handler(){try{return await this.validate(),await this.handle()}catch(t){return console.error(t),g({error:t?t.toString():"Error logged on console"})}}};function gt(o){if(o===null)return o;if(Array.isArray(o))return o.map(gt);if(typeof o=="object"){let t={};for(let[e,n]of Object.entries(o))t[e]=gt(n);return t}return o}function Ro(o){return o!==null}function Po(o){return o!==void 0}var v=class{#t;#e=1;constructor(t){if(t.post){this.#t=t.post;return}if(!t.url)throw new Error("JsonRpcMcpClient requires post or url");let e=t.fetch??fetch;this.#t=async n=>{let r=typeof t.headers=="function"?await t.headers():t.headers??{};return await(await e(t.url,{method:"POST",headers:se(r),body:JSON.stringify(n)})).json()}}async listTools(){let e=(await this.#o("tools/list",{}))?.tools;return Array.isArray(e)?e:[]}async callTool(t,e={}){let n=await this.#o("tools/call",{name:t,arguments:e});if(n?.isError)throw re(n);return n?.structuredContent??null}async#o(t,e){let n=await this.#t({jsonrpc:"2.0",id:this.#e++,method:t,params:e});if(n.error)throw n.error.message??JSON.stringify(n.error);return n.result}};function re(o){let t=o?.content;if(Array.isArray(t)){let e=t[0];if(typeof e?.text=="string")return e.text}return"MCP tool failed"}function se(o){let t=new Headers(o);return t.set("Content-Type","application/json"),t}var U=class{#t;#e;#o=[];#s=new Map;#n=new Map;constructor(t){this.#t=t.postParty,this.#e=t.postPartyRaw}get toolCatalog(){return this.#o}async refreshCatalog(){let t=await this.#t("/ai/tools/catalog",{});this.setCatalog(t.tools)}setCatalog(t){let e=Array.isArray(t)?t:[];this.#o=e,this.#s=new Map(this.#o.filter(n=>n.tool?.name&&n.route).map(n=>[n.tool.name,n.route])),this.#n.clear()}chatTools(t={}){return[...this.#o.map(ae).filter(mt),...t.clientTools??[]]}async executeToolCalls(t){let e=[];for(let n of t)try{e.push({toolCallId:n.id,name:n.name,content:await this.executeToolCall(n)})}catch(r){e.push({toolCallId:n.id,name:n.name,content:String(r),isError:!0})}return e}async executeToolCall(t){let e=this.#s.get(t.name);if(!e)throw new Error(`No discovered tool named ${t.name}`);if(e.method!=="POST"||!e.path)throw new Error(`Unsupported route for tool ${t.name}`);if(e.kind==="platform"){let n=await this.#t(e.path,t.input);return JSON.stringify(n)}if(e.kind==="mcp")return await this.#r(e,t);throw new Error(`Unsupported route kind for tool ${t.name}`)}async#r(t,e){let n=this.#n.get(t.path);n||(n=new v({post:s=>this.#e(t.path,s)}),this.#n.set(t.path,n));let r=await n.callTool(t.mcpToolName||e.name,{...e.input});return JSON.stringify(r)}},L=class{#t;#e=new Map;constructor(t){this.#t=t}async refreshCatalog(){await Promise.all(this.#t.map(t=>t.runtime.refreshCatalog()))}chatTools(t={}){this.#e.clear();let e=this.#t.map(s=>s.runtime.chatTools().filter(i=>i.execution==="server"&&this.#o(s,i.name))),n=new Map;for(let s of e)for(let i of s)n.set(i.name,(n.get(i.name)??0)+1);let r=[];return this.#t.forEach((s,i)=>{for(let a of e[i]){let c=(n.get(a.name)??0)>1?`${i}__${a.name}`:a.name;this.#e.set(c,{provider:s,realName:a.name}),r.push({...a,name:c})}}),[...r,...t.clientTools??[]]}async executeToolCall(t){let e=this.#e.get(t.name);if(!e)throw new Error(`No discovered tool named ${t.name}`);return await e.provider.runtime.executeToolCall({...t,name:e.realName})}#o(t,e){return!t.allowedTools||t.allowedTools.has(e)}},D=class{#t;#e=[];constructor(t){this.#t=new v({post:t.postRpc})}async refreshCatalog(){let t=await this.#t.listTools();this.#e=t.map(ie).filter(mt)}chatTools(t={}){return[...this.#e,...t.clientTools??[]]}async executeToolCall(t){let e=await this.#t.callTool(t.name,{...t.input});return JSON.stringify(e)}};function ie(o){let t=o;return t?.name?{type:"function",name:t.name,execution:"server",description:t.description,parameters:t.inputSchema}:null}function ae(o){return o?.tool?.name?{type:"function",name:o.tool.name,execution:"server",description:o.tool.description,parameters:o.tool.inputSchema}:null}function ko(o,t){return!t||t===o?o:o?`${t}
9
9
 
10
- ${n}`:t}function mt(n){return n!=null}var ce="2025-06-18",F={"Access-Control-Allow-Origin":"*"},le="POST, GET",ft=class{#t;constructor(t){this.#t=t}listTools(){return this.#t.map(t=>({name:t.name,...t.title===void 0?{}:{title:t.title},description:t.description,inputSchema:t.inputSchema,...t.outputSchema===void 0?{}:{outputSchema:t.outputSchema},...t.annotations===void 0?{}:{annotations:t.annotations}}))}async callTool(t,e,o){let r=this.#t.find(s=>s.name===t);if(!r)throw new w(-32602,`Unknown tool: ${t}`);return await r.call(e,o)}},j=class{#t;#e;#n;constructor(t,e){this.#t=t,typeof e=="function"?(this.#e=e,this.#n={name:"mcp-server",version:"1"}):(this.#e=e.context,this.#n=e.serverInfo??{name:"mcp-server",version:"1"})}async handle(t){if(t.method==="GET")return he(t);if(t.method==="DELETE"||t.method!=="POST")return wt();let e;try{e=await t.json()}catch{return k(G(null,-32700,"Parse error"))}let o=pe(e.id);if(e.jsonrpc!=="2.0"||typeof e.method!="string")return k(G(o,-32600,"Invalid Request"));if(e.id===void 0)return ue();try{let r=await this.#s(e.method,e.params,t);return k({jsonrpc:"2.0",id:o,result:r})}catch(r){return r instanceof w?k(G(o,r.code,r.message)):k(G(o,-32603,String(r)))}}async#s(t,e,o){switch(t){case"initialize":return{protocolVersion:ce,capabilities:{tools:{listChanged:!1}},serverInfo:this.#n};case"notifications/initialized":return{};case"tools/list":return{tools:await this.#t.listTools(this.#e(o))};case"tools/call":return await this.#o(e,o);default:throw new w(-32601,`Method not found: ${t}`)}}async#o(t,e){if(!t||typeof t!="object"||Array.isArray(t))throw new w(-32602,"tools/call params must be an object");let{name:o,arguments:r={}}=t;if(typeof o!="string"||!r||typeof r!="object"||Array.isArray(r))throw new w(-32602,"Invalid tools/call params");try{let s=await this.#t.callTool(o,r,this.#e(e));return yt(s)}catch(s){if(s instanceof w)throw s;return yt({error:String(s)},!0)}}},w=class extends Error{code;constructor(t,e){super(e),this.code=t}};function yt(n,t=!1){return{content:[{type:"text",text:typeof n=="string"?n:JSON.stringify(n)}],structuredContent:n,isError:t}}function G(n,t,e){return{jsonrpc:"2.0",id:n,error:{code:t,message:e}}}function k(n){return new Response(JSON.stringify(n),{headers:{...F,"Content-Type":"application/json"}})}function ue(){return new Response(null,{status:202,headers:F})}function he(n){let t=new URL(n.url);return new Response(`event: endpoint
10
+ ${o}`:t}function mt(o){return o!=null}var ce="2025-06-18",F={"Access-Control-Allow-Origin":"*"},le="POST, GET",ft=class{#t;constructor(t){this.#t=t}listTools(){return this.#t.map(t=>({name:t.name,...t.title===void 0?{}:{title:t.title},description:t.description,inputSchema:t.inputSchema,...t.outputSchema===void 0?{}:{outputSchema:t.outputSchema},...t.annotations===void 0?{}:{annotations:t.annotations}}))}async callTool(t,e,n){let r=this.#t.find(s=>s.name===t);if(!r)throw new w(-32602,`Unknown tool: ${t}`);return await r.call(e,n)}},j=class{#t;#e;#o;constructor(t,e){this.#t=t,typeof e=="function"?(this.#e=e,this.#o={name:"mcp-server",version:"1"}):(this.#e=e.context,this.#o=e.serverInfo??{name:"mcp-server",version:"1"})}async handle(t){if(t.method==="GET")return he(t);if(t.method==="DELETE"||t.method!=="POST")return wt();let e;try{e=await t.json()}catch{return k(G(null,-32700,"Parse error"))}let n=pe(e.id);if(e.jsonrpc!=="2.0"||typeof e.method!="string")return k(G(n,-32600,"Invalid Request"));if(e.id===void 0)return ue();try{let r=await this.#s(e.method,e.params,t);return k({jsonrpc:"2.0",id:n,result:r})}catch(r){return r instanceof w?k(G(n,r.code,r.message)):k(G(n,-32603,String(r)))}}async#s(t,e,n){switch(t){case"initialize":return{protocolVersion:ce,capabilities:{tools:{listChanged:!1}},serverInfo:this.#o};case"notifications/initialized":return{};case"tools/list":return{tools:await this.#t.listTools(this.#e(n))};case"tools/call":return await this.#n(e,n);default:throw new w(-32601,`Method not found: ${t}`)}}async#n(t,e){if(!t||typeof t!="object"||Array.isArray(t))throw new w(-32602,"tools/call params must be an object");let{name:n,arguments:r={}}=t;if(typeof n!="string"||!r||typeof r!="object"||Array.isArray(r))throw new w(-32602,"Invalid tools/call params");try{let s=await this.#t.callTool(n,r,this.#e(e));return yt(s)}catch(s){if(s instanceof w)throw s;return yt({error:String(s)},!0)}}},w=class extends Error{code;constructor(t,e){super(e),this.code=t}};function yt(o,t=!1){return{content:[{type:"text",text:typeof o=="string"?o:JSON.stringify(o)}],structuredContent:o,isError:t}}function G(o,t,e){return{jsonrpc:"2.0",id:o,error:{code:t,message:e}}}function k(o){return new Response(JSON.stringify(o),{headers:{...F,"Content-Type":"application/json"}})}function ue(){return new Response(null,{status:202,headers:F})}function he(o){let t=new URL(o.url);return new Response(`event: endpoint
11
11
  data: ${t.pathname}
12
12
 
13
- `,{headers:{...F,"Content-Type":"text/event-stream","Cache-Control":"no-cache"}})}function wt(){return new Response(null,{status:405,headers:{...F,Allow:le}})}function pe(n){return typeof n=="string"||typeof n=="number"||n===null?n:null}var W="application/x-ndjson",K=class extends Array{#t;constructor(t){super(),this.#t=t}static get[Symbol.species](){return Array}push(...t){for(let e of t)this.#t?.(e);return super.push(...t)}};function q(n,t){de(n,t.reasoning),t.content?n.push({role:"assistant",content:t.content}):t.toolCalls?.length||n.push({role:"assistant",content:""})}function de(n,t){for(let e of t??[])e.redacted||!e.text||n.push({role:"thinking",content:e.text})}function X(n,t){return`${t?"Client tool call":"Agent tool call"}: ${n.name}
14
- ${JSON.stringify(n.input,null,2)}`}function A(n,t,e,o,r=!1){o&&n.push({role:"tool-result",content:ge(t,e,r),...r?{error:!0}:{}})}function ge(n,t,e=!1){return`${e?"Tool error":"Tool result"}: ${n}
15
- ${t}`}function Ct(n,t={}){let e=t.toolDetails??!0,o=t.clientToolNames,r=[];for(let s of n)if(s.role==="assistant"){if(q(r,s),e)for(let i of s.toolCalls??[])r.push({role:"tool",content:X(i,o?.has(i.name)??!1)})}else if(s.role==="tool")for(let i of s.toolResults??[])A(r,i.name??"tool",i.content,e,i.isError);else s.role==="user"&&s.content&&r.push({role:"user",content:s.content});return r}var me="useTools",fe=/[\s,;\|]+/;function Rt(n){let{token:t,providerSource:e,toolName:o,capability:r,providerYaml:s}=n;if(!t)return!1;if(Tt(t,e,r))return!0;if(!s)return!1;let i=String(t.getSourceUrl());return Tt(t,i,me)&&ye(s,o,r)&&we(s.grant,t.getCounterparty(),t.getSrc(),r)}function Tt(n,t,e){try{return n.hasCapability(t,e)}catch{return!1}}function ye(n,t,e){return!!n.mcp?.tools.some(o=>o.name===t&&o.capability===e)}function we(n,t,e,o){for(let r in n??{}){if(!St(t.toLowerCase(),r.toLowerCase()))continue;let s=n[r];if(Array.isArray(s)){if(s.includes(o))return!0;continue}for(let i in s)if(St(e,i)&&Ce(s[i]).includes(o))return!0}return!1}function Ce(n){return n.split(fe).filter(t=>t.length>0)}function St(n,t){return new RegExp(`^${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/%/g,".*").replace(/_/g,".")}$`).test(n)}var Te=4,Se=.2,Pt=d.TOKEN_HEADER,bt=class{#t;#e;#n;#s;#o;#r;#l;#p;#h;#a=new Map;#u=new Map;#f=new m;#i;#y;constructor(t){this.#t=t.targetScope,this.#e=t.defaultSystemPrompt,this.#n=t.defaultTemperature??Se,this.#s=t.defaultModel,this.#o=t.maxToolRounds??Te,this.#r=t.mcpPath??"/rpc",this.#l=t.resolveToolProviders,this.#p=t.resolveMemorySelection,this.#h=t.resolveStructuredMemorySelection,this.#i={temperature:this.#n,toolsEnabled:!0,toolDetails:!0,thinking:t.defaultThinking??!1},this.#y=new j(new Q(this),{context:Me,serverInfo:{name:"ai-chat-expert",version:"1"}})}async handler(t){if(m.shouldHandle(t))return await this.#f.handler(t);try{if(t.method!=="POST")throw"405 Method Not Allowed";let e=new URL(t.url);if(e.pathname===this.#r)return await this.#y.handle(t);switch(e.pathname){case"/session":return g({ok:await this.#_(t)});case"/settings":return g({ok:await this.#B(t)});case"/models":return g({ok:await this.#V(t)});case"/chats":return g({ok:await this.#H(t)});case"/send":return this.#w(t)?this.#m(o=>this.#M(t,o)):g({ok:await this.#M(t,[])});case"/client-tool-results":return this.#w(t)?this.#m(o=>this.#U(t,o)):g({ok:await this.#U(t,[])});case"/close":return g({ok:await this.#Y(t)});case"/delete":return g({ok:await this.#W(t)});default:throw"404 Not Found"}}catch(e){return console.error(e),g({error:String(e)})}}#w(t){return t.headers.get("Accept")?.includes(W)??!1}#m(t){let e=new TextEncoder,o=new ReadableStream({start:async r=>{let s=a=>r.enqueue(e.encode(`${JSON.stringify(a)}
16
- `)),i=new K(a=>s({type:"event",event:a}));try{let a=await t(i);s({type:"done",...a.clientToolCalls?.length?{clientToolCalls:a.clientToolCalls}:{}})}catch(a){console.error(a),s({type:"error",message:String(a)})}finally{r.close()}}});return new Response(o,{status:200,headers:{"Content-Type":W,"Cache-Control":"no-cache","Access-Control-Allow-Origin":"*"}})}async askExpert(t,e){let o=e.trim();if(!o)throw"Question is required";let r=this.#N(void 0),s=T(t),i=await this.#R(r,{expert:!0},s),a=this.#i.temperature,l=t.headers.get(J),c=l?xe(t,l):null;if(c)return await this.#C(t,r,s,c,i,a,o);let u=await this.#d(t,r,void 0,i,a);try{return{answer:await this.#T(u,o,a)}}finally{this.#a.delete(C(t,u.targetParty,u.chatId)),await this.#c(u.targetParty,"/ai/chat/close",{chatId:u.chatId},u.forward).catch(h=>console.error(h))}}async#C(t,e,o,r,s,i,a){let l=this.#u.get(r);try{let c=await this.#d(t,e,l,s,i);return l||this.#u.set(r,c.chatId),{answer:await this.#T(c,a,i)}}catch(c){if(l&&await this.#b(e,l,o)){this.#u.delete(r),this.#a.delete(C(t,e,l));let u=await this.#d(t,e,void 0,s,i);return this.#u.set(r,u.chatId),{answer:await this.#T(u,a,i)}}throw c}finally{let c=this.#u.get(r);c&&this.#a.delete(C(t,e,c))}}async askExpertConversation(t,e,o,r){let s=e.trim();if(!s)throw"Question is required";let i=this.#N(void 0),a=T(t),l=await this.#R(i,{expert:!0},a),c=this.#i.temperature,u=a.continuation,h=u?At(o,u):r?kt(o,r):null,p=h?this.#u.get(h):void 0;!p&&!u&&r&&(await this.#X(i,r,o,a),p=r);let y=async S=>{let f=await this.#d(t,i,S,l,c);this.#u.set(kt(o,f.chatId),f.chatId),u&&this.#u.set(At(o,u),f.chatId);try{return{answer:await this.#T(f,s,c),conversationId:f.chatId}}finally{this.#a.delete(C(t,i,f.chatId))}};try{return await y(p)}catch(S){if(p&&await this.#b(i,p,a)){if(h&&this.#u.delete(h),this.#a.delete(C(t,i,p)),!u&&r)throw Ot(r);return await y(void 0)}throw S}}async#T(t,e,o){z(t),t.toolRounds=0,await this.#S(t);let r=[],s=await this.#c(t.targetParty,"/ai/chat/send",{chatId:t.chatId,message:e,options:this.#k(t,this.#i.toolsEnabled,o)},t.forward),i=await this.#P(t,s.message,this.#i.toolsEnabled,!1,o,r);if(i.clientToolCalls?.length)throw"Expert MCP cannot execute browser client tools";let a=Ue(i.events);if(!a)throw"Expert did not return an answer";return a}async#M(t,e){let o=await xt(t);if(typeof o.message!="string"||!o.message.trim())throw"Message is required";let r=o.message.trim(),s=this.#F(o),i=this.#E(o),a=this.#O(o),l=this.#g(o),c=O(o),u=await this.#d(t,l,c,void 0,a,this.#j(o));return z(u),u.toolRounds=0,vt(u,o),s&&await this.#S(u),await this.#J(e,async()=>{let h=await this.#c(u.targetParty,"/ai/chat/send",{chatId:u.chatId,message:r,options:this.#k(u,s,a)},u.forward);return await this.#P(u,h.message,s,i,a,e)})}async#J(t,e){try{return await e()}catch(o){return t.push({role:"assistant",content:String(o),error:!0}),{events:t}}}async#U(t,e){let o=await xt(t),r=this.#F(o),s=this.#E(o),i=this.#O(o),a=this.#g(o),l=O(o),c=await this.#d(t,a,l,void 0,i);vt(c,o);let u=Pe(c,o.toolResults);for(let p of u)A(e,p.name??"client_tool",p.content,s,p.isError);let h=[...c.pendingToolResults,...u];return z(c),await this.#J(e,()=>this.#L(c,h,r,s,i,e))}async#P(t,e,o,r,s,i){let a=e;for(;;){q(i,a);let l=a.toolCalls??[];if(!l.length)return{events:i};if(t.toolRounds>=this.#o)return i.push({role:"tool-result",content:"Stopped after too many tool rounds.",error:!0}),{events:i};let{toolResults:c,clientToolCalls:u}=await Ne(t,l,r,i);if(u.length)return t.pendingClientToolCalls=new Map(u.map(p=>[p.id,p])),t.pendingToolResults=c,{events:i,clientToolCalls:u};let h=await this.#L(t,c,o,r,s,i);return h.clientToolCalls?.length,h}}async#L(t,e,o,r,s,i){if(t.toolRounds>=this.#o)return i.push({role:"tool-result",content:"Stopped after too many tool rounds.",error:!0}),{events:i};t.toolRounds++;let a=await this.#c(t.targetParty,"/ai/chat/send",{chatId:t.chatId,message:{role:"user",content:"",toolResults:e},options:this.#k(t,o,s)},t.forward);return await this.#P(t,a.message,o,r,s,i)}async#_(t){let e=await P(t),o=this.#g(e),r=O(e),s=T(t),i=await this.#d(t,o,r,r?void 0:await this.#tt(e,o,s),this.#O(e),this.#j(e));It(i,e.clientTools),await this.#S(i);let a=await this.#q(i);return{chatId:i.chatId,history:a,historyEvents:Ct(a,{toolDetails:this.#E(e),clientToolNames:i.clientToolNames}),closed:r?await this.#b(o,r,s):null}}async#B(t){let e=await P(t);return Object.keys(e).length&&this.#st(e),this.#rt()}async#V(t){let e=await P(t),o=this.#g(e),r=await this.#c(o,"/ai/chat/models",{},T(t));return{models:Array.isArray(r.models)?r.models:[]}}async#H(t){let e=await P(t),o=this.#g(e),r=await this.#c(o,"/ai/chat/list",{},T(t));return{chats:Array.isArray(r.chats)?r.chats:[]}}async#Y(t){let e=await P(t),o=this.#g(e),r=O(e);if(!r)throw"chatId is required";let s=T(t),i=C(t,o,r),a=this.#a.get(i);return a?(await this.#c(a.targetParty,"/ai/chat/close",{chatId:a.chatId},a.forward),this.#a.delete(i),!0):(await this.#c(o,"/ai/chat/close",{chatId:r},s),!0)}async#W(t){let e=await P(t),o=this.#g(e),r=O(e);if(!r)throw"chatId is required";let s=C(t,o,r);return await this.#c(o,"/ai/chat/delete",{chatId:r},T(t)),this.#a.delete(s),!0}async#d(t,e,o,r,s=this.#n,i=this.#s){let a=C(t,e,o);if(o){let h=this.#a.get(a);if(h)return h}let l=T(t),c=o?{id:o}:await this.#c(e,"/ai/chat/create",{system:r??await this.#R(e,{expert:!1},l),temperature:s,...i?{model:i}:{}},l);l.continuation??=String(c.id),a=C(t,e,String(c.id));let u={chatId:String(c.id),targetParty:e,forward:l,toolRuntime:await this.#Q(e,l),clientTools:[],clientToolNames:new Set,pendingClientToolCalls:new Map,pendingToolResults:[],toolRounds:0};return await this.#S(u),this.#a.set(a,u),u}async#q(t){let e=await this.#c(t.targetParty,"/ai/chat/history",{chatId:t.chatId},t.forward);return Array.isArray(e.messages)?e.messages:[]}async#D(t,e,o){let r=await this.#c(t,"/ai/chat/list",{},o);return(Array.isArray(r.chats)?r.chats:[]).find(i=>i.id===e)??null}async#b(t,e,o){let r=await this.#D(t,e,o);return typeof r?.closed=="string"?r.closed:null}async#X(t,e,o,r){let s=o.split(`
17
- `)[0],i=await this.#D(t,e,r),a=Array.isArray(i?.parties)?i.parties:[];if(!i||!a.includes(s))throw`Unknown or expired conversationId '${e}'. Omit conversationId to start a new conversation.`;if(typeof i.closed=="string")throw Ot(e)}#G(t,e,o,r,s){return new U({postParty:(i,a)=>this.#c(t,i,this.#z(i,a,r,s),e,o),postPartyRaw:(i,a)=>this.#A(t,i,a,e,o)})}#z(t,e,o,r){if(t!=="/ai/memory/catalog")return e;let s=e.kind==="structured"?r:o;return s?{...e,collections:s}:e}async#x(t,e){if(this.#p&&t===m.getConfig().system.party)return await this.#p(t,e??{pre:[],continuation:null})}async#v(t,e){if(this.#h&&t===m.getConfig().system.party)return await this.#h(t,e??{pre:[],continuation:null})}async#Q(t,e){let o=await this.#l?.(t,e);if(!o?.length)return this.#G(t,e,void 0,await this.#x(t,e),await this.#v(t,e));let r=m.getConfig().system.party;return new L(await Promise.all(o.map(async s=>({key:s.party,runtime:s.party===r?this.#G(s.party,e,s.scope,await this.#x(s.party,e),await this.#v(s.party,e)):this.#Z(s.party,e),allowedTools:s.tools?new Set(s.tools):void 0}))))}#Z(t,e){return new D({postRpc:o=>this.#A(t,"/mcp/rpc",o,e)})}async#S(t){await t.toolRuntime.refreshCatalog()}#k(t,e,o){let r=this.#i.thinking,s={temperature:o,thinking:r};if(!e)return s;let i=t.toolRuntime.chatTools({clientTools:t.clientTools});return i.length?{...s,tools:i,toolChoice:"auto"}:s}async#c(t,e,o,r,s){let i=await this.#A(t,e,o,r,s);if("error"in i)throw i.error;return i.ok}async#A(t,e,o,r,s){let i=m.getConfig(),a=new URL(i.system.source),l=`${a.origin}${a.pathname}${a.search}`,c=new URL(`${i.system.protocol}//${i.system.party}`).host,u=(r?.pre??[]).filter(f=>!(f.sub===c&&f.src===l)),h=await m.getTokenFor({[i.system.source]:s??this.#t},t,null,void 0,u),p=`${i.system.protocol}//${t}${e}`,y={"Content-Type":"application/json","X-Tabserver-Token":h.asSignedBase64()};return r?.continuation&&(y[J]=r.continuation),await(await fetch(p,{method:"POST",headers:y,body:JSON.stringify(o)})).json()}async#tt(t,e,o){let r=typeof t.systemPrompt=="string"&&t.systemPrompt.trim()?t.systemPrompt.trim():this.#$();return await this.#R(e,{basePrompt:r,expert:!1},o)}#j(t){return typeof t.model=="string"&&t.model.trim()?t.model.trim():void 0}#O(t){return typeof t.temperature=="number"&&Number.isFinite(t.temperature)&&t.temperature>=0&&t.temperature<=2?Math.round(t.temperature*10)/10:this.#i.temperature}#F(t){return typeof t.toolsEnabled=="boolean"?t.toolsEnabled:this.#i.toolsEnabled}#E(t){return typeof t.toolDetails=="boolean"?t.toolDetails:this.#i.toolDetails}#g(t){return this.#N(t.targetParty)}#N(t){let{system:{party:e,protocol:o}}=m.getConfig();if(t==null||t==="")return e;if(typeof t!="string")throw"targetParty must be a string";let r=t.trim();if(!r)return e;try{let s=r.includes("://")?new URL(r):new URL(`${o}//${r}`);if(!s.host)throw"missing host";return s.host}catch{throw`Invalid targetParty: ${t}`}}async#R(t,e,o){let r=e.basePrompt??this.#$(),s=await Ge(),i=e.expert&&s?`
18
- When answering expert MCP questions, prefer semantic and structured memory under root "${s}" when looking up remembered information.`:"",a=await this.#et(t,o),l=await this.#ot(t,o);return`${r}${i}${a}${l}`}async#et(t,e){try{let o=await this.#x(t,e),r=Z(),s=r?await this.#nt(t,r,e,o):await this.#I(t,{collections:o},e);return Le(s)}catch{return`
13
+ `,{headers:{...F,"Content-Type":"text/event-stream","Cache-Control":"no-cache"}})}function wt(){return new Response(null,{status:405,headers:{...F,Allow:le}})}function pe(o){return typeof o=="string"||typeof o=="number"||o===null?o:null}var W="application/x-ndjson",K=class extends Array{#t;constructor(t){super(),this.#t=t}static get[Symbol.species](){return Array}push(...t){for(let e of t)this.#t?.(e);return super.push(...t)}};function q(o,t){de(o,t.reasoning),t.content?o.push({role:"assistant",content:t.content}):t.toolCalls?.length||o.push({role:"assistant",content:""})}function de(o,t){for(let e of t??[])e.redacted||!e.text||o.push({role:"thinking",content:e.text})}function X(o,t){return`${t?"Client tool call":"Agent tool call"}: ${o.name}
14
+ ${JSON.stringify(o.input,null,2)}`}function A(o,t,e,n,r=!1){n&&o.push({role:"tool-result",content:ge(t,e,r),...r?{error:!0}:{}})}function ge(o,t,e=!1){return`${e?"Tool error":"Tool result"}: ${o}
15
+ ${t}`}function Ct(o,t={}){let e=t.toolDetails??!0,n=t.clientToolNames,r=[];for(let s of o)if(s.role==="assistant"){if(q(r,s),e)for(let i of s.toolCalls??[])r.push({role:"tool",content:X(i,n?.has(i.name)??!1)})}else if(s.role==="tool")for(let i of s.toolResults??[])A(r,i.name??"tool",i.content,e,i.isError);else s.role==="user"&&s.content&&r.push({role:"user",content:s.content});return r}var me="useTools",fe=/[\s,;\|]+/;function Rt(o){let{token:t,providerSource:e,toolName:n,capability:r,providerYaml:s}=o;if(!t)return!1;if(Tt(t,e,r))return!0;if(!s)return!1;let i=String(t.getSourceUrl());return Tt(t,i,me)&&ye(s,n,r)&&we(s.grant,t.getCounterparty(),t.getSrc(),r)}function Tt(o,t,e){try{return o.hasCapability(t,e)}catch{return!1}}function ye(o,t,e){return!!o.mcp?.tools.some(n=>n.name===t&&n.capability===e)}function we(o,t,e,n){for(let r in o??{}){if(!St(t.toLowerCase(),r.toLowerCase()))continue;let s=o[r];if(Array.isArray(s)){if(s.includes(n))return!0;continue}for(let i in s)if(St(e,i)&&Ce(s[i]).includes(n))return!0}return!1}function Ce(o){return o.split(fe).filter(t=>t.length>0)}function St(o,t){return new RegExp(`^${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/%/g,".*").replace(/_/g,".")}$`).test(o)}var Te=4,Se=.2,Pt=d.TOKEN_HEADER,bt=class{#t;#e;#o;#s;#n;#r;#l;#p;#h;#a=new Map;#u=new Map;#f=new m;#i;#y;constructor(t){this.#t=t.targetScope,this.#e=t.defaultSystemPrompt,this.#o=t.defaultTemperature??Se,this.#s=t.defaultModel,this.#n=t.maxToolRounds??Te,this.#r=t.mcpPath??"/rpc",this.#l=t.resolveToolProviders,this.#p=t.resolveMemorySelection,this.#h=t.resolveStructuredMemorySelection,this.#i={temperature:this.#o,toolsEnabled:!0,toolDetails:!0,thinking:t.defaultThinking??!1},this.#y=new j(new Q(this),{context:Me,serverInfo:{name:"ai-chat-expert",version:"1"}})}async handler(t){if(m.shouldHandle(t))return await this.#f.handler(t);try{if(t.method!=="POST")throw"405 Method Not Allowed";let e=new URL(t.url);if(e.pathname===this.#r)return await this.#y.handle(t);switch(e.pathname){case"/session":return g({ok:await this.#_(t)});case"/settings":return g({ok:await this.#B(t)});case"/models":return g({ok:await this.#V(t)});case"/chats":return g({ok:await this.#H(t)});case"/send":return this.#w(t)?this.#m(n=>this.#M(t,n)):g({ok:await this.#M(t,[])});case"/client-tool-results":return this.#w(t)?this.#m(n=>this.#U(t,n)):g({ok:await this.#U(t,[])});case"/close":return g({ok:await this.#Y(t)});case"/delete":return g({ok:await this.#W(t)});default:throw"404 Not Found"}}catch(e){return console.error(e),g({error:String(e)})}}#w(t){return t.headers.get("Accept")?.includes(W)??!1}#m(t){let e=new TextEncoder,n=new ReadableStream({start:async r=>{let s=a=>r.enqueue(e.encode(`${JSON.stringify(a)}
16
+ `)),i=new K(a=>s({type:"event",event:a}));try{let a=await t(i);s({type:"done",...a.clientToolCalls?.length?{clientToolCalls:a.clientToolCalls}:{}})}catch(a){console.error(a),s({type:"error",message:String(a)})}finally{r.close()}}});return new Response(n,{status:200,headers:{"Content-Type":W,"Cache-Control":"no-cache","Access-Control-Allow-Origin":"*"}})}async askExpert(t,e){let n=e.trim();if(!n)throw"Question is required";let r=this.#N(void 0),s=T(t),i=await this.#R(r,{expert:!0},s),a=this.#i.temperature,l=t.headers.get(J),c=l?xe(t,l):null;if(c)return await this.#C(t,r,s,c,i,a,n);let u=await this.#d(t,r,void 0,i,a);try{return{answer:await this.#T(u,n,a)}}finally{this.#a.delete(C(t,u.targetParty,u.chatId)),await this.#c(u.targetParty,"/ai/chat/close",{chatId:u.chatId},u.forward).catch(h=>console.error(h))}}async#C(t,e,n,r,s,i,a){let l=this.#u.get(r);try{let c=await this.#d(t,e,l,s,i);return l||this.#u.set(r,c.chatId),{answer:await this.#T(c,a,i)}}catch(c){if(l&&await this.#b(e,l,n)){this.#u.delete(r),this.#a.delete(C(t,e,l));let u=await this.#d(t,e,void 0,s,i);return this.#u.set(r,u.chatId),{answer:await this.#T(u,a,i)}}throw c}finally{let c=this.#u.get(r);c&&this.#a.delete(C(t,e,c))}}async askExpertConversation(t,e,n,r){let s=e.trim();if(!s)throw"Question is required";let i=this.#N(void 0),a=T(t),l=await this.#R(i,{expert:!0},a),c=this.#i.temperature,u=a.continuation,h=u?At(n,u):r?kt(n,r):null,p=h?this.#u.get(h):void 0;!p&&!u&&r&&(await this.#X(i,r,n,a),p=r);let y=async S=>{let f=await this.#d(t,i,S,l,c);this.#u.set(kt(n,f.chatId),f.chatId),u&&this.#u.set(At(n,u),f.chatId);try{return{answer:await this.#T(f,s,c),conversationId:f.chatId}}finally{this.#a.delete(C(t,i,f.chatId))}};try{return await y(p)}catch(S){if(p&&await this.#b(i,p,a)){if(h&&this.#u.delete(h),this.#a.delete(C(t,i,p)),!u&&r)throw Ot(r);return await y(void 0)}throw S}}async#T(t,e,n){z(t),t.toolRounds=0,await this.#S(t);let r=[],s=await this.#c(t.targetParty,"/ai/chat/send",{chatId:t.chatId,message:e,options:this.#k(t,this.#i.toolsEnabled,n)},t.forward),i=await this.#P(t,s.message,this.#i.toolsEnabled,!1,n,r);if(i.clientToolCalls?.length)throw"Expert MCP cannot execute browser client tools";let a=Ue(i.events);if(!a)throw"Expert did not return an answer";return a}async#M(t,e){let n=await xt(t);if(typeof n.message!="string"||!n.message.trim())throw"Message is required";let r=n.message.trim(),s=this.#F(n),i=this.#E(n),a=this.#O(n),l=this.#g(n),c=O(n),u=await this.#d(t,l,c,void 0,a,this.#j(n));return z(u),u.toolRounds=0,vt(u,n),s&&await this.#S(u),await this.#J(e,async()=>{let h=await this.#c(u.targetParty,"/ai/chat/send",{chatId:u.chatId,message:r,options:this.#k(u,s,a)},u.forward);return await this.#P(u,h.message,s,i,a,e)})}async#J(t,e){try{return await e()}catch(n){return t.push({role:"assistant",content:String(n),error:!0}),{events:t}}}async#U(t,e){let n=await xt(t),r=this.#F(n),s=this.#E(n),i=this.#O(n),a=this.#g(n),l=O(n),c=await this.#d(t,a,l,void 0,i);vt(c,n);let u=Pe(c,n.toolResults);for(let p of u)A(e,p.name??"client_tool",p.content,s,p.isError);let h=[...c.pendingToolResults,...u];return z(c),await this.#J(e,()=>this.#L(c,h,r,s,i,e))}async#P(t,e,n,r,s,i){let a=e;for(;;){q(i,a);let l=a.toolCalls??[];if(!l.length)return{events:i};if(t.toolRounds>=this.#n)return i.push({role:"tool-result",content:"Stopped after too many tool rounds.",error:!0}),{events:i};let{toolResults:c,clientToolCalls:u}=await Ne(t,l,r,i);if(u.length)return t.pendingClientToolCalls=new Map(u.map(p=>[p.id,p])),t.pendingToolResults=c,{events:i,clientToolCalls:u};let h=await this.#L(t,c,n,r,s,i);return h.clientToolCalls?.length,h}}async#L(t,e,n,r,s,i){if(t.toolRounds>=this.#n)return i.push({role:"tool-result",content:"Stopped after too many tool rounds.",error:!0}),{events:i};t.toolRounds++;let a=await this.#c(t.targetParty,"/ai/chat/send",{chatId:t.chatId,message:{role:"user",content:"",toolResults:e},options:this.#k(t,n,s)},t.forward);return await this.#P(t,a.message,n,r,s,i)}async#_(t){let e=await P(t),n=this.#g(e),r=O(e),s=T(t),i=await this.#d(t,n,r,r?void 0:await this.#tt(e,n,s),this.#O(e),this.#j(e));It(i,e.clientTools),await this.#S(i);let a=await this.#q(i);return{chatId:i.chatId,history:a,historyEvents:Ct(a,{toolDetails:this.#E(e),clientToolNames:i.clientToolNames}),closed:r?await this.#b(n,r,s):null}}async#B(t){let e=await P(t);return Object.keys(e).length&&this.#st(e),this.#rt()}async#V(t){let e=await P(t),n=this.#g(e),r=await this.#c(n,"/ai/chat/models",{},T(t));return{models:Array.isArray(r.models)?r.models:[]}}async#H(t){let e=await P(t),n=this.#g(e),r=await this.#c(n,"/ai/chat/list",{},T(t));return{chats:Array.isArray(r.chats)?r.chats:[]}}async#Y(t){let e=await P(t),n=this.#g(e),r=O(e);if(!r)throw"chatId is required";let s=T(t),i=C(t,n,r),a=this.#a.get(i);return a?(await this.#c(a.targetParty,"/ai/chat/close",{chatId:a.chatId},a.forward),this.#a.delete(i),!0):(await this.#c(n,"/ai/chat/close",{chatId:r},s),!0)}async#W(t){let e=await P(t),n=this.#g(e),r=O(e);if(!r)throw"chatId is required";let s=C(t,n,r);return await this.#c(n,"/ai/chat/delete",{chatId:r},T(t)),this.#a.delete(s),!0}async#d(t,e,n,r,s=this.#o,i=this.#s){let a=C(t,e,n);if(n){let h=this.#a.get(a);if(h)return h}let l=T(t),c=n?{id:n}:await this.#c(e,"/ai/chat/create",{system:r??await this.#R(e,{expert:!1},l),temperature:s,...i?{model:i}:{}},l);l.continuation??=String(c.id),a=C(t,e,String(c.id));let u={chatId:String(c.id),targetParty:e,forward:l,toolRuntime:await this.#Q(e,l),clientTools:[],clientToolNames:new Set,pendingClientToolCalls:new Map,pendingToolResults:[],toolRounds:0};return await this.#S(u),this.#a.set(a,u),u}async#q(t){let e=await this.#c(t.targetParty,"/ai/chat/history",{chatId:t.chatId},t.forward);return Array.isArray(e.messages)?e.messages:[]}async#D(t,e,n){let r=await this.#c(t,"/ai/chat/list",{},n);return(Array.isArray(r.chats)?r.chats:[]).find(i=>i.id===e)??null}async#b(t,e,n){let r=await this.#D(t,e,n);return typeof r?.closed=="string"?r.closed:null}async#X(t,e,n,r){let s=n.split(`
17
+ `)[0],i=await this.#D(t,e,r),a=Array.isArray(i?.parties)?i.parties:[];if(!i||!a.includes(s))throw`Unknown or expired conversationId '${e}'. Omit conversationId to start a new conversation.`;if(typeof i.closed=="string")throw Ot(e)}#G(t,e,n,r,s){return new U({postParty:(i,a)=>this.#c(t,i,this.#z(i,a,r,s),e,n),postPartyRaw:(i,a)=>this.#A(t,i,a,e,n)})}#z(t,e,n,r){if(t!=="/ai/memory/catalog")return e;let s=e.kind==="structured"?r:n;return s?{...e,collections:s}:e}async#x(t,e){if(this.#p&&t===m.getConfig().system.party)return await this.#p(t,e??{pre:[],continuation:null})}async#v(t,e){if(this.#h&&t===m.getConfig().system.party)return await this.#h(t,e??{pre:[],continuation:null})}async#Q(t,e){let n=await this.#l?.(t,e);if(!n?.length)return this.#G(t,e,void 0,await this.#x(t,e),await this.#v(t,e));let r=m.getConfig().system.party;return new L(await Promise.all(n.map(async s=>({key:s.party,runtime:s.party===r?this.#G(s.party,e,s.scope,await this.#x(s.party,e),await this.#v(s.party,e)):this.#Z(s.party,e),allowedTools:s.tools?new Set(s.tools):void 0}))))}#Z(t,e){return new D({postRpc:n=>this.#A(t,"/mcp/rpc",n,e)})}async#S(t){await t.toolRuntime.refreshCatalog()}#k(t,e,n){let r=this.#i.thinking,s={temperature:n,thinking:r};if(!e)return s;let i=t.toolRuntime.chatTools({clientTools:t.clientTools});return i.length?{...s,tools:i,toolChoice:"auto"}:s}async#c(t,e,n,r,s){let i=await this.#A(t,e,n,r,s);if("error"in i)throw i.error;return i.ok}async#A(t,e,n,r,s){let i=m.getConfig(),a=new URL(i.system.source),l=`${a.origin}${a.pathname}${a.search}`,c=new URL(`${i.system.protocol}//${i.system.party}`).host,u=(r?.pre??[]).filter(f=>!(f.sub===c&&f.src===l)),h=await m.getTokenFor({[i.system.source]:s??this.#t},t,null,void 0,u),p=`${i.system.protocol}//${t}${e}`,y={"Content-Type":"application/json","X-Tabserver-Token":h.asSignedBase64()};return r?.continuation&&(y[J]=r.continuation),await(await fetch(p,{method:"POST",headers:y,body:JSON.stringify(n)})).json()}async#tt(t,e,n){let r=typeof t.systemPrompt=="string"&&t.systemPrompt.trim()?t.systemPrompt.trim():this.#$();return await this.#R(e,{basePrompt:r,expert:!1},n)}#j(t){return typeof t.model=="string"&&t.model.trim()?t.model.trim():void 0}#O(t){return typeof t.temperature=="number"&&Number.isFinite(t.temperature)&&t.temperature>=0&&t.temperature<=2?Math.round(t.temperature*10)/10:this.#i.temperature}#F(t){return typeof t.toolsEnabled=="boolean"?t.toolsEnabled:this.#i.toolsEnabled}#E(t){return typeof t.toolDetails=="boolean"?t.toolDetails:this.#i.toolDetails}#g(t){return this.#N(t.targetParty)}#N(t){let{system:{party:e,protocol:n}}=m.getConfig();if(t==null||t==="")return e;if(typeof t!="string")throw"targetParty must be a string";let r=t.trim();if(!r)return e;try{let s=r.includes("://")?new URL(r):new URL(`${n}//${r}`);if(!s.host)throw"missing host";return s.host}catch{throw`Invalid targetParty: ${t}`}}async#R(t,e,n){let r=e.basePrompt??this.#$(),s=await Ge(),i=e.expert&&s?`
18
+ When answering expert MCP questions, prefer semantic and structured memory under root "${s}" when looking up remembered information.`:"",a=await this.#et(t,n),l=await this.#nt(t,n);return`${r}${i}${a}${l}`}async#et(t,e){try{let n=await this.#x(t,e),r=Z(),s=r?await this.#ot(t,r,e,n):await this.#I(t,{collections:n},e);return Le(s)}catch{return`
19
19
 
20
- Semantic memory catalog is unavailable for this session.`}}async#nt(t,e,o,r){let s=await this.#I(t,{root:e,collections:r},o);return s.length?s:await this.#I(t,{collections:r},o)}async#I(t,e,o){let r=await this.#c(t,"/ai/memory/catalog",{kind:"semantic",...e.root?{root:e.root}:{},...e.collections?{collections:e.collections}:{}},o);return Array.isArray(r.resources)?r.resources:[]}async#ot(t,e){try{let o=await this.#v(t,e),r=Z(),s=r?await this.#K(t,{root:r,collections:o},e):[],i=r&&s.length?s:await this.#K(t,{collections:o},e);return De(i)}catch{return`
20
+ Semantic memory catalog is unavailable for this session.`}}async#ot(t,e,n,r){let s=await this.#I(t,{root:e,collections:r},n);return s.length?s:await this.#I(t,{collections:r},n)}async#I(t,e,n){let r=await this.#c(t,"/ai/memory/catalog",{kind:"semantic",...e.root?{root:e.root}:{},...e.collections?{collections:e.collections}:{}},n);return Array.isArray(r.resources)?r.resources:[]}async#nt(t,e){try{let n=await this.#v(t,e),r=Z(),s=r?await this.#K(t,{root:r,collections:n},e):[],i=r&&s.length?s:await this.#K(t,{collections:n},e);return De(i)}catch{return`
21
21
 
22
- Structured memory catalog is unavailable for this session.`}}async#K(t,e,o){let r=await this.#c(t,"/ai/memory/catalog",{kind:"structured",...e.root?{root:e.root}:{},...e.collections?{collections:e.collections}:{}},o);return Array.isArray(r.resources)?r.resources:[]}#$(){return this.#i.systemPrompt??this.#e}#rt(){return{...this.#i,systemPrompt:this.#$()}}#st(t){if(t.systemPrompt!==void 0){if(typeof t.systemPrompt!="string")throw"systemPrompt must be a string";this.#i.systemPrompt=t.systemPrompt.trim()?t.systemPrompt:this.#e}if(t.temperature!==void 0){if(typeof t.temperature!="number"||!Number.isFinite(t.temperature)||t.temperature<0||t.temperature>2)throw"temperature must be between 0 and 2";this.#i.temperature=Math.round(t.temperature*10)/10}if(t.toolsEnabled!==void 0){if(typeof t.toolsEnabled!="boolean")throw"toolsEnabled must be a boolean";this.#i.toolsEnabled=t.toolsEnabled}if(t.toolDetails!==void 0){if(typeof t.toolDetails!="boolean")throw"toolDetails must be a boolean";this.#i.toolDetails=t.toolDetails}if(t.thinking!==void 0){if(typeof t.thinking!="boolean")throw"thinking must be a boolean";this.#i.thinking=t.thinking}}};async function xt(n){if(!n.headers.get("Content-Type")?.startsWith("application/json"))throw"Content-Type must be 'application/json'";let t=await n.json();if(!t||typeof t!="object"||Array.isArray(t))throw"Request body must be an object";return t}async function P(n){if(!n.headers.get("Content-Type")?.startsWith("application/json"))return{};let t=await n.json();return!t||typeof t!="object"||Array.isArray(t)?{}:t}function vt(n,t){Object.hasOwn(t,"clientTools")&&It(n,t.clientTools)}function It(n,t){let e=Array.isArray(t)?t.filter(Re):[];n.clientTools=e,n.clientToolNames=new Set(e.map(o=>o.name))}function Re(n){return!!n&&typeof n=="object"&&!Array.isArray(n)&&n.type==="function"&&typeof n.name=="string"&&n.execution==="client"}function Pe(n,t){if(!Array.isArray(t))throw"toolResults must be an array";let e=new Set(n.pendingClientToolCalls.keys());if(!e.size)throw"No pending client tool calls";let o=[];for(let r of t){if(!be(r))throw"Invalid client tool result";if(!e.delete(r.toolCallId))throw`Unexpected client tool result: ${r.toolCallId}`;if(n.pendingClientToolCalls.get(r.toolCallId)?.name!==r.name)throw`Client tool result name mismatch: ${r.toolCallId}`;o.push(r)}if(e.size)throw`Missing client tool results: ${[...e].join(", ")}`;return o}function be(n){return!!n&&typeof n=="object"&&!Array.isArray(n)&&typeof n.toolCallId=="string"&&typeof n.name=="string"&&typeof n.content=="string"&&(n.isError===void 0||typeof n.isError=="boolean")}function z(n){n.pendingClientToolCalls.clear(),n.pendingToolResults=[]}function O(n){if(!(n.chatId===void 0||n.chatId===null||n.chatId==="")){if(typeof n.chatId!="string")throw"chatId must be a string";return n.chatId}}function C(n,t,e){return`${Ae(n)}
22
+ Structured memory catalog is unavailable for this session.`}}async#K(t,e,n){let r=await this.#c(t,"/ai/memory/catalog",{kind:"structured",...e.root?{root:e.root}:{},...e.collections?{collections:e.collections}:{}},n);return Array.isArray(r.resources)?r.resources:[]}#$(){return this.#i.systemPrompt??this.#e}#rt(){return{...this.#i,systemPrompt:this.#$()}}#st(t){if(t.systemPrompt!==void 0){if(typeof t.systemPrompt!="string")throw"systemPrompt must be a string";this.#i.systemPrompt=t.systemPrompt.trim()?t.systemPrompt:this.#e}if(t.temperature!==void 0){if(typeof t.temperature!="number"||!Number.isFinite(t.temperature)||t.temperature<0||t.temperature>2)throw"temperature must be between 0 and 2";this.#i.temperature=Math.round(t.temperature*10)/10}if(t.toolsEnabled!==void 0){if(typeof t.toolsEnabled!="boolean")throw"toolsEnabled must be a boolean";this.#i.toolsEnabled=t.toolsEnabled}if(t.toolDetails!==void 0){if(typeof t.toolDetails!="boolean")throw"toolDetails must be a boolean";this.#i.toolDetails=t.toolDetails}if(t.thinking!==void 0){if(typeof t.thinking!="boolean")throw"thinking must be a boolean";this.#i.thinking=t.thinking}}};async function xt(o){if(!o.headers.get("Content-Type")?.startsWith("application/json"))throw"Content-Type must be 'application/json'";let t=await o.json();if(!t||typeof t!="object"||Array.isArray(t))throw"Request body must be an object";return t}async function P(o){if(!o.headers.get("Content-Type")?.startsWith("application/json"))return{};let t=await o.json();return!t||typeof t!="object"||Array.isArray(t)?{}:t}function vt(o,t){Object.hasOwn(t,"clientTools")&&It(o,t.clientTools)}function It(o,t){let e=Array.isArray(t)?t.filter(Re):[];o.clientTools=e,o.clientToolNames=new Set(e.map(n=>n.name))}function Re(o){return!!o&&typeof o=="object"&&!Array.isArray(o)&&o.type==="function"&&typeof o.name=="string"&&o.execution==="client"}function Pe(o,t){if(!Array.isArray(t))throw"toolResults must be an array";let e=new Set(o.pendingClientToolCalls.keys());if(!e.size)throw"No pending client tool calls";let n=[];for(let r of t){if(!be(r))throw"Invalid client tool result";if(!e.delete(r.toolCallId))throw`Unexpected client tool result: ${r.toolCallId}`;if(o.pendingClientToolCalls.get(r.toolCallId)?.name!==r.name)throw`Client tool result name mismatch: ${r.toolCallId}`;n.push(r)}if(e.size)throw`Missing client tool results: ${[...e].join(", ")}`;return n}function be(o){return!!o&&typeof o=="object"&&!Array.isArray(o)&&typeof o.toolCallId=="string"&&typeof o.name=="string"&&typeof o.content=="string"&&(o.isError===void 0||typeof o.isError=="boolean")}function z(o){o.pendingClientToolCalls.clear(),o.pendingToolResults=[]}function O(o){if(!(o.chatId===void 0||o.chatId===null||o.chatId==="")){if(typeof o.chatId!="string")throw"chatId must be a string";return o.chatId}}function C(o,t,e){return`${Ae(o)}
23
23
  ${t}
24
- ${e??"default"}`}function xe(n,t){try{let e=d.from(n);return e?`${e.getSub()}
24
+ ${e??"default"}`}function xe(o,t){try{let e=d.from(o);return e?`${e.getSub()}
25
25
  ${e.getSrc()}
26
- ${t}`:null}catch{return null}}function kt(n,t){return`${n}
27
- ${t}`}function At(n,t){return`${n}
26
+ ${t}`:null}catch{return null}}function kt(o,t){return`${o}
27
+ ${t}`}function At(o,t){return`${o}
28
28
  continuation
29
- ${t}`}function Ot(n){return`Conversation '${n}' is closed. Omit conversationId to start a new conversation.`}function ve(n){if(!n)return null;try{let t=n.getCounterparty();return t?`${t}
30
- ${n.getSrc()}`:null}catch{return null}}function ke(n){return Et(n.outputSchema)||Et(n.inputSchema)}function Et(n){let t=n?.properties;return!!(t&&"conversationId"in t)}function Ae(n){let t=n.headers.get(Pt);if(t)return t;throw`This request must provide a token in '${Pt}'`}function T(n){return{pre:Oe(n),continuation:n.headers.get(J)}}function Oe(n){let t=[];try{let e=d.from(n);if(e){t.push({sub:e.getCounterparty(),src:e.getSrc()});for(let o of e.getPre())t.push({sub:o.sub,src:o.src})}}catch{}return Ee(t)}function Ee(n){let t=new Set,e=[];for(let o of n){let r=`${o.sub}
31
- ${o.src}`;t.has(r)||(t.add(r),e.push(o))}return e}async function Ne(n,t,e,o){let r=[],s=[];for(let i of t){let a=n.clientToolNames.has(i.name);if(e&&o.push({role:"tool",content:X(i,a)}),a){s.push(i);continue}try{let l=await n.toolRuntime.executeToolCall(i);A(o,i.name,l,e),r.push({toolCallId:i.id,name:i.name,content:l})}catch(l){let c=String(l);A(o,i.name,c,e,!0),r.push({toolCallId:i.id,name:i.name,content:c,isError:!0})}}return{toolResults:r,clientToolCalls:s}}var Q=class{#t;constructor(t){this.#t=t}listTools(t){return Nt(t).map(Ie)}async callTool(t,e,o){let r=Nt(o).find(i=>i.name===t);if(!r)throw new w(-32602,`Unknown tool: ${t}`);if($e(o,r),typeof e.question!="string"||!e.question.trim())throw"question is required";let s=ke(r)?ve(o.token):null;if(s){let i=typeof e.conversationId=="string"&&e.conversationId?e.conversationId:null;return await this.#t.askExpertConversation(o.request,e.question,s,i)}return await this.#t.askExpert(o.request,e.question)}};function Nt(n){return n?.yaml?.mcp?.tools??[]}function Ie(n){return{name:n.name,...n.title===void 0?{}:{title:n.title},description:n.description,inputSchema:n.inputSchema,...n.outputSchema===void 0?{}:{outputSchema:n.outputSchema},...n.annotations===void 0?{}:{annotations:n.annotations}}}function $e(n,t){let e=t.capability;if(!e)throw`Tool '${t.name}' declares no capability`;if(!Rt({token:n.token,providerSource:n.source,toolName:t.name,capability:e,providerYaml:n.yaml}))throw`Missing capability: ${e}`}function Me(n){let{system:{party:t,source:e,protocol:o,sourcePrefix:r},content:{yaml:s}}=m.getConfig();return{party:t,source:e,protocol:o,sourcePrefix:r,yaml:s,token:Je(n),request:n}}function Je(n){return d.from(n)}function Ue(n){for(let t=n.length-1;t>=0;t--){let e=n[t];if(e.role==="assistant"&&!e.error)return e.content}return null}function Le(n){if(!n.length)return`
29
+ ${t}`}function Ot(o){return`Conversation '${o}' is closed. Omit conversationId to start a new conversation.`}function ve(o){if(!o)return null;try{let t=o.getCounterparty();return t?`${t}
30
+ ${o.getSrc()}`:null}catch{return null}}function ke(o){return Et(o.outputSchema)||Et(o.inputSchema)}function Et(o){let t=o?.properties;return!!(t&&"conversationId"in t)}function Ae(o){let t=o.headers.get(Pt);if(t)return t;throw`This request must provide a token in '${Pt}'`}function T(o){return{pre:Oe(o),continuation:o.headers.get(J)}}function Oe(o){let t=[];try{let e=d.from(o);if(e){t.push({sub:e.getCounterparty(),src:e.getSrc()});for(let n of e.getPre())t.push({sub:n.sub,src:n.src})}}catch{}return Ee(t)}function Ee(o){let t=new Set,e=[];for(let n of o){let r=`${n.sub}
31
+ ${n.src}`;t.has(r)||(t.add(r),e.push(n))}return e}async function Ne(o,t,e,n){let r=[],s=[];for(let i of t){let a=o.clientToolNames.has(i.name);if(e&&n.push({role:"tool",content:X(i,a)}),a){s.push(i);continue}try{let l=await o.toolRuntime.executeToolCall(i);A(n,i.name,l,e),r.push({toolCallId:i.id,name:i.name,content:l})}catch(l){let c=String(l);A(n,i.name,c,e,!0),r.push({toolCallId:i.id,name:i.name,content:c,isError:!0})}}return{toolResults:r,clientToolCalls:s}}var Q=class{#t;constructor(t){this.#t=t}listTools(t){return Nt(t).map(Ie)}async callTool(t,e,n){let r=Nt(n).find(i=>i.name===t);if(!r)throw new w(-32602,`Unknown tool: ${t}`);if($e(n,r),typeof e.question!="string"||!e.question.trim())throw"question is required";let s=ke(r)?ve(n.token):null;if(s){let i=typeof e.conversationId=="string"&&e.conversationId?e.conversationId:null;return await this.#t.askExpertConversation(n.request,e.question,s,i)}return await this.#t.askExpert(n.request,e.question)}};function Nt(o){return o?.yaml?.mcp?.tools??[]}function Ie(o){return{name:o.name,...o.title===void 0?{}:{title:o.title},description:o.description,inputSchema:o.inputSchema,...o.outputSchema===void 0?{}:{outputSchema:o.outputSchema},...o.annotations===void 0?{}:{annotations:o.annotations}}}function $e(o,t){let e=t.capability;if(!e)throw`Tool '${t.name}' declares no capability`;if(!Rt({token:o.token,providerSource:o.source,toolName:t.name,capability:e,providerYaml:o.yaml}))throw`Missing capability: ${e}`}function Me(o){let{system:{party:t,source:e,protocol:n,sourcePrefix:r},content:{yaml:s}}=m.getConfig();return{party:t,source:e,protocol:n,sourcePrefix:r,yaml:s,token:Je(o),request:o}}function Je(o){return d.from(o)}function Ue(o){for(let t=o.length-1;t>=0;t--){let e=o[t];if(e.role==="assistant"&&!e.error)return e.content}return null}function Le(o){if(!o.length)return`
32
32
 
33
33
  Available semantic memories:
34
- None discovered.`;let t=["","","Available semantic memories:","Use index_search with the exact root and collection when these memories are relevant.","Search results are chunks: pass a result's key to index_resolve to read the complete source document before quoting from it."];for(let e of n){let o=b(e.root),r=b(e.collection);if(!o||!r)continue;t.push(`- root: ${o}`),t.push(` collection: ${r}`);let s=b(e.description);s&&t.push(` description: ${s}`);let i=_(e.schema),a=$t(i?.textProperties);a.length&&t.push(` textProperties: ${a.join(", ")}`);let l=_(i?.propertyTypes);l&&t.push(` propertyTypes: ${JSON.stringify(l)}`),t.push(` query with: index_search({ root: ${JSON.stringify(o)}, collection: ${JSON.stringify(r)}, text: "<search text>", limit: 5 }) \u2014 then index_resolve({ root, collection, key }) for a full document`)}return t.join(`
35
- `)}function De(n){if(!n.length)return`
34
+ None discovered.`;let t=["","","Available semantic memories:","Use index_search with the exact root and collection when these memories are relevant.","Search results are chunks: pass a result's key to index_resolve to read the complete source document before quoting from it."];for(let e of o){let n=b(e.root),r=b(e.collection);if(!n||!r)continue;t.push(`- root: ${n}`),t.push(` collection: ${r}`);let s=b(e.description);s&&t.push(` description: ${s}`);let i=_(e.schema),a=$t(i?.textProperties);a.length&&t.push(` textProperties: ${a.join(", ")}`);let l=_(i?.propertyTypes);l&&t.push(` propertyTypes: ${JSON.stringify(l)}`),t.push(` query with: index_search({ root: ${JSON.stringify(n)}, collection: ${JSON.stringify(r)}, text: "<search text>", limit: 5 }) \u2014 then index_resolve({ root, collection, key }) for a full document`)}return t.join(`
35
+ `)}function De(o){if(!o.length)return`
36
36
 
37
37
  Available structured memories:
38
- None discovered.`;let t=["","","Available structured memories:","Use structured_query with the exact root and collection when these memories are relevant."];for(let e of n){let o=b(e.root),r=b(e.collection);if(!o||!r)continue;t.push(`- root: ${o}`),t.push(` collection: ${r}`);let s=b(e.description);s&&t.push(` description: ${s}`);let i=_(e.schema),a=$t(i?.textProperties);a.length&&t.push(` textProperties: ${a.join(", ")}`);let l=_(i?.propertyTypes);l&&t.push(` propertyTypes: ${JSON.stringify(l)}`),t.push(` query with: structured_query({ root: ${JSON.stringify(o)}, collection: ${JSON.stringify(r)}, query: { limit: 5 } })`)}return t.join(`
39
- `)}function b(n){return typeof n=="string"?n:""}function _(n){return n&&typeof n=="object"&&!Array.isArray(n)?n:null}function $t(n){return Array.isArray(n)?n.filter(t=>typeof t=="string"):[]}function Z(){let{system:{source:n}}=m.getConfig();return new URL(n).searchParams.get("root")?.trim().replace(/^\/+|\/+$/g,"")||void 0}async function Ge(){let{system:{source:n}}=m.getConfig(),t=new URL(n),e=Z();return e||(t.hash="",await E(t))}export{dt as AbstractHandler,U as AgentToolRuntime,L as AggregateToolRuntime,x as BrowserApp,ee as CONFIG_PATH,J as CONTINUATION_HEADER,M as ClientToolRegistry,ut as DAEMON_PREFIX,ne as EVENT_PATH,D as GatewayToolRuntime,bt as GenerativeChatAgent,ot as GenerativeChatClient,zt as ImgClass,v as JsonRpcMcpClient,j as JsonRpcMcpServer,rt as KeyPair,m as Lifecycle,ft as McpToolRegistry,st as ParentHelper,w as ProtocolError,it as QrCode,W as RENDER_STREAM_CONTENT_TYPE,K as RenderEventStream,R as Storage,d as Token,me as USE_TOOLS_CAPABILITY,q as appendAssistantEvent,de as appendReasoningEvents,A as appendToolResultEvent,sn as buildCookie,gt as cloneJSONValue,kn as composeToolDescription,ze as createDefaultBrowserChatTools,E as getAppId,Y as getClientHost,Qt as getClientPathname,H as getClientProtocol,cn as getClientUrl,Zt as getClientUrlPhp,un as getCookie,te as getCookies,Bt as getItem,Vt as getItemsLike,ln as getPathname,Rt as hasMcpToolCapability,Ct as historyToRenderEvents,Pn as isDefined,re as mcpToolErrorMessage,yt as mcpToolResult,Rn as notNull,Ht as removeItem,g as response,rn as response302,on as response404,_t as setItem,je as shortHexDigest,Ut as shortSafeDigest,ae as toChatTool,Tt as tokenHasCapability,X as toolCallMessage,ge as toolResultMessage,ye as yamlDeclaresMcpToolCapability,we as yamlGrantsCapability};
38
+ None discovered.`;let t=["","","Available structured memories:","Use structured_query with the exact root and collection when these memories are relevant."];for(let e of o){let n=b(e.root),r=b(e.collection);if(!n||!r)continue;t.push(`- root: ${n}`),t.push(` collection: ${r}`);let s=b(e.description);s&&t.push(` description: ${s}`);let i=_(e.schema),a=$t(i?.textProperties);a.length&&t.push(` textProperties: ${a.join(", ")}`);let l=_(i?.propertyTypes);l&&t.push(` propertyTypes: ${JSON.stringify(l)}`),t.push(` query with: structured_query({ root: ${JSON.stringify(n)}, collection: ${JSON.stringify(r)}, query: { limit: 5 } })`)}return t.join(`
39
+ `)}function b(o){return typeof o=="string"?o:""}function _(o){return o&&typeof o=="object"&&!Array.isArray(o)?o:null}function $t(o){return Array.isArray(o)?o.filter(t=>typeof t=="string"):[]}function Z(){let{system:{source:o}}=m.getConfig();return new URL(o).searchParams.get("root")?.trim().replace(/^\/+|\/+$/g,"")||void 0}async function Ge(){let{system:{source:o}}=m.getConfig(),t=new URL(o),e=Z();return e||(t.hash="",await E(t))}export{dt as AbstractHandler,U as AgentToolRuntime,L as AggregateToolRuntime,x as BrowserApp,ee as CONFIG_PATH,J as CONTINUATION_HEADER,M as ClientToolRegistry,ut as DAEMON_PREFIX,oe as EVENT_PATH,D as GatewayToolRuntime,bt as GenerativeChatAgent,nt as GenerativeChatClient,zt as ImgClass,v as JsonRpcMcpClient,j as JsonRpcMcpServer,rt as KeyPair,m as Lifecycle,ft as McpToolRegistry,st as ParentHelper,w as ProtocolError,it as QrCode,W as RENDER_STREAM_CONTENT_TYPE,K as RenderEventStream,R as Storage,d as Token,me as USE_TOOLS_CAPABILITY,q as appendAssistantEvent,de as appendReasoningEvents,A as appendToolResultEvent,so as buildCookie,gt as cloneJSONValue,ko as composeToolDescription,ze as createDefaultBrowserChatTools,E as getAppId,Y as getClientHost,Qt as getClientPathname,H as getClientProtocol,ao as getClientUrl,Zt as getClientUrlPhp,lo as getCookie,te as getCookies,Bt as getItem,Vt as getItemsLike,co as getPathname,Rt as hasMcpToolCapability,Ct as historyToRenderEvents,Po as isDefined,re as mcpToolErrorMessage,yt as mcpToolResult,Ro as notNull,Ht as removeItem,g as response,ro as response302,no as response404,_t as setItem,je as shortHexDigest,Ut as shortSafeDigest,ae as toChatTool,Tt as tokenHasCapability,X as toolCallMessage,ge as toolResultMessage,ye as yamlDeclaresMcpToolCapability,we as yamlGrantsCapability};
40
40
  //# sourceMappingURL=index.js.map