@useago/sdk 1.13.2 → 1.14.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.
Files changed (40) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/angular.cjs +1 -1
  3. package/dist/angular.d.cts +21 -4
  4. package/dist/angular.d.ts +21 -4
  5. package/dist/angular.js +1 -1
  6. package/dist/{createConversationSession-DrmOaZdO.js → createConversationSession-CybQdMpK.js} +1 -1
  7. package/dist/{createConversationSession-Digvn0GQ.cjs → createConversationSession-jwSXhTLe.cjs} +1 -1
  8. package/dist/createFormCollector-B_hSKcLd.cjs +1 -0
  9. package/dist/{createFormCollector-ki_GTlp9.js → createFormCollector-DJjms78E.js} +49 -47
  10. package/dist/devtools.d.cts +21 -4
  11. package/dist/devtools.d.ts +21 -4
  12. package/dist/helpers.d.cts +9 -4
  13. package/dist/helpers.d.ts +9 -4
  14. package/dist/index.cjs +1 -1
  15. package/dist/index.d.cts +24 -4
  16. package/dist/index.d.ts +24 -4
  17. package/dist/index.js +42 -38
  18. package/dist/react.cjs +4 -4
  19. package/dist/react.d.cts +22 -5
  20. package/dist/react.d.ts +22 -5
  21. package/dist/react.js +901 -912
  22. package/dist/speechToText-BB25_zVM.cjs +7 -0
  23. package/dist/speechToText-BLvTis4S.js +1496 -0
  24. package/dist/testing.d.cts +21 -4
  25. package/dist/testing.d.ts +21 -4
  26. package/dist/{types-D1ZrqVhr.js → types-C39MJUE3.js} +284 -259
  27. package/dist/{types-DNr6XEwI.cjs → types-PGXnhAmQ.cjs} +7 -7
  28. package/dist/vue.cjs +1 -1
  29. package/dist/vue.d.cts +21 -4
  30. package/dist/vue.d.ts +21 -4
  31. package/dist/vue.js +1 -1
  32. package/dist/widget.cjs +5 -6
  33. package/dist/widget.d.cts +31 -8
  34. package/dist/widget.d.ts +31 -8
  35. package/dist/widget.js +1875 -1848
  36. package/llms-full.txt +43 -4
  37. package/package.json +1 -1
  38. package/dist/createFormCollector-Cq7HWjtU.cjs +0 -1
  39. package/dist/speechToText-BV7qxqPF.js +0 -704
  40. package/dist/speechToText-ZciRyyJE.cjs +0 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.14.0] - 2026-10-19
11
+
12
+ ### Added
13
+
14
+ - UI and configured ticket-form translations in six languages. Language switching preserves drafts, attachments and submission state; explicit wording overrides remain supported.
15
+
16
+ ## [1.13.3] - 2026-10-13
17
+
18
+ ### Added
19
+
20
+ - **Form submission start notifications.** Use `form:submitting`, the
21
+ `onFormSubmitting` helper, or the widget callback to show a loading state
22
+ after validation and before submission starts. Concurrent submits share one
23
+ start notification; success and failure use the existing outcome events.
24
+
25
+ - **WebMCP `consequentialHint` and `debugging` annotations.** Both are now
26
+ supported in `webmcp.annotations` and forwarded to browser agents.
27
+ `consequentialHint` describes significant, real-world, or irreversible
28
+ effects; `debugging` marks developer tools. These annotations do not change
29
+ AGO's in-app agent or approval behavior. `consequentialHint` remains
30
+ independent of `requiresApproval`.
31
+
32
+ ## [1.13.1] - 2026-09-21
33
+
10
34
  ### Added
11
35
 
12
36
  - **`catalogue: "onDemand"` for navigation.** Route descriptions ride in the
