@useago/sdk 1.4.2 → 1.4.4

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 (41) hide show
  1. package/README.md +4 -1
  2. package/dist/AgoClient-CLmtYTJx.cjs +8 -0
  3. package/dist/{AgoClient-BdtuHX7k.js → AgoClient-Ozz2b1dQ.js} +301 -161
  4. package/dist/angular.cjs +1 -1
  5. package/dist/angular.d.cts +151 -6
  6. package/dist/angular.d.ts +151 -6
  7. package/dist/angular.js +1 -1
  8. package/dist/{createConversationSession-B8zfTL78.cjs → createConversationSession-CUkNp6mZ.cjs} +1 -1
  9. package/dist/{createConversationSession-CWpf4u6I.js → createConversationSession-QIBN0gLx.js} +1 -1
  10. package/dist/{createFormCollector-BB_l0Sia.cjs → createFormCollector-DHT1ObOb.cjs} +1 -1
  11. package/dist/{createFormCollector-B4n0_diV.js → createFormCollector-F3YJfsbg.js} +1 -1
  12. package/dist/createMockClient-BSr-UV8R.cjs +1 -0
  13. package/dist/{createMockClient-d-arlmCq.js → createMockClient-bAZ9KBHC.js} +18 -15
  14. package/dist/devtools.d.cts +149 -4
  15. package/dist/devtools.d.ts +149 -4
  16. package/dist/helpers.d.cts +6 -0
  17. package/dist/helpers.d.ts +6 -0
  18. package/dist/index.cjs +1 -1
  19. package/dist/index.d.cts +181 -5
  20. package/dist/index.d.ts +181 -5
  21. package/dist/index.js +4 -4
  22. package/dist/react.cjs +3 -3
  23. package/dist/react.d.cts +169 -10
  24. package/dist/react.d.ts +169 -10
  25. package/dist/react.js +441 -428
  26. package/dist/testing.cjs +1 -1
  27. package/dist/testing.d.cts +149 -4
  28. package/dist/testing.d.ts +149 -4
  29. package/dist/testing.js +1 -1
  30. package/dist/vue.cjs +1 -1
  31. package/dist/vue.d.cts +162 -5
  32. package/dist/vue.d.ts +162 -5
  33. package/dist/vue.js +22 -21
  34. package/dist/widget.cjs +3 -3
  35. package/dist/widget.d.cts +149 -4
  36. package/dist/widget.d.ts +149 -4
  37. package/dist/widget.js +120 -120
  38. package/llms-full.txt +1910 -0
  39. package/package.json +5 -3
  40. package/dist/AgoClient-CRAnT4qE.cjs +0 -8
  41. package/dist/createMockClient-ucPENDzz.cjs +0 -1
