@midscene/playground-app 1.7.3 → 1.7.4

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 (50) hide show
  1. package/dist/es/PlaygroundApp.css +0 -128
  2. package/dist/es/PlaygroundApp.mjs +74 -464
  3. package/dist/es/PlaygroundThemeProvider.mjs +10 -0
  4. package/dist/es/PreviewRenderer.mjs +4 -1
  5. package/dist/es/ScrcpyPanel.mjs +97 -89
  6. package/dist/es/SessionSetupPanel.css +292 -0
  7. package/dist/es/SessionSetupPanel.mjs +60 -39
  8. package/dist/es/controller/ai-config.mjs +37 -0
  9. package/dist/es/controller/auto-create.mjs +19 -0
  10. package/dist/es/controller/selectors.mjs +66 -0
  11. package/dist/es/controller/types.mjs +0 -0
  12. package/dist/es/controller/usePlaygroundController.mjs +356 -0
  13. package/dist/es/icons/dropdown-chevron.mjs +61 -0
  14. package/dist/es/icons/midscene-logo.mjs +247 -0
  15. package/dist/es/index.mjs +4 -1
  16. package/dist/es/panels/PlaygroundConversationPanel.css +20 -0
  17. package/dist/es/panels/PlaygroundConversationPanel.mjs +134 -0
  18. package/dist/es/scrcpy-preview.mjs +30 -0
  19. package/dist/lib/PlaygroundApp.css +0 -128
  20. package/dist/lib/PlaygroundApp.js +70 -460
  21. package/dist/lib/PlaygroundThemeProvider.js +44 -0
  22. package/dist/lib/PreviewRenderer.js +4 -1
  23. package/dist/lib/ScrcpyPanel.js +96 -88
  24. package/dist/lib/SessionSetupPanel.css +292 -0
  25. package/dist/lib/SessionSetupPanel.js +70 -38
  26. package/dist/lib/controller/ai-config.js +74 -0
  27. package/dist/lib/controller/auto-create.js +59 -0
  28. package/dist/lib/controller/selectors.js +103 -0
  29. package/dist/lib/controller/types.js +18 -0
  30. package/dist/lib/controller/usePlaygroundController.js +390 -0
  31. package/dist/lib/icons/dropdown-chevron.js +95 -0
  32. package/dist/lib/icons/midscene-logo.js +281 -0
  33. package/dist/lib/index.js +14 -2
  34. package/dist/lib/panels/PlaygroundConversationPanel.css +20 -0
  35. package/dist/lib/panels/PlaygroundConversationPanel.js +168 -0
  36. package/dist/lib/scrcpy-preview.js +79 -0
  37. package/dist/types/PlaygroundPreview.d.ts +6 -0
  38. package/dist/types/PlaygroundThemeProvider.d.ts +2 -0
  39. package/dist/types/PreviewRenderer.d.ts +7 -1
  40. package/dist/types/ScrcpyPanel.d.ts +14 -1
  41. package/dist/types/SessionSetupPanel.d.ts +4 -3
  42. package/dist/types/controller/ai-config.d.ts +4 -0
  43. package/dist/types/controller/auto-create.d.ts +15 -0
  44. package/dist/types/controller/selectors.d.ts +5 -0
  45. package/dist/types/controller/types.d.ts +36 -0
  46. package/dist/types/controller/usePlaygroundController.d.ts +9 -0
  47. package/dist/types/index.d.ts +5 -0
  48. package/dist/types/panels/PlaygroundConversationPanel.d.ts +20 -0
  49. package/dist/types/scrcpy-preview.d.ts +11 -0
  50. package/package.json +4 -3
