@tangle-network/ui 11.12.0 → 11.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (276) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/_virtual/_rolldown/runtime.js +13 -0
  3. package/dist/auth/auth.d.ts +53 -0
  4. package/dist/{auth-DOETfnd9.js → auth/auth.js} +7 -37
  5. package/dist/auth/login-layout.d.ts +20 -0
  6. package/dist/auth/login-layout.js +36 -0
  7. package/dist/auth.d.ts +2 -1
  8. package/dist/auth.js +2 -1
  9. package/dist/chat/agent-timeline.d.ts +83 -0
  10. package/dist/chat/agent-timeline.js +236 -0
  11. package/dist/chat/chat-container.d.ts +51 -0
  12. package/dist/chat/chat-container.js +309 -0
  13. package/dist/chat/chat-message.d.ts +22 -0
  14. package/dist/chat/chat-message.js +38 -0
  15. package/dist/chat/message-list.d.ts +32 -0
  16. package/dist/chat/message-list.js +37 -0
  17. package/dist/chat/thinking-indicator.d.ts +6 -0
  18. package/dist/chat/thinking-indicator.js +38 -0
  19. package/dist/chat/user-message.d.ts +21 -0
  20. package/dist/chat/user-message.js +42 -0
  21. package/dist/chat.d.ts +6 -1
  22. package/dist/chat.js +6 -1
  23. package/dist/editor/document-editor-pane.d.ts +37 -0
  24. package/dist/editor/document-editor-pane.js +199 -0
  25. package/dist/editor/editor-lazy.js +37 -0
  26. package/dist/editor/editor-loading.js +21 -0
  27. package/dist/editor/editor-peers.d.ts +6 -0
  28. package/dist/editor/editor-peers.js +155 -0
  29. package/dist/editor/editor-provider.d.ts +97 -0
  30. package/dist/editor/editor-provider.js +253 -0
  31. package/dist/editor/editor-toolbar.d.ts +11 -0
  32. package/dist/editor/editor-toolbar.js +106 -0
  33. package/dist/editor/markdown-conversion.js +23 -0
  34. package/dist/editor/markdown-document-editor.js +103 -0
  35. package/dist/editor/tiptap-editor.d.ts +45 -0
  36. package/dist/editor/tiptap-editor.js +271 -0
  37. package/dist/editor/use-editor.d.ts +67 -0
  38. package/dist/editor/use-editor.js +158 -0
  39. package/dist/editor.d.ts +6 -119
  40. package/dist/editor.js +5 -1
  41. package/dist/files/file-artifact-pane.d.ts +47 -0
  42. package/dist/files/file-artifact-pane.js +114 -0
  43. package/dist/files/file-format.d.ts +51 -0
  44. package/dist/{file-format-BgXbr-Ib.js → files/file-format.js} +1 -1
  45. package/dist/files/file-preview.d.ts +27 -0
  46. package/dist/files/file-preview.js +359 -0
  47. package/dist/files/file-tabs.d.ts +19 -0
  48. package/dist/files/file-tabs.js +48 -0
  49. package/dist/files/file-tree.d.ts +31 -0
  50. package/dist/files/file-tree.js +135 -0
  51. package/dist/files/rich-file-tree.d.ts +62 -0
  52. package/dist/files/rich-file-tree.js +122 -0
  53. package/dist/files.d.ts +6 -1
  54. package/dist/files.js +6 -2
  55. package/dist/hooks/use-auth.d.ts +40 -0
  56. package/dist/hooks/use-auth.js +91 -0
  57. package/dist/hooks/use-auto-scroll.d.ts +11 -0
  58. package/dist/hooks/use-auto-scroll.js +48 -0
  59. package/dist/hooks/use-dropdown-menu.d.ts +12 -0
  60. package/dist/hooks/use-dropdown-menu.js +31 -0
  61. package/dist/hooks/use-live-time.d.ts +7 -0
  62. package/dist/hooks/use-live-time.js +22 -0
  63. package/dist/hooks/use-realtime-session.d.ts +32 -0
  64. package/dist/hooks/use-realtime-session.js +235 -0
  65. package/dist/hooks/use-run-collapse-state.d.ts +13 -0
  66. package/dist/hooks/use-run-collapse-state.js +24 -0
  67. package/dist/hooks/use-run-groups.d.ts +11 -0
  68. package/dist/hooks/use-run-groups.js +85 -0
  69. package/dist/hooks/use-sdk-session.d.ts +59 -0
  70. package/dist/hooks/use-sdk-session.js +322 -0
  71. package/dist/hooks/use-sse-stream.d.ts +124 -0
  72. package/dist/hooks/use-sse-stream.js +229 -0
  73. package/dist/hooks/use-tool-call-stream.d.ts +23 -0
  74. package/dist/hooks/use-tool-call-stream.js +75 -0
  75. package/dist/hooks.d.ts +11 -49
  76. package/dist/hooks.js +10 -110
  77. package/dist/index.d.ts +99 -25
  78. package/dist/index.js +86 -36
  79. package/dist/lib/focus.d.ts +55 -0
  80. package/dist/{focus-BcE_SHqz.js → lib/focus.js} +1 -1
  81. package/dist/lib/utils.d.ts +4 -0
  82. package/dist/{utils-C_uf36nf.js → lib/utils.js} +1 -1
  83. package/dist/{code-block-B9miUPht.d.ts → markdown/code-block.d.ts} +5 -6
  84. package/dist/{code-block-B36KVUSN.js → markdown/code-block.js} +22 -47
  85. package/dist/{markdown-C0atSabr.d.ts → markdown/markdown.d.ts} +4 -5
  86. package/dist/{markdown-Db08KAYF.js → markdown/markdown.js} +3 -3
  87. package/dist/markdown.d.ts +2 -2
  88. package/dist/markdown.js +2 -2
  89. package/dist/{openui-artifact-renderer-fkBQaoLO.d.ts → openui/openui-artifact-renderer.d.ts} +20 -21
  90. package/dist/{openui-artifact-renderer-DG_i2lOR.js → openui/openui-artifact-renderer.js} +9 -7
  91. package/dist/{schema-BpW9rSSG.js → openui/schema-compiled.js} +2 -354
  92. package/dist/{schema-DAstk-J4.d.ts → openui/schema-data.d.ts} +3 -24
  93. package/dist/openui/schema-data.js +206 -0
  94. package/dist/openui-schema.d.ts +22 -3
  95. package/dist/openui-schema.js +138 -1
  96. package/dist/openui.d.ts +3 -2
  97. package/dist/openui.js +3 -2
  98. package/dist/{artifact-pane-BL_DFWNl.d.ts → primitives/artifact-pane.d.ts} +3 -4
  99. package/dist/{artifact-pane-DMXT9a8U.js → primitives/artifact-pane.js} +2 -2
  100. package/dist/primitives/avatar.d.ts +8 -0
  101. package/dist/primitives/avatar.js +25 -0
  102. package/dist/primitives/badge.d.ts +22 -0
  103. package/dist/primitives/badge.js +47 -0
  104. package/dist/{button-yoIv77e2.d.ts → primitives/button.d.ts} +2 -2
  105. package/dist/primitives/button.js +113 -0
  106. package/dist/primitives/card.d.ts +18 -0
  107. package/dist/primitives/card.js +52 -0
  108. package/dist/primitives/code-block.d.ts +6 -0
  109. package/dist/primitives/code-block.js +13 -0
  110. package/dist/primitives/dialog.d.ts +23 -0
  111. package/dist/primitives/dialog.js +59 -0
  112. package/dist/primitives/drop-zone.d.ts +23 -0
  113. package/dist/primitives/drop-zone.js +104 -0
  114. package/dist/primitives/dropdown-menu.d.ts +29 -0
  115. package/dist/{dropdown-menu-BpcLa5vF.js → primitives/dropdown-menu.js} +2 -23
  116. package/dist/primitives/empty-state.d.ts +11 -0
  117. package/dist/primitives/empty-state.js +32 -0
  118. package/dist/primitives/heading.d.ts +23 -0
  119. package/dist/primitives/heading.js +38 -0
  120. package/dist/primitives/input.d.ts +23 -0
  121. package/dist/primitives/input.js +110 -0
  122. package/dist/primitives/label.d.ts +6 -0
  123. package/dist/primitives/label.js +16 -0
  124. package/dist/primitives/metric-strip.d.ts +48 -0
  125. package/dist/primitives/metric-strip.js +52 -0
  126. package/dist/primitives/page-header.d.ts +25 -0
  127. package/dist/primitives/page-header.js +47 -0
  128. package/dist/primitives/page-shell.d.ts +14 -0
  129. package/dist/primitives/page-shell.js +17 -0
  130. package/dist/primitives/progress.d.ts +9 -0
  131. package/dist/primitives/progress.js +29 -0
  132. package/dist/primitives/segmented-control.d.ts +40 -0
  133. package/dist/primitives/segmented-control.js +57 -0
  134. package/dist/primitives/select.d.ts +15 -0
  135. package/dist/primitives/select.js +74 -0
  136. package/dist/primitives/sidebar-drop-zone.d.ts +21 -0
  137. package/dist/primitives/sidebar-drop-zone.js +88 -0
  138. package/dist/primitives/skeleton.d.ts +10 -0
  139. package/dist/primitives/skeleton.js +50 -0
  140. package/dist/primitives/stat-card.d.ts +16 -0
  141. package/dist/primitives/stat-card.js +60 -0
  142. package/dist/primitives/status-pill.d.ts +44 -0
  143. package/dist/primitives/status-pill.js +119 -0
  144. package/dist/primitives/switch.d.ts +6 -0
  145. package/dist/primitives/switch.js +16 -0
  146. package/dist/primitives/table.d.ts +22 -0
  147. package/dist/primitives/table.js +63 -0
  148. package/dist/primitives/tabs.d.ts +13 -0
  149. package/dist/{tabs-BVHR6NkO.js → primitives/tabs.js} +3 -3
  150. package/dist/primitives/terminal-display.d.ts +25 -0
  151. package/dist/primitives/terminal-display.js +109 -0
  152. package/dist/primitives/text-shimmer.d.ts +16 -0
  153. package/dist/{text-shimmer-BUUo6I-g.js → primitives/text-shimmer.js} +2 -2
  154. package/dist/primitives/theme-toggle.d.ts +11 -0
  155. package/dist/primitives/theme-toggle.js +154 -0
  156. package/dist/primitives/toast.d.ts +29 -0
  157. package/dist/primitives/toast.js +142 -0
  158. package/dist/primitives/toolbar.d.ts +55 -0
  159. package/dist/primitives/toolbar.js +37 -0
  160. package/dist/primitives/upload-progress.d.ts +23 -0
  161. package/dist/primitives/upload-progress.js +72 -0
  162. package/dist/primitives.d.ts +35 -5
  163. package/dist/primitives.js +35 -9
  164. package/dist/{index-COgqsFAQ.d.ts → redaction/redacted-document.d.ts} +6 -7
  165. package/dist/{redaction-CGGB2ENG.js → redaction/redacted-document.js} +2 -2
  166. package/dist/redaction.d.ts +1 -1
  167. package/dist/redaction.js +1 -1
  168. package/dist/run/expandable-content.js +41 -0
  169. package/dist/run/expanded-tool-detail.d.ts +12 -0
  170. package/dist/run/expanded-tool-detail.js +163 -0
  171. package/dist/run/inline-thinking-item.d.ts +11 -0
  172. package/dist/run/inline-thinking-item.js +60 -0
  173. package/dist/run/inline-tool-item.d.ts +25 -0
  174. package/dist/run/inline-tool-item.js +63 -0
  175. package/dist/run/run-group.d.ts +26 -0
  176. package/dist/{run-group-BWGeesgs.js → run/run-group.js} +9 -60
  177. package/dist/run/run-item-primitives.d.ts +5 -0
  178. package/dist/{run-ZsIKPA6J.js → run/run-item-primitives.js} +2 -2
  179. package/dist/run/run-row-shell.d.ts +53 -0
  180. package/dist/run/run-row-shell.js +114 -0
  181. package/dist/{tool-call-feed-BeB1_4pX.d.ts → run/tool-call-feed.d.ts} +7 -12
  182. package/dist/{tool-call-feed-BpmMLpPX.js → run/tool-call-feed.js} +4 -4
  183. package/dist/run/tool-call-step.d.ts +5 -0
  184. package/dist/run/tool-call-step.js +82 -0
  185. package/dist/run.d.ts +8 -2
  186. package/dist/run.js +7 -4
  187. package/dist/sdk-hooks.d.ts +8 -1
  188. package/dist/sdk-hooks.js +8 -2
  189. package/dist/stores/active-sessions-store.d.ts +83 -0
  190. package/dist/{active-sessions-store-Gt1R0rFG.js → stores/active-sessions-store.js} +1 -1
  191. package/dist/stores/chat-store.d.ts +14 -0
  192. package/dist/stores/chat-store.js +33 -0
  193. package/dist/stores.d.ts +3 -16
  194. package/dist/stores.js +2 -33
  195. package/dist/tool-previews/command-preview.d.ts +11 -0
  196. package/dist/tool-previews/command-preview.js +91 -0
  197. package/dist/tool-previews/diff-preview.d.ts +7 -0
  198. package/dist/tool-previews/diff-preview.js +76 -0
  199. package/dist/tool-previews/glob-results-preview.d.ts +7 -0
  200. package/dist/tool-previews/glob-results-preview.js +53 -0
  201. package/dist/tool-previews/grep-results-preview.d.ts +7 -0
  202. package/dist/tool-previews/grep-results-preview.js +99 -0
  203. package/dist/tool-previews/preview-primitives.js +58 -0
  204. package/dist/tool-previews/question-preview.d.ts +7 -0
  205. package/dist/tool-previews/question-preview.js +63 -0
  206. package/dist/tool-previews/web-search-preview.d.ts +7 -0
  207. package/dist/tool-previews/web-search-preview.js +78 -0
  208. package/dist/tool-previews/write-file-preview.d.ts +11 -0
  209. package/dist/tool-previews/write-file-preview.js +52 -0
  210. package/dist/tool-previews.d.ts +7 -1
  211. package/dist/tool-previews.js +7 -1
  212. package/dist/{branding-26d5ARIr.d.ts → types/branding.d.ts} +2 -3
  213. package/dist/{message-vhUI0c5G.d.ts → types/message.d.ts} +2 -3
  214. package/dist/{parts-5mhy9yJ3.d.ts → types/parts.d.ts} +8 -9
  215. package/dist/{run-OyWmIDqu.d.ts → types/run.d.ts} +9 -10
  216. package/dist/{tool-display-DgmL5rIU.d.ts → types/tool-display.d.ts} +5 -6
  217. package/dist/types.d.ts +5 -5
  218. package/dist/utils/copy-text.d.ts +7 -0
  219. package/dist/{utils-Bl_CZ0Qp.js → utils/copy-text.js} +1 -11
  220. package/dist/utils/format.d.ts +22 -0
  221. package/dist/{format-DfcLWqMa.js → utils/format.js} +1 -1
  222. package/dist/utils/time-ago.d.ts +3 -0
  223. package/dist/utils/time-ago.js +11 -0
  224. package/dist/utils/tool-display.d.ts +16 -0
  225. package/dist/{tool-display-BAuAVa43.js → utils/tool-display.js} +1 -1
  226. package/dist/utils.d.ts +6 -1
  227. package/dist/utils.js +6 -5
  228. package/package.json +2 -2
  229. package/src/files/rich-file-tree.stories.tsx +1 -1
  230. package/src/files/rich-file-tree.tsx +12 -9
  231. package/src/markdown/code-block.test.tsx +46 -2
  232. package/src/markdown/code-block.tsx +23 -60
  233. package/src/primitives/button.stories.tsx +37 -1
  234. package/src/primitives/button.test.tsx +230 -0
  235. package/src/primitives/button.tsx +62 -14
  236. package/src/primitives/card-anatomy.stories.tsx +51 -0
  237. package/src/primitives/card.test.tsx +71 -0
  238. package/src/primitives/card.tsx +25 -13
  239. package/src/primitives/heading.stories.tsx +35 -0
  240. package/src/primitives/heading.test.tsx +56 -0
  241. package/src/primitives/heading.tsx +76 -0
  242. package/src/primitives/index.ts +8 -0
  243. package/src/primitives/input.stories.tsx +28 -0
  244. package/src/primitives/input.test.tsx +161 -0
  245. package/src/primitives/input.tsx +34 -28
  246. package/src/primitives/page-header.stories.tsx +51 -0
  247. package/src/primitives/page-header.test.tsx +48 -0
  248. package/src/primitives/page-header.tsx +35 -35
  249. package/src/primitives/page-shell.stories.tsx +89 -0
  250. package/src/primitives/page-shell.test.tsx +24 -0
  251. package/src/primitives/page-shell.tsx +26 -0
  252. package/src/primitives/table-wrapper.stories.tsx +54 -0
  253. package/src/primitives/table.test.tsx +72 -0
  254. package/src/primitives/table.tsx +33 -12
  255. package/src/primitives/theme-toggle.test.tsx +167 -0
  256. package/src/primitives/theme-toggle.tsx +111 -39
  257. package/dist/active-sessions-store-nl70ZnMC.d.ts +0 -84
  258. package/dist/button-C87nEe2R.js +0 -78
  259. package/dist/chat-DDvF2oGQ.js +0 -672
  260. package/dist/diff-preview-BcK3nRXb.js +0 -533
  261. package/dist/document-editor-pane-BilJfiCo.d.ts +0 -136
  262. package/dist/document-editor-pane-POsq5Q0o.js +0 -1279
  263. package/dist/files-hywocVZz.js +0 -753
  264. package/dist/index-2UntyjBb.d.ts +0 -52
  265. package/dist/index-BgUHilZm.d.ts +0 -108
  266. package/dist/index-CJ8wRfiC.d.ts +0 -236
  267. package/dist/index-CPDET_s1.d.ts +0 -549
  268. package/dist/index-Cg6gYAqh.d.ts +0 -73
  269. package/dist/index-Cs7j8V7l.d.ts +0 -203
  270. package/dist/index-DjKxO357.d.ts +0 -128
  271. package/dist/primitives-Bx59fT-U.js +0 -1239
  272. package/dist/table-Bss73DhB.js +0 -146
  273. package/dist/tool-call-step-DNebqhmX.js +0 -434
  274. package/dist/use-auto-scroll-C5Pjeqon.js +0 -153
  275. package/dist/use-sse-stream-DjqRuDft.js +0 -884
  276. package/dist/use-sse-stream-Dm6R5YWz.d.ts +0 -282
