@opengeni/react 7.6.1 → 7.7.0-canary.37111190284001

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 (145) hide show
  1. package/README.md +47 -2
  2. package/dist/{browser-viewer-5X47I6T2.js → browser-viewer-63TXMINB.js} +6 -5
  3. package/dist/{chunk-5EXGU7UF.js → chunk-55DDDVKU.js} +3 -3
  4. package/dist/{chunk-UINDK6C3.js → chunk-7CYYXWHU.js} +5 -8
  5. package/dist/chunk-7CYYXWHU.js.map +1 -0
  6. package/dist/{chunk-LZ3KHA55.js → chunk-A2L5N3EI.js} +332 -339
  7. package/dist/chunk-A2L5N3EI.js.map +1 -0
  8. package/dist/{chunk-KGENSZKS.js → chunk-AAG4R3QN.js} +4 -3
  9. package/dist/chunk-AAG4R3QN.js.map +1 -0
  10. package/dist/{chunk-Z3DISEQN.js → chunk-CWWKTNKK.js} +35 -18
  11. package/dist/chunk-CWWKTNKK.js.map +1 -0
  12. package/dist/{chunk-WZ55DVGK.js → chunk-ELCE5SXV.js} +8 -4
  13. package/dist/chunk-ELCE5SXV.js.map +1 -0
  14. package/dist/{chunk-YSMMDOOE.js → chunk-GISEVGS6.js} +10 -2
  15. package/dist/chunk-GISEVGS6.js.map +1 -0
  16. package/dist/{chunk-BI57CQUV.js → chunk-I7IWRQLN.js} +2 -2
  17. package/dist/{chunk-XA6R7DJQ.js → chunk-IQUCRAT7.js} +3 -3
  18. package/dist/{chunk-CHPKSLPN.js → chunk-NBZ64YY7.js} +4 -2
  19. package/dist/chunk-NBZ64YY7.js.map +1 -0
  20. package/dist/{chunk-DV2DBNPQ.js → chunk-Q5QBEZIQ.js} +48 -29
  21. package/dist/chunk-Q5QBEZIQ.js.map +1 -0
  22. package/dist/{chunk-FGBCYQOT.js → chunk-RDKBXMWX.js} +120 -74
  23. package/dist/chunk-RDKBXMWX.js.map +1 -0
  24. package/dist/{chunk-45GE35O7.js → chunk-TKB4SB44.js} +10 -2
  25. package/dist/chunk-TKB4SB44.js.map +1 -0
  26. package/dist/{chunk-YCGBREUV.js → chunk-TOAH2BKA.js} +6 -2
  27. package/dist/{chunk-YCGBREUV.js.map → chunk-TOAH2BKA.js.map} +1 -1
  28. package/dist/chunk-UGLEYEMP.js +33 -0
  29. package/dist/chunk-UGLEYEMP.js.map +1 -0
  30. package/dist/{chunk-UJRYEWZI.js → chunk-UTRTG6LH.js} +48 -8
  31. package/dist/chunk-UTRTG6LH.js.map +1 -0
  32. package/dist/{chunk-YRYF2GLG.js → chunk-WYVLAAJA.js} +39 -31
  33. package/dist/chunk-WYVLAAJA.js.map +1 -0
  34. package/dist/{chunk-VGIKFIO2.js → chunk-XOAMRDDK.js} +6 -3
  35. package/dist/chunk-XOAMRDDK.js.map +1 -0
  36. package/dist/{chunk-6NEZPF53.js → chunk-YN7I3STW.js} +153 -32
  37. package/dist/chunk-YN7I3STW.js.map +1 -0
  38. package/dist/{chunk-KZ73RL76.js → chunk-YQEAA6LT.js} +7 -3
  39. package/dist/chunk-YQEAA6LT.js.map +1 -0
  40. package/dist/client.d.ts +4 -1
  41. package/dist/commands/types.d.ts +2 -0
  42. package/dist/components/approval-surface.d.ts +15 -0
  43. package/dist/components/session-conversation.d.ts +3 -0
  44. package/dist/composer.js +8 -7
  45. package/dist/{computer-viewer-7GF35SNY.js → computer-viewer-X2MBRZY4.js} +5 -4
  46. package/dist/connect.js +3 -3
  47. package/dist/hooks/use-browser-session.d.ts +4 -0
  48. package/dist/hooks/use-composer.d.ts +2 -0
  49. package/dist/hooks/use-computer-session.d.ts +2 -0
  50. package/dist/hooks/use-file-attachments.d.ts +2 -0
  51. package/dist/hooks/use-session-events.d.ts +1 -1
  52. package/dist/hooks/use-workspace-sessions.d.ts +15 -5
  53. package/dist/index.d.ts +2 -2
  54. package/dist/index.js +28 -21
  55. package/dist/index.js.map +1 -1
  56. package/dist/interaction.d.ts +1 -1
  57. package/dist/interaction.js +6 -5
  58. package/dist/interaction.js.map +1 -1
  59. package/dist/{latest-question-3BJGKQQ6.js → latest-question-CNEZ5KAN.js} +3 -3
  60. package/dist/lib/error-message.d.ts +7 -0
  61. package/dist/lib/format.d.ts +27 -3
  62. package/dist/lib/interaction-errors.d.ts +3 -0
  63. package/dist/machines.js +5 -4
  64. package/dist/{model-policy-picker-menu-PUTA5JOB.js → model-policy-picker-menu-GN2LTB7Z.js} +4 -4
  65. package/dist/model-policy.js +1 -1
  66. package/dist/provider.d.ts +5 -1
  67. package/dist/{queue-surface-implementation-2CAQAIHM.js → queue-surface-implementation-HENWYFWA.js} +3 -2
  68. package/dist/{queue-surface-implementation-2CAQAIHM.js.map → queue-surface-implementation-HENWYFWA.js.map} +1 -1
  69. package/dist/realtime.js +2 -2
  70. package/dist/{sandbox-files-AEJTWGT4.js → sandbox-files-BBC47SLD.js} +4 -3
  71. package/dist/session-ui.d.ts +1 -1
  72. package/dist/session-ui.js +13 -12
  73. package/dist/session-ui.js.map +1 -1
  74. package/dist/session.js +7 -6
  75. package/dist/usage.js +2 -1
  76. package/dist/usage.js.map +1 -1
  77. package/package.json +3 -3
  78. package/src/client.ts +5 -1
  79. package/src/commands/registry.ts +18 -15
  80. package/src/commands/types.ts +2 -0
  81. package/src/components/approval-surface.tsx +166 -42
  82. package/src/components/browser-viewer.tsx +38 -9
  83. package/src/components/composer.tsx +9 -2
  84. package/src/components/computer-viewer.tsx +160 -30
  85. package/src/components/generated-video-player.tsx +4 -2
  86. package/src/components/human-input-form.tsx +18 -5
  87. package/src/components/message-timeline.tsx +120 -168
  88. package/src/components/model-policy-picker.tsx +2 -15
  89. package/src/components/open-geni-chat.tsx +11 -4
  90. package/src/components/queue-surface-state.tsx +3 -1
  91. package/src/components/session-chrome.tsx +5 -2
  92. package/src/components/session-commands-panel.tsx +3 -1
  93. package/src/components/session-conversation.tsx +10 -3
  94. package/src/components/session-list.tsx +7 -5
  95. package/src/components/session-mcp-capability-card.tsx +11 -1
  96. package/src/hooks/internal.ts +3 -2
  97. package/src/hooks/use-browser-session.ts +115 -79
  98. package/src/hooks/use-composer.ts +70 -31
  99. package/src/hooks/use-computer-session.ts +57 -6
  100. package/src/hooks/use-file-attachments.ts +16 -3
  101. package/src/hooks/use-goal.ts +2 -1
  102. package/src/hooks/use-session-capabilities.ts +3 -2
  103. package/src/hooks/use-session-events.ts +15 -8
  104. package/src/hooks/use-slash-commands.ts +6 -11
  105. package/src/hooks/use-turn-queue.ts +2 -1
  106. package/src/hooks/use-workspace-sessions.ts +40 -7
  107. package/src/index.ts +7 -2
  108. package/src/interaction.ts +1 -0
  109. package/src/lib/error-message.ts +37 -0
  110. package/src/lib/format.ts +73 -9
  111. package/src/lib/interaction-errors.ts +15 -0
  112. package/src/model-policy.ts +6 -1
  113. package/src/provider.tsx +12 -4
  114. package/src/session-ui.ts +1 -1
  115. package/src/timeline/projection.ts +12 -1
  116. package/styles/compiled.css +14 -30
  117. package/dist/chunk-45GE35O7.js.map +0 -1
  118. package/dist/chunk-6NEZPF53.js.map +0 -1
  119. package/dist/chunk-CHPKSLPN.js.map +0 -1
  120. package/dist/chunk-DV2DBNPQ.js.map +0 -1
  121. package/dist/chunk-FGBCYQOT.js.map +0 -1
  122. package/dist/chunk-KGENSZKS.js.map +0 -1
  123. package/dist/chunk-KZ73RL76.js.map +0 -1
  124. package/dist/chunk-LZ3KHA55.js.map +0 -1
  125. package/dist/chunk-UINDK6C3.js.map +0 -1
  126. package/dist/chunk-UJRYEWZI.js.map +0 -1
  127. package/dist/chunk-VGIKFIO2.js.map +0 -1
  128. package/dist/chunk-WZ55DVGK.js.map +0 -1
  129. package/dist/chunk-YRYF2GLG.js.map +0 -1
  130. package/dist/chunk-YSMMDOOE.js.map +0 -1
  131. package/dist/chunk-Z3DISEQN.js.map +0 -1
  132. package/dist/components/timeline-pill-geometry.d.ts +0 -8
  133. package/dist/components/timeline-pill-placement.d.ts +0 -24
  134. package/dist/timeline-pill-geometry-Z23V243M.js +0 -110
  135. package/dist/timeline-pill-geometry-Z23V243M.js.map +0 -1
  136. package/src/components/timeline-pill-geometry.ts +0 -169
  137. package/src/components/timeline-pill-placement.ts +0 -99
  138. /package/dist/{browser-viewer-5X47I6T2.js.map → browser-viewer-63TXMINB.js.map} +0 -0
  139. /package/dist/{chunk-5EXGU7UF.js.map → chunk-55DDDVKU.js.map} +0 -0
  140. /package/dist/{chunk-BI57CQUV.js.map → chunk-I7IWRQLN.js.map} +0 -0
  141. /package/dist/{chunk-XA6R7DJQ.js.map → chunk-IQUCRAT7.js.map} +0 -0
  142. /package/dist/{computer-viewer-7GF35SNY.js.map → computer-viewer-X2MBRZY4.js.map} +0 -0
  143. /package/dist/{latest-question-3BJGKQQ6.js.map → latest-question-CNEZ5KAN.js.map} +0 -0
  144. /package/dist/{model-policy-picker-menu-PUTA5JOB.js.map → model-policy-picker-menu-GN2LTB7Z.js.map} +0 -0
  145. /package/dist/{sandbox-files-AEJTWGT4.js.map → sandbox-files-BBC47SLD.js.map} +0 -0
