@midscene/visualizer 0.28.7-beta-20250915040112.0 → 0.28.7-beta-20250915133700.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 (32) hide show
  1. package/dist/es/component/history-selector/index.css +18 -17
  2. package/dist/es/component/history-selector/index.mjs +5 -43
  3. package/dist/es/component/playground/index.css +42 -3
  4. package/dist/es/component/playground-result/index.css +0 -1
  5. package/dist/es/component/playground-result/index.mjs +1 -2
  6. package/dist/es/component/prompt-input/index.css +42 -2
  7. package/dist/es/component/service-mode-control/index.mjs +2 -2
  8. package/dist/es/component/universal-playground/index.css +2 -2
  9. package/dist/es/component/universal-playground/index.mjs +16 -16
  10. package/dist/es/hooks/usePlaygroundExecution.mjs +27 -12
  11. package/dist/es/hooks/usePlaygroundState.mjs +6 -8
  12. package/dist/es/hooks/useSafeOverrideAIConfig.mjs +24 -0
  13. package/dist/es/index.mjs +2 -1
  14. package/dist/lib/component/history-selector/index.css +18 -17
  15. package/dist/lib/component/history-selector/index.js +4 -42
  16. package/dist/lib/component/playground/index.css +42 -3
  17. package/dist/lib/component/playground-result/index.css +0 -1
  18. package/dist/lib/component/playground-result/index.js +1 -2
  19. package/dist/lib/component/prompt-input/index.css +42 -2
  20. package/dist/lib/component/service-mode-control/index.js +2 -2
  21. package/dist/lib/component/universal-playground/index.css +2 -2
  22. package/dist/lib/component/universal-playground/index.js +16 -16
  23. package/dist/lib/hooks/usePlaygroundExecution.js +27 -12
  24. package/dist/lib/hooks/usePlaygroundState.js +6 -8
  25. package/dist/lib/hooks/useSafeOverrideAIConfig.js +61 -0
  26. package/dist/lib/index.js +7 -0
  27. package/dist/types/hooks/usePlaygroundExecution.d.ts +1 -1
  28. package/dist/types/hooks/usePlaygroundState.d.ts +1 -1
  29. package/dist/types/hooks/useSafeOverrideAIConfig.d.ts +16 -0
  30. package/dist/types/index.d.ts +1 -0
  31. package/dist/types/types.d.ts +6 -10
  32. package/package.json +5 -5
@@ -103,50 +103,12 @@ const HistorySelector = (param)=>{
103
103
  height: 24
104
104
  })
105
105
  }),
