@superatomai/application-react 0.0.1 → 0.0.2-dev

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.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { z } from 'zod';
2
- import React, { Component as Component$1, ReactNode } from 'react';
2
+ import * as React from 'react';
3
+ import React__default, { Component as Component$1, ReactNode, CSSProperties } from 'react';
3
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
5
 
5
6
  declare const ExpressionSchema$1: z.ZodObject<{
@@ -185,7 +186,7 @@ type MessageParticipant = z.infer<typeof MessageParticipantSchema>;
185
186
  * Synced with sdk-nodejs/src/types.ts
186
187
  */
187
188
  declare const MessageSchema: z.ZodObject<{
188
- id: z.ZodString;
189
+ id: z.ZodDefault<z.ZodString>;
189
190
  type: z.ZodString;
190
191
  from: z.ZodObject<{
191
192
  id: z.ZodOptional<z.ZodString>;
@@ -202,6 +203,16 @@ type Message = z.infer<typeof MessageSchema>;
202
203
  * User prompt request payload schema
203
204
  * Synced with sdk-nodejs: UserPromptRequestPayloadSchema
204
205
  */
206
+ /**
207
+ * Where a question was asked from. Synced with sdk-web / sdk-nodejs.
208
+ *
209
+ * A backend that does not know the field drops it, so sending one is always safe.
210
+ */
211
+ declare const PromptContextSchema: z.ZodObject<{
212
+ dashboardId: z.ZodOptional<z.ZodString>;
213
+ filters: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
214
+ }, z.core.$strip>;
215
+ type PromptContext = z.infer<typeof PromptContextSchema>;
205
216
  declare const UserPromptRequestPayloadSchema: z.ZodObject<{
206
217
  prompt: z.ZodString;
207
218
  userId: z.ZodOptional<z.ZodString>;
@@ -213,6 +224,17 @@ declare const UserPromptRequestPayloadSchema: z.ZodObject<{
213
224
  component: "component";
214
225
  text: "text";
215
226
  }>>;
227
+ agentId: z.ZodOptional<z.ZodString>;
228
+ context: z.ZodOptional<z.ZodObject<{
229
+ dashboardId: z.ZodOptional<z.ZodString>;
230
+ filters: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
231
+ }, z.core.$strip>>;
232
+ attachments: z.ZodOptional<z.ZodArray<z.ZodObject<{
233
+ key: z.ZodString;
234
+ fileName: z.ZodString;
235
+ size: z.ZodNumber;
236
+ contentType: z.ZodOptional<z.ZodString>;
237
+ }, z.core.$strip>>>;
216
238
  }, z.core.$strip>;
217
239
  type UserPromptRequestPayload = z.infer<typeof UserPromptRequestPayloadSchema>;
218
240
  /**
@@ -241,9 +263,63 @@ declare const UserPromptRequestMessageSchema: z.ZodObject<{
241
263
  component: "component";
242
264
  text: "text";
243
265
  }>>;
266
+ agentId: z.ZodOptional<z.ZodString>;
267
+ context: z.ZodOptional<z.ZodObject<{
268
+ dashboardId: z.ZodOptional<z.ZodString>;
269
+ filters: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
270
+ }, z.core.$strip>>;
271
+ attachments: z.ZodOptional<z.ZodArray<z.ZodObject<{
272
+ key: z.ZodString;
273
+ fileName: z.ZodString;
274
+ size: z.ZodNumber;
275
+ contentType: z.ZodOptional<z.ZodString>;
276
+ }, z.core.$strip>>>;
244
277
  }, z.core.$strip>;
245
278
  }, z.core.$strip>;
246
279
  type UserPromptRequestMessage = z.infer<typeof UserPromptRequestMessageSchema>;
280
+ /**
281
+ * Narrator progress while an answer is being worked out — "reading the schema",
282
+ * "running the query". Arrives on its own message type as the work happens, in
283
+ * any response mode. Synced with sdk-web: UserPromptNarrationSchema.
284
+ */
285
+ declare const UserPromptNarrationSchema: z.ZodObject<{
286
+ uiBlockId: z.ZodString;
287
+ threadId: z.ZodOptional<z.ZodString>;
288
+ seq: z.ZodNumber;
289
+ elapsedMs: z.ZodNumber;
290
+ text: z.ZodString;
291
+ }, z.core.$strip>;
292
+ type UserPromptNarration = z.infer<typeof UserPromptNarrationSchema>;
293
+ /**
294
+ * User prompt abort request payload schema
295
+ * Synced with sdk-nodejs: UserPromptAbortRequestPayloadSchema
296
+ */
297
+ declare const UserPromptAbortRequestPayloadSchema: z.ZodObject<{
298
+ uiBlockId: z.ZodString;
299
+ threadId: z.ZodOptional<z.ZodString>;
300
+ }, z.core.$strip>;
301
+ type UserPromptAbortRequestPayload = z.infer<typeof UserPromptAbortRequestPayloadSchema>;
302
+ /**
303
+ * User prompt abort request message schema
304
+ * Synced with sdk-nodejs: UserPromptAbortRequestMessageSchema
305
+ */
306
+ declare const UserPromptAbortRequestMessageSchema: z.ZodObject<{
307
+ id: z.ZodString;
308
+ type: z.ZodLiteral<"USER_PROMPT_ABORT_REQ">;
309
+ from: z.ZodObject<{
310
+ id: z.ZodOptional<z.ZodString>;
311
+ type: z.ZodOptional<z.ZodString>;
312
+ }, z.core.$strip>;
313
+ to: z.ZodOptional<z.ZodObject<{
314
+ id: z.ZodOptional<z.ZodString>;
315
+ type: z.ZodOptional<z.ZodString>;
316
+ }, z.core.$strip>>;
317
+ payload: z.ZodObject<{
318
+ uiBlockId: z.ZodString;
319
+ threadId: z.ZodOptional<z.ZodString>;
320
+ }, z.core.$strip>;
321
+ }, z.core.$strip>;
322
+ type UserPromptAbortRequestMessage = z.infer<typeof UserPromptAbortRequestMessageSchema>;
247
323
  /**
248
324
  * Component schema (from backend)
249
325
  * Synced with sdk-nodejs: ComponentSchema
@@ -796,13 +872,21 @@ type UIQueryFilters = z.infer<typeof UIQueryFiltersSchema>;
796
872
  /**
797
873
  * DBUIBlock schema for database storage
798
874
  * Synced with sdk-nodejs: DBUIBlockSchema (from conversation-saver.ts)
875
+ *
876
+ * `passthrough`, deliberately, and for the same reason as the copy in
877
+ * sdk-nodejs. A bookmark stores a copy of the conversation row's `response`;
878
+ * the four fields below are only what a reader needs, while the row also
879
+ * carries `attachments`, `generatedFiles`, `narration`, `durationMs`, `error`
880
+ * and whatever is added next. `createBookmark` parses the outgoing message
881
+ * through this schema, so a plain object strips those keys *in the browser* —
882
+ * the request leaves with four fields and nothing downstream can recover them.
799
883
  */
800
884
  declare const DBUIBlockSchema: z.ZodObject<{
801
885
  id: z.ZodString;
802
886
  component: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodAny>>;
803
887
  analysis: z.ZodNullable<z.ZodString>;
804
888
  user_prompt: z.ZodString;
805
- }, z.core.$strip>;
889
+ }, z.core.$loose>;
806
890
  type DBUIBlock = z.infer<typeof DBUIBlockSchema>;
807
891
  /**
808
892
  * Bookmark data schema
@@ -815,7 +899,12 @@ declare const BookmarkDataSchema: z.ZodObject<{
815
899
  component: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodAny>>;
816
900
  analysis: z.ZodNullable<z.ZodString>;
817
901
  user_prompt: z.ZodString;
818
- }, z.core.$strip>;
902
+ }, z.core.$loose>;
903
+ name: z.ZodOptional<z.ZodString>;
904
+ description: z.ZodOptional<z.ZodString>;
905
+ userId: z.ZodOptional<z.ZodString>;
906
+ agentId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
907
+ threadId: z.ZodOptional<z.ZodString>;
819
908
  created_at: z.ZodOptional<z.ZodString>;
820
909
  updated_at: z.ZodOptional<z.ZodString>;
821
910
  }, z.core.$strip>;
@@ -826,6 +915,7 @@ type BookmarkData = z.infer<typeof BookmarkDataSchema>;
826
915
  */
827
916
  declare const BookmarkQueryFiltersSchema: z.ZodObject<{
828
917
  userId: z.ZodOptional<z.ZodString>;
918
+ agentId: z.ZodOptional<z.ZodString>;
829
919
  threadId: z.ZodOptional<z.ZodString>;
830
920
  name: z.ZodOptional<z.ZodString>;
831
921
  }, z.core.$strip>;
@@ -1026,8 +1116,17 @@ declare const ClientConfigSchema: z.ZodObject<{
1026
1116
  maxReconnectDelay: z.ZodDefault<z.ZodNumber>;
1027
1117
  defaultTimeout: z.ZodDefault<z.ZodNumber>;
1028
1118
  debug: z.ZodDefault<z.ZodBoolean>;
1119
+ token: z.ZodOptional<z.ZodString>;
1029
1120
  }, z.core.$strip>;
1030
- type ClientConfig = z.input<typeof ClientConfigSchema>;
1121
+ type ClientConfig = z.input<typeof ClientConfigSchema> & {
1122
+ /**
1123
+ * Called before every (re)connect for a valid session token, replacing
1124
+ * `token`. Used for SDK sign-in (see SdkSession in auth.ts). Rejecting with an
1125
+ * error whose `fatal` is true stops reconnecting; any other rejection is
1126
+ * retried with the normal back-off.
1127
+ */
1128
+ getAccessToken?: () => Promise<string>;
1129
+ };
1031
1130
  type ResolvedClientConfig = z.output<typeof ClientConfigSchema>;
1032
1131
 
1033
1132
  /**
@@ -1045,9 +1144,36 @@ type ResolvedClientConfig = z.output<typeof ClientConfigSchema>;
1045
1144
  * @param responseMode - 'component' for component response (default), 'text' for text streaming
1046
1145
  * @param onStream - Optional callback for streaming text chunks (only for text mode)
1047
1146
  * @param timeout - Request timeout in milliseconds
1147
+ * @param context - Where the question was asked from, e.g. the dashboard on screen
1148
+ * @param onNarration - Optional callback for narrator progress updates (any mode)
1048
1149
  * @returns Server response message
1049
1150
  */
1050
- declare function sendUserPromptRequest(client: SuperatomClient, prompt: string, threadId: string, uiBlockId: string, userId?: string, responseMode?: 'component' | 'text', onStream?: (chunk: string) => void, timeout?: number): Promise<Message>;
1151
+ declare function sendUserPromptRequest(client: SuperatomClient, prompt: string, threadId: string, uiBlockId: string, userId?: string, responseMode?: 'component' | 'text', onStream?: (chunk: string) => void, timeout?: number,
1152
+ /** Where the question was asked from, e.g. the dashboard on screen. Omitted when not given. */
1153
+ context?: PromptContext, onNarration?: (update: UserPromptNarration) => void,
1154
+ /** The chat agent this question belongs to. A new thread is saved against it. */
1155
+ agentId?: string,
1156
+ /** Files this question carries, already uploaded — references only. */
1157
+ attachments?: {
1158
+ key: string;
1159
+ fileName: string;
1160
+ size: number;
1161
+ contentType?: string;
1162
+ }[]): Promise<Message>;
1163
+ /**
1164
+ * Abort an in-flight user prompt request.
1165
+ *
1166
+ * Fire-and-forget: sends a USER_PROMPT_ABORT_REQ identifying the question by its
1167
+ * uiBlockId. The backend cancels the matching in-flight request (LLM stream,
1168
+ * source agents, any running script) and acks with USER_PROMPT_ABORTED. There's
1169
+ * no response to await — the caller has already marked the message "stopped" on
1170
+ * its side; this just stops the server-side work.
1171
+ *
1172
+ * @param client - SuperatomClient instance
1173
+ * @param uiBlockId - The uiBlockId of the question to cancel
1174
+ * @param threadId - The thread the question belongs to (optional context)
1175
+ */
1176
+ declare function abortUserPromptRequest(client: SuperatomClient, uiBlockId: string, threadId?: string): void;
1051
1177
  /**
1052
1178
  * Send a user prompt suggestions request
1053
1179
  * @param client - SuperatomClient instance
@@ -1080,6 +1206,61 @@ declare function requestBundle(client: SuperatomClient, options?: {
1080
1206
  }): Promise<string>;
1081
1207
 
1082
1208
  declare function sendComponents(client: SuperatomClient, components: any[]): Promise<void>;
1209
+ /**
1210
+ * Register the dashboard contract — every component a generated dashboard may
1211
+ * import, with the metadata describing it.
1212
+ *
1213
+ * The sibling of `sendComponents`, and deliberately the same shape: the browser
1214
+ * bundle is where these components are defined, so the browser is what says what
1215
+ * they are. It replaced a file generated into the backend by a build step, which
1216
+ * meant someone had to remember to run it and the committed copy could disagree
1217
+ * with the bundle a reader was actually running.
1218
+ *
1219
+ * Fire-and-forget: there is nothing useful to do with an acknowledgement, and
1220
+ * the backend refuses a build with no contract registered rather than relying on
1221
+ * this having arrived.
1222
+ *
1223
+ * Ported from sdk-web (dev, 0.0.14-mds) — the message type and payload are its
1224
+ * wire format, not a guess. Note the `_RES` suffix: it is what that SDK sends.
1225
+ */
1226
+ declare function sendDashContract(client: SuperatomClient, components: any[]): void;
1227
+
1228
+ /**
1229
+ * Workflow Service
1230
+ *
1231
+ * Sends pre-built workflow component descriptors to the backend SDK so the
1232
+ * main agent can route prompts to them. A workflow is a multi-step UI flow
1233
+ * (e.g., transfer review + Agility PO submission) that the LLM can pick when
1234
+ * the user wants to *do* something end-to-end, instead of generating chart
1235
+ * components.
1236
+ */
1237
+
1238
+ /**
1239
+ * Workflow descriptor sent over the wire.
1240
+ *
1241
+ * - `id`: unique workflow id (LLM tool name)
1242
+ * - `name`: React component name registered in the bundle (e.g. "OverstockTransferAnalysis")
1243
+ * - `description`: short human-readable summary
1244
+ * - `whenToUse`: 1–2 sentence trigger condition the LLM uses to decide
1245
+ * - `propsSchema`: prop name → type-and-description string. Mirrors the
1246
+ * `params` shape used for direct tools, e.g. `"string — branch id"`,
1247
+ * `"number (optional) — minimum ROI"`. Becomes the LLM tool's input_schema.
1248
+ * - `defaultProps`: static prop defaults merged with LLM-extracted props
1249
+ * before the component is returned (e.g. embedded externalTool config).
1250
+ */
1251
+ interface WorkflowDescriptor {
1252
+ id: string;
1253
+ name: string;
1254
+ description: string;
1255
+ whenToUse: string;
1256
+ propsSchema: Record<string, string>;
1257
+ defaultProps?: Record<string, unknown>;
1258
+ }
1259
+ /**
1260
+ * Send the full set of registered workflows to the backend.
1261
+ * Replaces any previously registered workflows.
1262
+ */
1263
+ declare function sendWorkflows(client: SuperatomClient, workflows: WorkflowDescriptor[]): Promise<void>;
1083
1264
 
1084
1265
  /**
1085
1266
  * Data Service
@@ -1303,6 +1484,7 @@ declare function queryReports(client: SuperatomClient, options?: QueryReportsOpt
1303
1484
  interface Bookmark {
1304
1485
  id?: number;
1305
1486
  userId?: string;
1487
+ agentId?: string | null;
1306
1488
  threadId?: string;
1307
1489
  name?: string;
1308
1490
  description?: string;
@@ -1316,6 +1498,7 @@ interface Bookmark {
1316
1498
  interface CreateBookmarkOptions {
1317
1499
  userId: string;
1318
1500
  uiblock: DBUIBlock;
1501
+ agentId?: string;
1319
1502
  threadId?: string;
1320
1503
  name?: string;
1321
1504
  description?: string;
@@ -1401,23 +1584,139 @@ declare function getBookmark(client: SuperatomClient, id: number, timeout?: numb
1401
1584
  interface QueryBookmarksOptions {
1402
1585
  filters?: BookmarkQueryFilters;
1403
1586
  limit?: number;
1587
+ /** Rows to skip — `offset`/`limit` page the list the same way threads do. */
1588
+ offset?: number;
1404
1589
  sort?: 'ASC' | 'DESC';
1405
1590
  }
1406
1591
  /**
1407
1592
  * Query bookmarks with filters, limit, and sort
1408
1593
  * @param client - SuperatomClient instance
1409
- * @param options - Query options with filters, limit, and sort
1594
+ * @param options - Query options with filters, limit, offset and sort
1410
1595
  * @param timeout - Request timeout in milliseconds
1411
- * @returns Server response with list of bookmarks
1596
+ * @returns Server response with a page of bookmarks. `count` is the size of
1597
+ * this page; `total` is how many match the filters, which is what tells a
1598
+ * caller whether another page exists.
1412
1599
  */
1413
1600
  declare function queryBookmarks(client: SuperatomClient, options?: QueryBookmarksOptions, timeout?: number): Promise<{
1414
1601
  success: boolean;
1415
1602
  error?: string;
1416
1603
  data?: BookmarkData[];
1417
1604
  count?: number;
1605
+ total?: number;
1418
1606
  message?: string;
1419
1607
  }>;
1420
1608
 
1609
+ /**
1610
+ * Answer feedback.
1611
+ *
1612
+ * Whether a particular answer was right, and why not when it was not. Read by
1613
+ * whoever is improving the project's agent, so what matters is that the
1614
+ * snapshot travels with the verdict: the question asked, the answer given, and
1615
+ * the thread it happened in. A verdict without them is unactionable.
1616
+ *
1617
+ * Not to be confused with feedback about Superatom itself — that belongs in
1618
+ * Superatom's own app, not inside a customer's.
1619
+ *
1620
+ * Mirrors runtime-react's `services/wsMessages/feedback.ts`, on the same
1621
+ * `answer-feedback` collection, so both write rows the same reader understands.
1622
+ */
1623
+
1624
+ interface SubmitAnswerFeedbackParams extends Record<string, unknown> {
1625
+ /** The answer being judged — the same id the abort registry and bookmarks use. */
1626
+ uiBlockId: string;
1627
+ threadId?: string;
1628
+ userId?: string;
1629
+ userPrompt: string;
1630
+ /** The answer as it stood when judged, so a later edit cannot rewrite history. */
1631
+ answerSnapshot?: unknown;
1632
+ status: 'correct' | 'partial' | 'incorrect' | null;
1633
+ feedbackText?: string;
1634
+ }
1635
+ /**
1636
+ * Submit a verdict on one answer.
1637
+ *
1638
+ * Resolves `{ success: false, error }` rather than throwing: feedback is never
1639
+ * the thing the user came to do, and a failed send should surface as a quiet
1640
+ * message, not an exception through the chat.
1641
+ */
1642
+ declare function submitAnswerFeedback(client: SuperatomClient, params: SubmitAnswerFeedbackParams, timeout?: number): Promise<{
1643
+ success: boolean;
1644
+ error?: string;
1645
+ data?: unknown;
1646
+ }>;
1647
+
1648
+ /**
1649
+ * What the SDK needs to know about the project it was pointed at.
1650
+ *
1651
+ * Deliberately narrow. The obvious routes return far more than this asks for —
1652
+ * `/auth/me` hands back the user, the organization *and* every app they can
1653
+ * open, and `/my/apps` returns apps across every project. Both are visible in
1654
+ * the network tab of a customer's own application, so the SDK uses neither.
1655
+ *
1656
+ * What it uses instead:
1657
+ *
1658
+ * orgId a claim in the access token already held
1659
+ * GET /projects/:projectId/apps this project's apps, and only this project's
1660
+ * GET /orgs/:orgId/projects/:projectId this project
1661
+ *
1662
+ * Two requests, both scoped to the project the host named. Nothing about other
1663
+ * projects, nothing about the user beyond what they already signed in as.
1664
+ */
1665
+ /** The app types sa-api stores — `appTypeEnum` in its schema. */
1666
+ type SaAppType = 'chat_agent' | 'dashboard' | 'report' | 'app';
1667
+ interface SaApp {
1668
+ id: string;
1669
+ /** `chat_agent` is what `agentId` names — not `chat`, which matches nothing. */
1670
+ type?: SaAppType | string;
1671
+ projectId?: string;
1672
+ name?: string;
1673
+ icon?: string | null;
1674
+ description?: string | null;
1675
+ createdAt?: string;
1676
+ updatedAt?: string;
1677
+ }
1678
+ interface SaProject {
1679
+ id?: string;
1680
+ name?: string;
1681
+ /** The project's logo — an Iconify name (`mdi:factory`) or an image URL. */
1682
+ icon?: string | null;
1683
+ designSystem?: {
1684
+ colors?: {
1685
+ primary?: string;
1686
+ secondary?: string;
1687
+ };
1688
+ } | null;
1689
+ /** `homeDash` here is the dashboard a project shows as its home page. */
1690
+ config?: Record<string, unknown> | null;
1691
+ }
1692
+ /**
1693
+ * The org this session belongs to, read from the access token's own claims.
1694
+ *
1695
+ * `mintAccessToken` puts `orgId` in every token it signs, so the SDK already
1696
+ * holds the answer and needs no request for it. Not verified here — it is only
1697
+ * used to build a URL, and the server checks the token properly on arrival.
1698
+ */
1699
+ declare function getOrgId(): Promise<string | null>;
1700
+ /** Forget everything cached — on sign-out, or when the user changes. */
1701
+ declare function resetProjectCache(): void;
1702
+ /** Every app in this project: its chat agents, dashboards and reports. */
1703
+ declare function getProjectApps(projectId: string, force?: boolean): Promise<SaApp[]>;
1704
+ /**
1705
+ * The chat agents in this project, which is what `agentId` has to be one of.
1706
+ *
1707
+ * The type is `chat_agent`. This said `chat` at first, which matched nothing —
1708
+ * so the list came back empty, every caller read that as "no session, cannot
1709
+ * tell", and a wrong `agentId` passed in silence.
1710
+ */
1711
+ declare function getChatAgents(projectId: string): Promise<SaApp[]>;
1712
+ /**
1713
+ * The project itself — its colours, its logo, its config.
1714
+ *
1715
+ * Resolves `null` rather than throwing: every caller is cosmetic or optional,
1716
+ * and a project that cannot be read should leave the chat working.
1717
+ */
1718
+ declare function getProject(projectId: string, force?: boolean): Promise<SaProject | null>;
1719
+
1421
1720
  /**
1422
1721
  * Artifacts Service
1423
1722
  * Handles ARTIFACTS message for artifact read operations
@@ -1740,6 +2039,150 @@ declare function queryMenus(client: SuperatomClient, options?: QueryMenusOptions
1740
2039
  message?: string;
1741
2040
  }>;
1742
2041
 
2042
+ /**
2043
+ * User Conversations Service
2044
+ * Thread list + thread history via the `user-conversations` data collection
2045
+ * (same calls as Runtime-react's services/wsMessages/userConversations.ts)
2046
+ */
2047
+
2048
+ /**
2049
+ * A single conversation thread summary, as returned by getUserThreads.
2050
+ * `title` is the opening question of the thread (its earliest prompt).
2051
+ */
2052
+ interface ThreadSummary {
2053
+ threadId: string;
2054
+ title: string;
2055
+ messageCount: number;
2056
+ createdAt: string;
2057
+ updatedAt: string;
2058
+ archived: boolean;
2059
+ config?: {
2060
+ dashboardId?: string;
2061
+ } | null;
2062
+ }
2063
+ /**
2064
+ * One persisted Q&A row inside a thread (the user_conversations table shape).
2065
+ * The full assistant response lives inside `response`.
2066
+ */
2067
+ interface ThreadConversationRow {
2068
+ id: number;
2069
+ userId: string;
2070
+ threadid: string | null;
2071
+ userprompt: string;
2072
+ status?: 'success' | 'error' | 'aborted';
2073
+ response: {
2074
+ id?: string;
2075
+ component?: any;
2076
+ analysis?: string | null;
2077
+ user_prompt?: string;
2078
+ error?: unknown;
2079
+ [key: string]: any;
2080
+ };
2081
+ createdAt: string;
2082
+ updatedAt: string;
2083
+ }
2084
+ /**
2085
+ * List the user's conversation threads, most-recently-active first.
2086
+ * `total` is the user's full thread count (independent of the page window).
2087
+ */
2088
+ declare function getUserThreads(client: SuperatomClient, userId: string, agentId: string | undefined, limit?: number, offset?: number, timeout?: number): Promise<{
2089
+ success: boolean;
2090
+ threads: ThreadSummary[];
2091
+ total: number;
2092
+ error?: string;
2093
+ }>;
2094
+ /**
2095
+ * One thread's title and config, or null when it is not found — and equally when
2096
+ * the backend has no such operation.
2097
+ *
2098
+ * Null for both cases on purpose: a caller only ever asks this to find out what a
2099
+ * thread was started on, and "we cannot tell" and "it was started on nothing" lead
2100
+ * to the same behaviour. So this is safe to call against a backend that has never
2101
+ * heard of it.
2102
+ */
2103
+ /**
2104
+ * One thread, as the backend stores it.
2105
+ *
2106
+ * `attachments` is the files already sent in this chat. It is read for the
2107
+ * per-chat limits in ui/stores/attachmentsStore — a chat has a ceiling on how many
2108
+ * files and how many bytes it can hold across all its questions, and that
2109
+ * cannot be known from the tray alone.
2110
+ */
2111
+ interface ThreadRecord {
2112
+ threadId: string;
2113
+ title: string;
2114
+ config?: {
2115
+ dashboardId?: string;
2116
+ } | null;
2117
+ attachments?: {
2118
+ key?: string;
2119
+ fileName?: string;
2120
+ size?: number;
2121
+ }[] | null;
2122
+ }
2123
+ declare function getThread(client: SuperatomClient, userId: string, agentId: string | undefined, threadId: string, timeout?: number): Promise<ThreadRecord | null>;
2124
+ /**
2125
+ * Delete a whole thread (all its conversations).
2126
+ */
2127
+ declare function deleteThread(client: SuperatomClient, userId: string, threadId: string, clearCache?: boolean, timeout?: number): Promise<{
2128
+ success: boolean;
2129
+ error?: string;
2130
+ message?: string;
2131
+ deletedCount?: number;
2132
+ }>;
2133
+ /**
2134
+ * Delete one saved question/answer, by the question that produced it.
2135
+ *
2136
+ * `clearCache` also drops what was cached for it (query results and embeddings),
2137
+ * so asking the same thing again is answered from the data, not from the old
2138
+ * result. Same call Runtime-react's trash button makes.
2139
+ */
2140
+ declare function deleteUserConversation(client: SuperatomClient, userPrompt: string, userId?: string, clearCache?: boolean, timeout?: number): Promise<{
2141
+ success: boolean;
2142
+ error?: string;
2143
+ message?: string;
2144
+ queriesDeleted?: number;
2145
+ }>;
2146
+ /**
2147
+ * Rename a thread's title.
2148
+ */
2149
+ declare function updateThreadTitle(client: SuperatomClient, userId: string, threadId: string, title: string, timeout?: number): Promise<{
2150
+ success: boolean;
2151
+ error?: string;
2152
+ title?: string;
2153
+ }>;
2154
+ /**
2155
+ * Fetch a page of conversations within a thread, newest-first (offset 0 = the
2156
+ * most recent `limit` messages). `total` is the thread's full message count.
2157
+ */
2158
+ declare function getThreadConversations(client: SuperatomClient, userId: string, agentId: string | undefined, threadId: string, limit?: number, offset?: number, timeout?: number): Promise<{
2159
+ success: boolean;
2160
+ rows: ThreadConversationRow[];
2161
+ total: number;
2162
+ error?: string;
2163
+ }>;
2164
+
2165
+ /**
2166
+ * Project Sources Service
2167
+ *
2168
+ * The data sources a project is connected to — what the sidebar shows as
2169
+ * "Connected to POSTGRES" with the source's own name under it. Read over the
2170
+ * socket from the project's backend, the same way runtime-react reads it.
2171
+ */
2172
+
2173
+ interface ProjectSource {
2174
+ type: string;
2175
+ name: string;
2176
+ /** False when the source is configured but has no running instance. */
2177
+ connected: boolean;
2178
+ }
2179
+ /**
2180
+ * The project's data sources, or an empty list when there are none — and
2181
+ * equally when the backend has no such operation, since both mean there is
2182
+ * nothing to show. Safe against a backend that has never heard of it.
2183
+ */
2184
+ declare function getProjectSources(client: SuperatomClient, projectId: string, timeout?: number): Promise<ProjectSource[]>;
2185
+
1743
2186
  /**
1744
2187
  * Services Index
1745
2188
  * Re-exports all service functions for easy importing
@@ -1752,6 +2195,7 @@ type index_Dashboard = Dashboard;
1752
2195
  type index_Menu = Menu;
1753
2196
  type index_Page = Page;
1754
2197
  declare const index_PageSchema: typeof PageSchema;
2198
+ type index_ProjectSource = ProjectSource;
1755
2199
  type index_QueryArtifactsFilters = QueryArtifactsFilters;
1756
2200
  type index_QueryArtifactsOptions = QueryArtifactsOptions;
1757
2201
  type index_QueryBookmarksOptions = QueryBookmarksOptions;
@@ -1761,12 +2205,23 @@ type index_QueryReportsOptions = QueryReportsOptions;
1761
2205
  type index_QueryUIsOptions = QueryUIsOptions;
1762
2206
  type index_QueryUsersOptions = QueryUsersOptions;
1763
2207
  type index_Report = Report;
2208
+ type index_SaApp = SaApp;
2209
+ type index_SaAppType = SaAppType;
2210
+ type index_SaProject = SaProject;
2211
+ type index_SubmitAnswerFeedbackParams = SubmitAnswerFeedbackParams;
2212
+ type index_ThreadConversationRow = ThreadConversationRow;
2213
+ type index_ThreadRecord = ThreadRecord;
2214
+ type index_ThreadSummary = ThreadSummary;
1764
2215
  type index_UI = UI;
1765
2216
  type index_UpdateBookmarkOptions = UpdateBookmarkOptions;
1766
2217
  type index_User = User;
2218
+ type index_WorkflowDescriptor = WorkflowDescriptor;
2219
+ declare const index_abortUserPromptRequest: typeof abortUserPromptRequest;
1767
2220
  declare const index_createBookmark: typeof createBookmark;
1768
2221
  declare const index_deleteArtifact: typeof deleteArtifact;
1769
2222
  declare const index_deleteBookmark: typeof deleteBookmark;
2223
+ declare const index_deleteThread: typeof deleteThread;
2224
+ declare const index_deleteUserConversation: typeof deleteUserConversation;
1770
2225
  declare const index_getActions: typeof getActions;
1771
2226
  declare const index_getAllArtifacts: typeof getAllArtifacts;
1772
2227
  declare const index_getAllBookmarks: typeof getAllBookmarks;
@@ -1776,13 +2231,21 @@ declare const index_getAllReports: typeof getAllReports;
1776
2231
  declare const index_getAllUIs: typeof getAllUIs;
1777
2232
  declare const index_getArtifact: typeof getArtifact;
1778
2233
  declare const index_getBookmark: typeof getBookmark;
2234
+ declare const index_getChatAgents: typeof getChatAgents;
1779
2235
  declare const index_getChildMenus: typeof getChildMenus;
1780
2236
  declare const index_getDashboard: typeof getDashboard;
1781
2237
  declare const index_getMenu: typeof getMenu;
1782
2238
  declare const index_getMenusHierarchy: typeof getMenusHierarchy;
2239
+ declare const index_getOrgId: typeof getOrgId;
2240
+ declare const index_getProject: typeof getProject;
2241
+ declare const index_getProjectApps: typeof getProjectApps;
2242
+ declare const index_getProjectSources: typeof getProjectSources;
1783
2243
  declare const index_getReport: typeof getReport;
1784
2244
  declare const index_getRootMenus: typeof getRootMenus;
2245
+ declare const index_getThread: typeof getThread;
2246
+ declare const index_getThreadConversations: typeof getThreadConversations;
1785
2247
  declare const index_getUI: typeof getUI;
2248
+ declare const index_getUserThreads: typeof getUserThreads;
1786
2249
  declare const index_injectBundleStyles: typeof injectBundleStyles;
1787
2250
  declare const index_queryArtifacts: typeof queryArtifacts;
1788
2251
  declare const index_queryBookmarks: typeof queryBookmarks;
@@ -1793,12 +2256,17 @@ declare const index_queryUIs: typeof queryUIs;
1793
2256
  declare const index_queryUsers: typeof queryUsers;
1794
2257
  declare const index_requestBundle: typeof requestBundle;
1795
2258
  declare const index_requestData: typeof requestData;
2259
+ declare const index_resetProjectCache: typeof resetProjectCache;
1796
2260
  declare const index_sendComponents: typeof sendComponents;
2261
+ declare const index_sendDashContract: typeof sendDashContract;
1797
2262
  declare const index_sendUserPromptRequest: typeof sendUserPromptRequest;
1798
2263
  declare const index_sendUserPromptSuggestionsRequest: typeof sendUserPromptSuggestionsRequest;
2264
+ declare const index_sendWorkflows: typeof sendWorkflows;
2265
+ declare const index_submitAnswerFeedback: typeof submitAnswerFeedback;
1799
2266
  declare const index_updateBookmark: typeof updateBookmark;
2267
+ declare const index_updateThreadTitle: typeof updateThreadTitle;
1800
2268
  declare namespace index {
1801
- export { type index_Artifact as Artifact, type Binding$1 as Binding, BindingSchema$1 as BindingSchema, type index_Bookmark as Bookmark, type index_CreateBookmarkOptions as CreateBookmarkOptions, type DSLRendererProps$3 as DSLRendererProps, DSLRendererPropsSchema$3 as DSLRendererPropsSchema, type index_Dashboard as Dashboard, type Expression$1 as Expression, ExpressionSchema$1 as ExpressionSchema, type ForDirective$1 as ForDirective, ForDirectiveSchema$1 as ForDirectiveSchema, type index_Menu as Menu, type index_Page as Page, index_PageSchema as PageSchema, type index_QueryArtifactsFilters as QueryArtifactsFilters, type index_QueryArtifactsOptions as QueryArtifactsOptions, type index_QueryBookmarksOptions as QueryBookmarksOptions, type index_QueryDashboardsOptions as QueryDashboardsOptions, type index_QueryMenusOptions as QueryMenusOptions, type index_QueryReportsOptions as QueryReportsOptions, type QuerySpec$1 as QuerySpec, QuerySpecSchema$1 as QuerySpecSchema, type index_QueryUIsOptions as QueryUIsOptions, type index_QueryUsersOptions as QueryUsersOptions, type index_Report as Report, type DSLRendererProps$2 as ReportDSLRendererProps, type index_UI as UI, type UIComponent$1 as UIComponent, UIComponentSchema$1 as UIComponentSchema, type DSLRendererProps$1 as UIDSLRendererProps, type UIElement$1 as UIElement, UIElementSchema$1 as UIElementSchema, type index_UpdateBookmarkOptions as UpdateBookmarkOptions, type index_User as User, index_createBookmark as createBookmark, index_deleteArtifact as deleteArtifact, index_deleteBookmark as deleteBookmark, index_getActions as getActions, index_getAllArtifacts as getAllArtifacts, index_getAllBookmarks as getAllBookmarks, index_getAllDashboards as getAllDashboards, index_getAllMenus as getAllMenus, index_getAllReports as getAllReports, index_getAllUIs as getAllUIs, index_getArtifact as getArtifact, index_getBookmark as getBookmark, index_getChildMenus as getChildMenus, index_getDashboard as getDashboard, index_getMenu as getMenu, index_getMenusHierarchy as getMenusHierarchy, index_getReport as getReport, index_getRootMenus as getRootMenus, index_getUI as getUI, index_injectBundleStyles as injectBundleStyles, index_queryArtifacts as queryArtifacts, index_queryBookmarks as queryBookmarks, index_queryDashboards as queryDashboards, index_queryMenus as queryMenus, index_queryReports as queryReports, index_queryUIs as queryUIs, index_queryUsers as queryUsers, index_requestBundle as requestBundle, index_requestData as requestData, index_sendComponents as sendComponents, index_sendUserPromptRequest as sendUserPromptRequest, index_sendUserPromptSuggestionsRequest as sendUserPromptSuggestionsRequest, index_updateBookmark as updateBookmark };
2269
+ export { type index_Artifact as Artifact, type Binding$1 as Binding, BindingSchema$1 as BindingSchema, type index_Bookmark as Bookmark, type index_CreateBookmarkOptions as CreateBookmarkOptions, type DSLRendererProps$3 as DSLRendererProps, DSLRendererPropsSchema$3 as DSLRendererPropsSchema, type index_Dashboard as Dashboard, type Expression$1 as Expression, ExpressionSchema$1 as ExpressionSchema, type ForDirective$1 as ForDirective, ForDirectiveSchema$1 as ForDirectiveSchema, type index_Menu as Menu, type index_Page as Page, index_PageSchema as PageSchema, type index_ProjectSource as ProjectSource, type index_QueryArtifactsFilters as QueryArtifactsFilters, type index_QueryArtifactsOptions as QueryArtifactsOptions, type index_QueryBookmarksOptions as QueryBookmarksOptions, type index_QueryDashboardsOptions as QueryDashboardsOptions, type index_QueryMenusOptions as QueryMenusOptions, type index_QueryReportsOptions as QueryReportsOptions, type QuerySpec$1 as QuerySpec, QuerySpecSchema$1 as QuerySpecSchema, type index_QueryUIsOptions as QueryUIsOptions, type index_QueryUsersOptions as QueryUsersOptions, type index_Report as Report, type DSLRendererProps$2 as ReportDSLRendererProps, type index_SaApp as SaApp, type index_SaAppType as SaAppType, type index_SaProject as SaProject, type index_SubmitAnswerFeedbackParams as SubmitAnswerFeedbackParams, type index_ThreadConversationRow as ThreadConversationRow, type index_ThreadRecord as ThreadRecord, type index_ThreadSummary as ThreadSummary, type index_UI as UI, type UIComponent$1 as UIComponent, UIComponentSchema$1 as UIComponentSchema, type DSLRendererProps$1 as UIDSLRendererProps, type UIElement$1 as UIElement, UIElementSchema$1 as UIElementSchema, type index_UpdateBookmarkOptions as UpdateBookmarkOptions, type index_User as User, type index_WorkflowDescriptor as WorkflowDescriptor, index_abortUserPromptRequest as abortUserPromptRequest, index_createBookmark as createBookmark, index_deleteArtifact as deleteArtifact, index_deleteBookmark as deleteBookmark, index_deleteThread as deleteThread, index_deleteUserConversation as deleteUserConversation, index_getActions as getActions, index_getAllArtifacts as getAllArtifacts, index_getAllBookmarks as getAllBookmarks, index_getAllDashboards as getAllDashboards, index_getAllMenus as getAllMenus, index_getAllReports as getAllReports, index_getAllUIs as getAllUIs, index_getArtifact as getArtifact, index_getBookmark as getBookmark, index_getChatAgents as getChatAgents, index_getChildMenus as getChildMenus, index_getDashboard as getDashboard, index_getMenu as getMenu, index_getMenusHierarchy as getMenusHierarchy, index_getOrgId as getOrgId, index_getProject as getProject, index_getProjectApps as getProjectApps, index_getProjectSources as getProjectSources, index_getReport as getReport, index_getRootMenus as getRootMenus, index_getThread as getThread, index_getThreadConversations as getThreadConversations, index_getUI as getUI, index_getUserThreads as getUserThreads, index_injectBundleStyles as injectBundleStyles, index_queryArtifacts as queryArtifacts, index_queryBookmarks as queryBookmarks, index_queryDashboards as queryDashboards, index_queryMenus as queryMenus, index_queryReports as queryReports, index_queryUIs as queryUIs, index_queryUsers as queryUsers, index_requestBundle as requestBundle, index_requestData as requestData, index_resetProjectCache as resetProjectCache, index_sendComponents as sendComponents, index_sendDashContract as sendDashContract, index_sendUserPromptRequest as sendUserPromptRequest, index_sendUserPromptSuggestionsRequest as sendUserPromptSuggestionsRequest, index_sendWorkflows as sendWorkflows, index_submitAnswerFeedback as submitAnswerFeedback, index_updateBookmark as updateBookmark, index_updateThreadTitle as updateThreadTitle };
1802
2270
  }
1803
2271
 
1804
2272
  type MessageHandler = (message: Message) => void;
@@ -1823,6 +2291,10 @@ declare class SuperatomClient {
1823
2291
  private config;
1824
2292
  private connectPromise;
1825
2293
  private connectResolve;
2294
+ private lastComponents;
2295
+ private lastWorkflows;
2296
+ private getAccessToken;
2297
+ private fetchingToken;
1826
2298
  private heartbeatInterval;
1827
2299
  private pongDeadline;
1828
2300
  private readonly HEARTBEAT_INTERVAL_MS;
@@ -1839,6 +2311,12 @@ declare class SuperatomClient {
1839
2311
  * Get WebSocket URL with query parameters
1840
2312
  */
1841
2313
  private getWebSocketUrl;
2314
+ /**
2315
+ * Swap the session token used on the next (re)connect.
2316
+ * Deliberately does NOT re-dial a live socket: the relay only checks the
2317
+ * token at handshake, so an open connection stays valid.
2318
+ */
2319
+ setToken(token: string): void;
1842
2320
  /**
1843
2321
  * Calculate reconnection delay with exponential backoff
1844
2322
  */
@@ -1885,6 +2363,14 @@ declare class SuperatomClient {
1885
2363
  * window 'online' / 'visibilitychange' handlers.
1886
2364
  */
1887
2365
  forceReconnect(): Promise<void>;
2366
+ /**
2367
+ * Drop the current socket without triggering its handlers: they are detached
2368
+ * first, so its eventual real close is a no-op (on Linux/Chrome that close
2369
+ * can arrive 30-60s later). Returns whether it was open.
2370
+ */
2371
+ private discardSocket;
2372
+ /** A connection attempt is under way — fetching the session token, or the socket handshake. */
2373
+ private isConnecting;
1888
2374
  /**
1889
2375
  * Attach window-level listeners that catch network changes faster than
1890
2376
  * the socket's own onclose. The browser's onclose for a half-open TCP can
@@ -1908,6 +2394,16 @@ declare class SuperatomClient {
1908
2394
  * The Promise never rejects - failures are logged silently and auto-reconnect is triggered
1909
2395
  */
1910
2396
  connect(): Promise<void>;
2397
+ /**
2398
+ * Get a valid session token, then open the socket. The relay checks the token
2399
+ * only at handshake, so every (re)connect must present one that is still valid.
2400
+ *
2401
+ * A fatal auth failure (see SuperAtomAuthError.fatal) stops reconnecting — the
2402
+ * session reports it to the host, and retrying would only repeat it. Anything
2403
+ * else goes through the normal back-off.
2404
+ */
2405
+ private openWithFreshToken;
2406
+ private openSocket;
1911
2407
  /**
1912
2408
  * Disconnect from WebSocket server
1913
2409
  */
@@ -1992,8 +2488,25 @@ declare class SuperatomClient {
1992
2488
  * @param userId - User ID for the request
1993
2489
  * @param responseMode - 'component' for component response (default), 'text' for text streaming
1994
2490
  * @param onStream - Optional callback for streaming text chunks (only for text mode)
2491
+ * @param onNarration - Optional callback for narrator progress updates (any mode)
1995
2492
  */
1996
- sendUserPromptRequest(prompt: string, threadId: string, uiBlockId: string, userId?: string, responseMode?: 'component' | 'text', onStream?: (chunk: string) => void, timeout?: number): Promise<Message>;
2493
+ sendUserPromptRequest(prompt: string, threadId: string, uiBlockId: string, userId?: string, responseMode?: 'component' | 'text', onStream?: (chunk: string) => void, timeout?: number,
2494
+ /** Where the question was asked from — the dashboard on screen, when there is one. */
2495
+ context?: PromptContext, onNarration?: (update: UserPromptNarration) => void,
2496
+ /** The chat agent this question belongs to. A new thread is saved against it. */
2497
+ agentId?: string,
2498
+ /** Files this question carries, already uploaded — references only. */
2499
+ attachments?: {
2500
+ key: string;
2501
+ fileName: string;
2502
+ size: number;
2503
+ contentType?: string;
2504
+ }[]): Promise<Message>;
2505
+ /**
2506
+ * Abort an in-flight user prompt request (frontend "Stop" button).
2507
+ * Fire-and-forget — cancels the backend work for the given uiBlockId.
2508
+ */
2509
+ abortUserPromptRequest(uiBlockId: string, threadId?: string): void;
1997
2510
  /**
1998
2511
  * Send a user prompt suggestions request
1999
2512
  * Delegates to user prompt service
@@ -2007,6 +2520,8 @@ declare class SuperatomClient {
2007
2520
  requestBundle(options?: {
2008
2521
  timeout?: number;
2009
2522
  onProgress?: (progress: number) => void;
2523
+ devbundlereq?: boolean;
2524
+ /** @deprecated Use `devbundlereq` */
2010
2525
  devbundle?: boolean;
2011
2526
  }): Promise<string>;
2012
2527
  /**
@@ -2014,6 +2529,22 @@ declare class SuperatomClient {
2014
2529
  * Delegates to component service
2015
2530
  */
2016
2531
  sendComponents(components: any[]): Promise<void>;
2532
+ /**
2533
+ * Register the dashboard contract with the backend.
2534
+ *
2535
+ * Required before a program dashboard can be built: without it the backend has
2536
+ * no record of which components a generated dashboard may import. The project
2537
+ * bundle calls this during its own init, so it has to exist on the client the
2538
+ * bundle is handed.
2539
+ */
2540
+ sendDashContract(components: any[]): void;
2541
+ /**
2542
+ * Send registered workflow descriptors to the backend so the main agent
2543
+ * can route prompts to them. Each descriptor is the routing metadata for a
2544
+ * pre-built workflow component (id, name, description, whenToUse,
2545
+ * propsSchema, defaultProps).
2546
+ */
2547
+ sendWorkflows(workflows: WorkflowDescriptor[]): Promise<void>;
2017
2548
  /**
2018
2549
  * Request data from a collection
2019
2550
  * Delegates to data service
@@ -2330,6 +2861,140 @@ declare class SuperatomClient {
2330
2861
  private log;
2331
2862
  }
2332
2863
 
2864
+ /**
2865
+ * SDK sign-in with the customer's own login.
2866
+ *
2867
+ * The host app hands us `getToken()` — a function THEY write that asks their
2868
+ * backend for a short-lived JWT signed with their SDK secret. We exchange it at
2869
+ * sa-api (`POST /auth/sdk/exchange`) for OUR 15-minute access token, which the
2870
+ * WebSocket relay accepts at handshake.
2871
+ *
2872
+ * There is no refresh token in this mode: the customer's own session is the
2873
+ * long-lived one. To renew we simply call `getToken()` again and re-exchange —
2874
+ * before every (re)connect when ours is about to expire, and on a timer a
2875
+ * couple of minutes ahead, so a reconnect never has to wait for it.
2876
+ *
2877
+ * Failures are split in two:
2878
+ * - fatal (their token rejected, SDK not enabled, user deactivated, or
2879
+ * `getToken()` itself failing): reported once through `onAuthError`, and
2880
+ * every later call fails fast with the same error — no loop against their
2881
+ * backend or ours — until `reset()`.
2882
+ * - transient (network, sa-api 5xx / 429): thrown to the caller, whose normal
2883
+ * reconnect back-off retries.
2884
+ */
2885
+ declare const DEFAULT_API_URL = "https://sa-api.superatom.ai";
2886
+ /** The signed-in user, as returned by the exchange. `id` is OUR user id. */
2887
+ interface SdkUser {
2888
+ id: string;
2889
+ email: string;
2890
+ name: string;
2891
+ /** The role this session acts with — always "member" for SDK sessions. */
2892
+ role: string;
2893
+ /** Their own role names, from the `roles` claim. */
2894
+ externalRoles: string[];
2895
+ }
2896
+ type SuperAtomAuthErrorCode =
2897
+ /** `getToken()` threw or returned no token. */
2898
+ 'get_token_failed'
2899
+ /** sa-api refused the token (400 / 401 / 403). `status` and `message` say why. */
2900
+ | 'exchange_rejected'
2901
+ /** sa-api unavailable (5xx / 429). Retried. */
2902
+ | 'exchange_unavailable'
2903
+ /** Could not reach sa-api, or it timed out. Retried. */
2904
+ | 'network';
2905
+ declare class SuperAtomAuthError extends Error {
2906
+ readonly code: SuperAtomAuthErrorCode;
2907
+ /**
2908
+ * Why Superatom refused it, verbatim — `expired`, `bad_signature`,
2909
+ * `bad_access_filters`, `inactive`, … Present for `exchange_rejected` only.
2910
+ */
2911
+ readonly reason?: string;
2912
+ /** HTTP status from sa-api, when there was a response. */
2913
+ readonly status?: number;
2914
+ /** True when retrying cannot help — see the module comment. */
2915
+ readonly fatal: boolean;
2916
+ constructor(code: SuperAtomAuthErrorCode, message: string, options: {
2917
+ status?: number;
2918
+ reason?: string;
2919
+ fatal: boolean;
2920
+ cause?: unknown;
2921
+ });
2922
+ }
2923
+ interface SdkSessionOptions {
2924
+ projectId: string;
2925
+ /** Returns the customer-signed JWT. Written by the host app. */
2926
+ getToken: () => Promise<string> | string;
2927
+ /** Called once for each fatal failure. */
2928
+ onAuthError?: (error: SuperAtomAuthError) => void;
2929
+ /** Called after each successful exchange. */
2930
+ onSession?: (user: SdkUser) => void;
2931
+ /**
2932
+ * Sign-in keeps failing for a retryable reason (Superatom unreachable or down),
2933
+ * after a couple of attempts. Called again on each further failure, and with
2934
+ * null once a sign-in succeeds.
2935
+ */
2936
+ onRetrying?: (error: SuperAtomAuthError | null) => void;
2937
+ /** True while an exchange is in flight, false when it finishes either way. */
2938
+ onSigningIn?: (signingIn: boolean) => void;
2939
+ /** sa-api base URL. Default: prod. */
2940
+ apiUrl?: string;
2941
+ debug?: boolean;
2942
+ }
2943
+ declare class SdkSession {
2944
+ private readonly opts;
2945
+ private readonly apiUrl;
2946
+ private token;
2947
+ private expiresAt;
2948
+ private currentUser;
2949
+ /** The one renewal in flight — every caller shares it. */
2950
+ private inFlight;
2951
+ private fatalError;
2952
+ /** Retryable failures in a row; reset by a successful exchange. */
2953
+ private retries;
2954
+ private renewTimer;
2955
+ private stopped;
2956
+ constructor(opts: SdkSessionOptions);
2957
+ /** The sa-api this session talks to, so callers need not re-derive it. */
2958
+ get baseUrl(): string;
2959
+ get user(): SdkUser | null;
2960
+ /** The fatal error that stopped the session, if any. */
2961
+ get error(): SuperAtomAuthError | null;
2962
+ /**
2963
+ * A token with at least a minute left — the cached one, or a fresh exchange.
2964
+ * Rejects with SuperAtomAuthError.
2965
+ */
2966
+ getAccessToken(): Promise<string>;
2967
+ /**
2968
+ * Start over: forget the session held and let the next `getAccessToken()`
2969
+ * exchange a brand new one.
2970
+ *
2971
+ * Called by `reconnect()`, and the cached token is dropped deliberately. A
2972
+ * token carries what the host's backend put in it — who the user is, and
2973
+ * what data they may see — and those can change while the tab stays open: a
2974
+ * customer picked from a dropdown, a role granted, an account switched. The
2975
+ * host says so by calling `reconnect()`, and if the cached token were kept
2976
+ * the old claims would stand until it expired, which looks exactly like the
2977
+ * filter not working.
2978
+ *
2979
+ * The cost is one extra round trip to the host's `getToken` and to sa-api.
2980
+ * That is the right price for "sign me in again" meaning what it says.
2981
+ */
2982
+ reset(): void;
2983
+ /** Stop renewing — the host unmounted or disconnected. */
2984
+ stop(): void;
2985
+ private renew;
2986
+ private exchange;
2987
+ /** Record a failure: a fatal one stops the session and is reported once. */
2988
+ private fail;
2989
+ /**
2990
+ * Renew in the background ahead of expiry. Timers are paused while the machine
2991
+ * sleeps and fire on wake; a reconnect after wake also renews first if needed.
2992
+ */
2993
+ private scheduleRenew;
2994
+ private clearRenewTimer;
2995
+ private log;
2996
+ }
2997
+
2333
2998
  /**
2334
2999
  * Component mount function type
2335
3000
  */
@@ -3423,13 +4088,13 @@ interface ExtendedDSLRendererProps extends DSLRendererProps {
3423
4088
  onNavigate?: NavigationHandler;
3424
4089
  handlers?: Record<string, Function>;
3425
4090
  }
3426
- declare const DSLRenderer: React.FC<ExtendedDSLRendererProps>;
4091
+ declare const DSLRenderer: React__default.FC<ExtendedDSLRendererProps>;
3427
4092
 
3428
4093
  interface ComponentDefinition {
3429
4094
  id: string;
3430
4095
  name: string;
3431
4096
  head: string;
3432
- COMP: React.ComponentType<any>;
4097
+ COMP: React__default.ComponentType<any>;
3433
4098
  dependencies?: string[];
3434
4099
  version?: string;
3435
4100
  }
@@ -3449,10 +4114,10 @@ declare const useDynamicComponent: (componentType: string) => {
3449
4114
  isLoaded: boolean;
3450
4115
  error: string | null;
3451
4116
  };
3452
- declare const DynamicComponent: React.FC<{
4117
+ declare const DynamicComponent: React__default.FC<{
3453
4118
  type: string;
3454
4119
  props?: any;
3455
- children?: React.ReactNode;
4120
+ children?: React__default.ReactNode;
3456
4121
  }>;
3457
4122
 
3458
4123
  interface DSLErrorBoundaryProps {
@@ -3460,7 +4125,7 @@ interface DSLErrorBoundaryProps {
3460
4125
  fallback?: ReactNode;
3461
4126
  elementType?: string;
3462
4127
  elementKey?: string | number;
3463
- onError?: (error: Error, errorInfo: React.ErrorInfo) => void;
4128
+ onError?: (error: Error, errorInfo: React__default.ErrorInfo) => void;
3464
4129
  skipBoundary?: boolean;
3465
4130
  }
3466
4131
  interface DSLErrorBoundaryState {
@@ -3471,14 +4136,196 @@ interface DSLErrorBoundaryState {
3471
4136
  declare class DSLErrorBoundary extends Component$1<DSLErrorBoundaryProps, DSLErrorBoundaryState> {
3472
4137
  constructor(props: DSLErrorBoundaryProps);
3473
4138
  static getDerivedStateFromError(error: Error): DSLErrorBoundaryState;
3474
- componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void;
3475
- render(): string | number | boolean | Iterable<React.ReactNode> | react_jsx_runtime.JSX.Element | null | undefined;
4139
+ componentDidCatch(error: Error, errorInfo: React__default.ErrorInfo): void;
4140
+ render(): string | number | boolean | Iterable<React__default.ReactNode> | react_jsx_runtime.JSX.Element | null | undefined;
3476
4141
  }
3477
4142
  declare const withConditionalErrorBoundary: (component: ReactNode, elementType: string, elementKey?: string | number, forceWrap?: boolean) => ReactNode;
3478
4143
 
4144
+ /**
4145
+ * Register every component exposed on window.SUPERATOM.COMPONENTS into COMP_REGISTRY.
4146
+ * Safe to call repeatedly — each call reflects the currently loaded bundle.
4147
+ */
3479
4148
  declare function registerBundleComponents(): number;
4149
+ /**
4150
+ * Remove all bundle components added by registerBundleComponents from COMP_REGISTRY.
4151
+ */
3480
4152
  declare function resetRegistration(): void;
3481
4153
 
4154
+ /**
4155
+ * 'dashboard' is a dashboard saved in Superatom (sa-api); 'bundle-dashboard' is
4156
+ * one the project bundle ships as a component (see useBundleDashboards).
4157
+ */
4158
+ type AssistantView = 'home' | 'chat' | 'dashboard' | 'report' | 'bundle-dashboard' | 'bookmark';
4159
+ interface AssistantNavigation {
4160
+ view: AssistantView;
4161
+ dashboardId: string | null;
4162
+ reportId: string | null;
4163
+ bundleDashboard: string | null;
4164
+ bookmarkId: number | null;
4165
+ setView: (view: AssistantView) => void;
4166
+ /**
4167
+ * Send what is in the composer, from wherever the reader is.
4168
+ *
4169
+ * `sendMessage` from the session only sends; this also decides where the
4170
+ * answer should appear, which depends on the view and is therefore
4171
+ * navigation's business rather than the composer's.
4172
+ */
4173
+ send: () => void;
4174
+ /** Open a thread, and the dashboard it belongs to if it has one. */
4175
+ openThread: (threadId: string) => void;
4176
+ /** Start a new conversation and show it. */
4177
+ newChat: () => void;
4178
+ goHome: () => void;
4179
+ openDashboard: (dashboardId: string) => void;
4180
+ openReport: (reportId: string) => void;
4181
+ openBundleDashboard: (key: string) => void;
4182
+ openBookmark: (bookmarkId: number) => void;
4183
+ }
4184
+ interface AssistantNavigationProviderProps {
4185
+ children: ReactNode;
4186
+ /** Which view it opens on. Default 'home'. */
4187
+ defaultView?: AssistantView;
4188
+ view?: AssistantView;
4189
+ onViewChange?: (view: AssistantView) => void;
4190
+ dashboardId?: string | null;
4191
+ onDashboardChange?: (dashboardId: string | null) => void;
4192
+ reportId?: string | null;
4193
+ onReportChange?: (reportId: string | null) => void;
4194
+ bundleDashboard?: string | null;
4195
+ onBundleDashboardChange?: (key: string | null) => void;
4196
+ }
4197
+ /**
4198
+ * Where the assistant is, and how to move it.
4199
+ *
4200
+ * This used to live inside `SuperatomAssistant`, which meant a host composing
4201
+ * the pieces had to write it again: five pieces of state, and a thread click
4202
+ * handler that has to know a thread can belong to a dashboard. That is not
4203
+ * host code — it is how this SDK's screens relate to each other — and every
4204
+ * copy of it was a chance to leave something out. The sidebar lost its
4205
+ * dashboards exactly that way.
4206
+ *
4207
+ * `SuperatomSurface` provides one automatically, so `<Sidebar />` on its own
4208
+ * already navigates. A host that wants to drive navigation itself reads this
4209
+ * hook and ignores the parts it does not want.
4210
+ */
4211
+ declare function AssistantNavigationProvider({ children, defaultView, view: viewProp, onViewChange, dashboardId: dashboardIdProp, onDashboardChange, reportId: reportIdProp, onReportChange, bundleDashboard: bundleDashboardProp, onBundleDashboardChange, }: AssistantNavigationProviderProps): react_jsx_runtime.JSX.Element;
4212
+ /**
4213
+ * Where the assistant is. Throws outside a `SuperatomSurface`, which is what
4214
+ * provides it — a navigation that nothing renders from is a bug, not a default.
4215
+ */
4216
+ declare function useAssistantNavigation(): AssistantNavigation;
4217
+ /** True when a navigation is already above this component. */
4218
+ declare function useHasAssistantNavigation(): boolean;
4219
+
4220
+ /**
4221
+ * No session options here. `projectId`, `agentId` and `getToken` are given to
4222
+ * the `SuperatomProvider` this component must be rendered under — one session
4223
+ * per app, made in one place. These props are about what the assistant shows.
4224
+ */
4225
+ interface SuperatomAssistantProps {
4226
+ className?: string;
4227
+ /** Hidden when the host has navigation of its own. Default true. */
4228
+ showSidebar?: boolean;
4229
+ /**
4230
+ * The project's logo at the top of the sidebar. Default true.
4231
+ *
4232
+ * A host whose own chrome already carries its branding turns this off rather
4233
+ * than showing the customer two logos one above the other.
4234
+ */
4235
+ showSidebarLogo?: boolean;
4236
+ /**
4237
+ * Let a question carry files — the "+" in the composer. Default false.
4238
+ *
4239
+ * Off unless asked for, because an assistant that accepts files is a
4240
+ * decision about the product, not about the SDK: an agent that does nothing
4241
+ * with an attachment should not invite one. Both `projectId` and `agentId`
4242
+ * are needed as well, since an upload is addressed to them.
4243
+ */
4244
+ enableAttachments?: boolean;
4245
+ /**
4246
+ * Which view it opens on. Default 'home' — the landing page, with the
4247
+ * project's dashboards and a composer on it. Pass 'chat' for an assistant
4248
+ * that is only a conversation.
4249
+ */
4250
+ defaultView?: 'home' | 'chat';
4251
+ /** Shown while the connection and the project bundle are still coming up. */
4252
+ connectingText?: string;
4253
+ /** Placeholder for an empty conversation. Nothing is shown unless it is set. */
4254
+ emptyText?: string;
4255
+ /** Replaces the built-in greeting on an empty chat. */
4256
+ emptyState?: ReactNode;
4257
+ /**
4258
+ * Follow-up questions below a dashboard: the dashboard, its thread under it,
4259
+ * the composer below both, scrolling as one page.
4260
+ *
4261
+ * On by default, for every dashboard. Pass false for a dashboard that is
4262
+ * only to be looked at — the page then renders on its own, with the composer
4263
+ * still there to start an ordinary chat.
4264
+ */
4265
+ dashboardFollowUps?: boolean;
4266
+ /**
4267
+ * Render inside a shadow root, so the host page's CSS cannot reach in.
4268
+ *
4269
+ * On by default. Scoping the stylesheet to `.sa-ui` wins the collisions it can
4270
+ * — a bare `.btn` against our `.sa-ui .btn` — but it cannot win against a
4271
+ * host's bare element rules, and a page that styles `button` or `input`
4272
+ * directly reaches our components whatever our selectors say. Only a boundary
4273
+ * stops that, so it is the default rather than something a host has to know
4274
+ * to ask for.
4275
+ *
4276
+ * The escape hatch stays because the boundary has real costs: the document
4277
+ * can no longer see our elements, so a host script doing
4278
+ * `document.querySelector` inside the assistant, an analytics or a11y tool
4279
+ * that walks the DOM, or a listener reading `event.target` on `document` all
4280
+ * see less than they did. A host that hits one of those sets this to `false`
4281
+ * and is back to scoping alone, rather than having to pin an old version.
4282
+ */
4283
+ shadowDom?: boolean;
4284
+ /** Which view is showing. Uncontrolled when absent — see `defaultView`. */
4285
+ view?: AssistantView;
4286
+ onViewChange?: (view: AssistantView) => void;
4287
+ /** The open thread, or null for a new chat. Uncontrolled when absent. */
4288
+ threadId?: string | null;
4289
+ onThreadChange?: (threadId: string | null) => void;
4290
+ /** The open dashboard. Uncontrolled when absent. */
4291
+ dashboardId?: string | null;
4292
+ onDashboardChange?: (dashboardId: string | null) => void;
4293
+ /** The open report. Uncontrolled when absent. */
4294
+ reportId?: string | null;
4295
+ onReportChange?: (reportId: string | null) => void;
4296
+ /**
4297
+ * The open bundle dashboard — the key of a project-bundle component that
4298
+ * declares `Metadata.dashboard`. Uncontrolled when absent.
4299
+ */
4300
+ bundleDashboard?: string | null;
4301
+ onBundleDashboardChange?: (key: string | null) => void;
4302
+ }
4303
+
4304
+ /**
4305
+ * The whole assistant, composed.
4306
+ *
4307
+ * The SDK has always been a component kit: a host takes `useSuperAtom`,
4308
+ * `Sidebar`, `MessageList` and `ChatInput` and arranges them. That is still the
4309
+ * way to build something of your own shape, and nothing here replaces it.
4310
+ *
4311
+ * What it costs is that every app arranges the same five components the same
4312
+ * way and has to get the same details right — which view is showing, that the
4313
+ * composer is a sibling of the page and not a child of it, that the two boxes
4314
+ * around it all are a row and a column with `min-h-0`. This component is that
4315
+ * arrangement, once, inside the SDK:
4316
+ *
4317
+ * <SuperatomAssistant />
4318
+ *
4319
+ * It composes the exported components rather than reimplementing them, so
4320
+ * there is one implementation of the chat and two ways to reach it. That now
4321
+ * includes the navigation and the sidebar's wiring: this component used to
4322
+ * hold its own copy of both, and a composed layout had to be written against
4323
+ * the same rules by hand — which is how one lost its dashboards and its
4324
+ * bookmarks without anyone noticing. Both read `AssistantNavigationProvider`
4325
+ * now, so they cannot disagree.
4326
+ */
4327
+ declare function SuperatomAssistant({ className, shadowDom, defaultView, view, onViewChange, dashboardId, onDashboardChange, reportId, onReportChange, bundleDashboard, onBundleDashboardChange, ...rest }: SuperatomAssistantProps): react_jsx_runtime.JSX.Element;
4328
+
3482
4329
  interface ChatMessage {
3483
4330
  id: string;
3484
4331
  role: 'user' | 'assistant';
@@ -3491,14 +4338,111 @@ interface ChatMessage {
3491
4338
  isLoading?: boolean;
3492
4339
  isStreaming?: boolean;
3493
4340
  isTextOnlyResponse?: boolean;
3494
- }
4341
+ aborted?: boolean;
4342
+ fromHistory?: boolean;
4343
+ /**
4344
+ * The saved conversation row's `response`, carried as it came off the wire.
4345
+ *
4346
+ * Nothing renders from this — every reader works off the mapped fields above.
4347
+ * It exists so bookmarking can store the response *verbatim* rather than
4348
+ * reassembling it from the parts that happened to be mapped, which silently
4349
+ * dropped whatever the backend had added since. Set only on a message
4350
+ * rehydrated from history, where the saved row is in hand.
4351
+ */
4352
+ rawResponse?: Record<string, unknown>;
4353
+ /**
4354
+ * The narrator's progress while the answer was being worked out — "reading
4355
+ * the schema", "running the query". Shown live under the question, then
4356
+ * collapsed into a "Steps taken" accordion once the answer is in. Absent for
4357
+ * a backend that does not narrate, which renders exactly as before.
4358
+ */
4359
+ narration?: {
4360
+ elapsedMs: number;
4361
+ text: string;
4362
+ }[];
4363
+ /**
4364
+ * Files the answer handed over, as references — the id, the name, and enough
4365
+ * to label the tile. The download link is minted per press, so it is not here;
4366
+ * see ui/components/FileDownloads.
4367
+ */
4368
+ generatedFiles?: {
4369
+ id: string;
4370
+ fileName: string;
4371
+ size?: number;
4372
+ version?: number;
4373
+ }[];
4374
+ /**
4375
+ * Files the question carried up, named on the user's own bubble so it is
4376
+ * clear afterwards what the answer was given to work from.
4377
+ */
4378
+ attachments?: {
4379
+ key: string;
4380
+ fileName: string;
4381
+ size: number;
4382
+ contentType?: string;
4383
+ }[];
4384
+ /** When this was said. ISO 8601; `createdAt` for a message read back from a thread. */
4385
+ timestamp?: string;
4386
+ /**
4387
+ * How long the answer took, saved with it.
4388
+ *
4389
+ * Only for a message read back from history: a response this bubble watched
4390
+ * being generated has its own live timer, and "now − start" on a rehydrated
4391
+ * one would measure its age instead.
4392
+ */
4393
+ durationMs?: number;
4394
+ }
3495
4395
 
3496
4396
  interface UseSuperAtomOptions {
4397
+ /** A Superatom session token, passed directly (our own apps). Use `getToken` for SDK sign-in instead. */
3497
4398
  token?: string;
3498
4399
  userId?: string;
3499
4400
  projectId: string;
4401
+ /**
4402
+ * SDK sign-in with your own login: return a short-lived JWT for the signed-in
4403
+ * user, signed by YOUR backend with your Superatom SDK secret. Called at start
4404
+ * and again whenever the session needs renewing — e.g.
4405
+ * `() => fetch('/api/superatom-token').then(r => r.text())`.
4406
+ */
4407
+ getToken?: () => Promise<string> | string;
4408
+ /**
4409
+ * Called when sign-in fails in a way retrying cannot fix: `getToken` threw, or
4410
+ * Superatom refused the token (invalid, SDK not enabled, user deactivated).
4411
+ * The SDK stops reconnecting; call `reconnect()` once the user can sign in again.
4412
+ */
4413
+ onAuthError?: (error: SuperAtomAuthError) => void;
4414
+ /**
4415
+ * Which chat agent this assistant is.
4416
+ *
4417
+ * A project can hold more than one — a shipments agent and an audits agent,
4418
+ * say — and a thread belongs to the one it was asked to. The sidebar lists
4419
+ * only this agent's threads, a new thread is saved against it, and so is a
4420
+ * bookmark.
4421
+ *
4422
+ * Required, and it used to be optional. A project with one agent resolves it
4423
+ * by itself, which made omitting it look safe — and on a project with two it
4424
+ * silently stopped scoping anything: every agent's threads in one list, new
4425
+ * ones tagged with none, bookmarks saved with a null agent. A type that says
4426
+ * "optional" while the runtime quietly misbehaves is the worst of both, so
4427
+ * the resolve stays as a convenience for the single-agent case and the
4428
+ * answer is now always asked for.
4429
+ */
4430
+ agentId: string;
4431
+ /** sa-api URL. Default: prod. For testing against dev / local only. */
4432
+ apiUrl?: string;
4433
+ /** WebSocket URL. Default: prod. For testing against dev / local only. */
4434
+ wsUrl?: string;
3500
4435
  debug?: boolean;
4436
+ /** Stream the answer as it is written. On by default; false waits for the whole reply. */
3501
4437
  streaming?: boolean;
4438
+ /**
4439
+ * Internal. False makes this instance inert: no sign-in, no socket, no
4440
+ * bundle. `useSuperAtom` calls the implementation either way so the hook
4441
+ * order never changes, then returns the provider's session instead of this
4442
+ * one — React forbids calling a hook conditionally, so the switch has to be
4443
+ * in what the hook does, not whether it runs.
4444
+ */
4445
+ enabled?: boolean;
3502
4446
  }
3503
4447
  interface UseSuperAtomReturn {
3504
4448
  bundleReady: boolean;
@@ -3506,9 +4450,127 @@ interface UseSuperAtomReturn {
3506
4450
  input: string;
3507
4451
  setInput: (value: string) => void;
3508
4452
  sendMessage: () => void;
4453
+ /** A question is in flight in the thread on screen. */
3509
4454
  isSending: boolean;
4455
+ /**
4456
+ * Stop the in-flight response in the thread on screen (keeps any partial
4457
+ * answer, labels it "Stopped"). A question answering in another thread is
4458
+ * left running.
4459
+ */
4460
+ abortRequest: () => void;
4461
+ /**
4462
+ * Threads whose answer arrived while the user was looking at something else.
4463
+ * Cleared when the thread is opened — what the sidebar's unread dot reads.
4464
+ */
4465
+ unreadThreadIds: Set<string>;
4466
+ /**
4467
+ * Threads with a question in flight right now — what the sidebar's spinner
4468
+ * reads, so a thread answering in the background is visibly busy.
4469
+ */
4470
+ respondingThreadIds: Set<string>;
4471
+ /** The open thread has older messages on the server than have been loaded. */
4472
+ hasMoreMessages: boolean;
4473
+ /** A page of older messages is being fetched. */
4474
+ isLoadingOlderMessages: boolean;
4475
+ /** Prepend the next page of older messages in the open thread. */
4476
+ loadOlderMessages: () => void;
4477
+ /**
4478
+ * Delete a bookmark by its id. The list itself is read from the bookmarks
4479
+ * store (`useBookmarks`), which this keeps in step.
4480
+ */
4481
+ removeBookmark: (id: number) => Promise<{
4482
+ success: boolean;
4483
+ error?: string;
4484
+ }>;
4485
+ /** More bookmarks match than have been loaded. */
4486
+ hasMoreBookmarks: boolean;
4487
+ /** A page of bookmarks is being fetched. */
4488
+ isLoadingBookmarks: boolean;
4489
+ /** Append the next page of bookmarks — what the sidebar calls as it scrolls. */
4490
+ loadMoreBookmarks: () => void;
4491
+ /** The user's conversation threads, most recent first */
4492
+ threads: ThreadSummary[];
4493
+ /** More threads exist on the server than have been loaded. */
4494
+ hasMoreThreads: boolean;
4495
+ /** A page of threads is being fetched. */
4496
+ isLoadingThreads: boolean;
4497
+ /** Append the next page of threads — what the sidebar calls as it scrolls. */
4498
+ loadMoreThreads: () => void;
4499
+ /** Thread the chat is currently in */
4500
+ activeThreadId: string;
4501
+ /** Open a saved thread and load its messages */
4502
+ openThread: (threadId: string) => void;
4503
+ /** Start a fresh chat (new thread) */
4504
+ newChat: () => void;
4505
+ /** A saved thread's messages are loading */
4506
+ isLoadingThread: boolean;
4507
+ /**
4508
+ * The chat is ready and empty — show a greeting (e.g. `<NewChatHero>`) instead
4509
+ * of the message list. Saves every app computing the same condition.
4510
+ */
4511
+ isNewChat: boolean;
4512
+ /** Re-fetch the thread list */
4513
+ refreshThreads: () => void;
4514
+ /** Delete a thread and all its messages; if it's the open one, starts a new chat */
4515
+ deleteThread: (threadId: string) => Promise<{
4516
+ success: boolean;
4517
+ error?: string;
4518
+ }>;
4519
+ /** Rename a thread */
4520
+ renameThread: (threadId: string, title: string) => Promise<{
4521
+ success: boolean;
4522
+ error?: string;
4523
+ }>;
4524
+ /** The signed-in user (SDK sign-in with `getToken` only; null until signed in). */
4525
+ user: SdkUser | null;
4526
+ /** The sign-in failure that stopped the SDK, if any (same as passed to `onAuthError`). */
4527
+ authError: SuperAtomAuthError | null;
4528
+ /**
4529
+ * A sign-in attempt is in flight — at start, on renewal, and after
4530
+ * `reconnect()`. The chat already shows "Signing in…" by itself; use this only
4531
+ * if you want your own screen for it.
4532
+ */
4533
+ isSigningIn: boolean;
4534
+ /** Try signing in and connecting again — e.g. after the user signed in again on your side. */
4535
+ reconnect: () => void;
4536
+ /**
4537
+ * The project and chat agent this session is actually on.
4538
+ *
4539
+ * Returned because under a `SuperatomProvider` the ids are given to the
4540
+ * provider, so a component inside it has no other way to know them — and
4541
+ * anything addressed to the project rather than to the socket needs them.
4542
+ * File attachments are uploaded to sa-api by project and app, which is why
4543
+ * the "+" in the composer was never shown: `SuperatomAssistant` was reading
4544
+ * them from its own props, and under a provider it is not given any.
4545
+ *
4546
+ * `agentId` is the one in use, not the raw option: a project with exactly one
4547
+ * chat agent resolves it, so it is set even when the host never passed it.
4548
+ */
4549
+ projectId: string;
4550
+ agentId?: string;
4551
+ /**
4552
+ * Who the session is for, as the SDK resolved it.
4553
+ *
4554
+ * `user.id` with SDK sign-in, and the only answer at all for a host passing
4555
+ * `userId` or a `token` directly — there is no `user` object on that path.
4556
+ * Anything addressed to the person rather than to the socket needs this.
4557
+ */
4558
+ userId: string;
3510
4559
  }
3511
- declare function useSuperAtom({ token, userId, projectId, debug, streaming }: UseSuperAtomOptions): UseSuperAtomReturn;
4560
+
4561
+ interface SuperatomProviderProps extends UseSuperAtomOptions {
4562
+ children: ReactNode;
4563
+ }
4564
+ declare function SuperatomProvider({ children, ...options }: SuperatomProviderProps): react_jsx_runtime.JSX.Element;
4565
+ /**
4566
+ * The session this part of the tree is on.
4567
+ *
4568
+ * Takes no arguments: the options live on the provider, which is the only
4569
+ * place a session is made.
4570
+ */
4571
+ declare function useSuperAtom(): UseSuperAtomReturn;
4572
+ /** True when a `SuperatomProvider` is above this component. */
4573
+ declare function useHasSuperatomProvider(): boolean;
3512
4574
 
3513
4575
  interface ChatInputProps {
3514
4576
  input: string;
@@ -3518,22 +4580,94 @@ interface ChatInputProps {
3518
4580
  placeholder?: string;
3519
4581
  primaryColor?: string;
3520
4582
  className?: string;
4583
+ /** A response is in flight — swaps Send for Stop and enables Esc-to-stop */
4584
+ isResponding?: boolean;
4585
+ onStop?: () => void;
4586
+ /**
4587
+ * Files. Off unless a host asks for it: a project whose agent does nothing
4588
+ * with files should not show a "+" that leads nowhere.
4589
+ */
4590
+ enableAttachments?: boolean;
4591
+ /** Picked from the file dialog — already filtered by `accept`, not yet checked. */
4592
+ onAttachFiles?: (files: File[]) => void;
4593
+ /** This chat can hold no more. The "+" stays pressable so it can say why. */
4594
+ attachmentsFull?: boolean;
4595
+ onAttachBlocked?: () => void;
4596
+ /** The tray: what is uploading, ready or failed. */
4597
+ attachments?: {
4598
+ id: number;
4599
+ name: string;
4600
+ status: 'uploading' | 'ready' | 'error';
4601
+ error?: string;
4602
+ }[];
4603
+ onRemoveAttachment?: (id: number) => void;
4604
+ /** A file is still going up — the question waits rather than arriving without it. */
4605
+ sendBlocked?: boolean;
4606
+ /**
4607
+ * Speak the question instead of typing it. Off unless a host asks for it,
4608
+ * and even then the microphone only appears once sa-api confirms this
4609
+ * deployment can transcribe — a button that always fails is worse than none.
4610
+ */
4611
+ enableVoice?: boolean;
4612
+ /** Which project the recording belongs to, for the transcriber's vocabulary. */
4613
+ projectId?: string;
3521
4614
  }
3522
- declare function ChatInput({ input, setInput, onSend, disabled, placeholder, primaryColor, className, }: ChatInputProps): react_jsx_runtime.JSX.Element;
4615
+ declare function ChatInput({ input, setInput, onSend, disabled, placeholder, primaryColor, className, isResponding, onStop, enableAttachments, onAttachFiles, attachmentsFull, onAttachBlocked, attachments, onRemoveAttachment, sendBlocked, enableVoice, projectId, }: ChatInputProps): react_jsx_runtime.JSX.Element | null;
3523
4616
 
3524
4617
  interface MessageListProps {
3525
4618
  messages: ChatMessage[];
3526
4619
  bundleReady: boolean;
3527
4620
  connectingText?: string;
4621
+ /** Placeholder for an empty conversation. Nothing is shown unless it is set. */
3528
4622
  emptyText?: string;
4623
+ /**
4624
+ * Shown in place of `emptyText` while the chat is empty — e.g. a greeting, or
4625
+ * `<NewChatHero>` with the input inside it. With this, the whole chat is just
4626
+ * <MessageList /> + <ChatInput />; without it, render your own empty screen
4627
+ * using the hook's `isNewChat`.
4628
+ */
4629
+ emptyState?: ReactNode;
3529
4630
  className?: string;
4631
+ /** A response is in flight — shows a Stop button on the latest assistant message */
4632
+ isResponding?: boolean;
4633
+ onStop?: () => void;
4634
+ /** A saved thread is being opened — shows a loading state instead of the empty text */
4635
+ isLoadingThread?: boolean;
4636
+ loadingThreadText?: string;
4637
+ /**
4638
+ * Paging backwards inside the thread — pass `hasMoreMessages`,
4639
+ * `isLoadingOlderMessages` and `loadOlderMessages` from useSuperAtom. Left
4640
+ * out, the list shows whatever `messages` holds and never asks for more.
4641
+ *
4642
+ * The scroll position is kept across a prepend, so the reader stays on the
4643
+ * message they were looking at rather than being pushed down a page.
4644
+ */
4645
+ hasMoreMessages?: boolean;
4646
+ isLoadingOlderMessages?: boolean;
4647
+ onLoadOlderMessages?: () => void;
4648
+ /**
4649
+ * The host owns the scrolling. The list then takes its natural height and
4650
+ * flows inside the host's scroll box — what a dashboard with its thread
4651
+ * underneath needs, so the two scroll as one page rather than two panes.
4652
+ */
4653
+ flow?: boolean;
3530
4654
  }
3531
- declare function MessageList({ messages, bundleReady, connectingText, emptyText, className, }: MessageListProps): react_jsx_runtime.JSX.Element;
4655
+ declare function MessageList({ messages, bundleReady, connectingText, emptyText, emptyState, className, isResponding, onStop, isLoadingThread, loadingThreadText, hasMoreMessages, isLoadingOlderMessages, onLoadOlderMessages, flow, }: MessageListProps): react_jsx_runtime.JSX.Element;
3532
4656
 
3533
4657
  interface MessageBubbleProps {
3534
4658
  message: ChatMessage;
4659
+ /** When set, this message's response is in flight and a Stop button is shown */
4660
+ onStop?: () => void;
4661
+ /**
4662
+ * Drop the bookmark, delete and feedback actions, keeping the timing and the
4663
+ * timestamp. For the bookmark page, where the answer on screen is the saved
4664
+ * copy: bookmarking what is already a bookmark means nothing, deleting would
4665
+ * reach for a conversation row this page never loaded, and rating belongs
4666
+ * with the answer in its thread.
4667
+ */
4668
+ hideActions?: boolean;
3535
4669
  }
3536
- declare function MessageBubble({ message }: MessageBubbleProps): react_jsx_runtime.JSX.Element;
4670
+ declare function MessageBubble({ message, onStop, hideActions }: MessageBubbleProps): react_jsx_runtime.JSX.Element;
3537
4671
 
3538
4672
  interface MenuV1Item {
3539
4673
  id: string;
@@ -3561,29 +4695,800 @@ interface MenuV1Root {
3561
4695
  }
3562
4696
 
3563
4697
  interface SidebarProps {
3564
- children?: React.ReactNode;
4698
+ children?: React__default.ReactNode;
3565
4699
  className?: string;
3566
4700
  onItemClick?: (item: MenuV1Item) => void;
4701
+ /** Shows the "New chat" button when provided (pass `newChat` from useSuperAtom) */
4702
+ onNewChat?: () => void;
4703
+ /** Conversation threads for the "Chats" section (pass `threads` from useSuperAtom) */
4704
+ threads?: ThreadSummary[];
4705
+ /** Highlighted thread (pass `activeThreadId` from useSuperAtom) */
4706
+ activeThreadId?: string;
4707
+ /**
4708
+ * Threads whose answer landed while the user was elsewhere — each gets a dot
4709
+ * until opened (pass `unreadThreadIds` from useSuperAtom).
4710
+ */
4711
+ unreadThreadIds?: Set<string>;
4712
+ /**
4713
+ * Threads answering right now — each gets a spinner while the user is looking
4714
+ * at something else (pass `respondingThreadIds` from useSuperAtom).
4715
+ */
4716
+ respondingThreadIds?: Set<string>;
4717
+ /** Open a thread (pass `openThread` from useSuperAtom) */
4718
+ onSelectThread?: (threadId: string) => void;
4719
+ /**
4720
+ * Paging for the Chats list — pass `hasMoreThreads`, `isLoadingThreads` and
4721
+ * `loadMoreThreads` from useSuperAtom. Left out, the list shows whatever
4722
+ * `threads` holds and never asks for more.
4723
+ */
4724
+ hasMoreThreads?: boolean;
4725
+ isLoadingThreads?: boolean;
4726
+ onLoadMoreThreads?: () => void;
4727
+ /** The same three for the Bookmarks list, from the same hook. */
4728
+ hasMoreBookmarks?: boolean;
4729
+ isLoadingBookmarks?: boolean;
4730
+ onLoadMoreBookmarks?: () => void;
4731
+ /** Enables "Delete chat" in each thread's menu (pass `deleteThread` from useSuperAtom) */
4732
+ onDeleteThread?: (threadId: string) => Promise<{
4733
+ success: boolean;
4734
+ error?: string;
4735
+ }>;
4736
+ /** Enables "Rename" in each thread's menu (pass `renameThread` from useSuperAtom) */
4737
+ onRenameThread?: (threadId: string, title: string) => Promise<{
4738
+ success: boolean;
4739
+ error?: string;
4740
+ }>;
4741
+ /**
4742
+ * Shows the "Home" entry when provided. The host decides what Home renders.
4743
+ * Its label is the bundle Home component's `Metadata.homeLabel`, else "Home".
4744
+ */
4745
+ onHome?: () => void;
4746
+ /** Which view the host is showing, so the entry can be highlighted. */
4747
+ activeView?: 'home' | 'chat' | 'dashboard' | 'report' | 'bundle-dashboard' | 'bookmark';
4748
+ /**
4749
+ * Open one of the project bundle's own dashboards — components that declare
4750
+ * `Metadata.dashboard` (see useBundleDashboards). Shows one entry per
4751
+ * dashboard when provided; the list comes from the bundle, so the host
4752
+ * supplies only what to do on click. Receives the component's key.
4753
+ */
4754
+ onSelectBundleDashboard?: (key: string) => void;
4755
+ /** Highlighted bundle dashboard (its key), when `activeView` is 'bundle-dashboard'. */
4756
+ activeBundleDashboard?: string;
4757
+ /** Open a dashboard. Shows the "Dashboards" section when provided. */
4758
+ onSelectDashboard?: (dashboardId: string) => void;
4759
+ /** Highlighted dashboard. */
4760
+ activeDashboardId?: string;
4761
+ /** Open a report. Shows the "Reports" section when provided. */
4762
+ onSelectReport?: (reportId: string) => void;
4763
+ /** Highlighted report. */
4764
+ activeReportId?: string;
4765
+ /**
4766
+ * Open a saved answer. Shows the "Bookmarks" section when provided — the list
4767
+ * itself comes from the SDK, so the host supplies only what to do on click.
4768
+ */
4769
+ onSelectBookmark?: (bookmark: BookmarkData) => void;
4770
+ /** Highlighted bookmark, when `activeView` is 'bookmark'. */
4771
+ activeBookmarkId?: number;
4772
+ /** Remove a bookmark. The trash icon on a row appears only when given. */
4773
+ onDeleteBookmark?: (id: number) => Promise<{
4774
+ success: boolean;
4775
+ error?: string;
4776
+ }>;
4777
+ /**
4778
+ * The project's logo in the header. Default true.
4779
+ *
4780
+ * Off for a host whose own chrome already carries its branding — otherwise
4781
+ * the customer sees two logos stacked. The project's name and its data
4782
+ * sources stay either way; this hides the mark alone.
4783
+ */
4784
+ showLogo?: boolean;
4785
+ primaryColor?: string;
4786
+ }
4787
+ declare function Sidebar({ children, className, onItemClick, onNewChat: onNewChatProp, threads: threadsProp, activeThreadId: activeThreadIdProp, unreadThreadIds: unreadThreadIdsProp, respondingThreadIds: respondingThreadIdsProp, onSelectThread: onSelectThreadProp, hasMoreThreads: hasMoreThreadsProp, isLoadingThreads: isLoadingThreadsProp, onLoadMoreThreads: onLoadMoreThreadsProp, hasMoreBookmarks: hasMoreBookmarksProp, isLoadingBookmarks: isLoadingBookmarksProp, onLoadMoreBookmarks: onLoadMoreBookmarksProp, onDeleteThread: onDeleteThreadProp, onRenameThread: onRenameThreadProp, onHome: onHomeProp, activeView: activeViewProp, onSelectBundleDashboard: onSelectBundleDashboardProp, activeBundleDashboard: activeBundleDashboardProp, onSelectDashboard: onSelectDashboardProp, activeDashboardId: activeDashboardIdProp, onSelectReport: onSelectReportProp, activeReportId: activeReportIdProp, onSelectBookmark: onSelectBookmarkProp, activeBookmarkId: activeBookmarkIdProp, onDeleteBookmark: onDeleteBookmarkProp, showLogo, primaryColor, }: SidebarProps): react_jsx_runtime.JSX.Element | null;
4788
+
4789
+ /**
4790
+ * Opening a dashboard: it shows on its own, whatever was asked on it before.
4791
+ *
4792
+ * Only the thread is touched. `onScreen` has exactly one owner — the mounted
4793
+ * DashboardPage — because anything else that sets it has no matching moment to
4794
+ * clear it, and a stale dashboard here blanks the ordinary chat view.
4795
+ *
4796
+ * The clearing lives here rather than in setDashboardOnScreen because that one
4797
+ * also fires on unmount — in StrictMode a remount would wipe the conversation
4798
+ * the user is reading. Navigating to a dashboard is the deliberate act, and it
4799
+ * is the only thing that resets, so clicking the same dashboard again starts
4800
+ * over exactly like clicking a different one.
4801
+ */
4802
+ declare function openDashboard(_dashboardId: string): void;
4803
+ /**
4804
+ * Opening a thread that was started on a dashboard: the dashboard comes back
4805
+ * above it, rather than the thread opening on its own.
4806
+ *
4807
+ * runtime-react does this by routing the thread to `/d/:dashboardId/c/:threadId`
4808
+ * instead of `/c/:threadId` — see its `threadPath()`. Here the host switches to
4809
+ * the dashboard view, which mounts DashboardPage and sets `onScreen`; this only
4810
+ * records the thread that belongs under it.
4811
+ */
4812
+ declare function openDashboardThread(dashboardId: string, threadId: string): void;
4813
+ /** Forgets the thread under the dashboard — it was deleted, so the dashboard is alone again. */
4814
+ declare function clearDashboardThread(): void;
4815
+ /** The dashboard currently on screen, if any. */
4816
+ declare function dashboardOnScreen(): string | null;
4817
+ /** The thread to show under the dashboard on screen. null = the dashboard alone. */
4818
+ declare function dashboardThread(): string | null;
4819
+ /** The latest filter values a dashboard reported. */
4820
+ declare function setDashboardFilters(dashboardId: string, values: Record<string, unknown>): void;
4821
+ /** The dashboard a thread belongs to, if it is known to belong to one. */
4822
+ declare function dashboardForThread(threadId: string): string | undefined;
4823
+ /**
4824
+ * A thread's dashboard: already known, or read from the thread's own `config`.
4825
+ *
4826
+ * The map covers a thread started or listed in this session, which is the
4827
+ * common case. The lookup is for the rest — a thread opened by id before any
4828
+ * list has loaded, which is what a URL like /chat/:threadId does on a cold
4829
+ * page. Undefined for a plain chat thread, and equally for a backend that
4830
+ * cannot answer, since both mean "do not open this on a dashboard".
4831
+ */
4832
+ declare function resolveThreadDashboard(userId: string, threadId: string,
4833
+ /** The chat agent the thread belongs to, when the host works in agents. */
4834
+ agentId?: string): Promise<string | undefined>;
4835
+
4836
+ interface ReportPageProps {
4837
+ /** Which report to open. Pass the id the Sidebar handed you. */
4838
+ reportId: string;
4839
+ className?: string;
4840
+ }
4841
+ /**
4842
+ * A report, rendered the way runtime-react renders it.
4843
+ *
4844
+ * Far simpler than a dashboard: a report is one DSL tree, so there is no grid,
4845
+ * no pages and no layout engine — fetch it, normalise the component names, hand
4846
+ * it to DSLRenderer. The SDK fetches it itself, so a host only says which one.
4847
+ */
4848
+ declare function ReportPageInner({ reportId, className }: ReportPageProps): react_jsx_runtime.JSX.Element;
4849
+ /** Memoised for the same reason as DashboardPage — see the note there. */
4850
+ declare const ReportPage: React.MemoExoticComponent<typeof ReportPageInner>;
4851
+
4852
+ interface BookmarkPageProps {
4853
+ /** The bookmark's own id, as listed in the sidebar. */
4854
+ bookmarkId: number;
4855
+ /** Called when the bookmark turns out to be gone, so the host can leave. */
4856
+ onMissing?: () => void;
4857
+ className?: string;
4858
+ }
4859
+ /**
4860
+ * One saved answer, on its own.
4861
+ *
4862
+ * A bookmark means "this answer, without the conversation around it" — so this
4863
+ * rebuilds what was saved into the same assistant message a live response
4864
+ * produces, and hands it to `MessageBubble`. It therefore renders identically
4865
+ * to the answer it was taken from, actions row and all, without re-running
4866
+ * anything.
4867
+ *
4868
+ * Replaces an earlier shortcut that opened the thread the bookmark came from.
4869
+ * That showed the whole conversation rather than the answer, highlighted the
4870
+ * thread in the sidebar instead of the bookmark, and on a long thread did not
4871
+ * even land on the right message.
4872
+ *
4873
+ * Follows runtime-react's `BookmarkView`, minus its route: the SDK owns no
4874
+ * routing, so the host says which bookmark to show.
4875
+ */
4876
+ declare function BookmarkPage({ bookmarkId, onMissing, className }: BookmarkPageProps): react_jsx_runtime.JSX.Element;
4877
+
4878
+ interface DashboardPageProps {
4879
+ /** Which dashboard to open. Pass the id the Sidebar handed you. */
4880
+ dashboardId: string;
4881
+ /**
4882
+ * Rendered inside someone else's scroll area — MessageList's `header`, so the
4883
+ * dashboard and the questions about it scroll together.
4884
+ *
4885
+ * Drops this component's own height and scrolling (a scroller inside a
4886
+ * scroller traps the wheel) and pins the title row instead, so it stays
4887
+ * readable once the thread has scrolled the widgets away.
4888
+ */
4889
+ embedded?: boolean;
4890
+ className?: string;
4891
+ }
4892
+ /**
4893
+ * A dashboard.
4894
+ *
4895
+ * The SDK fetches it through the client, so a host only has to say which one.
4896
+ *
4897
+ * Only program dashboards are drawn. A DSL dashboard — a stored widget tree,
4898
+ * laid out on a grid — is recognised and refused: the GridStack canvas that
4899
+ * drew them is gone, and the page says so rather than rendering an empty
4900
+ * frame. See the note on `isDsl` below.
4901
+ */
4902
+ declare function DashboardPageInner({ dashboardId, embedded, className }: DashboardPageProps): react_jsx_runtime.JSX.Element;
4903
+ /**
4904
+ * Memoised because the composer is a sibling: the chat's `input` lives in
4905
+ * useSuperAtom, so every keystroke re-renders the assistant and would re-run a
4906
+ * whole dashboard's layout with it. The props here are a dashboard id and two
4907
+ * flags, so a shallow compare is exactly right.
4908
+ */
4909
+ declare const DashboardPage: React.MemoExoticComponent<typeof DashboardPageInner>;
4910
+
4911
+ interface DashboardConversationProps extends Omit<MessageListProps, 'className' | 'flow'> {
4912
+ /** Which dashboard the conversation is about. Pass the id the Sidebar handed you. */
4913
+ dashboardId: string;
4914
+ /** The composer. Stays below the scroll, always reachable. */
4915
+ children?: ReactNode;
4916
+ className?: string;
4917
+ }
4918
+ /**
4919
+ * A dashboard with its thread underneath, as one page: the dashboard at its own
4920
+ * height, the conversation flowing below it, and a single scrollbar over both.
4921
+ *
4922
+ * It opens on the dashboard rather than at the end of the thread — the question
4923
+ * is about what is on screen, so the dashboard is what you should see first.
4924
+ */
4925
+ declare function DashboardConversation({ dashboardId, children, className, ...messageListProps }: DashboardConversationProps): react_jsx_runtime.JSX.Element;
4926
+
4927
+ interface HomePageProps {
4928
+ className?: string;
4929
+ /**
4930
+ * Which bundle component to show — a key in `SUPERATOM.COMPONENTS`. Default
4931
+ * `'Home'`. Any other key renders one of the bundle's own dashboards (those
4932
+ * with `Metadata.dashboard`, listed by useBundleDashboards) as a page.
4933
+ */
4934
+ componentKey?: string;
4935
+ }
4936
+ /**
4937
+ * The project's own Home dashboard, as a page.
4938
+ *
4939
+ * It renders nothing of its own: `Home` is a component of the project bundle the
4940
+ * server delivers, which `registerBundleComponents` puts in COMP_REGISTRY under
4941
+ * `COMP_HOME` (the key is uppercased there, so `Home` is not a valid type). This
4942
+ * component only gives it a box to live in.
4943
+ *
4944
+ * `SA_RUNTIME` is the one prop that has to be supplied here. Everywhere else it
4945
+ * is built by useSuperAtom and baked into a message's DSL props; none of
4946
+ * DSLRenderer, DynamicComponent or BundleComponentWrapper adds it, they all pass
4947
+ * props straight through. Home is not an answer inside a thread, so there is no
4948
+ * real block or thread to name and a stable synthetic pair stands in. The field
4949
+ * is optional in DataRequestPayloadSchema, so a query carrying this is still
4950
+ * well formed on the wire.
4951
+ */
4952
+ declare function HomePageInner({ className, componentKey }: HomePageProps): react_jsx_runtime.JSX.Element;
4953
+ /** Memoised for the same reason as DashboardPage — see the note there. */
4954
+ declare const HomePage: React.MemoExoticComponent<typeof HomePageInner>;
4955
+
4956
+ /**
4957
+ * Dashboards the project bundle ships, and what its Home button is called.
4958
+ *
4959
+ * Both come from the bundle's component metadata, so the SDK never hardcodes
4960
+ * which dashboards a project has:
4961
+ *
4962
+ * Metadata.dashboard = { label, icon?, order?, placement?, group?, groupIcon? }
4963
+ * makes a component a top-level dashboard with its own sidebar entry.
4964
+ * Metadata.homeLabel
4965
+ * is the Home button's text when that component is registered as `Home`.
4966
+ *
4967
+ * Ported from runtime-react's lib/bundleDashboards.ts so a bundle reads the same
4968
+ * in both hosts; only the refresh trigger differs (see useBundleDashboards).
4969
+ * The convention is documented in a project's frontend/src/modules/DASHBOARDS.md.
4970
+ */
4971
+ /** A top-level dashboard entry, discovered from the loaded bundle. */
4972
+ interface BundleDashboard {
4973
+ /** Key in SUPERATOM.COMPONENTS; also what HomePage's `componentKey` takes. */
4974
+ key: string;
4975
+ label: string;
4976
+ /** Iconify icon name. */
4977
+ icon: string;
4978
+ /** Ascending sort order among dashboards. */
4979
+ order: number;
4980
+ /**
4981
+ * "footer" pins the entry below everything else, for utility pages like Docs
4982
+ * or Help. Anything else — or nothing — is "main".
4983
+ */
4984
+ placement: 'main' | 'footer';
4985
+ /** Optional heading; dashboards sharing it nest under one entry. */
4986
+ group?: string;
4987
+ /** Icon for that heading, taken from the first dashboard that sets one. */
4988
+ groupIcon?: string;
4989
+ }
4990
+ /** A sidebar row: a dashboard on its own, or a named group of dashboards. */
4991
+ type BundleDashboardEntry = {
4992
+ kind: 'dashboard';
4993
+ dashboard: BundleDashboard;
4994
+ } | {
4995
+ kind: 'group';
4996
+ name: string;
4997
+ icon: string;
4998
+ order: number;
4999
+ dashboards: BundleDashboard[];
5000
+ };
5001
+ /**
5002
+ * Every bundle component with `Metadata.dashboard`, sorted by `order`.
5003
+ *
5004
+ * The component currently serving as Home is left out — Home has its own button
5005
+ * — so a dashboard aliased to `Home` never appears twice, even when it is also
5006
+ * registered under its own key.
5007
+ */
5008
+ declare function readBundleDashboards(): BundleDashboard[];
5009
+ /**
5010
+ * Nest grouped dashboards under one heading, placed where its first member
5011
+ * would sit. Ungrouped dashboards come back unchanged.
5012
+ */
5013
+ declare function groupBundleDashboards(list: BundleDashboard[]): BundleDashboardEntry[];
5014
+ /** The Home button's text: the Home component's `Metadata.homeLabel`, else "Home". */
5015
+ declare function readHomeLabel(): string;
5016
+ /**
5017
+ * The bundle's dashboards, kept current.
5018
+ *
5019
+ * runtime-react re-reads on its own module-loaded events, which the SDK does not
5020
+ * fire. Here the signal is the end of start-up: useSuperAtom marks the chat ready
5021
+ * only after the bundle has loaded and registered its components.
5022
+ */
5023
+ declare function useBundleDashboards(): BundleDashboard[];
5024
+ /** The Home button's text, kept current the same way. */
5025
+ declare function useHomeLabel(): string;
5026
+
5027
+ interface NewChatHeroProps {
5028
+ /** The chat input to center, e.g. <ChatInput ... /> */
5029
+ children: React__default.ReactNode;
5030
+ title?: string;
5031
+ subtitle?: string;
5032
+ className?: string;
5033
+ }
5034
+ /**
5035
+ * Centered "new chat" empty state (like most chat apps): a greeting with the
5036
+ * chat box in the middle of the screen. Same as Runtime-react's NewChatHero.
5037
+ * Render it instead of <MessageList /> + bottom <ChatInput /> while the chat is empty.
5038
+ *
5039
+ * Type and spacing follow the width of its own box rather than the window, so it
5040
+ * reads correctly embedded in a narrow side panel as well as full-page.
5041
+ */
5042
+ declare function NewChatHero({ children, title, subtitle, className, }: NewChatHeroProps): react_jsx_runtime.JSX.Element;
5043
+
5044
+ type ChatPageProps = NewChatHeroProps;
5045
+ /**
5046
+ * The empty chat, as a page.
5047
+ *
5048
+ * It is `NewChatHero` and nothing else — the greeting with the chat box centred
5049
+ * on the screen rather than pinned to the bottom. It exists so the four views
5050
+ * the assistant can show are four pages side by side, instead of three pages and
5051
+ * one component reached a different way.
5052
+ *
5053
+ * Put the composer inside it: that is the whole point of this view.
5054
+ */
5055
+ declare function ChatPage(props: ChatPageProps): react_jsx_runtime.JSX.Element;
5056
+
5057
+ declare function ThreadRowsSkeleton({ count }: {
5058
+ count: number;
5059
+ }): react_jsx_runtime.JSX.Element;
5060
+
5061
+ interface ConfirmDeleteModalProps {
5062
+ isOpen: boolean;
5063
+ onClose: () => void;
5064
+ onConfirm: () => void;
5065
+ isDeleting: boolean;
5066
+ title?: string;
5067
+ message?: string;
5068
+ }
5069
+ /** Same as Runtime-react's components/chat/ConfirmDeleteModal */
5070
+ declare function ConfirmDeleteModal({ isOpen, onClose, onConfirm, isDeleting, title, message, }: ConfirmDeleteModalProps): react_jsx_runtime.JSX.Element | null;
5071
+
5072
+ type AnswerVerdict = 'correct' | 'partial' | 'incorrect' | null;
5073
+ interface FeedbackModalProps {
5074
+ isOpen: boolean;
5075
+ onClose: () => void;
5076
+ onSubmit?: (status: AnswerVerdict, feedbackText: string) => void;
5077
+ isSubmitting: boolean;
5078
+ title?: string;
5079
+ submitLabel?: string;
5080
+ }
5081
+ /**
5082
+ * What was wrong with this answer.
5083
+ *
5084
+ * Both fields are optional, deliberately: a verdict on its own is a signal
5085
+ * worth having, and so is a note without one. Requiring both would mean most
5086
+ * people submit neither.
5087
+ *
5088
+ * Copied from runtime-react's `FeedbackModal`, with its `VoiceTextarea` swapped
5089
+ * for a plain one — voice input is not ported, and a textarea that silently
5090
+ * lacks its microphone is worse than one that never had it.
5091
+ */
5092
+ declare function FeedbackModal({ isOpen, onClose, onSubmit, isSubmitting, title, submitLabel, }: FeedbackModalProps): react_jsx_runtime.JSX.Element | null;
5093
+
5094
+ interface BookmarkModalProps {
5095
+ isOpen: boolean;
5096
+ onClose: () => void;
5097
+ onCreate?: (name: string, description: string) => void;
5098
+ isBookmarking: boolean;
5099
+ /** Prefilled from the answer's own title and description, so most saves are one click. */
5100
+ defaults: {
5101
+ name: string;
5102
+ description: string;
5103
+ };
5104
+ title?: string;
5105
+ submitLabel?: string;
5106
+ }
5107
+ /**
5108
+ * Name an answer so it can be found again.
5109
+ *
5110
+ * The name is required and the description is not: a bookmark list of
5111
+ * "Untitled" is no more use than no list, while a missing description costs
5112
+ * nothing. Both are prefilled from the answer itself where it says what it is.
5113
+ *
5114
+ * Copied from runtime-react's `BookmarkModal`.
5115
+ */
5116
+ declare function BookmarkModal({ isOpen, onClose, onCreate, isBookmarking, defaults, title, submitLabel, }: BookmarkModalProps): react_jsx_runtime.JSX.Element | null;
5117
+
5118
+ /**
5119
+ * Run a menu item — a quick action, or anything else the project's menu offers.
5120
+ *
5121
+ * It puts a component into the conversation through the bundle's own
5122
+ * `SA.addComponent`, which is what the chat listens to. Shared by the Sidebar's
5123
+ * default handler and by SuperatomAssistant, which wraps it so the chat is on
5124
+ * screen first: added to a conversation nobody is looking at, the action looks
5125
+ * like nothing happened.
5126
+ */
5127
+ declare function runMenuItem(item: MenuV1Item): void;
5128
+
5129
+ declare function useBookmarks(): BookmarkData[];
5130
+ /** Re-reads on every change, so a bubble's icon follows the list. */
5131
+ declare function useBookmarkForMessage(messageId: string): BookmarkData | undefined;
5132
+
5133
+ /** The configuration mistake, if there is one. Re-renders on change. */
5134
+ declare function useConfigError(): Error | null;
5135
+
5136
+ /** Detected once at module load — the answer never changes for a given browser. */
5137
+ declare const SUPPORTED_MIME: string | null;
5138
+ type VoiceState = 'idle' | 'recording' | 'transcribing' | 'error';
5139
+ /**
5140
+ * Registers `onToggle` on Ctrl/Cmd+., but only actually invokes it while this
5141
+ * call is the topmost registered voice surface — background surfaces still
5142
+ * register, so the stack stays correct, but no-op on the keypress.
5143
+ */
5144
+ declare function useVoiceShortcut(eligible: boolean, onToggle: () => void): void;
5145
+ interface UseVoiceInputReturn {
5146
+ state: VoiceState;
5147
+ error: string | null;
5148
+ elapsedMs: number;
5149
+ maxMs: number;
5150
+ start: () => void;
5151
+ stop: () => void;
5152
+ cancel: () => void;
5153
+ toggle: () => void;
5154
+ clearError: () => void;
5155
+ }
5156
+ declare function useVoiceInput(onTranscript: (text: string) => void, projectId?: string): UseVoiceInputReturn;
5157
+
5158
+ /** runtime-react's fallback. Ours was indigo, which is why the two differed. */
5159
+ declare const DEFAULT_THEME_COLOR = "#14b8a6";
5160
+ /**
5161
+ * The colour to paint with.
5162
+ *
5163
+ * `override` is the component's own `primaryColor` prop and wins outright, so a
5164
+ * host styling one surface by hand still can.
5165
+ */
5166
+ declare function useThemeColor(override?: string): string;
5167
+
5168
+ /** A file already uploaded, as the question carries it. */
5169
+ interface ChatAttachment {
5170
+ key: string;
5171
+ fileName: string;
5172
+ size: number;
5173
+ contentType?: string;
5174
+ }
5175
+ /** A file an answer handed over. The answer keeps only the id. */
5176
+ interface DeliveredFile {
5177
+ id: string;
5178
+ fileName: string;
5179
+ size?: number;
5180
+ version?: number;
5181
+ }
5182
+
5183
+ interface FileDownloadsProps {
5184
+ files: DeliveredFile[];
5185
+ }
5186
+ /**
5187
+ * The files an answer hands over, each with a download button.
5188
+ *
5189
+ * The answer carries only the file's id. The link is asked for when the button
5190
+ * is pressed rather than when the answer renders: it lasts minutes and is
5191
+ * minted for the signed-in user, so one fetched up front would be dead by the
5192
+ * time anyone clicked it, and fetching one per file per answer would be a
5193
+ * burst of requests for links mostly never used.
5194
+ */
5195
+ declare function FileDownloads({ files }: FileDownloadsProps): react_jsx_runtime.JSX.Element | null;
5196
+
5197
+ interface PendingAttachment {
5198
+ id: number;
5199
+ name: string;
5200
+ size: number;
5201
+ status: 'uploading' | 'ready' | 'error';
5202
+ error?: string;
5203
+ /** Set once the upload is confirmed. */
5204
+ uploaded?: ChatAttachment;
5205
+ }
5206
+ interface AttachTarget {
5207
+ projectId?: string;
5208
+ /** The chat agent — `agentId`. */
5209
+ appId?: string;
5210
+ threadId?: string;
5211
+ }
5212
+ declare function useAttachments(): PendingAttachment[];
5213
+ /** A chat that can take no more — by count or by size, counting the tray. */
5214
+ declare function isAttachmentsFull(threadId?: string): boolean;
5215
+ /** Said when "+" is pressed on a full chat. */
5216
+ declare function notifyAttachmentsFull(threadId?: string): void;
5217
+ /**
5218
+ * Takes the picked files and uploads them.
5219
+ *
5220
+ * What the server accepts — types, size — is the server's call, and a file it
5221
+ * turns away comes back with its own message. The count and total-size limits
5222
+ * are checked here, before anything is sent, so an over-limit file costs no
5223
+ * upload at all.
5224
+ */
5225
+ declare function addAttachments(files: File[], target: AttachTarget): void;
5226
+ /** Takes a file off before sending, and removes its upload. */
5227
+ declare function removeAttachment(id: number): void;
5228
+ /**
5229
+ * The question is being sent: hands over the confirmed uploads, counts them
5230
+ * against the thread, and empties the tray.
5231
+ */
5232
+ declare function consumeAttachments(threadId?: string): ChatAttachment[];
5233
+ /** Everything goes — on sign-out, or when a host unmounts the assistant. */
5234
+ declare function clearAttachments(): void;
5235
+
5236
+ interface ToasterProps {
5237
+ /** Applied to the stack, for a host that needs it somewhere else. */
5238
+ className?: string;
5239
+ }
5240
+ /**
5241
+ * Where toasts appear.
5242
+ *
5243
+ * Top centre, as runtime-react places them (`<Toaster position="top-center" />`).
5244
+ * The top edge is the one place nothing else in the SDK lives — the composer is
5245
+ * at the bottom, the scroll-to-bottom button floats above it, and a toast over
5246
+ * either covers something the user is using.
5247
+ *
5248
+ * Rendered in place, never portalled. A portal to `document.body` would put the
5249
+ * stack outside `.sa-ui` — so none of our styles would reach it — and outside
5250
+ * the shadow boundary, where the host's CSS could. `position: fixed` needs no
5251
+ * portal here: nothing in the tree above makes itself a containing block.
5252
+ *
5253
+ * One of these belongs in `SuperatomAssistant`, which is why a host composing
5254
+ * their own layout has to place it themselves; `toast.success(...)` from
5255
+ * anywhere is a no-op without it, which is the right failure — silent, not
5256
+ * broken.
5257
+ *
5258
+ * `aria-live="polite"` rather than `assertive`: these confirm something the
5259
+ * user just did, so they should wait for a pause rather than cut in. Errors go
5260
+ * through the same region deliberately — an error toast here is still a
5261
+ * confirmation of an action, not an alert the user must handle.
5262
+ */
5263
+ declare function Toaster({ className }: ToasterProps): react_jsx_runtime.JSX.Element | null;
5264
+
5265
+ type ToastKind = 'success' | 'error' | 'info' | 'warning';
5266
+ interface Toast {
5267
+ id: number;
5268
+ kind: ToastKind;
5269
+ message: string;
5270
+ /** How long before it dismisses itself. `0` means it stays until dismissed. */
5271
+ duration: number;
5272
+ }
5273
+ /**
5274
+ * Raise one. Returns its id, so a caller holding a long-running toast
5275
+ * (`duration: 0`) can take it down when the work finishes.
5276
+ */
5277
+ declare function showToast(message: string, kind?: ToastKind, duration?: number): number;
5278
+ declare function dismissToast(id: number): void;
5279
+ /** Everything goes — on sign-out, or when a host unmounts the assistant. */
5280
+ declare function clearToasts(): void;
5281
+ declare function useToasts(): Toast[];
5282
+ /**
5283
+ * The shorthands, which is what calling code should use.
5284
+ *
5285
+ * `toast.success('Thread deleted')` reads the way the runtime's does, so moving
5286
+ * code between the two does not mean rewriting its confirmations.
5287
+ */
5288
+ declare const toast: {
5289
+ success: (message: string, duration?: number) => number;
5290
+ error: (message: string, duration?: number) => number;
5291
+ info: (message: string, duration?: number) => number;
5292
+ warning: (message: string, duration?: number) => number;
5293
+ dismiss: typeof dismissToast;
5294
+ clear: typeof clearToasts;
5295
+ };
5296
+
5297
+ /**
5298
+ * The whole assistant, held until the session is back.
5299
+ *
5300
+ * A corner pill is the right weight for a blip nobody needs to act on. It is
5301
+ * the wrong weight for this: between connections the thread on screen belongs
5302
+ * to a session that no longer exists, and anything typed into it goes nowhere.
5303
+ * Covering the surface says that plainly, and stops a question being written
5304
+ * into a socket that is gone.
5305
+ *
5306
+ * Nothing is unmounted underneath — the conversation, the dashboard and the
5307
+ * draft all survive, because this is a layer over them rather than a screen
5308
+ * instead of them. When the session comes back, the overlay goes and what was
5309
+ * on screen is still there.
5310
+ *
5311
+ * Silent until there has been a connection to lose: a first sign-in is not a
5312
+ * reconnection, and the chat already says "Connecting to SuperAtom…" for that.
5313
+ */
5314
+ declare function ConnectionOverlay(): react_jsx_runtime.JSX.Element | null;
5315
+
5316
+ /**
5317
+ * The connection, but only when there is something to say about it.
5318
+ *
5319
+ * Nothing renders while the socket is healthy. The states below are reached on
5320
+ * a timer, not immediately — see useConnectionStatus, where a blip has to last
5321
+ * a second before it is worth a pill and fifteen before it is worth alarm.
5322
+ */
5323
+ declare function ConnectionStatusPill(): react_jsx_runtime.JSX.Element | null;
5324
+
5325
+ /**
5326
+ * `'connecting'` is the SDK's own, and means "never connected yet". Nothing is
5327
+ * shown for it: a first connection is not a reconnection, and the chat already
5328
+ * says "Connecting to SuperAtom…" by itself. The other three are runtime's.
5329
+ */
5330
+ type ConnectionStatus = 'connecting' | 'connected' | 'reconnecting' | 'disconnected';
5331
+ /**
5332
+ * Why the socket will not connect.
5333
+ *
5334
+ * The browser never exposes a WebSocket close reason — a failed handshake is
5335
+ * always code 1006 with an empty reason — so this cannot be read off the
5336
+ * socket. runtime-react probes `/auth/me` to tell these apart. The SDK does
5337
+ * not: that route returns the user, their organization and every app they can
5338
+ * open, and `services/project.ts` exists precisely to avoid putting it in a
5339
+ * customer's network tab.
5340
+ *
5341
+ * It does not need to. A host signs in through `getToken`, so a dead session
5342
+ * arrives as a sign-in failure the SDK already handles and already stores —
5343
+ * `authError` is the answer the probe was asking for.
5344
+ *
5345
+ * 'auth' — sign-in failed in a way retrying cannot fix. The host's token
5346
+ * is the problem, and the host has already been told through
5347
+ * `onAuthError`.
5348
+ * 'network' — signed in fine, so the relay or the network is at fault.
5349
+ *
5350
+ * runtime's third reason, 'forbidden' (signed in to the wrong organization for
5351
+ * this project), has no analogue here: the host picks the organization when it
5352
+ * mints the token, and a mismatch surfaces as a sign-in failure, not as a
5353
+ * socket that will not open.
5354
+ */
5355
+ type DisconnectReason = 'network' | 'auth';
5356
+ declare function useConnectionStatus(): {
5357
+ status: ConnectionStatus;
5358
+ reason: DisconnectReason;
5359
+ retry: () => void;
5360
+ };
5361
+
5362
+ interface SuperatomSurfaceProps {
5363
+ children: ReactNode;
5364
+ /**
5365
+ * Applied to the element the host's layout sees — the shadow host when the
5366
+ * boundary is on, the root box when it is off. Either way it is what gives
5367
+ * this its size.
5368
+ */
5369
+ className?: string;
5370
+ /**
5371
+ * Render inside a shadow root, so the host page's CSS cannot reach in.
5372
+ *
5373
+ * On by default. Scoping the stylesheet to `.sa-ui` wins the collisions it
5374
+ * can — a bare `.btn` against our `.sa-ui .btn` — but it cannot win against
5375
+ * a host's bare element rules, and a page that styles `button` or `input`
5376
+ * directly reaches our components whatever our selectors say. Only a
5377
+ * boundary stops that.
5378
+ *
5379
+ * The escape hatch stays because the boundary has real costs: the document
5380
+ * can no longer see our elements, so a host script doing
5381
+ * `document.querySelector` inside, an analytics or a11y tool that walks the
5382
+ * DOM, or a listener reading `event.target` on `document` all see less than
5383
+ * they did.
5384
+ */
5385
+ shadowDom?: boolean;
5386
+ /**
5387
+ * Which view the navigation opens on. Default 'home'.
5388
+ *
5389
+ * Ignored when a navigation is already above this — then it belongs to
5390
+ * whoever provided that one.
5391
+ */
5392
+ defaultView?: AssistantView;
5393
+ }
5394
+ /**
5395
+ * Where the SDK's UI begins.
5396
+ *
5397
+ * Two things, and they belong together: the shadow boundary that keeps the
5398
+ * host's CSS out, and the root box every page inside expects to be laid out
5399
+ * in — a flex row that fills what it is given, with `min-h-0` so the scroll
5400
+ * areas inside size themselves instead of growing the page.
5401
+ *
5402
+ * This is deliberately *not* on `SuperatomProvider`. The provider says which
5403
+ * session the tree is on; that is data, and it has no business deciding how
5404
+ * anything renders. Putting the boundary there would isolate whatever a host
5405
+ * puts inside it — including their own header, which is in there precisely so
5406
+ * it can read the session — and leave them choosing between the two. Session
5407
+ * and pixels are separate questions, so they are separate components.
5408
+ *
5409
+ * <SuperatomProvider getToken={getToken} projectId={id} agentId={agent}>
5410
+ * <MyHeader /> // host markup, host CSS
5411
+ * <SuperatomSurface> // SDK territory from here down
5412
+ * <Sidebar … /><HomePage /><ChatInput … />
5413
+ * </SuperatomSurface>
5414
+ * </SuperatomProvider>
5415
+ *
5416
+ * `SuperatomAssistant` renders one of these itself, so a host using the single
5417
+ * import never sees it. A host composing the pieces wraps them in one — once,
5418
+ * around the whole tree, not around each component. Per-component boundaries
5419
+ * would each get their own root, and the layout classes the host writes on the
5420
+ * wrappers between them would have nothing to apply to.
5421
+ */
5422
+ declare function SuperatomSurface({ children, className, shadowDom, defaultView, }: SuperatomSurfaceProps): react_jsx_runtime.JSX.Element;
5423
+
5424
+ interface ShadowBoundaryProps {
5425
+ children: ReactNode;
5426
+ /** Applied to the host element, which is what the host app's layout sees. */
5427
+ className?: string;
5428
+ /**
5429
+ * `open` lets anything outside reach in through `.shadowRoot`. That includes
5430
+ * our own tests and devtools, so it stays open unless a host asks otherwise.
5431
+ * `closed` hides the tree from the host's scripts — privacy from the page,
5432
+ * not extra style isolation; the two modes are identical to CSS.
5433
+ */
5434
+ mode?: 'open' | 'closed';
5435
+ /**
5436
+ * Overrides the host element's layout, which is set inline — see the element
5437
+ * itself for why it cannot be set with classes.
5438
+ */
5439
+ style?: CSSProperties;
3567
5440
  }
3568
- declare function Sidebar({ children, className, onItemClick }: SidebarProps): react_jsx_runtime.JSX.Element;
5441
+ /**
5442
+ * Renders its children inside a shadow root.
5443
+ *
5444
+ * The point is CSS: a rule in the host page cannot match an element inside a
5445
+ * shadow tree, so Bootstrap's `.btn` never reaches ours however it is written
5446
+ * or whenever it loads. Nothing else about the React tree changes — this
5447
+ * portals, so context, state and events all behave as they did.
5448
+ *
5449
+ * What it does *not* do is worth saying plainly, because it is easy to assume
5450
+ * otherwise. The boundary stops rules from matching. It does not stop
5451
+ * inheritance, and it does not scope units: `font-size` and `line-height` set
5452
+ * on the host's `body` inherit straight through, and `rem` still resolves
5453
+ * against the document's `html`. Those are handled before this — by the reset
5454
+ * and the rem conversion in `sa.css` and `scripts/scope-css.mjs` — and both
5455
+ * remain necessary with a shadow root in place.
5456
+ *
5457
+ * Two stylesheets live in here. Ours, compiled when this package was built, and
5458
+ * the project bundle's, compiled when *its* backend was built and sent over the
5459
+ * socket with the bundle itself. Neither is produced in the browser, so nothing
5460
+ * has to read the page to know what to generate — which is what makes a shadow
5461
+ * root safe to use at all. The Tailwind compiler that used to do that could not
5462
+ * see in here, and every widget the bundle rendered came up unstyled.
5463
+ */
5464
+ declare function ShadowBoundary({ children, className, mode, style }: ShadowBoundaryProps): react_jsx_runtime.JSX.Element;
5465
+ /**
5466
+ * The root to search from, given any element inside the boundary.
5467
+ *
5468
+ * `document.querySelector` cannot see into a shadow tree, so every lookup that
5469
+ * used to start at the document has to start here instead. Returns the document
5470
+ * when there is no shadow root above the node, which is what a host rendering
5471
+ * the components directly gets.
5472
+ */
5473
+ declare function searchRootFor(node: Node | null | undefined): Document | ShadowRoot;
3569
5474
 
3570
5475
  interface MenuV1RendererProps {
3571
5476
  items: MenuV1Item[];
3572
5477
  onItemClick: (item: MenuV1Item) => void;
3573
5478
  isCollapsed: boolean;
3574
5479
  }
3575
- declare const MenuV1Renderer: React.FC<MenuV1RendererProps>;
5480
+ declare const MenuV1Renderer: React__default.FC<MenuV1RendererProps>;
3576
5481
 
3577
5482
  interface MenuV1RendererCollapsedProps {
3578
5483
  items: MenuV1Item[];
3579
5484
  onItemClick: (item: MenuV1Item) => void;
3580
5485
  }
3581
- declare const MenuV1RendererCollapsed: React.FC<MenuV1RendererCollapsedProps>;
5486
+ declare const MenuV1RendererCollapsed: React__default.FC<MenuV1RendererCollapsedProps>;
3582
5487
 
3583
5488
  /**
3584
5489
  * @superatomai/application-sdk
3585
5490
  * SuperAtom Application SDK - WebSocket client, DSL renderer, and pre-built chat UI
3586
5491
  */
3587
- declare const SDK_VERSION = "0.0.1";
5492
+ declare const SDK_VERSION = "0.0.3";
3588
5493
 
3589
- export { type ActionsRequestMessage, ActionsRequestMessageSchema, type ActionsRequestPayload, ActionsRequestPayloadSchema, type ActionsResponseMessage, ActionsResponseMessageSchema, type ActionsResponsePayload, ActionsResponsePayloadSchema, type Binding, BindingSchema, type BundleChunkMessage, BundleChunkMessageSchema, type BundleChunkPayload, BundleChunkPayloadSchema, type BundleErrorMessage, BundleErrorMessageSchema, type BundleErrorPayload, BundleErrorPayloadSchema, type BundleRequestMessage, BundleRequestMessageSchema, type BundleRequestPayload, BundleRequestPayloadSchema, COMP_REGISTRY, ChatInput, type ChatInputProps, type ChatMessage, type ClientConfig, ClientConfigSchema, type Component, type ComponentDefinition, type ComponentRegistryType, ComponentSchema, type ComponentsRegistry, type ComponentsSendMessage, ComponentsSendMessageSchema, type ComponentsSendPayload, ComponentsSendPayloadSchema, DSLErrorBoundary, DSLRenderer, type DSLRendererProps, DSLRendererPropsSchema, type DataRequestMessage, DataRequestMessageSchema, type DataRequestPayload, DataRequestPayloadSchema, type DataResponseMessage, DataResponseMessageSchema, type DataResponsePayload, DataResponsePayloadSchema, DynamicComponent, type Expression, ExpressionSchema, type ForDirective, ForDirectiveSchema, type MenuData, MenuDataSchema, type MenuQueryFilters, MenuQueryFiltersSchema, type MenuV1Item, MenuV1Renderer, MenuV1RendererCollapsed, type MenuV1Root, type MenusRequestMessage, MenusRequestMessageSchema, type MenusRequestPayload, MenusRequestPayloadSchema, type MenusResponseMessage, MenusResponseMessageSchema, type MenusResponsePayload, MenusResponsePayloadSchema, type Message, MessageBubble, type MessageBubbleProps, MessageList, type MessageListProps, type MessageParticipant, MessageParticipantSchema, MessageSchema, type MountFunction, type QuerySpec, QuerySpecSchema, type ResolvedClientConfig, SDK_VERSION, Sidebar, type SidebarProps, type SuperAtomGlobal, SuperatomClient, type UIComponent, UIComponentSchema, type UIElement, UIElementSchema, type UILogEntry, UILogEntrySchema, type UILogsMessage, UILogsMessageSchema, type UILogsPayload, UILogsPayloadSchema, type UseSuperAtomOptions, type UseSuperAtomReturn, type UserPromptRequestMessage, UserPromptRequestMessageSchema, type UserPromptRequestPayload, UserPromptRequestPayloadSchema, type UserPromptResponseMessage, UserPromptResponseMessageSchema, type UserPromptResponsePayload, UserPromptResponsePayloadSchema, type UserPromptSuggestionsRequestMessage, UserPromptSuggestionsRequestMessageSchema, type UserPromptSuggestionsRequestPayload, UserPromptSuggestionsRequestPayloadSchema, type UserPromptSuggestionsResponseMessage, UserPromptSuggestionsResponseMessageSchema, type UserPromptSuggestionsResponsePayload, UserPromptSuggestionsResponsePayloadSchema, getComponent, getComponentStates, getComponents, hasComponents, registerBundleComponents, resetAllFailedComponents, resetFailedComponent, resetRegistration, sanitizeDSL, index as services, setup, useDynamicComponent, useSuperAtom, validateDSL, validateUIComponent, validateUIElement, withConditionalErrorBoundary };
5494
+ export { type ActionsRequestMessage, ActionsRequestMessageSchema, type ActionsRequestPayload, ActionsRequestPayloadSchema, type ActionsResponseMessage, ActionsResponseMessageSchema, type ActionsResponsePayload, ActionsResponsePayloadSchema, type AnswerVerdict, type AssistantNavigation, AssistantNavigationProvider, type AssistantNavigationProviderProps, type AssistantView, type AttachTarget, type Binding, BindingSchema, BookmarkModal, type BookmarkModalProps, BookmarkPage, type BookmarkPageProps, type BundleChunkMessage, BundleChunkMessageSchema, type BundleChunkPayload, BundleChunkPayloadSchema, type BundleDashboard, type BundleDashboardEntry, type BundleErrorMessage, BundleErrorMessageSchema, type BundleErrorPayload, BundleErrorPayloadSchema, type BundleRequestMessage, BundleRequestMessageSchema, type BundleRequestPayload, BundleRequestPayloadSchema, COMP_REGISTRY, ChatInput, type ChatInputProps, type ChatMessage, ChatPage, type ChatPageProps, type ClientConfig, ClientConfigSchema, type Component, type ComponentDefinition, type ComponentRegistryType, ComponentSchema, type ComponentsRegistry, type ComponentsSendMessage, ComponentsSendMessageSchema, type ComponentsSendPayload, ComponentsSendPayloadSchema, ConfirmDeleteModal, type ConfirmDeleteModalProps, ConnectionOverlay, type ConnectionStatus, ConnectionStatusPill, DEFAULT_API_URL, DEFAULT_THEME_COLOR, DSLErrorBoundary, DSLRenderer, type DSLRendererProps, DSLRendererPropsSchema, DashboardConversation, type DashboardConversationProps, DashboardPage, type DashboardPageProps, type DataRequestMessage, DataRequestMessageSchema, type DataRequestPayload, DataRequestPayloadSchema, type DataResponseMessage, DataResponseMessageSchema, type DataResponsePayload, DataResponsePayloadSchema, type DisconnectReason, DynamicComponent, type Expression, ExpressionSchema, FeedbackModal, type FeedbackModalProps, FileDownloads, type FileDownloadsProps, type ForDirective, ForDirectiveSchema, HomePage, type HomePageProps, type MenuData, MenuDataSchema, type MenuQueryFilters, MenuQueryFiltersSchema, type MenuV1Item, MenuV1Renderer, MenuV1RendererCollapsed, type MenuV1Root, type MenusRequestMessage, MenusRequestMessageSchema, type MenusRequestPayload, MenusRequestPayloadSchema, type MenusResponseMessage, MenusResponseMessageSchema, type MenusResponsePayload, MenusResponsePayloadSchema, type Message, MessageBubble, type MessageBubbleProps, MessageList, type MessageListProps, type MessageParticipant, MessageParticipantSchema, MessageSchema, type MountFunction, NewChatHero, type NewChatHeroProps, type PendingAttachment, type QuerySpec, QuerySpecSchema, ReportPage, type ReportPageProps, type ResolvedClientConfig, SDK_VERSION, SUPPORTED_MIME, SdkSession, type SdkSessionOptions, type SdkUser, ShadowBoundary, type ShadowBoundaryProps, Sidebar, type SidebarProps, SuperAtomAuthError, type SuperAtomAuthErrorCode, type SuperAtomGlobal, SuperatomAssistant, type SuperatomAssistantProps, SuperatomClient, SuperatomProvider, type SuperatomProviderProps, SuperatomSurface, type SuperatomSurfaceProps, type ThreadConversationRow, ThreadRowsSkeleton, type ThreadSummary, type Toast, type ToastKind, Toaster, type ToasterProps, type UIComponent, UIComponentSchema, type UIElement, UIElementSchema, type UILogEntry, UILogEntrySchema, type UILogsMessage, UILogsMessageSchema, type UILogsPayload, UILogsPayloadSchema, type UseSuperAtomOptions, type UseSuperAtomReturn, type UseVoiceInputReturn, type UserPromptAbortRequestMessage, UserPromptAbortRequestMessageSchema, type UserPromptAbortRequestPayload, UserPromptAbortRequestPayloadSchema, type UserPromptNarration, UserPromptNarrationSchema, type UserPromptRequestMessage, UserPromptRequestMessageSchema, type UserPromptRequestPayload, UserPromptRequestPayloadSchema, type UserPromptResponseMessage, UserPromptResponseMessageSchema, type UserPromptResponsePayload, UserPromptResponsePayloadSchema, type UserPromptSuggestionsRequestMessage, UserPromptSuggestionsRequestMessageSchema, type UserPromptSuggestionsRequestPayload, UserPromptSuggestionsRequestPayloadSchema, type UserPromptSuggestionsResponseMessage, UserPromptSuggestionsResponseMessageSchema, type UserPromptSuggestionsResponsePayload, UserPromptSuggestionsResponsePayloadSchema, type VoiceState, type WorkflowDescriptor, addAttachments, clearAttachments, clearDashboardThread, clearToasts, consumeAttachments, dashboardForThread, dashboardOnScreen, dashboardThread, dismissToast, getComponent, getComponentStates, getComponents, groupBundleDashboards, hasComponents, isAttachmentsFull, notifyAttachmentsFull, openDashboard, openDashboardThread, readBundleDashboards, readHomeLabel, registerBundleComponents, removeAttachment, resetAllFailedComponents, resetFailedComponent, resetRegistration, resolveThreadDashboard, runMenuItem, sanitizeDSL, searchRootFor, index as services, setDashboardFilters, setup, showToast, toast, useAssistantNavigation, useAttachments, useBookmarkForMessage, useBookmarks, useBundleDashboards, useConfigError, useConnectionStatus, useDynamicComponent, useHasAssistantNavigation, useHasSuperatomProvider, useHomeLabel, useSuperAtom, useThemeColor, useToasts, useVoiceInput, useVoiceShortcut, validateDSL, validateUIComponent, validateUIElement, withConditionalErrorBoundary };