@@ -1,10 +1,11 @@
1
1
  import {
2
2
  InteractionInterventionBanner,
3
+ isInteractionControlUnavailable,
3
4
  isNonRetryableInteractionError,
4
5
  isSourcePlacementChangedError,
5
6
  useInteractionInterventions,
6
7
  useInteractionInvalidation
7
- } from "./chunk-YSMMDOOE.js";
8
+ } from "./chunk-GISEVGS6.js";
8
9
  import {
9
10
  copyTextToClipboard
10
11
  } from "./chunk-JVYQRRC4.js";
@@ -13,7 +14,7 @@ import {
13
14
  } from "./chunk-RHREZ7BO.js";
14
15
  import {
15
16
  formatBytes
16
- } from "./chunk-UJRYEWZI.js";
17
+ } from "./chunk-UTRTG6LH.js";
17
18
  import {
18
19
  STREAM_CLOSE_REASON_NORMAL,
19
20
  STREAM_KIND_BROWSER,
@@ -25,7 +26,7 @@ import {
25
26
  } from "./chunk-5J4FOW6Q.js";
26
27
  import {
27
28
  usePageLiveActivity
28
- } from "./chunk-KZ73RL76.js";
29
+ } from "./chunk-YQEAA6LT.js";
29
30
  import {
30
31
  useEmbeddedBrowserInteraction
31
32
  } from "./chunk-NEXLLTP4.js";
