@midscene/visualizer 1.0.1-beta-20251209112631.0 → 1.0.1-beta-20251211095502.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 (27) hide show
  1. package/dist/es/component/player/index.mjs +2 -2
  2. package/dist/es/component/playground-result/index.mjs +12 -5
  3. package/dist/es/component/shiny-text/index.css +20 -3
  4. package/dist/es/component/shiny-text/index.mjs +3 -2
  5. package/dist/es/component/universal-playground/index.css +0 -1
  6. package/dist/es/component/universal-playground/index.mjs +49 -52
  7. package/dist/es/component/universal-playground/providers/indexeddb-storage-provider.mjs +13 -18
  8. package/dist/es/component/universal-playground/providers/storage-provider.mjs +2 -2
  9. package/dist/es/hooks/usePlaygroundExecution.mjs +105 -20
  10. package/dist/es/index.mjs +2 -2
  11. package/dist/es/store/store.mjs +23 -2
  12. package/dist/lib/component/player/index.js +1 -1
  13. package/dist/lib/component/playground-result/index.js +12 -5
  14. package/dist/lib/component/shiny-text/index.css +20 -3
  15. package/dist/lib/component/shiny-text/index.js +3 -2
  16. package/dist/lib/component/universal-playground/index.css +0 -1
  17. package/dist/lib/component/universal-playground/index.js +49 -51
  18. package/dist/lib/component/universal-playground/providers/indexeddb-storage-provider.js +13 -18
  19. package/dist/lib/component/universal-playground/providers/storage-provider.js +2 -2
  20. package/dist/lib/hooks/usePlaygroundExecution.js +105 -20
  21. package/dist/lib/index.js +3 -0
  22. package/dist/lib/store/store.js +26 -5
  23. package/dist/types/hooks/usePlaygroundExecution.d.ts +1 -1
  24. package/dist/types/index.d.ts +1 -1
  25. package/dist/types/store/store.d.ts +5 -1
  26. package/dist/types/types.d.ts +8 -2
  27. package/package.json +5 -5
@@ -67,11 +67,18 @@ const PlaygroundResultView = ({ result, loading, serverValid, serviceMode, repla
67
67
  })
68
68
  ]
69
69
  });
70
- else if (replayScriptsInfo) resultDataToShow = /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_player_index_js_namespaceObject.Player, {
71
- replayScripts: replayScriptsInfo.scripts,
72
- imageWidth: replayScriptsInfo.width,
73
- imageHeight: replayScriptsInfo.height,
74
- reportFileContent: ('In-Browser-Extension' === serviceMode || 'Server' === serviceMode) && (null == result ? void 0 : result.reportHTML) ? null == result ? void 0 : result.reportHTML : null,
70
+ else if (replayScriptsInfo) {
71
+ const reportContent = ('In-Browser-Extension' === serviceMode || 'Server' === serviceMode) && (null == result ? void 0 : result.reportHTML) ? null == result ? void 0 : result.reportHTML : null;
72
+ resultDataToShow = /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_player_index_js_namespaceObject.Player, {
73
+ replayScripts: replayScriptsInfo.scripts,
74
+ imageWidth: replayScriptsInfo.width,
75
+ imageHeight: replayScriptsInfo.height,
76
+ reportFileContent: reportContent,
77
+ fitMode: fitMode,
78
+ autoZoom: autoZoom
79
+ }, replayCounter);
80
+ } else if ((null == result ? void 0 : result.reportHTML) && ('In-Browser-Extension' === serviceMode || 'Server' === serviceMode)) resultDataToShow = /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_player_index_js_namespaceObject.Player, {
81
+ reportFileContent: result.reportHTML,
75
82
  fitMode: fitMode,
76
83
  autoZoom: autoZoom
77
84
  }, replayCounter);
@@ -13,6 +13,23 @@
13
13
  overflow: hidden;
14
14
  }
15
15
 
