@useago/sdk 1.3.2 → 1.4.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.
@@ -154,6 +154,37 @@ declare class AgoClient {
154
154
  path: string;
155
155
  description: string;
156
156
  }>): void;
157
+ /**
158
+ * Register a "page state" function that lets AGO change the current page's
159
+ * state (filters, sort, view mode, selection…) and reads the current state
160
+ * back as dynamic context. This is the state-mutation mirror of
161
+ * {@link registerNavigationFunction}.
162
+ *
163
+ * It does two things:
164
+ * - Synthesizes ONE client function (default name `setPageState`) whose
165
+ * properties are the controls — all optional, so the agent sets only the
166
+ * ones the user asked for.
167
+ * - Registers a dynamic context provider (keyed `page-state:<fnName>`) that
168
+ * reports each control's current `get()` value on every message.
169
+ *
170
+ * ```ts
171
+ * client.registerPageStateFunction([
172
+ * {
173
+ * name: "statusFilter",
174
+ * description: "Filter the list by review status",
175
+ * schema: { type: "string", enum: ["all", "pending", "approved"] },
176
+ * get: () => filters.status,
177
+ * set: (v) => setFilters({ ...filters, status: v }),
178
+ * },
179
+ * ]);
180
+ * ```
181
+ */
182
+ registerPageStateFunction(controls: AgoStateControl[], opts?: AgoPageStateOptions): void;
183
+ /**
184
+ * Unregister a page state function and its dynamic context provider.
185
+ * Mirror of unregistering `navigateToPage`.
186
+ */
187
+ unregisterPageStateFunction(functionName?: string): void;
157
188
  /**
158
189
  * Register or update a piece of client-side context.
159
190
  * This context is sent with every message so the AI understands the user's situation.
@@ -386,9 +417,23 @@ export declare interface AgoMessage {
386
417
  followUpReplies?: string[];
387
418
  /** Uploaded files on this message (usually the user's). */
388
419
  attachments?: AgoAttachment[];
420
+ /**
421
+ * True when the backend flagged this message as hidden (e.g. an
422
+ * auto-continuation nudge). Kept in the model's context but not displayed;
423
+ * UI helpers like `useMessages`/`ChatWidget` filter these out.
424
+ */
425
+ hidden?: boolean;
389
426
  createdAt: Date;
390
427
  }
391
428
 
429
+ /**
430
+ * Options for {@link AgoClient.registerPageStateFunction}.
431
+ */
432
+ export declare interface AgoPageStateOptions {
433
+ /** Name of the synthesized client function. Defaults to "setPageState". */
434
+ functionName?: string;
435
+ }
436
+
392
437
  export declare type AgoProvideOptions = AgoConfig;
393
438
 
394
439
  /**
@@ -466,6 +511,10 @@ export declare class AgoService {
466
511
  path: string;
467
512
  description: string;
468
513
  }>): void;
514
+ /** Register editable page-state controls (filters, sort, view mode…) */
515
+ registerPageStateFunction(controls: AgoStateControl[], opts?: AgoPageStateOptions): void;
516
+ /** Unregister a page-state function and its dynamic context */
517
+ unregisterPageStateFunction(functionName?: string): void;
469
518
  /** Subscribe to a client event */
470
519
  on<K extends AgoEventName>(event: K, handler: (data: AgoClientEvents[K]) => void): void;
471
520
  /** Unsubscribe from a client event */
@@ -487,6 +536,32 @@ export declare interface AgoSource {
487
536
  url?: string;
488
537
  }
489
538
 