@@ -35,7 +36,6 @@ import {
35
36
 
36
37
  // src/components/browser-viewer.tsx
37
38
  import { interactionControlFailureFromError } from "@opengeni/sdk/interaction";
38
- import { OpenGeniApiError as OpenGeniApiError2 } from "@opengeni/sdk";
39
39
  import {
40
40
  BugIcon,
41
41
  ArchiveIcon,
@@ -875,6 +875,8 @@ function useBrowserSession(options) {
875
875
  const [state, setState] = useState5(() => emptyState4(browserSessionId, enabled));
876
876
  const visible = state.browserSessionId === browserSessionId ? state : emptyState4(browserSessionId, enabled);
877
877
  const refreshBlocked = isNonRetryableInteractionError(visible.error);
878
+ const inputFailureRef = useRef5(visible.inputFailure);
879
+ inputFailureRef.current = visible.inputFailure;
878
880
  const selectedTargetIdRef = useRef5(visible.selectedTargetId);
879
881
  selectedTargetIdRef.current = visible.selectedTargetId;
880
882
  const selectedTargetRef = useRef5(
@@ -905,72 +907,81 @@ function useBrowserSession(options) {
905
907
  requestRef.current.controller?.abort();
906
908
  requestRef.current = { id, controller: null };
907
909
  }, []);
908
- const refresh = useCallback5(async () => {
909
- if (!enabled || !browserSessionId) return;
910
- const id = requestRef.current.id + 1;
911
- requestRef.current.controller?.abort();
912
- const controller = new AbortController();
913
- requestRef.current = { id, controller };
914
- try {
915
- const [session, targetResponse] = await Promise.all([
916
- client.getBrowserSession(workspaceId, browserSessionId, {
917
- signal: controller.signal
918
- }),
919
- client.listBrowserTargets(workspaceId, browserSessionId, {
920
- signal: controller.signal
921
- })
922
- ]);
923
- if (!mountedRef.current || requestRef.current.id !== id) return;
924
- const selected = chooseTarget(targetResponse.targets, selectedTargetIdRef.current);
925
- selectedTargetIdRef.current = selected?.id ?? null;
926
- const previousObservation = observationRef.current.browserSessionId === browserSessionId ? observationRef.current.observation : null;
927
- const retainedObservation = selected && previousObservation && sameObservationTarget(previousObservation, selected) ? previousObservation : null;
928
- observationRef.current = { browserSessionId, observation: retainedObservation };
929
- setState(
930
- (current) => current.browserSessionId === browserSessionId ? {
931
- ...current,
932
- session,
933
- targets: targetResponse.targets,
934
- selectedTargetId: selected?.id ?? null,
935
- observation: retainedObservation,
936
- loading: false,
937
- error: null
938
- } : current
939
- );
940
- if (!selected || !semanticObservationEnabledRef.current) return;
910
+ const refreshInventory = useCallback5(
911
+ async (checkInput = false) => {
912
+ if (!enabled || !browserSessionId) return;
913
+ const checkedInputFailure = inputFailureRef.current;
914
+ const id = requestRef.current.id + 1;
915
+ requestRef.current.controller?.abort();
916
+ const controller = new AbortController();
917
+ requestRef.current = { id, controller };
941
918
  try {
942
- const observation = await client.observeBrowserTarget(
943
- workspaceId,
944
- browserSessionId,
945
- selected.id,
946
- { signal: controller.signal }
947
- );
919
+ const [session, targetResponse] = await Promise.all([
920
+ client.getBrowserSession(workspaceId, browserSessionId, {
921
+ signal: controller.signal
922
+ }),
923
+ client.listBrowserTargets(workspaceId, browserSessionId, {
924
+ signal: controller.signal
925
+ })
926
+ ]);
948
927
  if (!mountedRef.current || requestRef.current.id !== id) return;
949
- observationRef.current = { browserSessionId, observation };
950
- lastObservationAtRef.current = Date.now();
928
+ const selected = chooseTarget(targetResponse.targets, selectedTargetIdRef.current);
929
+ selectedTargetIdRef.current = selected?.id ?? null;
930
+ const previousObservation = observationRef.current.browserSessionId === browserSessionId ? observationRef.current.observation : null;
931
+ const retainedObservation = selected && previousObservation && sameObservationTarget(previousObservation, selected) ? previousObservation : null;
932
+ observationRef.current = { browserSessionId, observation: retainedObservation };
951
933
  setState(
952
- (current) => current.browserSessionId === browserSessionId && current.selectedTargetId === observation.target.id ? { ...current, observation } : current
934
+ (current) => current.browserSessionId === browserSessionId ? {
935
+ ...current,
936
+ session,
937
+ targets: targetResponse.targets,
938
+ selectedTargetId: selected?.id ?? null,
939
+ observation: retainedObservation,
940
+ loading: false,
941
+ error: null,
942
+ // Media and background polling cannot confirm an input outcome.
943
+ // Only an explicit fresh check clears the notice it began with.
944
+ inputFailure: checkInput && session.id === browserSessionId && targetResponse.browserSessionId === browserSessionId && current.inputFailure === checkedInputFailure ? null : current.inputFailure
945
+ } : current
953
946
  );
947
+ if (!selected || !semanticObservationEnabledRef.current) return;
948
+ try {
949
+ const observation = await client.observeBrowserTarget(
950
+ workspaceId,
951
+ browserSessionId,
952
+ selected.id,
953
+ { signal: controller.signal }
954
+ );
955
+ if (!mountedRef.current || requestRef.current.id !== id) return;
956
+ observationRef.current = { browserSessionId, observation };
957
+ lastObservationAtRef.current = Date.now();
958
+ setState(
959
+ (current) => current.browserSessionId === browserSessionId && current.selectedTargetId === observation.target.id ? { ...current, observation } : current
960
+ );
961
+ } catch (cause) {
962
+ if (controller.signal.aborted || !mountedRef.current || requestRef.current.id !== id)
963
+ return;
964
+ void cause;
965
+ }
954
966
  } catch (cause) {
955
967
  if (controller.signal.aborted || !mountedRef.current || requestRef.current.id !== id)
956
968
  return;
957
- void cause;
958
- }
959
- } catch (cause) {
960
- if (controller.signal.aborted || !mountedRef.current || requestRef.current.id !== id) return;
961
- setState(
962
- (current) => current.browserSessionId === browserSessionId ? {
963
- ...current,
964
- loading: false,
965
- error: cause instanceof Error ? cause : new Error(String(cause))
966
- } : current
967
- );
968
- } finally {
969
- if (requestRef.current.id === id) {
970
- requestRef.current = { id, controller: null };
969
+ setState(
970
+ (current) => current.browserSessionId === browserSessionId ? {
971
+ ...current,
972
+ loading: false,
973
+ error: cause instanceof Error ? cause : new Error(String(cause))
974
+ } : current
975
+ );
976
+ } finally {
977
+ if (requestRef.current.id === id) {
978
+ requestRef.current = { id, controller: null };
979
+ }
971
980
  }
972
- }
973
- }, [browserSessionId, client, enabled, workspaceId]);
981
+ },
982
+ [browserSessionId, client, enabled, workspaceId]
983
+ );
984
+ const refresh = useCallback5(async () => await refreshInventory(true), [refreshInventory]);
974
985
  const refreshSemantic = useCallback5(async () => {
975
986
  if (!enabled || !browserSessionId) return;
976
987
  const target = selectedTargetRef.current;
@@ -1008,12 +1019,12 @@ function useBrowserSession(options) {
1008
1019
  setState(
1009
1020
  (current) => current.browserSessionId === browserSessionId ? { ...current, loading: true } : emptyState4(browserSessionId, true)
1010
1021
  );
1011
- void refresh();
1022
+ void refreshInventory();
1012
1023
  return () => {
1013
1024
  mountedRef.current = false;
1014
1025
  invalidateRefresh();
1015
1026
  };
1016
- }, [browserSessionId, enabled, invalidateRefresh, refresh]);
1027
+ }, [browserSessionId, enabled, invalidateRefresh, refreshInventory]);
1017
1028
  useEffect5(() => {
1018
1029
  const previous = previousSemanticObservationRef.current;
1019
1030
  previousSemanticObservationRef.current = {
@@ -1035,16 +1046,16 @@ function useBrowserSession(options) {
1035
1046
  useEffect5(() => {
1036
1047
  if (!enabled || !pageLive || visible.mutating || refreshBlocked) return;
1037
1048
  const timer = setInterval(() => {
1038
- if (!requestRef.current.controller) void refresh();
1049
+ if (!requestRef.current.controller) void refreshInventory();
1039
1050
  }, pollIntervalMs);
1040
1051
  return () => clearInterval(timer);
1041
- }, [enabled, pageLive, pollIntervalMs, refresh, refreshBlocked, visible.mutating]);
1052
+ }, [enabled, pageLive, pollIntervalMs, refreshInventory, refreshBlocked, visible.mutating]);
1042
1053
  useEffect5(() => {
1043
1054
  if (!enabled || !browserSessionId || !pageLive || refreshBlocked) return;
1044
1055
  let disposed = false;
1045
1056
  const heartbeat = () => {
1046
1057
  void client.heartbeatBrowserSession(workspaceId, browserSessionId).catch(() => {
1047
- if (!disposed) void refresh();
1058
+ if (!disposed) void refreshInventory();
1048
1059
  });
1049
1060
  };
1050
1061
  const timer = setInterval(heartbeat, 3e4);
@@ -1052,7 +1063,7 @@ function useBrowserSession(options) {
1052
1063
  disposed = true;
1053
1064
  clearInterval(timer);
1054
1065
  };
1055
- }, [browserSessionId, client, enabled, pageLive, refresh, refreshBlocked, workspaceId]);
1066
+ }, [browserSessionId, client, enabled, pageLive, refreshInventory, refreshBlocked, workspaceId]);
1056
1067
  const runMutation = useCallback5(
1057
1068
  async (scopeBrowserSessionId, operation) => {
1058
1069
  invalidateRefresh();
@@ -1222,6 +1233,16 @@ function useBrowserSession(options) {
1222
1233
  observationMode,
1223
1234
  action
1224
1235
  });
1236
+ if (receipt.state !== "completed") {
1237
+ const inputFailure = {
1238
+ operationId: receipt.operationId,
1239
+ state: receipt.state,
1240
+ error: receipt.error
1241
+ };
1242
+ setState(
1243
+ (current) => current.browserSessionId === browserSessionId ? { ...current, inputFailure } : current
1244
+ );
1245
+ }
1225
1246
  if (receipt.observation) {
1226
1247
  observationRef.current = {
1227
1248
  browserSessionId,
@@ -1310,6 +1331,7 @@ function useBrowserSession(options) {
1310
1331
  loading: visible.loading,
1311
1332
  mutating: visible.mutating,
1312
1333
  error: visible.error,
1334
+ inputFailure: visible.inputFailure,
1313
1335
  refresh,
1314
1336
  observeForInput,
1315
1337
  actFromObservation,
@@ -1331,7 +1353,8 @@ function emptyState4(browserSessionId, loading) {
1331
1353
  observation: null,
1332
1354
  loading,
1333
1355
  mutating: false,
1334
- error: null
1356
+ error: null,
1357
+ inputFailure: null
1335
1358
  };
1336
1359
  }
1337
1360
  function chooseTarget(targets, preferredId) {
@@ -2265,7 +2288,7 @@ function BrowserViewer({
2265
2288
  setHasLiveFrame(frameIsLive);
2266
2289
  }, [frameIsLive]);
2267
2290
  const supportsLiveFrames = (browser.session ?? selectedRegistrySession)?.capabilities.liveFrames === true;
2268
- const controlUnavailable = isBrowserControlUnavailable(browser.error);
2291
+ const controlUnavailable = isInteractionControlUnavailable(browser.error);
2269
2292
  const connectionError = controlUnavailable ? browser.error : frames.error ?? browser.error;
2270
2293
  const selectedPlacement = (browser.session ?? selectedRegistrySession)?.placement;
2271
2294
  const selectedChromeGenerationLoss = selectedPlacement?.kind === "attached_device" && isAttachedChromeGenerationLossError(connectionError);
@@ -2643,6 +2666,30 @@ function BrowserViewer({
2643
2666
  }
2644
2667
  }
2645
2668
  ),
2669
+ browser.inputFailure ? /* @__PURE__ */ jsxs2(
2670
+ "div",
2671
+ {
2672
+ role: "alert",
2673
+ "aria-label": "Browser input status",
2674
+ className: "flex shrink-0 items-center gap-2 border-t border-og-border bg-og-surface-1 px-3 py-2 text-og-xs",
2675
+ children: [
2676
+ /* @__PURE__ */ jsx2(CircleAlertIcon, { className: "size-4 shrink-0 text-og-status-failed" }),
2677
+ /* @__PURE__ */ jsxs2("div", { className: "min-w-0 flex-1", children: [
2678
+ /* @__PURE__ */ jsx2("span", { className: "font-medium", children: browser.inputFailure.state === "failed" ? "Browser input failed" : "Input result unknown" }),
2679
+ /* @__PURE__ */ jsx2("p", { className: "text-og-fg-subtle", children: browser.inputFailure.error?.message ?? "Inspect the page before continuing." })
2680
+ ] }),
2681
+ /* @__PURE__ */ jsx2(
2682
+ "button",
2683
+ {
2684
+ type: "button",
2685
+ onClick: () => void browser.refresh(),
2686
+ className: "shrink-0 rounded border border-og-border px-2 py-1 transition hover:bg-og-surface-2",
2687
+ children: "Check browser"
2688
+ }
2689
+ )
2690
+ ]
2691
+ }
2692
+ ) : null,
2646
2693
  /* @__PURE__ */ jsxs2("div", { className: "relative flex min-h-0 min-w-0 flex-1 overflow-hidden", children: [
2647
2694
  /* @__PURE__ */ jsx2(
2648
2695
  BrowserViewport,
@@ -2728,6 +2775,7 @@ function BrowserViewer({
2728
2775
  profile: selectedProfile,
2729
2776
  target: browser.selectedTarget,
2730
2777
  observation: browser.observation,
2778
+ inputFailure: browser.inputFailure,
2731
2779
  connectionState: displayConnectionState,
2732
2780
  refreshing: registry.refreshing,
2733
2781
  diagnosticsOpen: diagnosticsView !== null,
@@ -3921,6 +3969,7 @@ function BrowserStatusBar(props) {
3921
3969
  }
3922
3970
  ),
3923
3971
  /* @__PURE__ */ jsx2("span", { children: props.connectionState === "live" ? "Live" : props.connectionState === "semantic" ? "Semantic" : browserConnectionLabel(props.connectionState) }),
3972
+ props.inputFailure ? /* @__PURE__ */ jsx2("span", { className: "text-og-status-failed", children: props.inputFailure.state === "failed" ? "Input failed" : "Input result unknown" }) : null,
3924
3973
  /* @__PURE__ */ jsx2("span", { children: props.profile?.name ?? "Temporary browser" }),
3925
3974
  /* @__PURE__ */ jsx2("span", { className: "min-w-0 flex-1 truncate", children: props.target?.title }),
3926
3975
  props.refreshing ? /* @__PURE__ */ jsx2(LoaderCircleIcon, { className: "size-3 animate-spin" }) : null,
@@ -4397,9 +4446,6 @@ function attachedChromeGenerationLoss(sessions) {
4397
4446
  );
4398
4447
  return lost?.placement.kind === "attached_device" ? { deviceId: lost.placement.deviceId } : null;
4399
4448
  }
4400
- function isBrowserControlUnavailable(error) {
4401
- return error instanceof OpenGeniApiError2 && (error.status >= 500 || error.status === 0);
4402
- }
4403
4449
  function isAttachedChromeGenerationLossError(error) {
4404
4450
  if (!error) return false;
4405
4451
  return /placement instance changed|controller authority changed/i.test(error.message);
@@ -4471,4 +4517,4 @@ export {
4471
4517
  useBrowserFrameStream,
4472
4518
  BrowserViewer
4473
4519
  };
4474
- //# sourceMappingURL=chunk-FGBCYQOT.js.map
4520
+ //# sourceMappingURL=chunk-RDKBXMWX.js.map