16
+ .shiny-text.theme-blue {
17
+ background-image: linear-gradient(45deg, #2b83ff, #6a11cb, #2575fc, #4481eb);
18
+ }
19
+
20
+ .shiny-text.theme-purple {
21
+ background-image: linear-gradient(45deg, #667eea, #764ba2, #b06ab3, #9d50bb);
22
+ }
23
+
24
+ .shiny-text.theme-green {
25
+ background-image: linear-gradient(45deg, #11998e, #38ef7d, #2dd4bf, #10b981);
26
+ }
27
+
28
+ .shiny-text.theme-rainbow {
29
+ background-image: linear-gradient(45deg, #ff0080, #ff8c00, #40e0d0, #9d50bb, #ff0080);
30
+ background-size: 400%;
31
+ }
32
+
16
33
  .shiny-text:after {
17
34
  content: "";
18
35
  width: 120%;
@@ -28,9 +45,9 @@
28
45
  }
29
46
 
30
47
  .shiny-text.disabled {
31
- background: #2b83ff;
32
- -webkit-background-clip: text;
33
- background-clip: text;
48
+ color: #000;
49
+ background: none;
50
+ font-weight: normal;
34
51
  animation: none;
35
52
  }
36
53
 
@@ -28,12 +28,13 @@ __webpack_require__.d(__webpack_exports__, {
28
28
  });
29
29
  const jsx_runtime_namespaceObject = require("react/jsx-runtime");
30
30
  require("./index.css");
31
- const ShinyText = ({ text, disabled = false, speed = 5, className = '' })=>{
31
+ const ShinyText = ({ text, disabled = false, speed = 5, className = '', colorTheme = 'blue' })=>{
32
32
  const style = {
33
33
  '--animation-duration': `${speed}s`
34
34
  };
35
+ const themeClass = `theme-${colorTheme}`;
35
36
  return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
36
- className: `shiny-text ${disabled ? 'disabled' : ''} ${className}`,
37
+ className: `shiny-text ${themeClass} ${disabled ? 'disabled' : ''} ${className}`,
37
38
  style: style,
38
39
  children: text
39
40
  });
@@ -160,7 +160,6 @@
160
160
  }
161
161
 
162
162
  .playground-container .progress-description {
163
- color: #000;
164
163
  padding: 8px 0;
165
164
  font-size: 14px;
166
165
  line-height: 22px;
@@ -52,6 +52,8 @@ const avatar_js_namespaceObject = require("../../icons/avatar.js");
52
52
  var avatar_js_default = /*#__PURE__*/ __webpack_require__.n(avatar_js_namespaceObject);
53
53
  const constants_js_namespaceObject = require("../../utils/constants.js");
54
54
  const external_prompt_input_index_js_namespaceObject = require("../prompt-input/index.js");
55
+ const external_shiny_text_index_js_namespaceObject = require("../shiny-text/index.js");
56
+ var external_shiny_text_index_js_default = /*#__PURE__*/ __webpack_require__.n(external_shiny_text_index_js_namespaceObject);
55
57
  const storage_provider_js_namespaceObject = require("./providers/storage-provider.js");
56
58
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
57
59
  try {
@@ -86,11 +88,16 @@ function getSDKId(sdk) {
86
88
  }
87
89
  function ErrorMessage({ error }) {
88
90
  if (!error) return null;
89
- return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("span", {
90
- children: [
91
- "Error: ",
92
- error
93
- ]
91
+ const cleanError = error.replace(/^(Error:\s*)+/, 'Error: ');
92
+ return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_antd_namespaceObject.Alert, {
93
+ message: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("span", {
94
+ style: {
95
+ color: '#ff4d4f'
96
+ },
97
+ children: cleanError
98
+ }),
99
+ type: "error",
100
+ showIcon: true
94
101
  });
95
102
  }
96
103
  function UniversalPlayground({ playgroundSDK, storage, contextProvider, config: componentConfig = {}, branding = {}, className = '', dryMode = false, showContextPreview = true }) {
@@ -133,7 +140,7 @@ function UniversalPlayground({ playgroundSDK, storage, contextProvider, config:
133
140
  playgroundSDK
134
141
  ]);
135
142
  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);
136
- const { handleRun: executeAction, handleStop, canStop } = (0, usePlaygroundExecution_js_namespaceObject.usePlaygroundExecution)(playgroundSDK, effectiveStorage, actionSpace, loading, setLoading, infoList, setInfoList, replayCounter, setReplayCounter, verticalMode, currentRunningIdRef, interruptedFlagRef);
143
+ const { handleRun: executeAction, handleStop, canStop } = (0, usePlaygroundExecution_js_namespaceObject.usePlaygroundExecution)(playgroundSDK, effectiveStorage, actionSpace, loading, setLoading, setInfoList, replayCounter, setReplayCounter, verticalMode, currentRunningIdRef, interruptedFlagRef);
137
144
  (0, external_react_namespaceObject.useEffect)(()=>{
138
145
  if ((null == playgroundSDK ? void 0 : playgroundSDK.overrideConfig) && config) playgroundSDK.overrideConfig(config).catch((error)=>{
139
146
  console.error('Failed to override SDK config:', error);
@@ -156,6 +163,12 @@ function UniversalPlayground({ playgroundSDK, storage, contextProvider, config:
156
163
  const configAlreadySet = Object.keys(config || {}).length >= 1;
157
164
  const runButtonEnabled = componentConfig.serverMode || !dryMode && !actionSpaceLoading && configAlreadySet;
158
165
  const selectedType = external_antd_namespaceObject.Form.useWatch('type', form);
166
+ const serviceMode = (0, external_react_namespaceObject.useMemo)(()=>{
167
+ if (!playgroundSDK || 'function' != typeof playgroundSDK.getServiceMode) return 'Server';
168
+ return playgroundSDK.getServiceMode();
169
+ }, [
170
+ playgroundSDK
171
+ ]);
159
172
  const finalShowContextPreview = showContextPreview && false !== componentConfig.showContextPreview;
160
173
  const layout = componentConfig.layout || 'vertical';
161
174
  const showVersionInfo = false !== componentConfig.showVersionInfo;
@@ -194,9 +207,7 @@ function UniversalPlayground({ playgroundSDK, storage, contextProvider, config:
194
207
  children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_antd_namespaceObject.List, {
195
208
  itemLayout: "vertical",
196
209
  dataSource: infoList,
197
- renderItem: (item)=>{
198
- var _item_result;
199
- return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_antd_namespaceObject.List.Item, {
210
+ renderItem: (item)=>/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_antd_namespaceObject.List.Item, {
200
211
  className: "list-item",
201
212
  children: 'user' === item.type ? /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
202
213
  className: "user-message-container",
@@ -229,9 +240,10 @@ function UniversalPlayground({ playgroundSDK, storage, contextProvider, config:
229
240
  ]
230
241
  }),
231
242
  description && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
232
- children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("span", {
243
+ children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_shiny_text_index_js_default(), {
244
+ text: description,
233
245
  className: "progress-description",
234
- children: description
246
+ disabled: !shouldShowLoading
235
247
  })
236
248
  }),
237
249
  (null == (_item_result2 = item.result) ? void 0 : _item_result2.error) && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(ErrorMessage, {
@@ -273,50 +285,36 @@ function UniversalPlayground({ playgroundSDK, storage, contextProvider, config:
273
285
  })
274
286
  ]
275
287
  }),
276
- (item.content || item.result) && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
288
+ (item.content || item.result) && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
277
289
  className: "system-message-content",
278
- children: [
279
- 'result' === item.type && (null == (_item_result = item.result) ? void 0 : _item_result.error) && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
280
- className: "error-message",
281
- children: [
282
- /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
283
- className: "divider"
284
- }),
285
- /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(ErrorMessage, {
286
- error: item.result.error
287
- })
288
- ]
289
- }),
290
- 'result' === item.type ? /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_playground_result_index_js_namespaceObject.PlaygroundResultView, {
291
- result: item.result || null,
292
- loading: item.loading || false,
293
- serverValid: true,
294
- serviceMode: 'Server',
295
- replayScriptsInfo: item.replayScriptsInfo || null,
296
- replayCounter: item.replayCounter || 0,
297
- loadingProgressText: item.loadingProgressText || '',
298
- verticalMode: item.verticalMode || false,
299
- fitMode: "width"
300
- }) : /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(jsx_runtime_namespaceObject.Fragment, {
301
- children: [
302
- /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
303
- className: "system-message-text",
304
- children: item.content
305
- }),
306
- item.loading && item.loadingProgressText && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
307
- className: "loading-progress-text",
308
- children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("span", {
309
- children: item.loadingProgressText
310
- })
290
+ children: 'result' === item.type ? /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_playground_result_index_js_namespaceObject.PlaygroundResultView, {
291
+ result: item.result || null,
292
+ loading: item.loading || false,
293
+ serverValid: true,
294
+ serviceMode: serviceMode,
295
+ replayScriptsInfo: item.replayScriptsInfo || null,
296
+ replayCounter: item.replayCounter || 0,
297
+ loadingProgressText: item.loadingProgressText || '',
298
+ verticalMode: item.verticalMode || false,
299
+ fitMode: "width"
300
+ }) : /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(jsx_runtime_namespaceObject.Fragment, {
301
+ children: [
302
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
303
+ className: "system-message-text",
304
+ children: item.content
305
+ }),
306
+ item.loading && item.loadingProgressText && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
307
+ className: "loading-progress-text",
308
+ children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("span", {
309
+ children: item.loadingProgressText
311
310
  })
312
- ]
313
- })
314
- ]
311
+ })
312
+ ]
313
+ })
315
314
  })
316
315
  ]