106
- /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_antd_namespaceObject.Modal, {
107
- open: isModalOpen,
108
- onCancel: ()=>setIsModalOpen(false),
109
- footer: null,
110
- width: "100%",
111
- closable: false,
112
- centered: false,
113
- transitionName: "",
114
- maskTransitionName: "",
115
- style: {
116
- margin: 0,
117
- padding: 0,
118
- maxWidth: 'none',
119
- top: 'auto',
120
- bottom: 0
121
- },
122
- styles: {
123
- wrapper: {
124
- alignItems: 'flex-end',
125
- justifyContent: 'center',
126
- paddingBottom: 0,
127
- display: 'flex'
128
- },
129
- body: {
130
- height: '70vh',
131
- padding: 0,
132
- margin: 0
133
- },
134
- content: {
135
- height: '70vh',
136
- borderRadius: '12px 12px 0 0',
137
- margin: 0,
138
- padding: 0,
139
- marginBottom: 0,
140
- position: 'fixed',
141
- bottom: 0,
142
- left: 0,
143
- right: 0
144
- }
145
- },
146
- maskClosable: true,
147
- destroyOnClose: true,
106
+ isModalOpen && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
107
+ className: "history-modal-overlay",
108
+ onClick: ()=>setIsModalOpen(false),
148
109
  children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
149
110
  className: "history-modal-container",
111
+ onClick: (e)=>e.stopPropagation(),
150
112
  children: [
151
113
  /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
152
114
  className: "history-modal-header",
@@ -1,6 +1,5 @@
1
1
  .result-wrapper {
2
2
  justify-content: center;
3
- align-items: center;
4
3
  height: 100%;
5
4
  margin: 4px 0;
6
5
  display: flex;
@@ -38,24 +37,50 @@
38
37
  }
39
38
 
40
39
  .prompt-input-wrapper .mode-radio-group-wrapper {
41
- justify-content: space-between;
42
40
  align-items: center;
41
+ gap: 8px;
43
42
  display: flex;
43
+ position: relative;
44
44
  }
45
45
 
46
46
  .prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group {
47
+ scrollbar-width: none;
48
+ -ms-overflow-style: none;
49
+ flex: 1;
47
50
  align-items: center;
51
+ gap: 8px;
52
+ min-width: 0;
48
53
  height: 100%;
54
+ margin-right: 80px;
55
+ display: flex;
56
+ overflow-x: auto;
57
+ overflow-y: hidden;
58
+ }
59
+
60
+ .prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group::-webkit-scrollbar {
61
+ display: none;
62
+ }
63
+
64
+ .prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .ant-form-item {
65
+ flex-shrink: 0;
66
+ margin: 0 !important;
67
+ }
68
+
69
+ .prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .ant-form-item .ant-radio-group {
70
+ flex-wrap: nowrap;
71
+ gap: 8px;
49
72
  display: flex;
50
73
  }
51
74
 
52
75
  .prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .ant-radio-button-wrapper {
53
76
  height: 24px;
54
77
  box-shadow: none;
78
+ white-space: nowrap;
55
79
  background-color: #f7f7f7;
56
80
  border: none;
57
81
  border-radius: 11px;
58
- margin-right: 8px;
82
+ flex-shrink: 0;
83
+ margin-right: 0;
59
84
  padding: 0 8px;
60
85
  font-size: 12px;
61
86
  line-height: 24px;
@@ -79,12 +104,18 @@
79
104
  color: #fff;
80
105
  }
81
106
 
107
+ .prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .ant-dropdown-trigger {
108
+ flex-shrink: 0;
109
+ }
110
+
82
111
  .prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .more-apis-button {
83
112
  height: 24px;
84
113
  box-shadow: none;
114
+ white-space: nowrap;
85
115
  background-color: #f7f7f7;
86
116
  border: none;
87
117
  border-radius: 11px;
118
+ flex-shrink: 0;
88
119
  align-items: center;
89
120
  gap: 2px;
90
121
  max-width: 160px;
@@ -114,8 +145,16 @@
114
145
  }
115
146
 
116
147
  .prompt-input-wrapper .mode-radio-group-wrapper .action-icons {
148
+ z-index: 10;
149
+ background: #fff;
150
+ flex-shrink: 0;
117
151
  align-items: center;
152
+ padding-left: 8px;
118
153
  display: flex;
154
+ position: absolute;
155
+ top: 50%;
156
+ right: 0;
157
+ transform: translateY(-50%);
119
158
  }
120
159
 
121
160
  .prompt-input-wrapper .main-side-console-input {
@@ -1,6 +1,5 @@
1
1
  .result-wrapper {
2
2
  justify-content: center;
3
- align-items: center;
4
3
  height: 100%;
5
4
  margin: 4px 0;
6
5
  display: flex;
@@ -92,8 +92,7 @@ const PlaygroundResultView = (param)=>{
92
92
  display: 'flex',
93
93
  flexDirection: 'column',
94
94
  flex: '1 1 auto',
95
- justifyContent: 'center',
96
- alignItems: 'center'
95
+ justifyContent: 'center'
97
96
  },
98
97
  children: resultDataToShow
99
98
  });
@@ -3,24 +3,50 @@
3
3
  }
4
4
 
5
5
  .prompt-input-wrapper .mode-radio-group-wrapper {
6
- justify-content: space-between;
7
6
  align-items: center;
7
+ gap: 8px;
8
8
  display: flex;
9
+ position: relative;
9
10
  }
10
11
 
11
12
  .prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group {
13
+ scrollbar-width: none;
14
+ -ms-overflow-style: none;
15
+ flex: 1;
12
16
  align-items: center;
17
+ gap: 8px;
18
+ min-width: 0;
13
19
  height: 100%;
20
+ margin-right: 80px;
21
+ display: flex;
22
+ overflow-x: auto;
23
+ overflow-y: hidden;
24
+ }
25
+
26
+ .prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group::-webkit-scrollbar {
27
+ display: none;
28
+ }
29
+
30
+ .prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .ant-form-item {
31
+ flex-shrink: 0;
32
+ margin: 0 !important;
33
+ }
34
+
35
+ .prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .ant-form-item .ant-radio-group {
36
+ flex-wrap: nowrap;
37
+ gap: 8px;
14
38
  display: flex;
15
39
  }
16
40
 
17
41
  .prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .ant-radio-button-wrapper {
18
42
  height: 24px;
19
43
  box-shadow: none;
44
+ white-space: nowrap;
20
45
  background-color: #f7f7f7;
21
46
  border: none;
22
47
  border-radius: 11px;
23
- margin-right: 8px;
48
+ flex-shrink: 0;
49
+ margin-right: 0;
24
50
  padding: 0 8px;
25
51
  font-size: 12px;
26
52
  line-height: 24px;
@@ -44,12 +70,18 @@
44
70
  color: #fff;
45
71
  }
46
72
 
73
+ .prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .ant-dropdown-trigger {
74
+ flex-shrink: 0;
75
+ }
76
+
47
77
  .prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .more-apis-button {
48
78
  height: 24px;
49
79
  box-shadow: none;
80
+ white-space: nowrap;
50
81
  background-color: #f7f7f7;
51
82
  border: none;
52
83
  border-radius: 11px;
84
+ flex-shrink: 0;
53
85
  align-items: center;
54
86
  gap: 2px;
55
87
  max-width: 160px;
@@ -79,8 +111,16 @@
79
111
  }
80
112
 
81
113
  .prompt-input-wrapper .mode-radio-group-wrapper .action-icons {
114
+ z-index: 10;
115
+ background: #fff;
116
+ flex-shrink: 0;
82
117
  align-items: center;
118
+ padding-left: 8px;
83
119
  display: flex;
120
+ position: absolute;
121
+ top: 50%;
122
+ right: 0;
123
+ transform: translateY(-50%);
84
124
  }
85
125
 
86
126
  .prompt-input-wrapper .main-side-console-input {
@@ -28,9 +28,9 @@ __webpack_require__.d(__webpack_exports__, {
28
28
  });
29
29
  const jsx_runtime_namespaceObject = require("react/jsx-runtime");
30
30
  const playground_namespaceObject = require("@midscene/playground");
31
- const env_namespaceObject = require("@midscene/shared/env");
32
31
  const external_antd_namespaceObject = require("antd");
33
32
  const external_react_namespaceObject = require("react");
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
36
  const index_js_namespaceObject = require("../env-config/index.js");
@@ -85,7 +85,7 @@ const ServiceModeControl = (param)=>{
85
85
  });
86
86
  };