package/dist/index.d.cts CHANGED
@@ -50,12 +50,45 @@ export declare class AgoClient {
50
50
  private config;
51
51
  /** Conversations already warned about an empty reply (one warning each). */
52
52
  private warnedEmptyConversations;
53
+ /** Paused turns awaiting auto-resume, keyed by assistant message id. */
54
+ private pendingResumes;
55
+ /** App-provided gate deciding WHEN a paused turn resumes (see {@link registerResumeGate}). */
56
+ private resumeGate;
53
57
  constructor(config: AgoConfig);
54
58
  /**
55
59
  * Send a message and receive a streaming response
56
60
  */
57
61
  sendMessage(content: string, options?: SendMessageOptions): Promise<AgoMessage>;
58
62
  private processSSEResponse;
63
+ private resolveClientFunctionsMode;
64
+ /**
65
+ * Register a gate deciding WHEN a paused turn resumes. The SDK still decides
66
+ * *whether* (it resumes once every waiting result is submitted); the gate only
67
+ * delays the continue call — e.g. `useAgoAutoContinueAfterNavigation` waits for
68
+ * the destination page to register its page state. One gate at a time (last
69
+ * registration wins). Returns an unregister function.
70
+ */
71
+ registerResumeGate(gate: ResumeGate): () => void;
72
+ /**
73
+ * Resume a turn paused on client function results (`WAITING_CLIENT`).
74
+ *
75
+ * Sends the CURRENT page's registered functions and context — the page may
76
+ * have changed since the pause (that's the point of pausing on a navigation) —
77
+ * and streams the continuation through the same event pipeline as
78
+ * `sendMessage`, so `message:chunk` / `message:complete` (or another
79
+ * `message:waiting-client` for chained pauses) fire as usual.
80
+ *
81
+ * The SDK calls this automatically after submitting the waiting results; call
82
+ * it manually only for custom flows (e.g. after restoring a reloaded page via
83
+ * {@link resumePendingClientFunctions}).
84
+ */
85
+ continueMessage(messageId: string): Promise<AgoMessage>;
86
+ /**
87
+ * Record one of the two auto-resume preconditions for a paused turn and fire
88
+ * the resume when both are in (see {@link PendingResume}).
89
+ */
90
+ private markResumeSignal;
91
+ private runAutoResume;
59
92
  /**
60
93
  * Detect a reply that completed as DONE with no content and no activity —
61
94
  * today's backend answers an unknown `agent` slug with an empty 200, which
@@ -88,9 +121,25 @@ export declare class AgoClient {
88
121
  */
89
122
  getMessages(conversationId: string): Promise<AgoMessage[]>;
90
123
  /**
91
- * Submit form data for a tool call
124
+ * Resume a turn left paused on client function results by a page reload.
125
+ *
126
+ * A paused turn (pause mode) survives a full reload: the backend keeps the
127
+ * assistant message in `WAITING_CLIENT` with its waiting tool calls. After
128
+ * restoring the conversation (`getConversation`) and re-registering the page's
129
+ * functions, call this: it re-executes each waiting client function through the
130
+ * registry, submits the results, and continues the turn.
131
+ *
132
+ * Opt-in on purpose — re-running functions on reload can be surprising (e.g. a
133
+ * 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.
136
+ */
137
+ resumePendingClientFunctions(conversation: Conversation): Promise<AgoMessage | null>;
138
+ /**
139
+ * Submit form data for a tool call. The response's `resume` field (pause mode
140
+ * only) tells whether the paused turn is ready to be resumed.
92
141
  */
93
- submitToolCallForm(toolCallId: string, formData: Record<string, unknown>): Promise<void>;
142
+ submitToolCallForm(toolCallId: string, formData: Record<string, unknown>): Promise<SubmitToolCallResult>;
94
143
  /**
95
144
  * Confirm a tool call
96
145
  */
@@ -137,7 +186,7 @@ export declare class AgoClient {
137
186
  * ```
138
187
  */
139
188
  registerFunction(definition: ClientFunctionDefinition): void;
140
- registerFunction(name: string, handler: ClientFunctionHandler, schema: Omit<ClientFunctionSchema, "name">): void;
189
+ registerFunction(name: string, handler: ClientFunctionHandler, schema: ClientFunctionRegisterOptions): void;
141
190
  /**
142
191
  * Short alias for `registerFunction`. Also accepts an array of definitions.
143
192
  *
@@ -163,6 +212,12 @@ export declare class AgoClient {
163
212
  * the agent know *where* it is after it navigates (e.g. so auto-continuation
164
213
  * can apply page state on the destination), not just how to navigate away.
165
214
  *
215
+ * Routes may contain `:param` placeholders (`/users/:id`). Each distinct
216
+ * placeholder becomes a top-level string argument of `navigateToPage`
217
+ * (`{ page: "userDetail", id: "42" }`), so one route covers every detail
218
+ * page of an entity. Flat arguments only: nested object parameters are not
219
+ * reliably rendered to the model, so placeholders must not be named `page`.
220
+ *
166
221
  * @param navigate - A callback that performs the navigation (e.g. react-router's navigate)
167
222
  * @param routes - Map of route names to paths, with descriptions for the LLM
168
223
  */
@@ -330,6 +385,19 @@ export declare interface AgoClientEvents {
330
385
  */
331
386
  "message:answer-complete": AgoMessage;
332
387
  "message:complete": AgoMessage;
388
+ /**
389
+ * The turn paused on client function call(s) (pause mode): the stream closed
390
+ * with status `WAITING_CLIENT` instead of `DONE`. `message:complete` does NOT
391
+ * fire for this stream — it fires when the resumed turn concludes, so one
392
+ * logical turn still emits exactly one `message:complete`. The SDK submits the
393
+ * function results and resumes automatically; listen to this to know the agent
394
+ * is waiting on the page (e.g. to keep a "working…" indicator up).
395
+ */
396
+ "message:waiting-client": {
397
+ conversationId: string;
398
+ messageId: string;
399
+ waitingToolCallIds: string[];
400
+ };
333
401
  /**
334
402
  * A reply finished as `DONE` with empty content and no tool calls, client
335
403
  * functions, or follow-up replies — usually an unknown `agent` slug (the
@@ -417,6 +485,24 @@ export declare interface AgoConfig {
417
485
  * event fires regardless of this setting.
418
486
  */
419
487
  warnOnEmptyReply?: boolean;
488
+ /**
489
+ * 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
493
+ * `WAITING_CLIENT`; once every result is submitted, the SDK resumes the SAME
494
+ * turn via `POST /messages/{id}/continue`, so the agent sees the real results.
495
+ * Older backends ignore the flag, so `"pause"` degrades to legacy behavior.
496
+ */
497
+ clientFunctionsMode?: ClientFunctionsMode;
498
+ /**
499
+ * Max serialized size (bytes) of a client function result before the SDK
500
+ * replaces it with a flagged, truncated preview. Everything a handler
501
+ * returns is sent into the LLM context, so this caps runaway payloads
502
+ * (raw API responses, full tables). Default `50000`. Override per function
503
+ * with `maxResultBytes` on its definition; `Infinity` disables the guard.
504
+ */
505
+ maxFunctionResultBytes?: number;
420
506
  }
421
507
 
422
508
  /**
@@ -655,6 +741,12 @@ export declare interface ClientFunctionDefinition {
655
741
  description: string;
656
742
  parameters: ClientFunctionSchema["parameters"];
657
743
  handler: ClientFunctionHandler;
744
+ /**
745
+ * Max serialized result size in bytes before the SDK truncates it to a
746
+ * flagged preview (default: `AgoConfig.maxFunctionResultBytes`, 50 000).
747
+ * `Infinity` disables the guard for this function.
748
+ */
749
+ maxResultBytes?: number;
658
750
  }
659
751
 
660
752
  /**
@@ -669,6 +761,20 @@ export declare interface ClientFunctionInvocation {
669
761
  conversationId: string;
670
762
  }
671
763
 
764
+ /**
765
+ * Schema-plus-settings object accepted when registering a function: the schema
766
+ * (minus `name`) and SDK-side options that are NOT sent to the backend.
767
+ */
768
+ export declare type ClientFunctionRegisterOptions = Omit<ClientFunctionSchema, "name"> & {
769
+ /**
770
+ * Max serialized result size in bytes before the SDK truncates it to a
771
+ * flagged preview. Overrides the client-level default
772
+ * (`AgoConfig.maxFunctionResultBytes`, 50 000 by default). `Infinity`
773
+ * disables the guard for this function.
774
+ */
775
+ maxResultBytes?: number;
776
+ };
777
+
672
778
  /**
673
779
  * Schema for a client-side function that AGO can call
674
780
  */
@@ -694,6 +800,9 @@ export declare interface ClientFunctionSchema {
694
800
  };
695
801
  }
696
802
 
803
+ /** See {@link AgoConfig.clientFunctionsMode}. */
804
+ export declare type ClientFunctionsMode = "placeholder" | "pause";
805
+
697
806
  /**
698
807
  * A single piece of context the client wants the LLM to know about.
699
808
  */
@@ -1163,12 +1272,16 @@ export declare interface FunctionDefinition {
1163
1272
  */
1164
1273
  export declare class FunctionRegistry {
1165
1274
  private functions;
1275
+ private defaultMaxResultBytes;
1276
+ constructor(options?: FunctionRegistryOptions);
1277
+ /** Update the client-level result-size ceiling at runtime. */
1278
+ setDefaultMaxResultBytes(bytes: number): void;
1166
1279
  /**
1167
1280
  * Register a function that AGO can call.
1168
1281
  * Accepts either a single definition object or (name, handler, schema) args.
1169
1282
  */
1170
1283
  register(definition: ClientFunctionDefinition): void;
1171
- register(name: string, handler: ClientFunctionHandler, schema: Omit<ClientFunctionSchema, "name">): void;
1284
+ register(name: string, handler: ClientFunctionHandler, schema: ClientFunctionRegisterOptions): void;
1172
1285
  /**
1173
1286
  * Unregister a function
1174
1287
  */
@@ -1189,6 +1302,14 @@ export declare class FunctionRegistry {
1189
1302
  * Execute a registered function
1190
1303
  */
1191
1304
  execute(name: string, args: Record<string, unknown>): Promise<unknown>;
1305
+ /**
1306
+ * Cap the size of a function result before it goes back to the backend.
1307
+ * Everything a handler returns lands in the LLM context, so an unbounded
1308
+ * payload (a raw API response, a full table) inflates cost and can overflow
1309
+ * the model. Oversized results are replaced with a flagged preview so the
1310
+ * agent knows to request less instead of receiving hundreds of KB verbatim.
1311
+ */
1312
+ private guardResultSize;
1192
1313
  /**
1193
1314
  * Clear all registered functions
1194
1315
  */
@@ -1199,6 +1320,11 @@ export declare class FunctionRegistry {
1199
1320
  get size(): number;
1200
1321
  }
1201
1322
 
1323
+ declare interface FunctionRegistryOptions {
1324
+ /** Client-level default for the result-size ceiling, in bytes. */
1325
+ maxResultBytes?: number;
1326
+ }
1327
+
1202
1328
  /**
1203
1329
  * Client-side function types
1204
1330
  */
@@ -1276,7 +1402,13 @@ declare class Logger {
1276
1402
 
1277
1403
  export declare const logger: Logger;
1278
1404
 
1279
- export declare type MessageStatus = "IN_PROGRESS" | "DONE" | "ERROR" | "TODO" | "CANCELED";
1405
+ export declare type MessageStatus = "IN_PROGRESS" | "DONE" | "ERROR" | "TODO" | "CANCELED"
1406
+ /**
1407
+ * The turn paused on client function call(s) (pause mode): the agent waits for
1408
+ * every waiting call to be submitted, then the turn resumes via
1409
+ * `continueMessage`. Not a final state.
1410
+ */
1411
+ | "WAITING_CLIENT";
1280
1412
 
1281
1413
  export declare interface MockAgoClient extends AgoClient {
1282
1414
  /**
@@ -1384,8 +1516,21 @@ export declare interface PersistOptions {
1384
1516
  export declare interface RegisteredFunction {
1385
1517
  schema: ClientFunctionSchema;
1386
1518
  handler: ClientFunctionHandler;
1519
+ /** Per-function result-size ceiling; falls back to the registry default. */
1520
+ maxResultBytes?: number;
1387
1521
  }
1388
1522
 
1523
+ /**
1524
+ * Hook run before a paused turn is resumed, so the app controls WHEN the
1525
+ * continuation fires (e.g. wait for the destination page to mount after a
1526
+ * navigation). It must resolve — throwing or hanging blocks the resume; on
1527
+ * timeout-style situations resolve anyway and let the agent conclude.
1528
+ */
1529
+ export declare type ResumeGate = (info: {
1530
+ conversationId: string;
1531
+ messageId: string;
1532
+ }) => Promise<void> | void;
1533
+
1389
1534
  /**
1390
1535
  * Allow only URL schemes that are safe to put in an `<img src>` / `<a href>`.
1391
1536
  * Presigned attachment URLs are `https:` and optimistic previews are `blob:`;
@@ -1417,6 +1562,8 @@ export declare interface SendMessageOptions {
1417
1562
  * Requires backend support for the `hidden` flag; older backends ignore it.
1418
1563
  */
1419
1564
  hidden?: boolean;
1565
+ /** Per-message override of {@link AgoConfig.clientFunctionsMode}. */
1566
+ clientFunctionsMode?: ClientFunctionsMode;
1420
1567
  }
1421
1568
 
1422
1569
  /**
@@ -1491,6 +1638,8 @@ export declare interface SSEChunkData {
1491
1638
  follow_up_replies?: string[];
1492
1639
  satisfaction_feedback?: unknown;
1493
1640
  ask_to_talk_to_human?: boolean;
1641
+ /** Tool call ids still awaiting a client result, sent with the final `WAITING_CLIENT` event. */
1642
+ waiting_tool_call_ids?: string[];
1494
1643
  }
1495
1644
 
1496
1645
  /**
@@ -1505,6 +1654,7 @@ export declare class SSEHandler {
1505
1654
  private followUpReplies;
1506
1655
  private isFirstChunk;
1507
1656
  private answerCompleteEmitted;
1657
+ private waitingClientEmitted;
1508
1658
  private firedClientFunctions;
1509
1659
  constructor(callbacks: SSEHandlerCallbacks);
1510
1660
  /**
@@ -1547,6 +1697,17 @@ declare interface SSEHandlerCallbacks {
1547
1697
  * with the message as it stands at that moment (no `followUpReplies` yet).
1548
1698
  */
1549
1699
  onAnswerComplete?: (message: AgoMessage) => void;
1700
+ /**
1701
+ * The turn paused on client function call(s) (pause mode): the backend closed
1702
+ * the stream with `status: "WAITING_CLIENT"` and the tool call ids awaiting a
1703
+ * result. {@link onComplete} does NOT fire for this stream — the turn is not
1704
+ * over; it resumes in a separate request once every result is submitted.
1705
+ */
1706
+ onWaitingClient?: (data: {
1707
+ conversationId: string;
1708
+ messageId: string;
1709
+ waitingToolCallIds: string[];
1710
+ }) => void;
1550
1711
  onComplete?: (message: AgoMessage) => void;
1551
1712
  onError?: (error: Error) => void;
1552
1713
  }
@@ -1602,6 +1763,21 @@ export declare type SubmitConfig<V = Record<string, unknown>> = string | {
1602
1763
  */
1603
1764
  export declare const submitForm: ClientFunctionDefinition;
1604
1765
 
1766
+ /**
1767
+ * Response of `POST /tool-calls/{id}/submit`. `resume` is only present when the
1768
+ * tool call belongs to a turn paused on client functions (pause mode): `ready`
1769
+ * flips to `true` once ALL waiting calls of that message are submitted, meaning
1770
+ * the turn can be resumed via `continueMessage(resume.message_id)`.
1771
+ */
1772
+ export declare interface SubmitToolCallResult {
1773
+ status: string;
1774
+ result?: unknown;
1775
+ resume?: {
1776
+ message_id: string;
1777
+ ready: boolean;
1778
+ };
1779
+ }
1780
+
1605
1781
  /**
1606
1782
  * Tool call data from SSE stream
1607
1783
  */
package/dist/index.d.ts CHANGED
@@ -50,12 +50,45 @@ export declare class AgoClient {
50
50
  private config;
51
51
  /** Conversations already warned about an empty reply (one warning each). */
52
52
  private warnedEmptyConversations;
53
+ /** Paused turns awaiting auto-resume, keyed by assistant message id. */
54
+ private pendingResumes;
55
+ /** App-provided gate deciding WHEN a paused turn resumes (see {@link registerResumeGate}). */
56
+ private resumeGate;
53
57
  constructor(config: AgoConfig);
54
58
  /**
55
59
  * Send a message and receive a streaming response
56
60
  */
57
61
  sendMessage(content: string, options?: SendMessageOptions): Promise<AgoMessage>;
58
62
  private processSSEResponse;
63
+ private resolveClientFunctionsMode;
64
+ /**
65
+ * Register a gate deciding WHEN a paused turn resumes. The SDK still decides
66
+ * *whether* (it resumes once every waiting result is submitted); the gate only
67
+ * delays the continue call — e.g. `useAgoAutoContinueAfterNavigation` waits for
68
+ * the destination page to register its page state. One gate at a time (last
69
+ * registration wins). Returns an unregister function.
70
+ */
71
+ registerResumeGate(gate: ResumeGate): () => void;
72
+ /**
73
+ * Resume a turn paused on client function results (`WAITING_CLIENT`).
74
+ *
75
+ * Sends the CURRENT page's registered functions and context — the page may
76
+ * have changed since the pause (that's the point of pausing on a navigation) —
77
+ * and streams the continuation through the same event pipeline as
78
+ * `sendMessage`, so `message:chunk` / `message:complete` (or another
79
+ * `message:waiting-client` for chained pauses) fire as usual.
80
+ *
81
+ * The SDK calls this automatically after submitting the waiting results; call
82
+ * it manually only for custom flows (e.g. after restoring a reloaded page via
83
+ * {@link resumePendingClientFunctions}).
84
+ */
85
+ continueMessage(messageId: string): Promise<AgoMessage>;
86
+ /**
87
+ * Record one of the two auto-resume preconditions for a paused turn and fire
88
+ * the resume when both are in (see {@link PendingResume}).
89
+ */
90
+ private markResumeSignal;
91
+ private runAutoResume;
59
92
  /**
60
93
  * Detect a reply that completed as DONE with no content and no activity —
61
94
  * today's backend answers an unknown `agent` slug with an empty 200, which
@@ -88,9 +121,25 @@ export declare class AgoClient {
88
121
  */
89
122
  getMessages(conversationId: string): Promise<AgoMessage[]>;
90
123
  /**
91
- * Submit form data for a tool call
124
+ * Resume a turn left paused on client function results by a page reload.
125
+ *
126
+ * A paused turn (pause mode) survives a full reload: the backend keeps the
127
+ * assistant message in `WAITING_CLIENT` with its waiting tool calls. After
128
+ * restoring the conversation (`getConversation`) and re-registering the page's
129
+ * functions, call this: it re-executes each waiting client function through the
130
+ * registry, submits the results, and continues the turn.
131
+ *
132
+ * Opt-in on purpose — re-running functions on reload can be surprising (e.g. a
133
+ * 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.
136
+ */
137
+ resumePendingClientFunctions(conversation: Conversation): Promise<AgoMessage | null>;
138
+ /**
139
+ * Submit form data for a tool call. The response's `resume` field (pause mode
140
+ * only) tells whether the paused turn is ready to be resumed.
92
141
  */
93
- submitToolCallForm(toolCallId: string, formData: Record<string, unknown>): Promise<void>;
142
+ submitToolCallForm(toolCallId: string, formData: Record<string, unknown>): Promise<SubmitToolCallResult>;
94
143
  /**
95
144
  * Confirm a tool call
96
145
  */
@@ -137,7 +186,7 @@ export declare class AgoClient {
137
186
  * ```
138
187
  */
139
188
  registerFunction(definition: ClientFunctionDefinition): void;
140
- registerFunction(name: string, handler: ClientFunctionHandler, schema: Omit<ClientFunctionSchema, "name">): void;
189
+ registerFunction(name: string, handler: ClientFunctionHandler, schema: ClientFunctionRegisterOptions): void;
141
190
  /**
142
191
  * Short alias for `registerFunction`. Also accepts an array of definitions.
143
192
  *
@@ -163,6 +212,12 @@ export declare class AgoClient {
163
212
  * the agent know *where* it is after it navigates (e.g. so auto-continuation
164
213
  * can apply page state on the destination), not just how to navigate away.
165
214
  *
215
+ * Routes may contain `:param` placeholders (`/users/:id`). Each distinct
216
+ * placeholder becomes a top-level string argument of `navigateToPage`
217
+ * (`{ page: "userDetail", id: "42" }`), so one route covers every detail
218
+ * page of an entity. Flat arguments only: nested object parameters are not
219
+ * reliably rendered to the model, so placeholders must not be named `page`.
220
+ *
166
221
  * @param navigate - A callback that performs the navigation (e.g. react-router's navigate)
167
222
  * @param routes - Map of route names to paths, with descriptions for the LLM
168
223
  */
@@ -330,6 +385,19 @@ export declare interface AgoClientEvents {
330
385
  */
331
386
  "message:answer-complete": AgoMessage;
332
387
  "message:complete": AgoMessage;
388
+ /**
389
+ * The turn paused on client function call(s) (pause mode): the stream closed
390
+ * with status `WAITING_CLIENT` instead of `DONE`. `message:complete` does NOT
391
+ * fire for this stream — it fires when the resumed turn concludes, so one
392
+ * logical turn still emits exactly one `message:complete`. The SDK submits the
393
+ * function results and resumes automatically; listen to this to know the agent
394
+ * is waiting on the page (e.g. to keep a "working…" indicator up).
395
+ */
396
+ "message:waiting-client": {
397
+ conversationId: string;
398
+ messageId: string;
399
+ waitingToolCallIds: string[];
400
+ };
333
401
  /**
334
402
  * A reply finished as `DONE` with empty content and no tool calls, client
335
403
  * functions, or follow-up replies — usually an unknown `agent` slug (the
@@ -417,6 +485,24 @@ export declare interface AgoConfig {
417
485
  * event fires regardless of this setting.
418
486
  */
419
487
  warnOnEmptyReply?: boolean;
488
+ /**
489
+ * 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
493
+ * `WAITING_CLIENT`; once every result is submitted, the SDK resumes the SAME
494
+ * turn via `POST /messages/{id}/continue`, so the agent sees the real results.
495
+ * Older backends ignore the flag, so `"pause"` degrades to legacy behavior.
496
+ */
497
+ clientFunctionsMode?: ClientFunctionsMode;
498
+ /**
499
+ * Max serialized size (bytes) of a client function result before the SDK
500
+ * replaces it with a flagged, truncated preview. Everything a handler
501
+ * returns is sent into the LLM context, so this caps runaway payloads
502
+ * (raw API responses, full tables). Default `50000`. Override per function
503
+ * with `maxResultBytes` on its definition; `Infinity` disables the guard.
504
+ */
505
+ maxFunctionResultBytes?: number;
420
506
  }
421
507
 
422
508
  /**
@@ -655,6 +741,12 @@ export declare interface ClientFunctionDefinition {
655
741
  description: string;
656
742
  parameters: ClientFunctionSchema["parameters"];
657
743
  handler: ClientFunctionHandler;
744
+ /**
745
+ * Max serialized result size in bytes before the SDK truncates it to a
746
+ * flagged preview (default: `AgoConfig.maxFunctionResultBytes`, 50 000).
747
+ * `Infinity` disables the guard for this function.
748
+ */
749
+ maxResultBytes?: number;
658
750
  }
659
751
 
660
752
  /**
@@ -669,6 +761,20 @@ export declare interface ClientFunctionInvocation {
669
761
  conversationId: string;
670
762
  }
671
763
 
764
+ /**
765
+ * Schema-plus-settings object accepted when registering a function: the schema
766
+ * (minus `name`) and SDK-side options that are NOT sent to the backend.
767
+ */
768
+ export declare type ClientFunctionRegisterOptions = Omit<ClientFunctionSchema, "name"> & {
769
+ /**
770
+ * Max serialized result size in bytes before the SDK truncates it to a
771
+ * flagged preview. Overrides the client-level default
772
+ * (`AgoConfig.maxFunctionResultBytes`, 50 000 by default). `Infinity`
773
+ * disables the guard for this function.
774
+ */
775
+ maxResultBytes?: number;
776
+ };
777
+
672
778
  /**
673
779
  * Schema for a client-side function that AGO can call
674
780
  */
@@ -694,6 +800,9 @@ export declare interface ClientFunctionSchema {
694
800
  };
695
801
  }