539
+ /**
540
+ * A single editable control on the current page (a filter, a sort, a view mode,
541
+ * a selection…). It becomes one optional property of the synthesized
542
+ * `setPageState` function, and its current value is surfaced back to the agent
543
+ * as dynamic context. This is the state-mutation mirror of a navigation route.
544
+ */
545
+ export declare interface AgoStateControl<T = unknown> {
546
+ /** Machine name of the control, e.g. "statusFilter". Becomes a property of the tool. */
547
+ name: string;
548
+ /** Description for the LLM, e.g. "Filter the list by review status". */
549
+ description: string;
550
+ /** JSON schema for a SINGLE field (like one property of navigateToPage). */
551
+ schema: {
552
+ type: "string" | "number" | "boolean" | "array";
553
+ enum?: (string | number)[];
554
+ items?: {
555
+ type: string;
556
+ enum?: (string | number)[];
557
+ };
558
+ };
559
+ /** Current value → pushed as dynamic context so the agent knows what to change. */
560
+ get?: () => T;
561
+ /** Apply the state change on the page. May be async. */
562
+ set: (value: T) => void | Promise<void>;
563
+ }
564
+
490
565
  /**
491
566
  * Single-object function definition — combines name, schema, and handler.
492
567
  *
@@ -533,7 +608,11 @@ declare interface ClientFunctionSchema {
533
608
  properties: Record<string, {
534
609
  type: string;
535
610
  description?: string;
536
- enum?: string[];
611
+ enum?: (string | number)[];
612
+ items?: {
613
+ type: string;
614
+ enum?: (string | number)[];
615
+ };
537
616
  default?: unknown;
538
617
  }>;
539
618
  required?: string[];
@@ -718,6 +797,13 @@ declare interface SendMessageOptions {
718
797
  agentId?: string;
719
798
  /** File attachments */
720
799
  files?: File[];
800
+ /**
801
+ * Mark this message as hidden. The backend keeps it in the model's context but
802
+ * flags it so the UI never displays it. Used by auto-continuation to nudge the
803
+ * agent after a navigation without polluting the visible transcript.
804
+ * Requires backend support for the `hidden` flag; older backends ignore it.
805
+ */
806
+ hidden?: boolean;
721
807
  }
722
808
 
723
809
  /**
package/dist/angular.d.ts CHANGED
@@ -154,6 +154,37 @@ declare class AgoClient {
154
154
  path: string;
155
155
  description: string;
156
156
  }>): void;
157
+ /**
158
+ * Register a "page state" function that lets AGO change the current page's
159
+ * state (filters, sort, view mode, selection…) and reads the current state
160
+ * back as dynamic context. This is the state-mutation mirror of
161
+ * {@link registerNavigationFunction}.
162
+ *
163
+ * It does two things:
164
+ * - Synthesizes ONE client function (default name `setPageState`) whose
165
+ * properties are the controls — all optional, so the agent sets only the
166
+ * ones the user asked for.
167
+ * - Registers a dynamic context provider (keyed `page-state:<fnName>`) that
168
+ * reports each control's current `get()` value on every message.
169
+ *
170
+ * ```ts
171
+ * client.registerPageStateFunction([
172
+ * {
173
+ * name: "statusFilter",
174
+ * description: "Filter the list by review status",
175
+ * schema: { type: "string", enum: ["all", "pending", "approved"] },
176
+ * get: () => filters.status,
177
+ * set: (v) => setFilters({ ...filters, status: v }),
178
+ * },
179
+ * ]);
180
+ * ```
181
+ */
182
+ registerPageStateFunction(controls: AgoStateControl[], opts?: AgoPageStateOptions): void;
183
+ /**
184
+ * Unregister a page state function and its dynamic context provider.
185
+ * Mirror of unregistering `navigateToPage`.
186
+ */
187
+ unregisterPageStateFunction(functionName?: string): void;
157
188
  /**
158
189
  * Register or update a piece of client-side context.
159
190
  * This context is sent with every message so the AI understands the user's situation.
@@ -386,9 +417,23 @@ export declare interface AgoMessage {
386
417
  followUpReplies?: string[];
387
418
  /** Uploaded files on this message (usually the user's). */
388
419
  attachments?: AgoAttachment[];
420
+ /**
421
+ * True when the backend flagged this message as hidden (e.g. an
422
+ * auto-continuation nudge). Kept in the model's context but not displayed;
423
+ * UI helpers like `useMessages`/`ChatWidget` filter these out.
424
+ */
425
+ hidden?: boolean;
389
426
  createdAt: Date;
390
427
  }
391
428
 
429
+ /**
430
+ * Options for {@link AgoClient.registerPageStateFunction}.
431
+ */
432
+ export declare interface AgoPageStateOptions {
433
+ /** Name of the synthesized client function. Defaults to "setPageState". */
434
+ functionName?: string;
435
+ }
436
+
392
437
  export declare type AgoProvideOptions = AgoConfig;
