@midscene/core 1.17.6 → 1.17.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.
- package/dist/es/agent/agent-report-manager.mjs +1 -1
- package/dist/es/agent/agent-report-manager.mjs.map +1 -1
- package/dist/es/agent/utils.mjs +1 -1
- package/dist/es/ai-model/model-adapter/locate-prompt-order.mjs +80 -0
- package/dist/es/ai-model/model-adapter/locate-prompt-order.mjs.map +1 -0
- package/dist/es/ai-model/model-adapter/locate.mjs +2 -1
- package/dist/es/ai-model/model-adapter/locate.mjs.map +1 -1
- package/dist/es/ai-model/workflows/grounding/locate.mjs +1 -1
- package/dist/es/ai-model/workflows/grounding/locate.mjs.map +1 -1
- package/dist/es/ai-model/workflows/grounding/section-locate.mjs +1 -1
- package/dist/es/ai-model/workflows/grounding/section-locate.mjs.map +1 -1
- package/dist/es/ai-model/workflows/grounding/utils.mjs +8 -26
- package/dist/es/ai-model/workflows/grounding/utils.mjs.map +1 -1
- package/dist/es/dump/report-image-export.mjs +58 -0
- package/dist/es/dump/report-image-export.mjs.map +1 -0
- package/dist/es/dump/screenshot-store.mjs +5 -0
- package/dist/es/dump/screenshot-store.mjs.map +1 -1
- package/dist/es/report-cli.mjs +13 -29
- package/dist/es/report-cli.mjs.map +1 -1
- package/dist/es/report-generator.mjs +22 -8
- package/dist/es/report-generator.mjs.map +1 -1
- package/dist/es/report-html-template.mjs +1 -1
- package/dist/es/report-markdown.mjs +50 -53
- package/dist/es/report-markdown.mjs.map +1 -1
- package/dist/es/report.mjs +8 -24
- package/dist/es/report.mjs.map +1 -1
- package/dist/es/utils.mjs +1 -1
- package/dist/lib/agent/agent-report-manager.js +1 -1
- package/dist/lib/agent/agent-report-manager.js.map +1 -1
- package/dist/lib/agent/utils.js +1 -1
- package/dist/lib/ai-model/model-adapter/locate-prompt-order.js +117 -0
- package/dist/lib/ai-model/model-adapter/locate-prompt-order.js.map +1 -0
- package/dist/lib/ai-model/model-adapter/locate.js +2 -1
- package/dist/lib/ai-model/model-adapter/locate.js.map +1 -1
- package/dist/lib/ai-model/workflows/grounding/locate.js +1 -1
- package/dist/lib/ai-model/workflows/grounding/locate.js.map +1 -1
- package/dist/lib/ai-model/workflows/grounding/section-locate.js +1 -1
- package/dist/lib/ai-model/workflows/grounding/section-locate.js.map +1 -1
- package/dist/lib/ai-model/workflows/grounding/utils.js +8 -26
- package/dist/lib/ai-model/workflows/grounding/utils.js.map +1 -1
- package/dist/lib/dump/report-image-export.js +92 -0
- package/dist/lib/dump/report-image-export.js.map +1 -0
- package/dist/lib/dump/screenshot-store.js +5 -0
- package/dist/lib/dump/screenshot-store.js.map +1 -1
- package/dist/lib/report-cli.js +12 -28
- package/dist/lib/report-cli.js.map +1 -1
- package/dist/lib/report-generator.js +22 -8
- package/dist/lib/report-generator.js.map +1 -1
- package/dist/lib/report-html-template.js +1 -1
- package/dist/lib/report-markdown.js +50 -53
- package/dist/lib/report-markdown.js.map +1 -1
- package/dist/lib/report.js +6 -22
- package/dist/lib/report.js.map +1 -1
- package/dist/lib/utils.js +1 -1
- package/dist/types/ai-model/model-adapter/locate-prompt-order.d.ts +24 -0
- package/dist/types/ai-model/model-adapter/locate-prompt-order.d.ts.map +1 -0
- package/dist/types/ai-model/model-adapter/locate.d.ts.map +1 -1
- package/dist/types/ai-model/model-adapter/types.d.ts +9 -3
- package/dist/types/ai-model/model-adapter/types.d.ts.map +1 -1
- package/dist/types/ai-model/workflows/grounding/utils.d.ts +4 -9
- package/dist/types/ai-model/workflows/grounding/utils.d.ts.map +1 -1
- package/dist/types/dump/report-image-export.d.ts +12 -0
- package/dist/types/dump/report-image-export.d.ts.map +1 -0
- package/dist/types/dump/screenshot-store.d.ts +2 -0
- package/dist/types/dump/screenshot-store.d.ts.map +1 -1
- package/dist/types/report-cli.d.ts.map +1 -1
- package/dist/types/report-generator.d.ts +4 -2
- package/dist/types/report-generator.d.ts.map +1 -1
- package/dist/types/report-markdown.d.ts +4 -2
- package/dist/types/report-markdown.d.ts.map +1 -1
- package/dist/types/report.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-model/model-adapter/locate-prompt-order.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/ai-model/model-adapter/locate-prompt-order.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type {\n ConversationSystemMessage,\n ConversationUserMessage,\n MessageContent,\n} from '../service-caller/types';\n\nconst parts = ['instructions', 'screenshot', 'task', 'references'] as const;\ntype Part = (typeof parts)[number];\n\nexport type LocateMessages = (\n | ConversationSystemMessage\n | ConversationUserMessage\n)[];\n\ntype TextPart = Extract<Part, 'instructions' | 'task'>;\ntype PromptGroup =\n | { mode: 'system'; parts: TextPart[] }\n | { mode: 'userTogether' | 'userEach'; parts: Part[] };\n\nexport interface LocatePromptOrder {\n groups: readonly PromptGroup[];\n}\n\nexport function parseLocatePromptOrder(\n order = 'system(instructions):userTogether(screenshot:task):userEach(references)',\n): LocatePromptOrder {\n const groups = order.split(/(?<=\\)):/);\n const remaining = new Set<string>(parts);\n\n function invalid(reason: string): Error {\n return new Error(`Invalid locate promptOrder \"${order}\": ${reason}`);\n }\n\n const promptGroups = groups.map((group): PromptGroup => {\n const match = /^(system|userTogether|userEach)\\(([^()]+)\\)$/.exec(group);\n if (!match) {\n throw invalid(\n `expected system(...), userTogether(...) or userEach(...), got \"${group}\"`,\n );\n }\n const groupParts = match[2].split(':');\n for (const part of groupParts) {\n if (!remaining.delete(part)) {\n throw invalid(`unknown or repeated part \"${part}\"`);\n }\n if (\n match[1] === 'system' &&\n (part === 'screenshot' || part === 'references')\n ) {\n throw invalid(`system cannot contain image part \"${part}\"`);\n }\n }\n if (match[1] === 'system') {\n return { mode: 'system', parts: groupParts as TextPart[] };\n }\n return {\n mode: match[1] as 'userTogether' | 'userEach',\n parts: groupParts as Part[],\n };\n });\n if (remaining.size) {\n throw invalid(`missing ${[...remaining].join(', ')}`);\n }\n return { groups: promptGroups };\n}\n\nexport function buildLocateMessages(\n order: LocatePromptOrder,\n input: {\n instructions: string;\n screenshot: string;\n task: string;\n references: ConversationUserMessage[];\n },\n): LocateMessages {\n const messages: LocateMessages = [];\n for (const group of order.groups) {\n if (group.mode === 'system') {\n messages.push({\n role: 'system',\n content: group.parts.map((part) => input[part]).join('\\n\\n'),\n });\n continue;\n }\n const expanded = group.parts.flatMap((part): ConversationUserMessage[] => {\n if (part === 'references') {\n return input.references;\n }\n const content =\n part === 'screenshot'\n ? [{ type: 'image' as const, url: input.screenshot }]\n : input[part];\n return [{ role: 'user', content }];\n });\n if (group.mode === 'userEach') {\n messages.push(...expanded);\n } else if (expanded.length) {\n const content = expanded.flatMap((message): MessageContent[] =>\n typeof message.content === 'string'\n ? [{ type: 'text', text: message.content }]\n : message.content,\n );\n messages.push({ role: 'user', content });\n }\n }\n return messages;\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","parts","parseLocatePromptOrder","order","groups","remaining","Set","invalid","reason","Error","promptGroups","group","match","groupParts","part","buildLocateMessages","input","messages","expanded","content","message"],"mappings":"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"}
|
|
@@ -29,6 +29,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
29
29
|
const factory_js_namespaceObject = require("../shared/model-locate-result/factory.js");
|
|
30
30
|
const planning_action_locate_js_namespaceObject = require("../workflows/grounding/planning-action-locate.js");
|
|
31
31
|
const external_default_locate_protocol_js_namespaceObject = require("./default-locate-protocol.js");
|
|
32
|
+
const external_locate_prompt_order_js_namespaceObject = require("./locate-prompt-order.js");
|
|
32
33
|
const defaultLocateResultFormatDefinition = {
|
|
33
34
|
coordinates: {
|
|
34
35
|
shape: 'bbox',
|
|
@@ -59,7 +60,7 @@ function resolveLocate(locate, resolvedCustomPlanner, protocolContext) {
|
|
|
59
60
|
const searchAreaResultCodec = searchAreaResultFormat ? (0, factory_js_namespaceObject.createLocateResultCodec)(searchAreaResultFormat) : void 0;
|
|
60
61
|
return {
|
|
61
62
|
kind: 'standard',
|
|
62
|
-
|
|
63
|
+
promptOrder: (0, external_locate_prompt_order_js_namespaceObject.parseLocatePromptOrder)(locate?.promptOrder),
|
|
63
64
|
element: {
|
|
64
65
|
protocol: elementProtocol,
|
|
65
66
|
resultCodec: elementResultCodec
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/model-adapter/locate.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/ai-model/model-adapter/locate.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { createLocateResultCodec } from '../shared/model-locate-result/factory';\nimport type { LocateResultFormatDefinition } from '../shared/model-locate-result/types';\nimport { resolvePlanningTapLocator } from '../workflows/grounding/planning-action-locate';\nimport type { ResolvedCustomPlanningDefinition } from './custom-planning-types';\nimport {\n createDefaultElementProtocol,\n createDefaultSearchAreaProtocol,\n} from './default-locate-protocol';\nimport type {\n StandardLocateProtocolContext,\n StandardLocateProtocolDefinition,\n} from './locate-protocol';\nimport type { LocateAdapter, ModelAdapterDefinition } from './types';\n\nconst defaultLocateResultFormatDefinition: LocateResultFormatDefinition = {\n coordinates: { shape: 'bbox', order: 'xy', normalizedBy: 1000 },\n};\n\nconst resolveLocateProtocolDefinition = (\n protocolDefinition: StandardLocateProtocolDefinition,\n protocolContext: StandardLocateProtocolContext,\n) =>\n typeof protocolDefinition === 'function'\n ? protocolDefinition(protocolContext)\n : protocolDefinition;\n\nexport function resolveLocate(\n locate: ModelAdapterDefinition['locate'],\n resolvedCustomPlanner: ResolvedCustomPlanningDefinition | undefined,\n protocolContext: StandardLocateProtocolContext,\n): LocateAdapter {\n if (locate?.kind === 'custom') {\n let locateFn = locate.locateFn;\n\n if (!locateFn) {\n const planningTapLocator = locate.planningTapLocator;\n\n if (!planningTapLocator) {\n throw new Error(\n 'Custom locate definition requires either locateFn or planningTapLocator',\n );\n }\n\n if (!resolvedCustomPlanner) {\n throw new Error(\n 'Custom planning tap locator requires a custom planning planner definition',\n );\n }\n locateFn = resolvePlanningTapLocator(\n planningTapLocator,\n resolvedCustomPlanner,\n );\n }\n\n return {\n kind: 'custom',\n locateFn,\n };\n }\n\n const elementProtocol = resolveLocateProtocolDefinition(\n locate?.element?.protocol ?? createDefaultElementProtocol,\n protocolContext,\n );\n const elementResultFormat =\n locate?.element?.resultFormat ?? defaultLocateResultFormatDefinition;\n const elementResultCodec = createLocateResultCodec(elementResultFormat);\n const searchAreaProtocol =\n locate?.searchArea === false\n ? undefined\n : resolveLocateProtocolDefinition(\n locate?.searchArea?.protocol ?? createDefaultSearchAreaProtocol,\n protocolContext,\n );\n const searchAreaResultFormat =\n locate?.searchArea === false\n ? undefined\n : (locate?.searchArea?.resultFormat ?? elementResultFormat);\n const searchAreaResultCodec = searchAreaResultFormat\n ? createLocateResultCodec(searchAreaResultFormat)\n : undefined;\n\n return {\n kind: 'standard',\n
|
|
1
|
+
{"version":3,"file":"ai-model/model-adapter/locate.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/ai-model/model-adapter/locate.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { createLocateResultCodec } from '../shared/model-locate-result/factory';\nimport type { LocateResultFormatDefinition } from '../shared/model-locate-result/types';\nimport { resolvePlanningTapLocator } from '../workflows/grounding/planning-action-locate';\nimport type { ResolvedCustomPlanningDefinition } from './custom-planning-types';\nimport {\n createDefaultElementProtocol,\n createDefaultSearchAreaProtocol,\n} from './default-locate-protocol';\nimport { parseLocatePromptOrder } from './locate-prompt-order';\nimport type {\n StandardLocateProtocolContext,\n StandardLocateProtocolDefinition,\n} from './locate-protocol';\nimport type { LocateAdapter, ModelAdapterDefinition } from './types';\n\nconst defaultLocateResultFormatDefinition: LocateResultFormatDefinition = {\n coordinates: { shape: 'bbox', order: 'xy', normalizedBy: 1000 },\n};\n\nconst resolveLocateProtocolDefinition = (\n protocolDefinition: StandardLocateProtocolDefinition,\n protocolContext: StandardLocateProtocolContext,\n) =>\n typeof protocolDefinition === 'function'\n ? protocolDefinition(protocolContext)\n : protocolDefinition;\n\nexport function resolveLocate(\n locate: ModelAdapterDefinition['locate'],\n resolvedCustomPlanner: ResolvedCustomPlanningDefinition | undefined,\n protocolContext: StandardLocateProtocolContext,\n): LocateAdapter {\n if (locate?.kind === 'custom') {\n let locateFn = locate.locateFn;\n\n if (!locateFn) {\n const planningTapLocator = locate.planningTapLocator;\n\n if (!planningTapLocator) {\n throw new Error(\n 'Custom locate definition requires either locateFn or planningTapLocator',\n );\n }\n\n if (!resolvedCustomPlanner) {\n throw new Error(\n 'Custom planning tap locator requires a custom planning planner definition',\n );\n }\n locateFn = resolvePlanningTapLocator(\n planningTapLocator,\n resolvedCustomPlanner,\n );\n }\n\n return {\n kind: 'custom',\n locateFn,\n };\n }\n\n const elementProtocol = resolveLocateProtocolDefinition(\n locate?.element?.protocol ?? createDefaultElementProtocol,\n protocolContext,\n );\n const elementResultFormat =\n locate?.element?.resultFormat ?? defaultLocateResultFormatDefinition;\n const elementResultCodec = createLocateResultCodec(elementResultFormat);\n const searchAreaProtocol =\n locate?.searchArea === false\n ? undefined\n : resolveLocateProtocolDefinition(\n locate?.searchArea?.protocol ?? createDefaultSearchAreaProtocol,\n protocolContext,\n );\n const searchAreaResultFormat =\n locate?.searchArea === false\n ? undefined\n : (locate?.searchArea?.resultFormat ?? elementResultFormat);\n const searchAreaResultCodec = searchAreaResultFormat\n ? createLocateResultCodec(searchAreaResultFormat)\n : undefined;\n\n return {\n kind: 'standard',\n promptOrder: parseLocatePromptOrder(locate?.promptOrder),\n element: {\n protocol: elementProtocol,\n resultCodec: elementResultCodec,\n },\n ...(searchAreaProtocol && searchAreaResultCodec\n ? {\n searchArea: {\n protocol: searchAreaProtocol,\n resultCodec: searchAreaResultCodec,\n },\n }\n : {}),\n };\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","defaultLocateResultFormatDefinition","resolveLocateProtocolDefinition","protocolDefinition","protocolContext","resolveLocate","locate","resolvedCustomPlanner","locateFn","planningTapLocator","Error","resolvePlanningTapLocator","elementProtocol","createDefaultElementProtocol","elementResultFormat","elementResultCodec","createLocateResultCodec","searchAreaProtocol","undefined","createDefaultSearchAreaProtocol","searchAreaResultFormat","searchAreaResultCodec","parseLocatePromptOrder"],"mappings":";;;IAAAA,oBAAoB,CAAC,GAAG,CAAC,UAASC;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGD,oBAAoB,CAAC,CAACC,YAAYC,QAAQ,CAACF,oBAAoB,CAAC,CAAC,UAASE,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAF,oBAAoB,CAAC,GAAG,CAACI,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFL,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,eAAlB,OAAOM,UAA0BA,OAAO,WAAW,EACrDH,OAAO,cAAc,CAAC,UAASG,OAAO,WAAW,EAAE;YAAE,OAAO;QAAS;QAEtEH,OAAO,cAAc,CAAC,UAAS,cAAc;YAAE,OAAO;QAAK;IAC5D;;;;;;;;;;;ACSA,MAAMI,sCAAoE;IACxE,aAAa;QAAE,OAAO;QAAQ,OAAO;QAAM,cAAc;IAAK;AAChE;AAEA,MAAMC,kCAAkC,CACtCC,oBACAC,kBAEA,AAA8B,cAA9B,OAAOD,qBACHA,mBAAmBC,mBACnBD;AAEC,SAASE,cACdC,MAAwC,EACxCC,qBAAmE,EACnEH,eAA8C;IAE9C,IAAIE,QAAQ,SAAS,UAAU;QAC7B,IAAIE,WAAWF,OAAO,QAAQ;QAE9B,IAAI,CAACE,UAAU;YACb,MAAMC,qBAAqBH,OAAO,kBAAkB;YAEpD,IAAI,CAACG,oBACH,MAAM,IAAIC,MACR;YAIJ,IAAI,CAACH,uBACH,MAAM,IAAIG,MACR;YAGJF,WAAWG,AAAAA,IAAAA,0CAAAA,yBAAAA,AAAAA,EACTF,oBACAF;QAEJ;QAEA,OAAO;YACL,MAAM;YACNC;QACF;IACF;IAEA,MAAMI,kBAAkBV,gCACtBI,QAAQ,SAAS,YAAYO,oDAAAA,4BAA4BA,EACzDT;IAEF,MAAMU,sBACJR,QAAQ,SAAS,gBAAgBL;IACnC,MAAMc,qBAAqBC,AAAAA,IAAAA,2BAAAA,uBAAAA,AAAAA,EAAwBF;IACnD,MAAMG,qBACJX,QAAQ,eAAe,QACnBY,SACAhB,gCACEI,QAAQ,YAAY,YAAYa,oDAAAA,+BAA+BA,EAC/Df;IAER,MAAMgB,yBACJd,QAAQ,eAAe,QACnBY,SACCZ,QAAQ,YAAY,gBAAgBQ;IAC3C,MAAMO,wBAAwBD,yBAC1BJ,AAAAA,IAAAA,2BAAAA,uBAAAA,AAAAA,EAAwBI,0BACxBF;IAEJ,OAAO;QACL,MAAM;QACN,aAAaI,AAAAA,IAAAA,gDAAAA,sBAAAA,AAAAA,EAAuBhB,QAAQ;QAC5C,SAAS;YACP,UAAUM;YACV,aAAaG;QACf;QACA,GAAIE,sBAAsBI,wBACtB;YACE,YAAY;gBACV,UAAUJ;gBACV,aAAaI;YACf;QACF,IACA,CAAC,CAAC;IACR;AACF"}
|
|
@@ -114,7 +114,7 @@ async function genericLocate(locateRequest) {
|
|
|
114
114
|
locateImage: locateRequest.locateImage,
|
|
115
115
|
imagePreprocess: adapter.imagePreprocess,
|
|
116
116
|
targetDescription: targetElementDescription,
|
|
117
|
-
|
|
117
|
+
promptOrder: adapter.locate.promptOrder
|
|
118
118
|
});
|
|
119
119
|
try {
|
|
120
120
|
return await (0, semantic_retry_js_namespaceObject.callAiAndParseWithRetry)({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/workflows/grounding/locate.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../../src/ai-model/workflows/grounding/locate.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\nimport type { TUserPrompt } from '../../../common';\nimport { userPromptToString } from '../../../common';\nimport { buildElementLocateSystemPrompt } from '../../prompt/locate';\nimport {\n AIResponseParseError,\n callGenerativeAI,\n} from '../../service-caller/index';\nimport {\n callAiAndParseWithRetry,\n withSemanticRetryFeedback,\n} from '../../service-caller/semantic-retry';\nimport { mapSearchAreaResultToOriginalResult } from './search-area-mapping';\nimport type {\n LocateModelResponse,\n LocateOptions,\n LocateRequest,\n LocateResult,\n} from './types';\nimport { formatLocateModelContext, prepareLocateModelInput } from './utils';\n\nconst debugGrounding = getDebug('ai:grounding');\n\nexport { userPromptToString as extraTextFromUserPrompt } from '../../../common';\n\nexport async function AiLocateElement(\n options: LocateOptions & { targetElementDescription: TUserPrompt },\n): Promise<LocateResult> {\n const { targetElementDescription, ...locateOptions } = options;\n assert(\n targetElementDescription,\n 'cannot find the target element description',\n );\n\n const { context } = locateOptions;\n const locateImage = locateOptions.searchConfig?.image ?? {\n imageBase64: context.screenshot.base64,\n width: context.shotSize.width,\n height: context.shotSize.height,\n };\n const locateRequest: LocateRequest = {\n targetElementDescription,\n locateImage,\n options: locateOptions,\n };\n\n const locateAdapter = options.modelRuntime.adapter.locate;\n const locateFn =\n locateAdapter.kind === 'custom' ? locateAdapter.locateFn : genericLocate;\n const locateResponse = await locateFn(locateRequest);\n const {\n locatedPixelResult,\n rawResponse,\n rawAssistantOutput,\n usage,\n reasoningContent,\n errors = [],\n } = locateResponse;\n const baseLocateResult = {\n rawResponse,\n rawAssistantOutput,\n usage,\n reasoning_content: reasoningContent,\n };\n\n if (!locatedPixelResult) {\n return {\n parseResult: {\n element: undefined,\n errors,\n },\n ...baseLocateResult,\n };\n }\n\n try {\n const mappedResult = mapSearchAreaResultToOriginalResult(\n locatedPixelResult,\n locateOptions.searchConfig?.mapping,\n );\n debugGrounding('center', mappedResult.center);\n\n return {\n parseResult: {\n element: {\n ...mappedResult,\n description: userPromptToString(targetElementDescription),\n },\n errors: [],\n },\n ...baseLocateResult,\n };\n } catch (error) {\n const msg =\n error instanceof Error\n ? `Failed to parse locate result: ${error.message}`\n : 'unknown error in locate';\n return {\n parseResult: {\n element: undefined,\n errors: errors.length > 0 ? [...errors, `(${msg})`] : [msg],\n },\n ...baseLocateResult,\n };\n }\n}\n\nexport async function genericLocate(\n locateRequest: LocateRequest,\n): Promise<LocateModelResponse> {\n const { options, targetElementDescription } = locateRequest;\n const modelRuntime = options.modelRuntime;\n const { adapter } = modelRuntime;\n assert(\n adapter.locate.kind === 'standard',\n 'generic locate requires a standard locate adapter',\n );\n const { protocol, resultCodec } = adapter.locate.element;\n\n const systemPrompt = buildElementLocateSystemPrompt({\n systemPromptIntroduction: protocol.systemPromptIntroduction,\n responseInstructions: protocol.buildResponseInstructions(\n resultCodec.promptSpec,\n ),\n });\n\n const userInstructionPrompt = protocol.buildUserPrompt(\n userPromptToString(targetElementDescription),\n );\n\n const { messages, preparedImage } = await prepareLocateModelInput({\n systemPrompt,\n userPrompt: userInstructionPrompt,\n locateImage: locateRequest.locateImage,\n imagePreprocess: adapter.imagePreprocess,\n targetDescription: targetElementDescription,\n userMessageContentOrder: adapter.locate.userMessageContentOrder,\n });\n\n try {\n return await callAiAndParseWithRetry({\n callAi: (retryAttempt, previousParseError) =>\n callGenerativeAI(\n withSemanticRetryFeedback(messages, previousParseError),\n modelRuntime,\n {\n abortSignal: options.abortSignal,\n expectedJsonObjectResponse: protocol.expectedJsonObjectResponse,\n semanticRetryAttempt: retryAttempt,\n },\n ),\n parseResponse: (response): LocateModelResponse => {\n const parsedLocateResult = protocol.parseRawResponse(\n response.content,\n resultCodec.promptSpec,\n );\n const rawResponse = response.content;\n const locateError = parsedLocateResult.error;\n if (parsedLocateResult.kind === 'not-found') {\n return {\n rawResponse,\n rawAssistantOutput: response.rawAssistantOutput,\n usage: response.usage,\n reasoningContent: response.reasoning_content,\n errors: locateError ? [locateError] : [],\n };\n }\n\n try {\n const result = resultCodec.toPixelResult(parsedLocateResult.target, {\n preparedSize: preparedImage.preparedSize,\n contentSize: preparedImage.contentSize,\n });\n return {\n locatedPixelResult: result,\n rawResponse,\n rawAssistantOutput: response.rawAssistantOutput,\n usage: response.usage,\n reasoningContent: response.reasoning_content,\n errors: [],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n const message = [\n locateError && `error in locate result: ${locateError}`,\n `coordinate parsing error: ${errorMessage}`,\n formatLocateModelContext(modelRuntime),\n ]\n .filter(Boolean)\n .join('\\n');\n throw new Error(message, { cause: error });\n }\n },\n toParseError: (error, response) => {\n const parseErrorMessage =\n error instanceof Error\n ? `Failed to parse locate result: ${error.message}`\n : 'unknown error in locate result';\n return new AIResponseParseError(\n parseErrorMessage,\n response.content,\n response.usage,\n response.rawAssistantOutput,\n response.reasoning_content,\n );\n },\n parseRetryTimes: modelRuntime.config.retryCount,\n parseRetryInterval: modelRuntime.config.retryInterval,\n abortSignal: options.abortSignal,\n onParseRetry: (error) => {\n debugGrounding(\n 'retrying locate after coordinate parsing failed: %s',\n error instanceof Error ? error.message : String(error),\n );\n },\n });\n } catch (callError) {\n if (callError instanceof AIResponseParseError) {\n return {\n rawResponse: callError.rawResponse,\n rawAssistantOutput: callError.rawAssistantOutput,\n usage: callError.usage,\n reasoningContent: callError.reasoningContent,\n errors: [callError.message],\n };\n }\n\n const errorMessage =\n callError instanceof Error ? callError.message : String(callError);\n return {\n rawResponse: errorMessage,\n errors: [`AI call error: ${errorMessage}`],\n };\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","debugGrounding","getDebug","AiLocateElement","options","targetElementDescription","locateOptions","assert","context","locateImage","locateRequest","locateAdapter","locateFn","genericLocate","locateResponse","locatedPixelResult","rawResponse","rawAssistantOutput","usage","reasoningContent","errors","baseLocateResult","undefined","mappedResult","mapSearchAreaResultToOriginalResult","userPromptToString","error","msg","Error","modelRuntime","adapter","protocol","resultCodec","systemPrompt","buildElementLocateSystemPrompt","userInstructionPrompt","messages","preparedImage","prepareLocateModelInput","callAiAndParseWithRetry","retryAttempt","previousParseError","callGenerativeAI","withSemanticRetryFeedback","response","parsedLocateResult","locateError","result","errorMessage","String","message","formatLocateModelContext","Boolean","parseErrorMessage","AIResponseParseError","callError"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ai-model/workflows/grounding/locate.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../../src/ai-model/workflows/grounding/locate.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\nimport type { TUserPrompt } from '../../../common';\nimport { userPromptToString } from '../../../common';\nimport { buildElementLocateSystemPrompt } from '../../prompt/locate';\nimport {\n AIResponseParseError,\n callGenerativeAI,\n} from '../../service-caller/index';\nimport {\n callAiAndParseWithRetry,\n withSemanticRetryFeedback,\n} from '../../service-caller/semantic-retry';\nimport { mapSearchAreaResultToOriginalResult } from './search-area-mapping';\nimport type {\n LocateModelResponse,\n LocateOptions,\n LocateRequest,\n LocateResult,\n} from './types';\nimport { formatLocateModelContext, prepareLocateModelInput } from './utils';\n\nconst debugGrounding = getDebug('ai:grounding');\n\nexport { userPromptToString as extraTextFromUserPrompt } from '../../../common';\n\nexport async function AiLocateElement(\n options: LocateOptions & { targetElementDescription: TUserPrompt },\n): Promise<LocateResult> {\n const { targetElementDescription, ...locateOptions } = options;\n assert(\n targetElementDescription,\n 'cannot find the target element description',\n );\n\n const { context } = locateOptions;\n const locateImage = locateOptions.searchConfig?.image ?? {\n imageBase64: context.screenshot.base64,\n width: context.shotSize.width,\n height: context.shotSize.height,\n };\n const locateRequest: LocateRequest = {\n targetElementDescription,\n locateImage,\n options: locateOptions,\n };\n\n const locateAdapter = options.modelRuntime.adapter.locate;\n const locateFn =\n locateAdapter.kind === 'custom' ? locateAdapter.locateFn : genericLocate;\n const locateResponse = await locateFn(locateRequest);\n const {\n locatedPixelResult,\n rawResponse,\n rawAssistantOutput,\n usage,\n reasoningContent,\n errors = [],\n } = locateResponse;\n const baseLocateResult = {\n rawResponse,\n rawAssistantOutput,\n usage,\n reasoning_content: reasoningContent,\n };\n\n if (!locatedPixelResult) {\n return {\n parseResult: {\n element: undefined,\n errors,\n },\n ...baseLocateResult,\n };\n }\n\n try {\n const mappedResult = mapSearchAreaResultToOriginalResult(\n locatedPixelResult,\n locateOptions.searchConfig?.mapping,\n );\n debugGrounding('center', mappedResult.center);\n\n return {\n parseResult: {\n element: {\n ...mappedResult,\n description: userPromptToString(targetElementDescription),\n },\n errors: [],\n },\n ...baseLocateResult,\n };\n } catch (error) {\n const msg =\n error instanceof Error\n ? `Failed to parse locate result: ${error.message}`\n : 'unknown error in locate';\n return {\n parseResult: {\n element: undefined,\n errors: errors.length > 0 ? [...errors, `(${msg})`] : [msg],\n },\n ...baseLocateResult,\n };\n }\n}\n\nexport async function genericLocate(\n locateRequest: LocateRequest,\n): Promise<LocateModelResponse> {\n const { options, targetElementDescription } = locateRequest;\n const modelRuntime = options.modelRuntime;\n const { adapter } = modelRuntime;\n assert(\n adapter.locate.kind === 'standard',\n 'generic locate requires a standard locate adapter',\n );\n const { protocol, resultCodec } = adapter.locate.element;\n\n const systemPrompt = buildElementLocateSystemPrompt({\n systemPromptIntroduction: protocol.systemPromptIntroduction,\n responseInstructions: protocol.buildResponseInstructions(\n resultCodec.promptSpec,\n ),\n });\n\n const userInstructionPrompt = protocol.buildUserPrompt(\n userPromptToString(targetElementDescription),\n );\n\n const { messages, preparedImage } = await prepareLocateModelInput({\n systemPrompt,\n userPrompt: userInstructionPrompt,\n locateImage: locateRequest.locateImage,\n imagePreprocess: adapter.imagePreprocess,\n targetDescription: targetElementDescription,\n promptOrder: adapter.locate.promptOrder,\n });\n\n try {\n return await callAiAndParseWithRetry({\n callAi: (retryAttempt, previousParseError) =>\n callGenerativeAI(\n withSemanticRetryFeedback(messages, previousParseError),\n modelRuntime,\n {\n abortSignal: options.abortSignal,\n expectedJsonObjectResponse: protocol.expectedJsonObjectResponse,\n semanticRetryAttempt: retryAttempt,\n },\n ),\n parseResponse: (response): LocateModelResponse => {\n const parsedLocateResult = protocol.parseRawResponse(\n response.content,\n resultCodec.promptSpec,\n );\n const rawResponse = response.content;\n const locateError = parsedLocateResult.error;\n if (parsedLocateResult.kind === 'not-found') {\n return {\n rawResponse,\n rawAssistantOutput: response.rawAssistantOutput,\n usage: response.usage,\n reasoningContent: response.reasoning_content,\n errors: locateError ? [locateError] : [],\n };\n }\n\n try {\n const result = resultCodec.toPixelResult(parsedLocateResult.target, {\n preparedSize: preparedImage.preparedSize,\n contentSize: preparedImage.contentSize,\n });\n return {\n locatedPixelResult: result,\n rawResponse,\n rawAssistantOutput: response.rawAssistantOutput,\n usage: response.usage,\n reasoningContent: response.reasoning_content,\n errors: [],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n const message = [\n locateError && `error in locate result: ${locateError}`,\n `coordinate parsing error: ${errorMessage}`,\n formatLocateModelContext(modelRuntime),\n ]\n .filter(Boolean)\n .join('\\n');\n throw new Error(message, { cause: error });\n }\n },\n toParseError: (error, response) => {\n const parseErrorMessage =\n error instanceof Error\n ? `Failed to parse locate result: ${error.message}`\n : 'unknown error in locate result';\n return new AIResponseParseError(\n parseErrorMessage,\n response.content,\n response.usage,\n response.rawAssistantOutput,\n response.reasoning_content,\n );\n },\n parseRetryTimes: modelRuntime.config.retryCount,\n parseRetryInterval: modelRuntime.config.retryInterval,\n abortSignal: options.abortSignal,\n onParseRetry: (error) => {\n debugGrounding(\n 'retrying locate after coordinate parsing failed: %s',\n error instanceof Error ? error.message : String(error),\n );\n },\n });\n } catch (callError) {\n if (callError instanceof AIResponseParseError) {\n return {\n rawResponse: callError.rawResponse,\n rawAssistantOutput: callError.rawAssistantOutput,\n usage: callError.usage,\n reasoningContent: callError.reasoningContent,\n errors: [callError.message],\n };\n }\n\n const errorMessage =\n callError instanceof Error ? callError.message : String(callError);\n return {\n rawResponse: errorMessage,\n errors: [`AI call error: ${errorMessage}`],\n };\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","debugGrounding","getDebug","AiLocateElement","options","targetElementDescription","locateOptions","assert","context","locateImage","locateRequest","locateAdapter","locateFn","genericLocate","locateResponse","locatedPixelResult","rawResponse","rawAssistantOutput","usage","reasoningContent","errors","baseLocateResult","undefined","mappedResult","mapSearchAreaResultToOriginalResult","userPromptToString","error","msg","Error","modelRuntime","adapter","protocol","resultCodec","systemPrompt","buildElementLocateSystemPrompt","userInstructionPrompt","messages","preparedImage","prepareLocateModelInput","callAiAndParseWithRetry","retryAttempt","previousParseError","callGenerativeAI","withSemanticRetryFeedback","response","parsedLocateResult","locateError","result","errorMessage","String","message","formatLocateModelContext","Boolean","parseErrorMessage","AIResponseParseError","callError"],"mappings":"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"}
|
|
@@ -59,7 +59,7 @@ async function AiLocateSection(options) {
|
|
|
59
59
|
},
|
|
60
60
|
imagePreprocess: adapter.imagePreprocess,
|
|
61
61
|
targetDescription: sectionDescription,
|
|
62
|
-
|
|
62
|
+
promptOrder: adapter.locate.promptOrder
|
|
63
63
|
});
|
|
64
64
|
let parsedResult;
|
|
65
65
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/workflows/grounding/section-locate.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../../src/ai-model/workflows/grounding/section-locate.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type { RawAssistantOutput } from '@/types';\nimport type { AIUsageInfo, Rect, UIContext } from '@/types';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\nimport type { TUserPrompt } from '../../../common';\nimport { userPromptToString } from '../../../common';\nimport type { ModelRuntime } from '../../models';\nimport { buildSearchAreaLocateSystemPrompt } from '../../prompt/locate';\nimport {\n AIResponseParseError,\n callGenerativeAI,\n} from '../../service-caller/index';\nimport {\n callAiAndParseWithRetry,\n withSemanticRetryFeedback,\n} from '../../service-caller/semantic-retry';\nimport {\n buildSearchAreaConfig,\n expandSearchArea,\n mergeSearchAreaResults,\n} from './search-area';\nimport type { SearchAreaConfig } from './types';\nimport { formatLocateModelContext, prepareLocateModelInput } from './utils';\n\nconst debugSection = getDebug('ai:grounding:section');\n\ntype SectionLocateRawResponse = Awaited<ReturnType<typeof callGenerativeAI>>;\n\nexport async function AiLocateSection(options: {\n context: UIContext;\n sectionDescription: TUserPrompt;\n modelRuntime: ModelRuntime;\n abortSignal?: AbortSignal;\n}): Promise<{\n searchAreaConfig?: SearchAreaConfig;\n error?: string;\n rawResponse: string;\n rawAssistantOutput?: RawAssistantOutput;\n usage?: AIUsageInfo;\n}> {\n const { context, sectionDescription } = options;\n const modelRuntime = options.modelRuntime;\n const { adapter } = modelRuntime;\n assert(\n adapter.locate.kind === 'standard',\n 'section locate requires a standard locate adapter',\n );\n const searchArea = adapter.locate.searchArea;\n assert(searchArea, 'section locate requires a search area operation');\n const { protocol: searchAreaProtocol, resultCodec } = searchArea;\n const screenshotBase64 = context.screenshot.base64;\n\n const systemPrompt = buildSearchAreaLocateSystemPrompt({\n systemPromptIntroduction: searchAreaProtocol.systemPromptIntroduction,\n responseInstructions: searchAreaProtocol.buildResponseInstructions(\n resultCodec.promptSpec,\n ),\n });\n\n const userInstructionPrompt = searchAreaProtocol.buildUserPrompt(\n userPromptToString(sectionDescription),\n );\n\n const { messages, preparedImage } = await prepareLocateModelInput({\n systemPrompt,\n userPrompt: userInstructionPrompt,\n locateImage: {\n imageBase64: screenshotBase64,\n width: context.shotSize.width,\n height: context.shotSize.height,\n },\n imagePreprocess: adapter.imagePreprocess,\n targetDescription: sectionDescription,\n userMessageContentOrder: adapter.locate.userMessageContentOrder,\n });\n\n let parsedResult:\n | {\n result: SectionLocateRawResponse;\n sectionError?: string;\n mergedRect?: undefined;\n }\n | {\n result: SectionLocateRawResponse;\n sectionError?: string;\n mergedRect: Rect;\n };\n\n try {\n parsedResult = await callAiAndParseWithRetry({\n callAi: (retryAttempt, previousParseError) =>\n callGenerativeAI(\n withSemanticRetryFeedback(messages, previousParseError),\n modelRuntime,\n {\n abortSignal: options.abortSignal,\n expectedJsonObjectResponse:\n searchAreaProtocol.expectedJsonObjectResponse,\n semanticRetryAttempt: retryAttempt,\n },\n ),\n parseResponse: (response) => {\n const parsedLocateResult = searchAreaProtocol.parseRawResponse(\n response.content,\n resultCodec.promptSpec,\n );\n const sectionError = parsedLocateResult.error;\n if (parsedLocateResult.kind === 'not-found') {\n return { result: response, sectionError };\n }\n\n try {\n const locateResultContext = {\n preparedSize: preparedImage.preparedSize,\n contentSize: preparedImage.contentSize,\n };\n const target = resultCodec.toPixelResult(\n parsedLocateResult.target,\n locateResultContext,\n );\n const references = parsedLocateResult.references?.map((reference) =>\n resultCodec.toPixelResult(reference, locateResultContext),\n );\n const mergedRect = mergeSearchAreaResults(target, references);\n debugSection('mergedRect %j', mergedRect);\n return {\n result: response,\n sectionError,\n mergedRect,\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n const message = [\n sectionError && `error in section locate result: ${sectionError}`,\n `coordinate parsing error: ${errorMessage}`,\n formatLocateModelContext(modelRuntime),\n ]\n .filter(Boolean)\n .join('\\n');\n throw new Error(message, { cause: error });\n }\n },\n toParseError: (error, response) => {\n const parseErrorMessage =\n error instanceof Error\n ? `Failed to parse section locate result: ${error.message}`\n : 'unknown error in section locate';\n return new AIResponseParseError(\n parseErrorMessage,\n response.content,\n response.usage,\n response.rawAssistantOutput,\n response.reasoning_content,\n );\n },\n parseRetryTimes: modelRuntime.config.retryCount,\n parseRetryInterval: modelRuntime.config.retryInterval,\n abortSignal: options.abortSignal,\n onParseRetry: (error) => {\n debugSection(\n 'retrying section locate after coordinate parsing failed: %s',\n error instanceof Error ? error.message : String(error),\n );\n },\n });\n } catch (callError) {\n if (callError instanceof AIResponseParseError) {\n return {\n searchAreaConfig: undefined,\n error: callError.message,\n rawResponse: callError.rawResponse,\n rawAssistantOutput: callError.rawAssistantOutput,\n usage: callError.usage,\n };\n }\n\n const errorMessage =\n callError instanceof Error ? callError.message : String(callError);\n return {\n searchAreaConfig: undefined,\n error: `AI call error: ${errorMessage}`,\n rawResponse: errorMessage,\n };\n }\n\n const { result, sectionError, mergedRect } = parsedResult;\n if (!mergedRect) {\n return {\n searchAreaConfig: undefined,\n error: sectionError,\n rawResponse: result.content,\n rawAssistantOutput: result.rawAssistantOutput,\n usage: result.usage,\n };\n }\n\n try {\n const expandedRect = expandSearchArea(mergedRect, context.shotSize);\n const originalWidth = expandedRect.width;\n const originalHeight = expandedRect.height;\n debugSection('expanded sectionRect %j', expandedRect);\n\n const searchAreaConfig = await buildSearchAreaConfig({\n context,\n baseRect: mergedRect,\n });\n\n debugSection(\n 'scaled section image from %dx%d to %dx%d (scale=%d)',\n originalWidth,\n originalHeight,\n searchAreaConfig.image.width,\n searchAreaConfig.image.height,\n searchAreaConfig.mapping.scale,\n );\n return {\n searchAreaConfig,\n error: sectionError,\n rawResponse: result.content,\n rawAssistantOutput: result.rawAssistantOutput,\n usage: result.usage,\n };\n } catch (error) {\n const parseErrorMessage =\n error instanceof Error\n ? `Failed to parse section locate result: ${error.message}`\n : 'unknown error in section locate';\n const errorMessage = sectionError\n ? `${sectionError} (${parseErrorMessage})`\n : parseErrorMessage;\n return {\n searchAreaConfig: undefined,\n error: errorMessage,\n rawResponse: result.content,\n rawAssistantOutput: result.rawAssistantOutput,\n usage: result.usage,\n };\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","debugSection","getDebug","AiLocateSection","options","context","sectionDescription","modelRuntime","adapter","assert","searchArea","searchAreaProtocol","resultCodec","screenshotBase64","systemPrompt","buildSearchAreaLocateSystemPrompt","userInstructionPrompt","userPromptToString","messages","preparedImage","prepareLocateModelInput","parsedResult","callAiAndParseWithRetry","retryAttempt","previousParseError","callGenerativeAI","withSemanticRetryFeedback","response","parsedLocateResult","sectionError","locateResultContext","target","references","reference","mergedRect","mergeSearchAreaResults","error","errorMessage","Error","String","message","formatLocateModelContext","Boolean","parseErrorMessage","AIResponseParseError","callError","undefined","result","expandedRect","expandSearchArea","originalWidth","originalHeight","searchAreaConfig","buildSearchAreaConfig"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ai-model/workflows/grounding/section-locate.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../../src/ai-model/workflows/grounding/section-locate.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type { RawAssistantOutput } from '@/types';\nimport type { AIUsageInfo, Rect, UIContext } from '@/types';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\nimport type { TUserPrompt } from '../../../common';\nimport { userPromptToString } from '../../../common';\nimport type { ModelRuntime } from '../../models';\nimport { buildSearchAreaLocateSystemPrompt } from '../../prompt/locate';\nimport {\n AIResponseParseError,\n callGenerativeAI,\n} from '../../service-caller/index';\nimport {\n callAiAndParseWithRetry,\n withSemanticRetryFeedback,\n} from '../../service-caller/semantic-retry';\nimport {\n buildSearchAreaConfig,\n expandSearchArea,\n mergeSearchAreaResults,\n} from './search-area';\nimport type { SearchAreaConfig } from './types';\nimport { formatLocateModelContext, prepareLocateModelInput } from './utils';\n\nconst debugSection = getDebug('ai:grounding:section');\n\ntype SectionLocateRawResponse = Awaited<ReturnType<typeof callGenerativeAI>>;\n\nexport async function AiLocateSection(options: {\n context: UIContext;\n sectionDescription: TUserPrompt;\n modelRuntime: ModelRuntime;\n abortSignal?: AbortSignal;\n}): Promise<{\n searchAreaConfig?: SearchAreaConfig;\n error?: string;\n rawResponse: string;\n rawAssistantOutput?: RawAssistantOutput;\n usage?: AIUsageInfo;\n}> {\n const { context, sectionDescription } = options;\n const modelRuntime = options.modelRuntime;\n const { adapter } = modelRuntime;\n assert(\n adapter.locate.kind === 'standard',\n 'section locate requires a standard locate adapter',\n );\n const searchArea = adapter.locate.searchArea;\n assert(searchArea, 'section locate requires a search area operation');\n const { protocol: searchAreaProtocol, resultCodec } = searchArea;\n const screenshotBase64 = context.screenshot.base64;\n\n const systemPrompt = buildSearchAreaLocateSystemPrompt({\n systemPromptIntroduction: searchAreaProtocol.systemPromptIntroduction,\n responseInstructions: searchAreaProtocol.buildResponseInstructions(\n resultCodec.promptSpec,\n ),\n });\n\n const userInstructionPrompt = searchAreaProtocol.buildUserPrompt(\n userPromptToString(sectionDescription),\n );\n\n const { messages, preparedImage } = await prepareLocateModelInput({\n systemPrompt,\n userPrompt: userInstructionPrompt,\n locateImage: {\n imageBase64: screenshotBase64,\n width: context.shotSize.width,\n height: context.shotSize.height,\n },\n imagePreprocess: adapter.imagePreprocess,\n targetDescription: sectionDescription,\n promptOrder: adapter.locate.promptOrder,\n });\n\n let parsedResult:\n | {\n result: SectionLocateRawResponse;\n sectionError?: string;\n mergedRect?: undefined;\n }\n | {\n result: SectionLocateRawResponse;\n sectionError?: string;\n mergedRect: Rect;\n };\n\n try {\n parsedResult = await callAiAndParseWithRetry({\n callAi: (retryAttempt, previousParseError) =>\n callGenerativeAI(\n withSemanticRetryFeedback(messages, previousParseError),\n modelRuntime,\n {\n abortSignal: options.abortSignal,\n expectedJsonObjectResponse:\n searchAreaProtocol.expectedJsonObjectResponse,\n semanticRetryAttempt: retryAttempt,\n },\n ),\n parseResponse: (response) => {\n const parsedLocateResult = searchAreaProtocol.parseRawResponse(\n response.content,\n resultCodec.promptSpec,\n );\n const sectionError = parsedLocateResult.error;\n if (parsedLocateResult.kind === 'not-found') {\n return { result: response, sectionError };\n }\n\n try {\n const locateResultContext = {\n preparedSize: preparedImage.preparedSize,\n contentSize: preparedImage.contentSize,\n };\n const target = resultCodec.toPixelResult(\n parsedLocateResult.target,\n locateResultContext,\n );\n const references = parsedLocateResult.references?.map((reference) =>\n resultCodec.toPixelResult(reference, locateResultContext),\n );\n const mergedRect = mergeSearchAreaResults(target, references);\n debugSection('mergedRect %j', mergedRect);\n return {\n result: response,\n sectionError,\n mergedRect,\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n const message = [\n sectionError && `error in section locate result: ${sectionError}`,\n `coordinate parsing error: ${errorMessage}`,\n formatLocateModelContext(modelRuntime),\n ]\n .filter(Boolean)\n .join('\\n');\n throw new Error(message, { cause: error });\n }\n },\n toParseError: (error, response) => {\n const parseErrorMessage =\n error instanceof Error\n ? `Failed to parse section locate result: ${error.message}`\n : 'unknown error in section locate';\n return new AIResponseParseError(\n parseErrorMessage,\n response.content,\n response.usage,\n response.rawAssistantOutput,\n response.reasoning_content,\n );\n },\n parseRetryTimes: modelRuntime.config.retryCount,\n parseRetryInterval: modelRuntime.config.retryInterval,\n abortSignal: options.abortSignal,\n onParseRetry: (error) => {\n debugSection(\n 'retrying section locate after coordinate parsing failed: %s',\n error instanceof Error ? error.message : String(error),\n );\n },\n });\n } catch (callError) {\n if (callError instanceof AIResponseParseError) {\n return {\n searchAreaConfig: undefined,\n error: callError.message,\n rawResponse: callError.rawResponse,\n rawAssistantOutput: callError.rawAssistantOutput,\n usage: callError.usage,\n };\n }\n\n const errorMessage =\n callError instanceof Error ? callError.message : String(callError);\n return {\n searchAreaConfig: undefined,\n error: `AI call error: ${errorMessage}`,\n rawResponse: errorMessage,\n };\n }\n\n const { result, sectionError, mergedRect } = parsedResult;\n if (!mergedRect) {\n return {\n searchAreaConfig: undefined,\n error: sectionError,\n rawResponse: result.content,\n rawAssistantOutput: result.rawAssistantOutput,\n usage: result.usage,\n };\n }\n\n try {\n const expandedRect = expandSearchArea(mergedRect, context.shotSize);\n const originalWidth = expandedRect.width;\n const originalHeight = expandedRect.height;\n debugSection('expanded sectionRect %j', expandedRect);\n\n const searchAreaConfig = await buildSearchAreaConfig({\n context,\n baseRect: mergedRect,\n });\n\n debugSection(\n 'scaled section image from %dx%d to %dx%d (scale=%d)',\n originalWidth,\n originalHeight,\n searchAreaConfig.image.width,\n searchAreaConfig.image.height,\n searchAreaConfig.mapping.scale,\n );\n return {\n searchAreaConfig,\n error: sectionError,\n rawResponse: result.content,\n rawAssistantOutput: result.rawAssistantOutput,\n usage: result.usage,\n };\n } catch (error) {\n const parseErrorMessage =\n error instanceof Error\n ? `Failed to parse section locate result: ${error.message}`\n : 'unknown error in section locate';\n const errorMessage = sectionError\n ? `${sectionError} (${parseErrorMessage})`\n : parseErrorMessage;\n return {\n searchAreaConfig: undefined,\n error: errorMessage,\n rawResponse: result.content,\n rawAssistantOutput: result.rawAssistantOutput,\n usage: result.usage,\n };\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","debugSection","getDebug","AiLocateSection","options","context","sectionDescription","modelRuntime","adapter","assert","searchArea","searchAreaProtocol","resultCodec","screenshotBase64","systemPrompt","buildSearchAreaLocateSystemPrompt","userInstructionPrompt","userPromptToString","messages","preparedImage","prepareLocateModelInput","parsedResult","callAiAndParseWithRetry","retryAttempt","previousParseError","callGenerativeAI","withSemanticRetryFeedback","response","parsedLocateResult","sectionError","locateResultContext","target","references","reference","mergedRect","mergeSearchAreaResults","error","errorMessage","Error","String","message","formatLocateModelContext","Boolean","parseErrorMessage","AIResponseParseError","callError","undefined","result","expandedRect","expandSearchArea","originalWidth","originalHeight","searchAreaConfig","buildSearchAreaConfig"],"mappings":"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"}
|
|
@@ -29,8 +29,9 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
29
29
|
});
|
|
30
30
|
const external_common_js_namespaceObject = require("../../../common.js");
|
|
31
31
|
const image_preprocess_js_namespaceObject = require("../../model-adapter/image-preprocess.js");
|
|
32
|
+
const locate_prompt_order_js_namespaceObject = require("../../model-adapter/locate-prompt-order.js");
|
|
32
33
|
const multimodal_prompt_js_namespaceObject = require("../../shared/multimodal-prompt.js");
|
|
33
|
-
async function prepareLocateModelInput({ locateImage, targetDescription, systemPrompt, userPrompt, imagePreprocess,
|
|
34
|
+
async function prepareLocateModelInput({ locateImage, targetDescription, systemPrompt, userPrompt, imagePreprocess, promptOrder }) {
|
|
34
35
|
const preparedImage = await (0, image_preprocess_js_namespaceObject.prepareModelImage)({
|
|
35
36
|
imageBase64: locateImage.imageBase64,
|
|
36
37
|
width: locateImage.width,
|
|
@@ -38,33 +39,14 @@ async function prepareLocateModelInput({ locateImage, targetDescription, systemP
|
|
|
38
39
|
policy: imagePreprocess
|
|
39
40
|
});
|
|
40
41
|
const referenceImageMessages = await (0, multimodal_prompt_js_namespaceObject.multimodalPromptToMessages)((0, external_common_js_namespaceObject.userPromptToMultimodalPrompt)(targetDescription));
|
|
41
|
-
const imageContent = {
|
|
42
|
-
type: 'image',
|
|
43
|
-
url: preparedImage.imageBase64
|
|
44
|
-
};
|
|
45
|
-
const promptContent = {
|
|
46
|
-
type: 'text',
|
|
47
|
-
text: userPrompt
|
|
48
|
-
};
|
|
49
42
|
return {
|
|
50
43
|
preparedImage,
|
|
51
|
-
messages:
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
role: 'user',
|
|
58
|
-
content: 'prompt-first' === userMessageContentOrder ? [
|
|
59
|
-
promptContent,
|
|
60
|
-
imageContent
|
|
61
|
-
] : [
|
|
62
|
-
imageContent,
|
|
63
|
-
promptContent
|
|
64
|
-
]
|
|
65
|
-
},
|
|
66
|
-
...referenceImageMessages
|
|
67
|
-
]
|
|
44
|
+
messages: (0, locate_prompt_order_js_namespaceObject.buildLocateMessages)(promptOrder, {
|
|
45
|
+
instructions: systemPrompt,
|
|
46
|
+
screenshot: preparedImage.imageBase64,
|
|
47
|
+
task: userPrompt,
|
|
48
|
+
references: referenceImageMessages
|
|
49
|
+
})
|
|
68
50
|
};
|
|
69
51
|
}
|
|
70
52
|
function formatLocateModelContext(modelRuntime) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/workflows/grounding/utils.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../../src/ai-model/workflows/grounding/utils.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import
|
|
1
|
+
{"version":3,"file":"ai-model/workflows/grounding/utils.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../../src/ai-model/workflows/grounding/utils.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { type TUserPrompt, userPromptToMultimodalPrompt } from '@/common';\nimport {\n type ImagePreprocessPolicy,\n type PreparedModelImage,\n prepareModelImage,\n} from '../../model-adapter/image-preprocess';\nimport {\n type LocateMessages,\n type LocatePromptOrder,\n buildLocateMessages,\n} from '../../model-adapter/locate-prompt-order';\nimport type { ModelRuntime } from '../../models';\nimport { multimodalPromptToMessages } from '../../shared/multimodal-prompt';\n\nexport async function prepareLocateModelInput({\n locateImage,\n targetDescription,\n systemPrompt,\n userPrompt,\n imagePreprocess,\n promptOrder,\n}: {\n locateImage: {\n imageBase64: string;\n width: number;\n height: number;\n };\n targetDescription: TUserPrompt;\n systemPrompt: string;\n userPrompt: string;\n imagePreprocess: ImagePreprocessPolicy;\n promptOrder: LocatePromptOrder;\n}): Promise<{\n messages: LocateMessages;\n preparedImage: PreparedModelImage;\n}> {\n const preparedImage = await prepareModelImage({\n imageBase64: locateImage.imageBase64,\n width: locateImage.width,\n height: locateImage.height,\n policy: imagePreprocess,\n });\n const referenceImageMessages = await multimodalPromptToMessages(\n userPromptToMultimodalPrompt(targetDescription),\n );\n return {\n preparedImage,\n messages: buildLocateMessages(promptOrder, {\n instructions: systemPrompt,\n screenshot: preparedImage.imageBase64,\n task: userPrompt,\n references: referenceImageMessages,\n }),\n };\n}\n\nexport function formatLocateModelContext(modelRuntime: ModelRuntime): string {\n const { modelFamily, modelName } = modelRuntime.config;\n return `modelName=${modelName ?? 'unset'} modelFamily=${modelFamily ?? 'unset'}`;\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","prepareLocateModelInput","locateImage","targetDescription","systemPrompt","userPrompt","imagePreprocess","promptOrder","preparedImage","prepareModelImage","referenceImageMessages","multimodalPromptToMessages","userPromptToMultimodalPrompt","buildLocateMessages","formatLocateModelContext","modelRuntime","modelFamily","modelName"],"mappings":";;;IAAAA,oBAAoB,CAAC,GAAG,CAAC,UAASC;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGD,oBAAoB,CAAC,CAACC,YAAYC,QAAQ,CAACF,oBAAoB,CAAC,CAAC,UAASE,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAF,oBAAoB,CAAC,GAAG,CAACI,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFL,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,eAAlB,OAAOM,UAA0BA,OAAO,WAAW,EACrDH,OAAO,cAAc,CAAC,UAASG,OAAO,WAAW,EAAE;YAAE,OAAO;QAAS;QAEtEH,OAAO,cAAc,CAAC,UAAS,cAAc;YAAE,OAAO;QAAK;IAC5D;;;;;;;;;;;;ACQO,eAAeI,wBAAwB,EAC5CC,WAAW,EACXC,iBAAiB,EACjBC,YAAY,EACZC,UAAU,EACVC,eAAe,EACfC,WAAW,EAYZ;IAIC,MAAMC,gBAAgB,MAAMC,AAAAA,IAAAA,oCAAAA,iBAAAA,AAAAA,EAAkB;QAC5C,aAAaP,YAAY,WAAW;QACpC,OAAOA,YAAY,KAAK;QACxB,QAAQA,YAAY,MAAM;QAC1B,QAAQI;IACV;IACA,MAAMI,yBAAyB,MAAMC,AAAAA,IAAAA,qCAAAA,0BAAAA,AAAAA,EACnCC,AAAAA,IAAAA,mCAAAA,4BAAAA,AAAAA,EAA6BT;IAE/B,OAAO;QACLK;QACA,UAAUK,AAAAA,IAAAA,uCAAAA,mBAAAA,AAAAA,EAAoBN,aAAa;YACzC,cAAcH;YACd,YAAYI,cAAc,WAAW;YACrC,MAAMH;YACN,YAAYK;QACd;IACF;AACF;AAEO,SAASI,yBAAyBC,YAA0B;IACjE,MAAM,EAAEC,WAAW,EAAEC,SAAS,EAAE,GAAGF,aAAa,MAAM;IACtD,OAAO,CAAC,UAAU,EAAEE,aAAa,QAAQ,aAAa,EAAED,eAAe,SAAS;AAClF"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
ReportImageExporter: ()=>ReportImageExporter
|
|
28
|
+
});
|
|
29
|
+
const external_node_fs_namespaceObject = require("node:fs");
|
|
30
|
+
const external_node_path_namespaceObject = require("node:path");
|
|
31
|
+
const external_image_reference_js_namespaceObject = require("./image-reference.js");
|
|
32
|
+
const external_screenshot_store_js_namespaceObject = require("./screenshot-store.js");
|
|
33
|
+
function _define_property(obj, key, value) {
|
|
34
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
35
|
+
value: value,
|
|
36
|
+
enumerable: true,
|
|
37
|
+
configurable: true,
|
|
38
|
+
writable: true
|
|
39
|
+
});
|
|
40
|
+
else obj[key] = value;
|
|
41
|
+
return obj;
|
|
42
|
+
}
|
|
43
|
+
class ReportImageExporter {
|
|
44
|
+
write(ref, dataUri) {
|
|
45
|
+
const key = JSON.stringify([
|
|
46
|
+
ref.id,
|
|
47
|
+
ref.mimeType,
|
|
48
|
+
ref.storage,
|
|
49
|
+
ref.path
|
|
50
|
+
]);
|
|
51
|
+
const known = this.locations.get(key);
|
|
52
|
+
if (known) return known;
|
|
53
|
+
const source = dataUri ? {
|
|
54
|
+
type: 'data-uri',
|
|
55
|
+
dataUri
|
|
56
|
+
} : (0, external_screenshot_store_js_namespaceObject.resolveImageSource)(ref, {
|
|
57
|
+
reportPath: this.reportPath
|
|
58
|
+
});
|
|
59
|
+
const bytes = 'file' === source.type ? (0, external_node_fs_namespaceObject.readFileSync)(source.filePath) : Buffer.from((0, external_screenshot_store_js_namespaceObject.parseBase64ImageDataUrl)(source.dataUri).rawBase64, 'base64');
|
|
60
|
+
const name = (0, external_screenshot_store_js_namespaceObject.reportImageFileName)((0, external_image_reference_js_namespaceObject.imageRefFileExtension)(ref), bytes);
|
|
61
|
+
if (!this.writtenFiles.has(name)) {
|
|
62
|
+
(0, external_node_fs_namespaceObject.writeFileSync)((0, external_node_path_namespaceObject.join)(this.screenshotsDir, name), bytes);
|
|
63
|
+
this.writtenFiles.add(name);
|
|
64
|
+
}
|
|
65
|
+
this.locations.set(key, name);
|
|
66
|
+
return name;
|
|
67
|
+
}
|
|
68
|
+
get files() {
|
|
69
|
+
return [
|
|
70
|
+
...this.writtenFiles
|
|
71
|
+
].sort().map((name)=>(0, external_node_path_namespaceObject.join)(this.screenshotsDir, name));
|
|
72
|
+
}
|
|
73
|
+
constructor(reportPath, screenshotsDir){
|
|
74
|
+
_define_property(this, "reportPath", void 0);
|
|
75
|
+
_define_property(this, "screenshotsDir", void 0);
|
|
76
|
+
_define_property(this, "locations", void 0);
|
|
77
|
+
_define_property(this, "writtenFiles", void 0);
|
|
78
|
+
this.reportPath = reportPath;
|
|
79
|
+
this.screenshotsDir = screenshotsDir;
|
|
80
|
+
this.locations = new Map();
|
|
81
|
+
this.writtenFiles = new Set();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
exports.ReportImageExporter = __webpack_exports__.ReportImageExporter;
|
|
85
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
86
|
+
"ReportImageExporter"
|
|
87
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
88
|
+
Object.defineProperty(exports, '__esModule', {
|
|
89
|
+
value: true
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
//# sourceMappingURL=report-image-export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dump/report-image-export.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/dump/report-image-export.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { type StoredImageRef, imageRefFileExtension } from './image-reference';\nimport {\n parseBase64ImageDataUrl,\n reportImageFileName,\n resolveImageSource,\n} from './screenshot-store';\n\n/** Export image bytes once while keeping every observation's own metadata. */\nexport class ReportImageExporter {\n private readonly locations = new Map<string, string>();\n private readonly writtenFiles = new Set<string>();\n\n constructor(\n private readonly reportPath: string,\n private readonly screenshotsDir: string,\n ) {}\n\n write(ref: StoredImageRef, dataUri?: string): string {\n const key = JSON.stringify([ref.id, ref.mimeType, ref.storage, ref.path]);\n const known = this.locations.get(key);\n if (known) return known;\n const source = dataUri\n ? { type: 'data-uri' as const, dataUri }\n : resolveImageSource(ref, { reportPath: this.reportPath });\n const bytes =\n source.type === 'file'\n ? readFileSync(source.filePath)\n : Buffer.from(\n parseBase64ImageDataUrl(source.dataUri).rawBase64,\n 'base64',\n );\n const name = reportImageFileName(imageRefFileExtension(ref), bytes);\n if (!this.writtenFiles.has(name)) {\n writeFileSync(join(this.screenshotsDir, name), bytes);\n this.writtenFiles.add(name);\n }\n this.locations.set(key, name);\n return name;\n }\n\n get files(): string[] {\n return [...this.writtenFiles]\n .sort()\n .map((name) => join(this.screenshotsDir, name));\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","ReportImageExporter","ref","dataUri","JSON","known","source","resolveImageSource","bytes","readFileSync","Buffer","parseBase64ImageDataUrl","name","reportImageFileName","imageRefFileExtension","writeFileSync","join","reportPath","screenshotsDir","Map","Set"],"mappings":";;;IAAAA,oBAAoB,CAAC,GAAG,CAAC,UAASC;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGD,oBAAoB,CAAC,CAACC,YAAYC,QAAQ,CAACF,oBAAoB,CAAC,CAAC,UAASE,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAF,oBAAoB,CAAC,GAAG,CAACI,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFL,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,eAAlB,OAAOM,UAA0BA,OAAO,WAAW,EACrDH,OAAO,cAAc,CAAC,UAASG,OAAO,WAAW,EAAE;YAAE,OAAO;QAAS;QAEtEH,OAAO,cAAc,CAAC,UAAS,cAAc;YAAE,OAAO;QAAK;IAC5D;;;;;;;;;;;;;;;;;;;;;ACIO,MAAMI;IASX,MAAMC,GAAmB,EAAEC,OAAgB,EAAU;QACnD,MAAMP,MAAMQ,KAAK,SAAS,CAAC;YAACF,IAAI,EAAE;YAAEA,IAAI,QAAQ;YAAEA,IAAI,OAAO;YAAEA,IAAI,IAAI;SAAC;QACxE,MAAMG,QAAQ,IAAI,CAAC,SAAS,CAAC,GAAG,CAACT;QACjC,IAAIS,OAAO,OAAOA;QAClB,MAAMC,SAASH,UACX;YAAE,MAAM;YAAqBA;QAAQ,IACrCI,AAAAA,IAAAA,6CAAAA,kBAAAA,AAAAA,EAAmBL,KAAK;YAAE,YAAY,IAAI,CAAC,UAAU;QAAC;QAC1D,MAAMM,QACJF,AAAgB,WAAhBA,OAAO,IAAI,GACPG,AAAAA,IAAAA,iCAAAA,YAAAA,AAAAA,EAAaH,OAAO,QAAQ,IAC5BI,OAAO,IAAI,CACTC,AAAAA,IAAAA,6CAAAA,uBAAAA,AAAAA,EAAwBL,OAAO,OAAO,EAAE,SAAS,EACjD;QAER,MAAMM,OAAOC,AAAAA,IAAAA,6CAAAA,mBAAAA,AAAAA,EAAoBC,AAAAA,IAAAA,4CAAAA,qBAAAA,AAAAA,EAAsBZ,MAAMM;QAC7D,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAACI,OAAO;YAChCG,IAAAA,iCAAAA,aAAAA,AAAAA,EAAcC,AAAAA,IAAAA,mCAAAA,IAAAA,AAAAA,EAAK,IAAI,CAAC,cAAc,EAAEJ,OAAOJ;YAC/C,IAAI,CAAC,YAAY,CAAC,GAAG,CAACI;QACxB;QACA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAChB,KAAKgB;QACxB,OAAOA;IACT;IAEA,IAAI,QAAkB;QACpB,OAAO;eAAI,IAAI,CAAC,YAAY;SAAC,CAC1B,IAAI,GACJ,GAAG,CAAC,CAACA,OAASI,AAAAA,IAAAA,mCAAAA,IAAAA,AAAAA,EAAK,IAAI,CAAC,cAAc,EAAEJ;IAC7C;IAhCA,YACmBK,UAAkB,EAClBC,cAAsB,CACvC;;;QANF,uBAAiB,aAAjB;QACA,uBAAiB,gBAAjB;aAGmBD,UAAU,GAAVA;aACAC,cAAc,GAAdA;aALF,SAAS,GAAG,IAAIC;aAChB,YAAY,GAAG,IAAIC;IAKjC;AA8BL"}
|
|
@@ -125,6 +125,11 @@ class ReportImageStore {
|
|
|
125
125
|
if (!file) throw new Error(`ReportImageStore: image ${id} has no persisted file`);
|
|
126
126
|
return file.relativePath;
|
|
127
127
|
}
|
|
128
|
+
persistFileCopy(screenshot) {
|
|
129
|
+
return this.persistToSharedFileIfNeeded(screenshot, {
|
|
130
|
+
markAsPersisted: false
|
|
131
|
+
});
|
|
132
|
+
}
|
|
128
133
|
async persist(screenshot) {
|
|
129
134
|
await this.ensureExistingInlineImageIdsLoaded();
|
|
130
135
|
const shouldWriteFileCopy = 'directory' === this.mode || this.alsoWriteFileCopy;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dump/screenshot-store.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/dump/screenshot-store.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { createHash } from 'node:crypto';\nimport { existsSync, mkdirSync, readFileSync, rmSync } from 'node:fs';\nimport { dirname, isAbsolute, join } from 'node:path';\nimport type { ScreenshotItem } from '../screenshot-item';\nimport { collectImageScriptIds, extractImageByIdSync } from './html-utils';\nimport {\n type ImageUrlRef,\n type ScreenshotRef,\n type StoredImageRef,\n imageFileExtensionForMimeType,\n imageRefFileExtension,\n normalizeImageUrlRef,\n normalizeScreenshotRef,\n normalizeStoredImageRef,\n} from './image-reference';\nimport { writeReportArtifactFile } from './report-artifact-store';\n\nexport type {\n ImageUrlRef,\n ScreenshotRef,\n StoredImageRef,\n} from './image-reference';\nexport {\n imageRefFileExtension,\n normalizeImageUrlRef,\n normalizeScreenshotRef,\n normalizeStoredImageRef,\n} from './image-reference';\n\nconst base64ImageDataUrlPattern =\n /^data:(image\\/[a-z0-9.+-]+)(?:;[^,]*)?;base64,([a-z0-9+/=\\s]+)$/i;\ntype ResolvedImageSource =\n | {\n type: 'data-uri';\n id: string;\n mimeType: StoredImageRef['mimeType'];\n dataUri: string;\n }\n | {\n type: 'file';\n id: string;\n mimeType: StoredImageRef['mimeType'];\n filePath: string;\n };\n\n/** Parse and normalize a base64 image data URL for report persistence. */\nexport function parseBase64ImageDataUrl(imageUrl: string): {\n mimeType: `image/${string}`;\n extension: string;\n rawBase64: string;\n} {\n const match = imageUrl.match(base64ImageDataUrlPattern);\n if (!match) {\n throw new Error(\n 'ReportImageStore: reference image must be a valid base64 image data URL',\n );\n }\n const mimeType = match[1].toLowerCase() as `image/${string}`;\n return {\n mimeType,\n extension: imageFileExtensionForMimeType(mimeType),\n rawBase64: match[2].replace(/\\s/g, ''),\n };\n}\n\nexport function isBase64ImageDataUrl(value: string): boolean {\n return base64ImageDataUrlPattern.test(value);\n}\n\n/** Stable asset names allow different observations to share the same bytes. */\nexport function reportImageFileName(\n extension: string,\n bytes: Uint8Array,\n): string {\n const hash = createHash('sha256')\n .update(extension)\n .update('\\0')\n .update(bytes)\n .digest('hex');\n return `${hash}.${extension}`;\n}\n\nexport function resolveImageSource(\n refInput: unknown,\n options: {\n reportPath: string;\n imageDirectory?: string;\n fallbackId?: string;\n fallbackMimeType?: ScreenshotRef['mimeType'];\n },\n): ResolvedImageSource {\n const ref = normalizeStoredImageRef(refInput);\n const id = ref?.id ?? options.fallbackId;\n const mimeType = ref?.mimeType ?? options.fallbackMimeType;\n\n if (!id || !mimeType) {\n throw new Error(\n 'ReportImageStore: image id and mimeType are required to resolve an image',\n );\n }\n\n const resolveReportRelativePath = (filePath: string): string =>\n isAbsolute(filePath)\n ? filePath\n : join(dirname(options.reportPath), filePath);\n\n if (ref?.storage === 'file') {\n if (!ref.path) {\n throw new Error(\n `ReportImageStore: image ref \"${ref.id}\" missing file path`,\n );\n }\n\n const explicitFilePath = resolveReportRelativePath(ref.path);\n if (existsSync(explicitFilePath)) {\n return {\n type: 'file',\n id,\n mimeType,\n filePath: explicitFilePath,\n };\n }\n }\n\n const inlineDataUri = extractImageByIdSync(options.reportPath, id);\n if (inlineDataUri) {\n return {\n type: 'data-uri',\n id,\n mimeType,\n dataUri: inlineDataUri,\n };\n }\n\n const extension = ref\n ? imageRefFileExtension(ref)\n : imageFileExtensionForMimeType(options.fallbackMimeType!);\n if (options.imageDirectory) {\n const companionImagePath = join(\n options.imageDirectory,\n `${id}.${extension}`,\n );\n if (existsSync(companionImagePath)) {\n return {\n type: 'file',\n id,\n mimeType,\n filePath: companionImagePath,\n };\n }\n }\n const siblingImagePath = join(\n dirname(options.reportPath),\n 'screenshots',\n `${id}.${extension}`,\n );\n if (existsSync(siblingImagePath)) {\n return {\n type: 'file',\n id,\n mimeType,\n filePath: siblingImagePath,\n };\n }\n\n throw new Error(\n `ReportImageStore: cannot resolve image \"${id}\" from ${options.reportPath}`,\n );\n}\n\nexport function resolveScreenshotSource(\n refInput: unknown,\n options: {\n reportPath: string;\n imageDirectory?: string;\n fallbackId?: string;\n fallbackMimeType?: ScreenshotRef['mimeType'];\n },\n): ResolvedImageSource {\n const ref = normalizeScreenshotRef(refInput);\n return resolveImageSource(ref, options);\n}\n\n/** Persists and restores every image asset referenced by a report. */\nexport class ReportImageStore {\n private readonly mode: 'inline' | 'directory';\n private readonly reportPath: string;\n private readonly screenshotsDir?: string;\n private readonly writeInlineImage?: (\n id: string,\n base64: string,\n ) => void | Promise<void>;\n private alsoWriteFileCopy: boolean;\n private readonly writtenInlineIds = new Set<string>();\n private readonly writtenFileIds = new Set<string>();\n private readonly fileLocations = new Map<\n string,\n { relativePath: string; absolutePath: string }\n >();\n private readonly pendingFiles = new Map<\n string,\n Promise<{ relativePath: string; absolutePath: string }>\n >();\n private readonly shouldReuseExistingInlineReport: boolean;\n private existingInlineImageIdsPromise?: Promise<void>;\n\n constructor(options: {\n mode: 'inline' | 'directory';\n reportPath: string;\n screenshotsDir?: string;\n writeInlineImage?: (id: string, base64: string) => void | Promise<void>;\n alsoWriteFileCopy?: boolean;\n /** @deprecated Use alsoWriteFileCopy instead. */\n ensureFileCopy?: boolean;\n /** Reuse inline image assets already present in reportPath. */\n reuseExistingReport?: boolean;\n }) {\n this.mode = options.mode;\n this.reportPath = options.reportPath;\n this.screenshotsDir = options.screenshotsDir;\n this.writeInlineImage = options.writeInlineImage;\n this.alsoWriteFileCopy =\n options.alsoWriteFileCopy ?? options.ensureFileCopy ?? false;\n this.shouldReuseExistingInlineReport = Boolean(\n options.reuseExistingReport && this.mode === 'inline',\n );\n }\n\n enableFileCopies(): void {\n this.alsoWriteFileCopy = true;\n }\n\n /** Resolve an observation/reference ID to its content-addressed asset. */\n getFilePath(id: string): string {\n const file = this.fileLocations.get(id);\n if (!file)\n throw new Error(`ReportImageStore: image ${id} has no persisted file`);\n return file.relativePath;\n }\n\n async persist(screenshot: ScreenshotItem): Promise<ScreenshotRef> {\n await this.ensureExistingInlineImageIdsLoaded();\n const shouldWriteFileCopy =\n this.mode === 'directory' || this.alsoWriteFileCopy;\n const fileRef = shouldWriteFileCopy\n ? await this.persistToSharedFileIfNeeded(screenshot, {\n markAsPersisted: this.mode === 'directory',\n })\n : null;\n\n if (this.mode === 'inline') {\n if (!this.writeInlineImage) {\n throw new Error(\n 'ReportImageStore: writeInlineImage is required in inline mode',\n );\n }\n if (!this.writtenInlineIds.has(screenshot.id)) {\n await this.writeInlineImage(screenshot.id, screenshot.base64);\n this.writtenInlineIds.add(screenshot.id);\n }\n return screenshot.markPersistedInline(this.reportPath);\n }\n\n if (!fileRef) {\n throw new Error(\n 'ReportImageStore: file persistence is required in directory mode',\n );\n }\n return fileRef;\n }\n\n /** Persist a base64 multimodal prompt image and return its content-addressed ref. */\n async persistReferenceImage(imageUrl: string): Promise<ImageUrlRef> {\n await this.ensureExistingInlineImageIdsLoaded();\n const { mimeType, extension, rawBase64 } =\n parseBase64ImageDataUrl(imageUrl);\n const id = `reference-${createHash('sha256')\n .update(mimeType)\n .update('\\0')\n .update(Buffer.from(rawBase64, 'base64'))\n .digest('hex')}`;\n const shouldWriteFileCopy =\n this.mode === 'directory' || this.alsoWriteFileCopy;\n const fileLocation = shouldWriteFileCopy\n ? await this.writeImageFileIfNeeded({ id, extension, rawBase64 })\n : null;\n\n let ref: ImageUrlRef;\n if (this.mode === 'inline') {\n if (!this.writeInlineImage) {\n throw new Error(\n 'ReportImageStore: writeInlineImage is required in inline mode',\n );\n }\n if (!this.writtenInlineIds.has(id)) {\n await this.writeInlineImage(id, imageUrl);\n this.writtenInlineIds.add(id);\n }\n ref = {\n type: 'midscene_image_url_ref',\n id,\n mimeType,\n storage: 'inline',\n };\n } else {\n if (!fileLocation) {\n throw new Error(\n 'ReportImageStore: file persistence is required in directory mode',\n );\n }\n ref = {\n type: 'midscene_image_url_ref',\n id,\n mimeType,\n storage: 'file',\n path: fileLocation.relativePath,\n };\n }\n return ref;\n }\n\n private async ensureExistingInlineImageIdsLoaded(): Promise<void> {\n if (!this.shouldReuseExistingInlineReport) return;\n if (!this.existingInlineImageIdsPromise) {\n this.existingInlineImageIdsPromise = (async () => {\n try {\n const imageIds = await collectImageScriptIds(this.reportPath);\n for (const imageId of imageIds) this.writtenInlineIds.add(imageId);\n } catch (error) {\n if (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === 'ENOENT'\n ) {\n return;\n }\n throw new Error(\n `ReportImageStore: failed to index existing inline images from ${this.reportPath}`,\n { cause: error },\n );\n }\n })();\n }\n await this.existingInlineImageIdsPromise;\n }\n\n private async persistToSharedFileIfNeeded(\n screenshot: ScreenshotItem,\n options: {\n markAsPersisted: boolean;\n },\n ): Promise<ScreenshotRef> {\n const { relativePath, absolutePath } =\n this.fileLocations.get(screenshot.id) ??\n (await this.writeImageFileIfNeeded({\n id: screenshot.id,\n extension: screenshot.extension,\n rawBase64: screenshot.rawBase64,\n }));\n\n if (options.markAsPersisted) {\n return screenshot.markPersistedToPath(relativePath, absolutePath);\n }\n\n return screenshot.registerPersistedFileCopy(relativePath, absolutePath);\n }\n\n private async writeImageFileIfNeeded(image: {\n id: string;\n extension: string;\n rawBase64: string;\n }): Promise<{ relativePath: string; absolutePath: string }> {\n const screenshotsDir = this.screenshotsDir;\n if (!screenshotsDir) {\n throw new Error(\n 'ReportImageStore: screenshotsDir is required when file persistence is enabled',\n );\n }\n if (!existsSync(screenshotsDir)) {\n mkdirSync(screenshotsDir, { recursive: true });\n }\n\n const known = this.fileLocations.get(image.id);\n if (known) return known;\n const bytes = Buffer.from(image.rawBase64, 'base64');\n const fileName = reportImageFileName(image.extension, bytes);\n const relativePath = `./screenshots/${fileName}`;\n const absolutePath = join(screenshotsDir, fileName);\n let publication = this.pendingFiles.get(fileName);\n if (!publication) {\n publication = (async () => {\n if (!this.writtenFileIds.has(fileName)) {\n await writeReportArtifactFile(absolutePath, bytes);\n this.writtenFileIds.add(fileName);\n }\n return { relativePath, absolutePath };\n })();\n this.pendingFiles.set(fileName, publication);\n }\n try {\n const location = await publication;\n this.fileLocations.set(image.id, location);\n return location;\n } finally {\n this.pendingFiles.delete(fileName);\n }\n }\n\n /** Resolve any stored report image reference to a data URI. */\n loadDataUri(refInput: unknown): string {\n const ref = normalizeStoredImageRef(refInput);\n if (!ref) {\n throw new Error('ReportImageStore: invalid image reference');\n }\n\n const resolved = resolveImageSource(ref, {\n reportPath: this.reportPath,\n imageDirectory: this.screenshotsDir,\n });\n\n if (resolved.type === 'data-uri') {\n return resolved.dataUri;\n }\n\n const data = readFileSync(resolved.filePath);\n return `data:${resolved.mimeType};base64,${data.toString('base64')}`;\n }\n\n /** @deprecated Use loadDataUri. */\n loadBase64(refInput: unknown): string {\n const screenshotRef = normalizeScreenshotRef(refInput);\n if (!screenshotRef) {\n throw new Error('ReportImageStore: invalid screenshot reference');\n }\n return this.loadDataUri(screenshotRef);\n }\n\n cleanup(): void {\n if (\n this.mode === 'directory' &&\n this.screenshotsDir &&\n existsSync(this.screenshotsDir)\n ) {\n rmSync(this.screenshotsDir, { recursive: true, force: true });\n }\n this.writtenInlineIds.clear();\n this.writtenFileIds.clear();\n this.fileLocations.clear();\n this.pendingFiles.clear();\n this.existingInlineImageIdsPromise = undefined;\n }\n}\n\n/** @deprecated Use ReportImageStore. */\nexport { ReportImageStore as ScreenshotStore };\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","base64ImageDataUrlPattern","parseBase64ImageDataUrl","imageUrl","match","Error","mimeType","imageFileExtensionForMimeType","isBase64ImageDataUrl","value","reportImageFileName","extension","bytes","hash","createHash","resolveImageSource","refInput","options","ref","normalizeStoredImageRef","id","resolveReportRelativePath","filePath","isAbsolute","join","dirname","explicitFilePath","existsSync","inlineDataUri","extractImageByIdSync","imageRefFileExtension","companionImagePath","siblingImagePath","resolveScreenshotSource","normalizeScreenshotRef","ReportImageStore","file","screenshot","shouldWriteFileCopy","fileRef","rawBase64","Buffer","fileLocation","imageIds","collectImageScriptIds","imageId","error","relativePath","absolutePath","image","screenshotsDir","mkdirSync","known","fileName","publication","writeReportArtifactFile","location","resolved","data","readFileSync","screenshotRef","rmSync","undefined","Set","Map","Boolean"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dump/screenshot-store.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/dump/screenshot-store.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { createHash } from 'node:crypto';\nimport { existsSync, mkdirSync, readFileSync, rmSync } from 'node:fs';\nimport { dirname, isAbsolute, join } from 'node:path';\nimport type { ScreenshotItem } from '../screenshot-item';\nimport { collectImageScriptIds, extractImageByIdSync } from './html-utils';\nimport {\n type ImageUrlRef,\n type ScreenshotRef,\n type StoredImageRef,\n imageFileExtensionForMimeType,\n imageRefFileExtension,\n normalizeImageUrlRef,\n normalizeScreenshotRef,\n normalizeStoredImageRef,\n} from './image-reference';\nimport { writeReportArtifactFile } from './report-artifact-store';\n\nexport type {\n ImageUrlRef,\n ScreenshotRef,\n StoredImageRef,\n} from './image-reference';\nexport {\n imageRefFileExtension,\n normalizeImageUrlRef,\n normalizeScreenshotRef,\n normalizeStoredImageRef,\n} from './image-reference';\n\nconst base64ImageDataUrlPattern =\n /^data:(image\\/[a-z0-9.+-]+)(?:;[^,]*)?;base64,([a-z0-9+/=\\s]+)$/i;\ntype ResolvedImageSource =\n | {\n type: 'data-uri';\n id: string;\n mimeType: StoredImageRef['mimeType'];\n dataUri: string;\n }\n | {\n type: 'file';\n id: string;\n mimeType: StoredImageRef['mimeType'];\n filePath: string;\n };\n\n/** Parse and normalize a base64 image data URL for report persistence. */\nexport function parseBase64ImageDataUrl(imageUrl: string): {\n mimeType: `image/${string}`;\n extension: string;\n rawBase64: string;\n} {\n const match = imageUrl.match(base64ImageDataUrlPattern);\n if (!match) {\n throw new Error(\n 'ReportImageStore: reference image must be a valid base64 image data URL',\n );\n }\n const mimeType = match[1].toLowerCase() as `image/${string}`;\n return {\n mimeType,\n extension: imageFileExtensionForMimeType(mimeType),\n rawBase64: match[2].replace(/\\s/g, ''),\n };\n}\n\nexport function isBase64ImageDataUrl(value: string): boolean {\n return base64ImageDataUrlPattern.test(value);\n}\n\n/** Stable asset names allow different observations to share the same bytes. */\nexport function reportImageFileName(\n extension: string,\n bytes: Uint8Array,\n): string {\n const hash = createHash('sha256')\n .update(extension)\n .update('\\0')\n .update(bytes)\n .digest('hex');\n return `${hash}.${extension}`;\n}\n\nexport function resolveImageSource(\n refInput: unknown,\n options: {\n reportPath: string;\n imageDirectory?: string;\n fallbackId?: string;\n fallbackMimeType?: ScreenshotRef['mimeType'];\n },\n): ResolvedImageSource {\n const ref = normalizeStoredImageRef(refInput);\n const id = ref?.id ?? options.fallbackId;\n const mimeType = ref?.mimeType ?? options.fallbackMimeType;\n\n if (!id || !mimeType) {\n throw new Error(\n 'ReportImageStore: image id and mimeType are required to resolve an image',\n );\n }\n\n const resolveReportRelativePath = (filePath: string): string =>\n isAbsolute(filePath)\n ? filePath\n : join(dirname(options.reportPath), filePath);\n\n if (ref?.storage === 'file') {\n if (!ref.path) {\n throw new Error(\n `ReportImageStore: image ref \"${ref.id}\" missing file path`,\n );\n }\n\n const explicitFilePath = resolveReportRelativePath(ref.path);\n if (existsSync(explicitFilePath)) {\n return {\n type: 'file',\n id,\n mimeType,\n filePath: explicitFilePath,\n };\n }\n }\n\n const inlineDataUri = extractImageByIdSync(options.reportPath, id);\n if (inlineDataUri) {\n return {\n type: 'data-uri',\n id,\n mimeType,\n dataUri: inlineDataUri,\n };\n }\n\n const extension = ref\n ? imageRefFileExtension(ref)\n : imageFileExtensionForMimeType(options.fallbackMimeType!);\n if (options.imageDirectory) {\n const companionImagePath = join(\n options.imageDirectory,\n `${id}.${extension}`,\n );\n if (existsSync(companionImagePath)) {\n return {\n type: 'file',\n id,\n mimeType,\n filePath: companionImagePath,\n };\n }\n }\n const siblingImagePath = join(\n dirname(options.reportPath),\n 'screenshots',\n `${id}.${extension}`,\n );\n if (existsSync(siblingImagePath)) {\n return {\n type: 'file',\n id,\n mimeType,\n filePath: siblingImagePath,\n };\n }\n\n throw new Error(\n `ReportImageStore: cannot resolve image \"${id}\" from ${options.reportPath}`,\n );\n}\n\nexport function resolveScreenshotSource(\n refInput: unknown,\n options: {\n reportPath: string;\n imageDirectory?: string;\n fallbackId?: string;\n fallbackMimeType?: ScreenshotRef['mimeType'];\n },\n): ResolvedImageSource {\n const ref = normalizeScreenshotRef(refInput);\n return resolveImageSource(ref, options);\n}\n\n/** Persists and restores every image asset referenced by a report. */\nexport class ReportImageStore {\n private readonly mode: 'inline' | 'directory';\n private readonly reportPath: string;\n private readonly screenshotsDir?: string;\n private readonly writeInlineImage?: (\n id: string,\n base64: string,\n ) => void | Promise<void>;\n private alsoWriteFileCopy: boolean;\n private readonly writtenInlineIds = new Set<string>();\n private readonly writtenFileIds = new Set<string>();\n private readonly fileLocations = new Map<\n string,\n { relativePath: string; absolutePath: string }\n >();\n private readonly pendingFiles = new Map<\n string,\n Promise<{ relativePath: string; absolutePath: string }>\n >();\n private readonly shouldReuseExistingInlineReport: boolean;\n private existingInlineImageIdsPromise?: Promise<void>;\n\n constructor(options: {\n mode: 'inline' | 'directory';\n reportPath: string;\n screenshotsDir?: string;\n writeInlineImage?: (id: string, base64: string) => void | Promise<void>;\n alsoWriteFileCopy?: boolean;\n /** @deprecated Use alsoWriteFileCopy instead. */\n ensureFileCopy?: boolean;\n /** Reuse inline image assets already present in reportPath. */\n reuseExistingReport?: boolean;\n }) {\n this.mode = options.mode;\n this.reportPath = options.reportPath;\n this.screenshotsDir = options.screenshotsDir;\n this.writeInlineImage = options.writeInlineImage;\n this.alsoWriteFileCopy =\n options.alsoWriteFileCopy ?? options.ensureFileCopy ?? false;\n this.shouldReuseExistingInlineReport = Boolean(\n options.reuseExistingReport && this.mode === 'inline',\n );\n }\n\n enableFileCopies(): void {\n this.alsoWriteFileCopy = true;\n }\n\n /** Resolve an observation/reference ID to its content-addressed asset. */\n getFilePath(id: string): string {\n const file = this.fileLocations.get(id);\n if (!file)\n throw new Error(`ReportImageStore: image ${id} has no persisted file`);\n return file.relativePath;\n }\n\n /** Keep diagnostic bytes without changing the screenshot's report location. */\n persistFileCopy(screenshot: ScreenshotItem): Promise<ScreenshotRef> {\n return this.persistToSharedFileIfNeeded(screenshot, {\n markAsPersisted: false,\n });\n }\n\n async persist(screenshot: ScreenshotItem): Promise<ScreenshotRef> {\n await this.ensureExistingInlineImageIdsLoaded();\n const shouldWriteFileCopy =\n this.mode === 'directory' || this.alsoWriteFileCopy;\n const fileRef = shouldWriteFileCopy\n ? await this.persistToSharedFileIfNeeded(screenshot, {\n markAsPersisted: this.mode === 'directory',\n })\n : null;\n\n if (this.mode === 'inline') {\n if (!this.writeInlineImage) {\n throw new Error(\n 'ReportImageStore: writeInlineImage is required in inline mode',\n );\n }\n if (!this.writtenInlineIds.has(screenshot.id)) {\n await this.writeInlineImage(screenshot.id, screenshot.base64);\n this.writtenInlineIds.add(screenshot.id);\n }\n return screenshot.markPersistedInline(this.reportPath);\n }\n\n if (!fileRef) {\n throw new Error(\n 'ReportImageStore: file persistence is required in directory mode',\n );\n }\n return fileRef;\n }\n\n /** Persist a base64 multimodal prompt image and return its content-addressed ref. */\n async persistReferenceImage(imageUrl: string): Promise<ImageUrlRef> {\n await this.ensureExistingInlineImageIdsLoaded();\n const { mimeType, extension, rawBase64 } =\n parseBase64ImageDataUrl(imageUrl);\n const id = `reference-${createHash('sha256')\n .update(mimeType)\n .update('\\0')\n .update(Buffer.from(rawBase64, 'base64'))\n .digest('hex')}`;\n const shouldWriteFileCopy =\n this.mode === 'directory' || this.alsoWriteFileCopy;\n const fileLocation = shouldWriteFileCopy\n ? await this.writeImageFileIfNeeded({ id, extension, rawBase64 })\n : null;\n\n let ref: ImageUrlRef;\n if (this.mode === 'inline') {\n if (!this.writeInlineImage) {\n throw new Error(\n 'ReportImageStore: writeInlineImage is required in inline mode',\n );\n }\n if (!this.writtenInlineIds.has(id)) {\n await this.writeInlineImage(id, imageUrl);\n this.writtenInlineIds.add(id);\n }\n ref = {\n type: 'midscene_image_url_ref',\n id,\n mimeType,\n storage: 'inline',\n };\n } else {\n if (!fileLocation) {\n throw new Error(\n 'ReportImageStore: file persistence is required in directory mode',\n );\n }\n ref = {\n type: 'midscene_image_url_ref',\n id,\n mimeType,\n storage: 'file',\n path: fileLocation.relativePath,\n };\n }\n return ref;\n }\n\n private async ensureExistingInlineImageIdsLoaded(): Promise<void> {\n if (!this.shouldReuseExistingInlineReport) return;\n if (!this.existingInlineImageIdsPromise) {\n this.existingInlineImageIdsPromise = (async () => {\n try {\n const imageIds = await collectImageScriptIds(this.reportPath);\n for (const imageId of imageIds) this.writtenInlineIds.add(imageId);\n } catch (error) {\n if (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === 'ENOENT'\n ) {\n return;\n }\n throw new Error(\n `ReportImageStore: failed to index existing inline images from ${this.reportPath}`,\n { cause: error },\n );\n }\n })();\n }\n await this.existingInlineImageIdsPromise;\n }\n\n private async persistToSharedFileIfNeeded(\n screenshot: ScreenshotItem,\n options: {\n markAsPersisted: boolean;\n },\n ): Promise<ScreenshotRef> {\n const { relativePath, absolutePath } =\n this.fileLocations.get(screenshot.id) ??\n (await this.writeImageFileIfNeeded({\n id: screenshot.id,\n extension: screenshot.extension,\n rawBase64: screenshot.rawBase64,\n }));\n\n if (options.markAsPersisted) {\n return screenshot.markPersistedToPath(relativePath, absolutePath);\n }\n\n return screenshot.registerPersistedFileCopy(relativePath, absolutePath);\n }\n\n private async writeImageFileIfNeeded(image: {\n id: string;\n extension: string;\n rawBase64: string;\n }): Promise<{ relativePath: string; absolutePath: string }> {\n const screenshotsDir = this.screenshotsDir;\n if (!screenshotsDir) {\n throw new Error(\n 'ReportImageStore: screenshotsDir is required when file persistence is enabled',\n );\n }\n if (!existsSync(screenshotsDir)) {\n mkdirSync(screenshotsDir, { recursive: true });\n }\n\n const known = this.fileLocations.get(image.id);\n if (known) return known;\n const bytes = Buffer.from(image.rawBase64, 'base64');\n const fileName = reportImageFileName(image.extension, bytes);\n const relativePath = `./screenshots/${fileName}`;\n const absolutePath = join(screenshotsDir, fileName);\n let publication = this.pendingFiles.get(fileName);\n if (!publication) {\n publication = (async () => {\n if (!this.writtenFileIds.has(fileName)) {\n await writeReportArtifactFile(absolutePath, bytes);\n this.writtenFileIds.add(fileName);\n }\n return { relativePath, absolutePath };\n })();\n this.pendingFiles.set(fileName, publication);\n }\n try {\n const location = await publication;\n this.fileLocations.set(image.id, location);\n return location;\n } finally {\n this.pendingFiles.delete(fileName);\n }\n }\n\n /** Resolve any stored report image reference to a data URI. */\n loadDataUri(refInput: unknown): string {\n const ref = normalizeStoredImageRef(refInput);\n if (!ref) {\n throw new Error('ReportImageStore: invalid image reference');\n }\n\n const resolved = resolveImageSource(ref, {\n reportPath: this.reportPath,\n imageDirectory: this.screenshotsDir,\n });\n\n if (resolved.type === 'data-uri') {\n return resolved.dataUri;\n }\n\n const data = readFileSync(resolved.filePath);\n return `data:${resolved.mimeType};base64,${data.toString('base64')}`;\n }\n\n /** @deprecated Use loadDataUri. */\n loadBase64(refInput: unknown): string {\n const screenshotRef = normalizeScreenshotRef(refInput);\n if (!screenshotRef) {\n throw new Error('ReportImageStore: invalid screenshot reference');\n }\n return this.loadDataUri(screenshotRef);\n }\n\n cleanup(): void {\n if (\n this.mode === 'directory' &&\n this.screenshotsDir &&\n existsSync(this.screenshotsDir)\n ) {\n rmSync(this.screenshotsDir, { recursive: true, force: true });\n }\n this.writtenInlineIds.clear();\n this.writtenFileIds.clear();\n this.fileLocations.clear();\n this.pendingFiles.clear();\n this.existingInlineImageIdsPromise = undefined;\n }\n}\n\n/** @deprecated Use ReportImageStore. */\nexport { ReportImageStore as ScreenshotStore };\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","base64ImageDataUrlPattern","parseBase64ImageDataUrl","imageUrl","match","Error","mimeType","imageFileExtensionForMimeType","isBase64ImageDataUrl","value","reportImageFileName","extension","bytes","hash","createHash","resolveImageSource","refInput","options","ref","normalizeStoredImageRef","id","resolveReportRelativePath","filePath","isAbsolute","join","dirname","explicitFilePath","existsSync","inlineDataUri","extractImageByIdSync","imageRefFileExtension","companionImagePath","siblingImagePath","resolveScreenshotSource","normalizeScreenshotRef","ReportImageStore","file","screenshot","shouldWriteFileCopy","fileRef","rawBase64","Buffer","fileLocation","imageIds","collectImageScriptIds","imageId","error","relativePath","absolutePath","image","screenshotsDir","mkdirSync","known","fileName","publication","writeReportArtifactFile","location","resolved","data","readFileSync","screenshotRef","rmSync","undefined","Set","Map","Boolean"],"mappings":"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"}
|