package/dist/angular.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("./types-DNr6XEwI.cjs"),a=require("./autoContinue-C3UsCvT5.cjs");var n=class{constructor(t){this.client=new s.AgoClient(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")}fromEvent(t){const e=this.client;return{subscribe(i){const r=o=>{i.next?.(o)};return e.on(t,r),{unsubscribe:()=>e.off(t,r)}}}}sendMessage(t,e){return this.client.sendMessage(t,e)}transcribeAudio(t,e){return this.client.transcribeAudio(t,e)}stop(){return this.client.stop()}stopMessage(t){return this.client.stopMessage(t)}isGenerating(){return this.client.isGenerating()}getConversations(){return this.client.getConversations().then(t=>t.data)}getConversation(t){return this.client.getConversation(t)}getMessages(t){return this.client.getMessages(t)}submitToolCallForm(t,e){return this.client.submitToolCallForm(t,e)}confirmToolCall(t){return this.client.confirmToolCall(t)}rejectToolCall(t){return this.client.rejectToolCall(t)}submitFeedback(t,e,i){return this.client.submitFeedback(t,e,i)}submitConversationFeedback(t,e,i){return this.client.submitConversationFeedback(t,e,i)}registerFunction(t,e,i){typeof t=="object"?this.client.registerFunction(t):this.client.registerFunction(t,e,i)}unregisterFunction(t){return this.client.unregisterFunction(t)}registerNavigationFunction(t,e,i){this.client.registerNavigationFunction(t,e,{catalogue:i?.catalogue==="onDemand"?"onDemand":"inline"})}unregisterNavigationFunction(){this.client.unregisterNavigationFunction()}enableAutoContinueAfterNavigation(t){return a.attachAutoContinueAfterNavigation(this.client,t)}registerPageStateFunction(t,e){this.client.registerPageStateFunction(t,e)}unregisterPageStateFunction(t){this.client.unregisterPageStateFunction(t)}on(t,e){this.client.on(t,e)}off(t,e){this.client.off(t,e)}updateConfig(t){this.client.updateConfig(t)}getClient(){return this.client}destroy(){this.client.destroy()}};function c(t){return{provide:n,useValue:new n(t)}}exports.AgoService=n;exports.FEEDBACK_REASONS=s.FEEDBACK_REASONS;exports.provideAgo=c;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("./types-PGXnhAmQ.cjs"),a=require("./autoContinue-C3UsCvT5.cjs");var n=class{constructor(t){this.client=new s.AgoClient(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")}fromEvent(t){const e=this.client;return{subscribe(i){const r=o=>{i.next?.(o)};return e.on(t,r),{unsubscribe:()=>e.off(t,r)}}}}sendMessage(t,e){return this.client.sendMessage(t,e)}transcribeAudio(t,e){return this.client.transcribeAudio(t,e)}stop(){return this.client.stop()}stopMessage(t){return this.client.stopMessage(t)}isGenerating(){return this.client.isGenerating()}getConversations(){return this.client.getConversations().then(t=>t.data)}getConversation(t){return this.client.getConversation(t)}getMessages(t){return this.client.getMessages(t)}submitToolCallForm(t,e){return this.client.submitToolCallForm(t,e)}confirmToolCall(t){return this.client.confirmToolCall(t)}rejectToolCall(t){return this.client.rejectToolCall(t)}submitFeedback(t,e,i){return this.client.submitFeedback(t,e,i)}submitConversationFeedback(t,e,i){return this.client.submitConversationFeedback(t,e,i)}registerFunction(t,e,i){typeof t=="object"?this.client.registerFunction(t):this.client.registerFunction(t,e,i)}unregisterFunction(t){return this.client.unregisterFunction(t)}registerNavigationFunction(t,e,i){this.client.registerNavigationFunction(t,e,{catalogue:i?.catalogue==="onDemand"?"onDemand":"inline"})}unregisterNavigationFunction(){this.client.unregisterNavigationFunction()}enableAutoContinueAfterNavigation(t){return a.attachAutoContinueAfterNavigation(this.client,t)}registerPageStateFunction(t,e){this.client.registerPageStateFunction(t,e)}unregisterPageStateFunction(t){this.client.unregisterPageStateFunction(t)}on(t,e){this.client.on(t,e)}off(t,e){this.client.off(t,e)}updateConfig(t){this.client.updateConfig(t)}getClient(){return this.client}destroy(){this.client.destroy()}};function c(t){return{provide:n,useValue:new n(t)}}exports.AgoService=n;exports.FEEDBACK_REASONS=s.FEEDBACK_REASONS;exports.provideAgo=c;
@@ -262,6 +262,8 @@ declare class AgoClient {
262
262
  * Show the returned text as a draft; call `sendMessage` when the user sends it.
263
263
  */
264
264
  transcribeAudio(file: File, options?: TranscribeAudioOptions): Promise<AudioTranscription>;
265
+ /** The requested language, before UI fallback. */
266
+ getLanguage(): string | null;
265
267
  /**
266
268
  * The tenant's SDK configuration (`GET /api/sdk/v1/config`): per-permission
267
269
  * agents, the ticket form the agent's `ago_ticketing` tool opens, and the
@@ -637,6 +639,9 @@ declare class AgoClient {
637
639
  * SDK Events
638
640
  */
639
641
  export declare interface AgoClientEvents {
642
+ "config:changed": {
643
+ language: string | null;
644
+ };
640
645
  /**
641
646
  * The client-side context changed: a context entry or dynamic provider was
642
647
  * added/removed, or a stateful helper (e.g. `createFormCollector`) updated its
@@ -746,6 +751,11 @@ export declare interface AgoClientEvents {
746
751
  result: unknown;
747
752
  error?: string;
748
753
  };
754
+ /** A validated form collector submission is about to call its submit target. */
755
+ "form:submitting": {
756
+ name: string;
757
+ values: Record<string, unknown>;
758
+ };
749
759
  /**
750
760
  * A form collector submitted successfully. `result` is the raw submit response
751
761
  * (POST body / handler return value / backend relay result) — the third-party
@@ -2134,6 +2144,7 @@ declare interface SubmitToolCallResult {
2134
2144
 
2135
2145
  /** A custom field of a ticket form. */
2136
2146
  declare interface TicketField {
2147
+ prefillAliases?: string[];
2137
2148
  id: string;
2138
2149
  /** The key the ticketing backend expects; used as the submit key when set. */
2139
2150
  externalId?: string;
@@ -2180,6 +2191,7 @@ declare interface TicketFieldOption {
2180
2191
 
2181
2192
  /** The ticket form an agent's `ago_ticketing` tool opens in the conversation. */
2182
2193
  declare interface TicketForm {
2194
+ embedDescription?: string;
2183
2195
  id: string;
2184
2196
  name?: string;
2185
2197
  /** `"form"` renders the SDK's own fields; `"embed"` hosts third-party HTML. */
@@ -2246,16 +2258,21 @@ export declare interface TranscribeAudioOptions {
2246
2258
  signal?: AbortSignal;
2247
2259
  }
2248
2260
 
2249
- /** The MCP behavior hints AGO has no equivalent for. */
2261
+ /** Metadata for tools exposed through the WebMCP bridge. */
2250
2262
  declare interface WebMCPToolMeta {
2251
2263
  /**
2252
- * Both default to `false`, so only set what is true: `readOnlyHint` marks a
2253
- * function that changes nothing, `untrustedContentHint` one whose result may
2254
- * carry third-party text.
2264
+ * Optional WebMCP metadata; all fields default to `false` in WebMCP.
2265
+ * These annotations do not affect AGO's in-app agent or approval behavior.
2255
2266
  */
2256
2267
  annotations?: {
2268
+ /** The tool only reads data and does not change state. */
2257
2269
  readOnlyHint?: boolean;
2270
+ /** The output contains content untrusted by the tool author. */
2258
2271
  untrustedContentHint?: boolean;
2272
+ /** Significant, real-world, or irreversible effects; independent of requiresApproval. */
2273
+ consequentialHint?: boolean;
2274
+ /** Intended for debugging and developer tooling. */
2275
+ debugging?: boolean;
2259
2276
  };
2260
2277
  /**
2261
2278
  * This function navigates. The WebMCP call is held open until the function
package/dist/angular.d.ts CHANGED
@@ -262,6 +262,8 @@ declare class AgoClient {
262
262
  * Show the returned text as a draft; call `sendMessage` when the user sends it.
263
263
  */
264
264
  transcribeAudio(file: File, options?: TranscribeAudioOptions): Promise<AudioTranscription>;
265
+ /** The requested language, before UI fallback. */
266
+ getLanguage(): string | null;
265
267
  /**
266
268
  * The tenant's SDK configuration (`GET /api/sdk/v1/config`): per-permission
267
269
  * agents, the ticket form the agent's `ago_ticketing` tool opens, and the
@@ -637,6 +639,9 @@ declare class AgoClient {
637
639
  * SDK Events
638
640
  */
639
641
  export declare interface AgoClientEvents {
642
+ "config:changed": {
643
+ language: string | null;
644
+ };
640
645
  /**
641
646
  * The client-side context changed: a context entry or dynamic provider was
642
647
  * added/removed, or a stateful helper (e.g. `createFormCollector`) updated its
@@ -746,6 +751,11 @@ export declare interface AgoClientEvents {
746
751
  result: unknown;
747
752
  error?: string;
748
753
  };
754
+ /** A validated form collector submission is about to call its submit target. */
755
+ "form:submitting": {
756
+ name: string;
757
+ values: Record<string, unknown>;
758
+ };
749
759
  /**
750
760
  * A form collector submitted successfully. `result` is the raw submit response
751
761
  * (POST body / handler return value / backend relay result) — the third-party
@@ -2134,6 +2144,7 @@ declare interface SubmitToolCallResult {
2134
2144
 
2135
2145
  /** A custom field of a ticket form. */
2136
2146
  declare interface TicketField {
2147
+ prefillAliases?: string[];
2137
2148
  id: string;
2138
2149
  /** The key the ticketing backend expects; used as the submit key when set. */
2139
2150
  externalId?: string;
@@ -2180,6 +2191,7 @@ declare interface TicketFieldOption {
2180
2191
 
2181
2192
  /** The ticket form an agent's `ago_ticketing` tool opens in the conversation. */
2182
2193
  declare interface TicketForm {
2194
+ embedDescription?: string;
2183
2195
  id: string;
2184
2196
  name?: string;
2185
2197
  /** `"form"` renders the SDK's own fields; `"embed"` hosts third-party HTML. */
@@ -2246,16 +2258,21 @@ export declare interface TranscribeAudioOptions {
2246
2258
  signal?: AbortSignal;
2247
2259
  }
2248
2260
 
2249
- /** The MCP behavior hints AGO has no equivalent for. */
2261
+ /** Metadata for tools exposed through the WebMCP bridge. */
2250
2262
  declare interface WebMCPToolMeta {
2251
2263
  /**
2252
- * Both default to `false`, so only set what is true: `readOnlyHint` marks a
2253
- * function that changes nothing, `untrustedContentHint` one whose result may
2254
- * carry third-party text.
2264
+ * Optional WebMCP metadata; all fields default to `false` in WebMCP.
2265
+ * These annotations do not affect AGO's in-app agent or approval behavior.
2255
2266
  */
2256
2267
  annotations?: {
2268
+ /** The tool only reads data and does not change state. */
2257
2269
  readOnlyHint?: boolean;
2270
+ /** The output contains content untrusted by the tool author. */
2258
2271
  untrustedContentHint?: boolean;
2272
+ /** Significant, real-world, or irreversible effects; independent of requiresApproval. */
2273
+ consequentialHint?: boolean;
2274
+ /** Intended for debugging and developer tooling. */
2275
+ debugging?: boolean;
2259
2276
  };
2260
2277
  /**
2261
2278
  * This function navigates. The WebMCP call is held open until the function
package/dist/angular.js CHANGED
@@ -1,4 +1,4 @@
1
- import { n as o, t as u } from "./types-D1ZrqVhr.js";
1
+ import { n as o, t as u } from "./types-C39MJUE3.js";
2
2
  import { t as a } from "./autoContinue-Cb4_iEbO.js";
3
3
  var s = class {
4
4
  constructor(t) {
@@ -1,4 +1,4 @@
1
- import { g as d } from "./types-D1ZrqVhr.js";
1
+ import { g as d } from "./types-C39MJUE3.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("./types-DNr6XEwI.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}),s=o.get();s.value!==null&&c(s.lastMessageAt)&&o.set({value:null,lastMessageAt:null});function c(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||c(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("./types-PGXnhAmQ.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}),s=o.get();s.value!==null&&c(s.lastMessageAt)&&o.set({value:null,lastMessageAt:null});function c(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||c(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 _}});
@@ -0,0 +1 @@
1
+ const C=require("./types-PGXnhAmQ.cjs");var W=/^[a-zA-Z0-9_-]{1,40}$/,V=n=>n==null||n==="";function S(n,e){if("anyOf"in n)return n.anyOf.some(c=>S(c,e));if("allOf"in n)return n.allOf.every(c=>S(c,e));const l=e[n.property];if(V(l))return!1;if(Array.isArray(n.value))return n.value.some(c=>String(l)===String(c));if(!n.op)return String(l)===String(n.value);const i=Number(l),a=Number(n.value);if(Number.isNaN(i)||Number.isNaN(a))return!1;switch(n.op){case">=":return i>=a;case"<=":return i<=a;case">":return i>a;case"<":return i<a;default:return C.logger.warn(`Unknown requiredWhen op "${n.op}"; treating as not required.`),!1}}function h(n,e){const l=n.properties??{},i=new Set;for(const c of n.required??[]){const b=l[c]?.requiredWhen;(!b||S(b,e))&&i.add(c)}for(const[c,b]of Object.entries(l))b.requiredWhen&&S(b.requiredWhen,e)&&i.add(c);const a=[...i].filter(c=>V(e[c]));return{missing:a,complete:a.length===0}}function B(n){const e={};for(const[l,i]of Object.entries(n.properties??{}))e[l]={type:i.type,...i.description!=null&&{description:i.description},...i.enum&&{enum:i.enum},...i.default!==void 0&&{default:i.default}};return{type:"object",properties:e,required:[]}}function A(n){const{name:e,description:l,schema:i}=n;if(!W.test(e))throw new Error(`Invalid form collector name "${e}": must match ${W} (it becomes the update_/submit_ function names).`);const a=typeof n.submit=="string"?n.submit?{via:"client",url:n.submit}:!1:n.submit??!1;n.autoSubmit===!0&&!a&&C.logger.warn(`FormCollector "${e}": autoSubmit is ignored because no submit target is configured.`);const c=(n.autoSubmit??!0)&&!!a,b=i.properties??{},$=t=>{const r={};for(const[o,s]of Object.entries(t)){const u=b[o];if(u)if(s==null)r[o]=s;else if(u.type==="number"||u.type==="integer"){const f=typeof s=="number"?s:Number(s);r[o]=Number.isNaN(f)?s:f}else u.type==="boolean"?r[o]=typeof s=="boolean"?s:s==="true"?!0:s==="false"?!1:!!s:r[o]=s}return r},F=n.initialValues??{},m=C.createStore({values:F,submitted:!1}),w=t=>{const r=m.get(),o={...r,values:{...r.values,...t}};return m.set(o),o};let d=null;const k=(t,r)=>{d?.emitFormEvent("form:error",{name:e,values:t,error:r})};let p=null;const I=async()=>{const{values:t}=m.get(),{complete:r,missing:o}=h(i,t);if(!r)return{ok:!1,missing:o};if(!a)return{ok:!1,error:"No submit target configured for this form collector."};if(a.via==="backend"&&!d)return{ok:!1,error:"Backend submit requires install(client) (or useFormCollector) first."};const s=t;try{d?.emitFormEvent("form:submitting",{name:e,values:s});let u;if(a.via==="client")if("handler"in a)u=await a.handler(s);else{const f=await fetch(a.url,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify(s)});if(!f.ok){const j=`Submit failed: HTTP ${f.status}`;return k(s,j),{ok:!1,error:j}}u=await f.json().catch(()=>{})}else u=await d.submitFormCollector(e,s);return m.set({...m.get(),submitted:!0,submitResult:u}),d?.emitFormEvent("form:submitted",{name:e,values:s,result:u}),{ok:!0,result:u}}catch(u){const f=u instanceof Error?u.message:"Submit failed";return C.logger.error(`FormCollector "${e}" submit failed:`,u),k(s,f),{ok:!1,error:f}}},N=()=>p||(p=(async()=>{try{return await I()}finally{p=null}})(),p),q=async()=>{if(!c||!a)return null;const{values:t,submitted:r}=m.get();return r||!h(i,t).complete?null:N()},O={name:`update_${e}`,description:`Fill or update fields of the "${e}" form. ${l} 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:B(i),handler:async t=>{const r=w($(t)),{missing:o}=h(i,r.values),s=await q();return s?s.ok?{ok:!0,values:r.values,missing:o,submitted:!0}:{ok:!0,values:r.values,missing:o,submitted:!1,submitError:s.error}:{ok:!0,values:r.values,missing:o}}},y=[O];a&&!c&&y.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 D="client__",_=a?`submit_${e}`:null,R=t=>{const r=t.functionName??t.toolName;if(r)return r.startsWith(D)?r.slice(8):r},x=t=>{let r={...F},o=!1;for(const s of t){const u=R(s);u===O.name?s.arguments&&(r={...r,...$(s.arguments)}):_&&u===_&&s.status?.toLowerCase()==="done"&&(o=!0)}m.set({values:r,submitted:o})},g=`form:${e}`,v=`${g}:definition`,E=()=>({name:`Form definition: ${e}`,description:`${l} 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(i)}.`,stable:!0}),P=()=>{const{values:t,submitted:r}=m.get(),{missing:o,complete:s}=h(i,t),u=a?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}.`:"",f=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:`${f} The form's schema and field requirements are in the "${v}" client context. Call update_${e} with any fields the user provides; ask only for what is still missing.${u}`,data:{values:t,missing:o,complete:s,submitted:r}}},T=t=>{x((t.messages??[]).flatMap(r=>r.toolCalls??[]))};return{name:e,store:m,functions:y,contextKey:g,contextProvider:P,definitionContextKey:v,definitionContextProvider:E,install:t=>{d=t;for(const o of y)t.register(o);t.addDynamicContext(v,E),t.addDynamicContext(g,P);const r=m.subscribe(()=>t.notifyContextChanged());return t.on("conversation:loaded",T),()=>{r();for(const o of y)t.unregisterFunction(o.name);t.removeDynamicContext(g),t.removeDynamicContext(v),t.off("conversation:loaded",T),d===t&&(d=null)}},hydrate:x,submit:N,getValues:()=>m.get().values,setValues:t=>{w($(t)),q()},reset:()=>{m.set({values:F,submitted:!1})},getStatus:()=>h(i,m.get().values)}}async function L(n,e){const l=await n.getFormCollector(e.name);return A({name:l.name,description:e.description??l.description,schema:e.schema??l.schema,submit:e.submit??l.submit,initialValues:e.initialValues,autoSubmit:e.autoSubmit??l.autoSubmit})}Object.defineProperty(exports,"createFormCollector",{enumerable:!0,get:function(){return A}});Object.defineProperty(exports,"deriveFormStatus",{enumerable:!0,get:function(){return h}});Object.defineProperty(exports,"loadFormCollector",{enumerable:!0,get:function(){return L}});
@@ -1,11 +1,11 @@
1
- import { S as w, g as R } from "./types-D1ZrqVhr.js";
1
+ import { S as w, g as R } from "./types-C39MJUE3.js";
2
2
  var j = /^[a-zA-Z0-9_-]{1,40}$/, V = (s) => s == null || s === "";
3
3
  function S(s, e) {
4
- if ("anyOf" in s) return s.anyOf.some((c) => S(c, e));
5
- if ("allOf" in s) return s.allOf.every((c) => S(c, e));
4
+ if ("anyOf" in s) return s.anyOf.some((m) => S(m, e));
5
+ if ("allOf" in s) return s.allOf.every((m) => S(m, e));
6
6
  const l = e[s.property];
7
7
  if (V(l)) return !1;
8
- if (Array.isArray(s.value)) return s.value.some((c) => String(l) === String(c));
8
+ if (Array.isArray(s.value)) return s.value.some((m) => String(l) === String(m));
9
9
  if (!s.op) return String(l) === String(s.value);
10
10
  const i = Number(l), a = Number(s.value);
11
11
  if (Number.isNaN(i) || Number.isNaN(a)) return !1;
@@ -24,12 +24,12 @@ function S(s, e) {
24
24
  }
25
25
  function p(s, e) {
26
26
  const l = s.properties ?? {}, i = /* @__PURE__ */ new Set();
27
- for (const c of s.required ?? []) {
28
- const d = l[c]?.requiredWhen;
29
- (!d || S(d, e)) && i.add(c);
27
+ for (const m of s.required ?? []) {
28
+ const b = l[m]?.requiredWhen;
29
+ (!b || S(b, e)) && i.add(m);
30
30
  }
31
- for (const [c, d] of Object.entries(l)) d.requiredWhen && S(d.requiredWhen, e) && i.add(c);
32
- const a = [...i].filter((c) => V(e[c]));
31
+ for (const [m, b] of Object.entries(l)) b.requiredWhen && S(b.requiredWhen, e) && i.add(m);
32
+ const a = [...i].filter((m) => V(e[m]));
33
33
  return {
34
34
  missing: a,
35
35
  complete: a.length === 0
@@ -57,10 +57,10 @@ function L(s) {
57
57
  url: s.submit
58
58
  } : !1 : s.submit ?? !1;
59
59
  s.autoSubmit === !0 && !a && w.warn(`FormCollector "${e}": autoSubmit is ignored because no submit target is configured.`);
60
- const c = (s.autoSubmit ?? !0) && !!a, d = i.properties ?? {}, $ = (t) => {
60
+ const m = (s.autoSubmit ?? !0) && !!a, b = i.properties ?? {}, $ = (t) => {
61
61
  const r = {};
62
62
  for (const [o, n] of Object.entries(t)) {
63
- const u = d[o];
63
+ const u = b[o];
64
64
  if (u)
65
65
  if (n == null) r[o] = n;
66
66
  else if (u.type === "number" || u.type === "integer") {
@@ -69,22 +69,22 @@ function L(s) {
69
69
  } else u.type === "boolean" ? r[o] = typeof n == "boolean" ? n : n === "true" ? !0 : n === "false" ? !1 : !!n : r[o] = n;
70
70
  }
71
71
  return r;
72
- }, C = s.initialValues ?? {}, m = R({
72
+ }, C = s.initialValues ?? {}, c = R({
73
73
  values: C,
74
74
  submitted: !1
75
75
  }), F = (t) => {
76
- const r = m.get(), o = {
76
+ const r = c.get(), o = {
77
77
  ...r,
78
78
  values: {
79
79
  ...r.values,
80
80
  ...t
81
81
  }
82
82
  };
83
- return m.set(o), o;
83
+ return c.set(o), o;
84
84
  };
85
- let b = null;
85
+ let d = null;
86
86
  const k = (t, r) => {
87
- b?.emitFormEvent("form:error", {
87
+ d?.emitFormEvent("form:error", {
88
88
  name: e,
89
89
  values: t,
90
90
  error: r
@@ -92,7 +92,7 @@ function L(s) {
92
92
  };
93
93
  let h = null;
94
94
  const A = async () => {
95
- const { values: t } = m.get(), { complete: r, missing: o } = p(i, t);
95
+ const { values: t } = c.get(), { complete: r, missing: o } = p(i, t);
96
96
  if (!r) return {
97
97
  ok: !1,
98
98
  missing: o
@@ -101,8 +101,16 @@ function L(s) {
101
101
  ok: !1,
102
102
  error: "No submit target configured for this form collector."
103
103
  };
104
+ if (a.via === "backend" && !d) return {
105
+ ok: !1,
106
+ error: "Backend submit requires install(client) (or useFormCollector) first."
107
+ };
104
108
  const n = t;
105
109
  try {
110
+ d?.emitFormEvent("form:submitting", {
111
+ name: e,
112
+ values: n
113
+ });
106
114
  let u;
107
115
  if (a.via === "client") if ("handler" in a) u = await a.handler(n);
108
116
  else {
@@ -122,18 +130,12 @@ function L(s) {
122
130
  u = await f.json().catch(() => {
123
131
  });
124
132
  }
125
- else {
126
- if (!b) return {
127
- ok: !1,
128
- error: "Backend submit requires install(client) (or useFormCollector) first."
129
- };
130
- u = await b.submitFormCollector(e, n);
131
- }
132
- return m.set({
133
- ...m.get(),
133
+ else u = await d.submitFormCollector(e, n);
134
+ return c.set({
135
+ ...c.get(),
134
136
  submitted: !0,
135
137
  submitResult: u
136
- }), b?.emitFormEvent("form:submitted", {
138
+ }), d?.emitFormEvent("form:submitted", {
137
139
  name: e,
138
140
  values: n,
139
141
  result: u
@@ -155,8 +157,8 @@ function L(s) {
155
157
  h = null;
156
158
  }
157
159
  })(), h), q = async () => {
158
- if (!c || !a) return null;
159
- const { values: t, submitted: r } = m.get();
160
+ if (!m || !a) return null;
161
+ const { values: t, submitted: r } = c.get();
160
162
  return r || !p(i, t).complete ? null : N();
161
163
  }, x = {
162
164
  name: `update_${e}`,
@@ -182,7 +184,7 @@ function L(s) {
182
184
  };
183
185
  }
184
186
  }, y = [x];
185
- a && !c && y.push({
187
+ a && !m && y.push({
186
188
  name: `submit_${e}`,
187
189
  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.`,
188
190
  parameters: {
@@ -195,7 +197,7 @@ function L(s) {
195
197
  const r = t.functionName ?? t.toolName;
196
198
  if (r)
197
199
  return r.startsWith(I) ? r.slice(8) : r;
198
- }, O = (t) => {
200
+ }, E = (t) => {
199
201
  let r = { ...C }, o = !1;
200
202
  for (const n of t) {
201
203
  const u = D(n);
@@ -204,16 +206,16 @@ function L(s) {
204
206
  ...$(n.arguments)
205
207
  }) : _ && u === _ && n.status?.toLowerCase() === "done" && (o = !0);
206
208
  }
207
- m.set({
209
+ c.set({
208
210
  values: r,
209
211
  submitted: o
210
212
  });
211
- }, g = `form:${e}`, v = `${g}:definition`, T = () => ({
213
+ }, g = `form:${e}`, v = `${g}:definition`, O = () => ({
212
214
  name: `Form definition: ${e}`,
213
215
  description: `${l} 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(i)}.`,
214
216
  stable: !0
215
- }), E = () => {
216
- const { values: t, submitted: r } = m.get(), { missing: o, complete: n } = p(i, t), u = a ? 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}.` : "", f = r ? `The "${e}" form has been submitted.` : `You are currently collecting information from the user to fill the "${e}" form.`;
217
+ }), T = () => {
218
+ const { values: t, submitted: r } = c.get(), { missing: o, complete: n } = p(i, t), u = a ? m ? " 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}.` : "", f = r ? `The "${e}" form has been submitted.` : `You are currently collecting information from the user to fill the "${e}" form.`;
217
219
  return {
218
220
  name: `Form: ${e}`,
219
221
  description: `${f} The form's schema and field requirements are in the "${v}" client context. Call update_${e} with any fields the user provides; ask only for what is still missing.${u}`,
@@ -225,40 +227,40 @@ function L(s) {
225
227
  }
226
228
  };
227
229
  }, P = (t) => {
228
- O((t.messages ?? []).flatMap((r) => r.toolCalls ?? []));
230
+ E((t.messages ?? []).flatMap((r) => r.toolCalls ?? []));
229
231
  };
230
232
  return {
231
233
  name: e,
232
- store: m,
234
+ store: c,
233
235
  functions: y,
234
236
  contextKey: g,
235
- contextProvider: E,
237
+ contextProvider: T,
236
238
  definitionContextKey: v,
237
- definitionContextProvider: T,
239
+ definitionContextProvider: O,
238
240
  install: (t) => {
239
- b = t;
241
+ d = t;
240
242
  for (const o of y) t.register(o);
241
- t.addDynamicContext(v, T), t.addDynamicContext(g, E);
242
- const r = m.subscribe(() => t.notifyContextChanged());
243
+ t.addDynamicContext(v, O), t.addDynamicContext(g, T);
244
+ const r = c.subscribe(() => t.notifyContextChanged());
243
245
  return t.on("conversation:loaded", P), () => {
244
246
  r();
245
247
  for (const o of y) t.unregisterFunction(o.name);
246
- t.removeDynamicContext(g), t.removeDynamicContext(v), t.off("conversation:loaded", P), b === t && (b = null);
248
+ t.removeDynamicContext(g), t.removeDynamicContext(v), t.off("conversation:loaded", P), d === t && (d = null);
247
249
  };
248
250
  },
249
- hydrate: O,
251
+ hydrate: E,
250
252
  submit: N,
251
- getValues: () => m.get().values,
253
+ getValues: () => c.get().values,
252
254
  setValues: (t) => {
253
255
  F($(t)), q();
254
256
  },
255
257
  reset: () => {
256
- m.set({
258
+ c.set({
257
259
  values: C,
258
260
  submitted: !1
259
261
  });
260
262
  },
261
- getStatus: () => p(i, m.get().values)
263
+ getStatus: () => p(i, c.get().values)
262
264
  };
263
265
  }
264
266
  async function K(s, e) {
@@ -245,6 +245,8 @@ declare class AgoClient {
245
245
  * Show the returned text as a draft; call `sendMessage` when the user sends it.
246
246
  */
247
247
  transcribeAudio(file: File, options?: TranscribeAudioOptions): Promise<AudioTranscription>;
248
+ /** The requested language, before UI fallback. */
249
+ getLanguage(): string | null;
248
250
  /**
249
251
  * The tenant's SDK configuration (`GET /api/sdk/v1/config`): per-permission
250
252
  * agents, the ticket form the agent's `ago_ticketing` tool opens, and the
@@ -620,6 +622,9 @@ declare class AgoClient {
620
622
  * SDK Events
621
623
  */
622
624
  declare interface AgoClientEvents {
625
+ "config:changed": {
626
+ language: string | null;
627
+ };
623
628
  /**
624
629
  * The client-side context changed: a context entry or dynamic provider was
625
630
  * added/removed, or a stateful helper (e.g. `createFormCollector`) updated its
@@ -729,6 +734,11 @@ declare interface AgoClientEvents {
729
734
  result: unknown;
730
735
  error?: string;
731
736
  };
737
+ /** A validated form collector submission is about to call its submit target. */
738
+ "form:submitting": {
739
+ name: string;
740
+ values: Record<string, unknown>;
741
+ };
732
742
  /**
733
743
  * A form collector submitted successfully. `result` is the raw submit response
734
744
  * (POST body / handler return value / backend relay result) — the third-party
@@ -1974,6 +1984,7 @@ declare interface SubmitToolCallResult {
1974
1984
 
1975
1985
  /** A custom field of a ticket form. */
1976
1986
  declare interface TicketField {
1987
+ prefillAliases?: string[];
1977
1988
  id: string;
1978
1989
  /** The key the ticketing backend expects; used as the submit key when set. */
1979
1990
  externalId?: string;
@@ -2020,6 +2031,7 @@ declare interface TicketFieldOption {
2020
2031
 
2021
2032
  /** The ticket form an agent's `ago_ticketing` tool opens in the conversation. */
2022
2033
  declare interface TicketForm {
2034
+ embedDescription?: string;
2023
2035
  id: string;
2024
2036
  name?: string;
2025
2037
  /** `"form"` renders the SDK's own fields; `"embed"` hosts third-party HTML. */
@@ -2086,16 +2098,21 @@ declare interface TranscribeAudioOptions {
2086
2098
  signal?: AbortSignal;
2087
2099
  }
2088
2100
 
2089
- /** The MCP behavior hints AGO has no equivalent for. */
2101
+ /** Metadata for tools exposed through the WebMCP bridge. */
2090
2102
  declare interface WebMCPToolMeta {
2091
2103
  /**
2092
- * Both default to `false`, so only set what is true: `readOnlyHint` marks a
2093
- * function that changes nothing, `untrustedContentHint` one whose result may
2094
- * carry third-party text.
2104
+ * Optional WebMCP metadata; all fields default to `false` in WebMCP.
2105
+ * These annotations do not affect AGO's in-app agent or approval behavior.
2095
2106
  */
2096
2107
  annotations?: {
2108
+ /** The tool only reads data and does not change state. */
2097
2109
  readOnlyHint?: boolean;
2110
+ /** The output contains content untrusted by the tool author. */
2098
2111
  untrustedContentHint?: boolean;
2112
+ /** Significant, real-world, or irreversible effects; independent of requiresApproval. */
2113
+ consequentialHint?: boolean;
2114
+ /** Intended for debugging and developer tooling. */
2115
+ debugging?: boolean;
2099
2116
  };
2100
2117
  /**
2101
2118
  * This function navigates. The WebMCP call is held open until the function
@@ -245,6 +245,8 @@ declare class AgoClient {
245
245
  * Show the returned text as a draft; call `sendMessage` when the user sends it.
246
246
  */
247
247
  transcribeAudio(file: File, options?: TranscribeAudioOptions): Promise<AudioTranscription>;
248
+ /** The requested language, before UI fallback. */
249
+ getLanguage(): string | null;
248
250
  /**
249
251
  * The tenant's SDK configuration (`GET /api/sdk/v1/config`): per-permission
250
252
  * agents, the ticket form the agent's `ago_ticketing` tool opens, and the
@@ -620,6 +622,9 @@ declare class AgoClient {
620
622
  * SDK Events
621
623
  */
622
624
  declare interface AgoClientEvents {
625
+ "config:changed": {
626
+ language: string | null;
627
+ };
623
628
  /**
624
629
  * The client-side context changed: a context entry or dynamic provider was
625
630
  * added/removed, or a stateful helper (e.g. `createFormCollector`) updated its
@@ -729,6 +734,11 @@ declare interface AgoClientEvents {
729
734
  result: unknown;
730
735
  error?: string;
731
736
  };
737
+ /** A validated form collector submission is about to call its submit target. */
738
+ "form:submitting": {
739
+ name: string;
740
+ values: Record<string, unknown>;
741
+ };
732
742
  /**
733
743
  * A form collector submitted successfully. `result` is the raw submit response
734
744
  * (POST body / handler return value / backend relay result) — the third-party
@@ -1974,6 +1984,7 @@ declare interface SubmitToolCallResult {
1974
1984
 
1975
1985
  /** A custom field of a ticket form. */
1976
1986
  declare interface TicketField {
1987
+ prefillAliases?: string[];
1977
1988
  id: string;
1978
1989
  /** The key the ticketing backend expects; used as the submit key when set. */
1979
1990
  externalId?: string;
@@ -2020,6 +2031,7 @@ declare interface TicketFieldOption {
2020
2031
 
2021
2032
  /** The ticket form an agent's `ago_ticketing` tool opens in the conversation. */
2022
2033
  declare interface TicketForm {
2034
+ embedDescription?: string;
2023
2035
  id: string;
2024
2036
  name?: string;
2025
2037
  /** `"form"` renders the SDK's own fields; `"embed"` hosts third-party HTML. */
@@ -2086,16 +2098,21 @@ declare interface TranscribeAudioOptions {
2086
2098
  signal?: AbortSignal;
2087
2099
  }
2088
2100
 
2089
- /** The MCP behavior hints AGO has no equivalent for. */
2101
+ /** Metadata for tools exposed through the WebMCP bridge. */
2090
2102
  declare interface WebMCPToolMeta {
2091
2103
  /**
2092
- * Both default to `false`, so only set what is true: `readOnlyHint` marks a
2093
- * function that changes nothing, `untrustedContentHint` one whose result may
2094
- * carry third-party text.
2104
+ * Optional WebMCP metadata; all fields default to `false` in WebMCP.
2105
+ * These annotations do not affect AGO's in-app agent or approval behavior.
2095
2106
  */
2096
2107
  annotations?: {
2108
+ /** The tool only reads data and does not change state. */
2097
2109
  readOnlyHint?: boolean;
2110
+ /** The output contains content untrusted by the tool author. */
2098
2111
  untrustedContentHint?: boolean;
2112
+ /** Significant, real-world, or irreversible effects; independent of requiresApproval. */
2113
+ consequentialHint?: boolean;
2114
+ /** Intended for debugging and developer tooling. */
2115
+ debugging?: boolean;
2099
2116
  };
2100
2117
  /**
2101
2118
  * This function navigates. The WebMCP call is held open until the function
@@ -144,16 +144,21 @@ export declare const submitForm: ClientFunctionDefinition;
144
144
  */
145
145
  export declare const trackEvent: ClientFunctionDefinition;
146
146
 
147
- /** The MCP behavior hints AGO has no equivalent for. */
147
+ /** Metadata for tools exposed through the WebMCP bridge. */
148
148
  declare interface WebMCPToolMeta {
149
149
  /**
150
- * Both default to `false`, so only set what is true: `readOnlyHint` marks a
151
- * function that changes nothing, `untrustedContentHint` one whose result may
152
- * carry third-party text.
150
+ * Optional WebMCP metadata; all fields default to `false` in WebMCP.
151
+ * These annotations do not affect AGO's in-app agent or approval behavior.
153
152
  */
154
153
  annotations?: {
154
+ /** The tool only reads data and does not change state. */
155
155
  readOnlyHint?: boolean;
156
+ /** The output contains content untrusted by the tool author. */
156
157
  untrustedContentHint?: boolean;
158
+ /** Significant, real-world, or irreversible effects; independent of requiresApproval. */
159
+ consequentialHint?: boolean;
160
+ /** Intended for debugging and developer tooling. */
161
+ debugging?: boolean;
157
162
  };
158
163
  /**
159
164
  * This function navigates. The WebMCP call is held open until the function
package/dist/helpers.d.ts CHANGED
@@ -144,16 +144,21 @@ export declare const submitForm: ClientFunctionDefinition;
144
144
  */
145
145
  export declare const trackEvent: ClientFunctionDefinition;
146
146
 
147
- /** The MCP behavior hints AGO has no equivalent for. */
147
+ /** Metadata for tools exposed through the WebMCP bridge. */
148
148
  declare interface WebMCPToolMeta {
149
149
  /**
150
- * Both default to `false`, so only set what is true: `readOnlyHint` marks a
151
- * function that changes nothing, `untrustedContentHint` one whose result may
152
- * carry third-party text.
150
+ * Optional WebMCP metadata; all fields default to `false` in WebMCP.
151
+ * These annotations do not affect AGO's in-app agent or approval behavior.
153
152
  */
154
153
  annotations?: {
154
+ /** The tool only reads data and does not change state. */
155
155
  readOnlyHint?: boolean;
156
+ /** The output contains content untrusted by the tool author. */
156
157
  untrustedContentHint?: boolean;
158
+ /** Significant, real-world, or irreversible effects; independent of requiresApproval. */
159
+ consequentialHint?: boolean;
160
+ /** Intended for debugging and developer tooling. */
161
+ debugging?: boolean;
157
162
  };
158
163
  /**
159
164
  * This function navigates. The WebMCP call is held open until the function