393
438
 
394
439
  /**
@@ -466,6 +511,10 @@ export declare class AgoService {
466
511
  path: string;
467
512
  description: string;
468
513
  }>): void;
514
+ /** Register editable page-state controls (filters, sort, view mode…) */
515
+ registerPageStateFunction(controls: AgoStateControl[], opts?: AgoPageStateOptions): void;
516
+ /** Unregister a page-state function and its dynamic context */
517
+ unregisterPageStateFunction(functionName?: string): void;
469
518
  /** Subscribe to a client event */
470
519
  on<K extends AgoEventName>(event: K, handler: (data: AgoClientEvents[K]) => void): void;
471
520
  /** Unsubscribe from a client event */
@@ -487,6 +536,32 @@ export declare interface AgoSource {
487
536
  url?: string;
488
537
  }
489
538
 
539
+ /**
540
+ * A single editable control on the current page (a filter, a sort, a view mode,
541
+ * a selection…). It becomes one optional property of the synthesized
542
+ * `setPageState` function, and its current value is surfaced back to the agent
543
+ * as dynamic context. This is the state-mutation mirror of a navigation route.
544
+ */
545
+ export declare interface AgoStateControl<T = unknown> {
546
+ /** Machine name of the control, e.g. "statusFilter". Becomes a property of the tool. */
547
+ name: string;
548
+ /** Description for the LLM, e.g. "Filter the list by review status". */
549
+ description: string;
550
+ /** JSON schema for a SINGLE field (like one property of navigateToPage). */
551
+ schema: {
552
+ type: "string" | "number" | "boolean" | "array";
553
+ enum?: (string | number)[];
554
+ items?: {
555
+ type: string;
556
+ enum?: (string | number)[];
557
+ };
558
+ };
559
+ /** Current value → pushed as dynamic context so the agent knows what to change. */
560
+ get?: () => T;
561
+ /** Apply the state change on the page. May be async. */
562
+ set: (value: T) => void | Promise<void>;
563
+ }
564
+
490
565
  /**
491
566
  * Single-object function definition — combines name, schema, and handler.
492
567
  *
@@ -533,7 +608,11 @@ declare interface ClientFunctionSchema {
533
608
  properties: Record<string, {
534
609
  type: string;
535
610
  description?: string;
536
- enum?: string[];
611
+ enum?: (string | number)[];
612
+ items?: {
613
+ type: string;
614
+ enum?: (string | number)[];
615
+ };
537
616
  default?: unknown;
538
617
  }>;
539
618
  required?: string[];
@@ -718,6 +797,13 @@ declare interface SendMessageOptions {
718
797
  agentId?: string;
719
798
  /** File attachments */
720
799
  files?: File[];
800
+ /**
801
+ * Mark this message as hidden. The backend keeps it in the model's context but
802
+ * flags it so the UI never displays it. Used by auto-continuation to nudge the
803
+ * agent after a navigation without polluting the visible transcript.
804
+ * Requires backend support for the `hidden` flag; older backends ignore it.
805
+ */
806
+ hidden?: boolean;
721
807
  }
722
808
 