@@ -1,223 +1,25 @@
1
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
- import { PlaygroundSDK } from "@midscene/playground";
3
- import { Logo, NavActions, UniversalPlayground, globalThemeConfig } from "@midscene/visualizer";
4
- import { Alert, Button, ConfigProvider, Form, Layout, Modal, Space, Typography, message } from "antd";
5
- import { useCallback, useEffect, useMemo, useRef, useState } from "react";
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Logo, NavActions } from "@midscene/visualizer";
3
+ import { Layout } from "antd";
4
+ import { useEffect, useState } from "react";
6
5
  import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels";
7
- import { PreviewRenderer } from "./PreviewRenderer.mjs";
8
- import { SessionSetupPanel } from "./SessionSetupPanel.mjs";
6
+ import { PlaygroundPreview } from "./PlaygroundPreview.mjs";
7
+ import { PlaygroundThemeProvider } from "./PlaygroundThemeProvider.mjs";
8
+ import { usePlaygroundController } from "./controller/usePlaygroundController.mjs";
9
9
  import server_offline_background from "./icons/server-offline-background.mjs";
10
10
  import server_offline_foreground from "./icons/server-offline-foreground.mjs";
11
- import { resolveAutoCreateSessionInput } from "./session-setup.mjs";
12
- import { buildSessionInitialValues, resolveSessionViewState } from "./session-state.mjs";
13
- import { useServerStatus } from "./useServerStatus.mjs";
11
+ import { PlaygroundConversationPanel } from "./panels/PlaygroundConversationPanel.mjs";
14
12
  import "./PlaygroundApp.css";
15
- function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
16
- try {
17
- var info = gen[key](arg);
18
- var value = info.value;
19
- } catch (error) {
20
- reject(error);
21
- return;
22
- }
23
- if (info.done) resolve(value);
24
- else Promise.resolve(value).then(_next, _throw);
25
- }
26
- function _async_to_generator(fn) {
27
- return function() {
28
- var self = this, args = arguments;
29
- return new Promise(function(resolve, reject) {
30
- var gen = fn.apply(self, args);
31
- function _next(value) {
32
- asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
33
- }
34
- function _throw(err) {
35
- asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
36
- }
37
- _next(void 0);
38
- });
39
- };
40
- }
41
- function _define_property(obj, key, value) {
42
- if (key in obj) Object.defineProperty(obj, key, {
43
- value: value,
44
- enumerable: true,
45
- configurable: true,
46
- writable: true
47
- });
48
- else obj[key] = value;
49
- return obj;
50
- }
51
- function _object_spread(target) {
52
- for(var i = 1; i < arguments.length; i++){
53
- var source = null != arguments[i] ? arguments[i] : {};
54
- var ownKeys = Object.keys(source);
55
- if ("function" == typeof Object.getOwnPropertySymbols) ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
56
- return Object.getOwnPropertyDescriptor(source, sym).enumerable;
57
- }));
58
- ownKeys.forEach(function(key) {
59
- _define_property(target, key, source[key]);
60
- });
61
- }
62
- return target;
63
- }
64
- function PlaygroundApp_ownKeys(object, enumerableOnly) {
65
- var keys = Object.keys(object);
66
- if (Object.getOwnPropertySymbols) {
67
- var symbols = Object.getOwnPropertySymbols(object);
68
- if (enumerableOnly) symbols = symbols.filter(function(sym) {
69
- return Object.getOwnPropertyDescriptor(object, sym).enumerable;
70
- });
71
- keys.push.apply(keys, symbols);
72
- }
73
- return keys;
74
- }
75
- function _object_spread_props(target, source) {
76
- source = null != source ? source : {};
77
- if (Object.getOwnPropertyDescriptors) Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
78
- else PlaygroundApp_ownKeys(Object(source)).forEach(function(key) {
79
- Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
80
- });
81
- return target;
82
- }
83
13
  const { Content } = Layout;
