@midscene/playground 1.9.8 → 1.10.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 (33) hide show
  1. package/dist/es/index.mjs +3 -2
  2. package/dist/es/launcher.mjs +4 -3
  3. package/dist/es/launcher.mjs.map +1 -1
  4. package/dist/es/recorder-ai-service.mjs +2 -0
  5. package/dist/es/recorder-ui-describer-prompt.mjs +56 -0
  6. package/dist/es/recorder-ui-describer-prompt.mjs.map +1 -0
  7. package/dist/es/recorder-ui-describer.mjs +392 -0
  8. package/dist/es/recorder-ui-describer.mjs.map +1 -0
  9. package/dist/es/server.mjs +32 -8
  10. package/dist/es/server.mjs.map +1 -1
  11. package/dist/lib/index.js +19 -6
  12. package/dist/lib/launcher.js +3 -2
  13. package/dist/lib/launcher.js.map +1 -1
  14. package/dist/lib/recorder-ai-service.js +38 -0
  15. package/dist/lib/recorder-ai-service.js.map +1 -0
  16. package/dist/lib/recorder-ui-describer-prompt.js +90 -0
  17. package/dist/lib/recorder-ui-describer-prompt.js.map +1 -0
  18. package/dist/lib/recorder-ui-describer.js +432 -0
  19. package/dist/lib/recorder-ui-describer.js.map +1 -0
  20. package/dist/lib/server.js +40 -7
  21. package/dist/lib/server.js.map +1 -1
  22. package/dist/types/index.d.ts +2 -1
  23. package/dist/types/recorder-ai-service.d.ts +1 -0
  24. package/dist/types/recorder-ui-describer-prompt.d.ts +1 -0
  25. package/dist/types/recorder-ui-describer.d.ts +20 -0
  26. package/dist/types/server.d.ts +4 -0
  27. package/package.json +9 -3
  28. package/static/index.html +1 -1
  29. package/static/static/js/index.9c67d55f.js +951 -0
  30. package/static/static/js/index.9c67d55f.js.map +1 -0
  31. package/static/static/js/index.44b83907.js +0 -948
  32. package/static/static/js/index.44b83907.js.map +0 -1
  33. /package/static/static/js/{index.44b83907.js.LICENSE.txt → index.9c67d55f.js.LICENSE.txt} +0 -0
@@ -37,9 +37,12 @@ var __webpack_exports__ = {};
37
37
  __webpack_require__.r(__webpack_exports__);
38
38
  __webpack_require__.d(__webpack_exports__, {
39
39
  createManualExecutorContext: ()=>createManualExecutorContext,
40
- default: ()=>server,
40
+ buildPlaygroundBrowserUrl: ()=>buildPlaygroundBrowserUrl,
41
41
  PlaygroundServer: ()=>PlaygroundServer,
42
+ default: ()=>server,
43
+ resolvePlaygroundBrowserHost: ()=>resolvePlaygroundBrowserHost,
42
44
  serializeZodField: ()=>serializeZodField,
45
+ resolvePlaygroundListenHost: ()=>resolvePlaygroundListenHost,
43
46
  InteractParamsValidationError: ()=>InteractParamsValidationError,
44
47
  buildInteractParams: ()=>buildInteractParams
45
48
  });
@@ -48,6 +51,7 @@ const external_node_fs_namespaceObject = require("node:fs");
48
51
  const external_node_path_namespaceObject = require("node:path");
49
52
  const external_node_url_namespaceObject = require("node:url");
50
53
  const core_namespaceObject = require("@midscene/core");
54
+ const ai_model_namespaceObject = require("@midscene/core/ai-model");
51
55
  const utils_namespaceObject = require("@midscene/core/utils");
52
56
  const common_namespaceObject = require("@midscene/shared/common");
53
57
  const constants_namespaceObject = require("@midscene/shared/constants");
@@ -78,6 +82,15 @@ const defaultPort = constants_namespaceObject.PLAYGROUND_SERVER_PORT;
78
82
  const RECORDER_CAPTURE_AFTER_INTERACT_DELAY_MS = 250;
79
83
  const RECORDER_AI_DESCRIBE_AFTER_INTERACT_TIMEOUT_MS = 30000;
80
84
  const RECORDER_AI_DESCRIBE_SCREENSHOT_DUMP_DIR = 'recorder-ai-describe-screenshots';