696
802
 
803
+ /** See {@link AgoConfig.clientFunctionsMode}. */
804
+ export declare type ClientFunctionsMode = "placeholder" | "pause";
805
+
697
806
  /**
698
807
  * A single piece of context the client wants the LLM to know about.
699
808
  */
@@ -1163,12 +1272,16 @@ export declare interface FunctionDefinition {
1163
1272
  */
1164
1273
  export declare class FunctionRegistry {
1165
1274
  private functions;
1275
+ private defaultMaxResultBytes;
1276
+ constructor(options?: FunctionRegistryOptions);
1277
+ /** Update the client-level result-size ceiling at runtime. */
1278
+ setDefaultMaxResultBytes(bytes: number): void;
1166
1279
  /**
1167
1280
  * Register a function that AGO can call.
1168
1281
  * Accepts either a single definition object or (name, handler, schema) args.
1169
1282
  */
1170
1283
  register(definition: ClientFunctionDefinition): void;
1171
- register(name: string, handler: ClientFunctionHandler, schema: Omit<ClientFunctionSchema, "name">): void;
1284
+ register(name: string, handler: ClientFunctionHandler, schema: ClientFunctionRegisterOptions): void;
1172
1285
  /**
1173
1286
  * Unregister a function
1174
1287
  */
@@ -1189,6 +1302,14 @@ export declare class FunctionRegistry {
1189
1302
  * Execute a registered function
1190
1303
  */
1191
1304
  execute(name: string, args: Record<string, unknown>): Promise<unknown>;
1305
+ /**
1306
+ * Cap the size of a function result before it goes back to the backend.
1307
+ * Everything a handler returns lands in the LLM context, so an unbounded
1308
+ * payload (a raw API response, a full table) inflates cost and can overflow
1309
+ * the model. Oversized results are replaced with a flagged preview so the
1310
+ * agent knows to request less instead of receiving hundreds of KB verbatim.
1311
+ */
1312
+ private guardResultSize;
1192
1313
  /**
1193
1314
  * Clear all registered functions
1194
1315
  */
@@ -1199,6 +1320,11 @@ export declare class FunctionRegistry {
1199
1320
  get size(): number;
1200
1321
  }
1201
1322
 
1323
+ declare interface FunctionRegistryOptions {
1324
+ /** Client-level default for the result-size ceiling, in bytes. */
1325
+ maxResultBytes?: number;
1326
+ }
1327
+
1202
1328
  /**
1203
1329
  * Client-side function types
1204
1330
  */
@@ -1276,7 +1402,13 @@ declare class Logger {
1276
1402
 
1277
1403
  export declare const logger: Logger;
1278
1404
 
1279
- export declare type MessageStatus = "IN_PROGRESS" | "DONE" | "ERROR" | "TODO" | "CANCELED";
1405
+ export declare type MessageStatus = "IN_PROGRESS" | "DONE" | "ERROR" | "TODO" | "CANCELED"
1406
+ /**
1407
+ * The turn paused on client function call(s) (pause mode): the agent waits for
1408
+ * every waiting call to be submitted, then the turn resumes via
1409
+ * `continueMessage`. Not a final state.
1410
+ */
1411
+ | "WAITING_CLIENT";
1280
1412
 
1281
1413
  export declare interface MockAgoClient extends AgoClient {
1282
1414
  /**
@@ -1384,8 +1516,21 @@ export declare interface PersistOptions {
1384
1516
  export declare interface RegisteredFunction {
1385
1517
  schema: ClientFunctionSchema;
1386
1518
  handler: ClientFunctionHandler;
1519
+ /** Per-function result-size ceiling; falls back to the registry default. */
1520
+ maxResultBytes?: number;
1387
1521
  }
1388
1522
 
1523
+ /**
1524
+ * Hook run before a paused turn is resumed, so the app controls WHEN the
1525
+ * continuation fires (e.g. wait for the destination page to mount after a
1526
+ * navigation). It must resolve — throwing or hanging blocks the resume; on
1527
+ * timeout-style situations resolve anyway and let the agent conclude.
1528
+ */
1529
+ export declare type ResumeGate = (info: {
1530
+ conversationId: string;
1531
+ messageId: string;
1532
+ }) => Promise<void> | void;
1533
+
1389
1534
  /**
1390
1535
  * Allow only URL schemes that are safe to put in an `<img src>` / `<a href>`.
1391
1536
  * Presigned attachment URLs are `https:` and optimistic previews are `blob:`;
@@ -1417,6 +1562,8 @@ export declare interface SendMessageOptions {
1417
1562
  * Requires backend support for the `hidden` flag; older backends ignore it.
1418
1563
  */
1419
1564
  hidden?: boolean;
1565
+ /** Per-message override of {@link AgoConfig.clientFunctionsMode}. */
1566
+ clientFunctionsMode?: ClientFunctionsMode;
1420
1567
  }
1421
1568
 
1422
1569
  /**
@@ -1491,6 +1638,8 @@ export declare interface SSEChunkData {
1491
1638
  follow_up_replies?: string[];
1492
1639
  satisfaction_feedback?: unknown;
1493
1640
  ask_to_talk_to_human?: boolean;
1641
+ /** Tool call ids still awaiting a client result, sent with the final `WAITING_CLIENT` event. */
1642
+ waiting_tool_call_ids?: string[];
1494
1643
  }
1495
1644
 
1496
1645
  /**
@@ -1505,6 +1654,7 @@ export declare class SSEHandler {
1505
1654
  private followUpReplies;
1506
1655
  private isFirstChunk;
1507
1656
  private answerCompleteEmitted;
1657
+ private waitingClientEmitted;
1508
1658
  private firedClientFunctions;
1509
1659
  constructor(callbacks: SSEHandlerCallbacks);
1510
1660
  /**
@@ -1547,6 +1697,17 @@ declare interface SSEHandlerCallbacks {
1547
1697
  * with the message as it stands at that moment (no `followUpReplies` yet).
1548
1698
  */
1549
1699
  onAnswerComplete?: (message: AgoMessage) => void;
1700
+ /**
1701
+ * The turn paused on client function call(s) (pause mode): the backend closed
1702
+ * the stream with `status: "WAITING_CLIENT"` and the tool call ids awaiting a
1703
+ * result. {@link onComplete} does NOT fire for this stream — the turn is not
1704
+ * over; it resumes in a separate request once every result is submitted.
1705
+ */
1706
+ onWaitingClient?: (data: {
1707
+ conversationId: string;
1708
+ messageId: string;
1709
+ waitingToolCallIds: string[];
1710
+ }) => void;
1550
1711
  onComplete?: (message: AgoMessage) => void;
1551
1712
  onError?: (error: Error) => void;
1552
1713
  }
@@ -1602,6 +1763,21 @@ export declare type SubmitConfig<V = Record<string, unknown>> = string | {
1602
1763
  */
1603
1764
  export declare const submitForm: ClientFunctionDefinition;
1604
1765
 
1766
+ /**
1767
+ * Response of `POST /tool-calls/{id}/submit`. `resume` is only present when the
1768
+ * tool call belongs to a turn paused on client functions (pause mode): `ready`
1769
+ * flips to `true` once ALL waiting calls of that message are submitted, meaning
1770
+ * the turn can be resumed via `continueMessage(resume.message_id)`.
1771
+ */
1772
+ export declare interface SubmitToolCallResult {
1773
+ status: string;
1774
+ result?: unknown;
1775
+ resume?: {
1776
+ message_id: string;
1777
+ ready: boolean;
1778
+ };
1779
+ }
1780
+
1605
1781
  /**
1606
1782
  * Tool call data from SSE stream
1607
1783
  */
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { a as h, c as A, d as y, f as C, i as E, l as S, m as b, o as v, p as F, r as M, s as I, t as k, u as T } from "./functions-CApuQZ2b.js";
2
- import { _ as G, a as O, c as _, d as q, f as x, g as L, h as N, l as D, m as d, n as H, o as J, p as R, r as j, s as z, t as c, u as B } from "./AgoClient-BdtuHX7k.js";
3
- import { i as $, n as K, r as Q, t as V } from "./createFormCollector-B4n0_diV.js";
4
- import { t as X } from "./createConversationSession-CWpf4u6I.js";
5
- import { t as Z } from "./createMockClient-d-arlmCq.js";
2
+ import { _ as G, a as O, c as _, d as q, f as x, g as L, h as N, l as D, m as d, n as H, o as J, p as R, r as j, s as z, t as c, u as B } from "./AgoClient-Ozz2b1dQ.js";
3
+ import { i as $, n as K, r as Q, t as V } from "./createFormCollector-F3YJfsbg.js";
4
+ import { t as X } from "./createConversationSession-QIBN0gLx.js";
5
+ import { t as Z } from "./createMockClient-bAZ9KBHC.js";
6
6
  import "./testing.js";
7
7
  function oe(e) {
8
8
  return e;