@useago/sdk 1.4.4 → 1.5.2

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 (50) hide show
  1. package/CHANGELOG.md +63 -1
  2. package/dist/AgoClient-5VGybmvz.cjs +8 -0
  3. package/dist/AgoClient-DXrH2AMi.js +964 -0
  4. package/dist/angular.cjs +1 -1
  5. package/dist/angular.d.cts +124 -5
  6. package/dist/angular.d.ts +124 -5
  7. package/dist/angular.js +5 -1
  8. package/dist/autoContinue-CC8K9mBU.js +63 -0
  9. package/dist/autoContinue-CP9pJR-V.cjs +1 -0
  10. package/dist/{createConversationSession-CUkNp6mZ.cjs → createConversationSession-0WTqcCLK.cjs} +1 -1
  11. package/dist/{createConversationSession-QIBN0gLx.js → createConversationSession-DPrrr70o.js} +1 -1
  12. package/dist/createFormCollector-1GKKwQV_.cjs +1 -0
  13. package/dist/{createFormCollector-F3YJfsbg.js → createFormCollector-DYh90kiG.js} +97 -91
  14. package/dist/devtools.d.cts +82 -5
  15. package/dist/devtools.d.ts +82 -5
  16. package/dist/functions-CPs7omgM.cjs +1 -0
  17. package/dist/helpers.cjs +1 -1
  18. package/dist/helpers.d.cts +5 -0
  19. package/dist/helpers.d.ts +5 -0
  20. package/dist/helpers.js +1 -1
  21. package/dist/index.cjs +1 -1
  22. package/dist/index.d.cts +147 -7
  23. package/dist/index.d.ts +147 -7
  24. package/dist/index.js +45 -43
  25. package/dist/react.cjs +3 -3
  26. package/dist/react.d.cts +191 -21
  27. package/dist/react.d.ts +191 -21
  28. package/dist/react.js +666 -529
  29. package/dist/testing.cjs +1 -1
  30. package/dist/testing.d.cts +82 -5
  31. package/dist/testing.d.ts +82 -5
  32. package/dist/testing.js +1 -1
  33. package/dist/vue.cjs +1 -1
  34. package/dist/vue.d.cts +82 -5
  35. package/dist/vue.d.ts +82 -5
  36. package/dist/vue.js +1 -1
  37. package/dist/widget.cjs +4 -4
  38. package/dist/widget.d.cts +82 -5
  39. package/dist/widget.d.ts +82 -5
  40. package/dist/widget.js +437 -423
  41. package/llms-full.txt +100 -6
  42. package/package.json +1 -1
  43. package/dist/AgoClient-CLmtYTJx.cjs +0 -8
  44. package/dist/AgoClient-Ozz2b1dQ.js +0 -912
  45. package/dist/createFormCollector-DHT1ObOb.cjs +0 -1
  46. package/dist/functions-Djnq-JAo.cjs +0 -1
  47. package/dist/rolldown-runtime-16Nf8qvH.cjs +0 -1
  48. /package/dist/{createMockClient-BSr-UV8R.cjs → createMockClient-C-wrjb2C.cjs} +0 -0
  49. /package/dist/{createMockClient-bAZ9KBHC.js → createMockClient-we-XoPom.js} +0 -0
  50. /package/dist/{functions-CApuQZ2b.js → functions-tzyOZNp6.js} +0 -0
package/dist/helpers.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("./functions-Djnq-JAo.cjs");exports.copyToClipboard=o.copyToClipboard;exports.getLocalStorage=o.getLocalStorage;exports.getUserLocation=o.getUserLocation;exports.highlightElement=o.highlightElement;exports.openUrl=o.openUrl;exports.scrollToElement=o.scrollToElement;exports.setLocalStorage=o.setLocalStorage;exports.setTheme=o.setTheme;exports.showConfirmDialog=o.showConfirmDialog;exports.showNotification=o.showNotification;exports.showToast=o.showToast;exports.submitForm=o.submitForm;exports.trackEvent=o.trackEvent;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("./functions-CPs7omgM.cjs");exports.copyToClipboard=o.copyToClipboard;exports.getLocalStorage=o.getLocalStorage;exports.getUserLocation=o.getUserLocation;exports.highlightElement=o.highlightElement;exports.openUrl=o.openUrl;exports.scrollToElement=o.scrollToElement;exports.setLocalStorage=o.setLocalStorage;exports.setTheme=o.setTheme;exports.showConfirmDialog=o.showConfirmDialog;exports.showNotification=o.showNotification;exports.showToast=o.showToast;exports.submitForm=o.submitForm;exports.trackEvent=o.trackEvent;
@@ -22,6 +22,11 @@ declare interface ClientFunctionDefinition {
22
22
  * `Infinity` disables the guard for this function.
23
23
  */
24
24
  maxResultBytes?: number;
25
+ /**
26
+ * Require explicit user approval before this function runs. See
27
+ * {@link AgoConfig.approvalPolicy} — pause mode only. ORs with the policy.
28
+ */
29
+ requiresApproval?: boolean;
25
30
  }