85
+ function createElementDescriberRuntime(agent) {
86
+ const modelConfigManager = agent.modelConfigManager;
87
+ const missingModelRuntime = void 0;
88
+ return {
89
+ service: agent.service,
90
+ describeModelRuntime: modelConfigManager ? (0, ai_model_namespaceObject.getModelRuntime)(modelConfigManager.getModelConfig('insight')) : missingModelRuntime,
91
+ locateModelRuntime: modelConfigManager ? (0, ai_model_namespaceObject.getModelRuntime)(modelConfigManager.getModelConfig('default')) : missingModelRuntime
92
+ };
93
+ }
81
94
  function extractBase64Payload(value) {
82
95
  const dataUrlMatch = value.match(/^data:([^;,]+)?(?:;[^,]*)?,([\s\S]*)$/);
83
96
  if (dataUrlMatch) return {
@@ -286,6 +299,17 @@ function createRecorderAiDescribeTraceBase(event, eventScreenshot) {
286
299
  screenshotBytes: estimateBase64Bytes(eventScreenshot)
287
300
  };
288
301
  }
302
+ function resolvePlaygroundListenHost() {
303
+ return process.env.MIDSCENE_PLAYGROUND_HOST?.trim() || '0.0.0.0';
304
+ }
305
+ function resolvePlaygroundBrowserHost() {
306
+ const listenHost = resolvePlaygroundListenHost();
307
+ return '0.0.0.0' === listenHost || '::' === listenHost ? '127.0.0.1' : listenHost;
308
+ }
309
+ function buildPlaygroundBrowserUrl(host, port) {
310
+ const normalizedHost = host.includes(':') && !host.startsWith('[') ? `[${host}]` : host;
311
+ return `http://${normalizedHost}:${port}`;
312
+ }
289
313
  function serializeAiConfigSignature(aiConfig) {
290
314
  return JSON.stringify(Object.entries(aiConfig).sort(([leftKey], [rightKey])=>leftKey.localeCompare(rightKey)));
291
315
  }
@@ -1000,7 +1024,7 @@ class PlaygroundServer {
1000
1024
  let screenshotAnnotation;
1001
1025
  let screenshotPersistError;
1002
1026
  let annotatedScreenshotPersistError;
1003
- if ('failed' === status) try {
1027
+ if ('failed' === status || extra.verifyResult?.pass === false) try {
1004
1028
  const screenshotDump = await persistRecorderAiDescribeScreenshot(event, eventScreenshot, extra.verifyResult);
1005
1029
  screenshotRef = screenshotDump?.screenshotRef;
1006
1030
  annotatedScreenshotRef = screenshotDump?.annotatedScreenshotRef;
@@ -1036,7 +1060,7 @@ class PlaygroundServer {
1036
1060
  trace
1037
1061
  };
1038
1062
  }
1039
- if ('function' != typeof agent?.describeElementAtPoint) {
1063
+ if (!agent) {
1040
1064
  const error = 'Active agent does not support describeElementAtPoint.';
1041
1065
  const trace = await finishTrace('failed', {
1042
1066
  error
@@ -1063,7 +1087,8 @@ class PlaygroundServer {
1063
1087
  if (!event.pageInfo?.width || !event.pageInfo?.height) throw new Error('Skipped aiDescribe because the recorder event has no pageInfo for coordinate mapping.');
1064
1088
  const verifyPrompt = shouldVerifyRecorderAiDescribeEvent(event);
1065
1089
  modelCallStartedAt = Date.now();
1066
- const describeResult = await withTimeout(agent.describeElementAtPoint([
1090
+ const elementDescriber = createElementDescriberRuntime(agent);
1091
+ const describeResult = await withTimeout((0, core_namespaceObject.describeElementAtPoint)(elementDescriber, [
1067
1092
  x,
1068
1093
  y
1069
1094
  ], {
@@ -1082,7 +1107,7 @@ class PlaygroundServer {
1082
1107
  deepLocate = describeResult.deepLocate;
1083
1108
  verifyResult = verifyPrompt ? describeResult.verifyResult : void 0;
1084
1109
  if (!elementDescription) throw new Error("aiDescribe returned an empty element description.");
1085
- if (verifyResult && false === verifyResult.pass) throw new Error('aiDescribe verification failed.');
1110
+ if (false === describeResult.success) throw new Error(describeResult.error || `aiDescribe ${describeResult.failureStage || 'unknown'} failed.`);
1086
1111
  const semanticAction = buildRecorderSemanticAction(event.actionType || event.type, event.rawPayload || {}, event.url);
1087
1112
  const trace = await finishTrace('ready', {
1088
1113
  modelCallDurationMs,
@@ -1105,7 +1130,8 @@ class PlaygroundServer {
1105
1130
  x,
1106
1131
  y
1107
1132
  ],
1108
- actualCenter: verifyResult?.center
1133
+ actualCenter: verifyResult?.center,
1134
+ annotatedScreenshotPath: trace.annotatedScreenshotRef?.path
1109
1135
  }
1110
1136
  })
1111
1137
  },
@@ -2069,7 +2095,8 @@ class PlaygroundServer {
2069
2095
  this.port = port || defaultPort;
2070
2096
  return new Promise((resolve)=>{
2071
2097
  const serverPort = this.port ?? defaultPort;
2072
- this.server = this._app.listen(serverPort, '0.0.0.0', ()=>{
2098
+ const listenHost = resolvePlaygroundListenHost();
2099
+ this.server = this._app.listen(serverPort, listenHost, ()=>{
2073
2100
  resolve(this);
2074
2101
  });
2075
2102
  });
@@ -2149,15 +2176,21 @@ const server = PlaygroundServer;
2149
2176
  exports.InteractParamsValidationError = __webpack_exports__.InteractParamsValidationError;
2150
2177
  exports.PlaygroundServer = __webpack_exports__.PlaygroundServer;
2151
2178
  exports.buildInteractParams = __webpack_exports__.buildInteractParams;
2179
+ exports.buildPlaygroundBrowserUrl = __webpack_exports__.buildPlaygroundBrowserUrl;
2152
2180
  exports.createManualExecutorContext = __webpack_exports__.createManualExecutorContext;
2153
2181
  exports["default"] = __webpack_exports__["default"];
2182
+ exports.resolvePlaygroundBrowserHost = __webpack_exports__.resolvePlaygroundBrowserHost;
2183
+ exports.resolvePlaygroundListenHost = __webpack_exports__.resolvePlaygroundListenHost;
2154
2184
  exports.serializeZodField = __webpack_exports__.serializeZodField;
2155
2185
  for(var __rspack_i in __webpack_exports__)if (-1 === [
2156
2186
  "InteractParamsValidationError",
2157
2187
  "PlaygroundServer",
2158
2188
  "buildInteractParams",
2189
+ "buildPlaygroundBrowserUrl",
2159
2190
  "createManualExecutorContext",
2160
2191
  "default",
2192
+ "resolvePlaygroundBrowserHost",
2193
+ "resolvePlaygroundListenHost",
2161
2194
  "serializeZodField"
2162
2195
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
2163
2196
  Object.defineProperty(exports, '__esModule', {