87
87
  (0, external_react_namespaceObject.useEffect)(()=>{
88
- (0, env_namespaceObject.overrideAIConfig)(config);
88
+ (0, useSafeOverrideAIConfig_js_namespaceObject.safeOverrideAIConfig)(config, false, false);
89
89
  if ('Server' === serviceMode) {
90
90
  const playgroundSDK = new playground_namespaceObject.PlaygroundSDK({
91
91
  type: 'remote-execution'
@@ -4,13 +4,13 @@
4
4
  width: 100%;
5
5
  height: 100vh;
6
6
  display: flex;
7
+ position: relative;
7
8
  }
8
9
 
9
10
  .playground-container .command-form {
10
11
  flex-direction: column;
11
12
  width: 100%;
12
13
  height: 100%;
13
- padding: 0 12px;
14
14
  display: flex;
15
15
  }
16
16
 
@@ -119,7 +119,7 @@
119
119
 
120
120
  .playground-container .user-message-container .user-message-bubble {
121
121
  color: rgba(0, 0, 0, .85);
122
- text-align: center;
122
+ text-align: left;
123
123
  background: #f2f4f7;
124
124
  border-radius: 12px;
125
125
  max-width: 80%;
@@ -51,7 +51,12 @@ require("./index.css");
51
51
  const avatar_js_namespaceObject = require("../../icons/avatar.js");
52
52
  var avatar_js_default = /*#__PURE__*/ __webpack_require__.n(avatar_js_namespaceObject);
53
53
  const external_prompt_input_index_js_namespaceObject = require("../prompt-input/index.js");
54
+ const storage_provider_js_namespaceObject = require("./providers/storage-provider.js");
54
55
  const { Text } = external_antd_namespaceObject.Typography;
56
+ function getSDKId(sdk) {
57
+ if (sdk.id && 'string' == typeof sdk.id) return `agent-${sdk.id}`;
58
+ return 'playground-default';
59
+ }
55
60
  function ErrorMessage(param) {
56
61
  let { error } = param;
57
62
  if (!error) return null;
@@ -75,26 +80,21 @@ function ErrorMessage(param) {
75
80
  function UniversalPlayground(param) {
76
81
  let { playgroundSDK, storage, contextProvider, config: componentConfig = {}, branding = {}, className = '', dryMode = false, showContextPreview = true } = param;
77
82
  const [form] = external_antd_namespaceObject.Form.useForm();
78
- const { deepThink, screenshotIncluded, domIncluded, config } = (0, store_js_namespaceObject.useEnvConfig)();
79
- const enablePersistence = false !== componentConfig.enablePersistence;
80
- const { loading, setLoading, infoList, setInfoList, actionSpace, actionSpaceLoading, uiContextPreview, setUiContextPreview, showScrollToBottomButton, verticalMode, replayCounter, setReplayCounter, infoListRef, currentRunningIdRef, interruptedFlagRef, clearInfoList, handleScrollToBottom } = (0, usePlaygroundState_js_namespaceObject.usePlaygroundState)(playgroundSDK, storage, contextProvider, enablePersistence);
81
- const { handleRun: executeAction, handleStop, canStop } = (0, usePlaygroundExecution_js_namespaceObject.usePlaygroundExecution)(playgroundSDK, storage, actionSpace, loading, setLoading, infoList, setInfoList, replayCounter, setReplayCounter, verticalMode, currentRunningIdRef, interruptedFlagRef);
83
+ const { config } = (0, store_js_namespaceObject.useEnvConfig)();
84
+ const effectiveStorage = (()=>{
85
+ if (storage) return storage;
86
+ const namespace = componentConfig.storageNamespace || getSDKId(playgroundSDK);
87
+ return new storage_provider_js_namespaceObject.LocalStorageProvider(namespace);
88
+ })();
89
+ const { loading, setLoading, infoList, setInfoList, actionSpace, actionSpaceLoading, uiContextPreview, setUiContextPreview, showScrollToBottomButton, verticalMode, replayCounter, setReplayCounter, infoListRef, currentRunningIdRef, interruptedFlagRef, clearInfoList, handleScrollToBottom } = (0, usePlaygroundState_js_namespaceObject.usePlaygroundState)(playgroundSDK, effectiveStorage, contextProvider);
90
+ const { handleRun: executeAction, handleStop, canStop } = (0, usePlaygroundExecution_js_namespaceObject.usePlaygroundExecution)(playgroundSDK, effectiveStorage, actionSpace, loading, setLoading, infoList, setInfoList, replayCounter, setReplayCounter, verticalMode, currentRunningIdRef, interruptedFlagRef);
82
91
  (0, external_react_namespaceObject.useEffect)(()=>{
83
- const completeConfig = {
84
- ...config,
85
- deepThink,
86
- screenshotIncluded,
87
- domIncluded
88
- };
89
- if (playgroundSDK.overrideConfig) playgroundSDK.overrideConfig(completeConfig).catch((error)=>{
92
+ if ((null == playgroundSDK ? void 0 : playgroundSDK.overrideConfig) && config) playgroundSDK.overrideConfig(config).catch((error)=>{
90
93
  console.error('Failed to override SDK config:', error);
91
94
  });
92
95
  }, [
93
96
  playgroundSDK,
94
- config,
95
- deepThink,
96
- screenshotIncluded,
97
- domIncluded
97
+ config
98
98
  ]);
99
99
  const handleFormRun = (0, external_react_namespaceObject.useCallback)(async ()=>{
100
100
  try {
@@ -285,7 +285,7 @@ function UniversalPlayground(param) {
285
285
  /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
286
286
  className: "bottom-input-section",
287
287
  children: [
288
- !componentConfig.serverMode && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_env_config_reminder_index_js_namespaceObject.EnvConfigReminder, {}),
288
+ componentConfig.showEnvConfigReminder ? /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_env_config_reminder_index_js_namespaceObject.EnvConfigReminder, {}) : null,
289
289
  /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_prompt_input_index_js_namespaceObject.PromptInput, {
290
290
  runButtonEnabled: runButtonEnabled,
291
291
  form: form,
@@ -27,6 +27,7 @@ __webpack_require__.d(__webpack_exports__, {
27
27
  usePlaygroundExecution: ()=>usePlaygroundExecution
28
28
  });
29
29
  const external_react_namespaceObject = require("react");
30
+ const store_js_namespaceObject = require("../store/store.js");
30
31
  const constants_js_namespaceObject = require("../utils/constants.js");
31
32
  const replay_scripts_js_namespaceObject = require("../utils/replay-scripts.js");
32
33
  const noReplayAPIs = [
@@ -34,7 +35,9 @@ const noReplayAPIs = [
34
35
  'aiAssert'
35
36
  ];
36
37
  function usePlaygroundExecution(playgroundSDK, storage, actionSpace, loading, setLoading, infoList, setInfoList, replayCounter, setReplayCounter, verticalMode, currentRunningIdRef, interruptedFlagRef) {
38
+ const { deepThink, screenshotIncluded, domIncluded } = (0, store_js_namespaceObject.useEnvConfig)();
37
39
  const handleRun = (0, external_react_namespaceObject.useCallback)(async (value)=>{
40
+ if (!playgroundSDK) return void console.warn('PlaygroundSDK is not available');
38
41
  const thisRunningId = Date.now();
39
42
  const actionType = value.type;
40
43
  const displayContent = `${value.type}: ${value.prompt || JSON.stringify(value.params)}`;
@@ -67,21 +70,29 @@ function usePlaygroundExecution(playgroundSDK, storage, actionSpace, loading, se
67
70
  try {
68
71
  currentRunningIdRef.current = thisRunningId;
69
72
  interruptedFlagRef.current[thisRunningId] = false;
73
+ if (playgroundSDK.onProgressUpdate) playgroundSDK.onProgressUpdate(()=>{});
70
74
  if (playgroundSDK.onProgressUpdate) playgroundSDK.onProgressUpdate((tip)=>{
71
75
  if (interruptedFlagRef.current[thisRunningId]) return;
72
- const progressItem = {
73
- id: `progress-${thisRunningId}-${Date.now()}`,
74
- type: 'progress',
75
- content: tip,
76
- timestamp: new Date()
77
- };
78
- setInfoList((prev)=>[
76
+ setInfoList((prev)=>{
77
+ const lastItem = prev[prev.length - 1];
78
+ if (lastItem && 'progress' === lastItem.type && lastItem.content === tip) return prev;
79
+ const progressItem = {
80
+ id: `progress-${thisRunningId}-${Date.now()}`,
81
+ type: 'progress',
82
+ content: tip,
83
+ timestamp: new Date()
84
+ };
85
+ return [
79
86
  ...prev,
80
87
  progressItem
81
- ]);
88
+ ];
89
+ });
82
90
  });
83
91
  result.result = await playgroundSDK.executeAction(actionType, value, {
84
- requestId: thisRunningId.toString()
92
+ requestId: thisRunningId.toString(),
93
+ deepThink,
94
+ screenshotIncluded,
95
+ domIncluded
85
96
  });
86
97
  if ('object' == typeof result.result && null !== result.result) {
87
98
  const resultObj = result.result;
@@ -152,14 +163,18 @@ function usePlaygroundExecution(playgroundSDK, storage, actionSpace, loading, se
152
163
  setReplayCounter,
153
164
  verticalMode,
154
165
  currentRunningIdRef,
155
- interruptedFlagRef
166
+ interruptedFlagRef,
167
+ deepThink,
168
+ screenshotIncluded,
169
+ domIncluded
156
170
  ]);
157
171
  const handleStop = (0, external_react_namespaceObject.useCallback)(async ()=>{
158
172
  const thisRunningId = currentRunningIdRef.current;
159
- if (thisRunningId && playgroundSDK.cancelExecution) try {
173
+ if (thisRunningId && playgroundSDK && playgroundSDK.cancelExecution) try {
160
174
  await playgroundSDK.cancelExecution(thisRunningId.toString());
161
175
  interruptedFlagRef.current[thisRunningId] = true;
162
176
  setLoading(false);
177
+ if (playgroundSDK.onProgressUpdate) playgroundSDK.onProgressUpdate(()=>{});
163
178
  setInfoList((prev)=>prev.map((item)=>item.id === `system-${thisRunningId}` && item.loading ? {
164
179
  ...item,
165
180
  content: 'Operation stopped',
@@ -186,7 +201,7 @@ function usePlaygroundExecution(playgroundSDK, storage, actionSpace, loading, se
186
201
  setLoading,
187
202
  setInfoList
188
203
  ]);
189
- const canStop = loading && !!currentRunningIdRef.current && !!playgroundSDK.cancelExecution;
204
+ const canStop = loading && !!currentRunningIdRef.current && !!playgroundSDK && !!playgroundSDK.cancelExecution;
190
205
  return {
191
206
  handleRun,
192
207
  handleStop,
@@ -29,7 +29,6 @@ __webpack_require__.d(__webpack_exports__, {
29
29
  const external_react_namespaceObject = require("react");
30
30
  const constants_js_namespaceObject = require("../utils/constants.js");
31
31
  function usePlaygroundState(playgroundSDK, storage, contextProvider) {
32
- let enablePersistence = arguments.length > 3 && void 0 !== arguments[3] ? arguments[3] : true;
33
32
  const [loading, setLoading] = (0, external_react_namespaceObject.useState)(false);
34
33
  const [infoList, setInfoList] = (0, external_react_namespaceObject.useState)([]);
35
34
  const [actionSpace, setActionSpace] = (0, external_react_namespaceObject.useState)([]);
@@ -48,7 +47,7 @@ function usePlaygroundState(playgroundSDK, storage, contextProvider) {
48
47
  id: 'welcome',
49
48
  timestamp: new Date()
50
49
  };
51
- if (enablePersistence && (null == storage ? void 0 : storage.loadMessages)) try {
50
+ if (null == storage ? void 0 : storage.loadMessages) try {
52
51
  const storedMessages = await storage.loadMessages();
53
52
  const hasWelcomeMessage = storedMessages.some((msg)=>'welcome' === msg.id);
54
53
  hasWelcomeMessage ? setInfoList(storedMessages) : setInfoList([
@@ -68,13 +67,12 @@ function usePlaygroundState(playgroundSDK, storage, contextProvider) {
68
67
  if (0 === infoList.length) initializeMessages();
69
68
  }, []);
70
69
  (0, external_react_namespaceObject.useEffect)(()=>{
71
- if (enablePersistence && (null == storage ? void 0 : storage.saveMessages) && infoList.length > 1) storage.saveMessages(infoList).catch((error)=>{
70
+ if ((null == storage ? void 0 : storage.saveMessages) && infoList.length > 1) storage.saveMessages(infoList).catch((error)=>{
72
71
  console.error('Failed to save messages:', error);
73
72
  });
74
73
  }, [
75
74
  infoList,
76
- storage,
77
- enablePersistence
75
+ storage
78
76
  ]);
79
77
  (0, external_react_namespaceObject.useEffect)(()=>{
80
78
  if (!(null == contextProvider ? void 0 : contextProvider.getUIContext) || uiContextPreview) return;
@@ -90,6 +88,7 @@ function usePlaygroundState(playgroundSDK, storage, contextProvider) {
90
88
  setActionSpaceLoading(true);
91
89
  try {
92
90
  var _contextProvider_getUIContext;
91
+ if (!playgroundSDK) return void setActionSpace([]);
93
92
  const context = uiContextPreview || await (null == contextProvider ? void 0 : null == (_contextProvider_getUIContext = contextProvider.getUIContext) ? void 0 : _contextProvider_getUIContext.call(contextProvider));
94
93
  const space = await playgroundSDK.getActionSpace(context);
95
94
  setActionSpace(space || []);
@@ -163,14 +162,13 @@ function usePlaygroundState(playgroundSDK, storage, contextProvider) {
163
162
  setInfoList([
164
163
  welcomeMessage
165
164
  ]);
166
- if (enablePersistence && (null == storage ? void 0 : storage.clearMessages)) try {
165
+ if (null == storage ? void 0 : storage.clearMessages) try {
167
166
  await storage.clearMessages();
168
167
  } catch (error) {
169
168
  console.error('Failed to clear stored messages:', error);
170
169
  }
171
170
  }, [
172
- storage,
173
- enablePersistence
171
+ storage
174
172
  ]);
175
173
  const refreshContext = (0, external_react_namespaceObject.useCallback)(async ()=>{
176
174
  if (null == contextProvider ? void 0 : contextProvider.refreshContext) try {
@@ -0,0 +1,61 @@
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
+ safeOverrideAIConfig: ()=>safeOverrideAIConfig,
28
+ useSafeOverrideAIConfig: ()=>useSafeOverrideAIConfig
29
+ });
30
+ const env_namespaceObject = require("@midscene/shared/env");
31
+ const external_antd_namespaceObject = require("antd");
32
+ function safeOverrideAIConfig(newConfig) {
33
+ let extendMode = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : false, showErrorMessage = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : true;
34
+ try {
35
+ (0, env_namespaceObject.overrideAIConfig)(newConfig, extendMode);
36
+ return true;
37
+ } catch (error) {
38
+ const err = error instanceof Error ? error : new Error(String(error));
39
+ console.error('Failed to override AI config:', err);
40
+ if (showErrorMessage) external_antd_namespaceObject.message.error(`Failed to apply AI configuration: ${err.message}`);
41
+ return false;
42
+ }
43
+ }
44
+ function useSafeOverrideAIConfig() {
45
+ const applyConfig = function(newConfig) {
46
+ let extendMode = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : false, showErrorMessage = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : true;
47
+ return safeOverrideAIConfig(newConfig, extendMode, showErrorMessage);
48
+ };
49
+ return {
50
+ applyConfig
51
+ };
52
+ }
53
+ exports.safeOverrideAIConfig = __webpack_exports__.safeOverrideAIConfig;
54
+ exports.useSafeOverrideAIConfig = __webpack_exports__.useSafeOverrideAIConfig;
55
+ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
56
+ "safeOverrideAIConfig",
57
+ "useSafeOverrideAIConfig"
58
+ ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
59
+ Object.defineProperty(exports, '__esModule', {
60
+ value: true
61
+ });
package/dist/lib/index.js CHANGED
@@ -45,10 +45,12 @@ __webpack_require__.d(__webpack_exports__, {
45
45
  ShinyText: ()=>shiny_text_index_js_default(),
46
46
  getPlaceholderForType: ()=>playground_utils_js_namespaceObject.getPlaceholderForType,
47
47
  staticAgentFromContext: ()=>playground_utils_js_namespaceObject.staticAgentFromContext,
48
+ useSafeOverrideAIConfig: ()=>useSafeOverrideAIConfig_js_namespaceObject.useSafeOverrideAIConfig,
48
49
  useServerValid: ()=>useServerValid_js_namespaceObject.useServerValid,
49
50
  ServiceModeControl: ()=>service_mode_control_index_js_namespaceObject.ServiceModeControl,
50
51
  BaseContextProvider: ()=>context_provider_js_namespaceObject.BaseContextProvider,
51
52
  colorForName: ()=>color_js_namespaceObject.colorForName,
53
+ safeOverrideAIConfig: ()=>useSafeOverrideAIConfig_js_namespaceObject.safeOverrideAIConfig,
52
54
  GithubStar: ()=>github_star_index_js_namespaceObject.GithubStar,
53
55
  Logo: ()=>logo_index_js_namespaceObject.Logo,
54
56
  UniversalPlayground: ()=>universal_playground_index_js_namespaceObject.UniversalPlayground,
@@ -78,6 +80,7 @@ const env_config_reminder_index_js_namespaceObject = require("./component/env-co
78
80
  const logo_index_js_namespaceObject = require("./component/logo/index.js");
79
81
  const misc_index_js_namespaceObject = require("./component/misc/index.js");
80
82
  const useServerValid_js_namespaceObject = require("./hooks/useServerValid.js");
83
+ const useSafeOverrideAIConfig_js_namespaceObject = require("./hooks/useSafeOverrideAIConfig.js");
81
84
  const playground_result_index_js_namespaceObject = require("./component/playground-result/index.js");
82
85
  const service_mode_control_index_js_namespaceObject = require("./component/service-mode-control/index.js");
83
86
  const context_preview_index_js_namespaceObject = require("./component/context-preview/index.js");
@@ -122,10 +125,12 @@ exports.getPlaceholderForType = __webpack_exports__.getPlaceholderForType;
122
125
  exports.globalThemeConfig = __webpack_exports__.globalThemeConfig;
123
126
  exports.highlightColorForType = __webpack_exports__.highlightColorForType;
124
127
  exports.iconForStatus = __webpack_exports__.iconForStatus;
128
+ exports.safeOverrideAIConfig = __webpack_exports__.safeOverrideAIConfig;
125
129
  exports.staticAgentFromContext = __webpack_exports__.staticAgentFromContext;
126
130
  exports.timeCostStrElement = __webpack_exports__.timeCostStrElement;
127
131
  exports.timeStr = __webpack_exports__.timeStr;
128
132
  exports.useEnvConfig = __webpack_exports__.useEnvConfig;
133
+ exports.useSafeOverrideAIConfig = __webpack_exports__.useSafeOverrideAIConfig;
129
134
  exports.useServerValid = __webpack_exports__.useServerValid;
130
135
  for(var __webpack_i__ in __webpack_exports__)if (-1 === [
131
136
  "AgentContextProvider",
@@ -157,10 +162,12 @@ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
157
162
  "globalThemeConfig",
158
163
  "highlightColorForType",
159
164
  "iconForStatus",
165
+ "safeOverrideAIConfig",
160
166
  "staticAgentFromContext",
161
167
  "timeCostStrElement",
162
168
  "timeStr",
163
169
  "useEnvConfig",
170
+ "useSafeOverrideAIConfig",
164
171
  "useServerValid"
165
172
  ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
166
173
  Object.defineProperty(exports, '__esModule', {
@@ -3,7 +3,7 @@ import type { FormValue, InfoListItem, PlaygroundSDKLike, StorageProvider } from
3
3
  /**
4
4
  * Hook for handling playground execution logic
5
5
  */
6
- export declare function usePlaygroundExecution(playgroundSDK: PlaygroundSDKLike, storage: StorageProvider | undefined, actionSpace: DeviceAction<unknown>[], loading: boolean, setLoading: (loading: boolean) => void, infoList: InfoListItem[], setInfoList: React.Dispatch<React.SetStateAction<InfoListItem[]>>, replayCounter: number, setReplayCounter: React.Dispatch<React.SetStateAction<number>>, verticalMode: boolean, currentRunningIdRef: React.MutableRefObject<number | null>, interruptedFlagRef: React.MutableRefObject<Record<number, boolean>>): {
6
+ export declare function usePlaygroundExecution(playgroundSDK: PlaygroundSDKLike | null, storage: StorageProvider | undefined, actionSpace: DeviceAction<unknown>[], loading: boolean, setLoading: (loading: boolean) => void, infoList: InfoListItem[], setInfoList: React.Dispatch<React.SetStateAction<InfoListItem[]>>, replayCounter: number, setReplayCounter: React.Dispatch<React.SetStateAction<number>>, verticalMode: boolean, currentRunningIdRef: React.MutableRefObject<number | null>, interruptedFlagRef: React.MutableRefObject<Record<number, boolean>>): {
7
7
  handleRun: (value: FormValue) => Promise<void>;
8
8
  handleStop: () => Promise<void>;
9
9
  canStop: boolean;
@@ -3,7 +3,7 @@ import type { ContextProvider, InfoListItem, PlaygroundSDKLike, StorageProvider
3
3
  /**
4
4
  * Hook for managing playground state
5
5
  */
6
- export declare function usePlaygroundState(playgroundSDK: PlaygroundSDKLike, storage?: StorageProvider, contextProvider?: ContextProvider, enablePersistence?: boolean): {
6
+ export declare function usePlaygroundState(playgroundSDK: PlaygroundSDKLike | null, storage?: StorageProvider, contextProvider?: ContextProvider): {
7
7
  loading: boolean;
8
8
  setLoading: import("react").Dispatch<import("react").SetStateAction<boolean>>;
9
9
  infoList: InfoListItem[];
@@ -0,0 +1,16 @@
1
+ import type { GLOBAL_ENV_KEYS, MODEL_ENV_KEYS } from '@midscene/shared/env';
2
+ /**
3
+ * Safely override AI configuration with built-in error handling
4
+ * @param newConfig - The configuration to override
5
+ * @param extendMode - Whether to extend or replace the config (default: false)
6
+ * @param showErrorMessage - Whether to show error message in UI (default: true)
7
+ * @returns boolean indicating success
8
+ */
9
+ export declare function safeOverrideAIConfig(newConfig: Partial<Record<(typeof GLOBAL_ENV_KEYS)[number] | (typeof MODEL_ENV_KEYS)[number], string>>, extendMode?: boolean, showErrorMessage?: boolean): boolean;
10
+ /**
11
+ * React Hook for safely overriding AI config with error handling
12
+ * Useful for components that need to handle config changes
13
+ */
14
+ export declare function useSafeOverrideAIConfig(): {
15
+ applyConfig: (newConfig: Partial<Record<(typeof GLOBAL_ENV_KEYS)[number] | (typeof MODEL_ENV_KEYS)[number], string>>, extendMode?: boolean, showErrorMessage?: boolean) => boolean;
16
+ };
@@ -8,6 +8,7 @@ export { EnvConfigReminder } from './component/env-config-reminder';
8
8
  export { Logo } from './component/logo';
9
9
  export { iconForStatus, timeCostStrElement } from './component/misc';
10
10
  export { useServerValid } from './hooks/useServerValid';
11
+ export { useSafeOverrideAIConfig, safeOverrideAIConfig, } from './hooks/useSafeOverrideAIConfig';
11
12
  export { PlaygroundResultView } from './component/playground-result';
12
13
  export type { PlaygroundResult } from './types';
13
14
  export { ServiceModeControl } from './component/service-mode-control';