26
31
 
27
32
  /**
package/dist/helpers.d.ts CHANGED
@@ -22,6 +22,11 @@ declare interface ClientFunctionDefinition {
22
22
  * `Infinity` disables the guard for this function.
23
23
  */
24
24
  maxResultBytes?: number;
25
+ /**
26
+ * Require explicit user approval before this function runs. See
27
+ * {@link AgoConfig.approvalPolicy} — pause mode only. ORs with the policy.
28
+ */
29
+ requiresApproval?: boolean;
25
30
  }
26
31
 
27
32
  /**
package/dist/helpers.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a, c as s, d as t, f as e, i as r, l as i, m as l, o as m, p as c, r as g, s as h, t as n, u as p } from "./functions-CApuQZ2b.js";
1
+ import { a, c as s, d as t, f as e, i as r, l as i, m as l, o as m, p as c, r as g, s as h, t as n, u as p } from "./functions-tzyOZNp6.js";
2
2
  export {
3
3
  n as copyToClipboard,
4
4
  g as getLocalStorage,
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./AgoClient-CLmtYTJx.cjs"),f=require("./createFormCollector-DHT1ObOb.cjs"),h=require("./createConversationSession-CUkNp6mZ.cjs"),p=require("./createMockClient-BSr-UV8R.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-5VGybmvz.cjs"),h=require("./autoContinue-CP9pJR-V.cjs"),f=require("./createFormCollector-1GKKwQV_.cjs"),p=require("./createConversationSession-0WTqcCLK.cjs"),w=require("./createMockClient-C-wrjb2C.cjs");require("./testing.cjs");const g=require("./functions-CPs7omgM.cjs");function S(e){return e}function E(e,o){return e.on("message:complete",o),()=>e.off("message:complete",o)}function y(e,o){return e.on("message:chunk",o),()=>e.off("message:chunk",o)}function F(e,o){return e.on("message:start",o),()=>e.off("message:start",o)}function v(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 q(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 k(e,o){return e.on("function:invoke",o),()=>e.off("function:invoke",o)}async function*T(e,o,l){const a=[];let n=null,i=!1;const c=s=>{a.push(s),n?.()},m=s=>c({type:"start",data:s}),t=s=>c({type:"chunk",data:s}),u=s=>{c({type:"complete",data:s}),i=!0,n?.()},d=s=>{c({type:"error",data:s}),i=!0,n?.()},A=s=>c({type:"toolCall",data:s});e.on("message:start",m),e.on("message:chunk",t),e.on("message:complete",u),e.on("message:error",d),e.on("toolCall:received",A),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",m),e.off("message:chunk",t),e.off("message:complete",u),e.off("message:error",d),e.off("toolCall:received",A)}}function C(e){let o,l,a,n,i,c;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,c=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,c=e?.userJwt||c;const m=e?.debug;return o?{baseUrl:o,widgetId:l,agent:a,permission:n,userEmail:i,userJwt:c,debug:m}:null}function I(e){const o=C(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 U(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.attachAutoContinueAfterNavigation=h.attachAutoContinueAfterNavigation;exports.autoDetectConfig=C;exports.canInlineImage=r.canInlineImage;exports.copyToClipboard=g.copyToClipboard;exports.createAgo=I;exports.createConversationSession=p.createConversationSession;exports.createFormCollector=f.createFormCollector;exports.createMessageStream=T;exports.createMockClient=w.createMockClient;exports.createStore=f.createStore;exports.defineFunction=S;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=q;exports.onFunctionInvoke=k;exports.onMessage=E;exports.onMessageChunk=y;exports.onMessageError=v;exports.onMessageStart=F;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=U;
package/dist/index.d.cts CHANGED
@@ -39,6 +39,23 @@ export declare interface AgoAttachment {
39
39
  isSafeImage: boolean;
40
40
  }
41
41
 
42
+ export declare interface AgoAutoContinueOptions {
43
+ /** Function names whose invocation counts as "navigated". Default `["navigateToPage"]`. */
44
+ navigationFunctions?: string[];
45
+ /** Registered function that signals the destination has editable state. Default `"setPageState"`. */
46
+ pageStateFunctionName?: string;
47
+ /** The hidden continuation prompt. Override for i18n / tone. */
48
+ continuationPrompt?: string;
49
+ /** Max continuations per user gesture (guards navigate→continue→navigate loops). Default `1`. */
50
+ maxDepth?: number;
51
+ /** How long to wait for the destination page to register page-state before giving up. Default `4000`ms. */
52
+ readinessTimeoutMs?: number;
53
+ /** Extra settle delay after page-state appears, to let sibling state mount. Default `150`ms. */
54
+ settleMs?: number;
55
+ /** Opt-out escape hatch. Default `true`. */
56
+ enabled?: boolean;
57
+ }
58
+
42
59
  /**
43
60
  * Main SDK client for AGO Chat integration
44
61
  */
