@tangle-network/sandbox-ui 0.3.6 → 0.3.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/active-sessions-store-CeOmXgv5.d.ts +85 -0
  2. package/dist/artifact-pane-Bh45Ssco.d.ts +24 -0
  3. package/dist/{chat-container-C8eHLw8z.d.ts → chat-container-Dn1jWtWo.d.ts} +20 -3
  4. package/dist/chat.d.ts +17 -4
  5. package/dist/chat.js +6 -2
  6. package/dist/{chunk-4F2GJRGU.js → chunk-6H3EFUUC.js} +196 -77
  7. package/dist/{chunk-WUR652Y3.js → chunk-72UEKFZ2.js} +113 -89
  8. package/dist/{chunk-TXI4MZAZ.js → chunk-CSIXZEKN.js} +152 -1
  9. package/dist/{chunk-5LV6DZZF.js → chunk-FOQTE67I.js} +278 -21
  10. package/dist/chunk-MGCVTFKB.js +10910 -0
  11. package/dist/chunk-OEX7NZE3.js +321 -0
  12. package/dist/chunk-Q56BYXQF.js +61 -0
  13. package/dist/{chunk-QGI5E7JD.js → chunk-RQOX5JRR.js} +541 -76
  14. package/dist/{chunk-PDV7W4NY.js → chunk-SULQQJPB.js} +1 -56
  15. package/dist/chunk-W4LM3QYZ.js +54 -0
  16. package/dist/{chunk-JF6E2DS5.js → chunk-ZYGWTIWO.js} +171 -155
  17. package/dist/document-editor-pane-Bk-9MQmw.d.ts +116 -0
  18. package/dist/document-editor-pane-GRIQOJHB.js +11 -0
  19. package/dist/editor.d.ts +7 -84
  20. package/dist/editor.js +18 -699
  21. package/dist/{expanded-tool-detail-BDi_h_dZ.d.ts → expanded-tool-detail-DM5M_T9h.d.ts} +10 -2
  22. package/dist/{file-tabs-CmaoDVBI.d.ts → file-tabs-BLfxfmAH.d.ts} +1 -22
  23. package/dist/files.d.ts +25 -3
  24. package/dist/files.js +2 -1
  25. package/dist/hooks.d.ts +3 -1
  26. package/dist/hooks.js +6 -1
  27. package/dist/index.d.ts +13 -7
  28. package/dist/index.js +26 -9
  29. package/dist/pages.js +4 -2
  30. package/dist/primitives.d.ts +45 -1
  31. package/dist/primitives.js +9 -3
  32. package/dist/run.d.ts +1 -1
  33. package/dist/run.js +1 -1
  34. package/dist/sdk-hooks.d.ts +32 -1
  35. package/dist/sdk-hooks.js +6 -1
  36. package/dist/stores.d.ts +1 -0
  37. package/dist/stores.js +60 -1
  38. package/dist/types.d.ts +2 -0
  39. package/dist/workspace.d.ts +84 -6
  40. package/dist/workspace.js +10 -4
  41. package/package.json +17 -6
@@ -1,6 +1,17 @@
1
1
  import {
2
2
  parseToolEvent
3
3
  } from "./chunk-CCKNIAS7.js";
4
+ import {
5
+ bumpActiveSessionActivity,
6
+ registerActiveSession,
7
+ setActiveSessionAttention,
8
+ setActiveSessionConnection,
9
+ setActiveSessionError,
10
+ setActiveSessionRunning,
11
+ setForegroundActiveSession,
12
+ unregisterActiveSession,
13
+ updateActiveSessionMeta
14
+ } from "./chunk-OEX7NZE3.js";
4
15
 
5
16
  // src/hooks/use-tool-call-stream.ts
6
17
  import { useState, useCallback, useRef } from "react";
@@ -744,8 +755,252 @@ function useSdkSession({
744
755
  };
745
756
  }
746
757
 
