@midscene/visualizer 1.8.0 → 1.8.1

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.
@@ -3,6 +3,7 @@ import { SettingOutlined } from "@ant-design/icons";
3
3
  import { Alert, Button, Input, Modal, Tooltip, message } from "antd";
4
4
  import { useEffect, useRef, useState } from "react";
5
5
  import { useEnvConfig } from "../../store/store.mjs";
6
+ import { notifyError } from "../../utils/index.mjs";
6
7
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
7
8
  try {
8
9
  var info = gen[key](arg);
@@ -78,7 +79,9 @@ function EnvConfig({ showTooltipWhenEmpty = true, showModelName = true, tooltipP
78
79
  } else message.warning('Model verification found issues');
79
80
  } catch (error) {
80
81
  const errorMessage = error instanceof Error ? error.message : String(error);
81
- message.error(`Model verification failed: ${errorMessage}`);
82
+ notifyError(error, {
83
+ title: 'Model verification failed'
84
+ });
82
85
  setConnectivityResult({
83
86
  passed: false,
84
87
  checks: [
@@ -7,6 +7,7 @@ import { Button, Dropdown, Progress, Switch, Tooltip, message } from "antd";
7
7
  import global_perspective from "../../icons/global-perspective.mjs";
8
8
  import player_setting from "../../icons/player-setting.mjs";
9
9
  import { useGlobalPreference } from "../../store/store.mjs";
10
+ import { notifyError } from "../../utils/index.mjs";
10
11
  import { shouldRestartPlaybackFromBeginning } from "./playback-controls.mjs";
11
12
  import { triggerReportDownload } from "./report-download.mjs";
12
13
  import { StepsTimeline } from "./scenes/StepScene.mjs";
@@ -180,8 +181,9 @@ function Player(props) {
180
181
  onDownloadReport: props.onDownloadReport
181
182
  });
182
183
  } catch (error) {
183
- const errorMessage = error instanceof Error ? error.message : String(error);
184
- message.error(`Failed to download report: ${errorMessage}`);
184
+ notifyError(error, {
185
+ title: 'Failed to download report'
186
+ });
185
187
  }
186
188
  })(), [
187
189
  null == props ? void 0 : props.onDownloadReport,
@@ -293,8 +295,9 @@ function Player(props) {
293
295
  message.success('Video exported');
294
296
  } catch (e) {
295
297
  console.error('Export failed:', e);
296
- const errorMessage = e instanceof Error ? e.message : 'Export failed';
297
- message.error(errorMessage);
298
+ notifyError(e, {
299
+ title: 'Video export failed'
300
+ });
298
301
  } finally{
299
302
  exportInFlightRef.current = false;
300
303
  setIsExporting(false);
@@ -867,6 +867,31 @@
867
867
  color: rgba(255, 255, 255, .72) !important;
868
868
  }
869
869
 
870
+ [data-theme="dark"] .prompt-input-wrapper.prompt-input-wrapper-minimal .minimal-main-side-console-input .minimal-run-trigger:disabled {
871
+ color: rgba(255, 255, 255, .35);
872
+ background: rgba(255, 255, 255, .08);
873
+ }
874
+
875
+ [data-theme="dark"] .prompt-input-wrapper.prompt-input-wrapper-minimal .minimal-main-side-console-input .minimal-run-trigger-stop {
876
+ color: #f8fafd;
877
+ background: rgba(255, 255, 255, .12);
878
+ }
879
+
880
+ [data-theme="dark"] .prompt-input-wrapper.prompt-input-wrapper-minimal .minimal-main-side-console-input .minimal-run-trigger-stop:hover {
881
+ color: #fff;
882
+ background: rgba(255, 255, 255, .18);
883
+ }
884
+
885
+ [data-theme="dark"] .prompt-input-wrapper.prompt-input-wrapper-minimal .minimal-main-side-console-input .minimal-run-trigger-stop:focus-visible {
886
+ color: #fff;
887
+ background: rgba(255, 255, 255, .18);
888
+ }
889
+
890
+ [data-theme="dark"] .prompt-input-wrapper.prompt-input-wrapper-minimal .minimal-main-side-console-input .minimal-run-trigger-stop:disabled {
891
+ color: rgba(255, 255, 255, .35);
892
+ background: rgba(255, 255, 255, .08);
893
+ }
894
+
870
895
  [data-theme="dark"] .prompt-input .tip-button {
871
896
  background-color: rgba(255, 255, 255, .08);
872
897
  }
@@ -775,6 +775,31 @@
775
775
  color: rgba(255, 255, 255, .72) !important;
776
776
  }
777
777
 
778
+ [data-theme="dark"] .prompt-input-wrapper.prompt-input-wrapper-minimal .minimal-main-side-console-input .minimal-run-trigger:disabled {
779
+ color: rgba(255, 255, 255, .35);
780
+ background: rgba(255, 255, 255, .08);
781
+ }
782
+
783
+ [data-theme="dark"] .prompt-input-wrapper.prompt-input-wrapper-minimal .minimal-main-side-console-input .minimal-run-trigger-stop {
784
+ color: #f8fafd;
785
+ background: rgba(255, 255, 255, .12);
786
+ }
787
+
788
+ [data-theme="dark"] .prompt-input-wrapper.prompt-input-wrapper-minimal .minimal-main-side-console-input .minimal-run-trigger-stop:hover {
789
+ color: #fff;
790
+ background: rgba(255, 255, 255, .18);
791
+ }
792
+
793
+ [data-theme="dark"] .prompt-input-wrapper.prompt-input-wrapper-minimal .minimal-main-side-console-input .minimal-run-trigger-stop:focus-visible {
794
+ color: #fff;
795
+ background: rgba(255, 255, 255, .18);
796
+ }
797
+
798
+ [data-theme="dark"] .prompt-input-wrapper.prompt-input-wrapper-minimal .minimal-main-side-console-input .minimal-run-trigger-stop:disabled {
799
+ color: rgba(255, 255, 255, .35);
800
+ background: rgba(255, 255, 255, .08);
801
+ }
802
+
778
803
  [data-theme="dark"] .prompt-input .tip-button {
779
804
  background-color: rgba(255, 255, 255, .08);
780
805
  }
@@ -1,10 +1,11 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  import { PlaygroundSDK } from "@midscene/playground";
3
- import { Button, Tooltip, message } from "antd";
3
+ import { Button, Tooltip } from "antd";
4
4
  import { useEffect } from "react";
5
5
  import { safeOverrideAIConfig } from "../../hooks/useSafeOverrideAIConfig.mjs";
6
6
  import { useServerValid } from "../../hooks/useServerValid.mjs";
7
7
  import { useEnvConfig } from "../../store/store.mjs";
8
+ import { notifyError } from "../../utils/index.mjs";
8
9
  import { EnvConfig } from "../env-config/index.mjs";
9
10
  import { iconForStatus } from "../misc/index.mjs";
10
11
  const TITLE_TEXT = {
@@ -62,8 +63,9 @@ const ServiceModeControl = ({ serviceMode })=>{
62
63
  type: 'remote-execution'
63
64
  });
64
65
  playgroundSDK.overrideConfig(config).catch((error)=>{
65
- const errorMsg = error instanceof Error ? error.message : String(error);
66
- message.error(`Failed to apply AI configuration: ${errorMsg}`);
66
+ notifyError(error, {
67
+ title: 'Failed to apply AI configuration'
68
+ });
67
69
  });
68
70
  }