@@ -52,6 +69,12 @@ export declare class AgoClient {
52
69
  private warnedEmptyConversations;
53
70
  /** Paused turns awaiting auto-resume, keyed by assistant message id. */
54
71
  private pendingResumes;
72
+ /**
73
+ * Client function invocations held pending user approval, keyed by
74
+ * invocationId (the tool-call id). Populated when {@link requiresApproval}
75
+ * matches; drained by {@link approveFunction} / {@link rejectFunction}.
76
+ */
77
+ private pendingApprovals;
55
78
  /** App-provided gate deciding WHEN a paused turn resumes (see {@link registerResumeGate}). */
56
79
  private resumeGate;
57
80
  constructor(config: AgoConfig);
@@ -102,6 +125,24 @@ export declare class AgoClient {
102
125
  */
103
126
  private maybeFlagEmptyReply;
104
127
  private handleClientFunctionInvocation;
128
+ /**
129
+ * Whether a client function invocation must wait for explicit user approval.
130
+ * True when the {@link AgoConfig.approvalPolicy} returns true OR the function
131
+ * was registered with `requiresApproval: true` — the two OR together.
132
+ */
133
+ private requiresApproval;
134
+ /**
135
+ * Approve a client function call held by the approval gate: run it, submit its
136
+ * result, and let the paused turn resume. No-op if the invocation is unknown
137
+ * (already handled, or never gated).
138
+ */
139
+ approveFunction(invocationId: string): Promise<void>;
140
+ /**
141
+ * Reject a client function call held by the approval gate: submit a rejection
142
+ * result so the agent sees the user declined, and let the paused turn resume
143
+ * (the agent decides what to do next). No-op if the invocation is unknown.
144
+ */
145
+ rejectFunction(invocationId: string): Promise<void>;
105
146
  /**
106
147
  * Get list of conversations
107
148
  */
@@ -131,8 +172,10 @@ export declare class AgoClient {
131
172
  *
132
173
  * Opt-in on purpose — re-running functions on reload can be surprising (e.g. a
133
174
  * navigation function would navigate again), so the app decides. Returns the
134
- * resumed turn's final message, or `null` when there was nothing to resume or
135
- * some waiting function is not registered on this page.
175
+ * resumed turn's final message, or `null` when there was nothing to resume,
176
+ * some waiting function is not registered on this page, or a waiting call is
177
+ * gated by the approval policy (it is held for `approveFunction` /
178
+ * `rejectFunction` and the turn stays paused, exactly as on the live stream).
136
179
  */
137
180
  resumePendingClientFunctions(conversation: Conversation): Promise<AgoMessage | null>;
138
181
  /**
@@ -427,6 +470,15 @@ export declare interface AgoClientEvents {
427
470
  "toolCall:received": ToolCallData;
428
471
  "toolCall:form": ToolCallData;
429
472
  "function:invoke": ClientFunctionInvocation;
473
+ /**
474
+ * A client function call is held pending the user's approval (pause mode +
475
+ * an {@link AgoConfig.approvalPolicy}/`requiresApproval` match). The turn stays
476
+ * at `WAITING_CLIENT`; call `approveFunction(invocationId)` to run it and
477
+ * resume, or `rejectFunction(invocationId)` to decline. Fires after
478
+ * `function:invoke` (which still fires for every call) and instead of the
479
+ * call running immediately.
480
+ */
481
+ "function:awaiting-approval": ClientFunctionInvocation;
430
482
  "function:result": {
431
483
  invocationId: string;
432
484
  result: unknown;
@@ -487,14 +539,28 @@ export declare interface AgoConfig {
487
539
  warnOnEmptyReply?: boolean;
488
540
  /**
489
541
  * How the agent loop treats client function calls (requires backend support):
490
- * - `"placeholder"` (default): the turn continues immediately on a placeholder
491
- * result; the real result is only visible to the agent on later turns.
492
- * - `"pause"`: the turn stops on client function call(s) with status
542
+ * - `"pause"` (default): the turn stops on client function call(s) with status
493
543
  * `WAITING_CLIENT`; once every result is submitted, the SDK resumes the SAME
494
544
  * turn via `POST /messages/{id}/continue`, so the agent sees the real results.
545
+ * - `"placeholder"` (legacy): the turn continues immediately on a placeholder
546
+ * result; the real result is only visible to the agent on later turns.
495
547
  * Older backends ignore the flag, so `"pause"` degrades to legacy behavior.
496
548
  */
497
549
  clientFunctionsMode?: ClientFunctionsMode;
550
+ /**
551
+ * Gate client function calls behind explicit user approval. Return `true` for
552
+ * an invocation the user must approve/reject before it runs; return `false`
553
+ * (or omit the policy) to let it run immediately as before.
554
+ *
555
+ * Only effective in pause mode (`clientFunctionsMode: "pause"`) — a gated call
556
+ * holds at `WAITING_CLIENT`, the SDK emits `function:awaiting-approval`, and it
557
+ * runs (and the turn resumes) only after `approveFunction(invocationId)`; a
558
+ * `rejectFunction(invocationId)` submits a rejection so the agent sees the
559
+ * decline. In placeholder mode there is no pause to hold, so the policy is a
560
+ * no-op and the call runs normally. A per-function `requiresApproval: true`
561
+ * also gates a call; the policy and the flag OR together.
562
+ */
563
+ approvalPolicy?: (invocation: ClientFunctionInvocation) => boolean;
498
564
  /**
499
565
  * Max serialized size (bytes) of a client function result before the SDK
500
566
  * replaces it with a flagged, truncated preview. Everything a handler
@@ -571,6 +637,11 @@ export declare class AgoNetworkError extends AgoError {
571
637
  export declare interface AgoPageStateOptions {
572
638
  /** Name of the synthesized client function. Defaults to "setPageState". */
573
639
  functionName?: string;
640
+ /**
641
+ * Require explicit user approval before this state change runs. See
642
+ * {@link AgoConfig.approvalPolicy} — pause mode only. Defaults to `false`.
643
+ */
644
+ requiresApproval?: boolean;
574
645
  }
575
646
 
576
647
  /**
@@ -659,6 +730,38 @@ declare interface ApiErrorResponse {
659
730
  };
660
731
  }
661
732
 
733
+ /**
734
+ * Auto-continue the agent after it navigates, so a "go to page B and change X"
735
+ * request completes in one user gesture. Attach once per client; returns a
736
+ * detach function that removes every listener.
737
+ *
738
+ * Two mechanisms, picked by the turn's client-functions mode:
739
+ *
740
+ * - **Pause mode** (`clientFunctionsMode: "pause"`, the default): the backend pauses the turn
741
+ * on the navigation call (`message:waiting-client`) and the SDK resumes it once
742
+ * the result is submitted. This helper only registers a *resume gate* that delays
743
+ * the resume until the destination page's page-state registered (plus a settle
744
+ * delay), so the continued turn ships the new page's `setPageState` and current
745
+ * state. Same turn, no extra prompt, backend budget as the guardrail —
746
+ * `continuationPrompt` and `maxDepth` are unused here.
747
+ *
748
+ * - **Placeholder mode** (legacy, `clientFunctionsMode: "placeholder"`): when the agent calls the navigation
749
+ * function and that turn ends, this waits for the destination page's state to
750
+ * register, then sends a hidden continuation message; the agent applies the
751
+ * state in a second turn (requires backend support for the `hidden` flag).
752
+ *
753
+ * ```ts
754
+ * const detach = attachAutoContinueAfterNavigation(client);
755
+ * // later, on teardown:
756
+ * detach();
757
+ * ```
758
+ *
759
+ * Options can be a plain object, or a getter for live options: the getter is
760
+ * re-read on every event, so changing what it returns never re-subscribes the
761
+ * listeners (this is how the React hook keeps options reactive).
762
+ */
763
+ export declare function attachAutoContinueAfterNavigation(client: AgoClient, options?: AgoAutoContinueOptions | (() => AgoAutoContinueOptions | undefined)): () => void;
764
+
662
765
  /**
663
766
  * Auto-detect AGO configuration from the DOM environment.
664
767
  *
@@ -747,6 +850,11 @@ export declare interface ClientFunctionDefinition {
747
850
  * `Infinity` disables the guard for this function.
748
851
  */
749
852
  maxResultBytes?: number;
853
+ /**
854
+ * Require explicit user approval before this function runs. See
855
+ * {@link AgoConfig.approvalPolicy} — pause mode only. ORs with the policy.
856
+ */
857
+ requiresApproval?: boolean;
750
858
  }
751
859
 
752
860
  /**
@@ -773,6 +881,11 @@ export declare type ClientFunctionRegisterOptions = Omit<ClientFunctionSchema, "
773
881
  * disables the guard for this function.
774
882
  */
775
883
  maxResultBytes?: number;
884
+ /**
885
+ * Require explicit user approval before this function runs. See
886
+ * {@link AgoConfig.approvalPolicy} — pause mode only. ORs with the policy.
887
+ */
888
+ requiresApproval?: boolean;
776
889
  };
777
890
 
778
891
  /**
@@ -813,6 +926,19 @@ export declare interface ContextEntry {
813
926
  description?: string;
814
927
  /** Arbitrary structured data the AI should know about */
815
928
  data?: Record<string, unknown>;
929
+ /**
930
+ * Marks the entry as constant for the whole conversation. The backend then
931
+ * pins it right after the system prompt, where LLM providers cache it across
932
+ * turns, instead of re-processing it next to every new user message.
933
+ *
934
+ * Only set this when the entry's content is byte-identical on every message
935
+ * of a conversation (a schema, a capability list, static instructions). A
936
+ * stable entry that changes between messages invalidates the provider's
937
+ * cache for the entire conversation history, which costs more than leaving
938
+ * the flag off. Default: `false` (re-sent near the newest user message).
939
+ * Backends that don't know the flag ignore it.
940
+ */
941
+ stable?: boolean;
816
942
  }
817
943
 
818
944
  /**
@@ -1111,10 +1237,22 @@ export declare interface FormCollector<V = Record<string, unknown>> {
1111
1237
  store: Store<FormCollectorState<V>>;
1112
1238
  /** Client functions to register: `[update]` or `[update, submit]`. */
1113
1239
  functions: ClientFunctionDefinition[];
1114
- /** Dynamic-context key under which the form state is exposed. */
1240
+ /** Dynamic-context key under which the live form state is exposed. */
1115
1241
  contextKey: string;
1116
- /** Dynamic-context provider — re-read on every message. */
1242
+ /**
1243
+ * Dynamic-context provider for the live form state (phase, values, missing)
1244
+ * — re-read on every message. The schema itself rides in the companion
1245
+ * {@link definitionContextProvider} entry.
1246
+ */
1117
1247
  contextProvider: () => ContextEntry;
1248
+ /** Context key of the stable form definition (`<contextKey>:definition`). */
1249
+ definitionContextKey: string;
1250
+ /**
1251
+ * Provider for the form's definition (description + schema): identical on
1252
+ * every message and marked `stable: true`, so the backend can pin it in the
1253
+ * cacheable part of the prompt. Registered/removed by `install` alongside `contextProvider`.
1254
+ */
1255
+ definitionContextProvider: () => ContextEntry;
1118
1256
  /** Register the functions + dynamic context on a client. Returns an uninstall fn. */
1119
1257
  install: (client: AgoClient) => () => void;
1120
1258
  /**
@@ -1518,6 +1656,8 @@ export declare interface RegisteredFunction {
1518
1656
  handler: ClientFunctionHandler;
1519
1657
  /** Per-function result-size ceiling; falls back to the registry default. */
1520
1658
  maxResultBytes?: number;
1659
+ /** Require explicit user approval before running (pause mode only). */
1660
+ requiresApproval?: boolean;
1521
1661
  }
