@midscene/web 0.15.0 → 0.15.1

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/agent.js +8 -11
  2. package/dist/es/agent.js.map +1 -1
  3. package/dist/es/bridge-mode-browser.js +3 -3
  4. package/dist/es/bridge-mode.js +14 -15
  5. package/dist/es/bridge-mode.js.map +1 -1
  6. package/dist/es/chrome-extension.js +9 -12
  7. package/dist/es/chrome-extension.js.map +1 -1
  8. package/dist/es/index.js +8 -11
  9. package/dist/es/index.js.map +1 -1
  10. package/dist/es/midscene-playground.js +8 -11
  11. package/dist/es/midscene-playground.js.map +1 -1
  12. package/dist/es/midscene-server.js +1 -1
  13. package/dist/es/midscene-server.js.map +1 -1
  14. package/dist/es/playground.js +8 -11
  15. package/dist/es/playground.js.map +1 -1
  16. package/dist/es/playwright-report.js +2 -2
  17. package/dist/es/playwright-report.js.map +1 -1
  18. package/dist/es/playwright.js +8 -11
  19. package/dist/es/playwright.js.map +1 -1
  20. package/dist/es/puppeteer-agent-launcher.js +8 -11
  21. package/dist/es/puppeteer-agent-launcher.js.map +1 -1
  22. package/dist/es/puppeteer.js +8 -11
  23. package/dist/es/puppeteer.js.map +1 -1
  24. package/dist/es/utils.js +2 -2
  25. package/dist/es/utils.js.map +1 -1
  26. package/dist/lib/agent.js +7 -10
  27. package/dist/lib/agent.js.map +1 -1
  28. package/dist/lib/bridge-mode-browser.js +3 -3
  29. package/dist/lib/bridge-mode.js +15 -16
  30. package/dist/lib/bridge-mode.js.map +1 -1
  31. package/dist/lib/chrome-extension.js +8 -11
  32. package/dist/lib/chrome-extension.js.map +1 -1
  33. package/dist/lib/index.js +7 -10
  34. package/dist/lib/index.js.map +1 -1
  35. package/dist/lib/midscene-playground.js +7 -10
  36. package/dist/lib/midscene-playground.js.map +1 -1
  37. package/dist/lib/midscene-server.js.map +1 -1
  38. package/dist/lib/playground.js +7 -10
  39. package/dist/lib/playground.js.map +1 -1
  40. package/dist/lib/playwright-report.js +1 -1
  41. package/dist/lib/playwright-report.js.map +1 -1
  42. package/dist/lib/playwright.js +7 -10
  43. package/dist/lib/playwright.js.map +1 -1
  44. package/dist/lib/puppeteer-agent-launcher.js +7 -10
  45. package/dist/lib/puppeteer-agent-launcher.js.map +1 -1
  46. package/dist/lib/puppeteer.js +7 -10
  47. package/dist/lib/puppeteer.js.map +1 -1
  48. package/dist/lib/utils.js +1 -1
  49. package/dist/lib/utils.js.map +1 -1
  50. package/package.json +3 -3
package/dist/es/utils.js CHANGED
@@ -9,7 +9,7 @@ import { uploadTestInfoToServer } from "@midscene/core/utils";
9
9
  import { NodeType } from "@midscene/shared/constants";
10
10
  import { traverseTree, treeToList } from "@midscene/shared/extractor";
11
11
  import { compositeElementInfoImg, resizeImgBase64 } from "@midscene/shared/img";
12
- import { assert, uuid } from "@midscene/shared/utils";
12
+ import { assert, logMsg, uuid } from "@midscene/shared/utils";
13
13
  import dayjs from "dayjs";
14
14
 
15
15
  // src/web-element.ts
@@ -109,7 +109,7 @@ function reportFileName(tag = "web") {
109
109
  return `${reportTagName || tag}-${dateTimeInFileName}`;
110
110
  }
111
111
  function printReportMsg(filepath) {
112
- console.log("Midscene - report file updated:", filepath);
112
+ logMsg(`Midscene - report file updated: ${filepath}`);
113
113
  }