723
809
  /**
package/dist/angular.js CHANGED
@@ -1,15 +1,15 @@
1
- import { t as o } from "./AgoClient-Cwx_eYSu.js";
2
- var n = class {
1
+ import { t as o } from "./AgoClient-BrhKkDWt.js";
2
+ var s = 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");
5
5
  }
6
6
  fromEvent(t) {
7
7
  const e = this.client;
8
8
  return { subscribe(i) {
9
- const s = (r) => {
9
+ const n = (r) => {
10
10
  i.next?.(r);
11
11
  };
12
- return e.on(t, s), { unsubscribe: () => e.off(t, s) };
12
+ return e.on(t, n), { unsubscribe: () => e.off(t, n) };
13
13
  } };
14
14
  }
15
15
  sendMessage(t, e) {
@@ -45,6 +45,12 @@ var n = class {
45
45
  registerNavigationFunction(t, e) {
46
46
  this.client.registerNavigationFunction(t, e);
47
47
  }
48
+ registerPageStateFunction(t, e) {
49
+ this.client.registerPageStateFunction(t, e);
50
+ }
51
+ unregisterPageStateFunction(t) {
52
+ this.client.unregisterPageStateFunction(t);
53
+ }
48
54
  on(t, e) {
49
55
  this.client.on(t, e);
50
56
  }
@@ -63,11 +69,11 @@ var n = class {
63
69
  };
64
70
  function l(t) {
65
71
  return {
66
- provide: n,
67
- useValue: new n(t)
72
+ provide: s,
73
+ useValue: new s(t)
68
74
  };
69
75
  }
70
76
  export {
71
- n as AgoService,
77
+ s as AgoService,
72
78
  l as provideAgo
73
79
  };
@@ -1,4 +1,4 @@
1
- import { i as d } from "./createFormCollector-CyWisAkI.js";
1
+ import { i as d } from "./createFormCollector-BYKe5Uxm.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-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
+ const d=require("./createFormCollector-CpYX_5PT.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,4 +1,4 @@
1
- import { f as $ } from "./AgoClient-Cwx_eYSu.js";
1
+ import { f as $ } from "./AgoClient-BrhKkDWt.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;
@@ -1 +1 @@
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
+ const C=require("./AgoClient-B2BU8tfB.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}});
@@ -154,6 +154,37 @@ declare class AgoClient {
154
154
  path: string;
155
155
  description: string;
156
156
  }>): void;
157
+ /**
158
+ * Register a "page state" function that lets AGO change the current page's
159
+ * state (filters, sort, view mode, selection…) and reads the current state
160
+ * back as dynamic context. This is the state-mutation mirror of
161
+ * {@link registerNavigationFunction}.
162
+ *
163
+ * It does two things:
164
+ * - Synthesizes ONE client function (default name `setPageState`) whose
165
+ * properties are the controls — all optional, so the agent sets only the
166
+ * ones the user asked for.
167
+ * - Registers a dynamic context provider (keyed `page-state:<fnName>`) that
168
+ * reports each control's current `get()` value on every message.
169
+ *
170
+ * ```ts
171
+ * client.registerPageStateFunction([
172
+ * {
173
+ * name: "statusFilter",
174
+ * description: "Filter the list by review status",
175
+ * schema: { type: "string", enum: ["all", "pending", "approved"] },
176
+ * get: () => filters.status,
177
+ * set: (v) => setFilters({ ...filters, status: v }),
178
+ * },
179
+ * ]);
180
+ * ```
181
+ */
182
+ registerPageStateFunction(controls: AgoStateControl[], opts?: AgoPageStateOptions): void;
183
+ /**
184
+ * Unregister a page state function and its dynamic context provider.
185
+ * Mirror of unregistering `navigateToPage`.
186
+ */
187
+ unregisterPageStateFunction(functionName?: string): void;
157
188
  /**
158
189
  * Register or update a piece of client-side context.
159
190
  * This context is sent with every message so the AI understands the user's situation.
@@ -386,9 +417,23 @@ declare interface AgoMessage {
386
417
  followUpReplies?: string[];
387
418
  /** Uploaded files on this message (usually the user's). */
388
419
  attachments?: AgoAttachment[];
420
+ /**
421
+ * True when the backend flagged this message as hidden (e.g. an
422
+ * auto-continuation nudge). Kept in the model's context but not displayed;
423
+ * UI helpers like `useMessages`/`ChatWidget` filter these out.
424
+ */
425
+ hidden?: boolean;
389
426
  createdAt: Date;
390
427
  }
391
428
 
429
+ /**
430
+ * Options for {@link AgoClient.registerPageStateFunction}.
431
+ */
432
+ declare interface AgoPageStateOptions {
433
+ /** Name of the synthesized client function. Defaults to "setPageState". */
434
+ functionName?: string;
435
+ }
436
+
392
437
  /**
393
438
  * Knowledge source citation
394
439
  */
@@ -398,6 +443,32 @@ declare interface AgoSource {
398
443
  url?: string;
399
444
  }
400
445
 
