@useago/sdk 1.12.0 → 1.13.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/CHANGELOG.md +71 -4
- package/README.md +73 -0
- package/dist/angular.cjs +1 -1
- package/dist/angular.d.cts +97 -28
- package/dist/angular.d.ts +97 -28
- package/dist/angular.js +4 -1
- package/dist/{createConversationSession-B1Qn-y0I.js → createConversationSession-BfJg0WyA.js} +1 -1
- package/dist/{createConversationSession-B3v_xOU7.cjs → createConversationSession-CiOXKWl0.cjs} +1 -1
- package/dist/{createFormCollector-m79zk_NA.js → createFormCollector-DN1xjAv5.js} +1 -1
- package/dist/{createFormCollector-FvwDOqnV.cjs → createFormCollector-DnQl77Ko.cjs} +1 -1
- package/dist/createMockClient-BPt1gSve.cjs +1 -0
- package/dist/{createMockClient-Beao82tu.js → createMockClient-YoYr3pQr.js} +1 -0
- package/dist/devtools.cjs +4 -4
- package/dist/devtools.d.cts +95 -28
- package/dist/devtools.d.ts +95 -28
- package/dist/devtools.js +87 -84
- package/dist/helpers.d.cts +42 -12
- package/dist/helpers.d.ts +42 -12
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +101 -35
- package/dist/index.d.ts +101 -35
- package/dist/index.js +44 -43
- package/dist/react.cjs +4 -4
- package/dist/react.d.cts +147 -28
- package/dist/react.d.ts +147 -28
- package/dist/react.js +814 -727
- package/dist/speechToText-BV7qxqPF.js +704 -0
- package/dist/speechToText-ZciRyyJE.cjs +1 -0
- package/dist/testing.cjs +1 -1
- package/dist/testing.d.cts +95 -28
- package/dist/testing.d.ts +95 -28
- package/dist/testing.js +1 -1
- package/dist/{types-Ct1hlKwg.js → types-Q7t1peH-.js} +595 -419
- package/dist/types-a7teDBnC.cjs +10 -0
- package/dist/vue.cjs +1 -1
- package/dist/vue.d.cts +105 -28
- package/dist/vue.d.ts +105 -28
- package/dist/vue.js +103 -101
- package/dist/widget.cjs +6 -6
- package/dist/widget.d.cts +127 -28
- package/dist/widget.d.ts +127 -28
- package/dist/widget.js +1717 -1772
- package/llms-full.txt +129 -1
- package/package.json +1 -1
- package/dist/createMockClient-BEOXI8yW.cjs +0 -1
- package/dist/sheetController-BThJRtOu.cjs +0 -1
- package/dist/sheetController-aEKXIvjk.js +0 -343
- package/dist/types-mcW8vB1U.cjs +0 -10
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
const y=require("./errors-o1IB5fEu.cjs");var Re=10,H=1e3;function Te(e){if(typeof e!="object"||e===null)return!1;const t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function F(e,t){if(typeof e=="string"){if(e.length<=1e3)return e;const r=e.length-H;return e.slice(0,H)+`…[truncated ${r} chars]`}if(Array.isArray(e)){if(t.has(e))return"…[circular]";t.add(e);const r=e.slice(0,50).map(i=>F(i,t));return e.length>50&&r.push(`…[+${e.length-50} more]`),t.delete(e),r}if(Te(e)){if(t.has(e))return"…[circular]";t.add(e);const r={};for(const[i,s]of Object.entries(e))r[i]=F(s,t);return t.delete(e),r}return e}function ce(e){return F(e,new WeakSet)}var le=class{constructor(e=10){this.entries=[];const t=Math.floor(e);this.maxEntries=Number.isFinite(t)?Math.max(1,t):10}add(e){const t={ts:e.ts??Date.now(),actor:e.actor??"user",name:e.name,summary:e.summary,...e.data!==void 0?{data:ce(e.data)}:{}};this.entries.push(t);const r=this.entries.length-this.maxEntries;return r>0&&this.entries.splice(0,r),t}getRecent(){return[...this.entries]}get size(){return this.entries.length}clear(){this.entries=[]}};function P(e){if(e==null)return null;if(typeof e=="string"){const t=e.trim().replace(/_/g,"-");try{const[r]=/^[a-z]{2,3}(?:-[a-z0-9]{1,8})*$/i.test(t)?Intl.getCanonicalLocales(t):[];if(r)return r}catch{}}throw new y.AgoError('Use a language tag such as "fr", "de-DE", or "pt-BR", or null to clear it. See docs/general/configuration.md#language (config_invalid_language).',"config_invalid_language")}var Ie=class{constructor(e=!1){this.enabled=e}enable(){this.enabled=!0}disable(){this.enabled=!1}log(...e){this.enabled&&console.log("[AGO SDK]",...e)}warn(...e){this.enabled&&console.warn("[AGO SDK]",...e)}error(...e){console.error("[AGO SDK]",...e)}debug(...e){this.enabled&&console.debug("[AGO SDK]",...e)}},l=new Ie,X="ago_widget_id";function M(e){return typeof DOMException<"u"&&e instanceof DOMException&&e.name==="AbortError"||e instanceof Error&&e.name==="AbortError"}function xe(){if(typeof localStorage<"u"){const t=localStorage.getItem(X);if(t)return t}const e=typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`ago-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,12)}`;if(typeof localStorage<"u")try{localStorage.setItem(X,e)}catch{}return e}var Fe=class{constructor(e){this.baseUrl=e.baseUrl.replace(/\/$/,""),this.headers={"X-User-Anon-Id":e.widgetId||xe()},e.userEmail&&(this.headers["X-User-Email"]=e.userEmail),e.userJwt&&(this.headers.Authorization=`Bearer ${e.userJwt}`),e.permission&&(this.headers["X-Widget-Permission"]=e.permission);const t=P(e.language);t&&(this.headers["Accept-Language"]=t)}updateConfig(e){const t=P(e.language);e.baseUrl&&(this.baseUrl=e.baseUrl.replace(/\/$/,"")),e.widgetId&&(this.headers["X-User-Anon-Id"]=e.widgetId),e.userEmail&&(this.headers["X-User-Email"]=e.userEmail),e.userJwt&&(this.headers.Authorization=`Bearer ${e.userJwt}`),e.permission!==void 0&&(e.permission?this.headers["X-Widget-Permission"]=e.permission:delete this.headers["X-Widget-Permission"]),e.language!==void 0&&(t?this.headers["Accept-Language"]=t:delete this.headers["Accept-Language"])}async get(e){return this.request("GET",e)}async post(e,t,r){return this.request("POST",e,t,r)}async postStream(e,t,r){const i=`${this.baseUrl}${e}`;l.debug("POST (stream)",i,t);try{const s=await fetch(i,{method:"POST",headers:{...this.headers,"Content-Type":"application/json"},body:t?JSON.stringify(t):void 0,signal:r?.signal});return s.ok||await this.handleErrorResponse(s),s}catch(s){throw s instanceof y.AgoApiError||M(s)?s:new y.AgoNetworkError(`Network error: ${s instanceof Error?s.message:"Unknown error"}. Check that \`baseUrl\` is reachable and includes the protocol (https://).`,s instanceof Error?s:void 0)}}async postFormData(e,t,r){const i=`${this.baseUrl}${e}`;l.debug("POST (formData)",i);const s={...this.headers};try{const n=await fetch(i,{method:"POST",headers:s,body:t,signal:r?.signal});return n.ok||await this.handleErrorResponse(n),n}catch(n){throw n instanceof y.AgoApiError||M(n)?n:new y.AgoNetworkError(`Network error: ${n instanceof Error?n.message:"Unknown error"}. Check that \`baseUrl\` is reachable and includes the protocol (https://).`,n instanceof Error?n:void 0)}}async request(e,t,r,i){const s=`${this.baseUrl}${t}`;l.debug(e,s,r);try{const n=await fetch(s,{method:e,headers:{...this.headers,"Content-Type":"application/json"},body:r?JSON.stringify(r):void 0,...i?.keepalive?{keepalive:!0}:{}});return n.ok||await this.handleErrorResponse(n),n.status===204?void 0:n.json()}catch(n){throw n instanceof y.AgoApiError?n:new y.AgoNetworkError(`Network error: ${n instanceof Error?n.message:"Unknown error"}. Check that \`baseUrl\` is reachable and includes the protocol (https://).`,n instanceof Error?n:void 0)}}async handleErrorResponse(e){let t;try{t=await e.json()}catch{}if(t?.error)throw y.AgoApiError.fromResponse(t,e.status);let r="";throw e.status===401||e.status===403?r=" Check `userJwt` (and that it has not expired).":e.status===404&&(r=" Check that `baseUrl` points at your AGO API root."),new y.AgoApiError(`HTTP ${e.status}: ${e.statusText}.${r}`,"http_error",e.status,"api_error")}},Pe=10,Me=6e5;var Oe="[AGO SDK]",De=300;function O(e,t){return e.length<=t?e:e.slice(0,t)+`…[truncated ${e.length-t} chars]`}function $e(e){const t=e.search(/[?#]/);return t===-1?e:e.slice(0,t)}function q(e){return typeof e=="object"&&e!==null&&typeof e.message=="string"}function ue(e){if(typeof e=="string")return e;if(q(e))return(typeof e.name=="string"&&e.name?`${e.name}: `:"")+e.message;if(typeof e=="object"&&e!==null)try{return O(JSON.stringify(e),De)}catch{return String(e)}return String(e)}function R(e){return q(e)?{message:(typeof e.name=="string"&&e.name&&e.name!=="Error"?`${e.name}: `:"")+e.message,stack:typeof e.stack=="string"?e.stack:void 0}:{message:ue(e)}}var de=class{constructor(e={}){this.started=!1,this.teardowns=[],this.errors=[],this.listeners=new Set,this.capturing=!1;const t=Math.floor(e.maxErrors??10);this.maxErrors=Number.isFinite(t)?Math.max(1,t):10,this.maxAgeMs=e.maxAgeMs??6e5,this.maxStackChars=e.maxStackChars??2e3,this.filter=e.filter}start(){if(this.started||typeof window>"u")return;this.started=!0;const e=r=>this.onErrorEvent(r);window.addEventListener("error",e),this.teardowns.push(()=>window.removeEventListener("error",e));const t=r=>this.onRejectionEvent(r);window.addEventListener("unhandledrejection",t),this.teardowns.push(()=>window.removeEventListener("unhandledrejection",t)),this.wrapConsoleError(),l.log("ErrorWatcher started")}destroy(){for(const e of this.teardowns)e();this.teardowns=[],this.listeners.clear(),this.started=!1,l.log("ErrorWatcher destroyed")}report(e,t){const r=R(e);this.capture({type:"manual",message:r.message,stack:r.stack,...t?{context:ce(t)}:{}})}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}getErrors(){return this.prune(),this.errors.map(e=>({...e}))}clear(){this.errors=[]}onErrorEvent(e){if(typeof e.message!="string"&&!e.error)return;const t=e.error!==void 0&&e.error!==null?R(e.error):{message:e.message??""};this.capture({type:"error",message:t.message||e.message||"Unknown error",stack:t.stack,source:e.filename?$e(e.filename):void 0,line:e.lineno||void 0,col:e.colno||void 0})}onRejectionEvent(e){const t=e.reason,r=R(t);this.capture({type:"unhandledrejection",message:r.message||"Unhandled promise rejection",stack:r.stack})}wrapConsoleError(){if(typeof console>"u"||typeof console.error!="function")return;const e=console.error,t=(...r)=>{try{this.onConsoleError(r)}catch{}return e.apply(console,r)};console.error=t,this.teardowns.push(()=>{console.error===t&&(console.error=e)})}onConsoleError(e){if(e.length===0)return;const t=e[0];if(typeof t=="string"&&t.startsWith(Oe))return;const r=e.find(q),i=e.map(ue).join(" ");this.capture({type:"console",message:i,stack:r&&typeof r.stack=="string"?r.stack:void 0})}capture(e){if(!this.capturing){this.capturing=!0;try{const t=Date.now(),r=e.stack!==void 0?this.trimStack(e.stack,e.message):void 0;let i={type:e.type,message:O(e.message,500),...e.source!==void 0?{source:e.source}:{},...e.line!==void 0?{line:e.line}:{},...e.col!==void 0?{col:e.col}:{},...r?{stack:r}:{},route:this.currentPathname(),firstAt:t,lastAt:t,count:1,...e.context!==void 0?{context:e.context}:{}};if(this.filter){const o=this.filter(i);if(!o)return;i=o}this.prune(t);const s=z(i),n=this.errors.find(o=>z(o)===s);if(n){n.count+=1,n.lastAt=t,i.context!==void 0&&(n.context=i.context),this.notify(n);return}this.errors.push(i);const a=this.errors.length-this.maxErrors;a>0&&this.errors.splice(0,a),this.notify(i)}finally{this.capturing=!1}}}notify(e){const t={...e};for(const r of this.listeners)try{r(t)}catch(i){l.error("ErrorWatcher listener threw:",i)}}prune(e=Date.now()){Number.isFinite(this.maxAgeMs)&&(this.errors=this.errors.filter(t=>e-t.lastAt<=this.maxAgeMs))}trimStack(e,t){let r=e;const i=r.indexOf(`
|
|
2
|
+
`);if(i!==-1&&r.slice(0,i).includes(t.slice(0,80))&&(r=r.slice(i+1)),r=r.trim(),!!r)return O(r,this.maxStackChars)}currentPathname(){return typeof window<"u"&&window.location?window.location.pathname:""}};function z(e){return`${e.type}|${e.message}|${e.source??""}|${e.line??""}`}var Ne=5e4,je=2e4,Le=2e3,he=class{constructor(e){this.functions=new Map,this.changeListeners=new Set,this.defaultMaxResultBytes=e?.maxResultBytes??Ne}onChange(e){return this.changeListeners.add(e),()=>{this.changeListeners.delete(e)}}emitChange(){for(const e of this.changeListeners)try{e()}catch(t){l.error("Function registry change listener failed:",t)}}setDefaultMaxResultBytes(e){this.defaultMaxResultBytes=e}getDefaultMaxResultBytes(){return this.defaultMaxResultBytes}register(e,t,r){if(typeof e=="object"){const{name:c,handler:u,description:d,parameters:g,maxResultBytes:m,requiresApproval:w,webmcp:f}=e;return this.register(c,u,{description:d,parameters:g,maxResultBytes:m,requiresApproval:w,webmcp:f})}const i=e;if(!t||!r)throw new y.AgoError(`registerFunction("${i}"): both a handler and a schema are required. Pass them as arguments or use the single-object form: registerFunction({ name, parameters, handler }).`,"function_invalid_registration");this.functions.has(i)&&l.warn(`Function "${i}" is being overwritten`);const{maxResultBytes:s,requiresApproval:n,webmcp:a,...o}=r;this.functions.set(i,{schema:{...o,name:i},handler:t,maxResultBytes:s,requiresApproval:n,webmcp:a}),l.log(`Registered function: ${i}`),this.emitChange()}unregister(e){const t=this.functions.delete(e);return t&&(l.log(`Unregistered function: ${e}`),this.emitChange()),t}get(e){return this.functions.get(e)}has(e){return this.functions.has(e)}getSchemas(){return Array.from(this.functions.values()).map(e=>e.schema)}getAll(){return Array.from(this.functions.entries()).map(([e,t])=>({...t,name:e}))}async execute(e,t){const r=this.functions.get(e);if(!r)throw new y.AgoFunctionError(`Function "${e}" is not registered`,e);l.log(`Executing function: ${e}`,t);try{const i=await r.handler(t);return l.log(`Function ${e} completed:`,i),this.guardResultSize(e,i,r.maxResultBytes)}catch(i){throw l.error(`Function ${e} failed:`,i),new y.AgoFunctionError(`Function "${e}" execution failed: ${i instanceof Error?i.message:"Unknown error"}`,e,i instanceof Error?i:void 0)}}guardResultSize(e,t,r){let i;try{i=JSON.stringify(t)}catch{return t}if(i===void 0)return t;const s=new TextEncoder().encode(i).length,n=r??this.defaultMaxResultBytes;return s>n?(l.warn(`Function "${e}" result is ${s} bytes, over the ${n}-byte limit; a truncated preview was sent to the agent instead. Return fewer fields, paginate, or raise maxResultBytes for this function.`),{truncated:!0,originalBytes:s,maxBytes:n,preview:i.slice(0,Le),hint:`The result of "${e}" exceeded the ${n}-byte limit and was truncated. Request less data (use limit or filter parameters if available), or tell the user the result is too large to process.`}):(s>je&&l.warn(`Function "${e}" returned a large result (${Math.round(s/1024)} KB). Large results consume LLM context: return fewer fields, paginate, or push the data to the UI and return a summary.`),t)}clear(){const e=this.functions.size>0;this.functions.clear(),l.log("Cleared all registered functions"),e&&this.emitChange()}get size(){return this.functions.size}},Ue=new TextEncoder;function E(e){return Ue.encode(e).length}function D(e){return E(JSON.stringify(e))-2}function fe(e,t){if(t<=0)return"";let r="",i=0;for(const s of e){const n=D(s);if(i+n>t)break;r+=s,i+=n}return r}var We=50,Be=2;var qe=2e3;function C(e){try{return JSON.stringify(e)}catch{return}}var $=Symbol("ago.pageData.timeout");function Ge(e,t){return t<=0?Promise.resolve($):new Promise((r,i)=>{const s=setTimeout(()=>r($),t);e.then(n=>{clearTimeout(s),r(n)},n=>{clearTimeout(s),i(n)})})}async function Ke(e,t){const r=Date.now()+t;let i=0;for(;Date.now()<r&&i<Be;)i=e().isLoading?.()?0:i+1,await new Promise(o=>setTimeout(o,We));const s=e().get();if(!V(s))return s;const n=await Ge(Promise.resolve(s),r-Date.now());if(n!==$)return n;l.warn("Page data did not resolve within the settle timeout; returning what the page has now. Raise settleTimeoutMs if the work legitimately takes longer.");const a=e().get();if(!V(a))return a;Promise.resolve(a).catch(()=>{})}function V(e){return typeof e=="object"&&e!==null&&typeof e.then=="function"}function Je(e){if(typeof e!="object"||e===null||Array.isArray(e))return;const t=e;let r;for(const i of Object.keys(t)){const s=t[i];Array.isArray(s)&&(r===void 0||s.length>t[r].length)&&(r=i)}return r}function He(e,t){let r=2,i=0;for(const s of e){const n=E(C(s)??"null")+(i>0?1:0);if(r+n>t)break;r+=n,i++}return i}function N(e){return`The page data returned by "${e}" was too large to send in full. Only the first items are included: ask for fewer rows or narrow the filters to see the rest.`}function Xe(e,t,r,i){const s={truncated:!0,originalBytes:r,maxBytes:i,preview:"",hint:N(e)},n=E(C(s)??"{}");return{...s,preview:fe(t,Math.min(qe,i-n))}}function ze(e,t,r,i,s){const n=r===void 0?{}:{...t},a=r??"items",o=E(C({...n,[a]:[],truncation:{truncated:!0,returnedItems:i.length,totalItems:i.length,hint:N(e)}})??"{}")-2;if(o>=s)return;const c=i.slice(0,He(i,s-o));return{...n,[a]:c,truncation:{truncated:!0,returnedItems:c.length,totalItems:i.length,hint:N(e)}}}function Y(e,t,r){const i=C(t);if(i===void 0)return t;const s=E(i);if(s<=r)return t;l.warn(`Page data for "${e}" is ${s} bytes, over the ${r}-byte limit; it was truncated to the first items that fit. Return fewer fields per item, paginate, or raise maxResultBytes on the data source.`);const n=Je(t),a=Array.isArray(t)?t:n!==void 0?t[n]:void 0;if(a){const o=ze(e,t,n,a,r),c=E(C(o)??"");if(o!==void 0&&c<=r)return o}return Xe(e,i,s,r)}function k(e,t){if(e===t)return!0;if(e===null||t===null||typeof e!="object"||typeof t!="object"||Array.isArray(e)!==Array.isArray(t))return!1;if(Array.isArray(e))return e.length!==t.length?!1:e.every((s,n)=>k(s,t[n]));const r=Object.keys(e),i=Object.keys(t);return r.length!==i.length?!1:r.every(s=>s in t&&k(e[s],t[s]))}var Q=100,T=" … [truncated]",ge={truncated:!0},Ve=E(',"data":'+JSON.stringify(ge));function j(e){return E(JSON.stringify(e))}function Z(e,t){if(j(e)<=t||!e.rejected)return e;const r=Object.entries(e.rejected),i=Object.fromEntries(r.map(([o])=>[o,T])),s={...e,rejected:i};let n=j(s);if(n>t)return s;const a=D(T);for(const[o,c]of r){const u=D(c),d=t-n+a;if(u<=d){i[o]=c,n+=u-a;continue}i[o]=fe(c,d-a)+T;break}return s}function _(e){return Array.isArray(e)?"array":typeof e}function ee(e){return typeof e!="number"?`Expected type "number", got "${_(e)}".`:Number.isFinite(e)?null:"Expected a finite number."}function me(e){const t=e.slice(0,Q).map(i=>JSON.stringify(i)),r=e.length-Q;return r>0?`${t.join(", ")} (${r} more not shown)`:t.join(", ")}function te(e,t){return t.includes(e)?null:`${JSON.stringify(e)} is not an allowed value. Allowed values: ${me(t)}.`}function Ye(e,t){const{schema:r}=t;if(r.type==="array"){if(!Array.isArray(e))return`Expected type "array", got "${_(e)}".`;for(let s=0;s<e.length;s++){const n=e[s];if(r.items?.type){const a=r.items.type==="number"?ee(n):_(n)!==r.items.type?`Expected type "${r.items.type}", got "${_(n)}".`:null;if(a)return`Array item at index ${s}: ${a[0].toLowerCase()}${a.slice(1)}`}if(r.items?.enum){const a=te(n,r.items.enum);if(a)return`Array item ${a}`}}return null}if(r.type==="number"){const s=ee(e);if(s)return s}else if(_(e)!==r.type)return`Expected type "${r.type}", got "${_(e)}".`;const i=pe(t);return i?te(e,i):null}function G(e){return e.clearable===!0&&e.schema.type==="string"}function pe(e){const t=e.schema.enum;if(t)return G(e)&&!t.includes("")?[...t,""]:t}function Qe(e){const t={...e.schema,description:e.description};G(e)&&(t.description=`${e.description} Pass "" to clear it.`);const r=pe(e);return r&&(t.enum=r),t}function Ze(e,t){const r=new Map(e.map(n=>[n.name,n])),i=e.map(n=>n.name),s=e.map(n=>`- "${n.name}": ${n.description}`).join(`
|
|
3
|
+
`);return{name:t.name,handler:async n=>{const a=[],o=[],c={};for(const[h,p]of Object.entries(n)){const v=r.get(h);if(!v){c[h]=`"${h}" is not a registered control. Available controls: ${me(i)}.`;continue}if(p==null||p===""&&!G(v))continue;const S=Ye(p,v);if(S){c[h]=S;continue}if(v.get&&k(p,v.get())){o.push(h);continue}const b=await v.set(p);b?b.result==="rejected"?c[h]=b.reason||"The page rejected this field's update.":b.result==="unchanged"?o.push(h):a.push(h):a.push(h)}const u=Object.keys(c).length>0,d={success:!u,applied:a,unchanged:o,...u?{rejected:c}:{}},g=t.getResultBudget();if(!t.data)return Z(d,g);const m=Z(d,g-Ve),w=await t.data.read(m),f={...m,data:w};return j(f)<=g?f:{...m,data:ge}},description:(e.length>0?`Change the state of the current page. Set ONLY the controls the user explicitly asked for; leave the others unset. Available controls:
|
|
4
|
+
${s}`:"The current page has no editable state — nothing to change here.")+(t.data?`
|
|
5
|
+
Returns the resulting page data once it has loaded: ${t.data.description}`:""),parameters:{type:"object",properties:Object.fromEntries(e.map(n=>[n.name,Qe(n)])),required:[]},requiresApproval:t.requiresApproval,maxResultBytes:t.data?.maxResultBytes}}var et=250,tt=3,rt=1e3,it=24,st=10,nt=50,ot=["mousemove","mousedown","keydown","scroll","touchstart"],ye=class{constructor(e={}){this.started=!1,this.teardowns=[],this.route="",this.routeEnteredAt=0,this.lastActivityAt=0,this.lastHeavyActivityAt=0,this.recentRoutes=[],this.routeBounces=0,this.rageClicks=0,this.jsErrors=0,this.fieldErrors={},this.recentClicks=[],this.signals=[],this.listeners=new Set,this.getPageState=e.getPageState,this.activityThrottleMs=e.activityThrottleMs??et,this.rageClickCount=e.rageClickCount??tt,this.rageClickWindowMs=e.rageClickWindowMs??rt,this.rageClickRadiusPx=e.rageClickRadiusPx??it,this.maxRecentRoutes=e.maxRecentRoutes??st,this.maxSignals=e.maxSignals??nt}start(){if(this.started||typeof window>"u"||typeof document>"u")return;this.started=!0;const e=Date.now();this.route=this.currentPathname(),this.routeEnteredAt=e,this.lastActivityAt=e,this.recentRoutes=[this.route];const t=(i,s,n)=>{i.addEventListener(s,n,{passive:!0}),this.teardowns.push(()=>i.removeEventListener(s,n))},r=()=>this.recordActivity();for(const i of ot)t(window,i,r);t(document,"visibilitychange",()=>{document.visibilityState==="visible"&&this.recordActivity()}),t(window,"popstate",()=>this.checkRoute()),t(window,"hashchange",()=>this.checkRoute()),t(window,"click",i=>this.onClick(i)),l.log("SignalCollector started")}destroy(){for(const e of this.teardowns)e();this.teardowns=[],this.listeners.clear(),this.recentClicks=[],this.started=!1,l.log("SignalCollector destroyed")}signalFieldError(e){this.checkRoute();const t=(this.fieldErrors[e]??0)+1;this.fieldErrors[e]=t,this.pushSignal({type:"field_error",route:this.route,at:Date.now(),count:t,meta:{field:e}})}signalJsError(e){this.checkRoute(),this.jsErrors+=1,this.pushSignal({type:"js_error",route:this.route,at:Date.now(),count:this.jsErrors,meta:{kind:e}})}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}getSignals(){return[...this.signals]}getSnapshot(e){this.checkRoute();const t=Date.now();return{route:this.route,dwellMs:this.started?t-this.routeEnteredAt:0,idleMs:this.started?t-this.lastActivityAt:0,rageClicks:this.rageClicks,jsErrors:this.jsErrors,routeBounces:this.routeBounces,fieldErrors:{...this.fieldErrors},recentRoutes:[...this.recentRoutes],pageState:e?.pageState===!1?null:this.readPageState()}}currentPathname(){return typeof window<"u"&&window.location?window.location.pathname:""}readPageState(){if(!this.getPageState)return null;try{return this.getPageState()??null}catch(e){return l.warn("SignalCollector getPageState threw:",e),null}}recordActivity(){const e=Date.now();this.lastActivityAt=e,e-this.lastHeavyActivityAt>=this.activityThrottleMs&&(this.lastHeavyActivityAt=e,this.checkRoute())}checkRoute(){if(!this.started)return;const e=this.currentPathname();if(e===this.route)return;const t=Date.now(),r=this.route;this.route=e,this.routeEnteredAt=t,this.rageClicks=0,this.jsErrors=0,this.fieldErrors={},this.recentClicks=[],this.recentRoutes.push(e),this.recentRoutes.length>this.maxRecentRoutes&&this.recentRoutes.splice(0,this.recentRoutes.length-this.maxRecentRoutes),this.pushSignal({type:"route_change",route:e,at:t,meta:{from:r}});const i=this.recentRoutes,s=i.length;s>=4&&i[s-1]===i[s-3]&&i[s-2]===i[s-4]&&i[s-1]!==i[s-2]&&(this.routeBounces+=1,this.pushSignal({type:"route_bounce",route:e,at:t,count:this.routeBounces,meta:{between:`${i[s-2]}↔${i[s-1]}`}}))}onClick(e){this.recordActivity();const t=Date.now(),r=this.pageStateKey(),i={at:t,x:e.clientX,y:e.clientY,stateKey:r};this.recentClicks=this.recentClicks.filter(o=>t-o.at<=this.rageClickWindowMs);const s=this.recentClicks[0],n=!s||Math.abs(i.x-s.x)<=this.rageClickRadiusPx&&Math.abs(i.y-s.y)<=this.rageClickRadiusPx,a=!s||s.stateKey===r;if(!n||!a){this.recentClicks=[i];return}this.recentClicks.push(i),this.recentClicks.length>=this.rageClickCount&&(this.rageClicks+=1,this.recentClicks=[],this.pushSignal({type:"rage_click",route:this.route,at:t,count:this.rageClicks}))}pageStateKey(){const e=this.readPageState();if(!e)return"";try{return JSON.stringify(e)}catch{return""}}pushSignal(e){this.signals.push(e),this.signals.length>this.maxSignals&&this.signals.splice(0,this.signals.length-this.maxSignals);for(const t of this.listeners)try{t(e)}catch(r){l.error("Signal listener threw:",r)}}};function ve(e,t){const r=t?t.storage??(typeof localStorage<"u"?localStorage:void 0):void 0;let i=e;if(t&&r)try{const o=r.getItem(t.key);o!=null&&(i=JSON.parse(o))}catch{}const s=new Set,n=()=>s.forEach(o=>o(i));function a(){if(t&&r)try{r.setItem(t.key,JSON.stringify(i))}catch{}}return{get:()=>i,set:o=>{i=o,a(),n()},subscribe:o=>(s.add(o),()=>{s.delete(o)})}}var at=6e4,ct=1440*60*1e3,lt="ago_proactive";function I(e){const t=new Date(e),r=String(t.getMonth()+1).padStart(2,"0"),i=String(t.getDate()).padStart(2,"0");return`${t.getFullYear()}-${r}-${i}`}var ut=class{constructor(e={}){this.killSwitchEnabled=!1,this.engaged=!1,this.turnInFlight=!1,this.slotOccupied=!1,this.sessionCount=0,this.perSessionCap=e.frequencyCap?.perSession,this.perDayCap=e.frequencyCap?.perDay,this.store=ve({optOut:!1,lastFiredAt:{},dismissedAt:{},day:{date:I(Date.now()),count:0}},{key:e.storageKey??lt,storage:e.storage})}setKillSwitch(e){this.killSwitchEnabled=e}optOut(){this.store.set({...this.store.get(),optOut:!0})}optIn(){this.store.set({...this.store.get(),optOut:!1})}isOptedOut(){return this.store.get().optOut}setEngaged(e){this.engaged=e}setTurnInFlight(e){this.turnInFlight=e}isSlotOccupied(){return this.slotOccupied}occupySlot(){this.slotOccupied=!0}releaseSlot(){this.slotOccupied=!1}canFire(e,t=Date.now()){if(!this.killSwitchEnabled)return this.deny(e,"kill-switch (proactive disabled server-side)");const r=this.store.get();if(r.optOut)return this.deny(e,"user opted out");if(this.engaged)return this.deny(e,"user engaged (widget open)");if(this.turnInFlight)return this.deny(e,"message turn in flight");if(this.slotOccupied)return this.deny(e,"nudge slot occupied");const i=r.lastFiredAt[e.id],s=e.cooldownMs??at;if(i!==void 0&&t-i<s)return this.deny(e,"cooldown");const n=r.dismissedAt[e.id],a=e.resurfaceAfterMs??ct;return n!==void 0&&t-n<a?this.deny(e,"dismissed recently"):this.perSessionCap!==void 0&&this.sessionCount>=this.perSessionCap?this.deny(e,"perSession cap"):this.perDayCap!==void 0&&this.dayCount(t)>=this.perDayCap?this.deny(e,"perDay cap"):!0}recordFired(e,t=Date.now()){const r=this.store.get();this.store.set({...r,lastFiredAt:{...r.lastFiredAt,[e]:t}})}recordNudgeShown(e=Date.now()){this.sessionCount+=1;const t=this.store.get(),r=I(e),i=t.day.date===r?{date:r,count:t.day.count+1}:{date:r,count:1};this.store.set({...t,day:i})}recordDismissed(e,t=Date.now()){const r=this.store.get();this.store.set({...r,dismissedAt:{...r.dismissedAt,[e]:t}})}dayCount(e){const t=this.store.get();return t.day.date===I(e)?t.day.count:0}deny(e,t){return l.debug(`NudgeGovernor: trigger "${e.id}" blocked — ${t}`),!1}};function L(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=Math.floor(Math.random()*16);return(e==="x"?t:t&3|8).toString(16)})}function dt(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function we(e,t){if(e==="*"||e===t)return!0;const r=e.split("/"),i=r.map((s,n)=>{const a=n===r.length-1;return s==="*"?a?"[^/]+(?:/[^/]+)*":"[^/]+":s.startsWith(":")?"[^/]+":dt(s)});return new RegExp("^"+i.join("/")+"/?$").test(t)}function K(e,t){return e===t?!0:e===null||t===null?!1:Array.isArray(e)?!Array.isArray(t)||t.length!==e.length?!1:e.every((r,i)=>k(r,t[i])):typeof e=="object"?typeof t!="object"||Array.isArray(t)?!1:Object.entries(e).every(([r,i])=>K(i,t[r])):!1}function be(e,t){if(e.route!==void 0&&!we(e.route,t.route)||e.idleMs!==void 0&&t.idleMs<e.idleMs||e.dwellMs!==void 0&&t.dwellMs<e.dwellMs||e.rageClicks!==void 0&&t.rageClicks<e.rageClicks||e.jsErrors!==void 0&&(t.jsErrors??0)<e.jsErrors||e.routeBounces!==void 0&&t.routeBounces<e.routeBounces)return!1;if(e.fieldErrors!==void 0){for(const[r,i]of Object.entries(e.fieldErrors))if((t.fieldErrors[r]??0)<i)return!1}return!(e.pageState!==void 0&&!K(e.pageState,t.pageState??{}))}var ht=1e3,ft="/api/sdk/v1/config",gt="/api/sdk/v1/proactive/evaluate",mt=class{constructor(e){this.tickTimer=null,this.teardowns=[],this.started=!1,this.activeNudge=null,this.lastConversationId=null,this.shownIds=new Set,this.resolvedIds=new Set,this.lastEvaluationAt=0,this.client=e.client,this.collector=e.collector,this.governor=e.governor,this.tracker=e.tracker,this.options=e.options,this.tickMs=e.options.tickMs??ht}start(){if(this.started)return;this.started=!0,this.options.enabledOverride!==void 0?this.governor.setKillSwitch(this.options.enabledOverride):this.loadKillSwitch();const e=s=>{s.conversationId&&(this.lastConversationId=s.conversationId),this.governor.setTurnInFlight(!0)},t=()=>this.governor.setTurnInFlight(!1),r=()=>this.governor.setTurnInFlight(!1),i=s=>{s?.id&&(this.lastConversationId=s.id)};this.client.on("message:start",e),this.client.on("message:complete",t),this.client.on("message:error",r),this.client.on("conversation:loaded",i),this.teardowns.push(()=>{this.client.off("message:start",e),this.client.off("message:complete",t),this.client.off("message:error",r),this.client.off("conversation:loaded",i)}),this.tickTimer=setInterval(()=>this.evaluate(),this.tickMs),this.teardowns.push(this.collector.subscribe(()=>{Date.now()-this.lastEvaluationAt>=this.tickMs&&this.evaluate()}))}stop(){this.tickTimer!==null&&(clearInterval(this.tickTimer),this.tickTimer=null);for(const e of this.teardowns)e();this.teardowns=[],this.started=!1}getActiveNudge(){return this.activeNudge}async loadKillSwitch(){try{const e=await this.client.getHttp().get(ft);this.governor.setKillSwitch(e?.proactive?.enabled===!0)}catch(e){l.debug("Proactive config fetch failed; staying disabled:",e),this.governor.setKillSwitch(!1)}}evaluate(){if(this.lastEvaluationAt=Date.now(),typeof document<"u"&&document.visibilityState==="hidden"||this.governor.isSlotOccupied())return;const e=this.collector.getSnapshot();for(const t of this.options.triggers)if(be(t.when,e)&&this.governor.canFire(t)){this.fire(t);return}}fire(e){if(this.governor.recordFired(e.id),this.governor.occupySlot(),e.intervene==="agent"){this.evaluateWithAgent(e);return}this.setReady({id:L(),triggerId:e.id,source:"static",message:e.intervene.message,action:e.intervene.action,goal:e.goal,kickoff:e.kickoff,createdAt:new Date})}async evaluateWithAgent(e){const t=L(),r={client_nudge_id:t,trigger_id:e.id,goal:e.goal??"",agent:this.client.getConfiguredAgent(),signals:this.collector.getSnapshot(),client_context:this.client.getContextSnapshot()??{entries:{}},client_functions:this.client.getRegisteredFunctions()};let i;try{i=await this.client.getHttp().post(gt,r)}catch(s){l.debug("Proactive evaluate failed (treated as no-intervene):",s),this.governor.releaseSlot();return}if(!i?.intervene||!i.message){this.governor.releaseSlot();return}this.setReady({id:t,triggerId:e.id,source:"agent",message:i.message,action:pt(i.action),goal:e.goal,kickoff:e.kickoff,createdAt:new Date,serverNudgeId:i.nudge_id})}setReady(e){this.activeNudge=e,this.client.emitProactiveEvent("nudge:ready",e)}shown(e){this.shownIds.has(e.id)||(this.shownIds.add(e.id),this.governor.recordNudgeShown(),this.tracker.track({clientNudgeId:e.id,triggerId:e.triggerId,source:e.source,type:"shown",message:e.message,occurredAt:Date.now()}),this.client.emitProactiveEvent("nudge:shown",{nudge:e}))}dismiss(e){this.resolvedIds.has(e.id)||(this.resolvedIds.add(e.id),this.governor.recordDismissed(e.triggerId),this.tracker.track({clientNudgeId:e.id,triggerId:e.triggerId,source:e.source,type:"dismissed",occurredAt:Date.now()}),this.clearActive(e),this.client.emitProactiveEvent("nudge:dismissed",{nudge:e}))}async accept(e){this.resolvedIds.has(e.id)||(this.resolvedIds.add(e.id),this.tracker.track({clientNudgeId:e.id,triggerId:e.triggerId,source:e.source,type:"accepted",occurredAt:Date.now()}),this.clearActive(e),this.client.emitProactiveEvent("nudge:accepted",{nudge:e}),(e.source==="agent"||e.goal)&&(this.lastConversationId?this.client.sendMessage(yt(e),{hidden:!0,conversationId:this.lastConversationId}).catch(t=>l.debug("Nudge kickoff message failed:",t)):e.kickoff?this.client.sendMessage(e.kickoff).catch(t=>l.debug("Nudge kickoff message failed:",t)):l.debug("Nudge accepted with no open conversation and no trigger.kickoff; skipping the chat pre-seed (a hidden message cannot open a conversation).")),e.action&&await this.runAction(e.action))}markConverted(e){this.tracker.track({clientNudgeId:e.id,triggerId:e.triggerId,source:e.source,type:"converted",occurredAt:Date.now()})}clearActive(e){this.activeNudge?.id===e.id&&(this.activeNudge=null),this.governor.releaseSlot()}async runAction(e){try{"functionName"in e?await this.client.executeClientFunction(e.functionName,e.arguments??{}):await this.client.executeClientFunction("setPageState",e.setPageState)}catch(t){l.warn("Nudge action failed:",t)}}};function pt(e){if(e)return{label:e.label,functionName:e.function_name,arguments:e.arguments}}function yt(e){const t=e.goal?` Goal: ${e.goal}.`:"";return`The user accepted a proactive nudge that said: "${e.message}".${t} Recent friction signals are in the client context (friction_signals). Start helping with this now: briefly explain what you can do and take the first concrete step.`}var vt=5e3,wt="/api/sdk/v1/proactive/events",bt=class{constructor(e){if(this.queue=[],this.flushTimer=null,this.teardowns=[],this.destroyed=!1,this.post=e.post,this.agent=e.agent,this.flushIntervalMs=e.flushIntervalMs??vt,typeof document<"u"){const t=()=>{document.visibilityState==="hidden"&&this.flush({keepalive:!0})};document.addEventListener("visibilitychange",t),this.teardowns.push(()=>document.removeEventListener("visibilitychange",t))}if(typeof window<"u"){const t=()=>this.flush({keepalive:!0});window.addEventListener("pagehide",t),this.teardowns.push(()=>window.removeEventListener("pagehide",t))}}track(e){this.destroyed||(this.queue.push(e),this.flushTimer===null&&(this.flushTimer=setTimeout(()=>this.flush(),this.flushIntervalMs)))}flush(e){if(this.flushTimer!==null&&(clearTimeout(this.flushTimer),this.flushTimer=null),this.queue.length===0)return;const t=this.queue;this.queue=[];const r={events:t.map(i=>({client_nudge_id:i.clientNudgeId,trigger_id:i.triggerId,source:i.source,type:i.type,...i.message!==void 0?{message:i.message}:{},...this.agent?{agent:this.agent}:{},occurred_at:new Date(i.occurredAt).toISOString()}))};this.post(wt,r,e).catch(i=>{l.debug("Proactive event batch failed:",i)})}destroy(){if(!this.destroyed){this.flush({keepalive:!0}),this.destroyed=!0;for(const e of this.teardowns)e();this.teardowns=[]}}},re="friction_signals";function U(e,t){e.proactive&&(l.warn("createAgoProactive: a proactive controller is already attached; replacing it."),e.proactive.destroy());const r=new ye({...t.signals,getPageState:()=>{const c=e.getContextSnapshot();if(!c)return null;const u={};for(const[d,g]of Object.entries(c.entries))d.startsWith("page-state:")&&g.data&&Object.assign(u,g.data);return Object.keys(u).length>0?u:null}});r.start();const i=c=>{r.signalJsError(c.type)};e.on("error:captured",i),e.addDynamicContext(re,()=>{const{pageState:c,...u}=r.getSnapshot({pageState:!1});return{name:"Friction signals",description:"Behavioral friction observed on the current page: dwell/idle times, rage clicks, route bounces, repeated field errors, JavaScript error count (names and counters only).",data:u}});const s=new ut({frequencyCap:t.frequencyCap,storage:t.storage,storageKey:t.storageKey}),n=new bt({post:(c,u,d)=>e.getHttp().post(c,u,d),agent:e.getConfiguredAgent()}),a=new mt({client:e,collector:r,governor:s,tracker:n,options:t});a.start();const o={optOut:()=>s.optOut(),optIn:()=>s.optIn(),isOptedOut:()=>s.isOptedOut(),setEngaged:c=>s.setEngaged(c),signalFieldError:c=>r.signalFieldError(c),getSignalsSnapshot:()=>r.getSnapshot(),getActiveNudge:()=>a.getActiveNudge(),shown:c=>a.shown(c),accept:c=>a.accept(c),dismiss:c=>a.dismiss(c),markConverted:c=>a.markConverted(c),destroy:()=>{a.stop(),n.destroy(),e.off("error:captured",i),r.destroy(),e.removeDynamicContext(re),e.proactive===o&&(e.proactive=null)}};return e.proactive=o,o}var Ee=class{constructor(){this.entries=new Map,this.dynamicProviders=new Map}set(e,t){this.entries.set(e,t),l.log(`ClientContext set: ${e}`)}remove(e){const t=this.entries.delete(e);return t&&l.log(`ClientContext removed: ${e}`),t}addDynamicProvider(e,t){this.dynamicProviders.set(e,t),l.log(`DynamicContext provider added: ${e}`)}removeDynamicProvider(e){const t=this.dynamicProviders.delete(e);return t&&l.log(`DynamicContext provider removed: ${e}`),t}getSnapshot(){if(this.entries.size===0&&this.dynamicProviders.size===0)return null;const e={};for(const[t,r]of this.entries)e[t]=r;for(const[t,r]of this.dynamicProviders)try{const i=r();i&&(e[t]=i)}catch(i){l.error(`DynamicContext provider "${t}" threw:`,i)}return Object.keys(e).length===0?null:{entries:e}}clear(){this.entries.clear(),this.dynamicProviders.clear(),l.log("ClientContext cleared")}},Et="page-state:";function St(e){const t={};for(const[r,i]of Object.entries(e))r.startsWith(Et)&&i.data&&Object.assign(t,i.data);return t}function _t(e){const t=e["current-page"]?.data;return t?.page?t.page:t?.url?t.url:e["browser-page"]?.data?.url}function Ct(e,t){return e===t?!0:JSON.stringify(e)===JSON.stringify(t)}function At(e,t){const r=[];for(const i of Object.keys(t))i in e&&(Ct(e[i],t[i])||r.push({field:i,from:e[i],to:t[i]}));return r}function kt(e,t){const r=St(t),i=_t(t);return{changes:e&&e.page===i?At(e.state,r):[],baseline:{page:i,state:r}}}function W(e){return e===null||typeof e!="object"?JSON.stringify(e)??"null":Array.isArray(e)?`[${e.map(W).join(",")}]`:`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${W(e[t])}`).join(",")}}`}var ie="",Se=class{constructor(e,t={}){this.callbacks=e,this.options=t,this.buffer="",this.message={},this.toolCalls=[],this.sources=[],this.followUpReplies=[],this.isFirstChunk=!0,this.answerCompleteEmitted=!1,this.waitingClientEmitted=!1,this.firedClientFunctions=new Map}async processStream(e){if(!e.body)throw new y.AgoStreamError("Response has no body. The endpoint did not return a stream: check that `baseUrl` points at an AGO API and nothing (proxy, mock) strips the SSE body.","stream_no_body");const t=e.body.getReader(),r=new TextDecoder;try{for(;;){const{done:i,value:s}=await t.read();if(i)break;const n=r.decode(s,{stream:!0});this.buffer+=n,this.processBuffer()}return this.buffer.trim()&&this.processBuffer(),this.buildFinalMessage()}catch(i){if(this.options.signal?.aborted)return this.message.status="CANCELED",this.buildFinalMessage();const s=i instanceof Error?i:new y.AgoStreamError("Stream processing failed mid-flight. The connection may have dropped; retry the message.");throw this.callbacks.onError?.(s),s}finally{t.releaseLock()}}processBuffer(){const e=this.buffer.split(`
|
|
6
|
+
|
|
7
|
+
`);this.buffer=e.pop()||"";for(const t of e){if(!t.trim())continue;const r=t.split(`
|
|
8
|
+
`);for(const i of r)if(!i.startsWith(": ")&&i.startsWith("data: ")){const s=i.slice(6);try{const n=JSON.parse(s);this.handleChunk(n)}catch(n){l.warn("Failed to parse SSE data:",s,n)}}}}handleChunk(e){if(this.callbacks.onRawChunk?.(e),e.message_id&&!this.message.id&&(this.message.id=e.message_id),e.thread?.id&&(this.message.conversationId=e.thread.id,this.isFirstChunk&&this.message.id&&(this.isFirstChunk=!1,this.callbacks.onStart?.({conversationId:this.message.conversationId,messageId:this.message.id}))),e.title&&this.message.conversationId&&this.callbacks.onTitle?.({conversationId:this.message.conversationId,title:e.title}),e.content!==void 0&&(this.message.content=(this.message.content||"")+e.content,this.message.conversationId&&this.message.id&&this.callbacks.onChunk?.({content:e.content,conversationId:this.message.conversationId,messageId:this.message.id})),e.full_content!==void 0&&(this.message.content=e.full_content),e.status&&(this.message.status=e.status),e.agent&&(this.message.agent={id:e.agent.id,name:e.agent.name,displayName:e.agent.display_name}),e.knowledge_sources&&(this.sources=e.knowledge_sources.map(t=>{const r=t.knowledge_document;return{id:r.id,title:r.title,url:r.use_external_link?r.external_link_url:r.internal_link_url}})),e.type==="client_function"&&e.function_name){const t=`${e.function_name}::${W(e.arguments??{})}`,r=e.id||"",i=this.firedClientFunctions.get(t);let s=!1;i?r&&!i.has(r)&&(i.has(ie)?(i.delete(ie),i.add(r)):(i.add(r),s=!0)):(this.firedClientFunctions.set(t,new Set([r])),s=!0),s&&this.callbacks.onClientFunction?.({invocationId:r,functionName:e.function_name,arguments:e.arguments||{},conversationId:this.message.conversationId||""})}if(e.tool_call_data&&e.type&&e.type!=="client_function"){const t=this.parseToolCall(e);this.callbacks.onToolCall?.(t);const r=this.toolCalls.findIndex(i=>i.id===t.id);r>=0?this.toolCalls[r]=t:this.toolCalls.push(t)}e.follow_up_replies&&(this.followUpReplies=e.follow_up_replies),this.message.status==="DONE"&&!this.answerCompleteEmitted&&this.message.id&&(this.answerCompleteEmitted=!0,this.callbacks.onAnswerComplete?.(this.buildMessage())),this.message.status==="WAITING_CLIENT"&&!this.waitingClientEmitted&&this.message.id&&(this.waitingClientEmitted=!0,this.callbacks.onWaitingClient?.({conversationId:this.message.conversationId||"",messageId:this.message.id,waitingToolCallIds:e.waiting_tool_call_ids??[]}))}parseToolCall(e){return{id:e.id||"",type:e.type||"status_message",status:e.status||"unknown",toolName:e.tool_name||"",toolDisplayName:e.tool_display_name,message:e.message,formSchema:e.form_schema,data:e.data,functionName:e.function_name,arguments:e.arguments,displayMode:e.display_mode,askToTalkToHuman:e.ask_to_talk_to_human,allowedToCreateTicket:e.allowed_to_create_ticket,ticket:e.ticket,mode:e.mode,ticketFormId:e.ticket_form_id,embedHtml:e.embed_html,embedDescription:e.embed_description}}buildMessage(){return{id:this.message.id||"",conversationId:this.message.conversationId||"",content:this.message.content||"",role:"assistant",status:this.message.status||"DONE",agent:this.message.agent,sources:this.sources.length>0?this.sources:void 0,toolCalls:this.toolCalls.length>0?this.toolCalls:void 0,followUpReplies:this.followUpReplies.length>0?this.followUpReplies:void 0,createdAt:new Date}}buildFinalMessage(){const e=this.buildMessage();return e.status!=="WAITING_CLIENT"&&this.callbacks.onComplete?.(e),e}};function Rt(e){const t=e.message.toLowerCase();return t.includes("load failed")||t.includes("failed to fetch")||t.includes("network")||t.includes("abort")}var Tt=new Set(["image/jpeg","image/png","image/gif","image/webp","image/bmp","image/tiff"]);function _e(e){if(!e)return;const t=typeof window<"u"&&window.location?window.location.href:"https://ago.local/";try{const r=new URL(e,t);if(r.protocol==="http:"||r.protocol==="https:"||r.protocol==="blob:")return e}catch{}}function It(e){return e.isSafeImage===!0&&typeof e.contentType=="string"&&e.contentType.startsWith("image/")&&_e(e.url)!==void 0}function xt(e){if(e==null||e<0)return"";if(e<1024)return`${e} B`;const t=e/1024;return t<1024?`${t.toFixed(1)} KB`:`${(t/1024).toFixed(1)} MB`}function Ft(e){return{id:String(e.id??""),name:typeof e.name=="string"&&e.name?e.name:"file",contentType:typeof e.content_type=="string"?e.content_type:void 0,fileSize:typeof e.file_size=="number"?e.file_size:void 0,url:typeof e.file_url=="string"?e.file_url:void 0,isSafeImage:e.is_safe_image===!0}}function Pt(e){return e.map((t,r)=>({id:`local-${r}-${t.name}`,name:t.name,contentType:t.type||void 0,fileSize:t.size,url:typeof URL<"u"&&URL.createObjectURL?URL.createObjectURL(t):void 0,isSafeImage:Tt.has(t.type)}))}var Ce=class{constructor(){this.handlers=new Map}on(e,t){this.handlers.has(e)||this.handlers.set(e,new Set),this.handlers.get(e).add(t)}off(e,t){const r=this.handlers.get(e);r&&r.delete(t)}emit(e,t){const r=this.handlers.get(e);r&&r.forEach(i=>{try{i(t)}catch(s){console.error(`Error in event handler for ${String(e)}:`,s)}})}once(e,t){const r=(i=>{this.off(e,r),t(i)});this.on(e,r)}waitFor(e,t){return new Promise((r,i)=>{let s;const n=(a=>{s&&clearTimeout(s),r(a)});this.once(e,n),t?.timeout&&(s=setTimeout(()=>{this.off(e,n),i(new Error(`waitFor("${String(e)}") timed out after ${t.timeout}ms`))},t.timeout))})}removeAllListeners(e){e?this.handlers.delete(e):this.handlers.clear()}},Mt=4e3,Ot=150,Dt=600;function $t(){if(!(typeof document>"u"))return document.modelContext}function Nt(e,t){return new Promise(r=>{let i,s=!1;const n=()=>{if(!s){s=!0,clearTimeout(i),clearTimeout(c),clearTimeout(o);for(const d of t)d?.removeEventListener("abort",n);u(),r()}},a=()=>{clearTimeout(c),clearTimeout(i),i=setTimeout(n,Ot)},o=setTimeout(n,Mt),c=setTimeout(n,Dt),u=e(a);for(const d of t){if(d?.aborted)return n();d?.addEventListener("abort",n)}})}function jt(e){const t=$t();if(!t)return l.log("WebMCP is not available in this browser; bridge not attached"),()=>{};const r=t,i=new Map,s=new Set,n=new AbortController;let a=!1,o=!1;function c(f){return JSON.stringify([f.description,f.inputSchema,f.annotations])}function u(f,h){const p=e.getFunctionRegistrations().find(v=>v.name===f)?.webmcp;return!p||!p.navigates?!1:h?.success!==!1}function d(){const f=new Map;for(const h of e.getFunctionRegistrations()){if(h.webmcp===!1)continue;const p=h.webmcp||void 0,v=h.name,S={name:v,description:h.schema.description,inputSchema:h.schema.parameters,annotations:p?.annotations,execute:async(b,Ae)=>{const J=await e.runExternalFunction(v,b??{});return!a&&u(v,J)&&await Nt(ke=>e.onFunctionsChanged(ke),[Ae?.signal,n.signal]),J}};f.set(v,{tool:S,signature:c(S)})}return f}function g(){a||o||(o=!0,queueMicrotask(()=>{o=!1,m()}))}function m(){if(a)return;const f=d();for(const[h,p]of i)f.get(h)?.signature!==p.signature&&(p.controller.abort(),i.delete(h));for(const[h,p]of f){if(i.has(h))continue;const v=new AbortController;i.set(h,{signature:p.signature,controller:v}),Promise.resolve(r.registerTool(p.tool,{signal:v.signal})).catch(S=>{if(l.error(`WebMCP rejected the tool "${h}":`,S),i.get(h)?.controller!==v)return;i.delete(h);const b=JSON.stringify([h,p.signature]);s.has(b)||(s.add(b),g())})}}const w=e.onFunctionsChanged(g);return m(),l.log("WebMCP bridge attached"),()=>{if(!a){a=!0,n.abort(),w();for(const f of i.values())f.controller.abort();i.clear(),l.log("WebMCP bridge detached")}}}var se='`baseUrl` is required, e.g. new AgoClient({ baseUrl: "https://YOUR-DOMAIN.api.useago.com" }). Try the public demo account https://playground.api.useago.com (agent generic-guide). See docs/general/configuration.md#error-codes (config_missing_base_url).',Lt=/^[a-z][a-z0-9+.-]*:\/\//i,ne=!1;function B(e,t="AgoClient"){if(typeof e!="object"||e===null)throw new y.AgoError(`${t}: ${se}`,"config_missing_base_url");const r=e.baseUrl;if(typeof r!="string"||r.trim()==="")throw new y.AgoError(`${t}: ${se}`,"config_missing_base_url");P(e.language),!r.startsWith("/")&&!Lt.test(r)&&(ne||(ne=!0,console.warn(`[AGO] ${t}: \`baseUrl\` has no protocol and is not a relative path (config_suspect_base_url). Requests will fail: Node throws a URL parse error, browsers fetch it as a relative path. Use "https://..." (or a "/path" for a same-origin proxy).`)))}function Ut(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function x(e){return e.split("/").filter(t=>t.startsWith(":")).map(t=>t.slice(1))}function Wt(e,t){const r=[];return{path:e.split("/").map(i=>{if(!i.startsWith(":"))return i;const s=i.slice(1),n=t[s];return n==null||n===""?(r.push(s),i):encodeURIComponent(String(n))}).join("/"),missing:r}}function Bt(e,t){const r=t.find(s=>s.path===e);if(r)return r;const i=t.find(s=>{if(!s.path.includes(":"))return!1;const n="^"+s.path.split("/").map(a=>a.startsWith(":")?"[^/]+":Ut(a)).join("/")+"/?$";return new RegExp(n).test(e)});return i||t.filter(s=>s.path!=="/"&&e.startsWith(s.path)).sort((s,n)=>n.path.length-s.path.length)[0]}var qt="activity:recent",Gt="state:delta",oe="errors:recent";function ae(e){return e==="setPageState"?"readPageData":`read${e.charAt(0).toUpperCase()}${e.slice(1)}Data`}var Kt=class A{constructor(t){this.errorWatcher=null,this.lastSentPageState=null,this.warnedEmptyConversations=new Set,this.warnedPageDataPlaceholder=!1,this.pageDataCompanions=new Set,this.pendingResumes=new Map,this.pendingApprovals=new Map,this.resumeGate=null,this.activeTurn=null,this.pausedTurn=null,this.stoppedTurnIds=new Set,this.proactive=null,this.detachWebMCP=null,B(t,"AgoClient"),this.config=t,this.activityLedger=new le(t.maxActivityEntries),this.httpClient=new Fe(t),this.functionRegistry=new he({maxResultBytes:t.maxFunctionResultBytes}),this.contextRegistry=new Ee,this.eventEmitter=new Ce,this.registerActivityContext(),this.functionRegistry.onChange(()=>{this.eventEmitter.emit("functions:changed",this.functionRegistry.getSchemas())}),t.debug&&l.enable(),t.errorWatcher&&this.enableErrorWatcher(t.errorWatcher===!0?void 0:t.errorWatcher),t.proactive&&U(this,t.proactive),this.attachWebMCPBridge(),l.log("AgoClient initialized")}attachWebMCPBridge(){!this.config.webmcp||this.detachWebMCP||(this.detachWebMCP=jt(this))}async sendMessage(t,r){const i=this.functionRegistry.getSchemas(),s=this.buildSendContext(),n=this.config.agent||this.config.defaultAgentId,a=this.resolveClientFunctionsMode(r),o=r?.metadata!==void 0?r.metadata:this.config.metadata,c=o!=null?JSON.stringify(o):void 0,u={content:t,conversation_id:r?.conversationId,agent_id:r?.agentId||n};o!=null&&(u.metadata=o),i.length>0&&(u.client_functions=i,a==="pause"&&(u.client_functions_mode=a)),s&&(u.client_context=s),r?.hidden&&(u.hidden=!0);const d=this.beginTurn();let g;if(r?.files&&r.files.length>0){const m=new FormData;m.append("content",t),c!==void 0&&m.append("metadata",c),r.conversationId&&m.append("conversation_id",r.conversationId),(r.agentId||n)&&m.append("agent_id",r.agentId||n||""),i.length>0&&(m.append("client_functions",JSON.stringify(i)),a==="pause"&&m.append("client_functions_mode",a)),s&&m.append("client_context",JSON.stringify(s)),r.hidden&&m.append("hidden","true");for(const w of r.files)m.append("files",w);g=await this.sendRequest(d,()=>this.httpClient.postFormData("/api/sdk/v1/messages",m,{signal:d.controller.signal}))}else g=await this.sendRequest(d,()=>this.httpClient.postStream("/api/sdk/v1/messages",u,{signal:d.controller.signal}));return g?this.processSSEResponse(g,d):this.buildStoppedMessage(d)}async sendRequest(t,r){try{return await r()}catch(i){if(this.endTurn(t),M(i))return null;throw i}}async processSSEResponse(t,r){let i=!1;const s=new Se({onRawChunk:n=>{r&&(n.message_id&&!r.messageId&&(r.messageId=n.message_id),n.thread?.id&&(r.conversationId=n.thread.id)),this.eventEmitter.emit("stream:message",n)},onStart:n=>{this.eventEmitter.emit("message:start",n)},onChunk:n=>{this.eventEmitter.emit("message:chunk",n)},onToolCall:n=>{this.eventEmitter.emit("toolCall:received",n),n.type==="form"&&this.eventEmitter.emit("toolCall:form",n)},onClientFunction:async n=>{if(i=!0,this.eventEmitter.emit("function:invoke",n),this.recordAgentAction(n),n.invocationId&&this.requiresApproval(n)){this.pendingApprovals.set(n.invocationId,n),this.eventEmitter.emit("function:awaiting-approval",n);return}await this.handleClientFunctionInvocation(n)},onTitle:n=>{this.eventEmitter.emit("conversation:title",n)},onAnswerComplete:n=>{this.eventEmitter.emit("message:answer-complete",n)},onWaitingClient:n=>{this.pausedTurn={messageId:n.messageId,conversationId:n.conversationId},this.eventEmitter.emit("message:waiting-client",n),this.markResumeSignal(n.messageId,n.conversationId,"waitingConfirmed")},onComplete:n=>{r?.stopRequested&&!n.id||this.eventEmitter.emit("message:complete",n)},onError:n=>{this.eventEmitter.emit("message:error",{error:n.message,code:n instanceof y.AgoError?n.code:void 0})}},{signal:r?.controller.signal});try{const n=await s.processStream(t);return r?.stopRequested&&(this.postStopForTurn(r,r.messageId??n.id),this.eventEmitter.emit("message:stopped",{conversationId:r.conversationId??n.conversationId??"",messageId:r.messageId??n.id??""})),n.status!=="WAITING_CLIENT"&&this.maybeFlagEmptyReply(n,i),n}finally{r&&this.endTurn(r)}}async stop(){const t=this.activeTurn;if(t){t.stopRequested=!0;const s=t.messageId;return t.controller.abort(),s?this.postStopForTurn(t,s):null}const r=this.pausedTurn;if(!r)return null;this.pausedTurn=null,this.pendingResumes.delete(r.messageId),this.stoppedTurnIds.add(r.messageId);let i=null;try{i=await this.stopMessage(r.messageId)}catch(s){l.warn("Failed to stop the paused turn:",s)}return this.eventEmitter.emit("message:stopped",{conversationId:r.conversationId,messageId:r.messageId}),i}async stopMessage(t){const r=await this.httpClient.post(`/api/sdk/v1/messages/${t}/stop`);return{status:r.status,messageStatus:r.message_status}}isGenerating(){return this.activeTurn!==null||this.pausedTurn!==null}beginTurn(){this.pausedTurn=null;const t={controller:new AbortController,messageId:null,conversationId:null,stopRequested:!1,stopPosted:!1};return this.activeTurn=t,t}endTurn(t){this.activeTurn===t&&(this.activeTurn=null)}async postStopForTurn(t,r){if(!r||t.stopPosted)return null;t.stopPosted=!0;try{return await this.stopMessage(r)}catch(i){return l.warn("Failed to stop the turn server-side:",i),null}}buildStoppedMessage(t){const r={id:t.messageId??"",conversationId:t.conversationId??"",content:"",role:"assistant",status:"CANCELED",createdAt:new Date};return r.id&&this.eventEmitter.emit("message:complete",r),this.eventEmitter.emit("message:stopped",{conversationId:r.conversationId,messageId:r.id}),r}resolveClientFunctionsMode(t){return t?.clientFunctionsMode??this.config.clientFunctionsMode??"pause"}registerResumeGate(t){return this.resumeGate=t,()=>{this.resumeGate===t&&(this.resumeGate=null)}}async continueMessage(t){const r=this.functionRegistry.getSchemas(),i=this.buildSendContext(),s={};r.length>0&&(s.client_functions=r),i&&(s.client_context=i);const n=this.beginTurn();n.messageId=t;const a=await this.sendRequest(n,()=>this.httpClient.postStream(`/api/sdk/v1/messages/${t}/continue`,s,{signal:n.controller.signal}));return a?this.processSSEResponse(a,n):this.buildStoppedMessage(n)}markResumeSignal(t,r,i){if(!t)return;const s=this.pendingResumes.get(t)??{conversationId:r,waitingConfirmed:!1,resultsReady:!1,started:!1};s[i]=!0,r&&(s.conversationId=r),this.pendingResumes.set(t,s),!(!s.waitingConfirmed||!s.resultsReady||s.started)&&(s.started=!0,this.runAutoResume(t,s.conversationId))}async runAutoResume(t,r){try{this.resumeGate&&await this.resumeGate({conversationId:r,messageId:t})}catch(i){l.warn("Resume gate threw; resuming anyway:",i)}if(this.pendingResumes.delete(t),!this.stoppedTurnIds.delete(t))try{await this.continueMessage(t)}catch(i){l.warn("Auto-resume of paused turn failed:",i)}}maybeFlagEmptyReply(t,r){t.status==="DONE"&&(t.content??"").trim()===""&&!r&&!(t.toolCalls&&t.toolCalls.length>0)&&!(t.followUpReplies&&t.followUpReplies.length>0)&&setTimeout(()=>{if(this.eventEmitter.emit("message:empty",{conversationId:t.conversationId??"",messageId:t.id??""}),this.config.warnOnEmptyReply===!1)return;const i=t.conversationId||"(no conversation)";if(this.warnedEmptyConversations.has(i))return;this.warnedEmptyConversations.add(i);const s=this.config.agent||this.config.defaultAgentId;t.id?console.warn("[AGO] Reply completed with empty content. Possible causes: "+(s?`the agent "${s}" may not exist for this tenant, `:"an unknown `agent` slug, ")+"or the agent replied with no text. Listen for the `message:empty` event to handle this in your app; silence this warning with `warnOnEmptyReply: false`."):console.warn("[AGO] The stream completed without any message data. Possible causes: "+(s?`the agent "${s}" may not exist for this tenant, or `:"")+"`baseUrl` does not point at an AGO endpoint that returns server-sent events. Listen for the `message:empty` event to handle this in your app; silence this warning with `warnOnEmptyReply: false`.")},0)}async handleClientFunctionInvocation(t){let r,i;try{r=await this.functionRegistry.execute(t.functionName,t.arguments)}catch(s){i=s instanceof Error?s.message:"Unknown error",l.error("Client function execution failed:",s)}if(t.invocationId)try{const s=await this.submitToolCallForm(t.invocationId,{result:r,error:i,_type:"client_function_result"});s?.resume?.ready&&this.markResumeSignal(s.resume.message_id,t.conversationId,"resultsReady")}catch(s){l.error("Failed to submit function result:",s)}this.eventEmitter.emit("function:result",{invocationId:t.invocationId,result:r,error:i})}requiresApproval(t){const r=this.config.approvalPolicy;if(r)try{if(r(t))return!0}catch(i){l.warn("approvalPolicy threw; not gating this call:",i)}return this.functionRegistry.get(t.functionName)?.requiresApproval===!0}async approveFunction(t){const r=this.pendingApprovals.get(t);r&&(this.pendingApprovals.delete(t),await this.handleClientFunctionInvocation(r))}async rejectFunction(t){const r=this.pendingApprovals.get(t);if(!r)return;this.pendingApprovals.delete(t);const i={approved:!1,reason:"user_rejected"};try{const s=await this.submitToolCallForm(t,{result:i,_type:"client_function_result"});s?.resume?.ready&&this.markResumeSignal(s.resume.message_id,r.conversationId,"resultsReady")}catch(s){l.error("Failed to submit function rejection:",s)}this.eventEmitter.emit("function:result",{invocationId:t,result:i})}async runExternalFunction(t,r){const i={invocationId:`webmcp-${L()}`,functionName:t,arguments:r,conversationId:""},{invocationId:s}=i;this.eventEmitter.emit("function:invoke",i);try{const n=await this.functionRegistry.execute(t,r);return this.eventEmitter.emit("function:result",{invocationId:s,result:n}),n}catch(n){throw this.eventEmitter.emit("function:result",{invocationId:s,result:null,error:n instanceof Error?n.message:String(n)}),n}}async getConversations(t){const r=new URLSearchParams;t?.page!==void 0&&r.set("page",String(t.page)),t?.pageSize!==void 0&&r.set("page_size",String(t.pageSize));const i=r.toString(),s=await this.httpClient.get(`/api/sdk/v1/conversations${i?`?${i}`:""}`),n=(Array.isArray(s.data)?s.data:[]).map(a=>({id:String(a.id),title:a.title??"",lastMessageDate:new Date(a.last_message_at??a.created_at??0)}));return{data:n,hasMore:s.has_more??!1,total:s.total??n.length}}async getConversation(t){const r=await this.httpClient.get(`/api/sdk/v1/conversations/${t}`),i={id:r.id,title:r.title,lastMessageDate:new Date(r.last_message_at??r.created_at??0),messages:r.messages.map(s=>({id:s.id,conversationId:r.id,content:s.content,role:s.role,status:s.status,createdAt:new Date(s.created_at),hidden:s.hidden,sources:s.sources&&s.sources.length>0?s.sources.map(({id:n,title:a,url:o})=>({id:n,title:a,url:o??void 0})):void 0,toolCalls:A.mapPersistedToolCalls(s.tool_call_data),attachments:s.attachments&&s.attachments.length>0?s.attachments.map(Ft):void 0,followUpReplies:s.follow_up_replies&&s.follow_up_replies.length>0?s.follow_up_replies:void 0}))};return this.eventEmitter.emit("conversation:loaded",i),i}static mapPersistedToolCalls(t){if(!(!t||t.length===0))return t.map(r=>({id:String(r.id??""),type:r.type??"status_message",status:String(r.status??"unknown"),toolName:r.tool_name??"",toolDisplayName:r.tool_display_name,message:r.message,formSchema:r.form_schema,data:r.data,functionName:r.function_name,arguments:r.arguments,displayMode:r.display_mode,askToTalkToHuman:r.ask_to_talk_to_human,allowedToCreateTicket:r.allowed_to_create_ticket,ticket:r.ticket,mode:r.mode,ticketFormId:r.ticket_form_id,embedHtml:r.embed_html,embedDescription:r.embed_description}))}async transcribeAudio(t,r){const i=new FormData;return i.append("file",t,t.name),(await this.httpClient.postFormData("/api/sdk/v1/audio/transcriptions",i,r)).json()}async getConfig(){const t=await this.httpClient.get("/api/sdk/v1/config");return{permissions:(t.permissions??[]).map(r=>({id:r.id??void 0,name:r.name??void 0,displayName:r.display_name??void 0,agents:(r.agents??[]).map(i=>({id:i.id,name:i.name??void 0})),ticketForm:r.ticket_form?A.mapTicketForm(r.ticket_form):void 0,homePage:r.home_page?A.mapHomePage(r.home_page):void 0,fileAttachmentsEnabled:!!r.file_attachments_enabled,voiceEnabled:!!r.voice_enabled,speechToTextEnabled:!!r.speech_to_text_enabled})),proactive:{enabled:!!t.proactive?.enabled}}}static mapHomePage(t){const r=t.widget_starter;return{title:t.title??void 0,subtitle:t.subtitle??void 0,starters:(t.home_starters??[]).flatMap(i=>{const s=i.description||i.title||"",n=i.initial_message||s;return!s||!n?[]:[{id:i.id,label:s,message:n,agentId:i.agent_id??void 0}]}),widgetStarter:r&&r.initial_message?{id:r.id,message:r.initial_message,agentId:r.agent_id??void 0}:void 0}}static mapTicketForm(t){return{id:t.id,name:t.name??void 0,mode:t.mode==="embed"?"embed":"form",showSubject:t.show_subject??!0,showBody:t.show_body??!0,showPriority:t.show_priority??!0,showTypology:t.show_typology??!0,priorityTypologies:t.priority_typologies??void 0,successMessageText:t.success_message_text??void 0,successMessageUrlLabel:t.success_message_url_label??void 0,fields:(t.fields??[]).map(r=>({id:r.id,externalId:r.external_id??void 0,title:r.title??void 0,type:r.type??void 0,required:!!r.required,hidden:!!r.hidden,active:r.active,alwaysVisible:r.always_visible,regexpForValidation:r.regexp_for_validation??void 0,position:r.position??0,options:(r.options??[]).map(i=>({id:i.id,name:i.name??void 0,value:i.value??void 0,default:!!i.default,position:i.position??void 0,group:i.group??void 0,noDisplay:i.no_display,conditionalFieldId:i.conditional_field_id??void 0,conditionalFieldValues:i.conditional_field_values??void 0,message:i.message??void 0,messageType:i.message_type??"info"})),conditionalFieldId:r.conditional_field_id??void 0,conditionalFieldValue:r.conditional_field_value??void 0,conditionalFieldValues:r.conditional_field_values??void 0}))}}async createTicket(t){const r=new FormData;r.append("subject",t.subject),r.append("body",t.body),t.priority&&r.append("priority",t.priority),t.typology&&r.append("typology",t.typology),t.conversationId&&r.append("conversation_id",t.conversationId),t.email&&r.append("email",t.email),t.customFields&&t.customFields.length>0&&r.append("custom_fields",JSON.stringify(t.customFields));for(const s of t.files??[])r.append("files",s,s.name);t.ticketFormId&&r.append("ticket_form_id",t.ticketFormId);const i=await(await this.httpClient.postFormData("/api/sdk/v1/tickets",r)).json();return{id:String(i.id??""),url:typeof i.url=="string"&&i.url?i.url:void 0}}async getMessages(t){return(await this.getConversation(t)).messages||[]}async resumePendingClientFunctions(t){const r=[...t.messages??[]].reverse().find(o=>o.role==="assistant"&&o.status==="WAITING_CLIENT");if(!r)return null;const i=(r.toolCalls??[]).filter(o=>o.type==="client_function"&&o.status==="waiting_input"&&o.functionName),s=new Set(this.functionRegistry.getSchemas().map(o=>o.name)),n=i.filter(o=>!s.has(o.functionName));if(n.length>0)return l.warn("Cannot resume paused turn: function(s) not registered on this page:",n.map(o=>o.functionName)),null;let a=i.length===0;for(const o of i){const c={invocationId:o.id,functionName:o.functionName,arguments:o.arguments??{},conversationId:t.id};if(this.requiresApproval(c)){this.pendingApprovals.set(o.id,c),this.markResumeSignal(r.id,t.id,"waitingConfirmed"),this.eventEmitter.emit("function:awaiting-approval",c),a=!1;continue}this.eventEmitter.emit("function:invoke",c);let u,d;try{u=await this.functionRegistry.execute(o.functionName,o.arguments??{})}catch(g){d=g instanceof Error?g.message:"Unknown error",l.error("Client function execution failed:",g)}this.eventEmitter.emit("function:result",{invocationId:o.id,result:u,error:d}),a=(await this.submitToolCallForm(o.id,{result:u,error:d,_type:"client_function_result"}))?.resume?.ready??a}return a?this.continueMessage(r.id):null}async submitToolCallForm(t,r){return this.httpClient.post(`/api/sdk/v1/tool-calls/${t}/submit`,{formData:r})}async confirmToolCall(t){await this.httpClient.post(`/api/tool-calls/${t}/confirm/`)}async rejectToolCall(t){await this.httpClient.post(`/api/tool-calls/${t}/reject/`)}async getFormCollector(t){const r=await this.httpClient.get(`/api/sdk/v1/forms/${encodeURIComponent(t)}`);return{name:r.name,description:r.description,schema:r.schema,submit:r.submit??void 0}}async submitFormCollector(t,r){return this.httpClient.post("/api/sdk/v1/forms/submit",{name:t,values:r})}async submitFeedback(t,r,i){const s=i?.comment?.trim(),n=i?.reasons?.length?[...new Set(i.reasons)]:[];await this.httpClient.post(`/api/sdk/v1/messages/${t}/feedback`,{rating:r,...n.length?{reasons:n}:{},...s?{comment:s}:{}})}async submitConversationFeedback(t,r,i){let s=i?.lastMessageId;if(!s){const n=[...(await this.getConversation(t)).messages??[]].reverse().find(a=>a.role==="assistant"&&!a.hidden&&!!a.content&&a.status!=="IN_PROGRESS"&&a.status!=="WAITING_CLIENT");if(!n)throw new y.AgoError(`Conversation ${t} has no finished answer to report feedback on. Wait for the turn to complete, or pass \`lastMessageId\`.`,"feedback_no_message");s=n.id}return await this.submitFeedback(s,r,i),s}registerFunction(t,r,i){typeof t=="object"?this.functionRegistry.register(t):this.functionRegistry.register(t,r,i)}register(t){if(Array.isArray(t))for(const r of t)this.functionRegistry.register(r);else this.functionRegistry.register(t)}unregisterFunction(t){return this.functionRegistry.unregister(t)}getRegisteredFunctions(){return this.functionRegistry.getSchemas()}onFunctionsChanged(t){return this.functionRegistry.onChange(t)}getFunctionRegistrations(){return this.functionRegistry.getAll()}async executeClientFunction(t,r){return this.functionRegistry.execute(t,r)}registerNavigationFunction(t,r){const i=r.map(o=>o.name),s=r.map(o=>{const c=x(o.path),u=c.length>0?` (requires ${c.map(d=>`"${d}"`).join(", ")})`:"";return`- "${o.name}"${u}: ${o.description}`}).join(`
|
|
9
|
+
`),n=new Map;for(const o of r)for(const c of x(o.path))n.set(c,[...n.get(c)??[],o.name]);const a={page:{type:"string",description:"The page to navigate to",enum:i}};for(const[o,c]of n){if(o==="page"){l.error('registerNavigationFunction: a ":page" placeholder collides with the "page" argument and is ignored. Rename the placeholder.');continue}a[o]={type:"string",description:`Value for ":${o}" in the page path. Required when page is ${c.map(u=>`"${u}"`).join(" or ")}.`}}this.registerFunction("navigateToPage",async o=>{const c=o.page,u=r.find(f=>f.name===c);if(!u)return{success:!1,error:`Unknown page: ${c}`};let d={};if(typeof o.params=="string")try{d=JSON.parse(o.params)}catch{}else o.params&&typeof o.params=="object"&&(d=o.params);const g={};for(const f of x(u.path))g[f]=o[f]??d[f];const{path:m,missing:w}=Wt(u.path,g);if(w.length>0){const f=w.map(h=>`"${h}": "..."`).join(", ");return{success:!1,error:`Page "${c}" needs ${w.map(h=>`"${h}"`).join(", ")}. Retry with { "page": "${c}", ${f} }.`}}return t(m),{success:!0,navigatedTo:m}},{description:`Navigate the user to a page in the application. Available pages:
|
|
10
|
+
${s}`,parameters:{type:"object",properties:a,required:["page"]},webmcp:{navigates:!0}}),this.addDynamicContext("current-page",()=>{if(typeof window>"u"||!window.location)return null;const o=window.location.href,c=typeof document<"u"?document.title:void 0,u=Bt(window.location.pathname,r),d={url:o};return u&&(d.page=u.name),c&&(d.title=c),{name:"Current page",description:"The page the user is currently viewing.",data:d}})}unregisterNavigationFunction(){this.unregisterFunction("navigateToPage"),this.removeDynamicContext("current-page")}registerPageStateFunction(t,r){const i=r?.functionName??"setPageState",s=r?.data;this.registerFunction(Ze(t,{name:i,requiresApproval:r?.requiresApproval,getResultBudget:()=>s?this.pageDataBudget(s):this.functionRegistry.getDefaultMaxResultBytes(),data:s?{description:s.description,maxResultBytes:s.maxResultBytes,read:async a=>Y(i,await this.readPageData(i,s,r),this.pageDataBudget(s)-this.envelopeBytes(a))}:void 0}));const n=ae(i);s?(this.warnIfPlaceholderMode(i),this.registerFunction(n,async()=>({data:Y(i,await this.readPageData(i,s,r),this.pageDataBudget(s)-this.envelopeBytes({}))}),{description:`Read what the current page is displaying, without changing anything: ${s.description}`,parameters:{type:"object",properties:{}},maxResultBytes:s.maxResultBytes}),this.pageDataCompanions.add(n)):this.pageDataCompanions.delete(n)&&this.unregisterFunction(n),this.addDynamicContext(`page-state:${i}`,()=>{const a=t.filter(c=>typeof c.get=="function");if(a.length===0)return null;const o={};for(const c of a)o[c.name]=c.get();return{name:"Page state",description:"Current, editable state of the page the user is viewing.",data:o}})}unregisterPageStateFunction(t){const r=t??"setPageState";this.unregisterFunction(r);const i=ae(r);this.pageDataCompanions.delete(i)&&this.unregisterFunction(i),this.removeDynamicContext(`page-state:${r}`)}pageDataBudget(t){return t.maxResultBytes??this.functionRegistry.getDefaultMaxResultBytes()}envelopeBytes(t){return E(JSON.stringify({...t,data:null}))-4}readPageData(t,r,i){return Ke(()=>r,i?.settleTimeoutMs??1e4).catch(s=>(l.warn(`Reading page data for "${t}" failed:`,s),{error:"page_data_unavailable",message:s instanceof Error?s.message:String(s)}))}warnIfPlaceholderMode(t){this.warnedPageDataPlaceholder||this.config.clientFunctionsMode==="placeholder"&&(this.warnedPageDataPlaceholder=!0,l.warn(`"${t}" declares a data source, but clientFunctionsMode is "placeholder": the agent will not see that data during the turn it calls the function. Switch to "pause" (the default) for the data to come back as the result of its own call.`))}setContext(t,r){this.contextRegistry.set(t,r),this.notifyContextChanged()}removeContext(t){const r=this.contextRegistry.remove(t);return r&&this.notifyContextChanged(),r}addDynamicContext(t,r){this.contextRegistry.addDynamicProvider(t,r),this.notifyContextChanged()}removeDynamicContext(t){const r=this.contextRegistry.removeDynamicProvider(t);return r&&this.notifyContextChanged(),r}notifyContextChanged(){this.eventEmitter.emit("context:changed",this.contextRegistry.getSnapshot())}emitFormEvent(t,r){this.eventEmitter.emit(t,r)}emitProactiveEvent(t,r){this.eventEmitter.emit(t,r)}getHttp(){return this.httpClient}getConfiguredAgent(){return this.config.agent||this.config.defaultAgentId}getUserIdentity(){return{email:this.config.userEmail||void 0,hasJwt:!!this.config.userJwt}}enableAutoPageContext(){this.addDynamicContext("browser-page",()=>{const t=typeof window<"u"?window.location.href:void 0,r=typeof document<"u"?document.title:void 0;return!t&&!r?null:{name:"Browser page",description:"Current page the user is viewing",data:{url:t,title:r}}})}getContextSnapshot(){return this.contextRegistry.getSnapshot()}buildSendContext(){const t=this.contextRegistry.getSnapshot(),r=t?.entries??{},{changes:i,baseline:s}=kt(this.lastSentPageState,r);return this.lastSentPageState=s,i.length===0?t:{entries:{...r,[Gt]:{name:"State changes",description:"Fields in the page state that changed since your last message, as field: <old> -> <new>.",data:{changes:i}}}}}recordActivity(t){this.addActivity(t)}getRecentActivity(){return this.activityLedger.getRecent()}clearActivity(){this.activityLedger.clear()}addActivity(t){const r=this.activityLedger.add(t);this.eventEmitter.emit("activity:recorded",r)}recordAgentAction(t){const r=t.functionName,i=t.arguments;let s,n;if(r==="navigateToPage"){const a=i?.page;s="agent.navigate",n=a?`Agent navigated to "${String(a)}"`:"Agent navigated"}else r==="setPageState"?(s="agent.page_state",n="Agent changed the page state"):(s=`agent.${r}`,n=`Agent ran "${r}"`);this.addActivity({actor:"agent",name:s,summary:n,...i&&Object.keys(i).length>0?{data:{arguments:i}}:{}})}registerActivityContext(){this.contextRegistry.addDynamicProvider(qt,()=>{const t=this.activityLedger.getRecent();return t.length===0?null:{name:"Recent activity",description:"Recent actions by the user and the agent in the app, oldest first. Use this to understand what just happened before this message.",data:{events:t}}})}enableErrorWatcher(t){this.disableErrorWatcher();const r=new de(t);this.errorWatcher=r,r.start(),r.subscribe(i=>{this.eventEmitter.emit("error:captured",i),this.notifyContextChanged()}),this.contextRegistry.addDynamicProvider(oe,()=>{const i=r.getErrors();if(i.length===0)return null;const s=Date.now();return{name:"Recent JavaScript errors",description:"JavaScript errors captured on the page in the last minutes, oldest first, with how long ago each last fired (ageMs) and how many times (count). Use them to diagnose when the user reports something broken or unresponsive; do not bring them up otherwise.",data:{errors:i.map(({firstAt:n,lastAt:a,...o})=>({...o,ageMs:Math.max(0,s-a),...n!==a?{firstSeenAgoMs:Math.max(0,s-n)}:{}}))}}})}disableErrorWatcher(){this.errorWatcher&&(this.errorWatcher.destroy(),this.errorWatcher=null,this.contextRegistry.removeDynamicProvider(oe))}reportError(t,r){if(!this.errorWatcher){l.warn("reportError() ignored: enable the error watcher first (errorWatcher: true).");return}this.errorWatcher.report(t,r)}getRecentErrors(){return this.errorWatcher?.getErrors()??[]}clearErrors(){this.errorWatcher?.clear()}on(t,r){this.eventEmitter.on(t,r)}off(t,r){this.eventEmitter.off(t,r)}once(t,r){this.eventEmitter.once(t,r)}waitFor(t,r){return this.eventEmitter.waitFor(t,r)}updateConfig(t){const r={};for(const[s,n]of Object.entries(t))n!==void 0&&(r[s]=n);const i={...this.config,...r};B(i,"AgoClient.updateConfig"),this.config=i,this.httpClient.updateConfig(r),r.debug!==void 0&&(r.debug?l.enable():l.disable()),r.maxFunctionResultBytes!==void 0&&this.functionRegistry.setDefaultMaxResultBytes(r.maxFunctionResultBytes),r.errorWatcher!==void 0&&(r.errorWatcher?this.enableErrorWatcher(r.errorWatcher===!0?void 0:r.errorWatcher):this.disableErrorWatcher())}destroy(){this.proactive?.destroy(),this.proactive=null,this.errorWatcher?.destroy(),this.errorWatcher=null,this.detachWebMCP?.(),this.detachWebMCP=null,this.activeTurn?.controller.abort(),this.activeTurn=null,this.pausedTurn=null,this.stoppedTurnIds.clear(),this.eventEmitter.removeAllListeners(),this.functionRegistry.clear(),this.contextRegistry.clear(),this.pendingResumes.clear(),this.pendingApprovals.clear(),this.resumeGate=null,l.log("AgoClient destroyed")}reviveAfterDestroy(){this.registerActivityContext(),this.config.errorWatcher&&!this.errorWatcher&&this.enableErrorWatcher(this.config.errorWatcher===!0?void 0:this.config.errorWatcher),this.config.proactive&&!this.proactive&&U(this,this.config.proactive),this.attachWebMCPBridge()}},Jt=["inaccurate","incomplete","information_not_found","technical_issue"];Object.defineProperty(exports,"ActivityLedger",{enumerable:!0,get:function(){return le}});Object.defineProperty(exports,"AgoClient",{enumerable:!0,get:function(){return Kt}});Object.defineProperty(exports,"ClientContextRegistry",{enumerable:!0,get:function(){return Ee}});Object.defineProperty(exports,"DEFAULT_MAX_ACTIVITY_ENTRIES",{enumerable:!0,get:function(){return Re}});Object.defineProperty(exports,"DEFAULT_MAX_ERRORS",{enumerable:!0,get:function(){return Pe}});Object.defineProperty(exports,"DEFAULT_MAX_ERROR_AGE_MS",{enumerable:!0,get:function(){return Me}});Object.defineProperty(exports,"ErrorWatcher",{enumerable:!0,get:function(){return de}});Object.defineProperty(exports,"EventEmitter",{enumerable:!0,get:function(){return Ce}});Object.defineProperty(exports,"FEEDBACK_REASONS",{enumerable:!0,get:function(){return Jt}});Object.defineProperty(exports,"FunctionRegistry",{enumerable:!0,get:function(){return he}});Object.defineProperty(exports,"SSEHandler",{enumerable:!0,get:function(){return Se}});Object.defineProperty(exports,"SignalCollector",{enumerable:!0,get:function(){return ye}});Object.defineProperty(exports,"attachmentsFromFiles",{enumerable:!0,get:function(){return Pt}});Object.defineProperty(exports,"canInlineImage",{enumerable:!0,get:function(){return It}});Object.defineProperty(exports,"createAgoProactive",{enumerable:!0,get:function(){return U}});Object.defineProperty(exports,"createStore",{enumerable:!0,get:function(){return ve}});Object.defineProperty(exports,"formatFileSize",{enumerable:!0,get:function(){return xt}});Object.defineProperty(exports,"isStreamNetworkError",{enumerable:!0,get:function(){return Rt}});Object.defineProperty(exports,"logger",{enumerable:!0,get:function(){return l}});Object.defineProperty(exports,"matchesRoutePattern",{enumerable:!0,get:function(){return we}});Object.defineProperty(exports,"matchesWhen",{enumerable:!0,get:function(){return be}});Object.defineProperty(exports,"partialDeepMatch",{enumerable:!0,get:function(){return K}});Object.defineProperty(exports,"safeAttachmentUrl",{enumerable:!0,get:function(){return _e}});Object.defineProperty(exports,"validateConfig",{enumerable:!0,get:function(){return B}});
|
package/dist/vue.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const y=require("./types-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const y=require("./types-a7teDBnC.cjs");let o=require("vue");var S=Symbol("ago-client"),I={install(t,e){const n=new y.AgoClient(e);t.provide(S,n)}};function g(t){if(t)return new y.AgoClient(t);const e=(0,o.inject)(S);if(!e)throw new Error("useAgo(): no AgoClient found. Either pass config or install AgoPlugin.");return e}function b(t={}){const e=t.client??g(),n=(0,o.ref)([]),a=(0,o.ref)(t.conversationId),r=(0,o.ref)(!1),l=(0,o.ref)(null),v=s=>{a.value||(a.value=s.conversationId)},m=s=>{const i=n.value.findIndex(d=>d.id===s.messageId);i>=0&&(n.value[i]={...n.value[i],content:n.value[i].content+s.content})},p=s=>{const i=n.value.findIndex(d=>d.id===s.id);i>=0?n.value[i]=s:n.value.push(s),r.value=!1},C=s=>{l.value=new Error(s.error),r.value=!1},u=()=>{let s=-1;for(let i=n.value.length-1;i>=0;i--){const d=n.value[i];if(d.role==="assistant"&&(d.status==="IN_PROGRESS"||d.status==="WAITING_CLIENT")){s=i;break}}s>=0&&(n.value[s].content?n.value[s]={...n.value[s],status:"CANCELED"}:n.value.splice(s,1)),r.value=!1};(0,o.onMounted)(()=>{e.on("message:start",v),e.on("message:chunk",m),e.on("message:complete",p),e.on("message:error",C),e.on("message:stopped",u)}),(0,o.onUnmounted)(()=>{e.off("message:start",v),e.off("message:chunk",m),e.off("message:complete",p),e.off("message:error",C),e.off("message:stopped",u)});async function c(s,i){r.value=!0,l.value=null;const d={id:`temp-${Date.now()}`,conversationId:a.value||"",content:s,role:"user",status:"DONE",createdAt:new Date},F={id:`temp-assistant-${Date.now()}`,conversationId:a.value||"",content:"",role:"assistant",status:"IN_PROGRESS",createdAt:new Date};n.value.push(d,F);try{const f=await e.sendMessage(s,{conversationId:a.value,files:i});f.conversationId&&!a.value&&(a.value=f.conversationId),n.value=n.value.filter(A=>!A.id.startsWith("temp-"));const E={...d,id:d.id.replace("temp-","user-"),conversationId:f.conversationId};return n.value.some(A=>A.id===f.id)?n.value.push(E):n.value.push(E,f),f}catch(f){return l.value=f instanceof Error?f:new Error("Failed to send"),r.value=!1,n.value=n.value.filter(E=>!E.id.startsWith("temp-")),null}}async function h(){await e.stop()}function w(){n.value=[],a.value=void 0,l.value=null}return{messages:n,isLoading:r,error:l,conversationId:a,sendMessage:c,stop:h,clearMessages:w}}function N(t={}){const e=t.client??g(),n=t.autoLoad??!0,a=(0,o.ref)([]),r=(0,o.ref)(null),l=(0,o.ref)(!1),v=(0,o.ref)(null);async function m(){l.value=!0,v.value=null;try{a.value=(await e.getConversations()).data}catch(u){v.value=u instanceof Error?u:new Error("Failed to load conversations")}finally{l.value=!1}}async function p(u){l.value=!0,v.value=null;try{r.value=await e.getConversation(u)}catch(c){v.value=c instanceof Error?c:new Error("Failed to load conversation")}finally{l.value=!1}}function C(){r.value=null}return(0,o.onMounted)(()=>{n&&m()}),{conversations:a,currentConversation:r,isLoading:l,error:v,selectConversation:p,startNewConversation:C,refreshConversations:m}}function M(t={}){const e=b({client:t.client,conversationId:t.conversationId}),n=N({client:t.client,autoLoad:t.autoLoad}),a=(0,o.computed)(()=>e.error.value||n.error.value);return{messages:e.messages,isLoading:e.isLoading,error:a,sendMessage:e.sendMessage,stop:e.stop,clearMessages:e.clearMessages,conversationId:e.conversationId,conversations:n.conversations,currentConversation:n.currentConversation,isConversationsLoading:n.isLoading,selectConversation:n.selectConversation,startNewConversation:n.startNewConversation,refreshConversations:n.refreshConversations}}function L(t={}){const e=t.client??g(),n=(0,o.ref)({}),a=(0,o.ref)(!1),r=(0,o.ref)(null),l=new Map;function v(u){const c=(l.get(u)??0)+1;return l.set(u,c),c}const m=(u,c)=>l.get(u)===c;async function p(u,c,h){const w=v(u);a.value=!0,r.value=null;try{await e.submitFeedback(u,c,h),m(u,w)&&(n.value={...n.value,[u]:c})}catch(s){const i=s instanceof Error?s:new Error("Failed to submit feedback");throw r.value=i,i}finally{a.value=!1}}async function C(u,c,h){const w=v(u);a.value=!0,r.value=null;try{const s=await e.submitConversationFeedback(u,c,h);return m(u,w)&&(n.value={...n.value,[s]:c}),s}catch(s){const i=s instanceof Error?s:new Error("Failed to submit feedback");throw r.value=i,i}finally{a.value=!1}}return{ratings:n,isSubmitting:a,error:r,submitFeedback:p,submitConversationFeedback:C}}function R(t,e){const n=g();(0,o.onMounted)(()=>{n.registerFunction(t,e.handler,{description:e.description,parameters:e.parameters,maxResultBytes:e.maxResultBytes,requiresApproval:e.requiresApproval,webmcp:e.webmcp})}),(0,o.onUnmounted)(()=>{n.unregisterFunction(t)})}function P(t,e){const n=g();(0,o.onMounted)(()=>{n.registerNavigationFunction(t,e)}),(0,o.onUnmounted)(()=>{n.unregisterNavigationFunction()})}function k(t,e){const n=g(),a=e?.functionName??"setPageState";(0,o.onMounted)(()=>{n.registerPageStateFunction(t,{...e,functionName:a})}),(0,o.onUnmounted)(()=>{n.unregisterPageStateFunction(a)})}function q(t,e){const n=g();(0,o.onMounted)(()=>{n.on(t,e)}),(0,o.onUnmounted)(()=>{n.off(t,e)})}function _(t){const e=(0,o.shallowRef)(t.get());return(0,o.onScopeDispose)(t.subscribe(n=>{e.value=n})),e}function D(){const t=g(),e=(0,o.shallowRef)(null),n=r=>{e.value=r,t.proactive?.shown(r)},a=({nudge:r})=>{e.value?.id===r.id&&(e.value=null)};return(0,o.onMounted)(()=>{t.on("nudge:ready",n),t.on("nudge:accepted",a),t.on("nudge:dismissed",a)}),(0,o.onUnmounted)(()=>{t.off("nudge:ready",n),t.off("nudge:accepted",a),t.off("nudge:dismissed",a)}),{nudge:e,accept:async()=>{const r=e.value;r&&(e.value=null,await t.proactive?.accept(r))},dismiss:()=>{const r=e.value;r&&(e.value=null,t.proactive?.dismiss(r))}}}exports.AGO_CLIENT_KEY=S;exports.AgoPlugin=I;exports.FEEDBACK_REASONS=y.FEEDBACK_REASONS;exports.useAgo=g;exports.useAgoEvents=q;exports.useAgoFunction=R;exports.useAgoNavigation=P;exports.useAgoPageState=k;exports.useAgoStore=_;exports.useChat=M;exports.useConversation=N;exports.useFeedback=L;exports.useMessages=b;exports.useProactiveNudge=D;
|
package/dist/vue.d.cts
CHANGED
|
@@ -100,7 +100,10 @@ declare class AgoClient {
|
|
|
100
100
|
* `null` otherwise.
|
|
101
101
|
*/
|
|
102
102
|
proactive: ProactiveController | null;
|
|
103
|
+
/** Removes the mirrored WebMCP tools; `null` when the bridge is off. */
|
|
104
|
+
private detachWebMCP;
|
|
103
105
|
constructor(config: AgoConfig);
|
|
106
|
+
private attachWebMCPBridge;
|
|
104
107
|
/**
|
|
105
108
|
* Send a message and receive a streaming response
|
|
106
109
|
*/
|
|
@@ -212,6 +215,7 @@ declare class AgoClient {
|
|
|
212
215
|
* (the agent decides what to do next). No-op if the invocation is unknown.
|
|
213
216
|
*/
|
|
214
217
|
rejectFunction(invocationId: string): Promise<void>;
|
|
218
|
+
/* Excluded from this release type: runExternalFunction */
|
|
215
219
|
/**
|
|
216
220
|
* Get a page of conversations, newest-first. `pageSize` is capped at 100 by
|
|
217
221
|
* the backend (default 50). Returns the `{ data, has_more, total }` envelope
|
|
@@ -231,11 +235,20 @@ declare class AgoClient {
|
|
|
231
235
|
* `SSEHandler.parseToolCall` so persisted and streamed tool calls match.
|
|
232
236
|
*/
|
|
233
237
|
private static mapPersistedToolCalls;
|
|
238
|
+
/**
|
|
239
|
+
* Transcribe an audio file into editable text (`POST /api/sdk/v1/audio/transcriptions`).
|
|
240
|
+
* Requires speech to text to be enabled for the tenant. Supports FLAC, MP3,
|
|
241
|
+
* MP4, MPEG, MPGA, M4A, OGG, WAV and WebM files up to 25 MB.
|
|
242
|
+
* The filename must include the matching extension. For a MediaRecorder blob,
|
|
243
|
+
* wrap it in a File with the recording's extension and MIME type.
|
|
244
|
+
* Show the returned text as a draft; call `sendMessage` when the user sends it.
|
|
245
|
+
*/
|
|
246
|
+
transcribeAudio(file: File, options?: TranscribeAudioOptions): Promise<AudioTranscription>;
|
|
234
247
|
/**
|
|
235
248
|
* The tenant's SDK configuration (`GET /api/sdk/v1/config`): per-permission
|
|
236
249
|
* agents, the ticket form the agent's `ago_ticketing` tool opens, and the
|
|
237
|
-
* file-attachment
|
|
238
|
-
* form first appears in a conversation.
|
|
250
|
+
* file-attachment and speech-to-text flags. The vanilla widget fetches it
|
|
251
|
+
* once, when a ticket form first appears in a conversation.
|
|
239
252
|
*/
|
|
240
253
|
getConfig(): Promise<SdkConfig>;
|
|
241
254
|
/**
|
|
@@ -372,6 +385,9 @@ declare class AgoClient {
|
|
|
372
385
|
* Get all registered function schemas
|
|
373
386
|
*/
|
|
374
387
|
getRegisteredFunctions(): ClientFunctionSchema[];
|
|
388
|
+
/** The callback form of `functions:changed`. Returns an unsubscribe. */
|
|
389
|
+
onFunctionsChanged(listener: () => void): () => void;
|
|
390
|
+
/* Excluded from this release type: getFunctionRegistrations */
|
|
375
391
|
/**
|
|
376
392
|
* Execute a registered client function locally, through the same
|
|
377
393
|
* FunctionRegistry path (result-size guard, error wrapping) as agent-invoked
|
|
@@ -704,6 +720,8 @@ declare interface AgoClientEvents {
|
|
|
704
720
|
* call running immediately.
|
|
705
721
|
*/
|
|
706
722
|
"function:awaiting-approval": ClientFunctionInvocation;
|
|
723
|
+
/** A function was registered or unregistered, or the registry cleared. */
|
|
724
|
+
"functions:changed": ClientFunctionSchema[];
|
|
707
725
|
"function:result": {
|
|
708
726
|
invocationId: string;
|
|
709
727
|
result: unknown;
|
|
@@ -776,6 +794,8 @@ export declare interface AgoConfig {
|
|
|
776
794
|
defaultAgentId?: string;
|
|
777
795
|
/** Permission name to apply to all requests (sent as `X-Widget-Permission`). Mirrors the widget's `window.AGO.permission`. */
|
|
778
796
|
permission?: string;
|
|
797
|
+
/** Interface locale selected by the host app, sent as Accept-Language. Null clears the override. */
|
|
798
|
+
language?: string | null;
|
|
779
799
|
/** User email for identification */
|
|
780
800
|
userEmail?: string;
|
|
781
801
|
/** JWT token for authenticated users */
|
|
@@ -853,6 +873,15 @@ export declare interface AgoConfig {
|
|
|
853
873
|
* mode's `jsErrors` signal. See `client.reportError()` for caught errors.
|
|
854
874
|
*/
|
|
855
875
|
errorWatcher?: boolean | ErrorWatcherOptions;
|
|
876
|
+
/** Mirror every registered client function into the browser's WebMCP registry
|
|
877
|
+
* (`document.modelContext`), so an external agent can call the same functions
|
|
878
|
+
* the in-app agent calls. Off by default; no-ops without WebMCP.
|
|
879
|
+
*
|
|
880
|
+
* A mirrored function runs immediately: the approval gate
|
|
881
|
+
* ({@link approvalPolicy}, `requiresApproval`) covers the agent loop only.
|
|
882
|
+
* Use `webmcp: false` on a definition to keep it out.
|
|
883
|
+
*/
|
|
884
|
+
webmcp?: boolean;
|
|
856
885
|
}
|
|
857
886
|
|
|
858
887
|
declare type AgoEventHandler<K extends AgoEventName> = (data: AgoClientEvents[K]) => void;
|
|
@@ -1058,6 +1087,11 @@ declare type AgoStateSetResult = {
|
|
|
1058
1087
|
result: "unchanged";
|
|
1059
1088
|
};
|
|
1060
1089
|
|
|
1090
|
+
/** Editable text returned by `AgoClient.transcribeAudio`. */
|
|
1091
|
+
declare interface AudioTranscription {
|
|
1092
|
+
text: string;
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1061
1095
|
/** One JavaScript error captured on the page (deduplicated, see `count`). */
|
|
1062
1096
|
declare interface CapturedError {
|
|
1063
1097
|
type: CapturedErrorType;
|
|
@@ -1097,22 +1131,11 @@ declare type CapturedErrorType = "error" | "unhandledrejection" | "console" | "m
|
|
|
1097
1131
|
* client.registerFunction(fn);
|
|
1098
1132
|
* ```
|
|
1099
1133
|
*/
|
|
1100
|
-
declare interface ClientFunctionDefinition {
|
|
1134
|
+
declare interface ClientFunctionDefinition extends ClientFunctionSettings {
|
|
1101
1135
|
name: string;
|
|
1102
1136
|
description: string;
|
|
1103
1137
|
parameters: ClientFunctionSchema["parameters"];
|
|
1104
1138
|
handler: ClientFunctionHandler;
|
|
1105
|
-
/**
|
|
1106
|
-
* Max serialized result size in bytes before the SDK truncates it to a
|
|
1107
|
-
* flagged preview (default: `AgoConfig.maxFunctionResultBytes`, 50 000).
|
|
1108
|
-
* `Infinity` disables the guard for this function.
|
|
1109
|
-
*/
|
|
1110
|
-
maxResultBytes?: number;
|
|
1111
|
-
/**
|
|
1112
|
-
* Require explicit user approval before this function runs. See
|
|
1113
|
-
* {@link AgoConfig.approvalPolicy} — pause mode only. ORs with the policy.
|
|
1114
|
-
*/
|
|
1115
|
-
requiresApproval?: boolean;
|
|
1116
1139
|
}
|
|
1117
1140
|
|
|
1118
1141
|
/**
|
|
@@ -1131,20 +1154,7 @@ declare interface ClientFunctionInvocation {
|
|
|
1131
1154
|
* Schema-plus-settings object accepted when registering a function: the schema
|
|
1132
1155
|
* (minus `name`) and SDK-side options that are NOT sent to the backend.
|
|
1133
1156
|
*/
|
|
1134
|
-
declare type ClientFunctionRegisterOptions = Omit<ClientFunctionSchema, "name"> &
|
|
1135
|
-
/**
|
|
1136
|
-
* Max serialized result size in bytes before the SDK truncates it to a
|
|
1137
|
-
* flagged preview. Overrides the client-level default
|
|
1138
|
-
* (`AgoConfig.maxFunctionResultBytes`, 50 000 by default). `Infinity`
|
|
1139
|
-
* disables the guard for this function.
|
|
1140
|
-
*/
|
|
1141
|
-
maxResultBytes?: number;
|
|
1142
|
-
/**
|
|
1143
|
-
* Require explicit user approval before this function runs. See
|
|
1144
|
-
* {@link AgoConfig.approvalPolicy} — pause mode only. ORs with the policy.
|
|
1145
|
-
*/
|
|
1146
|
-
requiresApproval?: boolean;
|
|
1147
|
-
};
|
|
1157
|
+
declare type ClientFunctionRegisterOptions = Omit<ClientFunctionSchema, "name"> & ClientFunctionSettings;
|
|
1148
1158
|
|
|
1149
1159
|
/**
|
|
1150
1160
|
* Schema for a client-side function that AGO can call
|
|
@@ -1171,6 +1181,28 @@ declare interface ClientFunctionSchema {
|
|
|
1171
1181
|
};
|
|
1172
1182
|
}
|
|
1173
1183
|
|
|
1184
|
+
/** SDK-side function settings that are never sent to the backend. */
|
|
1185
|
+
declare interface ClientFunctionSettings {
|
|
1186
|
+
/**
|
|
1187
|
+
* Max serialized result size in bytes before the SDK truncates it to a
|
|
1188
|
+
* flagged preview. Overrides the client-level default
|
|
1189
|
+
* (`AgoConfig.maxFunctionResultBytes`, 50 000 by default). `Infinity`
|
|
1190
|
+
* disables the guard for this function.
|
|
1191
|
+
*/
|
|
1192
|
+
maxResultBytes?: number;
|
|
1193
|
+
/**
|
|
1194
|
+
* Require explicit user approval before this function runs. See
|
|
1195
|
+
* {@link AgoConfig.approvalPolicy} — pause mode only. ORs with the policy.
|
|
1196
|
+
*/
|
|
1197
|
+
requiresApproval?: boolean;
|
|
1198
|
+
/**
|
|
1199
|
+
* WebMCP metadata, read only when the bridge is on (`AgoConfig.webmcp`).
|
|
1200
|
+
* `false` keeps this function out of WebMCP while leaving it available to the
|
|
1201
|
+
* in-app agent.
|
|
1202
|
+
*/
|
|
1203
|
+
webmcp?: WebMCPToolMeta | false;
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1174
1206
|
/** See {@link AgoConfig.clientFunctionsMode}. */
|
|
1175
1207
|
declare type ClientFunctionsMode = "placeholder" | "pause";
|
|
1176
1208
|
|
|
@@ -1656,6 +1688,14 @@ declare interface ProactiveTriggerWhen {
|
|
|
1656
1688
|
fieldErrors?: Record<string, number>;
|
|
1657
1689
|
}
|
|
1658
1690
|
|
|
1691
|
+
/**
|
|
1692
|
+
* Registered function with handler
|
|
1693
|
+
*/
|
|
1694
|
+
declare interface RegisteredFunction extends ClientFunctionSettings {
|
|
1695
|
+
schema: ClientFunctionSchema;
|
|
1696
|
+
handler: ClientFunctionHandler;
|
|
1697
|
+
}
|
|
1698
|
+
|
|
1659
1699
|
/**
|
|
1660
1700
|
* Hook run before a paused turn is resumed, so the app controls WHEN the
|
|
1661
1701
|
* continuation fires (e.g. wait for the destination page to mount after a
|
|
@@ -1712,6 +1752,8 @@ declare interface SdkPermissionConfig {
|
|
|
1712
1752
|
homePage?: SdkHomePageConfig;
|
|
1713
1753
|
fileAttachmentsEnabled: boolean;
|
|
1714
1754
|
voiceEnabled: boolean;
|
|
1755
|
+
/** Whether audio uploads can be transcribed. Defaults to false on older backends. */
|
|
1756
|
+
speechToTextEnabled: boolean;
|
|
1715
1757
|
}
|
|
1716
1758
|
|
|
1717
1759
|
/**
|
|
@@ -2047,6 +2089,12 @@ declare type ToolCallType = "form" | "confirmation_input" | "status_message" | "
|
|
|
2047
2089
|
|
|
2048
2090
|
declare type ToolCallType_2 = "form" | "confirmation_input" | "status_message" | "progress_indicator" | "client_function" | "reasoning" | "mcp_ui_resource";
|
|
2049
2091
|
|
|
2092
|
+
/** Options for `AgoClient.transcribeAudio`. */
|
|
2093
|
+
declare interface TranscribeAudioOptions {
|
|
2094
|
+
/** Cancel the upload or stop waiting for its transcription. */
|
|
2095
|
+
signal?: AbortSignal;
|
|
2096
|
+
}
|
|
2097
|
+
|
|
2050
2098
|
/**
|
|
2051
2099
|
* Get or create an AgoClient.
|
|
2052
2100
|
*
|
|
@@ -2095,6 +2143,16 @@ export declare function useAgoFunction(name: string, options: {
|
|
|
2095
2143
|
* `Infinity` disables the guard for this function.
|
|
2096
2144
|
*/
|
|
2097
2145
|
maxResultBytes?: number;
|
|
2146
|
+
/**
|
|
2147
|
+
* Require explicit user approval before this function runs (pause mode
|
|
2148
|
+
* only). See `AgoConfig.approvalPolicy`.
|
|
2149
|
+
*/
|
|
2150
|
+
requiresApproval?: boolean;
|
|
2151
|
+
/**
|
|
2152
|
+
* WebMCP metadata, read only when the bridge is on (`AgoConfig.webmcp`).
|
|
2153
|
+
* `false` keeps this function out of WebMCP.
|
|
2154
|
+
*/
|
|
2155
|
+
webmcp?: WebMCPToolMeta | false;
|
|
2098
2156
|
}): void;
|
|
2099
2157
|
|
|
2100
2158
|
/**
|
|
@@ -3029,4 +3087,23 @@ export declare interface UseProactiveNudgeResult {
|
|
|
3029
3087
|
dismiss: () => void;
|
|
3030
3088
|
}
|
|
3031
3089
|
|
|
3090
|
+
/** The MCP behavior hints AGO has no equivalent for. */
|
|
3091
|
+
declare interface WebMCPToolMeta {
|
|
3092
|
+
/**
|
|
3093
|
+
* Both default to `false`, so only set what is true: `readOnlyHint` marks a
|
|
3094
|
+
* function that changes nothing, `untrustedContentHint` one whose result may
|
|
3095
|
+
* carry third-party text.
|
|
3096
|
+
*/
|
|
3097
|
+
annotations?: {
|
|
3098
|
+
readOnlyHint?: boolean;
|
|
3099
|
+
untrustedContentHint?: boolean;
|
|
3100
|
+
};
|
|
3101
|
+
/**
|
|
3102
|
+
* This function navigates. The WebMCP call is held open until the function
|
|
3103
|
+
* registry goes quiet, so the caller sees the destination page's tools rather
|
|
3104
|
+
* than the departing page's. Already set on the built-in `navigateToPage`.
|
|
3105
|
+
*/
|
|
3106
|
+
navigates?: boolean;
|
|
3107
|
+
}
|
|
3108
|
+
|
|
3032
3109
|
export { }
|