@useago/sdk 1.0.10 → 1.1.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.
@@ -7,6 +7,27 @@ export declare interface AgoAgent {
7
7
  displayName?: string;
8
8
  }
9
9
 
10
+ /**
11
+ * An uploaded file attached to a message.
12
+ *
13
+ * `url` is a presigned, time-limited URL the backend generates per request (or a
14
+ * local `blob:` URL for an optimistic preview). `isSafeImage` is the backend's
15
+ * verdict that the file is a real, script-free image safe to embed inline; the
16
+ * UI only renders an `<img>` when it is true and otherwise shows a download link.
17
+ */
18
+ declare interface AgoAttachment {
19
+ id: string;
20
+ name: string;
21
+ /** MIME type reported by the backend (e.g. `image/png`). */
22
+ contentType?: string;
23
+ /** Size in bytes. */
24
+ fileSize?: number;
25
+ /** Presigned download/preview URL, or a local `blob:` URL before upload. */
26
+ url?: string;
27
+ /** True only when the backend verified the file is a safe inline image. */
28
+ isSafeImage: boolean;
29
+ }
30
+
10
31
  /**
11
32
  * Main SDK client for AGO Chat integration
12
33
  */
@@ -363,6 +384,8 @@ export declare interface AgoMessage {
363
384
  sources?: AgoSource[];
364
385
  toolCalls?: ToolCallData[];
365
386
  followUpReplies?: string[];
387
+ /** Uploaded files on this message (usually the user's). */
388
+ attachments?: AgoAttachment[];
366
389
  createdAt: Date;
367
390
  }
368
391
 
package/dist/angular.d.ts CHANGED
@@ -7,6 +7,27 @@ export declare interface AgoAgent {
7
7
  displayName?: string;
8
8
  }
9
9
 
10
+ /**
11
+ * An uploaded file attached to a message.
12
+ *
13
+ * `url` is a presigned, time-limited URL the backend generates per request (or a
14
+ * local `blob:` URL for an optimistic preview). `isSafeImage` is the backend's
15
+ * verdict that the file is a real, script-free image safe to embed inline; the
16
+ * UI only renders an `<img>` when it is true and otherwise shows a download link.
17
+ */
18
+ declare interface AgoAttachment {
19
+ id: string;
20
+ name: string;
21
+ /** MIME type reported by the backend (e.g. `image/png`). */
22
+ contentType?: string;
23
+ /** Size in bytes. */
24
+ fileSize?: number;
25
+ /** Presigned download/preview URL, or a local `blob:` URL before upload. */
26
+ url?: string;
27
+ /** True only when the backend verified the file is a safe inline image. */
28
+ isSafeImage: boolean;
29
+ }
30
+
10
31
  /**
11
32
  * Main SDK client for AGO Chat integration
12
33
  */
@@ -363,6 +384,8 @@ export declare interface AgoMessage {
363
384
  sources?: AgoSource[];
364
385
  toolCalls?: ToolCallData[];
365
386
  followUpReplies?: string[];
387
+ /** Uploaded files on this message (usually the user's). */
388
+ attachments?: AgoAttachment[];
366
389
  createdAt: Date;
367
390
  }
368
391
 