446
+ /**
447
+ * A single editable control on the current page (a filter, a sort, a view mode,
448
+ * a selection…). It becomes one optional property of the synthesized
449
+ * `setPageState` function, and its current value is surfaced back to the agent
450
+ * as dynamic context. This is the state-mutation mirror of a navigation route.
451
+ */
452
+ declare interface AgoStateControl<T = unknown> {
453
+ /** Machine name of the control, e.g. "statusFilter". Becomes a property of the tool. */
454
+ name: string;
455
+ /** Description for the LLM, e.g. "Filter the list by review status". */
456
+ description: string;
457
+ /** JSON schema for a SINGLE field (like one property of navigateToPage). */
458
+ schema: {
459
+ type: "string" | "number" | "boolean" | "array";
460
+ enum?: (string | number)[];
461
+ items?: {
462
+ type: string;
463
+ enum?: (string | number)[];
464
+ };
465
+ };
466
+ /** Current value → pushed as dynamic context so the agent knows what to change. */
467
+ get?: () => T;
468
+ /** Apply the state change on the page. May be async. */
469
+ set: (value: T) => void | Promise<void>;
470
+ }
471
+
401
472
  /**
402
473
  * Single-object function definition — combines name, schema, and handler.
403
474
  *
@@ -444,7 +515,11 @@ declare interface ClientFunctionSchema {
444
515
  properties: Record<string, {
445
516
  type: string;
446
517
  description?: string;
447
- enum?: string[];
518
+ enum?: (string | number)[];
519
+ items?: {
520
+ type: string;
521
+ enum?: (string | number)[];
522
+ };
448
523
  default?: unknown;
449
524
  }>;
450
525
  required?: string[];
@@ -621,6 +696,13 @@ declare interface SendMessageOptions {
621
696
  agentId?: string;
622
697
  /** File attachments */
623
698
  files?: File[];
699
+ /**
700
+ * Mark this message as hidden. The backend keeps it in the model's context but
701
+ * flags it so the UI never displays it. Used by auto-continuation to nudge the
702
+ * agent after a navigation without polluting the visible transcript.
703
+ * Requires backend support for the `hidden` flag; older backends ignore it.
704
+ */
705
+ hidden?: boolean;
624
706
  }
625
707
 
626
708
  /**
@@ -154,6 +154,37 @@ declare class AgoClient {
154
154
  path: string;
155
155
  description: string;
156
156
  }>): void;
157
+ /**
158
+ * Register a "page state" function that lets AGO change the current page's
159
+ * state (filters, sort, view mode, selection…) and reads the current state
160
+ * back as dynamic context. This is the state-mutation mirror of
161
+ * {@link registerNavigationFunction}.
162
+ *
163
+ * It does two things:
164
+ * - Synthesizes ONE client function (default name `setPageState`) whose
165
+ * properties are the controls — all optional, so the agent sets only the
166
+ * ones the user asked for.
167
+ * - Registers a dynamic context provider (keyed `page-state:<fnName>`) that
168
+ * reports each control's current `get()` value on every message.
169
+ *
170
+ * ```ts
171
+ * client.registerPageStateFunction([
172
+ * {
173
+ * name: "statusFilter",
174
+ * description: "Filter the list by review status",
175
+ * schema: { type: "string", enum: ["all", "pending", "approved"] },
176
+ * get: () => filters.status,
177
+ * set: (v) => setFilters({ ...filters, status: v }),
178
+ * },
179
+ * ]);
180
+ * ```
181
+ */
182
+ registerPageStateFunction(controls: AgoStateControl[], opts?: AgoPageStateOptions): void;
183
+ /**
184
+ * Unregister a page state function and its dynamic context provider.
185
+ * Mirror of unregistering `navigateToPage`.
186
+ */
187
+ unregisterPageStateFunction(functionName?: string): void;
157
188
  /**
158
189
  * Register or update a piece of client-side context.
159
190
  * This context is sent with every message so the AI understands the user's situation.
@@ -386,9 +417,23 @@ declare interface AgoMessage {
386
417
  followUpReplies?: string[];
387
418
  /** Uploaded files on this message (usually the user's). */
388
419
  attachments?: AgoAttachment[];