114
114
  function getCurrentExecutionFile(trace) {
115
115
  const error = new Error();
@@ -1 +1 @@
1
- {"version":3,"mappings":"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","names":[],"ignoreList":[],"sources":["../../src/common/utils.ts","../../src/web-element.ts"],"sourcesContent":["import type { StaticPage } from '@/playground';\nimport type {\n ElementTreeNode,\n PlaywrightParserOpt,\n UIContext,\n} from '@midscene/core';\nimport {\n MIDSCENE_REPORT_TAG_NAME,\n MIDSCENE_USE_VLM_UI_TARS,\n getAIConfig,\n getAIConfigInBoolean,\n} from '@midscene/core/env';\nimport { uploadTestInfoToServer } from '@midscene/core/utils';\nimport { NodeType } from '@midscene/shared/constants';\nimport type { ElementInfo } from '@midscene/shared/extractor';\nimport { traverseTree, treeToList } from '@midscene/shared/extractor';\nimport { compositeElementInfoImg, resizeImgBase64 } from '@midscene/shared/img';\nimport { assert, uuid } from '@midscene/shared/utils';\nimport dayjs from 'dayjs';\nimport { WebElementInfo } from '../web-element';\nimport type { WebPage } from './page';\nexport type WebUIContext = UIContext<WebElementInfo> & {\n url: string;\n};\n\nexport async function parseContextFromWebPage(\n page: WebPage,\n _opt?: PlaywrightParserOpt,\n): Promise<WebUIContext> {\n assert(page, 'page is required');\n if ((page as StaticPage)._forceUsePageContext) {\n return await (page as any)._forceUsePageContext();\n }\n const url = await page.url();\n uploadTestInfoToServer({ testUrl: url });\n\n let screenshotBase64: string;\n let tree: ElementTreeNode<ElementInfo>;\n\n await Promise.all([\n page.screenshotBase64().then((base64) => {\n screenshotBase64 = base64;\n }),\n page.getElementsNodeTree().then(async (treeRoot) => {\n tree = treeRoot;\n }),\n ]);\n\n const webTree = traverseTree(tree!, (elementInfo) => {\n const { rect, id, content, attributes, locator, indexId } = elementInfo;\n return new WebElementInfo({\n rect,\n locator,\n id,\n content,\n attributes,\n indexId,\n });\n });\n\n const elementsInfo = treeToList(webTree);\n\n assert(screenshotBase64!, 'screenshotBase64 is required');\n\n const elementsPositionInfoWithoutText = elementsInfo!.filter(\n (elementInfo) => {\n if (elementInfo.attributes.nodeType === NodeType.TEXT) {\n return false;\n }\n return true;\n },\n );\n\n const size = await page.size();\n\n if (size.dpr && size.dpr > 1) {\n // console.time('resizeImgBase64');\n screenshotBase64 = await resizeImgBase64(screenshotBase64, {\n width: size.width,\n height: size.height,\n });\n // console.timeEnd('resizeImgBase64');\n }\n\n let screenshotBase64WithElementMarker = screenshotBase64;\n if (!getAIConfigInBoolean(MIDSCENE_USE_VLM_UI_TARS)) {\n if (_opt?.ignoreMarker) {\n screenshotBase64WithElementMarker = screenshotBase64;\n } else {\n screenshotBase64WithElementMarker = await compositeElementInfoImg({\n inputImgBase64: screenshotBase64,\n elementsPositionInfo: elementsPositionInfoWithoutText,\n size,\n });\n }\n }\n\n return {\n content: elementsInfo!,\n tree: webTree,\n size,\n screenshotBase64: screenshotBase64!,\n screenshotBase64WithElementMarker: screenshotBase64WithElementMarker,\n url,\n };\n}\n\nexport function reportFileName(tag = 'web') {\n const reportTagName = getAIConfig(MIDSCENE_REPORT_TAG_NAME);\n const dateTimeInFileName = dayjs().format('YYYY-MM-DD_HH-mm-ss-SSS');\n return `${reportTagName || tag}-${dateTimeInFileName}`;\n}\n\nexport function printReportMsg(filepath: string) {\n //mcp need use obj format to console msg: https://github.com/modelcontextprotocol/typescript-sdk/issues/244\n console.log('Midscene - report file updated:', filepath);\n // For MCP\n // console.log(`{\"midscene-report-file-updated\": \"${filepath}\"}`);\n}\n\n/**\n * Get the current execution file name\n * @returns The name of the current execution file\n */\nexport function getCurrentExecutionFile(trace?: string): string | false {\n const error = new Error();\n const stackTrace = trace || error.stack;\n const pkgDir = process.cwd() || '';\n if (stackTrace) {\n const stackLines = stackTrace.split('\\n');\n for (const line of stackLines) {\n if (\n line.includes('.spec.') ||\n line.includes('.test.') ||\n line.includes('.ts') ||\n line.includes('.js')\n ) {\n const match = line.match(/(?:at\\s+)?(.*?\\.(?:spec|test)\\.[jt]s)/);\n if (match?.[1]) {\n const targetFileName = match[1]\n .replace(pkgDir, '')\n .trim()\n .replace('at ', '');\n return targetFileName;\n }\n }\n }\n }\n return false;\n}\n\nconst testFileIndex = new Map<string, number>();\n\nexport function generateCacheId(fileName?: string): string {\n let taskFile = fileName || getCurrentExecutionFile();\n if (!taskFile) {\n taskFile = uuid();\n console.warn(\n 'Midscene - using random UUID for cache id. Cache may be invalid.',\n );\n }\n\n if (testFileIndex.has(taskFile)) {\n const currentIndex = testFileIndex.get(taskFile);\n if (currentIndex !== undefined) {\n testFileIndex.set(taskFile, currentIndex + 1);\n }\n } else {\n testFileIndex.set(taskFile, 1);\n }\n return `${taskFile}-${testFileIndex.get(taskFile)}`;\n}\n\nexport const ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED =\n 'NOT_IMPLEMENTED_AS_DESIGNED';\n","import type { BaseElement, Rect } from '@midscene/core';\nimport type { NodeType } from '@midscene/shared/constants';\n\nexport interface WebElementInfoType extends BaseElement {\n id: string;\n locator: string;\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n}\n\nexport class WebElementInfo implements BaseElement {\n content: string;\n\n locator?: string;\n\n rect: Rect;\n\n center: [number, number];\n\n // page: WebPage;\n\n id: string;\n\n indexId: number;\n\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n\n constructor({\n content,\n rect,\n // page,\n locator,\n id,\n attributes,\n indexId,\n }: {\n content: string;\n rect: Rect;\n // page: WebPage;\n locator?: string;\n id: string;\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n indexId: number;\n }) {\n this.content = content;\n this.rect = rect;\n this.center = [\n Math.floor(rect.left + rect.width / 2),\n Math.floor(rect.top + rect.height / 2),\n ];\n // this.page = page;\n this.locator = locator;\n this.id = id;\n this.attributes = attributes;\n this.indexId = indexId;\n }\n}\n"]}
1
+ {"version":3,"mappings":";AAMA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,8BAA8B;AACvC,SAAS,gBAAgB;AAEzB,SAAS,cAAc,kBAAkB;AACzC,SAAS,yBAAyB,uBAAuB;AACzD,SAAS,QAAQ,QAAQ,YAAY;AACrC,OAAO,WAAW;;;ACNX,IAAM,iBAAN,MAA4C;AAAA,EAoBjD,YAAY;AAAA,IACV;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAWG;AACD,SAAK,UAAU;AACf,SAAK,OAAO;AACZ,SAAK,SAAS;AAAA,MACZ,KAAK,MAAM,KAAK,OAAO,KAAK,QAAQ,CAAC;AAAA,MACrC,KAAK,MAAM,KAAK,MAAM,KAAK,SAAS,CAAC;AAAA,IACvC;AAEA,SAAK,UAAU;AACf,SAAK,KAAK;AACV,SAAK,aAAa;AAClB,SAAK,UAAU;AAAA,EACjB;AACF;;;ADvCA,eAAsB,wBACpB,MACA,MACuB;AACvB,SAAO,MAAM,kBAAkB;AAC/B,MAAK,KAAoB,sBAAsB;AAC7C,WAAO,MAAO,KAAa,qBAAqB;AAAA,EAClD;AACA,QAAM,MAAM,MAAM,KAAK,IAAI;AAC3B,yBAAuB,EAAE,SAAS,IAAI,CAAC;AAEvC,MAAI;AACJ,MAAI;AAEJ,QAAM,QAAQ,IAAI;AAAA,IAChB,KAAK,iBAAiB,EAAE,KAAK,CAAC,WAAW;AACvC,yBAAmB;AAAA,IACrB,CAAC;AAAA,IACD,KAAK,oBAAoB,EAAE,KAAK,OAAO,aAAa;AAClD,aAAO;AAAA,IACT,CAAC;AAAA,EACH,CAAC;AAED,QAAM,UAAU,aAAa,MAAO,CAAC,gBAAgB;AACnD,UAAM,EAAE,MAAM,IAAI,SAAS,YAAY,SAAS,QAAQ,IAAI;AAC5D,WAAO,IAAI,eAAe;AAAA,MACxB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,QAAM,eAAe,WAAW,OAAO;AAEvC,SAAO,kBAAmB,8BAA8B;AAExD,QAAM,kCAAkC,aAAc;AAAA,IACpD,CAAC,gBAAgB;AACf,UAAI,YAAY,WAAW,aAAa,SAAS,MAAM;AACrD,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,OAAO,MAAM,KAAK,KAAK;AAE7B,MAAI,KAAK,OAAO,KAAK,MAAM,GAAG;AAE5B,uBAAmB,MAAM,gBAAgB,kBAAkB;AAAA,MACzD,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,IACf,CAAC;AAAA,EAEH;AAEA,MAAI,oCAAoC;AACxC,MAAI,CAAC,qBAAqB,wBAAwB,GAAG;AACnD,QAAI,MAAM,cAAc;AACtB,0CAAoC;AAAA,IACtC,OAAO;AACL,0CAAoC,MAAM,wBAAwB;AAAA,QAChE,gBAAgB;AAAA,QAChB,sBAAsB;AAAA,QACtB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,eAAe,MAAM,OAAO;AAC1C,QAAM,gBAAgB,YAAY,wBAAwB;AAC1D,QAAM,qBAAqB,MAAM,EAAE,OAAO,yBAAyB;AACnE,SAAO,GAAG,iBAAiB,GAAG,IAAI,kBAAkB;AACtD;AAEO,SAAS,eAAe,UAAkB;AAC/C,SAAO,mCAAmC,QAAQ,EAAE;AACtD;AAMO,SAAS,wBAAwB,OAAgC;AACtE,QAAM,QAAQ,IAAI,MAAM;AACxB,QAAM,aAAa,SAAS,MAAM;AAClC,QAAM,SAAS,QAAQ,IAAI,KAAK;AAChC,MAAI,YAAY;AACd,UAAM,aAAa,WAAW,MAAM,IAAI;AACxC,eAAW,QAAQ,YAAY;AAC7B,UACE,KAAK,SAAS,QAAQ,KACtB,KAAK,SAAS,QAAQ,KACtB,KAAK,SAAS,KAAK,KACnB,KAAK,SAAS,KAAK,GACnB;AACA,cAAM,QAAQ,KAAK,MAAM,uCAAuC;AAChE,YAAI,QAAQ,CAAC,GAAG;AACd,gBAAM,iBAAiB,MAAM,CAAC,EAC3B,QAAQ,QAAQ,EAAE,EAClB,KAAK,EACL,QAAQ,OAAO,EAAE;AACpB,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,IAAM,gBAAgB,oBAAI,IAAoB;AAEvC,SAAS,gBAAgB,UAA2B;AACzD,MAAI,WAAW,YAAY,wBAAwB;AACnD,MAAI,CAAC,UAAU;AACb,eAAW,KAAK;AAChB,YAAQ;AAAA,MACN;AAAA,IACF;AAAA,EACF;AAEA,MAAI,cAAc,IAAI,QAAQ,GAAG;AAC/B,UAAM,eAAe,cAAc,IAAI,QAAQ;AAC/C,QAAI,iBAAiB,QAAW;AAC9B,oBAAc,IAAI,UAAU,eAAe,CAAC;AAAA,IAC9C;AAAA,EACF,OAAO;AACL,kBAAc,IAAI,UAAU,CAAC;AAAA,EAC/B;AACA,SAAO,GAAG,QAAQ,IAAI,cAAc,IAAI,QAAQ,CAAC;AACnD;AAEO,IAAM,yCACX","names":[],"ignoreList":[],"sources":["../../src/common/utils.ts","../../src/web-element.ts"],"sourcesContent":["import type { StaticPage } from '@/playground';\nimport type {\n ElementTreeNode,\n PlaywrightParserOpt,\n UIContext,\n} from '@midscene/core';\nimport {\n MIDSCENE_REPORT_TAG_NAME,\n MIDSCENE_USE_VLM_UI_TARS,\n getAIConfig,\n getAIConfigInBoolean,\n} from '@midscene/core/env';\nimport { uploadTestInfoToServer } from '@midscene/core/utils';\nimport { NodeType } from '@midscene/shared/constants';\nimport type { ElementInfo } from '@midscene/shared/extractor';\nimport { traverseTree, treeToList } from '@midscene/shared/extractor';\nimport { compositeElementInfoImg, resizeImgBase64 } from '@midscene/shared/img';\nimport { assert, logMsg, uuid } from '@midscene/shared/utils';\nimport dayjs from 'dayjs';\nimport { WebElementInfo } from '../web-element';\nimport type { WebPage } from './page';\nexport type WebUIContext = UIContext<WebElementInfo> & {\n url: string;\n};\n\nexport async function parseContextFromWebPage(\n page: WebPage,\n _opt?: PlaywrightParserOpt,\n): Promise<WebUIContext> {\n assert(page, 'page is required');\n if ((page as StaticPage)._forceUsePageContext) {\n return await (page as any)._forceUsePageContext();\n }\n const url = await page.url();\n uploadTestInfoToServer({ testUrl: url });\n\n let screenshotBase64: string;\n let tree: ElementTreeNode<ElementInfo>;\n\n await Promise.all([\n page.screenshotBase64().then((base64) => {\n screenshotBase64 = base64;\n }),\n page.getElementsNodeTree().then(async (treeRoot) => {\n tree = treeRoot;\n }),\n ]);\n\n const webTree = traverseTree(tree!, (elementInfo) => {\n const { rect, id, content, attributes, locator, indexId } = elementInfo;\n return new WebElementInfo({\n rect,\n locator,\n id,\n content,\n attributes,\n indexId,\n });\n });\n\n const elementsInfo = treeToList(webTree);\n\n assert(screenshotBase64!, 'screenshotBase64 is required');\n\n const elementsPositionInfoWithoutText = elementsInfo!.filter(\n (elementInfo) => {\n if (elementInfo.attributes.nodeType === NodeType.TEXT) {\n return false;\n }\n return true;\n },\n );\n\n const size = await page.size();\n\n if (size.dpr && size.dpr > 1) {\n // console.time('resizeImgBase64');\n screenshotBase64 = await resizeImgBase64(screenshotBase64, {\n width: size.width,\n height: size.height,\n });\n // console.timeEnd('resizeImgBase64');\n }\n\n let screenshotBase64WithElementMarker = screenshotBase64;\n if (!getAIConfigInBoolean(MIDSCENE_USE_VLM_UI_TARS)) {\n if (_opt?.ignoreMarker) {\n screenshotBase64WithElementMarker = screenshotBase64;\n } else {\n screenshotBase64WithElementMarker = await compositeElementInfoImg({\n inputImgBase64: screenshotBase64,\n elementsPositionInfo: elementsPositionInfoWithoutText,\n size,\n });\n }\n }\n\n return {\n content: elementsInfo!,\n tree: webTree,\n size,\n screenshotBase64: screenshotBase64!,\n screenshotBase64WithElementMarker: screenshotBase64WithElementMarker,\n url,\n };\n}\n\nexport function reportFileName(tag = 'web') {\n const reportTagName = getAIConfig(MIDSCENE_REPORT_TAG_NAME);\n const dateTimeInFileName = dayjs().format('YYYY-MM-DD_HH-mm-ss-SSS');\n return `${reportTagName || tag}-${dateTimeInFileName}`;\n}\n\nexport function printReportMsg(filepath: string) {\n logMsg(`Midscene - report file updated: ${filepath}`);\n}\n\n/**\n * Get the current execution file name\n * @returns The name of the current execution file\n */\nexport function getCurrentExecutionFile(trace?: string): string | false {\n const error = new Error();\n const stackTrace = trace || error.stack;\n const pkgDir = process.cwd() || '';\n if (stackTrace) {\n const stackLines = stackTrace.split('\\n');\n for (const line of stackLines) {\n if (\n line.includes('.spec.') ||\n line.includes('.test.') ||\n line.includes('.ts') ||\n line.includes('.js')\n ) {\n const match = line.match(/(?:at\\s+)?(.*?\\.(?:spec|test)\\.[jt]s)/);\n if (match?.[1]) {\n const targetFileName = match[1]\n .replace(pkgDir, '')\n .trim()\n .replace('at ', '');\n return targetFileName;\n }\n }\n }\n }\n return false;\n}\n\nconst testFileIndex = new Map<string, number>();\n\nexport function generateCacheId(fileName?: string): string {\n let taskFile = fileName || getCurrentExecutionFile();\n if (!taskFile) {\n taskFile = uuid();\n console.warn(\n 'Midscene - using random UUID for cache id. Cache may be invalid.',\n );\n }\n\n if (testFileIndex.has(taskFile)) {\n const currentIndex = testFileIndex.get(taskFile);\n if (currentIndex !== undefined) {\n testFileIndex.set(taskFile, currentIndex + 1);\n }\n } else {\n testFileIndex.set(taskFile, 1);\n }\n return `${taskFile}-${testFileIndex.get(taskFile)}`;\n}\n\nexport const ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED =\n 'NOT_IMPLEMENTED_AS_DESIGNED';\n","import type { BaseElement, Rect } from '@midscene/core';\nimport type { NodeType } from '@midscene/shared/constants';\n\nexport interface WebElementInfoType extends BaseElement {\n id: string;\n locator: string;\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n}\n\nexport class WebElementInfo implements BaseElement {\n content: string;\n\n locator?: string;\n\n rect: Rect;\n\n center: [number, number];\n\n // page: WebPage;\n\n id: string;\n\n indexId: number;\n\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n\n constructor({\n content,\n rect,\n // page,\n locator,\n id,\n attributes,\n indexId,\n }: {\n content: string;\n rect: Rect;\n // page: WebPage;\n locator?: string;\n id: string;\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n indexId: number;\n }) {\n this.content = content;\n this.rect = rect;\n this.center = [\n Math.floor(rect.left + rect.width / 2),\n Math.floor(rect.top + rect.height / 2),\n ];\n // this.page = page;\n this.locator = locator;\n this.id = id;\n this.attributes = attributes;\n this.indexId = indexId;\n }\n}\n"]}
package/dist/lib/agent.js CHANGED
@@ -678,6 +678,10 @@ var PageTaskExecutor = class {
678
678
  const dumpCollector = (dump) => {
679
679
  insightDump = dump;
680
680
  usage = dump?.taskInfo?.usage;
681
+ task.log = {
682
+ dump: insightDump
683
+ };
684
+ task.usage = usage;
681
685
  };
682
686
  this.insight.onceDumpUpdatedFn = dumpCollector;
683
687
  const shotTime = Date.now();
@@ -688,6 +692,7 @@ var PageTaskExecutor = class {
688
692
  screenshot: pageContext.screenshotBase64,
689
693
  timing: "before locate"
690
694
  };
695
+ task.recorder = [recordItem];
691
696
  const cachePrompt = param.prompt;
692
697
  const locateCache = cacheGroup?.matchCache(
693
698
  pageContext,
@@ -731,9 +736,6 @@ var PageTaskExecutor = class {
731
736
  });
732
737
  }
733
738
  if (!element) {
734
- task.log = {
735
- dump: insightDump
736
- };
737
739
  throw new Error(`Element not found: ${param.prompt}`);
738
740
  }
739
741
  return {
@@ -741,15 +743,10 @@ var PageTaskExecutor = class {
741
743
  element
742
744
  },
743
745
  pageContext,
744
- log: {
745
- dump: insightDump
746
- },
747
746
  cache: {
748
747
  hit: cacheHitFlag
749
748
  },
750
- recorder: [recordItem],
751
- aiCost,
752
- usage
749
+ aiCost
753
750
  };
754
751
  }
755
752
  };
@@ -1664,7 +1661,7 @@ function reportFileName(tag = "web") {
1664
1661
  return `${reportTagName || tag}-${dateTimeInFileName}`;
1665
1662
  }
1666
1663
  function printReportMsg(filepath) {
1667
- console.log("Midscene - report file updated:", filepath);
1664
+ (0, import_utils9.logMsg)(`Midscene - report file updated: ${filepath}`);
1668
1665
  }
1669
1666
 
1670
1667
  // src/common/agent.ts