@@ -0,0 +1,235 @@
1
+ import { bumpActiveSessionActivity, registerActiveSession, setActiveSessionAttention, setActiveSessionConnection, setActiveSessionError, setActiveSessionRunning, setForegroundActiveSession, unregisterActiveSession, updateActiveSessionMeta } from "../stores/active-sessions-store.js";
2
+ import { createElement, useEffect, useMemo, useRef, useState } from "react";
3
+ //#region src/hooks/use-realtime-session.ts
4
+ function parseEvent(message) {
5
+ try {
6
+ const parsed = JSON.parse(message);
7
+ return typeof parsed?.type === "string" ? parsed : null;
8
+ } catch {
9
+ return null;
10
+ }
11
+ }
12
+ function eventTimestamp(event) {
13
+ const rootTimestamp = event.timestamp;
14
+ if (typeof rootTimestamp === "number" && Number.isFinite(rootTimestamp)) return rootTimestamp;
15
+ const raw = event.data?.timestamp ?? event.data?.ts ?? event.data?.time ?? event.data?.eventAt;
16
+ if (typeof raw === "number" && Number.isFinite(raw)) return raw;
17
+ return null;
18
+ }
19
+ function resolveErrorMessage(event) {
20
+ const message = event.data?.message;
21
+ return typeof message === "string" && message.length > 0 ? message : null;
22
+ }
23
+ function updateStoreFromEvent(sessionId, event) {
24
+ const lastEventAt = eventTimestamp(event) ?? Date.now();
25
+ bumpActiveSessionActivity(sessionId, { lastEventAt });
26
+ if (event.type === "session.run.started") {
27
+ setActiveSessionRunning(sessionId, true, { lastEventAt });
28
+ return;
29
+ }
30
+ if (event.type === "session.run.completed" || event.type === "done" || event.type === "result") {
31
+ setActiveSessionRunning(sessionId, false, { lastEventAt });
32
+ return;
33
+ }
34
+ if (event.type === "session.attention") {
35
+ setActiveSessionAttention(sessionId, true, { lastEventAt });
36
+ return;
37
+ }
38
+ if (event.type === "error" || event.type === "session.run.failed") {
39
+ setActiveSessionError(sessionId, resolveErrorMessage(event) ?? "Session error");
40
+ return;
41
+ }
42
+ }
43
+ function useRealtimeSession({ sessionId, projectId = null, projectLabel, title, href, metadata, connectUrl, enabled = true, foreground = true, keepRegistered = true, reconnect = true, reconnectIntervalMs = 1500, maxReconnectAttempts = Infinity, transportMode = "websocket", onEvent, onOpen, onClose, onError }) {
44
+ const [connectionState, setConnectionState] = useState("disconnected");
45
+ const [lastError, setLastError] = useState(null);
46
+ const [reconnectAttempts, setReconnectAttempts] = useState(0);
47
+ const socketRef = useRef(null);
48
+ const timerRef = useRef(null);
49
+ const reconnectAttemptsRef = useRef(0);
50
+ const shouldReconnectRef = useRef(true);
51
+ const registration = useMemo(() => ({
52
+ sessionId,
53
+ projectId,
54
+ projectLabel,
55
+ title,
56
+ href,
57
+ metadata
58
+ }), [
59
+ href,
60
+ metadata,
61
+ projectId,
62
+ projectLabel,
63
+ sessionId,
64
+ title
65
+ ]);
66
+ useEffect(() => {
67
+ if (!sessionId || !keepRegistered) return void 0;
68
+ registerActiveSession(registration);
69
+ return () => {
70
+ unregisterActiveSession(sessionId);
71
+ };
72
+ }, [
73
+ keepRegistered,
74
+ registration,
75
+ sessionId
76
+ ]);
77
+ useEffect(() => {
78
+ if (!sessionId || !keepRegistered) return;
79
+ updateActiveSessionMeta(sessionId, {
80
+ projectId,
81
+ projectLabel,
82
+ title,
83
+ href,
84
+ metadata
85
+ });
86
+ }, [
87
+ href,
88
+ keepRegistered,
89
+ metadata,
90
+ projectId,
91
+ projectLabel,
92
+ sessionId,
93
+ title
94
+ ]);
95
+ useEffect(() => {
96
+ if (!sessionId || !foreground) return void 0;
97
+ setForegroundActiveSession(sessionId);
98
+ return () => {
99
+ setForegroundActiveSession(null);
100
+ };
101
+ }, [foreground, sessionId]);
102
+ useEffect(() => {
103
+ if (!enabled || !sessionId || !connectUrl || typeof window === "undefined") {
104
+ setConnectionState("disconnected");
105
+ if (sessionId) setActiveSessionConnection(sessionId, {
106
+ connectionState: "disconnected",
107
+ reconnectState: "idle",
108
+ transportMode
109
+ });
110
+ return;
111
+ }
112
+ shouldReconnectRef.current = true;
113
+ const clearReconnectTimer = () => {
114
+ if (timerRef.current != null) {
115
+ window.clearTimeout(timerRef.current);
116
+ timerRef.current = null;
117
+ }
118
+ };
119
+ const connect = () => {
120
+ clearReconnectTimer();
121
+ setConnectionState(reconnectAttemptsRef.current > 0 ? "reconnecting" : "connecting");
122
+ setActiveSessionConnection(sessionId, {
123
+ connectionState: reconnectAttemptsRef.current > 0 ? "reconnecting" : "connecting",
124
+ reconnectState: reconnectAttemptsRef.current > 0 ? "reconnecting" : "idle",
125
+ transportMode,
126
+ lastError: null
127
+ });
128
+ const socket = new window.WebSocket(connectUrl);
129
+ socketRef.current = socket;
130
+ socket.onopen = () => {
131
+ reconnectAttemptsRef.current = 0;
132
+ setReconnectAttempts(0);
133
+ setLastError(null);
134
+ setConnectionState("connected");
135
+ registerActiveSession(registration);
136
+ setActiveSessionConnection(sessionId, {
137
+ connectionState: "connected",
138
+ reconnectState: "idle",
139
+ transportMode,
140
+ lastError: null,
141
+ lastEventAt: Date.now()
142
+ });
143
+ onOpen?.();
144
+ };
145
+ socket.onmessage = (message) => {
146
+ const event = parseEvent(message.data);
147
+ if (!event) return;
148
+ registerActiveSession(registration);
149
+ updateStoreFromEvent(sessionId, event);
150
+ onEvent?.(event);
151
+ };
152
+ socket.onerror = () => {
153
+ const nextError = "Realtime session connection error";
154
+ setLastError(nextError);
155
+ setConnectionState("error");
156
+ setActiveSessionConnection(sessionId, {
157
+ connectionState: "error",
158
+ reconnectState: reconnect ? "reconnecting" : "failed",
159
+ transportMode,
160
+ lastError: nextError
161
+ });
162
+ onError?.(/* @__PURE__ */ new Error(nextError));
163
+ };
164
+ socket.onclose = () => {
165
+ socketRef.current = null;
166
+ onClose?.();
167
+ if (!shouldReconnectRef.current || !reconnect) {
168
+ setConnectionState("disconnected");
169
+ setActiveSessionConnection(sessionId, {
170
+ connectionState: "disconnected",
171
+ reconnectState: "idle",
172
+ transportMode
173
+ });
174
+ return;
175
+ }
176
+ reconnectAttemptsRef.current += 1;
177
+ setReconnectAttempts(reconnectAttemptsRef.current);
178
+ if (reconnectAttemptsRef.current > maxReconnectAttempts) {
179
+ setConnectionState("error");
180
+ setActiveSessionConnection(sessionId, {
181
+ connectionState: "error",
182
+ reconnectState: "failed",
183
+ transportMode,
184
+ lastError: "Unable to reconnect to realtime session"
185
+ });
186
+ return;
187
+ }
188
+ setConnectionState("reconnecting");
189
+ timerRef.current = window.setTimeout(connect, reconnectIntervalMs);
190
+ };
191
+ };
192
+ connect();
193
+ return () => {
194
+ shouldReconnectRef.current = false;
195
+ clearReconnectTimer();
196
+ const socket = socketRef.current;
197
+ socketRef.current = null;
198
+ if (socket && socket.readyState < WebSocket.CLOSING) socket.close();
199
+ };
200
+ }, [
201
+ connectUrl,
202
+ enabled,
203
+ maxReconnectAttempts,
204
+ onClose,
205
+ onError,
206
+ onEvent,
207
+ onOpen,
208
+ reconnect,
209
+ reconnectIntervalMs,
210
+ registration,
211
+ sessionId,
212
+ transportMode
213
+ ]);
214
+ return {
215
+ connectionState,
216
+ lastError,
217
+ reconnectAttempts,
218
+ isConnected: connectionState === "connected"
219
+ };
220
+ }
221
+ function RealtimeSessionRegistryItem(props) {
222
+ useRealtimeSession({
223
+ ...props,
224
+ foreground: props.foreground ?? false
225
+ });
226
+ return null;
227
+ }
228
+ function RealtimeSessionRegistry({ sessions }) {
229
+ return sessions.map((session) => createElement(RealtimeSessionRegistryItem, {
230
+ key: session.key ?? session.sessionId,
231
+ ...session
232
+ }));
233
+ }
234
+ //#endregion
235
+ export { RealtimeSessionRegistry, useRealtimeSession };
@@ -0,0 +1,13 @@
1
+ import { Run } from "../types/run.js";
2
+ //#region src/hooks/use-run-collapse-state.d.ts
3
+ /**
4
+ * Manages per-run collapse state with auto-collapse after run completion.
5
+ *
6
+ * - Runs stay expanded by default
7
+ * - Collapse is manual only
8
+ */
9
+ export declare function useRunCollapseState(runs: Run[]): {
10
+ isCollapsed: (runId: string) => boolean;
11
+ toggleCollapse: (runId: string) => void;
12
+ };
13
+ //#endregion
@@ -0,0 +1,24 @@
1
+ import { useCallback, useState } from "react";
2
+ //#region src/hooks/use-run-collapse-state.ts
3
+ /**
4
+ * Manages per-run collapse state with auto-collapse after run completion.
5
+ *
6
+ * - Runs stay expanded by default
7
+ * - Collapse is manual only
8
+ */
9
+ function useRunCollapseState(runs) {
10
+ const [collapsedMap, setCollapsedMap] = useState({});
11
+ return {
12
+ isCollapsed: useCallback((runId) => {
13
+ return collapsedMap[runId] ?? false;
14
+ }, [collapsedMap]),
15
+ toggleCollapse: useCallback((runId) => {
16
+ setCollapsedMap((prev) => ({
17
+ ...prev,
18
+ [runId]: !prev[runId]
19
+ }));
20
+ }, [])
21
+ };
22
+ }
23
+ //#endregion
24
+ export { useRunCollapseState };
@@ -0,0 +1,11 @@
1
+ import { SessionMessage } from "../types/message.js";
2
+ import { SessionPart } from "../types/parts.js";
3
+ import { GroupedMessage } from "../types/run.js";
4
+ //#region src/hooks/use-run-groups.d.ts
5
+ export interface UseRunGroupsOptions {
6
+ messages: SessionMessage[];
7
+ partMap: Record<string, SessionPart[]>;
8
+ isStreaming: boolean;
9
+ }
10
+ export declare function useRunGroups({ messages, partMap, isStreaming }: UseRunGroupsOptions): GroupedMessage[];
11
+ //#endregion
@@ -0,0 +1,85 @@
1
+ import { getToolCategory } from "../utils/tool-display.js";
2
+ import { useMemo } from "react";
3
+ //#region src/hooks/use-run-groups.ts
4
+ function computeRunStats(messages, partMap) {
5
+ const stats = {
6
+ toolCount: 0,
7
+ messageCount: messages.length,
8
+ thinkingDurationMs: 0,
9
+ textPartCount: 0,
10
+ toolCategories: /* @__PURE__ */ new Set()
11
+ };
12
+ for (const msg of messages) {
13
+ const parts = partMap[msg.id] ?? [];
14
+ for (const part of parts) switch (part.type) {
15
+ case "tool":
16
+ stats.toolCount++;
17
+ stats.toolCategories.add(getToolCategory(part.tool));
18
+ break;
19
+ case "text":
20
+ if (!part.synthetic) stats.textPartCount++;
21
+ break;
22
+ case "reasoning": {
23
+ const start = part.time?.start;
24
+ const end = part.time?.end;
25
+ if (start && end) stats.thinkingDurationMs += end - start;
26
+ break;
27
+ }
28
+ }
29
+ }
30
+ return stats;
31
+ }
32
+ function getLastTextContent(messages, partMap) {
33
+ for (let i = messages.length - 1; i >= 0; i--) {
34
+ const parts = partMap[messages[i].id] ?? [];
35
+ for (let j = parts.length - 1; j >= 0; j--) {
36
+ const part = parts[j];
37
+ if (part.type === "text" && !part.synthetic && part.text.trim()) return part.text.trim();
38
+ }
39
+ }
40
+ return null;
41
+ }
42
+ function useRunGroups({ messages, partMap, isStreaming }) {
43
+ return useMemo(() => {
44
+ const groups = [];
45
+ let currentRunMessages = [];
46
+ function flushRun(streaming) {
47
+ if (currentRunMessages.length === 0) return;
48
+ const msgs = [...currentRunMessages];
49
+ const stats = computeRunStats(msgs, partMap);
50
+ const summaryText = getLastTextContent(msgs, partMap);
51
+ const isComplete = !streaming;
52
+ groups.push({
53
+ type: "run",
54
+ run: {
55
+ id: msgs[0].id,
56
+ messages: msgs,
57
+ isComplete,
58
+ isStreaming: streaming,
59
+ stats,
60
+ summaryText,
61
+ finalTextPart: null
62
+ }
63
+ });
64
+ currentRunMessages = [];
65
+ }
66
+ for (let i = 0; i < messages.length; i++) {
67
+ const msg = messages[i];
68
+ if (msg.role === "user") {
69
+ flushRun(false);
70
+ groups.push({
71
+ type: "user",
72
+ message: msg
73
+ });
74
+ } else currentRunMessages.push(msg);
75
+ }
76
+ if (currentRunMessages.length > 0) flushRun(isStreaming);
77
+ return groups;
78
+ }, [
79
+ messages,
80
+ partMap,
81
+ isStreaming
82
+ ]);
83
+ }
84
+ //#endregion
85
+ export { useRunGroups };
@@ -0,0 +1,59 @@
1
+ import { SessionMessage } from "../types/message.js";
2
+ import { SessionPart } from "../types/parts.js";
3
+ //#region src/hooks/use-sdk-session.d.ts
4
+ export interface SdkSessionAttachment {
5
+ name: string;
6
+ size?: number;
7
+ }
8
+ export interface SdkSessionSeed {
9
+ id: string;
10
+ role: SessionMessage["role"];
11
+ createdAt?: number | string | Date;
12
+ content?: string;
13
+ attachments?: SdkSessionAttachment[];
14
+ parts?: SessionPart[];
15
+ }
16
+ export interface SdkSessionEvent {
17
+ type: string;
18
+ data?: Record<string, unknown>;
19
+ }
20
+ export interface BeginAssistantMessageOptions {
21
+ id?: string;
22
+ role?: Extract<SessionMessage["role"], "assistant" | "system">;
23
+ createdAt?: number | string | Date;
24
+ }
25
+ export interface AppendUserMessageOptions {
26
+ id?: string;
27
+ role?: Extract<SessionMessage["role"], "user" | "system">;
28
+ content: string;
29
+ createdAt?: number | string | Date;
30
+ attachments?: SdkSessionAttachment[];
31
+ }
32
+ export interface CompleteAssistantMessageOptions {
33
+ messageId?: string;
34
+ finalText?: string;
35
+ }
36
+ export interface ApplySdkEventOptions {
37
+ messageId?: string;
38
+ }
39
+ export interface UseSdkSessionOptions {
40
+ initialMessages?: SdkSessionSeed[];
41
+ }
42
+ export interface UseSdkSessionReturn {
43
+ messages: SessionMessage[];
44
+ partMap: Record<string, SessionPart[]>;
45
+ isStreaming: boolean;
46
+ activeAssistantMessageId: string | null;
47
+ replaceHistory: (messages: SdkSessionSeed[]) => void;
48
+ appendUserMessage: (message: AppendUserMessageOptions) => string;
49
+ beginAssistantMessage: (options?: BeginAssistantMessageOptions) => string;
50
+ applySdkEvent: (event: SdkSessionEvent, options?: ApplySdkEventOptions) => void;
51
+ completeAssistantMessage: (options?: CompleteAssistantMessageOptions) => void;
52
+ failAssistantMessage: (error: string, options?: {
53
+ messageId?: string;
54
+ }) => void;
55
+ setStreaming: (value: boolean) => void;
56
+ reset: () => void;
57
+ }
58
+ export declare function useSdkSession({ initialMessages }?: UseSdkSessionOptions): UseSdkSessionReturn;
59
+ //#endregion