1522
1662
 
1523
1663
  /**
package/dist/index.d.ts CHANGED
@@ -39,6 +39,23 @@ export declare interface AgoAttachment {
39
39
  isSafeImage: boolean;
40
40
  }
41
41
 
42
+ export declare interface AgoAutoContinueOptions {
43
+ /** Function names whose invocation counts as "navigated". Default `["navigateToPage"]`. */
44
+ navigationFunctions?: string[];
45
+ /** Registered function that signals the destination has editable state. Default `"setPageState"`. */
46
+ pageStateFunctionName?: string;
47
+ /** The hidden continuation prompt. Override for i18n / tone. */
48
+ continuationPrompt?: string;
49
+ /** Max continuations per user gesture (guards navigate→continue→navigate loops). Default `1`. */
50
+ maxDepth?: number;
51
+ /** How long to wait for the destination page to register page-state before giving up. Default `4000`ms. */
52
+ readinessTimeoutMs?: number;
53
+ /** Extra settle delay after page-state appears, to let sibling state mount. Default `150`ms. */
54
+ settleMs?: number;
55
+ /** Opt-out escape hatch. Default `true`. */
56
+ enabled?: boolean;
57
+ }
58
+
42
59
  /**
43
60
  * Main SDK client for AGO Chat integration
44
61
  */