420
+ /**
421
+ * True when the backend flagged this message as hidden (e.g. an
422
+ * auto-continuation nudge). Kept in the model's context but not displayed;
423
+ * UI helpers like `useMessages`/`ChatWidget` filter these out.
424
+ */
425
+ hidden?: boolean;
389
426
  createdAt: Date;
390
427
  }
391
428
 
429
+ /**
430
+ * Options for {@link AgoClient.registerPageStateFunction}.
431
+ */
432
+ declare interface AgoPageStateOptions {
433
+ /** Name of the synthesized client function. Defaults to "setPageState". */
434
+ functionName?: string;
435
+ }
436
+
392
437
  /**
393
438
  * Knowledge source citation
394
439
  */
@@ -398,6 +443,32 @@ declare interface AgoSource {
398
443
  url?: string;
399
444
  }
400
445
 
446
+ /**
447
+ * A single editable control on the current page (a filter, a sort, a view mode,
448
+ * a selection…). It becomes one optional property of the synthesized
449
+ * `setPageState` function, and its current value is surfaced back to the agent
450
+ * as dynamic context. This is the state-mutation mirror of a navigation route.
451
+ */
452
+ declare interface AgoStateControl<T = unknown> {
453
+ /** Machine name of the control, e.g. "statusFilter". Becomes a property of the tool. */
454
+ name: string;
455
+ /** Description for the LLM, e.g. "Filter the list by review status". */
456
+ description: string;
457
+ /** JSON schema for a SINGLE field (like one property of navigateToPage). */
458
+ schema: {
459
+ type: "string" | "number" | "boolean" | "array";
460
+ enum?: (string | number)[];
461
+ items?: {
462
+ type: string;
463
+ enum?: (string | number)[];
464
+ };
465
+ };
466
+ /** Current value → pushed as dynamic context so the agent knows what to change. */
467
+ get?: () => T;
468
+ /** Apply the state change on the page. May be async. */
469
+ set: (value: T) => void | Promise<void>;
470
+ }
471
+
401
472
  /**
402
473
  * Single-object function definition — combines name, schema, and handler.
403
474
  *
@@ -444,7 +515,11 @@ declare interface ClientFunctionSchema {
444
515
  properties: Record<string, {
445
516
  type: string;
446
517
  description?: string;
447
- enum?: string[];
518
+ enum?: (string | number)[];
519
+ items?: {
520
+ type: string;
521
+ enum?: (string | number)[];
522
+ };
448
523
  default?: unknown;
449
524
  }>;
450
525
  required?: string[];
@@ -621,6 +696,13 @@ declare interface SendMessageOptions {
621
696
  agentId?: string;
622
697
  /** File attachments */
623
698
  files?: File[];
699
+ /**
700
+ * Mark this message as hidden. The backend keeps it in the model's context but
701
+ * flags it so the UI never displays it. Used by auto-continuation to nudge the
702
+ * agent after a navigation without polluting the visible transcript.
703
+ * Requires backend support for the `hidden` flag; older backends ignore it.
704
+ */
705
+ hidden?: boolean;
624
706
  }
625
707
 
626
708
  /**
@@ -37,7 +37,11 @@ declare interface ClientFunctionSchema {
37
37
  properties: Record<string, {
38
38
  type: string;
39
39
  description?: string;
40
- enum?: string[];
40
+ enum?: (string | number)[];
41
+ items?: {
42
+ type: string;
43
+ enum?: (string | number)[];
44
+ };
41
45
  default?: unknown;
42
46
  }>;
43
47
  required?: string[];
package/dist/helpers.d.ts CHANGED
@@ -37,7 +37,11 @@ declare interface ClientFunctionSchema {
37
37
  properties: Record<string, {
38
38
  type: string;
39
39
  description?: string;
40
- enum?: string[];
40
+ enum?: (string | number)[];
41
+ items?: {
42
+ type: string;
43
+ enum?: (string | number)[];
44
+ };
41
45
  default?: unknown;
42
46
  }>;
43
47
  required?: string[];
package/dist/index.cjs CHANGED
@@ -1 +1 @@
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;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./AgoClient-B2BU8tfB.cjs"),f=require("./createFormCollector-CpYX_5PT.cjs"),h=require("./createConversationSession-Cin8dVNq.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;