package/dist/angular.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as o } from "./AgoClient-QcTtrN7u.js";
1
+ import { t as o } from "./AgoClient-Cwx_eYSu.js";
2
2
  var n = class {
3
3
  constructor(t) {
4
4
  this.client = new o(t), this.messages$ = this.fromEvent("message:complete"), this.chunks$ = this.fromEvent("message:chunk"), this.errors$ = this.fromEvent("message:error"), this.messageStart$ = this.fromEvent("message:start");
@@ -1,4 +1,4 @@
1
- import { i as d } from "./createFormCollector-CFt1_QSL.js";
1
+ import { i as d } from "./createFormCollector-CyWisAkI.js";
2
2
  var f = "ago_widget_id", g = "ago_last_thread", y = 7200 * 1e3;
3
3
  function v() {
4
4
  return typeof crypto < "u" && typeof crypto.randomUUID == "function" ? crypto.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (e) => {
@@ -1 +1 @@
1
- const d=require("./createFormCollector-BI3DXaew.cjs");var f="ago_widget_id",g="ago_last_thread",y=7200*1e3;function v(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const r=Math.floor(Math.random()*16);return(e==="x"?r:r&3|8).toString(16)})}function _(e={}){const r=e.key??f,i=e.threadKey??g,u=e.ttlMs??y,l=e.storage??(typeof localStorage<"u"?localStorage:void 0);let n=e.widgetId??"";if(!n&&l)try{n=l.getItem(r)??""}catch{}if(n||(n=v()),l)try{l.setItem(r,n)}catch{}const o=d.createStore({value:null,lastMessageAt:null},{key:i,storage:l}),c=o.get();c.value!==null&&s(c.lastMessageAt)&&o.set({value:null,lastMessageAt:null});function s(t){return t===null?!0:Number.isFinite(u)?Date.now()-t>u:!1}return{widgetId:n,key:r,getLastActiveThread(){const{value:t,lastMessageAt:a}=o.get();return t===null||s(a)?null:t},setActiveThread(t,a){const x=a==null?null:a instanceof Date?a.getTime():a;o.set({value:t,lastMessageAt:x})},clear(){o.set({value:null,lastMessageAt:null})}}}Object.defineProperty(exports,"createConversationSession",{enumerable:!0,get:function(){return _}});
1
+ const d=require("./createFormCollector-BB3Uscuo.cjs");var f="ago_widget_id",g="ago_last_thread",y=7200*1e3;function v(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const r=Math.floor(Math.random()*16);return(e==="x"?r:r&3|8).toString(16)})}function _(e={}){const r=e.key??f,i=e.threadKey??g,u=e.ttlMs??y,l=e.storage??(typeof localStorage<"u"?localStorage:void 0);let n=e.widgetId??"";if(!n&&l)try{n=l.getItem(r)??""}catch{}if(n||(n=v()),l)try{l.setItem(r,n)}catch{}const o=d.createStore({value:null,lastMessageAt:null},{key:i,storage:l}),c=o.get();c.value!==null&&s(c.lastMessageAt)&&o.set({value:null,lastMessageAt:null});function s(t){return t===null?!0:Number.isFinite(u)?Date.now()-t>u:!1}return{widgetId:n,key:r,getLastActiveThread(){const{value:t,lastMessageAt:a}=o.get();return t===null||s(a)?null:t},setActiveThread(t,a){const x=a==null?null:a instanceof Date?a.getTime():a;o.set({value:t,lastMessageAt:x})},clear(){o.set({value:null,lastMessageAt:null})}}}Object.defineProperty(exports,"createConversationSession",{enumerable:!0,get:function(){return _}});
@@ -1 +1 @@
1
- const C=require("./AgoClient-B3-WGVne.cjs");function W(n,e){const a=e?e.storage??(typeof localStorage<"u"?localStorage:void 0):void 0;let s=n;if(e&&a)try{const m=a.getItem(e.key);m!=null&&(s=JSON.parse(m))}catch{}const i=new Set,c=()=>i.forEach(m=>m(s));function b(){if(e&&a)try{a.setItem(e.key,JSON.stringify(s))}catch{}}return{get:()=>s,set:m=>{s=m,b(),c()},subscribe:m=>(i.add(m),()=>{i.delete(m)})}}var T=/^[a-zA-Z0-9_-]{1,40}$/,x=n=>n==null||n==="";function v(n,e){if("anyOf"in n)return n.anyOf.some(c=>v(c,e));if("allOf"in n)return n.allOf.every(c=>v(c,e));const a=e[n.property];if(x(a))return!1;if(Array.isArray(n.value))return n.value.some(c=>String(a)===String(c));if(!n.op)return String(a)===String(n.value);const s=Number(a),i=Number(n.value);if(Number.isNaN(s)||Number.isNaN(i))return!1;switch(n.op){case">=":return s>=i;case"<=":return s<=i;case">":return s>i;case"<":return s<i;default:return C.logger.warn(`Unknown requiredWhen op "${n.op}"; treating as not required.`),!1}}function h(n,e){const a=n.properties??{},s=new Set;for(const c of n.required??[]){const b=a[c]?.requiredWhen;(!b||v(b,e))&&s.add(c)}for(const[c,b]of Object.entries(a))b.requiredWhen&&v(b.requiredWhen,e)&&s.add(c);const i=[...s].filter(c=>x(e[c]));return{missing:i,complete:i.length===0}}function R(n){const e={};for(const[a,s]of Object.entries(n.properties??{}))e[a]={type:s.type,...s.description!=null&&{description:s.description},...s.enum&&{enum:s.enum},...s.default!==void 0&&{default:s.default}};return{type:"object",properties:e,required:[]}}function A(n){const{name:e,description:a,schema:s}=n;if(!T.test(e))throw new Error(`Invalid form collector name "${e}": must match ${T} (it becomes the update_/submit_ function names).`);const i=typeof n.submit=="string"?n.submit?{via:"client",url:n.submit}:!1:n.submit??!1;n.autoSubmit===!0&&!i&&C.logger.warn(`FormCollector "${e}": autoSubmit is ignored because no submit target is configured.`);const c=(n.autoSubmit??!0)&&!!i,b=s.properties??{},m=t=>{const r={};for(const[u,o]of Object.entries(t)){const l=b[u];if(l)if(o==null)r[u]=o;else if(l.type==="number"||l.type==="integer"){const d=typeof o=="number"?o:Number(o);r[u]=Number.isNaN(d)?o:d}else l.type==="boolean"?r[u]=typeof o=="boolean"?o:o==="true"?!0:o==="false"?!1:!!o:r[u]=o}return r},S=n.initialValues??{},f=W({values:S,submitted:!1}),$=t=>{const r=f.get(),u={...r,values:{...r.values,...t}};return f.set(u),u};let g=null;const F=(t,r)=>{g?.emitFormEvent("form:error",{name:e,values:t,error:r})};let y=null;const I=async()=>{const{values:t}=f.get(),{complete:r,missing:u}=h(s,t);if(!r)return{ok:!1,missing:u};if(!i)return{ok:!1,error:"No submit target configured for this form collector."};const o=t;try{let l;if(i.via==="client")if("handler"in i)l=await i.handler(o);else{const d=await fetch(i.url,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify(o)});if(!d.ok){const j=`Submit failed: HTTP ${d.status}`;return F(o,j),{ok:!1,error:j}}l=await d.json().catch(()=>{})}else{if(!g)return{ok:!1,error:"Backend submit requires install(client) (or useFormCollector) first."};l=await g.submitFormCollector(e,o)}return f.set({...f.get(),submitted:!0,submitResult:l}),g?.emitFormEvent("form:submitted",{name:e,values:o,result:l}),{ok:!0,result:l}}catch(l){const d=l instanceof Error?l.message:"Submit failed";return C.logger.error(`FormCollector "${e}" submit failed:`,l),F(o,d),{ok:!1,error:d}}},N=()=>y||(y=(async()=>{try{return await I()}finally{y=null}})(),y),k=async()=>{if(!c||!i)return null;const{values:t,submitted:r}=f.get();return r||!h(s,t).complete?null:N()},O={name:`update_${e}`,description:`Fill or update fields of the "${e}" form. ${a} Pass any subset of fields; call it repeatedly to fill the form as the user provides information. Returns the current values and which required fields are still missing.`,parameters:R(s),handler:async t=>{const r=$(m(t)),{missing:u}=h(s,r.values),o=await k();return o?o.ok?{ok:!0,values:r.values,missing:u,submitted:!0}:{ok:!0,values:r.values,missing:u,submitted:!1,submitError:o.error}:{ok:!0,values:r.values,missing:u}}},p=[O];i&&!c&&p.push({name:`submit_${e}`,description:`Submit the completed "${e}" form. Only call this once every required field is collected and the user has confirmed. If fields are missing it returns them instead of submitting.`,parameters:{type:"object",properties:{}},handler:()=>N()});const V="client__",q=i?`submit_${e}`:null,J=t=>{const r=t.functionName??t.toolName;if(r)return r.startsWith(V)?r.slice(8):r},_=t=>{let r={...S},u=!1;for(const o of t){const l=J(o);l===O.name?o.arguments&&(r={...r,...m(o.arguments)}):q&&l===q&&o.status?.toLowerCase()==="done"&&(u=!0)}f.set({values:r,submitted:u})},w=`form:${e}`,E=()=>{const{values:t,submitted:r}=f.get(),{missing:u,complete:o}=h(s,t),l=i?c?" The form is submitted automatically as soon as every required field is filled, so there is no submit function to call.":` When nothing is missing and the user confirms, call submit_${e}.`:"",d=r?`The "${e}" form has been submitted.`:`You are currently collecting information from the user to fill the "${e}" form.`;return{name:`Form: ${e}`,description:`${d} ${a} Some fields are conditionally required; the requiredWhen field in the schema tells you when each becomes required. The form schema is the following: ${JSON.stringify(s)}. Data collected so far: ${JSON.stringify(t)}. Call update_${e} with any fields the user provides; ask only for what is still missing.${l}`,data:{values:t,missing:u,complete:o,submitted:r}}},P=t=>{_((t.messages??[]).flatMap(r=>r.toolCalls??[]))};return{name:e,store:f,functions:p,contextKey:w,contextProvider:E,install:t=>{g=t;for(const u of p)t.register(u);t.addDynamicContext(w,E);const r=f.subscribe(()=>t.notifyContextChanged());return t.on("conversation:loaded",P),()=>{r();for(const u of p)t.unregisterFunction(u.name);t.removeDynamicContext(w),t.off("conversation:loaded",P),g===t&&(g=null)}},hydrate:_,submit:N,getValues:()=>f.get().values,setValues:t=>{$(m(t)),k()},reset:()=>{f.set({values:S,submitted:!1})},getStatus:()=>h(s,f.get().values)}}async function B(n,e){const a=await n.getFormCollector(e.name);return A({name:a.name,description:e.description??a.description,schema:e.schema??a.schema,submit:e.submit??a.submit,initialValues:e.initialValues,autoSubmit:e.autoSubmit??a.autoSubmit})}Object.defineProperty(exports,"createFormCollector",{enumerable:!0,get:function(){return A}});Object.defineProperty(exports,"createStore",{enumerable:!0,get:function(){return W}});Object.defineProperty(exports,"deriveFormStatus",{enumerable:!0,get:function(){return h}});Object.defineProperty(exports,"loadFormCollector",{enumerable:!0,get:function(){return B}});
1
+ const C=require("./AgoClient-CzSmJQxl.cjs");function W(n,e){const a=e?e.storage??(typeof localStorage<"u"?localStorage:void 0):void 0;let s=n;if(e&&a)try{const m=a.getItem(e.key);m!=null&&(s=JSON.parse(m))}catch{}const i=new Set,c=()=>i.forEach(m=>m(s));function b(){if(e&&a)try{a.setItem(e.key,JSON.stringify(s))}catch{}}return{get:()=>s,set:m=>{s=m,b(),c()},subscribe:m=>(i.add(m),()=>{i.delete(m)})}}var T=/^[a-zA-Z0-9_-]{1,40}$/,x=n=>n==null||n==="";function v(n,e){if("anyOf"in n)return n.anyOf.some(c=>v(c,e));if("allOf"in n)return n.allOf.every(c=>v(c,e));const a=e[n.property];if(x(a))return!1;if(Array.isArray(n.value))return n.value.some(c=>String(a)===String(c));if(!n.op)return String(a)===String(n.value);const s=Number(a),i=Number(n.value);if(Number.isNaN(s)||Number.isNaN(i))return!1;switch(n.op){case">=":return s>=i;case"<=":return s<=i;case">":return s>i;case"<":return s<i;default:return C.logger.warn(`Unknown requiredWhen op "${n.op}"; treating as not required.`),!1}}function h(n,e){const a=n.properties??{},s=new Set;for(const c of n.required??[]){const b=a[c]?.requiredWhen;(!b||v(b,e))&&s.add(c)}for(const[c,b]of Object.entries(a))b.requiredWhen&&v(b.requiredWhen,e)&&s.add(c);const i=[...s].filter(c=>x(e[c]));return{missing:i,complete:i.length===0}}function R(n){const e={};for(const[a,s]of Object.entries(n.properties??{}))e[a]={type:s.type,...s.description!=null&&{description:s.description},...s.enum&&{enum:s.enum},...s.default!==void 0&&{default:s.default}};return{type:"object",properties:e,required:[]}}function A(n){const{name:e,description:a,schema:s}=n;if(!T.test(e))throw new Error(`Invalid form collector name "${e}": must match ${T} (it becomes the update_/submit_ function names).`);const i=typeof n.submit=="string"?n.submit?{via:"client",url:n.submit}:!1:n.submit??!1;n.autoSubmit===!0&&!i&&C.logger.warn(`FormCollector "${e}": autoSubmit is ignored because no submit target is configured.`);const c=(n.autoSubmit??!0)&&!!i,b=s.properties??{},m=t=>{const r={};for(const[u,o]of Object.entries(t)){const l=b[u];if(l)if(o==null)r[u]=o;else if(l.type==="number"||l.type==="integer"){const d=typeof o=="number"?o:Number(o);r[u]=Number.isNaN(d)?o:d}else l.type==="boolean"?r[u]=typeof o=="boolean"?o:o==="true"?!0:o==="false"?!1:!!o:r[u]=o}return r},S=n.initialValues??{},f=W({values:S,submitted:!1}),$=t=>{const r=f.get(),u={...r,values:{...r.values,...t}};return f.set(u),u};let g=null;const F=(t,r)=>{g?.emitFormEvent("form:error",{name:e,values:t,error:r})};let y=null;const I=async()=>{const{values:t}=f.get(),{complete:r,missing:u}=h(s,t);if(!r)return{ok:!1,missing:u};if(!i)return{ok:!1,error:"No submit target configured for this form collector."};const o=t;try{let l;if(i.via==="client")if("handler"in i)l=await i.handler(o);else{const d=await fetch(i.url,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify(o)});if(!d.ok){const j=`Submit failed: HTTP ${d.status}`;return F(o,j),{ok:!1,error:j}}l=await d.json().catch(()=>{})}else{if(!g)return{ok:!1,error:"Backend submit requires install(client) (or useFormCollector) first."};l=await g.submitFormCollector(e,o)}return f.set({...f.get(),submitted:!0,submitResult:l}),g?.emitFormEvent("form:submitted",{name:e,values:o,result:l}),{ok:!0,result:l}}catch(l){const d=l instanceof Error?l.message:"Submit failed";return C.logger.error(`FormCollector "${e}" submit failed:`,l),F(o,d),{ok:!1,error:d}}},N=()=>y||(y=(async()=>{try{return await I()}finally{y=null}})(),y),k=async()=>{if(!c||!i)return null;const{values:t,submitted:r}=f.get();return r||!h(s,t).complete?null:N()},O={name:`update_${e}`,description:`Fill or update fields of the "${e}" form. ${a} Pass any subset of fields; call it repeatedly to fill the form as the user provides information. Returns the current values and which required fields are still missing.`,parameters:R(s),handler:async t=>{const r=$(m(t)),{missing:u}=h(s,r.values),o=await k();return o?o.ok?{ok:!0,values:r.values,missing:u,submitted:!0}:{ok:!0,values:r.values,missing:u,submitted:!1,submitError:o.error}:{ok:!0,values:r.values,missing:u}}},p=[O];i&&!c&&p.push({name:`submit_${e}`,description:`Submit the completed "${e}" form. Only call this once every required field is collected and the user has confirmed. If fields are missing it returns them instead of submitting.`,parameters:{type:"object",properties:{}},handler:()=>N()});const V="client__",q=i?`submit_${e}`:null,J=t=>{const r=t.functionName??t.toolName;if(r)return r.startsWith(V)?r.slice(8):r},_=t=>{let r={...S},u=!1;for(const o of t){const l=J(o);l===O.name?o.arguments&&(r={...r,...m(o.arguments)}):q&&l===q&&o.status?.toLowerCase()==="done"&&(u=!0)}f.set({values:r,submitted:u})},w=`form:${e}`,E=()=>{const{values:t,submitted:r}=f.get(),{missing:u,complete:o}=h(s,t),l=i?c?" The form is submitted automatically as soon as every required field is filled, so there is no submit function to call.":` When nothing is missing and the user confirms, call submit_${e}.`:"",d=r?`The "${e}" form has been submitted.`:`You are currently collecting information from the user to fill the "${e}" form.`;return{name:`Form: ${e}`,description:`${d} ${a} Some fields are conditionally required; the requiredWhen field in the schema tells you when each becomes required. The form schema is the following: ${JSON.stringify(s)}. Data collected so far: ${JSON.stringify(t)}. Call update_${e} with any fields the user provides; ask only for what is still missing.${l}`,data:{values:t,missing:u,complete:o,submitted:r}}},P=t=>{_((t.messages??[]).flatMap(r=>r.toolCalls??[]))};return{name:e,store:f,functions:p,contextKey:w,contextProvider:E,install:t=>{g=t;for(const u of p)t.register(u);t.addDynamicContext(w,E);const r=f.subscribe(()=>t.notifyContextChanged());return t.on("conversation:loaded",P),()=>{r();for(const u of p)t.unregisterFunction(u.name);t.removeDynamicContext(w),t.off("conversation:loaded",P),g===t&&(g=null)}},hydrate:_,submit:N,getValues:()=>f.get().values,setValues:t=>{$(m(t)),k()},reset:()=>{f.set({values:S,submitted:!1})},getStatus:()=>h(s,f.get().values)}}async function B(n,e){const a=await n.getFormCollector(e.name);return A({name:a.name,description:e.description??a.description,schema:e.schema??a.schema,submit:e.submit??a.submit,initialValues:e.initialValues,autoSubmit:e.autoSubmit??a.autoSubmit})}Object.defineProperty(exports,"createFormCollector",{enumerable:!0,get:function(){return A}});Object.defineProperty(exports,"createStore",{enumerable:!0,get:function(){return W}});Object.defineProperty(exports,"deriveFormStatus",{enumerable:!0,get:function(){return h}});Object.defineProperty(exports,"loadFormCollector",{enumerable:!0,get:function(){return B}});
@@ -1,4 +1,4 @@
1
- import { c as $ } from "./AgoClient-QcTtrN7u.js";
1
+ import { f as $ } from "./AgoClient-Cwx_eYSu.js";
2
2
  function A(s, e) {
3
3
  const a = e ? e.storage ?? (typeof localStorage < "u" ? localStorage : void 0) : void 0;
4
4
  let n = s;
@@ -7,6 +7,27 @@ declare interface AgoAgent {
7
7
  displayName?: string;
8
8
  }
9
9
 
10
+ /**
11
+ * An uploaded file attached to a message.
12
+ *
13
+ * `url` is a presigned, time-limited URL the backend generates per request (or a
14
+ * local `blob:` URL for an optimistic preview). `isSafeImage` is the backend's
15
+ * verdict that the file is a real, script-free image safe to embed inline; the
16
+ * UI only renders an `<img>` when it is true and otherwise shows a download link.
17
+ */
18
+ declare interface AgoAttachment {
19
+ id: string;
20
+ name: string;
21
+ /** MIME type reported by the backend (e.g. `image/png`). */
22
+ contentType?: string;
23
+ /** Size in bytes. */
24
+ fileSize?: number;
25
+ /** Presigned download/preview URL, or a local `blob:` URL before upload. */
26
+ url?: string;
27
+ /** True only when the backend verified the file is a safe inline image. */
28
+ isSafeImage: boolean;
29
+ }
30
+
10
31
  /**
11
32
  * Main SDK client for AGO Chat integration
12
33
  */
@@ -363,6 +384,8 @@ declare interface AgoMessage {
363
384
  sources?: AgoSource[];
364
385
  toolCalls?: ToolCallData[];
365
386
  followUpReplies?: string[];
387
+ /** Uploaded files on this message (usually the user's). */
388
+ attachments?: AgoAttachment[];
366
389
  createdAt: Date;
367
390
  }
368
391
 
@@ -7,6 +7,27 @@ declare interface AgoAgent {
7
7
  displayName?: string;
8
8
  }
9
9
 
10
+ /**
11
+ * An uploaded file attached to a message.
12
+ *
13
+ * `url` is a presigned, time-limited URL the backend generates per request (or a
14
+ * local `blob:` URL for an optimistic preview). `isSafeImage` is the backend's
15
+ * verdict that the file is a real, script-free image safe to embed inline; the
16
+ * UI only renders an `<img>` when it is true and otherwise shows a download link.
17
+ */
18
+ declare interface AgoAttachment {
19
+ id: string;
20
+ name: string;
21
+ /** MIME type reported by the backend (e.g. `image/png`). */
22
+ contentType?: string;
23
+ /** Size in bytes. */
24
+ fileSize?: number;
25
+ /** Presigned download/preview URL, or a local `blob:` URL before upload. */
26
+ url?: string;
27
+ /** True only when the backend verified the file is a safe inline image. */
28
+ isSafeImage: boolean;
29
+ }
30
+
10
31
  /**
11
32
  * Main SDK client for AGO Chat integration
12
33
  */
@@ -363,6 +384,8 @@ declare interface AgoMessage {
363
384
  sources?: AgoSource[];
364
385
  toolCalls?: ToolCallData[];
365
386
  followUpReplies?: string[];
387
+ /** Uploaded files on this message (usually the user's). */
388
+ attachments?: AgoAttachment[];
366
389
  createdAt: Date;
367
390
  }
368
391
 
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("./AgoClient-B3-WGVne.cjs"),f=require("./createFormCollector-BI3DXaew.cjs"),p=require("./createConversationSession-C0diFTUk.cjs"),w=require("./createMockClient-zHQ0cjUH.cjs");require("./testing.cjs");const g=require("./functions-Djnq-JAo.cjs");function h(e){return e}function E(e,o){return e.on("message:complete",o),()=>e.off("message:complete",o)}function S(e,o){return e.on("message:chunk",o),()=>e.off("message:chunk",o)}function y(e,o){return e.on("message:start",o),()=>e.off("message:start",o)}function b(e,o){return e.on("message:error",o),()=>e.off("message:error",o)}function F(e,o){return e.on("toolCall:received",o),()=>e.off("toolCall:received",o)}function v(e,o){return e.on("form:submitted",o),()=>e.off("form:submitted",o)}function M(e,o){return e.on("form:error",o),()=>e.off("form:error",o)}function q(e,o){return e.on("function:invoke",o),()=>e.off("function:invoke",o)}async function*k(e,o,l){const a=[];let r=null,s=!1;const m=i=>{a.push(i),r?.()},c=i=>m({type:"start",data:i}),t=i=>m({type:"chunk",data:i}),u=i=>{m({type:"complete",data:i}),s=!0,r?.()},d=i=>{m({type:"error",data:i}),s=!0,r?.()},C=i=>m({type:"toolCall",data:i});e.on("message:start",c),e.on("message:chunk",t),e.on("message:complete",u),e.on("message:error",d),e.on("toolCall:received",C),e.sendMessage(o,l).catch(()=>{s=!0,r?.()});try{for(;!s||a.length>0;)a.length>0?yield a.shift():(await new Promise(i=>{r=i}),r=null)}finally{e.off("message:start",c),e.off("message:chunk",t),e.off("message:complete",u),e.off("message:error",d),e.off("toolCall:received",C)}}function A(e){let o,l,a,r,s,m;if(typeof window<"u"&&window.AGO){const t=window.AGO;o=t.basepath,l=t.widgetId,a=t.agent||t.defaultAgent,r=t.permission,s=t.email,m=t.jwt}if(typeof document<"u"){const t=u=>document.querySelector(`meta[name="${u}"]`)?.getAttribute("content")||void 0;o=o||t("ago-base-url"),l=l||t("ago-widget-id"),a=a||t("ago-agent")||t("ago-agent-id"),r=r||t("ago-permission"),s=s||t("ago-user-email")}if(typeof document<"u"){const t=[document.body,...Array.from(document.querySelectorAll("script[data-ago-base-url]"))].filter(Boolean);for(const u of t)u&&(o=o||u.getAttribute("data-ago-base-url")||void 0,l=l||u.getAttribute("data-ago-widget-id")||void 0,a=a||u.getAttribute("data-ago-agent")||u.getAttribute("data-ago-agent-id")||void 0,r=r||u.getAttribute("data-ago-permission")||void 0,s=s||u.getAttribute("data-ago-user-email")||void 0)}o=e?.baseUrl||o,l=e?.widgetId||l,a=e?.agent||e?.defaultAgentId||a,r=e?.permission||r,s=e?.userEmail||s,m=e?.userJwt||m;const c=e?.debug;return o?{baseUrl:o,widgetId:l,agent:a,permission:r,userEmail:s,userJwt:m,debug:c}:null}function T(e){const o=A(e);if(!o)throw new n.AgoError('createAgo(): could not detect AGO configuration. Set window.AGO, add <meta name="ago-base-url">, or pass { baseUrl } explicitly.',"config_missing_base_url");return new n.AgoClient(o)}function _(e,o){return{...e,handler:o}}exports.AgoApiError=n.AgoApiError;exports.AgoClient=n.AgoClient;exports.AgoError=n.AgoError;exports.AgoFunctionError=n.AgoFunctionError;exports.AgoNetworkError=n.AgoNetworkError;exports.AgoStreamError=n.AgoStreamError;exports.ClientContextRegistry=n.ClientContextRegistry;exports.EventEmitter=n.EventEmitter;exports.FunctionRegistry=n.FunctionRegistry;exports.SSEHandler=n.SSEHandler;exports.autoDetectConfig=A;exports.copyToClipboard=g.copyToClipboard;exports.createAgo=T;exports.createConversationSession=p.createConversationSession;exports.createFormCollector=f.createFormCollector;exports.createMessageStream=k;exports.createMockClient=w.createMockClient;exports.createStore=f.createStore;exports.defineFunction=h;exports.deriveFormStatus=f.deriveFormStatus;exports.getLocalStorage=g.getLocalStorage;exports.getUserLocation=g.getUserLocation;exports.highlightElement=g.highlightElement;exports.isStreamNetworkError=n.isStreamNetworkError;exports.loadFormCollector=f.loadFormCollector;exports.logger=n.logger;exports.onFormError=M;exports.onFormSubmitted=v;exports.onFunctionInvoke=q;exports.onMessage=E;exports.onMessageChunk=S;exports.onMessageError=b;exports.onMessageStart=y;exports.onToolCall=F;exports.openUrl=g.openUrl;exports.scrollToElement=g.scrollToElement;exports.setLocalStorage=g.setLocalStorage;exports.setTheme=g.setTheme;exports.showConfirmDialog=g.showConfirmDialog;exports.showNotification=g.showNotification;exports.showToast=g.showToast;exports.submitForm=g.submitForm;exports.trackEvent=g.trackEvent;exports.validateConfig=n.validateConfig;exports.withHandler=_;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./AgoClient-CzSmJQxl.cjs"),f=require("./createFormCollector-BB3Uscuo.cjs"),h=require("./createConversationSession-DV0Xp_3O.cjs"),p=require("./createMockClient-zHQ0cjUH.cjs");require("./testing.cjs");const g=require("./functions-Djnq-JAo.cjs");function w(e){return e}function S(e,o){return e.on("message:complete",o),()=>e.off("message:complete",o)}function E(e,o){return e.on("message:chunk",o),()=>e.off("message:chunk",o)}function y(e,o){return e.on("message:start",o),()=>e.off("message:start",o)}function F(e,o){return e.on("message:error",o),()=>e.off("message:error",o)}function b(e,o){return e.on("toolCall:received",o),()=>e.off("toolCall:received",o)}function v(e,o){return e.on("form:submitted",o),()=>e.off("form:submitted",o)}function M(e,o){return e.on("form:error",o),()=>e.off("form:error",o)}function q(e,o){return e.on("function:invoke",o),()=>e.off("function:invoke",o)}async function*k(e,o,l){const a=[];let n=null,i=!1;const m=s=>{a.push(s),n?.()},c=s=>m({type:"start",data:s}),t=s=>m({type:"chunk",data:s}),u=s=>{m({type:"complete",data:s}),i=!0,n?.()},d=s=>{m({type:"error",data:s}),i=!0,n?.()},C=s=>m({type:"toolCall",data:s});e.on("message:start",c),e.on("message:chunk",t),e.on("message:complete",u),e.on("message:error",d),e.on("toolCall:received",C),e.sendMessage(o,l).catch(()=>{i=!0,n?.()});try{for(;!i||a.length>0;)a.length>0?yield a.shift():(await new Promise(s=>{n=s}),n=null)}finally{e.off("message:start",c),e.off("message:chunk",t),e.off("message:complete",u),e.off("message:error",d),e.off("toolCall:received",C)}}function A(e){let o,l,a,n,i,m;if(typeof window<"u"&&window.AGO){const t=window.AGO;o=t.basepath,l=t.widgetId,a=t.agent||t.defaultAgent,n=t.permission,i=t.email,m=t.jwt}if(typeof document<"u"){const t=u=>document.querySelector(`meta[name="${u}"]`)?.getAttribute("content")||void 0;o=o||t("ago-base-url"),l=l||t("ago-widget-id"),a=a||t("ago-agent")||t("ago-agent-id"),n=n||t("ago-permission"),i=i||t("ago-user-email")}if(typeof document<"u"){const t=[document.body,...Array.from(document.querySelectorAll("script[data-ago-base-url]"))].filter(Boolean);for(const u of t)u&&(o=o||u.getAttribute("data-ago-base-url")||void 0,l=l||u.getAttribute("data-ago-widget-id")||void 0,a=a||u.getAttribute("data-ago-agent")||u.getAttribute("data-ago-agent-id")||void 0,n=n||u.getAttribute("data-ago-permission")||void 0,i=i||u.getAttribute("data-ago-user-email")||void 0)}o=e?.baseUrl||o,l=e?.widgetId||l,a=e?.agent||e?.defaultAgentId||a,n=e?.permission||n,i=e?.userEmail||i,m=e?.userJwt||m;const c=e?.debug;return o?{baseUrl:o,widgetId:l,agent:a,permission:n,userEmail:i,userJwt:m,debug:c}:null}function T(e){const o=A(e);if(!o)throw new r.AgoError('createAgo(): could not detect AGO configuration. Set window.AGO, add <meta name="ago-base-url">, or pass { baseUrl } explicitly.',"config_missing_base_url");return new r.AgoClient(o)}function I(e,o){return{...e,handler:o}}exports.AgoApiError=r.AgoApiError;exports.AgoClient=r.AgoClient;exports.AgoError=r.AgoError;exports.AgoFunctionError=r.AgoFunctionError;exports.AgoNetworkError=r.AgoNetworkError;exports.AgoStreamError=r.AgoStreamError;exports.ClientContextRegistry=r.ClientContextRegistry;exports.EventEmitter=r.EventEmitter;exports.FunctionRegistry=r.FunctionRegistry;exports.SSEHandler=r.SSEHandler;exports.autoDetectConfig=A;exports.canInlineImage=r.canInlineImage;exports.copyToClipboard=g.copyToClipboard;exports.createAgo=T;exports.createConversationSession=h.createConversationSession;exports.createFormCollector=f.createFormCollector;exports.createMessageStream=k;exports.createMockClient=p.createMockClient;exports.createStore=f.createStore;exports.defineFunction=w;exports.deriveFormStatus=f.deriveFormStatus;exports.formatFileSize=r.formatFileSize;exports.getLocalStorage=g.getLocalStorage;exports.getUserLocation=g.getUserLocation;exports.highlightElement=g.highlightElement;exports.isStreamNetworkError=r.isStreamNetworkError;exports.loadFormCollector=f.loadFormCollector;exports.logger=r.logger;exports.onFormError=M;exports.onFormSubmitted=v;exports.onFunctionInvoke=q;exports.onMessage=S;exports.onMessageChunk=E;exports.onMessageError=F;exports.onMessageStart=y;exports.onToolCall=b;exports.openUrl=g.openUrl;exports.safeAttachmentUrl=r.safeAttachmentUrl;exports.scrollToElement=g.scrollToElement;exports.setLocalStorage=g.setLocalStorage;exports.setTheme=g.setTheme;exports.showConfirmDialog=g.showConfirmDialog;exports.showNotification=g.showNotification;exports.showToast=g.showToast;exports.submitForm=g.submitForm;exports.trackEvent=g.trackEvent;exports.validateConfig=r.validateConfig;exports.withHandler=I;
package/dist/index.d.cts CHANGED
@@ -18,6 +18,27 @@ export declare class AgoApiError extends AgoError {
18
18
  static fromResponse(data: ApiErrorResponse, statusCode: number): AgoApiError;
19
19
  }
20
20
 
21
+ /**
22
+ * An uploaded file attached to a message.
23
+ *
24
+ * `url` is a presigned, time-limited URL the backend generates per request (or a
25
+ * local `blob:` URL for an optimistic preview). `isSafeImage` is the backend's
26
+ * verdict that the file is a real, script-free image safe to embed inline; the
27
+ * UI only renders an `<img>` when it is true and otherwise shows a download link.
28
+ */
29
+ export declare interface AgoAttachment {
30
+ id: string;
31
+ name: string;
32
+ /** MIME type reported by the backend (e.g. `image/png`). */
33
+ contentType?: string;
34
+ /** Size in bytes. */
35
+ fileSize?: number;
36
+ /** Presigned download/preview URL, or a local `blob:` URL before upload. */
37
+ url?: string;
38
+ /** True only when the backend verified the file is a safe inline image. */
39
+ isSafeImage: boolean;
40
+ }
41
+
21
42
  /**
22
43
  * Main SDK client for AGO Chat integration
23
44
  */
@@ -398,6 +419,8 @@ export declare interface AgoMessage {
398
419
  sources?: AgoSource[];
399
420
  toolCalls?: ToolCallData[];
400
421
  followUpReplies?: string[];
422
+ /** Uploaded files on this message (usually the user's). */
423
+ attachments?: AgoAttachment[];
401
424
  createdAt: Date;
402
425
  }
403
426
 
@@ -493,6 +516,14 @@ declare interface ApiErrorResponse {
493
516
  */
494
517
  export declare function autoDetectConfig(overrides?: Partial<AgoConfig>): AgoConfig | null;
495
518
 
519
+ /**
520
+ * Whether an attachment may be embedded inline as an `<img>`. Secure by default:
521
+ * requires the backend's `isSafeImage` verdict, an `image/*` content type, and a
522
+ * safe URL. PDFs, documents, SVGs, and unverified/spoofed types all return false
523
+ * and are shown as download links instead.
524
+ */
525
+ export declare function canInlineImage(attachment: AgoAttachment): boolean;
526
+
496
527
  /**
497
528
  * Registry that collects client-side context from across the component tree.
498
529
  *
@@ -888,6 +919,9 @@ export declare class EventEmitter<Events extends Record<string, any> = Record<st
888
919
 
889
920
  declare type EventHandler<T = unknown> = (data: T) => void;
890
921
 
922
+ /** Human-readable file size (e.g. "12.3 KB"). Empty string when size is unknown. */
923
+ export declare function formatFileSize(bytes?: number): string;
924
+
891
925
  export declare interface FormCollector<V = Record<string, unknown>> {
892
926
  name: string;
893
927
  /** Observable store driving the form UI (read via `useAgoStore`). */
@@ -1278,6 +1312,15 @@ export declare interface RegisteredFunction {
1278
1312
  handler: ClientFunctionHandler;
1279
1313
  }
1280
1314
 
1315
+ /**
1316
+ * Allow only URL schemes that are safe to put in an `<img src>` / `<a href>`.
1317
+ * Presigned attachment URLs are `https:` and optimistic previews are `blob:`;
1318
+ * anything else (notably `javascript:`/`data:`) is rejected and the attachment
1319
+ * falls back to a plain, non-clickable label. Defense in depth against a bad URL
1320
+ * reaching the DOM.
1321
+ */
1322
+ export declare function safeAttachmentUrl(url?: string): string | undefined;
1323
+
1281
1324
  /**
1282
1325
  * Scroll to an element on the page.
1283
1326
  */
package/dist/index.d.ts CHANGED
@@ -18,6 +18,27 @@ export declare class AgoApiError extends AgoError {
18
18
  static fromResponse(data: ApiErrorResponse, statusCode: number): AgoApiError;
19
19
  }
20
20
 
21
+ /**
22
+ * An uploaded file attached to a message.
23
+ *
24
+ * `url` is a presigned, time-limited URL the backend generates per request (or a
25
+ * local `blob:` URL for an optimistic preview). `isSafeImage` is the backend's
26
+ * verdict that the file is a real, script-free image safe to embed inline; the
27
+ * UI only renders an `<img>` when it is true and otherwise shows a download link.
28
+ */
29
+ export declare interface AgoAttachment {
30
+ id: string;
31
+ name: string;
32
+ /** MIME type reported by the backend (e.g. `image/png`). */
33
+ contentType?: string;
34
+ /** Size in bytes. */
35
+ fileSize?: number;
36
+ /** Presigned download/preview URL, or a local `blob:` URL before upload. */
37
+ url?: string;
38
+ /** True only when the backend verified the file is a safe inline image. */
39
+ isSafeImage: boolean;
40
+ }
41
+
21
42
  /**
22
43
  * Main SDK client for AGO Chat integration
23
44
  */
@@ -398,6 +419,8 @@ export declare interface AgoMessage {
398
419
  sources?: AgoSource[];
399
420
  toolCalls?: ToolCallData[];
400
421
  followUpReplies?: string[];
422
+ /** Uploaded files on this message (usually the user's). */
423
+ attachments?: AgoAttachment[];
401
424
  createdAt: Date;
402
425
  }
403
426
 
@@ -493,6 +516,14 @@ declare interface ApiErrorResponse {
493
516
  */
494
517
  export declare function autoDetectConfig(overrides?: Partial<AgoConfig>): AgoConfig | null;
495
518
 
519
+ /**
520
+ * Whether an attachment may be embedded inline as an `<img>`. Secure by default:
521
+ * requires the backend's `isSafeImage` verdict, an `image/*` content type, and a
522
+ * safe URL. PDFs, documents, SVGs, and unverified/spoofed types all return false
523
+ * and are shown as download links instead.
524
+ */
525
+ export declare function canInlineImage(attachment: AgoAttachment): boolean;
526
+
496
527
  /**
497
528
  * Registry that collects client-side context from across the component tree.
498
529
  *
@@ -888,6 +919,9 @@ export declare class EventEmitter<Events extends Record<string, any> = Record<st
888
919
 
889
920
  declare type EventHandler<T = unknown> = (data: T) => void;
890
921
 
922
+ /** Human-readable file size (e.g. "12.3 KB"). Empty string when size is unknown. */
923
+ export declare function formatFileSize(bytes?: number): string;
924
+
891
925
  export declare interface FormCollector<V = Record<string, unknown>> {
892
926
  name: string;
893
927
  /** Observable store driving the form UI (read via `useAgoStore`). */
@@ -1278,6 +1312,15 @@ export declare interface RegisteredFunction {
1278
1312
  handler: ClientFunctionHandler;
1279
1313
  }
1280
1314
 
1315
+ /**
1316
+ * Allow only URL schemes that are safe to put in an `<img src>` / `<a href>`.
1317
+ * Presigned attachment URLs are `https:` and optimistic previews are `blob:`;
1318
+ * anything else (notably `javascript:`/`data:`) is rejected and the attachment
1319
+ * falls back to a plain, non-clickable label. Defense in depth against a bad URL
1320
+ * reaching the DOM.
1321
+ */
1322
+ export declare function safeAttachmentUrl(url?: string): string | undefined;
1323
+
1281
1324
  /**
1282
1325
  * Scroll to an element on the page.
1283
1326
  */
package/dist/index.js CHANGED
@@ -1,37 +1,37 @@
1
- import { a as h, c as A, d as y, f as C, i as E, l as b, m as S, o as v, p as F, r as M, s as k, t as T, u as I } from "./functions-CApuQZ2b.js";
2
- import { a as G, c as O, d as q, f as x, i as L, l as N, n as _, o as D, p as H, r as J, s as R, t as d, u as c } from "./AgoClient-QcTtrN7u.js";
3
- import { i as B, n as P, r as $, t as z } from "./createFormCollector-CFt1_QSL.js";
4
- import { t as Q } from "./createConversationSession-CR-71aLR.js";
5
- import { t as W } from "./createMockClient-DwdxNwEn.js";
1
+ import { a as h, c as A, d as y, f as C, i as E, l as S, m as b, o as v, p as F, r as M, s as I, t as k, u as T } from "./functions-CApuQZ2b.js";
2
+ import { _ as G, a as O, c as _, d as q, f as x, g as L, h as N, l as D, m as d, n as H, o as J, p as R, r as j, s as z, t as c, u as B } from "./AgoClient-Cwx_eYSu.js";
3
+ import { i as $, n as K, r as Q, t as V } from "./createFormCollector-CyWisAkI.js";
4
+ import { t as X } from "./createConversationSession-B3h567tt.js";
5
+ import { t as Z } from "./createMockClient-DwdxNwEn.js";
6
6
  import "./testing.js";
7
- function Y(e) {
7
+ function oe(e) {
8
8
  return e;
9
9
  }
10
- function Z(e, o) {
10
+ function te(e, o) {
11
11
  return e.on("message:complete", o), () => e.off("message:complete", o);
12
12
  }
13
- function ee(e, o) {
13
+ function re(e, o) {
14
14
  return e.on("message:chunk", o), () => e.off("message:chunk", o);
15
15
  }
16
- function oe(e, o) {
16
+ function ne(e, o) {
17
17
  return e.on("message:start", o), () => e.off("message:start", o);
18
18
  }
19
- function te(e, o) {
19
+ function ae(e, o) {
20
20
  return e.on("message:error", o), () => e.off("message:error", o);
21
21
  }
22
- function re(e, o) {
22
+ function se(e, o) {
23
23
  return e.on("toolCall:received", o), () => e.off("toolCall:received", o);
24
24
  }
25
- function ne(e, o) {
25
+ function ie(e, o) {
26
26
  return e.on("form:submitted", o), () => e.off("form:submitted", o);
27
27
  }
28
- function ae(e, o) {
28
+ function ue(e, o) {
29
29
  return e.on("form:error", o), () => e.off("form:error", o);
30
30
  }
31
- function se(e, o) {
31
+ function ge(e, o) {
32
32
  return e.on("function:invoke", o), () => e.off("function:invoke", o);
33
33
  }
34
- async function* ie(e, o, u) {
34
+ async function* fe(e, o, u) {
35
35
  const n = [];
36
36
  let r = null, a = !1;
37
37
  const g = (s) => {
@@ -94,61 +94,64 @@ function p(e) {
94
94
  debug: f
95
95
  } : null;
96
96
  }
97
- function ue(e) {
97
+ function me(e) {
98
98
  const o = p(e);
99
- if (!o) throw new c('createAgo(): could not detect AGO configuration. Set window.AGO, add <meta name="ago-base-url">, or pass { baseUrl } explicitly.', "config_missing_base_url");
100
- return new d(o);
99
+ if (!o) throw new d('createAgo(): could not detect AGO configuration. Set window.AGO, add <meta name="ago-base-url">, or pass { baseUrl } explicitly.', "config_missing_base_url");
100
+ return new c(o);
101
101
  }
102
- function ge(e, o) {
102
+ function le(e, o) {
103
103
  return {
104
104
  ...e,
105
105
  handler: o
106
106
  };
107
107
  }
108
108
  export {
109
- N as AgoApiError,
110
- d as AgoClient,
111
- c as AgoError,
112
- q as AgoFunctionError,
113
- x as AgoNetworkError,
114
- H as AgoStreamError,
115
- D as ClientContextRegistry,
116
- J as EventEmitter,
117
- R as FunctionRegistry,
118
- L as SSEHandler,
109
+ R as AgoApiError,
110
+ c as AgoClient,
111
+ d as AgoError,
112
+ N as AgoFunctionError,
113
+ L as AgoNetworkError,
114
+ G as AgoStreamError,
115
+ B as ClientContextRegistry,
116
+ j as EventEmitter,
117
+ q as FunctionRegistry,
118
+ _ as SSEHandler,
119
119
  p as autoDetectConfig,
120
- T as copyToClipboard,
121
- ue as createAgo,
122
- Q as createConversationSession,
123
- z as createFormCollector,
124
- ie as createMessageStream,
125
- W as createMockClient,
126
- B as createStore,
127
- Y as defineFunction,
128
- P as deriveFormStatus,
120
+ O as canInlineImage,
121
+ k as copyToClipboard,
122
+ me as createAgo,
123
+ X as createConversationSession,
124
+ V as createFormCollector,
125
+ fe as createMessageStream,
126
+ Z as createMockClient,
127
+ $ as createStore,
128
+ oe as defineFunction,
129
+ K as deriveFormStatus,
130
+ J as formatFileSize,
129
131
  M as getLocalStorage,
130
132
  E as getUserLocation,
131
133
  h as highlightElement,
132
- G as isStreamNetworkError,
133
- $ as loadFormCollector,
134
- O as logger,
135
- ae as onFormError,
136
- ne as onFormSubmitted,
137
- se as onFunctionInvoke,
138
- Z as onMessage,
139
- ee as onMessageChunk,
140
- te as onMessageError,
141
- oe as onMessageStart,
142
- re as onToolCall,
134
+ D as isStreamNetworkError,
135
+ Q as loadFormCollector,
136
+ x as logger,
137
+ ue as onFormError,
138
+ ie as onFormSubmitted,
139
+ ge as onFunctionInvoke,
140
+ te as onMessage,
141
+ re as onMessageChunk,
142
+ ae as onMessageError,
143
+ ne as onMessageStart,
144
+ se as onToolCall,
143
145
  v as openUrl,
144
- k as scrollToElement,
146
+ z as safeAttachmentUrl,
147
+ I as scrollToElement,
145
148
  A as setLocalStorage,
146
- b as setTheme,
147
- I as showConfirmDialog,
149
+ S as setTheme,
150
+ T as showConfirmDialog,
148
151
  y as showNotification,
149
152
  C as showToast,
150
153
  F as submitForm,
151
- S as trackEvent,
152
- _ as validateConfig,
153
- ge as withHandler
154
+ b as trackEvent,
155
+ H as validateConfig,
156
+ le as withHandler
154
157
  };