317
316
  })
318
- }, item.id);
319
- }
317
+ }, item.id)
320
318
  })
321
319
  }),
322
320
  showScrollToBottomButton && false !== componentConfig.enableScrollToBottom && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_antd_namespaceObject.Button, {
@@ -336,7 +334,7 @@ function UniversalPlayground({ playgroundSDK, storage, contextProvider, config:
336
334
  /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_prompt_input_index_js_namespaceObject.PromptInput, {
337
335
  runButtonEnabled: runButtonEnabled,
338
336
  form: form,
339
- serviceMode: 'Server',
337
+ serviceMode: serviceMode,
340
338
  selectedType: selectedType,
341
339
  dryMode: dryMode,
342
340
  stoppable: canStop,
@@ -111,7 +111,7 @@ class IndexedDBStorageProvider {
111
111
  const messagesToSave = messages.slice(-MAX_STORED_MESSAGES);
112
112
  yield Promise.all(messagesToSave.map((msg, index)=>{
113
113
  const lightMessage = _object_spread_props(_object_spread({}, msg), {
114
- result: void 0
114
+ result: 'result' === msg.type ? void 0 : msg.result
115
115
  });
116
116
  const data = {
117
117
  id: msg.id || `msg-${index}`,
@@ -183,28 +183,23 @@ class IndexedDBStorageProvider {
183
183
  }
184
184
  compressResultForStorage(result) {
185
185
  var _result_result_dump, _result_result;
186
- if (!(null == (_result_result = result.result) ? void 0 : null == (_result_result_dump = _result_result.dump) ? void 0 : _result_result_dump.executions)) return result;
187
- const compressedExecutions = result.result.dump.executions.map((execution)=>{
188
- var _execution_tasks;
189
- return _object_spread_props(_object_spread({}, execution), {
190
- tasks: (null == (_execution_tasks = execution.tasks) ? void 0 : _execution_tasks.map((task)=>{
191
- var _task_recorder;
192
- var _this_compressScreenshotIfNeeded;
193
- return _object_spread_props(_object_spread({}, task), {
194
- uiContext: task.uiContext ? _object_spread_props(_object_spread({}, task.uiContext), {
195
- screenshotBase64: null != (_this_compressScreenshotIfNeeded = this.compressScreenshotIfNeeded(task.uiContext.screenshotBase64)) ? _this_compressScreenshotIfNeeded : task.uiContext.screenshotBase64
196
- }) : task.uiContext,
197
- recorder: null == (_task_recorder = task.recorder) ? void 0 : _task_recorder.map((record)=>_object_spread_props(_object_spread({}, record), {
198
- screenshot: this.compressScreenshotIfNeeded(record.screenshot)
199
- }))
200
- });
201
- })) || []
186
+ if (!(null == (_result_result = result.result) ? void 0 : null == (_result_result_dump = _result_result.dump) ? void 0 : _result_result_dump.tasks)) return result;
187
+ const compressedTasks = result.result.dump.tasks.map((task)=>{
188
+ var _task_recorder;
189
+ var _this_compressScreenshotIfNeeded;
190
+ return _object_spread_props(_object_spread({}, task), {
191
+ uiContext: task.uiContext ? _object_spread_props(_object_spread({}, task.uiContext), {
192
+ screenshotBase64: null != (_this_compressScreenshotIfNeeded = this.compressScreenshotIfNeeded(task.uiContext.screenshotBase64)) ? _this_compressScreenshotIfNeeded : task.uiContext.screenshotBase64
193
+ }) : task.uiContext,
194
+ recorder: null == (_task_recorder = task.recorder) ? void 0 : _task_recorder.map((record)=>_object_spread_props(_object_spread({}, record), {
195
+ screenshot: this.compressScreenshotIfNeeded(record.screenshot)
196
+ }))
202
197
  });
203
198
  });
204
199
  return _object_spread_props(_object_spread({}, result), {
205
200
  result: _object_spread_props(_object_spread({}, result.result), {
206
201
  dump: _object_spread_props(_object_spread({}, result.result.dump), {
207
- executions: compressedExecutions
202
+ tasks: compressedTasks
208
203
  })
209
204
  })
210
205
  });
@@ -124,7 +124,7 @@ class LocalStorageProvider {
124
124
  }
125
125
  const messagesToSave = messages.slice(-this.maxStorageItems);
126
126
  const lightMessages = messagesToSave.map((msg)=>_object_spread_props(_object_spread({}, msg), {
127
- result: void 0
127
+ result: 'result' === msg.type ? void 0 : msg.result
128
128
  }));
129
129
  const messageData = JSON.stringify(lightMessages);
130
130
  localStorage.setItem(this.messagesKey, messageData);
@@ -135,7 +135,7 @@ class LocalStorageProvider {
135
135
  try {
136
136
  const recentMessages = messages.slice(-10);
137
137
  const lightRecentMessages = recentMessages.map((msg)=>_object_spread_props(_object_spread({}, msg), {
138
- result: void 0
138
+ result: 'result' === msg.type ? void 0 : msg.result
139
139
  }));
140
140
  const messageData = JSON.stringify(lightRecentMessages);
141
141
  localStorage.setItem(this.messagesKey, messageData);
@@ -26,6 +26,7 @@ __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
27
  usePlaygroundExecution: ()=>usePlaygroundExecution
28
28
  });
29
+ const agent_namespaceObject = require("@midscene/core/agent");
29
30
  const external_react_namespaceObject = require("react");
30
31
  const store_js_namespaceObject = require("../store/store.js");
31
32
  const playground_namespaceObject = require("@midscene/playground");
@@ -99,7 +100,33 @@ function _object_spread_props(target, source) {
99
100
  });
100
101
  return target;
101
102
  }
102
- function usePlaygroundExecution(playgroundSDK, storage, actionSpace, loading, setLoading, infoList, setInfoList, replayCounter, setReplayCounter, verticalMode, currentRunningIdRef, interruptedFlagRef) {
103
+ function buildProgressContent(task) {
104
+ const action = (0, agent_namespaceObject.typeStr)(task);
105
+ const description = (0, agent_namespaceObject.paramStr)(task);
106
+ return description ? `${action} - ${description}` : action;
107
+ }
108
+ function wrapExecutionDumpForReplay(dump) {
109
+ const modelBriefsSet = new Set();
110
+ if ((null == dump ? void 0 : dump.tasks) && Array.isArray(dump.tasks)) dump.tasks.forEach((task)=>{
111
+ if (task.usage) {
112
+ const { model_name, model_description, intent } = task.usage;
113
+ if (intent && model_name) modelBriefsSet.add(model_description ? `${intent}/${model_name}(${model_description})` : `${intent}/${model_name}`);
114
+ }
115
+ });
116
+ else console.warn('[wrapExecutionDumpForReplay] Invalid dump structure:', dump);
117
+ const modelBriefs = [
118
+ ...modelBriefsSet
119
+ ];
120
+ return {
121
+ sdkVersion: '',
122
+ groupName: 'Playground Execution',
123
+ modelBriefs,
124
+ executions: [
125
+ dump
126
+ ]
127
+ };
128
+ }
129
+ function usePlaygroundExecution(playgroundSDK, storage, actionSpace, loading, setLoading, setInfoList, replayCounter, setReplayCounter, verticalMode, currentRunningIdRef, interruptedFlagRef) {
103
130
  const { deepThink, screenshotIncluded, domIncluded } = (0, store_js_namespaceObject.useEnvConfig)();
104
131
  const handleRun = (0, external_react_namespaceObject.useCallback)((value)=>_async_to_generator(function*() {
105
132
  if (!playgroundSDK) return void console.warn('PlaygroundSDK is not available');
@@ -133,21 +160,30 @@ function usePlaygroundExecution(playgroundSDK, storage, actionSpace, loading, se
133
160
  try {
134
161
  currentRunningIdRef.current = thisRunningId;
135
162
  interruptedFlagRef.current[thisRunningId] = false;
136
- if (playgroundSDK.onProgressUpdate) playgroundSDK.onProgressUpdate(()=>{});
137
- if (playgroundSDK.onProgressUpdate) playgroundSDK.onProgressUpdate((tip)=>{
138
- if (interruptedFlagRef.current[thisRunningId]) return;
139
- setInfoList((prev)=>{
140
- const lastItem = prev[prev.length - 1];
141
- if (lastItem && 'progress' === lastItem.type && lastItem.content === tip) return prev;
142
- const progressItem = {
143
- id: `progress-${thisRunningId}-${Date.now()}`,
163
+ if (playgroundSDK.onDumpUpdate) playgroundSDK.onDumpUpdate((_, executionDump)=>{
164
+ var _executionDump_tasks;
165
+ if (interruptedFlagRef.current[thisRunningId] || !(null == executionDump ? void 0 : null == (_executionDump_tasks = executionDump.tasks) ? void 0 : _executionDump_tasks.length)) return;
166
+ const progressItems = executionDump.tasks.map((task, index)=>{
167
+ var _task_timing;
168
+ return {
169
+ id: `progress-${thisRunningId}-task-${index}`,
144
170
  type: 'progress',
145
- content: tip,
146
- timestamp: new Date()
171
+ content: buildProgressContent(task),
172
+ timestamp: new Date((null == (_task_timing = task.timing) ? void 0 : _task_timing.start) || Date.now()),
173
+ result: task.error ? {
174
+ error: String(task.error),
175
+ result: null
176
+ } : void 0
147
177
  };
178
+ });
179
+ setInfoList((prev)=>{
180
+ const systemItemIndex = prev.findIndex((item)=>item.id === `system-${thisRunningId}`);
181
+ if (-1 === systemItemIndex) return prev;
182
+ const listWithoutCurrentProgress = prev.filter((item)=>!('progress' === item.type && item.id.startsWith(`progress-${thisRunningId}-`)));
148
183
  return [
149
- ...prev,
150
- progressItem
184
+ ...listWithoutCurrentProgress.slice(0, systemItemIndex + 1),
185
+ ...progressItems,
186
+ ...listWithoutCurrentProgress.slice(systemItemIndex + 1)
151
187
  ];
152
188
  });
153
189
  });
@@ -167,6 +203,10 @@ function usePlaygroundExecution(playgroundSDK, storage, actionSpace, loading, se
167
203
  } catch (e) {
168
204
  result.error = (null == e ? void 0 : e.message) || String(e);
169
205
  console.error('Playground execution error:', e);
206
+ if ('object' == typeof e && null !== e) {
207
+ if (e.dump) result.dump = e.dump;
208
+ if (e.reportHTML) result.reportHTML = e.reportHTML;
209
+ }
170
210
  }
171
211
  if (interruptedFlagRef.current[thisRunningId]) return;
172
212
  setLoading(false);
@@ -174,10 +214,13 @@ function usePlaygroundExecution(playgroundSDK, storage, actionSpace, loading, se
174
214
  let replayInfo = null;
175
215
  let counter = replayCounter;
176
216
  if ((null == result ? void 0 : result.dump) && !playground_namespaceObject.noReplayAPIs.includes(actionType)) {
177
- const info = (0, replay_scripts_js_namespaceObject.allScriptsFromDump)(result.dump);
178
- setReplayCounter((c)=>c + 1);
179
- replayInfo = info;
180
- counter = replayCounter + 1;
217
+ if (result.dump.tasks && Array.isArray(result.dump.tasks)) {
218
+ const groupedDump = wrapExecutionDumpForReplay(result.dump);
219
+ const info = (0, replay_scripts_js_namespaceObject.allScriptsFromDump)(groupedDump);
220
+ setReplayCounter((c)=>c + 1);
221
+ replayInfo = info;
222
+ counter = replayCounter + 1;
223
+ }
181
224
  }
182
225
  setInfoList((prev)=>prev.map((item)=>item.id === `system-${thisRunningId}` ? _object_spread_props(_object_spread({}, item), {
183
226
  content: '',
@@ -233,15 +276,55 @@ function usePlaygroundExecution(playgroundSDK, storage, actionSpace, loading, se
233
276
  const handleStop = (0, external_react_namespaceObject.useCallback)(()=>_async_to_generator(function*() {
234
277
  const thisRunningId = currentRunningIdRef.current;
235
278
  if (thisRunningId && playgroundSDK && playgroundSDK.cancelExecution) try {
279
+ let executionData = null;
280
+ if (playgroundSDK.getCurrentExecutionData) try {
281
+ executionData = yield playgroundSDK.getCurrentExecutionData();
282
+ } catch (error) {
283
+ console.error('Failed to get execution data before stop:', error);
284
+ }
236
285
  yield playgroundSDK.cancelExecution(thisRunningId.toString());
237
286
  interruptedFlagRef.current[thisRunningId] = true;
238
287
  setLoading(false);
239
288
  if (playgroundSDK.onProgressUpdate) playgroundSDK.onProgressUpdate(()=>{});
240
- setInfoList((prev)=>prev.map((item)=>item.id === `system-${thisRunningId}` && item.loading ? _object_spread_props(_object_spread({}, item), {
241
- content: 'Operation stopped',
289
+ if (playgroundSDK.onDumpUpdate) playgroundSDK.onDumpUpdate(()=>{});
290
+ setInfoList((prev)=>prev.map((item)=>item.id === `system-${thisRunningId}` ? _object_spread_props(_object_spread({}, item), {
291
+ content: '',
242
292
  loading: false,
243
293
  loadingProgressText: ''
244
294
  }) : item));
295
+ if (executionData && (executionData.dump || executionData.reportHTML)) {
296
+ const resultItem = {
297
+ id: `stop-result-${thisRunningId}`,
298
+ type: 'result',
299
+ content: 'Execution stopped by user',
300
+ timestamp: new Date(),
301
+ result: {
302
+ result: null,
303
+ dump: executionData.dump,
304
+ reportHTML: executionData.reportHTML,
305
+ error: null
306
+ },
307
+ loading: false,
308
+ verticalMode,
309
+ replayCounter
310
+ };
311
+ setInfoList((prev)=>[
312
+ ...prev,
313
+ resultItem
314
+ ]);
315
+ } else {
316
+ const stopItem = {
317
+ id: `stop-${thisRunningId}`,
318
+ type: 'system',
319
+ content: 'Operation stopped',
320
+ timestamp: new Date(),
321
+ loading: false
322
+ };
323
+ setInfoList((prev)=>[
324
+ ...prev,
325
+ stopItem
326
+ ]);
327
+ }
245
328
  const separatorItem = {
246
329
  id: `separator-${thisRunningId}`,
247
330
  type: 'separator',
@@ -260,7 +343,9 @@ function usePlaygroundExecution(playgroundSDK, storage, actionSpace, loading, se
260
343
  currentRunningIdRef,
261
344
  interruptedFlagRef,
262
345
  setLoading,
263
- setInfoList
346
+ setInfoList,
347
+ verticalMode,
348
+ replayCounter
264
349
  ]);
265
350
  const canStop = loading && !!currentRunningIdRef.current && !!playgroundSDK && !!playgroundSDK.cancelExecution;
266
351
  return {
package/dist/lib/index.js CHANGED
@@ -47,6 +47,7 @@ __webpack_require__.d(__webpack_exports__, {
47
47
  PlaygroundResultView: ()=>playground_result_index_js_namespaceObject.PlaygroundResultView,
48
48
  safeOverrideAIConfig: ()=>useSafeOverrideAIConfig_js_namespaceObject.safeOverrideAIConfig,
49
49
  highlightColorForType: ()=>color_js_namespaceObject.highlightColorForType,
50
+ useGlobalPreference: ()=>store_js_namespaceObject.useGlobalPreference,
50
51
  AgentContextProvider: ()=>context_provider_js_namespaceObject.AgentContextProvider,
51
52
  UniversalPlaygroundDefault: ()=>universal_playground_index_js_default(),
52
53
  actionNameForType: ()=>playground_utils_js_namespaceObject.actionNameForType,
@@ -142,6 +143,7 @@ exports.staticAgentFromContext = __webpack_exports__.staticAgentFromContext;
142
143
  exports.timeCostStrElement = __webpack_exports__.timeCostStrElement;
143
144
  exports.timeStr = __webpack_exports__.timeStr;
144
145
  exports.useEnvConfig = __webpack_exports__.useEnvConfig;
146
+ exports.useGlobalPreference = __webpack_exports__.useGlobalPreference;
145
147
  exports.useSafeOverrideAIConfig = __webpack_exports__.useSafeOverrideAIConfig;
146
148
  exports.useServerValid = __webpack_exports__.useServerValid;
147
149
  exports.useTheme = __webpack_exports__.useTheme;
@@ -185,6 +187,7 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
185
187
  "timeCostStrElement",
186
188
  "timeStr",
187
189
  "useEnvConfig",
190
+ "useGlobalPreference",
188
191
  "useSafeOverrideAIConfig",
189
192
  "useServerValid",
190
193
  "useTheme"
@@ -25,13 +25,15 @@ var __webpack_exports__ = {};
25
25
  __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
27
  useEnvConfig: ()=>useEnvConfig,
28
- useBlackboardPreference: ()=>useBlackboardPreference
28
+ useGlobalPreference: ()=>useGlobalPreference
29
29
  });
30
30
  const external_zustand_namespaceObject = require("zustand");
31
31
  const { create } = external_zustand_namespaceObject;
32
32
  const AUTO_ZOOM_KEY = 'midscene-auto-zoom';
33
33
  const BACKGROUND_VISIBLE_KEY = 'midscene-background-visible';
34
34
  const ELEMENTS_VISIBLE_KEY = 'midscene-elements-visible';
35
+ const MODEL_CALL_DETAILS_KEY = 'midscene-model-call-details';
36
+ const DARK_MODE_KEY = 'midscene-dark-mode';
35
37
  const parseBooleanParam = (value)=>{
36
38
  if (null === value) return;
37
39
  const normalized = value.trim().toLowerCase();
@@ -53,16 +55,23 @@ const getQueryPreference = (paramName)=>{
53
55
  const searchParams = new URLSearchParams(window.location.search);
54
56
  return parseBooleanParam(searchParams.get(paramName));
55
57
  };
56
- const useBlackboardPreference = create((set)=>{
58
+ const useGlobalPreference = create((set)=>{
57
59
  const savedAutoZoom = 'false' !== localStorage.getItem(AUTO_ZOOM_KEY);
58
60
  const savedBackgroundVisible = 'false' !== localStorage.getItem(BACKGROUND_VISIBLE_KEY);
59
61
  const savedElementsVisible = 'false' !== localStorage.getItem(ELEMENTS_VISIBLE_KEY);
62
+ const savedModelCallDetails = 'true' === localStorage.getItem(MODEL_CALL_DETAILS_KEY);
63
+ const savedDarkMode = 'true' === localStorage.getItem(DARK_MODE_KEY);
60
64
  const autoZoomFromQuery = getQueryPreference('focusOnCursor');
61
65
  const elementsVisibleFromQuery = getQueryPreference('showElementMarkers');
66
+ const darkModeFromQuery = getQueryPreference('darkMode');
67
+ const initialDarkMode = void 0 === darkModeFromQuery ? savedDarkMode : darkModeFromQuery;
68
+ if (void 0 !== darkModeFromQuery) localStorage.setItem(DARK_MODE_KEY, initialDarkMode.toString());
62
69
  return {
63
70
  backgroundVisible: savedBackgroundVisible,
64
71
  elementsVisible: void 0 === elementsVisibleFromQuery ? savedElementsVisible : elementsVisibleFromQuery,
65
72
  autoZoom: void 0 === autoZoomFromQuery ? savedAutoZoom : autoZoomFromQuery,
73
+ modelCallDetailsEnabled: savedModelCallDetails,
74
+ darkModeEnabled: initialDarkMode,
66
75
  setBackgroundVisible: (visible)=>{
67
76
  set({
68
77
  backgroundVisible: visible
@@ -80,6 +89,18 @@ const useBlackboardPreference = create((set)=>{
80
89
  autoZoom: enabled
81
90
  });
82
91
  localStorage.setItem(AUTO_ZOOM_KEY, enabled.toString());
92
+ },
93
+ setModelCallDetailsEnabled: (enabled)=>{
94
+ set({
95
+ modelCallDetailsEnabled: enabled
96
+ });
97
+ localStorage.setItem(MODEL_CALL_DETAILS_KEY, enabled.toString());
98
+ },
99
+ setDarkModeEnabled: (enabled)=>{
100
+ set({
101
+ darkModeEnabled: enabled
102
+ });
103
+ localStorage.setItem(DARK_MODE_KEY, enabled.toString());
83
104
  }
84
105
  };
85
106
  });
@@ -221,11 +242,11 @@ const useEnvConfig = create((set, get)=>{
221
242
  }
222
243
  };
223
244
  });
224
- exports.useBlackboardPreference = __webpack_exports__.useBlackboardPreference;
225
245
  exports.useEnvConfig = __webpack_exports__.useEnvConfig;
246
+ exports.useGlobalPreference = __webpack_exports__.useGlobalPreference;
226
247
  for(var __rspack_i in __webpack_exports__)if (-1 === [
227
- "useBlackboardPreference",
228
- "useEnvConfig"
248
+ "useEnvConfig",
249
+ "useGlobalPreference"
229
250
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
230
251
  Object.defineProperty(exports, '__esModule', {
231
252
  value: true
@@ -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 | null, storage: StorageProvider | undefined | null, 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 | null, actionSpace: DeviceAction<unknown>[], loading: boolean, setLoading: (loading: boolean) => void, 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;
@@ -1,5 +1,5 @@
1
1
  export { type AnimationScript, type ReplayScriptsInfo, allScriptsFromDump, generateAnimationScripts, } from './utils/replay-scripts';
2
- export { useEnvConfig } from './store/store';
2
+ export { useEnvConfig, useGlobalPreference } from './store/store';
3
3
  export { colorForName, highlightColorForType, globalThemeConfig, } from './utils/color';
4
4
  export { EnvConfig } from './component/env-config';
5
5
  export { EnvConfigReminder } from './component/env-config-reminder';