@useago/sdk 1.5.5 → 1.7.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 (42) hide show
  1. package/CHANGELOG.md +230 -0
  2. package/README.md +59 -0
  3. package/dist/AgoClient-BHegN73y.cjs +9 -0
  4. package/dist/{AgoClient-BI5esqbd.js → AgoClient-PWPaekcg.js} +657 -387
  5. package/dist/angular.cjs +1 -1
  6. package/dist/angular.d.cts +230 -5
  7. package/dist/angular.d.ts +230 -5
  8. package/dist/angular.js +10 -1
  9. package/dist/{createConversationSession-0zVkMdYj.cjs → createConversationSession-BbUUukV0.cjs} +1 -1
  10. package/dist/{createConversationSession-BlYTpxwz.js → createConversationSession-BkruoOVm.js} +1 -1
  11. package/dist/{createFormCollector-DiCe_8ik.cjs → createFormCollector-C1ixsjV0.cjs} +1 -1
  12. package/dist/{createFormCollector-Bgs94NyR.js → createFormCollector-CvVFNkp6.js} +1 -1
  13. package/dist/{createMockClient-DcuNlufr.js → createMockClient-BDLW6tVc.js} +5 -2
  14. package/dist/createMockClient-BSNuN3ys.cjs +1 -0
  15. package/dist/devtools.d.cts +220 -5
  16. package/dist/devtools.d.ts +220 -5
  17. package/dist/index.cjs +1 -1
  18. package/dist/index.d.cts +238 -6
  19. package/dist/index.d.ts +238 -6
  20. package/dist/index.js +111 -109
  21. package/dist/react.cjs +40 -3
  22. package/dist/react.d.cts +419 -7
  23. package/dist/react.d.ts +419 -7
  24. package/dist/react.js +1195 -743
  25. package/dist/sheetController-CBUVOroo.js +205 -0
  26. package/dist/sheetController-DY-sC13T.cjs +1 -0
  27. package/dist/testing.cjs +1 -1
  28. package/dist/testing.d.cts +220 -5
  29. package/dist/testing.d.ts +220 -5
  30. package/dist/testing.js +1 -1
  31. package/dist/vue.cjs +1 -1
  32. package/dist/vue.d.cts +235 -5
  33. package/dist/vue.d.ts +235 -5
  34. package/dist/vue.js +121 -100
  35. package/dist/widget.cjs +4 -4
  36. package/dist/widget.d.cts +328 -5
  37. package/dist/widget.d.ts +328 -5
  38. package/dist/widget.js +721 -629
  39. package/llms-full.txt +202 -14
  40. package/package.json +1 -1
  41. package/dist/AgoClient-CQh8YovA.cjs +0 -8
  42. package/dist/createMockClient-Dw-cyISN.cjs +0 -1
package/dist/react.d.cts CHANGED
@@ -1,4 +1,6 @@
1
1
  import { default as default_2 } from 'react';
2
+ import { ForwardRefExoticComponent } from 'react';
3
+ import { RefAttributes } from 'react';
2
4
 