758
+ // src/hooks/use-realtime-session.ts
759
+ import { createElement, useEffect as useEffect2, useMemo as useMemo2, useRef as useRef4, useState as useState4 } from "react";
760
+ function parseEvent(message) {
761
+ try {
762
+ const parsed = JSON.parse(message);
763
+ return typeof parsed?.type === "string" ? parsed : null;
764
+ } catch {
765
+ return null;
766
+ }
767
+ }
768
+ function eventTimestamp(event) {
769
+ const rootTimestamp = event.timestamp;
770
+ if (typeof rootTimestamp === "number" && Number.isFinite(rootTimestamp)) {
771
+ return rootTimestamp;
772
+ }
773
+ const raw = event.data?.timestamp ?? event.data?.ts ?? event.data?.time ?? event.data?.eventAt;
774
+ if (typeof raw === "number" && Number.isFinite(raw)) return raw;
775
+ return null;
776
+ }
777
+ function resolveErrorMessage(event) {
778
+ const message = event.data?.message;
779
+ return typeof message === "string" && message.length > 0 ? message : null;
780
+ }
781
+ function updateStoreFromEvent(sessionId, event) {
782
+ const lastEventAt = eventTimestamp(event) ?? Date.now();
783
+ bumpActiveSessionActivity(sessionId, { lastEventAt });
784
+ if (event.type === "session.run.started") {
785
+ setActiveSessionRunning(sessionId, true, { lastEventAt });
786
+ return;
787
+ }
788
+ if (event.type === "session.run.completed" || event.type === "done" || event.type === "result") {
789
+ setActiveSessionRunning(sessionId, false, { lastEventAt });
790
+ return;
791
+ }
792
+ if (event.type === "session.attention") {
793
+ setActiveSessionAttention(sessionId, true, { lastEventAt });
794
+ return;
795
+ }
796
+ if (event.type === "error" || event.type === "session.run.failed") {
797
+ setActiveSessionError(sessionId, resolveErrorMessage(event) ?? "Session error");
798
+ return;
799
+ }
800
+ }
801
+ function useRealtimeSession({
802
+ sessionId,
803
+ projectId = null,
804
+ projectLabel,
805
+ title,
806
+ href,
807
+ metadata,
808
+ connectUrl,
809
+ enabled = true,
810
+ foreground = true,
811
+ keepRegistered = true,
812
+ reconnect = true,
813
+ reconnectIntervalMs = 1500,
814
+ maxReconnectAttempts = Infinity,
815
+ transportMode = "websocket",
816
+ onEvent,
817
+ onOpen,
818
+ onClose,
819
+ onError
820
+ }) {
821
+ const [connectionState, setConnectionState] = useState4("disconnected");
822
+ const [lastError, setLastError] = useState4(null);
823
+ const [reconnectAttempts, setReconnectAttempts] = useState4(0);
824
+ const socketRef = useRef4(null);
825
+ const timerRef = useRef4(null);
826
+ const reconnectAttemptsRef = useRef4(0);
827
+ const shouldReconnectRef = useRef4(true);
828
+ const registration = useMemo2(
829
+ () => ({
830
+ sessionId,
831
+ projectId,
832
+ projectLabel,
833
+ title,
834
+ href,
835
+ metadata
836
+ }),
837
+ [href, metadata, projectId, projectLabel, sessionId, title]
838
+ );
839
+ useEffect2(() => {
840
+ if (!sessionId || !keepRegistered) return void 0;
841
+ registerActiveSession(registration);
842
+ return () => {
843
+ unregisterActiveSession(sessionId);
844
+ };
845
+ }, [keepRegistered, registration, sessionId]);
846
+ useEffect2(() => {
847
+ if (!sessionId || !keepRegistered) return;
848
+ updateActiveSessionMeta(sessionId, {
849
+ projectId,
850
+ projectLabel,
851
+ title,
852
+ href,
853
+ metadata
854
+ });
855
+ }, [href, keepRegistered, metadata, projectId, projectLabel, sessionId, title]);
856
+ useEffect2(() => {
857
+ if (!sessionId || !foreground) return void 0;
858
+ setForegroundActiveSession(sessionId);
859
+ return () => {
860
+ setForegroundActiveSession(null);
861
+ };
862
+ }, [foreground, sessionId]);
863
+ useEffect2(() => {
864
+ if (!enabled || !sessionId || !connectUrl || typeof window === "undefined") {
865
+ setConnectionState("disconnected");
866
+ if (sessionId) {
867
+ setActiveSessionConnection(sessionId, {
868
+ connectionState: "disconnected",
869
+ reconnectState: "idle",
870
+ transportMode
871
+ });
872
+ }
873
+ return void 0;
874
+ }
875
+ shouldReconnectRef.current = true;
876
+ const clearReconnectTimer = () => {
877
+ if (timerRef.current != null) {
878
+ window.clearTimeout(timerRef.current);
879
+ timerRef.current = null;
880
+ }
881
+ };
882
+ const connect = () => {
883
+ clearReconnectTimer();
884
+ setConnectionState(reconnectAttemptsRef.current > 0 ? "reconnecting" : "connecting");
885
+ setActiveSessionConnection(sessionId, {
886
+ connectionState: reconnectAttemptsRef.current > 0 ? "reconnecting" : "connecting",
887
+ reconnectState: reconnectAttemptsRef.current > 0 ? "reconnecting" : "idle",
888
+ transportMode,
889
+ lastError: null
890
+ });
891
+ const socket = new window.WebSocket(connectUrl);
892
+ socketRef.current = socket;
893
+ socket.onopen = () => {
894
+ reconnectAttemptsRef.current = 0;
895
+ setReconnectAttempts(0);
896
+ setLastError(null);
897
+ setConnectionState("connected");
898
+ registerActiveSession(registration);
899
+ setActiveSessionConnection(sessionId, {
900
+ connectionState: "connected",
901
+ reconnectState: "idle",
902
+ transportMode,
903
+ lastError: null,
904
+ lastEventAt: Date.now()
905
+ });
906
+ onOpen?.();
907
+ };
908
+ socket.onmessage = (message) => {
909
+ const event = parseEvent(message.data);
910
+ if (!event) return;
911
+ registerActiveSession(registration);
912
+ updateStoreFromEvent(sessionId, event);
913
+ onEvent?.(event);
914
+ };
915
+ socket.onerror = () => {
916
+ const nextError = "Realtime session connection error";
917
+ setLastError(nextError);
918
+ setConnectionState("error");
919
+ setActiveSessionConnection(sessionId, {
920
+ connectionState: "error",
921
+ reconnectState: reconnect ? "reconnecting" : "failed",
922
+ transportMode,
923
+ lastError: nextError
924
+ });
925
+ onError?.(new Error(nextError));
926
+ };
927
+ socket.onclose = () => {
928
+ socketRef.current = null;
929
+ onClose?.();
930
+ if (!shouldReconnectRef.current || !reconnect) {
931
+ setConnectionState("disconnected");
932
+ setActiveSessionConnection(sessionId, {
933
+ connectionState: "disconnected",
934
+ reconnectState: "idle",
935
+ transportMode
936
+ });
937
+ return;
938
+ }
939
+ reconnectAttemptsRef.current += 1;
940
+ setReconnectAttempts(reconnectAttemptsRef.current);
941
+ if (reconnectAttemptsRef.current > maxReconnectAttempts) {
942
+ setConnectionState("error");
943
+ setActiveSessionConnection(sessionId, {
944
+ connectionState: "error",
945
+ reconnectState: "failed",
946
+ transportMode,
947
+ lastError: "Unable to reconnect to realtime session"
948
+ });
949
+ return;
950
+ }
951
+ setConnectionState("reconnecting");
952
+ timerRef.current = window.setTimeout(connect, reconnectIntervalMs);
953
+ };
954
+ };
955
+ connect();
956
+ return () => {
957
+ shouldReconnectRef.current = false;
958
+ clearReconnectTimer();
959
+ const socket = socketRef.current;
960
+ socketRef.current = null;
961
+ if (socket && socket.readyState < WebSocket.CLOSING) {
962
+ socket.close();
963
+ }
964
+ };
965
+ }, [
966
+ connectUrl,
967
+ enabled,
968
+ maxReconnectAttempts,
969
+ onClose,
970
+ onError,
971
+ onEvent,
972
+ onOpen,
973
+ reconnect,
974
+ reconnectIntervalMs,
975
+ registration,
976
+ sessionId,
977
+ transportMode
978
+ ]);
979
+ return {
980
+ connectionState,
981
+ lastError,
982
+ reconnectAttempts,
983
+ isConnected: connectionState === "connected"
984
+ };
985
+ }
986
+ function RealtimeSessionRegistryItem(props) {
987
+ useRealtimeSession({
988
+ ...props,
989
+ foreground: props.foreground ?? false
990
+ });
991
+ return null;
992
+ }
993
+ function RealtimeSessionRegistry({ sessions }) {
994
+ return sessions.map(
995
+ (session) => createElement(RealtimeSessionRegistryItem, {
996
+ key: session.key ?? session.sessionId,
997
+ ...session
998
+ })
999
+ );
1000
+ }
1001
+
747
1002
  // src/hooks/use-session-stream.ts