84
- const { Text } = Typography;
85
- function getPlatformSelectorFieldKey(setup) {
86
- var _setup_platformSelector;
87
- return null == setup ? void 0 : null == (_setup_platformSelector = setup.platformSelector) ? void 0 : _setup_platformSelector.fieldKey;
88
- }
89
14
  function PlaygroundApp({ serverUrl, appVersion, title = 'Playground', defaultDeviceType = 'web', branding, playgroundConfig, offlineTitle = 'Midscene Playground', offlineStatusText = 'Server offline...', pollIntervalMs = 5000 }) {
90
15
  var _playgroundConfig_executionUx;
91
16
  const [isNarrowScreen, setIsNarrowScreen] = useState(false);
92
- const [countdown, setCountdown] = useState(null);
93
- const [setupForm] = Form.useForm();
94
- const [sessionSetup, setSessionSetup] = useState(null);
95
- const [sessionSetupError, setSessionSetupError] = useState(null);
96
- const [sessionLoading, setSessionLoading] = useState(false);
97
- const [sessionMutating, setSessionMutating] = useState(false);
98
- const [messageApi, messageContextHolder] = message.useMessage();
99
- var _playgroundConfig_executionUx_countdownSeconds;
100
- const countdownSeconds = null != (_playgroundConfig_executionUx_countdownSeconds = null == playgroundConfig ? void 0 : null == (_playgroundConfig_executionUx = playgroundConfig.executionUx) ? void 0 : _playgroundConfig_executionUx.countdownSeconds) ? _playgroundConfig_executionUx_countdownSeconds : 3;
101
- const platformSelectorFieldKey = getPlatformSelectorFieldKey(sessionSetup);
102
- var _Form_useWatch;
103
- const selectedPlatformId = null != (_Form_useWatch = Form.useWatch(platformSelectorFieldKey || 'platformId', setupForm)) ? _Form_useWatch : void 0;
104
- const playgroundSDK = useMemo(()=>new PlaygroundSDK({
105
- type: 'remote-execution',
106
- serverUrl
107
- }), [
108
- serverUrl
109
- ]);
110
- const { serverOnline, isUserOperating, deviceType, runtimeInfo, executionUxHints, refreshServerState } = useServerStatus(playgroundSDK, defaultDeviceType, pollIntervalMs);
111
- const sessionViewState = useMemo(()=>resolveSessionViewState(runtimeInfo), [
112
- runtimeInfo
113
- ]);
114
- const countdownTimerRef = useRef(null);
115
- const countdownResolveRef = useRef(null);
116
- const mountedRef = useRef(true);
117
- const lastSetupPlatformIdRef = useRef(void 0);
118
- const autoCreateSignatureRef = useRef(null);
119
- const autoCreateDisabledRef = useRef(false);
120
- const finishCountdown = useCallback(()=>{
121
- if (null !== countdownTimerRef.current) {
122
- window.clearInterval(countdownTimerRef.current);
123
- countdownTimerRef.current = null;
124
- }
125
- const resolve = countdownResolveRef.current;
126
- countdownResolveRef.current = null;
127
- if (mountedRef.current) setCountdown(null);
128
- null == resolve || resolve();
129
- }, []);
130
- const showCountdownModal = useCallback(()=>_async_to_generator(function*() {
131
- if (countdownSeconds <= 0) return;
132
- finishCountdown();
133
- return new Promise((resolve)=>{
134
- countdownResolveRef.current = resolve;
135
- let count = countdownSeconds;
136
- if (mountedRef.current) setCountdown(count);
137
- countdownTimerRef.current = window.setInterval(()=>{
138
- count -= 1;
139
- if (count > 0) {
140
- if (mountedRef.current) setCountdown(count);
141
- return;
142
- }
143
- if (0 === count) {
144
- if (mountedRef.current) setCountdown('GO!');
145
- return;
146
- }
147
- finishCountdown();
148
- }, 1000);
149
- });
150
- })(), [
151
- countdownSeconds,
152
- finishCountdown
153
- ]);
154
- useEffect(()=>{
155
- mountedRef.current = true;
156
- return ()=>{
157
- mountedRef.current = false;
158
- finishCountdown();
159
- };
160
- }, [
161
- finishCountdown
162
- ]);
163
- useEffect(()=>{
164
- if (!executionUxHints.includes('countdown-before-run')) return void playgroundSDK.setBeforeActionHook(void 0);
165
- playgroundSDK.setBeforeActionHook(()=>_async_to_generator(function*() {
166
- yield showCountdownModal();
167
- })());
168
- return ()=>{
169
- playgroundSDK.setBeforeActionHook(void 0);
170
- };
171
- }, [
172
- executionUxHints,
173
- playgroundSDK,
174
- showCountdownModal
175
- ]);
176
- const refreshSessionSetup = useCallback((input)=>_async_to_generator(function*() {
177
- const currentValues = _object_spread({}, setupForm.getFieldsValue(true), input || {});
178
- setSessionLoading(true);
179
- try {
180
- const setup = yield playgroundSDK.getSessionSetup(input);
181
- setSessionSetup(setup);
182
- setSessionSetupError(null);
183
- const currentPlatformSelectorFieldKey = getPlatformSelectorFieldKey(setup);
184
- lastSetupPlatformIdRef.current = currentPlatformSelectorFieldKey && 'string' == typeof currentValues[currentPlatformSelectorFieldKey] ? currentValues[currentPlatformSelectorFieldKey] : void 0;
185
- setupForm.setFieldsValue(buildSessionInitialValues(setup, currentValues));
186
- } catch (error) {
187
- console.error('Failed to load session setup:', error);
188
- setSessionSetupError(error instanceof Error ? error.message : 'Failed to load session setup');
189
- } finally{
190
- setSessionLoading(false);
191
- }
192
- })(), [
193
- playgroundSDK,
194
- setupForm
195
- ]);
196
- useEffect(()=>{
197
- if (!serverOnline || sessionViewState.connected) return;
198
- refreshSessionSetup();
199
- }, [
200
- refreshSessionSetup,
201
- serverOnline,
202
- sessionViewState.connected
203
- ]);
204
- useEffect(()=>{
205
- if (!serverOnline || sessionViewState.connected || !selectedPlatformId) return;
206
- const currentPlatformSelectorFieldKey = getPlatformSelectorFieldKey(sessionSetup);
207
- if (!currentPlatformSelectorFieldKey) return;
208
- if (lastSetupPlatformIdRef.current === selectedPlatformId) return;
209
- refreshSessionSetup(_object_spread_props(_object_spread({}, setupForm.getFieldsValue(true)), {
210
- [currentPlatformSelectorFieldKey]: selectedPlatformId
211
- }));
212
- }, [
213
- platformSelectorFieldKey,
214
- refreshSessionSetup,
215
- selectedPlatformId,
216
- serverOnline,
217
- sessionSetup,
218
- sessionViewState.connected,
219
- setupForm
220
- ]);
17
+ const controller = usePlaygroundController({
18
+ serverUrl,
19
+ defaultDeviceType,
20
+ countdownSeconds: null == playgroundConfig ? void 0 : null == (_playgroundConfig_executionUx = playgroundConfig.executionUx) ? void 0 : _playgroundConfig_executionUx.countdownSeconds,
21
+ pollIntervalMs
22
+ });
221
23
  useEffect(()=>{
222
24
  const handleResize = ()=>{
223
25
  setIsNarrowScreen(window.innerWidth <= 1024);
@@ -226,105 +28,7 @@ function PlaygroundApp({ serverUrl, appVersion, title = 'Playground', defaultDev
226
28
  window.addEventListener('resize', handleResize);
227
29
  return ()=>window.removeEventListener('resize', handleResize);
228
30
  }, []);
229
- const mergedConfig = _object_spread({
230
- showContextPreview: false,
231
- layout: 'vertical',
232
- showVersionInfo: true,
233
- enableScrollToBottom: true,
234
- serverMode: true,
235
- showEnvConfigReminder: true,
236
- deviceType,
237
- executionUx: {
238
- hints: executionUxHints,
239
- countdownSeconds
240
- }
241
- }, playgroundConfig);
242
- var _runtimeInfo_title, _runtimeInfo_platformId, _ref, _ref1;
243
- const mergedBranding = _object_spread_props(_object_spread({}, branding), {
244
- title: null != (_runtimeInfo_title = null == runtimeInfo ? void 0 : runtimeInfo.title) ? _runtimeInfo_title : title,
245
- version: appVersion,
246
- targetName: null != (_ref1 = null != (_ref = null != (_runtimeInfo_platformId = null == runtimeInfo ? void 0 : runtimeInfo.platformId) ? _runtimeInfo_platformId : null == branding ? void 0 : branding.targetName) ? _ref : deviceType) ? _ref1 : 'screen'
247
- });
248
- const createSession = useCallback((input, options)=>_async_to_generator(function*() {
249
- try {
250
- const values = null != input ? input : yield setupForm.validateFields();
251
- setSessionMutating(true);
252
- yield playgroundSDK.createSession(values);
253
- if (!(null == options ? void 0 : options.silent)) messageApi.success('Agent created');
254
- yield refreshServerState();
255
- return true;
256
- } catch (error) {
257
- if (error.errorFields) return false;
258
- const errorMessage = error instanceof Error ? error.message : 'Failed to create Agent';
259
- messageApi.error(errorMessage);
260
- return false;
261
- } finally{
262
- setSessionMutating(false);
263
- }
264
- })(), [
265
- messageApi,
266
- playgroundSDK,
267
- refreshServerState,
268
- setupForm
269
- ]);
270
- const handleCreateSession = useCallback(()=>_async_to_generator(function*() {
271
- autoCreateDisabledRef.current = true;
272
- yield createSession();
273
- })(), [
274
- createSession
275
- ]);
276
- const handleDestroySession = useCallback(()=>_async_to_generator(function*() {
277
- try {
278
- autoCreateDisabledRef.current = true;
279
- setSessionMutating(true);
280
- yield playgroundSDK.destroySession();
281
- messageApi.success('Session disconnected');
282
- yield refreshServerState();
283
- yield refreshSessionSetup();
284
- } catch (error) {
285
- const errorMessage = error instanceof Error ? error.message : 'Failed to disconnect session';
286
- messageApi.error(errorMessage);
287
- } finally{
288
- setSessionMutating(false);
289
- }
290
- })(), [
291
- messageApi,
292
- playgroundSDK,
293
- refreshServerState,
294
- refreshSessionSetup
295
- ]);
296
- useEffect(()=>{
297
- if (sessionViewState.connected) {
298
- autoCreateSignatureRef.current = null;
299
- return;
300
- }
301
- if (!serverOnline || sessionLoading || sessionMutating || sessionSetupError || autoCreateDisabledRef.current) return;
302
- const autoCreateInput = resolveAutoCreateSessionInput(sessionSetup, setupForm.getFieldsValue(true));
303
- if (!autoCreateInput) {
304
- autoCreateSignatureRef.current = null;
305
- return;
306
- }
307
- const signature = JSON.stringify(autoCreateInput);
308
- if (autoCreateSignatureRef.current === signature) return;
309
- autoCreateSignatureRef.current = signature;
310
- (()=>_async_to_generator(function*() {
311
- const created = yield createSession(autoCreateInput, {
312
- silent: true
313
- });
314
- if (!created) autoCreateSignatureRef.current = null;
315
- })())();
316
- }, [
317
- createSession,
318
- serverOnline,
319
- sessionLoading,
320
- sessionMutating,
321
- sessionSetup,
322
- sessionSetupError,
323
- sessionViewState.connected,
324
- setupForm
325
- ]);
326
- if (!serverOnline) return /*#__PURE__*/ jsx(ConfigProvider, {
327
- theme: globalThemeConfig(),
31
+ if (!controller.state.serverOnline) return /*#__PURE__*/ jsx(PlaygroundThemeProvider, {
328
32
  children: /*#__PURE__*/ jsx("div", {
329
33
  className: "server-offline-container",
330
34
  children: /*#__PURE__*/ jsxs("div", {
@@ -358,166 +62,72 @@ function PlaygroundApp({ serverUrl, appVersion, title = 'Playground', defaultDev
358
62
  })
359
63
  })
360
64
  });
361
- return /*#__PURE__*/ jsxs(ConfigProvider, {
362
- theme: globalThemeConfig(),
363
- children: [
364
- messageContextHolder,
365
- /*#__PURE__*/ jsx(Modal, {
366
- open: null !== countdown,
367
- footer: /*#__PURE__*/ jsx(Button, {
368
- onClick: finishCountdown,
369
- type: "default",
370
- children: "Skip countdown"
371
- }),
372
- closable: true,
373
- maskClosable: true,
374
- onCancel: finishCountdown,
375
- centered: true,
376
- width: 400,
377
- style: {
378
- top: '30%'
379
- },
380
- styles: {
381
- mask: {
382
- backgroundColor: 'rgba(0, 0, 0, 0.75)'
383
- }
384
- },
385
- children: /*#__PURE__*/ jsxs("div", {
386
- style: {
387
- textAlign: 'center',
388
- padding: '40px 20px'
389
- },
65
+ return /*#__PURE__*/ jsx(PlaygroundThemeProvider, {
66
+ children: /*#__PURE__*/ jsx(Layout, {
67
+ className: "app-container playground-container",
68
+ children: /*#__PURE__*/ jsx(Content, {
69
+ className: "app-content",
70
+ children: /*#__PURE__*/ jsxs(PanelGroup, {
71
+ autoSaveId: "playground-layout",
72
+ direction: isNarrowScreen ? 'vertical' : 'horizontal',
390
73
  children: [
391
- /*#__PURE__*/ jsx("div", {
392
- style: {
393
- fontSize: '72px',
394
- fontWeight: 'bold',
395
- color: 'GO!' === countdown ? '#52c41a' : '#1890ff',
396
- marginBottom: '24px',
397
- lineHeight: 1
398
- },
399
- children: countdown
400
- }),
401
- /*#__PURE__*/ jsx("div", {
402
- style: {
403
- fontSize: '18px',
404
- fontWeight: 500,
405
- marginBottom: '12px'
406
- },
407
- children: "Automation Starting Soon"
408
- }),
409
- /*#__PURE__*/ jsxs("div", {
410
- style: {
411
- fontSize: '14px',
412
- color: 'rgba(0, 0, 0, 0.65)'
413
- },
414
- children: [
415
- "The selected session requested a countdown before execution.",
416
- /*#__PURE__*/ jsx("br", {}),
417
- "Please wait until the run starts."
418
- ]
419
- })
420
- ]
421
- })
422
- }),
423
- /*#__PURE__*/ jsx(Layout, {
424
- className: "app-container playground-container",
425
- children: /*#__PURE__*/ jsx(Content, {
426
- className: "app-content",
427
- children: /*#__PURE__*/ jsxs(PanelGroup, {
428
- autoSaveId: "playground-layout",
429
- direction: isNarrowScreen ? 'vertical' : 'horizontal',
430
- children: [
431
- /*#__PURE__*/ jsx(Panel, {
432
- defaultSize: isNarrowScreen ? 67 : 32,
433
- maxSize: isNarrowScreen ? 85 : 60,
434
- minSize: isNarrowScreen ? 67 : 25,
435
- className: "app-panel left-panel",
436
- children: /*#__PURE__*/ jsxs("div", {
437
- className: "panel-content left-panel-content",
438
- children: [
439
- /*#__PURE__*/ jsx("div", {
440
- className: "playground-panel-header",
441
- children: /*#__PURE__*/ jsxs("div", {
442
- className: "header-row",
443
- children: [
444
- /*#__PURE__*/ jsx(Logo, {}),
445
- /*#__PURE__*/ jsx(NavActions, {
446
- showTooltipWhenEmpty: false,
447
- showModelName: false,
448
- playgroundSDK: playgroundSDK
449
- })
450
- ]
451
- })
452
- }),
453
- /*#__PURE__*/ jsx("div", {
454
- className: "playground-panel-playground",
455
- children: sessionViewState.connected ? /*#__PURE__*/ jsx(UniversalPlayground, {
456
- playgroundSDK: playgroundSDK,
457
- config: mergedConfig,
458
- branding: mergedBranding,
459
- className: "playground-container"
460
- }) : /*#__PURE__*/ jsx(SessionSetupPanel, {
461
- form: setupForm,
462
- sessionSetup: sessionSetup,
463
- sessionSetupError: sessionSetupError,
464
- sessionViewState: sessionViewState,
465
- sessionLoading: sessionLoading,
466
- sessionMutating: sessionMutating,
467
- onCreateSession: handleCreateSession,
468
- onRefreshTargets: ()=>refreshSessionSetup(setupForm.getFieldsValue(true))
469
- })
74
+ /*#__PURE__*/ jsx(Panel, {
75
+ defaultSize: isNarrowScreen ? 67 : 32,
76
+ maxSize: isNarrowScreen ? 85 : 60,
77
+ minSize: isNarrowScreen ? 67 : 25,
78
+ className: "app-panel left-panel",
79
+ children: /*#__PURE__*/ jsxs("div", {
80
+ className: "panel-content left-panel-content",
81
+ children: [
82
+ /*#__PURE__*/ jsx("div", {
83
+ className: "playground-panel-header",
84
+ children: /*#__PURE__*/ jsxs("div", {
85
+ className: "header-row",
86
+ children: [
87
+ /*#__PURE__*/ jsx(Logo, {}),
88
+ /*#__PURE__*/ jsx(NavActions, {
89
+ showTooltipWhenEmpty: false,
90
+ showModelName: false,
91
+ playgroundSDK: controller.state.playgroundSDK
92
+ })
93
+ ]
94
+ })
95
+ }),
96
+ /*#__PURE__*/ jsx("div", {
97
+ className: "playground-panel-playground",
98
+ children: /*#__PURE__*/ jsx(PlaygroundConversationPanel, {
99
+ controller: controller,
100
+ appVersion: appVersion,
101
+ branding: branding,
102
+ playgroundConfig: playgroundConfig,
103
+ title: title
470
104
  })
471
- ]
472
- })
473
- }),
474
- /*#__PURE__*/ jsx(PanelResizeHandle, {
475
- className: `panel-resize-handle ${isNarrowScreen ? 'vertical' : 'horizontal'}`
476
- }),
477
- /*#__PURE__*/ jsx(Panel, {
478
- className: "app-panel right-panel",
479
- children: /*#__PURE__*/ jsx("div", {
480
- className: "panel-content right-panel-content",
481
- children: sessionViewState.connected ? /*#__PURE__*/ jsxs(Fragment, {
482
- children: [
483
- /*#__PURE__*/ jsxs("div", {
484
- className: "session-toolbar",
485
- children: [
486
- /*#__PURE__*/ jsx(Text, {
487
- strong: true,
488
- children: sessionViewState.displayName || 'Connected session'
489
- }),
490
- /*#__PURE__*/ jsx(Space, {
491
- size: 8,
492
- children: /*#__PURE__*/ jsx(Button, {
493
- onClick: handleDestroySession,
494
- loading: sessionMutating,
495
- children: "Change target"
496
- })
497
- })
498
- ]
499
- }),
500
- /*#__PURE__*/ jsx(PreviewRenderer, {
501
- playgroundSDK: playgroundSDK,
502
- runtimeInfo: runtimeInfo,
503
- serverUrl: serverUrl,
504
- serverOnline: serverOnline,
505
- isUserOperating: isUserOperating
506
- })
507
- ]
508
- }) : /*#__PURE__*/ jsx(Alert, {
509
- type: "info",
510
- showIcon: true,
511
- message: mergedBranding.title || 'Playground session',
512
- description: 'blocked' === sessionViewState.setupState ? sessionViewState.setupBlockingReason || 'Resolve the local setup issue before creating an Agent.' : 'Create an Agent from the left panel to enable preview and execution.'
513
105
  })
106
+ ]
107
+ })
108
+ }),
109
+ /*#__PURE__*/ jsx(PanelResizeHandle, {
110
+ className: "panel-resize-handle"
111
+ }),
112
+ /*#__PURE__*/ jsx(Panel, {
113
+ defaultSize: isNarrowScreen ? 33 : 68,
114
+ minSize: isNarrowScreen ? 15 : 40,
115
+ className: "app-panel right-panel",
116
+ children: /*#__PURE__*/ jsx("div", {
117
+ className: "panel-content right-panel-content",
118
+ children: /*#__PURE__*/ jsx(PlaygroundPreview, {
119
+ playgroundSDK: controller.state.playgroundSDK,
120
+ runtimeInfo: controller.state.runtimeInfo,
121
+ serverUrl: serverUrl,
122
+ serverOnline: controller.state.serverOnline,
123
+ isUserOperating: controller.state.isUserOperating
514
124
  })
515
125
  })
516
- ]
517
- })
126
+ })
127
+ ]
518
128
  })
519
129
  })
520
- ]
130
+ })
521
131
  });
522
132
  }
523
133
  export { PlaygroundApp };
@@ -0,0 +1,10 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { globalThemeConfig } from "@midscene/visualizer";
3
+ import { ConfigProvider } from "antd";
4
+ function PlaygroundThemeProvider({ children }) {
5
+ return /*#__PURE__*/ jsx(ConfigProvider, {
6
+ theme: globalThemeConfig(),
7
+ children: children
8
+ });
9
+ }
10
+ export { PlaygroundThemeProvider };
@@ -13,7 +13,7 @@ function isNonLocalhostHttp() {
13
13
  return false;
14
14
  }
15
15
  }
16
- function PreviewRenderer({ playgroundSDK, runtimeInfo, serverUrl, serverOnline, isUserOperating }) {
16
+ function PreviewRenderer({ connectingOverlay, onScrcpyStatusChange, renderErrorOverlay, playgroundSDK, runtimeInfo, serverUrl, serverOnline, isUserOperating }) {
17
17
  const previewConnection = resolvePreviewConnectionInfo(runtimeInfo, serverUrl);
18
18
  const scrcpyAvailable = 'scrcpy' === previewConnection.type && WebCodecsVideoDecoder.isSupported;
19
19
  const useScreenshot = 'screenshot' === previewConnection.type || 'scrcpy' === previewConnection.type && !scrcpyAvailable;
@@ -118,6 +118,9 @@ function PreviewRenderer({ playgroundSDK, runtimeInfo, serverUrl, serverOnline,
118
118
  message: "Preview unavailable",
119
119
  description: "This session did not expose a preview capability in runtime metadata."
120
120
  }) : scrcpyAvailable ? /*#__PURE__*/ jsx(ScrcpyPanel, {
121
+ connectingOverlay: connectingOverlay,
122
+ onStatusChange: onScrcpyStatusChange,
123
+ renderErrorOverlay: renderErrorOverlay,
121
124
  serverUrl: previewConnection.scrcpyUrl
122
125
  }) : /*#__PURE__*/ jsx(ScreenshotViewer, {
123
126
  getScreenshot: ()=>useScreenshot ? playgroundSDK.getScreenshot() : Promise.resolve(null),