@@ -52,6 +69,12 @@ export declare class AgoClient {
52
69
  private warnedEmptyConversations;
53
70
  /** Paused turns awaiting auto-resume, keyed by assistant message id. */
54
71
  private pendingResumes;
72
+ /**
73
+ * Client function invocations held pending user approval, keyed by
74
+ * invocationId (the tool-call id). Populated when {@link requiresApproval}
75
+ * matches; drained by {@link approveFunction} / {@link rejectFunction}.
76
+ */
77
+ private pendingApprovals;
55
78
  /** App-provided gate deciding WHEN a paused turn resumes (see {@link registerResumeGate}). */
56
79
  private resumeGate;
57
80
  constructor(config: AgoConfig);
@@ -102,6 +125,24 @@ export declare class AgoClient {
102
125
  */
103
126
  private maybeFlagEmptyReply;
104
127
  private handleClientFunctionInvocation;
128
+ /**
129
+ * Whether a client function invocation must wait for explicit user approval.
130
+ * True when the {@link AgoConfig.approvalPolicy} returns true OR the function
131
+ * was registered with `requiresApproval: true` — the two OR together.
132
+ */
133
+ private requiresApproval;
134
+ /**
135
+ * Approve a client function call held by the approval gate: run it, submit its
136
+ * result, and let the paused turn resume. No-op if the invocation is unknown
137
+ * (already handled, or never gated).
138
+ */
139
+ approveFunction(invocationId: string): Promise<void>;
140
+ /**
141
+ * Reject a client function call held by the approval gate: submit a rejection
142
+ * result so the agent sees the user declined, and let the paused turn resume
143
+ * (the agent decides what to do next). No-op if the invocation is unknown.
144
+ */
145
+ rejectFunction(invocationId: string): Promise<void>;
105
146
  /**
106
147
  * Get list of conversations
107
148
  */
@@ -131,8 +172,10 @@ export declare class AgoClient {
131
172
  *
132
173
  * Opt-in on purpose — re-running functions on reload can be surprising (e.g. a
133
174
  * navigation function would navigate again), so the app decides. Returns the
134
- * resumed turn's final message, or `null` when there was nothing to resume or
135
- * some waiting function is not registered on this page.
175
+ * resumed turn's final message, or `null` when there was nothing to resume,
176
+ * some waiting function is not registered on this page, or a waiting call is
177
+ * gated by the approval policy (it is held for `approveFunction` /
178
+ * `rejectFunction` and the turn stays paused, exactly as on the live stream).
136
179
  */
137
180
  resumePendingClientFunctions(conversation: Conversation): Promise<AgoMessage | null>;
138
181
  /**
@@ -427,6 +470,15 @@ export declare interface AgoClientEvents {
427
470
  "toolCall:received": ToolCallData;
428
471
  "toolCall:form": ToolCallData;
429
472
  "function:invoke": ClientFunctionInvocation;
473
+ /**
474
+ * A client function call is held pending the user's approval (pause mode +
475
+ * an {@link AgoConfig.approvalPolicy}/`requiresApproval` match). The turn stays
476
+ * at `WAITING_CLIENT`; call `approveFunction(invocationId)` to run it and
477
+ * resume, or `rejectFunction(invocationId)` to decline. Fires after
478
+ * `function:invoke` (which still fires for every call) and instead of the
479
+ * call running immediately.
480
+ */
481
+ "function:awaiting-approval": ClientFunctionInvocation;
430
482
  "function:result": {
431
483
  invocationId: string;
432
484
  result: unknown;
@@ -487,14 +539,28 @@ export declare interface AgoConfig {
487
539
  warnOnEmptyReply?: boolean;
488
540
  /**
489
541
  * How the agent loop treats client function calls (requires backend support):
490
- * - `"placeholder"` (default): the turn continues immediately on a placeholder
491
- * result; the real result is only visible to the agent on later turns.
492
- * - `"pause"`: the turn stops on client function call(s) with status
542
+ * - `"pause"` (default): the turn stops on client function call(s) with status
493
543
  * `WAITING_CLIENT`; once every result is submitted, the SDK resumes the SAME
494
544
  * turn via `POST /messages/{id}/continue`, so the agent sees the real results.
545
+ * - `"placeholder"` (legacy): the turn continues immediately on a placeholder
546
+ * result; the real result is only visible to the agent on later turns.
495
547
  * Older backends ignore the flag, so `"pause"` degrades to legacy behavior.
496
548
  */
497
549
  clientFunctionsMode?: ClientFunctionsMode;
550
+ /**
551
+ * Gate client function calls behind explicit user approval. Return `true` for
552
+ * an invocation the user must approve/reject before it runs; return `false`
553
+ * (or omit the policy) to let it run immediately as before.
554
+ *
555
+ * Only effective in pause mode (`clientFunctionsMode: "pause"`) — a gated call
556
+ * holds at `WAITING_CLIENT`, the SDK emits `function:awaiting-approval`, and it
557
+ * runs (and the turn resumes) only after `approveFunction(invocationId)`; a
558
+ * `rejectFunction(invocationId)` submits a rejection so the agent sees the
559
+ * decline. In placeholder mode there is no pause to hold, so the policy is a
560
+ * no-op and the call runs normally. A per-function `requiresApproval: true`
561
+ * also gates a call; the policy and the flag OR together.
562
+ */
563
+ approvalPolicy?: (invocation: ClientFunctionInvocation) => boolean;
498
564
  /**
499
565
  * Max serialized size (bytes) of a client function result before the SDK
500
566
  * replaces it with a flagged, truncated preview. Everything a handler
@@ -571,6 +637,11 @@ export declare class AgoNetworkError extends AgoError {
571
637
  export declare interface AgoPageStateOptions {
572
638
  /** Name of the synthesized client function. Defaults to "setPageState". */
573
639
  functionName?: string;
640
+ /**
641
+ * Require explicit user approval before this state change runs. See
642
+ * {@link AgoConfig.approvalPolicy} — pause mode only. Defaults to `false`.
643
+ */
644
+ requiresApproval?: boolean;
574
645
  }
575
646
 
576
647
  /**
@@ -659,6 +730,38 @@ declare interface ApiErrorResponse {
659
730
  };
660
731
  }
661
732
 
733
+ /**
734
+ * Auto-continue the agent after it navigates, so a "go to page B and change X"
735
+ * request completes in one user gesture. Attach once per client; returns a
736
+ * detach function that removes every listener.
737
+ *
738
+ * Two mechanisms, picked by the turn's client-functions mode:
739
+ *
740
+ * - **Pause mode** (`clientFunctionsMode: "pause"`, the default): the backend pauses the turn
741
+ * on the navigation call (`message:waiting-client`) and the SDK resumes it once
742
+ * the result is submitted. This helper only registers a *resume gate* that delays
743
+ * the resume until the destination page's page-state registered (plus a settle
744
+ * delay), so the continued turn ships the new page's `setPageState` and current
745
+ * state. Same turn, no extra prompt, backend budget as the guardrail —
746
+ * `continuationPrompt` and `maxDepth` are unused here.
747
+ *
748
+ * - **Placeholder mode** (legacy, `clientFunctionsMode: "placeholder"`): when the agent calls the navigation
749
+ * function and that turn ends, this waits for the destination page's state to
750
+ * register, then sends a hidden continuation message; the agent applies the
751
+ * state in a second turn (requires backend support for the `hidden` flag).
752
+ *
753
+ * ```ts
754
+ * const detach = attachAutoContinueAfterNavigation(client);
755
+ * // later, on teardown:
756
+ * detach();
757
+ * ```
758
+ *
759
+ * Options can be a plain object, or a getter for live options: the getter is
760
+ * re-read on every event, so changing what it returns never re-subscribes the
761
+ * listeners (this is how the React hook keeps options reactive).
762
+ */
763
+ export declare function attachAutoContinueAfterNavigation(client: AgoClient, options?: AgoAutoContinueOptions | (() => AgoAutoContinueOptions | undefined)): () => void;
764
+
662
765
  /**
663
766
  * Auto-detect AGO configuration from the DOM environment.
664
767
  *
@@ -747,6 +850,11 @@ export declare interface ClientFunctionDefinition {
747
850
  * `Infinity` disables the guard for this function.
748
851
  */
749
852
  maxResultBytes?: number;
853
+ /**
854
+ * Require explicit user approval before this function runs. See
855
+ * {@link AgoConfig.approvalPolicy} — pause mode only. ORs with the policy.
856
+ */
857
+ requiresApproval?: boolean;
750
858
  }
751
859
 
752
860
  /**
@@ -773,6 +881,11 @@ export declare type ClientFunctionRegisterOptions = Omit<ClientFunctionSchema, "
773
881
  * disables the guard for this function.
774
882
  */
775
883
  maxResultBytes?: number;
884
+ /**
885
+ * Require explicit user approval before this function runs. See
886
+ * {@link AgoConfig.approvalPolicy} — pause mode only. ORs with the policy.
887
+ */
888
+ requiresApproval?: boolean;
776
889
  };
777
890
 
778
891
  /**
@@ -813,6 +926,19 @@ export declare interface ContextEntry {
813
926
  description?: string;
814
927
  /** Arbitrary structured data the AI should know about */
815
928
  data?: Record<string, unknown>;
929
+ /**
930
+ * Marks the entry as constant for the whole conversation. The backend then
931
+ * pins it right after the system prompt, where LLM providers cache it across
932
+ * turns, instead of re-processing it next to every new user message.
933
+ *
934
+ * Only set this when the entry's content is byte-identical on every message
935
+ * of a conversation (a schema, a capability list, static instructions). A
936
+ * stable entry that changes between messages invalidates the provider's
937
+ * cache for the entire conversation history, which costs more than leaving
938
+ * the flag off. Default: `false` (re-sent near the newest user message).
939
+ * Backends that don't know the flag ignore it.
940
+ */
941
+ stable?: boolean;
816
942
  }
817
943
 
818
944
  /**
@@ -1111,10 +1237,22 @@ export declare interface FormCollector<V = Record<string, unknown>> {
1111
1237
  store: Store<FormCollectorState<V>>;
1112
1238
  /** Client functions to register: `[update]` or `[update, submit]`. */
1113
1239
  functions: ClientFunctionDefinition[];
1114
- /** Dynamic-context key under which the form state is exposed. */
1240
+ /** Dynamic-context key under which the live form state is exposed. */
1115
1241
  contextKey: string;
1116
- /** Dynamic-context provider — re-read on every message. */
1242
+ /**
1243
+ * Dynamic-context provider for the live form state (phase, values, missing)
1244
+ * — re-read on every message. The schema itself rides in the companion
1245
+ * {@link definitionContextProvider} entry.
1246
+ */
1117
1247
  contextProvider: () => ContextEntry;
1248
+ /** Context key of the stable form definition (`<contextKey>:definition`). */
1249
+ definitionContextKey: string;
1250
+ /**
1251
+ * Provider for the form's definition (description + schema): identical on
1252
+ * every message and marked `stable: true`, so the backend can pin it in the
1253
+ * cacheable part of the prompt. Registered/removed by `install` alongside `contextProvider`.
1254
+ */
1255
+ definitionContextProvider: () => ContextEntry;
1118
1256
  /** Register the functions + dynamic context on a client. Returns an uninstall fn. */
1119
1257
  install: (client: AgoClient) => () => void;
1120
1258
  /**
@@ -1518,6 +1656,8 @@ export declare interface RegisteredFunction {
1518
1656
  handler: ClientFunctionHandler;
1519
1657
  /** Per-function result-size ceiling; falls back to the registry default. */
1520
1658
  maxResultBytes?: number;
1659
+ /** Require explicit user approval before running (pause mode only). */
1660
+ requiresApproval?: boolean;
1521
1661
  }
1522
1662
 
1523
1663
  /**