69
71
  }, [
@@ -1,10 +1,11 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  import icons, { ArrowDownOutlined, ClearOutlined, LoadingOutlined, UpOutlined } from "@ant-design/icons";
3
- import { Alert, Button, Form, List, Typography, message } from "antd";
3
+ import { Alert, Button, Form, List, Typography } from "antd";
4
4
  import { useCallback, useEffect, useMemo, useState } from "react";
5
5
  import { usePlaygroundExecution } from "../../hooks/usePlaygroundExecution.mjs";
6
6
  import { usePlaygroundState } from "../../hooks/usePlaygroundState.mjs";
7
7
  import { useEnvConfig } from "../../store/store.mjs";
8
+ import { notifyError } from "../../utils/index.mjs";
8
9
  import { ContextPreview } from "../context-preview/index.mjs";
9
10
  import { EnvConfigReminder } from "../env-config-reminder/index.mjs";
10
11
  import { PlaygroundResultView } from "../playground-result/index.mjs";
@@ -121,8 +122,9 @@ function UniversalPlayground({ playgroundSDK, storage, contextProvider, config:
121
122
  useEffect(()=>{
122
123
  if ((null == playgroundSDK ? void 0 : playgroundSDK.overrideConfig) && config) playgroundSDK.overrideConfig(config).catch((error)=>{
123
124
  console.error('Failed to override SDK config:', error);
124
- const errorMsg = error instanceof Error ? error.message : String(error);
125
- message.error(`Failed to apply AI configuration: ${errorMsg}`);
125
+ notifyError(error, {
126
+ title: 'Failed to apply AI configuration'
127
+ });
126
128
  });
127
129
  }, [
128
130
  playgroundSDK,
@@ -133,7 +135,9 @@ function UniversalPlayground({ playgroundSDK, storage, contextProvider, config:
133
135
  const value = form.getFieldsValue();
134
136
  yield executeAction(value);
135
137
  } catch (error) {
136
- message.error((null == error ? void 0 : error.message) || 'Execution failed');
138
+ notifyError(error, {
139
+ title: 'Execution failed'
140
+ });
137
141
  }
138
142
  })(), [
139
143
  form,
@@ -1,5 +1,5 @@
1
1
  import { overrideAIConfig } from "@midscene/shared/env";
2
- import { message } from "antd";
2
+ import { notifyError } from "../utils/index.mjs";
3
3
  function safeOverrideAIConfig(newConfig, extendMode = false, showErrorMessage = true) {
4
4
  try {
5
5
  overrideAIConfig(newConfig, extendMode);
@@ -7,7 +7,9 @@ function safeOverrideAIConfig(newConfig, extendMode = false, showErrorMessage =
7
7
  } catch (error) {
8
8
  const err = error instanceof Error ? error : new Error(String(error));
9
9
  console.error('Failed to override AI config:', err);
10
- if (showErrorMessage) message.error(`Failed to apply AI configuration: ${err.message}`);
10
+ if (showErrorMessage) notifyError(err, {
11
+ title: 'Failed to apply AI configuration'
12
+ });
11
13
  return false;
12
14
  }
13
15
  }
package/dist/es/index.mjs CHANGED
@@ -17,9 +17,9 @@ import { Player } from "./component/player/index.mjs";
17
17
  import { Blackboard } from "./component/blackboard/index.mjs";
18
18
  import screenshot_viewer from "./component/screenshot-viewer/index.mjs";
19
19
  import { actionNameForType, getPlaceholderForType, staticAgentFromContext } from "./utils/playground-utils.mjs";
20
- import { filterBase64Value, timeStr } from "./utils/index.mjs";
20
+ import { filterBase64Value, notifyError, timeStr } from "./utils/index.mjs";
21
21
  import shiny_text from "./component/shiny-text/index.mjs";
22
22
  import universal_playground, { UniversalPlayground } from "./component/universal-playground/index.mjs";
23
23
  import { IndexedDBStorageProvider, LocalStorageProvider, MemoryStorageProvider, NoOpStorageProvider, StorageType, createStorageProvider, detectBestStorageType } from "./component/universal-playground/providers/storage-provider.mjs";
24
24
  import { AgentContextProvider, BaseContextProvider, NoOpContextProvider, StaticContextProvider } from "./component/universal-playground/providers/context-provider.mjs";
25
- export { AgentContextProvider, BaseContextProvider, Blackboard, ContextPreview, EnvConfig, EnvConfigReminder, IndexedDBStorageProvider, LocalStorageProvider, Logo, MemoryStorageProvider, NavActions, NoOpContextProvider, NoOpStorageProvider, Player, PlaygroundResultView, PromptInput, screenshot_viewer as ScreenshotViewer, ServiceModeControl, shiny_text as ShinyText, StaticContextProvider, StorageType, UniversalPlayground, universal_playground as UniversalPlaygroundDefault, actionNameForType, allScriptsFromDump, colorForName, createStorageProvider, detectBestStorageType, extractDumpMetaInfo, filterBase64Value, generateAnimationScripts, getPlaceholderForType, globalThemeConfig, highlightColorForType, iconForStatus, safeOverrideAIConfig, staticAgentFromContext, timeCostStrElement, timeStr, useEnvConfig, useGlobalPreference, useSafeOverrideAIConfig, useServerValid, useTheme };
25
+ export { AgentContextProvider, BaseContextProvider, Blackboard, ContextPreview, EnvConfig, EnvConfigReminder, IndexedDBStorageProvider, LocalStorageProvider, Logo, MemoryStorageProvider, NavActions, NoOpContextProvider, NoOpStorageProvider, Player, PlaygroundResultView, PromptInput, screenshot_viewer as ScreenshotViewer, ServiceModeControl, shiny_text as ShinyText, StaticContextProvider, StorageType, UniversalPlayground, universal_playground as UniversalPlaygroundDefault, actionNameForType, allScriptsFromDump, colorForName, createStorageProvider, detectBestStorageType, extractDumpMetaInfo, filterBase64Value, generateAnimationScripts, getPlaceholderForType, globalThemeConfig, highlightColorForType, iconForStatus, notifyError, safeOverrideAIConfig, staticAgentFromContext, timeCostStrElement, timeStr, useEnvConfig, useGlobalPreference, useSafeOverrideAIConfig, useServerValid, useTheme };
@@ -148,7 +148,7 @@ const parseConfig = (configString)=>{
148
148
  const trimmed = line.trim();
149
149
  if (trimmed.startsWith('#')) return;
150
150
  const cleanLine = trimmed.replace(/^export\s+/i, '').replace(/;$/, '').trim();
151
- const match = cleanLine.match(/^(\w+)=(.*)$/);
151
+ const match = cleanLine.match(/^(\w+)\s*=\s*(.*)$/);
152
152
  if (match) {
153
153
  const [, key, value] = match;
154
154
  let parsedValue = value.trim();
@@ -274,4 +274,4 @@ const useEnvConfig = store_create((set, get)=>{
274
274
  }
275
275
  };
276
276
  });
277
- export { useEnvConfig, useGlobalPreference };
277
+ export { parseConfig, useEnvConfig, useGlobalPreference };
@@ -1,4 +1,5 @@
1
1
  import dayjs from "dayjs";
2
+ import { notifyError } from "./notify.mjs";
2
3
  function timeStr(timestamp) {
3
4
  return timestamp ? dayjs(timestamp).format('YYYY-MM-DD HH:mm:ss') : '-';
4
5
  }
@@ -10,4 +11,4 @@ function filterBase64Value(input) {
10
11
  }
11
12
  const mousePointer = 'data:image/png;base64,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';
12
13
  const mouseLoading = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAhGVYSWZNTQAqAAAACAAFARIAAwAAAAEAAQAAARoABQAAAAEAAABKARsABQAAAAEAAABSASgAAwAAAAEAAgAAh2kABAAAAAEAAABaAAAAAAAAAEgAAAABAAAASAAAAAEAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAYKADAAQAAAABAAAAYAAAAABaCTJNAAAACXBIWXMAAAsTAAALEwEAmpwYAAABWWlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNi4wLjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgoZXuEHAAAZfUlEQVR4Ae1da5Ac1XXue7tnHzMrYSMMEqyMYB/CCOyEhTjxH9YYk0p4GEsBJxTgFNjalYDEruCHMAkjEsd2gsu4AD1DUrYpUoZgy4iEAhNbqiRQDpIxGAGSdnmYt4wgknZmd2em++b7TnfPzvZ0z660u3rNXGmnu2/f53fOPffccx9tWQ3XQKCBwEFAwFiWOgjZNLKIQ8BkLR3nf7j6mcss+0grcxWW5HipSMD5ZumpxxyJlWIdqio3jR4zwpksNOSNUfdbLq/5ZZ2/n9fq+jffOLFlGss+I0mRcYb7O1fl+zuu5z3rYLK9zkwxz7TLZRZUZS2Phc8v6zhLGbXC0WpJCT6uZX1m1pqB+4RAqNiMIHiAiYblHlreeUGLUo/YWln5krfBuN7ftK178ddMdibKPW0twBiInAD8kWULF4KDbkqn7C2tjlpS9IxhhZDZZXuXdh9Hrsoepv2C8qwbUVRruOgV0yl9qdL66Vx/11/nb+hs91uDpVnXA6RzVbRpIYBwhoLIAefn+zr/xDXuf6MBrEQlyEXkdDQI/LesT2lV+ghvbtk2fZVgelNxFDEsO4C+COmcP1IyLK2TL7gUoSrdpG41RevxfF/XYoZTqCvrPJU8w7hTJkDYLFmJXF9Xv6esu1tsdRwy0MZjPRQLqiGC3CZbpbSyV5ilPamQm8KCHKorC6iymwA5GcL0pZu0wn0J5SH2Nu5NvuCVUPb5tm09kO/v+jLLKuWfBiJMqSmF4O9Z3tFpe2p9Jm335vMi2j2/AuO43HM0CWG9Aw5anl49cL9UPmgarNShcKHYHOrr+mSTbT0KccmyxzGmC9FkQ/yQqx6ybe+vWu56cUeIwYGWPS6jSaUlzRayfN/nOxfZrvr3TJPuzefcQhCZ6UaJK60AHHYcuoTFUvFDDD7LSpEiV+V9AQxSy9nQI4i/l27WF3muepB191tyr1MrYq13tbNMiLmFIgTNdmRZ9/kQME8026qbzRSQNyVECbyVGkW/0Kz1n+be7ryCniRE7Tgz9zbMO7es68J0k/3HwyUDCVrT8bXKj3rFlK0Xatt6XDAAFsSkZsyEl/tdeXL+2eu2FpkxWutPIDJnFfxmW4sLwDiWm3aUhrDdPeqZzZC0m6VMWb93TijfzHrfEuSt3F35orcRHZSGrCcmbBXSMmIKQCKkCq7xEH42MSAWxITYxISv6TUBwcfHlc4TGQ2R8433IPT7VnSuSTIzjFxEJilUzBpxzbvo4a5Jv9v8sLp/WyiuwnCH5EqVUrQatMShtzp6taXWQv3sHEVn5RohQi0mRb8GpvLMsFH6krbVOx4LMZpsZSZNAJH5aGq55aeeozy9GXo9wKeKKVpOfH7KKkHmO6MFzwLnr8jMbb+NoouB0SRQ70PI/RUlruxI74Nmc+Gcjq8qS33Nr6OhVlFD5TSuo7XtkgjaOzez6sUnQ6wqski8nRQBWKjL0eFygAVtcgNk/mng5loFo8gxUEf1qGv+x1M6S+5gKchxK1ei7ws6v8SSHeQXZAjrMozigxH60NJTz8Qg7F4w0BkQTyWwComQhJeLutqo6wtQsy9tWb19e6hdTVSNpATL8ULuGLnu1O6SpzdmHN2NAiWDzzEMBioouEa4DWn3mMtVIB9D7i8nfpjehHUe+twpJyjHXoe6XAIlg6KWeCVh5kJ02bmCt8PT7iWzV7+0PUynVjVryTfh1pAjXFd/G6omwafsTmqS5HwLBdEYBd+TzqSvJPjbLlvUdKSAz/KLagmtpu2fXno7nUtfIXVBnQKBKXVkuIiz2VIyKdWtjb1x73WnzfFV1NpaXk0CWBAVzISjP9xcBPWLXJCkbonYSbdolSu6/4CB1lXqtmdybIqLDpMONwJYzUdptRC96gfP5FgXqRPqhkhSz4TITr5kCplWu8v2ikskzAQml6TmVLb80f7BITgGTzRxMvPqOPBHj+q1NqMJjnjfals78FVmHmoYUpAj9KeyDkN9nd/MtOiv5EeAhI9CNRZBPfFin1Hm6szqwQ21RFFsCwgjDC1fMBeJ3E66+9bkGPDJEZD5BH+44IMPKvmWUfgfobiXix2qqKwTGSs3itaNwQ8CsG5J9fNgBZ4Fs90dxFBEUYLdqIoAzGjlIj9hbVI3YfA0v+DW6HRRCJH5AB9NVTjfytLAlTiQKVfuSLmRuqBOLG/bmsGvDJfQv0HJwGMSATREUSmdUu3EUOp5vz9HIvcVP5JoxXNZ9OT6Tj0bw/Mn8wU2QglRFRa+yERD7nkbMqsHPs1QJCACJhVMEjpSf0JxZG78cCa/L39PS0pdOiLm9tixkAhsmLIVzNrnZNa+uCWULJX1r2oBbC7U+wHjTQIjZDsiJINfdF/2RqylTJTxjlbwWb9QHFG5wGj+M6MlsxlMyjoX+T7iMJYLpYBawXfENhJmvIpECjEARoLXpB39aTQjgl+tcvqdrjPqeszh2ln/MvBbDsE5WItmcLQ9UxztvKGzWUwpRq1l/dDciVFcq4dqaizHVosL/Z2/K2EjxsdyCxDRAQDNF9tbQavr0OkmO3Su7IdgLlkxa83gz2ToDX0/OcLR9abrjoFRqtfptTv/FQO0LLBI7A/QOlxihcHT1ytQKEuU8k1ov8j1d3y+2dbrMKwORU85TJCAR6tmrmgehVbwhxWJ1tWtMCy4nlIjP6dzFzA5NpAYZaYWQCAtbFj4YNjLK22uSa8a/GEYl+8lsHQuMJLtuXbRseD+Pgo1po2fKPjSLmDS56vb+BuKLd7XkwMwhq1A5DosvLmS2c0ZP2Ag6JSxQE8A8KmspD1PrTBfWPA+xoUtTLD3qXW5/5BqGu3GbE8PVSgAXC37adOH+oVpu4cya3eKcc2CelXOrM5uVgb1Tc9rfhhM/iub+p/PuFEkaKbgZM+H86N2B1+eHoyQfQLc54MI9j7P70oMU4o6emKlAHsHtRb34ACsJsA1GrBenmnRFdUyuw2ouN+A2C7SNI36R5lS4JIBnLGuJz6hwqKJJtWrfH/3SZgs+QtOGcLLJwxDjjnTmkI6lvVYZs3Oh6T5Bbb9sSD1dxcOWj3jPA10NtBkAydAjUdD6QK0Frz6RKW/5qiVHp5yz8cExAmQV3RVCcAD5mVDxVRkv4Rq/FhhK5i9bsc7rjEP+GKoGj9iSvwxgzYfxk0x1JGJtRXIImX0xylP4KLNh34GEXndljlxQGT/0WRqYMWm4sIBVlvR+Q/0j7t8JSZWNHNtFCyX5kuSH7CXXnxvX+cfQFtazNVJCc5L+dL+lw3g4xESkfzP2/eBV29ubhIJHjcoVZi6ZK95ItdSkXASMqXUQkypzQom2KPih52vjUmJnNHu7cyemcUXo459A0li22YzzNWctHIIVQQRhY6aXvNTRsnIWID0lOm2U2WqRQlQam2xofKY+9tWv/SMgJ+tSjiSTx0+Bup4c1PhVXAsbERlPCvBoKJaSLfaXHHxO3whoaD9tFN9jSIvMcWkBKp5agufn9u2qK5VT8Ek5gfYYVSMqdfvvDYMPDfEBBEvEEdziQi61LNp9tH55R3zgfxHS/AEzNHBFz0dTEVSDO1iCqcv+kBcJ52UX535bxO5j0HZsxgv7UF/6wC/8WIIfA5pQuF0rJVLZ7CgBTM3xjoFK70IVrQRcGkJfQc9p/RfPpqbGgSYgK1c29oLNEc1BU50VhDMjyU9NG1/aNQuztEFS50GGZ9CmjA/VBNA++pnrm3Vy28hUYVxg1BqgjLU52vOegHbtlU7fwXo30z5+uh4vCDSEabU2mxnisY5A/h6FxgZocVqNqAf45unBNFsL5Mcn2B9Qh1ba8FmZa8vxpW1xceuiqkZVxNzrHP5BDrhWKObnwGoSckEou0Wj22bGuD7yNT4DUS0Mb+gqIETRSc+gkqTACcmTb5ATikmAjpskgSCyfr4xBq+4xAwyrecjfMc/4ANRAW0AnOyT6iYpsI+BBNfReW9KVFvaYif8RBWP60MvLRtngeu8fsNwNGU+uD+0zmZNgSc4yU7WxB6bW3Z6SDdxmUCBG4JmNS4akTQE3AjkQI/XFrYAj4IKx4FfZWjFgVXShn9qtzFhBH/xs8YAgFGBdd+C57cZRnriDn+nahtrecliaAgstsyd+5rTAXPjU44Fs4xzxCjY3QbMUsigGK/C9P1PO7uiJdTFWm+Pfh889hj4246EUALqKUmSVbmhNZ2WvcabhIIhMJ8ROdOQnDuM45zhuNbjNre1J5ntoMIdFVhA5tD6j373Q8FAQKpJOEbP3EIBChCc5yP146MY6PhEMafOVOvYk5YjdDgmewMtoun/FNOqkiUHKve32CLXx6werHQhh0F9lqQ99/wTRbVLcD3UbajvLkC6MrY5Ood6/H1DzCC5jgP3E9raKLDK9kb/rpvb6sOx7gkDvbFtFe/bfjEIhDOsSvrXFqSRdusDog5dmqV5llcMGSoDhD6eJxEBoF6xCNIPHzZuCYjAB3/eJEsUXO0RDFGrMxK/a/GDMIjwuaxqyEM9h9LD7FQ4r2/x++uk/NtvAkxMlYHORcMHiOEMGeGV8D+dYyE1Vs0+OA5LqByxRhntQ9/buEp/nbTCdXWuiUCAFTE6LfXLOQk1/uMWDkDe0IMKrbRr+gmY+3Kj7hvYFEWJ2Wis11KViJa1jzPds9gGps29TZaQQyY9Nq6tIcrIazZTd4FgH0RDv/g43gJD9mEd5jmdfOYms9jRkzvQaA3/EURVa2AEmw0nXGakMxZTK39zNei88b0bjgg0PPeVmFgbKs/A5v0iAnniMcTAKopO2f8e67JTr2puaQODecJnGXFCNEWAHJhoh5nPSBGj/nzBS2yOSGaKGPWuRPxM7ZD6MzkfhUmamANXDequ17YHYgT8xhOumJ7oRiSdlPGE+boIl8Zc2bOUceIfzZC1XLgOr4JMMkv7foo0PoktuwSSRFJFagQW9v134mBUwjgKvMO3uyRUQGDjHfcD1BKtzgLQLlPjX/VeIoi4GpzVqbFng3dhwdYjRc/IAk3cYy43nvQg55nXFypA1km19+5Bbs4erCRgHKrSs5To0KnvmskZXXNuWNgbzTjxrOPQK6v88EWR12MqVyK84jCYnCgh81lnk+k1wx8jPsrNI9oYVQopnfiBW+rwKcnNSqcEHV8U8H8EZ/rdWsS6x514VrZERz6CsMmwWeQCPjgdPK6PzT+uaSBRQ463GKktfef9Iy2GQno/0Ct5ZI6tWRff8fxXNmLxxrBK2LWyS127d6Is5RYW+HkSLW5WY876H+DyfjvyjusI6JkEXJh996rwPPHrb42RDEUddRf4cxiR9vd8jJcAxMNWUfP/u7SsUNfY3V/Hw9DEzSawCvY2ivLPIm9NBPZGY9AOAPrVvQBDE6ohTB8CBzP/Cymm20cz+VdKH51vk4IAPmHvmYpbqKHvoawhVf/+GYYd75Hn1BsCQGeC9b7ZJzRV/DuKR6+gWt1K4BaxfPf4Jbv4zG+FEOSOb3q0AX9Jw/7Q/94UXCqVkwfis4XYgPMvTVftO+rRIqcLk6oCcIM9XVcjV17d0M2OTBDU8qXwwRBeRQL94u9m3l3wO8LyAnVLSYIfnRfgo3aL0D246RF6RWjeFGSGLzH+Xne0syawfXhpngiIy1AIAqoaTveZoT314JGk5KAluYBp0jwWOwQv1m8slVE8kMexb8EkdUbmdP5JUiMTjlZoJpZGcSQYfH+6XTr6D30sLKbytKlTABfnPQ6rXe99AqCrJdl6clcTSOdh10gWZyo9WfcN8YDLCTxOviRjRjYogtt8Dw0/W9U9JvVtYcM8bVScxc3b8i+4gpcywRgzPBgPdPsPQh16Sc8EwLecSoVRY5PRWX6WKDwAIvqEhxdPgIgzsAz+A4CwLm7WcwHsUv7WXGv2VGqUDLbcHjT9+lBRuc1dOMIQE9m0Pbdl962jPd3AeWi2pDEhWeK5+sjg3Pzx47+kIcYsSUczWMD1k0kxVU4sEl7d2NUuwDcz30VUZuPQAmMBF+sQfl7FZywIuBV/FQRgAMzEoEnPGHXzL3pVoe9esK6IGXjYwc8TfzS4Vx+DdNF05BDLCryOCpuqe2xbqzMcFt+DcTvJfmiS26OAx/exsvAJA3Zf2fb6p33ImLs5pYqAkC0GGtRr3S/yHAdrKQFaERN8JXMWYCIw5FcHjQjfeVQf8e35F326CKCqNqoE+vGOrKuvsoZe6QDg8HmD7WzZF41uvR1esipvMQ24gToiJ88+rIO3wfAtnpHmX9LUEnDqEIeOTO0cWwlYYawwpJPoy/HoU4/CrEMwaq8VrWA8GU4yJq1ZucD6IVvxd5WEqsYvo9cRQHjwa48VzNsCSKOgmPQIuGPiMdKscM6yZmhPLzWZ9sk5i36WKnvCfhBv5FU4UQCVEZIO9a3h0fcndCKOGHDTifOsUCKh5pmUvaX8e2wHxh0VkJIaElxEQ5nPzkXjkoFT0hEXaROPLCVstz/iyt+Cf1hKjfs/hxm+y9KgCQyBbFrEkC0GnAwevC9JeVejGPKdmDQwU5nnCpVURLJDpqBB6PelflM/l6qazzgLhy4VIQ9LG+BsBw6K2o1GIfHU0pdUKcJON/D2XAOTg7e4dpmKedMRPTEyP3Kik9AHz+oNEVww/4dXw/tCJMP0BRehgi7lof7MTUWipoWMq7qkCoLdijuw3oybw4wQYo+qtnU9OBFrJLwIvgag9O9mM762Kz1A9tqyX2mH7qkBMP35Wtovygs7z4HH274GeR7GxokW0KM8akcTQ525dcooEOvaNk98I/hQCRMrxzyEN3IuIVmdVh2fXEph/DdzFE+i8SxDnCvVUcXvSM/8LMP5wksaVu786eTBZ/pT5oADBx+niO3rONSTOvjcCJLY7BG7qglymSgAtFlQTQNgBR9bXMHN4l4g27NdHnP68F2UaB4UDnKt552LppaUB7+Jej5Ulr5tBXAh3gyS+Sgbn7gaD+O8Nw/AgArRPCPajyu42J8J/L7MMOGH/GpRQSKG7EIshvjoX9Iai2PPpNq8GVADCvLFRszI54o35G+1DkkOmf3OMHEOQ68WAbD2TE0NqJIDCdhwzJGruFXM4ZwANNV6XcGN0oLQhxEmrR4rZVBJL/qR378TGGMAPk3GxyTNCQfiyj6cfB1DUTAi8cwTXdby6qBR8cCofToJ7ZijWXPuq2l/alMZRrhPQnL1XxcUMaONfTffUPnbM5vc4oVOS7mRBPnOibRopmEiFbMob+AVbZXZ1bteDJMd3+vB0QA4SQsw2NTk4+ZaetH0JG7+X0tFCBVqxBEHZkSWIerxzBUtzCXuhG98sP4Gt8v0+t2/qIyPsWeFaw4szhxdEvAXUgA/8ucJmXi08qAa7mSG0SsFAdcWMa1TbK8xqi/5SIDMV6xQJjtQ2oOYuGppitSHadGiJZziXwvhmU8QGaZKLOaJQllqHzK0FXr8OWIj+eHgahvM6klkpgu4eKfpulbo4/Ijbh7UaCfwu/XQOLZvQX96AfkGDD4HKDjomJZ18qllVxmjwVmXOM0MurKSg8kWy5HzSz81mulUViOiaiWy3dieHTnFE6PnBIBWOCQCGzSLUXrO/D5LO0gWHxE7YFEmEwe0uFBeDqtPGkKNOTkNjQU8vH/4W8QjLkLz5u5a58bx7l3mdtnuYOTmwi5j41bqbibBxp7O+xXPch4IdBtRxnmyfpWiBiu8uNCM7zjBrrJlI3V9O1huEFBb+XAlGMjirewL2GgA3GTLUDNtEMiMBA1CX51A810Po7zZQ0J7kStwU/f5zL2JQxvIw3cMQWIKaBFcYUE+Ukpvmc4qsGsA15Q9LH/VnKePDeWcG8Dl9dLd4NFxghEdZJxJ1ceKbsxtAjTKInv2F5B0wzilxmP91NxLPy0OIGGPxA/8tkOz/ka1Dk5JTaYKyVIzG+yeTI8/sD3kip+KJ+D2NGEgsB+DL9GIHwQd//zZQoGDKCpKoDw9yLvda2rBzaT6/lyqpzPNOgmC4YfehK/la1haFnXFdgSflOToxaBISlWQlBqDWwmkYsfhKBPYwXYXHHYFbaWIl32S5wV5MQU50aYY2Xd+DwdbhrLP1YcFjQ0NxjMFWMFxdWA6jq0iI+QEPzKNlhZ1qUi1oyUYaw0k7pzKdYw+lX+DJcsSljPqVnODkp9MEcylc42qRQzVnlwkQx6wqbKEwLzw81XwrsPo+IeHmDKtY38CId0t9iNFpBixsoUgMCehqVj30R+sLgaEMDz9VM4UO92rgwJFicI14fMxADT7Wa6slLeyqbL/VPplHs5+P+zaPMnQ85+kCIeX2qiLk4U2LFiBwP+yhJ/ytVmuoSd1xTn0ZswAsTXkMQX5fgxVwVyYZpa/Zv3mNvBslUdFAJIhaRF9NqVzZhmAKD8l3h/HtgSp/fq99tQQw24UU7q4hp7caLdsKzR8lY+E2C68Mp7Ao7d0MoBk1sKyHOcggB7QPNBAH8nFyVzXSzD0eHduI96+r4z91tZgZnLpSLlJC0iz/OrcZQjqt+OzuFiEOR0mAf8g6KACs60YAsRx0ITRsou3EodwNC4gVkST9RcfU/eoDPFJkSEewP3TwDix9ySeWf2+sHHJbHgh+tjuUQzm/WJVvluJu+lnDOZQa20Q27jIoDKlmHwIcyCW5znYijgKu9kaCYnQaP8PXDsGSgwW0URQM7nWUc8bgegQ1002/Gep1QR7NfxnnbkRzA0eIs7QbkZUfbDBQUq532I5yb+H8lGaZooTb2GAAAAAElFTkSuQmCC';
13
- export { filterBase64Value, fullTimeStrWithMilliseconds, mouseLoading, mousePointer, timeStr };
14
+ export { filterBase64Value, fullTimeStrWithMilliseconds, mouseLoading, mousePointer, notifyError, timeStr };
@@ -0,0 +1,25 @@
1
+ import { notification } from "antd";
2
+ const DEFAULT_TITLE = 'Something went wrong';
3
+ function normalizeMessage(error) {
4
+ if ('string' == typeof error) return error;
5
+ if (error instanceof Error) return error.message || error.toString();
6
+ if (error && 'object' == typeof error && 'message' in error) {
7
+ const value = error.message;
8
+ if ('string' == typeof value) return value;
9
+ }
10
+ try {
11
+ return JSON.stringify(error);
12
+ } catch (e) {
13
+ return String(error);
14
+ }
15
+ }
16
+ function notifyError(error, options = {}) {
17
+ var _options_title, _options_description, _options_duration;
18
+ notification.error({
19
+ message: null != (_options_title = options.title) ? _options_title : DEFAULT_TITLE,
20
+ description: null != (_options_description = options.description) ? _options_description : normalizeMessage(error),
21
+ placement: 'bottomRight',
22
+ duration: null != (_options_duration = options.duration) ? _options_duration : 5
23
+ });
24
+ }
25
+ export { notifyError };
@@ -31,6 +31,7 @@ const icons_namespaceObject = require("@ant-design/icons");
31
31
  const external_antd_namespaceObject = require("antd");
32
32
  const external_react_namespaceObject = require("react");
33
33
  const store_js_namespaceObject = require("../../store/store.js");
34
+ const index_js_namespaceObject = require("../../utils/index.js");
34
35
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
35
36
  try {
36
37
  var info = gen[key](arg);
@@ -106,7 +107,9 @@ function EnvConfig({ showTooltipWhenEmpty = true, showModelName = true, tooltipP
106
107
  } else external_antd_namespaceObject.message.warning('Model verification found issues');
107
108
  } catch (error) {
108
109
  const errorMessage = error instanceof Error ? error.message : String(error);
109
- external_antd_namespaceObject.message.error(`Model verification failed: ${errorMessage}`);
110
+ (0, index_js_namespaceObject.notifyError)(error, {
111
+ title: 'Model verification failed'
112
+ });
110
113
  setConnectivityResult({
111
114
  passed: false,
112
115
  checks: [
@@ -46,6 +46,7 @@ var global_perspective_js_default = /*#__PURE__*/ __webpack_require__.n(global_p
46
46
  const player_setting_js_namespaceObject = require("../../icons/player-setting.js");
47
47
  var player_setting_js_default = /*#__PURE__*/ __webpack_require__.n(player_setting_js_namespaceObject);
48
48
  const store_js_namespaceObject = require("../../store/store.js");
49
+ const index_js_namespaceObject = require("../../utils/index.js");
49
50
  const external_playback_controls_js_namespaceObject = require("./playback-controls.js");
50
51
  const external_report_download_js_namespaceObject = require("./report-download.js");
51
52
  const StepScene_js_namespaceObject = require("./scenes/StepScene.js");
@@ -219,8 +220,9 @@ function Player(props) {
219
220
  onDownloadReport: props.onDownloadReport
220
221
  });
221
222
  } catch (error) {
222
- const errorMessage = error instanceof Error ? error.message : String(error);
223
- external_antd_namespaceObject.message.error(`Failed to download report: ${errorMessage}`);
223
+ (0, index_js_namespaceObject.notifyError)(error, {
224
+ title: 'Failed to download report'
225
+ });
224
226
  }
225
227
  })(), [
226
228
  null == props ? void 0 : props.onDownloadReport,
@@ -332,8 +334,9 @@ function Player(props) {
332
334
  external_antd_namespaceObject.message.success('Video exported');
333
335
  } catch (e) {
334
336
  console.error('Export failed:', e);
335
- const errorMessage = e instanceof Error ? e.message : 'Export failed';
336
- external_antd_namespaceObject.message.error(errorMessage);
337
+ (0, index_js_namespaceObject.notifyError)(e, {
338
+ title: 'Video export failed'
339
+ });
337
340
  } finally{
338
341
  exportInFlightRef.current = false;
339
342
  setIsExporting(false);
@@ -867,6 +867,31 @@
867
867
  color: rgba(255, 255, 255, .72) !important;
868
868
  }
869
869
 
870
+ [data-theme="dark"] .prompt-input-wrapper.prompt-input-wrapper-minimal .minimal-main-side-console-input .minimal-run-trigger:disabled {
871
+ color: rgba(255, 255, 255, .35);
872
+ background: rgba(255, 255, 255, .08);
873
+ }
874
+
875
+ [data-theme="dark"] .prompt-input-wrapper.prompt-input-wrapper-minimal .minimal-main-side-console-input .minimal-run-trigger-stop {
876
+ color: #f8fafd;
877
+ background: rgba(255, 255, 255, .12);
878
+ }
879
+
880
+ [data-theme="dark"] .prompt-input-wrapper.prompt-input-wrapper-minimal .minimal-main-side-console-input .minimal-run-trigger-stop:hover {
881
+ color: #fff;
882
+ background: rgba(255, 255, 255, .18);
883
+ }
884
+
885
+ [data-theme="dark"] .prompt-input-wrapper.prompt-input-wrapper-minimal .minimal-main-side-console-input .minimal-run-trigger-stop:focus-visible {
886
+ color: #fff;
887
+ background: rgba(255, 255, 255, .18);
888
+ }
889
+
890
+ [data-theme="dark"] .prompt-input-wrapper.prompt-input-wrapper-minimal .minimal-main-side-console-input .minimal-run-trigger-stop:disabled {
891
+ color: rgba(255, 255, 255, .35);
892
+ background: rgba(255, 255, 255, .08);
893
+ }
894
+
870
895
  [data-theme="dark"] .prompt-input .tip-button {
871
896
  background-color: rgba(255, 255, 255, .08);
872
897
  }
@@ -775,6 +775,31 @@
775
775
  color: rgba(255, 255, 255, .72) !important;
776
776
  }
777
777
 
778
+ [data-theme="dark"] .prompt-input-wrapper.prompt-input-wrapper-minimal .minimal-main-side-console-input .minimal-run-trigger:disabled {
779
+ color: rgba(255, 255, 255, .35);
780
+ background: rgba(255, 255, 255, .08);
781
+ }
782
+
783
+ [data-theme="dark"] .prompt-input-wrapper.prompt-input-wrapper-minimal .minimal-main-side-console-input .minimal-run-trigger-stop {
784
+ color: #f8fafd;
785
+ background: rgba(255, 255, 255, .12);
786
+ }
787
+
788
+ [data-theme="dark"] .prompt-input-wrapper.prompt-input-wrapper-minimal .minimal-main-side-console-input .minimal-run-trigger-stop:hover {
789
+ color: #fff;
790
+ background: rgba(255, 255, 255, .18);
791
+ }
792
+
793
+ [data-theme="dark"] .prompt-input-wrapper.prompt-input-wrapper-minimal .minimal-main-side-console-input .minimal-run-trigger-stop:focus-visible {
794
+ color: #fff;
795
+ background: rgba(255, 255, 255, .18);
796
+ }
797
+
798
+ [data-theme="dark"] .prompt-input-wrapper.prompt-input-wrapper-minimal .minimal-main-side-console-input .minimal-run-trigger-stop:disabled {
799
+ color: rgba(255, 255, 255, .35);
800
+ background: rgba(255, 255, 255, .08);
801
+ }
802
+
778
803
  [data-theme="dark"] .prompt-input .tip-button {
779
804
  background-color: rgba(255, 255, 255, .08);
780
805
  }
@@ -33,7 +33,8 @@ const external_react_namespaceObject = require("react");
33
33
  const useSafeOverrideAIConfig_js_namespaceObject = require("../../hooks/useSafeOverrideAIConfig.js");
34
34
  const useServerValid_js_namespaceObject = require("../../hooks/useServerValid.js");
35
35
  const store_js_namespaceObject = require("../../store/store.js");
36
- const index_js_namespaceObject = require("../env-config/index.js");
36
+ const index_js_namespaceObject = require("../../utils/index.js");
37
+ const external_env_config_index_js_namespaceObject = require("../env-config/index.js");
37
38
  const external_misc_index_js_namespaceObject = require("../misc/index.js");
38
39
  const TITLE_TEXT = {
39
40
  Server: 'Server Status',
@@ -90,8 +91,9 @@ const ServiceModeControl = ({ serviceMode })=>{
90
91
  type: 'remote-execution'
91
92
  });
92
93
  playgroundSDK.overrideConfig(config).catch((error)=>{
93
- const errorMsg = error instanceof Error ? error.message : String(error);
94
- external_antd_namespaceObject.message.error(`Failed to apply AI configuration: ${errorMsg}`);
94
+ (0, index_js_namespaceObject.notifyError)(error, {
95
+ title: 'Failed to apply AI configuration'
96
+ });
95
97
  });
96
98
  }
97
99
  }, [
@@ -120,7 +122,7 @@ const ServiceModeControl = ({ serviceMode })=>{
120
122
  children: title
121
123
  }),
122
124
  statusContent,
123
- /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(index_js_namespaceObject.EnvConfig, {
125
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_env_config_index_js_namespaceObject.EnvConfig, {
124
126
  showTooltipWhenEmpty: 'Server' !== serviceMode
125
127
  })
126
128
  ]
@@ -44,7 +44,8 @@ const external_react_namespaceObject = require("react");
44
44
  const usePlaygroundExecution_js_namespaceObject = require("../../hooks/usePlaygroundExecution.js");
45
45
  const usePlaygroundState_js_namespaceObject = require("../../hooks/usePlaygroundState.js");
46
46
  const store_js_namespaceObject = require("../../store/store.js");
47
- const index_js_namespaceObject = require("../context-preview/index.js");
47
+ const index_js_namespaceObject = require("../../utils/index.js");
48
+ const external_context_preview_index_js_namespaceObject = require("../context-preview/index.js");
48
49
  const external_env_config_reminder_index_js_namespaceObject = require("../env-config-reminder/index.js");
49
50
  const external_playground_result_index_js_namespaceObject = require("../playground-result/index.js");
50
51
  require("./index.css");
@@ -162,8 +163,9 @@ function UniversalPlayground({ playgroundSDK, storage, contextProvider, config:
162
163
  (0, external_react_namespaceObject.useEffect)(()=>{
163
164
  if ((null == playgroundSDK ? void 0 : playgroundSDK.overrideConfig) && config) playgroundSDK.overrideConfig(config).catch((error)=>{
164
165
  console.error('Failed to override SDK config:', error);
165
- const errorMsg = error instanceof Error ? error.message : String(error);
166
- external_antd_namespaceObject.message.error(`Failed to apply AI configuration: ${errorMsg}`);
166
+ (0, index_js_namespaceObject.notifyError)(error, {
167
+ title: 'Failed to apply AI configuration'
168
+ });
167
169
  });
168
170
  }, [
169
171
  playgroundSDK,
@@ -174,7 +176,9 @@ function UniversalPlayground({ playgroundSDK, storage, contextProvider, config:
174
176
  const value = form.getFieldsValue();
175
177
  yield executeAction(value);
176
178
  } catch (error) {
177
- external_antd_namespaceObject.message.error((null == error ? void 0 : error.message) || 'Execution failed');
179
+ (0, index_js_namespaceObject.notifyError)(error, {
180
+ title: 'Execution failed'
181
+ });
178
182
  }
179
183
  })(), [
180
184
  form,
@@ -295,7 +299,7 @@ function UniversalPlayground({ playgroundSDK, storage, contextProvider, config:
295
299
  children: [
296
300
  finalShowContextPreview && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
297
301
  className: "context-preview-section",
298
- children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(index_js_namespaceObject.ContextPreview, {
302
+ children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_context_preview_index_js_namespaceObject.ContextPreview, {
299
303
  uiContextPreview: uiContextPreview,
300
304
  setUiContextPreview: setUiContextPreview,
301
305
  showContextPreview: finalShowContextPreview
@@ -28,7 +28,7 @@ __webpack_require__.d(__webpack_exports__, {
28
28
  useSafeOverrideAIConfig: ()=>useSafeOverrideAIConfig
29
29
  });
30
30
  const env_namespaceObject = require("@midscene/shared/env");
31
- const external_antd_namespaceObject = require("antd");
31
+ const index_js_namespaceObject = require("../utils/index.js");
32
32
  function safeOverrideAIConfig(newConfig, extendMode = false, showErrorMessage = true) {
33
33
  try {
34
34
  (0, env_namespaceObject.overrideAIConfig)(newConfig, extendMode);
@@ -36,7 +36,9 @@ function safeOverrideAIConfig(newConfig, extendMode = false, showErrorMessage =
36
36
  } catch (error) {
37
37
  const err = error instanceof Error ? error : new Error(String(error));
38
38
  console.error('Failed to override AI config:', err);
39
- if (showErrorMessage) external_antd_namespaceObject.message.error(`Failed to apply AI configuration: ${err.message}`);
39
+ if (showErrorMessage) (0, index_js_namespaceObject.notifyError)(err, {
40
+ title: 'Failed to apply AI configuration'
41
+ });
40
42
  return false;
41
43
  }
42
44
  }
package/dist/lib/index.js CHANGED
@@ -37,6 +37,7 @@ __webpack_require__.d(__webpack_exports__, {
37
37
  allScriptsFromDump: ()=>replay_scripts_js_namespaceObject.allScriptsFromDump,
38
38
  staticAgentFromContext: ()=>playground_utils_js_namespaceObject.staticAgentFromContext,
39
39
  iconForStatus: ()=>misc_index_js_namespaceObject.iconForStatus,
40
+ notifyError: ()=>external_utils_index_js_namespaceObject.notifyError,
40
41
  StorageType: ()=>storage_provider_js_namespaceObject.StorageType,
41
42
  detectBestStorageType: ()=>storage_provider_js_namespaceObject.detectBestStorageType,
42
43
  StaticContextProvider: ()=>context_provider_js_namespaceObject.StaticContextProvider,
@@ -140,6 +141,7 @@ exports.getPlaceholderForType = __webpack_exports__.getPlaceholderForType;
140
141
  exports.globalThemeConfig = __webpack_exports__.globalThemeConfig;
141
142
  exports.highlightColorForType = __webpack_exports__.highlightColorForType;
142
143
  exports.iconForStatus = __webpack_exports__.iconForStatus;
144
+ exports.notifyError = __webpack_exports__.notifyError;
143
145
  exports.safeOverrideAIConfig = __webpack_exports__.safeOverrideAIConfig;
144
146
  exports.staticAgentFromContext = __webpack_exports__.staticAgentFromContext;
145
147
  exports.timeCostStrElement = __webpack_exports__.timeCostStrElement;
@@ -185,6 +187,7 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
185
187
  "globalThemeConfig",
186
188
  "highlightColorForType",
187
189
  "iconForStatus",
190
+ "notifyError",
188
191
  "safeOverrideAIConfig",
189
192
  "staticAgentFromContext",
190
193
  "timeCostStrElement",
@@ -24,6 +24,7 @@ var __webpack_require__ = {};
24
24
  var __webpack_exports__ = {};
25
25
  __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
+ parseConfig: ()=>parseConfig,
27
28
  useEnvConfig: ()=>useEnvConfig,
28
29
  useGlobalPreference: ()=>useGlobalPreference
29
30
  });
@@ -150,7 +151,7 @@ const parseConfig = (configString)=>{
150
151
  const trimmed = line.trim();
151
152
  if (trimmed.startsWith('#')) return;
152
153
  const cleanLine = trimmed.replace(/^export\s+/i, '').replace(/;$/, '').trim();
153
- const match = cleanLine.match(/^(\w+)=(.*)$/);
154
+ const match = cleanLine.match(/^(\w+)\s*=\s*(.*)$/);
154
155
  if (match) {
155
156
  const [, key, value] = match;
156
157
  let parsedValue = value.trim();
@@ -276,9 +277,11 @@ const useEnvConfig = create((set, get)=>{
276
277
  }
277
278
  };
278
279
  });
280
+ exports.parseConfig = __webpack_exports__.parseConfig;
279
281
  exports.useEnvConfig = __webpack_exports__.useEnvConfig;
280
282
  exports.useGlobalPreference = __webpack_exports__.useGlobalPreference;
281
283
  for(var __rspack_i in __webpack_exports__)if (-1 === [
284
+ "parseConfig",
282
285
  "useEnvConfig",
283
286
  "useGlobalPreference"
284
287
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
@@ -36,11 +36,13 @@ __webpack_require__.d(__webpack_exports__, {
36
36
  fullTimeStrWithMilliseconds: ()=>fullTimeStrWithMilliseconds,
37
37
  mouseLoading: ()=>mouseLoading,
38
38
  mousePointer: ()=>mousePointer,
39
+ notifyError: ()=>external_notify_js_namespaceObject.notifyError,
39
40
  timeStr: ()=>timeStr,
40
41
  filterBase64Value: ()=>filterBase64Value
41
42
  });
42
43
  const external_dayjs_namespaceObject = require("dayjs");
43
44
  var external_dayjs_default = /*#__PURE__*/ __webpack_require__.n(external_dayjs_namespaceObject);
45
+ const external_notify_js_namespaceObject = require("./notify.js");
44
46
  function timeStr(timestamp) {
45
47
  return timestamp ? external_dayjs_default()(timestamp).format('YYYY-MM-DD HH:mm:ss') : '-';
46
48
  }
@@ -56,12 +58,14 @@ exports.filterBase64Value = __webpack_exports__.filterBase64Value;
56
58
  exports.fullTimeStrWithMilliseconds = __webpack_exports__.fullTimeStrWithMilliseconds;
57
59
  exports.mouseLoading = __webpack_exports__.mouseLoading;
58
60
  exports.mousePointer = __webpack_exports__.mousePointer;
61
+ exports.notifyError = __webpack_exports__.notifyError;
59
62
  exports.timeStr = __webpack_exports__.timeStr;
60
63
  for(var __rspack_i in __webpack_exports__)if (-1 === [
61
64
  "filterBase64Value",
62
65
  "fullTimeStrWithMilliseconds",
63
66
  "mouseLoading",
64
67
  "mousePointer",
68
+ "notifyError",
65
69
  "timeStr"
66
70
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
67
71
  Object.defineProperty(exports, '__esModule', {
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ notifyError: ()=>notifyError
28
+ });
29
+ const external_antd_namespaceObject = require("antd");
30
+ const DEFAULT_TITLE = 'Something went wrong';
31
+ function normalizeMessage(error) {
32
+ if ('string' == typeof error) return error;
33
+ if (error instanceof Error) return error.message || error.toString();
34
+ if (error && 'object' == typeof error && 'message' in error) {
35
+ const value = error.message;
36
+ if ('string' == typeof value) return value;
37
+ }
38
+ try {
39
+ return JSON.stringify(error);
40
+ } catch (e) {
41
+ return String(error);
42
+ }
43
+ }
44
+ function notifyError(error, options = {}) {
45
+ var _options_title, _options_description, _options_duration;
46
+ external_antd_namespaceObject.notification.error({
47
+ message: null != (_options_title = options.title) ? _options_title : DEFAULT_TITLE,
48
+ description: null != (_options_description = options.description) ? _options_description : normalizeMessage(error),
49
+ placement: 'bottomRight',
50
+ duration: null != (_options_duration = options.duration) ? _options_duration : 5
51
+ });
52
+ }
53
+ exports.notifyError = __webpack_exports__.notifyError;
54
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
55
+ "notifyError"
56
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
57
+ Object.defineProperty(exports, '__esModule', {
58
+ value: true
59
+ });
@@ -20,7 +20,8 @@ export { Blackboard } from './component/blackboard';
20
20
  export { default as ScreenshotViewer } from './component/screenshot-viewer';
21
21
  export type { ScreenshotViewerMode } from './component/screenshot-viewer';
22
22
  export { actionNameForType, staticAgentFromContext, getPlaceholderForType, } from './utils/playground-utils';
23
- export { timeStr, filterBase64Value } from './utils';
23
+ export { timeStr, filterBase64Value, notifyError } from './utils';
24
+ export type { NotifyErrorOptions } from './utils';
24
25
  export { default as ShinyText } from './component/shiny-text';
25
26
  export { UniversalPlayground, default as UniversalPlaygroundDefault, } from './component/universal-playground';
26
27
  export type { UniversalPlaygroundProps, PlaygroundSDKLike, StorageProvider, ContextProvider, UniversalPlaygroundConfig, PlaygroundBranding, InfoListItem, FormValue, ExecutionOptions, ProgressCallback, DeviceType, ExecutionUxHint, ExecutionUxConfig, PromptInputChromeConfig, ReportDownloadHandler, ReportDownloadRequest, } from './types';
@@ -16,6 +16,7 @@ export declare const useGlobalPreference: Z.UseBoundStore<Z.StoreApi<{
16
16
  setPlaybackSpeed: (speed: PlaybackSpeedType) => void;
17
17
  setSubtitleEnabled: (enabled: boolean) => void;
18
18
  }>>;
19
+ export declare const parseConfig: (configString: string) => Record<string, string>;
19
20
  /**
20
21
  * Service Mode
21
22
  *
@@ -1,3 +1,5 @@
1
+ export { notifyError } from './notify';
2
+ export type { NotifyErrorOptions } from './notify';
1
3
  export declare function timeStr(timestamp?: number): string;
2
4
  export declare function fullTimeStrWithMilliseconds(timestamp?: number): string;
3
5
  export declare function filterBase64Value(input: string): string;
@@ -0,0 +1,15 @@
1
+ export interface NotifyErrorOptions {
2
+ /** Short, descriptive label rendered as the toast title. */
3
+ title?: string;
4
+ /** Custom body text; defaults to the normalized error message. */
5
+ description?: string;
6
+ /** Seconds before auto-dismiss. Mirrors antd's default of 4.5. */
7
+ duration?: number;
8
+ }
9
+ /**
10
+ * Project-wide error toast. Consolidates the ad-hoc `message.error(...)`
11
+ * calls that used to pop a full-width banner at the top of the window — the
12
+ * playground and shell now share a single bottom-right notification format,
13
+ * so a series of failures stack instead of clobbering the chrome.
14
+ */
15
+ export declare function notifyError(error: unknown, options?: NotifyErrorOptions): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@midscene/visualizer",
3
- "version": "1.8.0",
3
+ "version": "1.8.1",
4
4
  "repository": "https://github.com/web-infra-dev/midscene",
5
5
  "homepage": "https://midscenejs.com/",
6
6
  "types": "./dist/types/index.d.ts",
@@ -65,10 +65,10 @@
65
65
  "antd": "^5.21.6",
66
66
  "buffer": "6.0.3",
67
67
  "dayjs": "^1.11.11",
68
- "@midscene/core": "1.8.0",
69
- "@midscene/playground": "1.8.0",
70
- "@midscene/shared": "1.8.0",
71
- "@midscene/web": "1.8.0"
68
+ "@midscene/core": "1.8.1",
69
+ "@midscene/playground": "1.8.1",
70
+ "@midscene/shared": "1.8.1",
71
+ "@midscene/web": "1.8.1"
72
72
  },
73
73
  "license": "MIT",
74
74
  "scripts": {