@midscene/visualizer 1.9.6 → 1.9.7

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.
@@ -27,6 +27,15 @@ const ConfigSelector = ({ showDeepLocateOption = false, showDeepThinkOption = fa
27
27
  const hasDeviceOptions = hasDeviceSpecificConfig(deviceType);
28
28
  if (!enableTracking && !showDeepLocateOption && !showDeepThinkOption && !showDataExtractionOptions && !hasDeviceOptions) return null;
29
29
  const configItems = buildConfigItems();
30
+ const dropdownTrigger = null != trigger ? trigger : /*#__PURE__*/ jsx("button", {
31
+ "aria-label": "Open run configuration",
32
+ className: "selector-trigger-button",
33
+ type: "button",
34
+ children: /*#__PURE__*/ jsx(setting, {
35
+ width: 24,
36
+ height: 24
37
+ })
38
+ });
30
39
  return /*#__PURE__*/ jsx("div", {
31
40
  className: "selector-trigger",
32
41
  children: /*#__PURE__*/ jsx(Dropdown, {
@@ -42,10 +51,7 @@ const ConfigSelector = ({ showDeepLocateOption = false, showDeepThinkOption = fa
42
51
  trigger: [
43
52
  'click'
44
53
  ],
45
- children: null != trigger ? trigger : /*#__PURE__*/ jsx(setting, {
46
- width: 24,
47
- height: 24
48
- })
54
+ children: dropdownTrigger
49
55
  })
50
56
  });
51
57
  function buildConfigItems() {
@@ -1,6 +1,6 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { SettingOutlined } from "@ant-design/icons";
3
- import { Alert, Button, Input, Modal, Tooltip, message } from "antd";
3
+ import { Alert, App, Button, Input, Modal, Tooltip } from "antd";
4
4
  import { useEffect, useRef, useState } from "react";
5
5
  import { useEnvConfig } from "../../store/store.mjs";
6
6
  import { notifyError } from "../../utils/index.mjs";
@@ -31,6 +31,7 @@ function _async_to_generator(fn) {
31
31
  };
32
32
  }
33
33
  function EnvConfig({ showTooltipWhenEmpty = true, showModelName = true, tooltipPlacement = 'bottom', mode = 'icon', playgroundSDK }) {
34
+ const { message } = App.useApp();
34
35
  const { config, configString, loadConfig, syncFromStorage } = useEnvConfig();
35
36
  const [isModalOpen, setIsModalOpen] = useState(false);
36
37
  const [tempConfigString, setTempConfigString] = useState(configString);
@@ -3,7 +3,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
4
4
  import "./index.css";
5
5
  import { CaretRightOutlined, CompressOutlined, DownloadOutlined, ExpandOutlined, ExportOutlined, FontSizeOutlined, PauseOutlined, ThunderboltOutlined } from "@ant-design/icons";
6
- import { Button, Dropdown, Progress, Switch, Tooltip, message } from "antd";
6
+ import { App, Button, Dropdown, Progress, Switch, Tooltip } 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";
@@ -64,6 +64,7 @@ function formatTime(frame, fps) {
64
64
  return `${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`;
65
65
  }
66
66
  function Player(props) {
67
+ const { message } = App.useApp();
67
68
  const { autoZoom, setAutoZoom, playbackSpeed, setPlaybackSpeed, subtitleEnabled, setSubtitleEnabled } = useGlobalPreference();
68
69
  useEffect(()=>{
69
70
  if ((null == props ? void 0 : props.autoZoom) !== void 0) setAutoZoom(props.autoZoom);
@@ -551,6 +551,19 @@
551
551
  transition: all .2s;
552
552
  }
553
553
 
554
+ .selector-trigger .selector-trigger-button {
555
+ cursor: pointer;
556
+ width: 24px;
557
+ height: 24px;
558
+ color: inherit;
559
+ background: none;
560
+ border: none;
561
+ justify-content: center;
562
+ align-items: center;
563
+ padding: 0;
564
+ display: inline-flex;
565
+ }
566
+
554
567
  .selector-trigger .action-icon {
555
568
  color: rgba(0, 0, 0, .85);
556
569
  font-size: 14px;
@@ -459,6 +459,19 @@
459
459
  transition: all .2s;
460
460
  }
461
461
 
462
+ .selector-trigger .selector-trigger-button {
463
+ cursor: pointer;
464
+ width: 24px;
465
+ height: 24px;
466
+ color: inherit;
467
+ background: none;
468
+ border: none;
469
+ justify-content: center;
470
+ align-items: center;
471
+ padding: 0;
472
+ display: inline-flex;
473
+ }
474
+
462
475
  .selector-trigger .action-icon {
463
476
  color: rgba(0, 0, 0, .85);
464
477
  font-size: 14px;
@@ -46,6 +46,29 @@ function _async_to_generator(fn) {
46
46
  });
47
47
  };
48
48
  }
49
+ function _define_property(obj, key, value) {
50
+ if (key in obj) Object.defineProperty(obj, key, {
51
+ value: value,
52
+ enumerable: true,
53
+ configurable: true,
54
+ writable: true
55
+ });
56
+ else obj[key] = value;
57
+ return obj;
58
+ }
59
+ function _object_spread(target) {
60
+ for(var i = 1; i < arguments.length; i++){
61
+ var source = null != arguments[i] ? arguments[i] : {};
62
+ var ownKeys = Object.keys(source);
63
+ if ("function" == typeof Object.getOwnPropertySymbols) ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
64
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
65
+ }));
66
+ ownKeys.forEach(function(key) {
67
+ _define_property(target, key, source[key]);
68
+ });
69
+ }
70
+ return target;
71
+ }
49
72
  const { Text } = Typography;
50
73
  const handledExternalRunRequestIds = new Set();
51
74
  const MAX_HANDLED_EXTERNAL_RUN_REQUEST_IDS = 100;
@@ -73,13 +96,6 @@ function UniversalPlayground({ playgroundSDK, storage, contextProvider, config:
73
96
  const { config } = useEnvConfig();
74
97
  const [sdkReady, setSdkReady] = useState(false);
75
98
  const lastExternalRunRequestIdRef = useRef(null);
76
- useEffect(()=>{
77
- form.setFieldsValue({
78
- type: defaultMainButtons["0"]
79
- });
80
- }, [
81
- form
82
- ]);
83
99
  useEffect(()=>{
84
100
  const initializeSDK = ()=>_async_to_generator(function*() {
85
101
  if (playgroundSDK && 'function' == typeof playgroundSDK.checkStatus) try {
@@ -164,9 +180,11 @@ function UniversalPlayground({ playgroundSDK, storage, contextProvider, config:
164
180
  const oldestRequestId = handledExternalRunRequestIds.values().next().value;
165
181
  if (oldestRequestId) handledExternalRunRequestIds.delete(oldestRequestId);
166
182
  }
167
- executeAction(request.value, {
183
+ executeAction(request.value, _object_spread({
168
184
  displayContent: request.displayContent
169
- }).catch((error)=>{
185
+ }, request.reportDisplay ? {
186
+ reportDisplay: request.reportDisplay
187
+ } : {})).catch((error)=>{
170
188
  notifyError(error, {
171
189
  title: 'Execution failed'
172
190
  });
@@ -180,7 +198,7 @@ function UniversalPlayground({ playgroundSDK, storage, contextProvider, config:
180
198
  const configAlreadySet = Object.keys(config || {}).length >= 1;
181
199
  const runButtonEnabled = componentConfig.serverMode || !dryMode && !actionSpaceLoading && configAlreadySet;
182
200
  const watchedType = Form.useWatch('type', form);
183
- const selectedType = watchedType || form.getFieldValue('type');
201
+ const selectedType = watchedType || defaultMainButtons["0"];
184
202
  const serviceMode = useMemo(()=>{
185
203
  if (!playgroundSDK || 'function' != typeof playgroundSDK.getServiceMode) return 'Server';
186
204
  return playgroundSDK.getServiceMode();
@@ -289,6 +307,9 @@ function UniversalPlayground({ playgroundSDK, storage, contextProvider, config:
289
307
  form: form,
290
308
  onFinish: handleFormRun,
291
309
  className: "command-form",
310
+ initialValues: {
311
+ type: defaultMainButtons["0"]
312
+ },
292
313
  children: [
293
314
  finalShowContextPreview && /*#__PURE__*/ jsx("div", {
294
315
  className: "context-preview-section",
@@ -67,6 +67,9 @@ function _object_spread_props(target, source) {
67
67
  });
68
68
  return target;
69
69
  }
70
+ function isReportActionDump(dump) {
71
+ return Array.isArray(null == dump ? void 0 : dump.executions);
72
+ }
70
73
  const DB_NAME = 'midscene_playground';
71
74
  const DB_VERSION = 1;
72
75
  const MESSAGES_STORE = 'playground_messages';
@@ -152,9 +155,29 @@ class IndexedDBStorageProvider {
152
155
  }).call(this);
153
156
  }
154
157
  compressResultForStorage(result) {
155
- var _result_result_dump, _result_result;
156
- if (!(null == (_result_result = result.result) ? void 0 : null == (_result_result_dump = _result_result.dump) ? void 0 : _result_result_dump.tasks)) return result;
157
- const compressedTasks = result.result.dump.tasks.map((task)=>{
158
+ const playgroundResult = result.result;
159
+ const dump = null == playgroundResult ? void 0 : playgroundResult.dump;
160
+ if (!playgroundResult || !dump) return result;
161
+ if (isReportActionDump(dump)) return _object_spread_props(_object_spread({}, result), {
162
+ result: _object_spread_props(_object_spread({}, playgroundResult), {
163
+ dump: _object_spread_props(_object_spread({}, dump), {
164
+ executions: dump.executions.map((execution)=>_object_spread_props(_object_spread({}, execution), {
165
+ tasks: this.compressExecutionTasks(execution.tasks)
166
+ }))
167
+ })
168
+ })
169
+ });
170
+ if (!dump.tasks) return result;
171
+ return _object_spread_props(_object_spread({}, result), {
172
+ result: _object_spread_props(_object_spread({}, playgroundResult), {
173
+ dump: _object_spread_props(_object_spread({}, dump), {
174
+ tasks: this.compressExecutionTasks(dump.tasks)
175
+ })
176
+ })
177
+ });
178
+ }
179
+ compressExecutionTasks(tasks) {
180
+ return tasks.map((task)=>{
158
181
  var _task_recorder;
159
182
  return _object_spread_props(_object_spread({}, task), {
160
183
  uiContext: task.uiContext ? _object_spread_props(_object_spread({}, task.uiContext), {
@@ -165,13 +188,6 @@ class IndexedDBStorageProvider {
165
188
  }))
166
189
  });
167
190
  });
168
- return _object_spread_props(_object_spread({}, result), {
169
- result: _object_spread_props(_object_spread({}, result.result), {
170
- dump: _object_spread_props(_object_spread({}, result.result.dump), {
171
- tasks: compressedTasks
172
- })
173
- })
174
- });
175
191
  }
176
192
  compressScreenshotIfNeeded(screenshot) {
177
193
  if (!screenshot) return screenshot;
@@ -99,6 +99,15 @@ function wrapExecutionDumpForReplay(dump, deviceType) {
99
99
  deviceType
100
100
  };
101
101
  }
102
+ function isReportActionDump(dump) {
103
+ return Array.isArray(null == dump ? void 0 : dump.executions);
104
+ }
105
+ function replayInfoFromDump(dump, deviceType) {
106
+ if (!dump) return null;
107
+ if (isReportActionDump(dump)) return allScriptsFromDump(dump);
108
+ if (dump.tasks && Array.isArray(dump.tasks)) return allScriptsFromDump(wrapExecutionDumpForReplay(dump, deviceType));
109
+ return null;
110
+ }
102
111
  function shouldForwardDeepThink(actionType) {
103
112
  return 'aiAct' === actionType || 'runMarkdown' === actionType;
104
113
  }
@@ -170,7 +179,7 @@ function usePlaygroundExecution(options) {
170
179
  requestId: thisRunningId.toString()
171
180
  });
172
181
  const resolvedDeepThink = 'unset' === deepThink ? void 0 : deepThink;
173
- const executionOptions = _object_spread_props(_object_spread({
182
+ const executionOptions = _object_spread(_object_spread_props(_object_spread({
174
183
  requestId: thisRunningId.toString(),
175
184
  deepLocate
176
185
  }, shouldForwardDeepThink(actionType) && void 0 !== resolvedDeepThink ? {
@@ -184,7 +193,9 @@ function usePlaygroundExecution(options) {
184
193
  keyboardDismissStrategy,
185
194
  alwaysRefreshScreenInfo
186
195
  }
187
- });
196
+ }), runOptions.reportDisplay ? {
197
+ reportDisplay: runOptions.reportDisplay
198
+ } : {});
188
199
  result.result = yield playgroundSDK.executeAction(actionType, value, executionOptions);
189
200
  if ('object' == typeof result.result && null !== result.result) {
190
201
  const resultObj = result.result;
@@ -207,9 +218,8 @@ function usePlaygroundExecution(options) {
207
218
  let replayInfo = null;
208
219
  let counter = replayCounter;
209
220
  if (null == result ? void 0 : result.dump) {
210
- if (result.dump.tasks && Array.isArray(result.dump.tasks)) {
211
- const groupedDump = wrapExecutionDumpForReplay(result.dump, deviceType);
212
- const info = allScriptsFromDump(groupedDump);
221
+ const info = replayInfoFromDump(result.dump, deviceType);
222
+ if (info) {
213
223
  setReplayCounter((c)=>c + 1);
214
224
  replayInfo = info;
215
225
  counter = replayCounter + 1;
@@ -294,12 +304,10 @@ function usePlaygroundExecution(options) {
294
304
  loadingProgressText: ''
295
305
  }) : item));
296
306
  if (executionData && (executionData.dump || executionData.reportHTML)) {
297
- var _executionData_dump;
298
307
  let replayInfo = null;
299
308
  let counter = replayCounter;
300
- if ((null == (_executionData_dump = executionData.dump) ? void 0 : _executionData_dump.tasks) && Array.isArray(executionData.dump.tasks)) {
301
- const groupedDump = wrapExecutionDumpForReplay(executionData.dump, deviceType);
302
- replayInfo = allScriptsFromDump(groupedDump);
309
+ replayInfo = replayInfoFromDump(executionData.dump, deviceType);
310
+ if (replayInfo) {
303
311
  setReplayCounter((c)=>c + 1);
304
312
  counter = replayCounter + 1;
305
313
  }
@@ -110,13 +110,21 @@ const normalizeDump = (dump)=>{
110
110
  ]
111
111
  };
112
112
  };
113
+ const sortExecutionsByLogTime = (executions)=>executions.map((execution, index)=>({
114
+ execution,
115
+ index
116
+ })).sort((left, right)=>{
117
+ const leftTime = Number.isFinite(left.execution.logTime) ? left.execution.logTime : 1 / 0;
118
+ const rightTime = Number.isFinite(right.execution.logTime) ? right.execution.logTime : 1 / 0;
119
+ return leftTime - rightTime || left.index - right.index;
120
+ }).map(({ execution })=>execution);
113
121
  const extractMetaFromNormalized = (normalizedDump)=>{
114
122
  var _normalizedDump_executions;
115
123
  let firstWidth;
116
124
  let firstHeight;
117
125
  const sdkVersion = normalizedDump.sdkVersion;
118
126
  const modelBriefs = [];
119
- null == (_normalizedDump_executions = normalizedDump.executions) || _normalizedDump_executions.filter(Boolean).forEach((execution)=>{
127
+ sortExecutionsByLogTime((null == (_normalizedDump_executions = normalizedDump.executions) ? void 0 : _normalizedDump_executions.filter(Boolean)) || []).forEach((execution)=>{
120
128
  execution.tasks.forEach((task)=>{
121
129
  var _task_uiContext;
122
130
  const shotSize = null == (_task_uiContext = task.uiContext) ? void 0 : _task_uiContext.shotSize;
@@ -174,7 +182,7 @@ const allScriptsFromDump = (dump)=>{
174
182
  };
175
183
  const { width: firstWidth, height: firstHeight } = metaInfo;
176
184
  const allScripts = [];
177
- const executions = (null == (_normalizedDump_executions = normalizedDump.executions) ? void 0 : _normalizedDump_executions.filter(Boolean)) || [];
185
+ const executions = sortExecutionsByLogTime((null == (_normalizedDump_executions = normalizedDump.executions) ? void 0 : _normalizedDump_executions.filter(Boolean)) || []);
178
186
  for(let execIndex = 0; execIndex < executions.length; execIndex++){
179
187
  const execution = executions[execIndex];
180
188
  const scripts = generateAnimationScripts(execution, -1, firstWidth, firstHeight, execIndex);
@@ -65,6 +65,15 @@ const ConfigSelector = ({ showDeepLocateOption = false, showDeepThinkOption = fa
65
65
  const hasDeviceOptions = (0, device_capabilities_js_namespaceObject.hasDeviceSpecificConfig)(deviceType);
66
66
  if (!enableTracking && !showDeepLocateOption && !showDeepThinkOption && !showDataExtractionOptions && !hasDeviceOptions) return null;
67
67
  const configItems = buildConfigItems();
68
+ const dropdownTrigger = null != trigger ? trigger : /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("button", {
69
+ "aria-label": "Open run configuration",
70
+ className: "selector-trigger-button",
71
+ type: "button",
72
+ children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(setting_js_default(), {
73
+ width: 24,
74
+ height: 24
75
+ })
76
+ });
68
77
  return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
69
78
  className: "selector-trigger",
70
79
  children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_antd_namespaceObject.Dropdown, {
@@ -80,10 +89,7 @@ const ConfigSelector = ({ showDeepLocateOption = false, showDeepThinkOption = fa
80
89
  trigger: [
81
90
  'click'
82
91
  ],
83
- children: null != trigger ? trigger : /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(setting_js_default(), {
84
- width: 24,
85
- height: 24
86
- })
92
+ children: dropdownTrigger
87
93
  })
88
94
  });
89
95
  function buildConfigItems() {
@@ -59,6 +59,7 @@ function _async_to_generator(fn) {
59
59
  };
60
60
  }
61
61
  function EnvConfig({ showTooltipWhenEmpty = true, showModelName = true, tooltipPlacement = 'bottom', mode = 'icon', playgroundSDK }) {
62
+ const { message } = external_antd_namespaceObject.App.useApp();
62
63
  const { config, configString, loadConfig, syncFromStorage } = (0, store_js_namespaceObject.useEnvConfig)();
63
64
  const [isModalOpen, setIsModalOpen] = (0, external_react_namespaceObject.useState)(false);
64
65
  const [tempConfigString, setTempConfigString] = (0, external_react_namespaceObject.useState)(configString);
@@ -98,13 +99,13 @@ function EnvConfig({ showTooltipWhenEmpty = true, showModelName = true, tooltipP
98
99
  const result = yield sdk.runConnectivityTest();
99
100
  setConnectivityResult(result);
100
101
  if (result.passed) {
101
- external_antd_namespaceObject.message.success('Model verification passed');
102
+ message.success('Model verification passed');
102
103
  clearCloseTimer();
103
104
  closeTimerRef.current = window.setTimeout(()=>{
104
105
  setIsModalOpen(false);
105
106
  closeTimerRef.current = null;
106
107
  }, 2000);
107
- } else external_antd_namespaceObject.message.warning('Model verification found issues');
108
+ } else message.warning('Model verification found issues');
108
109
  } catch (error) {
109
110
  const errorMessage = error instanceof Error ? error.message : String(error);
110
111
  (0, index_js_namespaceObject.notifyError)(error, {
@@ -103,6 +103,7 @@ function formatTime(frame, fps) {
103
103
  return `${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`;
104
104
  }
105
105
  function Player(props) {
106
+ const { message } = external_antd_namespaceObject.App.useApp();
106
107
  const { autoZoom, setAutoZoom, playbackSpeed, setPlaybackSpeed, subtitleEnabled, setSubtitleEnabled } = (0, store_js_namespaceObject.useGlobalPreference)();
107
108
  (0, external_react_namespaceObject.useEffect)(()=>{
108
109
  if ((null == props ? void 0 : props.autoZoom) !== void 0) setAutoZoom(props.autoZoom);
@@ -331,7 +332,7 @@ function Player(props) {
331
332
  yield (0, export_branded_video_js_namespaceObject.exportBrandedVideo)(frameMap, {
332
333
  autoZoom
333
334
  }, (pct)=>setExportProgress(Math.round(100 * pct)));
334
- external_antd_namespaceObject.message.success('Video exported');
335
+ message.success('Video exported');
335
336
  } catch (e) {
336
337
  console.error('Export failed:', e);
337
338
  (0, index_js_namespaceObject.notifyError)(e, {
@@ -551,6 +551,19 @@
551
551
  transition: all .2s;
552
552
  }
553
553
 
554
+ .selector-trigger .selector-trigger-button {
555
+ cursor: pointer;
556
+ width: 24px;
557
+ height: 24px;
558
+ color: inherit;
559
+ background: none;
560
+ border: none;
561
+ justify-content: center;
562
+ align-items: center;
563
+ padding: 0;
564
+ display: inline-flex;
565
+ }
566
+
554
567
  .selector-trigger .action-icon {
555
568
  color: rgba(0, 0, 0, .85);
556
569
  font-size: 14px;
@@ -459,6 +459,19 @@
459
459
  transition: all .2s;
460
460
  }
461
461
 
462
+ .selector-trigger .selector-trigger-button {
463
+ cursor: pointer;
464
+ width: 24px;
465
+ height: 24px;
466
+ color: inherit;
467
+ background: none;
468
+ border: none;
469
+ justify-content: center;
470
+ align-items: center;
471
+ padding: 0;
472
+ display: inline-flex;
473
+ }
474
+
462
475
  .selector-trigger .action-icon {
463
476
  color: rgba(0, 0, 0, .85);
464
477
  font-size: 14px;
@@ -87,6 +87,29 @@ function _async_to_generator(fn) {
87
87
  });
88
88
  };
89
89
  }
90
+ function _define_property(obj, key, value) {
91
+ if (key in obj) Object.defineProperty(obj, key, {
92
+ value: value,
93
+ enumerable: true,
94
+ configurable: true,
95
+ writable: true
96
+ });
97
+ else obj[key] = value;
98
+ return obj;
99
+ }
100
+ function _object_spread(target) {
101
+ for(var i = 1; i < arguments.length; i++){
102
+ var source = null != arguments[i] ? arguments[i] : {};
103
+ var ownKeys = Object.keys(source);
104
+ if ("function" == typeof Object.getOwnPropertySymbols) ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
105
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
106
+ }));
107
+ ownKeys.forEach(function(key) {
108
+ _define_property(target, key, source[key]);
109
+ });
110
+ }
111
+ return target;
112
+ }
90
113
  const { Text } = external_antd_namespaceObject.Typography;
91
114
  const handledExternalRunRequestIds = new Set();
92
115
  const MAX_HANDLED_EXTERNAL_RUN_REQUEST_IDS = 100;
@@ -114,13 +137,6 @@ function UniversalPlayground({ playgroundSDK, storage, contextProvider, config:
114
137
  const { config } = (0, store_js_namespaceObject.useEnvConfig)();
115
138
  const [sdkReady, setSdkReady] = (0, external_react_namespaceObject.useState)(false);
116
139
  const lastExternalRunRequestIdRef = (0, external_react_namespaceObject.useRef)(null);
117
- (0, external_react_namespaceObject.useEffect)(()=>{
118
- form.setFieldsValue({
119
- type: constants_js_namespaceObject.defaultMainButtons["0"]
120
- });
121
- }, [
122
- form
123
- ]);
124
140
  (0, external_react_namespaceObject.useEffect)(()=>{
125
141
  const initializeSDK = ()=>_async_to_generator(function*() {
126
142
  if (playgroundSDK && 'function' == typeof playgroundSDK.checkStatus) try {
@@ -205,9 +221,11 @@ function UniversalPlayground({ playgroundSDK, storage, contextProvider, config:
205
221
  const oldestRequestId = handledExternalRunRequestIds.values().next().value;
206
222
  if (oldestRequestId) handledExternalRunRequestIds.delete(oldestRequestId);
207
223
  }
208
- executeAction(request.value, {
224
+ executeAction(request.value, _object_spread({
209
225
  displayContent: request.displayContent
210
- }).catch((error)=>{
226
+ }, request.reportDisplay ? {
227
+ reportDisplay: request.reportDisplay
228
+ } : {})).catch((error)=>{
211
229
  (0, index_js_namespaceObject.notifyError)(error, {
212
230
  title: 'Execution failed'
213
231
  });
@@ -221,7 +239,7 @@ function UniversalPlayground({ playgroundSDK, storage, contextProvider, config:
221
239
  const configAlreadySet = Object.keys(config || {}).length >= 1;
222
240
  const runButtonEnabled = componentConfig.serverMode || !dryMode && !actionSpaceLoading && configAlreadySet;
223
241
  const watchedType = external_antd_namespaceObject.Form.useWatch('type', form);
224
- const selectedType = watchedType || form.getFieldValue('type');
242
+ const selectedType = watchedType || constants_js_namespaceObject.defaultMainButtons["0"];
225
243
  const serviceMode = (0, external_react_namespaceObject.useMemo)(()=>{
226
244
  if (!playgroundSDK || 'function' != typeof playgroundSDK.getServiceMode) return 'Server';
227
245
  return playgroundSDK.getServiceMode();
@@ -330,6 +348,9 @@ function UniversalPlayground({ playgroundSDK, storage, contextProvider, config:
330
348
  form: form,
331
349
  onFinish: handleFormRun,
332
350
  className: "command-form",
351
+ initialValues: {
352
+ type: constants_js_namespaceObject.defaultMainButtons["0"]
353
+ },
333
354
  children: [
334
355
  finalShowContextPreview && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
335
356
  className: "context-preview-section",
@@ -97,6 +97,9 @@ function _object_spread_props(target, source) {
97
97
  });
98
98
  return target;
99
99
  }
100
+ function isReportActionDump(dump) {
101
+ return Array.isArray(null == dump ? void 0 : dump.executions);
102
+ }
100
103
  const DB_NAME = 'midscene_playground';
101
104
  const DB_VERSION = 1;
102
105
  const MESSAGES_STORE = 'playground_messages';
@@ -182,9 +185,29 @@ class IndexedDBStorageProvider {
182
185
  }).call(this);
183
186
  }
184
187
  compressResultForStorage(result) {
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.tasks)) return result;
187
- const compressedTasks = result.result.dump.tasks.map((task)=>{
188
+ const playgroundResult = result.result;
189
+ const dump = null == playgroundResult ? void 0 : playgroundResult.dump;
190
+ if (!playgroundResult || !dump) return result;
191
+ if (isReportActionDump(dump)) return _object_spread_props(_object_spread({}, result), {
192
+ result: _object_spread_props(_object_spread({}, playgroundResult), {
193
+ dump: _object_spread_props(_object_spread({}, dump), {
194
+ executions: dump.executions.map((execution)=>_object_spread_props(_object_spread({}, execution), {
195
+ tasks: this.compressExecutionTasks(execution.tasks)
196
+ }))
197
+ })
198
+ })
199
+ });
200
+ if (!dump.tasks) return result;
201
+ return _object_spread_props(_object_spread({}, result), {
202
+ result: _object_spread_props(_object_spread({}, playgroundResult), {
203
+ dump: _object_spread_props(_object_spread({}, dump), {
204
+ tasks: this.compressExecutionTasks(dump.tasks)
205
+ })
206
+ })
207
+ });
208
+ }
209
+ compressExecutionTasks(tasks) {
210
+ return tasks.map((task)=>{
188
211
  var _task_recorder;
189
212
  return _object_spread_props(_object_spread({}, task), {
190
213
  uiContext: task.uiContext ? _object_spread_props(_object_spread({}, task.uiContext), {
@@ -195,13 +218,6 @@ class IndexedDBStorageProvider {
195
218
  }))
196
219
  });
197
220
  });
198
- return _object_spread_props(_object_spread({}, result), {
199
- result: _object_spread_props(_object_spread({}, result.result), {
200
- dump: _object_spread_props(_object_spread({}, result.result.dump), {
201
- tasks: compressedTasks
202
- })
203
- })
204
- });
205
221
  }
206
222
  compressScreenshotIfNeeded(screenshot) {
207
223
  if (!screenshot) return screenshot;
@@ -127,6 +127,15 @@ function wrapExecutionDumpForReplay(dump, deviceType) {
127
127
  deviceType
128
128
  };
129
129
  }
130
+ function isReportActionDump(dump) {
131
+ return Array.isArray(null == dump ? void 0 : dump.executions);
132
+ }
133
+ function replayInfoFromDump(dump, deviceType) {
134
+ if (!dump) return null;
135
+ if (isReportActionDump(dump)) return (0, replay_scripts_js_namespaceObject.allScriptsFromDump)(dump);
136
+ if (dump.tasks && Array.isArray(dump.tasks)) return (0, replay_scripts_js_namespaceObject.allScriptsFromDump)(wrapExecutionDumpForReplay(dump, deviceType));
137
+ return null;
138
+ }
130
139
  function shouldForwardDeepThink(actionType) {
131
140
  return 'aiAct' === actionType || 'runMarkdown' === actionType;
132
141
  }
@@ -198,7 +207,7 @@ function usePlaygroundExecution(options) {
198
207
  requestId: thisRunningId.toString()
199
208
  });
200
209
  const resolvedDeepThink = 'unset' === deepThink ? void 0 : deepThink;
201
- const executionOptions = _object_spread_props(_object_spread({
210
+ const executionOptions = _object_spread(_object_spread_props(_object_spread({
202
211
  requestId: thisRunningId.toString(),
203
212
  deepLocate
204
213
  }, shouldForwardDeepThink(actionType) && void 0 !== resolvedDeepThink ? {
@@ -212,7 +221,9 @@ function usePlaygroundExecution(options) {
212
221
  keyboardDismissStrategy,
213
222
  alwaysRefreshScreenInfo
214
223
  }
215
- });
224
+ }), runOptions.reportDisplay ? {
225
+ reportDisplay: runOptions.reportDisplay
226
+ } : {});
216
227
  result.result = yield playgroundSDK.executeAction(actionType, value, executionOptions);
217
228
  if ('object' == typeof result.result && null !== result.result) {
218
229
  const resultObj = result.result;
@@ -235,9 +246,8 @@ function usePlaygroundExecution(options) {
235
246
  let replayInfo = null;
236
247
  let counter = replayCounter;
237
248
  if (null == result ? void 0 : result.dump) {
238
- if (result.dump.tasks && Array.isArray(result.dump.tasks)) {
239
- const groupedDump = wrapExecutionDumpForReplay(result.dump, deviceType);
240
- const info = (0, replay_scripts_js_namespaceObject.allScriptsFromDump)(groupedDump);
249
+ const info = replayInfoFromDump(result.dump, deviceType);
250
+ if (info) {
241
251
  setReplayCounter((c)=>c + 1);
242
252
  replayInfo = info;
243
253
  counter = replayCounter + 1;
@@ -322,12 +332,10 @@ function usePlaygroundExecution(options) {
322
332
  loadingProgressText: ''
323
333
  }) : item));
324
334
  if (executionData && (executionData.dump || executionData.reportHTML)) {
325
- var _executionData_dump;
326
335
  let replayInfo = null;
327
336
  let counter = replayCounter;
328
- if ((null == (_executionData_dump = executionData.dump) ? void 0 : _executionData_dump.tasks) && Array.isArray(executionData.dump.tasks)) {
329
- const groupedDump = wrapExecutionDumpForReplay(executionData.dump, deviceType);
330
- replayInfo = (0, replay_scripts_js_namespaceObject.allScriptsFromDump)(groupedDump);
337
+ replayInfo = replayInfoFromDump(executionData.dump, deviceType);
338
+ if (replayInfo) {
331
339
  setReplayCounter((c)=>c + 1);
332
340
  counter = replayCounter + 1;
333
341
  }
@@ -142,13 +142,21 @@ const normalizeDump = (dump)=>{
142
142
  ]
143
143
  };
144
144
  };
145
+ const sortExecutionsByLogTime = (executions)=>executions.map((execution, index)=>({
146
+ execution,
147
+ index
148
+ })).sort((left, right)=>{
149
+ const leftTime = Number.isFinite(left.execution.logTime) ? left.execution.logTime : 1 / 0;
150
+ const rightTime = Number.isFinite(right.execution.logTime) ? right.execution.logTime : 1 / 0;
151
+ return leftTime - rightTime || left.index - right.index;
152
+ }).map(({ execution })=>execution);
145
153
  const extractMetaFromNormalized = (normalizedDump)=>{
146
154
  var _normalizedDump_executions;
147
155
  let firstWidth;
148
156
  let firstHeight;
149
157
  const sdkVersion = normalizedDump.sdkVersion;
150
158
  const modelBriefs = [];
151
- null == (_normalizedDump_executions = normalizedDump.executions) || _normalizedDump_executions.filter(Boolean).forEach((execution)=>{
159
+ sortExecutionsByLogTime((null == (_normalizedDump_executions = normalizedDump.executions) ? void 0 : _normalizedDump_executions.filter(Boolean)) || []).forEach((execution)=>{
152
160
  execution.tasks.forEach((task)=>{
153
161
  var _task_uiContext;
154
162
  const shotSize = null == (_task_uiContext = task.uiContext) ? void 0 : _task_uiContext.shotSize;
@@ -206,7 +214,7 @@ const allScriptsFromDump = (dump)=>{
206
214
  };
207
215
  const { width: firstWidth, height: firstHeight } = metaInfo;
208
216
  const allScripts = [];
209
- const executions = (null == (_normalizedDump_executions = normalizedDump.executions) ? void 0 : _normalizedDump_executions.filter(Boolean)) || [];
217
+ const executions = sortExecutionsByLogTime((null == (_normalizedDump_executions = normalizedDump.executions) ? void 0 : _normalizedDump_executions.filter(Boolean)) || []);
210
218
  for(let execIndex = 0; execIndex < executions.length; execIndex++){
211
219
  const execution = executions[execIndex];
212
220
  const scripts = generateAnimationScripts(execution, -1, firstWidth, firstHeight, execIndex);
@@ -33,6 +33,7 @@ export declare class IndexedDBStorageProvider implements StorageProvider {
33
33
  * Compress result data for storage while preserving playback functionality
34
34
  */
35
35
  private compressResultForStorage;
36
+ private compressExecutionTasks;
36
37
  /**
37
38
  * Compress screenshot if it exceeds size threshold
38
39
  */
@@ -1,5 +1,5 @@
1
1
  import type { DeviceAction } from '@midscene/core';
2
- import type { FormValue, InfoListItem, PlaygroundSDKLike, StorageProvider } from '../types';
2
+ import type { ExecutionReportDisplay, FormValue, InfoListItem, PlaygroundSDKLike, StorageProvider } from '../types';
3
3
  export interface UsePlaygroundExecutionOptions {
4
4
  playgroundSDK: PlaygroundSDKLike | null;
5
5
  storage: StorageProvider | undefined | null;
@@ -16,6 +16,7 @@ export interface UsePlaygroundExecutionOptions {
16
16
  }
17
17
  export interface RunActionOptions {
18
18
  displayContent?: string;
19
+ reportDisplay?: ExecutionReportDisplay;
19
20
  }
20
21
  /**
21
22
  * Hook for handling playground execution logic
@@ -72,11 +72,11 @@ export declare const unwrapZodType: (field: ZodType) => {
72
72
  hasDefault: boolean;
73
73
  };
74
74
  export declare const extractDefaultValue: (field: ZodType) => unknown;
75
- import type { ExecutionDump, IExecutionDump } from '@midscene/core';
75
+ import type { ExecutionDump, IExecutionDump, IReportActionDump } from '@midscene/core';
76
76
  import type { BeforeActionHook, ExecutionOptions, PlaygroundAgent, PlaygroundRuntimeInfo } from '@midscene/playground';
77
77
  export interface PlaygroundResult {
78
78
  result: any;
79
- dump?: ExecutionDump | IExecutionDump | null;
79
+ dump?: ExecutionDump | IExecutionDump | IReportActionDump | null;
80
80
  reportHTML?: string | null;
81
81
  error: string | null;
82
82
  }
@@ -105,10 +105,15 @@ export interface FormValue {
105
105
  prompt?: string;
106
106
  params?: Record<string, unknown>;
107
107
  }
108
+ export interface ExecutionReportDisplay {
109
+ type?: string;
110
+ prompt?: string;
111
+ }
108
112
  export interface ExternalRunRequest {
109
113
  id: string;
110
114
  value: FormValue;
111
115
  displayContent?: string;
116
+ reportDisplay?: ExecutionReportDisplay;
112
117
  }
113
118
  export type { ExecutionOptions };
114
119
  export type ProgressCallback = (step: string, status?: 'loading' | 'completed' | 'error') => void;
@@ -118,11 +123,11 @@ export interface PlaygroundSDKLike {
118
123
  onProgressUpdate?: (callback: ProgressCallback) => void;
119
124
  onDumpUpdate?: (callback: (dump: string, executionDump?: ExecutionDump) => void) => void;
120
125
  cancelExecution?(requestId: string): Promise<{
121
- dump: ExecutionDump | null;
126
+ dump: ExecutionDump | IExecutionDump | IReportActionDump | null;
122
127
  reportHTML: string | null;
123
128
  } | null>;
124
129
  getCurrentExecutionData?(): Promise<{
125
- dump: ExecutionDump | null;
130
+ dump: ExecutionDump | IExecutionDump | IReportActionDump | null;
126
131
  reportHTML: string | null;
127
132
  }>;
128
133
  overrideConfig?(config: any): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@midscene/visualizer",
3
- "version": "1.9.6",
3
+ "version": "1.9.7",
4
4
  "repository": "https://github.com/web-infra-dev/midscene",
5
5
  "homepage": "https://midscenejs.com/",
6
6
  "types": "./dist/types/index.d.ts",
@@ -73,10 +73,10 @@
73
73
  "antd": "^5.21.6",
74
74
  "buffer": "6.0.3",
75
75
  "dayjs": "^1.11.11",
76
- "@midscene/playground": "1.9.6",
77
- "@midscene/shared": "1.9.6",
78
- "@midscene/web": "1.9.6",
79
- "@midscene/core": "1.9.6"
76
+ "@midscene/core": "1.9.7",
77
+ "@midscene/playground": "1.9.7",
78
+ "@midscene/shared": "1.9.7",
79
+ "@midscene/web": "1.9.7"
80
80
  },
81
81
  "license": "MIT",
82
82
  "scripts": {