748
- import { useCallback as useCallback4, useEffect as useEffect2, useRef as useRef4, useState as useState4 } from "react";
1003
+ import { useCallback as useCallback4, useEffect as useEffect3, useRef as useRef5, useState as useState5 } from "react";
749
1004
  var _insertionCounter = 0;
750
1005
  function mapApiMessage(msg) {
751
1006
  const created = msg.info.timestamp ? new Date(msg.info.timestamp).getTime() : Date.now();
@@ -795,13 +1050,13 @@ function useSessionStream({
795
1050
  sessionId,
796
1051
  enabled = true
797
1052
  }) {
798
- const [messages, setMessages] = useState4([]);
799
- const [partMap, setPartMap] = useState4({});
800
- const [isStreaming, setIsStreaming] = useState4(false);
801
- const [error, setError] = useState4(null);
802
- const [connected, setConnected] = useState4(false);
803
- const abortRef = useRef4(null);
804
- const streamingMsgIdRef = useRef4(null);
1053
+ const [messages, setMessages] = useState5([]);
1054
+ const [partMap, setPartMap] = useState5({});
1055
+ const [isStreaming, setIsStreaming] = useState5(false);
1056
+ const [error, setError] = useState5(null);
1057
+ const [connected, setConnected] = useState5(false);
1058
+ const abortRef = useRef5(null);
1059
+ const streamingMsgIdRef = useRef5(null);
805
1060
  const refetch = useCallback4(async () => {
806
1061
  if (!token || !sessionId || !apiUrl) return;
807
1062
  try {
@@ -988,7 +1243,7 @@ function useSessionStream({
988
1243
  setError(msg);
989
1244
  }
990
1245
  }, [apiUrl, token, sessionId]);
991
- useEffect2(() => {
1246
+ useEffect3(() => {
992
1247
  if (!enabled || !token || !sessionId) return;
993
1248
  refetch();
994
1249
  connectSSE();
@@ -1001,12 +1256,12 @@ function useSessionStream({
1001
1256
  }
1002
1257
 
1003
1258
  // src/hooks/use-dropdown-menu.ts
1004
- import { useEffect as useEffect3, useRef as useRef5, useState as useState5 } from "react";
1259
+ import { useEffect as useEffect4, useRef as useRef6, useState as useState6 } from "react";
1005
1260
  function useDropdownMenu(options) {
1006
1261
  const closeOnEsc = options?.closeOnEsc ?? true;
1007
- const [open, setOpen] = useState5(false);
1008
- const ref = useRef5(null);
1009
- useEffect3(() => {
1262
+ const [open, setOpen] = useState6(false);
1263
+ const ref = useRef6(null);
1264
+ useEffect4(() => {
1010
1265
  function handleClick(e) {
1011
1266
  if (ref.current && !ref.current.contains(e.target)) {
1012
1267
  setOpen(false);
@@ -1017,7 +1272,7 @@ function useDropdownMenu(options) {
1017
1272
  }
1018
1273
  return () => document.removeEventListener("mousedown", handleClick);
1019
1274
  }, [open]);
1020
- useEffect3(() => {
1275
+ useEffect4(() => {
1021
1276
  if (!open || !closeOnEsc) return;
1022
1277
  function handleKey(e) {
1023
1278
  if (e.key === "Escape") setOpen(false);
@@ -1035,7 +1290,7 @@ function useDropdownMenu(options) {
1035
1290
  }
1036
1291
 
1037
1292
  // src/hooks/use-sidecar-auth.ts
1038
- import { useState as useState6, useCallback as useCallback5, useEffect as useEffect4, useRef as useRef6 } from "react";
1293
+ import { useState as useState7, useCallback as useCallback5, useEffect as useEffect5, useRef as useRef7 } from "react";
1039
1294
  function storageKey(resourceId, apiUrl) {
1040
1295
  return `sidecar_session_${resourceId}__${apiUrl}`;
1041
1296
  }
@@ -1067,11 +1322,11 @@ function clearSession(resourceId, apiUrl) {
1067
1322
  }
1068
1323
  function useSidecarAuth({ resourceId, apiUrl, signMessage }) {
1069
1324
  const cached = loadSession(resourceId, apiUrl);
1070
- const [token, setToken] = useState6(cached?.token ?? null);
1071
- const [expiresAt, setExpiresAt] = useState6(cached?.expiresAt ?? 0);
1072
- const [isAuthenticating, setIsAuthenticating] = useState6(false);
1073
- const [error, setError] = useState6(null);
1074
- const refreshTimerRef = useRef6(void 0);
1325
+ const [token, setToken] = useState7(cached?.token ?? null);
1326
+ const [expiresAt, setExpiresAt] = useState7(cached?.expiresAt ?? 0);
1327
+ const [isAuthenticating, setIsAuthenticating] = useState7(false);
1328
+ const [error, setError] = useState7(null);
1329
+ const refreshTimerRef = useRef7(void 0);
1075
1330
  const clearCachedToken = useCallback5(() => {
1076
1331
  setToken(null);
1077
1332
  setExpiresAt(0);
@@ -1112,7 +1367,7 @@ function useSidecarAuth({ resourceId, apiUrl, signMessage }) {
1112
1367
  setIsAuthenticating(false);
1113
1368
  }
1114
1369
  }, [resourceId, apiUrl, signMessage, clearCachedToken]);
1115
- useEffect4(() => {
1370
+ useEffect5(() => {
1116
1371
  if (refreshTimerRef.current) {
1117
1372
  clearTimeout(refreshTimerRef.current);
1118
1373
  }
@@ -1147,6 +1402,8 @@ export {
1147
1402
  useToolCallStream,
1148
1403
  useSSEStream,
1149
1404
  useSdkSession,
1405
+ useRealtimeSession,
1406
+ RealtimeSessionRegistry,
1150
1407
  useSessionStream,
1151
1408
  useDropdownMenu,
1152
1409
  useSidecarAuth