3
5
  export declare interface ActivityEntry {
4
6
  ts: number;
@@ -112,6 +114,10 @@ declare class AgoClient {
112
114
  private config;
113
115
  /** Conversations already warned about an empty reply (one warning each). */
114
116
  private warnedEmptyConversations;
117
+ /** Whether the placeholder-mode page-data warning has already been logged. */
118
+ private warnedPageDataPlaceholder;
119
+ /** `readPageData` companions this SDK registered, so cleanup only removes its own. */
120
+ private pageDataCompanions;
115
121
  /** Paused turns awaiting auto-resume, keyed by assistant message id. */
116
122
  private pendingResumes;
117
123
  /**
@@ -122,6 +128,20 @@ declare class AgoClient {
122
128
  private pendingApprovals;
123
129
  /** App-provided gate deciding WHEN a paused turn resumes (see {@link registerResumeGate}). */
124
130
  private resumeGate;
131
+ /** The turn currently streaming, or `null` when the client is idle. */
132
+ private activeTurn;
133
+ /**
134
+ * A turn that closed as `WAITING_CLIENT` and has not resumed yet. There is no
135
+ * open stream in that window, but the turn is still live for the user, so it
136
+ * stays stoppable (see {@link stop}).
137
+ */
138
+ private pausedTurn;
139
+ /**
140
+ * Turns stopped while they were paused on client functions. A resume may
141
+ * already be queued (or waiting on the resume gate) at that point; this drops
142
+ * it, so a stopped turn is never restarted.
143
+ */
144
+ private stoppedTurnIds;
125
145
  /**
126
146
  * Proactive-mode controller, set when the client was created with
127
147
  * `proactive` options or when `createAgoProactive(client, opts)` was called.
@@ -133,7 +153,53 @@ declare class AgoClient {
133
153
  * Send a message and receive a streaming response
134
154
  */
135
155
  sendMessage(content: string, options?: SendMessageOptions): Promise<AgoMessage>;
156
+ /**
157
+ * Fire the streaming request, returning `null` when the user stopped before
158
+ * the response came back. Any other failure ends the turn and propagates, so
159
+ * a real error still reaches the caller.
160
+ */
161
+ private sendRequest;
136
162
  private processSSEResponse;
163
+ /**
164
+ * Stop the turn that is generating right now: closes the stream so the UI
165
+ * stops immediately, and tells the backend to stop generating.
166
+ *
167
+ * Both halves matter. Closing the stream alone does NOT stop the agent — it
168
+ * keeps running and the full answer reappears the next time the conversation
169
+ * is loaded. The backend unwinds at its next safe point (any tool already
170
+ * running finishes, no further tool or reasoning round starts), keeps the text
171
+ * produced so far and finalizes the message as `CANCELED`.
172
+ *
173
+ * The in-flight `sendMessage` / `continueMessage` promise resolves normally
174
+ * with that partial message (it does not reject), `message:complete` fires
175
+ * with status `CANCELED`, then `message:stopped`.
176
+ *
177
+ * ```ts
178
+ * // "Stop" button
179
+ * stopButton.onclick = () => void client.stop();
180
+ * ```
181
+ *
182
+ * Returns the backend's verdict, or `null` when nothing was generating or the
183
+ * stop landed before the message had an id (the stream is still closed).
184
+ */
185
+ stop(): Promise<StopMessageResult | null>;
186
+ /**
187
+ * Ask the backend to stop a specific in-flight turn, without touching any
188
+ * local stream. Idempotent — stopping a finished turn answers
189
+ * `{ status: "not_running" }` rather than failing. Most apps want
190
+ * {@link stop} instead; use this to stop a turn started elsewhere (e.g. one
191
+ * still running after a page reload, found via `getConversation`).
192
+ */
193
+ stopMessage(messageId: string): Promise<StopMessageResult>;
194
+ /** Whether a turn is generating right now (i.e. {@link stop} has something to stop). */
195
+ isGenerating(): boolean;
196
+ /** Open a new turn, replacing any bookkeeping left by the previous one. */
197
+ private beginTurn;
198
+ private endTurn;
199
+ /** POST the stop for a turn, once, never letting the failure escape. */
200
+ private postStopForTurn;
201
+ /** The message a caller gets back when the stop beat the response. */
202
+ private buildStoppedMessage;
137
203
  private resolveClientFunctionsMode;
138
204
  /**
139
205
  * Register a gate deciding WHEN a paused turn resumes. The SDK still decides
@@ -361,13 +427,38 @@ declare class AgoClient {
361
427
  * },
362
428
  * ]);
363
429
  * ```
430
+ *
431
+ * Pass `opts.data` and the agent also gets back **what the page now shows**,
432
+ * as the result of its own call, instead of having to wait for the next
433
+ * message's context. That also registers a read-only `readPageData`
434
+ * companion. See {@link AgoPageDataSource}.
364
435
  */
365
436
  registerPageStateFunction(controls: AgoStateControl[], opts?: AgoPageStateOptions): void;
366
437
  /**
367
- * Unregister a page state function and its dynamic context provider.
368
- * Mirror of unregistering `navigateToPage`.
438
+ * Unregister a page state function, its `readPageData` companion, and its
439
+ * dynamic context provider. Mirror of unregistering `navigateToPage`.
369
440
  */
370
441
  unregisterPageStateFunction(functionName?: string): void;
442
+ /**
443
+ * Size ceiling for a page snapshot, before the envelope is accounted for.
444
+ * Read at call time, not at registration, so `updateConfig` moves it.
445
+ */
446
+ private pageDataBudget;
447
+ /** Bytes the non-`data` part of the result costs, `data` included as `null`. */
448
+ private envelopeBytes;
449
+ /**
450
+ * Wait for the page to stop reloading, then read the snapshot. `get` and
451
+ * `isLoading` are re-read from `source` on every tick so a re-render that
452
+ * swaps the closures (without re-registering) is picked up mid-wait.
453
+ */
454
+ private readPageData;
455
+ /**
456
+ * The snapshot only reaches the agent inside the same turn in pause mode,
457
+ * where the SDK submits the tool result and resumes. In placeholder mode the
458
+ * turn is already over, so a `data` source looks broken from the outside:
459
+ * say so once rather than let the integrator hunt for an SDK bug.
460
+ */
461
+ private warnIfPlaceholderMode;
371
462
  /**
372
463
  * Register or update a piece of client-side context.
373
464
  * This context is sent with every message so the AI understands the user's situation.
@@ -535,6 +626,18 @@ declare interface AgoClientEvents {
535
626
  conversationId: string;
536
627
  messageId: string;
537
628
  };
629
+ /**
630
+ * The user stopped the turn (`client.stop()`): the stream was closed and the
631
+ * backend was told to stop generating. Always fires, so this is the event to
632
+ * finalize a UI on. When there was an answer to keep, a `message:complete`
633
+ * carrying it with status `CANCELED` fires first; there is none when the stop
634
+ * landed before the backend named the message (`messageId` is then an empty
635
+ * string) or when the stopped turn was paused on client functions.
636
+ */
637
+ "message:stopped": {
638
+ conversationId: string;
639
+ messageId: string;
640
+ };
538
641
  "message:error": {
539
642
  error: string;
540
643
  /** Stable error code (see configuration.md#error-codes) when the failure was an AgoError. */
@@ -768,6 +871,80 @@ export declare interface AgoNudgeProps {
768
871
  className?: string;
769
872
  }
770
873
 
874
+ /**
875
+ * What the page currently displays, returned to the agent as the *result* of
876
+ * `setPageState` instead of only as context on the next message.
877
+ *
878
+ * Declare it when the agent should be able to act on what its own change
879
+ * produced ("search for dupont" → it can say who was found).
880
+ *
881
+ * A control change usually kicks off work (a refetch, a recomputation). The SDK
882
+ * has to wait for that work before reading, and there are two ways to tell it
883
+ * when the work is done. **Prefer the first.**
884
+ *
885
+ * **1. Return a promise from `get()`** — you own the await, so the SDK is
886
+ * exact: it resolves when your work resolves, with no polling and no timing
887
+ * assumption. With TanStack Query, `ensureQueryData` gives you that promise and
888
+ * shares the single in-flight request with the UI:
889
+ *
890
+ * ```ts
891
+ * useAgoPageState(controls, {
892
+ * data: {
893
+ * description: "The users matching the current filters.",
894
+ * get: () => queryClient.ensureQueryData({
895
+ * queryKey: ["users", filters],
896
+ * queryFn: fetchUsers,
897
+ * }),
898
+ * },
899
+ * });
900
+ * ```
901
+ *
902
+ * **2. Declare `isLoading`** — for data you cannot get a promise for. The SDK
903
+ * polls it instead, which is a heuristic: the flag has to be up within ~100 ms
904
+ * of the change or the SDK concludes the page settled and reads the previous
905
+ * rows. Fine for a query library that flips `isFetching` on render, wrong for a
906
+ * debounced fetch.
907
+ *
908
+ * ```ts
909
+ * const { data: users, isFetching } = useQuery({ queryKey: ["users", filters], queryFn: fetchUsers });
910
+ *
911
+ * useAgoPageState(controls, {
912
+ * data: {
913
+ * description: "The users matching the current filters.",
914
+ * get: () => users ?? [],
915
+ * // isFetching, NOT isLoading: a background refetch must count as loading,
916
+ * // otherwise the agent reads the rows from the previous search.
917
+ * isLoading: () => isFetching,
918
+ * },
919
+ * });
920
+ * ```
921
+ */
922
+ export declare interface AgoPageDataSource<T = unknown> {
923
+ /** What this data is, for the LLM: "The users matching the current filters." */
924
+ description: string;
925
+ /**
926
+ * The snapshot handed back to the agent.
927
+ *
928
+ * Return a promise and the SDK awaits it: that promise resolving *is* the
929
+ * signal that the work the change triggered has finished, so nothing is
930
+ * guessed. It is bounded by `settleTimeoutMs`.
931
+ */
932
+ get: () => T | Promise<T>;
933
+ /**
934
+ * True while the page is (re)loading this data. Only needed when `get()`
935
+ * cannot return a promise. The SDK polls it every 50 ms and treats two
936
+ * consecutive `false` readings as settled, so a flag raised more than ~100 ms
937
+ * after the change is missed and the agent reads stale rows.
938
+ */
939
+ isLoading?: () => boolean;
940
+ /**
941
+ * Size ceiling for the returned snapshot, in bytes. Defaults to the client's
942
+ * `maxFunctionResultBytes`. Over the ceiling the snapshot keeps the first
943
+ * whole items that fit; `success` and `applied` are never dropped.
944
+ */
945
+ maxResultBytes?: number;
946
+ }
947
+
771
948
  /**
772
949
  * Options for {@link AgoClient.registerPageStateFunction}.
773
950
  */
@@ -779,6 +956,23 @@ export declare interface AgoPageStateOptions {
779
956
  * {@link AgoConfig.approvalPolicy} — pause mode only. Defaults to `false`.
780
957
  */
781
958
  requiresApproval?: boolean;
959
+ /**
960
+ * Declare what the page displays so `setPageState` returns it. Omit it and
961
+ * the result stays exactly `{ success, applied }`.
962
+ *
963
+ * Also registers a read-only companion function (`readPageData`, derived from
964
+ * `functionName`) that returns the same snapshot without touching the page.
965
+ *
966
+ * The snapshot travels only when the agent calls one of those functions: it
967
+ * is deliberately kept out of the `page-state:` dynamic context, which would
968
+ * put it in every message.
969
+ */
970
+ data?: AgoPageDataSource;
971
+ /**
972
+ * How long to wait for the page to finish reloading before reading the
973
+ * snapshot. Defaults to 10 000 ms; on timeout whatever is there is returned.
974
+ */
975
+ settleTimeoutMs?: number;
782
976
  }
783
977
 
784
978
  /**
@@ -866,7 +1060,18 @@ export declare interface AgoStateControl<T = unknown> {
866
1060
  export declare const ChatInput: default_2.FC<ChatInputProps>;
867
1061
 
868
1062
  export declare interface ChatInputProps {
869
- onSend: (message: string, files?: File[]) => void;
1063
+ /**
1064
+ * Send the message. The composer clears immediately so the UI feels instant,
1065
+ * so resolving to `false` means "that send failed" and puts the text (and any
1066
+ * attachments) back rather than losing what the user typed.
1067
+ */
1068
+ onSend: (message: string, files?: File[]) => void | boolean | Promise<void | boolean>;
1069
+ /**
1070
+ * Stop the turn being generated. When provided, the send button becomes an
1071
+ * enabled Stop button for as long as `disabled` is true (i.e. while the agent
1072
+ * is answering).
1073
+ */
1074
+ onStop?: () => void;
870
1075
  disabled?: boolean;
871
1076
  placeholder?: string;
872
1077
  allowFiles?: boolean;
@@ -876,7 +1081,24 @@ export declare interface ChatInputProps {
876
1081
  /**
877
1082
  * Pre-built chat widget component
878
1083
  */
879
- export declare const ChatWidget: default_2.FC<ChatWidgetProps>;
1084
+ export declare const ChatWidget: ForwardRefExoticComponent<ChatWidgetProps & RefAttributes<ChatWidgetHandle>>;
1085
+
1086
+ /** Imperative handle exposed via `ref`. */
1087
+ export declare interface ChatWidgetHandle {
1088
+ /**
1089
+ * Expand the sheet to full screen.
1090
+ *
1091
+ * Only the presentation is gated on a compact viewport: off-compact (or with
1092
+ * the sheet disabled) nothing moves on screen, but the state still changes and
1093
+ * `onStateChange` still fires. Guard on `state` if that matters to you.
1094
+ */
1095
+ expand: () => void;
1096
+ /** Collapse back to `peek`. The draft and the conversation are kept. */
1097
+ collapse: () => void;
1098
+ toggle: () => void;
1099
+ /** Current sheet state. `"peek"` when the sheet is off. */
1100
+ state: SheetState;
1101
+ }
880
1102
 
881
1103
  export declare interface ChatWidgetProps {
882
1104
  /** The AGO client instance. If omitted, reads from AgoProvider context. */
@@ -891,6 +1113,11 @@ export declare interface ChatWidgetProps {
891
1113
  placeholder?: string;
892
1114
  /** Enable file attachments */
893
1115
  allowFiles?: boolean;
1116
+ /**
1117
+ * While the agent is answering, turn the send button into a Stop button that
1118
+ * interrupts the turn. Defaults to `true`.
1119
+ */
1120
+ allowStop?: boolean;
894
1121
  /** Widget height */
895
1122
  height?: string | number;
896
1123
  /** URL of a logo to display in the header */
@@ -921,6 +1148,42 @@ export declare interface ChatWidgetProps {
921
1148
  id: string;
922
1149
  content: string;
923
1150
  }) => void;
1151
+ /**
1152
+ * Present the widget as a bottom sheet on compact viewports: a slim `peek`
1153
+ * bar pinned to the bottom edge that expands to `full`.
1154
+ *
1155
+ * Off by default, because it turns the widget into a fixed overlay on the
1156
+ * host page. Pass `false` explicitly to be sure it stays off, or an object to
1157
+ * tune the breakpoint, resting state, and the space to leave for a host
1158
+ * bottom nav (`bottomOffset`).
1159
+ */
1160
+ sheet?: SheetOptions | false;
1161
+ /**
1162
+ * Shown next to the animated dots in the collapsed sheet while the agent is
1163
+ * working and has not produced any text yet. Defaults to `"Thinking..."`.
1164
+ */
1165
+ thinkingLabel?: string;
1166
+ /**
1167
+ * What to show while a client function the agent called is still running.
1168
+ * Between the call and the turn resuming the page can be busy for seconds,
1169
+ * and a bare typing indicator says nothing about it.
1170
+ *
1171
+ * Map a function name to a label, or pass a function for full control.
1172
+ * Unmapped names fall back to a prettified version of the name itself
1173
+ * (`lookupFlavorPrices` -> "Lookup Flavor Prices"). Pass `false` to keep the
1174
+ * plain thinking indicator.
1175
+ *
1176
+ * ```tsx
1177
+ * <ChatWidget functionLabels={{ lookupFlavorPrices: "Je regarde les prix" }} />
1178
+ * ```
1179
+ */
1180
+ functionLabels?: Record<string, string> | ((functionName: string, args: Record<string, unknown>) => string) | false;
1181
+ /**
1182
+ * Include the agent's `reasoning` steps in the activity row. On by default:
1183
+ * they are the backend's own progress messages, and without them the row goes
1184
+ * blank between two function calls. Set `false` to show only tool activity.
1185
+ */
1186
+ showReasoning?: boolean;
924
1187
  }
925
1188
 
926
1189
  /**
@@ -1134,6 +1397,13 @@ export declare function deriveFormStatus(schema: FormCollectorSchema, values: Pa
1134
1397
  */
1135
1398
  declare type DynamicContextProvider = () => ContextEntry | null | undefined;
1136
1399
 
1400
+ /** Style/attribute bag for one element. Style keys are camelCase: React spreads
1401
+ * them directly, and the vanilla `css()` helper takes the same shape. */
1402
+ declare interface ElementProps {
1403
+ style: Record<string, string>;
1404
+ attrs: Record<string, string | null>;
1405
+ }
1406
+
1137
1407
  export declare interface FormCollector<V = Record<string, unknown>> {
1138
1408
  name: string;
1139
1409
  /** Observable store driving the form UI (read via `useAgoStore`). */
@@ -1328,13 +1598,21 @@ declare class HttpClient {
1328
1598
  keepalive?: boolean;
1329
1599
  }): Promise<T>;
1330
1600
  /**
1331
- * Make a POST request and return the raw Response (for streaming)
1601
+ * Make a POST request and return the raw Response (for streaming).
1602
+ *
1603
+ * `signal` lets the caller close the stream mid-flight (see
1604
+ * `AgoClient.stop`); an abort is rethrown as-is rather than wrapped in an
1605
+ * `AgoNetworkError`, so a deliberate stop is not mistaken for a network drop.
1332
1606
  */
1333
- postStream(path: string, body?: unknown): Promise<Response>;
1607
+ postStream(path: string, body?: unknown, options?: {
1608
+ signal?: AbortSignal;
1609
+ }): Promise<Response>;
1334
1610
  /**
1335
1611
  * Make a POST request with FormData (for file uploads)
1336
1612
  */
1337
- postFormData(path: string, formData: FormData): Promise<Response>;
1613
+ postFormData(path: string, formData: FormData, options?: {
1614
+ signal?: AbortSignal;
1615
+ }): Promise<Response>;
1338
1616
  private request;
1339
1617
  private handleErrorResponse;
1340
1618
  }
@@ -1393,6 +1671,13 @@ export declare interface MessageProps {
1393
1671
  * follow-up buttons render but are not interactive (backwards-compatible).
1394
1672
  */
1395
1673
  onFollowUpClick?: (reply: string) => void;
1674
+ /**
1675
+ * Show the animated dots for an answer that has not started writing yet.
1676
+ * Defaults to `true`. Pass `false` when something else on screen already
1677
+ * reports progress (an activity row naming the running function): the empty
1678
+ * bubble is then dropped entirely rather than left as a blank box.
1679
+ */
1680
+ showStreamingDots?: boolean;
1396
1681
  }
1397
1682
 
1398
1683
  declare type MessageStatus = "IN_PROGRESS" | "DONE" | "ERROR" | "TODO" | "CANCELED"
@@ -1651,6 +1936,73 @@ declare interface SendMessageOptions {
1651
1936
  clientFunctionsMode?: ClientFunctionsMode;
1652
1937
  }
1653
1938
 
1939
+ /** Why a transition happened, so hosts can tell a tap from a breakpoint change. */
1940
+ export declare type SheetChangeCause = "api" | "user" | "breakpoint";
1941
+
1942
+ export declare interface SheetOptions {
1943
+ /**
1944
+ * Max viewport width (px) treated as compact. A short landscape viewport
1945
+ * (`max-height: 500px`) counts as compact too, so a phone turned sideways
1946
+ * keeps the sheet instead of dropping to the desktop layout mid-conversation.
1947
+ * Defaults to `768`.
1948
+ */
1949
+ breakpoint?: number;
1950
+ /** State to rest in when the compact layout first applies. Defaults to `"peek"`. */
1951
+ initialState?: SheetState;
1952
+ /**
1953
+ * Space to leave below the sheet, for hosts whose page already owns the bottom
1954
+ * edge (a bottom nav, a sticky checkout bar). A number is treated as px; a
1955
+ * string is used verbatim, so `env(safe-area-inset-bottom)` or a `calc()` both
1956
+ * work. Defaults to `0`.
1957
+ */
1958
+ bottomOffset?: number | string;
1959
+ /**
1960
+ * Minimum height of the collapsed sheet, excluding the bottom safe area.
1961
+ * The bar grows past it if the host's own composer styling is taller.
1962
+ * Defaults to `152`.
1963
+ */
1964
+ peekHeight?: number;
1965
+ /** Called after every state change, with what caused it. */
1966
+ onStateChange?: (state: SheetState, cause: SheetChangeCause) => void;
1967
+ }
1968
+
1969
+ export declare interface SheetSnapshot {
1970
+ /** Whether the compact (phone-shaped) layout applies at all. */
1971
+ compact: boolean;
1972
+ /** Current resting state. Meaningless while `compact` is false. */
1973
+ state: SheetState;
1974
+ /**
1975
+ * Whether the sheet currently covers the viewport. Drives scroll locking,
1976
+ * dialog semantics, focus trapping and Escape. One predicate, so those can
1977
+ * never drift apart. False on a desktop viewport even when open: the host page
1978
+ * is still usable beside the widget and must stay keyboard-reachable.
1979
+ */
1980
+ isModal: boolean;
1981
+ /** Props for the sheet surface itself. */
1982
+ surface: ElementProps;
1983
+ }
1984
+
1985
+ /**
1986
+ * Framework-agnostic bottom-sheet controller.
1987
+ *
1988
+ * Owns the `peek <-> full` state machine and turns it into a **props bag**: a
1989
+ * plain object of styles and ARIA attributes that a renderer applies however it
1990
+ * likes. It never touches the DOM itself.
1991
+ *
1992
+ * That shape is deliberate. The React widget re-renders on every streamed token
1993
+ * and re-applies its inline `style` object, so a controller that wrote to the
1994
+ * DOM directly would be clobbered mid-stream. Returning props instead means
1995
+ * React can spread them, the vanilla adapter can hand them to `css()`, and a Vue
1996
+ * or Angular binding can bind them, all from one implementation.
1997
+ *
1998
+ * Modality is expressed, not delegated to `<dialog>`: promoting a dialog from
1999
+ * `show()` to `showModal()` requires closing it and re-parenting into the top
2000
+ * layer, which cancels any running transition. The renderer applies
2001
+ * `role="dialog"` / `aria-modal` / focus trapping from `isModal` instead.
2002
+ */
2003
+ /** The two resting states. There is no `half`: it needs a drag engine to be worth having. */
2004
+ export declare type SheetState = "peek" | "full";
2005
+
1654
2006
  /** Tuning knobs for the collector's detectors. All optional. */
1655
2007
  declare interface SignalCollectorTuning {
1656
2008
  /** Min gap between heavy activity work (route checks, notifications), ms. Default 250. */
@@ -1744,6 +2096,21 @@ declare interface SSEChunkData {
1744
2096
  waiting_tool_call_ids?: string[];
1745
2097
  }
1746
2098
 
2099
+ /**
2100
+ * Response of `POST /messages/{id}/stop` (see `AgoClient.stopMessage`).
2101
+ *
2102
+ * - `"stopping"` — the request was accepted; the turn unwinds at its next safe
2103
+ * point and finalizes as `CANCELED`, keeping the text produced so far.
2104
+ * - `"not_running"` — the turn had already finished. Harmless.
2105
+ * - `"not_supported"` — a background agent run, which cannot be stopped once
2106
+ * started.
2107
+ */
2108
+ declare interface StopMessageResult {
2109
+ status: "stopping" | "not_running" | "not_supported";
2110
+ /** The message's status when the stop was requested. */
2111
+ messageStatus?: MessageStatus;
2112
+ }
2113
+
1747
2114
  /** The slice of the Web Storage API that {@link createStore} relies on. */
1748
2115
  declare type StorageLike = Pick<Storage, "getItem" | "setItem">;
1749
2116
 
@@ -2059,6 +2426,21 @@ export declare type UseAgoOptions = AgoConfig;
2059
2426
  * },
2060
2427
  * ]);
2061
2428
  * ```
2429
+ *
2430
+ * Pass `opts.data` to also hand the agent what the page ends up displaying, as
2431
+ * the result of its own `setPageState` call:
2432
+ *
2433
+ * ```tsx
2434
+ * const { data: rows, isFetching } = useQuery({ queryKey: ["rows", status], queryFn: fetchRows });
2435
+ *
2436
+ * useAgoPageState(controls, {
2437
+ * data: {
2438
+ * description: "The rows matching the current filters.",
2439
+ * get: () => rows ?? [],
2440
+ * isLoading: () => isFetching,
2441
+ * },
2442
+ * });
2443
+ * ```
2062
2444
  */
2063
2445
  export declare function useAgoPageState(controls: AgoStateControl[], opts?: AgoPageStateOptions): void;
2064
2446
 
@@ -2114,6 +2496,8 @@ export declare interface UseChatResult {
2114
2496
  error: Error | null;
2115
2497
  /** Send a message */
2116
2498
  sendMessage: (content: string, files?: File[]) => Promise<AgoMessage | null>;
2499
+ /** Stop the turn that is generating (the "Stop" button). No-op when idle. */
2500
+ stop: () => Promise<void>;
2117
2501
  /** Clear current messages */
2118
2502
  clearMessages: () => void;
2119
2503
  /** Current conversation ID */
@@ -2223,6 +2607,13 @@ export declare interface UseMessagesResult {
2223
2607
  error: Error | null;
2224
2608
  /** Send a new message */
2225
2609
  sendMessage: (content: string, files?: File[]) => Promise<AgoMessage | null>;
2610
+ /**
2611
+ * Stop the turn that is generating: closes the stream and tells the backend
2612
+ * to stop. The partial answer stays in the transcript as `CANCELED`. No-op
2613
+ * when nothing is generating. Wire it to a Stop button shown while
2614
+ * {@link isLoading} is true.
2615
+ */
2616
+ stop: () => Promise<void>;
2226
2617
  /** Clear messages */
2227
2618
  clearMessages: () => void;
2228
2619
  /** Current conversation ID */
@@ -2272,4 +2663,25 @@ export declare interface UseProactiveNudgeResult {
2272
2663
  dismiss: () => void;
2273
2664
  }
2274
2665
 
2666
+ /**
2667
+ * React binding for {@link createSheetController}.
2668
+ *
2669
+ * Reads through `useSyncExternalStore` with a **non-compact server snapshot**, so
2670
+ * `matchMedia` (which does not exist in Node) never runs during render. The
2671
+ * server emits the ordinary layout and the client promotes to a sheet after
2672
+ * hydration, instead of throwing on the server or flashing on the client.
2673
+ *
2674
+ * Pass `false` to opt out entirely: no sheet, no scroll lock, no focus trap, no
2675
+ * fixed overlay on the host page.
2676
+ */
2677
+ export declare function useSheet(options?: SheetOptions | false): UseSheetResult;
2678
+
2679
+ export declare interface UseSheetResult {
2680
+ /** Current state + the props bag to apply to the sheet surface. */
2681
+ sheet: SheetSnapshot;
2682
+ expand: (cause?: SheetChangeCause) => void;
2683
+ collapse: (cause?: SheetChangeCause) => void;
2684
+ toggle: (cause?: SheetChangeCause) => void;
2685
+ }
2686
+
2275
2687
  export { }